Merge branch 'dev' into medtronic_modules

This commit is contained in:
Andy Rozman 2020-07-12 20:21:03 +01:00
commit 6e50c3651d
473 changed files with 4279 additions and 960 deletions

View file

@ -11,4 +11,6 @@
dev: [![codecov](https://codecov.io/gh/MilosKozak/AndroidAPS/branch/dev/graph/badge.svg)](https://codecov.io/gh/MilosKozak/AndroidAPS)
[![Donate via PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=Y4LHGJJESAVB8)
[![Donate via PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=Y4LHGJJESAVB8)
![BTC](https://bitit.io/assets/coins/icon-btc-1e5a37bc0eb730ac83130d7aa859052bd4b53ac3f86f99966627801f7b0410be.svg) 3KawK8aQe48478s6fxJ8Ms6VTWkwjgr9f2

View file

@ -245,9 +245,9 @@ dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.google.android.gms:play-services-wearable:17.0.0'
implementation "com.google.android.gms:play-services-location:17.0.0"
implementation 'com.google.firebase:firebase-core:17.4.2'
implementation 'com.google.firebase:firebase-core:17.4.3'
implementation 'com.google.firebase:firebase-auth:19.3.1'
implementation 'com.google.firebase:firebase-database:19.3.0'
implementation 'com.google.firebase:firebase-database:19.3.1'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.legacy:legacy-support-v13:1.0.0'

View file

@ -68,6 +68,7 @@
<activity android:name=".plugins.general.maintenance.activities.PrefImportListActivity" />
<activity android:name=".historyBrowser.HistoryBrowseActivity" />
<activity android:name=".activities.SurveyActivity" />
<activity android:name=".activities.ProfileHelperActivity" />
<activity android:name=".activities.StatsActivity" />
<!-- Receive new BG readings from other local apps -->

View file

@ -27,6 +27,7 @@ import androidx.viewpager2.widget.ViewPager2
import com.google.android.material.tabs.TabLayoutMediator
import com.joanzapata.iconify.Iconify
import com.joanzapata.iconify.fonts.FontAwesomeModule
import info.nightscout.androidaps.activities.ProfileHelperActivity
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity
import info.nightscout.androidaps.activities.PreferencesActivity
import info.nightscout.androidaps.activities.SingleFragmentActivity
@ -49,10 +50,10 @@ import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicato
import info.nightscout.androidaps.setupwizard.SetupWizardActivity
import info.nightscout.androidaps.utils.AndroidPermission
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.locale.LocaleHelper
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
import info.nightscout.androidaps.utils.extensions.isRunningRealPumpTest
import info.nightscout.androidaps.utils.locale.LocaleHelper
import info.nightscout.androidaps.utils.protection.ProtectionCheck
import info.nightscout.androidaps.utils.resources.IconsProvider
import info.nightscout.androidaps.utils.resources.ResourceHelper
@ -138,15 +139,15 @@ class MainActivity : NoSplashAppCompatActivity() {
}
androidPermission.notifyForStoragePermission(this)
androidPermission.notifyForBatteryOptimizationPermission(this)
androidPermission.notifyForLocationPermissions(this)
if (config.PUMPDRIVERS) {
androidPermission.notifyForLocationPermissions(this)
androidPermission.notifyForSMSPermissions(this, smsCommunicatorPlugin)
androidPermission.notifyForSystemWindowPermissions(this)
}
}
private fun checkPluginPreferences(viewPager: ViewPager2) {
pluginPreferencesMenuItem?.isEnabled = (viewPager.adapter as TabPageAdapter).getPluginAt(viewPager.currentItem).preferencesId != -1
if (viewPager.currentItem > 0) pluginPreferencesMenuItem?.isEnabled = (viewPager.adapter as TabPageAdapter).getPluginAt(viewPager.currentItem).preferencesId != -1
}
override fun onPostCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {
@ -324,6 +325,11 @@ class MainActivity : NoSplashAppCompatActivity() {
return true
}
*/
R.id.nav_defaultprofile -> {
startActivity(Intent(this, ProfileHelperActivity::class.java))
return true
}
R.id.nav_stats -> {
startActivity(Intent(this, StatsActivity::class.java))
return true

View file

@ -53,6 +53,7 @@ public class MainApp extends DaggerApplication {
@Inject VersionCheckerUtils versionCheckersUtils;
@Inject SP sp;
@Inject NSUpload nsUpload;
@Inject Config config;
@Inject ConfigBuilderPlugin configBuilderPlugin;
@Inject KeepAliveReceiver.KeepAliveManager keepAliveManager;
@ -103,6 +104,13 @@ public class MainApp extends DaggerApplication {
private void doMigrations() {
// set values for different builds
if (!sp.contains(R.string.key_ns_alarms))
sp.putBoolean(R.string.key_ns_alarms, config.getNSCLIENT());
if (!sp.contains(R.string.key_ns_announcements))
sp.putBoolean(R.string.key_ns_announcements, config.getNSCLIENT());
if (!sp.contains(R.string.key_language))
sp.putString(R.string.key_language, "default");
}
@Override

View file

@ -13,16 +13,20 @@ import dagger.android.HasAndroidInjector
import dagger.android.support.AndroidSupportInjection
import info.nightscout.androidaps.Config
import info.nightscout.androidaps.R
import info.nightscout.androidaps.danaRKorean.DanaRKoreanPlugin
import info.nightscout.androidaps.danaRv2.DanaRv2Plugin
import info.nightscout.androidaps.danar.DanaRPlugin
import info.nightscout.androidaps.danars.DanaRSPlugin
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.events.EventPreferenceChange
import info.nightscout.androidaps.events.EventRebuildTabs
import info.nightscout.androidaps.interfaces.PluginBase
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
import info.nightscout.androidaps.plugins.aps.openAPSAMA.OpenAPSAMAPlugin
import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.configBuilder.PluginStore
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.plugins.constraints.safety.SafetyPlugin
import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin
import info.nightscout.androidaps.plugins.general.maintenance.MaintenancePlugin
@ -34,10 +38,6 @@ import info.nightscout.androidaps.plugins.general.wear.WearPlugin
import info.nightscout.androidaps.plugins.general.xdripStatusline.StatusLinePlugin
import info.nightscout.androidaps.plugins.insulin.InsulinOrefFreePeakPlugin
import info.nightscout.androidaps.plugins.pump.combo.ComboPlugin
import info.nightscout.androidaps.danar.DanaRPlugin
import info.nightscout.androidaps.danaRKorean.DanaRKoreanPlugin
import info.nightscout.androidaps.danars.DanaRSPlugin
import info.nightscout.androidaps.danaRv2.DanaRv2Plugin
import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin
import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
@ -204,14 +204,44 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang
activity?.recreate()
return
}
if (key == resourceHelper.gs(R.string.key_openapsama_useautosens) && sp.getBoolean(R.string.key_openapsama_useautosens, false))
if (key == resourceHelper.gs(R.string.key_openapsama_useautosens) && sp.getBoolean(R.string.key_openapsama_useautosens, false)) {
activity?.let {
show(it, resourceHelper.gs(R.string.configbuilder_sensitivity), resourceHelper.gs(R.string.sensitivity_warning))
}
}
checkForBiometricFallback(key)
updatePrefSummary(findPreference(key))
}
private fun checkForBiometricFallback(key: String) {
// Biometric protection activated without set master password
if ((resourceHelper.gs(R.string.key_settings_protection) == key ||
resourceHelper.gs(R.string.key_application_protection) == key ||
resourceHelper.gs(R.string.key_bolus_protection) == key) &&
sp.getString(R.string.key_master_password, "") == "" &&
sp.getInt(key, ProtectionCheck.ProtectionType.NONE.ordinal) == ProtectionCheck.ProtectionType.BIOMETRIC.ordinal
) {
activity?.let {
val title = resourceHelper.gs(R.string.unsecure_fallback_biometric)
val message = resourceHelper.gs(R.string.master_password_missing, resourceHelper.gs(R.string.configbuilder_general), resourceHelper.gs(R.string.protection))
show(it, title = title, message = message)
}
}
// Master password erased with activated Biometric protection
val isBiometricActivated = sp.getInt(R.string.key_settings_protection, ProtectionCheck.ProtectionType.NONE.ordinal) == ProtectionCheck.ProtectionType.BIOMETRIC.ordinal ||
sp.getInt(R.string.key_application_protection, ProtectionCheck.ProtectionType.NONE.ordinal) == ProtectionCheck.ProtectionType.BIOMETRIC.ordinal ||
sp.getInt(R.string.key_bolus_protection, ProtectionCheck.ProtectionType.NONE.ordinal) == ProtectionCheck.ProtectionType.BIOMETRIC.ordinal
if (resourceHelper.gs(R.string.key_master_password) == key && sp.getString(key, "") == "" && isBiometricActivated) {
activity?.let {
val title = resourceHelper.gs(R.string.unsecure_fallback_biometric)
val message = resourceHelper.gs(R.string.unsecure_fallback_descriotion_biometric)
show(it, title = title, message = message)
}
}
}
@SuppressLint("RestrictedApi")
private fun addPreferencesFromResource(@XmlRes preferencesResId: Int, key: String?) {
val xmlRoot = preferenceManager.inflateFromResource(context,
@ -276,7 +306,7 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang
}
for (plugin in pluginStore.plugins) {
pref?.let { it.key?.let { plugin.updatePreferenceSummary(pref) }}
pref?.let { it.key?.let { plugin.updatePreferenceSummary(pref) } }
}
val hmacPasswords = arrayOf(

View file

@ -0,0 +1,66 @@
package info.nightscout.androidaps.activities
import android.os.Bundle
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.defaultProfile.DefaultProfile
import info.nightscout.androidaps.dialogs.ProfileViewerDialog
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.ToastUtils
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.stats.TddCalculator
import kotlinx.android.synthetic.main.activity_profilehelper.*
import java.text.DecimalFormat
import javax.inject.Inject
class ProfileHelperActivity : NoSplashAppCompatActivity() {
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var tddCalculator: TddCalculator
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var defaultProfile: DefaultProfile
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_profilehelper)
profilehelper_age.setParams(15.0, 1.0, 80.0, 1.0, DecimalFormat("0"), false, null)
profilehelper_weight.setParams(50.0, 5.0, 150.0, 1.0, DecimalFormat("0"), false, null)
profilehelper_tdd.setParams(50.0, 3.0, 200.0, 1.0, DecimalFormat("0"), false, null)
profilehelper_tdds.text = tddCalculator.stats()
profilehelper_profile.setOnClickListener {
val age = profilehelper_age.value
val weight = profilehelper_weight.value
val tdd = profilehelper_tdd.value
if (age < 1 || age > 120) {
ToastUtils.showToastInUiThread(this, R.string.invalidage)
return@setOnClickListener
}
if ((weight < 5 || weight > 150) && tdd == 0.0) {
ToastUtils.showToastInUiThread(this, R.string.invalidweight)
return@setOnClickListener
}
if ((tdd < 5 || tdd > 150) && weight == 0.0) {
ToastUtils.showToastInUiThread(this, R.string.invalidweight)
return@setOnClickListener
}
profileFunction.getProfile()?.let { runningProfile ->
val profile = defaultProfile.profile(age, tdd, weight, profileFunction.getUnits())
ProfileViewerDialog().also { pvd ->
pvd.arguments = Bundle().also {
it.putLong("time", DateUtil.now())
it.putInt("mode", ProfileViewerDialog.Mode.PROFILE_COMPARE.ordinal)
it.putString("customProfile", runningProfile.data.toString())
it.putString("customProfile2", profile.data.toString())
it.putString("customProfileUnits", profile.units)
it.putString("customProfileName", "Age: $age TDD: $tdd Weight: $weight")
}
}.show(supportFragmentManager, "ProfileViewDialog")
}
}
}
}

View file

@ -8,9 +8,9 @@ import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.defaultProfile.DefaultProfile
import info.nightscout.androidaps.dialogs.ProfileViewerDialog
import info.nightscout.androidaps.interfaces.ActivePluginProvider
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.utils.ActivityMonitor
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.InstanceId
@ -19,7 +19,7 @@ import info.nightscout.androidaps.utils.ToastUtils
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.stats.TddCalculator
import info.nightscout.androidaps.utils.stats.TirCalculator
import kotlinx.android.synthetic.main.survey_activity.*
import kotlinx.android.synthetic.main.activity_survey.*
import javax.inject.Inject
class SurveyActivity : NoSplashAppCompatActivity() {
@ -34,7 +34,7 @@ class SurveyActivity : NoSplashAppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.survey_activity)
setContentView(R.layout.activity_survey)
survey_id.text = InstanceId.instanceId()
@ -62,16 +62,19 @@ class SurveyActivity : NoSplashAppCompatActivity() {
ToastUtils.showToastInUiThread(this, R.string.invalidweight)
return@setOnClickListener
}
val profile = defaultProfile.profile(age, tdd, weight, profileFunction.getUnits())
val args = Bundle()
args.putLong("time", DateUtil.now())
args.putInt("mode", ProfileViewerDialog.Mode.CUSTOM_PROFILE.ordinal)
args.putString("customProfile", profile.data.toString())
args.putString("customProfileUnits", profile.units)
args.putString("customProfileName", "Age: $age TDD: $tdd Weight: $weight")
val pvd = ProfileViewerDialog()
pvd.arguments = args
pvd.show(supportFragmentManager, "ProfileViewDialog")
profileFunction.getProfile()?.let { runningProfile ->
val profile = defaultProfile.profile(age, tdd, weight, profileFunction.getUnits())
ProfileViewerDialog().also { pvd ->
pvd.arguments = Bundle().also {
it.putLong("time", DateUtil.now())
it.putInt("mode", ProfileViewerDialog.Mode.PROFILE_COMPARE.ordinal)
it.putString("customProfile", runningProfile.data.toString())
it.putString("customProfile2", profile.data.toString())
it.putString("customProfileUnits", profile.units)
it.putString("customProfileName", "Age: $age TDD: $tdd Weight: $weight")
}
}.show(supportFragmentManager, "ProfileViewDialog")
}
}
survey_submit.setOnClickListener {

View file

@ -93,4 +93,9 @@ public class DatabaseHelperProvider implements DatabaseHelperInterface {
@NotNull @Override public List<TDD> getTDDsForLastXDays(int days) {
return MainApp.getDbHelper().getTDDsForLastXDays(days);
}
@NotNull @Override public List<ProfileSwitch> getProfileSwitchData(long from, boolean ascending) {
return MainApp.getDbHelper().getProfileSwitchData(from, ascending);
}
}

View file

@ -37,5 +37,6 @@ abstract class ActivitiesModule {
@ContributesAndroidInjector abstract fun contributesSmsCommunicatorOtpActivity(): SmsCommunicatorOtpActivity
@ContributesAndroidInjector abstract fun contributesStatsActivity(): StatsActivity
@ContributesAndroidInjector abstract fun contributesSurveyActivity(): SurveyActivity
@ContributesAndroidInjector abstract fun contributesDefaultProfileActivity(): ProfileHelperActivity
@ContributesAndroidInjector abstract fun contributesPrefImportListActivity(): PrefImportListActivity
}

View file

@ -83,13 +83,13 @@ class CareDialog : DialogFragmentWithDate() {
}
actions_care_icon.setImageResource(when (options) {
EventType.BGCHECK -> R.drawable.icon_cp_bgcheck
EventType.SENSOR_INSERT -> R.drawable.icon_cp_cgm_insert
EventType.BATTERY_CHANGE -> R.drawable.icon_cp_pump_battery
EventType.NOTE -> R.drawable.icon_cp_note
EventType.EXERCISE -> R.drawable.icon_cp_exercise
EventType.QUESTION -> R.drawable.icon_cp_question
EventType.ANNOUNCEMENT -> R.drawable.icon_cp_announcement
EventType.BGCHECK -> R.drawable.ic_cp_bgcheck
EventType.SENSOR_INSERT -> R.drawable.ic_cp_cgm_insert
EventType.BATTERY_CHANGE -> R.drawable.ic_cp_pump_battery
EventType.NOTE -> R.drawable.ic_cp_note
EventType.EXERCISE -> R.drawable.ic_cp_exercise
EventType.QUESTION -> R.drawable.ic_cp_question
EventType.ANNOUNCEMENT -> R.drawable.ic_cp_announcement
})
actions_care_title.text = resourceHelper.gs(when (options) {
EventType.BGCHECK -> R.string.careportal_bgcheck

View file

@ -28,6 +28,8 @@ class ProfileSwitchDialog : DialogFragmentWithDate() {
@Inject lateinit var treatmentsPlugin: TreatmentsPlugin
@Inject lateinit var activePlugin: ActivePluginProvider
var profileIndex: Int? = null
override fun onSaveInstanceState(savedInstanceState: Bundle) {
super.onSaveInstanceState(savedInstanceState)
savedInstanceState.putDouble("overview_profileswitch_duration", overview_profileswitch_duration.value)
@ -38,6 +40,9 @@ class ProfileSwitchDialog : DialogFragmentWithDate() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
onCreateViewGeneral()
arguments?.let { bundle ->
profileIndex = bundle.getInt("profileIndex", 0)
}
return inflater.inflate(R.layout.dialog_profileswitch, container, false)
}
@ -59,9 +64,12 @@ class ProfileSwitchDialog : DialogFragmentWithDate() {
val adapter = ArrayAdapter(context, R.layout.spinner_centered, profileList)
overview_profileswitch_profile.adapter = adapter
// set selected to actual profile
for (p in profileList.indices)
if (profileList[p] == profileFunction.getProfileName(false))
overview_profileswitch_profile.setSelection(p)
if (profileIndex != null)
overview_profileswitch_profile.setSelection(profileIndex as Int)
else
for (p in profileList.indices)
if (profileList[p] == profileFunction.getProfileName(false))
overview_profileswitch_profile.setSelection(p)
} ?: return
treatmentsPlugin.getProfileSwitchFromHistory(DateUtil.now())?.let { ps ->

View file

@ -76,7 +76,7 @@ class TempTargetDialog : DialogFragmentWithDate() {
val adapterReason = ArrayAdapter(context, R.layout.spinner_centered, reasonList)
overview_temptarget_reason.adapter = adapterReason
overview_temptarget_reason.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View, position: Int, id: Long) {
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
val defaultDuration: Double
val defaultTarget: Double
when (reasonList[position]) {

View file

@ -108,6 +108,7 @@ public class LoopPlugin extends PluginBase implements LoopInterface {
private boolean isDisconnected;
private long carbsSuggestionsSuspendedUntil = 0;
private int prevCarbsreq = 0;
@Nullable private LastRun lastRun = null;
@ -396,7 +397,7 @@ public class LoopPlugin extends PluginBase implements LoopInterface {
}
result.percent = (int) (result.rate / profile.getBasal() * 100);
// check rate for constrais
// check rate for constraints
final APSResult resultAfterConstraints = result.newAndClone(injector);
resultAfterConstraints.rateConstraint = new Constraint<>(resultAfterConstraints.rate);
resultAfterConstraints.rate = constraintChecker.applyBasalConstraints(resultAfterConstraints.rateConstraint, profile).value();
@ -414,6 +415,10 @@ public class LoopPlugin extends PluginBase implements LoopInterface {
resultAfterConstraints.smb = 0;
}
if (lastRun != null) {
prevCarbsreq = lastRun.getConstraintsProcessed().carbsReq;
}
if (lastRun == null) lastRun = new LastRun();
lastRun.setRequest(result);
lastRun.setConstraintsProcessed(resultAfterConstraints);
@ -494,12 +499,19 @@ public class LoopPlugin extends PluginBase implements LoopInterface {
mNotificationManager.notify(Constants.notificationID, builder.build());
rxBus.send(new EventNewOpenLoopNotification());
// Send to Wear
actionStringHandler.get().handleInitiate("changeRequest");
//only send to wear if Native notifications are turned off
if (!sp.getBoolean(R.string.key_raise_notifications_as_android_notifications, false)) {
// Send to Wear
actionStringHandler.get().handleInitiate("changeRequest");
}
}
} else {
dismissSuggestion();
//If carbs were required previously, but are no longer needed, dismiss notifications
if ( prevCarbsreq > 0 ) {
dismissSuggestion();
rxBus.send(new EventDismissNotification(Notification.CARBS_REQUIRED));
}
}
}

View file

@ -12,6 +12,7 @@ import android.widget.RadioButton
import android.widget.TextView
import androidx.annotation.StringRes
import dagger.android.support.DaggerFragment
import info.nightscout.androidaps.Config
import info.nightscout.androidaps.R
import info.nightscout.androidaps.activities.PreferencesActivity
import info.nightscout.androidaps.events.EventRebuildTabs
@ -20,9 +21,9 @@ import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.configBuilder.events.EventConfigBuilderUpdateGui
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.extensions.plusAssign
import info.nightscout.androidaps.utils.extensions.toVisibility
import info.nightscout.androidaps.utils.protection.ProtectionCheck
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.extensions.toVisibility
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.configbuilder_fragment.*
@ -36,6 +37,7 @@ class ConfigBuilderFragment : DaggerFragment() {
@Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var activePlugin: ActivePluginProvider
@Inject lateinit var protectionCheck: ProtectionCheck
@Inject lateinit var config: Config
private var disposable: CompositeDisposable = CompositeDisposable()
private val pluginViewHolders = ArrayList<PluginViewHolder>()
@ -86,14 +88,20 @@ class ConfigBuilderFragment : DaggerFragment() {
@Synchronized
private fun updateGUI() {
configbuilder_categories.removeAllViews()
createViewsForPlugins(R.string.configbuilder_profile, R.string.configbuilder_profile_description, PluginType.PROFILE, activePlugin.getSpecificPluginsVisibleInListByInterface(ProfileInterface::class.java, PluginType.PROFILE))
if (!config.NSCLIENT) {
createViewsForPlugins(R.string.configbuilder_profile, R.string.configbuilder_profile_description, PluginType.PROFILE, activePlugin.getSpecificPluginsVisibleInListByInterface(ProfileInterface::class.java, PluginType.PROFILE))
}
createViewsForPlugins(R.string.configbuilder_insulin, R.string.configbuilder_insulin_description, PluginType.INSULIN, activePlugin.getSpecificPluginsVisibleInListByInterface(InsulinInterface::class.java, PluginType.INSULIN))
createViewsForPlugins(R.string.configbuilder_bgsource, R.string.configbuilder_bgsource_description, PluginType.BGSOURCE, activePlugin.getSpecificPluginsVisibleInListByInterface(BgSourceInterface::class.java, PluginType.BGSOURCE))
createViewsForPlugins(R.string.configbuilder_pump, R.string.configbuilder_pump_description, PluginType.PUMP, activePlugin.getSpecificPluginsVisibleInList(PluginType.PUMP))
if (!config.NSCLIENT) {
createViewsForPlugins(R.string.configbuilder_bgsource, R.string.configbuilder_bgsource_description, PluginType.BGSOURCE, activePlugin.getSpecificPluginsVisibleInListByInterface(BgSourceInterface::class.java, PluginType.BGSOURCE))
createViewsForPlugins(R.string.configbuilder_pump, R.string.configbuilder_pump_description, PluginType.PUMP, activePlugin.getSpecificPluginsVisibleInList(PluginType.PUMP))
}
createViewsForPlugins(R.string.configbuilder_sensitivity, R.string.configbuilder_sensitivity_description, PluginType.SENSITIVITY, activePlugin.getSpecificPluginsVisibleInListByInterface(SensitivityInterface::class.java, PluginType.SENSITIVITY))
createViewsForPlugins(R.string.configbuilder_aps, R.string.configbuilder_aps_description, PluginType.APS, activePlugin.getSpecificPluginsVisibleInList(PluginType.APS))
createViewsForPlugins(R.string.configbuilder_loop, R.string.configbuilder_loop_description, PluginType.LOOP, activePlugin.getSpecificPluginsVisibleInList(PluginType.LOOP))
createViewsForPlugins(R.string.constraints, R.string.configbuilder_constraints_description, PluginType.CONSTRAINTS, activePlugin.getSpecificPluginsVisibleInListByInterface(ConstraintsInterface::class.java, PluginType.CONSTRAINTS))
if (config.APS) {
createViewsForPlugins(R.string.configbuilder_aps, R.string.configbuilder_aps_description, PluginType.APS, activePlugin.getSpecificPluginsVisibleInList(PluginType.APS))
createViewsForPlugins(R.string.configbuilder_loop, R.string.configbuilder_loop_description, PluginType.LOOP, activePlugin.getSpecificPluginsVisibleInList(PluginType.LOOP))
createViewsForPlugins(R.string.constraints, R.string.configbuilder_constraints_description, PluginType.CONSTRAINTS, activePlugin.getSpecificPluginsVisibleInListByInterface(ConstraintsInterface::class.java, PluginType.CONSTRAINTS))
}
createViewsForPlugins(R.string.configbuilder_treatments, R.string.configbuilder_treatments_description, PluginType.TREATMENT, activePlugin.getSpecificPluginsVisibleInList(PluginType.TREATMENT))
createViewsForPlugins(R.string.configbuilder_general, R.string.configbuilder_general_description, PluginType.GENERAL, activePlugin.getSpecificPluginsVisibleInList(PluginType.GENERAL))
}

View file

@ -4,6 +4,7 @@ import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.Handler
import android.os.HandlerThread
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.events.EventBTChange
@ -39,7 +40,6 @@ import org.json.JSONException
import org.json.JSONObject
import javax.inject.Inject
import javax.inject.Singleton
import kotlin.collections.ArrayList
@Singleton
class AutomationPlugin @Inject constructor(
@ -71,7 +71,7 @@ class AutomationPlugin @Inject constructor(
var executionLog: MutableList<String> = ArrayList()
var btConnects : MutableList<EventBTChange> = ArrayList()
private val loopHandler = Handler()
private val loopHandler : Handler = Handler(HandlerThread(AutomationPlugin::class.java.simpleName + "Handler").also { it.start() }.looper)
private lateinit var refreshLoop: Runnable
init {

View file

@ -27,7 +27,7 @@ class ActionProfileSwitch(injector: HasAndroidInjector) : Action(injector) {
override fun friendlyName(): Int = R.string.profilename
override fun shortDescription(): String = resourceHelper.gs(R.string.changengetoprofilename, inputProfileName.value)
@DrawableRes override fun icon(): Int = R.drawable.icon_actions_profileswitch
@DrawableRes override fun icon(): Int = R.drawable.ic_actions_profileswitch
override fun doAction(callback: Callback) {
val activeProfileName = profileFunction.getProfileName()

View file

@ -30,7 +30,7 @@ class ActionProfileSwitchPercent(injector: HasAndroidInjector) : Action(injector
if (duration.value == 0) resourceHelper.gs(R.string.startprofileforever, pct.value.toInt())
else resourceHelper.gs(R.string.startprofile, pct.value.toInt(), duration.value)
@DrawableRes override fun icon(): Int = R.drawable.icon_actions_profileswitch
@DrawableRes override fun icon(): Int = R.drawable.ic_actions_profileswitch
init {
precondition = TriggerProfilePercent(injector, 100.0, Comparator.Compare.IS_EQUAL)

View file

@ -37,7 +37,7 @@ class ActionStartTempTarget(injector: HasAndroidInjector) : Action(injector) {
override fun friendlyName(): Int = R.string.starttemptarget
override fun shortDescription(): String = resourceHelper.gs(R.string.starttemptarget) + ": " + tt().friendlyDescription(value.units, resourceHelper)
@DrawableRes override fun icon(): Int = R.drawable.icon_cp_cgm_target
@DrawableRes override fun icon(): Int = R.drawable.ic_cp_cgm_target
override fun doAction(callback: Callback) {
activePlugin.activeTreatments.addToHistoryTempTarget(tt())

View file

@ -74,7 +74,7 @@ class Comparator(injector: HasAndroidInjector) : Element(injector) {
spinnerParams.setMargins(0, resourceHelper.dpToPx(4), 0, resourceHelper.dpToPx(4))
spinner.layoutParams = spinnerParams
spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View, position: Int, id: Long) {
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
value = Compare.values()[position]
}

View file

@ -48,7 +48,7 @@ class ComparatorConnect(injector: HasAndroidInjector) : Element(injector) {
spinnerParams.setMargins(0, resourceHelper.dpToPx(4), 0, resourceHelper.dpToPx(4))
spinner.layoutParams = spinnerParams
spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View, position: Int, id: Long) {
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
value = Compare.values()[position]
}

View file

@ -48,7 +48,7 @@ class ComparatorExists(injector: HasAndroidInjector) : Element(injector) {
spinnerParams.setMargins(0, resourceHelper.dpToPx(4), 0, resourceHelper.dpToPx(4))
spinner.layoutParams = spinnerParams
spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View, position: Int, id: Long) {
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
value = Compare.values()[position]
}

View file

@ -76,7 +76,7 @@ class InputDelta(injector: HasAndroidInjector) : Element(injector) {
spinnerParams.setMargins(0, resourceHelper.dpToPx(4), 0, resourceHelper.dpToPx(4))
spinner.layoutParams = spinnerParams
spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View, position: Int, id: Long) {
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
deltaType = DeltaType.values()[position]
}

View file

@ -38,7 +38,7 @@ class InputDropdownMenu(injector: HasAndroidInjector) : Element(injector) {
).also { it.setMargins(0, resourceHelper.dpToPx(4), 0, resourceHelper.dpToPx(4)) }
spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View, position: Int, id: Long) {
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
setValue(itemList[position].toString())
}

View file

@ -62,7 +62,7 @@ class InputLocationMode(injector: HasAndroidInjector) : Element(injector) {
spinnerParams.setMargins(0, resourceHelper.dpToPx(4), 0, resourceHelper.dpToPx(4))
spinner.layoutParams = spinnerParams
spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View, position: Int, id: Long) {
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
value = Mode.values()[position]
}

View file

@ -36,7 +36,7 @@ class InputProfileName(injector: HasAndroidInjector) : Element(injector) {
spinnerParams.setMargins(0, resourceHelper.dpToPx(4), 0, resourceHelper.dpToPx(4))
spinner.layoutParams = spinnerParams
spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View, position: Int, id: Long) {
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
value = profileList[position].toString()
}

View file

@ -4,14 +4,18 @@ import android.widget.LinearLayout
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.utils.NumberPicker
import java.text.DecimalFormat
import javax.inject.Inject
class InputTempTarget(injector: HasAndroidInjector) : Element(injector) {
var units = Constants.MGDL
var value = 0.0
@Inject lateinit var profileFunction: ProfileFunction
init {
units = profileFunction.getUnits()
value = if (units == Constants.MMOL) 6.0 else 110.0
}

View file

@ -91,7 +91,7 @@ class TriggerBg(injector: HasAndroidInjector) : Trigger(injector) {
resourceHelper.gs(if (bg.units == Constants.MGDL) R.string.glucosecomparedmgdl else R.string.glucosecomparedmmol, resourceHelper.gs(comparator.value.stringRes), bg.value, bg.units)
}
override fun icon(): Optional<Int?> = Optional.of(R.drawable.icon_cp_bgcheck)
override fun icon(): Optional<Int?> = Optional.of(R.drawable.ic_cp_bgcheck)
override fun duplicate(): Trigger = TriggerBg(injector, this)

View file

@ -160,7 +160,7 @@ class TriggerConnector(injector: HasAndroidInjector) : Trigger(injector) {
params.weight = 1.0f
spinner.layoutParams = params
spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View, position: Int, id: Long) {
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
setType(Type.values()[position])
}

View file

@ -77,7 +77,7 @@ class TriggerProfilePercent(injector: HasAndroidInjector) : Trigger(injector) {
override fun friendlyDescription(): String =
resourceHelper.gs(R.string.percentagecompared, resourceHelper.gs(comparator.value.stringRes), pct.value.toInt())
override fun icon(): Optional<Int?> = Optional.of(R.drawable.icon_actions_profileswitch)
override fun icon(): Optional<Int?> = Optional.of(R.drawable.ic_actions_profileswitch)
override fun duplicate(): Trigger = TriggerProfilePercent(injector, this)

View file

@ -47,7 +47,7 @@ class TriggerWifiSsid(injector: HasAndroidInjector) : Trigger(injector) {
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
return true
}
if (eventNetworkChange.wifiConnected && comparator.value.check(eventNetworkChange.connectedSsid(), ssid.value)) {
if (eventNetworkChange.wifiConnected && comparator.value.check(eventNetworkChange.ssid, ssid.value)) {
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
return true
}

View file

@ -1,5 +1,7 @@
package info.nightscout.androidaps.plugins.general.nsclient;
import java.util.Arrays;
import javax.inject.Inject;
import javax.inject.Singleton;
@ -48,6 +50,7 @@ class NsClientReceiverDelegate {
ev.isChanged(resourceHelper, R.string.key_ns_allowroaming)
) {
receiverStatusStore.updateNetworkStatus();
onStatusEvent(receiverStatusStore.getLastNetworkEvent());
} else if (ev.isChanged(resourceHelper, R.string.key_ns_chargingonly)) {
receiverStatusStore.broadcastChargingState();
}
@ -92,14 +95,15 @@ class NsClientReceiverDelegate {
boolean calculateStatus(final EventNetworkChange ev) {
boolean wifiOnly = sp.getBoolean(R.string.key_ns_wifionly, false);
String allowedSSIDs = sp.getString(R.string.key_ns_wifi_ssids, "");
String allowedSSIDstring = sp.getString(R.string.key_ns_wifi_ssids, "");
String[] allowedSSIDs = allowedSSIDstring.split(";");
if (allowedSSIDstring.isEmpty()) allowedSSIDs = new String[0];
boolean allowRoaming = sp.getBoolean(R.string.key_ns_allowroaming, true);
boolean newAllowedState = true;
if (ev.getWifiConnected()) {
if (!allowedSSIDs.trim().isEmpty() &&
(!allowedSSIDs.contains(ev.connectedSsid()) && !allowedSSIDs.contains(ev.getSsid()))) {
if (allowedSSIDs.length != 0 && !Arrays.asList(allowedSSIDs).contains(ev.getSsid())) {
newAllowedState = false;
}
} else {

View file

@ -139,7 +139,7 @@ class NSSettingsStatus @Inject constructor(
val targetlow = getSettingsThreshold("bgTargetBottom")
if (targetHigh != null) defaultValueHelper.bgTargetHigh = targetHigh
if (targetlow != null) defaultValueHelper.bgTargetLow = targetlow
copyStatusLightsNsSettings(null)
if (config.NSCLIENT) copyStatusLightsNsSettings(null)
}
fun getName(): String? =

View file

@ -158,7 +158,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
private val secondaryGraphs = ArrayList<GraphView>()
private val secondaryGraphsLabel = ArrayList<TextView>()
private lateinit var carbAnimation: AnimationDrawable
private var carbAnimation: AnimationDrawable? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
@ -190,9 +190,9 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
overview_bggraph?.gridLabelRenderer?.labelVerticalWidth = axisWidth
overview_bggraph?.layoutParams?.height = resourceHelper.dpToPx(skinProvider.activeSkin().mainGraphHeight)
carbAnimation = overview_carbs_icon.background as AnimationDrawable
carbAnimation.setEnterFadeDuration(1200)
carbAnimation.setExitFadeDuration(1200)
carbAnimation = overview_carbs_icon?.background as AnimationDrawable?
carbAnimation?.setEnterFadeDuration(1200)
carbAnimation?.setExitFadeDuration(1200)
rangeToDisplay = sp.getInt(R.string.key_rangetodisplay, 6)
@ -572,9 +572,9 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
val glucoseStatus = GlucoseStatus(injector).glucoseStatusData
if (glucoseStatus != null) {
overview_delta?.text = "Δ ${Profile.toSignedUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units)}"
overview_delta?.text = "${Profile.toSignedUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units)}"
overview_deltashort?.text = Profile.toSignedUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units)
overview_avgdelta?.text = "Δ15m: ${Profile.toUnitsString(glucoseStatus.short_avgdelta, glucoseStatus.short_avgdelta * Constants.MGDL_TO_MMOLL, units)}\nΔ40m: ${Profile.toUnitsString(glucoseStatus.long_avgdelta, glucoseStatus.long_avgdelta * Constants.MGDL_TO_MMOLL, units)}"
overview_avgdelta?.text = "${Profile.toSignedUnitsString(glucoseStatus.short_avgdelta, glucoseStatus.short_avgdelta * Constants.MGDL_TO_MMOLL, units)}\n${Profile.toSignedUnitsString(glucoseStatus.long_avgdelta, glucoseStatus.long_avgdelta * Constants.MGDL_TO_MMOLL, units)}"
} else {
overview_delta?.text = "Δ " + resourceHelper.gs(R.string.notavailable)
overview_deltashort?.text = "---"
@ -600,49 +600,51 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
overview_apsmode?.visibility = View.VISIBLE
when {
loopPlugin.isEnabled() && loopPlugin.isSuperBolus -> {
overview_apsmode.setImageResource(R.drawable.ic_loop_superbolus)
overview_apsmode?.setImageResource(R.drawable.ic_loop_superbolus)
overview_apsmode_text?.text = DateUtil.age(loopPlugin.minutesToEndOfSuspend() * 60000L, true, resourceHelper)
}
loopPlugin.isDisconnected -> {
overview_apsmode.setImageResource(R.drawable.ic_loop_disconnected)
overview_apsmode?.setImageResource(R.drawable.ic_loop_disconnected)
overview_apsmode_text?.text = DateUtil.age(loopPlugin.minutesToEndOfSuspend() * 60000L, true, resourceHelper)
}
loopPlugin.isEnabled() && loopPlugin.isSuspended -> {
overview_apsmode.setImageResource(R.drawable.ic_loop_paused)
overview_apsmode?.setImageResource(R.drawable.ic_loop_paused)
overview_apsmode_text?.text = DateUtil.age(loopPlugin.minutesToEndOfSuspend() * 60000L, true, resourceHelper)
}
pump.isSuspended -> {
overview_apsmode.setImageResource(R.drawable.ic_loop_paused)
overview_apsmode?.setImageResource(R.drawable.ic_loop_paused)
overview_apsmode_text?.text = ""
}
loopPlugin.isEnabled() && closedLoopEnabled.value() && loopPlugin.isLGS -> {
overview_apsmode.setImageResource(R.drawable.ic_loop_lgs)
overview_apsmode?.setImageResource(R.drawable.ic_loop_lgs)
overview_apsmode_text?.text = ""
}
loopPlugin.isEnabled() && closedLoopEnabled.value() -> {
overview_apsmode.setImageResource(R.drawable.ic_loop_closed)
overview_apsmode?.setImageResource(R.drawable.ic_loop_closed)
overview_apsmode_text?.text = ""
}
loopPlugin.isEnabled() && !closedLoopEnabled.value() -> {
overview_apsmode.setImageResource(R.drawable.ic_loop_open)
overview_apsmode?.setImageResource(R.drawable.ic_loop_open)
overview_apsmode_text?.text = ""
}
else -> {
overview_apsmode.setImageResource(R.drawable.ic_loop_disabled)
overview_apsmode?.setImageResource(R.drawable.ic_loop_disabled)
overview_apsmode_text?.text = ""
}
}
} else {
overview_apsmode?.visibility = View.GONE
overview_apsmode_text?.visibility = View.GONE
}
val lastRun = loopPlugin.lastRun
val predictionsAvailable = if (config.APS) lastRun?.request?.hasPredictions == true else config.NSCLIENT
// temp target
val tempTarget = treatmentsPlugin.tempTargetFromHistory
@ -654,7 +656,8 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
// If the target is not the same as set in the profile then oref has overridden it
val targetUsed = lastRun?.constraintsProcessed?.targetBG ?: 0.0
if (targetUsed != 0.0 && profile.targetMgdl != targetUsed) {
if (targetUsed != 0.0 && abs(profile.targetMgdl-targetUsed) > 0.01) {
aapsLogger.debug("Adjusted target. Profile: ${profile.targetMgdl} APS: $targetUsed")
overview_temptarget?.text = Profile.toTargetRangeString(targetUsed, targetUsed, Constants.MGDL, units)
overview_temptarget?.setTextColor(resourceHelper.gc(R.color.ribbonTextWarning))
overview_temptarget?.setBackgroundColor(resourceHelper.gc(R.color.tempTargetBackground))
@ -681,9 +684,9 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
?: resourceHelper.gc(R.color.defaulttextcolor))
if (activeTemp != null)
overview_basebasal_icon.setImageResource(if (activeTemp.tempBasalConvertedToPercent(System.currentTimeMillis(), profile) > 100) R.drawable.ic_cp_basal_tbr_high else R.drawable.ic_cp_basal_tbr_low)
overview_basebasal_icon?.setImageResource(if (activeTemp.tempBasalConvertedToPercent(System.currentTimeMillis(), profile) > 100) R.drawable.ic_cp_basal_tbr_high else R.drawable.ic_cp_basal_tbr_low)
else
overview_basebasal_icon.setImageResource(R.drawable.ic_cp_basal_no_tbr)
overview_basebasal_icon?.setImageResource(R.drawable.ic_cp_basal_no_tbr)
// Extended bolus
val extendedBolus = treatmentsPlugin.getExtendedBolusFromHistory(System.currentTimeMillis())
@ -748,18 +751,19 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
if (config.APS && lastRun?.constraintsProcessed != null) {
if (lastRun.constraintsProcessed!!.carbsReq > 0) {
overview_cob?.text = cobText + " | " + lastRun.constraintsProcessed!!.carbsReq + " " + resourceHelper.gs(R.string.required)
if (!carbAnimation.isRunning)
carbAnimation.start()
//only display carbsreq when carbs havnt been entered recently
if (treatmentsPlugin.lastCarbTime < lastRun.lastAPSRun) {
cobText = cobText + " | " + lastRun.constraintsProcessed!!.carbsReq + " " + resourceHelper.gs(R.string.required)
}
overview_cob?.text = cobText
if (carbAnimation?.isRunning == false)
carbAnimation?.start()
} else {
overview_cob?.text = cobText
if (carbAnimation.isRunning)
carbAnimation.stop()
carbAnimation.selectDrawable(0);
carbAnimation?.stop()
carbAnimation?.selectDrawable(0)
}
}
val predictionsAvailable = if (config.APS) lastRun?.request?.hasPredictions == true else config.NSCLIENT
} else overview_cob?.text = cobText
// pump status from ns
overview_pump?.text = nsDeviceStatus.pumpStatus
@ -775,9 +779,9 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
// Sensitivity
if (sp.getBoolean(R.string.key_openapsama_useautosens, false) && constraintChecker.isAutosensModeEnabled().value()) {
overview_sensitivity_icon.setImageResource(R.drawable.ic_swap_vert_black_48dp_green)
overview_sensitivity_icon?.setImageResource(R.drawable.ic_swap_vert_black_48dp_green)
} else {
overview_sensitivity_icon.setImageResource(R.drawable.ic_x_swap_vert)
overview_sensitivity_icon?.setImageResource(R.drawable.ic_x_swap_vert)
}
overview_sensitivity?.text =

View file

@ -104,7 +104,7 @@ class EditQuickWizardDialog : DaggerDialogFragment() {
overview_editquickwizard_usetemptarget_spinner.setSelection(entry.useTempTarget())
overview_editquickwizard_usecob_spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>, view: View, position: Int, id: Long) = processCob()
override fun onItemSelected(parent: AdapterView<*>, view: View?, position: Int, id: Long) = processCob()
override fun onNothingSelected(parent: AdapterView<*>) {}
}
processCob()

View file

@ -1,5 +1,6 @@
package info.nightscout.androidaps.plugins.general.persistentNotification
import android.app.Notification
import android.app.Service
import android.content.Intent
import android.os.IBinder
@ -26,13 +27,17 @@ class DummyService : DaggerService() {
private val disposable = CompositeDisposable()
override fun onBind(intent: Intent): IBinder? = null
override fun onBind(intent: Intent?): IBinder? = null
override fun onCreate() {
super.onCreate()
// TODO: I guess this was moved here in order to adhere to the 5 seconds rule to call "startForeground" after a Service was called as Foreground service?
// As onCreate() is not called every time a service is started, copied to onStartCommand().
startForeground(notificationHolder.notificationID, notificationHolder.notification)
try {
startForeground(notificationHolder.notificationID, notificationHolder.notification)
} catch (e: Exception) {
startForeground(4711, Notification())
}
disposable.add(rxBus
.toObservable(EventAppExit::class.java)
.observeOn(Schedulers.io())
@ -52,7 +57,11 @@ class DummyService : DaggerService() {
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
super.onStartCommand(intent, flags, startId)
startForeground(notificationHolder.notificationID, notificationHolder.notification)
try {
startForeground(notificationHolder.notificationID, notificationHolder.notification)
} catch (e: Exception) {
startForeground(4711, Notification())
}
return Service.START_STICKY
}
}

View file

@ -152,7 +152,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
if (wearIntegration()) {
handler.post(() -> {
if (googleApiClient.isConnected()) {
if (googleApiClient != null && googleApiClient.isConnected()) {
if (ACTION_RESEND.equals(action)) {
resendData();
} else if (ACTION_OPEN_SETTINGS.equals(action)) {
@ -180,7 +180,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
sendData();
}
} else {
googleApiClient.connect();
if (googleApiClient != null) googleApiClient.connect();
}
});
}
@ -298,9 +298,11 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
private DataMap dataMapSingleBG(BgReading lastBG, GlucoseStatus glucoseStatus) {
String units = profileFunction.getUnits();
double lowLine = defaultValueHelper.determineLowLine();
double highLine = defaultValueHelper.determineHighLine();
double convert2MGDL = 1.0;
if (units.equals(Constants.MMOL))
convert2MGDL = Constants.MMOLL_TO_MGDL;
double lowLine = defaultValueHelper.determineLowLine()*convert2MGDL;
double highLine = defaultValueHelper.determineHighLine()*convert2MGDL;
long sgvLevel = 0L;
if (lastBG.value > highLine) {
@ -323,7 +325,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
dataMap.putString("avgDelta", deltastring(glucoseStatus.avgdelta, glucoseStatus.avgdelta * Constants.MGDL_TO_MMOLL, units));
}
dataMap.putLong("sgvLevel", sgvLevel);
dataMap.putDouble("sgvDouble", lastBG.valueToUnits(units));
dataMap.putDouble("sgvDouble", lastBG.value);
dataMap.putDouble("high", highLine);
dataMap.putDouble("low", lowLine);
return dataMap;
@ -539,7 +541,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
final String units = profileFunction.getUnits();
for (BgReading bg : predArray) {
if (bg.value < 40) continue;
predictions.add(predictionMap(bg.date, bg.valueToUnits(units), bg.getPredectionColor()));
predictions.add(predictionMap(bg.date, bg.value, bg.getPredectionColor()));
}
}
}
@ -592,7 +594,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
private void sendNotification() {
if (googleApiClient.isConnected()) {
if (googleApiClient != null && googleApiClient.isConnected()) {
PutDataMapRequest dataMapRequest = PutDataMapRequest.create(OPEN_SETTINGS_PATH);
//unique content
dataMapRequest.getDataMap().putLong("timestamp", System.currentTimeMillis());
@ -606,7 +608,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
}
private void sendBolusProgress(int progresspercent, String status) {
if (googleApiClient.isConnected()) {
if (googleApiClient != null && googleApiClient.isConnected()) {
PutDataMapRequest dataMapRequest = PutDataMapRequest.create(BOLUS_PROGRESS_PATH);
//unique content
dataMapRequest.getDataMap().putLong("timestamp", System.currentTimeMillis());
@ -622,7 +624,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
}
private void sendActionConfirmationRequest(String title, String message, String actionstring) {
if (googleApiClient.isConnected()) {
if (googleApiClient != null && googleApiClient.isConnected()) {
PutDataMapRequest dataMapRequest = PutDataMapRequest.create(ACTION_CONFIRMATION_REQUEST_PATH);
//unique content
dataMapRequest.getDataMap().putLong("timestamp", System.currentTimeMillis());
@ -642,7 +644,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
}
private void sendChangeConfirmationRequest(String title, String message, String actionstring) {
if (googleApiClient.isConnected()) {
if (googleApiClient != null && googleApiClient.isConnected()) {
PutDataMapRequest dataMapRequest = PutDataMapRequest.create(ACTION_CHANGECONFIRMATION_REQUEST_PATH);
//unique content
dataMapRequest.getDataMap().putLong("timestamp", System.currentTimeMillis());
@ -662,7 +664,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
}
private void sendCancelNotificationRequest(String actionstring) {
if (googleApiClient.isConnected()) {
if (googleApiClient != null && googleApiClient.isConnected()) {
PutDataMapRequest dataMapRequest = PutDataMapRequest.create(ACTION_CANCELNOTIFICATION_REQUEST_PATH);
//unique content
dataMapRequest.getDataMap().putLong("timestamp", System.currentTimeMillis());
@ -681,7 +683,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
private void sendStatus() {
if (googleApiClient.isConnected()) {
if (googleApiClient != null && googleApiClient.isConnected()) {
Profile profile = profileFunction.getProfile();
String status = resourceHelper.gs(R.string.noprofile);
String iobSum, iobDetail, cobString, currentBasal, bgiString;
@ -745,7 +747,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
}
private void sendPreferences() {
if (googleApiClient.isConnected()) {
if (googleApiClient != null && googleApiClient.isConnected()) {
boolean wearcontrol = sp.getBoolean("wearcontrol", false);

View file

@ -2,7 +2,8 @@ package info.nightscout.androidaps.plugins.iob.iobCobCalculator
import info.nightscout.androidaps.db.BgReading
class InMemoryGlucoseValue constructor(var timestamp: Long = 0L, var value: Double = 0.0) {
class InMemoryGlucoseValue @JvmOverloads constructor(var timestamp: Long = 0L, var value: Double = 0.0, var interpolated : Boolean = false) {
constructor(gv: BgReading) : this(gv.date, gv.value)
// var generated : value doesn't correspond to real value with timestamp close to real BG
}

View file

@ -79,6 +79,11 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat
private LongSparseArray<AutosensData> autosensDataTable = new LongSparseArray<>(); // oldest at index 0
private LongSparseArray<BasalData> basalDataTable = new LongSparseArray<>(); // oldest at index 0
// we need to make sure that bucketed_data will always have the same timestamp for correct use of cached values
// once referenceTime != null all bucketed data should be (x * 5min) from referenceTime
Long referenceTime = null;
private Boolean lastUsed5minCalculation = null; // true if used 5min bucketed data
private volatile List<BgReading> bgReadings = null; // newest at index 0
private volatile List<InMemoryGlucoseValue> bucketed_data = null;
@ -135,9 +140,8 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat
.subscribe(event -> {
stopCalculation("onEventConfigBuilderChange");
synchronized (dataLock) {
getAapsLogger().debug(LTag.AUTOSENS, "Invalidating cached data because of configuration change. IOB: " + iobTable.size() + " Autosens: " + autosensDataTable.size() + " records");
iobTable = new LongSparseArray<>();
autosensDataTable = new LongSparseArray<>();
getAapsLogger().debug(LTag.AUTOSENS, "Invalidating cached data because of configuration change.");
resetData();
}
runCalculation("onEventConfigBuilderChange", System.currentTimeMillis(), false, true, event);
}, fabricPrivacy::logException)
@ -152,10 +156,8 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat
}
stopCalculation("onNewProfile");
synchronized (dataLock) {
getAapsLogger().debug(LTag.AUTOSENS, "Invalidating cached data because of new profile. IOB: " + iobTable.size() + " Autosens: " + autosensDataTable.size() + " records");
iobTable = new LongSparseArray<>();
autosensDataTable = new LongSparseArray<>();
basalDataTable = new LongSparseArray<>();
getAapsLogger().debug(LTag.AUTOSENS, "Invalidating cached data because of new profile.");
resetData();
}
runCalculation("onNewProfile", System.currentTimeMillis(), false, true, event);
}, fabricPrivacy::logException)
@ -185,10 +187,8 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat
) {
stopCalculation("onEventPreferenceChange");
synchronized (dataLock) {
getAapsLogger().debug(LTag.AUTOSENS, "Invalidating cached data because of preference change. IOB: " + iobTable.size() + " Autosens: " + autosensDataTable.size() + " records" + " BasalData: " + basalDataTable.size() + " records");
iobTable = new LongSparseArray<>();
autosensDataTable = new LongSparseArray<>();
basalDataTable = new LongSparseArray<>();
getAapsLogger().debug(LTag.AUTOSENS, "Invalidating cached data because of preference change.");
resetData();
}
runCalculation("onEventPreferenceChange", System.currentTimeMillis(), false, true, event);
}
@ -248,6 +248,19 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat
return rounded;
}
long adjustToReferenceTime(long someTime) {
if (referenceTime == null) {
referenceTime = someTime;
return someTime;
}
long diff = Math.abs(someTime - referenceTime);
diff %= T.mins(5).msecs();
if (diff > T.mins(2).plus(T.secs(30)).msecs())
diff = diff - T.mins(5).msecs();
long newTime = someTime + diff;
return newTime;
}
void loadBgData(long to) {
Profile profile = profileFunction.getProfile(to);
double dia = Constants.defaultDIA;
@ -291,7 +304,23 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat
}
}
private void resetData() {
synchronized (dataLock) {
iobTable = new LongSparseArray<>();
autosensDataTable = new LongSparseArray<>();
basalDataTable = new LongSparseArray<>();
absIobTable = new LongSparseArray<>();
}
}
public void createBucketedData() {
boolean fiveMinData = isAbout5minData();
if (lastUsed5minCalculation != null && lastUsed5minCalculation != fiveMinData) {
// changing mode => clear cache
getAapsLogger().debug("Invalidating cached data because of changed mode.");
resetData();
}
lastUsed5minCalculation = fiveMinData;
if (isAbout5minData())
createBucketedData5min();
else
@ -332,6 +361,8 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat
bucketed_data = new ArrayList<>();
long currentTime = bgReadings.get(0).date - bgReadings.get(0).date % T.mins(5).msecs();
currentTime = adjustToReferenceTime(currentTime);
getAapsLogger().debug("Adjusted time " + dateUtil.dateAndTimeAndSecondsString(currentTime));
//log.debug("First reading: " + new Date(currentTime).toLocaleString());
while (true) {
@ -348,9 +379,7 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat
long timeDiffToNew = newer.date - currentTime;
double currentBg = newer.value - (double) timeDiffToNew / (newer.date - older.date) * bgDelta;
InMemoryGlucoseValue newBgreading = new InMemoryGlucoseValue();
newBgreading.setTimestamp(currentTime);
newBgreading.setValue(Math.round(currentBg));
InMemoryGlucoseValue newBgreading = new InMemoryGlucoseValue(currentTime, Math.round(currentBg), true);
bucketed_data.add(newBgreading);
//log.debug("BG: " + newBgreading.value + " (" + new Date(newBgreading.date).toLocaleString() + ") Prev: " + older.value + " (" + new Date(older.date).toLocaleString() + ") Newer: " + newer.value + " (" + new Date(newer.date).toLocaleString() + ")");
}
@ -388,12 +417,10 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat
while (elapsed_minutes > 5) {
nextbgTime = lastbgTime - 5 * 60 * 1000;
j++;
InMemoryGlucoseValue newBgreading = new InMemoryGlucoseValue();
newBgreading.setTimestamp(nextbgTime);
double gapDelta = bgReadings.get(i).value - lastbg;
//console.error(gapDelta, lastbg, elapsed_minutes);
double nextbg = lastbg + (5d / elapsed_minutes * gapDelta);
newBgreading.setValue(Math.round(nextbg));
InMemoryGlucoseValue newBgreading = new InMemoryGlucoseValue(nextbgTime, Math.round(nextbg), true);
//console.error("Interpolated", bucketed_data[j]);
bucketed_data.add(newBgreading);
getAapsLogger().debug(LTag.AUTOSENS, "Adding. bgTime: " + DateUtil.toISOString(bgTime) + " lastbgTime: " + DateUtil.toISOString(lastbgTime) + " " + newBgreading.toString());
@ -403,16 +430,12 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat
lastbgTime = nextbgTime;
}
j++;
InMemoryGlucoseValue newBgreading = new InMemoryGlucoseValue();
newBgreading.setValue(bgReadings.get(i).value);
newBgreading.setTimestamp(bgTime);
InMemoryGlucoseValue newBgreading = new InMemoryGlucoseValue(bgTime, bgReadings.get(i).value);
bucketed_data.add(newBgreading);
getAapsLogger().debug(LTag.AUTOSENS, "Adding. bgTime: " + DateUtil.toISOString(bgTime) + " lastbgTime: " + DateUtil.toISOString(lastbgTime) + " " + newBgreading.toString());
} else if (Math.abs(elapsed_minutes) > 2) {
j++;
InMemoryGlucoseValue newBgreading = new InMemoryGlucoseValue();
newBgreading.setValue(bgReadings.get(i).value);
newBgreading.setTimestamp(bgTime);
InMemoryGlucoseValue newBgreading = new InMemoryGlucoseValue(bgTime, bgReadings.get(i).value);
bucketed_data.add(newBgreading);
getAapsLogger().debug(LTag.AUTOSENS, "Adding. bgTime: " + DateUtil.toISOString(bgTime) + " lastbgTime: " + DateUtil.toISOString(lastbgTime) + " " + newBgreading.toString());
} else {
@ -422,12 +445,15 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat
}
// Normalize bucketed data
InMemoryGlucoseValue oldest = bucketed_data.get(bucketed_data.size() - 1);
oldest.setTimestamp(adjustToReferenceTime(oldest.getTimestamp()));
getAapsLogger().debug("Adjusted time " + dateUtil.dateAndTimeAndSecondsString(oldest.getTimestamp()));
for (int i = bucketed_data.size() - 2; i >= 0; i--) {
InMemoryGlucoseValue current = bucketed_data.get(i);
InMemoryGlucoseValue previous = bucketed_data.get(i + 1);
long msecDiff = current.getTimestamp() - previous.getTimestamp();
long adjusted = (msecDiff - T.mins(5).msecs()) / 1000;
getAapsLogger().debug(LTag.AUTOSENS, "Adjusting bucketed data time. Current: " + DateUtil.toISOString(current.getTimestamp()) + " to: " + DateUtil.toISOString(previous.getTimestamp() + T.mins(5).msecs()) + " by " + adjusted + " sec");
getAapsLogger().debug(LTag.AUTOSENS, "Adjusting bucketed data time. Current: " + dateUtil.dateAndTimeAndSecondsString(current.getTimestamp()) + " to: " + dateUtil.dateAndTimeAndSecondsString(previous.getTimestamp() + T.mins(5).msecs()) + " by " + adjusted + " sec");
if (Math.abs(adjusted) > 90) {
// too big adjustment, fallback to non 5 min data
getAapsLogger().debug(LTag.AUTOSENS, "Fallback to non 5 min data");
@ -450,7 +476,7 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat
if (limitDataToOldestAvailable) {
getBGDataFrom = Math.max(oldestDataAvailable, (long) (from - T.hours(1).msecs() * (24 + dia)));
if (getBGDataFrom == oldestDataAvailable)
getAapsLogger().debug(LTag.AUTOSENS, "Limiting data to oldest available temps: " + dateUtil.dateAndTimeString(oldestDataAvailable));
getAapsLogger().debug(LTag.AUTOSENS, "Limiting data to oldest available temps: " + dateUtil.dateAndTimeAndSecondsString(oldestDataAvailable));
} else
getBGDataFrom = (long) (from - T.hours(1).msecs() * (24 + dia));
return getBGDataFrom;
@ -685,7 +711,7 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat
return null;
}
if (data.time < System.currentTimeMillis() - 11 * 60 * 1000) {
getAapsLogger().debug(LTag.AUTOSENS, "AUTOSENSDATA null: data is old (" + reason + ") size()=" + autosensDataTable.size() + " lastdata=" + dateUtil.dateAndTimeString(data.time));
getAapsLogger().debug(LTag.AUTOSENS, "AUTOSENSDATA null: data is old (" + reason + ") size()=" + autosensDataTable.size() + " lastdata=" + dateUtil.dateAndTimeAndSecondsString(data.time));
return null;
} else {
getAapsLogger().debug(LTag.AUTOSENS, "AUTOSENSDATA (" + reason + ") " + data.toString());
@ -696,7 +722,7 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat
@Override
public String lastDataTime() {
if (autosensDataTable.size() > 0)
return dateUtil.dateAndTimeString(autosensDataTable.valueAt(autosensDataTable.size() - 1).time);
return dateUtil.dateAndTimeAndSecondsString(autosensDataTable.valueAt(autosensDataTable.size() - 1).time);
else
return "autosensDataTable empty";
}
@ -817,7 +843,7 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat
}
public void runCalculation(String from, long end, boolean bgDataReload, boolean limitDataToOldestAvailable, Event cause) {
getAapsLogger().debug(LTag.AUTOSENS, "Starting calculation thread: " + from + " to " + dateUtil.dateAndTimeString(end));
getAapsLogger().debug(LTag.AUTOSENS, "Starting calculation thread: " + from + " to " + dateUtil.dateAndTimeAndSecondsString(end));
if (thread == null || thread.getState() == Thread.State.TERMINATED) {
if (sensitivityOref1Plugin.isEnabled())
thread = new IobCobOref1Thread(injector, this, treatmentsPlugin, from, end, bgDataReload, limitDataToOldestAvailable, cause);
@ -834,10 +860,10 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat
synchronized (dataLock) {
// clear up 5 min back for proper COB calculation
long time = ev.getTime() - 5 * 60 * 1000L;
getAapsLogger().debug(LTag.AUTOSENS, "Invalidating cached data to: " + dateUtil.dateAndTimeString(time));
getAapsLogger().debug(LTag.AUTOSENS, "Invalidating cached data to: " + dateUtil.dateAndTimeAndSecondsString(time));
for (int index = iobTable.size() - 1; index >= 0; index--) {
if (iobTable.keyAt(index) > time) {
getAapsLogger().debug(LTag.AUTOSENS, "Removing from iobTable: " + dateUtil.dateAndTimeString(iobTable.keyAt(index)));
getAapsLogger().debug(LTag.AUTOSENS, "Removing from iobTable: " + dateUtil.dateAndTimeAndSecondsString(iobTable.keyAt(index)));
iobTable.removeAt(index);
} else {
break;
@ -845,7 +871,7 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat
}
for (int index = absIobTable.size() - 1; index >= 0; index--) {
if (absIobTable.keyAt(index) > time) {
getAapsLogger().debug(LTag.AUTOSENS, "Removing from absIobTable: " + dateUtil.dateAndTimeString(absIobTable.keyAt(index)));
getAapsLogger().debug(LTag.AUTOSENS, "Removing from absIobTable: " + dateUtil.dateAndTimeAndSecondsString(absIobTable.keyAt(index)));
absIobTable.removeAt(index);
} else {
break;
@ -853,7 +879,7 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat
}
for (int index = autosensDataTable.size() - 1; index >= 0; index--) {
if (autosensDataTable.keyAt(index) > time) {
getAapsLogger().debug(LTag.AUTOSENS, "Removing from autosensDataTable: " + dateUtil.dateAndTimeString(autosensDataTable.keyAt(index)));
getAapsLogger().debug(LTag.AUTOSENS, "Removing from autosensDataTable: " + dateUtil.dateAndTimeAndSecondsString(autosensDataTable.keyAt(index)));
autosensDataTable.removeAt(index);
} else {
break;
@ -861,7 +887,7 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat
}
for (int index = basalDataTable.size() - 1; index >= 0; index--) {
if (basalDataTable.keyAt(index) > time) {
getAapsLogger().debug(LTag.AUTOSENS, "Removing from basalDataTable: " + dateUtil.dateAndTimeString(basalDataTable.keyAt(index)));
getAapsLogger().debug(LTag.AUTOSENS, "Removing from basalDataTable: " + dateUtil.dateAndTimeAndSecondsString(basalDataTable.keyAt(index)));
basalDataTable.removeAt(index);
} else {
break;

View file

@ -180,8 +180,9 @@ class LocalProfileFragment : DaggerFragment() {
localprofile_units.text = resourceHelper.gs(R.string.units_colon) + " " + (if (localProfilePlugin.currentProfile().mgdl) resourceHelper.gs(R.string.mgdl) else resourceHelper.gs(R.string.mmol))
localprofile_profileswitch.setOnClickListener {
// TODO: select in dialog localProfilePlugin.currentProfileIndex
ProfileSwitchDialog().show(childFragmentManager, "NewNSTreatmentDialog")
ProfileSwitchDialog()
.also { it.arguments = Bundle().also { bundle -> bundle.putInt("profileIndex", localProfilePlugin.currentProfileIndex) }}
.show(childFragmentManager, "NewNSTreatmentDialog")
}
localprofile_reset.setOnClickListener {

View file

@ -4,6 +4,7 @@ import android.content.Intent
import android.content.pm.PackageManager
import androidx.core.content.ContextCompat
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Config
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
@ -32,18 +33,24 @@ class DexcomPlugin @Inject constructor(
private val mainApp: MainApp,
resourceHelper: ResourceHelper,
aapsLogger: AAPSLogger,
private val nsUpload: NSUpload
private val nsUpload: NSUpload,
config: Config
) : PluginBase(PluginDescription()
.mainType(PluginType.BGSOURCE)
.fragmentClass(BGSourceFragment::class.java.name)
.pluginName(R.string.dexcom_app_patched)
.shortName(R.string.dexcom_short)
.preferencesId(R.xml.pref_bgsourcedexcom)
.description(R.string.description_source_dexcom)
.setDefault(),
.description(R.string.description_source_dexcom),
aapsLogger, resourceHelper, injector
), BgSourceInterface {
init {
if (!config.NSCLIENT) {
pluginDescription.setDefault()
}
}
override fun advancedFilteringSupported(): Boolean {
return true
}

View file

@ -2,6 +2,7 @@ package info.nightscout.androidaps.plugins.source
import android.content.Intent
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Config
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.db.BgReading
@ -26,7 +27,8 @@ class NSClientSourcePlugin @Inject constructor(
injector: HasAndroidInjector,
resourceHelper: ResourceHelper,
aapsLogger: AAPSLogger,
private val sp: SP
private val sp: SP,
config: Config
) : PluginBase(PluginDescription()
.mainType(PluginType.BGSOURCE)
.fragmentClass(BGSourceFragment::class.java.name)
@ -38,6 +40,14 @@ class NSClientSourcePlugin @Inject constructor(
private var lastBGTimeStamp: Long = 0
private var isAdvancedFilteringEnabled = false
init {
if (config.NSCLIENT) {
pluginDescription
.alwaysEnabled(true)
.setDefault()
}
}
override fun advancedFilteringSupported(): Boolean {
return isAdvancedFilteringEnabled
}

View file

@ -2,6 +2,7 @@ package info.nightscout.androidaps.plugins.source
import android.content.Intent
import android.os.Handler
import android.os.HandlerThread
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
@ -12,6 +13,7 @@ import info.nightscout.androidaps.interfaces.PluginDescription
import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
import info.nightscout.androidaps.utils.DateUtil
@ -31,6 +33,8 @@ class RandomBgPlugin @Inject constructor(
injector: HasAndroidInjector,
resourceHelper: ResourceHelper,
aapsLogger: AAPSLogger,
private val virtualPumpPlugin: VirtualPumpPlugin,
private val buildHelper: BuildHelper,
private val sp: SP,
private val nsUpload: NSUpload
) : PluginBase(PluginDescription()
@ -43,7 +47,7 @@ class RandomBgPlugin @Inject constructor(
aapsLogger, resourceHelper, injector
), BgSourceInterface {
private val loopHandler = Handler()
private val loopHandler : Handler = Handler(HandlerThread(RandomBgPlugin::class.java.simpleName + "Handler").also { it.start() }.looper)
private lateinit var refreshLoop: Runnable
companion object {
@ -72,7 +76,7 @@ class RandomBgPlugin @Inject constructor(
}
override fun specialEnableCondition(): Boolean {
return true //isRunningTest() || virtualPumpPlugin.isEnabled(PluginType.PUMP) && buildHelper.isEngineeringMode()
return isRunningTest() || virtualPumpPlugin.isEnabled(PluginType.PUMP) && buildHelper.isEngineeringMode()
}
override fun handleNewData(intent: Intent) {

View file

@ -308,6 +308,9 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> {
//preserve carbs
if (existingTreatment.isValid && existingTreatment.carbs > 0 && treatment.carbs == 0) {
treatment.carbs = existingTreatment.carbs;
// preserve insulin
} else if (existingTreatment.isValid && existingTreatment.insulin > 0 && treatment.insulin == 0) {
treatment.insulin = existingTreatment.insulin;
}
getDao().delete(existingTreatment); // need to delete/create because date may change too

View file

@ -156,7 +156,7 @@ class TreatmentsProfileSwitchFragment : DaggerFragment() {
R.id.profileswitch_date, R.id.profileswitch_name -> {
val args = Bundle()
args.putLong("time", (v.tag as ProfileSwitch).date)
args.putInt("mode", ProfileViewerDialog.Mode.RUNNING_PROFILE.ordinal)
args.putInt("mode", ProfileViewerDialog.Mode.DB_PROFILE.ordinal)
val pvd = ProfileViewerDialog()
pvd.arguments = args
pvd.show(childFragmentManager, "ProfileViewDialog")

View file

@ -39,32 +39,37 @@ class TimeDateOrTZChangeReceiver : DaggerBroadcastReceiver() {
val activePump: PumpInterface = activePlugin.activePump
aapsLogger.debug(LTag.PUMP,"TimeDateOrTZChangeReceiver::Date, Time and/or TimeZone changed. [action={}]", action)
aapsLogger.debug(LTag.PUMP,"TimeDateOrTZChangeReceiver::Intent::{}", gson.toJson(intent))
try {
aapsLogger.debug(LTag.PUMP, "TimeDateOrTZChangeReceiver::Intent::{}", gson.toJson(intent))
} catch (ignored : Exception) {}
if (action == null) {
aapsLogger.error(LTag.PUMP,"TimeDateOrTZChangeReceiver::Action is null. Exiting.")
} else if (Intent.ACTION_TIMEZONE_CHANGED == action) {
aapsLogger.info(LTag.PUMP,"TimeDateOrTZChangeReceiver::Timezone changed. Notifying pump driver.")
activePump.timezoneOrDSTChanged(TimeChangeType.TimezoneChange)
} else if (Intent.ACTION_TIME_CHANGED == action) {
val currentDst = calculateDST()
if (currentDst == isDST) {
aapsLogger.info(LTag.PUMP,"TimeDateOrTZChangeReceiver::Time changed (manual). Notifying pump driver.")
activePump.timezoneOrDSTChanged(TimeChangeType.ManualTimeChange)
} else {
if (currentDst) {
aapsLogger.info(LTag.PUMP,"TimeDateOrTZChangeReceiver::DST started. Notifying pump driver.")
activePump.timezoneOrDSTChanged(TimeChangeType.DST_Started)
} else {
aapsLogger.info(LTag.PUMP,"TimeDateOrTZChangeReceiver::DST ended. Notifying pump driver.")
activePump.timezoneOrDSTChanged(TimeChangeType.DST_Ended)
}
when {
action == null -> {
aapsLogger.error(LTag.PUMP,"TimeDateOrTZChangeReceiver::Action is null. Exiting.")
}
Intent.ACTION_TIMEZONE_CHANGED == action -> {
aapsLogger.info(LTag.PUMP,"TimeDateOrTZChangeReceiver::Timezone changed. Notifying pump driver.")
activePump.timezoneOrDSTChanged(TimeChangeType.TimezoneChange)
}
Intent.ACTION_TIME_CHANGED == action -> {
val currentDst = calculateDST()
if (currentDst == isDST) {
aapsLogger.info(LTag.PUMP,"TimeDateOrTZChangeReceiver::Time changed (manual). Notifying pump driver.")
activePump.timezoneOrDSTChanged(TimeChangeType.ManualTimeChange)
} else {
if (currentDst) {
aapsLogger.info(LTag.PUMP,"TimeDateOrTZChangeReceiver::DST started. Notifying pump driver.")
activePump.timezoneOrDSTChanged(TimeChangeType.DST_Started)
} else {
aapsLogger.info(LTag.PUMP,"TimeDateOrTZChangeReceiver::DST ended. Notifying pump driver.")
activePump.timezoneOrDSTChanged(TimeChangeType.DST_Ended)
}
}
isDST = currentDst
}
else -> {
aapsLogger.error(LTag.PUMP,"TimeDateOrTZChangeReceiver::Unknown action received [name={}]. Exiting.", action)
}
isDST = currentDst
} else {
aapsLogger.error(LTag.PUMP,"TimeDateOrTZChangeReceiver::Unknown action received [name={}]. Exiting.", action)
}
}
}

View file

@ -11,6 +11,7 @@ import org.json.JSONObject;
import javax.inject.Inject;
import dagger.android.DaggerIntentService;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.db.CareportalEvent;
@ -55,6 +56,7 @@ public class DataService extends DaggerIntentService {
@Inject XdripPlugin xdripPlugin;
@Inject NSProfilePlugin nsProfilePlugin;
@Inject ActivePluginProvider activePlugin;
@Inject Config config;
public DataService() {
super("DataService");
@ -68,7 +70,6 @@ public class DataService extends DaggerIntentService {
boolean acceptNSData = !sp.getBoolean(R.string.key_ns_upload_only, false);
Bundle bundles = intent.getExtras();
final String action = intent.getAction();
if (Intents.ACTION_NEW_BG_ESTIMATE.equals(action)) {
@ -234,8 +235,11 @@ public class DataService extends DaggerIntentService {
String notes = JsonHelper.safeGetString(json, "notes", "");
if (date > now - 15 * 60 * 1000L && !notes.isEmpty()
&& !enteredBy.equals(sp.getString("careportal_enteredby", "AndroidAPS"))) {
Notification announcement = new Notification(Notification.NSANNOUNCEMENT, notes, Notification.ANNOUNCEMENT, 60);
rxBus.send(new EventNewNotification(announcement));
boolean defaultVal = config.getNSCLIENT();
if (sp.getBoolean(R.string.key_ns_announcements, defaultVal)) {
Notification announcement = new Notification(Notification.NSANNOUNCEMENT, notes, Notification.ANNOUNCEMENT, 60);
rxBus.send(new EventNewNotification(announcement));
}
}
}
}

View file

@ -1,6 +1,7 @@
package info.nightscout.androidaps.services
import android.Manifest
import android.app.Notification
import android.app.Service
import android.content.Context
import android.content.Intent
@ -71,19 +72,29 @@ class LocationService : DaggerService() {
}
}
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
super.onStartCommand(intent, flags, startId)
startForeground(notificationHolder.notificationID, notificationHolder.notification)
try {
startForeground(notificationHolder.notificationID, notificationHolder.notification)
} catch (e: Exception) {
startForeground(4711, Notification())
}
return Service.START_STICKY
}
override fun onCreate() {
super.onCreate()
startForeground(notificationHolder.notificationID, notificationHolder.notification)
try {
startForeground(notificationHolder.notificationID, notificationHolder.notification)
} catch (e: Exception) {
startForeground(4711, Notification())
}
// Get last location once until we get regular update
LocationServices.getFusedLocationProviderClient(this).lastLocation.addOnSuccessListener {
lastLocationDataContainer.lastLocation = it
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
LocationServices.getFusedLocationProviderClient(this).lastLocation.addOnSuccessListener {
lastLocationDataContainer.lastLocation = it
}
}
initializeLocationManager()

View file

@ -461,7 +461,7 @@ class SWDefinition @Inject constructor(
.add(screenUnits)
.add(displaySettings)
.add(screenNsClient)
.add(screenBgSource)
//.add(screenBgSource)
.add(screenPatientName)
.add(screenAge)
.add(screenInsulin)

View file

@ -54,6 +54,7 @@ class TddCalculator @Inject constructor(
val midnight = MidnightTime.calc(t.date)
val tdd = result[midnight] ?: TDD(midnight, 0.0, 0.0, 0.0)
tdd.bolus += t.insulin
tdd.carbs += t.carbs
result.put(midnight, tdd)
}
@ -81,10 +82,12 @@ class TddCalculator @Inject constructor(
totalTdd.basal += tdd.basal
totalTdd.bolus += tdd.bolus
totalTdd.total += tdd.total
totalTdd.carbs += tdd.carbs
}
totalTdd.basal /= tdds.size().toDouble()
totalTdd.bolus /= tdds.size().toDouble()
totalTdd.total /= tdds.size().toDouble()
totalTdd.carbs /= tdds.size().toDouble()
return totalTdd
}
@ -93,16 +96,16 @@ class TddCalculator @Inject constructor(
val averageTdd = averageTDD(tdds)
return HtmlHelper.fromHtml(
"<b>" + resourceHelper.gs(R.string.tdd) + ":</b><br>" +
toText(tdds) +
toText(tdds, true) +
"<b>" + resourceHelper.gs(R.string.average) + ":</b><br>" +
averageTdd.toText(resourceHelper, tdds.size())
averageTdd.toText(resourceHelper, tdds.size(), true)
)
}
private fun toText(tdds: LongSparseArray<TDD>): String {
private fun toText(tdds: LongSparseArray<TDD>, includeCarbs: Boolean): String {
var t = ""
for (i in 0 until tdds.size()) {
t += "${tdds.valueAt(i).toText(resourceHelper, dateUtil)}<br>"
t += "${tdds.valueAt(i).toText(resourceHelper, dateUtil, includeCarbs)}<br>"
}
return t
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 953 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 771 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 963 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 963 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 413 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 911 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 806 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 687 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1,007 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 932 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 913 B

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