Merge branch 'nightscout:dev' into dev

This commit is contained in:
Tim Street 2022-06-13 21:12:14 +01:00 committed by GitHub
commit 0b3223d71f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
205 changed files with 2116 additions and 812 deletions

View file

@ -104,12 +104,14 @@ tasks.matching { it instanceof Test }.all {
} }
android { android {
namespace 'info.nightscout.androidaps'
ndkVersion "21.1.6352462" ndkVersion "21.1.6352462"
defaultConfig { defaultConfig {
multiDexEnabled true multiDexEnabled true
versionCode 1500 versionCode 1500
version "3.0.0.2-dev-l" version "3.0.0.2-dev-m"
buildConfigField "String", "VERSION", '"' + version + '"' buildConfigField "String", "VERSION", '"' + version + '"'
buildConfigField "String", "BUILDVERSION", '"' + generateGitBuild() + '-' + generateDate() + '"' buildConfigField "String", "BUILDVERSION", '"' + generateGitBuild() + '-' + generateDate() + '"'
buildConfigField "String", "REMOTE", '"' + generateGitRemote() + '"' buildConfigField "String", "REMOTE", '"' + generateGitRemote() + '"'

View file

@ -1,7 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android">
xmlns:tools="http://schemas.android.com/tools"
package="info.nightscout.androidaps">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH" />
@ -48,7 +46,7 @@
android:restoreAnyVersion="true" android:restoreAnyVersion="true"
android:roundIcon="${appIconRound}" android:roundIcon="${appIconRound}"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/AppTheme.Launcher" > android:theme="@style/AppTheme.Launcher">
<meta-data <meta-data
android:name="com.google.android.gms.version" android:name="com.google.android.gms.version"
@ -65,7 +63,7 @@
<receiver <receiver
android:name=".widget.Widget" android:name=".widget.Widget"
android:exported="true" > android:exported="true">
<intent-filter> <intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter> </intent-filter>
@ -83,69 +81,86 @@
android:name="com.google.android.gms.car.application" android:name="com.google.android.gms.car.application"
android:resource="@xml/automotive_app_desc" /> android:resource="@xml/automotive_app_desc" />
<activity android:name=".MainActivity" <activity
android:theme="@style/AppTheme" android:name=".MainActivity"
android:exported="true"> android:exported="true"
android:theme="@style/AppTheme">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name=".activities.PreferencesActivity" /> <activity
<activity android:name=".plugins.general.overview.activities.QuickWizardListActivity" android:name=".activities.PreferencesActivity"
android:theme="@style/AppTheme" android:exported="false" />
android:exported="false"> <activity
android:name=".plugins.general.overview.activities.QuickWizardListActivity"
android:exported="false"
android:theme="@style/AppTheme">
<intent-filter> <intent-filter>
<action android:name="info.nightscout.androidaps.plugins.general.overview.activities.QuickWizardListActivity" /> <action android:name="info.nightscout.androidaps.plugins.general.overview.activities.QuickWizardListActivity" />
<category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.DEFAULT" />
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name=".plugins.general.maintenance.activities.PrefImportListActivity" <activity
android:name=".plugins.general.maintenance.activities.PrefImportListActivity"
android:exported="false"
android:theme="@style/AppTheme" /> android:theme="@style/AppTheme" />
<activity android:name=".activities.HistoryBrowseActivity" <activity
android:name=".activities.HistoryBrowseActivity"
android:exported="false"
android:theme="@style/AppTheme" /> android:theme="@style/AppTheme" />
<activity android:name=".activities.TreatmentsActivity" <activity
android:name=".activities.TreatmentsActivity"
android:exported="false"
android:theme="@style/AppTheme" /> android:theme="@style/AppTheme" />
<activity android:name=".activities.SurveyActivity" <activity
android:name=".activities.SurveyActivity"
android:exported="false"
android:theme="@style/AppTheme" /> android:theme="@style/AppTheme" />
<activity android:name=".activities.ProfileHelperActivity" <activity
android:name=".activities.ProfileHelperActivity"
android:exported="false"
android:theme="@style/AppTheme" /> android:theme="@style/AppTheme" />
<activity android:name=".activities.StatsActivity" <activity
android:name=".activities.StatsActivity"
android:exported="false"
android:theme="@style/AppTheme" /> android:theme="@style/AppTheme" />
<!-- Receive new BG readings from other local apps --> <!-- Receive new BG readings from other local apps -->
<receiver <receiver
android:name=".receivers.DataReceiver" android:name=".receivers.DataReceiver"
android:enabled="true" android:enabled="true"
android:exported="true"> android:exported="true">
<intent-filter> <intent-filter>
<!-- Receiver from xDrip --> <!-- Receiver from xDrip -->
<action android:name="com.eveningoutpost.dexdrip.BgEstimate"/> <action android:name="com.eveningoutpost.dexdrip.BgEstimate" />
<!-- Receiver from 640g uploader --> <!-- Receiver from 640g uploader -->
<action android:name="com.eveningoutpost.dexdrip.NS_EMULATOR"/> <action android:name="com.eveningoutpost.dexdrip.NS_EMULATOR" />
<!-- Receiver from glimp --> <!-- Receiver from glimp -->
<action android:name="it.ct.glicemia.ACTION_GLUCOSE_MEASURED"/> <action android:name="it.ct.glicemia.ACTION_GLUCOSE_MEASURED" />
<!-- Receiver from Dexcom --> <!-- Receiver from Dexcom -->
<action android:name="com.dexcom.cgm.EXTERNAL_BROADCAST"/> <action android:name="com.dexcom.cgm.EXTERNAL_BROADCAST" />
<!-- Receiver from Poctech --> <!-- Receiver from Poctech -->
<action android:name="com.china.poctech.data"/> <action android:name="com.china.poctech.data" />
<!-- Receiver from Tomato --> <!-- Receiver from Tomato -->
<action android:name="com.fanqies.tomatofn.BgEstimate"/> <action android:name="com.fanqies.tomatofn.BgEstimate" />
<!-- Receiver from GlucoRx Aidex --> <!-- Receiver from GlucoRx Aidex -->
<action android:name="com.microtechmd.cgms.aidex.action.BgEstimate"/> <action android:name="com.microtechmd.cgms.aidex.action.BgEstimate" />
</intent-filter> </intent-filter>
</receiver> </receiver>
<!-- Receive new SMS messages --> <!-- Receive new SMS messages -->
<receiver <receiver
android:name=".receivers.SmsReceiver" android:name=".receivers.SmsReceiver"
android:enabled="true" android:enabled="true"
android:exported="true" android:exported="true"
android:permission="android.permission.BROADCAST_SMS"> android:permission="android.permission.BROADCAST_SMS">
<intent-filter> <intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"/> <action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter> </intent-filter>
</receiver> </receiver>
@ -212,15 +227,23 @@
<activity <activity
android:name=".setupwizard.SetupWizardActivity" android:name=".setupwizard.SetupWizardActivity"
android:configChanges="orientation|keyboardHidden|screenSize" android:configChanges="orientation|keyboardHidden|screenSize"
android:theme="@style/AppTheme" android:exported="false"
android:label="@string/title_activity_setup_wizard" /> android:label="@string/title_activity_setup_wizard"
android:theme="@style/AppTheme" />
<activity <activity
android:name=".activities.SingleFragmentActivity" android:name=".activities.SingleFragmentActivity"
android:exported="false"
android:theme="@style/AppTheme" /> android:theme="@style/AppTheme" />
<activity android:name=".plugins.general.maintenance.activities.LogSettingActivity" /> <activity
<activity android:name=".activities.RequestDexcomPermissionActivity" /> android:name=".plugins.general.maintenance.activities.LogSettingActivity"
<activity android:name=".plugins.general.smsCommunicator.activities.SmsCommunicatorOtpActivity"> android:exported="false" />
<activity
android:name=".activities.RequestDexcomPermissionActivity"
android:exported="false" />
<activity
android:name=".plugins.general.smsCommunicator.activities.SmsCommunicatorOtpActivity"
android:exported="false">
<intent-filter> <intent-filter>
<action android:name="info.nightscout.androidaps.plugins.general.smsCommunicator.activities.SmsCommunicatorOtpActivity" /> <action android:name="info.nightscout.androidaps.plugins.general.smsCommunicator.activities.SmsCommunicatorOtpActivity" />
@ -228,7 +251,9 @@
</intent-filter> </intent-filter>
</activity> </activity>
<uses-library android:name="org.apache.http.legacy" android:required="false"/> <uses-library
android:name="org.apache.http.legacy"
android:required="false" />
</application> </application>

View file

@ -324,7 +324,7 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_
rT.reason += ", but Min. Delta " + minDelta.toFixed(2) + " > Exp. Delta " + expectedDelta; rT.reason += ", but Min. Delta " + minDelta.toFixed(2) + " > Exp. Delta " + expectedDelta;
} }
if (currenttemp.duration > 15 && (round_basal(basal, profile) === round_basal(currenttemp.rate, profile))) { if (currenttemp.duration > 15 && (round_basal(basal, profile) === round_basal(currenttemp.rate, profile))) {
rT.reason += ", temp " + currenttemp.rate + " ~ req " + basal + "U/hr"; rT.reason += ", temp " + currenttemp.rate + " ~ req " + round(basal, 2) + "U/hr";
return rT; return rT;
} else { } else {
rT.reason += "; setting current basal of " + round(basal, 2) + " as temp"; rT.reason += "; setting current basal of " + round(basal, 2) + " as temp";
@ -367,10 +367,10 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_
return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp);
} }
if (typeof currenttemp.rate !== 'undefined' && (currenttemp.duration > 5 && rate >= currenttemp.rate * 0.8)) { if (typeof currenttemp.rate !== 'undefined' && (currenttemp.duration > 5 && rate >= currenttemp.rate * 0.8)) {
rT.reason += ", temp " + currenttemp.rate + " ~< req " + rate + "U/hr"; rT.reason += ", temp " + (currenttemp.rate).toFixed(3) + " ~< req " + round(rate, 2) + "U/hr";
return rT; return rT;
} else { } else {
rT.reason += ", setting " + rate + "U/hr"; rT.reason += ", setting " + round(rate, 2) + "U/hr";
return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp);
} }
} }
@ -476,22 +476,22 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_
var insulinScheduled = currenttemp.duration * (currenttemp.rate - basal) / 60; var insulinScheduled = currenttemp.duration * (currenttemp.rate - basal) / 60;
if (insulinScheduled >= insulinReq * 2) { // if current temp would deliver >2x more than the required insulin, lower the rate if (insulinScheduled >= insulinReq * 2) { // if current temp would deliver >2x more than the required insulin, lower the rate
rT.reason += currenttemp.duration + "m@" + (currenttemp.rate - basal).toFixed(3) + " = " + insulinScheduled.toFixed(3) + " > 2 * req " + insulinReq + ". Setting temp basal of " + rate + "U/hr"; rT.reason += currenttemp.duration + "m@" + (currenttemp.rate - basal).toFixed(3) + " = " + insulinScheduled.toFixed(3) + " > 2 * req " + insulinReq + ". Setting temp basal of " + round(rate, 2) + "U/hr";
return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp);
} }
if (typeof currenttemp.duration == 'undefined' || currenttemp.duration == 0) { // no temp is set if (typeof currenttemp.duration == 'undefined' || currenttemp.duration == 0) { // no temp is set
rT.reason += "no temp, setting " + rate + "U/hr"; rT.reason += "no temp, setting " + round(rate, 2) + "U/hr";
return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp);
} }
if (currenttemp.duration > 5 && (round_basal(rate, profile) <= round_basal(currenttemp.rate, profile))) { // if required temp <~ existing temp basal if (currenttemp.duration > 5 && (round_basal(rate, profile) <= round_basal(currenttemp.rate, profile))) { // if required temp <~ existing temp basal
rT.reason += "temp " + currenttemp.rate + " >~ req " + rate + "U/hr"; rT.reason += "temp " + (currenttemp.rate).toFixed(3) + " >~ req " + round(rate, 2) + "U/hr";
return rT; return rT;
} }
// required temp > existing temp basal // required temp > existing temp basal
rT.reason += "temp " + currenttemp.rate + "<" + rate + "U/hr"; rT.reason += "temp " + (currenttemp.rate).toFixed(3) + " < " + round(rate, 2) + "U/hr";
return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp);
} }

View file

@ -955,7 +955,7 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_
return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp);
} }
if (typeof currenttemp.rate !== 'undefined' && (currenttemp.duration > 5 && rate >= currenttemp.rate * 0.8)) { if (typeof currenttemp.rate !== 'undefined' && (currenttemp.duration > 5 && rate >= currenttemp.rate * 0.8)) {
rT.reason += ", temp " + currenttemp.rate + " ~< req " + rate + "U/hr. "; rT.reason += ", temp " + currenttemp.rate + " ~< req " + round(rate, 2) + "U/hr. ";
return rT; return rT;
} else { } else {
// calculate a long enough zero temp to eventually correct back up to target // calculate a long enough zero temp to eventually correct back up to target
@ -976,7 +976,7 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_
return tempBasalFunctions.setTempBasal(rate, durationReq, profile, rT, currenttemp); return tempBasalFunctions.setTempBasal(rate, durationReq, profile, rT, currenttemp);
} }
} else { } else {
rT.reason += ", setting " + rate + "U/hr. "; rT.reason += ", setting " + round(rate, 2) + "U/hr. ";
} }
return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp);
} }
@ -1143,22 +1143,22 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_
insulinScheduled = currenttemp.duration * (currenttemp.rate - basal) / 60; insulinScheduled = currenttemp.duration * (currenttemp.rate - basal) / 60;
if (insulinScheduled >= insulinReq * 2) { // if current temp would deliver >2x more than the required insulin, lower the rate if (insulinScheduled >= insulinReq * 2) { // if current temp would deliver >2x more than the required insulin, lower the rate
rT.reason += currenttemp.duration + "m@" + (currenttemp.rate).toFixed(2) + " > 2 * insulinReq. Setting temp basal of " + rate + "U/hr. "; rT.reason += currenttemp.duration + "m@" + (currenttemp.rate).toFixed(2) + " > 2 * insulinReq. Setting temp basal of " + round(rate, 2) + "U/hr. ";
return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp);
} }
if (typeof currenttemp.duration === 'undefined' || currenttemp.duration === 0) { // no temp is set if (typeof currenttemp.duration === 'undefined' || currenttemp.duration === 0) { // no temp is set
rT.reason += "no temp, setting " + rate + "U/hr. "; rT.reason += "no temp, setting " + round(rate, 2) + "U/hr. ";
return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp);
} }
if (currenttemp.duration > 5 && (round_basal(rate, profile) <= round_basal(currenttemp.rate, profile))) { // if required temp <~ existing temp basal if (currenttemp.duration > 5 && (round_basal(rate, profile) <= round_basal(currenttemp.rate, profile))) { // if required temp <~ existing temp basal
rT.reason += "temp " + currenttemp.rate + " >~ req " + rate + "U/hr. "; rT.reason += "temp " + (currenttemp.rate).toFixed(2) + " >~ req " + round(rate, 2) + "U/hr. ";
return rT; return rT;
} }
// required temp > existing temp basal // required temp > existing temp basal
rT.reason += "temp " + currenttemp.rate + "<" + rate + "U/hr. "; rT.reason += "temp " + (currenttemp.rate).toFixed(2) + " < " + round(rate, 2) + "U/hr. ";
return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp);
} }

View file

@ -1317,22 +1317,22 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_
insulinScheduled = currenttemp.duration * (currenttemp.rate - basal) / 60; insulinScheduled = currenttemp.duration * (currenttemp.rate - basal) / 60;
if (insulinScheduled >= insulinReq * 2) { // if current temp would deliver >2x more than the required insulin, lower the rate if (insulinScheduled >= insulinReq * 2) { // if current temp would deliver >2x more than the required insulin, lower the rate
rT.reason += currenttemp.duration + "m@" + (currenttemp.rate).toFixed(2) + " > 2 * insulinReq. Setting temp basal of " + rate + "U/hr. "; rT.reason += currenttemp.duration + "m@" + (currenttemp.rate).toFixed(2) + " > 2 * insulinReq. Setting temp basal of " + round(rate, 2) + "U/hr. ";
return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp);
} }
if (typeof currenttemp.duration === 'undefined' || currenttemp.duration === 0) { // no temp is set if (typeof currenttemp.duration === 'undefined' || currenttemp.duration === 0) { // no temp is set
rT.reason += "no temp, setting " + rate + "U/hr. "; rT.reason += "no temp, setting " + round(rate, 2) + "U/hr. ";
return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp);
} }
if (currenttemp.duration > 5 && (round_basal(rate, profile) <= round_basal(currenttemp.rate, profile))) { // if required temp <~ existing temp basal if (currenttemp.duration > 5 && (round_basal(rate, profile) <= round_basal(currenttemp.rate, profile))) { // if required temp <~ existing temp basal
rT.reason += "temp " + currenttemp.rate + " >~ req " + rate + "U/hr. "; rT.reason += "temp " + (currenttemp.rate).toFixed(2) + " >~ req " + round(rate, 2) + "U/hr. ";
return rT; return rT;
} }
// required temp > existing temp basal // required temp > existing temp basal
rT.reason += "temp " + currenttemp.rate + "<" + rate + "U/hr. "; rT.reason += "temp " + (currenttemp.rate).toFixed(2) + " < " + round(rate, 2) + "U/hr. ";
return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp); return tempBasalFunctions.setTempBasal(rate, 30, profile, rT, currenttemp);
} }

View file

@ -39,7 +39,6 @@ import info.nightscout.androidaps.events.EventPreferenceChange
import info.nightscout.androidaps.events.EventRebuildTabs import info.nightscout.androidaps.events.EventRebuildTabs
import info.nightscout.androidaps.interfaces.* import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
import info.nightscout.androidaps.plugins.constraints.signatureVerifier.SignatureVerifierPlugin import info.nightscout.androidaps.plugins.constraints.signatureVerifier.SignatureVerifierPlugin
import info.nightscout.androidaps.plugins.constraints.versionChecker.VersionCheckerUtils import info.nightscout.androidaps.plugins.constraints.versionChecker.VersionCheckerUtils
@ -49,7 +48,7 @@ import info.nightscout.androidaps.setupwizard.SetupWizardActivity
import info.nightscout.androidaps.utils.AndroidPermission import info.nightscout.androidaps.utils.AndroidPermission
import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.androidaps.utils.extensions.isRunningRealPumpTest import info.nightscout.androidaps.utils.extensions.isRunningRealPumpTest
import info.nightscout.androidaps.utils.locale.LocaleHelper import info.nightscout.androidaps.utils.locale.LocaleHelper
import info.nightscout.androidaps.utils.protection.PasswordCheck import info.nightscout.androidaps.utils.protection.PasswordCheck

View file

@ -43,7 +43,7 @@ import info.nightscout.androidaps.utils.ActivityMonitor
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.LocalAlertUtils import info.nightscout.androidaps.utils.LocalAlertUtils
import info.nightscout.androidaps.utils.ProcessLifecycleListener import info.nightscout.androidaps.utils.ProcessLifecycleListener
import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.androidaps.utils.locale.LocaleHelper import info.nightscout.androidaps.utils.locale.LocaleHelper
import info.nightscout.androidaps.widget.updateWidget import info.nightscout.androidaps.widget.updateWidget
import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.AAPSLogger
@ -249,7 +249,7 @@ class MainApp : DaggerApplication() {
override fun onTerminate() { override fun onTerminate() {
aapsLogger.debug(LTag.CORE, "onTerminate") aapsLogger.debug(LTag.CORE, "onTerminate")
unregisterActivityLifecycleCallbacks(activityMonitor) unregisterActivityLifecycleCallbacks(activityMonitor)
alarmSoundServiceHelper.stopService(this) alarmSoundServiceHelper.stopService(this, "onTerminate")
super.onTerminate() super.onTerminate()
} }
} }

View file

@ -37,7 +37,7 @@ import info.nightscout.androidaps.utils.DefaultValueHelper
import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.Translator import info.nightscout.androidaps.utils.Translator
import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.androidaps.workflow.CalculationWorkflow import info.nightscout.androidaps.workflow.CalculationWorkflow
import info.nightscout.shared.logging.LTag import info.nightscout.shared.logging.LTag

View file

@ -11,7 +11,7 @@ import info.nightscout.androidaps.activities.fragments.*
import info.nightscout.androidaps.databinding.TreatmentsFragmentBinding import info.nightscout.androidaps.databinding.TreatmentsFragmentBinding
import info.nightscout.androidaps.extensions.toVisibility import info.nightscout.androidaps.extensions.toVisibility
import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.interfaces.BuildHelper
import javax.inject.Inject import javax.inject.Inject
class TreatmentsActivity : NoSplashAppCompatActivity() { class TreatmentsActivity : NoSplashAppCompatActivity() {

View file

@ -40,7 +40,7 @@ import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.ToastUtils import info.nightscout.androidaps.utils.ToastUtils
import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag import info.nightscout.shared.logging.LTag

View file

@ -25,7 +25,7 @@ import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart
import info.nightscout.androidaps.utils.* import info.nightscout.androidaps.utils.*
import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.AAPSLogger

View file

@ -36,7 +36,7 @@ import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.ToastUtils import info.nightscout.androidaps.utils.ToastUtils
import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.AAPSLogger

View file

@ -35,7 +35,7 @@ import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientR
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryData import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryData
import info.nightscout.androidaps.utils.* import info.nightscout.androidaps.utils.*
import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag import info.nightscout.shared.logging.LTag

View file

@ -28,7 +28,7 @@ import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.HardLimits import info.nightscout.androidaps.utils.HardLimits
import info.nightscout.androidaps.utils.androidNotification.NotificationHolderImpl import info.nightscout.androidaps.utils.androidNotification.NotificationHolderImpl
import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.androidaps.utils.buildHelper.BuildHelperImpl import info.nightscout.androidaps.utils.buildHelper.BuildHelperImpl
import info.nightscout.androidaps.utils.buildHelper.ConfigImpl import info.nightscout.androidaps.utils.buildHelper.ConfigImpl
import info.nightscout.androidaps.utils.resources.IconsProviderImplementation import info.nightscout.androidaps.utils.resources.IconsProviderImplementation

View file

@ -3,6 +3,8 @@ package info.nightscout.androidaps.dialogs
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.os.Handler
import android.os.HandlerThread
import android.text.Editable import android.text.Editable
import android.text.TextWatcher import android.text.TextWatcher
import android.view.LayoutInflater import android.view.LayoutInflater
@ -24,6 +26,7 @@ import info.nightscout.androidaps.database.ValueWrapper
import info.nightscout.androidaps.databinding.DialogWizardBinding import info.nightscout.androidaps.databinding.DialogWizardBinding
import info.nightscout.androidaps.events.EventAutosensCalculationFinished import info.nightscout.androidaps.events.EventAutosensCalculationFinished
import info.nightscout.androidaps.extensions.formatColor import info.nightscout.androidaps.extensions.formatColor
import info.nightscout.androidaps.extensions.runOnUiThread
import info.nightscout.androidaps.extensions.toVisibility import info.nightscout.androidaps.extensions.toVisibility
import info.nightscout.androidaps.extensions.valueToUnits import info.nightscout.androidaps.extensions.valueToUnits
import info.nightscout.androidaps.interfaces.* import info.nightscout.androidaps.interfaces.*
@ -63,6 +66,8 @@ class WizardDialog : DaggerDialogFragment() {
@Inject lateinit var dateUtil: DateUtil @Inject lateinit var dateUtil: DateUtil
@Inject lateinit var protectionCheck: ProtectionCheck @Inject lateinit var protectionCheck: ProtectionCheck
private val handler = Handler(HandlerThread(this::class.simpleName + "Handler").also { it.start() }.looper)
private var queryingProtection = false private var queryingProtection = false
private var wizard: BolusWizard? = null private var wizard: BolusWizard? = null
private var calculatedPercentage = 100.0 private var calculatedPercentage = 100.0
@ -168,7 +173,7 @@ class WizardDialog : DaggerDialogFragment() {
savedInstanceState?.getDouble("carb_time_input") savedInstanceState?.getDouble("carb_time_input")
?: 0.0, -60.0, 60.0, 5.0, DecimalFormat("0"), false, binding.okcancel.ok, timeTextWatcher ?: 0.0, -60.0, 60.0, 5.0, DecimalFormat("0"), false, binding.okcancel.ok, timeTextWatcher
) )
initDialog() handler.post { initDialog() }
calculatedPercentage = sp.getInt(R.string.key_boluswizard_percentage, 100).toDouble() calculatedPercentage = sp.getInt(R.string.key_boluswizard_percentage, 100).toDouble()
binding.percentUsed.text = rh.gs(R.string.format_percent, sp.getInt(R.string.key_boluswizard_percentage, 100)) binding.percentUsed.text = rh.gs(R.string.format_percent, sp.getInt(R.string.key_boluswizard_percentage, 100))
// ok button // ok button
@ -257,6 +262,7 @@ class WizardDialog : DaggerDialogFragment() {
override fun onDestroyView() { override fun onDestroyView() {
super.onDestroyView() super.onDestroyView()
disposable.clear() disposable.clear()
handler.removeCallbacksAndMessages(null)
_binding = null _binding = null
} }
@ -323,14 +329,9 @@ class WizardDialog : DaggerDialogFragment() {
else DecimalFormatter.to1Decimal(value * Constants.MGDL_TO_MMOLL) else DecimalFormatter.to1Decimal(value * Constants.MGDL_TO_MMOLL)
private fun initDialog() { private fun initDialog() {
if (carbsPassedIntoWizard != 0.0) {
binding.carbsInput.value = carbsPassedIntoWizard
}
if (notesPassedIntoWizard.isNotBlank()) {
binding.notesLayout.notes.setText(notesPassedIntoWizard)
}
val profile = profileFunction.getProfile() val profile = profileFunction.getProfile()
val profileStore = activePlugin.activeProfileSource.profile val profileStore = activePlugin.activeProfileSource.profile
val tempTarget = repository.getTemporaryTargetActiveAt(dateUtil.now()).blockingGet()
if (profile == null || profileStore == null) { if (profile == null || profileStore == null) {
ToastUtils.showToastInUiThread(ctx, rh.gs(R.string.noprofile)) ToastUtils.showToastInUiThread(ctx, rh.gs(R.string.noprofile))
@ -338,32 +339,40 @@ class WizardDialog : DaggerDialogFragment() {
return return
} }
val profileList: ArrayList<CharSequence> = profileStore.getProfileList()
profileList.add(0, rh.gs(R.string.active))
context?.let { context ->
binding.profileList.setAdapter(ArrayAdapter(context, R.layout.spinner_centered, profileList))
binding.profileList.setText(profileList[0], false)
}
val units = profileFunction.getUnits()
binding.bgUnits.text = units.asText
binding.bgInput.step = if (units == GlucoseUnit.MGDL) 1.0 else 0.1
// Set BG if not old
binding.bgInput.value = iobCobCalculator.ads.actualBg()?.valueToUnits(units) ?: 0.0
binding.ttCheckbox.isEnabled = repository.getTemporaryTargetActiveAt(dateUtil.now()).blockingGet() is ValueWrapper.Existing
binding.ttCheckboxIcon.visibility = binding.ttCheckbox.isEnabled.toVisibility()
// IOB calculation // IOB calculation
val bolusIob = iobCobCalculator.calculateIobFromBolus().round() val bolusIob = iobCobCalculator.calculateIobFromBolus().round()
val basalIob = iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended().round() val basalIob = iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended().round()
binding.iobInsulin.text = rh.gs(R.string.formatinsulinunits, -bolusIob.iob - basalIob.basaliob) runOnUiThread {
if (carbsPassedIntoWizard != 0.0) {
binding.carbsInput.value = carbsPassedIntoWizard
}
if (notesPassedIntoWizard.isNotBlank()) {
binding.notesLayout.notes.setText(notesPassedIntoWizard)
}
calculateInsulin() val profileList: ArrayList<CharSequence> = profileStore.getProfileList()
profileList.add(0, rh.gs(R.string.active))
context?.let { context ->
binding.profileList.setAdapter(ArrayAdapter(context, R.layout.spinner_centered, profileList))
binding.profileList.setText(profileList[0], false)
}
binding.percentUsed.visibility = (sp.getInt(R.string.key_boluswizard_percentage, 100) != 100 || correctionPercent).toVisibility() val units = profileFunction.getUnits()
binding.bgUnits.text = units.asText
binding.bgInput.step = if (units == GlucoseUnit.MGDL) 1.0 else 0.1
// Set BG if not old
binding.bgInput.value = iobCobCalculator.ads.actualBg()?.valueToUnits(units) ?: 0.0
binding.ttCheckbox.isEnabled = tempTarget is ValueWrapper.Existing
binding.ttCheckboxIcon.visibility = binding.ttCheckbox.isEnabled.toVisibility()
binding.iobInsulin.text = rh.gs(R.string.formatinsulinunits, -bolusIob.iob - basalIob.basaliob)
calculateInsulin()
binding.percentUsed.visibility = (sp.getInt(R.string.key_boluswizard_percentage, 100) != 100 || correctionPercent).toVisibility()
}
} }
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
@ -496,7 +505,7 @@ class WizardDialog : DaggerDialogFragment() {
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
if(!queryingProtection) { if (!queryingProtection) {
queryingProtection = true queryingProtection = true
activity?.let { activity -> activity?.let { activity ->
val cancelFail = { val cancelFail = {

View file

@ -60,7 +60,7 @@ class WizardInfoDialog : DaggerDialogFragment() {
override fun onSaveInstanceState(outState: Bundle) { override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState) super.onSaveInstanceState(outState)
outState.putString("data", data.toJson(true, dateUtil).toString()) outState.putString("data", data.toJson(true, dateUtil, profileFunction).toString())
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {

View file

@ -17,7 +17,7 @@ import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProv
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.HardLimits import info.nightscout.androidaps.utils.HardLimits
import info.nightscout.androidaps.utils.Profiler import info.nightscout.androidaps.utils.Profiler
import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP

View file

@ -23,7 +23,7 @@ import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.configBuilder.events.EventConfigBuilderUpdateGui import info.nightscout.androidaps.plugins.configBuilder.events.EventConfigBuilderUpdateGui
import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.androidaps.utils.protection.ProtectionCheck import info.nightscout.androidaps.utils.protection.ProtectionCheck
import info.nightscout.androidaps.utils.protection.ProtectionCheck.Protection.PREFERENCES import info.nightscout.androidaps.utils.protection.ProtectionCheck.Protection.PREFERENCES
import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.interfaces.ResourceHelper

View file

@ -19,7 +19,7 @@ import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.DecimalFormatter import info.nightscout.androidaps.utils.DecimalFormatter
import info.nightscout.androidaps.utils.HardLimits import info.nightscout.androidaps.utils.HardLimits
import info.nightscout.androidaps.utils.Round import info.nightscout.androidaps.utils.Round
import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP
import org.json.JSONObject import org.json.JSONObject

View file

@ -39,7 +39,7 @@ import info.nightscout.androidaps.skins.SkinProvider
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.androidaps.utils.protection.ProtectionCheck import info.nightscout.androidaps.utils.protection.ProtectionCheck
import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.AapsSchedulers

View file

@ -28,9 +28,9 @@ class AutotuneCore @Inject constructor(
//console.error(isf); //console.error(isf);
var carbRatio = previousAutotune.ic var carbRatio = previousAutotune.ic
//console.error(carbRatio); //console.error(carbRatio);
var csf = isf / carbRatio val csf = isf / carbRatio
var dia = previousAutotune.dia val dia = previousAutotune.dia
var peak = previousAutotune.peak val peak = previousAutotune.peak
val csfGlucose = preppedGlucose.csfGlucoseData val csfGlucose = preppedGlucose.csfGlucoseData
val isfGlucose = preppedGlucose.isfGlucoseData val isfGlucose = preppedGlucose.isfGlucoseData
val basalGlucose = preppedGlucose.basalGlucoseData val basalGlucose = preppedGlucose.basalGlucoseData

View file

@ -1,5 +1,6 @@
package info.nightscout.androidaps.plugins.general.autotune package info.nightscout.androidaps.plugins.general.autotune
import android.graphics.Paint
import android.graphics.Typeface import android.graphics.Typeface
import android.os.Bundle import android.os.Bundle
import android.text.Editable import android.text.Editable
@ -79,7 +80,8 @@ class AutotuneFragment : DaggerFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
sp.putBoolean(R.string.key_autotune_tune_insulin_curve, false) // put to false tune insulin curve sp.putBoolean(R.string.key_autotune_tune_insulin_curve, false) // put to false tune insulin curve
autotunePlugin.lastRun = sp.getLong(R.string.key_autotune_last_run, 0) sp.putBoolean(R.string.key_autotune_additional_log, false) // put to false additional log
autotunePlugin.loadLastRun()
if (autotunePlugin.lastNbDays.isEmpty()) if (autotunePlugin.lastNbDays.isEmpty())
autotunePlugin.lastNbDays = sp.getInt(R.string.key_autotune_default_tune_days, 5).toString() autotunePlugin.lastNbDays = sp.getInt(R.string.key_autotune_default_tune_days, 5).toString()
val defaultValue = sp.getInt(R.string.key_autotune_default_tune_days, 5).toDouble() val defaultValue = sp.getInt(R.string.key_autotune_default_tune_days, 5).toDouble()
@ -144,6 +146,7 @@ class AutotuneFragment : DaggerFragment() {
autotunePlugin.tunedProfile?.profilename = localName autotunePlugin.tunedProfile?.profilename = localName
autotunePlugin.updateProfile(autotunePlugin.tunedProfile) autotunePlugin.updateProfile(autotunePlugin.tunedProfile)
autotunePlugin.updateButtonVisibility = View.GONE autotunePlugin.updateButtonVisibility = View.GONE
autotunePlugin.saveLastRun()
uel.log( uel.log(
UserEntry.Action.STORE_PROFILE, UserEntry.Action.STORE_PROFILE,
UserEntry.Sources.Autotune, UserEntry.Sources.Autotune,
@ -163,6 +166,7 @@ class AutotuneFragment : DaggerFragment() {
autotunePlugin.tunedProfile?.profilename = "" autotunePlugin.tunedProfile?.profilename = ""
autotunePlugin.updateProfile(autotunePlugin.pumpProfile) autotunePlugin.updateProfile(autotunePlugin.pumpProfile)
autotunePlugin.updateButtonVisibility = View.VISIBLE autotunePlugin.updateButtonVisibility = View.VISIBLE
autotunePlugin.saveLastRun()
uel.log( uel.log(
UserEntry.Action.STORE_PROFILE, UserEntry.Action.STORE_PROFILE,
UserEntry.Sources.Autotune, UserEntry.Sources.Autotune,
@ -251,6 +255,14 @@ class AutotuneFragment : DaggerFragment() {
} }
} }
} }
binding.tuneLastrun.setOnClickListener {
if (!autotunePlugin.calculationRunning) {
autotunePlugin.loadLastRun()
updateGui()
}
}
binding.tuneLastrun.paintFlags = binding.tuneLastrun.paintFlags or Paint.UNDERLINE_TEXT_FLAG
} }
@Synchronized @Synchronized
@ -263,7 +275,6 @@ class AutotuneFragment : DaggerFragment() {
updateGui() updateGui()
}, { fabricPrivacy.logException(it) }) }, { fabricPrivacy.logException(it) })
checkNewDay() checkNewDay()
binding.tuneDays.value = autotunePlugin.lastNbDays.toDouble()
updateGui() updateGui()
} }
@ -276,6 +287,7 @@ class AutotuneFragment : DaggerFragment() {
@Synchronized @Synchronized
private fun updateGui() { private fun updateGui() {
_binding ?: return _binding ?: return
binding.tuneDays.value = autotunePlugin.lastNbDays.toDouble()
profileStore = activePlugin.activeProfileSource.profile ?: ProfileStore(injector, JSONObject(), dateUtil) profileStore = activePlugin.activeProfileSource.profile ?: ProfileStore(injector, JSONObject(), dateUtil)
profileName = if (binding.profileList.text.toString() == rh.gs(R.string.active)) "" else binding.profileList.text.toString() profileName = if (binding.profileList.text.toString() == rh.gs(R.string.active)) "" else binding.profileList.text.toString()
profileFunction.getProfile()?.let { currentProfile -> profileFunction.getProfile()?.let { currentProfile ->

View file

@ -7,6 +7,7 @@ import info.nightscout.androidaps.data.LocalInsulin
import info.nightscout.androidaps.data.ProfileSealed import info.nightscout.androidaps.data.ProfileSealed
import info.nightscout.androidaps.database.entities.UserEntry import info.nightscout.androidaps.database.entities.UserEntry
import info.nightscout.androidaps.database.entities.ValueWithUnit import info.nightscout.androidaps.database.entities.ValueWithUnit
import info.nightscout.androidaps.extensions.pureProfileFromJson
import info.nightscout.androidaps.interfaces.* import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.bus.RxBus
@ -16,9 +17,10 @@ import info.nightscout.androidaps.plugins.general.autotune.events.EventAutotuneU
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin
import info.nightscout.androidaps.plugins.profile.local.events.EventLocalProfileChanged import info.nightscout.androidaps.plugins.profile.local.events.EventLocalProfileChanged
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.JsonHelper
import info.nightscout.androidaps.utils.MidnightTime import info.nightscout.androidaps.utils.MidnightTime
import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP
import org.json.JSONException import org.json.JSONException
@ -48,7 +50,7 @@ class AutotunePlugin @Inject constructor(
private val autotuneIob: AutotuneIob, private val autotuneIob: AutotuneIob,
private val autotunePrep: AutotunePrep, private val autotunePrep: AutotunePrep,
private val autotuneCore: AutotuneCore, private val autotuneCore: AutotuneCore,
private val buildHelper:BuildHelper, private val buildHelper: BuildHelper,
private val uel: UserEntryLogger, private val uel: UserEntryLogger,
aapsLogger: AAPSLogger aapsLogger: AAPSLogger
) : PluginBase(PluginDescription() ) : PluginBase(PluginDescription()
@ -115,37 +117,39 @@ class AutotunePlugin @Inject constructor(
val from = starttime + i * 24 * 60 * 60 * 1000L // get 24 hours BG values from 4 AM to 4 AM next day val from = starttime + i * 24 * 60 * 60 * 1000L // get 24 hours BG values from 4 AM to 4 AM next day
val to = from + 24 * 60 * 60 * 1000L val to = from + 24 * 60 * 60 * 1000L
log("Tune day " + (i + 1) + " of " + daysBack) log("Tune day " + (i + 1) + " of " + daysBack)
tunedProfile?.let { tunedProfile -> tunedProfile?.let { it ->
autotuneIob.initializeData(from, to, tunedProfile) //autotuneIob contains BG and Treatments data from history (<=> query for ns-treatments and ns-entries) autotuneIob.initializeData(from, to, it) //autotuneIob contains BG and Treatments data from history (<=> query for ns-treatments and ns-entries)
autotuneFS.exportEntries(autotuneIob) //<=> ns-entries.yyyymmdd.json files exported for results compare with oref0 autotune on virtual machine autotuneFS.exportEntries(autotuneIob) //<=> ns-entries.yyyymmdd.json files exported for results compare with oref0 autotune on virtual machine
autotuneFS.exportTreatments(autotuneIob) //<=> ns-treatments.yyyymmdd.json files exported for results compare with oref0 autotune on virtual machine (include treatments ,tempBasal and extended autotuneFS.exportTreatments(autotuneIob) //<=> ns-treatments.yyyymmdd.json files exported for results compare with oref0 autotune on virtual machine (include treatments ,tempBasal and extended
preppedGlucose = autotunePrep.categorize(tunedProfile) //<=> autotune.yyyymmdd.json files exported for results compare with oref0 autotune on virtual machine preppedGlucose = autotunePrep.categorize(it) //<=> autotune.yyyymmdd.json files exported for results compare with oref0 autotune on virtual machine
preppedGlucose?.let { preppedGlucose ->
autotuneFS.exportPreppedGlucose(preppedGlucose)
tunedProfile = autotuneCore.tuneAllTheThings(preppedGlucose, it, pumpProfile).also { tunedProfile ->
autotuneFS.exportTunedProfile(tunedProfile) //<=> newprofile.yyyymmdd.json files exported for results compare with oref0 autotune on virtual machine
if (i < daysBack - 1) {
log("Partial result for day ${i + 1}".trimIndent())
result = rh.gs(R.string.autotune_partial_result, i + 1, daysBack)
rxBus.send(EventAutotuneUpdateGui())
}
logResult = showResults(tunedProfile, pumpProfile)
if (detailedLog)
autotuneFS.exportLog(lastRun, i + 1)
}
}
?: {
log("preppedGlucose is null on day ${i + 1}")
tunedProfile = null
}
} }
if (tunedProfile == null) {
if (preppedGlucose == null || tunedProfile == null) {
result = rh.gs(R.string.autotune_error) result = rh.gs(R.string.autotune_error)
log(result) log("TunedProfile is null on day ${i + 1}")
calculationRunning = false calculationRunning = false
rxBus.send(EventAutotuneUpdateGui()) rxBus.send(EventAutotuneUpdateGui())
tunedProfile = null
autotuneFS.exportResult(result) autotuneFS.exportResult(result)
autotuneFS.exportLogAndZip(lastRun) autotuneFS.exportLogAndZip(lastRun)
return result return result
} }
preppedGlucose?.let { preppedGlucose -> //preppedGlucose and tunedProfile should never be null here
autotuneFS.exportPreppedGlucose(preppedGlucose)
tunedProfile = autotuneCore.tuneAllTheThings(preppedGlucose, tunedProfile!!, pumpProfile)
}
// localInsulin = LocalInsulin("TunedInsulin", tunedProfile!!.peak, tunedProfile!!.dia) // Todo: Add tune Insulin option
autotuneFS.exportTunedProfile(tunedProfile!!) //<=> newprofile.yyyymmdd.json files exported for results compare with oref0 autotune on virtual machine
if (i < daysBack - 1) {
log("Partial result for day ${i + 1}".trimIndent())
result = rh.gs(R.string.autotune_partial_result, i + 1, daysBack)
rxBus.send(EventAutotuneUpdateGui())
}
logResult = showResults(tunedProfile, pumpProfile)
if (detailedLog)
autotuneFS.exportLog(lastRun, i + 1)
} }
result = rh.gs(R.string.autotune_result, dateUtil.dateAndTimeString(lastRun)) result = rh.gs(R.string.autotune_result, dateUtil.dateAndTimeString(lastRun))
if (!detailedLog) if (!detailedLog)
@ -161,7 +165,8 @@ class AutotunePlugin @Inject constructor(
updateProfile(tunedP) updateProfile(tunedP)
uel.log( uel.log(
UserEntry.Action.STORE_PROFILE, UserEntry.Action.STORE_PROFILE,
UserEntry.Sources.Autotune, UserEntry.Sources.Automation,
rh.gs(R.string.autotune),
ValueWithUnit.SimpleString(tunedP.profilename) ValueWithUnit.SimpleString(tunedP.profilename)
) )
updateButtonVisibility = View.GONE updateButtonVisibility = View.GONE
@ -178,22 +183,23 @@ class AutotunePlugin @Inject constructor(
log("Profile Switch succeed ${tunedP.profilename}") log("Profile Switch succeed ${tunedP.profilename}")
uel.log( uel.log(
UserEntry.Action.PROFILE_SWITCH, UserEntry.Action.PROFILE_SWITCH,
UserEntry.Sources.Autotune, UserEntry.Sources.Automation,
"Autotune AutoSwitch", rh.gs(R.string.autotune),
ValueWithUnit.SimpleString(tunedP.profilename)) ValueWithUnit.SimpleString(tunedP.profilename))
} }
rxBus.send(EventLocalProfileChanged()) rxBus.send(EventLocalProfileChanged())
} }
} }
} }
lastRunSuccess = true
sp.putLong(R.string.key_autotune_last_run, lastRun)
rxBus.send(EventAutotuneUpdateGui())
calculationRunning = false
tunedProfile?.let { tunedProfile?.let {
lastRunSuccess = true
saveLastRun()
rxBus.send(EventAutotuneUpdateGui())
calculationRunning = false
return result return result
} }
return "No Result" // should never occurs return rh.gs(R.string.autotune_error)
} }
private fun showResults(tunedProfile: ATProfile?, pumpProfile: ATProfile): String { private fun showResults(tunedProfile: ATProfile?, pumpProfile: ATProfile): String {
@ -296,6 +302,64 @@ class AutotunePlugin @Inject constructor(
localProfilePlugin.storeSettings() localProfilePlugin.storeSettings()
} }
fun saveLastRun() {
val json = JSONObject()
json.put("lastNbDays", lastNbDays)
json.put("lastRun",lastRun)
json.put("pumpProfile", pumpProfile.profile.toPureNsJson(dateUtil))
json.put("pumpProfileName", pumpProfile.profilename)
json.put("pumpPeak", pumpProfile.peak)
json.put("pumpDia", pumpProfile.dia)
tunedProfile?.let { atProfile ->
json.put("tunedProfile", atProfile.profile.toPureNsJson(dateUtil))
json.put("tunedCircadianProfile", atProfile.circadianProfile.toPureNsJson(dateUtil))
json.put("tunedProfileName", atProfile.profilename)
json.put("tunedPeak", atProfile.peak)
json.put("tunedDia", atProfile.dia)
for (i in 0..23) {
json.put("missingDays_$i", atProfile.basalUntuned[i])
}
}
json.put("result", result)
json.put("updateButtonVisibility", updateButtonVisibility)
sp.putString(R.string.key_autotune_last_run, json.toString())
}
fun loadLastRun() {
result = ""
lastRunSuccess = false
try {
val json = JSONObject(sp.getString(R.string.key_autotune_last_run, ""))
lastNbDays = JsonHelper.safeGetString(json, "lastNbDays", "")
lastRun = JsonHelper.safeGetLong(json, "lastRun")
val pumpPeak = JsonHelper.safeGetInt(json, "pumpPeak")
val pumpDia = JsonHelper.safeGetDouble(json, "pumpDia")
var localInsulin = LocalInsulin("PumpInsulin", pumpPeak, pumpDia)
selectedProfile = JsonHelper.safeGetString(json, "pumpProfileName", "")
val profile = JsonHelper.safeGetJSONObject(json, "pumpProfile", null)?.let { pureProfileFromJson(it, dateUtil) }
?: return
pumpProfile = ATProfile(ProfileSealed.Pure(profile), localInsulin, injector).also { it.profilename = selectedProfile }
val tunedPeak = JsonHelper.safeGetInt(json, "tunedPeak")
val tunedDia = JsonHelper.safeGetDouble(json, "tunedDia")
localInsulin = LocalInsulin("PumpInsulin", tunedPeak, tunedDia)
val tunedProfileName = JsonHelper.safeGetString(json, "tunedProfileName", "")
val tuned = JsonHelper.safeGetJSONObject(json, "tunedProfile", null)?.let { pureProfileFromJson(it, dateUtil) }
?: return
val circadianTuned = JsonHelper.safeGetJSONObject(json, "tunedCircadianProfile", null)?.let { pureProfileFromJson(it, dateUtil) }
?: return
tunedProfile = ATProfile(ProfileSealed.Pure(tuned), localInsulin, injector).also { atProfile ->
atProfile.profilename = tunedProfileName
atProfile.circadianProfile = ProfileSealed.Pure(circadianTuned)
for (i in 0..23) {
atProfile.basalUntuned[i] = JsonHelper.safeGetInt(json,"missingDays_$i")
}
}
result = JsonHelper.safeGetString(json, "result", "")
updateButtonVisibility = JsonHelper.safeGetInt(json, "updateButtonVisibility")
lastRunSuccess = true
} catch (e: Exception) {
}
}
private fun log(message: String) { private fun log(message: String) {
atLog("[Plugin] $message") atLog("[Plugin] $message")

View file

@ -39,7 +39,7 @@ import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.utils.alertDialogs.PrefImportSummaryDialog import info.nightscout.androidaps.utils.alertDialogs.PrefImportSummaryDialog
import info.nightscout.androidaps.utils.alertDialogs.TwoMessagesAlertDialog import info.nightscout.androidaps.utils.alertDialogs.TwoMessagesAlertDialog
import info.nightscout.androidaps.utils.alertDialogs.WarningDialog import info.nightscout.androidaps.utils.alertDialogs.WarningDialog
import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.androidaps.utils.protection.PasswordCheck import info.nightscout.androidaps.utils.protection.PasswordCheck
import info.nightscout.androidaps.utils.storage.Storage import info.nightscout.androidaps.utils.storage.Storage
import info.nightscout.androidaps.utils.userEntry.UserEntryPresentationHelper import info.nightscout.androidaps.utils.userEntry.UserEntryPresentationHelper

View file

@ -13,7 +13,7 @@ import info.nightscout.androidaps.interfaces.PluginDescription
import info.nightscout.androidaps.interfaces.PluginType import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus
import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP
import java.io.* import java.io.*

View file

@ -286,14 +286,14 @@ class DataSyncSelectorImplementation @Inject constructor(
bolusCalculatorResult.first.interfaceIDs.nightscoutId == null -> bolusCalculatorResult.first.interfaceIDs.nightscoutId == null ->
nsClientPlugin.nsClientService?.dbAdd( nsClientPlugin.nsClientService?.dbAdd(
"treatments", "treatments",
bolusCalculatorResult.first.toJson(true, dateUtil), bolusCalculatorResult.first.toJson(true, dateUtil, profileFunction),
DataSyncSelector.PairBolusCalculatorResult(bolusCalculatorResult.first, bolusCalculatorResult.second.id), DataSyncSelector.PairBolusCalculatorResult(bolusCalculatorResult.first, bolusCalculatorResult.second.id),
"$startId/$lastDbId" "$startId/$lastDbId"
) )
// with nsId = update // with nsId = update
bolusCalculatorResult.first.interfaceIDs.nightscoutId != null -> bolusCalculatorResult.first.interfaceIDs.nightscoutId != null ->
nsClientPlugin.nsClientService?.dbUpdate( nsClientPlugin.nsClientService?.dbUpdate(
"treatments", bolusCalculatorResult.first.interfaceIDs.nightscoutId, bolusCalculatorResult.first.toJson(false, dateUtil), "treatments", bolusCalculatorResult.first.interfaceIDs.nightscoutId, bolusCalculatorResult.first.toJson(false, dateUtil, profileFunction),
DataSyncSelector.PairBolusCalculatorResult(bolusCalculatorResult.first, bolusCalculatorResult.second.id), "$startId/$lastDbId" DataSyncSelector.PairBolusCalculatorResult(bolusCalculatorResult.first, bolusCalculatorResult.second.id), "$startId/$lastDbId"
) )
} }

View file

@ -27,7 +27,7 @@ import info.nightscout.androidaps.receivers.DataWorker
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.JsonHelper import info.nightscout.androidaps.utils.JsonHelper
import info.nightscout.androidaps.utils.JsonHelper.safeGetLong import info.nightscout.androidaps.utils.JsonHelper.safeGetLong
import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import javax.inject.Inject import javax.inject.Inject

View file

@ -14,7 +14,7 @@ import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag import info.nightscout.shared.logging.LTag
import info.nightscout.androidaps.plugins.general.nsclient.data.NSMbg import info.nightscout.androidaps.plugins.general.nsclient.data.NSMbg
import info.nightscout.androidaps.receivers.DataWorker import info.nightscout.androidaps.receivers.DataWorker
import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP
import javax.inject.Inject import javax.inject.Inject

View file

@ -33,7 +33,7 @@ import info.nightscout.androidaps.plugins.general.nsclient.services.NSClientServ
import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.HtmlHelper.fromHtml import info.nightscout.androidaps.utils.HtmlHelper.fromHtml
import info.nightscout.androidaps.utils.ToastUtils import info.nightscout.androidaps.utils.ToastUtils
import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag import info.nightscout.shared.logging.LTag

View file

@ -48,7 +48,7 @@ import info.nightscout.androidaps.utils.JsonHelper.safeGetString
import info.nightscout.androidaps.utils.JsonHelper.safeGetStringAllowNull import info.nightscout.androidaps.utils.JsonHelper.safeGetStringAllowNull
import info.nightscout.androidaps.utils.T.Companion.mins import info.nightscout.androidaps.utils.T.Companion.mins
import info.nightscout.androidaps.utils.XDripBroadcast import info.nightscout.androidaps.utils.XDripBroadcast
import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag import info.nightscout.shared.logging.LTag

View file

@ -251,7 +251,6 @@ class OverviewData @Inject constructor(
var bgReadingGraphSeries: PointsWithLabelGraphSeries<DataPointWithLabelInterface> = PointsWithLabelGraphSeries() var bgReadingGraphSeries: PointsWithLabelGraphSeries<DataPointWithLabelInterface> = PointsWithLabelGraphSeries()
var predictionsGraphSeries: PointsWithLabelGraphSeries<DataPointWithLabelInterface> = PointsWithLabelGraphSeries() var predictionsGraphSeries: PointsWithLabelGraphSeries<DataPointWithLabelInterface> = PointsWithLabelGraphSeries()
var maxBasalValueFound = 0.0
val basalScale = Scale() val basalScale = Scale()
var baseBasalGraphSeries: LineGraphSeries<ScaledDataPoint> = LineGraphSeries() var baseBasalGraphSeries: LineGraphSeries<ScaledDataPoint> = LineGraphSeries()
var tempBasalGraphSeries: LineGraphSeries<ScaledDataPoint> = LineGraphSeries() var tempBasalGraphSeries: LineGraphSeries<ScaledDataPoint> = LineGraphSeries()

View file

@ -66,7 +66,7 @@ import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.ToastUtils import info.nightscout.androidaps.utils.ToastUtils
import info.nightscout.androidaps.utils.TrendCalculator import info.nightscout.androidaps.utils.TrendCalculator
import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.androidaps.utils.protection.ProtectionCheck import info.nightscout.androidaps.utils.protection.ProtectionCheck
import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.androidaps.utils.ui.SingleClickButton import info.nightscout.androidaps.utils.ui.SingleClickButton
@ -224,7 +224,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
disposable += activePlugin.activeOverview.overviewBus disposable += activePlugin.activeOverview.overviewBus
.toObservable(EventUpdateOverviewIobCob::class.java) .toObservable(EventUpdateOverviewIobCob::class.java)
.debounce(1L, TimeUnit.SECONDS) .debounce(1L, TimeUnit.SECONDS)
.observeOn(aapsSchedulers.main) .observeOn(aapsSchedulers.io)
.subscribe({ updateIobCob() }, fabricPrivacy::logException) .subscribe({ updateIobCob() }, fabricPrivacy::logException)
disposable += activePlugin.activeOverview.overviewBus disposable += activePlugin.activeOverview.overviewBus
.toObservable(EventUpdateOverviewSensitivity::class.java) .toObservable(EventUpdateOverviewSensitivity::class.java)
@ -256,7 +256,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
disposable += rxBus disposable += rxBus
.toObservable(EventNewBG::class.java) .toObservable(EventNewBG::class.java)
.debounce(1L, TimeUnit.SECONDS) .debounce(1L, TimeUnit.SECONDS)
.observeOn(aapsSchedulers.main) .observeOn(aapsSchedulers.io)
.subscribe({ updateBg() }, fabricPrivacy::logException) .subscribe({ updateBg() }, fabricPrivacy::logException)
disposable += rxBus disposable += rxBus
.toObservable(EventRefreshOverview::class.java) .toObservable(EventRefreshOverview::class.java)
@ -287,19 +287,19 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
}, fabricPrivacy::logException) }, fabricPrivacy::logException)
disposable += rxBus disposable += rxBus
.toObservable(EventEffectiveProfileSwitchChanged::class.java) .toObservable(EventEffectiveProfileSwitchChanged::class.java)
.observeOn(aapsSchedulers.main) .observeOn(aapsSchedulers.io)
.subscribe({ updateProfile() }, fabricPrivacy::logException) .subscribe({ updateProfile() }, fabricPrivacy::logException)
disposable += rxBus disposable += rxBus
.toObservable(EventTempTargetChange::class.java) .toObservable(EventTempTargetChange::class.java)
.observeOn(aapsSchedulers.main) .observeOn(aapsSchedulers.io)
.subscribe({ updateTemporaryTarget() }, fabricPrivacy::logException) .subscribe({ updateTemporaryTarget() }, fabricPrivacy::logException)
disposable += rxBus disposable += rxBus
.toObservable(EventExtendedBolusChange::class.java) .toObservable(EventExtendedBolusChange::class.java)
.observeOn(aapsSchedulers.main) .observeOn(aapsSchedulers.io)
.subscribe({ updateExtendedBolus() }, fabricPrivacy::logException) .subscribe({ updateExtendedBolus() }, fabricPrivacy::logException)
disposable += rxBus disposable += rxBus
.toObservable(EventTempBasalChange::class.java) .toObservable(EventTempBasalChange::class.java)
.observeOn(aapsSchedulers.main) .observeOn(aapsSchedulers.io)
.subscribe({ updateTemporaryBasal() }, fabricPrivacy::logException) .subscribe({ updateTemporaryBasal() }, fabricPrivacy::logException)
refreshLoop = Runnable { refreshLoop = Runnable {
@ -316,17 +316,19 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
fun refreshAll() { fun refreshAll() {
runOnUiThread { runOnUiThread {
_binding ?: return@runOnUiThread _binding ?: return@runOnUiThread
updateBg()
updateTime() updateTime()
updateProfile()
updateTemporaryBasal()
updateExtendedBolus()
updateTemporaryTarget()
updateIobCob()
updateSensitivity() updateSensitivity()
updateGraph() updateGraph()
updateNotification() updateNotification()
} }
updateBg()
updateTemporaryBasal()
updateExtendedBolus()
updateIobCob()
processButtonsVisibility()
processAps()
updateProfile()
updateTemporaryTarget()
} }
@Synchronized @Synchronized
@ -513,13 +515,16 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
// QuickWizard button // QuickWizard button
val quickWizardEntry = quickWizard.getActive() val quickWizardEntry = quickWizard.getActive()
if (quickWizardEntry != null && lastBG != null && profile != null && pump.isInitialized() && !pump.isSuspended() && !loop.isDisconnected) { runOnUiThread {
binding.buttonsLayout.quickWizardButton.visibility = View.VISIBLE _binding ?: return@runOnUiThread
val wizard = quickWizardEntry.doCalc(profile, profileName, lastBG, false) if (quickWizardEntry != null && lastBG != null && profile != null && pump.isInitialized() && !pump.isSuspended() && !loop.isDisconnected) {
binding.buttonsLayout.quickWizardButton.text = quickWizardEntry.buttonText() + "\n" + rh.gs(R.string.format_carbs, quickWizardEntry.carbs()) + binding.buttonsLayout.quickWizardButton.visibility = View.VISIBLE
" " + rh.gs(R.string.formatinsulinunits, wizard.calculatedTotalInsulin) val wizard = quickWizardEntry.doCalc(profile, profileName, lastBG, false)
if (wizard.calculatedTotalInsulin <= 0) binding.buttonsLayout.quickWizardButton.visibility = View.GONE binding.buttonsLayout.quickWizardButton.text = quickWizardEntry.buttonText() + "\n" + rh.gs(R.string.format_carbs, quickWizardEntry.carbs()) +
} else binding.buttonsLayout.quickWizardButton.visibility = View.GONE " " + rh.gs(R.string.formatinsulinunits, wizard.calculatedTotalInsulin)
if (wizard.calculatedTotalInsulin <= 0) binding.buttonsLayout.quickWizardButton.visibility = View.GONE
} else binding.buttonsLayout.quickWizardButton.visibility = View.GONE
}
// **** Temp button **** // **** Temp button ****
val lastRun = loop.lastRun val lastRun = loop.lastRun
@ -530,72 +535,76 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
(lastRun.lastOpenModeAccept == 0L || lastRun.lastOpenModeAccept < lastRun.lastAPSRun) &&// never accepted or before last result (lastRun.lastOpenModeAccept == 0L || lastRun.lastOpenModeAccept < lastRun.lastAPSRun) &&// never accepted or before last result
lastRun.constraintsProcessed?.isChangeRequested == true // change is requested lastRun.constraintsProcessed?.isChangeRequested == true // change is requested
if (showAcceptButton && pump.isInitialized() && !pump.isSuspended() && (loop as PluginBase).isEnabled()) { runOnUiThread {
binding.buttonsLayout.acceptTempButton.visibility = View.VISIBLE _binding ?: return@runOnUiThread
binding.buttonsLayout.acceptTempButton.text = "${rh.gs(R.string.setbasalquestion)}\n${lastRun!!.constraintsProcessed}" if (showAcceptButton && pump.isInitialized() && !pump.isSuspended() && (loop as PluginBase).isEnabled()) {
} else { binding.buttonsLayout.acceptTempButton.visibility = View.VISIBLE
binding.buttonsLayout.acceptTempButton.visibility = View.GONE binding.buttonsLayout.acceptTempButton.text = "${rh.gs(R.string.setbasalquestion)}\n${lastRun!!.constraintsProcessed}"
} } else {
binding.buttonsLayout.acceptTempButton.visibility = View.GONE
// **** Various treatment buttons ****
binding.buttonsLayout.carbsButton.visibility =
((!activePlugin.activePump.pumpDescription.storesCarbInfo || pump.isInitialized() && !pump.isSuspended()) && profile != null
&& sp.getBoolean(R.string.key_show_carbs_button, true)).toVisibility()
binding.buttonsLayout.treatmentButton.visibility = (!loop.isDisconnected && pump.isInitialized() && !pump.isSuspended() && profile != null
&& sp.getBoolean(R.string.key_show_treatment_button, false)).toVisibility()
binding.buttonsLayout.wizardButton.visibility = (!loop.isDisconnected && pump.isInitialized() && !pump.isSuspended() && profile != null
&& sp.getBoolean(R.string.key_show_wizard_button, true)).toVisibility()
binding.buttonsLayout.insulinButton.visibility = (!loop.isDisconnected && pump.isInitialized() && !pump.isSuspended() && profile != null
&& sp.getBoolean(R.string.key_show_insulin_button, true)).toVisibility()
// **** Calibration & CGM buttons ****
val xDripIsBgSource = xdripPlugin.isEnabled()
val dexcomIsSource = dexcomPlugin.isEnabled()
binding.buttonsLayout.calibrationButton.visibility = (xDripIsBgSource && actualBG != null && sp.getBoolean(R.string.key_show_calibration_button, true)).toVisibility()
if (dexcomIsSource) {
binding.buttonsLayout.cgmButton.setCompoundDrawablesWithIntrinsicBounds(null, rh.gd(R.drawable.ic_byoda), null, null)
for (drawable in binding.buttonsLayout.cgmButton.compoundDrawables) {
drawable?.mutate()
drawable?.colorFilter = PorterDuffColorFilter(rh.gac(context, R.attr.cgmDexColor), PorterDuff.Mode.SRC_IN)
} }
binding.buttonsLayout.cgmButton.setTextColor(rh.gac(context, R.attr.cgmDexColor))
} else if (xDripIsBgSource) { // **** Various treatment buttons ****
binding.buttonsLayout.cgmButton.setCompoundDrawablesWithIntrinsicBounds(null, rh.gd(R.drawable.ic_xdrip), null, null) binding.buttonsLayout.carbsButton.visibility =
for (drawable in binding.buttonsLayout.cgmButton.compoundDrawables) { ((!activePlugin.activePump.pumpDescription.storesCarbInfo || pump.isInitialized() && !pump.isSuspended()) && profile != null
drawable?.mutate() && sp.getBoolean(R.string.key_show_carbs_button, true)).toVisibility()
drawable?.colorFilter = PorterDuffColorFilter(rh.gac(context, R.attr.cgmXdripColor), PorterDuff.Mode.SRC_IN) binding.buttonsLayout.treatmentButton.visibility = (!loop.isDisconnected && pump.isInitialized() && !pump.isSuspended() && profile != null
&& sp.getBoolean(R.string.key_show_treatment_button, false)).toVisibility()
binding.buttonsLayout.wizardButton.visibility = (!loop.isDisconnected && pump.isInitialized() && !pump.isSuspended() && profile != null
&& sp.getBoolean(R.string.key_show_wizard_button, true)).toVisibility()
binding.buttonsLayout.insulinButton.visibility = (!loop.isDisconnected && pump.isInitialized() && !pump.isSuspended() && profile != null
&& sp.getBoolean(R.string.key_show_insulin_button, true)).toVisibility()
// **** Calibration & CGM buttons ****
val xDripIsBgSource = xdripPlugin.isEnabled()
val dexcomIsSource = dexcomPlugin.isEnabled()
binding.buttonsLayout.calibrationButton.visibility = (xDripIsBgSource && actualBG != null && sp.getBoolean(R.string.key_show_calibration_button, true)).toVisibility()
if (dexcomIsSource) {
binding.buttonsLayout.cgmButton.setCompoundDrawablesWithIntrinsicBounds(null, rh.gd(R.drawable.ic_byoda), null, null)
for (drawable in binding.buttonsLayout.cgmButton.compoundDrawables) {
drawable?.mutate()
drawable?.colorFilter = PorterDuffColorFilter(rh.gac(context, R.attr.cgmDexColor), PorterDuff.Mode.SRC_IN)
}
binding.buttonsLayout.cgmButton.setTextColor(rh.gac(context, R.attr.cgmDexColor))
} else if (xDripIsBgSource) {
binding.buttonsLayout.cgmButton.setCompoundDrawablesWithIntrinsicBounds(null, rh.gd(R.drawable.ic_xdrip), null, null)
for (drawable in binding.buttonsLayout.cgmButton.compoundDrawables) {
drawable?.mutate()
drawable?.colorFilter = PorterDuffColorFilter(rh.gac(context, R.attr.cgmXdripColor), PorterDuff.Mode.SRC_IN)
}
binding.buttonsLayout.cgmButton.setTextColor(rh.gac(context, R.attr.cgmXdripColor))
} }
binding.buttonsLayout.cgmButton.setTextColor(rh.gac(context, R.attr.cgmXdripColor)) binding.buttonsLayout.cgmButton.visibility = (sp.getBoolean(R.string.key_show_cgm_button, false) && (xDripIsBgSource || dexcomIsSource)).toVisibility()
}
binding.buttonsLayout.cgmButton.visibility = (sp.getBoolean(R.string.key_show_cgm_button, false) && (xDripIsBgSource || dexcomIsSource)).toVisibility()
// Automation buttons // Automation buttons
binding.buttonsLayout.userButtonsLayout.removeAllViews() binding.buttonsLayout.userButtonsLayout.removeAllViews()
val events = automationPlugin.userEvents() val events = automationPlugin.userEvents()
if (!loop.isDisconnected && pump.isInitialized() && !pump.isSuspended() && profile != null) if (!loop.isDisconnected && pump.isInitialized() && !pump.isSuspended() && profile != null)
for (event in events) for (event in events)
if (event.isEnabled && event.trigger.shouldRun()) if (event.isEnabled && event.trigger.shouldRun())
context?.let { context -> context?.let { context ->
SingleClickButton(context).also { SingleClickButton(context).also {
it.setTextColor(rh.gac(context, R.attr.treatmentButton)) it.setTextColor(rh.gac(context, R.attr.treatmentButton))
it.setTextSize(TypedValue.COMPLEX_UNIT_SP, 10f) it.setTextSize(TypedValue.COMPLEX_UNIT_SP, 10f)
it.layoutParams = LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.MATCH_PARENT, 0.5f).also { l -> it.layoutParams = LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.MATCH_PARENT, 0.5f).also { l ->
l.setMargins(0, 0, rh.dpToPx(-4), 0) l.setMargins(0, 0, rh.dpToPx(-4), 0)
} }
it.setCompoundDrawablesWithIntrinsicBounds(null, rh.gd(R.drawable.ic_danar_useropt), null, null) it.setCompoundDrawablesWithIntrinsicBounds(null, rh.gd(R.drawable.ic_danar_useropt), null, null)
it.text = event.title it.text = event.title
it.setOnClickListener { it.setOnClickListener {
OKDialog.showConfirmation(context, rh.gs(R.string.run_question, event.title), { handler.post { automationPlugin.processEvent(event) } }) OKDialog.showConfirmation(context, rh.gs(R.string.run_question, event.title), { handler.post { automationPlugin.processEvent(event) } })
}
binding.buttonsLayout.userButtonsLayout.addView(it)
} }
binding.buttonsLayout.userButtonsLayout.addView(it)
} }
} binding.buttonsLayout.userButtonsLayout.visibility = events.isNotEmpty().toVisibility()
binding.buttonsLayout.userButtonsLayout.visibility = events.isNotEmpty().toVisibility() }
} }
private fun processAps() { private fun processAps() {
val pump = activePlugin.activePump val pump = activePlugin.activePump
val profile = profileFunction.getProfile()
// aps mode // aps mode
val closedLoopEnabled = constraintChecker.isClosedLoopAllowed() val closedLoopEnabled = constraintChecker.isClosedLoopAllowed()
@ -608,103 +617,106 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
} }
} }
if (config.APS && pump.pumpDescription.isTempBasalCapable) { runOnUiThread {
binding.infoLayout.apsMode.visibility = View.VISIBLE _binding ?: return@runOnUiThread
binding.infoLayout.timeLayout.visibility = View.GONE if (config.APS && pump.pumpDescription.isTempBasalCapable) {
when { binding.infoLayout.apsMode.visibility = View.VISIBLE
(loop as PluginBase).isEnabled() && loop.isSuperBolus -> { binding.infoLayout.timeLayout.visibility = View.GONE
binding.infoLayout.apsMode.setImageResource(R.drawable.ic_loop_superbolus) when {
apsModeSetA11yLabel(R.string.superbolus) (loop as PluginBase).isEnabled() && loop.isSuperBolus -> {
binding.infoLayout.apsModeText.text = dateUtil.age(loop.minutesToEndOfSuspend() * 60000L, true, rh) binding.infoLayout.apsMode.setImageResource(R.drawable.ic_loop_superbolus)
binding.infoLayout.apsModeText.visibility = View.VISIBLE apsModeSetA11yLabel(R.string.superbolus)
} binding.infoLayout.apsModeText.text = dateUtil.age(loop.minutesToEndOfSuspend() * 60000L, true, rh)
binding.infoLayout.apsModeText.visibility = View.VISIBLE
}
loop.isDisconnected -> { loop.isDisconnected -> {
binding.infoLayout.apsMode.setImageResource(R.drawable.ic_loop_disconnected) binding.infoLayout.apsMode.setImageResource(R.drawable.ic_loop_disconnected)
apsModeSetA11yLabel(R.string.disconnected) apsModeSetA11yLabel(R.string.disconnected)
binding.infoLayout.apsModeText.text = dateUtil.age(loop.minutesToEndOfSuspend() * 60000L, true, rh) binding.infoLayout.apsModeText.text = dateUtil.age(loop.minutesToEndOfSuspend() * 60000L, true, rh)
binding.infoLayout.apsModeText.visibility = View.VISIBLE binding.infoLayout.apsModeText.visibility = View.VISIBLE
} }
(loop as PluginBase).isEnabled() && loop.isSuspended -> { (loop as PluginBase).isEnabled() && loop.isSuspended -> {
binding.infoLayout.apsMode.setImageResource(R.drawable.ic_loop_paused) binding.infoLayout.apsMode.setImageResource(R.drawable.ic_loop_paused)
apsModeSetA11yLabel(R.string.suspendloop_label) apsModeSetA11yLabel(R.string.suspendloop_label)
binding.infoLayout.apsModeText.text = dateUtil.age(loop.minutesToEndOfSuspend() * 60000L, true, rh) binding.infoLayout.apsModeText.text = dateUtil.age(loop.minutesToEndOfSuspend() * 60000L, true, rh)
binding.infoLayout.apsModeText.visibility = View.VISIBLE binding.infoLayout.apsModeText.visibility = View.VISIBLE
} }
pump.isSuspended() -> { pump.isSuspended() -> {
binding.infoLayout.apsMode.setImageResource( binding.infoLayout.apsMode.setImageResource(
if (pump.model() == PumpType.OMNIPOD_EROS || pump.model() == PumpType.OMNIPOD_DASH) { if (pump.model() == PumpType.OMNIPOD_EROS || pump.model() == PumpType.OMNIPOD_DASH) {
// For Omnipod, indicate the pump as disconnected when it's suspended. // For Omnipod, indicate the pump as disconnected when it's suspended.
// The only way to 'reconnect' it, is through the Omnipod tab // The only way to 'reconnect' it, is through the Omnipod tab
apsModeSetA11yLabel(R.string.disconnected) apsModeSetA11yLabel(R.string.disconnected)
R.drawable.ic_loop_disconnected R.drawable.ic_loop_disconnected
} else { } else {
apsModeSetA11yLabel(R.string.pump_paused) apsModeSetA11yLabel(R.string.pump_paused)
R.drawable.ic_loop_paused R.drawable.ic_loop_paused
} }
)
binding.infoLayout.apsModeText.visibility = View.GONE
}
(loop as PluginBase).isEnabled() && closedLoopEnabled.value() && loop.isLGS -> {
binding.infoLayout.apsMode.setImageResource(R.drawable.ic_loop_lgs)
apsModeSetA11yLabel(R.string.uel_lgs_loop_mode)
binding.infoLayout.apsModeText.visibility = View.GONE
}
(loop as PluginBase).isEnabled() && closedLoopEnabled.value() -> {
binding.infoLayout.apsMode.setImageResource(R.drawable.ic_loop_closed)
apsModeSetA11yLabel(R.string.closedloop)
binding.infoLayout.apsModeText.visibility = View.GONE
}
(loop as PluginBase).isEnabled() && !closedLoopEnabled.value() -> {
binding.infoLayout.apsMode.setImageResource(R.drawable.ic_loop_open)
apsModeSetA11yLabel(R.string.openloop)
binding.infoLayout.apsModeText.visibility = View.GONE
}
else -> {
binding.infoLayout.apsMode.setImageResource(R.drawable.ic_loop_disabled)
apsModeSetA11yLabel(R.string.disabledloop)
binding.infoLayout.apsModeText.visibility = View.GONE
}
}
// Show variable sensitivity
val request = loop.lastRun?.request
if (request is DetermineBasalResultSMB) {
val isfMgdl = profileFunction.getProfile()?.getIsfMgdl()
val variableSens = request.variableSens
if (variableSens != isfMgdl && variableSens != null && isfMgdl != null) {
binding.infoLayout.variableSensitivity.text =
String.format(
Locale.getDefault(), "%1$.1f→%2$.1f",
Profile.toUnits(isfMgdl, isfMgdl * Constants.MGDL_TO_MMOLL, profileFunction.getUnits()),
Profile.toUnits(variableSens, variableSens * Constants.MGDL_TO_MMOLL, profileFunction.getUnits())
) )
binding.infoLayout.variableSensitivity.visibility = View.VISIBLE binding.infoLayout.apsModeText.visibility = View.GONE
}
(loop as PluginBase).isEnabled() && closedLoopEnabled.value() && loop.isLGS -> {
binding.infoLayout.apsMode.setImageResource(R.drawable.ic_loop_lgs)
apsModeSetA11yLabel(R.string.uel_lgs_loop_mode)
binding.infoLayout.apsModeText.visibility = View.GONE
}
(loop as PluginBase).isEnabled() && closedLoopEnabled.value() -> {
binding.infoLayout.apsMode.setImageResource(R.drawable.ic_loop_closed)
apsModeSetA11yLabel(R.string.closedloop)
binding.infoLayout.apsModeText.visibility = View.GONE
}
(loop as PluginBase).isEnabled() && !closedLoopEnabled.value() -> {
binding.infoLayout.apsMode.setImageResource(R.drawable.ic_loop_open)
apsModeSetA11yLabel(R.string.openloop)
binding.infoLayout.apsModeText.visibility = View.GONE
}
else -> {
binding.infoLayout.apsMode.setImageResource(R.drawable.ic_loop_disabled)
apsModeSetA11yLabel(R.string.disabledloop)
binding.infoLayout.apsModeText.visibility = View.GONE
}
}
// Show variable sensitivity
val request = loop.lastRun?.request
if (request is DetermineBasalResultSMB) {
val isfMgdl = profile?.getIsfMgdl()
val variableSens = request.variableSens
if (variableSens != isfMgdl && variableSens != null && isfMgdl != null) {
binding.infoLayout.variableSensitivity.text =
String.format(
Locale.getDefault(), "%1$.1f→%2$.1f",
Profile.toUnits(isfMgdl, isfMgdl * Constants.MGDL_TO_MMOLL, profileFunction.getUnits()),
Profile.toUnits(variableSens, variableSens * Constants.MGDL_TO_MMOLL, profileFunction.getUnits())
)
binding.infoLayout.variableSensitivity.visibility = View.VISIBLE
} else binding.infoLayout.variableSensitivity.visibility = View.GONE
} else binding.infoLayout.variableSensitivity.visibility = View.GONE } else binding.infoLayout.variableSensitivity.visibility = View.GONE
} else binding.infoLayout.variableSensitivity.visibility = View.GONE } else {
} else { //nsclient
//nsclient binding.infoLayout.apsMode.visibility = View.GONE
binding.infoLayout.apsMode.visibility = View.GONE binding.infoLayout.apsModeText.visibility = View.GONE
binding.infoLayout.apsModeText.visibility = View.GONE binding.infoLayout.timeLayout.visibility = View.VISIBLE
binding.infoLayout.timeLayout.visibility = View.VISIBLE }
// pump status from ns
binding.pump.text = nsDeviceStatus.pumpStatus
binding.pump.setOnClickListener { activity?.let { OKDialog.show(it, rh.gs(R.string.pump), nsDeviceStatus.extendedPumpStatus) } }
// OpenAPS status from ns
binding.openaps.text = nsDeviceStatus.openApsStatus
binding.openaps.setOnClickListener { activity?.let { OKDialog.show(it, rh.gs(R.string.openaps), nsDeviceStatus.extendedOpenApsStatus) } }
// Uploader status from ns
binding.uploader.text = nsDeviceStatus.uploaderStatusSpanned
binding.uploader.setOnClickListener { activity?.let { OKDialog.show(it, rh.gs(R.string.uploader), nsDeviceStatus.extendedUploaderStatus) } }
} }
// pump status from ns
binding.pump.text = nsDeviceStatus.pumpStatus
binding.pump.setOnClickListener { activity?.let { OKDialog.show(it, rh.gs(R.string.pump), nsDeviceStatus.extendedPumpStatus) } }
// OpenAPS status from ns
binding.openaps.text = nsDeviceStatus.openApsStatus
binding.openaps.setOnClickListener { activity?.let { OKDialog.show(it, rh.gs(R.string.openaps), nsDeviceStatus.extendedOpenApsStatus) } }
// Uploader status from ns
binding.uploader.text = nsDeviceStatus.uploaderStatusSpanned
binding.uploader.setOnClickListener { activity?.let { OKDialog.show(it, rh.gs(R.string.uploader), nsDeviceStatus.extendedUploaderStatus) } }
} }
private fun prepareGraphsIfNeeded(numOfGraphs: Int) { private fun prepareGraphsIfNeeded(numOfGraphs: Int) {
@ -760,59 +772,67 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
fun updateBg() { fun updateBg() {
_binding ?: return
val units = profileFunction.getUnits() val units = profileFunction.getUnits()
binding.infoLayout.bg.text = overviewData.lastBg?.valueToUnitsString(units) val lastBg = overviewData.lastBg
?: rh.gs(R.string.notavailable) val lastBgColor = overviewData.lastBgColor(context)
binding.infoLayout.bg.setTextColor(overviewData.lastBgColor(context)) val isActualBg = overviewData.isActualBg
binding.infoLayout.arrow.setImageResource(trendCalculator.getTrendArrow(overviewData.lastBg).directionToIcon())
binding.infoLayout.arrow.setColorFilter(overviewData.lastBgColor(context))
binding.infoLayout.arrow.contentDescription = overviewData.lastBgDescription + " " + rh.gs(R.string.and) + " " + trendCalculator.getTrendDescription(overviewData.lastBg)
val glucoseStatus = glucoseStatusProvider.glucoseStatusData val glucoseStatus = glucoseStatusProvider.glucoseStatusData
if (glucoseStatus != null) { val trendDescription = trendCalculator.getTrendDescription(lastBg)
binding.infoLayout.deltaLarge.text = Profile.toSignedUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units) val trendArrow = trendCalculator.getTrendArrow(lastBg)
binding.infoLayout.deltaLarge.setTextColor(overviewData.lastBgColor(context)) val lastBgDescription = overviewData.lastBgDescription
binding.infoLayout.delta.text = Profile.toSignedUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units) runOnUiThread {
binding.infoLayout.avgDelta.text = Profile.toSignedUnitsString(glucoseStatus.shortAvgDelta, glucoseStatus.shortAvgDelta * Constants.MGDL_TO_MMOLL, units) _binding ?: return@runOnUiThread
binding.infoLayout.longAvgDelta.text = Profile.toSignedUnitsString(glucoseStatus.longAvgDelta, glucoseStatus.longAvgDelta * Constants.MGDL_TO_MMOLL, units) binding.infoLayout.bg.text = lastBg?.valueToUnitsString(units)
} else { ?: rh.gs(R.string.notavailable)
binding.infoLayout.deltaLarge.text = "" binding.infoLayout.bg.setTextColor(lastBgColor)
binding.infoLayout.delta.text = "Δ " + rh.gs(R.string.notavailable) binding.infoLayout.arrow.setImageResource(trendArrow.directionToIcon())
binding.infoLayout.avgDelta.text = "" binding.infoLayout.arrow.setColorFilter(lastBgColor)
binding.infoLayout.longAvgDelta.text = "" binding.infoLayout.arrow.contentDescription = lastBgDescription + " " + rh.gs(R.string.and) + " " + trendDescription
}
// strike through if BG is old if (glucoseStatus != null) {
binding.infoLayout.bg.paintFlags = binding.infoLayout.deltaLarge.text = Profile.toSignedUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units)
if (!overviewData.isActualBg) binding.infoLayout.bg.paintFlags or Paint.STRIKE_THRU_TEXT_FLAG binding.infoLayout.deltaLarge.setTextColor(lastBgColor)
else binding.infoLayout.bg.paintFlags and Paint.STRIKE_THRU_TEXT_FLAG.inv() binding.infoLayout.delta.text = Profile.toSignedUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units)
binding.infoLayout.avgDelta.text = Profile.toSignedUnitsString(glucoseStatus.shortAvgDelta, glucoseStatus.shortAvgDelta * Constants.MGDL_TO_MMOLL, units)
val outDate = (if (!overviewData.isActualBg) rh.gs(R.string.a11y_bg_outdated) else "") binding.infoLayout.longAvgDelta.text = Profile.toSignedUnitsString(glucoseStatus.longAvgDelta, glucoseStatus.longAvgDelta * Constants.MGDL_TO_MMOLL, units)
binding.infoLayout.bg.contentDescription = } else {
rh.gs(R.string.a11y_blood_glucose) + " " + binding.infoLayout.bg.text.toString() + " " + overviewData.lastBgDescription + " " + outDate binding.infoLayout.deltaLarge.text = ""
binding.infoLayout.delta.text = "Δ " + rh.gs(R.string.notavailable)
binding.infoLayout.timeAgo.text = dateUtil.minAgo(rh, overviewData.lastBg?.timestamp) binding.infoLayout.avgDelta.text = ""
binding.infoLayout.timeAgo.contentDescription = dateUtil.minAgoLong(rh, overviewData.lastBg?.timestamp) binding.infoLayout.longAvgDelta.text = ""
binding.infoLayout.timeAgoShort.text = "(" + dateUtil.minAgoShort(overviewData.lastBg?.timestamp) + ")" }
val qualityIcon = bgQualityCheckPlugin.icon() // strike through if BG is old
if (qualityIcon != 0) { binding.infoLayout.bg.paintFlags =
binding.infoLayout.bgQuality.visibility = View.VISIBLE if (!isActualBg) binding.infoLayout.bg.paintFlags or Paint.STRIKE_THRU_TEXT_FLAG
binding.infoLayout.bgQuality.setImageResource(qualityIcon) else binding.infoLayout.bg.paintFlags and Paint.STRIKE_THRU_TEXT_FLAG.inv()
binding.infoLayout.bgQuality.contentDescription = rh.gs(R.string.a11y_bg_quality) + " " + bgQualityCheckPlugin.stateDescription()
binding.infoLayout.bgQuality.setOnClickListener { val outDate = (if (!isActualBg) rh.gs(R.string.a11y_bg_outdated) else "")
context?.let { context -> OKDialog.show(context, rh.gs(R.string.data_status), bgQualityCheckPlugin.message) } binding.infoLayout.bg.contentDescription = rh.gs(R.string.a11y_blood_glucose) + " " + binding.infoLayout.bg.text.toString() + " " + lastBgDescription + " " + outDate
binding.infoLayout.timeAgo.text = dateUtil.minAgo(rh, lastBg?.timestamp)
binding.infoLayout.timeAgo.contentDescription = dateUtil.minAgoLong(rh, lastBg?.timestamp)
binding.infoLayout.timeAgoShort.text = "(" + dateUtil.minAgoShort(lastBg?.timestamp) + ")"
val qualityIcon = bgQualityCheckPlugin.icon()
if (qualityIcon != 0) {
binding.infoLayout.bgQuality.visibility = View.VISIBLE
binding.infoLayout.bgQuality.setImageResource(qualityIcon)
binding.infoLayout.bgQuality.contentDescription = rh.gs(R.string.a11y_bg_quality) + " " + bgQualityCheckPlugin.stateDescription()
binding.infoLayout.bgQuality.setOnClickListener {
context?.let { context -> OKDialog.show(context, rh.gs(R.string.data_status), bgQualityCheckPlugin.message) }
}
} else {
binding.infoLayout.bgQuality.visibility = View.GONE
} }
} else {
binding.infoLayout.bgQuality.visibility = View.GONE
} }
} }
fun updateProfile() { fun updateProfile() {
_binding ?: return val profile = profileFunction.getProfile()
val profileBackgroundColor = runOnUiThread {
profileFunction.getProfile()?.let { _binding ?: return@runOnUiThread
val profileBackgroundColor = profile?.let {
if (it is ProfileSealed.EPS) { if (it is ProfileSealed.EPS) {
if (it.value.originalPercentage != 100 || it.value.originalTimeshift != 0L || it.value.originalDuration != 0L) if (it.value.originalPercentage != 100 || it.value.originalTimeshift != 0L || it.value.originalDuration != 0L)
R.attr.ribbonWarningColor R.attr.ribbonWarningColor
@ -824,8 +844,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
} }
} ?: R.attr.ribbonCriticalColor } ?: R.attr.ribbonCriticalColor
val profileTextColor = val profileTextColor = profile?.let {
profileFunction.getProfile()?.let {
if (it is ProfileSealed.EPS) { if (it is ProfileSealed.EPS) {
if (it.value.originalPercentage != 100 || it.value.originalTimeshift != 0L || it.value.originalDuration != 0L) if (it.value.originalPercentage != 100 || it.value.originalTimeshift != 0L || it.value.originalDuration != 0L)
R.attr.ribbonTextWarningColor R.attr.ribbonTextWarningColor
@ -836,27 +855,35 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
R.attr.ribbonTextDefaultColor R.attr.ribbonTextDefaultColor
} }
} ?: R.attr.ribbonTextDefaultColor } ?: R.attr.ribbonTextDefaultColor
setRibbon(binding.activeProfile, profileTextColor, profileBackgroundColor, profileFunction.getProfileNameWithRemainingTime()) setRibbon(binding.activeProfile, profileTextColor, profileBackgroundColor, profileFunction.getProfileNameWithRemainingTime())
}
} }
private fun updateTemporaryBasal() { private fun updateTemporaryBasal() {
_binding ?: return val temporaryBasalText = overviewData.temporaryBasalText(iobCobCalculator)
binding.infoLayout.baseBasal.text = overviewData.temporaryBasalText(iobCobCalculator) val temporaryBasalColor = overviewData.temporaryBasalColor(context, iobCobCalculator)
binding.infoLayout.baseBasal.setTextColor(overviewData.temporaryBasalColor(context, iobCobCalculator)) val temporaryBasalIcon = overviewData.temporaryBasalIcon(iobCobCalculator)
binding.infoLayout.baseBasalIcon.setImageResource(overviewData.temporaryBasalIcon(iobCobCalculator)) val temporaryBasalDialogText = overviewData.temporaryBasalDialogText(iobCobCalculator)
binding.infoLayout.basalLayout.setOnClickListener { runOnUiThread {
activity?.let { OKDialog.show(it, rh.gs(R.string.basal), overviewData.temporaryBasalDialogText(iobCobCalculator)) } _binding ?: return@runOnUiThread
binding.infoLayout.baseBasal.text = temporaryBasalText
binding.infoLayout.baseBasal.setTextColor(temporaryBasalColor)
binding.infoLayout.baseBasalIcon.setImageResource(temporaryBasalIcon)
binding.infoLayout.basalLayout.setOnClickListener { activity?.let { OKDialog.show(it, rh.gs(R.string.basal), temporaryBasalDialogText) } }
} }
} }
private fun updateExtendedBolus() { private fun updateExtendedBolus() {
_binding ?: return
val pump = activePlugin.activePump val pump = activePlugin.activePump
binding.infoLayout.extendedBolus.text = overviewData.extendedBolusText(iobCobCalculator) val extendedBolus = iobCobCalculator.getExtendedBolus(dateUtil.now())
binding.infoLayout.extendedLayout.setOnClickListener { val extendedBolusText = overviewData.extendedBolusText(iobCobCalculator)
activity?.let { OKDialog.show(it, rh.gs(R.string.extended_bolus), overviewData.extendedBolusDialogText(iobCobCalculator)) } val extendedBolusDialogText = overviewData.extendedBolusDialogText(iobCobCalculator)
runOnUiThread {
_binding ?: return@runOnUiThread
binding.infoLayout.extendedBolus.text = extendedBolusText
binding.infoLayout.extendedLayout.setOnClickListener { activity?.let { OKDialog.show(it, rh.gs(R.string.extended_bolus), extendedBolusDialogText) } }
binding.infoLayout.extendedLayout.visibility = (extendedBolus != null && !pump.isFakingTempsByExtendedBoluses).toVisibility()
} }
binding.infoLayout.extendedLayout.visibility = (iobCobCalculator.getExtendedBolus(dateUtil.now()) != null && !pump.isFakingTempsByExtendedBoluses).toVisibility()
} }
fun updateTime() { fun updateTime() {
@ -887,69 +914,73 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
binding.statusLightsLayout.pbAge, binding.statusLightsLayout.pbAge,
binding.statusLightsLayout.batteryLevel binding.statusLightsLayout.batteryLevel
) )
processButtonsVisibility()
processAps()
} }
fun updateIobCob() { fun updateIobCob() {
_binding ?: return val iobText = overviewData.iobText(iobCobCalculator)
binding.infoLayout.iob.text = overviewData.iobText(iobCobCalculator) val iobDialogText = overviewData.iobDialogText(iobCobCalculator)
binding.infoLayout.iobLayout.setOnClickListener { val displayText = overviewData.cobInfo(iobCobCalculator).displayText(rh, dateUtil, buildHelper.isEngineeringMode())
activity?.let { OKDialog.show(it, rh.gs(R.string.iob), overviewData.iobDialogText(iobCobCalculator)) } val lastCarbsTime = overviewData.lastCarbsTime
} runOnUiThread {
// cob _binding ?: return@runOnUiThread
var cobText = overviewData.cobInfo(iobCobCalculator).displayText(rh, dateUtil, buildHelper.isEngineeringMode()) ?: rh.gs(R.string.value_unavailable_short) binding.infoLayout.iob.text = iobText
binding.infoLayout.iobLayout.setOnClickListener { activity?.let { OKDialog.show(it, rh.gs(R.string.iob), iobDialogText) } }
// cob
var cobText = displayText ?: rh.gs(R.string.value_unavailable_short)
val constraintsProcessed = loop.lastRun?.constraintsProcessed val constraintsProcessed = loop.lastRun?.constraintsProcessed
val lastRun = loop.lastRun val lastRun = loop.lastRun
if (config.APS && constraintsProcessed != null && lastRun != null) { if (config.APS && constraintsProcessed != null && lastRun != null) {
if (constraintsProcessed.carbsReq > 0) { if (constraintsProcessed.carbsReq > 0) {
//only display carbsreq when carbs have not been entered recently //only display carbsreq when carbs have not been entered recently
if (overviewData.lastCarbsTime < lastRun.lastAPSRun) { if (lastCarbsTime < lastRun.lastAPSRun) {
cobText += " | " + constraintsProcessed.carbsReq + " " + rh.gs(R.string.required) cobText += " | " + constraintsProcessed.carbsReq + " " + rh.gs(R.string.required)
}
if (carbAnimation?.isRunning == false)
carbAnimation?.start()
} else {
carbAnimation?.stop()
carbAnimation?.selectDrawable(0)
} }
if (carbAnimation?.isRunning == false)
carbAnimation?.start()
} else {
carbAnimation?.stop()
carbAnimation?.selectDrawable(0)
} }
binding.infoLayout.cob.text = cobText
} }
binding.infoLayout.cob.text = cobText
} }
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
fun updateTemporaryTarget() { fun updateTemporaryTarget() {
_binding ?: return
val units = profileFunction.getUnits() val units = profileFunction.getUnits()
val tempTarget = overviewData.temporaryTarget val tempTarget = overviewData.temporaryTarget
if (tempTarget != null) { runOnUiThread {
setRibbon( _binding ?: return@runOnUiThread
binding.tempTarget, if (tempTarget != null) {
R.attr.ribbonTextWarningColor, setRibbon(
R.attr.ribbonWarningColor, binding.tempTarget,
Profile.toTargetRangeString(tempTarget.lowTarget, tempTarget.highTarget, GlucoseUnit.MGDL, units) + " " + dateUtil.untilString(tempTarget.end, rh) R.attr.ribbonTextWarningColor,
) R.attr.ribbonWarningColor,
} else { Profile.toTargetRangeString(tempTarget.lowTarget, tempTarget.highTarget, GlucoseUnit.MGDL, units) + " " + dateUtil.untilString(tempTarget.end, rh)
// If the target is not the same as set in the profile then oref has overridden it )
profileFunction.getProfile()?.let { profile -> } else {
val targetUsed = loop.lastRun?.constraintsProcessed?.targetBG ?: 0.0 // If the target is not the same as set in the profile then oref has overridden it
profileFunction.getProfile()?.let { profile ->
val targetUsed = loop.lastRun?.constraintsProcessed?.targetBG ?: 0.0
if (targetUsed != 0.0 && abs(profile.getTargetMgdl() - targetUsed) > 0.01) { if (targetUsed != 0.0 && abs(profile.getTargetMgdl() - targetUsed) > 0.01) {
aapsLogger.debug("Adjusted target. Profile: ${profile.getTargetMgdl()} APS: $targetUsed") aapsLogger.debug("Adjusted target. Profile: ${profile.getTargetMgdl()} APS: $targetUsed")
setRibbon( setRibbon(
binding.tempTarget, binding.tempTarget,
R.attr.ribbonTextWarningColor, R.attr.ribbonTextWarningColor,
R.attr.tempTargetBackgroundColor, R.attr.tempTargetBackgroundColor,
Profile.toTargetRangeString(targetUsed, targetUsed, GlucoseUnit.MGDL, units) Profile.toTargetRangeString(targetUsed, targetUsed, GlucoseUnit.MGDL, units)
) )
} else { } else {
setRibbon( setRibbon(
binding.tempTarget, binding.tempTarget,
R.attr.ribbonTextDefaultColor, R.attr.ribbonTextDefaultColor,
R.attr.ribbonDefaultColor, R.attr.ribbonDefaultColor,
Profile.toTargetRangeString(profile.getTargetLowMgdl(), profile.getTargetHighMgdl(), GlucoseUnit.MGDL, units) Profile.toTargetRangeString(profile.getTargetLowMgdl(), profile.getTargetHighMgdl(), GlucoseUnit.MGDL, units)
) )
}
} }
} }
} }

View file

@ -19,7 +19,7 @@ import info.nightscout.androidaps.interfaces.Loop
import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP
import javax.inject.Inject import javax.inject.Inject

View file

@ -1,6 +1,5 @@
package info.nightscout.androidaps.plugins.general.overview package info.nightscout.androidaps.plugins.general.overview
import android.graphics.Color
import android.widget.TextView import android.widget.TextView
import androidx.annotation.StringRes import androidx.annotation.StringRes
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
@ -97,7 +96,7 @@ class StatusLightHandler @Inject constructor(
if (level > OmnipodConstants.MAX_RESERVOIR_READING) { if (level > OmnipodConstants.MAX_RESERVOIR_READING) {
@Suppress("SetTextI18n") @Suppress("SetTextI18n")
view?.text = " 50+$units" view?.text = " 50+$units"
view?.setTextColor(Color.WHITE) view?.setTextColor(rh.gac(view.context, R.attr.defaultTextColor))
} else { } else {
handleLevel(view, criticalSetting, criticalDefaultValue, warnSetting, warnDefaultValue, level, units) handleLevel(view, criticalSetting, criticalDefaultValue, warnSetting, warnDefaultValue, level, units)
} }

View file

@ -73,12 +73,16 @@ class GraphData(
} }
fun addBasals() { fun addBasals() {
val scale = defaultValueHelper.determineLowLine() / maxY / 1.2 overviewData.basalScale.multiplier = 1.0 // get unscaled Y-values for max calculation
var maxBasalValue = maxOf(0.1, overviewData.baseBasalGraphSeries.highestValueY, overviewData.tempBasalGraphSeries.highestValueY)
maxBasalValue = maxOf(maxBasalValue, overviewData.basalLineGraphSeries.highestValueY, overviewData.absoluteBasalGraphSeries.highestValueY)
addSeries(overviewData.baseBasalGraphSeries) addSeries(overviewData.baseBasalGraphSeries)
addSeries(overviewData.tempBasalGraphSeries) addSeries(overviewData.tempBasalGraphSeries)
addSeries(overviewData.basalLineGraphSeries) addSeries(overviewData.basalLineGraphSeries)
addSeries(overviewData.absoluteBasalGraphSeries) addSeries(overviewData.absoluteBasalGraphSeries)
overviewData.basalScale.multiplier = maxY * scale / overviewData.maxBasalValueFound maxY = max(maxY, defaultValueHelper.determineHighLine())
val scale = defaultValueHelper.determineLowLine() / maxY / 1.2
overviewData.basalScale.multiplier = maxY * scale / maxBasalValue
} }
fun addTargetLine() { fun addTargetLine() {

View file

@ -17,12 +17,12 @@ import info.nightscout.androidaps.databinding.OverviewNotificationItemBinding
import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.IconsProvider import info.nightscout.androidaps.interfaces.IconsProvider
import info.nightscout.androidaps.interfaces.NotificationHolder import info.nightscout.androidaps.interfaces.NotificationHolder
import info.nightscout.shared.logging.AAPSLogger import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.shared.logging.LTag
import info.nightscout.androidaps.plugins.general.overview.events.EventUpdateOverviewNotification import info.nightscout.androidaps.plugins.general.overview.events.EventUpdateOverviewNotification
import info.nightscout.androidaps.services.AlarmSoundServiceHelper import info.nightscout.androidaps.services.AlarmSoundServiceHelper
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP
import java.util.* import java.util.*
import javax.inject.Inject import javax.inject.Inject
@ -68,7 +68,7 @@ class NotificationStore @Inject constructor(
store.add(n) store.add(n)
if (sp.getBoolean(R.string.key_raise_notifications_as_android_notifications, true) && n !is NotificationWithAction) if (sp.getBoolean(R.string.key_raise_notifications_as_android_notifications, true) && n !is NotificationWithAction)
raiseSystemNotification(n) raiseSystemNotification(n)
if (n.soundId != null && n.soundId != 0) alarmSoundServiceHelper.startAlarm(context, n.soundId!!) if (n.soundId != null && n.soundId != 0) alarmSoundServiceHelper.startAlarm(context, n.soundId!!, n.text)
Collections.sort(store, NotificationComparator()) Collections.sort(store, NotificationComparator())
return true return true
} }
@ -77,7 +77,7 @@ class NotificationStore @Inject constructor(
fun remove(id: Int): Boolean { fun remove(id: Int): Boolean {
for (i in store.indices) { for (i in store.indices) {
if (store[i].id == id) { if (store[i].id == id) {
if (store[i].soundId != null) alarmSoundServiceHelper.stopService(context) if (store[i].soundId != null) alarmSoundServiceHelper.stopService(context, "Removed " + store[i].text)
aapsLogger.debug(LTag.NOTIFICATION, "Notification removed: " + store[i].text) aapsLogger.debug(LTag.NOTIFICATION, "Notification removed: " + store[i].text)
store.removeAt(i) store.removeAt(i)
return true return true
@ -92,7 +92,7 @@ class NotificationStore @Inject constructor(
while (i < store.size) { while (i < store.size) {
val n = store[i] val n = store[i]
if (n.validTo != 0L && n.validTo < System.currentTimeMillis()) { if (n.validTo != 0L && n.validTo < System.currentTimeMillis()) {
if (store[i].soundId != null) alarmSoundServiceHelper.stopService(context) if (store[i].soundId != null) alarmSoundServiceHelper.stopService(context, "Expired " + store[i].text)
aapsLogger.debug(LTag.NOTIFICATION, "Notification expired: " + store[i].text) aapsLogger.debug(LTag.NOTIFICATION, "Notification expired: " + store[i].text)
store.removeAt(i) store.removeAt(i)
i-- i--

View file

@ -966,6 +966,7 @@ class SmsCommunicatorPlugin @Inject constructor(
var keyTarget = 0 var keyTarget = 0
var defaultTargetMMOL = 0.0 var defaultTargetMMOL = 0.0
var defaultTargetMGDL = 0.0 var defaultTargetMGDL = 0.0
var reason = TemporaryTarget.Reason.EATING_SOON
when { when {
isMeal -> { isMeal -> {
keyDuration = R.string.key_eatingsoon_duration keyDuration = R.string.key_eatingsoon_duration
@ -973,6 +974,7 @@ class SmsCommunicatorPlugin @Inject constructor(
keyTarget = R.string.key_eatingsoon_target keyTarget = R.string.key_eatingsoon_target
defaultTargetMMOL = Constants.defaultEatingSoonTTmmol defaultTargetMMOL = Constants.defaultEatingSoonTTmmol
defaultTargetMGDL = Constants.defaultEatingSoonTTmgdl defaultTargetMGDL = Constants.defaultEatingSoonTTmgdl
reason = TemporaryTarget.Reason.EATING_SOON
} }
isActivity -> { isActivity -> {
@ -981,6 +983,7 @@ class SmsCommunicatorPlugin @Inject constructor(
keyTarget = R.string.key_activity_target keyTarget = R.string.key_activity_target
defaultTargetMMOL = Constants.defaultActivityTTmmol defaultTargetMMOL = Constants.defaultActivityTTmmol
defaultTargetMGDL = Constants.defaultActivityTTmgdl defaultTargetMGDL = Constants.defaultActivityTTmgdl
reason = TemporaryTarget.Reason.ACTIVITY
} }
isHypo -> { isHypo -> {
@ -989,6 +992,7 @@ class SmsCommunicatorPlugin @Inject constructor(
keyTarget = R.string.key_hypo_target keyTarget = R.string.key_hypo_target
defaultTargetMMOL = Constants.defaultHypoTTmmol defaultTargetMMOL = Constants.defaultHypoTTmmol
defaultTargetMGDL = Constants.defaultHypoTTmgdl defaultTargetMGDL = Constants.defaultHypoTTmgdl
reason = TemporaryTarget.Reason.HYPOGLYCEMIA
} }
} }
var ttDuration = sp.getInt(keyDuration, defaultTargetDuration) var ttDuration = sp.getInt(keyDuration, defaultTargetDuration)
@ -999,7 +1003,7 @@ class SmsCommunicatorPlugin @Inject constructor(
disposable += repository.runTransactionForResult(InsertAndCancelCurrentTemporaryTargetTransaction( disposable += repository.runTransactionForResult(InsertAndCancelCurrentTemporaryTargetTransaction(
timestamp = dateUtil.now(), timestamp = dateUtil.now(),
duration = TimeUnit.MINUTES.toMillis(ttDuration.toLong()), duration = TimeUnit.MINUTES.toMillis(ttDuration.toLong()),
reason = TemporaryTarget.Reason.EATING_SOON, reason = reason,
lowTarget = Profile.toMgdl(tt, profileFunction.getUnits()), lowTarget = Profile.toMgdl(tt, profileFunction.getUnits()),
highTarget = Profile.toMgdl(tt, profileFunction.getUnits()) highTarget = Profile.toMgdl(tt, profileFunction.getUnits())
)).subscribe({ result -> )).subscribe({ result ->

View file

@ -30,6 +30,7 @@ import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.androidaps.workflow.CalculationWorkflow import info.nightscout.androidaps.workflow.CalculationWorkflow
import info.nightscout.androidaps.events.Event import info.nightscout.androidaps.events.Event
import info.nightscout.androidaps.utils.MidnightTime
import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag import info.nightscout.shared.logging.LTag
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP
@ -127,10 +128,20 @@ class IobCobCalculatorPlugin @Inject constructor(
} }
private fun resetDataAndRunCalculation(reason: String, event: Event?) { private fun resetDataAndRunCalculation(reason: String, event: Event?) {
calculationWorkflow.stopCalculation(CalculationWorkflow.MAIN_CALCULATION,reason) calculationWorkflow.stopCalculation(CalculationWorkflow.MAIN_CALCULATION, reason)
clearCache() clearCache()
ads.reset() ads.reset()
calculationWorkflow.runCalculation(CalculationWorkflow.MAIN_CALCULATION,this, overviewData, reason, System.currentTimeMillis(), bgDataReload = false, limitDataToOldestAvailable = true, cause = event, runLoop = true) calculationWorkflow.runCalculation(
CalculationWorkflow.MAIN_CALCULATION,
this,
overviewData,
reason,
System.currentTimeMillis(),
bgDataReload = false,
limitDataToOldestAvailable = true,
cause = event,
runLoop = true
)
} }
override fun clearCache() { override fun clearCache() {
@ -363,18 +374,21 @@ class IobCobCalculatorPlugin @Inject constructor(
scheduledHistoryPost?.cancel(false) scheduledHistoryPost?.cancel(false)
// prepare task for execution in 1 sec // prepare task for execution in 1 sec
scheduledEvent = event scheduledEvent = event
scheduledHistoryPost = historyWorker.schedule({ scheduledHistoryPost = historyWorker.schedule(
synchronized(this) { {
aapsLogger.debug(LTag.AUTOSENS, "Running newHistoryData") synchronized(this) {
newHistoryData( aapsLogger.debug(LTag.AUTOSENS, "Running newHistoryData")
event.oldDataTimestamp, repository.clearCachedData(MidnightTime.calc(event.oldDataTimestamp))
event.reloadBgData, newHistoryData(
if (event.newestGlucoseValue != null) EventNewBG(event.newestGlucoseValue) else event event.oldDataTimestamp,
) event.reloadBgData,
scheduledEvent = null if (event.newestGlucoseValue != null) EventNewBG(event.newestGlucoseValue) else event
scheduledHistoryPost = null )
} scheduledEvent = null
}, 1L, TimeUnit.SECONDS) scheduledHistoryPost = null
}
}, 1L, TimeUnit.SECONDS
)
} else { } else {
// asked reload is newer -> adjust params only // asked reload is newer -> adjust params only
scheduledEvent?.let { scheduledEvent?.let {
@ -391,7 +405,7 @@ class IobCobCalculatorPlugin @Inject constructor(
// When historical data is changed (coming from NS etc) finished calculations after this date must be invalidated // When historical data is changed (coming from NS etc) finished calculations after this date must be invalidated
private fun newHistoryData(oldDataTimestamp: Long, bgDataReload: Boolean, event: Event) { private fun newHistoryData(oldDataTimestamp: Long, bgDataReload: Boolean, event: Event) {
//log.debug("Locking onNewHistoryData"); //log.debug("Locking onNewHistoryData");
calculationWorkflow.stopCalculation(CalculationWorkflow.MAIN_CALCULATION,"onEventNewHistoryData") calculationWorkflow.stopCalculation(CalculationWorkflow.MAIN_CALCULATION, "onEventNewHistoryData")
synchronized(dataLock) { synchronized(dataLock) {
// clear up 5 min back for proper COB calculation // clear up 5 min back for proper COB calculation
@ -415,7 +429,7 @@ class IobCobCalculatorPlugin @Inject constructor(
} }
ads.newHistoryData(time, aapsLogger, dateUtil) ads.newHistoryData(time, aapsLogger, dateUtil)
} }
calculationWorkflow.runCalculation(CalculationWorkflow.MAIN_CALCULATION,this, overviewData, event.javaClass.simpleName, System.currentTimeMillis(), bgDataReload, true, event, runLoop = true) calculationWorkflow.runCalculation(CalculationWorkflow.MAIN_CALCULATION, this, overviewData, event.javaClass.simpleName, System.currentTimeMillis(), bgDataReload, true, event, runLoop = true)
//log.debug("Releasing onNewHistoryData"); //log.debug("Releasing onNewHistoryData");
} }

View file

@ -30,7 +30,7 @@ import info.nightscout.androidaps.utils.DecimalFormatter
import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.Profiler import info.nightscout.androidaps.utils.Profiler
import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.workflow.CalculationWorkflow import info.nightscout.androidaps.workflow.CalculationWorkflow
import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.AAPSLogger

View file

@ -28,7 +28,7 @@ import info.nightscout.androidaps.utils.DecimalFormatter
import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.Profiler import info.nightscout.androidaps.utils.Profiler
import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.workflow.CalculationWorkflow import info.nightscout.androidaps.workflow.CalculationWorkflow
import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.AAPSLogger

View file

@ -10,13 +10,10 @@ import info.nightscout.androidaps.R
import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.GlucoseValue import info.nightscout.androidaps.database.entities.GlucoseValue
import info.nightscout.androidaps.database.transactions.CgmSourceTransaction import info.nightscout.androidaps.database.transactions.CgmSourceTransaction
import info.nightscout.androidaps.interfaces.BgSource import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.interfaces.PluginBase
import info.nightscout.androidaps.interfaces.PluginDescription
import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.receivers.DataWorker import info.nightscout.androidaps.receivers.DataWorker
import info.nightscout.androidaps.receivers.Intents import info.nightscout.androidaps.receivers.Intents
import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag import info.nightscout.shared.logging.LTag
import javax.inject.Inject import javax.inject.Inject
@ -26,7 +23,9 @@ import javax.inject.Singleton
class AidexPlugin @Inject constructor( class AidexPlugin @Inject constructor(
injector: HasAndroidInjector, injector: HasAndroidInjector,
rh: ResourceHelper, rh: ResourceHelper,
aapsLogger: AAPSLogger aapsLogger: AAPSLogger,
private val buildHelper: BuildHelper,
private val config: Config
) : PluginBase( ) : PluginBase(
PluginDescription() PluginDescription()
.mainType(PluginType.BGSOURCE) .mainType(PluginType.BGSOURCE)
@ -49,6 +48,11 @@ class AidexPlugin @Inject constructor(
return advancedFiltering return advancedFiltering
} }
// Allow only for pumpcontrol or dev & engineering_mode
override fun specialEnableCondition(): Boolean {
return config.APS.not() || buildHelper.isDev() && buildHelper.isEngineeringMode()
}
// cannot be inner class because of needed injection // cannot be inner class because of needed injection
class AidexWorker( class AidexWorker(
context: Context, context: Context,

View file

@ -35,7 +35,7 @@ import info.nightscout.androidaps.utils.AndroidPermission
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.HtmlHelper import info.nightscout.androidaps.utils.HtmlHelper
import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.AAPSLogger
@ -327,7 +327,7 @@ class CommandQueueImplementation @Inject constructor(
} }
removeAll(CommandType.BOLUS) removeAll(CommandType.BOLUS)
removeAll(CommandType.SMB_BOLUS) removeAll(CommandType.SMB_BOLUS)
Thread { activePlugin.activePump.stopBolusDelivering() }.run() Thread { activePlugin.activePump.stopBolusDelivering() }.start()
} }
// returns true if command is queued // returns true if command is queued

View file

@ -12,15 +12,15 @@ import info.nightscout.androidaps.database.transactions.InsertTherapyEventAnnoun
import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.shared.logging.AAPSLogger import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.shared.logging.LTag
import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin
import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP
import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.kotlin.plusAssign import io.reactivex.rxjava3.kotlin.plusAssign
@ -128,7 +128,7 @@ class LocalAlertUtils @Inject constructor(
rxBus.send(EventNewNotification(n)) rxBus.send(EventNewNotification(n))
uel.log(Action.CAREPORTAL, Sources.Aaps, rh.gs(R.string.missed_bg_readings), ValueWithUnit.TherapyEventType(TherapyEvent.Type.ANNOUNCEMENT)) uel.log(Action.CAREPORTAL, Sources.Aaps, rh.gs(R.string.missed_bg_readings), ValueWithUnit.TherapyEventType(TherapyEvent.Type.ANNOUNCEMENT))
if (sp.getBoolean(R.string.key_ns_create_announcements_from_errors, true)) { if (sp.getBoolean(R.string.key_ns_create_announcements_from_errors, true)) {
n.text?.let { disposable += repository.runTransaction(InsertTherapyEventAnnouncementTransaction(it)).subscribe() } disposable += repository.runTransaction(InsertTherapyEventAnnouncementTransaction(n.text)).subscribe()
} }
} else if (dateUtil.isOlderThan(bgReading.timestamp, 5).not()) { } else if (dateUtil.isOlderThan(bgReading.timestamp, 5).not()) {
rxBus.send(EventDismissNotification(Notification.BG_READINGS_MISSED)) rxBus.send(EventDismissNotification(Notification.BG_READINGS_MISSED))

View file

@ -1,6 +1,7 @@
package info.nightscout.androidaps.utils.buildHelper package info.nightscout.androidaps.utils.buildHelper
import info.nightscout.androidaps.BuildConfig import info.nightscout.androidaps.BuildConfig
import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.plugins.general.maintenance.PrefFileListProvider import info.nightscout.androidaps.plugins.general.maintenance.PrefFileListProvider
import java.io.File import java.io.File

View file

@ -11,6 +11,8 @@ import android.widget.TableRow
import android.widget.TextView import android.widget.TextView
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.ValueWrapper
import info.nightscout.androidaps.database.embedments.InterfaceIDs
import info.nightscout.androidaps.database.entities.Bolus import info.nightscout.androidaps.database.entities.Bolus
import info.nightscout.androidaps.database.entities.TotalDailyDose import info.nightscout.androidaps.database.entities.TotalDailyDose
import info.nightscout.androidaps.extensions.convertedToAbsolute import info.nightscout.androidaps.extensions.convertedToAbsolute
@ -19,10 +21,10 @@ import info.nightscout.androidaps.extensions.toTableRowHeader
import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.IobCobCalculator import info.nightscout.androidaps.interfaces.IobCobCalculator
import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.MidnightTime import info.nightscout.androidaps.utils.MidnightTime
import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag import info.nightscout.shared.logging.LTag
import javax.inject.Inject import javax.inject.Inject
@ -38,48 +40,62 @@ class TddCalculator @Inject constructor(
) { ) {
fun calculate(days: Long): LongSparseArray<TotalDailyDose> { fun calculate(days: Long): LongSparseArray<TotalDailyDose> {
val startTime = MidnightTime.calc(dateUtil.now() - T.days(days).msecs()) var startTime = MidnightTime.calc(dateUtil.now() - T.days(days).msecs())
val endTime = MidnightTime.calc(dateUtil.now()) val endTime = MidnightTime.calc(dateUtil.now())
val result = LongSparseArray<TotalDailyDose>() val result = LongSparseArray<TotalDailyDose>()
repository.getBolusesDataFromTimeToTime(startTime, endTime, true).blockingGet() // Try to load cached values
.filter { it.type != Bolus.Type.PRIMING } while (startTime < endTime) {
.forEach { t -> val tdd = repository.getCalculatedTotalDailyDose(startTime).blockingGet()
val midnight = MidnightTime.calc(t.timestamp) if (tdd is ValueWrapper.Existing) result.put(startTime, tdd.value)
val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight) else break
tdd.bolusAmount += t.amount startTime += T.hours(24).msecs()
result.put(midnight, tdd)
}
repository.getCarbsDataFromTimeToTimeExpanded(startTime, endTime, true).blockingGet().forEach { t ->
val midnight = MidnightTime.calc(t.timestamp)
val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
tdd.carbs += t.amount
result.put(midnight, tdd)
} }
val calculationStep = T.mins(5).msecs() if (endTime > startTime) {
val tempBasals = iobCobCalculator.getTempBasalIncludingConvertedExtendedForRange(startTime, endTime, calculationStep) repository.getBolusesDataFromTimeToTime(startTime, endTime, true).blockingGet()
for (t in startTime until endTime step calculationStep) { .filter { it.type != Bolus.Type.PRIMING }
val midnight = MidnightTime.calc(t) .forEach { t ->
val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight) val midnight = MidnightTime.calc(t.timestamp)
val tbr = tempBasals[t] val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
val profile = profileFunction.getProfile(t) ?: continue tdd.bolusAmount += t.amount
val absoluteRate = tbr?.convertedToAbsolute(t, profile) ?: profile.getBasal(t) result.put(midnight, tdd)
tdd.basalAmount += absoluteRate / T.mins(60).msecs().toDouble() * calculationStep.toDouble() }
repository.getCarbsDataFromTimeToTimeExpanded(startTime, endTime, true).blockingGet().forEach { t ->
if (!activePlugin.activePump.isFakingTempsByExtendedBoluses) { val midnight = MidnightTime.calc(t.timestamp)
// they are not included in TBRs val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
val eb = iobCobCalculator.getExtendedBolus(t) tdd.carbs += t.amount
val absoluteEbRate = eb?.rate ?: 0.0 result.put(midnight, tdd)
tdd.bolusAmount += absoluteEbRate / T.mins(60).msecs().toDouble() * calculationStep.toDouble() }
val calculationStep = T.mins(5).msecs()
val tempBasals = iobCobCalculator.getTempBasalIncludingConvertedExtendedForRange(startTime, endTime, calculationStep)
for (t in startTime until endTime step calculationStep) {
val midnight = MidnightTime.calc(t)
val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
val tbr = tempBasals[t]
val profile = profileFunction.getProfile(t) ?: continue
val absoluteRate = tbr?.convertedToAbsolute(t, profile) ?: profile.getBasal(t)
tdd.basalAmount += absoluteRate / T.mins(60).msecs().toDouble() * calculationStep.toDouble()
if (!activePlugin.activePump.isFakingTempsByExtendedBoluses) {
// they are not included in TBRs
val eb = iobCobCalculator.getExtendedBolus(t)
val absoluteEbRate = eb?.rate ?: 0.0
tdd.bolusAmount += absoluteEbRate / T.mins(60).msecs().toDouble() * calculationStep.toDouble()
}
result.put(midnight, tdd)
} }
result.put(midnight, tdd)
} }
for (i in 0 until result.size()) { for (i in 0 until result.size()) {
val tdd = result.valueAt(i) val tdd = result.valueAt(i)
tdd.totalAmount = tdd.bolusAmount + tdd.basalAmount tdd.totalAmount = tdd.bolusAmount + tdd.basalAmount
if (tdd.interfaceIDs.pumpType != InterfaceIDs.PumpType.CACHE) {
tdd.interfaceIDs.pumpType = InterfaceIDs.PumpType.CACHE
aapsLogger.debug(LTag.CORE, "Storing TDD $tdd")
repository.createTotalDailyDose(tdd)
}
} }
aapsLogger.debug(LTag.CORE, result.toString())
return result return result
} }
@ -91,22 +107,13 @@ class TddCalculator @Inject constructor(
repository.getBolusesDataFromTimeToTime(startTime, endTime, true).blockingGet() repository.getBolusesDataFromTimeToTime(startTime, endTime, true).blockingGet()
.filter { it.type != Bolus.Type.PRIMING } .filter { it.type != Bolus.Type.PRIMING }
.forEach { t -> .forEach { t ->
//val midnight = MidnightTime.calc(t.timestamp)
//val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
tdd.bolusAmount += t.amount tdd.bolusAmount += t.amount
//result.put(midnight, tdd)
} }
repository.getCarbsDataFromTimeToTimeExpanded(startTime, endTime, true).blockingGet().forEach { t -> repository.getCarbsDataFromTimeToTimeExpanded(startTime, endTime, true).blockingGet().forEach { t ->
//val midnight = MidnightTime.calc(t.timestamp)
//val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
tdd.carbs += t.amount tdd.carbs += t.amount
//result.put(midnight, tdd)
} }
val calculationStep = T.mins(5).msecs() val calculationStep = T.mins(5).msecs()
for (t in startTime until endTime step calculationStep) { for (t in startTime until endTime step calculationStep) {
//val midnight = MidnightTime.calc(t)
//val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
val tbr = iobCobCalculator.getTempBasalIncludingConvertedExtended(t) val tbr = iobCobCalculator.getTempBasalIncludingConvertedExtended(t)
val profile = profileFunction.getProfile(t) ?: continue val profile = profileFunction.getProfile(t) ?: continue
val absoluteRate = tbr?.convertedToAbsolute(t, profile) ?: profile.getBasal(t) val absoluteRate = tbr?.convertedToAbsolute(t, profile) ?: profile.getBasal(t)
@ -118,13 +125,8 @@ class TddCalculator @Inject constructor(
val absoluteEbRate = eb?.rate ?: 0.0 val absoluteEbRate = eb?.rate ?: 0.0
tdd.bolusAmount += absoluteEbRate / 60.0 * 5.0 tdd.bolusAmount += absoluteEbRate / 60.0 * 5.0
} }
//result.put(midnight, tdd)
} }
//for (i in 0 until tdd.size()) {
//val tdd = result.valueAt(i)
tdd.totalAmount = tdd.bolusAmount + tdd.basalAmount tdd.totalAmount = tdd.bolusAmount + tdd.basalAmount
//}
aapsLogger.debug(LTag.CORE, tdd.toString()) aapsLogger.debug(LTag.CORE, tdd.toString())
return tdd return tdd
} }
@ -133,27 +135,16 @@ class TddCalculator @Inject constructor(
val startTime = dateUtil.now() - T.hours(hour = 24).msecs() val startTime = dateUtil.now() - T.hours(hour = 24).msecs()
val endTime = dateUtil.now() val endTime = dateUtil.now()
val tdd = TotalDailyDose(timestamp = startTime) val tdd = TotalDailyDose(timestamp = startTime)
//val result = TotalDailyDose()
repository.getBolusesDataFromTimeToTime(startTime, endTime, true).blockingGet() repository.getBolusesDataFromTimeToTime(startTime, endTime, true).blockingGet()
.filter { it.type != Bolus.Type.PRIMING } .filter { it.type != Bolus.Type.PRIMING }
.forEach { t -> .forEach { t ->
//val midnight = MidnightTime.calc(t.timestamp)
//val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
tdd.bolusAmount += t.amount tdd.bolusAmount += t.amount
//result.put(midnight, tdd)
} }
repository.getCarbsDataFromTimeToTimeExpanded(startTime, endTime, true).blockingGet().forEach { t -> repository.getCarbsDataFromTimeToTimeExpanded(startTime, endTime, true).blockingGet().forEach { t ->
//val midnight = MidnightTime.calc(t.timestamp)
//val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
tdd.carbs += t.amount tdd.carbs += t.amount
//result.put(midnight, tdd)
} }
val calculationStep = T.mins(5).msecs() val calculationStep = T.mins(5).msecs()
//val tempBasals = iobCobCalculator.getTempBasalIncludingConvertedExtendedForRange(startTime, endTime, calculationStep)
for (t in startTime until endTime step calculationStep) { for (t in startTime until endTime step calculationStep) {
//val midnight = MidnightTime.calc(t)
//val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
val tbr = iobCobCalculator.getTempBasalIncludingConvertedExtended(t) val tbr = iobCobCalculator.getTempBasalIncludingConvertedExtended(t)
val profile = profileFunction.getProfile(t) ?: continue val profile = profileFunction.getProfile(t) ?: continue
val absoluteRate = tbr?.convertedToAbsolute(t, profile) ?: profile.getBasal(t) val absoluteRate = tbr?.convertedToAbsolute(t, profile) ?: profile.getBasal(t)
@ -165,13 +156,8 @@ class TddCalculator @Inject constructor(
val absoluteEbRate = eb?.rate ?: 0.0 val absoluteEbRate = eb?.rate ?: 0.0
tdd.bolusAmount += absoluteEbRate / 60.0 * 5.0 tdd.bolusAmount += absoluteEbRate / 60.0 * 5.0
} }
//result.put(midnight, tdd)
} }
//for (i in 0 until tdd.size()) {
//val tdd = result.valueAt(i)
tdd.totalAmount = tdd.bolusAmount + tdd.basalAmount tdd.totalAmount = tdd.bolusAmount + tdd.basalAmount
//}
aapsLogger.debug(LTag.CORE, tdd.toString()) aapsLogger.debug(LTag.CORE, tdd.toString())
return tdd return tdd
} }

View file

@ -47,7 +47,6 @@ class PrepareBasalDataWorker(
?: return Result.failure(workDataOf("Error" to "missing input data")) ?: return Result.failure(workDataOf("Error" to "missing input data"))
rxBus.send(EventIobCalculationProgress(CalculationWorkflow.ProgressData.PREPARE_BASAL_DATA, 0, null)) rxBus.send(EventIobCalculationProgress(CalculationWorkflow.ProgressData.PREPARE_BASAL_DATA, 0, null))
data.overviewData.maxBasalValueFound = 0.0
val baseBasalArray: MutableList<ScaledDataPoint> = ArrayList() val baseBasalArray: MutableList<ScaledDataPoint> = ArrayList()
val tempBasalArray: MutableList<ScaledDataPoint> = ArrayList() val tempBasalArray: MutableList<ScaledDataPoint> = ArrayList()
val basalLineArray: MutableList<ScaledDataPoint> = ArrayList() val basalLineArray: MutableList<ScaledDataPoint> = ArrayList()
@ -104,7 +103,6 @@ class PrepareBasalDataWorker(
lastAbsoluteLineBasal = absoluteLineValue lastAbsoluteLineBasal = absoluteLineValue
lastLineBasal = baseBasalValue lastLineBasal = baseBasalValue
lastTempBasal = tempBasalValue lastTempBasal = tempBasalValue
data.overviewData.maxBasalValueFound = max(data.overviewData.maxBasalValueFound, max(tempBasalValue, baseBasalValue))
time += 60 * 1000L time += 60 * 1000L
} }

View file

@ -140,7 +140,8 @@
android:gravity="start" android:gravity="start"
android:paddingStart="5dp" android:paddingStart="5dp"
android:paddingEnd="5dp" android:paddingEnd="5dp"
android:textSize="14sp" /> android:textSize="14sp"
android:textColor="@color/colorCalculatorButton"/>
</LinearLayout> </LinearLayout>

View file

@ -127,6 +127,7 @@
<string name="end_user_license_agreement">Eindverbruiker Lisensie Ooreenkoms</string> <string name="end_user_license_agreement">Eindverbruiker Lisensie Ooreenkoms</string>
<string name="end_user_license_agreement_text">MOET NIE GEBRUIK WORD OM MEDIESE BESLUITE TE MAAK NIE. DAAR IS GEEN WAARBORG DAT DIE PROGRAM, ONDERWORPE AAN TOEPASSELIKE WETTE EN WETGEWING. TENSY ANDERS GEMELD IN TEKS VOORSIEN DIE KOPIEREG-HOUERS EN / OF ANDER PARTYE DIE PROGRAM \"AS IS\" SONDER ËNIGE WAARBORG VAN ENIGE ORDE, UITDRUKKELIK OF IMPLISIET, INKLUSIEF, MAAR NIE BEPERK TOT DIE IMPLISIETE WAARBORG VAN TOEPAASBAARHEID OF NUT VIR EEN SPESIFIEKE DOEL. DIE TOTALE EN ALLE RISIKOVIR DIE KWALITEIT EN PRESTASIE VAN DIE PROGRAM RUS MET JOUSELF. VIR ENIGE PROGRAM DEFEKTIEWE OF FALINGS MOET JY PERSOONLIK DIE KOSTE EN REGSAANSPREEKLIKHEID DRA VAN ALLE NODIGE AKSIES, DIENS, REPARASIES OF KORREKSIES VIR USELF OF ENIGE DERDE PARTYE EN/OF AKSIES, DIENS, REPARASIES OF KORREKSIES WAT DEUR DIE PROGRAM GEDOEN WAS.</string> <string name="end_user_license_agreement_text">MOET NIE GEBRUIK WORD OM MEDIESE BESLUITE TE MAAK NIE. DAAR IS GEEN WAARBORG DAT DIE PROGRAM, ONDERWORPE AAN TOEPASSELIKE WETTE EN WETGEWING. TENSY ANDERS GEMELD IN TEKS VOORSIEN DIE KOPIEREG-HOUERS EN / OF ANDER PARTYE DIE PROGRAM \"AS IS\" SONDER ËNIGE WAARBORG VAN ENIGE ORDE, UITDRUKKELIK OF IMPLISIET, INKLUSIEF, MAAR NIE BEPERK TOT DIE IMPLISIETE WAARBORG VAN TOEPAASBAARHEID OF NUT VIR EEN SPESIFIEKE DOEL. DIE TOTALE EN ALLE RISIKOVIR DIE KWALITEIT EN PRESTASIE VAN DIE PROGRAM RUS MET JOUSELF. VIR ENIGE PROGRAM DEFEKTIEWE OF FALINGS MOET JY PERSOONLIK DIE KOSTE EN REGSAANSPREEKLIKHEID DRA VAN ALLE NODIGE AKSIES, DIENS, REPARASIES OF KORREKSIES VIR USELF OF ENIGE DERDE PARTYE EN/OF AKSIES, DIENS, REPARASIES OF KORREKSIES WAT DEUR DIE PROGRAM GEDOEN WAS.</string>
<string name="end_user_license_agreement_i_understand">EK VERSTAAN en STEM IN</string> <string name="end_user_license_agreement_i_understand">EK VERSTAAN en STEM IN</string>
<string name="save">Stoor</string>
<string name="reloadprofile">Herlaai profiel</string> <string name="reloadprofile">Herlaai profiel</string>
<string name="smscommunicator">SMS Communicator</string> <string name="smscommunicator">SMS Communicator</string>
<string name="smscommunicator_allowednumbers">Toegelate telefoon nommers</string> <string name="smscommunicator_allowednumbers">Toegelate telefoon nommers</string>

View file

@ -879,5 +879,6 @@
<string name="not_available_full">Недостъпно</string> <string name="not_available_full">Недостъпно</string>
<!-- Theme switcher dark and light mode--> <!-- Theme switcher dark and light mode-->
<!-- WEAR OS--> <!-- WEAR OS-->
<string name="login">Вход</string>
<!-- Aidex Cgms --> <!-- Aidex Cgms -->
</resources> </resources>

View file

@ -154,6 +154,7 @@
<string name="end_user_license_agreement">Acord de llicència per a l\'usuari final</string> <string name="end_user_license_agreement">Acord de llicència per a l\'usuari final</string>
<string name="end_user_license_agreement_text">NO S\'HA D\'UTILITZAR PER A PRENDRE DECISIONS MÈDIQUES. EL PROGRAMA NO TÉ GARANTIA, EN LA MESURA QUE HO PERMET LA LLEI APLICABLE. EXCEPTE QUAN S\'INDIQUI EL CONTRARI PER ESCRIT, ELS PROPIETARIS DEL COPYRIGHT I/O ALTRES PARTS PROPORCIONEN EL PROGRAMA \"TAL QUAL\" SENSE CAP MENA DE GARANTIA, NI IMPLÍCITA NI EXPLÍCITA, INCLOENT, PERÒ SENSE ESTAR LIMITADES A, LES GARANTIES IMPLÍCITES DE COMERCIALITZACIÓ I ADEQUACIÓ A UN OBJECTIU PARTICULAR. US FEU RESPONSABLES TOTALMENT DELS RISCOS EN QUANT A LA QUALITAT I EL RENDIMENT DEL PROGRAMA. SI EL PROGRAMA FOS DEFECTUÓS, VOSALTRES ASSUMIU EL COST DE TOT SERVEI, REPARACIÓ O CORRECCIÓ.</string> <string name="end_user_license_agreement_text">NO S\'HA D\'UTILITZAR PER A PRENDRE DECISIONS MÈDIQUES. EL PROGRAMA NO TÉ GARANTIA, EN LA MESURA QUE HO PERMET LA LLEI APLICABLE. EXCEPTE QUAN S\'INDIQUI EL CONTRARI PER ESCRIT, ELS PROPIETARIS DEL COPYRIGHT I/O ALTRES PARTS PROPORCIONEN EL PROGRAMA \"TAL QUAL\" SENSE CAP MENA DE GARANTIA, NI IMPLÍCITA NI EXPLÍCITA, INCLOENT, PERÒ SENSE ESTAR LIMITADES A, LES GARANTIES IMPLÍCITES DE COMERCIALITZACIÓ I ADEQUACIÓ A UN OBJECTIU PARTICULAR. US FEU RESPONSABLES TOTALMENT DELS RISCOS EN QUANT A LA QUALITAT I EL RENDIMENT DEL PROGRAMA. SI EL PROGRAMA FOS DEFECTUÓS, VOSALTRES ASSUMIU EL COST DE TOT SERVEI, REPARACIÓ O CORRECCIÓ.</string>
<string name="end_user_license_agreement_i_understand">ENTENC I ACCEPTO</string> <string name="end_user_license_agreement_i_understand">ENTENC I ACCEPTO</string>
<string name="save">Desar</string>
<string name="reloadprofile">Recarregar perfil</string> <string name="reloadprofile">Recarregar perfil</string>
<string name="smscommunicator">Comunicador SMS</string> <string name="smscommunicator">Comunicador SMS</string>
<string name="smscommunicator_allowednumbers">Nrs. de telèfon permesos</string> <string name="smscommunicator_allowednumbers">Nrs. de telèfon permesos</string>
@ -314,5 +315,6 @@
<!-- SMS Communicator & OTP Authenticator --> <!-- SMS Communicator & OTP Authenticator -->
<!-- Theme switcher dark and light mode--> <!-- Theme switcher dark and light mode-->
<!-- WEAR OS--> <!-- WEAR OS-->
<string name="login">Iniciar sessió</string>
<!-- Aidex Cgms --> <!-- Aidex Cgms -->
</resources> </resources>

View file

@ -159,6 +159,7 @@
<string name="end_user_license_agreement">Endbenutzervereinbarung</string> <string name="end_user_license_agreement">Endbenutzervereinbarung</string>
<string name="end_user_license_agreement_text">DAS PROGRAMM DARF NICHT FÜR MEDIZINISCHE ENTSCHEIDUNGEN BENUTZT WERDEN. ES GIBT IN DIESEM PROJEKT KEINE GEWÄHRLEISTUNG ODER GARANTIERTE UNTERSTÜTZUNG IN IRGENDEINER ART. WENN DU DICH ENTSCHEIDEST, ES ZU NUTZEN, HÄNGT DIE QUALITÄT UND LEISTUNGSFÄHIGKEIT DIESES PROJEKTES VON DIR SELBST AB. ES WIRD \"WIE BESEHEN\" ZUR VERFÜGUNG GESTELLT. SOLLTE SICH DAS PROGRAMM ALS FEHLERHAFT ERWEISEN, ÜBERNIMMST DU ALLE NOTWENDIGEN KRANKHEITSKOSTEN, SERVICELEISTUNGEN, REPARATUREN ODER KORREKTUREN.</string> <string name="end_user_license_agreement_text">DAS PROGRAMM DARF NICHT FÜR MEDIZINISCHE ENTSCHEIDUNGEN BENUTZT WERDEN. ES GIBT IN DIESEM PROJEKT KEINE GEWÄHRLEISTUNG ODER GARANTIERTE UNTERSTÜTZUNG IN IRGENDEINER ART. WENN DU DICH ENTSCHEIDEST, ES ZU NUTZEN, HÄNGT DIE QUALITÄT UND LEISTUNGSFÄHIGKEIT DIESES PROJEKTES VON DIR SELBST AB. ES WIRD \"WIE BESEHEN\" ZUR VERFÜGUNG GESTELLT. SOLLTE SICH DAS PROGRAMM ALS FEHLERHAFT ERWEISEN, ÜBERNIMMST DU ALLE NOTWENDIGEN KRANKHEITSKOSTEN, SERVICELEISTUNGEN, REPARATUREN ODER KORREKTUREN.</string>
<string name="end_user_license_agreement_i_understand">Ich verstehe und stimme zu.</string> <string name="end_user_license_agreement_i_understand">Ich verstehe und stimme zu.</string>
<string name="save">Speichern</string>
<string name="reloadprofile">Profil neuladen</string> <string name="reloadprofile">Profil neuladen</string>
<string name="smscommunicator">SMS-Kommunikator</string> <string name="smscommunicator">SMS-Kommunikator</string>
<string name="smscommunicator_allowednumbers">Erlaubte Telefonnummern</string> <string name="smscommunicator_allowednumbers">Erlaubte Telefonnummern</string>
@ -939,5 +940,7 @@ Unerwartetes Verhalten.</string>
<string name="carbs_and_bolus">Kohlenhydrate &amp; Bolus</string> <string name="carbs_and_bolus">Kohlenhydrate &amp; Bolus</string>
<string name="confirm_remove_multiple_items">Sind Sie sicher, dass Sie diese(s) %1$d Element(e) löschen möchten?</string> <string name="confirm_remove_multiple_items">Sind Sie sicher, dass Sie diese(s) %1$d Element(e) löschen möchten?</string>
<string name="count_selected">%1$d ausgewählt</string> <string name="count_selected">%1$d ausgewählt</string>
<string name="sort_label">Sortieren</string>
<string name="login">Login</string>
<!-- Aidex Cgms --> <!-- Aidex Cgms -->
</resources> </resources>

View file

@ -605,7 +605,11 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S
<string name="secondcarbsincrement">Deuxième incrément de glucides</string> <string name="secondcarbsincrement">Deuxième incrément de glucides</string>
<string name="thirdcarbsincrement">Troisième incrément de glucides</string> <string name="thirdcarbsincrement">Troisième incrément de glucides</string>
<string name="cgm">MGC</string> <string name="cgm">MGC</string>
<string name="ns_cellular">Utiliser la connexion mobile</string>
<string name="ns_wifi">Utilisez la connexion Wi-Fi</string>
<string name="ns_wifi_ssids">Wi-fi SSID</string> <string name="ns_wifi_ssids">Wi-fi SSID</string>
<string name="ns_charging">Pendant la charge</string>
<string name="ns_battery">Sur batterie</string>
<string name="connectionsettings_title">Paramètres de connexion</string> <string name="connectionsettings_title">Paramètres de connexion</string>
<string name="ns_wifi_allowedssids">SSIDs autorisés (séparés par point-virgule)</string> <string name="ns_wifi_allowedssids">SSIDs autorisés (séparés par point-virgule)</string>
<string name="ns_allowroaming">Autoriser connexion données itinérance</string> <string name="ns_allowroaming">Autoriser connexion données itinérance</string>
@ -684,7 +688,7 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S
<string name="miscellaneous">Divers</string> <string name="miscellaneous">Divers</string>
<string name="nav_logsettings">Paramètres journal</string> <string name="nav_logsettings">Paramètres journal</string>
<string name="resettodefaults">Réinitialiser les valeurs par défaut</string> <string name="resettodefaults">Réinitialiser les valeurs par défaut</string>
<string name="nsmalfunction">Dysfonctionnement NSClient. Faites une réinitialisation de NS et de NSClient.</string> <string name="nsmalfunction">Dysfonctionnement NSClient. Redémarrez NS et NSClient.</string>
<string name="time_offset">Décalage horaire</string> <string name="time_offset">Décalage horaire</string>
<string name="bolus_reminder">Rappel du bolus plus tard</string> <string name="bolus_reminder">Rappel du bolus plus tard</string>
<string name="setupwizard_preferred_aps_mode">Mode APS préféré</string> <string name="setupwizard_preferred_aps_mode">Mode APS préféré</string>
@ -1035,4 +1039,6 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S
<string name="aidex">GlucoRx Aidex</string> <string name="aidex">GlucoRx Aidex</string>
<string name="aidex_short">Aidex</string> <string name="aidex_short">Aidex</string>
<string name="description_source_aidex">Recevoir les valeurs de glycémie du MGC GlucoRx Aidex.</string> <string name="description_source_aidex">Recevoir les valeurs de glycémie du MGC GlucoRx Aidex.</string>
<string name="blocked_by_charging">Bloqué par les options de recharge</string>
<string name="blocked_by_connectivity">Bloqué par les options de connectivité</string>
</resources> </resources>

View file

@ -59,6 +59,7 @@
<string name="nav_export">Socruithe Easpórtáil</string> <string name="nav_export">Socruithe Easpórtáil</string>
<string name="nav_import">Socruithe Iompórtáil</string> <string name="nav_import">Socruithe Iompórtáil</string>
<string name="check_preferences_import_btn">Iompórtáil</string> <string name="check_preferences_import_btn">Iompórtáil</string>
<string name="save">Sábháil</string>
<string name="reloadprofile">Athlódáil próifíl</string> <string name="reloadprofile">Athlódáil próifíl</string>
<string name="smscommunicator_loophasbeendisabled">Is lúb díchumasaithe</string> <string name="smscommunicator_loophasbeendisabled">Is lúb díchumasaithe</string>
<string name="smscommunicator_loophasbeenenabled">Is lúb cumasaithe</string> <string name="smscommunicator_loophasbeenenabled">Is lúb cumasaithe</string>

View file

@ -155,6 +155,7 @@
<string name="end_user_license_agreement">최종 사용자 라이선스 동의서</string> <string name="end_user_license_agreement">최종 사용자 라이선스 동의서</string>
<string name="end_user_license_agreement_text">이 프로그램을 의학적 결정을 내리는 데 사용해서는 안되며, 여기에 대한 어떠한 보증도 없습니다. 이 프로그램의 품질과 성능에 관한 모든 위험은 사용자에게 있습니다.\nMUST NOT BE USED TO MAKE MEDICAL DECISIONS. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</string> <string name="end_user_license_agreement_text">이 프로그램을 의학적 결정을 내리는 데 사용해서는 안되며, 여기에 대한 어떠한 보증도 없습니다. 이 프로그램의 품질과 성능에 관한 모든 위험은 사용자에게 있습니다.\nMUST NOT BE USED TO MAKE MEDICAL DECISIONS. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</string>
<string name="end_user_license_agreement_i_understand">모두 이해하였고 동의합니다.</string> <string name="end_user_license_agreement_i_understand">모두 이해하였고 동의합니다.</string>
<string name="save">저장</string>
<string name="reloadprofile">프로파일 새로고침</string> <string name="reloadprofile">프로파일 새로고침</string>
<string name="smscommunicator">SMS 통신기</string> <string name="smscommunicator">SMS 통신기</string>
<string name="smscommunicator_allowednumbers">허가된 전화번호</string> <string name="smscommunicator_allowednumbers">허가된 전화번호</string>
@ -849,5 +850,6 @@
<string name="calculation_in_progress">계산 진행 중</string> <string name="calculation_in_progress">계산 진행 중</string>
<!-- Theme switcher dark and light mode--> <!-- Theme switcher dark and light mode-->
<!-- WEAR OS--> <!-- WEAR OS-->
<string name="login">로그인</string>
<!-- Aidex Cgms --> <!-- Aidex Cgms -->
</resources> </resources>

View file

@ -159,6 +159,7 @@
<string name="end_user_license_agreement">Licencinė sutartis su vartotoju</string> <string name="end_user_license_agreement">Licencinė sutartis su vartotoju</string>
<string name="end_user_license_agreement_text">PROGRAMA NEGALI BŪTI NAUDOJAMA GYDYMO SPRENDIMAMS PRIIMTI. PAGAL GALIOJANČIUS ĮSTATYMUS PROGRAMA NESUTEIKIA JOKIŲ GARANTIJŲ VARTOTOJUI. JEI RAŠTU NENURODYTA KITAIP, PROGRAMOS AUTORINIŲ TEISIŲ TURĖTOJAS IR/AR KITOS ŠALYS PATEIKIA PROGRAMĄ \"KAIP YRA\" BE JOKIŲ GARANTIJŲ, TIEK AKIVAIZDŽIŲ, TIEK NUMANOMŲ, ĮSKAITANT, BET NEAPSIRIBOJANT GALIMYBĘ NAUDOTI PROGRAMĄ KOMERCINIAMS AR KITOKIEMS DALINIAMS TIKSLAMS. RIZIKĄ, KYLANČIĄ NAUDOJANT PROGRAMĄ PRISIIMA PATS VARTOTOJAS. JEI PROGRAMA VEIKIA NETINKAMAI, IŠLAIDOS, SUSIJUSIOS SU PROGRAMOS SERVISU, TAISYMU AR KOREGAVIMU, TENKA VARTOTOJUI.</string> <string name="end_user_license_agreement_text">PROGRAMA NEGALI BŪTI NAUDOJAMA GYDYMO SPRENDIMAMS PRIIMTI. PAGAL GALIOJANČIUS ĮSTATYMUS PROGRAMA NESUTEIKIA JOKIŲ GARANTIJŲ VARTOTOJUI. JEI RAŠTU NENURODYTA KITAIP, PROGRAMOS AUTORINIŲ TEISIŲ TURĖTOJAS IR/AR KITOS ŠALYS PATEIKIA PROGRAMĄ \"KAIP YRA\" BE JOKIŲ GARANTIJŲ, TIEK AKIVAIZDŽIŲ, TIEK NUMANOMŲ, ĮSKAITANT, BET NEAPSIRIBOJANT GALIMYBĘ NAUDOTI PROGRAMĄ KOMERCINIAMS AR KITOKIEMS DALINIAMS TIKSLAMS. RIZIKĄ, KYLANČIĄ NAUDOJANT PROGRAMĄ PRISIIMA PATS VARTOTOJAS. JEI PROGRAMA VEIKIA NETINKAMAI, IŠLAIDOS, SUSIJUSIOS SU PROGRAMOS SERVISU, TAISYMU AR KOREGAVIMU, TENKA VARTOTOJUI.</string>
<string name="end_user_license_agreement_i_understand">SUPRATAU IR SUTINKU</string> <string name="end_user_license_agreement_i_understand">SUPRATAU IR SUTINKU</string>
<string name="save">Išsaugoti</string>
<string name="reloadprofile">Atnaujinti profilį</string> <string name="reloadprofile">Atnaujinti profilį</string>
<string name="smscommunicator">SMS komunikatorius</string> <string name="smscommunicator">SMS komunikatorius</string>
<string name="smscommunicator_allowednumbers">Leidžiami telefono numeriai</string> <string name="smscommunicator_allowednumbers">Leidžiami telefono numeriai</string>
@ -893,5 +894,6 @@
<string name="not_available_full">Negalimas</string> <string name="not_available_full">Negalimas</string>
<!-- Theme switcher dark and light mode--> <!-- Theme switcher dark and light mode-->
<!-- WEAR OS--> <!-- WEAR OS-->
<string name="login">Prisijungti</string>
<!-- Aidex Cgms --> <!-- Aidex Cgms -->
</resources> </resources>

View file

@ -159,6 +159,7 @@
<string name="end_user_license_agreement">Umowa licencyjna użytkownika końcowego</string> <string name="end_user_license_agreement">Umowa licencyjna użytkownika końcowego</string>
<string name="end_user_license_agreement_text">NIE MOŻE BY WYKORZYSTYWANY DO PODEJMOWANIA DECYZJI MEDYCZNYCH. NIE MA ŻADNEJ GWARANCJI NA PROGRAM, W ZAKRESIE DOZWOLONYM PRZEZ OBOWIĄZUJĄCE PRAWO. Z WYJĄTKIEM PRZYPADKÓW, GDY W INNY SPOSÓB PISMO OŚWIADCZENIA PRAW AUTORSKICH I / LUB INNYCH STRON, PRZEDSTAWIAĆ PROGRAM \"W STANIE TAKIM, W JAKIM SIĘ ZNAJDUJE\" BEZ JAKIEJKOLWIEK GWARANCJI, WYRAŹNEJ LUB DOMNIEMANEJ, W TYM MIĘDZY INNYMI DOMNIEMANYCH GWARANCJI PRZYDATNOŚCI HANDLOWEJ I PRZYDATNOŚCI DO OKREŚLONEGO CELU. CAŁKOWITE RYZYKO ZWIĄZANE Z JAKOŚCIĄ I WYNIKIEM PROGRAMU JEST PO PAŃSTWA STRONIE. W PRZYPADKU USZKODZENIA PROGRAMU UŻYTKOWNIK PONOSI KOSZT CAŁEGO NIEZBĘDNEGO SERWISU, NAPRAWY LUB POPRAWEK. W PRZYPADKU NIEPOROZUMIEŃ ZASTOSOWANIE PRAWNE MA UMOWA W ANGIELSKIEJ WERSJI JĘZYKOWEJ!!!</string> <string name="end_user_license_agreement_text">NIE MOŻE BY WYKORZYSTYWANY DO PODEJMOWANIA DECYZJI MEDYCZNYCH. NIE MA ŻADNEJ GWARANCJI NA PROGRAM, W ZAKRESIE DOZWOLONYM PRZEZ OBOWIĄZUJĄCE PRAWO. Z WYJĄTKIEM PRZYPADKÓW, GDY W INNY SPOSÓB PISMO OŚWIADCZENIA PRAW AUTORSKICH I / LUB INNYCH STRON, PRZEDSTAWIAĆ PROGRAM \"W STANIE TAKIM, W JAKIM SIĘ ZNAJDUJE\" BEZ JAKIEJKOLWIEK GWARANCJI, WYRAŹNEJ LUB DOMNIEMANEJ, W TYM MIĘDZY INNYMI DOMNIEMANYCH GWARANCJI PRZYDATNOŚCI HANDLOWEJ I PRZYDATNOŚCI DO OKREŚLONEGO CELU. CAŁKOWITE RYZYKO ZWIĄZANE Z JAKOŚCIĄ I WYNIKIEM PROGRAMU JEST PO PAŃSTWA STRONIE. W PRZYPADKU USZKODZENIA PROGRAMU UŻYTKOWNIK PONOSI KOSZT CAŁEGO NIEZBĘDNEGO SERWISU, NAPRAWY LUB POPRAWEK. W PRZYPADKU NIEPOROZUMIEŃ ZASTOSOWANIE PRAWNE MA UMOWA W ANGIELSKIEJ WERSJI JĘZYKOWEJ!!!</string>
<string name="end_user_license_agreement_i_understand">ROZUMIEM I WYRAŻAM ZGODĘ</string> <string name="end_user_license_agreement_i_understand">ROZUMIEM I WYRAŻAM ZGODĘ</string>
<string name="save">ZACHOWAJ</string>
<string name="reloadprofile">Załaduj profil ponownie</string> <string name="reloadprofile">Załaduj profil ponownie</string>
<string name="smscommunicator">Komunikator SMS</string> <string name="smscommunicator">Komunikator SMS</string>
<string name="smscommunicator_allowednumbers">Dozwolone numery telefonów</string> <string name="smscommunicator_allowednumbers">Dozwolone numery telefonów</string>
@ -893,5 +894,10 @@
<string name="not_available_full">Niedostępne</string> <string name="not_available_full">Niedostępne</string>
<!-- Theme switcher dark and light mode--> <!-- Theme switcher dark and light mode-->
<!-- WEAR OS--> <!-- WEAR OS-->
<string name="remove_selected_items">Usuń wybrane pozycje</string>
<string name="confirm_remove_multiple_items">Czy na pewno chcesz usunąć %1$d pozycji</string>
<string name="count_selected">Wybrany %1$d</string>
<string name="sort_label">Sortuj</string>
<string name="login">Zaloguj się</string>
<!-- Aidex Cgms --> <!-- Aidex Cgms -->
</resources> </resources>

View file

@ -159,6 +159,7 @@
<string name="end_user_license_agreement">Condições de Utilização</string> <string name="end_user_license_agreement">Condições de Utilização</string>
<string name="end_user_license_agreement_text">NÃO DEVE SER USADO PARA FAZER DECISÕES MÉDICAS. NÃO HÁ NENHUMA GARANTIA PARA O PROGRAMA, NA EXTENSÃO PERMITIDA PELA LEGISLAÇÃO APLICÁVEL. EXCEPTO QUANDO DE OUTRA FORMA, POR ESCRITO, OS TITULARES DOS DIREITOS DE AUTOR E / OU OUTRAS PARTES FORNECEM O PROGRAMA “TAL COMO ESTÁ”, SEM GARANTIA DE QUALQUER TIPO, EXPRESSA OU IMPLÍCITA, INCLUINDO, MAS NÃO SE LIMITANDO, ÀS GARANTIAS IMPLÍCITAS DE COMERCIALIZAÇÃO E ADEQUAÇÃO A UMA FINALIDADE ESPECÍFICA. TODO O RISCO QUANTO À QUALIDADE E DESEMPENHO DO PROGRAMA É CONSIGO. CASO O PROGRAMA SEJA DEFEITUOSO, ASSUME O CUSTO DE TODOS OS SERVIÇOS, REPAROS OU CORREÇÕES NECESSÁRIOS.</string> <string name="end_user_license_agreement_text">NÃO DEVE SER USADO PARA FAZER DECISÕES MÉDICAS. NÃO HÁ NENHUMA GARANTIA PARA O PROGRAMA, NA EXTENSÃO PERMITIDA PELA LEGISLAÇÃO APLICÁVEL. EXCEPTO QUANDO DE OUTRA FORMA, POR ESCRITO, OS TITULARES DOS DIREITOS DE AUTOR E / OU OUTRAS PARTES FORNECEM O PROGRAMA “TAL COMO ESTÁ”, SEM GARANTIA DE QUALQUER TIPO, EXPRESSA OU IMPLÍCITA, INCLUINDO, MAS NÃO SE LIMITANDO, ÀS GARANTIAS IMPLÍCITAS DE COMERCIALIZAÇÃO E ADEQUAÇÃO A UMA FINALIDADE ESPECÍFICA. TODO O RISCO QUANTO À QUALIDADE E DESEMPENHO DO PROGRAMA É CONSIGO. CASO O PROGRAMA SEJA DEFEITUOSO, ASSUME O CUSTO DE TODOS OS SERVIÇOS, REPAROS OU CORREÇÕES NECESSÁRIOS.</string>
<string name="end_user_license_agreement_i_understand">EU ENTENDO E CONCORDO</string> <string name="end_user_license_agreement_i_understand">EU ENTENDO E CONCORDO</string>
<string name="save">Guardar</string>
<string name="reloadprofile">Recarregar perfil</string> <string name="reloadprofile">Recarregar perfil</string>
<string name="smscommunicator">Comunicador SMS</string> <string name="smscommunicator">Comunicador SMS</string>
<string name="smscommunicator_allowednumbers">Número de telefones permitidos</string> <string name="smscommunicator_allowednumbers">Número de telefones permitidos</string>
@ -894,5 +895,6 @@
<string name="not_available_full">Indisponível</string> <string name="not_available_full">Indisponível</string>
<!-- Theme switcher dark and light mode--> <!-- Theme switcher dark and light mode-->
<!-- WEAR OS--> <!-- WEAR OS-->
<string name="login">Login</string>
<!-- Aidex Cgms --> <!-- Aidex Cgms -->
</resources> </resources>

View file

@ -159,6 +159,7 @@
<string name="end_user_license_agreement">Licență utilizator final</string> <string name="end_user_license_agreement">Licență utilizator final</string>
<string name="end_user_license_agreement_text">NU FOLOSIȚI PENTRU LUAREA DE DECIZII MEDICALE. NU EXISTĂ RĂSPUNDERE LEGALĂ SAU GARANȚIE PENTRU ACEST PROGRAM, ÎN LIMITA APLICABILĂ A LEGII. CU EXCEPTIA CAZURILOR SPECIAL MENȚIONATE, AUTORUL ȘI/SAU ALTE PERSOANE IMPLICATE PUN LA DISPOZIȚIE ACEST PROGRAM FĂRĂ NICIO GARANȚIE, IMPLICITĂ SAU EXPLICITĂ, INCLUZÂND, DAR FĂRĂ A SE LIMITA LA, GARANȚIILE LEGATE DE VĂNZAREA SAU POTRIVIREA PENTRU UN ANUME SCOP. ÎNTREGUL RISC LEGAT DE CALITATEA ȘI PERFORMANȚA ACESTUI PROGRAM CAD ÎN RESPONSABILITATEA DUMNEAVOASTRĂ. DACĂ PROGRAMUL SE DOVEDEȘTE A FI DEFECT, DUMNEAVOASTRĂ VĂ ASUMAȚI ÎNTREAGA RĂSPUNDERE, PRECUM ȘI TOATE COSTURILE LEGATE DE SERVICE, REPARAȚII SAU CORECȚII.</string> <string name="end_user_license_agreement_text">NU FOLOSIȚI PENTRU LUAREA DE DECIZII MEDICALE. NU EXISTĂ RĂSPUNDERE LEGALĂ SAU GARANȚIE PENTRU ACEST PROGRAM, ÎN LIMITA APLICABILĂ A LEGII. CU EXCEPTIA CAZURILOR SPECIAL MENȚIONATE, AUTORUL ȘI/SAU ALTE PERSOANE IMPLICATE PUN LA DISPOZIȚIE ACEST PROGRAM FĂRĂ NICIO GARANȚIE, IMPLICITĂ SAU EXPLICITĂ, INCLUZÂND, DAR FĂRĂ A SE LIMITA LA, GARANȚIILE LEGATE DE VĂNZAREA SAU POTRIVIREA PENTRU UN ANUME SCOP. ÎNTREGUL RISC LEGAT DE CALITATEA ȘI PERFORMANȚA ACESTUI PROGRAM CAD ÎN RESPONSABILITATEA DUMNEAVOASTRĂ. DACĂ PROGRAMUL SE DOVEDEȘTE A FI DEFECT, DUMNEAVOASTRĂ VĂ ASUMAȚI ÎNTREAGA RĂSPUNDERE, PRECUM ȘI TOATE COSTURILE LEGATE DE SERVICE, REPARAȚII SAU CORECȚII.</string>
<string name="end_user_license_agreement_i_understand">ÎNȚELEG ȘI SUNT DE ACORD</string> <string name="end_user_license_agreement_i_understand">ÎNȚELEG ȘI SUNT DE ACORD</string>
<string name="save">Salvează</string>
<string name="reloadprofile">Reîncarcă profilul</string> <string name="reloadprofile">Reîncarcă profilul</string>
<string name="smscommunicator">Comunicator SMS</string> <string name="smscommunicator">Comunicator SMS</string>
<string name="smscommunicator_allowednumbers">Numere de telefon permise</string> <string name="smscommunicator_allowednumbers">Numere de telefon permise</string>
@ -894,5 +895,8 @@
<string name="not_available_full">Nu este disponibil</string> <string name="not_available_full">Nu este disponibil</string>
<!-- Theme switcher dark and light mode--> <!-- Theme switcher dark and light mode-->
<!-- WEAR OS--> <!-- WEAR OS-->
<string name="confirm_remove_multiple_items">Sigur vrei să elimini %1$d element(e)</string>
<string name="sort_label">Sortează</string>
<string name="login">Autentificare</string>
<!-- Aidex Cgms --> <!-- Aidex Cgms -->
</resources> </resources>

View file

@ -161,6 +161,7 @@ Eversense-appen.</string>
<string name="end_user_license_agreement">Licensavtal för slutanvändare</string> <string name="end_user_license_agreement">Licensavtal för slutanvändare</string>
<string name="end_user_license_agreement_text">FÅR INTE ANVÄNDAS FÖR ATT FATTA MEDICINSKA BESLUT. DET FINNS INGEN GARANTI FÖR PROGRAMMET I DEN UTSTRÄCKNING SOM TILLÅTS AV GÄLLANDE LAG. FÖRUTOM NÄR ANNAT ANGES SKRIFTLIGEN LEVERERAS APPLIKATIONEN SOM DEN ÄR HELT UTAN GARANTIER I NÅGON SOM HELST FORM, VARKEN UTTRYCKTA ELLER UNDERFÖRSTÅDDA, INKLUSIVE MEN INTE BEGRÄNSAT TILL SÄLJBARHET OCH LÄMPLIGHET FÖR ETT VISST ÄNDAMÅL. HELA RISKEN VAD GÄLLER KVALITET OCH PRESTANDA AV PROGRAMMET ÅLIGGER ANVÄNDAREN. OM PROGRAMMET VISAR SIG VARA DEFEKT ANTAR ANVÄNDAREN DEN FULLA FÖR KOSTNADEN FÖR ALL NÖDVÄNDIG SERVICE, REPARATION ELLER KORRIGERING.</string> <string name="end_user_license_agreement_text">FÅR INTE ANVÄNDAS FÖR ATT FATTA MEDICINSKA BESLUT. DET FINNS INGEN GARANTI FÖR PROGRAMMET I DEN UTSTRÄCKNING SOM TILLÅTS AV GÄLLANDE LAG. FÖRUTOM NÄR ANNAT ANGES SKRIFTLIGEN LEVERERAS APPLIKATIONEN SOM DEN ÄR HELT UTAN GARANTIER I NÅGON SOM HELST FORM, VARKEN UTTRYCKTA ELLER UNDERFÖRSTÅDDA, INKLUSIVE MEN INTE BEGRÄNSAT TILL SÄLJBARHET OCH LÄMPLIGHET FÖR ETT VISST ÄNDAMÅL. HELA RISKEN VAD GÄLLER KVALITET OCH PRESTANDA AV PROGRAMMET ÅLIGGER ANVÄNDAREN. OM PROGRAMMET VISAR SIG VARA DEFEKT ANTAR ANVÄNDAREN DEN FULLA FÖR KOSTNADEN FÖR ALL NÖDVÄNDIG SERVICE, REPARATION ELLER KORRIGERING.</string>
<string name="end_user_license_agreement_i_understand">JAG FÖRSTÅR OCH GODKÄNNER</string> <string name="end_user_license_agreement_i_understand">JAG FÖRSTÅR OCH GODKÄNNER</string>
<string name="save">Spara</string>
<string name="reloadprofile">Ladda om profil</string> <string name="reloadprofile">Ladda om profil</string>
<string name="smscommunicator">SMS-tjänst</string> <string name="smscommunicator">SMS-tjänst</string>
<string name="smscommunicator_allowednumbers">Godkända telefonnummer</string> <string name="smscommunicator_allowednumbers">Godkända telefonnummer</string>
@ -962,5 +963,6 @@ Eversense-appen.</string>
<string name="wear_unknown_action_string">Okänt kommando:</string> <string name="wear_unknown_action_string">Okänt kommando:</string>
<string name="overview_editquickwizard_percentage">Procent</string> <string name="overview_editquickwizard_percentage">Procent</string>
<string name="app_default">Appens standardinställning</string> <string name="app_default">Appens standardinställning</string>
<string name="login">Logga in</string>
<!-- Aidex Cgms --> <!-- Aidex Cgms -->
</resources> </resources>

View file

@ -475,6 +475,7 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d
<string name="localalertsettings_title">Yerel uyarılar</string> <string name="localalertsettings_title">Yerel uyarılar</string>
<string name="enable_missed_bg_readings_alert">KŞ bilgisi alınmadığında uyar</string> <string name="enable_missed_bg_readings_alert">KŞ bilgisi alınmadığında uyar</string>
<string name="enable_pump_unreachable_alert">Pompa ulaşılamıyorsa uyar</string> <string name="enable_pump_unreachable_alert">Pompa ulaşılamıyorsa uyar</string>
<string name="pump_unreachable_threshold">Pompa ulaşılamaz eşiği [dk]</string>
<string name="enable_carbs_req_alert">Karbonhidrat gerekliyse uyar</string> <string name="enable_carbs_req_alert">Karbonhidrat gerekliyse uyar</string>
<string name="urgent_alarm">Acil önemli Alarm</string> <string name="urgent_alarm">Acil önemli Alarm</string>
<string name="info">BİLGİ</string> <string name="info">BİLGİ</string>

View file

@ -36,11 +36,12 @@
android:key="@string/key_autotune_circadian_ic_isf" android:key="@string/key_autotune_circadian_ic_isf"
android:summary="@string/autotune_circadian_ic_isf_summary" android:summary="@string/autotune_circadian_ic_isf_summary"
android:title="@string/autotune_circadian_ic_isf_title" /> android:title="@string/autotune_circadian_ic_isf_title" />
<!-- Hide autotune_additional_log option
<SwitchPreference <SwitchPreference
android:defaultValue="false" android:defaultValue="false"
android:key="@string/key_autotune_additional_log" android:key="@string/key_autotune_additional_log"
android:summary="@string/autotune_additional_log_summary" android:summary="@string/autotune_additional_log_summary"
android:title="@string/autotune_additional_log_title" /> android:title="@string/autotune_additional_log_title" />
-->
</PreferenceCategory> </PreferenceCategory>
</androidx.preference.PreferenceScreen> </androidx.preference.PreferenceScreen>

View file

@ -31,7 +31,6 @@ import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin
import info.nightscout.androidaps.plugins.source.GlimpPlugin import info.nightscout.androidaps.plugins.source.GlimpPlugin
import info.nightscout.androidaps.utils.HardLimits import info.nightscout.androidaps.utils.HardLimits
import info.nightscout.androidaps.utils.Profiler import info.nightscout.androidaps.utils.Profiler
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
import info.nightscout.androidaps.utils.buildHelper.BuildHelperImpl import info.nightscout.androidaps.utils.buildHelper.BuildHelperImpl
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP
import org.junit.Assert import org.junit.Assert

View file

@ -17,7 +17,7 @@ import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin
import info.nightscout.androidaps.plugins.source.GlimpPlugin import info.nightscout.androidaps.plugins.source.GlimpPlugin
import info.nightscout.androidaps.utils.HardLimits import info.nightscout.androidaps.utils.HardLimits
import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP
import org.junit.Assert import org.junit.Assert
import org.junit.Before import org.junit.Before

View file

@ -1,16 +1,52 @@
package info.nightscout.androidaps.plugins.constraints.versionChecker package info.nightscout.androidaps.plugins.constraints.versionChecker
import org.joda.time.DateTime
import org.joda.time.LocalDate import org.joda.time.LocalDate
import org.junit.Assert import org.json.JSONArray
import org.junit.Assert.* import org.json.JSONObject
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue
import org.junit.Test import org.junit.Test
class AllowedVersionsTest { class AllowedVersionsTest {
fun generateSupportedVersions(): String =
JSONArray()
// Android API versions
.put(JSONObject().apply {
put("minAndroid", 1) // 1.0
put("maxAndroid", 23) // 6.0.1
})
.put(JSONObject().apply {
put("minAndroid", 24) // 7.0
put("maxAndroid", 25) // 7.1.2
put("supported", "2.6.2")
})
.put(JSONObject().apply {
put("minAndroid", 26) // 8.0
put("maxAndroid", 27) // 8.1
put("supported", "2.8.2")
})
.put(JSONObject().apply {
put("minAndroid", 28) // 9.0
put("maxAndroid", 99)
put("supported", "2.8.2")
})
// Version time limitation
.put(JSONObject().apply {
put("endDate", "2021-11-07")
put("version", "2.9.0-beta1")
})
.put(JSONObject().apply {
put("endDate", "2021-11-07")
put("version", "3.0-beta1")
})
.toString()
@Test @Test
fun generateSupportedVersionsTest() { fun generateSupportedVersionsTest() {
val definition = AllowedVersions().generateSupportedVersions() val definition = generateSupportedVersions()
assertNull(AllowedVersions().findByApi(definition, 0)) assertNull(AllowedVersions().findByApi(definition, 0))
assertFalse(AllowedVersions().findByApi(definition, 1)?.has("supported") ?: true) assertFalse(AllowedVersions().findByApi(definition, 1)?.has("supported") ?: true)
assertFalse(AllowedVersions().findByApi(definition, 23)?.has("supported") ?: true) assertFalse(AllowedVersions().findByApi(definition, 23)?.has("supported") ?: true)
@ -24,9 +60,10 @@ class AllowedVersionsTest {
@Test @Test
fun findByVersionTest() { fun findByVersionTest() {
//val definition = AllowedVersions().generateSupportedVersions() //val definition = AllowedVersions().generateSupportedVersions()
val definition = "[{\"minAndroid\":1,\"maxAndroid\":23},{\"minAndroid\":24,\"maxAndroid\":25,\"supported\":\"2.6.2\"},{\"minAndroid\":26,\"maxAndroid\":27,\"supported\":\"2.8.2\"},{\"minAndroid\":28,\"maxAndroid\":99,\"supported\":\"2.8.2\"},{\"endDate\":\"2021-11-07\",\"version\":\"2.9.0-beta1\"},{\"endDate\":\"2021-11-02\",\"version\":\"3.0-beta1\"},{\"endDate\":\"2021-11-04\",\"version\":\"3.0-beta2\"},{\"endDate\":\"2021-11-10\",\"version\":\"3.0-beta3\"},{\"endDate\":\"2021-11-14\",\"version\":\"3.0-beta4\"}\n" + val definition =
" ,{\"endDate\":\"2021-11-16\",\"version\":\"3.0-beta5\"}\n" + "[{\"minAndroid\":1,\"maxAndroid\":23},{\"minAndroid\":24,\"maxAndroid\":25,\"supported\":\"2.6.2\"},{\"minAndroid\":26,\"maxAndroid\":27,\"supported\":\"2.8.2\"},{\"minAndroid\":28,\"maxAndroid\":99,\"supported\":\"2.8.2\"},{\"endDate\":\"2021-11-07\",\"version\":\"2.9.0-beta1\"},{\"endDate\":\"2021-11-02\",\"version\":\"3.0-beta1\"},{\"endDate\":\"2021-11-04\",\"version\":\"3.0-beta2\"},{\"endDate\":\"2021-11-10\",\"version\":\"3.0-beta3\"},{\"endDate\":\"2021-11-14\",\"version\":\"3.0-beta4\"}\n" +
"]" " ,{\"endDate\":\"2021-11-16\",\"version\":\"3.0-beta5\"}\n" +
"]"
assertNull(AllowedVersions().findByVersion(definition, "2.6.0")) assertNull(AllowedVersions().findByVersion(definition, "2.6.0"))
assertTrue(AllowedVersions().findByVersion(definition, "2.9.0-beta1")?.has("endDate") ?: false) assertTrue(AllowedVersions().findByVersion(definition, "2.9.0-beta1")?.has("endDate") ?: false)
assertEquals("2021-11-07", AllowedVersions().findByVersion(definition, "2.9.0-beta1")?.getString("endDate")) assertEquals("2021-11-07", AllowedVersions().findByVersion(definition, "2.9.0-beta1")?.getString("endDate"))
@ -34,7 +71,7 @@ class AllowedVersionsTest {
@Test @Test
fun endDateToMilliseconds() { fun endDateToMilliseconds() {
val definition = AllowedVersions().generateSupportedVersions() val definition = generateSupportedVersions()
val endDate = AllowedVersions().endDateToMilliseconds(AllowedVersions().findByVersion(definition, "2.9.0-beta1")?.getString("endDate") ?: "1000/01/01") val endDate = AllowedVersions().endDateToMilliseconds(AllowedVersions().findByVersion(definition, "2.9.0-beta1")?.getString("endDate") ?: "1000/01/01")
val dateTime = LocalDate(endDate) val dateTime = LocalDate(endDate)
assertEquals(2021, dateTime.year) assertEquals(2021, dateTime.year)

View file

@ -5,7 +5,7 @@ import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.TestBase import info.nightscout.androidaps.TestBase
import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus
import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP
import org.junit.Assert import org.junit.Assert

View file

@ -25,7 +25,7 @@ import info.nightscout.androidaps.queue.commands.*
import info.nightscout.androidaps.utils.AndroidPermission import info.nightscout.androidaps.utils.AndroidPermission
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.androidaps.utils.buildHelper.BuildHelperImpl import info.nightscout.androidaps.utils.buildHelper.BuildHelperImpl
import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.AapsSchedulers

View file

@ -8,6 +8,9 @@ apply from: "${project.rootDir}/core/android_dependencies.gradle"
apply from: "${project.rootDir}/core/android_module_dependencies.gradle" apply from: "${project.rootDir}/core/android_module_dependencies.gradle"
apply from: "${project.rootDir}/core/test_dependencies.gradle" apply from: "${project.rootDir}/core/test_dependencies.gradle"
apply from: "${project.rootDir}/core/jacoco_global.gradle" apply from: "${project.rootDir}/core/jacoco_global.gradle"
android {
namespace 'info.nightscout.androidaps.automation'
}
dependencies { dependencies {

View file

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android">
package="info.nightscout.androidaps.automation">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH" />

View file

@ -28,7 +28,6 @@ class ActionRunAutotune(injector: HasAndroidInjector) : Action(injector) {
@Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var activePlugin: ActivePlugin @Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var sp: SP @Inject lateinit var sp: SP
@Inject lateinit var uel: UserEntryLogger
var defaultValue = 0 var defaultValue = 0
private var inputProfileName = InputProfileName(rh, activePlugin, "", true) private var inputProfileName = InputProfileName(rh, activePlugin, "", true)

View file

@ -113,4 +113,5 @@
<string name="automation_event">Automatisierungs-Ereignis</string> <string name="automation_event">Automatisierungs-Ereignis</string>
<string name="reorder_label">Umsortieren</string> <string name="reorder_label">Umsortieren</string>
<string name="user_action">Benutzeraktion</string> <string name="user_action">Benutzeraktion</string>
<string name="confirm_remove_multiple_items">Sind Sie sicher, dass Sie diese(s) %1$d Element(e) löschen möchten?</string>
</resources> </resources>

View file

@ -120,4 +120,7 @@
<string name="confirm_remove_multiple_items">Вы уверены, что хотите удалить %1$d элемент</string> <string name="confirm_remove_multiple_items">Вы уверены, что хотите удалить %1$d элемент</string>
<string name="sort_label">Сортировать</string> <string name="sort_label">Сортировать</string>
<string name="system_automation">Автоматизация системы</string> <string name="system_automation">Автоматизация системы</string>
<string name="run_automations">Запустить автоматизацию</string>
<string name="add_automation">Добавить правило</string>
<string name="remove_sort">Удаление/сортировка</string>
</resources> </resources>

View file

@ -2,7 +2,7 @@
buildscript { buildscript {
ext { ext {
kotlin_version = '1.6.21' kotlin_version = '1.7.0'
core_version = '1.8.0' core_version = '1.8.0'
rxjava_version = '3.1.5' rxjava_version = '3.1.5'
rxandroid_version = '3.0.0' rxandroid_version = '3.0.0'
@ -17,7 +17,7 @@ buildscript {
gson_version = '2.9.0' gson_version = '2.9.0'
nav_version = '2.4.2' nav_version = '2.4.2'
appcompat_version = '1.4.2' appcompat_version = '1.4.2'
material_version = '1.6.0' material_version = '1.6.1'
constraintlayout_version = '2.1.4' constraintlayout_version = '2.1.4'
preferencektx_version = '1.2.0' preferencektx_version = '1.2.0'
commonslang3_version = '3.12.0' commonslang3_version = '3.12.0'
@ -40,7 +40,7 @@ buildscript {
wearable_version = '2.9.0' wearable_version = '2.9.0'
play_services_wearable_version = '17.1.0' play_services_wearable_version = '17.1.0'
play_services_location_version = '19.0.1' play_services_location_version = '20.0.0'
} }
repositories { repositories {
google() google()
@ -66,7 +66,7 @@ plugins {
id "io.gitlab.arturbosch.detekt" version "1.20.0" id "io.gitlab.arturbosch.detekt" version "1.20.0"
id "org.jlleitschuh.gradle.ktlint" version "10.3.0" id "org.jlleitschuh.gradle.ktlint" version "10.3.0"
id 'org.barfuin.gradle.jacocolog' version '2.0.0' id 'org.barfuin.gradle.jacocolog' version '2.0.0'
id 'org.jetbrains.kotlin.android' version '1.6.21' apply false id 'org.jetbrains.kotlin.android' version '1.7.0' apply false
} }
allprojects { allprojects {

View file

@ -8,6 +8,9 @@ apply from: "${project.rootDir}/core/android_dependencies.gradle"
apply from: "${project.rootDir}/core/android_module_dependencies.gradle" apply from: "${project.rootDir}/core/android_module_dependencies.gradle"
apply from: "${project.rootDir}/core/test_dependencies.gradle" apply from: "${project.rootDir}/core/test_dependencies.gradle"
apply from: "${project.rootDir}/core/jacoco_global.gradle" apply from: "${project.rootDir}/core/jacoco_global.gradle"
android {
namespace 'info.nightscout.androidaps.combo'
}
dependencies { dependencies {
implementation project(':core') implementation project(':core')

View file

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android">
package="info.nightscout.androidaps.combo">
<application <application
android:supportsRtl="true"> android:supportsRtl="true">

View file

@ -15,3 +15,7 @@ dependencies {
implementation project(':shared') implementation project(':shared')
implementation project(':database') implementation project(':database')
} }
android {
namespace 'info.nightscout.androidaps.core'
}

View file

@ -1,5 +1,4 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android">
package="info.nightscout.androidaps.core">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
@ -9,14 +8,17 @@
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<application <application android:supportsRtl="true">
android:supportsRtl="true"> <activity
<activity android:name="info.nightscout.androidaps.activities.TDDStatsActivity" /> android:name="info.nightscout.androidaps.activities.TDDStatsActivity"
android:exported="false" />
<activity <activity
android:name="info.nightscout.androidaps.activities.BolusProgressHelperActivity" android:name="info.nightscout.androidaps.activities.BolusProgressHelperActivity"
android:exported="false"
android:theme="@style/Theme.MaterialComponents.Translucent" /> android:theme="@style/Theme.MaterialComponents.Translucent" />
<activity <activity
android:name="info.nightscout.androidaps.activities.ErrorHelperActivity" android:name="info.nightscout.androidaps.activities.ErrorHelperActivity"
android:exported="false"
android:theme="@style/Theme.MaterialComponents.Translucent" /> android:theme="@style/Theme.MaterialComponents.Translucent" />
</application> </application>

View file

@ -74,11 +74,11 @@ class ErrorDialog : DaggerDialogFragment() {
} }
binding.mute.setOnClickListener { binding.mute.setOnClickListener {
uel.log(Action.ERROR_DIALOG_MUTE, Sources.Unknown) uel.log(Action.ERROR_DIALOG_MUTE, Sources.Unknown)
stopAlarm() stopAlarm("Mute")
} }
binding.mute5min.setOnClickListener { binding.mute5min.setOnClickListener {
uel.log(Action.ERROR_DIALOG_MUTE_5MIN, Sources.Unknown) uel.log(Action.ERROR_DIALOG_MUTE_5MIN, Sources.Unknown)
stopAlarm() stopAlarm("Mute 5 min")
handler.postDelayed(this::startAlarm, T.mins(5).msecs()) handler.postDelayed(this::startAlarm, T.mins(5).msecs())
} }
startAlarm() startAlarm()
@ -110,14 +110,14 @@ class ErrorDialog : DaggerDialogFragment() {
super.dismissAllowingStateLoss() super.dismissAllowingStateLoss()
helperActivity?.finish() helperActivity?.finish()
handler.removeCallbacksAndMessages(null) handler.removeCallbacksAndMessages(null)
stopAlarm() stopAlarm("Dismiss")
} }
private fun startAlarm() { private fun startAlarm() {
if (sound != 0) if (sound != 0)
alarmSoundServiceHelper.startAlarm(ctx, sound) alarmSoundServiceHelper.startAlarm(ctx, sound, "$title:$status")
} }
private fun stopAlarm() = private fun stopAlarm(reason: String) =
alarmSoundServiceHelper.stopService(ctx) alarmSoundServiceHelper.stopService(ctx, reason)
} }

View file

@ -2,22 +2,23 @@ package info.nightscout.androidaps.extensions
import com.google.gson.Gson import com.google.gson.Gson
import com.google.gson.JsonSyntaxException import com.google.gson.JsonSyntaxException
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.database.entities.BolusCalculatorResult import info.nightscout.androidaps.database.entities.BolusCalculatorResult
import info.nightscout.androidaps.database.entities.TherapyEvent import info.nightscout.androidaps.database.entities.TherapyEvent
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.JsonHelper import info.nightscout.androidaps.utils.JsonHelper
import org.json.JSONObject import org.json.JSONObject
fun BolusCalculatorResult.toJson(isAdd: Boolean, dateUtil: DateUtil): JSONObject = fun BolusCalculatorResult.toJson(isAdd: Boolean, dateUtil: DateUtil, profileFunction: ProfileFunction): JSONObject =
JSONObject() JSONObject()
.put("eventType", TherapyEvent.Type.BOLUS_WIZARD.text) .put("eventType", TherapyEvent.Type.BOLUS_WIZARD.text)
.put("created_at", dateUtil.toISOString(timestamp)) .put("created_at", dateUtil.toISOString(timestamp))
.put("isValid", isValid) .put("isValid", isValid)
.put("bolusCalculatorResult", Gson().toJson(this)) .put("bolusCalculatorResult", Gson().toJson(this))
.put("date", timestamp) .put("date", timestamp)
.put("glucose", glucoseValue) .put("glucose", Profile.fromMgdlToUnits(glucoseValue, profileFunction.getUnits()))
.put("units", Constants.MGDL) .put("units", profileFunction.getUnits().asText)
.put("notes", note) .put("notes", note)
.also { if (isAdd && interfaceIDs.nightscoutId != null) it.put("_id", interfaceIDs.nightscoutId) } .also { if (isAdd && interfaceIDs.nightscoutId != null) it.put("_id", interfaceIDs.nightscoutId) }

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.utils.buildHelper package info.nightscout.androidaps.interfaces
interface BuildHelper { interface BuildHelper {

View file

@ -2,10 +2,9 @@ package info.nightscout.androidaps.interfaces
import android.text.Spanned import android.text.Spanned
import info.nightscout.androidaps.data.DetailedBolusInfo import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.queue.commands.CustomCommand
import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.queue.commands.Command import info.nightscout.androidaps.queue.commands.Command
import info.nightscout.androidaps.queue.commands.CustomCommand
interface CommandQueue { interface CommandQueue {

View file

@ -2,9 +2,7 @@ package info.nightscout.androidaps.interfaces
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import info.nightscout.androidaps.database.entities.UserEntry
import info.nightscout.androidaps.plugins.general.maintenance.PrefsFile import info.nightscout.androidaps.plugins.general.maintenance.PrefsFile
import io.reactivex.rxjava3.core.Single
interface ImportExportPrefs { interface ImportExportPrefs {

View file

@ -8,7 +8,6 @@ import info.nightscout.androidaps.utils.DecimalFormatter.to0Decimal
import info.nightscout.androidaps.utils.DecimalFormatter.to1Decimal import info.nightscout.androidaps.utils.DecimalFormatter.to1Decimal
import info.nightscout.androidaps.utils.HardLimits import info.nightscout.androidaps.utils.HardLimits
import info.nightscout.androidaps.utils.Round import info.nightscout.androidaps.utils.Round
import info.nightscout.androidaps.interfaces.ResourceHelper
import org.joda.time.DateTime import org.joda.time.DateTime
import org.json.JSONObject import org.json.JSONObject
@ -62,6 +61,7 @@ interface Profile {
* ISF value according to "now"" in MGDL * ISF value according to "now"" in MGDL
*/ */
fun getIsfMgdl(): Double fun getIsfMgdl(): Double
/** /**
* ISF value according to timestamp in MGDL * ISF value according to timestamp in MGDL
*/ */

View file

@ -4,43 +4,9 @@ import org.joda.time.LocalDate
import org.json.JSONArray import org.json.JSONArray
import org.json.JSONException import org.json.JSONException
import org.json.JSONObject import org.json.JSONObject
import java.lang.Exception
class AllowedVersions { class AllowedVersions {
fun generateSupportedVersions(): String =
JSONArray()
// Android API versions
.put(JSONObject().apply {
put("minAndroid", 1) // 1.0
put("maxAndroid", 23) // 6.0.1
})
.put(JSONObject().apply {
put("minAndroid", 24) // 7.0
put("maxAndroid", 25) // 7.1.2
put("supported", "2.6.2")
})
.put(JSONObject().apply {
put("minAndroid", 26) // 8.0
put("maxAndroid", 27) // 8.1
put("supported", "2.8.2")
})
.put(JSONObject().apply {
put("minAndroid", 28) // 9.0
put("maxAndroid", 99)
put("supported", "2.8.2")
})
// Version time limitation
.put(JSONObject().apply {
put("endDate", "2021-11-07")
put("version", "2.9.0-beta1")
})
.put(JSONObject().apply {
put("endDate", "2021-11-07")
put("version", "3.0-beta1")
})
.toString()
fun findByApi(definition: String?, api: Int): JSONObject? { fun findByApi(definition: String?, api: Int): JSONObject? {
if (definition == null) return null if (definition == null) return null
try { try {

View file

@ -1,6 +1,6 @@
package info.nightscout.androidaps.plugins.general.overview.graphExtensions package info.nightscout.androidaps.plugins.general.overview.graphExtensions
class Scale(var shift: Double = 0.0, var multiplier: Double = 0.0) { class Scale(var shift: Double = 0.0, var multiplier: Double = 1.0) {
fun transform(original: Double): Double { fun transform(original: Double): Double {
return original * multiplier + shift return original * multiplier + shift

View file

@ -8,7 +8,7 @@ open class Notification {
var id = 0 var id = 0
var date: Long = 0 var date: Long = 0
var text: String? = null var text: String = ""
var level = 0 var level = 0
var validTo: Long = 0 var validTo: Long = 0
@RawRes var soundId: Int? = null @RawRes var soundId: Int? = null

View file

@ -11,7 +11,8 @@ import kotlin.math.min
@Suppress("unused") @Suppress("unused")
enum class PumpType { enum class PumpType {
GENERIC_AAPS(description = "Generic AAPS", GENERIC_AAPS(
description = "Generic AAPS",
manufacturer = ManufacturerType.AndroidAPS, manufacturer = ManufacturerType.AndroidAPS,
model = "VirtualPump", model = "VirtualPump",
bolusSize = 0.1, bolusSize = 0.1,
@ -23,9 +24,11 @@ enum class PumpType {
baseBasalMinValue = 0.01, baseBasalMinValue = 0.01,
baseBasalStep = 0.01, baseBasalStep = 0.01,
baseBasalSpecialSteps = null, baseBasalSpecialSteps = null,
pumpCapability = PumpCapability.VirtualPumpCapabilities), pumpCapability = PumpCapability.VirtualPumpCapabilities
),
CELLNOVO(description = "Cellnovo", CELLNOVO(
description = "Cellnovo",
manufacturer = ManufacturerType.Cellnovo, manufacturer = ManufacturerType.Cellnovo,
model = "Cellnovo", model = "Cellnovo",
bolusSize = 0.05, bolusSize = 0.05,
@ -37,9 +40,11 @@ enum class PumpType {
baseBasalMinValue = 0.05, baseBasalMinValue = 0.05,
baseBasalStep = 0.05, baseBasalStep = 0.05,
baseBasalSpecialSteps = null, baseBasalSpecialSteps = null,
pumpCapability = PumpCapability.VirtualPumpCapabilities), pumpCapability = PumpCapability.VirtualPumpCapabilities
),
ACCU_CHEK_COMBO(description = "Accu-Chek Combo", ACCU_CHEK_COMBO(
description = "Accu-Chek Combo",
manufacturer = ManufacturerType.Roche, manufacturer = ManufacturerType.Roche,
model = "Combo", model = "Combo",
bolusSize = 0.1, bolusSize = 0.1,
@ -53,8 +58,10 @@ enum class PumpType {
baseBasalSpecialSteps = DoseStepSize.ComboBasal, baseBasalSpecialSteps = DoseStepSize.ComboBasal,
pumpCapability = PumpCapability.ComboCapabilities, pumpCapability = PumpCapability.ComboCapabilities,
source = Sources.Combo, source = Sources.Combo,
supportBatteryLevel = false), supportBatteryLevel = false
ACCU_CHEK_SPIRIT(description = "Accu-Chek Spirit", ),
ACCU_CHEK_SPIRIT(
description = "Accu-Chek Spirit",
manufacturer = ManufacturerType.Roche, manufacturer = ManufacturerType.Roche,
model = "Spirit", model = "Spirit",
bolusSize = 0.1, bolusSize = 0.1,
@ -66,8 +73,10 @@ enum class PumpType {
baseBasalMinValue = 0.01, baseBasalMinValue = 0.01,
baseBasalStep = 0.1, baseBasalStep = 0.1,
baseBasalSpecialSteps = null, baseBasalSpecialSteps = null,
pumpCapability = PumpCapability.VirtualPumpCapabilities), pumpCapability = PumpCapability.VirtualPumpCapabilities
ACCU_CHEK_INSIGHT_VIRTUAL(description = "Accu-Chek Insight", ),
ACCU_CHEK_INSIGHT_VIRTUAL(
description = "Accu-Chek Insight",
manufacturer = ManufacturerType.Roche, manufacturer = ManufacturerType.Roche,
model = "Insight", model = "Insight",
bolusSize = 0.05, bolusSize = 0.05,
@ -79,8 +88,10 @@ enum class PumpType {
baseBasalMinValue = 0.02, baseBasalMinValue = 0.02,
baseBasalStep = 0.01, baseBasalStep = 0.01,
baseBasalSpecialSteps = null, baseBasalSpecialSteps = null,
pumpCapability = PumpCapability.InsightCapabilities), pumpCapability = PumpCapability.InsightCapabilities
ACCU_CHEK_INSIGHT(description = "Accu-Chek Insight", ),
ACCU_CHEK_INSIGHT(
description = "Accu-Chek Insight",
manufacturer = ManufacturerType.Roche, manufacturer = ManufacturerType.Roche,
model = "Insight", model = "Insight",
bolusSize = 0.01, bolusSize = 0.01,
@ -94,8 +105,10 @@ enum class PumpType {
baseBasalStep = 0.01, baseBasalStep = 0.01,
baseBasalSpecialSteps = DoseStepSize.InsightBasal, baseBasalSpecialSteps = DoseStepSize.InsightBasal,
pumpCapability = PumpCapability.InsightCapabilities, pumpCapability = PumpCapability.InsightCapabilities,
source = Sources.Insight), source = Sources.Insight
ACCU_CHEK_SOLO(description = "Accu-Chek Solo", ),
ACCU_CHEK_SOLO(
description = "Accu-Chek Solo",
manufacturer = ManufacturerType.Roche, manufacturer = ManufacturerType.Roche,
model = "Solo", model = "Solo",
bolusSize = 0.01, bolusSize = 0.01,
@ -108,9 +121,11 @@ enum class PumpType {
baseBasalMaxValue = null, baseBasalMaxValue = null,
baseBasalStep = 0.01, baseBasalStep = 0.01,
baseBasalSpecialSteps = DoseStepSize.InsightBolus, baseBasalSpecialSteps = DoseStepSize.InsightBolus,
pumpCapability = PumpCapability.InsightCapabilities), pumpCapability = PumpCapability.InsightCapabilities
),
ANIMAS_VIBE(description = "Animas Vibe", ANIMAS_VIBE(
description = "Animas Vibe",
manufacturer = ManufacturerType.Animas, manufacturer = ManufacturerType.Animas,
model = "Vibe", model = "Vibe",
bolusSize = 0.05, bolusSize = 0.05,
@ -123,9 +138,11 @@ enum class PumpType {
baseBasalMaxValue = 5.0, baseBasalMaxValue = 5.0,
baseBasalStep = 0.0, baseBasalStep = 0.0,
baseBasalSpecialSteps = null, baseBasalSpecialSteps = null,
pumpCapability = PumpCapability.VirtualPumpCapabilities), pumpCapability = PumpCapability.VirtualPumpCapabilities
),
ANIMAS_PING(description = "Animas Ping", model = "Ping", parent = ANIMAS_VIBE), ANIMAS_PING(description = "Animas Ping", model = "Ping", parent = ANIMAS_VIBE),
DANA_R(description = "DanaR", DANA_R(
description = "DanaR",
manufacturer = ManufacturerType.Sooil, manufacturer = ManufacturerType.Sooil,
model = "DanaR", model = "DanaR",
bolusSize = 0.05, bolusSize = 0.05,
@ -138,8 +155,10 @@ enum class PumpType {
baseBasalStep = 0.01, baseBasalStep = 0.01,
baseBasalSpecialSteps = null, baseBasalSpecialSteps = null,
pumpCapability = PumpCapability.DanaCapabilities, pumpCapability = PumpCapability.DanaCapabilities,
source = Sources.DanaR), source = Sources.DanaR
DANA_R_KOREAN(description = "DanaR Korean", ),
DANA_R_KOREAN(
description = "DanaR Korean",
manufacturer = ManufacturerType.Sooil, manufacturer = ManufacturerType.Sooil,
model = "DanaRKorean", model = "DanaRKorean",
bolusSize = 0.05, bolusSize = 0.05,
@ -152,8 +171,10 @@ enum class PumpType {
baseBasalStep = 0.01, baseBasalStep = 0.01,
baseBasalSpecialSteps = null, baseBasalSpecialSteps = null,
pumpCapability = PumpCapability.DanaCapabilities, pumpCapability = PumpCapability.DanaCapabilities,
source = Sources.DanaRC), source = Sources.DanaRC
DANA_RS(description = "DanaRS", ),
DANA_RS(
description = "DanaRS",
manufacturer = ManufacturerType.Sooil, manufacturer = ManufacturerType.Sooil,
model = "DanaRS", model = "DanaRS",
bolusSize = 0.05, bolusSize = 0.05,
@ -166,11 +187,13 @@ enum class PumpType {
baseBasalStep = 0.01, baseBasalStep = 0.01,
baseBasalSpecialSteps = null, baseBasalSpecialSteps = null,
pumpCapability = PumpCapability.DanaWithHistoryCapabilities, pumpCapability = PumpCapability.DanaWithHistoryCapabilities,
source = Sources.DanaRS), source = Sources.DanaRS
),
DANA_RS_KOREAN(description = "DanaRSKorean", model = "DanaRSKorean", parent = DANA_RS), DANA_RS_KOREAN(description = "DanaRSKorean", model = "DanaRSKorean", parent = DANA_RS),
DANA_I(description = "DanaI", model = "DanaI", parent = DANA_RS, source = Sources.DanaI), DANA_I(description = "DanaI", model = "DanaI", parent = DANA_RS, source = Sources.DanaI),
DANA_RV2(description = "DanaRv2", model = "DanaRv2", parent = DANA_RS, source = Sources.DanaRv2), DANA_RV2(description = "DanaRv2", model = "DanaRv2", parent = DANA_RS, source = Sources.DanaRv2),
OMNIPOD_EROS(description = "Omnipod Eros", OMNIPOD_EROS(
description = "Omnipod Eros",
manufacturer = ManufacturerType.Insulet, manufacturer = ManufacturerType.Insulet,
model = "Eros", model = "Eros",
bolusSize = 0.05, bolusSize = 0.05,
@ -188,8 +211,10 @@ enum class PumpType {
isPatchPump = true, isPatchPump = true,
useHardwareLink = true, useHardwareLink = true,
supportBatteryLevel = false, supportBatteryLevel = false,
source = Sources.OmnipodEros), source = Sources.OmnipodEros
OMNIPOD_DASH(description = "Omnipod Dash", ),
OMNIPOD_DASH(
description = "Omnipod Dash",
manufacturer = ManufacturerType.Insulet, manufacturer = ManufacturerType.Insulet,
model = "Dash", model = "Dash",
bolusSize = 0.05, bolusSize = 0.05,
@ -205,8 +230,10 @@ enum class PumpType {
isPatchPump = true, isPatchPump = true,
pumpCapability = PumpCapability.OmnipodCapabilities, pumpCapability = PumpCapability.OmnipodCapabilities,
hasCustomUnreachableAlertCheck = false, hasCustomUnreachableAlertCheck = false,
supportBatteryLevel = false), supportBatteryLevel = false
MEDTRONIC_512_712(description = "Medtronic 512/712", ),
MEDTRONIC_512_712(
description = "Medtronic 512/712",
manufacturer = ManufacturerType.Medtronic, manufacturer = ManufacturerType.Medtronic,
model = "512/712", model = "512/712",
bolusSize = 0.1, bolusSize = 0.1,
@ -219,14 +246,20 @@ enum class PumpType {
baseBasalStep = 0.05, baseBasalStep = 0.05,
baseBasalSpecialSteps = null, baseBasalSpecialSteps = null,
pumpCapability = PumpCapability.MedtronicCapabilities, pumpCapability = PumpCapability.MedtronicCapabilities,
source = Sources.Medtronic), source = Sources.Medtronic
MEDTRONIC_515_715(description = "Medtronic 515/715", ),
MEDTRONIC_515_715(
description = "Medtronic 515/715",
model = "515/715", model = "515/715",
parent = MEDTRONIC_512_712), parent = MEDTRONIC_512_712
MEDTRONIC_522_722(description = "Medtronic 522/722", ),
MEDTRONIC_522_722(
description = "Medtronic 522/722",
model = "522/722", model = "522/722",
parent = MEDTRONIC_512_712), parent = MEDTRONIC_512_712
MEDTRONIC_523_723_REVEL(description = "Medtronic 523/723 (Revel)", ),
MEDTRONIC_523_723_REVEL(
description = "Medtronic 523/723 (Revel)",
manufacturer = ManufacturerType.Medtronic, manufacturer = ManufacturerType.Medtronic,
model = "523/723 (Revel)", model = "523/723 (Revel)",
bolusSize = 0.05, bolusSize = 0.05,
@ -239,9 +272,11 @@ enum class PumpType {
baseBasalStep = 0.025, baseBasalStep = 0.025,
baseBasalSpecialSteps = DoseStepSize.MedtronicVeoBasal, baseBasalSpecialSteps = DoseStepSize.MedtronicVeoBasal,
pumpCapability = PumpCapability.MedtronicCapabilities, pumpCapability = PumpCapability.MedtronicCapabilities,
source = Sources.Medtronic), source = Sources.Medtronic
),
MEDTRONIC_554_754_VEO(description = "Medtronic 554/754 (Veo)", model = "554/754 (Veo)", parent = MEDTRONIC_523_723_REVEL), MEDTRONIC_554_754_VEO(description = "Medtronic 554/754 (Veo)", model = "554/754 (Veo)", parent = MEDTRONIC_523_723_REVEL),
MEDTRONIC_640G(description = "Medtronic 640G", MEDTRONIC_640G(
description = "Medtronic 640G",
manufacturer = ManufacturerType.Medtronic, manufacturer = ManufacturerType.Medtronic,
model = "640G", model = "640G",
bolusSize = 0.025, bolusSize = 0.025,
@ -253,9 +288,11 @@ enum class PumpType {
baseBasalMinValue = 0.025, baseBasalMinValue = 0.025,
baseBasalStep = 0.025, baseBasalStep = 0.025,
baseBasalSpecialSteps = DoseStepSize.MedtronicVeoBasal, baseBasalSpecialSteps = DoseStepSize.MedtronicVeoBasal,
pumpCapability = PumpCapability.VirtualPumpCapabilities), pumpCapability = PumpCapability.VirtualPumpCapabilities
),
TANDEM_T_SLIM(description = "Tandem t:slim", TANDEM_T_SLIM(
description = "Tandem t:slim",
manufacturer = ManufacturerType.Tandem, manufacturer = ManufacturerType.Tandem,
model = "t:slim", model = "t:slim",
bolusSize = 0.01, bolusSize = 0.01,
@ -267,12 +304,14 @@ enum class PumpType {
baseBasalMinValue = 0.1, baseBasalMinValue = 0.1,
baseBasalStep = 0.001, baseBasalStep = 0.001,
baseBasalSpecialSteps = null, baseBasalSpecialSteps = null,
pumpCapability = PumpCapability.VirtualPumpCapabilities), pumpCapability = PumpCapability.VirtualPumpCapabilities
),
TANDEM_T_FLEX(description = "Tandem t:flex", model = "t:flex", parent = TANDEM_T_SLIM), TANDEM_T_FLEX(description = "Tandem t:flex", model = "t:flex", parent = TANDEM_T_SLIM),
TANDEM_T_SLIM_G4(description = "Tandem t:slim G4", model = "t:slim G4", parent = TANDEM_T_SLIM), TANDEM_T_SLIM_G4(description = "Tandem t:slim G4", model = "t:slim G4", parent = TANDEM_T_SLIM),
TANDEM_T_SLIM_X2(description = "Tandem t:slim X2", model = "t:slim X2", parent = TANDEM_T_SLIM), TANDEM_T_SLIM_X2(description = "Tandem t:slim X2", model = "t:slim X2", parent = TANDEM_T_SLIM),
YPSOPUMP(description = "YpsoPump", YPSOPUMP(
description = "YpsoPump",
manufacturer = ManufacturerType.Ypsomed, manufacturer = ManufacturerType.Ypsomed,
model = "Ypsopump", model = "Ypsopump",
bolusSize = 0.1, bolusSize = 0.1,
@ -285,26 +324,39 @@ enum class PumpType {
baseBasalMaxValue = 40.0, baseBasalMaxValue = 40.0,
baseBasalStep = 0.01, baseBasalStep = 0.01,
baseBasalSpecialSteps = DoseStepSize.YpsopumpBasal, baseBasalSpecialSteps = DoseStepSize.YpsopumpBasal,
pumpCapability = PumpCapability.YpsomedCapabilities), pumpCapability = PumpCapability.YpsomedCapabilities
MDI(description = "MDI", ),
MDI(
description = "MDI",
manufacturer = ManufacturerType.AndroidAPS, manufacturer = ManufacturerType.AndroidAPS,
bolusSize = 0.5, bolusSize = 0.5,
model = "MDI", model = "MDI",
tbrSettings = DoseSettings(1.0, 15, 24 * 60, 0.0, 500.0), tbrSettings = DoseSettings(1.0, 15, 24 * 60, 0.0, 500.0),
extendedBolusSettings = DoseSettings(0.1, 15, 12 * 60, 0.1), extendedBolusSettings = DoseSettings(0.1, 15, 12 * 60, 0.1),
pumpCapability = PumpCapability.MDI), pumpCapability = PumpCapability.MDI
),
// Not real pump. Used for User as a source // Not real pump. Used for User as a source
USER(description = "USER", USER(
description = "USER",
manufacturer = ManufacturerType.AndroidAPS, manufacturer = ManufacturerType.AndroidAPS,
model = "USER", model = "USER",
tbrSettings = DoseSettings(1.0, 15, 24 * 60, 0.0, 500.0), tbrSettings = DoseSettings(1.0, 15, 24 * 60, 0.0, 500.0),
extendedBolusSettings = DoseSettings(0.1, 15, 12 * 60, 0.1), extendedBolusSettings = DoseSettings(0.1, 15, 12 * 60, 0.1),
pumpCapability = PumpCapability.MDI, pumpCapability = PumpCapability.MDI,
source = Sources.MDI), source = Sources.MDI
),
// Not real, cached value
CACHE(
description = "CACHE",
model = "CACHE",
parent = USER
),
//Diaconn Pump //Diaconn Pump
DIACONN_G8(description = "Diaconn G8", DIACONN_G8(
description = "Diaconn G8",
manufacturer = ManufacturerType.G2e, manufacturer = ManufacturerType.G2e,
model = "DiaconnG8", model = "DiaconnG8",
bolusSize = 0.01, bolusSize = 0.01,
@ -319,7 +371,8 @@ enum class PumpType {
baseBasalSpecialSteps = null, baseBasalSpecialSteps = null,
pumpCapability = PumpCapability.DiaconnCapabilities, pumpCapability = PumpCapability.DiaconnCapabilities,
source = Sources.DiaconnG8, source = Sources.DiaconnG8,
useHardwareLink = true); useHardwareLink = true
);
val description: String val description: String
var manufacturer: ManufacturerType? = null var manufacturer: ManufacturerType? = null
@ -407,6 +460,7 @@ enum class PumpType {
InterfaceIDs.PumpType.MDI -> MDI InterfaceIDs.PumpType.MDI -> MDI
InterfaceIDs.PumpType.USER -> USER InterfaceIDs.PumpType.USER -> USER
InterfaceIDs.PumpType.DIACONN_G8 -> DIACONN_G8 InterfaceIDs.PumpType.DIACONN_G8 -> DIACONN_G8
InterfaceIDs.PumpType.CACHE -> TODO()
} }
} }
@ -418,25 +472,27 @@ enum class PumpType {
parent.model = model parent.model = model
} }
constructor(description: String, constructor(
manufacturer: ManufacturerType, description: String,
model: String, manufacturer: ManufacturerType,
bolusSize: Double = 0.0, model: String,
specialBolusSize: DoseStepSize? = null, bolusSize: Double = 0.0,
extendedBolusSettings: DoseSettings, specialBolusSize: DoseStepSize? = null,
pumpTempBasalType: PumpTempBasalType? = null, extendedBolusSettings: DoseSettings,
tbrSettings: DoseSettings, pumpTempBasalType: PumpTempBasalType? = null,
specialBasalDurations: PumpCapability? = null, tbrSettings: DoseSettings,
baseBasalMinValue: Double = 0.01, specialBasalDurations: PumpCapability? = null,
baseBasalMaxValue: Double? = null, baseBasalMinValue: Double = 0.01,
baseBasalStep: Double = 1.0, baseBasalMaxValue: Double? = null,
baseBasalSpecialSteps: DoseStepSize? = null, baseBasalStep: Double = 1.0,
pumpCapability: PumpCapability, baseBasalSpecialSteps: DoseStepSize? = null,
hasCustomUnreachableAlertCheck: Boolean = false, pumpCapability: PumpCapability,
isPatchPump: Boolean = false, hasCustomUnreachableAlertCheck: Boolean = false,
supportBatteryLevel: Boolean = true, isPatchPump: Boolean = false,
useHardwareLink: Boolean = false, supportBatteryLevel: Boolean = true,
source: Sources = Sources.VirtualPump) { useHardwareLink: Boolean = false,
source: Sources = Sources.VirtualPump
) {
this.description = description this.description = description
this.manufacturer = manufacturer this.manufacturer = manufacturer
this.model = model this.model = model
@ -463,12 +519,14 @@ enum class PumpType {
val eb = extendedBolusSettings ?: return "INVALID" val eb = extendedBolusSettings ?: return "INVALID"
val tbr = tbrSettings ?: return "INVALID" val tbr = tbrSettings ?: return "INVALID"
val extendedNote = if (hasExtendedBasals) rh.gs(R.string.def_extended_note) else "" val extendedNote = if (hasExtendedBasals) rh.gs(R.string.def_extended_note) else ""
return String.format(i18nTemplate, return String.format(
i18nTemplate,
getStep("" + bolusSize, specialBolusSize), getStep("" + bolusSize, specialBolusSize),
eb.step, eb.durationStep, eb.maxDuration / 60, eb.step, eb.durationStep, eb.maxDuration / 60,
getStep(baseBasalRange(), baseBasalSpecialSteps), getStep(baseBasalRange(), baseBasalSpecialSteps),
tbr.minDose.toString() + unit + "-" + tbr.maxDose + unit, tbr.step.toString() + unit, tbr.minDose.toString() + unit + "-" + tbr.maxDose + unit, tbr.step.toString() + unit,
tbr.durationStep, tbr.maxDuration / 60, extendedNote) tbr.durationStep, tbr.maxDuration / 60, extendedNote
)
} }
private fun baseBasalRange(): String = private fun baseBasalRange(): String =
@ -494,42 +552,45 @@ enum class PumpType {
fun determineCorrectBasalSize(basalAmount: Double): Double { fun determineCorrectBasalSize(basalAmount: Double): Double {
val tSettings = tbrSettings ?: throw IllegalStateException() val tSettings = tbrSettings ?: throw IllegalStateException()
return Round.roundTo(min(basalAmount, tSettings.maxDose), baseBasalSpecialSteps?.getStepSizeForAmount(basalAmount) return Round.roundTo(
?: baseBasalStep) min(basalAmount, tSettings.maxDose), baseBasalSpecialSteps?.getStepSizeForAmount(basalAmount)
?: baseBasalStep
)
} }
fun toDbPumpType(): InterfaceIDs.PumpType = fun toDbPumpType(): InterfaceIDs.PumpType =
when (this) { when (this) {
GENERIC_AAPS -> InterfaceIDs.PumpType.GENERIC_AAPS GENERIC_AAPS -> InterfaceIDs.PumpType.GENERIC_AAPS
CELLNOVO -> InterfaceIDs.PumpType.CELLNOVO CELLNOVO -> InterfaceIDs.PumpType.CELLNOVO
ACCU_CHEK_COMBO -> InterfaceIDs.PumpType.ACCU_CHEK_COMBO ACCU_CHEK_COMBO -> InterfaceIDs.PumpType.ACCU_CHEK_COMBO
ACCU_CHEK_SPIRIT -> InterfaceIDs.PumpType.ACCU_CHEK_SPIRIT ACCU_CHEK_SPIRIT -> InterfaceIDs.PumpType.ACCU_CHEK_SPIRIT
ACCU_CHEK_INSIGHT_VIRTUAL -> InterfaceIDs.PumpType.ACCU_CHEK_INSIGHT ACCU_CHEK_INSIGHT_VIRTUAL -> InterfaceIDs.PumpType.ACCU_CHEK_INSIGHT
ACCU_CHEK_INSIGHT -> InterfaceIDs.PumpType.ACCU_CHEK_INSIGHT_BLUETOOTH ACCU_CHEK_INSIGHT -> InterfaceIDs.PumpType.ACCU_CHEK_INSIGHT_BLUETOOTH
ACCU_CHEK_SOLO -> InterfaceIDs.PumpType.ACCU_CHEK_SOLO ACCU_CHEK_SOLO -> InterfaceIDs.PumpType.ACCU_CHEK_SOLO
ANIMAS_VIBE -> InterfaceIDs.PumpType.ANIMAS_VIBE ANIMAS_VIBE -> InterfaceIDs.PumpType.ANIMAS_VIBE
ANIMAS_PING -> InterfaceIDs.PumpType.ANIMAS_PING ANIMAS_PING -> InterfaceIDs.PumpType.ANIMAS_PING
DANA_R -> InterfaceIDs.PumpType.DANA_R DANA_R -> InterfaceIDs.PumpType.DANA_R
DANA_R_KOREAN -> InterfaceIDs.PumpType.DANA_R_KOREAN DANA_R_KOREAN -> InterfaceIDs.PumpType.DANA_R_KOREAN
DANA_RS -> InterfaceIDs.PumpType.DANA_RS DANA_RS -> InterfaceIDs.PumpType.DANA_RS
DANA_RS_KOREAN -> InterfaceIDs.PumpType.DANA_RS_KOREAN DANA_RS_KOREAN -> InterfaceIDs.PumpType.DANA_RS_KOREAN
DANA_RV2 -> InterfaceIDs.PumpType.DANA_RV2 DANA_RV2 -> InterfaceIDs.PumpType.DANA_RV2
DANA_I -> InterfaceIDs.PumpType.DANA_I DANA_I -> InterfaceIDs.PumpType.DANA_I
OMNIPOD_EROS -> InterfaceIDs.PumpType.OMNIPOD_EROS OMNIPOD_EROS -> InterfaceIDs.PumpType.OMNIPOD_EROS
OMNIPOD_DASH -> InterfaceIDs.PumpType.OMNIPOD_DASH OMNIPOD_DASH -> InterfaceIDs.PumpType.OMNIPOD_DASH
MEDTRONIC_512_712 -> InterfaceIDs.PumpType.MEDTRONIC_512_517 MEDTRONIC_512_712 -> InterfaceIDs.PumpType.MEDTRONIC_512_517
MEDTRONIC_515_715 -> InterfaceIDs.PumpType.MEDTRONIC_515_715 MEDTRONIC_515_715 -> InterfaceIDs.PumpType.MEDTRONIC_515_715
MEDTRONIC_522_722 -> InterfaceIDs.PumpType.MEDTRONIC_522_722 MEDTRONIC_522_722 -> InterfaceIDs.PumpType.MEDTRONIC_522_722
MEDTRONIC_523_723_REVEL -> InterfaceIDs.PumpType.MEDTRONIC_523_723_REVEL MEDTRONIC_523_723_REVEL -> InterfaceIDs.PumpType.MEDTRONIC_523_723_REVEL
MEDTRONIC_554_754_VEO -> InterfaceIDs.PumpType.MEDTRONIC_554_754_VEO MEDTRONIC_554_754_VEO -> InterfaceIDs.PumpType.MEDTRONIC_554_754_VEO
MEDTRONIC_640G -> InterfaceIDs.PumpType.MEDTRONIC_640G MEDTRONIC_640G -> InterfaceIDs.PumpType.MEDTRONIC_640G
TANDEM_T_SLIM -> InterfaceIDs.PumpType.TANDEM_T_SLIM TANDEM_T_SLIM -> InterfaceIDs.PumpType.TANDEM_T_SLIM
TANDEM_T_SLIM_G4 -> InterfaceIDs.PumpType.TANDEM_T_SLIM_G4 TANDEM_T_SLIM_G4 -> InterfaceIDs.PumpType.TANDEM_T_SLIM_G4
TANDEM_T_FLEX -> InterfaceIDs.PumpType.TANDEM_T_FLEX TANDEM_T_FLEX -> InterfaceIDs.PumpType.TANDEM_T_FLEX
TANDEM_T_SLIM_X2 -> InterfaceIDs.PumpType.TANDEM_T_SLIM_X2 TANDEM_T_SLIM_X2 -> InterfaceIDs.PumpType.TANDEM_T_SLIM_X2
YPSOPUMP -> InterfaceIDs.PumpType.YPSOPUMP YPSOPUMP -> InterfaceIDs.PumpType.YPSOPUMP
MDI -> InterfaceIDs.PumpType.MDI MDI -> InterfaceIDs.PumpType.MDI
USER -> InterfaceIDs.PumpType.USER USER -> InterfaceIDs.PumpType.USER
DIACONN_G8 -> InterfaceIDs.PumpType.DIACONN_G8 DIACONN_G8 -> InterfaceIDs.PumpType.DIACONN_G8
CACHE -> InterfaceIDs.PumpType.CACHE
} }
} }

View file

@ -28,8 +28,8 @@ class AlarmSoundServiceHelper @Inject constructor(
private val notificationHolder: NotificationHolder private val notificationHolder: NotificationHolder
) { ) {
fun startAlarm(context: Context, sound: Int) { fun startAlarm(context: Context, sound: Int, reason: String) {
aapsLogger.debug(LTag.CORE, "Starting alarm") aapsLogger.debug(LTag.CORE, "Starting alarm from $reason")
val connection = object : ServiceConnection { val connection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, service: IBinder?) { override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
// The binder of the service that returns the instance that is created. // The binder of the service that returns the instance that is created.
@ -62,8 +62,8 @@ class AlarmSoundServiceHelper @Inject constructor(
} }
} }
fun stopService(context: Context) { fun stopService(context: Context, reason: String) {
aapsLogger.debug(LTag.CORE, "Stopping alarm") aapsLogger.debug(LTag.CORE, "Stopping alarm from $reason")
val alarm = Intent(context, AlarmSoundService::class.java) val alarm = Intent(context, AlarmSoundService::class.java)
context.stopService(alarm) context.stopService(alarm)
} }

View file

@ -2,7 +2,9 @@
<resources> <resources>
<!-- Keys--> <!-- Keys-->
<!-- General--> <!-- General-->
<string name="save">Stoor</string>
<string name="pump_basebasalrate">%1$.2f U/h</string> <string name="pump_basebasalrate">%1$.2f U/h</string>
<string name="active"><![CDATA[<Active>]]></string>
<string name="yes">Ja</string> <string name="yes">Ja</string>
<string name="no">Nee</string> <string name="no">Nee</string>
<string name="loopdisabled">LOOP UIT AKSIE GESTEL DEUR BEPERKINGS</string> <string name="loopdisabled">LOOP UIT AKSIE GESTEL DEUR BEPERKINGS</string>
@ -60,5 +62,6 @@
<!-- HardLimits --> <!-- HardLimits -->
<string name="valuelimitedto">%1$.2f beperk tot %2$.2f</string> <string name="valuelimitedto">%1$.2f beperk tot %2$.2f</string>
<!-- Command Queue + readStatus reasons --> <!-- Command Queue + readStatus reasons -->
<string name="basal">Basale</string>
<!-- Autotune --> <!-- Autotune -->
</resources> </resources>

View file

@ -4,6 +4,7 @@
<!-- General--> <!-- General-->
<string name="refresh">Обнови</string> <string name="refresh">Обнови</string>
<string name="error">Грешка</string> <string name="error">Грешка</string>
<string name="save">Съхрани</string>
<string name="not_set_short">Не е зададен</string> <string name="not_set_short">Не е зададен</string>
<string name="failedupdatebasalprofile">Неуспешно обновяване на базалния профил</string> <string name="failedupdatebasalprofile">Неуспешно обновяване на базалния профил</string>
<string name="profile_set_ok">Профила на помпата е обновен</string> <string name="profile_set_ok">Профила на помпата е обновен</string>
@ -41,6 +42,7 @@
<string name="carbs">въглехидрати</string> <string name="carbs">въглехидрати</string>
<string name="invalidprofile">Грешен профил !!!</string> <string name="invalidprofile">Грешен профил !!!</string>
<string name="noprofileset">НЕ Е АКТИВИРАН ПРОФИЛ</string> <string name="noprofileset">НЕ Е АКТИВИРАН ПРОФИЛ</string>
<string name="active"><![CDATA[<Активно>]]></string>
<string name="date">Дата</string> <string name="date">Дата</string>
<string name="units_label">Единици</string> <string name="units_label">Единици</string>
<string name="dia_label">DIA (Време на действие на инсулина):</string> <string name="dia_label">DIA (Време на действие на инсулина):</string>
@ -285,6 +287,7 @@
<string name="valuelimitedto">%1$.2f ограничен до %2$.2f</string> <string name="valuelimitedto">%1$.2f ограничен до %2$.2f</string>
<!-- Command Queue + readStatus reasons --> <!-- Command Queue + readStatus reasons -->
<string name="sms" comment="26 characters max for translation">SMS</string> <string name="sms" comment="26 characters max for translation">SMS</string>
<string name="basal">Базал</string>
<!-- Autotune --> <!-- Autotune -->
<plurals name="days"> <plurals name="days">
<item quantity="one">%1$d дeн</item> <item quantity="one">%1$d дeн</item>

View file

@ -2,6 +2,8 @@
<resources> <resources>
<!-- Keys--> <!-- Keys-->
<!-- General--> <!-- General-->
<string name="save">Desar</string>
<string name="active"><![CDATA[<Actiu>]]></string>
<!-- Constraints--> <!-- Constraints-->
<!-- Dialogs--> <!-- Dialogs-->
<!-- BlePreCheck--> <!-- BlePreCheck-->
@ -66,5 +68,6 @@
<string name="valuelimitedto">%1$.2f limitat a %2$.2f</string> <string name="valuelimitedto">%1$.2f limitat a %2$.2f</string>
<string name="valueoutofrange">»%1$s« supera els límits</string> <string name="valueoutofrange">»%1$s« supera els límits</string>
<!-- Command Queue + readStatus reasons --> <!-- Command Queue + readStatus reasons -->
<string name="basal">Basal</string>
<!-- Autotune --> <!-- Autotune -->
</resources> </resources>

View file

@ -464,8 +464,8 @@
<string name="autotune_last_run">Poslední spuštění :</string> <string name="autotune_last_run">Poslední spuštění :</string>
<string name="autotune_warning">Varování :</string> <string name="autotune_warning">Varování :</string>
<string name="autotune_select_profile">Vyberte profil pro ladění</string> <string name="autotune_select_profile">Vyberte profil pro ladění</string>
<string name="autotune_ic_warning">Autotune funguje pouze s jedinou hodnotou IC, váš profil má %1$d hodnot. Průměrná hodnota je %2$.2fg/U</string> <string name="autotune_ic_warning">Vybraný profil má %1$d hodnot IC. Autotune bude používat %2$.2f g/U</string>
<string name="autotune_isf_warning">Autotune funguje pouze s jedinou hodnotou ISF, váš profil má %1$d hodnot. Průměrná hodnota je %2$.1f%3$s/U</string> <string name="autotune_isf_warning">Vybraný profil má %1$d hodnot ISF. Autotune bude používat %2$.1f %3$s/U</string>
<string name="autotune_error">Chyba vstupních dat, zkuste autotune spustit znovu nebo snížit počet dní</string> <string name="autotune_error">Chyba vstupních dat, zkuste autotune spustit znovu nebo snížit počet dní</string>
<string name="autotune_warning_during_run">Autotune spuštěno, prosím buďte trpěliví</string> <string name="autotune_warning_during_run">Autotune spuštěno, prosím buďte trpěliví</string>
<string name="autotune_warning_after_run">Před použitím výsledky pečlivě zkontrolujte!</string> <string name="autotune_warning_after_run">Před použitím výsledky pečlivě zkontrolujte!</string>

View file

@ -461,8 +461,6 @@
<string name="autotune_last_run">Sidst kørt :</string> <string name="autotune_last_run">Sidst kørt :</string>
<string name="autotune_warning">Advarsel :</string> <string name="autotune_warning">Advarsel :</string>
<string name="autotune_select_profile">Vælg profil, der skal justeres</string> <string name="autotune_select_profile">Vælg profil, der skal justeres</string>
<string name="autotune_ic_warning">Autotune fungerer med kun én IC-værdi, din profil har %1$d værdier. Gennemsnitsværdi er %2$.2fg/E</string>
<string name="autotune_isf_warning">Autotune virker med kun én ISF-værdi, din profil har %1$d værdier. Gennemsnitlig værdi er %2$.1f%3$s/E</string>
<string name="autotune_warning_during_run">Automatisk beregning startet, vær venligst tålmodig</string> <string name="autotune_warning_during_run">Automatisk beregning startet, vær venligst tålmodig</string>
<string name="autotune_warning_after_run">Kontrollér resultaterne omhyggeligt, før du bruger dem!</string> <string name="autotune_warning_after_run">Kontrollér resultaterne omhyggeligt, før du bruger dem!</string>
<string name="autotune_partial_result">Delvis resultat dag %1$d / %2$d justeret</string> <string name="autotune_partial_result">Delvis resultat dag %1$d / %2$d justeret</string>

View file

@ -42,6 +42,7 @@
<string name="carbs">Kohlenhydrate</string> <string name="carbs">Kohlenhydrate</string>
<string name="invalidprofile">Ungültiges oder defektes Profil!</string> <string name="invalidprofile">Ungültiges oder defektes Profil!</string>
<string name="noprofileset">KEIN PROFIL GESETZT</string> <string name="noprofileset">KEIN PROFIL GESETZT</string>
<string name="active"><![CDATA[<Aktiv>]]></string>
<string name="date">Datum</string> <string name="date">Datum</string>
<string name="units_label">Einheiten</string> <string name="units_label">Einheiten</string>
<string name="dia_label">DIA</string> <string name="dia_label">DIA</string>
@ -428,6 +429,9 @@
<string name="insight_refresh_button" comment="26 characters max for translation">Insight Refresh Button</string> <string name="insight_refresh_button" comment="26 characters max for translation">Insight Refresh Button</string>
<string name="a11y_min_button_description">abnehmend %1$s mit %2$s</string> <string name="a11y_min_button_description">abnehmend %1$s mit %2$s</string>
<string name="a11y_plus_button_description">zunehmend %1$s mit %2$s</string> <string name="a11y_plus_button_description">zunehmend %1$s mit %2$s</string>
<string name="basal">Basal</string>
<string name="count_selected">%1$d ausgewählt</string>
<string name="sort_label">Sortieren</string>
<!-- Autotune --> <!-- Autotune -->
<plurals name="days"> <plurals name="days">
<item quantity="one">%1$d Tag</item> <item quantity="one">%1$d Tag</item>

View file

@ -2,7 +2,9 @@
<resources> <resources>
<!-- Keys--> <!-- Keys-->
<!-- General--> <!-- General-->
<string name="save">Αποθήκευση</string>
<string name="pump_basebasalrate">%1$.2f U/h</string> <string name="pump_basebasalrate">%1$.2f U/h</string>
<string name="active"><![CDATA[<Ενεργή>]]></string>
<string name="yes">Ναι</string> <string name="yes">Ναι</string>
<string name="no">Όχι</string> <string name="no">Όχι</string>
<string name="loopdisabled">ΤΟ ΚΥΚΛΩΜΑ ΑΠΕΝΕΡΓΟΠΟΙΗΘΗΚΕ ΑΠΟ ΠΕΡΙΟΡΙΣΜΟΥΣ</string> <string name="loopdisabled">ΤΟ ΚΥΚΛΩΜΑ ΑΠΕΝΕΡΓΟΠΟΙΗΘΗΚΕ ΑΠΟ ΠΕΡΙΟΡΙΣΜΟΥΣ</string>
@ -60,5 +62,6 @@
<!-- HardLimits --> <!-- HardLimits -->
<string name="valuelimitedto">Το %1$.2f περιορίζεται σε %2$.2f</string> <string name="valuelimitedto">Το %1$.2f περιορίζεται σε %2$.2f</string>
<!-- Command Queue + readStatus reasons --> <!-- Command Queue + readStatus reasons -->
<string name="basal">Βασικός Ρυθμός</string>
<!-- Autotune --> <!-- Autotune -->
</resources> </resources>

View file

@ -464,8 +464,6 @@
<string name="autotune_last_run">Última ejecución :</string> <string name="autotune_last_run">Última ejecución :</string>
<string name="autotune_warning">Advertencia :</string> <string name="autotune_warning">Advertencia :</string>
<string name="autotune_select_profile">Selecciona el perfil para a ajustar</string> <string name="autotune_select_profile">Selecciona el perfil para a ajustar</string>
<string name="autotune_ic_warning">Autotune sólo funciona con un valor de IC. Tu perfil tiene %1$d valores. El valor promedio es %2$.2fg/U</string>
<string name="autotune_isf_warning">Autotune sólo funciona con un valor de ISF. Tu perfil tiene %1$d valores. El valor promedio es %2$.1f%3$s/U</string>
<string name="autotune_error">Error en los datos de entrada, intenta ejecutar de nuevo autotune o reducir el número de días</string> <string name="autotune_error">Error en los datos de entrada, intenta ejecutar de nuevo autotune o reducir el número de días</string>
<string name="autotune_warning_during_run">Cálculo de autototune iniciado, por favor ten paciencia</string> <string name="autotune_warning_during_run">Cálculo de autototune iniciado, por favor ten paciencia</string>
<string name="autotune_warning_after_run">¡Comprueba los resultados cuidadosamente antes de usarlos!</string> <string name="autotune_warning_after_run">¡Comprueba los resultados cuidadosamente antes de usarlos!</string>

View file

@ -446,7 +446,7 @@
<string name="autotune_description">Aide pour ajuster le profil (SI, rapport G/I et débits de basal)</string> <string name="autotune_description">Aide pour ajuster le profil (SI, rapport G/I et débits de basal)</string>
<string name="autotune_shortname">AT</string> <string name="autotune_shortname">AT</string>
<string name="autotune_settings">Paramètres Autotune</string> <string name="autotune_settings">Paramètres Autotune</string>
<string name="autotune_auto_title">Changement de profil avec l\'Automatisation</string> <string name="autotune_auto_title">Changr le profil avec l\'automatisation</string>
<string name="autotune_auto_summary">Si activé, Autotune mettra à jour automatiquement à jour le profil sélectionné et activera le profil calculé effectué à partir d\'une règle d\'automatisation.</string> <string name="autotune_auto_summary">Si activé, Autotune mettra à jour automatiquement à jour le profil sélectionné et activera le profil calculé effectué à partir d\'une règle d\'automatisation.</string>
<string name="autotune_categorize_uam_as_basal_title">Catégoriser UAM en tant que Basal</string> <string name="autotune_categorize_uam_as_basal_title">Catégoriser UAM en tant que Basal</string>
<string name="autotune_categorize_uam_as_basal_summary">Activer uniquement si vous avez correctement saisi tous les glucides consommés, avec cette option, des hausses soudaines vues par Autotune seront utilisées pour modifier les débits de basal.</string> <string name="autotune_categorize_uam_as_basal_summary">Activer uniquement si vous avez correctement saisi tous les glucides consommés, avec cette option, des hausses soudaines vues par Autotune seront utilisées pour modifier les débits de basal.</string>
@ -464,8 +464,8 @@
<string name="autotune_last_run">Dernier run :</string> <string name="autotune_last_run">Dernier run :</string>
<string name="autotune_warning">Avertissement :</string> <string name="autotune_warning">Avertissement :</string>
<string name="autotune_select_profile">Sélectionnez le profil à optimiser</string> <string name="autotune_select_profile">Sélectionnez le profil à optimiser</string>
<string name="autotune_ic_warning">Autotune ne fonctionne qu\'avec une seule valeur G/I, votre profil a %1$d valeurs. La valeur moyenne est de %2$.2f g/U</string> <string name="autotune_ic_warning">Le profil sélectionné %1$d valeurs de G/I. Autotune va utiliser la moyenne %2$.2f g/U</string>
<string name="autotune_isf_warning">Autotune ne calcule qu\'une seule valeur de SI, votre profil a %1$d valeurs. La valeur moyenne est de %2$.1f %3$s/U</string> <string name="autotune_isf_warning">Le profil sélectionné a %1$d valeurs de SI. Autotune va utiliser la moyenne %2$.1f %3$s/U</string>
<string name="autotune_error">Erreur dans les données d\'entrée, essayez de relancer le calcul ou réduire le nombre de jours</string> <string name="autotune_error">Erreur dans les données d\'entrée, essayez de relancer le calcul ou réduire le nombre de jours</string>
<string name="autotune_warning_during_run">Le calcul Autotune a commencé, veuillez patienter</string> <string name="autotune_warning_during_run">Le calcul Autotune a commencé, veuillez patienter</string>
<string name="autotune_warning_after_run">Vérifiez attentivement les résultats avant de les utiliser!</string> <string name="autotune_warning_after_run">Vérifiez attentivement les résultats avant de les utiliser!</string>

View file

@ -3,6 +3,7 @@
<!-- Keys--> <!-- Keys-->
<!-- General--> <!-- General-->
<string name="error">Earráid</string> <string name="error">Earráid</string>
<string name="save">Sábháil</string>
<string name="waitingforpump">Ag fanacht do caidéil</string> <string name="waitingforpump">Ag fanacht do caidéil</string>
<string name="connectingfor">Ag nascadh le %1$d s</string> <string name="connectingfor">Ag nascadh le %1$d s</string>
<string name="bolusdelivering">Ag seachadadh %1$.2f A</string> <string name="bolusdelivering">Ag seachadadh %1$.2f A</string>
@ -114,5 +115,6 @@
<!-- User Entry --> <!-- User Entry -->
<!-- HardLimits --> <!-- HardLimits -->
<!-- Command Queue + readStatus reasons --> <!-- Command Queue + readStatus reasons -->
<string name="basal">Bunaidh</string>
<!-- Autotune --> <!-- Autotune -->
</resources> </resources>

View file

@ -2,8 +2,10 @@
<resources> <resources>
<!-- Keys--> <!-- Keys-->
<!-- General--> <!-- General-->
<string name="close">Zatvori</string>
<!-- Constraints--> <!-- Constraints-->
<!-- Dialogs--> <!-- Dialogs-->
<string name="cancel">Otkaži</string>
<!-- BlePreCheck--> <!-- BlePreCheck-->
<!-- Protection--> <!-- Protection-->
<!-- Profile--> <!-- Profile-->

View file

@ -26,5 +26,6 @@
<!-- User Entry --> <!-- User Entry -->
<!-- HardLimits --> <!-- HardLimits -->
<!-- Command Queue + readStatus reasons --> <!-- Command Queue + readStatus reasons -->
<string name="basal">Bázis</string>
<!-- Autotune --> <!-- Autotune -->
</resources> </resources>

View file

@ -464,8 +464,8 @@
<string name="autotune_last_run">הפעלה אחרונה :</string> <string name="autotune_last_run">הפעלה אחרונה :</string>
<string name="autotune_warning">אזהרה :</string> <string name="autotune_warning">אזהרה :</string>
<string name="autotune_select_profile">בחרו פרופיל לכוונון</string> <string name="autotune_select_profile">בחרו פרופיל לכוונון</string>
<string name="autotune_ic_warning">כוונון אוטומטי עובד עם ערך IC אחד בלבד, לפרופיל שלכם יש %1$d ערכים. הערך הממוצע הוא %2$.2f גר\'\\יח\'</string> <string name="autotune_ic_warning">בפרופיל הנבחר יש %1$d ערכי יחס פחמימות. הכיוונון האוטומטי ישתמש ב-%2$.2f גר\'\\יח\'</string>
<string name="autotune_isf_warning">כוונון אוטומטי עובד עם ערך ISF אחד בלבד, לפרופיל שלכם יש %1$d ערכים. הערך הממוצע הוא %2$.1f %3$s\\יח\'</string> <string name="autotune_isf_warning">בפרופיל הנבחר יש %1$d ערכי יחס תיקון. הכיוונון האוטומטי ישתמש ב-%2$.1f %3$s\\יח\'</string>
<string name="autotune_error">שגיאה בנתוני הקלט, נסו להפעיל בשנית או שנסו לצמצם את מספר הימים</string> <string name="autotune_error">שגיאה בנתוני הקלט, נסו להפעיל בשנית או שנסו לצמצם את מספר הימים</string>
<string name="autotune_warning_during_run">חישוב הכוונון האוטומטי התחיל, אנא התאזרו בסבלנות</string> <string name="autotune_warning_during_run">חישוב הכוונון האוטומטי התחיל, אנא התאזרו בסבלנות</string>
<string name="autotune_warning_after_run">בדקו היטב את התוצאות לפני השימוש בהן!</string> <string name="autotune_warning_after_run">בדקו היטב את התוצאות לפני השימוש בהן!</string>

Some files were not shown because too many files have changed in this diff Show more