Merge remote-tracking branch 'Nightscout/dev' into Autotune/TuneWeekDaysClean
|
@ -111,7 +111,7 @@ android {
|
|||
defaultConfig {
|
||||
multiDexEnabled true
|
||||
versionCode 1500
|
||||
version "3.1.0.3-dev-d"
|
||||
version "3.1.0.3-dev-e"
|
||||
buildConfigField "String", "VERSION", '"' + version + '"'
|
||||
buildConfigField "String", "BUILDVERSION", '"' + generateGitBuild() + '-' + generateDate() + '"'
|
||||
buildConfigField "String", "REMOTE", '"' + generateGitRemote() + '"'
|
||||
|
@ -198,10 +198,12 @@ dependencies {
|
|||
implementation project(':plugins:aps')
|
||||
implementation project(':plugins:automation')
|
||||
implementation project(':plugins:configuration')
|
||||
implementation project(':plugins:constraints')
|
||||
implementation project(':plugins:insulin')
|
||||
implementation project(':plugins:main')
|
||||
implementation project(':plugins:openhumans')
|
||||
implementation project(':plugins:sensitivity')
|
||||
implementation project(':plugins:support')
|
||||
implementation project(':plugins:source')
|
||||
implementation project(':plugins:sync')
|
||||
implementation project(':implementation')
|
||||
implementation project(':database:entities')
|
||||
|
@ -217,10 +219,11 @@ dependencies {
|
|||
implementation project(':pump:medtronic')
|
||||
implementation project(':pump:pump-common')
|
||||
implementation project(':pump:pump-core')
|
||||
implementation project(':pump:rileylink')
|
||||
implementation project(':pump:omnipod-common')
|
||||
implementation project(':pump:omnipod-eros')
|
||||
implementation project(':pump:omnipod-dash')
|
||||
implementation project(':pump:rileylink')
|
||||
implementation project(':pump:virtual')
|
||||
implementation project(':workflow')
|
||||
|
||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||
|
|
|
@ -132,7 +132,7 @@
|
|||
</provider>
|
||||
|
||||
<service
|
||||
android:name="info.nightscout.core.services.AlarmSoundService"
|
||||
android:name="info.nightscout.ui.services.AlarmSoundService"
|
||||
android:enabled="true"
|
||||
android:exported="true" />
|
||||
<uses-library
|
||||
|
|
|
@ -151,10 +151,6 @@ class MainActivity : DaggerAppCompatActivityWithResult() {
|
|||
.toObservable(EventPreferenceChange::class.java)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe({ processPreferenceChange(it) }, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventInitializationChanged::class.java)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe({ passwordResetCheck(this) }, fabricPrivacy::logException)
|
||||
if (startWizard() && !isRunningRealPumpTest()) {
|
||||
protectionCheck.queryProtection(this, ProtectionCheck.Protection.PREFERENCES, {
|
||||
startActivity(Intent(this, SetupWizardActivity::class.java))
|
||||
|
@ -168,6 +164,7 @@ class MainActivity : DaggerAppCompatActivityWithResult() {
|
|||
androidPermission.notifyForSystemWindowPermissions(this)
|
||||
androidPermission.notifyForBtConnectPermission(this)
|
||||
}
|
||||
passwordResetCheck(this)
|
||||
}
|
||||
|
||||
private fun checkPluginPreferences(viewPager: ViewPager2) {
|
||||
|
@ -352,6 +349,7 @@ class MainActivity : DaggerAppCompatActivityWithResult() {
|
|||
message += "Flavor: ${BuildConfig.FLAVOR}${BuildConfig.BUILD_TYPE}\n"
|
||||
message += "${rh.gs(info.nightscout.configuration.R.string.configbuilder_nightscoutversion_label)} ${nsSettingsStatus.getVersion()}"
|
||||
if (config.isEngineeringMode()) message += "\n${rh.gs(info.nightscout.configuration.R.string.engineering_mode_enabled)}"
|
||||
if (config.isUnfinishedMode()) message += "\nUnfinished mode enabled"
|
||||
if (!fabricPrivacy.fabricEnabled()) message += "\n${rh.gs(R.string.fabric_upload_disabled)}"
|
||||
message += rh.gs(info.nightscout.pump.combo.R.string.about_link_urls)
|
||||
val messageSpanned = SpannableString(message)
|
||||
|
|
|
@ -28,6 +28,7 @@ import info.nightscout.automation.AutomationPlugin
|
|||
import info.nightscout.configuration.maintenance.MaintenancePlugin
|
||||
import info.nightscout.core.ui.dialogs.OKDialog
|
||||
import info.nightscout.implementation.plugin.PluginStore
|
||||
import info.nightscout.insulin.InsulinOrefFreePeakPlugin
|
||||
import info.nightscout.interfaces.Config
|
||||
import info.nightscout.interfaces.nsclient.NSSettingsStatus
|
||||
import info.nightscout.interfaces.plugin.PluginBase
|
||||
|
@ -47,22 +48,13 @@ import info.nightscout.plugins.general.autotune.AutotunePlugin
|
|||
import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorPlugin
|
||||
import info.nightscout.plugins.general.wear.WearPlugin
|
||||
import info.nightscout.plugins.general.xdripStatusline.StatusLinePlugin
|
||||
import info.nightscout.plugins.insulin.InsulinOrefFreePeakPlugin
|
||||
import info.nightscout.plugins.pump.virtual.VirtualPumpPlugin
|
||||
import info.nightscout.plugins.source.AidexPlugin
|
||||
import info.nightscout.plugins.source.DexcomPlugin
|
||||
import info.nightscout.plugins.source.EversensePlugin
|
||||
import info.nightscout.plugins.source.GlimpPlugin
|
||||
import info.nightscout.plugins.source.GlunovoPlugin
|
||||
import info.nightscout.plugins.source.IntelligoPlugin
|
||||
import info.nightscout.plugins.source.PoctechPlugin
|
||||
import info.nightscout.plugins.source.TomatoPlugin
|
||||
import info.nightscout.plugins.sync.nsclient.NSClientPlugin
|
||||
import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin
|
||||
import info.nightscout.plugins.sync.tidepool.TidepoolPlugin
|
||||
import info.nightscout.pump.combo.ComboPlugin
|
||||
import info.nightscout.pump.combov2.ComboV2Plugin
|
||||
import info.nightscout.pump.diaconn.DiaconnG8Plugin
|
||||
import info.nightscout.pump.virtual.VirtualPumpPlugin
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.events.EventPreferenceChange
|
||||
import info.nightscout.rx.events.EventRebuildTabs
|
||||
|
@ -72,6 +64,14 @@ import info.nightscout.sensitivity.SensitivityWeightedAveragePlugin
|
|||
import info.nightscout.shared.SafeParse
|
||||
import info.nightscout.shared.interfaces.ResourceHelper
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import info.nightscout.source.AidexPlugin
|
||||
import info.nightscout.source.DexcomPlugin
|
||||
import info.nightscout.source.EversensePlugin
|
||||
import info.nightscout.source.GlimpPlugin
|
||||
import info.nightscout.source.GlunovoPlugin
|
||||
import info.nightscout.source.IntelligoPlugin
|
||||
import info.nightscout.source.PoctechPlugin
|
||||
import info.nightscout.source.TomatoPlugin
|
||||
import javax.inject.Inject
|
||||
|
||||
class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChangeListener {
|
||||
|
|
|
@ -20,9 +20,10 @@ import info.nightscout.core.di.CoreModule
|
|||
import info.nightscout.core.validators.di.ValidatorsModule
|
||||
import info.nightscout.database.impl.DatabaseModule
|
||||
import info.nightscout.implementation.di.ImplementationModule
|
||||
import info.nightscout.insulin.di.InsulinModule
|
||||
import info.nightscout.plugins.aps.di.ApsModule
|
||||
import info.nightscout.plugins.constraints.di.PluginsConstraintsModule
|
||||
import info.nightscout.plugins.di.PluginsModule
|
||||
import info.nightscout.plugins.support.di.PluginsSupportModule
|
||||
import info.nightscout.plugins.sync.di.SyncModule
|
||||
import info.nightscout.pump.combo.di.ComboModule
|
||||
import info.nightscout.pump.combov2.di.ComboV2Module
|
||||
|
@ -31,9 +32,11 @@ import info.nightscout.pump.dana.di.DanaHistoryModule
|
|||
import info.nightscout.pump.dana.di.DanaModule
|
||||
import info.nightscout.pump.danars.di.DanaRSModule
|
||||
import info.nightscout.pump.diaconn.di.DiaconnG8Module
|
||||
import info.nightscout.pump.virtual.di.VirtualPumpModule
|
||||
import info.nightscout.rx.di.RxModule
|
||||
import info.nightscout.shared.di.SharedModule
|
||||
import info.nightscout.shared.impl.di.SharedImplModule
|
||||
import info.nightscout.source.di.SourceModule
|
||||
import info.nightscout.ui.di.UiModule
|
||||
import info.nightscout.workflow.di.WorkflowModule
|
||||
import javax.inject.Singleton
|
||||
|
@ -55,6 +58,7 @@ import javax.inject.Singleton
|
|||
CoreModule::class,
|
||||
DatabaseModule::class,
|
||||
ImplementationModule::class,
|
||||
InsulinModule::class,
|
||||
OpenHumansModule::class,
|
||||
PluginsModule::class,
|
||||
RxModule::class,
|
||||
|
@ -62,7 +66,8 @@ import javax.inject.Singleton
|
|||
SharedImplModule::class,
|
||||
UiModule::class,
|
||||
ValidatorsModule::class,
|
||||
PluginsSupportModule::class,
|
||||
PluginsConstraintsModule::class,
|
||||
SourceModule::class,
|
||||
SyncModule::class,
|
||||
WorkflowModule::class,
|
||||
|
||||
|
@ -81,7 +86,8 @@ import javax.inject.Singleton
|
|||
OmnipodDashModule::class,
|
||||
OmnipodErosModule::class,
|
||||
PumpCommonModule::class,
|
||||
RileyLinkModule::class
|
||||
RileyLinkModule::class,
|
||||
VirtualPumpModule::class
|
||||
]
|
||||
)
|
||||
interface AppComponent : AndroidInjector<MainApp> {
|
||||
|
|
|
@ -7,13 +7,15 @@ import dagger.Module
|
|||
import dagger.Provides
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.implementations.UiInteractionImpl
|
||||
import info.nightscout.androidaps.implementations.ConfigImpl
|
||||
import info.nightscout.androidaps.implementations.InstantiatorImpl
|
||||
import info.nightscout.androidaps.implementations.UiInteractionImpl
|
||||
import info.nightscout.androidaps.workflow.CalculationWorkflowImpl
|
||||
import info.nightscout.androidaps.workflow.WorkerClassesImpl
|
||||
import info.nightscout.core.workflow.CalculationWorkflow
|
||||
import info.nightscout.interfaces.Config
|
||||
import info.nightscout.interfaces.plugin.PluginBase
|
||||
import info.nightscout.interfaces.profile.Instantiator
|
||||
import info.nightscout.interfaces.ui.UiInteraction
|
||||
import info.nightscout.interfaces.workflow.WorkerClasses
|
||||
|
||||
|
@ -53,6 +55,8 @@ open class AppModule {
|
|||
@Binds fun bindActivityNames(activityNames: UiInteractionImpl): UiInteraction
|
||||
@Binds fun bindWorkerClasses(workerClassesImpl: WorkerClassesImpl): WorkerClasses
|
||||
@Binds fun bindCalculationWorkflow(calculationWorkflow: CalculationWorkflowImpl): CalculationWorkflow
|
||||
@Binds fun bindInstantiator(instantiatorImpl: InstantiatorImpl): Instantiator
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ import info.nightscout.androidaps.danaRKorean.DanaRKoreanPlugin
|
|||
import info.nightscout.androidaps.danaRv2.DanaRv2Plugin
|
||||
import info.nightscout.androidaps.danar.DanaRPlugin
|
||||
import info.nightscout.androidaps.plugin.general.openhumans.OpenHumansUploaderPlugin
|
||||
import info.nightscout.plugins.general.persistentNotification.PersistentNotificationPlugin
|
||||
import info.nightscout.androidaps.plugins.pump.eopatch.EopatchPumpPlugin
|
||||
import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin
|
||||
|
@ -17,6 +16,10 @@ import info.nightscout.androidaps.plugins.pump.omnipod.eros.OmnipodErosPumpPlugi
|
|||
import info.nightscout.automation.AutomationPlugin
|
||||
import info.nightscout.configuration.configBuilder.ConfigBuilderPlugin
|
||||
import info.nightscout.configuration.maintenance.MaintenancePlugin
|
||||
import info.nightscout.insulin.InsulinLyumjevPlugin
|
||||
import info.nightscout.insulin.InsulinOrefFreePeakPlugin
|
||||
import info.nightscout.insulin.InsulinOrefRapidActingPlugin
|
||||
import info.nightscout.insulin.InsulinOrefUltraRapidActingPlugin
|
||||
import info.nightscout.interfaces.plugin.PluginBase
|
||||
import info.nightscout.plugins.aps.loop.LoopPlugin
|
||||
import info.nightscout.plugins.aps.openAPSAMA.OpenAPSAMAPlugin
|
||||
|
@ -31,37 +34,34 @@ import info.nightscout.plugins.general.autotune.AutotunePlugin
|
|||
import info.nightscout.plugins.general.dataBroadcaster.DataBroadcastPlugin
|
||||
import info.nightscout.plugins.general.food.FoodPlugin
|
||||
import info.nightscout.plugins.general.overview.OverviewPlugin
|
||||
import info.nightscout.plugins.general.persistentNotification.PersistentNotificationPlugin
|
||||
import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorPlugin
|
||||
import info.nightscout.plugins.general.themes.ThemeSwitcherPlugin
|
||||
import info.nightscout.plugins.general.wear.WearPlugin
|
||||
import info.nightscout.plugins.general.xdripStatusline.StatusLinePlugin
|
||||
import info.nightscout.plugins.insulin.InsulinLyumjevPlugin
|
||||
import info.nightscout.plugins.insulin.InsulinOrefFreePeakPlugin
|
||||
import info.nightscout.plugins.insulin.InsulinOrefRapidActingPlugin
|
||||
import info.nightscout.plugins.insulin.InsulinOrefUltraRapidActingPlugin
|
||||
import info.nightscout.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
||||
import info.nightscout.plugins.profile.ProfilePlugin
|
||||
import info.nightscout.plugins.pump.virtual.VirtualPumpPlugin
|
||||
import info.nightscout.plugins.source.AidexPlugin
|
||||
import info.nightscout.plugins.source.DexcomPlugin
|
||||
import info.nightscout.plugins.source.GlimpPlugin
|
||||
import info.nightscout.plugins.source.GlunovoPlugin
|
||||
import info.nightscout.plugins.source.IntelligoPlugin
|
||||
import info.nightscout.plugins.source.MM640gPlugin
|
||||
import info.nightscout.plugins.source.NSClientSourcePlugin
|
||||
import info.nightscout.plugins.source.PoctechPlugin
|
||||
import info.nightscout.plugins.source.RandomBgPlugin
|
||||
import info.nightscout.plugins.source.TomatoPlugin
|
||||
import info.nightscout.plugins.source.XdripPlugin
|
||||
import info.nightscout.plugins.sync.nsclient.NSClientPlugin
|
||||
import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin
|
||||
import info.nightscout.plugins.sync.tidepool.TidepoolPlugin
|
||||
import info.nightscout.pump.combo.ComboPlugin
|
||||
import info.nightscout.pump.combov2.ComboV2Plugin
|
||||
import info.nightscout.pump.diaconn.DiaconnG8Plugin
|
||||
import info.nightscout.pump.virtual.VirtualPumpPlugin
|
||||
import info.nightscout.sensitivity.SensitivityAAPSPlugin
|
||||
import info.nightscout.sensitivity.SensitivityOref1Plugin
|
||||
import info.nightscout.sensitivity.SensitivityWeightedAveragePlugin
|
||||
import info.nightscout.source.AidexPlugin
|
||||
import info.nightscout.source.DexcomPlugin
|
||||
import info.nightscout.source.GlimpPlugin
|
||||
import info.nightscout.source.GlunovoPlugin
|
||||
import info.nightscout.source.IntelligoPlugin
|
||||
import info.nightscout.source.MM640gPlugin
|
||||
import info.nightscout.source.NSClientSourcePlugin
|
||||
import info.nightscout.source.PoctechPlugin
|
||||
import info.nightscout.source.RandomBgPlugin
|
||||
import info.nightscout.source.TomatoPlugin
|
||||
import info.nightscout.source.XdripPlugin
|
||||
import javax.inject.Qualifier
|
||||
|
||||
@Suppress("unused")
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
package info.nightscout.androidaps.implementations
|
||||
|
||||
import dagger.Reusable
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.implementation.profile.ProfileStoreObject
|
||||
import info.nightscout.interfaces.aps.APSResult
|
||||
import info.nightscout.interfaces.aps.AutosensData
|
||||
import info.nightscout.interfaces.profile.Instantiator
|
||||
import info.nightscout.interfaces.profile.ProfileStore
|
||||
import info.nightscout.plugins.aps.APSResultObject
|
||||
import info.nightscout.plugins.iob.iobCobCalculator.data.AutosensDataObject
|
||||
import info.nightscout.shared.utils.DateUtil
|
||||
import org.json.JSONObject
|
||||
import javax.inject.Inject
|
||||
|
||||
@Reusable
|
||||
class InstantiatorImpl @Inject constructor(
|
||||
private val injector: HasAndroidInjector,
|
||||
private val dateUtil: DateUtil
|
||||
) : Instantiator {
|
||||
|
||||
override fun provideProfileStore(jsonObject: JSONObject): ProfileStore =
|
||||
ProfileStoreObject(injector, jsonObject, dateUtil)
|
||||
|
||||
override fun provideAPSResultObject(): APSResult = APSResultObject(injector)
|
||||
|
||||
override fun provideAutosensDataObject(): AutosensData = AutosensDataObject(injector)
|
||||
}
|
|
@ -14,8 +14,8 @@ import info.nightscout.androidaps.activities.MyPreferenceFragment
|
|||
import info.nightscout.androidaps.activities.PreferencesActivity
|
||||
import info.nightscout.configuration.activities.SingleFragmentActivity
|
||||
import info.nightscout.core.events.EventNewNotification
|
||||
import info.nightscout.core.services.AlarmSoundService
|
||||
import info.nightscout.core.services.AlarmSoundServiceHelper
|
||||
import info.nightscout.ui.services.AlarmSoundService
|
||||
import info.nightscout.ui.services.AlarmSoundServiceHelper
|
||||
import info.nightscout.core.ui.toast.ToastUtils
|
||||
import info.nightscout.interfaces.notifications.Notification
|
||||
import info.nightscout.interfaces.nsclient.NSAlarm
|
||||
|
@ -39,6 +39,7 @@ import info.nightscout.ui.dialogs.TempBasalDialog
|
|||
import info.nightscout.ui.dialogs.TempTargetDialog
|
||||
import info.nightscout.ui.dialogs.TreatmentDialog
|
||||
import info.nightscout.ui.dialogs.WizardDialog
|
||||
import info.nightscout.ui.widget.Widget
|
||||
import javax.inject.Inject
|
||||
|
||||
class UiInteractionImpl @Inject constructor(
|
||||
|
@ -67,6 +68,10 @@ class UiInteractionImpl @Inject constructor(
|
|||
context.startActivity(i)
|
||||
}
|
||||
|
||||
override fun updateWidget(context: Context) {
|
||||
Widget.updateWidget(context)
|
||||
}
|
||||
|
||||
override fun runWizardDialog(fragmentManager: FragmentManager, carbs: Int?, name: String?) {
|
||||
WizardDialog().also { dialog ->
|
||||
dialog.arguments = Bundle().also { bundle ->
|
||||
|
|
|
@ -12,17 +12,17 @@ import info.nightscout.core.utils.extensions.copyString
|
|||
import info.nightscout.core.utils.receivers.DataWorkerStorage
|
||||
import info.nightscout.interfaces.receivers.Intents
|
||||
import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorPlugin
|
||||
import info.nightscout.plugins.source.AidexPlugin
|
||||
import info.nightscout.plugins.source.DexcomPlugin
|
||||
import info.nightscout.plugins.source.EversensePlugin
|
||||
import info.nightscout.plugins.source.GlimpPlugin
|
||||
import info.nightscout.plugins.source.MM640gPlugin
|
||||
import info.nightscout.plugins.source.PoctechPlugin
|
||||
import info.nightscout.plugins.source.TomatoPlugin
|
||||
import info.nightscout.plugins.source.XdripPlugin
|
||||
import info.nightscout.rx.logging.AAPSLogger
|
||||
import info.nightscout.rx.logging.BundleLogger
|
||||
import info.nightscout.rx.logging.LTag
|
||||
import info.nightscout.source.AidexPlugin
|
||||
import info.nightscout.source.DexcomPlugin
|
||||
import info.nightscout.source.EversensePlugin
|
||||
import info.nightscout.source.GlimpPlugin
|
||||
import info.nightscout.source.MM640gPlugin
|
||||
import info.nightscout.source.PoctechPlugin
|
||||
import info.nightscout.source.TomatoPlugin
|
||||
import info.nightscout.source.XdripPlugin
|
||||
import javax.inject.Inject
|
||||
|
||||
open class DataReceiver : DaggerBroadcastReceiver() {
|
||||
|
|
|
@ -3,7 +3,7 @@ package info.nightscout.androidaps.workflow
|
|||
import info.nightscout.interfaces.workflow.WorkerClasses
|
||||
import info.nightscout.plugins.general.food.FoodPlugin
|
||||
import info.nightscout.plugins.profile.ProfilePlugin
|
||||
import info.nightscout.plugins.source.NSClientSourcePlugin
|
||||
import info.nightscout.source.NSClientSourcePlugin
|
||||
import javax.inject.Inject
|
||||
|
||||
class WorkerClassesImpl @Inject constructor(): WorkerClasses{
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
<string name="authorizationfailed">Удостоверяването неуспешно</string>
|
||||
<string name="copytolocalprofile_invalid">Създаването на профила невъзможно. Профилът е невалиден.</string>
|
||||
<string name="cta_dont_kill_my_app_info">Не убивай приложението?</string>
|
||||
<string name="time_to_eat">Време за ядене!\nИзпълнете болус съветника и направете изчисления отново.</string>
|
||||
<string name="fabric_upload_disabled">Качването на данни за проблеми е забранено!(Fabric)</string>
|
||||
<string name="clear_filter">Премахни филтъра</string>
|
||||
<string name="cannula">Канюла</string>
|
||||
|
|
|
@ -44,7 +44,6 @@
|
|||
<string name="authorizationfailed">L\'autorització ha fallat</string>
|
||||
<string name="copytolocalprofile_invalid">No s\'ha pogut crear el perfil local. Perfil no vàlid.</string>
|
||||
<string name="cta_dont_kill_my_app_info">No matar la meva app?</string>
|
||||
<string name="time_to_eat">Hora de menjar!\nExecuteu l\'assistent de bolus i torneu a fer els càlculs.</string>
|
||||
<string name="fabric_upload_disabled">Enviament de logs d\'error desactivat!</string>
|
||||
<string name="clear_filter">Netejar filtres</string>
|
||||
<string name="cannula">Cànula</string>
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
<string name="authorizationfailed">Autorizace selhala</string>
|
||||
<string name="copytolocalprofile_invalid">Nelze vytvořit profil. Profil je neplatný.</string>
|
||||
<string name="cta_dont_kill_my_app_info">Nezabíjet mou aplikaci?</string>
|
||||
<string name="time_to_eat">Čas k jídlu!\nSpusťte Bolusovou kalkulačku a proveďte výpočet znovu.</string>
|
||||
<string name="fabric_upload_disabled">Nahrávání protokolů o pádech zakázáno!</string>
|
||||
<string name="clear_filter">Vymazat filtr</string>
|
||||
<string name="cannula">Kanyla</string>
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
<string name="authorizationfailed">Godkendelse mislykkedes</string>
|
||||
<string name="copytolocalprofile_invalid">Kunne ikke oprette profil. Profilen er ugyldig.</string>
|
||||
<string name="cta_dont_kill_my_app_info">Luk ikke min app?</string>
|
||||
<string name="time_to_eat">Tid til at spise!\nKør Bolus guiden og lav beregning igen.</string>
|
||||
<string name="fabric_upload_disabled">Upload af Crash logs deaktiveret!</string>
|
||||
<string name="clear_filter">Nulstil filter</string>
|
||||
<string name="cannula">Kanyle</string>
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
<string name="authorizationfailed">Autorisierung fehlgeschlagen</string>
|
||||
<string name="copytolocalprofile_invalid">Profil kann nicht erstellt werden. Profil ist ungültig.</string>
|
||||
<string name="cta_dont_kill_my_app_info">Don\'t kill my app?</string>
|
||||
<string name="time_to_eat">Zeit zum Essen!\nStarte den Bolus-Rechner und gib die KH ein. </string>
|
||||
<string name="fabric_upload_disabled">Hochladen von Crash-Protokollen deaktiviert!</string>
|
||||
<string name="clear_filter">Filter löschen</string>
|
||||
<string name="cannula">Kanüle</string>
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
<string name="authorizationfailed">Ha fallado la autorización</string>
|
||||
<string name="copytolocalprofile_invalid">No se puede crear el perfil. El perfil es inválido.</string>
|
||||
<string name="cta_dont_kill_my_app_info">¿No matar mi aplicación?</string>
|
||||
<string name="time_to_eat">¡Hora de comer!\nEjecutar el asistente de bolo y calcular de nuevo.</string>
|
||||
<string name="fabric_upload_disabled">¡Carga de registros de errores desactivada!</string>
|
||||
<string name="clear_filter">Borrar filtro</string>
|
||||
<string name="cannula">Cánula</string>
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
<string name="authorizationfailed">Echec de l\'authentification</string>
|
||||
<string name="copytolocalprofile_invalid">Impossible de créer le profil. Le profil est invalide.</string>
|
||||
<string name="cta_dont_kill_my_app_info">Garder l\'appli en arrière plan ?</string>
|
||||
<string name="time_to_eat">Il est temps de manger !\nExécutez l\'assistant Bolus et refaites le calcul.</string>
|
||||
<string name="fabric_upload_disabled">Téléchargement logs crashs désactivé!</string>
|
||||
<string name="clear_filter">Effacer le filtre</string>
|
||||
<string name="cannula">Canule</string>
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
<string name="authorizationfailed">Autorizzazione fallita</string>
|
||||
<string name="copytolocalprofile_invalid">Impossibile creare il profilo. Il profilo non è valido.</string>
|
||||
<string name="cta_dont_kill_my_app_info">Non terminare l\'app?</string>
|
||||
<string name="time_to_eat">Tempo di mangiare!\nEsegui il calcolatore e fai di nuovi i calcoli.</string>
|
||||
<string name="fabric_upload_disabled">Caricamento log dei crash disabilitato!</string>
|
||||
<string name="clear_filter">Cancella filtro</string>
|
||||
<string name="cannula">Cannula</string>
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
<string name="authorizationfailed">ההרשאה נכשלה</string>
|
||||
<string name="copytolocalprofile_invalid">לא ניתן ליצור פרופיל מקומי. הפרופיל אינו חוקי.</string>
|
||||
<string name="cta_dont_kill_my_app_info">איך לא להשבית את האפליקציה שלי?</string>
|
||||
<string name="time_to_eat">זמן לאכול!\nהפעילו את אשף הבולוסים וחשבו בולוס חדש.</string>
|
||||
<string name="fabric_upload_disabled">העלאת רשומות קריסה מושבתת!</string>
|
||||
<string name="clear_filter">נקה סינון</string>
|
||||
<string name="cannula">צינורית</string>
|
||||
|
|
|
@ -43,7 +43,6 @@
|
|||
<string name="chartmenu">차트 메뉴</string>
|
||||
<string name="authorizationfailed">인증 실패</string>
|
||||
<string name="cta_dont_kill_my_app_info">앱이 종료되지 않도록 합니다?</string>
|
||||
<string name="time_to_eat">식사할 시간입니다! \nBolus wizard를 켜고 다시 계산하십시오.</string>
|
||||
<string name="fabric_upload_disabled">충돌 로그 업로드가 작동하지 않습니다.</string>
|
||||
<string name="clear_filter">필터 지우기</string>
|
||||
<string name="cannula">캐뉼라</string>
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
<string name="authorizationfailed">Autorizacija nepavyko</string>
|
||||
<string name="copytolocalprofile_invalid">Nepavyksta sukurti profilio. Profilis neteisingas.</string>
|
||||
<string name="cta_dont_kill_my_app_info">Don\'t kill my app?</string>
|
||||
<string name="time_to_eat">Laikas valgyti!\nĮjunkite Boluso patarėją ir atlikite skaičiavimą dar kartą.</string>
|
||||
<string name="fabric_upload_disabled">Sutrikimų žurnalo įrašų įkėlimas išjungtas!</string>
|
||||
<string name="clear_filter">Valyti filtrą</string>
|
||||
<string name="cannula">Kaniulė</string>
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
<string name="authorizationfailed">Autorisatie mislukt</string>
|
||||
<string name="copytolocalprofile_invalid">Kan profiel niet aanmaken. Profiel is ongeldig.</string>
|
||||
<string name="cta_dont_kill_my_app_info">Don\'t kill my app?</string>
|
||||
<string name="time_to_eat">Tijd om te eten!\nVoer de boluswizard opnieuw uit.</string>
|
||||
<string name="fabric_upload_disabled">Upload van crashrapporten is uitgeschakeld!</string>
|
||||
<string name="clear_filter">Verwijder filter</string>
|
||||
<string name="cannula">Canule</string>
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
<string name="authorizationfailed">Autentisering feilet</string>
|
||||
<string name="copytolocalprofile_invalid">Klarte ikke å opprette profil. Profilen er ikke gyldig.</string>
|
||||
<string name="cta_dont_kill_my_app_info">Avslutte app?</string>
|
||||
<string name="time_to_eat">Nå må du spise!\Bruk bolus veiviseren og beregn på nytt.</string>
|
||||
<string name="fabric_upload_disabled">Opplast av krasj logger er deaktivert!</string>
|
||||
<string name="clear_filter">Nullstill filtre</string>
|
||||
<string name="cannula">Kanyle</string>
|
||||
|
|
|
@ -44,7 +44,6 @@
|
|||
<string name="authorizationfailed">Autoryzacja nie powiodła się</string>
|
||||
<string name="copytolocalprofile_invalid">Nie można utworzyć profilu. Profil jest nieprawidłowy.</string>
|
||||
<string name="cta_dont_kill_my_app_info">Nie zabij mojej aplikacji?</string>
|
||||
<string name="time_to_eat">Czas jeść!\nUruchom kreatora bolusa i zrób obliczenia ponownie.</string>
|
||||
<string name="fabric_upload_disabled">Przesyłanie dzienników awarii jest wyłączone!</string>
|
||||
<string name="clear_filter">Wyczyść filtr</string>
|
||||
<string name="cannula">Kaniula</string>
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
<string name="authorizationfailed">Falha na autorização</string>
|
||||
<string name="copytolocalprofile_invalid">Não foi possível criar o perfil. Perfil inválido.</string>
|
||||
<string name="cta_dont_kill_my_app_info">Não encerre meu aplicativo?</string>
|
||||
<string name="time_to_eat">Hora de comer!\nAbra o assistente de bolus e faça o cálculo novamente.</string>
|
||||
<string name="fabric_upload_disabled">Envio de logs de erro desativado!</string>
|
||||
<string name="clear_filter">Limpar filtro</string>
|
||||
<string name="cannula">Cânula</string>
|
||||
|
|
|
@ -44,7 +44,6 @@
|
|||
<string name="authorizationfailed">Falha na autorização</string>
|
||||
<string name="copytolocalprofile_invalid">Não é possível criar o perfil. O perfil é inválido.</string>
|
||||
<string name="cta_dont_kill_my_app_info">Não encerre minha app?</string>
|
||||
<string name="time_to_eat">Hora de comer!\nExecutar assistente de Bólus e fazer cálculo novamente.</string>
|
||||
<string name="fabric_upload_disabled">Envio de registos de erro desativado!</string>
|
||||
<string name="clear_filter">Limpar filtros</string>
|
||||
<string name="cannula">Cânula</string>
|
||||
|
|
|
@ -44,7 +44,6 @@
|
|||
<string name="authorizationfailed">Autorizarea a eșuat</string>
|
||||
<string name="copytolocalprofile_invalid">Nu se poate crea profilul. Profilul este invalid.</string>
|
||||
<string name="cta_dont_kill_my_app_info">Nu-mi opri aplicația?</string>
|
||||
<string name="time_to_eat">Timpul sa mănânci!\nRuleaza Calculatorul de Bolus pentru a face calculele din nou.</string>
|
||||
<string name="fabric_upload_disabled">Încărcarea jurnalelor de erori este dezactivata!</string>
|
||||
<string name="clear_filter">Șterge filtru</string>
|
||||
<string name="cannula">Canula</string>
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
<string name="authorizationfailed">Ошибка авторизации</string>
|
||||
<string name="copytolocalprofile_invalid">Не удается создать локальный профиль. Настройки профиля неправильны.</string>
|
||||
<string name="cta_dont_kill_my_app_info">Не закрывать приложение?</string>
|
||||
<string name="time_to_eat">Пора есть!\nЗапустите помощник болюса снова для подсчета.</string>
|
||||
<string name="fabric_upload_disabled">Загрузка журналов сбоя на сервер отключена!</string>
|
||||
<string name="clear_filter">Очистить фильтр</string>
|
||||
<string name="cannula">Катетер помпы</string>
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
<string name="authorizationfailed">Autorizácia zlyhala</string>
|
||||
<string name="copytolocalprofile_invalid">Nie je možné vytvoriť lokálny profil. Profil je neplatný.</string>
|
||||
<string name="cta_dont_kill_my_app_info">Nepotláčať moju aplikáciu?</string>
|
||||
<string name="time_to_eat">Čas na jedlo!\nSpustite Bolusovú kalkulačku a urobte výpočet znova.</string>
|
||||
<string name="fabric_upload_disabled">Odosielanie protokolov o zlyhaní je zakázané!</string>
|
||||
<string name="clear_filter">Vyčistiť filter</string>
|
||||
<string name="cannula">Kanyla</string>
|
||||
|
|
|
@ -44,7 +44,6 @@
|
|||
<string name="authorizationfailed">Behörighetskontroll misslyckades</string>
|
||||
<string name="copytolocalprofile_invalid">Kan inte att skapa profilen. Profilen är felaktig.</string>
|
||||
<string name="cta_dont_kill_my_app_info">Döda inte min app?</string>
|
||||
<string name="time_to_eat">Dags att äta!\nKör bolusguiden igen för ny beräkning.</string>
|
||||
<string name="fabric_upload_disabled">Uppladdning av kraschloggar inaktiverad!</string>
|
||||
<string name="clear_filter">Rensa filter</string>
|
||||
<string name="cannula">Kanyl</string>
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
<string name="authorizationfailed">Yetkilendirme başarısız oldu</string>
|
||||
<string name="copytolocalprofile_invalid">Profil oluşturulamıyor. Profil geçersiz.</string>
|
||||
<string name="cta_dont_kill_my_app_info">Uygulamamı devre dışı bırakma?</string>
|
||||
<string name="time_to_eat">Yemek zamanı!\nBolus sihirbazını çalıştırın ve yeniden hesaplama yapın.</string>
|
||||
<string name="fabric_upload_disabled">Çökme günlükleri yükleme devre dışı bırakıldı!</string>
|
||||
<string name="clear_filter">Filtreyi temizle</string>
|
||||
<string name="cannula">Kanül</string>
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
<string name="authorizationfailed">授权失败</string>
|
||||
<string name="copytolocalprofile_invalid">无法创建配置文件。配置文件无效。</string>
|
||||
<string name="cta_dont_kill_my_app_info">不要杀死我的应用程序?</string>
|
||||
<string name="time_to_eat">吃饭时间到了!\n请运行大剂量向导,然后进行计算。</string>
|
||||
<string name="fabric_upload_disabled">已禁用崩溃日志上传!</string>
|
||||
<string name="clear_filter">清除筛选</string>
|
||||
<string name="cannula">输注导管</string>
|
||||
|
|
|
@ -79,7 +79,6 @@
|
|||
<string name="authorizationfailed">Authorization failed</string>
|
||||
<string name="copytolocalprofile_invalid">Unable to create profile. Profile is invalid.</string>
|
||||
<string name="cta_dont_kill_my_app_info">Don\'t kill my app?</string>
|
||||
<string name="time_to_eat">Time to eat!\nRun Bolus wizard and do calculation again.</string>
|
||||
<string name="fabric_upload_disabled">Crash logs upload disabled!</string>
|
||||
<string name="clear_filter">Clear filter</string>
|
||||
<string name="cannula">Cannula</string>
|
||||
|
|
|
@ -10,9 +10,8 @@ import info.nightscout.androidaps.insight.database.InsightDatabase
|
|||
import info.nightscout.androidaps.insight.database.InsightDatabaseDao
|
||||
import info.nightscout.androidaps.insight.database.InsightDbHelper
|
||||
import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin
|
||||
import info.nightscout.core.iob.iobCobCalculator.GlucoseStatusProvider
|
||||
import info.nightscout.database.impl.AppRepository
|
||||
import info.nightscout.implementation.constraints.ConstraintsImpl
|
||||
import info.nightscout.implementation.iob.GlucoseStatusProviderImpl
|
||||
import info.nightscout.interfaces.bgQualityCheck.BgQualityCheck
|
||||
import info.nightscout.interfaces.constraints.Constraint
|
||||
import info.nightscout.interfaces.constraints.Constraints
|
||||
|
@ -21,7 +20,7 @@ import info.nightscout.interfaces.maintenance.PrefFileListProvider
|
|||
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||
import info.nightscout.interfaces.plugin.PluginBase
|
||||
import info.nightscout.interfaces.plugin.PluginType
|
||||
import info.nightscout.interfaces.profile.ProfileInstantiator
|
||||
import info.nightscout.interfaces.profile.Instantiator
|
||||
import info.nightscout.interfaces.profiling.Profiler
|
||||
import info.nightscout.interfaces.pump.DetailedBolusInfoStorage
|
||||
import info.nightscout.interfaces.pump.PumpEnactResult
|
||||
|
@ -34,17 +33,19 @@ import info.nightscout.interfaces.utils.HardLimits
|
|||
import info.nightscout.plugins.aps.openAPSAMA.OpenAPSAMAPlugin
|
||||
import info.nightscout.plugins.aps.openAPSSMB.OpenAPSSMBPlugin
|
||||
import info.nightscout.plugins.aps.openAPSSMBDynamicISF.OpenAPSSMBDynamicISFPlugin
|
||||
import info.nightscout.plugins.constraints.ConstraintsImpl
|
||||
import info.nightscout.plugins.constraints.objectives.ObjectivesPlugin
|
||||
import info.nightscout.plugins.constraints.objectives.objectives.Objective
|
||||
import info.nightscout.plugins.constraints.safety.SafetyPlugin
|
||||
import info.nightscout.plugins.pump.virtual.VirtualPumpPlugin
|
||||
import info.nightscout.plugins.source.GlimpPlugin
|
||||
import info.nightscout.pump.combo.ComboPlugin
|
||||
import info.nightscout.pump.combo.ruffyscripter.RuffyScripter
|
||||
import info.nightscout.pump.dana.DanaPump
|
||||
import info.nightscout.pump.dana.R
|
||||
import info.nightscout.pump.dana.database.DanaHistoryDatabase
|
||||
import info.nightscout.pump.virtual.VirtualPumpPlugin
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import org.junit.Assert
|
||||
import info.nightscout.source.GlimpPlugin
|
||||
import org.junit.jupiter.api.Assertions
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.mockito.Mock
|
||||
|
@ -69,7 +70,7 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
|
|||
@Mock lateinit var insightDatabaseDao: InsightDatabaseDao
|
||||
@Mock lateinit var ruffyScripter: RuffyScripter
|
||||
@Mock lateinit var uiInteraction: UiInteraction
|
||||
@Mock lateinit var profileInstantiator: ProfileInstantiator
|
||||
@Mock lateinit var instantiator: Instantiator
|
||||
@Mock lateinit var danaHistoryDatabase: DanaHistoryDatabase
|
||||
@Mock lateinit var insightDatabase: InsightDatabase
|
||||
@Mock lateinit var bgQualityCheck: BgQualityCheck
|
||||
|
@ -102,46 +103,49 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
|
|||
|
||||
@BeforeEach
|
||||
fun prepare() {
|
||||
`when`(rh.gs(info.nightscout.plugins.R.string.closed_loop_disabled_on_dev_branch)).thenReturn("Running dev version. Closed loop is disabled.")
|
||||
`when`(rh.gs(info.nightscout.plugins.R.string.closedmodedisabledinpreferences)).thenReturn("Closed loop mode disabled in preferences")
|
||||
`when`(rh.gs(info.nightscout.plugins.constraints.R.string.closed_loop_disabled_on_dev_branch)).thenReturn("Running dev version. Closed loop is disabled.")
|
||||
`when`(rh.gs(info.nightscout.plugins.constraints.R.string.closedmodedisabledinpreferences)).thenReturn("Closed loop mode disabled in preferences")
|
||||
`when`(rh.gs(info.nightscout.core.ui.R.string.no_valid_basal_rate)).thenReturn("No valid basal rate read from pump")
|
||||
`when`(rh.gs(info.nightscout.plugins.aps.R.string.autosens_disabled_in_preferences)).thenReturn("Autosens disabled in preferences")
|
||||
`when`(rh.gs(info.nightscout.plugins.aps.R.string.smb_disabled_in_preferences)).thenReturn("SMB disabled in preferences")
|
||||
`when`(rh.gs(info.nightscout.core.ui.R.string.pumplimit)).thenReturn("pump limit")
|
||||
`when`(rh.gs(info.nightscout.core.ui.R.string.itmustbepositivevalue)).thenReturn("it must be positive value")
|
||||
`when`(rh.gs(info.nightscout.plugins.R.string.maxvalueinpreferences)).thenReturn("max value in preferences")
|
||||
`when`(rh.gs(info.nightscout.plugins.constraints.R.string.maxvalueinpreferences)).thenReturn("max value in preferences")
|
||||
`when`(rh.gs(info.nightscout.plugins.aps.R.string.max_basal_multiplier)).thenReturn("max basal multiplier")
|
||||
`when`(rh.gs(info.nightscout.plugins.aps.R.string.max_daily_basal_multiplier)).thenReturn("max daily basal multiplier")
|
||||
`when`(rh.gs(info.nightscout.core.ui.R.string.pumplimit)).thenReturn("pump limit")
|
||||
`when`(rh.gs(info.nightscout.core.ui.R.string.limitingbolus)).thenReturn("Limiting bolus to %.1f U because of %s")
|
||||
`when`(rh.gs(info.nightscout.plugins.R.string.hardlimit)).thenReturn("hard limit")
|
||||
`when`(rh.gs(info.nightscout.plugins.constraints.R.string.hardlimit)).thenReturn("hard limit")
|
||||
`when`(rh.gs(info.nightscout.core.utils.R.string.key_child)).thenReturn("child")
|
||||
`when`(rh.gs(info.nightscout.plugins.R.string.limitingcarbs)).thenReturn("Limiting carbs to %d g because of %s")
|
||||
`when`(rh.gs(info.nightscout.plugins.constraints.R.string.limitingcarbs)).thenReturn("Limiting carbs to %d g because of %s")
|
||||
`when`(rh.gs(info.nightscout.plugins.aps.R.string.limiting_iob)).thenReturn("Limiting IOB to %.1f U because of %s")
|
||||
`when`(rh.gs(info.nightscout.core.ui.R.string.limitingbasalratio)).thenReturn("Limiting max basal rate to %1\$.2f U/h because of %2\$s")
|
||||
`when`(rh.gs(info.nightscout.core.ui.R.string.limitingpercentrate)).thenReturn("Limiting max percent rate to %1\$d%% because of %2\$s")
|
||||
`when`(rh.gs(info.nightscout.core.ui.R.string.itmustbepositivevalue)).thenReturn("it must be positive value")
|
||||
`when`(rh.gs(info.nightscout.plugins.R.string.smbnotallowedinopenloopmode)).thenReturn("SMB not allowed in open loop mode")
|
||||
`when`(rh.gs(info.nightscout.plugins.constraints.R.string.smbnotallowedinopenloopmode)).thenReturn("SMB not allowed in open loop mode")
|
||||
`when`(rh.gs(info.nightscout.core.ui.R.string.pumplimit)).thenReturn("pump limit")
|
||||
`when`(rh.gs(info.nightscout.plugins.R.string.smbalwaysdisabled)).thenReturn("SMB always and after carbs disabled because active BG source doesn\\'t support advanced filtering")
|
||||
`when`(rh.gs(info.nightscout.plugins.constraints.R.string.smbalwaysdisabled)).thenReturn("SMB always and after carbs disabled because active BG source doesn\\'t support advanced filtering")
|
||||
`when`(rh.gs(info.nightscout.core.ui.R.string.limitingpercentrate)).thenReturn("Limiting max percent rate to %1\$d%% because of %2\$s")
|
||||
`when`(rh.gs(info.nightscout.core.ui.R.string.limitingbolus)).thenReturn("Limiting bolus to %1\$.1f U because of %2\$s")
|
||||
`when`(rh.gs(info.nightscout.core.ui.R.string.limitingbasalratio)).thenReturn("Limiting max basal rate to %1\$.2f U/h because of %2\$s")
|
||||
`when`(context.getString(info.nightscout.pump.combo.R.string.combo_pump_unsupported_operation)).thenReturn("Requested operation not supported by pump")
|
||||
`when`(rh.gs(info.nightscout.plugins.R.string.objectivenotstarted)).thenReturn("Objective %1\$d not started")
|
||||
`when`(rh.gs(info.nightscout.plugins.constraints.R.string.objectivenotstarted)).thenReturn("Objective %1\$d not started")
|
||||
|
||||
// RS constructor
|
||||
`when`(sp.getString(info.nightscout.pump.dana.R.string.key_danars_address, "")).thenReturn("")
|
||||
`when`(sp.getString(R.string.key_danars_name, "")).thenReturn("")
|
||||
`when`(sp.getString(R.string.key_danars_address, "")).thenReturn("")
|
||||
// R
|
||||
`when`(sp.getString(R.string.key_danar_bt_name, "")).thenReturn("")
|
||||
|
||||
//SafetyPlugin
|
||||
`when`(activePlugin.activePump).thenReturn(virtualPumpPlugin)
|
||||
constraintChecker = ConstraintsImpl(activePlugin)
|
||||
|
||||
val glucoseStatusProvider = GlucoseStatusProvider(aapsLogger = aapsLogger, iobCobCalculator = iobCobCalculator, dateUtil = dateUtil)
|
||||
val glucoseStatusProvider = GlucoseStatusProviderImpl(aapsLogger = aapsLogger, iobCobCalculator = iobCobCalculator, dateUtil = dateUtil)
|
||||
|
||||
hardLimits = HardLimitsMock(sp, rh)
|
||||
insightDbHelper = InsightDbHelper(insightDatabaseDao)
|
||||
danaPump = DanaPump(aapsLogger, sp, dateUtil, profileInstantiator)
|
||||
danaPump = DanaPump(aapsLogger, sp, dateUtil, instantiator)
|
||||
objectivesPlugin = ObjectivesPlugin(injector, aapsLogger, rh, activePlugin, sp, config)
|
||||
comboPlugin = ComboPlugin(injector, aapsLogger, rxBus, rh, profileFunction, sp, commandQueue, pumpSync, dateUtil, ruffyScripter, uiInteraction)
|
||||
danaRPlugin = DanaRPlugin(injector, aapsLogger, aapsSchedulers, rxBus, context, rh, constraintChecker, activePlugin, sp, commandQueue, danaPump, dateUtil, fabricPrivacy, pumpSync,
|
||||
|
@ -238,7 +242,8 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
|
|||
hardLimits,
|
||||
ConfigImpl(fileListProvider),
|
||||
iobCobCalculator,
|
||||
dateUtil
|
||||
dateUtil,
|
||||
uiInteraction
|
||||
)
|
||||
val constraintsPluginsList = ArrayList<PluginBase>()
|
||||
constraintsPluginsList.add(safetyPlugin)
|
||||
|
@ -260,9 +265,9 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
|
|||
comboPlugin.setPluginEnabled(PluginType.PUMP, true)
|
||||
comboPlugin.setValidBasalRateProfileSelectedOnPump(false)
|
||||
val c = constraintChecker.isLoopInvocationAllowed()
|
||||
Assert.assertEquals(true, c.reasonList.size == 2) // Combo & Objectives
|
||||
Assert.assertEquals(true, c.mostLimitedReasonList.size == 2) // Combo & Objectives
|
||||
Assert.assertEquals(java.lang.Boolean.FALSE, c.value())
|
||||
Assertions.assertEquals(true, c.reasonList.size == 2) // Combo & Objectives
|
||||
Assertions.assertEquals(true, c.mostLimitedReasonList.size == 2) // Combo & Objectives
|
||||
Assertions.assertEquals(java.lang.Boolean.FALSE, c.value())
|
||||
}
|
||||
|
||||
// Safety & Objectives
|
||||
|
@ -273,13 +278,13 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
|
|||
objectivesPlugin.objectives[Objectives.MAXIOB_ZERO_CL_OBJECTIVE].startedOn = 0
|
||||
var c: Constraint<Boolean> = constraintChecker.isClosedLoopAllowed()
|
||||
aapsLogger.debug("Reason list: " + c.reasonList.toString())
|
||||
// Assert.assertTrue(c.reasonList[0].toString().contains("Closed loop is disabled")) // Safety & Objectives
|
||||
Assert.assertEquals(false, c.value())
|
||||
// Assertions.assertTrue(c.reasonList[0].toString().contains("Closed loop is disabled")) // Safety & Objectives
|
||||
Assertions.assertEquals(false, c.value())
|
||||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, "open")).thenReturn("open")
|
||||
c = constraintChecker.isClosedLoopAllowed()
|
||||
Assert.assertTrue(c.reasonList[0].contains("Closed loop mode disabled in preferences")) // Safety & Objectives
|
||||
// Assert.assertEquals(3, c.reasonList.size) // 2x Safety & Objectives
|
||||
Assert.assertEquals(false, c.value())
|
||||
Assertions.assertTrue(c.reasonList[0].contains("Closed loop mode disabled in preferences")) // Safety & Objectives
|
||||
// Assertions.assertEquals(3, c.reasonList.size) // 2x Safety & Objectives
|
||||
Assertions.assertEquals(false, c.value())
|
||||
}
|
||||
|
||||
// Safety & Objectives
|
||||
|
@ -289,9 +294,9 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
|
|||
objectivesPlugin.objectives[Objectives.AUTOSENS_OBJECTIVE].startedOn = 0
|
||||
`when`(sp.getBoolean(info.nightscout.plugins.aps.R.string.key_openapsama_use_autosens, false)).thenReturn(false)
|
||||
val c = constraintChecker.isAutosensModeEnabled()
|
||||
Assert.assertEquals(true, c.reasonList.size == 2) // Safety & Objectives
|
||||
Assert.assertEquals(true, c.mostLimitedReasonList.size == 2) // Safety & Objectives
|
||||
Assert.assertEquals(java.lang.Boolean.FALSE, c.value())
|
||||
Assertions.assertEquals(true, c.reasonList.size == 2) // Safety & Objectives
|
||||
Assertions.assertEquals(true, c.mostLimitedReasonList.size == 2) // Safety & Objectives
|
||||
Assertions.assertEquals(java.lang.Boolean.FALSE, c.value())
|
||||
}
|
||||
|
||||
// Safety
|
||||
|
@ -299,9 +304,9 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
|
|||
fun isAdvancedFilteringEnabledTest() {
|
||||
`when`(activePlugin.activeBgSource).thenReturn(glimpPlugin)
|
||||
val c = constraintChecker.isAdvancedFilteringEnabled()
|
||||
Assert.assertEquals(true, c.reasonList.size == 1) // Safety
|
||||
Assert.assertEquals(true, c.mostLimitedReasonList.size == 1) // Safety
|
||||
Assert.assertEquals(false, c.value())
|
||||
Assertions.assertEquals(true, c.reasonList.size == 1) // Safety
|
||||
Assertions.assertEquals(true, c.mostLimitedReasonList.size == 1) // Safety
|
||||
Assertions.assertEquals(false, c.value())
|
||||
}
|
||||
|
||||
// SMB should limit
|
||||
|
@ -309,7 +314,7 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
|
|||
fun isSuperBolusEnabledTest() {
|
||||
openAPSSMBPlugin.setPluginEnabled(PluginType.APS, true)
|
||||
val c = constraintChecker.isSuperBolusEnabled()
|
||||
Assert.assertEquals(java.lang.Boolean.FALSE, c.value()) // SMB should limit
|
||||
Assertions.assertEquals(java.lang.Boolean.FALSE, c.value()) // SMB should limit
|
||||
}
|
||||
|
||||
// Safety & Objectives
|
||||
|
@ -321,9 +326,9 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
|
|||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, "open")).thenReturn("open")
|
||||
// `when`(constraintChecker.isClosedLoopAllowed()).thenReturn(Constraint(true))
|
||||
val c = constraintChecker.isSMBModeEnabled()
|
||||
Assert.assertEquals(true, c.reasonList.size == 3) // 2x Safety & Objectives
|
||||
Assert.assertEquals(true, c.mostLimitedReasonList.size == 3) // 2x Safety & Objectives
|
||||
Assert.assertEquals(false, c.value())
|
||||
Assertions.assertEquals(true, c.reasonList.size == 3) // 2x Safety & Objectives
|
||||
Assertions.assertEquals(true, c.mostLimitedReasonList.size == 3) // 2x Safety & Objectives
|
||||
Assertions.assertEquals(false, c.value())
|
||||
}
|
||||
|
||||
// applyBasalConstraints tests
|
||||
|
@ -349,9 +354,9 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
|
|||
|
||||
// Apply all limits
|
||||
val d = constraintChecker.getMaxBasalAllowed(validProfile)
|
||||
Assert.assertEquals(0.8, d.value(), 0.01)
|
||||
Assert.assertEquals(3, d.reasonList.size)
|
||||
Assert.assertEquals("DanaR: Limiting max basal rate to 0.80 U/h because of pump limit", d.getMostLimitedReasons(aapsLogger))
|
||||
Assertions.assertEquals(0.8, d.value(), 0.01)
|
||||
Assertions.assertEquals(3, d.reasonList.size)
|
||||
Assertions.assertEquals("DanaR: Limiting max basal rate to 0.80 U/h because of pump limit", d.getMostLimitedReasons(aapsLogger))
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -376,9 +381,9 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
|
|||
|
||||
// Apply all limits
|
||||
val i = constraintChecker.getMaxBasalPercentAllowed(validProfile)
|
||||
Assert.assertEquals(200, i.value())
|
||||
Assert.assertEquals(6, i.reasonList.size)
|
||||
Assert.assertEquals("Safety: Limiting max percent rate to 200% because of pump limit", i.getMostLimitedReasons(aapsLogger))
|
||||
Assertions.assertEquals(200, i.value())
|
||||
Assertions.assertEquals(6, i.reasonList.size)
|
||||
Assertions.assertEquals("Safety: Limiting max percent rate to 200% because of pump limit", i.getMostLimitedReasons(aapsLogger))
|
||||
}
|
||||
|
||||
// applyBolusConstraints tests
|
||||
|
@ -403,9 +408,9 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
|
|||
|
||||
// Apply all limits
|
||||
val d = constraintChecker.getMaxBolusAllowed()
|
||||
Assert.assertEquals(3.0, d.value(), 0.01)
|
||||
Assert.assertEquals(4, d.reasonList.size) // 2x Safety & RS & R
|
||||
Assert.assertEquals("Safety: Limiting bolus to 3.0 U because of max value in preferences", d.getMostLimitedReasons(aapsLogger))
|
||||
Assertions.assertEquals(3.0, d.value(), 0.01)
|
||||
Assertions.assertEquals(4, d.reasonList.size) // 2x Safety & RS & R
|
||||
Assertions.assertEquals("Safety: Limiting bolus to 3.0 U because of max value in preferences", d.getMostLimitedReasons(aapsLogger))
|
||||
}
|
||||
|
||||
// applyCarbsConstraints tests
|
||||
|
@ -416,9 +421,9 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
|
|||
|
||||
// Apply all limits
|
||||
val i = constraintChecker.getMaxCarbsAllowed()
|
||||
Assert.assertEquals(48, i.value())
|
||||
Assert.assertEquals(true, i.reasonList.size == 1)
|
||||
Assert.assertEquals("Safety: Limiting carbs to 48 g because of max value in preferences", i.getMostLimitedReasons(aapsLogger))
|
||||
Assertions.assertEquals(48, i.value())
|
||||
Assertions.assertEquals(true, i.reasonList.size == 1)
|
||||
Assertions.assertEquals("Safety: Limiting carbs to 48 g because of max value in preferences", i.getMostLimitedReasons(aapsLogger))
|
||||
}
|
||||
|
||||
// applyMaxIOBConstraints tests
|
||||
|
@ -433,9 +438,9 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
|
|||
|
||||
// Apply all limits
|
||||
val d = constraintChecker.getMaxIOBAllowed()
|
||||
Assert.assertEquals(1.5, d.value(), 0.01)
|
||||
Assert.assertEquals(d.reasonList.toString(), 2, d.reasonList.size)
|
||||
Assert.assertEquals("OpenAPSAMA: Limiting IOB to 1.5 U because of max value in preferences", d.getMostLimitedReasons(aapsLogger))
|
||||
Assertions.assertEquals(1.5, d.value(), 0.01)
|
||||
Assertions.assertEquals(2, d.reasonList.size)
|
||||
Assertions.assertEquals("OpenAPSAMA: Limiting IOB to 1.5 U because of max value in preferences", d.getMostLimitedReasons(aapsLogger))
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -449,8 +454,8 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
|
|||
|
||||
// Apply all limits
|
||||
val d = constraintChecker.getMaxIOBAllowed()
|
||||
Assert.assertEquals(3.0, d.value(), 0.01)
|
||||
Assert.assertEquals(d.reasonList.toString(), 2, d.reasonList.size)
|
||||
Assert.assertEquals("OpenAPSSMB: Limiting IOB to 3.0 U because of max value in preferences", d.getMostLimitedReasons(aapsLogger))
|
||||
Assertions.assertEquals(3.0, d.value(), 0.01)
|
||||
Assertions.assertEquals(2, d.reasonList.size)
|
||||
Assertions.assertEquals("OpenAPSSMB: Limiting IOB to 3.0 U because of max value in preferences", d.getMostLimitedReasons(aapsLogger))
|
||||
}
|
||||
}
|
|
@ -21,7 +21,7 @@ import info.nightscout.interfaces.receivers.ReceiverStatusStore
|
|||
import info.nightscout.interfaces.ui.UiInteraction
|
||||
import info.nightscout.plugins.aps.loop.LoopFragment
|
||||
import info.nightscout.plugins.aps.loop.LoopPlugin
|
||||
import info.nightscout.plugins.pump.virtual.VirtualPumpPlugin
|
||||
import info.nightscout.pump.virtual.VirtualPumpPlugin
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.shared.interfaces.ResourceHelper
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
|
|
|
@ -4,25 +4,25 @@ import dagger.android.AndroidInjector
|
|||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.HardLimitsMock
|
||||
import info.nightscout.androidaps.TestBaseWithProfile
|
||||
import info.nightscout.core.iob.iobCobCalculator.GlucoseStatusProvider
|
||||
import info.nightscout.database.impl.AppRepository
|
||||
import info.nightscout.interfaces.Constants
|
||||
import info.nightscout.interfaces.bgQualityCheck.BgQualityCheck
|
||||
import info.nightscout.interfaces.constraints.Constraint
|
||||
import info.nightscout.interfaces.constraints.Constraints
|
||||
import info.nightscout.interfaces.iob.GlucoseStatusProvider
|
||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||
import info.nightscout.interfaces.plugin.PluginType
|
||||
import info.nightscout.interfaces.profiling.Profiler
|
||||
import info.nightscout.interfaces.pump.defs.PumpDescription
|
||||
import info.nightscout.interfaces.ui.UiInteraction
|
||||
import info.nightscout.interfaces.utils.HardLimits
|
||||
import info.nightscout.plugins.R
|
||||
import info.nightscout.plugins.aps.openAPSAMA.OpenAPSAMAPlugin
|
||||
import info.nightscout.plugins.aps.openAPSSMB.OpenAPSSMBPlugin
|
||||
import info.nightscout.plugins.constraints.safety.SafetyPlugin
|
||||
import info.nightscout.plugins.pump.virtual.VirtualPumpPlugin
|
||||
import info.nightscout.plugins.source.GlimpPlugin
|
||||
import info.nightscout.pump.virtual.VirtualPumpPlugin
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import org.junit.Assert
|
||||
import info.nightscout.source.GlimpPlugin
|
||||
import org.junit.jupiter.api.Assertions
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.mockito.Mock
|
||||
|
@ -39,6 +39,7 @@ class SafetyPluginTest : TestBaseWithProfile() {
|
|||
@Mock lateinit var repository: AppRepository
|
||||
@Mock lateinit var glucoseStatusProvider: GlucoseStatusProvider
|
||||
@Mock lateinit var bgQualityCheck: BgQualityCheck
|
||||
@Mock lateinit var uiInteraction: UiInteraction
|
||||
|
||||
private lateinit var hardLimits: HardLimits
|
||||
private lateinit var safetyPlugin: SafetyPlugin
|
||||
|
@ -50,24 +51,24 @@ class SafetyPluginTest : TestBaseWithProfile() {
|
|||
|
||||
@BeforeEach
|
||||
fun prepare() {
|
||||
`when`(rh.gs(R.string.hardlimit)).thenReturn("hard limit")
|
||||
`when`(rh.gs(info.nightscout.plugins.constraints.R.string.hardlimit)).thenReturn("hard limit")
|
||||
`when`(rh.gs(info.nightscout.core.ui.R.string.itmustbepositivevalue)).thenReturn("it must be positive value")
|
||||
`when`(rh.gs(info.nightscout.core.ui.R.string.pumplimit)).thenReturn("pump limit")
|
||||
`when`(rh.gs(R.string.maxvalueinpreferences)).thenReturn("max value in preferences")
|
||||
`when`(rh.gs(info.nightscout.plugins.constraints.R.string.maxvalueinpreferences)).thenReturn("max value in preferences")
|
||||
`when`(rh.gs(info.nightscout.plugins.aps.R.string.max_daily_basal_multiplier)).thenReturn("max daily basal multiplier")
|
||||
`when`(rh.gs(info.nightscout.plugins.aps.R.string.max_basal_multiplier)).thenReturn("max basal multiplier")
|
||||
`when`(rh.gs(info.nightscout.core.ui.R.string.limitingbolus)).thenReturn("Limiting bolus to %1\$.1f U because of %2\$s")
|
||||
`when`(rh.gs(info.nightscout.core.ui.R.string.limitingbasalratio)).thenReturn("Limiting max basal rate to %1\$.2f U/h because of %2\$s")
|
||||
`when`(rh.gs(info.nightscout.core.ui.R.string.limiting_iob)).thenReturn("Limiting IOB to %1\$.1f U because of %2\$s")
|
||||
`when`(rh.gs(R.string.limitingcarbs)).thenReturn("Limiting carbs to %1\$d g because of %2\$s")
|
||||
`when`(rh.gs(info.nightscout.plugins.constraints.R.string.limitingcarbs)).thenReturn("Limiting carbs to %1\$d g because of %2\$s")
|
||||
`when`(rh.gs(info.nightscout.core.ui.R.string.limitingpercentrate)).thenReturn("Limiting max percent rate to %1\$d%% because of %2\$s")
|
||||
`when`(rh.gs(R.string.pumpisnottempbasalcapable)).thenReturn("Pump is not temp basal capable")
|
||||
`when`(rh.gs(info.nightscout.plugins.constraints.R.string.pumpisnottempbasalcapable)).thenReturn("Pump is not temp basal capable")
|
||||
`when`(rh.gs(info.nightscout.plugins.aps.R.string.increasing_max_basal)).thenReturn("Increasing max basal value because setting is lower than your max basal in profile")
|
||||
`when`(rh.gs(info.nightscout.plugins.aps.R.string.smb_disabled_in_preferences)).thenReturn("SMB disabled in preferences")
|
||||
`when`(rh.gs(R.string.closedmodedisabledinpreferences)).thenReturn("Closed loop mode disabled in preferences")
|
||||
`when`(rh.gs(R.string.closed_loop_disabled_on_dev_branch)).thenReturn("Running dev version. Closed loop is disabled.")
|
||||
`when`(rh.gs(R.string.smbalwaysdisabled)).thenReturn("SMB always and after carbs disabled because active BG source doesn\\'t support advanced filtering")
|
||||
`when`(rh.gs(R.string.smbnotallowedinopenloopmode)).thenReturn("SMB not allowed in open loop mode")
|
||||
`when`(rh.gs(info.nightscout.plugins.constraints.R.string.closedmodedisabledinpreferences)).thenReturn("Closed loop mode disabled in preferences")
|
||||
`when`(rh.gs(info.nightscout.plugins.constraints.R.string.closed_loop_disabled_on_dev_branch)).thenReturn("Running dev version. Closed loop is disabled.")
|
||||
`when`(rh.gs(info.nightscout.plugins.constraints.R.string.smbalwaysdisabled)).thenReturn("SMB always and after carbs disabled because active BG source doesn\\'t support advanced filtering")
|
||||
`when`(rh.gs(info.nightscout.plugins.constraints.R.string.smbnotallowedinopenloopmode)).thenReturn("SMB not allowed in open loop mode")
|
||||
`when`(rh.gs(info.nightscout.core.utils.R.string.key_child)).thenReturn("child")
|
||||
`when`(rh.gs(info.nightscout.core.ui.R.string.lowglucosesuspend)).thenReturn("Low Glucose Suspend")
|
||||
|
||||
|
@ -75,7 +76,7 @@ class SafetyPluginTest : TestBaseWithProfile() {
|
|||
`when`(virtualPumpPlugin.pumpDescription).thenReturn(pumpDescription)
|
||||
`when`(config.APS).thenReturn(true)
|
||||
hardLimits = HardLimitsMock(sp, rh)
|
||||
safetyPlugin = SafetyPlugin(injector, aapsLogger, rh, sp, rxBus, constraintChecker, activePlugin, hardLimits, config, iobCobCalculator, dateUtil)
|
||||
safetyPlugin = SafetyPlugin(injector, aapsLogger, rh, sp, rxBus, constraintChecker, activePlugin, hardLimits, config, iobCobCalculator, dateUtil, uiInteraction)
|
||||
openAPSAMAPlugin = OpenAPSAMAPlugin(
|
||||
injector, aapsLogger, rxBus, constraintChecker, rh, profileFunction, context, activePlugin, iobCobCalculator, hardLimits, profiler, fabricPrivacy,
|
||||
dateUtil, repository, glucoseStatusProvider, sp
|
||||
|
@ -91,8 +92,8 @@ class SafetyPluginTest : TestBaseWithProfile() {
|
|||
pumpDescription.isTempBasalCapable = false
|
||||
var c = Constraint(true)
|
||||
c = safetyPlugin.isLoopInvocationAllowed(c)
|
||||
Assert.assertEquals("Safety: Pump is not temp basal capable", c.getReasons(aapsLogger))
|
||||
Assert.assertEquals(false, c.value())
|
||||
Assertions.assertEquals("Safety: Pump is not temp basal capable", c.getReasons(aapsLogger))
|
||||
Assertions.assertEquals(false, c.value())
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -101,8 +102,8 @@ class SafetyPluginTest : TestBaseWithProfile() {
|
|||
`when`(config.isEngineeringModeOrRelease()).thenReturn(false)
|
||||
var c = Constraint(true)
|
||||
c = safetyPlugin.isClosedLoopAllowed(c)
|
||||
Assert.assertTrue(c.getReasons(aapsLogger).contains("Running dev version. Closed loop is disabled."))
|
||||
Assert.assertEquals(false, c.value())
|
||||
Assertions.assertTrue(c.getReasons(aapsLogger).contains("Running dev version. Closed loop is disabled."))
|
||||
Assertions.assertEquals(false, c.value())
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -110,8 +111,8 @@ class SafetyPluginTest : TestBaseWithProfile() {
|
|||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, "open")).thenReturn("open")
|
||||
var c = Constraint(true)
|
||||
c = safetyPlugin.isClosedLoopAllowed(c)
|
||||
Assert.assertTrue(c.getReasons(aapsLogger).contains("Closed loop mode disabled in preferences"))
|
||||
Assert.assertEquals(false, c.value())
|
||||
Assertions.assertTrue(c.getReasons(aapsLogger).contains("Closed loop mode disabled in preferences"))
|
||||
Assertions.assertEquals(false, c.value())
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -120,8 +121,8 @@ class SafetyPluginTest : TestBaseWithProfile() {
|
|||
`when`(constraintChecker.isClosedLoopAllowed(anyObject())).thenReturn(Constraint(true))
|
||||
var c = Constraint(true)
|
||||
c = openAPSSMBPlugin.isSMBModeEnabled(c)
|
||||
Assert.assertTrue(c.getReasons(aapsLogger).contains("SMB disabled in preferences"))
|
||||
Assert.assertEquals(false, c.value())
|
||||
Assertions.assertTrue(c.getReasons(aapsLogger).contains("SMB disabled in preferences"))
|
||||
Assertions.assertEquals(false, c.value())
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -130,8 +131,8 @@ class SafetyPluginTest : TestBaseWithProfile() {
|
|||
`when`(constraintChecker.isClosedLoopAllowed(anyObject())).thenReturn(Constraint(false))
|
||||
var c = Constraint(true)
|
||||
c = safetyPlugin.isSMBModeEnabled(c)
|
||||
Assert.assertTrue(c.getReasons(aapsLogger).contains("SMB not allowed in open loop mode"))
|
||||
Assert.assertEquals(false, c.value())
|
||||
Assertions.assertTrue(c.getReasons(aapsLogger).contains("SMB not allowed in open loop mode"))
|
||||
Assertions.assertEquals(false, c.value())
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -139,8 +140,8 @@ class SafetyPluginTest : TestBaseWithProfile() {
|
|||
`when`(activePlugin.activeBgSource).thenReturn(glimpPlugin)
|
||||
var c = Constraint(true)
|
||||
c = safetyPlugin.isAdvancedFilteringEnabled(c)
|
||||
Assert.assertEquals("Safety: SMB always and after carbs disabled because active BG source doesn\\'t support advanced filtering", c.getReasons(aapsLogger))
|
||||
Assert.assertEquals(false, c.value())
|
||||
Assertions.assertEquals("Safety: SMB always and after carbs disabled because active BG source doesn\\'t support advanced filtering", c.getReasons(aapsLogger))
|
||||
Assertions.assertEquals(false, c.value())
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -151,13 +152,13 @@ class SafetyPluginTest : TestBaseWithProfile() {
|
|||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("child")
|
||||
val c = Constraint(Constants.REALLYHIGHBASALRATE)
|
||||
safetyPlugin.applyBasalConstraints(c, validProfile)
|
||||
Assert.assertEquals(2.0, c.value(), 0.01)
|
||||
Assert.assertEquals(
|
||||
Assertions.assertEquals(2.0, c.value(), 0.01)
|
||||
Assertions.assertEquals(
|
||||
"""
|
||||
Safety: Limiting max basal rate to 2.00 U/h because of hard limit
|
||||
""".trimIndent(), c.getReasons(aapsLogger)
|
||||
)
|
||||
Assert.assertEquals("Safety: Limiting max basal rate to 2.00 U/h because of hard limit", c.getMostLimitedReasons(aapsLogger))
|
||||
Assertions.assertEquals("Safety: Limiting max basal rate to 2.00 U/h because of hard limit", c.getMostLimitedReasons(aapsLogger))
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -165,8 +166,8 @@ class SafetyPluginTest : TestBaseWithProfile() {
|
|||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("child")
|
||||
val d = Constraint(-0.5)
|
||||
safetyPlugin.applyBasalConstraints(d, validProfile)
|
||||
Assert.assertEquals(0.0, d.value(), 0.01)
|
||||
Assert.assertEquals("Safety: Limiting max basal rate to 0.00 U/h because of it must be positive value", d.getReasons(aapsLogger))
|
||||
Assertions.assertEquals(0.0, d.value(), 0.01)
|
||||
Assertions.assertEquals("Safety: Limiting max basal rate to 0.00 U/h because of it must be positive value", d.getReasons(aapsLogger))
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -178,8 +179,8 @@ class SafetyPluginTest : TestBaseWithProfile() {
|
|||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("child")
|
||||
val i = Constraint(Constants.REALLYHIGHPERCENTBASALRATE)
|
||||
safetyPlugin.applyBasalPercentConstraints(i, validProfile)
|
||||
Assert.assertEquals(200, i.value())
|
||||
Assert.assertEquals(
|
||||
Assertions.assertEquals(200, i.value())
|
||||
Assertions.assertEquals(
|
||||
"""
|
||||
Safety: Percent rate 1111111% recalculated to 11111.11 U/h with current basal 1.00 U/h
|
||||
Safety: Limiting max basal rate to 2.00 U/h because of hard limit
|
||||
|
@ -187,7 +188,7 @@ Safety: Limiting max percent rate to 200% because of pump limit
|
|||
Safety: Limiting max basal rate to 500.00 U/h because of pump limit
|
||||
""".trimIndent(), i.getReasons(aapsLogger)
|
||||
)
|
||||
Assert.assertEquals("Safety: Limiting max percent rate to 200% because of pump limit", i.getMostLimitedReasons(aapsLogger))
|
||||
Assertions.assertEquals("Safety: Limiting max percent rate to 200% because of pump limit", i.getMostLimitedReasons(aapsLogger))
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -200,15 +201,15 @@ Safety: Limiting max basal rate to 500.00 U/h because of pump limit
|
|||
openAPSSMBPlugin.setPluginEnabled(PluginType.APS, true)
|
||||
val i = Constraint(Constants.REALLYHIGHBASALRATE)
|
||||
openAPSSMBPlugin.applyBasalConstraints(i, validProfile)
|
||||
Assert.assertEquals(1.0, i.value(), 0.01)
|
||||
Assert.assertEquals(
|
||||
Assertions.assertEquals(1.0, i.value(), 0.01)
|
||||
Assertions.assertEquals(
|
||||
"""
|
||||
OpenAPSSMB: Limiting max basal rate to 1.00 U/h because of max value in preferences
|
||||
OpenAPSSMB: Limiting max basal rate to 4.00 U/h because of max basal multiplier
|
||||
OpenAPSSMB: Limiting max basal rate to 3.00 U/h because of max daily basal multiplier
|
||||
""".trimIndent(), i.getReasons(aapsLogger)
|
||||
)
|
||||
Assert.assertEquals("OpenAPSSMB: Limiting max basal rate to 1.00 U/h because of max value in preferences", i.getMostLimitedReasons(aapsLogger))
|
||||
Assertions.assertEquals("OpenAPSSMB: Limiting max basal rate to 1.00 U/h because of max value in preferences", i.getMostLimitedReasons(aapsLogger))
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -216,15 +217,15 @@ Safety: Limiting max basal rate to 500.00 U/h because of pump limit
|
|||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("child")
|
||||
val i = Constraint(-22)
|
||||
safetyPlugin.applyBasalPercentConstraints(i, validProfile)
|
||||
Assert.assertEquals(0, i.value())
|
||||
Assert.assertEquals(
|
||||
Assertions.assertEquals(0, i.value())
|
||||
Assertions.assertEquals(
|
||||
"""
|
||||
Safety: Percent rate -22% recalculated to -0.22 U/h with current basal 1.00 U/h
|
||||
Safety: Limiting max basal rate to 0.00 U/h because of it must be positive value
|
||||
Safety: Limiting max percent rate to 0% because of pump limit
|
||||
""".trimIndent(), i.getReasons(aapsLogger)
|
||||
)
|
||||
Assert.assertEquals("Safety: Limiting max percent rate to 0% because of pump limit", i.getMostLimitedReasons(aapsLogger))
|
||||
Assertions.assertEquals("Safety: Limiting max percent rate to 0% because of pump limit", i.getMostLimitedReasons(aapsLogger))
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -233,14 +234,14 @@ Safety: Limiting max basal rate to 500.00 U/h because of pump limit
|
|||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("child")
|
||||
var d = Constraint(Constants.REALLYHIGHBOLUS)
|
||||
d = safetyPlugin.applyBolusConstraints(d)
|
||||
Assert.assertEquals(3.0, d.value(), 0.01)
|
||||
Assert.assertEquals(
|
||||
Assertions.assertEquals(3.0, d.value(), 0.01)
|
||||
Assertions.assertEquals(
|
||||
"""
|
||||
Safety: Limiting bolus to 3.0 U because of max value in preferences
|
||||
Safety: Limiting bolus to 5.0 U because of hard limit
|
||||
""".trimIndent(), d.getReasons(aapsLogger)
|
||||
)
|
||||
Assert.assertEquals("Safety: Limiting bolus to 3.0 U because of max value in preferences", d.getMostLimitedReasons(aapsLogger))
|
||||
Assertions.assertEquals("Safety: Limiting bolus to 3.0 U because of max value in preferences", d.getMostLimitedReasons(aapsLogger))
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -249,9 +250,9 @@ Safety: Limiting max basal rate to 500.00 U/h because of pump limit
|
|||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("child")
|
||||
var d = Constraint(-22.0)
|
||||
d = safetyPlugin.applyBolusConstraints(d)
|
||||
Assert.assertEquals(0.0, d.value(), 0.01)
|
||||
Assert.assertEquals("Safety: Limiting bolus to 0.0 U because of it must be positive value", d.getReasons(aapsLogger))
|
||||
Assert.assertEquals("Safety: Limiting bolus to 0.0 U because of it must be positive value", d.getMostLimitedReasons(aapsLogger))
|
||||
Assertions.assertEquals(0.0, d.value(), 0.01)
|
||||
Assertions.assertEquals("Safety: Limiting bolus to 0.0 U because of it must be positive value", d.getReasons(aapsLogger))
|
||||
Assertions.assertEquals("Safety: Limiting bolus to 0.0 U because of it must be positive value", d.getMostLimitedReasons(aapsLogger))
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -262,13 +263,13 @@ Safety: Limiting max basal rate to 500.00 U/h because of pump limit
|
|||
// Negative carbs not allowed
|
||||
var i = Constraint(-22)
|
||||
safetyPlugin.applyCarbsConstraints(i)
|
||||
Assert.assertEquals(0, i.value())
|
||||
Assert.assertEquals("Safety: Limiting carbs to 0 g because of it must be positive value", i.getReasons(aapsLogger))
|
||||
Assertions.assertEquals(0, i.value())
|
||||
Assertions.assertEquals("Safety: Limiting carbs to 0 g because of it must be positive value", i.getReasons(aapsLogger))
|
||||
|
||||
// Apply all limits
|
||||
i = safetyPlugin.applyCarbsConstraints(Constraint(Constants.REALLYHIGHCARBS))
|
||||
Assert.assertEquals(48, i.value())
|
||||
Assert.assertEquals("Safety: Limiting carbs to 48 g because of max value in preferences", i.getReasons(aapsLogger))
|
||||
Assertions.assertEquals(48, i.value())
|
||||
Assertions.assertEquals("Safety: Limiting carbs to 48 g because of max value in preferences", i.getReasons(aapsLogger))
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -285,22 +286,22 @@ Safety: Limiting max basal rate to 500.00 U/h because of pump limit
|
|||
// Apply all limits
|
||||
var d = Constraint(Constants.REALLYHIGHIOB)
|
||||
d = safetyPlugin.applyMaxIOBConstraints(d)
|
||||
Assert.assertEquals(HardLimits.MAX_IOB_LGS, d.value(), 0.01)
|
||||
Assert.assertEquals("Safety: Limiting IOB to 0.0 U because of Low Glucose Suspend", d.getReasons(aapsLogger))
|
||||
Assert.assertEquals("Safety: Limiting IOB to 0.0 U because of Low Glucose Suspend", d.getMostLimitedReasons(aapsLogger))
|
||||
Assertions.assertEquals(HardLimits.MAX_IOB_LGS, d.value(), 0.01)
|
||||
Assertions.assertEquals("Safety: Limiting IOB to 0.0 U because of Low Glucose Suspend", d.getReasons(aapsLogger))
|
||||
Assertions.assertEquals("Safety: Limiting IOB to 0.0 U because of Low Glucose Suspend", d.getMostLimitedReasons(aapsLogger))
|
||||
|
||||
// Apply all limits
|
||||
d = Constraint(Constants.REALLYHIGHIOB)
|
||||
val a = openAPSAMAPlugin.applyMaxIOBConstraints(d)
|
||||
Assert.assertEquals(1.5, a.value(), 0.01)
|
||||
Assert.assertEquals("OpenAPSAMA: Limiting IOB to 1.5 U because of max value in preferences\nOpenAPSAMA: Limiting IOB to 7.0 U because of hard limit", d.getReasons(aapsLogger))
|
||||
Assert.assertEquals("OpenAPSAMA: Limiting IOB to 1.5 U because of max value in preferences", d.getMostLimitedReasons(aapsLogger))
|
||||
Assertions.assertEquals(1.5, a.value(), 0.01)
|
||||
Assertions.assertEquals("OpenAPSAMA: Limiting IOB to 1.5 U because of max value in preferences\nOpenAPSAMA: Limiting IOB to 7.0 U because of hard limit", d.getReasons(aapsLogger))
|
||||
Assertions.assertEquals("OpenAPSAMA: Limiting IOB to 1.5 U because of max value in preferences", d.getMostLimitedReasons(aapsLogger))
|
||||
|
||||
// Apply all limits
|
||||
d = Constraint(Constants.REALLYHIGHIOB)
|
||||
val s = openAPSSMBPlugin.applyMaxIOBConstraints(d)
|
||||
Assert.assertEquals(3.0, s.value(), 0.01)
|
||||
Assert.assertEquals("OpenAPSSMB: Limiting IOB to 3.0 U because of max value in preferences\nOpenAPSSMB: Limiting IOB to 22.0 U because of hard limit", d.getReasons(aapsLogger))
|
||||
Assert.assertEquals("OpenAPSSMB: Limiting IOB to 3.0 U because of max value in preferences", d.getMostLimitedReasons(aapsLogger))
|
||||
Assertions.assertEquals(3.0, s.value(), 0.01)
|
||||
Assertions.assertEquals("OpenAPSSMB: Limiting IOB to 3.0 U because of max value in preferences\nOpenAPSSMB: Limiting IOB to 22.0 U because of hard limit", d.getReasons(aapsLogger))
|
||||
Assertions.assertEquals("OpenAPSSMB: Limiting IOB to 3.0 U because of max value in preferences", d.getMostLimitedReasons(aapsLogger))
|
||||
}
|
||||
}
|
|
@ -6,7 +6,7 @@ import info.nightscout.androidaps.TestBaseWithProfile
|
|||
import info.nightscout.core.pump.toHtml
|
||||
import info.nightscout.interfaces.pump.PumpEnactResult
|
||||
import info.nightscout.plugins.aps.loop.extensions.json
|
||||
import info.nightscout.plugins.extensions.toText
|
||||
import info.nightscout.pump.virtual.extensions.toText
|
||||
import info.nightscout.plugins.sync.nsShared.extensions.log
|
||||
import org.json.JSONObject
|
||||
import org.junit.jupiter.api.Assertions
|
||||
|
|
|
@ -12,7 +12,7 @@ buildscript {
|
|||
dagger_version = '2.44.2'
|
||||
coroutines_version = '1.6.4'
|
||||
activity_version = '1.6.1'
|
||||
fragmentktx_version = '1.5.4'
|
||||
fragmentktx_version = '1.5.5'
|
||||
ormLite_version = '4.46'
|
||||
gson_version = '2.10'
|
||||
nav_version = '2.5.3'
|
||||
|
@ -32,7 +32,7 @@ buildscript {
|
|||
swipe_version = '1.1.0'
|
||||
|
||||
junit_version = '4.13.2'
|
||||
junit_jupiter_version = '5.7.0'
|
||||
junit_jupiter_version = '5.9.1'
|
||||
mockito_version = '4.6.1'
|
||||
dexmaker_version = '1.2'
|
||||
retrofit2_version = '2.9.0'
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package info.nightscout.plugins.insulin
|
||||
package info.nightscout.core.graph
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
|
@ -1,14 +0,0 @@
|
|||
package info.nightscout.interfaces
|
||||
|
||||
interface BolusTimer {
|
||||
|
||||
/**
|
||||
* Create new Automation event to alarm when is time to bolus
|
||||
*/
|
||||
fun scheduleAutomationEventBolusReminder()
|
||||
|
||||
/**
|
||||
* Remove Automation event
|
||||
*/
|
||||
fun removeAutomationEventBolusReminder()
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
package info.nightscout.interfaces
|
||||
|
||||
interface CarbTimer {
|
||||
|
||||
/**
|
||||
* Generate reminder via [info.nightscout.androidaps.utils.TimerUtil]
|
||||
*
|
||||
* @param seconds seconds to the future
|
||||
*/
|
||||
fun scheduleTimeToEatReminder(seconds: Int)
|
||||
|
||||
/**
|
||||
* Create new Automation event to alarm when is time to eat
|
||||
*/
|
||||
fun scheduleAutomationEventEatReminder()
|
||||
|
||||
/**
|
||||
* Remove Automation event
|
||||
*/
|
||||
fun removeAutomationEventEatReminder()
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
package info.nightscout.interfaces.actions
|
||||
|
||||
interface Actions
|
|
@ -8,6 +8,7 @@ import info.nightscout.interfaces.iob.IobTotal
|
|||
import org.json.JSONObject
|
||||
|
||||
interface APSResult {
|
||||
var date: Long
|
||||
var json: JSONObject?
|
||||
var reason: String
|
||||
var rate: Double
|
||||
|
|
|
@ -18,8 +18,13 @@ interface AutosensData {
|
|||
var pastSensitivity: String
|
||||
var deviation: Double
|
||||
var validDeviation: Boolean
|
||||
var activeCarbsList: MutableList<CarbsInPast>
|
||||
var absorbed: Double
|
||||
var carbsFromBolus: Double
|
||||
var cob: Double
|
||||
var bgi: Double
|
||||
var delta: Double
|
||||
var avgDelta: Double
|
||||
var slopeFromMaxDeviation: Double
|
||||
var slopeFromMinDeviation: Double
|
||||
var usedMinCarbsImpact: Double
|
||||
|
@ -37,4 +42,6 @@ interface AutosensData {
|
|||
var autosensResult: AutosensResult
|
||||
|
||||
fun cloneCarbsList(): MutableList<CarbsInPast>
|
||||
fun deductAbsorbedCarbs()
|
||||
fun removeOldCarbs(toTime: Long, isAAPSOrWeighted: Boolean)
|
||||
}
|
|
@ -1,6 +1,36 @@
|
|||
package info.nightscout.interfaces.automation
|
||||
|
||||
interface Automation {
|
||||
|
||||
fun userEvents(): List<AutomationEvent>
|
||||
fun processEvent(someEvent: AutomationEvent)
|
||||
|
||||
/**
|
||||
* Generate reminder via [info.nightscout.interfaces.utils.TimerUtil]
|
||||
*
|
||||
*/
|
||||
fun scheduleAutomationEventBolusReminder()
|
||||
|
||||
/**
|
||||
* Remove scheduled reminder from automations
|
||||
*
|
||||
*/
|
||||
fun removeAutomationEventBolusReminder()
|
||||
|
||||
/**
|
||||
* Generate reminder via [info.nightscout.interfaces.utils.TimerUtil]
|
||||
*
|
||||
* @param seconds seconds to the future
|
||||
*/
|
||||
fun scheduleTimeToEatReminder(seconds: Int)
|
||||
|
||||
/**
|
||||
* Remove Automation event
|
||||
*/
|
||||
fun removeAutomationEventEatReminder()
|
||||
|
||||
/**
|
||||
* Create new Automation event to alarm when is time to eat
|
||||
*/
|
||||
fun scheduleAutomationEventEatReminder()
|
||||
}
|
|
@ -5,6 +5,7 @@ import info.nightscout.database.ValueWrapper
|
|||
import info.nightscout.database.entities.Bolus
|
||||
import info.nightscout.database.entities.BolusCalculatorResult
|
||||
import info.nightscout.database.entities.Carbs
|
||||
import info.nightscout.database.entities.EffectiveProfileSwitch
|
||||
import info.nightscout.database.entities.TemporaryTarget
|
||||
import info.nightscout.database.entities.UserEntry
|
||||
import info.nightscout.interfaces.queue.Callback
|
||||
|
@ -20,4 +21,5 @@ interface PersistenceLayer {
|
|||
|
||||
fun getTemporaryTargetActiveAt(timestamp: Long): Single<ValueWrapper<TemporaryTarget>>
|
||||
fun getUserEntryFilteredDataFromTime(timestamp: Long): Single<List<UserEntry>>
|
||||
fun getEffectiveProfileSwitchActiveAt(timestamp: Long): Single<ValueWrapper<EffectiveProfileSwitch>>
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
package info.nightscout.interfaces.iob
|
||||
|
||||
interface GlucoseStatusProvider {
|
||||
val glucoseStatusData: GlucoseStatus?
|
||||
fun getGlucoseStatusData(allowOldData: Boolean = false): GlucoseStatus?
|
||||
}
|
|
@ -1,7 +1,48 @@
|
|||
package info.nightscout.interfaces.nsclient
|
||||
|
||||
import info.nightscout.database.entities.Bolus
|
||||
import info.nightscout.database.entities.BolusCalculatorResult
|
||||
import info.nightscout.database.entities.Carbs
|
||||
import info.nightscout.database.entities.DeviceStatus
|
||||
import info.nightscout.database.entities.EffectiveProfileSwitch
|
||||
import info.nightscout.database.entities.ExtendedBolus
|
||||
import info.nightscout.database.entities.Food
|
||||
import info.nightscout.database.entities.GlucoseValue
|
||||
import info.nightscout.database.entities.OfflineEvent
|
||||
import info.nightscout.database.entities.ProfileSwitch
|
||||
import info.nightscout.database.entities.TemporaryBasal
|
||||
import info.nightscout.database.entities.TemporaryTarget
|
||||
import info.nightscout.database.entities.TherapyEvent
|
||||
import info.nightscout.database.transactions.TransactionGlucoseValue
|
||||
|
||||
interface StoreDataForDb {
|
||||
val glucoseValues: MutableList<TransactionGlucoseValue>
|
||||
val boluses: MutableList<Bolus>
|
||||
val carbs: MutableList<Carbs>
|
||||
val temporaryTargets: MutableList<TemporaryTarget>
|
||||
val effectiveProfileSwitches: MutableList<EffectiveProfileSwitch>
|
||||
val bolusCalculatorResults: MutableList<BolusCalculatorResult>
|
||||
val therapyEvents: MutableList<TherapyEvent>
|
||||
val extendedBoluses: MutableList<ExtendedBolus>
|
||||
val temporaryBasals: MutableList<TemporaryBasal>
|
||||
val profileSwitches: MutableList<ProfileSwitch>
|
||||
val offlineEvents: MutableList<OfflineEvent>
|
||||
|
||||
val nsIdGlucoseValues: MutableList<GlucoseValue>
|
||||
val nsIdBoluses: MutableList<Bolus>
|
||||
val nsIdCarbs: MutableList<Carbs>
|
||||
val nsIdFoods: MutableList<Food>
|
||||
val nsIdTemporaryTargets: MutableList<TemporaryTarget>
|
||||
val nsIdEffectiveProfileSwitches: MutableList<EffectiveProfileSwitch>
|
||||
val nsIdBolusCalculatorResults: MutableList<BolusCalculatorResult>
|
||||
val nsIdTherapyEvents: MutableList<TherapyEvent>
|
||||
val nsIdExtendedBoluses: MutableList<ExtendedBolus>
|
||||
val nsIdTemporaryBasals: MutableList<TemporaryBasal>
|
||||
val nsIdProfileSwitches: MutableList<ProfileSwitch>
|
||||
val nsIdOfflineEvents: MutableList<OfflineEvent>
|
||||
val nsIdDeviceStatuses: MutableList<DeviceStatus>
|
||||
|
||||
fun storeTreatmentsToDb()
|
||||
fun storeGlucoseValuesToDb()
|
||||
fun scheduleNsIdUpdate()
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package info.nightscout.interfaces.profile
|
||||
|
||||
import info.nightscout.interfaces.aps.APSResult
|
||||
import info.nightscout.interfaces.aps.AutosensData
|
||||
import org.json.JSONObject
|
||||
|
||||
interface Instantiator {
|
||||
|
||||
fun provideProfileStore(jsonObject: JSONObject): ProfileStore
|
||||
fun provideAPSResultObject(): APSResult
|
||||
fun provideAutosensDataObject(): AutosensData
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
package info.nightscout.interfaces.profile
|
||||
|
||||
import org.json.JSONObject
|
||||
|
||||
interface ProfileInstantiator {
|
||||
fun storeInstance(jsonObject: JSONObject): ProfileStore
|
||||
}
|
|
@ -1,3 +1,8 @@
|
|||
package info.nightscout.interfaces.source
|
||||
|
||||
interface DexcomBoyda
|
||||
interface DexcomBoyda {
|
||||
|
||||
fun isEnabled(): Boolean
|
||||
fun requestPermissionIfNeeded()
|
||||
fun findDexcomPackageName(): String?
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package info.nightscout.interfaces.source
|
||||
|
||||
interface XDrip {
|
||||
fun isEnabled(): Boolean
|
||||
}
|
|
@ -17,19 +17,24 @@ import org.json.JSONObject
|
|||
|
||||
interface DataSyncSelector {
|
||||
|
||||
data class PairTemporaryTarget(val value: TemporaryTarget, val updateRecordId: Long)
|
||||
data class PairGlucoseValue(val value: GlucoseValue, val updateRecordId: Long)
|
||||
data class PairTherapyEvent(val value: TherapyEvent, val updateRecordId: Long)
|
||||
data class PairFood(val value: Food, val updateRecordId: Long)
|
||||
data class PairBolus(val value: Bolus, val updateRecordId: Long)
|
||||
data class PairCarbs(val value: Carbs, val updateRecordId: Long)
|
||||
data class PairBolusCalculatorResult(val value: BolusCalculatorResult, val updateRecordId: Long)
|
||||
data class PairTemporaryBasal(val value: TemporaryBasal, val updateRecordId: Long)
|
||||
data class PairExtendedBolus(val value: ExtendedBolus, val updateRecordId: Long)
|
||||
data class PairProfileSwitch(val value: ProfileSwitch, val updateRecordId: Long)
|
||||
data class PairEffectiveProfileSwitch(val value: EffectiveProfileSwitch, val updateRecordId: Long)
|
||||
data class PairOfflineEvent(val value: OfflineEvent, val updateRecordId: Long)
|
||||
data class PairProfileStore(val value: JSONObject, val timestampSync: Long)
|
||||
interface DataPair {
|
||||
val value: Any
|
||||
val id: Long
|
||||
}
|
||||
data class PairTemporaryTarget(override val value: TemporaryTarget, override val id: Long): DataPair
|
||||
data class PairGlucoseValue(override val value: GlucoseValue, override val id: Long): DataPair
|
||||
data class PairTherapyEvent(override val value: TherapyEvent, override val id: Long): DataPair
|
||||
data class PairFood(override val value: Food, override val id: Long): DataPair
|
||||
data class PairBolus(override val value: Bolus, override val id: Long): DataPair
|
||||
data class PairCarbs(override val value: Carbs, override val id: Long): DataPair
|
||||
data class PairBolusCalculatorResult(override val value: BolusCalculatorResult, override val id: Long): DataPair
|
||||
data class PairTemporaryBasal(override val value: TemporaryBasal, override val id: Long): DataPair
|
||||
data class PairExtendedBolus(override val value: ExtendedBolus, override val id: Long): DataPair
|
||||
data class PairProfileSwitch(override val value: ProfileSwitch, override val id: Long): DataPair
|
||||
data class PairEffectiveProfileSwitch(override val value: EffectiveProfileSwitch, override val id: Long): DataPair
|
||||
data class PairOfflineEvent(override val value: OfflineEvent, override val id: Long): DataPair
|
||||
data class PairProfileStore(override val value: JSONObject, override val id: Long): DataPair
|
||||
data class PairDeviceStatus(override val value: DeviceStatus, override val id: Long): DataPair
|
||||
|
||||
fun queueSize(): Long
|
||||
|
||||
|
@ -38,81 +43,42 @@ interface DataSyncSelector {
|
|||
fun resetToNextFullSync()
|
||||
|
||||
fun confirmLastBolusIdIfGreater(lastSynced: Long)
|
||||
fun changedBoluses(): List<Bolus>
|
||||
|
||||
// Until NS v3
|
||||
fun processChangedBolusesCompat()
|
||||
|
||||
fun confirmLastCarbsIdIfGreater(lastSynced: Long)
|
||||
fun changedCarbs(): List<Carbs>
|
||||
|
||||
// Until NS v3
|
||||
fun processChangedCarbsCompat()
|
||||
|
||||
fun confirmLastBolusCalculatorResultsIdIfGreater(lastSynced: Long)
|
||||
fun changedBolusCalculatorResults(): List<BolusCalculatorResult>
|
||||
|
||||
// Until NS v3
|
||||
fun processChangedBolusCalculatorResultsCompat()
|
||||
|
||||
fun confirmLastTempTargetsIdIfGreater(lastSynced: Long)
|
||||
fun changedTempTargets(): List<TemporaryTarget>
|
||||
|
||||
// Until NS v3
|
||||
fun processChangedTempTargetsCompat()
|
||||
|
||||
fun confirmLastGlucoseValueIdIfGreater(lastSynced: Long)
|
||||
fun changedGlucoseValues(): List<GlucoseValue>
|
||||
|
||||
// Until NS v3
|
||||
fun processChangedGlucoseValuesCompat()
|
||||
|
||||
fun confirmLastTherapyEventIdIfGreater(lastSynced: Long)
|
||||
fun changedTherapyEvents(): List<TherapyEvent>
|
||||
|
||||
// Until NS v3
|
||||
fun processChangedTherapyEventsCompat()
|
||||
|
||||
fun confirmLastFoodIdIfGreater(lastSynced: Long)
|
||||
fun changedFoods(): List<Food>
|
||||
|
||||
// Until NS v3
|
||||
fun processChangedFoodsCompat()
|
||||
|
||||
fun confirmLastDeviceStatusIdIfGreater(lastSynced: Long)
|
||||
fun changedDeviceStatuses(): List<DeviceStatus>
|
||||
|
||||
// Until NS v3
|
||||
fun processChangedDeviceStatusesCompat()
|
||||
|
||||
fun confirmLastTemporaryBasalIdIfGreater(lastSynced: Long)
|
||||
fun changedTemporaryBasals(): List<TemporaryBasal>
|
||||
|
||||
// Until NS v3
|
||||
fun processChangedTemporaryBasalsCompat()
|
||||
|
||||
fun confirmLastExtendedBolusIdIfGreater(lastSynced: Long)
|
||||
fun changedExtendedBoluses(): List<ExtendedBolus>
|
||||
|
||||
// Until NS v3
|
||||
fun processChangedExtendedBolusesCompat()
|
||||
|
||||
fun confirmLastProfileSwitchIdIfGreater(lastSynced: Long)
|
||||
fun changedProfileSwitch(): List<ProfileSwitch>
|
||||
|
||||
// Until NS v3
|
||||
fun processChangedProfileSwitchesCompat()
|
||||
|
||||
fun confirmLastEffectiveProfileSwitchIdIfGreater(lastSynced: Long)
|
||||
fun changedEffectiveProfileSwitch(): List<EffectiveProfileSwitch>
|
||||
|
||||
// Until NS v3
|
||||
fun processChangedEffectiveProfileSwitchesCompat()
|
||||
|
||||
fun confirmLastOfflineEventIdIfGreater(lastSynced: Long)
|
||||
fun changedOfflineEvents(): List<OfflineEvent>
|
||||
|
||||
// Until NS v3
|
||||
fun processChangedOfflineEventsCompat()
|
||||
|
||||
fun confirmLastProfileStore(lastSynced: Long)
|
||||
|
|
|
@ -2,7 +2,6 @@ package info.nightscout.interfaces.sync
|
|||
|
||||
import android.text.Spanned
|
||||
import info.nightscout.interfaces.nsclient.NSAlarm
|
||||
import org.json.JSONObject
|
||||
|
||||
interface NsClient : Sync {
|
||||
enum class Version {
|
||||
|
@ -11,7 +10,6 @@ interface NsClient : Sync {
|
|||
|
||||
val version: Version
|
||||
val address: String
|
||||
val nsClientService: NSClientService?
|
||||
|
||||
fun pause(newState: Boolean)
|
||||
fun resend(reason: String)
|
||||
|
@ -24,9 +22,6 @@ interface NsClient : Sync {
|
|||
|
||||
fun resetToFullSync()
|
||||
|
||||
interface NSClientService {
|
||||
|
||||
fun dbAdd(collection: String, data: JSONObject, originalObject: Any, progress: String)
|
||||
fun dbUpdate(collection: String, _id: String?, data: JSONObject?, originalObject: Any, progress: String)
|
||||
}
|
||||
fun dbAdd(collection: String, dataPair: DataSyncSelector.DataPair, progress: String)
|
||||
fun dbUpdate(collection: String, dataPair: DataSyncSelector.DataPair, progress: String)
|
||||
}
|
|
@ -31,6 +31,9 @@ interface UiInteraction {
|
|||
* @param soundId sound resource. if == 0 alarm is not started
|
||||
*/
|
||||
fun runAlarm(status: String, title: String, @RawRes soundId: Int = 0)
|
||||
|
||||
fun updateWidget(context: Context)
|
||||
|
||||
fun runWizardDialog(fragmentManager: FragmentManager, carbs: Int? = null, name: String? = null)
|
||||
fun runLoopDialog(fragmentManager: FragmentManager, showOkCancel: Int)
|
||||
fun runProfileSwitchDialog(fragmentManager: FragmentManager, profileName: String? = null)
|
||||
|
|
|
@ -2,8 +2,6 @@ package info.nightscout.core.di
|
|||
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import info.nightscout.core.aps.APSResultObject
|
||||
import info.nightscout.core.iob.iobCobCalculator.data.AutosensDataObject
|
||||
import info.nightscout.core.wizard.BolusWizard
|
||||
import info.nightscout.core.wizard.QuickWizardEntry
|
||||
import info.nightscout.interfaces.pump.PumpEnactResult
|
||||
|
@ -13,8 +11,6 @@ import info.nightscout.interfaces.pump.PumpEnactResult
|
|||
abstract class CoreDataClassesModule {
|
||||
|
||||
@ContributesAndroidInjector abstract fun pumpEnactResultInjector(): PumpEnactResult
|
||||
@ContributesAndroidInjector abstract fun apsResultInjector(): APSResultObject
|
||||
@ContributesAndroidInjector abstract fun autosensDataInjector(): AutosensDataObject
|
||||
@ContributesAndroidInjector abstract fun bolusWizardInjector(): BolusWizard
|
||||
@ContributesAndroidInjector abstract fun quickWizardEntryInjector(): QuickWizardEntry
|
||||
}
|
||||
|
|
|
@ -5,14 +5,11 @@ import android.os.Build
|
|||
import android.telephony.SmsManager
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import info.nightscout.core.services.AlarmSoundService
|
||||
|
||||
@Module(
|
||||
includes = [
|
||||
CoreDataClassesModule::class,
|
||||
PreferencesModule::class,
|
||||
ServicesModule::class
|
||||
PreferencesModule::class
|
||||
]
|
||||
)
|
||||
open class CoreModule {
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
package info.nightscout.core.di
|
||||
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import info.nightscout.core.services.AlarmSoundService
|
||||
|
||||
@Module
|
||||
@Suppress("unused")
|
||||
abstract class ServicesModule {
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesAlarmSoundService(): AlarmSoundService
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
package info.nightscout.core.profile
|
||||
|
|
@ -6,7 +6,6 @@ import com.google.common.base.Joiner
|
|||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.core.extensions.highValueToUnitsToString
|
||||
import info.nightscout.core.extensions.lowValueToUnitsToString
|
||||
import info.nightscout.core.iob.iobCobCalculator.GlucoseStatusProvider
|
||||
import info.nightscout.core.iob.round
|
||||
import info.nightscout.core.ui.dialogs.OKDialog
|
||||
import info.nightscout.core.utils.extensions.formatColor
|
||||
|
@ -16,14 +15,14 @@ import info.nightscout.database.entities.TemporaryTarget
|
|||
import info.nightscout.database.entities.UserEntry.Action
|
||||
import info.nightscout.database.entities.UserEntry.Sources
|
||||
import info.nightscout.database.entities.ValueWithUnit
|
||||
import info.nightscout.interfaces.BolusTimer
|
||||
import info.nightscout.interfaces.CarbTimer
|
||||
import info.nightscout.interfaces.Config
|
||||
import info.nightscout.interfaces.aps.Loop
|
||||
import info.nightscout.interfaces.automation.Automation
|
||||
import info.nightscout.interfaces.constraints.Constraint
|
||||
import info.nightscout.interfaces.constraints.Constraints
|
||||
import info.nightscout.interfaces.db.PersistenceLayer
|
||||
import info.nightscout.interfaces.iob.GlucoseStatus
|
||||
import info.nightscout.interfaces.iob.GlucoseStatusProvider
|
||||
import info.nightscout.interfaces.iob.IobCobCalculator
|
||||
import info.nightscout.interfaces.logging.UserEntryLogger
|
||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||
|
@ -69,8 +68,7 @@ class BolusWizard @Inject constructor(
|
|||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var config: Config
|
||||
@Inject lateinit var uel: UserEntryLogger
|
||||
@Inject lateinit var carbTimer: CarbTimer
|
||||
@Inject lateinit var bolusTimer: BolusTimer
|
||||
@Inject lateinit var automation: Automation
|
||||
@Inject lateinit var glucoseStatusProvider: GlucoseStatusProvider
|
||||
@Inject lateinit var uiInteraction: UiInteraction
|
||||
@Inject lateinit var persistenceLayer: PersistenceLayer
|
||||
|
@ -361,9 +359,9 @@ class BolusWizard @Inject constructor(
|
|||
}
|
||||
accepted = true
|
||||
if (calculatedTotalInsulin > 0.0)
|
||||
bolusTimer.removeAutomationEventBolusReminder()
|
||||
automation.removeAutomationEventBolusReminder()
|
||||
if (carbs > 0.0)
|
||||
carbTimer.removeAutomationEventEatReminder()
|
||||
automation.removeAutomationEventEatReminder()
|
||||
if (sp.getBoolean(info.nightscout.core.ui.R.string.key_usebolusadvisor, false) && Profile.toMgdl(bg, profile.units) > 180 && carbs > 0 && carbTime >= 0)
|
||||
OKDialog.showYesNoCancel(ctx, rh.gs(info.nightscout.core.ui.R.string.bolus_advisor), rh.gs(info.nightscout.core.ui.R.string.bolus_advisor_message),
|
||||
{ bolusAdvisorProcessing(ctx) },
|
||||
|
@ -402,7 +400,7 @@ class BolusWizard @Inject constructor(
|
|||
if (!result.success) {
|
||||
uiInteraction.runAlarm(result.comment, rh.gs(info.nightscout.core.ui.R.string.treatmentdeliveryerror), info.nightscout.core.ui.R.raw.boluserror)
|
||||
} else
|
||||
carbTimer.scheduleAutomationEventEatReminder()
|
||||
automation.scheduleAutomationEventEatReminder()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -494,7 +492,7 @@ class BolusWizard @Inject constructor(
|
|||
bolusCalculatorResult?.let { persistenceLayer.insertOrUpdate(it) }
|
||||
}
|
||||
if (useAlarm && carbs > 0 && carbTime > 0) {
|
||||
carbTimer.scheduleTimeToEatReminder(T.mins(carbTime.toLong()).secs().toInt())
|
||||
automation.scheduleTimeToEatReminder(T.mins(carbTime.toLong()).secs().toInt())
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -3,13 +3,13 @@ package info.nightscout.core.wizard
|
|||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.annotations.OpenForTesting
|
||||
import info.nightscout.core.extensions.valueToUnits
|
||||
import info.nightscout.core.iob.iobCobCalculator.GlucoseStatusProvider
|
||||
import info.nightscout.core.iob.round
|
||||
import info.nightscout.core.utils.MidnightUtils
|
||||
import info.nightscout.database.ValueWrapper
|
||||
import info.nightscout.database.entities.GlucoseValue
|
||||
import info.nightscout.interfaces.aps.Loop
|
||||
import info.nightscout.interfaces.db.PersistenceLayer
|
||||
import info.nightscout.interfaces.iob.GlucoseStatusProvider
|
||||
import info.nightscout.interfaces.iob.IobCobCalculator
|
||||
import info.nightscout.interfaces.plugin.PluginBase
|
||||
import info.nightscout.interfaces.profile.Profile
|
||||
|
|
|
@ -1,107 +0,0 @@
|
|||
package info.nightscout.androidaps
|
||||
|
||||
import androidx.collection.ArrayMap
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.core.extensions.pureProfileFromJson
|
||||
import info.nightscout.core.profile.ProfileSealed
|
||||
import info.nightscout.interfaces.Config
|
||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||
import info.nightscout.interfaces.profile.ProfileStore
|
||||
import info.nightscout.interfaces.profile.PureProfile
|
||||
import info.nightscout.interfaces.utils.HardLimits
|
||||
import info.nightscout.interfaces.utils.JsonHelper
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.logging.AAPSLogger
|
||||
import info.nightscout.shared.interfaces.ResourceHelper
|
||||
import info.nightscout.shared.utils.DateUtil
|
||||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
import javax.inject.Inject
|
||||
|
||||
class ProfileStoreObject(val injector: HasAndroidInjector, override val data: JSONObject, val dateUtil: DateUtil) : ProfileStore {
|
||||
|
||||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
@Inject lateinit var activePlugin: ActivePlugin
|
||||
@Inject lateinit var config: Config
|
||||
@Inject lateinit var rh: ResourceHelper
|
||||
@Inject lateinit var rxBus: RxBus
|
||||
@Inject lateinit var hardLimits: HardLimits
|
||||
|
||||
init {
|
||||
injector.androidInjector().inject(this)
|
||||
}
|
||||
|
||||
private val cachedObjects = ArrayMap<String, PureProfile>()
|
||||
|
||||
private fun storeUnits(): String? = JsonHelper.safeGetStringAllowNull(data, "units", null)
|
||||
|
||||
private fun getStore(): JSONObject? {
|
||||
try {
|
||||
if (data.has("store")) return data.getJSONObject("store")
|
||||
} catch (e: JSONException) {
|
||||
aapsLogger.error("Unhandled exception", e)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
override fun getStartDate(): Long {
|
||||
val iso = JsonHelper.safeGetString(data, "startDate") ?: return 0
|
||||
return try {
|
||||
dateUtil.fromISODateString(iso)
|
||||
} catch (e: Exception) {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
override fun getDefaultProfile(): PureProfile? = getDefaultProfileName()?.let { getSpecificProfile(it) }
|
||||
override fun getDefaultProfileJson(): JSONObject? = getDefaultProfileName()?.let { getSpecificProfileJson(it) }
|
||||
|
||||
override fun getDefaultProfileName(): String? {
|
||||
val defaultProfileName = data.optString("defaultProfile")
|
||||
return if (defaultProfileName.isNotEmpty()) getStore()?.has(defaultProfileName)?.let { defaultProfileName } else null
|
||||
}
|
||||
|
||||
override fun getProfileList(): ArrayList<CharSequence> {
|
||||
val ret = ArrayList<CharSequence>()
|
||||
getStore()?.keys()?.let { keys ->
|
||||
while (keys.hasNext()) {
|
||||
val profileName = keys.next() as String
|
||||
ret.add(profileName)
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun getSpecificProfile(profileName: String): PureProfile? {
|
||||
var profile: PureProfile? = null
|
||||
val units = JsonHelper.safeGetStringAllowNull(data, "units", storeUnits())
|
||||
getStore()?.let { store ->
|
||||
if (store.has(profileName)) {
|
||||
profile = cachedObjects[profileName]
|
||||
if (profile == null) {
|
||||
JsonHelper.safeGetJSONObject(store, profileName, null)?.let { profileObject ->
|
||||
profile = pureProfileFromJson(profileObject, dateUtil, units)
|
||||
profile?.let { cachedObjects[profileName] = profile }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return profile
|
||||
}
|
||||
|
||||
private fun getSpecificProfileJson(profileName: String): JSONObject? {
|
||||
getStore()?.let { store ->
|
||||
if (store.has(profileName))
|
||||
return JsonHelper.safeGetJSONObject(store, profileName, null)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
override val allProfilesValid: Boolean
|
||||
get() = getProfileList()
|
||||
.asSequence()
|
||||
.map { profileName -> getSpecificProfile(profileName.toString()) }
|
||||
.map { pureProfile -> pureProfile?.let { ProfileSealed.Pure(pureProfile).isValid("allProfilesValid", activePlugin.activePump, config, rh, rxBus, hardLimits, false) } }
|
||||
.all { it?.isValid == true }
|
||||
}
|
|
@ -10,7 +10,6 @@ import info.nightscout.interfaces.plugin.ActivePlugin
|
|||
import info.nightscout.interfaces.profile.DefaultValueHelper
|
||||
import info.nightscout.interfaces.profile.Profile
|
||||
import info.nightscout.interfaces.profile.ProfileFunction
|
||||
import info.nightscout.interfaces.profile.ProfileStore
|
||||
import info.nightscout.interfaces.utils.HardLimits
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.shared.interfaces.ResourceHelper
|
||||
|
@ -38,18 +37,7 @@ open class TestBaseWithProfile : TestBase() {
|
|||
|
||||
val rxBus = RxBus(aapsSchedulers, aapsLogger)
|
||||
|
||||
val profileInjector = HasAndroidInjector {
|
||||
AndroidInjector {
|
||||
if (it is ProfileStoreObject) {
|
||||
it.aapsLogger = aapsLogger
|
||||
it.activePlugin = activePluginProvider
|
||||
it.config = config
|
||||
it.rh = rh
|
||||
it.rxBus = rxBus
|
||||
it.hardLimits = hardLimits
|
||||
}
|
||||
}
|
||||
}
|
||||
val profileInjector = HasAndroidInjector { AndroidInjector { } }
|
||||
|
||||
private lateinit var invalidProfileJSON: String
|
||||
private lateinit var validProfileJSON: String
|
||||
|
@ -70,32 +58,4 @@ open class TestBaseWithProfile : TestBase() {
|
|||
`when`(activePluginProvider.activePump).thenReturn(testPumpPlugin)
|
||||
hardLimits = HardLimitsMock(sp, rh)
|
||||
}
|
||||
|
||||
fun getValidProfileStore(): ProfileStore {
|
||||
val json = JSONObject()
|
||||
val store = JSONObject()
|
||||
store.put(TESTPROFILENAME, JSONObject(validProfileJSON))
|
||||
json.put("defaultProfile", TESTPROFILENAME)
|
||||
json.put("store", store)
|
||||
return ProfileStoreObject(profileInjector, json, dateUtil)
|
||||
}
|
||||
|
||||
fun getInvalidProfileStore1(): ProfileStore {
|
||||
val json = JSONObject()
|
||||
val store = JSONObject()
|
||||
store.put(TESTPROFILENAME, JSONObject(invalidProfileJSON))
|
||||
json.put("defaultProfile", TESTPROFILENAME)
|
||||
json.put("store", store)
|
||||
return ProfileStoreObject(profileInjector, json, dateUtil)
|
||||
}
|
||||
|
||||
fun getInvalidProfileStore2(): ProfileStore {
|
||||
val json = JSONObject()
|
||||
val store = JSONObject()
|
||||
store.put(TESTPROFILENAME, JSONObject(validProfileJSON))
|
||||
store.put("invalid", JSONObject(invalidProfileJSON))
|
||||
json.put("defaultProfile", TESTPROFILENAME + "invalid")
|
||||
json.put("store", store)
|
||||
return ProfileStoreObject(profileInjector, json, dateUtil)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,316 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.iob.iobCobCalculator
|
||||
|
||||
import android.content.Context
|
||||
import info.nightscout.androidaps.TestBase
|
||||
import info.nightscout.core.iob.iobCobCalculator.AutosensDataStoreObject
|
||||
import info.nightscout.database.entities.GlucoseValue
|
||||
import info.nightscout.shared.utils.DateUtil
|
||||
import info.nightscout.shared.utils.T
|
||||
import org.junit.Assert
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.mockito.Mock
|
||||
|
||||
class AutosensDataStoreTest : TestBase() {
|
||||
|
||||
@Mock lateinit var context: Context
|
||||
|
||||
lateinit var dateUtil: DateUtil
|
||||
|
||||
private val autosensDataStore = AutosensDataStoreObject()
|
||||
|
||||
@BeforeEach
|
||||
fun mock() {
|
||||
dateUtil = DateUtil(context)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isAbout5minDataTest() {
|
||||
val bgReadingList: MutableList<GlucoseValue> = ArrayList()
|
||||
|
||||
// Super data should not be touched
|
||||
bgReadingList.clear()
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
autosensDataStore.bgReadings = bgReadingList
|
||||
Assert.assertEquals(true, autosensDataStore.isAbout5minData(aapsLogger))
|
||||
|
||||
// too much shifted data should return false
|
||||
bgReadingList.clear()
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(9).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
autosensDataStore.bgReadings = bgReadingList
|
||||
Assert.assertEquals(false, autosensDataStore.isAbout5minData(aapsLogger))
|
||||
|
||||
// too much shifted and missing data should return false
|
||||
bgReadingList.clear()
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(9).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
autosensDataStore.bgReadings = bgReadingList
|
||||
Assert.assertEquals(false, autosensDataStore.isAbout5minData(aapsLogger))
|
||||
|
||||
// too much shifted and missing data should return false
|
||||
bgReadingList.clear()
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(83).plus(T.secs(40)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(78).plus(T.secs(40)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(73).plus(T.secs(40)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(68).plus(T.secs(40)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(63).plus(T.secs(40)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(58).plus(T.secs(40)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(53).plus(T.secs(40)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(48).plus(T.secs(40)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(43).plus(T.secs(40)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(38).plus(T.secs(40)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(33).plus(T.secs(1)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(28).plus(T.secs(0)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(23).plus(T.secs(0)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(16).plus(T.secs(36)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
autosensDataStore.bgReadings = bgReadingList
|
||||
Assert.assertEquals(false, autosensDataStore.isAbout5minData(aapsLogger))
|
||||
|
||||
// slightly shifted data should return true
|
||||
bgReadingList.clear()
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).plus(T.secs(10)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
autosensDataStore.bgReadings = bgReadingList
|
||||
Assert.assertEquals(true, autosensDataStore.isAbout5minData(aapsLogger))
|
||||
|
||||
// slightly shifted and missing data should return true
|
||||
bgReadingList.clear()
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).plus(T.secs(10)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
autosensDataStore.bgReadings = bgReadingList
|
||||
Assert.assertEquals(true, autosensDataStore.isAbout5minData(aapsLogger))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun createBucketedData5minTest1() {
|
||||
val bgReadingList: MutableList<GlucoseValue> = ArrayList()
|
||||
|
||||
// Super data should not be touched
|
||||
bgReadingList.clear()
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
autosensDataStore.bgReadings = bgReadingList
|
||||
Assert.assertEquals(true, autosensDataStore.isAbout5minData(aapsLogger))
|
||||
autosensDataStore.createBucketedData(aapsLogger, dateUtil)
|
||||
Assert.assertEquals(bgReadingList[0].timestamp, autosensDataStore.bucketedData!![0].timestamp)
|
||||
Assert.assertEquals(bgReadingList[3].timestamp, autosensDataStore.bucketedData!![3].timestamp)
|
||||
Assert.assertEquals(bgReadingList.size.toLong(), autosensDataStore.bucketedData!!.size.toLong())
|
||||
|
||||
// Missing value should be replaced
|
||||
bgReadingList.clear()
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).plus(T.secs(10)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
autosensDataStore.bgReadings = bgReadingList
|
||||
Assert.assertEquals(true, autosensDataStore.isAbout5minData(aapsLogger))
|
||||
autosensDataStore.createBucketedData(aapsLogger, dateUtil)
|
||||
Assert.assertEquals(bgReadingList[0].timestamp, autosensDataStore.bucketedData!![0].timestamp)
|
||||
Assert.assertEquals(bgReadingList[2].timestamp, autosensDataStore.bucketedData!![3].timestamp)
|
||||
Assert.assertEquals(bgReadingList.size + 1.toLong(), autosensDataStore.bucketedData!!.size.toLong())
|
||||
|
||||
// drift should be cleared
|
||||
bgReadingList.clear()
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs() + T.secs(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).msecs() + T.secs(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs() + T.secs(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(0).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
autosensDataStore.bgReadings = bgReadingList
|
||||
Assert.assertEquals(true, autosensDataStore.isAbout5minData(aapsLogger))
|
||||
autosensDataStore.createBucketedData(aapsLogger, dateUtil)
|
||||
Assert.assertEquals(T.mins(20).msecs(), autosensDataStore.bucketedData!![0].timestamp)
|
||||
Assert.assertEquals(T.mins(15).msecs(), autosensDataStore.bucketedData!![1].timestamp)
|
||||
Assert.assertEquals(T.mins(10).msecs(), autosensDataStore.bucketedData!![2].timestamp)
|
||||
Assert.assertEquals(T.mins(5).msecs(), autosensDataStore.bucketedData!![3].timestamp)
|
||||
Assert.assertEquals(bgReadingList.size.toLong(), autosensDataStore.bucketedData!!.size.toLong())
|
||||
|
||||
// bucketed data should return null if not enough bg data
|
||||
bgReadingList.clear()
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(30).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
autosensDataStore.bgReadings = bgReadingList
|
||||
Assert.assertEquals(true, autosensDataStore.isAbout5minData(aapsLogger))
|
||||
autosensDataStore.createBucketedData(aapsLogger, dateUtil)
|
||||
Assert.assertEquals(null, autosensDataStore.bucketedData)
|
||||
|
||||
// data should be reconstructed
|
||||
bgReadingList.clear()
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(50).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 90.0, timestamp = T.mins(45).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 40.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
autosensDataStore.bgReadings = bgReadingList
|
||||
Assert.assertEquals(true, autosensDataStore.isAbout5minData(aapsLogger))
|
||||
autosensDataStore.createBucketedData(aapsLogger, dateUtil)
|
||||
Assert.assertEquals(T.mins(50).msecs(), autosensDataStore.bucketedData!![0].timestamp)
|
||||
Assert.assertEquals(T.mins(20).msecs(), autosensDataStore.bucketedData!![6].timestamp)
|
||||
Assert.assertEquals(7, autosensDataStore.bucketedData!!.size.toLong())
|
||||
Assert.assertEquals(100.0, autosensDataStore.bucketedData!![0].value, 1.0)
|
||||
Assert.assertEquals(90.0, autosensDataStore.bucketedData!![1].value, 1.0)
|
||||
Assert.assertEquals(50.0, autosensDataStore.bucketedData!![5].value, 1.0)
|
||||
Assert.assertEquals(40.0, autosensDataStore.bucketedData!![6].value, 1.0)
|
||||
|
||||
// non 5min data should be reconstructed
|
||||
bgReadingList.clear()
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(50).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 96.0, timestamp = T.mins(48).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 40.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
autosensDataStore.bgReadings = bgReadingList
|
||||
Assert.assertEquals(false, autosensDataStore.isAbout5minData(aapsLogger))
|
||||
autosensDataStore.createBucketedData(aapsLogger, dateUtil)
|
||||
Assert.assertEquals(T.mins(50).msecs(), autosensDataStore.bucketedData!![0].timestamp)
|
||||
Assert.assertEquals(T.mins(20).msecs(), autosensDataStore.bucketedData!![6].timestamp)
|
||||
Assert.assertEquals(7, autosensDataStore.bucketedData!!.size.toLong())
|
||||
Assert.assertEquals(100.0, autosensDataStore.bucketedData!![0].value, 1.0)
|
||||
Assert.assertEquals(90.0, autosensDataStore.bucketedData!![1].value, 1.0)
|
||||
Assert.assertEquals(50.0, autosensDataStore.bucketedData!![5].value, 1.0)
|
||||
Assert.assertEquals(40.0, autosensDataStore.bucketedData!![6].value, 1.0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun createBucketedData5minTest2() {
|
||||
val bgReadingList: MutableList<GlucoseValue> = ArrayList()
|
||||
|
||||
//bucketed data should be null if no bg data available
|
||||
autosensDataStore.bgReadings = ArrayList()
|
||||
autosensDataStore.createBucketedData(aapsLogger, dateUtil)
|
||||
Assert.assertEquals(null, autosensDataStore.bucketedData)
|
||||
|
||||
// real data gap test
|
||||
bgReadingList.clear()
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T13:34:55Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T13:14:55Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T13:09:55Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T13:04:55Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T12:59:55Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T12:54:55Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T12:49:55Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T12:44:55Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T12:39:55Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T12:34:55Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T12:29:56Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T12:24:55Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T12:19:56Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T12:14:56Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T12:09:56Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T12:04:56Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T11:59:55Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T04:29:57Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T04:24:56Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T04:19:57Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T04:14:57Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T04:10:03Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T04:04:56Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T03:59:56Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T03:54:56Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T03:50:03Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T03:44:57Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
autosensDataStore.bgReadings = bgReadingList
|
||||
autosensDataStore.referenceTime = -1
|
||||
Assert.assertEquals(true, autosensDataStore.isAbout5minData(aapsLogger))
|
||||
autosensDataStore.createBucketedData(aapsLogger, dateUtil)
|
||||
Assert.assertEquals(dateUtil.fromISODateString("2018-09-05T13:34:57Z"), autosensDataStore.bucketedData!![0].timestamp)
|
||||
Assert.assertEquals(dateUtil.fromISODateString("2018-09-05T03:44:57Z"), autosensDataStore.bucketedData!![autosensDataStore.bucketedData!!.size - 1].timestamp)
|
||||
|
||||
// 5min 4sec data
|
||||
bgReadingList.clear()
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T06:33:40Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T06:28:36Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T06:23:32Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T06:18:28Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T06:13:24Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T06:08:19Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T06:03:16Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T05:58:11Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T05:53:07Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T05:48:03Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T05:42:58Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T05:37:54Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T05:32:51Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T05:27:46Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T05:22:42Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T05:17:38Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T05:12:33Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T05:07:29Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T05:02:26Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T04:57:21Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T04:52:17Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
autosensDataStore.bgReadings = bgReadingList
|
||||
Assert.assertEquals(false, autosensDataStore.isAbout5minData(aapsLogger))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun bgReadingsTest() {
|
||||
val bgReadingList: List<GlucoseValue> = ArrayList()
|
||||
autosensDataStore.bgReadings = bgReadingList
|
||||
Assert.assertEquals(bgReadingList, autosensDataStore.bgReadings)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun roundUpTimeTest() {
|
||||
Assert.assertEquals(T.mins(3).msecs(), autosensDataStore.roundUpTime(T.secs(155).msecs()))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findNewerTest() {
|
||||
val bgReadingList: MutableList<GlucoseValue> = ArrayList()
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
autosensDataStore.bgReadings = bgReadingList
|
||||
Assert.assertEquals(T.mins(10).msecs(), autosensDataStore.findNewer(T.mins(8).msecs())!!.timestamp)
|
||||
Assert.assertEquals(T.mins(5).msecs(), autosensDataStore.findNewer(T.mins(5).msecs())!!.timestamp)
|
||||
Assert.assertEquals(T.mins(10).msecs(), autosensDataStore.findNewer(T.mins(10).msecs())!!.timestamp)
|
||||
Assert.assertEquals(T.mins(20).msecs(), autosensDataStore.findNewer(T.mins(20).msecs())!!.timestamp)
|
||||
Assert.assertEquals(null, autosensDataStore.findNewer(T.mins(22).msecs()))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findOlderTest() {
|
||||
val bgReadingList: MutableList<GlucoseValue> = ArrayList()
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
autosensDataStore.bgReadings = bgReadingList
|
||||
Assert.assertEquals(T.mins(5).msecs(), autosensDataStore.findOlder(T.mins(8).msecs())!!.timestamp)
|
||||
Assert.assertEquals(T.mins(5).msecs(), autosensDataStore.findOlder(T.mins(5).msecs())!!.timestamp)
|
||||
Assert.assertEquals(T.mins(10).msecs(), autosensDataStore.findOlder(T.mins(10).msecs())!!.timestamp)
|
||||
Assert.assertEquals(T.mins(20).msecs(), autosensDataStore.findOlder(T.mins(20).msecs())!!.timestamp)
|
||||
Assert.assertEquals(null, autosensDataStore.findOlder(T.mins(4).msecs()))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findPreviousTimeFromBucketedDataTest() {
|
||||
val bgReadingList: MutableList<GlucoseValue> = ArrayList()
|
||||
autosensDataStore.bgReadings = bgReadingList
|
||||
autosensDataStore.createBucketedData(aapsLogger, dateUtil)
|
||||
Assert.assertEquals(null, autosensDataStore.findPreviousTimeFromBucketedData(1000))
|
||||
|
||||
// Super data should not be touched
|
||||
bgReadingList.clear()
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
autosensDataStore.bgReadings = bgReadingList
|
||||
autosensDataStore.createBucketedData(aapsLogger, dateUtil)
|
||||
Assert.assertEquals(null, autosensDataStore.findPreviousTimeFromBucketedData(T.mins(4).msecs()))
|
||||
Assert.assertEquals(T.mins(5).msecs(), autosensDataStore.findPreviousTimeFromBucketedData(T.mins(6).msecs()))
|
||||
Assert.assertEquals(T.mins(20).msecs(), autosensDataStore.findPreviousTimeFromBucketedData(T.mins(20).msecs()))
|
||||
Assert.assertEquals(T.mins(20).msecs(), autosensDataStore.findPreviousTimeFromBucketedData(T.mins(25).msecs()))
|
||||
}
|
||||
}
|
|
@ -3,12 +3,16 @@ package info.nightscout.sdk
|
|||
import android.content.Context
|
||||
import info.nightscout.sdk.exceptions.DateHeaderOutOfToleranceException
|
||||
import info.nightscout.sdk.exceptions.InvalidAccessTokenException
|
||||
import info.nightscout.sdk.exceptions.InvalidFormatNightscoutException
|
||||
import info.nightscout.sdk.exceptions.TodoNightscoutException
|
||||
import info.nightscout.sdk.exceptions.UnknownResponseNightscoutException
|
||||
import info.nightscout.sdk.interfaces.NSAndroidClient
|
||||
import info.nightscout.sdk.localmodel.Status
|
||||
import info.nightscout.sdk.localmodel.entry.NSSgvV3
|
||||
import info.nightscout.sdk.localmodel.treatment.CreateUpdateResponse
|
||||
import info.nightscout.sdk.localmodel.treatment.NSTreatment
|
||||
import info.nightscout.sdk.mapper.toLocal
|
||||
import info.nightscout.sdk.mapper.toRemoteTreatment
|
||||
import info.nightscout.sdk.mapper.toSgv
|
||||
import info.nightscout.sdk.mapper.toTreatment
|
||||
import info.nightscout.sdk.networking.NetworkStackBuilder
|
||||
|
@ -58,6 +62,8 @@ class NSAndroidClientImpl(
|
|||
accessToken = accessToken,
|
||||
logging = logging
|
||||
)
|
||||
override var lastStatus: Status? = null
|
||||
private set
|
||||
|
||||
/*
|
||||
* TODO: how should our result look like?
|
||||
|
@ -81,7 +87,7 @@ class NSAndroidClientImpl(
|
|||
}
|
||||
|
||||
override suspend fun getStatus(): Status = callWrapper(dispatcher) {
|
||||
api.statusSimple().result!!.toLocal()
|
||||
api.statusSimple().result!!.toLocal().also { lastStatus = it }
|
||||
}
|
||||
|
||||
// TODO: return something better than a String
|
||||
|
@ -132,11 +138,13 @@ class NSAndroidClientImpl(
|
|||
}
|
||||
}
|
||||
|
||||
override suspend fun getTreatmentsModifiedSince(from: Long, limit: Long): List<NSTreatment> = callWrapper(dispatcher) {
|
||||
override suspend fun getTreatmentsModifiedSince(from: Long, limit: Long): NSAndroidClient.ReadResponse<List<NSTreatment>> = callWrapper(dispatcher) {
|
||||
|
||||
val response = api.getTreatmentsModifiedSince(from, limit)
|
||||
val eTagString = response.headers()["ETag"]
|
||||
val eTag = eTagString?.substring(3, eTagString.length - 1)?.toLong() ?: throw TodoNightscoutException()
|
||||
if (response.isSuccessful) {
|
||||
return@callWrapper response.body()?.result?.map(RemoteTreatment::toTreatment).toNotNull()
|
||||
return@callWrapper NSAndroidClient.ReadResponse(eTag, response.body()?.result?.map(RemoteTreatment::toTreatment).toNotNull())
|
||||
} else {
|
||||
throw TodoNightscoutException() // TODO: react to response errors (offline, ...)
|
||||
}
|
||||
|
@ -152,6 +160,41 @@ class NSAndroidClientImpl(
|
|||
}
|
||||
}
|
||||
|
||||
override suspend fun createTreatment(nsTreatment: NSTreatment): CreateUpdateResponse = callWrapper(dispatcher) {
|
||||
|
||||
val remoteTreatment = nsTreatment.toRemoteTreatment() ?: throw InvalidFormatNightscoutException()
|
||||
remoteTreatment.app = "AAPS"
|
||||
val response = api.createTreatment(remoteTreatment)
|
||||
if (response.isSuccessful) {
|
||||
return@callWrapper CreateUpdateResponse(
|
||||
response = response.code(),
|
||||
identifier = response.body()?.result?.identifier ?: throw UnknownResponseNightscoutException(),
|
||||
isDeduplication = response.body()?.result?.isDeduplication ?: false,
|
||||
deduplicatedIdentifier = response.body()?.result?.deduplicatedIdentifier,
|
||||
lastModified = response.body()?.result?.lastModified
|
||||
)
|
||||
} else {
|
||||
throw TodoNightscoutException() // TODO: react to response errors (offline, ...)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun updateTreatment(nsTreatment: NSTreatment): CreateUpdateResponse = callWrapper(dispatcher) {
|
||||
|
||||
val remoteTreatment = nsTreatment.toRemoteTreatment() ?: throw InvalidFormatNightscoutException()
|
||||
val response = api.updateTreatment(remoteTreatment)
|
||||
if (response.isSuccessful) {
|
||||
return@callWrapper CreateUpdateResponse(
|
||||
response = response.code(),
|
||||
identifier = response.body()?.result?.identifier ?: throw UnknownResponseNightscoutException(),
|
||||
isDeduplication = response.body()?.result?.isDeduplication ?: false,
|
||||
deduplicatedIdentifier = response.body()?.result?.deduplicatedIdentifier,
|
||||
lastModified = response.body()?.result?.lastModified
|
||||
)
|
||||
} else {
|
||||
throw TodoNightscoutException() // TODO: react to response errors (offline, ...)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun <T> callWrapper(dispatcher: CoroutineDispatcher, block: suspend () -> T): T =
|
||||
withContext(dispatcher) {
|
||||
retry(
|
||||
|
|
|
@ -16,7 +16,7 @@ class NSAndroidRxClientImpl(private val client: NSAndroidClient) : NSAndroidRxCl
|
|||
override fun getStatus(): Single<Status> = rxSingle { client.getStatus() }
|
||||
override fun getLastModified(): Single<LastModified> = rxSingle { client.getLastModified() }
|
||||
override fun getSgvsModifiedSince(from: Long): Single<List<NSSgvV3>> = rxSingle { client.getSgvsModifiedSince(from) }
|
||||
override fun getTreatmentsModifiedSince(from: Long, limit: Long): Single<List<NSTreatment>> =
|
||||
override fun getTreatmentsModifiedSince(from: Long, limit: Long): Single<NSAndroidClient.ReadResponse<List<NSTreatment>>> =
|
||||
rxSingle { client.getTreatmentsModifiedSince(from, limit) }
|
||||
override fun getDeviceStatusModifiedSince(from: Long): Single<List<RemoteDeviceStatus>> =
|
||||
rxSingle { client.getDeviceStatusModifiedSince(from) }
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
package info.nightscout.sdk.exceptions
|
||||
|
||||
class InvalidFormatNightscoutException : NightscoutException()
|
|
@ -0,0 +1,3 @@
|
|||
package info.nightscout.sdk.exceptions
|
||||
|
||||
class UnknownResponseNightscoutException : NightscoutException()
|
|
@ -2,12 +2,19 @@ package info.nightscout.sdk.interfaces
|
|||
|
||||
import info.nightscout.sdk.localmodel.Status
|
||||
import info.nightscout.sdk.localmodel.entry.NSSgvV3
|
||||
import info.nightscout.sdk.localmodel.treatment.CreateUpdateResponse
|
||||
import info.nightscout.sdk.localmodel.treatment.NSTreatment
|
||||
import info.nightscout.sdk.remotemodel.LastModified
|
||||
import info.nightscout.sdk.remotemodel.RemoteDeviceStatus
|
||||
|
||||
interface NSAndroidClient {
|
||||
|
||||
class ReadResponse<T>(
|
||||
val lastServerModified: Long,
|
||||
val values: T
|
||||
)
|
||||
|
||||
val lastStatus: Status?
|
||||
suspend fun getVersion(): String
|
||||
suspend fun getStatus(): Status
|
||||
suspend fun getEntries(): String
|
||||
|
@ -16,6 +23,8 @@ interface NSAndroidClient {
|
|||
suspend fun getSgvs(): List<NSSgvV3>
|
||||
suspend fun getSgvsModifiedSince(from: Long): List<NSSgvV3>
|
||||
suspend fun getSgvsNewerThan(from: Long, limit: Long): List<NSSgvV3>
|
||||
suspend fun getTreatmentsModifiedSince(from: Long, limit: Long): List<NSTreatment>
|
||||
suspend fun getTreatmentsModifiedSince(from: Long, limit: Long): ReadResponse<List<NSTreatment>>
|
||||
suspend fun getDeviceStatusModifiedSince(from: Long): List<RemoteDeviceStatus>
|
||||
suspend fun createTreatment(nsTreatment: NSTreatment): CreateUpdateResponse
|
||||
suspend fun updateTreatment(nsTreatment: NSTreatment): CreateUpdateResponse
|
||||
}
|
|
@ -13,7 +13,7 @@ interface NSAndroidRxClient {
|
|||
fun getStatus(): Single<Status>
|
||||
fun getLastModified(): Single<LastModified>
|
||||
fun getSgvsModifiedSince(from: Long): Single<List<NSSgvV3>>
|
||||
fun getTreatmentsModifiedSince(from: Long, limit: Long): Single<List<NSTreatment>>
|
||||
fun getTreatmentsModifiedSince(from: Long, limit: Long): Single<NSAndroidClient.ReadResponse<List<NSTreatment>>>
|
||||
fun getDeviceStatusModifiedSince(from: Long): Single<List<RemoteDeviceStatus>>
|
||||
}
|
||||
|
||||
|
|
|
@ -7,4 +7,7 @@ data class ApiPermissions(
|
|||
val profile: ApiPermission,
|
||||
val settings: ApiPermission,
|
||||
val treatments: ApiPermission
|
||||
)
|
||||
) {
|
||||
fun isFull() = deviceStatus.full && entries.full && food.full && profile.full && settings.full && treatments.full
|
||||
fun isRead() = deviceStatus.read && entries.read && food.read && profile.read && settings.read && treatments.read
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
package info.nightscout.sdk.localmodel.treatment
|
||||
|
||||
class CreateUpdateResponse(
|
||||
val response: Int,
|
||||
val identifier: String?,
|
||||
val isDeduplication: Boolean? = false,
|
||||
val deduplicatedIdentifier: String? = null,
|
||||
val lastModified: Long? = null
|
||||
)
|
|
@ -4,14 +4,14 @@ import info.nightscout.sdk.localmodel.entry.NsUnits
|
|||
|
||||
data class NSBolus(
|
||||
override val date: Long,
|
||||
override val device: String?,
|
||||
override val identifier: String,
|
||||
override val units: NsUnits?,
|
||||
override val srvModified: Long,
|
||||
override val srvCreated: Long,
|
||||
override val device: String?= null,
|
||||
override val identifier: String?,
|
||||
override val units: NsUnits?= null,
|
||||
override val srvModified: Long? = null,
|
||||
override val srvCreated: Long? = null,
|
||||
override val utcOffset: Long,
|
||||
override val subject: String?,
|
||||
override var isReadOnly: Boolean,
|
||||
override val subject: String? = null,
|
||||
override var isReadOnly: Boolean = false,
|
||||
override val isValid: Boolean,
|
||||
override val eventType: EventType,
|
||||
override val notes: String?,
|
||||
|
@ -19,6 +19,7 @@ data class NSBolus(
|
|||
override val endId: Long?,
|
||||
override val pumpType: String?,
|
||||
override val pumpSerial: String?,
|
||||
override var app: String? = null,
|
||||
val insulin: Double,
|
||||
val type: BolusType
|
||||
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
package info.nightscout.sdk.localmodel.treatment
|
||||
|
||||
import info.nightscout.sdk.localmodel.entry.NsUnits
|
||||
import org.json.JSONObject
|
||||
|
||||
data class NSBolusWizard(
|
||||
override val date: Long,
|
||||
override val device: String?,
|
||||
override val identifier: String,
|
||||
override val identifier: String?,
|
||||
override val units: NsUnits?,
|
||||
override val srvModified: Long,
|
||||
override val srvCreated: Long,
|
||||
override val srvModified: Long?,
|
||||
override val srvCreated: Long?,
|
||||
override val utcOffset: Long,
|
||||
override val subject: String?,
|
||||
override var isReadOnly: Boolean,
|
||||
|
@ -20,6 +19,7 @@ data class NSBolusWizard(
|
|||
override val endId: Long?,
|
||||
override val pumpType: String?,
|
||||
override val pumpSerial: String?,
|
||||
override var app: String? = null,
|
||||
val bolusCalculatorResult: String?,
|
||||
val glucose: Double?,
|
||||
) : NSTreatment
|
|
@ -5,10 +5,10 @@ import info.nightscout.sdk.localmodel.entry.NsUnits
|
|||
data class NSCarbs(
|
||||
override val date: Long,
|
||||
override val device: String?,
|
||||
override val identifier: String,
|
||||
override val identifier: String?,
|
||||
override val units: NsUnits?,
|
||||
override val srvModified: Long,
|
||||
override val srvCreated: Long,
|
||||
override val srvModified: Long?,
|
||||
override val srvCreated: Long?,
|
||||
override val utcOffset: Long,
|
||||
override val subject: String?,
|
||||
override var isReadOnly: Boolean,
|
||||
|
@ -19,6 +19,7 @@ data class NSCarbs(
|
|||
override val endId: Long?,
|
||||
override val pumpType: String?,
|
||||
override val pumpSerial: String?,
|
||||
override var app: String? = null,
|
||||
val carbs: Double,
|
||||
val duration: Long
|
||||
) : NSTreatment
|
|
@ -6,10 +6,10 @@ import org.json.JSONObject
|
|||
data class NSEffectiveProfileSwitch(
|
||||
override val date: Long,
|
||||
override val device: String?,
|
||||
override val identifier: String,
|
||||
override val identifier: String?,
|
||||
override val units: NsUnits?,
|
||||
override val srvModified: Long,
|
||||
override val srvCreated: Long,
|
||||
override val srvModified: Long?,
|
||||
override val srvCreated: Long?,
|
||||
override val utcOffset: Long,
|
||||
override val subject: String?,
|
||||
override var isReadOnly: Boolean,
|
||||
|
@ -20,6 +20,7 @@ data class NSEffectiveProfileSwitch(
|
|||
override val endId: Long?,
|
||||
override val pumpType: String?,
|
||||
override val pumpSerial: String?,
|
||||
override var app: String? = null,
|
||||
val profileJson: JSONObject,
|
||||
val originalProfileName: String,
|
||||
val originalCustomizedName: String,
|
||||
|
|
|
@ -5,10 +5,10 @@ import info.nightscout.sdk.localmodel.entry.NsUnits
|
|||
data class NSExtendedBolus(
|
||||
override val date: Long,
|
||||
override val device: String?,
|
||||
override val identifier: String,
|
||||
override val identifier: String?,
|
||||
override val units: NsUnits?,
|
||||
override val srvModified: Long,
|
||||
override val srvCreated: Long,
|
||||
override val srvModified: Long?,
|
||||
override val srvCreated: Long?,
|
||||
override val utcOffset: Long,
|
||||
override val subject: String?,
|
||||
override var isReadOnly: Boolean,
|
||||
|
@ -19,7 +19,8 @@ data class NSExtendedBolus(
|
|||
override val endId: Long?,
|
||||
override val pumpType: String?,
|
||||
override val pumpSerial: String?,
|
||||
override var app: String? = null,
|
||||
val duration: Long,
|
||||
val enteredinsulin: Double,
|
||||
val isEmulatingTempbasal: Boolean
|
||||
val isEmulatingTempBasal: Boolean?
|
||||
) : NSTreatment
|
||||
|
|
|
@ -5,10 +5,10 @@ import info.nightscout.sdk.localmodel.entry.NsUnits
|
|||
data class NSOfflineEvent(
|
||||
override val date: Long,
|
||||
override val device: String?,
|
||||
override val identifier: String,
|
||||
override val identifier: String?,
|
||||
override val units: NsUnits?,
|
||||
override val srvModified: Long,
|
||||
override val srvCreated: Long,
|
||||
override val srvModified: Long?,
|
||||
override val srvCreated: Long?,
|
||||
override val utcOffset: Long,
|
||||
override val subject: String?,
|
||||
override var isReadOnly: Boolean,
|
||||
|
@ -19,6 +19,7 @@ data class NSOfflineEvent(
|
|||
override val endId: Long?,
|
||||
override val pumpType: String?,
|
||||
override val pumpSerial: String?,
|
||||
override var app: String? = null,
|
||||
val duration: Long,
|
||||
val reason: Reason
|
||||
) : NSTreatment {
|
||||
|
|
|
@ -6,10 +6,10 @@ import org.json.JSONObject
|
|||
data class NSProfileSwitch(
|
||||
override val date: Long,
|
||||
override val device: String?,
|
||||
override val identifier: String,
|
||||
override val identifier: String?,
|
||||
override val units: NsUnits?,
|
||||
override val srvModified: Long,
|
||||
override val srvCreated: Long,
|
||||
override val srvModified: Long?,
|
||||
override val srvCreated: Long?,
|
||||
override val utcOffset: Long,
|
||||
override val subject: String?,
|
||||
override var isReadOnly: Boolean,
|
||||
|
@ -20,6 +20,7 @@ data class NSProfileSwitch(
|
|||
override val endId: Long?,
|
||||
override val pumpType: String?,
|
||||
override val pumpSerial: String?,
|
||||
override var app: String? = null,
|
||||
val profileJson: JSONObject?,
|
||||
val profileName: String,
|
||||
val originalProfileName: String?,
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
package info.nightscout.sdk.localmodel.treatment
|
||||
|
||||
import info.nightscout.sdk.localmodel.entry.NsUnits
|
||||
import org.json.JSONObject
|
||||
|
||||
data class NSTemporaryBasal(
|
||||
override val date: Long,
|
||||
override val device: String?,
|
||||
override val identifier: String,
|
||||
override val identifier: String?,
|
||||
override val units: NsUnits?,
|
||||
override val srvModified: Long,
|
||||
override val srvCreated: Long,
|
||||
override val srvModified: Long?,
|
||||
override val srvCreated: Long?,
|
||||
override val utcOffset: Long,
|
||||
override val subject: String?,
|
||||
override var isReadOnly: Boolean,
|
||||
|
@ -20,10 +19,13 @@ data class NSTemporaryBasal(
|
|||
override val endId: Long?,
|
||||
override val pumpType: String?,
|
||||
override val pumpSerial: String?,
|
||||
override var app: String? = null,
|
||||
val duration: Long,
|
||||
val rate: Double,
|
||||
val rate: Double, // when sending to NS always convertedToAbsolute(timestamp, profile)
|
||||
val isAbsolute: Boolean,
|
||||
val type: Type
|
||||
val type: Type,
|
||||
val percent: Double? = null, // when sending to NS (rate - 100)
|
||||
val absolute: Double? = null // when sending to NS (rate)
|
||||
) : NSTreatment {
|
||||
|
||||
enum class Type {
|
||||
|
|
|
@ -5,10 +5,10 @@ import info.nightscout.sdk.localmodel.entry.NsUnits
|
|||
data class NSTemporaryTarget(
|
||||
override val date: Long,
|
||||
override val device: String?,
|
||||
override val identifier: String,
|
||||
override val identifier: String?,
|
||||
override val units: NsUnits?,
|
||||
override val srvModified: Long,
|
||||
override val srvCreated: Long,
|
||||
override val srvModified: Long?,
|
||||
override val srvCreated: Long?,
|
||||
override val utcOffset: Long,
|
||||
override val subject: String?,
|
||||
override var isReadOnly: Boolean,
|
||||
|
@ -19,6 +19,7 @@ data class NSTemporaryTarget(
|
|||
override val endId: Long?,
|
||||
override val pumpType: String?,
|
||||
override val pumpSerial: String?,
|
||||
override var app: String? = null,
|
||||
val duration: Long,
|
||||
val targetBottom: Double,
|
||||
val targetTop: Double,
|
||||
|
|
|
@ -6,10 +6,10 @@ import info.nightscout.sdk.localmodel.entry.NsUnits
|
|||
data class NSTherapyEvent(
|
||||
override val date: Long,
|
||||
override val device: String?,
|
||||
override val identifier: String,
|
||||
override val identifier: String?,
|
||||
override val units: NsUnits?,
|
||||
override val srvModified: Long,
|
||||
override val srvCreated: Long,
|
||||
override val srvModified: Long?,
|
||||
override val srvCreated: Long?,
|
||||
override val utcOffset: Long,
|
||||
override val subject: String?,
|
||||
override var isReadOnly: Boolean,
|
||||
|
@ -20,6 +20,7 @@ data class NSTherapyEvent(
|
|||
override val endId: Long?,
|
||||
override val pumpType: String?,
|
||||
override val pumpSerial: String?,
|
||||
override var app: String? = null,
|
||||
val duration: Long,
|
||||
var enteredBy: String? = null,
|
||||
var glucose: Double? = null,
|
||||
|
|
|
@ -5,11 +5,11 @@ import info.nightscout.sdk.localmodel.entry.NsUnits
|
|||
interface NSTreatment {
|
||||
val date: Long
|
||||
val device: String?
|
||||
val identifier: String
|
||||
val identifier: String?
|
||||
val units: NsUnits?
|
||||
val eventType: EventType
|
||||
val srvModified: Long
|
||||
val srvCreated: Long
|
||||
val srvModified: Long?
|
||||
val srvCreated: Long?
|
||||
val utcOffset: Long
|
||||
val subject: String?
|
||||
var isReadOnly: Boolean
|
||||
|
@ -19,6 +19,7 @@ interface NSTreatment {
|
|||
val endId: Long?
|
||||
val pumpType: String?
|
||||
val pumpSerial: String?
|
||||
var app: String?
|
||||
|
||||
fun Double.asMgdl() =
|
||||
when (units) {
|
||||
|
|
|
@ -117,7 +117,7 @@ internal fun RemoteTreatment.toTreatment(): NSTreatment? {
|
|||
pumpSerial = extendedEmulated.pumpSerial,
|
||||
enteredinsulin = extendedEmulated.enteredinsulin ?: 0.0,
|
||||
duration = extendedEmulated.durationInMilliseconds ?: TimeUnit.MINUTES.toMillis(extendedEmulated.duration ?: 0L),
|
||||
isEmulatingTempbasal = extendedEmulated.isEmulatingTempBasal
|
||||
isEmulatingTempBasal = extendedEmulated.isEmulatingTempBasal
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -329,10 +329,270 @@ internal fun RemoteTreatment.toTreatment(): NSTreatment? {
|
|||
pumpSerial = this.pumpSerial,
|
||||
enteredinsulin = this.enteredinsulin,
|
||||
duration = this.durationInMilliseconds ?: TimeUnit.MINUTES.toMillis(this.duration ?: 0L),
|
||||
isEmulatingTempbasal = this.isEmulatingTempBasal
|
||||
isEmulatingTempBasal = this.isEmulatingTempBasal
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
internal fun NSTreatment.toRemoteTreatment(): RemoteTreatment? =
|
||||
when (this) {
|
||||
is NSBolus -> RemoteTreatment(
|
||||
date = date,
|
||||
device = device,
|
||||
identifier = identifier,
|
||||
units = units?.value,
|
||||
utcOffset = utcOffset,
|
||||
subject = subject,
|
||||
isReadOnly = isReadOnly,
|
||||
isValid = isValid,
|
||||
eventType = eventType,
|
||||
notes = notes,
|
||||
pumpId = pumpId,
|
||||
endId = endId,
|
||||
pumpType = pumpType,
|
||||
pumpSerial = pumpSerial,
|
||||
insulin = insulin,
|
||||
type = type.name
|
||||
)
|
||||
|
||||
is NSCarbs -> RemoteTreatment(
|
||||
date = date,
|
||||
device = device,
|
||||
identifier = identifier,
|
||||
units = units?.value,
|
||||
utcOffset = utcOffset,
|
||||
subject = subject,
|
||||
isReadOnly = isReadOnly,
|
||||
isValid = isValid,
|
||||
eventType = eventType,
|
||||
notes = notes,
|
||||
pumpId = pumpId,
|
||||
endId = endId,
|
||||
pumpType = pumpType,
|
||||
pumpSerial = pumpSerial,
|
||||
carbs = carbs,
|
||||
duration = duration
|
||||
)
|
||||
|
||||
is NSTemporaryTarget -> RemoteTreatment(
|
||||
date = date,
|
||||
device = device,
|
||||
identifier = identifier,
|
||||
units = units?.value,
|
||||
srvModified = srvModified,
|
||||
srvCreated = srvCreated,
|
||||
utcOffset = utcOffset,
|
||||
subject = subject,
|
||||
isReadOnly = isReadOnly,
|
||||
isValid = isValid,
|
||||
eventType = eventType,
|
||||
notes = notes,
|
||||
pumpId = pumpId,
|
||||
endId = endId,
|
||||
pumpType = pumpType,
|
||||
pumpSerial = pumpSerial,
|
||||
duration = TimeUnit.MILLISECONDS.toMinutes(duration),
|
||||
durationInMilliseconds = duration,
|
||||
targetBottom = targetBottom,
|
||||
targetTop = targetTop,
|
||||
reason = reason.text
|
||||
)
|
||||
/*
|
||||
// Convert back emulated TBR -> EB
|
||||
eventType == EventType.TEMPORARY_BASAL && extendedEmulated != null ->
|
||||
|
||||
return RemoteTreatment(
|
||||
date = treatmentTimestamp,
|
||||
device = device,
|
||||
identifier = identifier,
|
||||
units = NsUnits.fromString(extendedEmulated.units),
|
||||
srvModified = srvModified,
|
||||
srvCreated = srvCreated,
|
||||
utcOffset = utcOffset ?: 0,
|
||||
subject = subject,
|
||||
isReadOnly = extendedEmulated.isReadOnly ?: false,
|
||||
isValid = extendedEmulated.isValid ?: true,
|
||||
eventType = extendedEmulated.eventType,
|
||||
notes = extendedEmulated.notes,
|
||||
pumpId = extendedEmulated.pumpId,
|
||||
endId = extendedEmulated.endId,
|
||||
pumpType = extendedEmulated.pumpType,
|
||||
pumpSerial = extendedEmulated.pumpSerial,
|
||||
enteredinsulin = extendedEmulated.enteredinsulin ?: 0.0,
|
||||
duration = extendedEmulated.durationInMilliseconds ?: TimeUnit.MINUTES.toMillis(extendedEmulated.duration ?: 0L),
|
||||
isEmulatingTempbasal = extendedEmulated.isEmulatingTempBasal
|
||||
)
|
||||
}
|
||||
*/
|
||||
is NSTemporaryBasal -> RemoteTreatment(
|
||||
date = date,
|
||||
device = device,
|
||||
identifier = identifier,
|
||||
units = units?.value,
|
||||
srvModified = srvModified,
|
||||
srvCreated = srvCreated,
|
||||
utcOffset = utcOffset,
|
||||
subject = subject,
|
||||
isReadOnly = isReadOnly,
|
||||
isValid = isValid,
|
||||
eventType = eventType,
|
||||
notes = notes,
|
||||
pumpId = pumpId,
|
||||
endId = endId,
|
||||
pumpType = pumpType,
|
||||
pumpSerial = pumpSerial,
|
||||
duration = TimeUnit.MILLISECONDS.toMinutes(duration),
|
||||
durationInMilliseconds = duration,
|
||||
absolute = absolute,
|
||||
percent = percent,
|
||||
rate = absolute,
|
||||
type = type.name
|
||||
)
|
||||
|
||||
is NSEffectiveProfileSwitch -> RemoteTreatment(
|
||||
date = date,
|
||||
device = device,
|
||||
identifier = identifier,
|
||||
units = units?.value,
|
||||
srvModified = srvModified,
|
||||
srvCreated = srvCreated,
|
||||
utcOffset = utcOffset,
|
||||
subject = subject,
|
||||
isReadOnly = isReadOnly,
|
||||
isValid = isValid,
|
||||
eventType = eventType,
|
||||
notes = notes,
|
||||
pumpId = pumpId,
|
||||
endId = endId,
|
||||
pumpType = pumpType,
|
||||
pumpSerial = pumpSerial,
|
||||
profileJson = profileJson.toString(),
|
||||
originalProfileName = originalProfileName,
|
||||
originalCustomizedName = originalCustomizedName,
|
||||
originalTimeshift = originalTimeshift,
|
||||
originalPercentage = originalPercentage,
|
||||
originalDuration = originalDuration,
|
||||
originalEnd = originalEnd
|
||||
)
|
||||
|
||||
is NSProfileSwitch -> RemoteTreatment(
|
||||
date = date,
|
||||
device = device,
|
||||
identifier = identifier,
|
||||
units = units?.value,
|
||||
srvModified = srvModified,
|
||||
srvCreated = srvCreated,
|
||||
utcOffset = utcOffset,
|
||||
subject = subject,
|
||||
isReadOnly = isReadOnly,
|
||||
isValid = isValid,
|
||||
eventType = eventType,
|
||||
notes = notes,
|
||||
pumpId = pumpId,
|
||||
endId = endId,
|
||||
pumpType = pumpType,
|
||||
pumpSerial = pumpSerial,
|
||||
profileJson = profileJson.toString(), // must be de-customized
|
||||
profile = profileName,
|
||||
originalProfileName = originalProfileName,
|
||||
originalDuration = originalDuration,
|
||||
duration = duration,
|
||||
timeshift = timeShift,
|
||||
percentage = percentage,
|
||||
)
|
||||
|
||||
is NSBolusWizard -> RemoteTreatment(
|
||||
date = date,
|
||||
device = device,
|
||||
identifier = identifier,
|
||||
units = units?.value,
|
||||
srvModified = srvModified,
|
||||
srvCreated = srvCreated,
|
||||
utcOffset = utcOffset,
|
||||
subject = subject,
|
||||
isReadOnly = isReadOnly,
|
||||
isValid = isValid,
|
||||
eventType = eventType,
|
||||
notes = notes,
|
||||
pumpId = pumpId,
|
||||
endId = endId,
|
||||
pumpType = pumpType,
|
||||
pumpSerial = pumpSerial,
|
||||
bolusCalculatorResult = bolusCalculatorResult,
|
||||
glucose = glucose
|
||||
)
|
||||
|
||||
is NSTherapyEvent -> RemoteTreatment(
|
||||
date = date,
|
||||
device = device,
|
||||
identifier = identifier,
|
||||
units = units?.value,
|
||||
srvModified = srvModified,
|
||||
srvCreated = srvCreated,
|
||||
utcOffset = utcOffset,
|
||||
subject = subject,
|
||||
isReadOnly = isReadOnly,
|
||||
isValid = isValid,
|
||||
eventType = eventType,
|
||||
notes = notes,
|
||||
pumpId = pumpId,
|
||||
endId = endId,
|
||||
pumpType = pumpType,
|
||||
pumpSerial = pumpSerial,
|
||||
duration = TimeUnit.MILLISECONDS.toMinutes(duration),
|
||||
durationInMilliseconds = duration,
|
||||
glucose = glucose,
|
||||
enteredBy = enteredBy,
|
||||
glucoseType = glucoseType?.text
|
||||
)
|
||||
|
||||
is NSOfflineEvent -> RemoteTreatment(
|
||||
date = date,
|
||||
device = device,
|
||||
identifier = identifier,
|
||||
units = units?.value,
|
||||
srvModified = srvModified,
|
||||
srvCreated = srvCreated,
|
||||
utcOffset = utcOffset,
|
||||
subject = subject,
|
||||
isReadOnly = isReadOnly,
|
||||
isValid = isValid,
|
||||
eventType = eventType,
|
||||
notes = notes,
|
||||
pumpId = pumpId,
|
||||
endId = endId,
|
||||
pumpType = pumpType,
|
||||
pumpSerial = pumpSerial,
|
||||
duration = TimeUnit.MILLISECONDS.toMinutes(duration),
|
||||
durationInMilliseconds = duration,
|
||||
reason = reason.name
|
||||
)
|
||||
|
||||
is NSExtendedBolus -> RemoteTreatment(
|
||||
date = date,
|
||||
device = device,
|
||||
identifier = identifier,
|
||||
units = units?.value,
|
||||
srvModified = srvModified,
|
||||
srvCreated = srvCreated,
|
||||
utcOffset = utcOffset,
|
||||
subject = subject,
|
||||
isReadOnly = isReadOnly,
|
||||
isValid = isValid,
|
||||
eventType = eventType,
|
||||
notes = notes,
|
||||
pumpId = pumpId,
|
||||
endId = endId,
|
||||
pumpType = pumpType,
|
||||
pumpSerial = pumpSerial,
|
||||
enteredinsulin = enteredinsulin,
|
||||
duration = TimeUnit.MILLISECONDS.toMinutes(duration),
|
||||
durationInMilliseconds = duration,
|
||||
isEmulatingTempBasal = isEmulatingTempBasal
|
||||
)
|
||||
|
||||
else -> null
|
||||
}
|
||||
|
|
|
@ -2,13 +2,17 @@ package info.nightscout.sdk.networking
|
|||
|
||||
import com.google.gson.JsonElement
|
||||
import info.nightscout.sdk.remotemodel.LastModified
|
||||
import info.nightscout.sdk.remotemodel.RemoteDeviceStatus
|
||||
import info.nightscout.sdk.remotemodel.NSResponse
|
||||
import info.nightscout.sdk.remotemodel.RemoteCreateUpdateResponse
|
||||
import info.nightscout.sdk.remotemodel.RemoteDeviceStatus
|
||||
import info.nightscout.sdk.remotemodel.RemoteEntry
|
||||
import info.nightscout.sdk.remotemodel.RemoteStatusResponse
|
||||
import info.nightscout.sdk.remotemodel.RemoteTreatment
|
||||
import retrofit2.Response
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.POST
|
||||
import retrofit2.http.PUT
|
||||
import retrofit2.http.Path
|
||||
import retrofit2.http.Query
|
||||
|
||||
|
@ -48,4 +52,11 @@ internal interface NightscoutRemoteService {
|
|||
|
||||
@GET("v3/devicestatus/history/{from}")
|
||||
suspend fun getDeviceStatusModifiedSince(@Path("from") from: Long): Response<NSResponse<List<RemoteDeviceStatus>>>
|
||||
|
||||
@POST("v3/treatments")
|
||||
suspend fun createTreatment(@Body remoteTreatment: RemoteTreatment): Response<NSResponse<RemoteCreateUpdateResponse>>
|
||||
|
||||
@PUT("v3/treatments")
|
||||
suspend fun updateTreatment(@Body remoteTreatment: RemoteTreatment): Response<NSResponse<RemoteCreateUpdateResponse>>
|
||||
|
||||
}
|
||||
|
|
|
@ -17,6 +17,13 @@ internal data class RemoteStorage(
|
|||
@SerializedName("version") val version: String
|
||||
)
|
||||
|
||||
internal data class RemoteCreateUpdateResponse(
|
||||
@SerializedName("identifier") val identifier: String?,
|
||||
@SerializedName("isDeduplication") val isDeduplication: Boolean?,
|
||||
@SerializedName("deduplicatedIdentifier") val deduplicatedIdentifier: String?,
|
||||
@SerializedName("lastModified") val lastModified: Long?
|
||||
)
|
||||
|
||||
internal data class RemoteApiPermissions(
|
||||
@SerializedName("devicestatus") val deviceStatus: RemoteApiPermission,
|
||||
@SerializedName("entries") val entries: RemoteApiPermission,
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
package info.nightscout.sdk.remotemodel
|
||||
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import info.nightscout.sdk.localmodel.treatment.EventType
|
||||
import org.joda.time.DateTime
|
||||
import org.joda.time.format.ISODateTimeFormat
|
||||
import org.json.JSONObject
|
||||
|
||||
/*
|
||||
* Depending on the type, different other fields are present.
|
||||
|
@ -17,73 +15,72 @@ import org.json.JSONObject
|
|||
*
|
||||
* */
|
||||
internal data class RemoteTreatment(
|
||||
@SerializedName("identifier") val identifier: String, // string Main addressing, required field that identifies document in the collection. The client should not create the identifier, the server automatically assigns it when the document is inserted.
|
||||
@SerializedName("date") val date: Long?, // integer($int64) or string required timestamp when the record or event occurred, you can choose from three input formats Unix epoch in milliseconds (1525383610088), Unix epoch in seconds (1525383610), ISO 8601 with optional timezone ('2018-05-03T21:40:10.088Z' or '2018-05-03T23:40:10.088+02:00')
|
||||
@SerializedName("mills") val mills: Long?, // integer($int64) or string required timestamp when the record or event occurred, you can choose from three input formats Unix
|
||||
@SerializedName("timestamp") val timestamp: Long?, // integer($int64) or string required timestamp when the record or event occurred, you can choose from three input formats Unix epoch in milliseconds (1525383610088), Unix epoch in seconds (1525383610), ISO 8601 with optional timezone ('2018-05-03T21:40:10.088Z' or '2018-05-03T23:40:10.088+02:00')
|
||||
@SerializedName("created_at") val created_at: String, // integer($int64) or string timestamp on previous version of api, in my examples, a lot of treatments don't have date, only created_at, some of them with string others with long...
|
||||
@SerializedName("utcOffset") val utcOffset: Long?, // integer Local UTC offset (timezone) of the event in minutes. This field can be set either directly by the client (in the incoming
|
||||
// document) or it is automatically parsed from the date field.
|
||||
// @SerializedName("app") val app : String, // TODO required ? Application or system in which the record was entered by human or device for the first time.
|
||||
@SerializedName("device") val device: String?, // string The device from which the data originated (including serial number of the device, if it is relevant and safe).
|
||||
@SerializedName("srvCreated") val srvCreated: Long, // integer($int64) example: 1525383610088 The server's timestamp of document insertion into the database (Unix epoch in ms). This field appears only for documents which were inserted by API v3.
|
||||
@SerializedName("subject") val subject: String?, // string Name of the security subject (within Nightscout scope) which has created the document. This field is automatically set by the server from the passed token or JWT.
|
||||
@SerializedName("srvModified") val srvModified: Long, // integer($int64) example: 1525383610088 The server's timestamp of the last document modification in the database (Unix epoch in ms). This field appears only for documents which were somehow modified by API v3 (inserted, updated or deleted).
|
||||
@SerializedName("modifiedBy") val modifiedBy: String?, // string Name of the security subject (within Nightscout scope) which has patched or deleted the document for the last time. This field is automatically set by the server.
|
||||
@SerializedName("isValid") val isValid: Boolean?, // boolean A flag set by the server only for deleted documents. This field appears only within history operation and for documents which were deleted by API v3 (and they always have a false value)
|
||||
@SerializedName("isReadOnly") val isReadOnly: Boolean?, // boolean A flag set by client that locks the document from any changes. Every document marked with isReadOnly=true is forever immutable and cannot even be deleted.
|
||||
@SerializedName("identifier") val identifier: String?, // string Main addressing, required field that identifies document in the collection. The client should not create the identifier, the server automatically assigns it when the document is inserted.
|
||||
@SerializedName("date") val date: Long? = null, // integer($int64) or string required timestamp when the record or event occurred, you can choose from three input formats Unix epoch in milliseconds (1525383610088), Unix epoch in seconds (1525383610), ISO 8601 with optional timezone ('2018-05-03T21:40:10.088Z' or '2018-05-03T23:40:10.088+02:00')
|
||||
@SerializedName("mills") val mills: Long? = null, // integer($int64) or string required timestamp when the record or event occurred, you can choose from three input formats Unix
|
||||
@SerializedName("timestamp") val timestamp: Long? = null, // integer($int64) or string required timestamp when the record or event occurred, you can choose from three input formats Unix epoch in milliseconds (1525383610088), Unix epoch in seconds (1525383610), ISO 8601 with optional timezone ('2018-05-03T21:40:10.088Z' or '2018-05-03T23:40:10.088+02:00')
|
||||
@SerializedName("created_at") val created_at: String? = null, // integer($int64) or string timestamp on previous version of api, in my examples, a lot of treatments don't have date, only created_at, some of them with string others with long...
|
||||
@SerializedName("utcOffset") val utcOffset: Long? = null, // integer Local UTC offset (timezone) of the event in minutes. This field can be set either directly by the client (in the incoming document) or it is automatically parsed from the date field.
|
||||
@SerializedName("app") var app : String? = null, // Application or system in which the record was entered by human or device for the first time.
|
||||
@SerializedName("device") val device: String? = null, // string The device from which the data originated (including serial number of the device, if it is relevant and safe).
|
||||
@SerializedName("srvCreated") val srvCreated: Long? = null, // integer($int64) example: 1525383610088 The server's timestamp of document insertion into the database (Unix epoch in ms). This field appears only for documents which were inserted by API v3.
|
||||
@SerializedName("subject") val subject: String? = null, // string Name of the security subject (within Nightscout scope) which has created the document. This field is automatically set by the server from the passed token or JWT.
|
||||
@SerializedName("srvModified") val srvModified: Long? = null, // integer($int64) example: 1525383610088 The server's timestamp of the last document modification in the database (Unix epoch in ms). This field appears only for documents which were somehow modified by API v3 (inserted, updated or deleted).
|
||||
@SerializedName("modifiedBy") val modifiedBy: String? = null, // string Name of the security subject (within Nightscout scope) which has patched or deleted the document for the last time. This field is automatically set by the server.
|
||||
@SerializedName("isValid") val isValid: Boolean? = null, // boolean A flag set by the server only for deleted documents. This field appears only within history operation and for documents which were deleted by API v3 (and they always have a false value)
|
||||
@SerializedName("isReadOnly") val isReadOnly: Boolean? = null, // boolean A flag set by client that locks the document from any changes. Every document marked with isReadOnly=true is forever immutable and cannot even be deleted.
|
||||
@SerializedName("eventType") val eventType: EventType, // string "BG Check", "Snack Bolus", "Meal Bolus", "Correction Bolus", "Carb Correction", "Combo Bolus", "Announcement", "Note", "Question", "Exercise", "Site Change", "Sensor Start", "Sensor Change", "Pump Battery Change", "Insulin Change", "Temp Basal", "Profile Switch", "D.A.D. Alert", "Temporary Target", "OpenAPS Offline", "Bolus Wizard"
|
||||
@SerializedName("glucose") val glucose: Double?, // double Current glucose
|
||||
@SerializedName("glucoseType") val glucoseType: String?, // string example: "Sensor", "Finger", "Manual"
|
||||
@SerializedName("units") val units: String?, // string The units for the glucose value, mg/dl or mmol/l. It is strongly recommended to fill in this field.
|
||||
@SerializedName("carbs") val carbs: Double?, // number... Amount of carbs given.
|
||||
@SerializedName("protein") val protein: Int?, // number... Amount of protein given.
|
||||
@SerializedName("fat") val fat: Int?, // number... Amount of fat given.
|
||||
@SerializedName("insulin") val insulin: Double?, // number... Amount of insulin, if any.
|
||||
@SerializedName("duration") val duration: Long?, // number... Duration in minutes.
|
||||
@SerializedName("durationInMilliseconds") val durationInMilliseconds: Long?, // number... Duration in milliseconds.
|
||||
@SerializedName("preBolus") val preBolus: Int?, // number... How many minutes the bolus was given before the meal started.
|
||||
@SerializedName("splitNow") val splitNow: Int?, // number... Immediate part of combo bolus (in percent).
|
||||
@SerializedName("splitExt") val splitExt: Int?, // number... Extended part of combo bolus (in percent).
|
||||
@SerializedName("percent") val percent: Double?, // number... Eventual basal change in percent.
|
||||
@SerializedName("absolute") val absolute: Double?, // number... Eventual basal change in absolute value (insulin units per hour).
|
||||
@SerializedName("targetTop") val targetTop: Double?, // number... Top limit of temporary target.
|
||||
@SerializedName("targetBottom") val targetBottom: Double?, // number... Bottom limit of temporary target.
|
||||
@SerializedName("profile") val profile: String?, // string Name of the profile to which the pump has been switched.
|
||||
@SerializedName("reason") val reason: String?, // string For example the reason why the profile has been switched or why the temporary target has been set.
|
||||
@SerializedName("notes") val notes: String?, // string Description/notes of treatment.
|
||||
@SerializedName("enteredBy") val enteredBy: String?, // string Who entered the treatment.
|
||||
@SerializedName("glucose") val glucose: Double? = null, // double Current glucose
|
||||
@SerializedName("glucoseType") val glucoseType: String? = null, // string example: "Sensor", "Finger", "Manual"
|
||||
@SerializedName("units") val units: String? = null, // string The units for the glucose value, mg/dl or mmol/l. It is strongly recommended to fill in this field.
|
||||
@SerializedName("carbs") val carbs: Double? = null, // number... Amount of carbs given.
|
||||
@SerializedName("protein") val protein: Int? = null, // number... Amount of protein given.
|
||||
@SerializedName("fat") val fat: Int? = null, // number... Amount of fat given.
|
||||
@SerializedName("insulin") val insulin: Double? = null, // number... Amount of insulin, if any.
|
||||
@SerializedName("duration") val duration: Long? = null, // number... Duration in minutes.
|
||||
@SerializedName("durationInMilliseconds") val durationInMilliseconds: Long? = null, // number... Duration in milliseconds.
|
||||
@SerializedName("preBolus") val preBolus: Int? = null, // number... How many minutes the bolus was given before the meal started.
|
||||
@SerializedName("splitNow") val splitNow: Int? = null, // number... Immediate part of combo bolus (in percent).
|
||||
@SerializedName("splitExt") val splitExt: Int? = null, // number... Extended part of combo bolus (in percent).
|
||||
@SerializedName("percent") val percent: Double? = null, // number... Eventual basal change in percent.
|
||||
@SerializedName("absolute") val absolute: Double? = null, // number... Eventual basal change in absolute value (insulin units per hour).
|
||||
@SerializedName("targetTop") val targetTop: Double? = null, // number... Top limit of temporary target.
|
||||
@SerializedName("targetBottom") val targetBottom: Double? = null, // number... Bottom limit of temporary target.
|
||||
@SerializedName("profile") val profile: String? = null, // string Name of the profile to which the pump has been switched.
|
||||
@SerializedName("reason") val reason: String? = null, // string For example the reason why the profile has been switched or why the temporary target has been set.
|
||||
@SerializedName("notes") val notes: String? = null, // string Description/notes of treatment.
|
||||
@SerializedName("enteredBy") val enteredBy: String? = null, // string Who entered the treatment.
|
||||
|
||||
@SerializedName("endId") val endId: Long?, // long id of record which ended this
|
||||
@SerializedName("pumpId") val pumpId: Long?, // long or "Meal Bolus", "Correction Bolus", "Combo Bolus" ex 4102 not sure if long or int
|
||||
@SerializedName("pumpType") val pumpType: String?, // string "Meal Bolus", "Correction Bolus", "Combo Bolus" ex "ACCU_CHEK_INSIGHT_BLUETOOTH",
|
||||
@SerializedName("pumpSerial") val pumpSerial: String?, // string "Meal Bolus", "Correction Bolus", "Combo Bolus" "33013206",
|
||||
@SerializedName("endId") val endId: Long? = null, // long id of record which ended this
|
||||
@SerializedName("pumpId") val pumpId: Long? = null, // long or "Meal Bolus", "Correction Bolus", "Combo Bolus" ex 4102 not sure if long or int
|
||||
@SerializedName("pumpType") val pumpType: String? = null, // string "Meal Bolus", "Correction Bolus", "Combo Bolus" ex "ACCU_CHEK_INSIGHT_BLUETOOTH",
|
||||
@SerializedName("pumpSerial") val pumpSerial: String? = null, // string "Meal Bolus", "Correction Bolus", "Combo Bolus" "33013206",
|
||||
|
||||
// other fields found in examples but not in documentation
|
||||
@SerializedName("profileJson") val profileJson: String?, // string "Profile Switch" ex json toString "{\"units\":\"mg\\/dl\",\"dia\":5,\"timezone\":\"Africa\\/Cairo\",
|
||||
@SerializedName("profileJson") val profileJson: String? = null, // string "Profile Switch" ex json toString "{\"units\":\"mg\\/dl\",\"dia\":5,\"timezone\":\"Africa\\/Cairo\",
|
||||
// \"sens\":[{\"time\":\"00:00\",\"timeAsSeconds\":0,\"value\":60},{\"time\":\"07:00\",\"timeAsSeconds\":25200,\"value\":60},{\"time\":\"08:00\",\"timeAsSeconds\":28800,\"value\":61.33333333333333},{\"time\":\"09:00\",\"timeAsSeconds\":32400,\"value\":65.33333333333333},{\"time\":\"10:00\",\"timeAsSeconds\":36000,\"value\":69.33333333333333},{\"time\":\"11:00\",\"timeAsSeconds\":39600,\"value\":73.33333333333333},{\"time\":\"13:00\",\"timeAsSeconds\":46800,\"value\":72},{\"time\":\"14:00\",\"timeAsSeconds\":50400,\"value\":68},{\"time\":\"15:00\",\"timeAsSeconds\":54000,\"value\":65.33333333333333},{\"time\":\"16:00\",\"timeAsSeconds\":57600,\"value\":65.33333333333333}],\"carbratio\":[{\"time\":\"00:00\",\"timeAsSeconds\":0,\"value\":5.7333333333333325},{\"time\":\"11:00\",\"timeAsSeconds\":39600,\"value\":7.333333333333333},{\"time\":\"16:00\",\"timeAsSeconds\":57600,\"value\":6.666666666666666}],\"basal\":[{\"time\":\"00:00\",\"timeAsSeconds\":0,\"value\":0.5249999999999999},{\"time\":\"01:00\",\"timeAsSeconds\":3600,\"value\":0.585},{\"time\":\"02:00\",\"timeAsSeconds\":7200,\"value\":0.6375},{\"time\":\"03:00\",\"timeAsSeconds\":10800,\"value\":0.5625},{\"time\":\"04:00\",\"timeAsSeconds\":14400,\"value\":0.4575},{\"time\":\"05:00\",\"timeAsSeconds\":18000,\"value\":0.5175},{\"time\":\"06:00\",\"timeAsSeconds\":21600,\"value\":0.48},{\"time\":\"07:00\",\"timeAsSeconds\":25200,\"value\":0.51},{\"time\":\"08:00\",\"timeAsSeconds\":28800,\"value\":0.48750000000000004},{\"time\":\"09:00\",\"timeAsSeconds\":32400,\"value\":0.48},{\"time\":\"10:00\",\"timeAsSeconds\":36000,\"value\":0.48750000000000004},{\"time\":\"11:00\",\"timeAsSeconds\":39600,\"value\":0.5025000000000001},{\"time\":\"12:00\",\"timeAsSeconds\":43200,\"value\":0.5549999999999999},{\"time\":\"13:00\",\"timeAsSeconds\":46800,\"value\":0.5700000000000001},{\"time\":\"14:00\",\"timeAsSeconds\":50400,\"value\":0.5700000000000001},{\"time\":\"15:00\",\"timeAsSeconds\":54000,\"value\":0.5775},{\"time\":\"16:00\",\"timeAsSeconds\":57600,\"value\":0.51},{\"time\":\"17:00\",\"timeAsSeconds\":61200,\"value\":0.54},{\"time\":\"18:00\",\"timeAsSeconds\":64800,\"value\":0.48750000000000004},{\"time\":\"19:00\",\"timeAsSeconds\":68400,\"value\":0.5249999999999999},{\"time\":\"20:00\",\"timeAsSeconds\":72000,\"value\":0.46499999999999997},{\"time\":\"21:00\",\"timeAsSeconds\":75600,\"value\":0.46499999999999997},{\"time\":\"22:00\",\"timeAsSeconds\":79200,\"value\":0.43499999999999994},{\"time\":\"23:00\",\"timeAsSeconds\":82800,\"value\":0.41250000000000003}],\"target_low\":[{\"time\":\"00:00\",\"timeAsSeconds\":0,\"value\":100},{\"time\":\"06:00\",\"timeAsSeconds\":21600,\"value\":90},{\"time\":\"09:00\",\"timeAsSeconds\":32400,\"value\":100},{\"time\":\"11:00\",\"timeAsSeconds\":39600,\"value\":90},{\"time\":\"14:00\",\"timeAsSeconds\":50400,\"value\":100},{\"time\":\"18:00\",\"timeAsSeconds\":64800,\"value\":90},{\"time\":\"21:00\",\"timeAsSeconds\":75600,\"value\":100}],\"target_high\":[{\"time\":\"00:00\",\"timeAsSeconds\":0,\"value\":100},{\"time\":\"06:00\",\"timeAsSeconds\":21600,\"value\":90},{\"time\":\"09:00\",\"timeAsSeconds\":32400,\"value\":100},{\"time\":\"11:00\",\"timeAsSeconds\":39600,\"value\":90},{\"time\":\"14:00\",\"timeAsSeconds\":50400,\"value\":100},{\"time\":\"18:00\",\"timeAsSeconds\":64800,\"value\":90},{\"time\":\"21:00\",\"timeAsSeconds\":75600,\"value\":100}]}",
|
||||
@SerializedName("originalProfileName") val originalProfileName: String?, // string "Effective Profile Switch"
|
||||
@SerializedName("originalCustomizedName") val originalCustomizedName: String?, // string "Effective Profile Switch"
|
||||
@SerializedName("originalTimeshift") val originalTimeshift: Long?, // long "Effective Profile Switch"
|
||||
@SerializedName("originalPercentage") val originalPercentage: Int?, // int "Effective Profile Switch"
|
||||
@SerializedName("originalDuration") val originalDuration: Long?, // long "Effective Profile Switch"
|
||||
@SerializedName("originalEnd") val originalEnd: Long?, // long "Effective Profile Switch"
|
||||
@SerializedName("originalProfileName") val originalProfileName: String? = null, // string "Effective Profile Switch"
|
||||
@SerializedName("originalCustomizedName") val originalCustomizedName: String? = null, // string "Effective Profile Switch"
|
||||
@SerializedName("originalTimeshift") val originalTimeshift: Long? = null, // long "Effective Profile Switch"
|
||||
@SerializedName("originalPercentage") val originalPercentage: Int? = null, // int "Effective Profile Switch"
|
||||
@SerializedName("originalDuration") val originalDuration: Long? = null, // long "Effective Profile Switch"
|
||||
@SerializedName("originalEnd") val originalEnd: Long? = null, // long "Effective Profile Switch"
|
||||
|
||||
@SerializedName("bolusCalculatorResult") val bolusCalculatorResult: String?, // string "Bolus Wizard" json toString ex "bolusCalculatorResult": "{\"basalIOB\":-0.247,\"bolusIOB\":-1.837,\"carbs\":45.0,\"carbsInsulin\":9.0,\"cob\":0.0,\"cobInsulin\":0.0,\"dateCreated\":1626202788810,\"glucoseDifference\":44.0,\"glucoseInsulin\":0.8979591836734694,\"glucoseTrend\":5.5,\"glucoseValue\":134.0,\"ic\":5.0,\"id\":331,\"interfaceIDs_backing\":{\"nightscoutId\":\"60ede2a4c574da0004a3869d\"},\"isValid\":true,\"isf\":49.0,\"note\":\"\",\"otherCorrection\":0.0,\"percentageCorrection\":90,\"profileName\":\"Tuned 13/01 90%Lyum\",\"superbolusInsulin\":0.0,\"targetBGHigh\":90.0,\"targetBGLow\":90.0,\"timestamp\":1626202783325,\"totalInsulin\":7.34,\"trendInsulin\":0.336734693877551,\"utcOffset\":7200000,\"version\":1,\"wasBasalIOBUsed\":true,\"wasBolusIOBUsed\":true,\"wasCOBUsed\":true,\"wasGlucoseUsed\":true,\"wasSuperbolusUsed\":false,\"wasTempTargetUsed\":false,\"wasTrendUsed\":true,\"wereCarbsUsed\":false}",
|
||||
@SerializedName("type") val type: String?, // string "Meal Bolus", "Correction Bolus", "Combo Bolus", "Temp Basal" type of bolus "NORMAL", "SMB", "FAKE_EXTENDED"
|
||||
@SerializedName("isSMB") val isSMB: Boolean, // boolean "Meal Bolus", "Correction Bolus", "Combo Bolus"
|
||||
@SerializedName("enteredinsulin") val enteredinsulin: Double?, // number... "Combo Bolus" insulin is missing only enteredinsulin field found
|
||||
@SerializedName("relative") val relative: Double?, // number... "Combo Bolus", "extendedEmulated" (not in doc see below)
|
||||
@SerializedName("isEmulatingTempBasal") val isEmulatingTempBasal: Boolean, // boolean "Combo Bolus", "extendedEmulated" (not in doc see below)
|
||||
@SerializedName("isAnnouncement") val isAnnouncement: Boolean, // boolean "Announcement"
|
||||
@SerializedName("rate") val rate: Double?, // Double "Temp Basal" absolute rate (could be calculated with percent and profile information...)
|
||||
@SerializedName("extendedEmulated") val extendedEmulated: RemoteTreatment?, // Gson of emulated EB
|
||||
@SerializedName("timeshift") val timeshift: Long, // integer "Profile Switch"
|
||||
@SerializedName("percentage") val percentage: Int?, // integer "Profile Switch"
|
||||
@SerializedName("bolusCalculatorResult") val bolusCalculatorResult: String? = null, // string "Bolus Wizard" json toString ex "bolusCalculatorResult": "{\"basalIOB\":-0.247,\"bolusIOB\":-1.837,\"carbs\":45.0,\"carbsInsulin\":9.0,\"cob\":0.0,\"cobInsulin\":0.0,\"dateCreated\":1626202788810,\"glucoseDifference\":44.0,\"glucoseInsulin\":0.8979591836734694,\"glucoseTrend\":5.5,\"glucoseValue\":134.0,\"ic\":5.0,\"id\":331,\"interfaceIDs_backing\":{\"nightscoutId\":\"60ede2a4c574da0004a3869d\"},\"isValid\":true,\"isf\":49.0,\"note\":\"\",\"otherCorrection\":0.0,\"percentageCorrection\":90,\"profileName\":\"Tuned 13/01 90%Lyum\",\"superbolusInsulin\":0.0,\"targetBGHigh\":90.0,\"targetBGLow\":90.0,\"timestamp\":1626202783325,\"totalInsulin\":7.34,\"trendInsulin\":0.336734693877551,\"utcOffset\":7200000,\"version\":1,\"wasBasalIOBUsed\":true,\"wasBolusIOBUsed\":true,\"wasCOBUsed\":true,\"wasGlucoseUsed\":true,\"wasSuperbolusUsed\":false,\"wasTempTargetUsed\":false,\"wasTrendUsed\":true,\"wereCarbsUsed\":false}",
|
||||
@SerializedName("type") val type: String? = null, // string "Meal Bolus", "Correction Bolus", "Combo Bolus", "Temp Basal" type of bolus "NORMAL", "SMB", "FAKE_EXTENDED"
|
||||
@SerializedName("isSMB") val isSMB: Boolean? = null, // boolean "Meal Bolus", "Correction Bolus", "Combo Bolus"
|
||||
@SerializedName("enteredinsulin") val enteredinsulin: Double? = null, // number... "Combo Bolus" insulin is missing only enteredinsulin field found
|
||||
@SerializedName("relative") val relative: Double? = null, // number... "Combo Bolus", "extendedEmulated" (not in doc see below)
|
||||
@SerializedName("isEmulatingTempBasal") val isEmulatingTempBasal: Boolean? = null, // boolean "Combo Bolus", "extendedEmulated" (not in doc see below)
|
||||
@SerializedName("isAnnouncement") val isAnnouncement: Boolean? = null, // boolean "Announcement"
|
||||
@SerializedName("rate") val rate: Double? = null, // Double "Temp Basal" absolute rate (could be calculated with percent and profile information...)
|
||||
@SerializedName("extendedEmulated") val extendedEmulated: RemoteTreatment? = null, // Gson of emulated EB
|
||||
@SerializedName("timeshift") val timeshift: Long? = null, // integer "Profile Switch"
|
||||
@SerializedName("percentage") val percentage: Int? = null // integer "Profile Switch"
|
||||
) {
|
||||
|
||||
fun timestamp(): Long {
|
||||
return date ?: mills ?: timestamp ?: fromISODateString(created_at)
|
||||
return date ?: mills ?: timestamp ?: created_at?. let { fromISODateString(created_at) } ?: 0L
|
||||
}
|
||||
|
||||
private fun fromISODateString(isoDateString: String): Long =
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package info.nightscout.androidaps.utils.extensions
|
||||
package info.nightscout.core.ui.extensions
|
||||
|
||||
import android.widget.RadioGroup
|
||||
import androidx.appcompat.widget.AppCompatRadioButton
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="48dp"
|
||||
android:height="48dp"
|
||||
android:tint="?attr/defaultTextColor"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="?attr/defaultTextColor"
|
||||
android:pathData="M22,12l-4,-4v3H3v2h15v3z" />
|
||||
</vector>
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 7.2 KiB |
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 7.4 KiB After Width: | Height: | Size: 7.4 KiB |