Merge remote-tracking branch 'Nightscout/dev' into Autotune/TuneWeekDaysClean

This commit is contained in:
Philoul 2023-02-26 17:35:57 +01:00
commit 3b6a3605a2
1049 changed files with 26413 additions and 12742 deletions

View file

@ -15,5 +15,5 @@ Reporting bugs
upper-right corner). upper-right corner).
- Obtain the app's log files, which can be found on the phone in - Obtain the app's log files, which can be found on the phone in
_/storage/emulated/0/Android/data/info.nightscout.androidaps/_ _/storage/emulated/0/Android/data/info.nightscout.androidaps/_
See https://androidaps.readthedocs.io/en/latest/Usage/Accessing-logfiles.html See https://wiki.aaps.app/en/latest/Usage/Accessing-logfiles.html
- Open an issue at https://github.com/nightscout/AndroidAPS/issues/new - Open an issue at https://github.com/nightscout/AndroidAPS/issues/new

View file

@ -4,6 +4,8 @@
<option name="WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN" value="true" /> <option name="WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN" value="true" />
<JetCodeStyleSettings> <JetCodeStyleSettings>
<option name="ALIGN_IN_COLUMNS_CASE_BRANCH" value="true" /> <option name="ALIGN_IN_COLUMNS_CASE_BRANCH" value="true" />
<option name="NAME_COUNT_TO_USE_STAR_IMPORT" value="2147483647" />
<option name="NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS" value="2147483647" />
<option name="BLANK_LINES_AROUND_BLOCK_WHEN_BRANCHES" value="1" /> <option name="BLANK_LINES_AROUND_BLOCK_WHEN_BRANCHES" value="1" />
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" /> <option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</JetCodeStyleSettings> </JetCodeStyleSettings>

View file

@ -7,9 +7,9 @@ General rules
============= =============
* There are plenty of ways you can help, some of them are listed on wiki: * There are plenty of ways you can help, some of them are listed on wiki:
https://androidaps.readthedocs.io/en/latest/EN/Getting-Started/How-can-I-help.html https://wiki.aaps.app/en/latest/Getting-Started/How-can-I-help.html
* If you wish to help with documentation or translating: * If you wish to help with documentation or translating:
https://androidaps.readthedocs.io/en/latest/EN/translations.html https://wiki.aaps.app/en/latest/translations.html
Development guidelines Development guidelines
====================== ======================

View file

@ -6,5 +6,5 @@ Reporting bugs
upper-right corner). upper-right corner).
- Obtain the app's log files, which can be found on the phone in - Obtain the app's log files, which can be found on the phone in
_/storage/emulated/0/Android/data/info.nightscout.androidaps/_ _/storage/emulated/0/Android/data/info.nightscout.androidaps/_
See https://androidaps.readthedocs.io/en/latest/EN/Usage/Accessing-logfiles.html See https://wiki.aaps.app/en/latest/Usage/Accessing-logfiles.html
- Open an issue at https://github.com/nightscout/AndroidAPS/issues/new - Open an issue at https://github.com/nightscout/AndroidAPS/issues/new

View file

@ -7,12 +7,11 @@
[![CircleCI](https://circleci.com/gh/nightscout/AndroidAPS/tree/master.svg?style=svg)](https://circleci.com/gh/nightscout/AndroidAPS/tree/master) [![CircleCI](https://circleci.com/gh/nightscout/AndroidAPS/tree/master.svg?style=svg)](https://circleci.com/gh/nightscout/AndroidAPS/tree/master)
[![Crowdin](https://d322cqt584bo4o.cloudfront.net/androidaps/localized.svg)](https://translations.aaps.app/project/androidaps) [![Crowdin](https://d322cqt584bo4o.cloudfront.net/androidaps/localized.svg)](https://translations.aaps.app/project/androidaps)
[![Documentation Status](https://readthedocs.org/projects/androidaps/badge/?version=latest)](https://wiki.aaps.app/en/latest/?badge=latest) [![Documentation Status](https://readthedocs.org/projects/androidaps/badge/?version=latest)](https://wiki.aaps.app/en/latest/?badge=latest)
[![codecov](https://codecov.io/gh/nightscout/AndroidAPS/branch/master/graph/badge.svg)](https://codecov.io/gh/MilosKozak/AndroidAPS) [![codecov](https://codecov.io/gh/nightscout/AndroidAPS/branch/master/graph/badge.svg?token=EmklfIV6bH)](https://codecov.io/gh/nightscout/AndroidAPS)
DEV: DEV:
[![CircleCI](https://circleci.com/gh/nightscout/AndroidAPS/tree/dev.svg?style=svg)](https://circleci.com/gh/nightscout/AndroidAPS/tree/dev) [![CircleCI](https://circleci.com/gh/nightscout/AndroidAPS/tree/dev.svg?style=svg)](https://circleci.com/gh/nightscout/AndroidAPS/tree/dev)
[![codecov](https://codecov.io/gh/nightscout/AndroidAPS/branch/dev/graph/badge.svg)](https://codecov.io/gh/MilosKozak/AndroidAPS) [![codecov](https://codecov.io/gh/nightscout/AndroidAPS/branch/dev/graph/badge.svg?token=EmklfIV6bH)](https://codecov.io/gh/nightscout/AndroidAPS/tree/dev)
<img src="https://cdn.iconscout.com/icon/free/png-256/bitcoin-384-920569.png" srcset="https://cdn.iconscout.com/icon/free/png-512/bitcoin-384-920569.png 2x" alt="Bitcoin Icon" width="100"> <img src="https://cdn.iconscout.com/icon/free/png-256/bitcoin-384-920569.png" srcset="https://cdn.iconscout.com/icon/free/png-512/bitcoin-384-920569.png 2x" alt="Bitcoin Icon" width="100">

View file

@ -3,7 +3,7 @@ package info.nightscout.rx.events
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Locale import java.util.Locale
class EventNSClientNewLog(val action: String, val logText: String) : Event() { class EventNSClientNewLog(val action: String, val logText: String?) : Event() {
var date = System.currentTimeMillis() var date = System.currentTimeMillis()
private var timeFormat = SimpleDateFormat("HH:mm:ss", Locale.getDefault()) private var timeFormat = SimpleDateFormat("HH:mm:ss", Locale.getDefault())
@ -15,7 +15,6 @@ class EventNSClientNewLog(val action: String, val logText: String) : Event() {
stringBuilder.append(action) stringBuilder.append(action)
stringBuilder.append("</b> ") stringBuilder.append("</b> ")
stringBuilder.append(logText) stringBuilder.append(logText)
stringBuilder.append("<br>")
return stringBuilder return stringBuilder
} }
} }

View file

@ -0,0 +1,21 @@
package info.nightscout.rx.events
import java.text.SimpleDateFormat
import java.util.Locale
class EventXdripNewLog(val action: String, val logText: String?) : Event() {
var date = System.currentTimeMillis()
private var timeFormat = SimpleDateFormat("HH:mm:ss", Locale.getDefault())
fun toPreparedHtml(): StringBuilder {
val stringBuilder = StringBuilder()
stringBuilder.append(timeFormat.format(date))
stringBuilder.append(" <b>")
stringBuilder.append(action)
stringBuilder.append("</b> ")
stringBuilder.append(logText)
stringBuilder.append("<br>")
return stringBuilder
}
}

View file

@ -13,6 +13,7 @@ enum class LTag(val tag: String, val defaultValue : Boolean = true, val requires
DATATREATMENTS("DATATREATMENTS"), DATATREATMENTS("DATATREATMENTS"),
EVENTS("EVENTS", defaultValue = false, requiresRestart = true), EVENTS("EVENTS", defaultValue = false, requiresRestart = true),
GLUCOSE("GLUCOSE", defaultValue = false), GLUCOSE("GLUCOSE", defaultValue = false),
HTTP("HTTP"),
LOCATION("LOCATION"), LOCATION("LOCATION"),
NOTIFICATION("NOTIFICATION"), NOTIFICATION("NOTIFICATION"),
NSCLIENT("NSCLIENT"), NSCLIENT("NSCLIENT"),
@ -27,5 +28,6 @@ enum class LTag(val tag: String, val defaultValue : Boolean = true, val requires
UI("UI", defaultValue = false), UI("UI", defaultValue = false),
WEAR("WEAR"), WEAR("WEAR"),
WIDGET("WIDGET"), WIDGET("WIDGET"),
WORKER("WORKER") WORKER("WORKER"),
XDRIP("XDRIP")
} }

View file

@ -2,7 +2,12 @@
<resources> <resources>
<!-- DateUtil--> <!-- DateUtil-->
<string name="minago">преди %1$d мин</string> <string name="minago">преди %1$d мин</string>
<string name="minago_long">Преди %1$d минути</string>
<string name="hoursago">преди %1$.1fч</string> <string name="hoursago">преди %1$.1fч</string>
<string name="days_ago">преди %1$.1f дни</string>
<string name="days_ago_round">преди %1$.0f дни</string>
<string name="in_days">за %1$.0f дни</string>
<string name="in_days_round">за %1$.0f дни</string>
<string name="shorthour">ч</string> <string name="shorthour">ч</string>
<string name="days">дни</string> <string name="days">дни</string>
<string name="hours">часа</string> <string name="hours">часа</string>
@ -18,6 +23,10 @@
<string name="unit_weeks">седмици</string> <string name="unit_weeks">седмици</string>
<string name="shortminute">м</string> <string name="shortminute">м</string>
<string name="shortday">д</string> <string name="shortday">д</string>
<string name="later_today">По-късно днес</string>
<string name="tomorrow">Утре</string>
<string name="today">Днес</string>
<string name="yesterday">Вчера</string>
<!-- Rx --> <!-- Rx -->
<string name="connecting_for">Свързване %1$d сек</string> <string name="connecting_for">Свързване %1$d сек</string>
<string name="handshaking">Сдвояване</string> <string name="handshaking">Сдвояване</string>

View file

@ -8,7 +8,7 @@
<string name="days_ago_round">vor %1$.0f Tagen</string> <string name="days_ago_round">vor %1$.0f Tagen</string>
<string name="in_days">in %1$.0f Tagen</string> <string name="in_days">in %1$.0f Tagen</string>
<string name="in_days_round">in %1$.0f Tagen</string> <string name="in_days_round">in %1$.0f Tagen</string>
<string name="shorthour">s</string> <string name="shorthour">h</string>
<string name="days">Tage</string> <string name="days">Tage</string>
<string name="hours">Stunden</string> <string name="hours">Stunden</string>
<string name="unit_second">Sekunde</string> <string name="unit_second">Sekunde</string>

View file

@ -2,6 +2,7 @@
<resources> <resources>
<!-- DateUtil--> <!-- DateUtil-->
<string name="minago">%1$d min temu</string> <string name="minago">%1$d min temu</string>
<string name="minago_long">%1$d minut temu</string>
<string name="hoursago">%1$.1f godz. temu</string> <string name="hoursago">%1$.1f godz. temu</string>
<string name="days_ago">%1$.1f dni temu</string> <string name="days_ago">%1$.1f dni temu</string>
<string name="days_ago_round">%1$.0f dni temu</string> <string name="days_ago_round">%1$.0f dni temu</string>

View file

@ -111,7 +111,7 @@ android {
defaultConfig { defaultConfig {
multiDexEnabled true multiDexEnabled true
versionCode 1500 versionCode 1500
version "3.1.0.3-dev-e" version "3.1.0.3-dev-h"
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() + '"'
@ -177,7 +177,6 @@ allprojects {
} }
dependencies { dependencies {
implementation project(path: ':plugins:aps')
wearApp project(':wear') wearApp project(':wear')
// in order to use internet's versions you'd need to enable Jetifier again // in order to use internet's versions you'd need to enable Jetifier again
@ -201,8 +200,8 @@ dependencies {
implementation project(':plugins:constraints') implementation project(':plugins:constraints')
implementation project(':plugins:insulin') implementation project(':plugins:insulin')
implementation project(':plugins:main') implementation project(':plugins:main')
implementation project(':plugins:openhumans')
implementation project(':plugins:sensitivity') implementation project(':plugins:sensitivity')
implementation project(':plugins:smoothing')
implementation project(':plugins:source') implementation project(':plugins:source')
implementation project(':plugins:sync') implementation project(':plugins:sync')
implementation project(':implementation') implementation project(':implementation')

View file

@ -88,6 +88,7 @@
<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" />
<action android:name="com.dexcom.g7.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 -->

View file

@ -51,7 +51,6 @@ import info.nightscout.interfaces.aps.Loop
import info.nightscout.interfaces.constraints.Constraints import info.nightscout.interfaces.constraints.Constraints
import info.nightscout.interfaces.logging.UserEntryLogger import info.nightscout.interfaces.logging.UserEntryLogger
import info.nightscout.interfaces.maintenance.PrefFileListProvider import info.nightscout.interfaces.maintenance.PrefFileListProvider
import info.nightscout.interfaces.nsclient.NSSettingsStatus
import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.plugin.PluginBase import info.nightscout.interfaces.plugin.PluginBase
import info.nightscout.interfaces.profile.ProfileFunction import info.nightscout.interfaces.profile.ProfileFunction
@ -62,7 +61,6 @@ import info.nightscout.interfaces.versionChecker.VersionCheckerUtils
import info.nightscout.plugins.constraints.signatureVerifier.SignatureVerifierPlugin import info.nightscout.plugins.constraints.signatureVerifier.SignatureVerifierPlugin
import info.nightscout.rx.AapsSchedulers import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.events.EventAppExit import info.nightscout.rx.events.EventAppExit
import info.nightscout.rx.events.EventInitializationChanged
import info.nightscout.rx.events.EventPreferenceChange import info.nightscout.rx.events.EventPreferenceChange
import info.nightscout.rx.events.EventRebuildTabs import info.nightscout.rx.events.EventRebuildTabs
import info.nightscout.rx.logging.LTag import info.nightscout.rx.logging.LTag
@ -88,7 +86,6 @@ class MainActivity : DaggerAppCompatActivityWithResult() {
@Inject lateinit var versionCheckerUtils: VersionCheckerUtils @Inject lateinit var versionCheckerUtils: VersionCheckerUtils
@Inject lateinit var smsCommunicator: SmsCommunicator @Inject lateinit var smsCommunicator: SmsCommunicator
@Inject lateinit var loop: Loop @Inject lateinit var loop: Loop
@Inject lateinit var nsSettingsStatus: NSSettingsStatus
@Inject lateinit var config: Config @Inject lateinit var config: Config
@Inject lateinit var activePlugin: ActivePlugin @Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var fabricPrivacy: FabricPrivacy @Inject lateinit var fabricPrivacy: FabricPrivacy
@ -347,11 +344,11 @@ class MainActivity : DaggerAppCompatActivityWithResult() {
R.id.nav_about -> { R.id.nav_about -> {
var message = "Build: ${BuildConfig.BUILDVERSION}\n" var message = "Build: ${BuildConfig.BUILDVERSION}\n"
message += "Flavor: ${BuildConfig.FLAVOR}${BuildConfig.BUILD_TYPE}\n" message += "Flavor: ${BuildConfig.FLAVOR}${BuildConfig.BUILD_TYPE}\n"
message += "${rh.gs(info.nightscout.configuration.R.string.configbuilder_nightscoutversion_label)} ${nsSettingsStatus.getVersion()}" message += "${rh.gs(info.nightscout.configuration.R.string.configbuilder_nightscoutversion_label)} ${activePlugin.activeNsClient?.detectedNsVersion() ?: rh.gs(info.nightscout.plugins.R.string.not_available_full)}"
if (config.isEngineeringMode()) message += "\n${rh.gs(info.nightscout.configuration.R.string.engineering_mode_enabled)}" if (config.isEngineeringMode()) message += "\n${rh.gs(info.nightscout.configuration.R.string.engineering_mode_enabled)}"
if (config.isUnfinishedMode()) message += "\nUnfinished mode enabled" if (config.isUnfinishedMode()) message += "\nUnfinished mode enabled"
if (!fabricPrivacy.fabricEnabled()) message += "\n${rh.gs(R.string.fabric_upload_disabled)}" if (!fabricPrivacy.fabricEnabled()) message += "\n${rh.gs(info.nightscout.core.ui.R.string.fabric_upload_disabled)}"
message += rh.gs(info.nightscout.pump.combo.R.string.about_link_urls) message += rh.gs(info.nightscout.core.ui.R.string.about_link_urls)
val messageSpanned = SpannableString(message) val messageSpanned = SpannableString(message)
Linkify.addLinks(messageSpanned, Linkify.WEB_URLS) Linkify.addLinks(messageSpanned, Linkify.WEB_URLS)
MaterialAlertDialogBuilder(this, info.nightscout.core.ui.R.style.DialogTheme) MaterialAlertDialogBuilder(this, info.nightscout.core.ui.R.style.DialogTheme)
@ -359,7 +356,7 @@ class MainActivity : DaggerAppCompatActivityWithResult() {
.setIcon(iconsProvider.getIcon()) .setIcon(iconsProvider.getIcon())
.setMessage(messageSpanned) .setMessage(messageSpanned)
.setPositiveButton(rh.gs(info.nightscout.core.ui.R.string.ok), null) .setPositiveButton(rh.gs(info.nightscout.core.ui.R.string.ok), null)
.setNeutralButton(rh.gs(R.string.cta_dont_kill_my_app_info)) { _, _ -> .setNeutralButton(rh.gs(info.nightscout.core.ui.R.string.cta_dont_kill_my_app_info)) { _, _ ->
startActivity( startActivity(
Intent( Intent(
Intent.ACTION_VIEW, Intent.ACTION_VIEW,

View file

@ -151,7 +151,7 @@ class MainApp : DaggerApplication() {
// schedule widget update // schedule widget update
refreshWidget = Runnable { refreshWidget = Runnable {
handler.postDelayed(refreshWidget, 60000) handler.postDelayed(refreshWidget, 60000)
Widget.updateWidget(this) Widget.updateWidget(this, "ScheduleEveryMin")
} }
handler.postDelayed(refreshWidget, 60000) handler.postDelayed(refreshWidget, 60000)
} }
@ -180,7 +180,7 @@ class MainApp : DaggerApplication() {
Thread.currentThread().uncaughtExceptionHandler?.uncaughtException(Thread.currentThread(), e) Thread.currentThread().uncaughtExceptionHandler?.uncaughtException(Thread.currentThread(), e)
return@setErrorHandler return@setErrorHandler
} }
aapsLogger.warn(LTag.CORE, "Undeliverable exception received, not sure what to do", e.toString()) aapsLogger.warn(LTag.CORE, "Undeliverable exception received, not sure what to do", e.localizedMessage)
} }
} }

View file

@ -295,7 +295,7 @@ class HistoryBrowseActivity : DaggerAppCompatActivity() {
val menuChartSettings = overviewMenus.setting val menuChartSettings = overviewMenus.setting
graphData.addInRangeArea(historyBrowserData.overviewData.fromTime, historyBrowserData.overviewData.endTime, defaultValueHelper.determineLowLine(), defaultValueHelper.determineHighLine()) graphData.addInRangeArea(historyBrowserData.overviewData.fromTime, historyBrowserData.overviewData.endTime, defaultValueHelper.determineLowLine(), defaultValueHelper.determineHighLine())
graphData.addBgReadings(menuChartSettings[0][OverviewMenus.CharType.PRE.ordinal], context) graphData.addBgReadings(menuChartSettings[0][OverviewMenus.CharType.PRE.ordinal], context)
if (config.isDev()) graphData.addBucketedData() graphData.addBucketedData()
graphData.addTreatments(context) graphData.addTreatments(context)
graphData.addEps(context, 0.95) graphData.addEps(context, 0.95)
if (menuChartSettings[0][OverviewMenus.CharType.TREAT.ordinal]) if (menuChartSettings[0][OverviewMenus.CharType.TREAT.ordinal])
@ -367,7 +367,7 @@ class HistoryBrowseActivity : DaggerAppCompatActivity() {
} }
private fun updateCalcProgress(percent: Int) { private fun updateCalcProgress(percent: Int) {
binding.progressBar.progress = percent
binding.progressBar.visibility = (percent != 100).toVisibilityKeepSpace() binding.progressBar.visibility = (percent != 100).toVisibilityKeepSpace()
binding.progressBar.progress = percent
} }
} }

View file

@ -20,7 +20,7 @@ import info.nightscout.androidaps.R
import info.nightscout.androidaps.danaRKorean.DanaRKoreanPlugin import info.nightscout.androidaps.danaRKorean.DanaRKoreanPlugin
import info.nightscout.androidaps.danaRv2.DanaRv2Plugin import info.nightscout.androidaps.danaRv2.DanaRv2Plugin
import info.nightscout.androidaps.danar.DanaRPlugin import info.nightscout.androidaps.danar.DanaRPlugin
import info.nightscout.androidaps.plugin.general.openhumans.OpenHumansUploaderPlugin import info.nightscout.plugins.sync.openhumans.OpenHumansUploaderPlugin
import info.nightscout.androidaps.plugins.pump.eopatch.EopatchPumpPlugin import info.nightscout.androidaps.plugins.pump.eopatch.EopatchPumpPlugin
import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin
import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin
@ -47,10 +47,10 @@ import info.nightscout.plugins.constraints.safety.SafetyPlugin
import info.nightscout.plugins.general.autotune.AutotunePlugin import info.nightscout.plugins.general.autotune.AutotunePlugin
import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorPlugin import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorPlugin
import info.nightscout.plugins.general.wear.WearPlugin import info.nightscout.plugins.general.wear.WearPlugin
import info.nightscout.plugins.general.xdripStatusline.StatusLinePlugin
import info.nightscout.plugins.sync.nsclient.NSClientPlugin import info.nightscout.plugins.sync.nsclient.NSClientPlugin
import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin
import info.nightscout.plugins.sync.tidepool.TidepoolPlugin import info.nightscout.plugins.sync.tidepool.TidepoolPlugin
import info.nightscout.plugins.sync.xdrip.XdripPlugin
import info.nightscout.pump.combo.ComboPlugin import info.nightscout.pump.combo.ComboPlugin
import info.nightscout.pump.combov2.ComboV2Plugin import info.nightscout.pump.combov2.ComboV2Plugin
import info.nightscout.pump.diaconn.DiaconnG8Plugin import info.nightscout.pump.diaconn.DiaconnG8Plugin
@ -116,7 +116,7 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang
@Inject lateinit var intelligoPlugin: IntelligoPlugin @Inject lateinit var intelligoPlugin: IntelligoPlugin
@Inject lateinit var aidexPlugin: AidexPlugin @Inject lateinit var aidexPlugin: AidexPlugin
@Inject lateinit var smsCommunicatorPlugin: SmsCommunicatorPlugin @Inject lateinit var smsCommunicatorPlugin: SmsCommunicatorPlugin
@Inject lateinit var statusLinePlugin: StatusLinePlugin @Inject lateinit var statusLinePlugin: XdripPlugin
@Inject lateinit var tidepoolPlugin: TidepoolPlugin @Inject lateinit var tidepoolPlugin: TidepoolPlugin
@Inject lateinit var virtualPumpPlugin: VirtualPumpPlugin @Inject lateinit var virtualPumpPlugin: VirtualPumpPlugin
@Inject lateinit var wearPlugin: WearPlugin @Inject lateinit var wearPlugin: WearPlugin
@ -260,7 +260,7 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang
private fun preprocessPreferences() { private fun preprocessPreferences() {
for (plugin in pluginStore.plugins) { for (plugin in pluginStore.plugins) {
plugin.preprocessPreferences(this) if (plugin.isEnabled()) plugin.preprocessPreferences(this)
} }
} }

View file

@ -8,7 +8,7 @@ import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.danar.di.DanaRModule import info.nightscout.androidaps.danar.di.DanaRModule
import info.nightscout.androidaps.insight.di.InsightDatabaseModule import info.nightscout.androidaps.insight.di.InsightDatabaseModule
import info.nightscout.androidaps.insight.di.InsightModule import info.nightscout.androidaps.insight.di.InsightModule
import info.nightscout.androidaps.plugin.general.openhumans.di.OpenHumansModule import info.nightscout.plugins.sync.di.OpenHumansModule
import info.nightscout.androidaps.plugins.pump.common.di.RileyLinkModule import info.nightscout.androidaps.plugins.pump.common.di.RileyLinkModule
import info.nightscout.androidaps.plugins.pump.eopatch.dagger.EopatchModule import info.nightscout.androidaps.plugins.pump.eopatch.dagger.EopatchModule
import info.nightscout.androidaps.plugins.pump.medtronic.di.MedtronicModule import info.nightscout.androidaps.plugins.pump.medtronic.di.MedtronicModule

View file

@ -34,14 +34,14 @@ open class AppModule {
@PluginsListModule.PumpDriver pumpDrivers: Lazy<Map<@JvmSuppressWildcards Int, @JvmSuppressWildcards PluginBase>>, @PluginsListModule.PumpDriver pumpDrivers: Lazy<Map<@JvmSuppressWildcards Int, @JvmSuppressWildcards PluginBase>>,
@PluginsListModule.NotNSClient notNsClient: Lazy<Map<@JvmSuppressWildcards Int, @JvmSuppressWildcards PluginBase>>, @PluginsListModule.NotNSClient notNsClient: Lazy<Map<@JvmSuppressWildcards Int, @JvmSuppressWildcards PluginBase>>,
@PluginsListModule.APS aps: Lazy<Map<@JvmSuppressWildcards Int, @JvmSuppressWildcards PluginBase>>, @PluginsListModule.APS aps: Lazy<Map<@JvmSuppressWildcards Int, @JvmSuppressWildcards PluginBase>>,
@PluginsListModule.Unfinished unfinished: Lazy<Map<@JvmSuppressWildcards Int, @JvmSuppressWildcards PluginBase>> //@PluginsListModule.Unfinished unfinished: Lazy<Map<@JvmSuppressWildcards Int, @JvmSuppressWildcards PluginBase>>
) )
: List<@JvmSuppressWildcards PluginBase> { : List<@JvmSuppressWildcards PluginBase> {
val plugins = allConfigs.toMutableMap() val plugins = allConfigs.toMutableMap()
if (config.PUMPDRIVERS) plugins += pumpDrivers.get() if (config.PUMPDRIVERS) plugins += pumpDrivers.get()
if (config.APS) plugins += aps.get() if (config.APS) plugins += aps.get()
if (!config.NSCLIENT) plugins += notNsClient.get() if (!config.NSCLIENT) plugins += notNsClient.get()
if (config.isUnfinishedMode()) plugins += unfinished.get() //if (config.isUnfinishedMode()) plugins += unfinished.get()
return plugins.toList().sortedBy { it.first }.map { it.second } return plugins.toList().sortedBy { it.first }.map { it.second }
} }

View file

@ -7,7 +7,7 @@ import dagger.multibindings.IntoMap
import info.nightscout.androidaps.danaRKorean.DanaRKoreanPlugin import info.nightscout.androidaps.danaRKorean.DanaRKoreanPlugin
import info.nightscout.androidaps.danaRv2.DanaRv2Plugin import info.nightscout.androidaps.danaRv2.DanaRv2Plugin
import info.nightscout.androidaps.danar.DanaRPlugin import info.nightscout.androidaps.danar.DanaRPlugin
import info.nightscout.androidaps.plugin.general.openhumans.OpenHumansUploaderPlugin import info.nightscout.plugins.sync.openhumans.OpenHumansUploaderPlugin
import info.nightscout.androidaps.plugins.pump.eopatch.EopatchPumpPlugin import info.nightscout.androidaps.plugins.pump.eopatch.EopatchPumpPlugin
import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin
import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin
@ -31,19 +31,19 @@ import info.nightscout.plugins.constraints.safety.SafetyPlugin
import info.nightscout.plugins.constraints.signatureVerifier.SignatureVerifierPlugin import info.nightscout.plugins.constraints.signatureVerifier.SignatureVerifierPlugin
import info.nightscout.plugins.general.actions.ActionsPlugin import info.nightscout.plugins.general.actions.ActionsPlugin
import info.nightscout.plugins.general.autotune.AutotunePlugin import info.nightscout.plugins.general.autotune.AutotunePlugin
import info.nightscout.plugins.general.dataBroadcaster.DataBroadcastPlugin
import info.nightscout.plugins.general.food.FoodPlugin import info.nightscout.plugins.general.food.FoodPlugin
import info.nightscout.plugins.general.overview.OverviewPlugin import info.nightscout.plugins.general.overview.OverviewPlugin
import info.nightscout.plugins.general.persistentNotification.PersistentNotificationPlugin import info.nightscout.plugins.general.persistentNotification.PersistentNotificationPlugin
import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorPlugin import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorPlugin
import info.nightscout.plugins.general.themes.ThemeSwitcherPlugin import info.nightscout.plugins.general.themes.ThemeSwitcherPlugin
import info.nightscout.plugins.general.wear.WearPlugin import info.nightscout.plugins.general.wear.WearPlugin
import info.nightscout.plugins.general.xdripStatusline.StatusLinePlugin
import info.nightscout.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin import info.nightscout.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.plugins.profile.ProfilePlugin import info.nightscout.plugins.profile.ProfilePlugin
import info.nightscout.plugins.sync.dataBroadcaster.DataBroadcastPlugin
import info.nightscout.plugins.sync.nsclient.NSClientPlugin import info.nightscout.plugins.sync.nsclient.NSClientPlugin
import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin
import info.nightscout.plugins.sync.tidepool.TidepoolPlugin import info.nightscout.plugins.sync.tidepool.TidepoolPlugin
import info.nightscout.plugins.sync.xdrip.XdripPlugin
import info.nightscout.pump.combo.ComboPlugin import info.nightscout.pump.combo.ComboPlugin
import info.nightscout.pump.combov2.ComboV2Plugin import info.nightscout.pump.combov2.ComboV2Plugin
import info.nightscout.pump.diaconn.DiaconnG8Plugin import info.nightscout.pump.diaconn.DiaconnG8Plugin
@ -51,6 +51,9 @@ import info.nightscout.pump.virtual.VirtualPumpPlugin
import info.nightscout.sensitivity.SensitivityAAPSPlugin import info.nightscout.sensitivity.SensitivityAAPSPlugin
import info.nightscout.sensitivity.SensitivityOref1Plugin import info.nightscout.sensitivity.SensitivityOref1Plugin
import info.nightscout.sensitivity.SensitivityWeightedAveragePlugin import info.nightscout.sensitivity.SensitivityWeightedAveragePlugin
import info.nightscout.smoothing.AvgSmoothingPlugin
import info.nightscout.smoothing.ExponentialSmoothingPlugin
import info.nightscout.smoothing.NoSmoothingPlugin
import info.nightscout.source.AidexPlugin import info.nightscout.source.AidexPlugin
import info.nightscout.source.DexcomPlugin import info.nightscout.source.DexcomPlugin
import info.nightscout.source.GlimpPlugin import info.nightscout.source.GlimpPlugin
@ -61,7 +64,7 @@ import info.nightscout.source.NSClientSourcePlugin
import info.nightscout.source.PoctechPlugin import info.nightscout.source.PoctechPlugin
import info.nightscout.source.RandomBgPlugin import info.nightscout.source.RandomBgPlugin
import info.nightscout.source.TomatoPlugin import info.nightscout.source.TomatoPlugin
import info.nightscout.source.XdripPlugin import info.nightscout.source.XdripSourcePlugin
import javax.inject.Qualifier import javax.inject.Qualifier
@Suppress("unused") @Suppress("unused")
@ -305,26 +308,38 @@ abstract class PluginsListModule {
@Binds @Binds
@AllConfigs @AllConfigs
@IntoMap @IntoMap
@IntKey(340) @IntKey(350)
abstract fun bindStatusLinePlugin(plugin: StatusLinePlugin): PluginBase abstract fun bindNSClientPlugin(plugin: NSClientPlugin): PluginBase
@Binds @Binds
@AllConfigs @AllConfigs
@IntoMap @IntoMap
@IntKey(360) @IntKey(355)
abstract fun bindNSClientPlugin(plugin: NSClientPlugin): PluginBase abstract fun bindNSClientV3Plugin(plugin: NSClientV3Plugin): PluginBase
@Binds @Binds
@Unfinished @NotNSClient
@IntoMap @IntoMap
@IntKey(368) @IntKey(360)
abstract fun bindTidepoolPlugin(plugin: TidepoolPlugin): PluginBase abstract fun bindTidepoolPlugin(plugin: TidepoolPlugin): PluginBase
@Binds @Binds
@Unfinished @AllConfigs
@IntoMap @IntoMap
@IntKey(362) @IntKey(364)
abstract fun bindNSClientV3Plugin(plugin: NSClientV3Plugin): PluginBase abstract fun bindXdripPlugin(plugin: XdripPlugin): PluginBase
@Binds
@AllConfigs
@IntoMap
@IntKey(366)
abstract fun bindDataBroadcastPlugin(plugin: DataBroadcastPlugin): PluginBase
@Binds
@NotNSClient
@IntoMap
@IntKey(368)
abstract fun bindsOpenHumansPlugin(plugin: OpenHumansUploaderPlugin): PluginBase
@Binds @Binds
@AllConfigs @AllConfigs
@ -344,17 +359,11 @@ abstract class PluginsListModule {
@IntKey(381) @IntKey(381)
abstract fun bindBgQualityCheckPlugin(plugin: BgQualityCheckPlugin): PluginBase abstract fun bindBgQualityCheckPlugin(plugin: BgQualityCheckPlugin): PluginBase
@Binds
@AllConfigs
@IntoMap
@IntKey(390)
abstract fun bindDataBroadcastPlugin(plugin: DataBroadcastPlugin): PluginBase
@Binds @Binds
@AllConfigs @AllConfigs
@IntoMap @IntoMap
@IntKey(400) @IntKey(400)
abstract fun bindXdripPlugin(plugin: XdripPlugin): PluginBase abstract fun bindXdripSourcePlugin(plugin: XdripSourcePlugin): PluginBase
@Binds @Binds
@AllConfigs @AllConfigs
@ -416,12 +425,6 @@ abstract class PluginsListModule {
@IntKey(475) @IntKey(475)
abstract fun bindRandomBgPlugin(plugin: RandomBgPlugin): PluginBase abstract fun bindRandomBgPlugin(plugin: RandomBgPlugin): PluginBase
@Binds
@NotNSClient
@IntoMap
@IntKey(480)
abstract fun bindsOpenHumansPlugin(plugin: OpenHumansUploaderPlugin): PluginBase
@Binds @Binds
@AllConfigs @AllConfigs
@IntoMap @IntoMap
@ -434,6 +437,24 @@ abstract class PluginsListModule {
@IntKey(500) @IntKey(500)
abstract fun bindThemeSwitcherPlugin(plugin: ThemeSwitcherPlugin): PluginBase abstract fun bindThemeSwitcherPlugin(plugin: ThemeSwitcherPlugin): PluginBase
@Binds
@AllConfigs
@IntoMap
@IntKey(600)
abstract fun bindNoSmoothingPlugin(plugin: NoSmoothingPlugin): PluginBase
@Binds
@AllConfigs
@IntoMap
@IntKey(605)
abstract fun bindExponentialSmoothingPlugin(plugin: ExponentialSmoothingPlugin): PluginBase
@Binds
@AllConfigs
@IntoMap
@IntKey(610)
abstract fun bindAvgSmoothingPlugin(plugin: AvgSmoothingPlugin): PluginBase
@Qualifier @Qualifier
annotation class AllConfigs annotation class AllConfigs

View file

@ -9,12 +9,13 @@ import java.io.File
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
@Suppress("KotlinConstantConditions")
@Singleton @Singleton
class ConfigImpl @Inject constructor( class ConfigImpl @Inject constructor(
fileListProvider: PrefFileListProvider fileListProvider: PrefFileListProvider
) : Config { ) : Config {
override val SUPPORTEDNSVERSION = 140206 // 14.2.6 override val SUPPORTED_NS_VERSION = 150000 // 15.0.0
override val APS = BuildConfig.FLAVOR == "full" override val APS = BuildConfig.FLAVOR == "full"
override val NSCLIENT = BuildConfig.FLAVOR == "aapsclient" || BuildConfig.FLAVOR == "aapsclient2" override val NSCLIENT = BuildConfig.FLAVOR == "aapsclient" || BuildConfig.FLAVOR == "aapsclient2"
override val PUMPCONTROL = BuildConfig.FLAVOR == "pumpcontrol" override val PUMPCONTROL = BuildConfig.FLAVOR == "pumpcontrol"

View file

@ -14,8 +14,6 @@ import info.nightscout.androidaps.activities.MyPreferenceFragment
import info.nightscout.androidaps.activities.PreferencesActivity import info.nightscout.androidaps.activities.PreferencesActivity
import info.nightscout.configuration.activities.SingleFragmentActivity import info.nightscout.configuration.activities.SingleFragmentActivity
import info.nightscout.core.events.EventNewNotification import info.nightscout.core.events.EventNewNotification
import info.nightscout.ui.services.AlarmSoundService
import info.nightscout.ui.services.AlarmSoundServiceHelper
import info.nightscout.core.ui.toast.ToastUtils import info.nightscout.core.ui.toast.ToastUtils
import info.nightscout.interfaces.notifications.Notification import info.nightscout.interfaces.notifications.Notification
import info.nightscout.interfaces.nsclient.NSAlarm import info.nightscout.interfaces.nsclient.NSAlarm
@ -24,6 +22,7 @@ import info.nightscout.plugins.general.overview.notifications.NotificationWithAc
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
import info.nightscout.ui.activities.BolusProgressHelperActivity import info.nightscout.ui.activities.BolusProgressHelperActivity
import info.nightscout.ui.activities.ErrorHelperActivity import info.nightscout.ui.activities.ErrorHelperActivity
import info.nightscout.ui.activities.QuickWizardListActivity
import info.nightscout.ui.activities.TDDStatsActivity import info.nightscout.ui.activities.TDDStatsActivity
import info.nightscout.ui.dialogs.BolusProgressDialog import info.nightscout.ui.dialogs.BolusProgressDialog
import info.nightscout.ui.dialogs.CalibrationDialog import info.nightscout.ui.dialogs.CalibrationDialog
@ -39,6 +38,8 @@ import info.nightscout.ui.dialogs.TempBasalDialog
import info.nightscout.ui.dialogs.TempTargetDialog import info.nightscout.ui.dialogs.TempTargetDialog
import info.nightscout.ui.dialogs.TreatmentDialog import info.nightscout.ui.dialogs.TreatmentDialog
import info.nightscout.ui.dialogs.WizardDialog import info.nightscout.ui.dialogs.WizardDialog
import info.nightscout.ui.services.AlarmSoundService
import info.nightscout.ui.services.AlarmSoundServiceHelper
import info.nightscout.ui.widget.Widget import info.nightscout.ui.widget.Widget
import javax.inject.Inject import javax.inject.Inject
@ -57,6 +58,7 @@ class UiInteractionImpl @Inject constructor(
override val singleFragmentActivity: Class<*> = SingleFragmentActivity::class.java override val singleFragmentActivity: Class<*> = SingleFragmentActivity::class.java
override val preferencesActivity: Class<*> = PreferencesActivity::class.java override val preferencesActivity: Class<*> = PreferencesActivity::class.java
override val myPreferenceFragment: Class<*> = MyPreferenceFragment::class.java override val myPreferenceFragment: Class<*> = MyPreferenceFragment::class.java
override val quickWizardListActivity: Class<*> = QuickWizardListActivity::class.java
override val prefGeneral: Int = R.xml.pref_general override val prefGeneral: Int = R.xml.pref_general
override fun runAlarm(status: String, title: String, @RawRes soundId: Int) { override fun runAlarm(status: String, title: String, @RawRes soundId: Int) {
@ -68,8 +70,8 @@ class UiInteractionImpl @Inject constructor(
context.startActivity(i) context.startActivity(i)
} }
override fun updateWidget(context: Context) { override fun updateWidget(context: Context, from: String) {
Widget.updateWidget(context) Widget.updateWidget(context, from)
} }
override fun runWizardDialog(fragmentManager: FragmentManager, carbs: Int?, name: String?) { override fun runWizardDialog(fragmentManager: FragmentManager, carbs: Int?, name: String?) {

View file

@ -32,12 +32,15 @@ class ChargingStateReceiver : DaggerBroadcastReceiver() {
var batteryLevel = 0 var batteryLevel = 0
val level = batteryStatus?.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) ?: -1 val level = batteryStatus?.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) ?: -1
val scale = batteryStatus?.getIntExtra(BatteryManager.EXTRA_SCALE, -1) ?: -1 val scale = batteryStatus?.getIntExtra(BatteryManager.EXTRA_SCALE, -1) ?: -1
val plugged = batteryStatus?.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) ?: -1
if (level != -1 && scale != -1) if (level != -1 && scale != -1)
batteryLevel = (level.toFloat() / scale.toFloat() * 100.0f).toInt() batteryLevel = (level.toFloat() / scale.toFloat() * 100.0f).toInt()
// Status // Plugged
val status: Int = batteryStatus?.getIntExtra(BatteryManager.EXTRA_STATUS, -1) ?: -1 val isCharging: Boolean =
val isCharging: Boolean = status == BatteryManager.BATTERY_STATUS_CHARGING plugged == BatteryManager.BATTERY_PLUGGED_AC ||
|| status == BatteryManager.BATTERY_STATUS_FULL plugged == BatteryManager.BATTERY_PLUGGED_USB ||
plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS ||
plugged == BatteryManager.BATTERY_PLUGGED_DOCK
return EventChargingState(isCharging, batteryLevel).also { receiverStatusStore.lastChargingEvent = it } return EventChargingState(isCharging, batteryLevel).also { receiverStatusStore.lastChargingEvent = it }
} }

View file

@ -22,7 +22,7 @@ import info.nightscout.source.GlimpPlugin
import info.nightscout.source.MM640gPlugin import info.nightscout.source.MM640gPlugin
import info.nightscout.source.PoctechPlugin import info.nightscout.source.PoctechPlugin
import info.nightscout.source.TomatoPlugin import info.nightscout.source.TomatoPlugin
import info.nightscout.source.XdripPlugin import info.nightscout.source.XdripSourcePlugin
import javax.inject.Inject import javax.inject.Inject
open class DataReceiver : DaggerBroadcastReceiver() { open class DataReceiver : DaggerBroadcastReceiver() {
@ -37,7 +37,7 @@ open class DataReceiver : DaggerBroadcastReceiver() {
when (intent.action) { when (intent.action) {
Intents.ACTION_NEW_BG_ESTIMATE -> Intents.ACTION_NEW_BG_ESTIMATE ->
OneTimeWorkRequest.Builder(XdripPlugin.XdripWorker::class.java) OneTimeWorkRequest.Builder(XdripSourcePlugin.XdripSourceWorker::class.java)
.setInputData(dataWorkerStorage.storeInputData(bundle, intent.action)).build() .setInputData(dataWorkerStorage.storeInputData(bundle, intent.action)).build()
Intents.POCTECH_BG -> Intents.POCTECH_BG ->
OneTimeWorkRequest.Builder(PoctechPlugin.PoctechWorker::class.java) OneTimeWorkRequest.Builder(PoctechPlugin.PoctechWorker::class.java)
@ -70,9 +70,11 @@ open class DataReceiver : DaggerBroadcastReceiver() {
Intents.EVERSENSE_BG -> Intents.EVERSENSE_BG ->
OneTimeWorkRequest.Builder(EversensePlugin.EversenseWorker::class.java) OneTimeWorkRequest.Builder(EversensePlugin.EversenseWorker::class.java)
.setInputData(dataWorkerStorage.storeInputData(bundle, intent.action)).build() .setInputData(dataWorkerStorage.storeInputData(bundle, intent.action)).build()
Intents.DEXCOM_BG ->
Intents.DEXCOM_BG, Intents.DEXCOM_G7_BG ->
OneTimeWorkRequest.Builder(DexcomPlugin.DexcomWorker::class.java) OneTimeWorkRequest.Builder(DexcomPlugin.DexcomWorker::class.java)
.setInputData(dataWorkerStorage.storeInputData(bundle, intent.action)).build() .setInputData(dataWorkerStorage.storeInputData(bundle, intent.action)).build()
Intents.AIDEX_NEW_BG_ESTIMATE -> Intents.AIDEX_NEW_BG_ESTIMATE ->
OneTimeWorkRequest.Builder(AidexPlugin.AidexWorker::class.java) OneTimeWorkRequest.Builder(AidexPlugin.AidexWorker::class.java)
.setInputData(dataWorkerStorage.storeInputData(bundle, intent.action)).build() .setInputData(dataWorkerStorage.storeInputData(bundle, intent.action)).build()

View file

@ -14,7 +14,6 @@ import info.nightscout.androidaps.BuildConfig
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.configuration.maintenance.MaintenancePlugin import info.nightscout.configuration.maintenance.MaintenancePlugin
import info.nightscout.core.profile.ProfileSealed import info.nightscout.core.profile.ProfileSealed
import info.nightscout.core.utils.fabric.FabricPrivacy
import info.nightscout.core.utils.worker.LoggingWorker import info.nightscout.core.utils.worker.LoggingWorker
import info.nightscout.database.impl.AppRepository import info.nightscout.database.impl.AppRepository
import info.nightscout.interfaces.Config import info.nightscout.interfaces.Config
@ -23,7 +22,6 @@ import info.nightscout.interfaces.aps.Loop
import info.nightscout.interfaces.configBuilder.RunningConfiguration import info.nightscout.interfaces.configBuilder.RunningConfiguration
import info.nightscout.interfaces.iob.IobCobCalculator import info.nightscout.interfaces.iob.IobCobCalculator
import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.plugin.PluginBase
import info.nightscout.interfaces.profile.ProfileFunction import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.queue.Command import info.nightscout.interfaces.queue.Command
import info.nightscout.interfaces.queue.CommandQueue import info.nightscout.interfaces.queue.CommandQueue
@ -35,7 +33,7 @@ import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil import info.nightscout.shared.utils.DateUtil
import info.nightscout.shared.utils.T import info.nightscout.shared.utils.T
import info.nightscout.ui.widget.Widget import kotlinx.coroutines.Dispatchers
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import javax.inject.Inject import javax.inject.Inject
import kotlin.math.abs import kotlin.math.abs
@ -43,7 +41,7 @@ import kotlin.math.abs
class KeepAliveWorker( class KeepAliveWorker(
private val context: Context, private val context: Context,
params: WorkerParameters params: WorkerParameters
) : LoggingWorker(context, params) { ) : LoggingWorker(context, params, Dispatchers.Default) {
@Inject lateinit var localAlertUtils: LocalAlertUtils @Inject lateinit var localAlertUtils: LocalAlertUtils
@Inject lateinit var repository: AppRepository @Inject lateinit var repository: AppRepository
@ -57,7 +55,6 @@ class KeepAliveWorker(
@Inject lateinit var receiverStatusStore: ReceiverStatusStore @Inject lateinit var receiverStatusStore: ReceiverStatusStore
@Inject lateinit var rxBus: RxBus @Inject lateinit var rxBus: RxBus
@Inject lateinit var commandQueue: CommandQueue @Inject lateinit var commandQueue: CommandQueue
@Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var maintenancePlugin: MaintenancePlugin @Inject lateinit var maintenancePlugin: MaintenancePlugin
@Inject lateinit var rh: ResourceHelper @Inject lateinit var rh: ResourceHelper
@Inject lateinit var sp: SP @Inject lateinit var sp: SP
@ -76,7 +73,7 @@ class KeepAliveWorker(
private const val KA_10 = "KeepAlive_10" private const val KA_10 = "KeepAlive_10"
} }
override fun doWorkAndLog(): Result { override suspend fun doWorkAndLog(): Result {
aapsLogger.debug(LTag.CORE, "KeepAlive received from: " + inputData.getString("schedule")) aapsLogger.debug(LTag.CORE, "KeepAlive received from: " + inputData.getString("schedule"))
// 15 min interval is WorkManager minimum so schedule another instances to have 5 min interval // 15 min interval is WorkManager minimum so schedule another instances to have 5 min interval
@ -110,7 +107,6 @@ class KeepAliveWorker(
} }
lastRun = dateUtil.now() lastRun = dateUtil.now()
Widget.updateWidget(context)
localAlertUtils.shortenSnoozeInterval() localAlertUtils.shortenSnoozeInterval()
localAlertUtils.checkStaleBGAlert() localAlertUtils.checkStaleBGAlert()
checkPump() checkPump()
@ -155,8 +151,7 @@ class KeepAliveWorker(
var shouldUploadStatus = false var shouldUploadStatus = false
if (config.NSCLIENT) return if (config.NSCLIENT) return
if (config.PUMPCONTROL) shouldUploadStatus = true if (config.PUMPCONTROL) shouldUploadStatus = true
else if (!(loop as PluginBase).isEnabled() || iobCobCalculator.ads.actualBg() == null) else if (!loop.isEnabled() || iobCobCalculator.ads.actualBg() == null) shouldUploadStatus = true
shouldUploadStatus = true
else if (dateUtil.isOlderThan(activePlugin.activeAPS.lastAPSRun, 5)) shouldUploadStatus = true else if (dateUtil.isOlderThan(activePlugin.activeAPS.lastAPSRun, 5)) shouldUploadStatus = true
if (dateUtil.isOlderThan(lastIobUpload, IOB_UPDATE_FREQUENCY_IN_MINUTES) && shouldUploadStatus) { if (dateUtil.isOlderThan(lastIobUpload, IOB_UPDATE_FREQUENCY_IN_MINUTES) && shouldUploadStatus) {
lastIobUpload = dateUtil.now() lastIobUpload = dateUtil.now()
@ -176,12 +171,22 @@ class KeepAliveWorker(
val requestedProfile = ProfileSealed.PS(ps) val requestedProfile = ProfileSealed.PS(ps)
val runningProfile = profileFunction.getProfile() val runningProfile = profileFunction.getProfile()
val lastConnection = pump.lastDataTime() val lastConnection = pump.lastDataTime()
val isStatusOutdated = lastConnection + STATUS_UPDATE_FREQUENCY < dateUtil.now() val now = dateUtil.now()
val isStatusOutdated = lastConnection + STATUS_UPDATE_FREQUENCY < now
val isBasalOutdated = abs(requestedProfile.getBasal() - pump.baseBasalRate) > pump.pumpDescription.basalStep val isBasalOutdated = abs(requestedProfile.getBasal() - pump.baseBasalRate) > pump.pumpDescription.basalStep
aapsLogger.debug(LTag.CORE, "Last connection: " + dateUtil.dateAndTimeString(lastConnection)) aapsLogger.debug(LTag.CORE, "Last connection: " + dateUtil.dateAndTimeString(lastConnection))
// sometimes keep alive broadcast stops // Sometimes it can happen that keepalive is not triggered every 5 minutes as it should.
// as as workaround test if readStatus was requested before an alarm is generated // In some cases, it may not even have been started at all.
if (lastReadStatus != 0L && lastReadStatus > dateUtil.now() - T.mins(5).msecs()) { // If these cases aren't handled, false "pump unreachable" alarms can be produced.
// Avoid this by checking that (a) readStatus was requested at least once (lastReadStatus
// is != 0 in that case) and (b) the last read status request was not too long ago.
//
// Also, use 5:30 as the threshold for (b) above instead of 5 minutes sharp. The keepalive
// checks come in 5 minute intervals, but due to temporal jitter, the interval between the
// last read status attempt and the current time can be slightly over 5 minutes (for example,
// 300041 milliseconds instead of exactly 300000). Add 30 extra seconds to allow for
// plenty of tolerance.
if (lastReadStatus != 0L && (now - lastReadStatus).coerceIn(minimumValue = 0, maximumValue = null) <= T.secs(5 * 60 + 30).msecs()) {
localAlertUtils.checkPumpUnreachableAlarm(lastConnection, isStatusOutdated, loop.isDisconnected) localAlertUtils.checkPumpUnreachableAlarm(lastConnection, isStatusOutdated, loop.isDisconnected)
} }
if (loop.isDisconnected) { if (loop.isDisconnected) {
@ -189,10 +194,10 @@ class KeepAliveWorker(
} else if (runningProfile == null || ((!pump.isThisProfileSet(requestedProfile) || !requestedProfile.isEqual(runningProfile)) && !commandQueue.isRunning(Command.CommandType.BASAL_PROFILE))) { } else if (runningProfile == null || ((!pump.isThisProfileSet(requestedProfile) || !requestedProfile.isEqual(runningProfile)) && !commandQueue.isRunning(Command.CommandType.BASAL_PROFILE))) {
rxBus.send(EventProfileSwitchChanged()) rxBus.send(EventProfileSwitchChanged())
} else if (isStatusOutdated && !pump.isBusy()) { } else if (isStatusOutdated && !pump.isBusy()) {
lastReadStatus = dateUtil.now() lastReadStatus = now
commandQueue.readStatus(rh.gs(info.nightscout.core.ui.R.string.keepalive_status_outdated), null) commandQueue.readStatus(rh.gs(info.nightscout.core.ui.R.string.keepalive_status_outdated), null)
} else if (isBasalOutdated && !pump.isBusy()) { } else if (isBasalOutdated && !pump.isBusy()) {
lastReadStatus = dateUtil.now() lastReadStatus = now
commandQueue.readStatus(rh.gs(info.nightscout.core.ui.R.string.keepalive_basal_outdated), null) commandQueue.readStatus(rh.gs(info.nightscout.core.ui.R.string.keepalive_basal_outdated), null)
} }
} }

View file

@ -5,16 +5,17 @@ import android.os.SystemClock
import androidx.work.Data import androidx.work.Data
import androidx.work.ExistingWorkPolicy import androidx.work.ExistingWorkPolicy
import androidx.work.OneTimeWorkRequest import androidx.work.OneTimeWorkRequest
import androidx.work.WorkContinuation
import androidx.work.WorkInfo import androidx.work.WorkInfo
import androidx.work.WorkManager import androidx.work.WorkManager
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.core.graph.OverviewData import info.nightscout.core.graph.OverviewData
import info.nightscout.core.utils.fabric.FabricPrivacy import info.nightscout.core.utils.fabric.FabricPrivacy
import info.nightscout.core.utils.receivers.DataWorkerStorage import info.nightscout.core.utils.receivers.DataWorkerStorage
import info.nightscout.core.utils.worker.then
import info.nightscout.core.workflow.CalculationWorkflow import info.nightscout.core.workflow.CalculationWorkflow
import info.nightscout.core.workflow.CalculationWorkflow.Companion.JOB import info.nightscout.core.workflow.CalculationWorkflow.Companion.JOB
import info.nightscout.core.workflow.CalculationWorkflow.Companion.MAIN_CALCULATION import info.nightscout.core.workflow.CalculationWorkflow.Companion.MAIN_CALCULATION
import info.nightscout.core.workflow.CalculationWorkflow.Companion.PASS
import info.nightscout.interfaces.iob.IobCobCalculator import info.nightscout.interfaces.iob.IobCobCalculator
import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin import info.nightscout.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
@ -42,6 +43,7 @@ import info.nightscout.workflow.PrepareTemporaryTargetDataWorker
import info.nightscout.workflow.PrepareTreatmentsDataWorker import info.nightscout.workflow.PrepareTreatmentsDataWorker
import info.nightscout.workflow.UpdateGraphWorker import info.nightscout.workflow.UpdateGraphWorker
import info.nightscout.workflow.UpdateIobCobSensWorker import info.nightscout.workflow.UpdateIobCobSensWorker
import info.nightscout.workflow.UpdateWidgetWorker
import info.nightscout.workflow.iob.IobCobOref1Worker import info.nightscout.workflow.iob.IobCobOref1Worker
import info.nightscout.workflow.iob.IobCobOrefWorker import info.nightscout.workflow.iob.IobCobOrefWorker
import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.disposables.CompositeDisposable
@ -156,7 +158,7 @@ class CalculationWorkflowImpl @Inject constructor(
) )
.then( .then(
OneTimeWorkRequest.Builder(UpdateGraphWorker::class.java) OneTimeWorkRequest.Builder(UpdateGraphWorker::class.java)
.setInputData(Data.Builder().putString(JOB, job).build()) .setInputData(Data.Builder().putString(JOB, job).putInt(PASS, CalculationWorkflow.ProgressData.DRAW_BG.pass).build())
.build() .build()
) )
.then( .then(
@ -176,7 +178,7 @@ class CalculationWorkflowImpl @Inject constructor(
) )
.then( .then(
OneTimeWorkRequest.Builder(UpdateGraphWorker::class.java) OneTimeWorkRequest.Builder(UpdateGraphWorker::class.java)
.setInputData(Data.Builder().putString(JOB, job).build()) .setInputData(Data.Builder().putString(JOB, job).putInt(PASS, CalculationWorkflow.ProgressData.DRAW_TT.pass).build())
.build() .build()
) )
.then( .then(
@ -196,8 +198,9 @@ class CalculationWorkflowImpl @Inject constructor(
.build() .build()
) )
.then( .then(
job == MAIN_CALCULATION,
OneTimeWorkRequest.Builder(UpdateGraphWorker::class.java) OneTimeWorkRequest.Builder(UpdateGraphWorker::class.java)
.setInputData(Data.Builder().putString(JOB, job).build()) .setInputData(Data.Builder().putString(JOB, job).putInt(PASS, CalculationWorkflow.ProgressData.DRAW_IOB.pass).build())
.build() .build()
) )
.then( .then(
@ -206,6 +209,10 @@ class CalculationWorkflowImpl @Inject constructor(
.setInputData(dataWorkerStorage.storeInputData(InvokeLoopWorker.InvokeLoopData(cause))) .setInputData(dataWorkerStorage.storeInputData(InvokeLoopWorker.InvokeLoopData(cause)))
.build() .build()
) )
.then(
job == MAIN_CALCULATION,
OneTimeWorkRequest.Builder(UpdateWidgetWorker::class.java).build()
)
.then( .then(
job == MAIN_CALCULATION, job == MAIN_CALCULATION,
OneTimeWorkRequest.Builder(PreparePredictionsWorker::class.java) OneTimeWorkRequest.Builder(PreparePredictionsWorker::class.java)
@ -213,17 +220,13 @@ class CalculationWorkflowImpl @Inject constructor(
.build() .build()
) )
.then( .then(
job == MAIN_CALCULATION,
OneTimeWorkRequest.Builder(UpdateGraphWorker::class.java) OneTimeWorkRequest.Builder(UpdateGraphWorker::class.java)
.setInputData(Data.Builder().putString(JOB, job).build()) .setInputData(Data.Builder().putString(JOB, job).putInt(PASS, CalculationWorkflow.ProgressData.DRAW_FINAL.pass).build())
.build() .build()
) )
.enqueue() .enqueue()
} }
fun WorkContinuation.then(shouldAdd: Boolean, work: OneTimeWorkRequest): WorkContinuation =
if (shouldAdd) then(work) else this
private fun runOnEventTherapyEventChange() { private fun runOnEventTherapyEventChange() {
WorkManager.getInstance(context) WorkManager.getInstance(context)
.beginUniqueWork( .beginUniqueWork(
@ -234,6 +237,7 @@ class CalculationWorkflowImpl @Inject constructor(
) )
.then( .then(
OneTimeWorkRequest.Builder(UpdateGraphWorker::class.java) OneTimeWorkRequest.Builder(UpdateGraphWorker::class.java)
.setInputData(Data.Builder().putInt(PASS, CalculationWorkflow.ProgressData.DRAW_FINAL.pass).build())
.build() .build()
) )
.enqueue() .enqueue()
@ -255,6 +259,7 @@ class CalculationWorkflowImpl @Inject constructor(
) )
.then( .then(
OneTimeWorkRequest.Builder(UpdateGraphWorker::class.java) OneTimeWorkRequest.Builder(UpdateGraphWorker::class.java)
.setInputData(Data.Builder().putInt(PASS, CalculationWorkflow.ProgressData.DRAW_FINAL.pass).build())
.build() .build()
) )
.enqueue() .enqueue()

View file

@ -1,14 +1,9 @@
package info.nightscout.androidaps.workflow package info.nightscout.androidaps.workflow
import info.nightscout.interfaces.workflow.WorkerClasses import info.nightscout.interfaces.workflow.WorkerClasses
import info.nightscout.plugins.general.food.FoodPlugin
import info.nightscout.plugins.profile.ProfilePlugin
import info.nightscout.source.NSClientSourcePlugin
import javax.inject.Inject import javax.inject.Inject
class WorkerClassesImpl @Inject constructor(): WorkerClasses{ class WorkerClassesImpl @Inject constructor() : WorkerClasses {
override val nsClientSourceWorker = NSClientSourcePlugin.NSClientSourceWorker::class.java //override val nsProfileWorker = ProfilePlugin.NSProfileWorker::class.java
override val nsProfileWorker = ProfilePlugin.NSProfileWorker::class.java
override val foodWorker = FoodPlugin.FoodWorker::class.java
} }

View file

@ -12,7 +12,7 @@
<string name="reloadprofile">Презареди профил</string> <string name="reloadprofile">Презареди профил</string>
<string name="correctionbous">Корекция</string> <string name="correctionbous">Корекция</string>
<string name="ns_upload_only">(ОПАСНО ЗА ДЕАКТИВИРАНЕ) Само качвай данни в NS</string> <string name="ns_upload_only">(ОПАСНО ЗА ДЕАКТИВИРАНЕ) Само качвай данни в NS</string>
<string name="ns_upload_only_summary">Само каване в NS (изключи синхронизиране). Може да спре данните за КЗ, освен ако не е избран локален източник като xDrip +. Не е ефективно за профила, освен ако не ползвате NS профил.\n!!! ВНИМАНИЕ !!! Деактивирането на тази опция може да причини проблеми и предозиране на инсулин, ако някой от Вашите компоненти (AAPS, NS, xDrip +) е неправилно конфигуриран. Внимателно гледайте, ако данните, показани от AAPS съответстват на състоянието на помпата!</string> <string name="ns_upload_only_summary">Само качване в NS (изключи синхронизиране). Може да спре данните за КЗ, освен ако не е избран локален източник като xDrip +. Не е ефективно за профила, освен ако не ползвате NS профил.\n!!! ВНИМАНИЕ !!! Деактивирането на тази опция може да причини проблеми и предозиране с инсулин, ако някой от Вашите компоненти (AAPS, NS, xDrip +) е неправилно конфигуриран. Внимателно гледайте, ако данните, показани от AAPS съответстват на състоянието на помпата!</string>
<string name="wear">Часовник</string> <string name="wear">Часовник</string>
<string name="nav_about">За приложението</string> <string name="nav_about">За приложението</string>
<string name="smscommunicator_missingphonestatepermission">Липсва разрешение до данни от телефона</string> <string name="smscommunicator_missingphonestatepermission">Липсва разрешение до данни от телефона</string>
@ -45,10 +45,16 @@
<string name="chartmenu">Меню на графиката</string> <string name="chartmenu">Меню на графиката</string>
<string name="authorizationfailed">Удостоверяването неуспешно</string> <string name="authorizationfailed">Удостоверяването неуспешно</string>
<string name="copytolocalprofile_invalid">Създаването на профила невъзможно. Профилът е невалиден.</string> <string name="copytolocalprofile_invalid">Създаването на профила невъзможно. Профилът е невалиден.</string>
<string name="cta_dont_kill_my_app_info">Не убивай приложението?</string>
<string name="fabric_upload_disabled">Качването на данни за проблеми е забранено!(Fabric)</string>
<string name="clear_filter">Премахни филтъра</string> <string name="clear_filter">Премахни филтъра</string>
<string name="cannula">Канюла</string> <string name="cannula">Канюла</string>
<string name="email_address">Електронна поща</string> <string name="email_address">Електронна поща</string>
<string name="remove_bg_readings">Премахване показанията нa КЗ</string>
<string name="identification_not_set">Идентификацията не е зададена в режим на разработчик</string>
<string name="a11y_dialog">диалог</string>
<!-- WEAR OS--> <!-- WEAR OS-->
<string name="wear_unknown_action_string">Неизвестна команда:</string>
<string name="remove_selected_items">Премахнете избраните елементи</string>
<string name="count_selected">%1$d избрано</string>
<string name="sort_label">Сортиране</string>
<string name="search">Търсене</string>
</resources> </resources>

View file

@ -43,8 +43,6 @@
<string name="chartmenu">Menú gràfica</string> <string name="chartmenu">Menú gràfica</string>
<string name="authorizationfailed">L\'autorització ha fallat</string> <string name="authorizationfailed">L\'autorització ha fallat</string>
<string name="copytolocalprofile_invalid">No s\'ha pogut crear el perfil local. Perfil no vàlid.</string> <string name="copytolocalprofile_invalid">No s\'ha pogut crear el perfil local. Perfil no vàlid.</string>
<string name="cta_dont_kill_my_app_info">No matar la meva app?</string>
<string name="fabric_upload_disabled">Enviament de logs d\'error desactivat!</string>
<string name="clear_filter">Netejar filtres</string> <string name="clear_filter">Netejar filtres</string>
<string name="cannula">Cànula</string> <string name="cannula">Cànula</string>
<string name="email_address">Correu electrònic</string> <string name="email_address">Correu electrònic</string>

View file

@ -45,8 +45,6 @@
<string name="chartmenu">Možnosti grafu</string> <string name="chartmenu">Možnosti grafu</string>
<string name="authorizationfailed">Autorizace selhala</string> <string name="authorizationfailed">Autorizace selhala</string>
<string name="copytolocalprofile_invalid">Nelze vytvořit profil. Profil je neplatný.</string> <string name="copytolocalprofile_invalid">Nelze vytvořit profil. Profil je neplatný.</string>
<string name="cta_dont_kill_my_app_info">Nezabíjet mou aplikaci?</string>
<string name="fabric_upload_disabled">Nahrávání protokolů o pádech zakázáno!</string>
<string name="clear_filter">Vymazat filtr</string> <string name="clear_filter">Vymazat filtr</string>
<string name="cannula">Kanyla</string> <string name="cannula">Kanyla</string>
<string name="email_address">E-mailová adresa</string> <string name="email_address">E-mailová adresa</string>

View file

@ -45,8 +45,6 @@
<string name="chartmenu">Diagrammenu</string> <string name="chartmenu">Diagrammenu</string>
<string name="authorizationfailed">Godkendelse mislykkedes</string> <string name="authorizationfailed">Godkendelse mislykkedes</string>
<string name="copytolocalprofile_invalid">Kunne ikke oprette profil. Profilen er ugyldig.</string> <string name="copytolocalprofile_invalid">Kunne ikke oprette profil. Profilen er ugyldig.</string>
<string name="cta_dont_kill_my_app_info">Luk ikke min app?</string>
<string name="fabric_upload_disabled">Upload af Crash logs deaktiveret!</string>
<string name="clear_filter">Nulstil filter</string> <string name="clear_filter">Nulstil filter</string>
<string name="cannula">Kanyle</string> <string name="cannula">Kanyle</string>
<string name="email_address">E-mail adresse</string> <string name="email_address">E-mail adresse</string>

View file

@ -45,8 +45,6 @@
<string name="chartmenu">Diagrammmenü</string> <string name="chartmenu">Diagrammmenü</string>
<string name="authorizationfailed">Autorisierung fehlgeschlagen</string> <string name="authorizationfailed">Autorisierung fehlgeschlagen</string>
<string name="copytolocalprofile_invalid">Profil kann nicht erstellt werden. Profil ist ungültig.</string> <string name="copytolocalprofile_invalid">Profil kann nicht erstellt werden. Profil ist ungültig.</string>
<string name="cta_dont_kill_my_app_info">Don\'t kill my app?</string>
<string name="fabric_upload_disabled">Hochladen von Crash-Protokollen deaktiviert!</string>
<string name="clear_filter">Filter löschen</string> <string name="clear_filter">Filter löschen</string>
<string name="cannula">Kanüle</string> <string name="cannula">Kanüle</string>
<string name="email_address">EMailAdresse</string> <string name="email_address">EMailAdresse</string>

View file

@ -45,8 +45,6 @@
<string name="chartmenu">Menú gráfico</string> <string name="chartmenu">Menú gráfico</string>
<string name="authorizationfailed">Ha fallado la autorización</string> <string name="authorizationfailed">Ha fallado la autorización</string>
<string name="copytolocalprofile_invalid">No se puede crear el perfil. El perfil es inválido.</string> <string name="copytolocalprofile_invalid">No se puede crear el perfil. El perfil es inválido.</string>
<string name="cta_dont_kill_my_app_info">¿No matar mi aplicación?</string>
<string name="fabric_upload_disabled">¡Carga de registros de errores desactivada!</string>
<string name="clear_filter">Borrar filtro</string> <string name="clear_filter">Borrar filtro</string>
<string name="cannula">Cánula</string> <string name="cannula">Cánula</string>
<string name="email_address">Dirección de Correo Electrónico</string> <string name="email_address">Dirección de Correo Electrónico</string>

View file

@ -45,8 +45,6 @@
<string name="chartmenu">Menu Graph</string> <string name="chartmenu">Menu Graph</string>
<string name="authorizationfailed">Echec de l\'authentification</string> <string name="authorizationfailed">Echec de l\'authentification</string>
<string name="copytolocalprofile_invalid">Impossible de créer le profil. Le profil est invalide.</string> <string name="copytolocalprofile_invalid">Impossible de créer le profil. Le profil est invalide.</string>
<string name="cta_dont_kill_my_app_info">Garder l\'appli en arrière plan ?</string>
<string name="fabric_upload_disabled">Téléchargement logs crashs désactivé!</string>
<string name="clear_filter">Effacer le filtre</string> <string name="clear_filter">Effacer le filtre</string>
<string name="cannula">Canule</string> <string name="cannula">Canule</string>
<string name="email_address">Adresse e-mail</string> <string name="email_address">Adresse e-mail</string>

View file

@ -45,8 +45,6 @@
<string name="chartmenu">Menu grafico</string> <string name="chartmenu">Menu grafico</string>
<string name="authorizationfailed">Autorizzazione fallita</string> <string name="authorizationfailed">Autorizzazione fallita</string>
<string name="copytolocalprofile_invalid">Impossibile creare il profilo. Il profilo non è valido.</string> <string name="copytolocalprofile_invalid">Impossibile creare il profilo. Il profilo non è valido.</string>
<string name="cta_dont_kill_my_app_info">Non terminare l\'app?</string>
<string name="fabric_upload_disabled">Caricamento log dei crash disabilitato!</string>
<string name="clear_filter">Cancella filtro</string> <string name="clear_filter">Cancella filtro</string>
<string name="cannula">Cannula</string> <string name="cannula">Cannula</string>
<string name="email_address">Indirizzo email</string> <string name="email_address">Indirizzo email</string>

View file

@ -45,8 +45,6 @@
<string name="chartmenu">תפריט תרשים</string> <string name="chartmenu">תפריט תרשים</string>
<string name="authorizationfailed">ההרשאה נכשלה</string> <string name="authorizationfailed">ההרשאה נכשלה</string>
<string name="copytolocalprofile_invalid">לא ניתן ליצור פרופיל מקומי. הפרופיל אינו חוקי.</string> <string name="copytolocalprofile_invalid">לא ניתן ליצור פרופיל מקומי. הפרופיל אינו חוקי.</string>
<string name="cta_dont_kill_my_app_info">איך לא להשבית את האפליקציה שלי?</string>
<string name="fabric_upload_disabled">העלאת רשומות קריסה מושבתת!</string>
<string name="clear_filter">נקה סינון</string> <string name="clear_filter">נקה סינון</string>
<string name="cannula">צינורית</string> <string name="cannula">צינורית</string>
<string name="email_address">כתובת דוא\"ל</string> <string name="email_address">כתובת דוא\"ל</string>

View file

@ -42,8 +42,6 @@
<string name="clearqueueconfirm">대기열을 삭제하시겠습니까? 대기열에 있는 모든 데이터가 삭제됩니다!</string> <string name="clearqueueconfirm">대기열을 삭제하시겠습니까? 대기열에 있는 모든 데이터가 삭제됩니다!</string>
<string name="chartmenu">차트 메뉴</string> <string name="chartmenu">차트 메뉴</string>
<string name="authorizationfailed">인증 실패</string> <string name="authorizationfailed">인증 실패</string>
<string name="cta_dont_kill_my_app_info">앱이 종료되지 않도록 합니다?</string>
<string name="fabric_upload_disabled">충돌 로그 업로드가 작동하지 않습니다.</string>
<string name="clear_filter">필터 지우기</string> <string name="clear_filter">필터 지우기</string>
<string name="cannula">캐뉼라</string> <string name="cannula">캐뉼라</string>
<string name="email_address">이메일 주소</string> <string name="email_address">이메일 주소</string>

View file

@ -21,7 +21,7 @@
<string name="ns_announcements">Sukurkite pranešimus iš NS perspėjimų</string> <string name="ns_announcements">Sukurkite pranešimus iš NS perspėjimų</string>
<string name="ns_alarm_stale_data_value_label">Seni duomenys, riba [min]</string> <string name="ns_alarm_stale_data_value_label">Seni duomenys, riba [min]</string>
<string name="ns_alarm_urgent_stale_data_value_label">Kritiškai seni duomenys, riba [min]</string> <string name="ns_alarm_urgent_stale_data_value_label">Kritiškai seni duomenys, riba [min]</string>
<string name="sensitivity_warning">Įjungę Autosens funkciją nepamirškite įvedinėti visus valgomus angliavandenius. To nedarant, angliavandenių sukeliami gliukos svyravimai bus klaidingai identifikuojami kaip jautrumo pasikeitimai!</string> <string name="sensitivity_warning">Įjungę Autosens funkciją nepamirškite įvedinėti visus valgomus angliavandenius. To nedarant, angliavandenių sukeliami glikemijos svyravimai bus klaidingai identifikuojami kaip jautrumo pasikeitimai!</string>
<string name="notloadedplugins">Ne visi profiliai įkelti!</string> <string name="notloadedplugins">Ne visi profiliai įkelti!</string>
<string name="valuesnotstored">Reikšmės neišsaugotos!</string> <string name="valuesnotstored">Reikšmės neišsaugotos!</string>
<string name="invalid">KLAIDA</string> <string name="invalid">KLAIDA</string>
@ -45,8 +45,6 @@
<string name="chartmenu">Grafiko meniu</string> <string name="chartmenu">Grafiko meniu</string>
<string name="authorizationfailed">Autorizacija nepavyko</string> <string name="authorizationfailed">Autorizacija nepavyko</string>
<string name="copytolocalprofile_invalid">Nepavyksta sukurti profilio. Profilis neteisingas.</string> <string name="copytolocalprofile_invalid">Nepavyksta sukurti profilio. Profilis neteisingas.</string>
<string name="cta_dont_kill_my_app_info">Don\'t kill my app?</string>
<string name="fabric_upload_disabled">Sutrikimų žurnalo įrašų įkėlimas išjungtas!</string>
<string name="clear_filter">Valyti filtrą</string> <string name="clear_filter">Valyti filtrą</string>
<string name="cannula">Kaniulė</string> <string name="cannula">Kaniulė</string>
<string name="email_address">El. pašto adresas</string> <string name="email_address">El. pašto adresas</string>

View file

@ -45,8 +45,6 @@
<string name="chartmenu">Grafiek menu</string> <string name="chartmenu">Grafiek menu</string>
<string name="authorizationfailed">Autorisatie mislukt</string> <string name="authorizationfailed">Autorisatie mislukt</string>
<string name="copytolocalprofile_invalid">Kan profiel niet aanmaken. Profiel is ongeldig.</string> <string name="copytolocalprofile_invalid">Kan profiel niet aanmaken. Profiel is ongeldig.</string>
<string name="cta_dont_kill_my_app_info">Don\'t kill my app?</string>
<string name="fabric_upload_disabled">Upload van crashrapporten is uitgeschakeld!</string>
<string name="clear_filter">Verwijder filter</string> <string name="clear_filter">Verwijder filter</string>
<string name="cannula">Canule</string> <string name="cannula">Canule</string>
<string name="email_address">E-mailadres</string> <string name="email_address">E-mailadres</string>

View file

@ -45,8 +45,6 @@
<string name="chartmenu">Diagram meny</string> <string name="chartmenu">Diagram meny</string>
<string name="authorizationfailed">Autentisering feilet</string> <string name="authorizationfailed">Autentisering feilet</string>
<string name="copytolocalprofile_invalid">Klarte ikke å opprette profil. Profilen er ikke gyldig.</string> <string name="copytolocalprofile_invalid">Klarte ikke å opprette profil. Profilen er ikke gyldig.</string>
<string name="cta_dont_kill_my_app_info">Avslutte app?</string>
<string name="fabric_upload_disabled">Opplast av krasj logger er deaktivert!</string>
<string name="clear_filter">Nullstill filtre</string> <string name="clear_filter">Nullstill filtre</string>
<string name="cannula">Kanyle</string> <string name="cannula">Kanyle</string>
<string name="email_address">E-postadresse</string> <string name="email_address">E-postadresse</string>

View file

@ -33,6 +33,8 @@
<string name="enable_carbs_req_alert">Alarm gdy wymagane jest podanie węglowodanów</string> <string name="enable_carbs_req_alert">Alarm gdy wymagane jest podanie węglowodanów</string>
<string name="open_navigation">Otwórz menu</string> <string name="open_navigation">Otwórz menu</string>
<string name="close_navigation">Zamknij menu</string> <string name="close_navigation">Zamknij menu</string>
<string name="remove_items">Usuń elementy</string>
<string name="sort_items">Sortuj elementy</string>
<string name="error_adding_treatment_title">Niekompletne dane leczenie</string> <string name="error_adding_treatment_title">Niekompletne dane leczenie</string>
<string name="error_adding_treatment_message">Leczenie (insulina: %1$.2f, węglowodany: %2$d, czas:%3$s) nie mogą być dodane. Sprawdź i dodaj ręcznie rekord w razie potrzeby.</string> <string name="error_adding_treatment_message">Leczenie (insulina: %1$.2f, węglowodany: %2$d, czas:%3$s) nie mogą być dodane. Sprawdź i dodaj ręcznie rekord w razie potrzeby.</string>
<string name="generated_ecarbs_note">eWęgle: %1$d g (%2$d h), Opóźnienie: %3$d m</string> <string name="generated_ecarbs_note">eWęgle: %1$d g (%2$d h), Opóźnienie: %3$d m</string>
@ -43,14 +45,16 @@
<string name="chartmenu">Menu wykresu</string> <string name="chartmenu">Menu wykresu</string>
<string name="authorizationfailed">Autoryzacja nie powiodła się</string> <string name="authorizationfailed">Autoryzacja nie powiodła się</string>
<string name="copytolocalprofile_invalid">Nie można utworzyć profilu. Profil jest nieprawidłowy.</string> <string name="copytolocalprofile_invalid">Nie można utworzyć profilu. Profil jest nieprawidłowy.</string>
<string name="cta_dont_kill_my_app_info">Nie zabij mojej aplikacji?</string>
<string name="fabric_upload_disabled">Przesyłanie dzienników awarii jest wyłączone!</string>
<string name="clear_filter">Wyczyść filtr</string> <string name="clear_filter">Wyczyść filtr</string>
<string name="cannula">Kaniula</string> <string name="cannula">Kaniula</string>
<string name="email_address">Adres e-mail</string> <string name="email_address">Adres e-mail</string>
<string name="remove_bg_readings">Usuń odczyty glikemii</string>
<string name="identification_not_set">Identyfikator nie jest ustawiony w trybie dev</string> <string name="identification_not_set">Identyfikator nie jest ustawiony w trybie dev</string>
<string name="a11y_dialog">dialog</string>
<!-- WEAR OS--> <!-- WEAR OS-->
<string name="wear_unknown_action_string">Nieznana akcja:</string>
<string name="remove_selected_items">Usuń wybrane pozycje</string> <string name="remove_selected_items">Usuń wybrane pozycje</string>
<string name="count_selected">Wybrany %1$d</string> <string name="count_selected">Wybrany %1$d</string>
<string name="sort_label">Sortuj</string> <string name="sort_label">Sortuj</string>
<string name="search">Szukaj</string>
</resources> </resources>

View file

@ -45,8 +45,6 @@
<string name="chartmenu">Menu do Gráfico</string> <string name="chartmenu">Menu do Gráfico</string>
<string name="authorizationfailed">Falha na autorização</string> <string name="authorizationfailed">Falha na autorização</string>
<string name="copytolocalprofile_invalid">Não foi possível criar o perfil. Perfil inválido.</string> <string name="copytolocalprofile_invalid">Não foi possível criar o perfil. Perfil inválido.</string>
<string name="cta_dont_kill_my_app_info">Não encerre meu aplicativo?</string>
<string name="fabric_upload_disabled">Envio de logs de erro desativado!</string>
<string name="clear_filter">Limpar filtro</string> <string name="clear_filter">Limpar filtro</string>
<string name="cannula">Cânula</string> <string name="cannula">Cânula</string>
<string name="email_address">Endereço de e-mail</string> <string name="email_address">Endereço de e-mail</string>

View file

@ -43,8 +43,6 @@
<string name="chartmenu">Menu do Gráfico</string> <string name="chartmenu">Menu do Gráfico</string>
<string name="authorizationfailed">Falha na autorização</string> <string name="authorizationfailed">Falha na autorização</string>
<string name="copytolocalprofile_invalid">Não é possível criar o perfil. O perfil é inválido.</string> <string name="copytolocalprofile_invalid">Não é possível criar o perfil. O perfil é inválido.</string>
<string name="cta_dont_kill_my_app_info">Não encerre minha app?</string>
<string name="fabric_upload_disabled">Envio de registos de erro desativado!</string>
<string name="clear_filter">Limpar filtros</string> <string name="clear_filter">Limpar filtros</string>
<string name="cannula">Cânula</string> <string name="cannula">Cânula</string>
<string name="email_address">Endereço de email</string> <string name="email_address">Endereço de email</string>

View file

@ -43,8 +43,6 @@
<string name="chartmenu">Meniu diagramă</string> <string name="chartmenu">Meniu diagramă</string>
<string name="authorizationfailed">Autorizarea a eșuat</string> <string name="authorizationfailed">Autorizarea a eșuat</string>
<string name="copytolocalprofile_invalid">Nu se poate crea profilul. Profilul este invalid.</string> <string name="copytolocalprofile_invalid">Nu se poate crea profilul. Profilul este invalid.</string>
<string name="cta_dont_kill_my_app_info">Nu-mi opri aplicația?</string>
<string name="fabric_upload_disabled">Încărcarea jurnalelor de erori este dezactivata!</string>
<string name="clear_filter">Șterge filtru</string> <string name="clear_filter">Șterge filtru</string>
<string name="cannula">Canula</string> <string name="cannula">Canula</string>
<string name="email_address">Adresă de e-mail</string> <string name="email_address">Adresă de e-mail</string>

View file

@ -45,8 +45,6 @@
<string name="chartmenu">Меню графика</string> <string name="chartmenu">Меню графика</string>
<string name="authorizationfailed">Ошибка авторизации</string> <string name="authorizationfailed">Ошибка авторизации</string>
<string name="copytolocalprofile_invalid">Не удается создать локальный профиль. Настройки профиля неправильны.</string> <string name="copytolocalprofile_invalid">Не удается создать локальный профиль. Настройки профиля неправильны.</string>
<string name="cta_dont_kill_my_app_info">Не закрывать приложение?</string>
<string name="fabric_upload_disabled">Загрузка журналов сбоя на сервер отключена!</string>
<string name="clear_filter">Очистить фильтр</string> <string name="clear_filter">Очистить фильтр</string>
<string name="cannula">Катетер помпы</string> <string name="cannula">Катетер помпы</string>
<string name="email_address">Адрес электронной почты</string> <string name="email_address">Адрес электронной почты</string>

View file

@ -45,8 +45,6 @@
<string name="chartmenu">Grafové menu</string> <string name="chartmenu">Grafové menu</string>
<string name="authorizationfailed">Autorizácia zlyhala</string> <string name="authorizationfailed">Autorizácia zlyhala</string>
<string name="copytolocalprofile_invalid">Nie je možné vytvoriť lokálny profil. Profil je neplatný.</string> <string name="copytolocalprofile_invalid">Nie je možné vytvoriť lokálny profil. Profil je neplatný.</string>
<string name="cta_dont_kill_my_app_info">Nepotláčať moju aplikáciu?</string>
<string name="fabric_upload_disabled">Odosielanie protokolov o zlyhaní je zakázané!</string>
<string name="clear_filter">Vyčistiť filter</string> <string name="clear_filter">Vyčistiť filter</string>
<string name="cannula">Kanyla</string> <string name="cannula">Kanyla</string>
<string name="email_address">Emailová adresa</string> <string name="email_address">Emailová adresa</string>

View file

@ -43,8 +43,6 @@
<string name="chartmenu">Diagrammeny</string> <string name="chartmenu">Diagrammeny</string>
<string name="authorizationfailed">Behörighetskontroll misslyckades</string> <string name="authorizationfailed">Behörighetskontroll misslyckades</string>
<string name="copytolocalprofile_invalid">Kan inte att skapa profilen. Profilen är felaktig.</string> <string name="copytolocalprofile_invalid">Kan inte att skapa profilen. Profilen är felaktig.</string>
<string name="cta_dont_kill_my_app_info">Döda inte min app?</string>
<string name="fabric_upload_disabled">Uppladdning av kraschloggar inaktiverad!</string>
<string name="clear_filter">Rensa filter</string> <string name="clear_filter">Rensa filter</string>
<string name="cannula">Kanyl</string> <string name="cannula">Kanyl</string>
<string name="email_address">E-postadress</string> <string name="email_address">E-postadress</string>

View file

@ -45,8 +45,6 @@
<string name="chartmenu">Grafik menüsü</string> <string name="chartmenu">Grafik menüsü</string>
<string name="authorizationfailed">Yetkilendirme başarısız oldu</string> <string name="authorizationfailed">Yetkilendirme başarısız oldu</string>
<string name="copytolocalprofile_invalid">Profil oluşturulamıyor. Profil geçersiz.</string> <string name="copytolocalprofile_invalid">Profil oluşturulamıyor. Profil geçersiz.</string>
<string name="cta_dont_kill_my_app_info">Uygulamamı devre dışı bırakma?</string>
<string name="fabric_upload_disabled">Çökme günlükleri yükleme devre dışı bırakıldı!</string>
<string name="clear_filter">Filtreyi temizle</string> <string name="clear_filter">Filtreyi temizle</string>
<string name="cannula">Kanül</string> <string name="cannula">Kanül</string>
<string name="email_address">E-posta adresi</string> <string name="email_address">E-posta adresi</string>

View file

@ -45,8 +45,6 @@
<string name="chartmenu">图表菜单</string> <string name="chartmenu">图表菜单</string>
<string name="authorizationfailed">授权失败</string> <string name="authorizationfailed">授权失败</string>
<string name="copytolocalprofile_invalid">无法创建配置文件。配置文件无效。</string> <string name="copytolocalprofile_invalid">无法创建配置文件。配置文件无效。</string>
<string name="cta_dont_kill_my_app_info">不要杀死我的应用程序?</string>
<string name="fabric_upload_disabled">已禁用崩溃日志上传!</string>
<string name="clear_filter">清除筛选</string> <string name="clear_filter">清除筛选</string>
<string name="cannula">输注导管</string> <string name="cannula">输注导管</string>
<string name="email_address">电子邮件地址</string> <string name="email_address">电子邮件地址</string>

View file

@ -78,8 +78,6 @@
<string name="chartmenu">Chart menu</string> <string name="chartmenu">Chart menu</string>
<string name="authorizationfailed">Authorization failed</string> <string name="authorizationfailed">Authorization failed</string>
<string name="copytolocalprofile_invalid">Unable to create profile. Profile is invalid.</string> <string name="copytolocalprofile_invalid">Unable to create profile. Profile is invalid.</string>
<string name="cta_dont_kill_my_app_info">Don\'t kill my app?</string>
<string name="fabric_upload_disabled">Crash logs upload disabled!</string>
<string name="clear_filter">Clear filter</string> <string name="clear_filter">Clear filter</string>
<string name="cannula">Cannula</string> <string name="cannula">Cannula</string>
<string name="email_address">Email address</string> <string name="email_address">Email address</string>

View file

@ -11,6 +11,7 @@ import info.nightscout.androidaps.insight.database.InsightDatabaseDao
import info.nightscout.androidaps.insight.database.InsightDbHelper import info.nightscout.androidaps.insight.database.InsightDbHelper
import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin
import info.nightscout.database.impl.AppRepository import info.nightscout.database.impl.AppRepository
import info.nightscout.interfaces.ApsMode
import info.nightscout.implementation.iob.GlucoseStatusProviderImpl import info.nightscout.implementation.iob.GlucoseStatusProviderImpl
import info.nightscout.interfaces.bgQualityCheck.BgQualityCheck import info.nightscout.interfaces.bgQualityCheck.BgQualityCheck
import info.nightscout.interfaces.constraints.Constraint import info.nightscout.interfaces.constraints.Constraint
@ -274,13 +275,13 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
// 2x Safety & Objectives // 2x Safety & Objectives
@Test @Test
fun isClosedLoopAllowedTest() { fun isClosedLoopAllowedTest() {
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, "open")).thenReturn("closed") `when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name)).thenReturn(ApsMode.CLOSED.name)
objectivesPlugin.objectives[Objectives.MAXIOB_ZERO_CL_OBJECTIVE].startedOn = 0 objectivesPlugin.objectives[Objectives.MAXIOB_ZERO_CL_OBJECTIVE].startedOn = 0
var c: Constraint<Boolean> = constraintChecker.isClosedLoopAllowed() var c: Constraint<Boolean> = constraintChecker.isClosedLoopAllowed()
aapsLogger.debug("Reason list: " + c.reasonList.toString()) aapsLogger.debug("Reason list: " + c.reasonList.toString())
// Assertions.assertTrue(c.reasonList[0].toString().contains("Closed loop is disabled")) // Safety & Objectives // Assertions.assertTrue(c.reasonList[0].toString().contains("Closed loop is disabled")) // Safety & Objectives
Assertions.assertEquals(false, c.value()) Assertions.assertEquals(false, c.value())
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, "open")).thenReturn("open") `when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name)).thenReturn(ApsMode.OPEN.name)
c = constraintChecker.isClosedLoopAllowed() c = constraintChecker.isClosedLoopAllowed()
Assertions.assertTrue(c.reasonList[0].contains("Closed loop mode disabled in preferences")) // Safety & Objectives Assertions.assertTrue(c.reasonList[0].contains("Closed loop mode disabled in preferences")) // Safety & Objectives
// Assertions.assertEquals(3, c.reasonList.size) // 2x Safety & Objectives // Assertions.assertEquals(3, c.reasonList.size) // 2x Safety & Objectives
@ -323,7 +324,7 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
openAPSSMBPlugin.setPluginEnabled(PluginType.APS, true) openAPSSMBPlugin.setPluginEnabled(PluginType.APS, true)
objectivesPlugin.objectives[Objectives.SMB_OBJECTIVE].startedOn = 0 objectivesPlugin.objectives[Objectives.SMB_OBJECTIVE].startedOn = 0
`when`(sp.getBoolean(info.nightscout.plugins.aps.R.string.key_use_smb, false)).thenReturn(false) `when`(sp.getBoolean(info.nightscout.plugins.aps.R.string.key_use_smb, false)).thenReturn(false)
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, "open")).thenReturn("open") `when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name)).thenReturn(ApsMode.OPEN.name)
// `when`(constraintChecker.isClosedLoopAllowed()).thenReturn(Constraint(true)) // `when`(constraintChecker.isClosedLoopAllowed()).thenReturn(Constraint(true))
val c = constraintChecker.isSMBModeEnabled() val c = constraintChecker.isSMBModeEnabled()
Assertions.assertEquals(true, c.reasonList.size == 3) // 2x Safety & Objectives Assertions.assertEquals(true, c.reasonList.size == 3) // 2x Safety & Objectives
@ -430,7 +431,7 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
@Test @Test
fun iobAMAShouldBeLimited() { fun iobAMAShouldBeLimited() {
// No limit by default // No limit by default
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, "open")).thenReturn("closed") `when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name)).thenReturn(ApsMode.CLOSED.name)
`when`(sp.getDouble(info.nightscout.plugins.aps.R.string.key_openapsma_max_iob, 1.5)).thenReturn(1.5) `when`(sp.getDouble(info.nightscout.plugins.aps.R.string.key_openapsma_max_iob, 1.5)).thenReturn(1.5)
`when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("teenage") `when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("teenage")
openAPSAMAPlugin.setPluginEnabled(PluginType.APS, true) openAPSAMAPlugin.setPluginEnabled(PluginType.APS, true)
@ -446,7 +447,7 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
@Test @Test
fun iobSMBShouldBeLimited() { fun iobSMBShouldBeLimited() {
// No limit by default // No limit by default
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, "open")).thenReturn("closed") `when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name)).thenReturn(ApsMode.CLOSED.name)
`when`(sp.getDouble(info.nightscout.plugins.aps.R.string.key_openapssmb_max_iob, 3.0)).thenReturn(3.0) `when`(sp.getDouble(info.nightscout.plugins.aps.R.string.key_openapssmb_max_iob, 3.0)).thenReturn(3.0)
`when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("teenage") `when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("teenage")
openAPSSMBPlugin.setPluginEnabled(PluginType.APS, true) openAPSSMBPlugin.setPluginEnabled(PluginType.APS, true)

View file

@ -7,6 +7,7 @@ import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.TestBase import info.nightscout.androidaps.TestBase
import info.nightscout.core.utils.fabric.FabricPrivacy import info.nightscout.core.utils.fabric.FabricPrivacy
import info.nightscout.database.impl.AppRepository import info.nightscout.database.impl.AppRepository
import info.nightscout.interfaces.ApsMode
import info.nightscout.interfaces.Config import info.nightscout.interfaces.Config
import info.nightscout.interfaces.configBuilder.RunningConfiguration import info.nightscout.interfaces.configBuilder.RunningConfiguration
import info.nightscout.interfaces.constraints.Constraints import info.nightscout.interfaces.constraints.Constraints
@ -70,7 +71,7 @@ class LoopPluginTest : TestBase() {
fun testPluginInterface() { fun testPluginInterface() {
`when`(rh.gs(info.nightscout.core.ui.R.string.loop)).thenReturn("Loop") `when`(rh.gs(info.nightscout.core.ui.R.string.loop)).thenReturn("Loop")
`when`(rh.gs(info.nightscout.plugins.aps.R.string.loop_shortname)).thenReturn("LOOP") `when`(rh.gs(info.nightscout.plugins.aps.R.string.loop_shortname)).thenReturn("LOOP")
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, "open")).thenReturn("closed") `when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name)).thenReturn(ApsMode.CLOSED.name)
val pumpDescription = PumpDescription() val pumpDescription = PumpDescription()
`when`(virtualPumpPlugin.pumpDescription).thenReturn(pumpDescription) `when`(virtualPumpPlugin.pumpDescription).thenReturn(pumpDescription)
Assert.assertEquals(LoopFragment::class.java.name, loopPlugin.pluginDescription.fragmentClass) Assert.assertEquals(LoopFragment::class.java.name, loopPlugin.pluginDescription.fragmentClass)

View file

@ -6,7 +6,9 @@ import info.nightscout.androidaps.TestBase
import info.nightscout.configuration.configBuilder.ConfigBuilderPlugin import info.nightscout.configuration.configBuilder.ConfigBuilderPlugin
import info.nightscout.interfaces.logging.UserEntryLogger import info.nightscout.interfaces.logging.UserEntryLogger
import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.protection.ProtectionCheck
import info.nightscout.interfaces.pump.PumpSync import info.nightscout.interfaces.pump.PumpSync
import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP
@ -21,6 +23,8 @@ class ConfigBuilderPluginTest : TestBase() {
@Mock lateinit var activePlugin: ActivePlugin @Mock lateinit var activePlugin: ActivePlugin
@Mock lateinit var uel: UserEntryLogger @Mock lateinit var uel: UserEntryLogger
@Mock lateinit var pumpSync: PumpSync @Mock lateinit var pumpSync: PumpSync
@Mock lateinit var protectionCheck: ProtectionCheck
@Mock lateinit var uiInteraction: UiInteraction
private lateinit var configBuilderPlugin: ConfigBuilderPlugin private lateinit var configBuilderPlugin: ConfigBuilderPlugin
@ -33,6 +37,6 @@ class ConfigBuilderPluginTest : TestBase() {
@BeforeEach @BeforeEach
fun prepareMock() { fun prepareMock() {
configBuilderPlugin = ConfigBuilderPlugin(injector, aapsLogger, rh, sp, RxBus(aapsSchedulers, aapsLogger), activePlugin, uel, pumpSync) configBuilderPlugin = ConfigBuilderPlugin(injector, aapsLogger, rh, sp, RxBus(aapsSchedulers, aapsLogger), activePlugin, uel, pumpSync, protectionCheck, uiInteraction)
} }
} }

View file

@ -5,6 +5,7 @@ import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.HardLimitsMock import info.nightscout.androidaps.HardLimitsMock
import info.nightscout.androidaps.TestBaseWithProfile import info.nightscout.androidaps.TestBaseWithProfile
import info.nightscout.database.impl.AppRepository import info.nightscout.database.impl.AppRepository
import info.nightscout.interfaces.ApsMode
import info.nightscout.interfaces.Constants import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.bgQualityCheck.BgQualityCheck import info.nightscout.interfaces.bgQualityCheck.BgQualityCheck
import info.nightscout.interfaces.constraints.Constraint import info.nightscout.interfaces.constraints.Constraint
@ -98,7 +99,7 @@ class SafetyPluginTest : TestBaseWithProfile() {
@Test @Test
fun disabledEngineeringModeShouldLimitClosedLoop() { fun disabledEngineeringModeShouldLimitClosedLoop() {
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, "open")).thenReturn("closed") `when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name)).thenReturn(ApsMode.CLOSED.name)
`when`(config.isEngineeringModeOrRelease()).thenReturn(false) `when`(config.isEngineeringModeOrRelease()).thenReturn(false)
var c = Constraint(true) var c = Constraint(true)
c = safetyPlugin.isClosedLoopAllowed(c) c = safetyPlugin.isClosedLoopAllowed(c)
@ -108,7 +109,7 @@ class SafetyPluginTest : TestBaseWithProfile() {
@Test @Test
fun setOpenLoopInPreferencesShouldLimitClosedLoop() { fun setOpenLoopInPreferencesShouldLimitClosedLoop() {
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, "open")).thenReturn("open") `when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name)).thenReturn(ApsMode.OPEN.name)
var c = Constraint(true) var c = Constraint(true)
c = safetyPlugin.isClosedLoopAllowed(c) c = safetyPlugin.isClosedLoopAllowed(c)
Assertions.assertTrue(c.getReasons(aapsLogger).contains("Closed loop mode disabled in preferences")) Assertions.assertTrue(c.getReasons(aapsLogger).contains("Closed loop mode disabled in preferences"))
@ -278,7 +279,7 @@ Safety: Limiting max basal rate to 500.00 U/h because of pump limit
openAPSSMBPlugin.setPluginEnabled(PluginType.APS, true) openAPSSMBPlugin.setPluginEnabled(PluginType.APS, true)
//`when`(openAPSSMBPlugin.isEnabled()).thenReturn(true) //`when`(openAPSSMBPlugin.isEnabled()).thenReturn(true)
//`when`(openAPSAMAPlugin.isEnabled()).thenReturn(false) //`when`(openAPSAMAPlugin.isEnabled()).thenReturn(false)
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, "open")).thenReturn("lgs") `when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name)).thenReturn(ApsMode.LGS.name)
`when`(sp.getDouble(info.nightscout.plugins.aps.R.string.key_openapsma_max_iob, 1.5)).thenReturn(1.5) `when`(sp.getDouble(info.nightscout.plugins.aps.R.string.key_openapsma_max_iob, 1.5)).thenReturn(1.5)
`when`(sp.getDouble(info.nightscout.plugins.aps.R.string.key_openapssmb_max_iob, 3.0)).thenReturn(3.0) `when`(sp.getDouble(info.nightscout.plugins.aps.R.string.key_openapssmb_max_iob, 3.0)).thenReturn(3.0)
`when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("teenage") `when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("teenage")

View file

@ -7,7 +7,6 @@ import info.nightscout.core.pump.toHtml
import info.nightscout.interfaces.pump.PumpEnactResult import info.nightscout.interfaces.pump.PumpEnactResult
import info.nightscout.plugins.aps.loop.extensions.json import info.nightscout.plugins.aps.loop.extensions.json
import info.nightscout.pump.virtual.extensions.toText import info.nightscout.pump.virtual.extensions.toText
import info.nightscout.plugins.sync.nsShared.extensions.log
import org.json.JSONObject import org.json.JSONObject
import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.BeforeEach
@ -109,15 +108,6 @@ class PumpEnactResultTest : TestBaseWithProfile() {
Assertions.assertEquals(true, per.queued) Assertions.assertEquals(true, per.queued)
} }
@Test fun logTest() {
val per = PumpEnactResult(injector)
Assertions.assertEquals(
"Success: false Enacted: false Comment: Duration: -1 Absolute: -1.0 Percent: -1 IsPercent: false IsTempCancel: false bolusDelivered: 0.0 Queued: false",
per.log()
)
}
@Test fun toStringTest() { @Test fun toStringTest() {
var per = PumpEnactResult(injector).enacted(true).bolusDelivered(10.0).comment("AAA") var per = PumpEnactResult(injector).enacted(true).bolusDelivered(10.0).comment("AAA")
Assertions.assertEquals( Assertions.assertEquals(

View file

@ -2,37 +2,37 @@
buildscript { buildscript {
ext { ext {
kotlin_version = '1.7.22' kotlin_version = '1.8.10'
core_version = '1.9.0' core_version = '1.9.0'
rxjava_version = '3.1.5' rxjava_version = '3.1.6'
rxandroid_version = '3.0.2' rxandroid_version = '3.0.2'
rxkotlin_version = '3.0.1' rxkotlin_version = '3.0.1'
room_version = '2.4.3' room_version = '2.5.0'
lifecycle_version = '2.5.1' lifecycle_version = '2.5.1'
dagger_version = '2.44.2' dagger_version = '2.45'
coroutines_version = '1.6.4' coroutines_version = '1.6.4'
activity_version = '1.6.1' activity_version = '1.6.1'
fragmentktx_version = '1.5.5' fragmentktx_version = '1.5.5'
ormLite_version = '4.46' ormLite_version = '4.46'
gson_version = '2.10' gson_version = '2.10.1'
nav_version = '2.5.3' nav_version = '2.5.3'
appcompat_version = '1.5.1' appcompat_version = '1.6.1'
material_version = '1.7.0' material_version = '1.8.0'
gridlayout_version = '1.0.0' gridlayout_version = '1.0.0'
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'
commonscodec_version = '1.15' commonscodec_version = '1.15'
jodatime_version = '2.10.14' jodatime_version = '2.10.14'
work_version = '2.7.1' work_version = '2.8.0'
tink_version = '1.7.0' tink_version = '1.8.0'
json_version = '20220320' json_version = '20220320'
serialization_version = '1.4.1' serialization_version = '1.4.1'
joda_version = '2.12.1.1' joda_version = '2.12.1.1'
swipe_version = '1.1.0' swipe_version = '1.1.0'
junit_version = '4.13.2' junit_version = '4.13.2'
junit_jupiter_version = '5.9.1' junit_jupiter_version = '5.9.2'
mockito_version = '4.6.1' mockito_version = '4.6.1'
dexmaker_version = '1.2' dexmaker_version = '1.2'
retrofit2_version = '2.9.0' retrofit2_version = '2.9.0'
@ -58,9 +58,9 @@ buildscript {
maven { url "https://plugins.gradle.org/m2/" } // jacoco 0.2 maven { url "https://plugins.gradle.org/m2/" } // jacoco 0.2
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:7.3.1' classpath 'com.android.tools.build:gradle:7.4.1'
classpath 'com.google.gms:google-services:4.3.14' classpath 'com.google.gms:google-services:4.3.14'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.2' classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.4'
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files
@ -76,8 +76,8 @@ buildscript {
plugins { plugins {
// Test Gradle build, keep disabled under normal circumstances // Test Gradle build, keep disabled under normal circumstances
// id "com.osacky.doctor" version "0.8.1" // id "com.osacky.doctor" version "0.8.1"
id "org.jlleitschuh.gradle.ktlint" version "11.0.0" id "org.jlleitschuh.gradle.ktlint" version "11.2.0"
id 'org.barfuin.gradle.jacocolog' version '2.0.0' id 'org.barfuin.gradle.jacocolog' version '3.1.0'
id 'org.jetbrains.kotlin.android' version "$kotlin_version" apply false id 'org.jetbrains.kotlin.android' version "$kotlin_version" apply false
} }

1
connectwsa.bat Normal file
View file

@ -0,0 +1 @@
adb connect 127.0.0.1:58526

View file

@ -16,16 +16,18 @@ import info.nightscout.core.graph.data.ScaledDataPoint
import info.nightscout.database.entities.GlucoseValue import info.nightscout.database.entities.GlucoseValue
import info.nightscout.database.entities.TemporaryTarget import info.nightscout.database.entities.TemporaryTarget
import info.nightscout.interfaces.aps.AutosensData import info.nightscout.interfaces.aps.AutosensData
import info.nightscout.interfaces.aps.AutosensDataStore
import info.nightscout.interfaces.iob.CobInfo import info.nightscout.interfaces.iob.CobInfo
import info.nightscout.interfaces.iob.InMemoryGlucoseValue
import info.nightscout.interfaces.iob.IobCobCalculator import info.nightscout.interfaces.iob.IobCobCalculator
import info.nightscout.interfaces.iob.IobTotal import info.nightscout.interfaces.iob.IobTotal
interface OverviewData { interface OverviewData {
var rangeToDisplay: Int // for graph var rangeToDisplay: Int // for graph
var toTime: Long var toTime: Long // current time rounded up to 1 hour
var fromTime: Long var fromTime: Long // toTime - range
var endTime: Long var endTime: Long // toTime + predictions
fun reset() fun reset()
fun initRange() fun initRange()
@ -45,12 +47,12 @@ interface OverviewData {
* BG * BG
*/ */
val lastBg: GlucoseValue? fun lastBg(autosensDataStore: AutosensDataStore): InMemoryGlucoseValue?
val isLow: Boolean fun isLow(autosensDataStore: AutosensDataStore): Boolean
val isHigh: Boolean fun isHigh(autosensDataStore: AutosensDataStore): Boolean
@ColorInt fun lastBgColor(context: Context?): Int @ColorInt fun lastBgColor(context: Context?, autosensDataStore: AutosensDataStore): Int
val lastBgDescription: String fun lastBgDescription(autosensDataStore: AutosensDataStore): String
val isActualBg: Boolean fun isActualBg(autosensDataStore: AutosensDataStore): Boolean
/* /*
* TEMPORARY BASAL * TEMPORARY BASAL
*/ */

View file

@ -1,6 +1,7 @@
package info.nightscout.core.graph.data package info.nightscout.core.graph.data
import android.content.Context import android.content.Context
import android.graphics.Paint
import info.nightscout.database.entities.Bolus import info.nightscout.database.entities.Bolus
import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.profile.DefaultValueHelper import info.nightscout.interfaces.profile.DefaultValueHelper
@ -22,7 +23,7 @@ class BolusDataPoint(
get() = DecimalFormatter.toPumpSupportedBolus(data.amount, activePlugin.activePump, rh) get() = DecimalFormatter.toPumpSupportedBolus(data.amount, activePlugin.activePump, rh)
override val duration = 0L override val duration = 0L
override val size = 2f override val size = 2f
override val paintStyle: Paint.Style = Paint.Style.FILL // not used
override val shape override val shape
get() = if (data.type == Bolus.Type.SMB) PointsWithLabelGraphSeries.Shape.SMB else PointsWithLabelGraphSeries.Shape.BOLUS get() = if (data.type == Bolus.Type.SMB) PointsWithLabelGraphSeries.Shape.SMB else PointsWithLabelGraphSeries.Shape.BOLUS

View file

@ -1,6 +1,7 @@
package info.nightscout.core.graph.data package info.nightscout.core.graph.data
import android.content.Context import android.content.Context
import android.graphics.Paint
import info.nightscout.core.graph.R import info.nightscout.core.graph.R
import info.nightscout.database.entities.Carbs import info.nightscout.database.entities.Carbs
import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.interfaces.ResourceHelper
@ -18,6 +19,7 @@ class CarbsDataPoint(
override val duration = 0L override val duration = 0L
override val size = 2f override val size = 2f
override val shape = PointsWithLabelGraphSeries.Shape.CARBS override val shape = PointsWithLabelGraphSeries.Shape.CARBS
override val paintStyle: Paint.Style = Paint.Style.FILL // not used
override fun color(context: Context?): Int { override fun color(context: Context?): Int {
return if (data.isValid) rh.gac(context, info.nightscout.core.ui.R.attr.cobColor) else rh.gac(context, info.nightscout.core.ui.R.attr.alarmColor) return if (data.isValid) rh.gac(context, info.nightscout.core.ui.R.attr.cobColor) else rh.gac(context, info.nightscout.core.ui.R.attr.alarmColor)

View file

@ -1,6 +1,8 @@
package info.nightscout.core.graph.data package info.nightscout.core.graph.data
import android.content.Context import android.content.Context
import android.graphics.Paint
import androidx.annotation.ColorInt
import com.jjoe64.graphview.series.DataPointInterface import com.jjoe64.graphview.series.DataPointInterface
interface DataPointWithLabelInterface : DataPointInterface { interface DataPointWithLabelInterface : DataPointInterface {
@ -13,5 +15,6 @@ interface DataPointWithLabelInterface : DataPointInterface {
val duration: Long val duration: Long
val shape: PointsWithLabelGraphSeries.Shape val shape: PointsWithLabelGraphSeries.Shape
val size: Float val size: Float
fun color(context: Context?): Int val paintStyle: Paint.Style
@ColorInt fun color(context: Context?): Int
} }

View file

@ -1,6 +1,7 @@
package info.nightscout.core.graph.data package info.nightscout.core.graph.data
import android.content.Context import android.content.Context
import android.graphics.Paint
import info.nightscout.database.entities.EffectiveProfileSwitch import info.nightscout.database.entities.EffectiveProfileSwitch
import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.utils.T import info.nightscout.shared.utils.T
@ -22,6 +23,7 @@ class EffectiveProfileSwitchDataPoint(
override val duration = 0L override val duration = 0L
override val shape = PointsWithLabelGraphSeries.Shape.PROFILE override val shape = PointsWithLabelGraphSeries.Shape.PROFILE
override val size = 2f override val size = 2f
override val paintStyle: Paint.Style = Paint.Style.FILL // not used
override fun color(context: Context?): Int { override fun color(context: Context?): Int {
return rh.gac(context, info.nightscout.core.ui.R.attr.profileSwitchColor) return rh.gac(context, info.nightscout.core.ui.R.attr.profileSwitchColor)
} }

View file

@ -1,6 +1,7 @@
package info.nightscout.core.graph.data package info.nightscout.core.graph.data
import android.content.Context import android.content.Context
import android.graphics.Paint
import info.nightscout.database.entities.ExtendedBolus import info.nightscout.database.entities.ExtendedBolus
import info.nightscout.interfaces.utils.DecimalFormatter import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.interfaces.ResourceHelper
@ -18,6 +19,7 @@ class ExtendedBolusDataPoint(
override val duration get() = data.duration override val duration get() = data.duration
override val size = 10f override val size = 10f
override val shape = PointsWithLabelGraphSeries.Shape.EXTENDEDBOLUS override val shape = PointsWithLabelGraphSeries.Shape.EXTENDEDBOLUS
override val paintStyle: Paint.Style = Paint.Style.FILL // not used
override fun color(context: Context?): Int { override fun color(context: Context?): Int {
return rh.gac(context, info.nightscout.core.ui.R.attr.extBolusColor) return rh.gac(context, info.nightscout.core.ui.R.attr.extBolusColor)
} }

View file

@ -1,22 +1,21 @@
package info.nightscout.core.graph.data package info.nightscout.core.graph.data
import android.content.Context import android.content.Context
import android.graphics.Paint
import info.nightscout.database.entities.GlucoseValue import info.nightscout.database.entities.GlucoseValue
import info.nightscout.interfaces.Constants import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.GlucoseUnit import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.profile.DefaultValueHelper
import info.nightscout.interfaces.profile.Profile import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.interfaces.ResourceHelper
class GlucoseValueDataPoint( class GlucoseValueDataPoint(
val data: GlucoseValue, val data: GlucoseValue,
private val defaultValueHelper: DefaultValueHelper,
private val profileFunction: ProfileFunction, private val profileFunction: ProfileFunction,
private val rh: ResourceHelper private val rh: ResourceHelper
) : DataPointWithLabelInterface { ) : DataPointWithLabelInterface {
fun valueToUnits(units: GlucoseUnit): Double = private fun valueToUnits(units: GlucoseUnit): Double =
if (units == GlucoseUnit.MGDL) data.value else data.value * Constants.MGDL_TO_MMOLL if (units == GlucoseUnit.MGDL) data.value else data.value * Constants.MGDL_TO_MMOLL
override fun getX(): Double = data.timestamp.toDouble() override fun getX(): Double = data.timestamp.toDouble()
@ -26,16 +25,13 @@ class GlucoseValueDataPoint(
override val label: String = Profile.toCurrentUnitsString(profileFunction, data.value) override val label: String = Profile.toCurrentUnitsString(profileFunction, data.value)
override val duration = 0L override val duration = 0L
override val shape get() = if (isPrediction) PointsWithLabelGraphSeries.Shape.PREDICTION else PointsWithLabelGraphSeries.Shape.BG override val shape get() = if (isPrediction) PointsWithLabelGraphSeries.Shape.PREDICTION else PointsWithLabelGraphSeries.Shape.BG
override val size = 1f override val size = if (isPrediction) 1f else 0.6f
override val paintStyle: Paint.Style = if (isPrediction) Paint.Style.FILL else Paint.Style.STROKE
override fun color(context: Context?): Int { override fun color(context: Context?): Int {
val units = profileFunction.getUnits()
val lowLine = defaultValueHelper.determineLowLine()
val highLine = defaultValueHelper.determineHighLine()
return when { return when {
isPrediction -> predictionColor(context) isPrediction -> predictionColor(context)
valueToUnits(units) < lowLine -> rh.gac(context, info.nightscout.core.ui.R.attr.bgLow) else -> rh.gac(context, info.nightscout.core.ui.R.attr.originalBgValueColor)
valueToUnits(units) > highLine -> rh.gac(context, info.nightscout.core.ui.R.attr.highColor)
else -> rh.gac(context, info.nightscout.core.ui.R.attr.bgInRange)
} }
} }

View file

@ -1,20 +1,25 @@
package info.nightscout.core.graph.data package info.nightscout.core.graph.data
import android.content.Context import android.content.Context
import android.graphics.Paint
import androidx.annotation.ColorInt
import androidx.core.graphics.ColorUtils
import info.nightscout.interfaces.Constants import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.GlucoseUnit import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.iob.InMemoryGlucoseValue import info.nightscout.interfaces.iob.InMemoryGlucoseValue
import info.nightscout.interfaces.profile.DefaultValueHelper
import info.nightscout.interfaces.profile.ProfileFunction import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.interfaces.ResourceHelper
class InMemoryGlucoseValueDataPoint( class InMemoryGlucoseValueDataPoint(
val data: InMemoryGlucoseValue, val data: InMemoryGlucoseValue,
private val defaultValueHelper: DefaultValueHelper,
private val profileFunction: ProfileFunction, private val profileFunction: ProfileFunction,
private val rh: ResourceHelper private val rh: ResourceHelper
) : DataPointWithLabelInterface { ) : DataPointWithLabelInterface {
fun valueToUnits(units: GlucoseUnit): Double = private fun valueToUnits(units: GlucoseUnit): Double =
if (units == GlucoseUnit.MGDL) data.value else data.value * Constants.MGDL_TO_MMOLL if (units == GlucoseUnit.MGDL) data.recalculated else data.recalculated * Constants.MGDL_TO_MMOLL
override fun getX(): Double = data.timestamp.toDouble() override fun getX(): Double = data.timestamp.toDouble()
override fun getY(): Double = valueToUnits(profileFunction.getUnits()) override fun getY(): Double = valueToUnits(profileFunction.getUnits())
@ -22,8 +27,20 @@ class InMemoryGlucoseValueDataPoint(
override val label: String = "" override val label: String = ""
override val duration = 0L override val duration = 0L
override val shape = PointsWithLabelGraphSeries.Shape.BUCKETED_BG override val shape = PointsWithLabelGraphSeries.Shape.BUCKETED_BG
override val size = 0.3f override val size = 1f
override val paintStyle: Paint.Style = Paint.Style.FILL
@ColorInt
override fun color(context: Context?): Int { override fun color(context: Context?): Int {
return rh.gac(context, info.nightscout.core.ui.R.attr.inMemoryColor) val units = profileFunction.getUnits()
val lowLine = defaultValueHelper.determineLowLine()
val highLine = defaultValueHelper.determineHighLine()
val color = when {
valueToUnits(units) < lowLine -> rh.gac(context, info.nightscout.core.ui.R.attr.bgLow)
valueToUnits(units) > highLine -> rh.gac(context, info.nightscout.core.ui.R.attr.highColor)
else -> rh.gac(context, info.nightscout.core.ui.R.attr.bgInRange)
}
return if (data.filledGap) ColorUtils.setAlphaComponent(color, 128) else color
} }
} }

View file

@ -179,20 +179,20 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
// draw data point // draw data point
if (!overdraw) { if (!overdraw) {
if (value.getShape() == Shape.BG || value.getShape() == Shape.COB_FAIL_OVER) { if (value.getShape() == Shape.BG || value.getShape() == Shape.COB_FAIL_OVER) {
mPaint.setStyle(Paint.Style.FILL); mPaint.setStyle(value.getPaintStyle());
mPaint.setStrokeWidth(0); mPaint.setStrokeWidth(0);
canvas.drawCircle(endX, endY, value.getSize() * scaledPxSize, mPaint); canvas.drawCircle(endX, endY, value.getSize() * scaledPxSize, mPaint);
} else if (value.getShape() == Shape.BG || value.getShape() == Shape.IOB_PREDICTION || value.getShape() == Shape.BUCKETED_BG) { } else if (value.getShape() == Shape.BG || value.getShape() == Shape.IOB_PREDICTION || value.getShape() == Shape.BUCKETED_BG) {
mPaint.setColor(value.color(graphView.getContext())); mPaint.setColor(value.color(graphView.getContext()));
mPaint.setStyle(Paint.Style.FILL); mPaint.setStyle(value.getPaintStyle());
mPaint.setStrokeWidth(0); mPaint.setStrokeWidth(0);
canvas.drawCircle(endX, endY, value.getSize() * scaledPxSize, mPaint); canvas.drawCircle(endX, endY, value.getSize() * scaledPxSize, mPaint);
} else if (value.getShape() == Shape.PREDICTION) { } else if (value.getShape() == Shape.PREDICTION) {
mPaint.setColor(value.color(graphView.getContext())); mPaint.setColor(value.color(graphView.getContext()));
mPaint.setStyle(Paint.Style.FILL); mPaint.setStyle(value.getPaintStyle());
mPaint.setStrokeWidth(0); mPaint.setStrokeWidth(0);
canvas.drawCircle(endX, endY, scaledPxSize, mPaint); canvas.drawCircle(endX, endY, scaledPxSize, mPaint);
mPaint.setStyle(Paint.Style.FILL); mPaint.setStyle(value.getPaintStyle());
mPaint.setStrokeWidth(0); mPaint.setStrokeWidth(0);
canvas.drawCircle(endX, endY, scaledPxSize / 3, mPaint); canvas.drawCircle(endX, endY, scaledPxSize / 3, mPaint);
} else if (value.getShape() == Shape.RECTANGLE) { } else if (value.getShape() == Shape.RECTANGLE) {

View file

@ -1,6 +1,7 @@
package info.nightscout.core.graph.data package info.nightscout.core.graph.data
import android.content.Context import android.content.Context
import android.graphics.Paint
import info.nightscout.database.entities.TherapyEvent import info.nightscout.database.entities.TherapyEvent
import info.nightscout.interfaces.Constants import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.Translator import info.nightscout.interfaces.Translator
@ -55,6 +56,7 @@ class TherapyEventDataPoint(
duration > 0 -> PointsWithLabelGraphSeries.Shape.GENERAL_WITH_DURATION duration > 0 -> PointsWithLabelGraphSeries.Shape.GENERAL_WITH_DURATION
else -> PointsWithLabelGraphSeries.Shape.GENERAL else -> PointsWithLabelGraphSeries.Shape.GENERAL
} }
override val paintStyle: Paint.Style = Paint.Style.FILL // not used
override val size get() = if (rh.gb(info.nightscout.shared.R.bool.isTablet)) 12.0f else 10.0f override val size get() = if (rh.gb(info.nightscout.shared.R.bool.isTablet)) 12.0f else 10.0f
override fun color(context: Context?): Int { override fun color(context: Context?): Int {

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="format_carbs">%1$dg</string> <string name="format_carbs">%1$d g</string>
</resources> </resources>

View file

@ -0,0 +1,48 @@
package info.nightscout.core.graph.data
import android.content.Context
import android.graphics.Color
import info.nightscout.database.entities.GlucoseValue
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.iob.InMemoryGlucoseValue
import info.nightscout.interfaces.profile.DefaultValueHelper
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.shared.interfaces.ResourceHelper
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.junit.jupiter.MockitoExtension
import org.mockito.junit.jupiter.MockitoSettings
import org.mockito.kotlin.any
import org.mockito.quality.Strictness
@ExtendWith(MockitoExtension::class)
@MockitoSettings(strictness = Strictness.LENIENT)
internal class InMemoryGlucoseValueDataPointTest {
@Mock lateinit var defaultValueHelper: DefaultValueHelper
@Mock lateinit var profileFunction: ProfileFunction
@Mock lateinit var rh: ResourceHelper
@Mock lateinit var context: Context
@BeforeEach
fun setup() {
Mockito.`when`(profileFunction.getUnits()).thenReturn(GlucoseUnit.MGDL)
Mockito.`when`(rh.gac(any(), any())).thenReturn(Color.GREEN)
}
@Test
fun alphaShouldBeAddedForFilledGaps() {
val gv = InMemoryGlucoseValue(1000, 100.0, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN)
val sut = InMemoryGlucoseValueDataPoint(gv, defaultValueHelper, profileFunction, rh)
var alpha = sut.color(context).ushr(24)
Assertions.assertEquals(255, alpha)
gv.filledGap = true
alpha = sut.color(context).ushr(24)
Assertions.assertEquals(128, alpha)
}
}

View file

@ -1,4 +1,4 @@
<?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">
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
</manifest> </manifest>

View file

@ -0,0 +1,13 @@
package info.nightscout.interfaces
enum class ApsMode() {
OPEN,
CLOSED,
LGS,
UNDEFINED;
companion object {
fun fromString(stringValue: String?) = values().firstOrNull { it.name == stringValue?.uppercase() } ?: UNDEFINED
}
}

View file

@ -2,7 +2,7 @@ package info.nightscout.interfaces
@Suppress("PropertyName") @Suppress("PropertyName")
interface Config { interface Config {
val SUPPORTEDNSVERSION: Int val SUPPORTED_NS_VERSION: Int
val APS: Boolean val APS: Boolean
val NSCLIENT: Boolean val NSCLIENT: Boolean
val PUMPCONTROL: Boolean val PUMPCONTROL: Boolean

View file

@ -1,16 +1,59 @@
package info.nightscout.interfaces package info.nightscout.interfaces
import android.widget.LinearLayout
import androidx.annotation.StringRes
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import info.nightscout.interfaces.plugin.PluginBase import info.nightscout.interfaces.plugin.PluginBase
import info.nightscout.interfaces.plugin.PluginType import info.nightscout.interfaces.plugin.PluginType
interface ConfigBuilder { interface ConfigBuilder {
/**
* Called during start of app to load configuration and start enabled plugins
*/
fun initialize() fun initialize()
/**
* Store current configuration to SharedPreferences
*/
fun storeSettings(from: String) fun storeSettings(from: String)
/**
* Enable another plugin and fragment and disable currently enabled if they are mutually exclusive
*/
fun performPluginSwitch(changedPlugin: PluginBase, enabled: Boolean, type: PluginType) fun performPluginSwitch(changedPlugin: PluginBase, enabled: Boolean, type: PluginType)
/** /**
* Make sure plugins configuration is valid after enabling/disabling plugin * Make sure plugins configuration is valid after enabling/disabling plugin
*/ */
fun processOnEnabledCategoryChanged(changedPlugin: PluginBase, type: PluginType) fun processOnEnabledCategoryChanged(changedPlugin: PluginBase, type: PluginType)
/**
* Fill LinearLayout with list of available plugins and checkboxes for enabling/disabling
*
* @param title Paragraph title or null if provided elsewhere
* @param description comment
* @param pluginType plugin category for example SYNC
* @param plugins list of plugins
* @param pluginViewHolders links to created UI elements (for calling `update` if configuration is changed)
* @param fragment
* @param activity either fragment or activity must be non null
* @param parent UI container to add views
*/
fun createViewsForPlugins(
@StringRes title: Int?,
@StringRes description: Int,
pluginType: PluginType,
plugins: List<PluginBase>,
pluginViewHolders: ArrayList<PluginViewHolderInterface>,
fragment: Fragment? = null,
activity: FragmentActivity? = null,
parent: LinearLayout
)
interface PluginViewHolderInterface {
fun update()
}
} }

View file

@ -1,14 +1,30 @@
package info.nightscout.interfaces package info.nightscout.interfaces
import info.nightscout.database.entities.GlucoseValue import info.nightscout.interfaces.sync.DataSyncSelector
import org.json.JSONArray
import org.json.JSONObject
/**
* Send data to xDrip+ via Inter-app settings
*/
interface XDripBroadcast { interface XDripBroadcast {
/**
* Send calibration to xDrip+
* Accepting must be enabled in Inter-app settings - Accept Calibrations
*/
fun sendCalibration(bg: Double): Boolean fun sendCalibration(bg: Double): Boolean
fun send(glucoseValue: GlucoseValue)
fun sendProfile(profileStoreJson: JSONObject) /**
fun sendTreatments(addedOrUpdatedTreatments: JSONArray) * Send data to xDrip+
fun sendSgvs(sgvs: JSONArray) *
* Accepting must be enabled in Inter-app settings - Accept Glucose/Treatments
*/
fun sendToXdrip(collection: String, dataPair: DataSyncSelector.DataPair, progress: String)
/**
* Send data to xDrip+
*
* Accepting must be enabled in Inter-app settings - Accept Glucose/Treatments
*/
fun sendToXdrip(collection: String, dataPairs: List<DataSyncSelector.DataPair>, progress:
String)
} }

View file

@ -15,8 +15,18 @@ interface AutosensDataStore {
var bucketedData: MutableList<InMemoryGlucoseValue>? var bucketedData: MutableList<InMemoryGlucoseValue>?
var lastUsed5minCalculation: Boolean? var lastUsed5minCalculation: Boolean?
fun lastBg(): GlucoseValue? /**
fun actualBg(): GlucoseValue? * Return last valid (>39) InMemoryGlucoseValue from bucketed data or null if db is empty
*
* @return InMemoryGlucoseValue or null
*/
fun lastBg(): InMemoryGlucoseValue?
/**
* Provide last bucketed InMemoryGlucoseValue or null if none exists within the last 9 minutes
*
* @return InMemoryGlucoseValue or null
*/
fun actualBg(): InMemoryGlucoseValue?
fun lastDataTime(dateUtil: DateUtil): String fun lastDataTime(dateUtil: DateUtil): String
fun clone(): AutosensDataStore fun clone(): AutosensDataStore
fun getBgReadingsDataTableCopy(): List<GlucoseValue> fun getBgReadingsDataTableCopy(): List<GlucoseValue>

View file

@ -1,6 +1,6 @@
package info.nightscout.interfaces.configBuilder package info.nightscout.interfaces.configBuilder
import info.nightscout.sdk.remotemodel.RemoteDeviceStatus import info.nightscout.sdk.localmodel.devicestatus.NSDeviceStatus
import org.json.JSONObject import org.json.JSONObject
interface RunningConfiguration { interface RunningConfiguration {
@ -9,5 +9,5 @@ interface RunningConfiguration {
fun configuration(): JSONObject fun configuration(): JSONObject
// called in NSClient mode only // called in NSClient mode only
fun apply(configuration: RemoteDeviceStatus.Configuration) fun apply(configuration: NSDeviceStatus.Configuration)
} }

View file

@ -2,8 +2,39 @@ package info.nightscout.interfaces.iob
import info.nightscout.database.entities.GlucoseValue import info.nightscout.database.entities.GlucoseValue
class InMemoryGlucoseValue constructor(var timestamp: Long = 0L, var value: Double = 0.0, var interpolated: Boolean = false) { /**
* Simplified [GlucoseValue] for storing in memory and calculations
* It may correspond to GlucoseValue value in db
* but because of 5 min recalculations and smoothing it may not
*/
class InMemoryGlucoseValue constructor(
var timestamp: Long = 0L,
/**
* Value in mg/dl
*/
var value: Double = 0.0,
var trendArrow: GlucoseValue.TrendArrow = GlucoseValue.TrendArrow.NONE,
/**
* Smoothed value. Value is added by smoothing plugin
* or null if smoothing was not done
*/
var smoothed: Double? = null,
/**
* if true value is not corresponding to received value,
* but it was recalculated to fill gap between BGs
*/
var filledGap: Boolean = false,
/**
* Taken from GlucoseValue
*/
var sourceSensor: GlucoseValue.SourceSensor
) {
constructor(gv: GlucoseValue) : this(gv.timestamp, gv.value) constructor(gv: GlucoseValue) : this(timestamp = gv.timestamp, value = gv.value, trendArrow = gv.trendArrow, sourceSensor = gv.sourceSensor)
// var generated : value doesn't correspond to real value with timestamp close to real BG
/**
* Provide smoothed value if available,
* non smoothed value as a fallback
*/
val recalculated: Double get() = smoothed ?: value
} }

View file

@ -32,11 +32,10 @@ interface IobCobCalculator {
/** /**
* Calculate CobInfo to now() * Calculate CobInfo to now()
* *
* @param waitForCalculationFinish access autosens data synchronized (wait for result if calculation is running)
* @param reason caller identification * @param reason caller identification
* @return CobInfo * @return CobInfo
*/ */
fun getCobInfo(waitForCalculationFinish: Boolean, reason: String): CobInfo fun getCobInfo(reason: String): CobInfo
/** /**
* Calculate IobTotal from boluses and extended boluses to now(). * Calculate IobTotal from boluses and extended boluses to now().

View file

@ -48,6 +48,7 @@ interface ProcessedDeviceStatusData {
var clock = 0L var clock = 0L
var battery = 0 var battery = 0
var isCharging: Boolean? = null
} }
val uploaderMap: HashMap<String, Uploader> val uploaderMap: HashMap<String, Uploader>

View file

@ -27,11 +27,11 @@ interface StoreDataForDb {
val temporaryBasals: MutableList<TemporaryBasal> val temporaryBasals: MutableList<TemporaryBasal>
val profileSwitches: MutableList<ProfileSwitch> val profileSwitches: MutableList<ProfileSwitch>
val offlineEvents: MutableList<OfflineEvent> val offlineEvents: MutableList<OfflineEvent>
val foods: MutableList<Food>
val nsIdGlucoseValues: MutableList<GlucoseValue> val nsIdGlucoseValues: MutableList<GlucoseValue>
val nsIdBoluses: MutableList<Bolus> val nsIdBoluses: MutableList<Bolus>
val nsIdCarbs: MutableList<Carbs> val nsIdCarbs: MutableList<Carbs>
val nsIdFoods: MutableList<Food>
val nsIdTemporaryTargets: MutableList<TemporaryTarget> val nsIdTemporaryTargets: MutableList<TemporaryTarget>
val nsIdEffectiveProfileSwitches: MutableList<EffectiveProfileSwitch> val nsIdEffectiveProfileSwitches: MutableList<EffectiveProfileSwitch>
val nsIdBolusCalculatorResults: MutableList<BolusCalculatorResult> val nsIdBolusCalculatorResults: MutableList<BolusCalculatorResult>
@ -41,8 +41,11 @@ interface StoreDataForDb {
val nsIdProfileSwitches: MutableList<ProfileSwitch> val nsIdProfileSwitches: MutableList<ProfileSwitch>
val nsIdOfflineEvents: MutableList<OfflineEvent> val nsIdOfflineEvents: MutableList<OfflineEvent>
val nsIdDeviceStatuses: MutableList<DeviceStatus> val nsIdDeviceStatuses: MutableList<DeviceStatus>
val nsIdFoods: MutableList<Food>
fun storeTreatmentsToDb() fun storeTreatmentsToDb()
fun storeGlucoseValuesToDb() fun storeGlucoseValuesToDb()
fun storeFoodsToDb()
fun scheduleNsIdUpdate() fun scheduleNsIdUpdate()
fun updateNsIds()
} }

View file

@ -9,6 +9,7 @@ import info.nightscout.interfaces.insulin.Insulin
import info.nightscout.interfaces.iob.IobCobCalculator import info.nightscout.interfaces.iob.IobCobCalculator
import info.nightscout.interfaces.profile.ProfileSource import info.nightscout.interfaces.profile.ProfileSource
import info.nightscout.interfaces.pump.Pump import info.nightscout.interfaces.pump.Pump
import info.nightscout.interfaces.smoothing.Smoothing
import info.nightscout.interfaces.source.BgSource import info.nightscout.interfaces.source.BgSource
import info.nightscout.interfaces.sync.NsClient import info.nightscout.interfaces.sync.NsClient
import info.nightscout.interfaces.sync.Sync import info.nightscout.interfaces.sync.Sync
@ -74,6 +75,11 @@ interface ActivePlugin {
*/ */
val activeObjectives: Objectives? val activeObjectives: Objectives?
/**
* Smoothing plugin
*/
val activeSmoothing: Smoothing
/** /**
* Currently selected NsClient plugin * Currently selected NsClient plugin
*/ */

View file

@ -6,5 +6,5 @@ package info.nightscout.interfaces.plugin
* set by [info.nightscout.interfaces.PluginDescription.mainType] * set by [info.nightscout.interfaces.PluginDescription.mainType]
*/ */
enum class PluginType { enum class PluginType {
GENERAL, SENSITIVITY, PROFILE, APS, PUMP, CONSTRAINTS, LOOP, BGSOURCE, INSULIN, SYNC GENERAL, SENSITIVITY, PROFILE, APS, PUMP, CONSTRAINTS, LOOP, BGSOURCE, INSULIN, SYNC, SMOOTHING
} }

View file

@ -1,34 +1,31 @@
package info.nightscout.interfaces.profile package info.nightscout.interfaces.profile
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import info.nightscout.interfaces.Constants
import org.json.JSONArray import org.json.JSONArray
interface ProfileSource { interface ProfileSource {
class SingleProfile { class SingleProfile(
var name: String,
var name: String? = null var mgdl: Boolean,
var mgdl: Boolean = false var dia: Double,
var dia: Double = Constants.defaultDIA var ic: JSONArray,
var ic: JSONArray? = null var isf: JSONArray,
var isf: JSONArray? = null var basal: JSONArray,
var basal: JSONArray? = null var targetLow: JSONArray,
var targetLow: JSONArray? = null var targetHigh: JSONArray,
var targetHigh: JSONArray? = null ) {
fun deepClone(): SingleProfile =
fun deepClone(): SingleProfile { SingleProfile(
val sp = SingleProfile() name = name,
sp.name = name mgdl = mgdl,
sp.mgdl = mgdl dia = dia,
sp.dia = dia ic = JSONArray(ic.toString()),
sp.ic = JSONArray(ic.toString()) isf = JSONArray(isf.toString()),
sp.isf = JSONArray(isf.toString()) basal = JSONArray(basal.toString()),
sp.basal = JSONArray(basal.toString()) targetLow = JSONArray(targetLow.toString()),
sp.targetLow = JSONArray(targetLow.toString()) targetHigh = JSONArray(targetHigh.toString())
sp.targetHigh = JSONArray(targetHigh.toString()) )
return sp
}
} }
val profile: ProfileStore? val profile: ProfileStore?
@ -38,6 +35,7 @@ interface ProfileSource {
var currentProfileIndex: Int var currentProfileIndex: Int
fun currentProfile(): SingleProfile? fun currentProfile(): SingleProfile?
fun storeSettings(activity: FragmentActivity? = null) fun storeSettings(activity: FragmentActivity? = null, emptyCreated: Boolean = false)
fun loadFromStore(store: ProfileStore)
} }

View file

@ -8,8 +8,14 @@ interface Intents {
// AAPS -> Xdrip // AAPS -> Xdrip
const val ACTION_NEW_TREATMENT = "info.nightscout.client.NEW_TREATMENT" const val ACTION_NEW_TREATMENT = "info.nightscout.client.NEW_TREATMENT"
const val ACTION_NEW_PROFILE = "info.nightscout.client.NEW_PROFILE" const val ACTION_NEW_PROFILE = "info.nightscout.client.NEW_PROFILE"
const val ACTION_NEW_DEVICE_STATUS = "info.nightscout.client.NEW_DEVICESTATUS"
const val ACTION_NEW_FOOD = "info.nightscout.client.NEW_FOOD"
const val ACTION_NEW_SGV = "info.nightscout.client.NEW_SGV" const val ACTION_NEW_SGV = "info.nightscout.client.NEW_SGV"
const val EXTRA_STATUSLINE = "com.eveningoutpost.dexdrip.Extras.Statusline"
const val ACTION_NEW_EXTERNAL_STATUSLINE = "com.eveningoutpost.dexdrip.ExternalStatusline"
const val RECEIVER_PERMISSION = "com.eveningoutpost.dexdrip.permissions.RECEIVE_EXTERNAL_STATUSLINE"
// AAPS -> xDrip 640G mode // AAPS -> xDrip 640G mode
const val XDRIP_PLUS_NS_EMULATOR = "com.eveningoutpost.dexdrip.NS_EMULATOR" const val XDRIP_PLUS_NS_EMULATOR = "com.eveningoutpost.dexdrip.NS_EMULATOR"
@ -27,6 +33,7 @@ interface Intents {
const val ACTION_REMOTE_CALIBRATION = "com.eveningoutpost.dexdrip.NewCalibration" const val ACTION_REMOTE_CALIBRATION = "com.eveningoutpost.dexdrip.NewCalibration"
const val GLIMP_BG = "it.ct.glicemia.ACTION_GLUCOSE_MEASURED" const val GLIMP_BG = "it.ct.glicemia.ACTION_GLUCOSE_MEASURED"
const val DEXCOM_BG = "com.dexcom.cgm.EXTERNAL_BROADCAST" const val DEXCOM_BG = "com.dexcom.cgm.EXTERNAL_BROADCAST"
const val DEXCOM_G7_BG = "com.dexcom.g7.EXTERNAL_BROADCAST"
const val EVERSENSE_BG = "com.senseonics.AndroidAPSEventSubscriber.BROADCAST" const val EVERSENSE_BG = "com.senseonics.AndroidAPSEventSubscriber.BROADCAST"
const val POCTECH_BG = "com.china.poctech.data" const val POCTECH_BG = "com.china.poctech.data"
const val TOMATO_BG = "com.fanqies.tomatofn.BgEstimate" const val TOMATO_BG = "com.fanqies.tomatofn.BgEstimate"

View file

@ -0,0 +1,16 @@
package info.nightscout.interfaces.smoothing
import info.nightscout.interfaces.iob.InMemoryGlucoseValue
interface Smoothing {
/**
* Smooth values in List
*
* @param data input glucose values ([0] to be the most recent one)
* @param updateWindow amount of values to the past to smooth
*
* @return new List with smoothed values (smoothed values are stored in [InMemoryGlucoseValue.smoothed])
*/
fun smooth(data: MutableList<InMemoryGlucoseValue>): MutableList<InMemoryGlucoseValue>
}

View file

@ -3,5 +3,6 @@ package info.nightscout.interfaces.source
import info.nightscout.database.entities.GlucoseValue import info.nightscout.database.entities.GlucoseValue
interface NSClientSource { interface NSClientSource {
fun isEnabled(): Boolean
fun detectSource(glucoseValue: GlucoseValue) fun detectSource(glucoseValue: GlucoseValue)
} }

View file

@ -7,10 +7,10 @@ import info.nightscout.database.entities.TotalDailyDose
interface TddCalculator { interface TddCalculator {
fun calculate(days: Long): LongSparseArray<TotalDailyDose> fun calculate(days: Long, allowMissingDays: Boolean): LongSparseArray<TotalDailyDose>?
fun calculateToday(): TotalDailyDose fun calculateToday(): TotalDailyDose?
fun calculateDaily(startHours: Long, endHours: Long): TotalDailyDose fun calculateDaily(startHours: Long, endHours: Long): TotalDailyDose?
fun calculate(startTime: Long, endTime: Long): TotalDailyDose fun calculate(startTime: Long, endTime: Long, allowMissingData: Boolean): TotalDailyDose?
fun averageTDD(tdds: LongSparseArray<TotalDailyDose>): TotalDailyDose? fun averageTDD(tdds: LongSparseArray<TotalDailyDose>?): TotalDailyDose?
fun stats(context: Context): TableLayout fun stats(context: Context): TableLayout
} }

View file

@ -17,70 +17,30 @@ import org.json.JSONObject
interface DataSyncSelector { interface DataSyncSelector {
interface DataPair { interface DataPair {
val value: Any val value: Any
val id: Long val id: Long
} }
data class PairTemporaryTarget(override val value: TemporaryTarget, override val id: Long): DataPair
data class PairGlucoseValue(override val value: GlucoseValue, override val id: Long): DataPair data class PairTemporaryTarget(override val value: TemporaryTarget, override val id: Long) : DataPair
data class PairTherapyEvent(override val value: TherapyEvent, override val id: Long): DataPair data class PairGlucoseValue(override val value: GlucoseValue, override val id: Long) : DataPair
data class PairFood(override val value: Food, override val id: Long): DataPair data class PairTherapyEvent(override val value: TherapyEvent, override val id: Long) : DataPair
data class PairBolus(override val value: Bolus, override val id: Long): DataPair data class PairFood(override val value: Food, override val id: Long) : DataPair
data class PairCarbs(override val value: Carbs, override val id: Long): DataPair data class PairBolus(override val value: Bolus, override val id: Long) : DataPair
data class PairBolusCalculatorResult(override val value: BolusCalculatorResult, override val id: Long): DataPair data class PairCarbs(override val value: Carbs, override val id: Long) : DataPair
data class PairTemporaryBasal(override val value: TemporaryBasal, override val id: Long): DataPair data class PairBolusCalculatorResult(override val value: BolusCalculatorResult, override val id: Long) : DataPair
data class PairExtendedBolus(override val value: ExtendedBolus, override val id: Long): DataPair data class PairTemporaryBasal(override val value: TemporaryBasal, override val id: Long) : DataPair
data class PairProfileSwitch(override val value: ProfileSwitch, override val id: Long): DataPair data class PairExtendedBolus(override val value: ExtendedBolus, override val id: Long) : DataPair
data class PairEffectiveProfileSwitch(override val value: EffectiveProfileSwitch, override val id: Long): DataPair data class PairProfileSwitch(override val value: ProfileSwitch, override val id: Long) : DataPair
data class PairOfflineEvent(override val value: OfflineEvent, override val id: Long): DataPair data class PairEffectiveProfileSwitch(override val value: EffectiveProfileSwitch, override val id: Long) : DataPair
data class PairProfileStore(override val value: JSONObject, override val id: Long): DataPair data class PairOfflineEvent(override val value: OfflineEvent, override val id: Long) : DataPair
data class PairDeviceStatus(override val value: DeviceStatus, override val id: Long): DataPair data class PairProfileStore(override val value: JSONObject, override val id: Long) : DataPair
data class PairDeviceStatus(override val value: DeviceStatus, override val id: Long) : DataPair
fun queueSize(): Long fun queueSize(): Long
fun doUpload()
fun resetToNextFullSync() fun resetToNextFullSync()
fun confirmLastBolusIdIfGreater(lastSynced: Long) suspend fun doUpload()
fun processChangedBolusesCompat()
fun confirmLastCarbsIdIfGreater(lastSynced: Long)
fun processChangedCarbsCompat()
fun confirmLastBolusCalculatorResultsIdIfGreater(lastSynced: Long)
fun processChangedBolusCalculatorResultsCompat()
fun confirmLastTempTargetsIdIfGreater(lastSynced: Long)
fun processChangedTempTargetsCompat()
fun confirmLastGlucoseValueIdIfGreater(lastSynced: Long)
fun processChangedGlucoseValuesCompat()
fun confirmLastTherapyEventIdIfGreater(lastSynced: Long)
fun processChangedTherapyEventsCompat()
fun confirmLastFoodIdIfGreater(lastSynced: Long)
fun processChangedFoodsCompat()
fun confirmLastDeviceStatusIdIfGreater(lastSynced: Long)
fun processChangedDeviceStatusesCompat()
fun confirmLastTemporaryBasalIdIfGreater(lastSynced: Long)
fun processChangedTemporaryBasalsCompat()
fun confirmLastExtendedBolusIdIfGreater(lastSynced: Long)
fun processChangedExtendedBolusesCompat()
fun confirmLastProfileSwitchIdIfGreater(lastSynced: Long)
fun processChangedProfileSwitchesCompat()
fun confirmLastEffectiveProfileSwitchIdIfGreater(lastSynced: Long)
fun processChangedEffectiveProfileSwitchesCompat()
fun confirmLastOfflineEventIdIfGreater(lastSynced: Long)
fun processChangedOfflineEventsCompat()
fun confirmLastProfileStore(lastSynced: Long)
fun processChangedProfileStore()
} }

View file

@ -0,0 +1,46 @@
package info.nightscout.interfaces.sync
interface DataSyncSelectorV1 : DataSyncSelector {
fun confirmLastBolusIdIfGreater(lastSynced: Long)
suspend fun processChangedBoluses()
fun confirmLastCarbsIdIfGreater(lastSynced: Long)
suspend fun processChangedCarbs()
fun confirmLastBolusCalculatorResultsIdIfGreater(lastSynced: Long)
suspend fun processChangedBolusCalculatorResults()
fun confirmLastTempTargetsIdIfGreater(lastSynced: Long)
suspend fun processChangedTempTargets()
fun confirmLastGlucoseValueIdIfGreater(lastSynced: Long)
suspend fun processChangedGlucoseValues()
fun confirmLastTherapyEventIdIfGreater(lastSynced: Long)
suspend fun processChangedTherapyEvents()
fun confirmLastFoodIdIfGreater(lastSynced: Long)
suspend fun processChangedFoods()
fun confirmLastDeviceStatusIdIfGreater(lastSynced: Long)
suspend fun processChangedDeviceStatuses()
fun confirmLastTemporaryBasalIdIfGreater(lastSynced: Long)
suspend fun processChangedTemporaryBasals()
fun confirmLastExtendedBolusIdIfGreater(lastSynced: Long)
suspend fun processChangedExtendedBoluses()
fun confirmLastProfileSwitchIdIfGreater(lastSynced: Long)
suspend fun processChangedProfileSwitches()
fun confirmLastEffectiveProfileSwitchIdIfGreater(lastSynced: Long)
suspend fun processChangedEffectiveProfileSwitches()
fun confirmLastOfflineEventIdIfGreater(lastSynced: Long)
suspend fun processChangedOfflineEvents()
fun confirmLastProfileStore(lastSynced: Long)
suspend fun processChangedProfileStore()
}

View file

@ -0,0 +1,3 @@
package info.nightscout.interfaces.sync
interface DataSyncSelectorV3 : DataSyncSelector

View file

@ -0,0 +1,3 @@
package info.nightscout.interfaces.sync
interface DataSyncSelectorXdrip : DataSyncSelector

View file

@ -1,27 +1,105 @@
package info.nightscout.interfaces.sync package info.nightscout.interfaces.sync
import android.text.Spanned
import info.nightscout.interfaces.nsclient.NSAlarm import info.nightscout.interfaces.nsclient.NSAlarm
import info.nightscout.rx.events.EventNSClientNewLog
/**
* Plugin providing communication with Nightscout server
*/
interface NsClient : Sync { interface NsClient : Sync {
enum class Version {
NONE, V1, V3
}
val version: Version /**
* NS URL
*/
val address: String val address: String
/**
* Set plugin in paused state
*/
fun pause(newState: Boolean) fun pause(newState: Boolean)
fun resend(reason: String)
fun textLog(): Spanned
fun clearLog()
/**
* Initiate new round of upload/download
*/
fun resend(reason: String)
/**
* List of log messages for fragment
*/
val listLog: MutableList<EventNSClientNewLog>
/**
* Used data sync selector
*/
val dataSyncSelector: DataSyncSelector
/**
* Version of NS server
* @return Returns detected version of NS server
*/
fun detectedNsVersion(): String?
enum class Collection { ENTRIES, TREATMENTS, FOODS, PROFILE }
/**
* NSC v3 does first load of all data
* next loads are using srvModified property for sync
* not used for NSCv1
*
* @return true if inside first load of NSCv3, true for NSCv1
*/
fun isFirstLoad(collection: Collection): Boolean = true
/**
* Update newest loaded timestamp for entries collection (first load or NSCv1)
* Update newest srvModified (sync loads)
*
* @param latestReceived timestamp
*
*/
fun updateLatestBgReceivedIfNewer(latestReceived: Long) fun updateLatestBgReceivedIfNewer(latestReceived: Long)
/**
* Update newest loaded timestamp for treatments collection (first load or NSCv1)
* Update newest srvModified (sync loads)
*
* @param latestReceived timestamp
*
*/
fun updateLatestTreatmentReceivedIfNewer(latestReceived: Long) fun updateLatestTreatmentReceivedIfNewer(latestReceived: Long)
/**
* Send alarm confirmation to NS
*
* @param originalAlarm alarm to be cleared
* @param silenceTimeInMilliseconds silence alarm for specified duration
*/
fun handleClearAlarm(originalAlarm: NSAlarm, silenceTimeInMilliseconds: Long) fun handleClearAlarm(originalAlarm: NSAlarm, silenceTimeInMilliseconds: Long)
/**
* Clear synchronization status
*
* Next synchronization will start from scratch
*/
fun resetToFullSync() fun resetToFullSync()
fun dbAdd(collection: String, dataPair: DataSyncSelector.DataPair, progress: String) /**
fun dbUpdate(collection: String, dataPair: DataSyncSelector.DataPair, progress: String) * Upload new record to NS
*
* @param collection target ns collection
* @param dataPair data to upload (data.first) and id of changed record (data.second)
* @param progress progress of sync in format "number/number". Only for display in fragment
* @return true for successful upload
*/
suspend fun nsAdd(collection: String, dataPair: DataSyncSelector.DataPair, progress: String): Boolean
/**
* Upload updated record to NS
*
* @param collection target ns collection
* @param dataPair data to upload (data.first) and id of changed record (data.second)
* @param progress progress of sync in format "number/number". Only for display in fragment
* @return true for successful upload
*/
suspend fun nsUpdate(collection: String, dataPair: DataSyncSelector.DataPair, progress: String): Boolean
} }

View file

@ -0,0 +1,3 @@
package info.nightscout.interfaces.sync
interface Tidepool : Sync

View file

@ -21,6 +21,7 @@ interface UiInteraction {
val singleFragmentActivity: Class<*> val singleFragmentActivity: Class<*>
val preferencesActivity: Class<*> val preferencesActivity: Class<*>
val myPreferenceFragment: Class<*> val myPreferenceFragment: Class<*>
val quickWizardListActivity: Class<*>
val prefGeneral: Int val prefGeneral: Int
/** /**
@ -32,7 +33,7 @@ interface UiInteraction {
*/ */
fun runAlarm(status: String, title: String, @RawRes soundId: Int = 0) fun runAlarm(status: String, title: String, @RawRes soundId: Int = 0)
fun updateWidget(context: Context) fun updateWidget(context: Context, from: String)
fun runWizardDialog(fragmentManager: FragmentManager, carbs: Int? = null, name: String? = null) fun runWizardDialog(fragmentManager: FragmentManager, carbs: Int? = null, name: String? = null)
fun runLoopDialog(fragmentManager: FragmentManager, showOkCancel: Int) fun runLoopDialog(fragmentManager: FragmentManager, showOkCancel: Int)

View file

@ -1,10 +1,15 @@
package info.nightscout.interfaces.utils package info.nightscout.interfaces.utils
import android.text.Html import android.text.Html
import android.text.SpannableStringBuilder
import android.text.Spanned import android.text.Spanned
object HtmlHelper { object HtmlHelper {
fun fromHtml(source: String): Spanned {
return Html.fromHtml(source, Html.FROM_HTML_MODE_LEGACY) fun fromHtml(source: String): Spanned =
} try {
Html.fromHtml(source, Html.FROM_HTML_MODE_LEGACY)
} catch (e: Exception) {
SpannableStringBuilder("")
}
} }

View file

@ -1,28 +0,0 @@
package info.nightscout.interfaces.utils
import android.content.Context
import android.content.Intent
import android.provider.AlarmClock
import info.nightscout.androidaps.annotations.OpenForTesting
import javax.inject.Inject
import javax.inject.Singleton
@OpenForTesting
@Singleton
open class TimerUtil @Inject constructor(
private val context: Context
) {
/**
* Schedule alarm in @seconds
*/
fun scheduleReminder(seconds: Int, text: String) {
Intent(AlarmClock.ACTION_SET_TIMER).apply {
flags = flags or Intent.FLAG_ACTIVITY_NEW_TASK
putExtra(AlarmClock.EXTRA_LENGTH, seconds)
putExtra(AlarmClock.EXTRA_SKIP_UI, true)
putExtra(AlarmClock.EXTRA_MESSAGE, text)
context.startActivity(this)
}
}
}

View file

@ -1,6 +1,8 @@
package info.nightscout.interfaces.utils package info.nightscout.interfaces.utils
import info.nightscout.database.entities.GlucoseValue import info.nightscout.database.entities.GlucoseValue
import info.nightscout.interfaces.aps.AutosensDataStore
import info.nightscout.interfaces.iob.InMemoryGlucoseValue
/** /**
* Convert BG direction value to trend arrow or calculate it if not provided * Convert BG direction value to trend arrow or calculate it if not provided
@ -15,6 +17,20 @@ interface TrendCalculator {
* @return TrendArrow * @return TrendArrow
*/ */
fun getTrendArrow(glucoseValue: GlucoseValue?): GlucoseValue.TrendArrow fun getTrendArrow(glucoseValue: GlucoseValue?): GlucoseValue.TrendArrow
/**
* Provide or calculate trend
*
* @param glucoseValue BG
* @return TrendArrow
*/
fun getTrendArrow(glucoseValue: InMemoryGlucoseValue?): GlucoseValue.TrendArrow
/**
* Provide or calculate trend from newest bucketed data
*
* @param autosensDataStore current store from IobCobCalculator
* @return TrendArrow
*/
fun getTrendArrow(autosensDataStore: AutosensDataStore): GlucoseValue.TrendArrow?
/** /**
* Provide or calculate trend * Provide or calculate trend
@ -23,4 +39,11 @@ interface TrendCalculator {
* @return string description of TrendArrow * @return string description of TrendArrow
*/ */
fun getTrendDescription(glucoseValue: GlucoseValue?): String fun getTrendDescription(glucoseValue: GlucoseValue?): String
/**
* Provide or calculate trend from newest bucketed data
*
* @param autosensDataStore current store from IobCobCalculator
* @return string description of TrendArrow
*/
fun getTrendDescription(autosensDataStore: AutosensDataStore): String
} }

View file

@ -1,9 +1,5 @@
package info.nightscout.interfaces.workflow package info.nightscout.interfaces.workflow
import androidx.work.ListenableWorker
interface WorkerClasses { interface WorkerClasses {
val nsClientSourceWorker: Class<out ListenableWorker> // val nsProfileWorker: Class<out ListenableWorker>
val nsProfileWorker: Class<out ListenableWorker>
val foodWorker: Class<out ListenableWorker>
} }

View file

@ -14,6 +14,7 @@
<!-- PumpType--> <!-- PumpType-->
<string name="def_extended_note">* Само конкретни стойности! Диапазони не се поддържат за базал/болус при виртуална помпа.</string> <string name="def_extended_note">* Само конкретни стойности! Диапазони не се поддържат за базал/болус при виртуална помпа.</string>
<!-- PumpPluginBase --> <!-- PumpPluginBase -->
<string name="pump_driver_changed" comment="26 characters max for translation">Драйверът на помпата е променен.</string>
<!-- DecimalFormatter--> <!-- DecimalFormatter-->
<string name="format_insulin_units1">%1$.1fЕ</string> <string name="format_insulin_units1">%1$.1fЕ</string>
<string name="format_insulin_units">%1$.2fЕ</string> <string name="format_insulin_units">%1$.2fЕ</string>

View file

@ -4,10 +4,10 @@
<string name="metadata_label_format">Filformat</string> <string name="metadata_label_format">Filformat</string>
<string name="metadata_label_created_at">Opprettet den</string> <string name="metadata_label_created_at">Opprettet den</string>
<string name="metadata_label_aaps_version">AAPS versjon</string> <string name="metadata_label_aaps_version">AAPS versjon</string>
<string name="metadata_label_aaps_flavour">Bygge variant</string> <string name="metadata_label_aaps_flavour">Byggvariant</string>
<string name="metadata_label_device_name">Eksporterer enhetens pasientnavn</string> <string name="metadata_label_device_name">Eksporterer enhetens pasientnavn</string>
<string name="metadata_label_device_model">Eksportere enhetsmodell</string> <string name="metadata_label_device_model">Eksportere enhetsmodell</string>
<string name="metadata_label_encryption">Fil kryptering</string> <string name="metadata_label_encryption">Filkryptering</string>
<string name="metadata_format_new">Nytt krypteringsformat</string> <string name="metadata_format_new">Nytt krypteringsformat</string>
<string name="metadata_format_debug">Nytt feilsøkingsformat (ukryptert)</string> <string name="metadata_format_debug">Nytt feilsøkingsformat (ukryptert)</string>
<string name="metadata_format_other">Ukjent eksportformat</string> <string name="metadata_format_other">Ukjent eksportformat</string>

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