Merge branch 'dev' into iobfix

This commit is contained in:
Milos Kozak 2019-07-15 15:52:02 +02:00
commit c0d85e85a0
303 changed files with 4872 additions and 2255 deletions

View file

@ -2,19 +2,19 @@ language: android
jdk: oraclejdk8 jdk: oraclejdk8
env: env:
matrix: matrix:
- ANDROID_TARGET=android-23 ANDROID_ABI=x86 org.gradle.jvmargs=-XX:-OmitStackTraceInFastThrow - ANDROID_TARGET=android-28 ANDROID_ABI=x86 org.gradle.jvmargs=-XX:-OmitStackTraceInFastThrow
android: android:
components: components:
- platform-tools - platform-tools
- tools - tools
- build-tools-27.0.2 - build-tools-28.0.3
- android-23 - android-28
- extra-google-m2repository - extra-google-m2repository
- extra-android-m2repository - extra-android-m2repository
- extra-google-google_play_services - extra-google-google_play_services
before_install: before_install:
- yes | sdkmanager "platforms;android-27" - yes | sdkmanager "platforms;android-28"
script: script:
# Unit Test # Unit Test

View file

@ -6,27 +6,37 @@ buildscript {
dependencies { dependencies {
classpath 'io.fabric.tools:gradle:1.+' classpath 'io.fabric.tools:gradle:1.+'
classpath 'com.dicedmelon.gradle:jacoco-android:0.1.3' classpath 'com.dicedmelon.gradle:jacoco-android:0.1.4'
classpath 'de.undercouch:gradle-download-task:3.4.3'
} }
} }
apply plugin: "com.android.application" apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'com.google.gms.google-services' apply plugin: 'com.google.gms.google-services'
apply plugin: "io.fabric" apply plugin: 'io.fabric'
apply plugin: "jacoco-android" apply plugin: 'jacoco-android'
apply plugin: 'com.jakewharton.butterknife' apply plugin: 'com.jakewharton.butterknife'
apply plugin: 'de.undercouch.download'
jacoco {
toolVersion = "0.8.3"
}
ext { ext {
supportLibraryVersion = "27.1.1" supportLibraryVersion = "28.0.0"
ormLiteVersion = "4.46" ormLiteVersion = "4.46"
powermockVersion = "1.7.3" powermockVersion = "1.7.3"
dexmakerVersion = "1.2" dexmakerVersion = "1.2"
butterknifeVersion = "8.8.1" butterknifeVersion = "10.1.0"
} }
repositories { repositories {
maven { url 'https://maven.fabric.io/public' } maven { url 'https://maven.fabric.io/public' }
jcenter { url "https://jcenter.bintray.com/" } jcenter { url "https://jcenter.bintray.com/" }
mavenCentral()
} }
def generateGitBuild = { -> def generateGitBuild = { ->
@ -67,31 +77,55 @@ def generateDate = { ->
return stringBuilder.toString() return stringBuilder.toString()
} }
def isMaster = { ->
return !version.contains('-')
}
def allCommited = { ->
StringBuilder stringBuilder = new StringBuilder();
try {
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'git', 'status', '-s'
standardOutput = stdout
}
String commitObject = stdout.toString().trim()
stringBuilder.append(commitObject)
} catch (ignored) {
return false; // NoGitSystemAvailable
}
return stringBuilder.toString().isEmpty()
}
tasks.matching { it instanceof Test }.all { tasks.matching { it instanceof Test }.all {
testLogging.events = ["failed", "skipped", "started"] testLogging.events = ["failed", "skipped", "started"]
testLogging.exceptionFormat = "full" testLogging.exceptionFormat = "full"
} }
android { android {
compileSdkVersion 27 compileSdkVersion 28
defaultConfig { defaultConfig {
minSdkVersion 21 minSdkVersion 23
targetSdkVersion 25 targetSdkVersion 28
multiDexEnabled true multiDexEnabled true
versionCode 1500 versionCode 1500
version "2.2.3-dev" version "2.4-dev"
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() + '"'
buildConfigField "String", "HEAD", '"' + generateGitBuild() + '"' buildConfigField "String", "HEAD", '"' + generateGitBuild() + '"'
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
// if you change minSdkVersion to less than 11, you need to change executeTask for wear // if you change minSdkVersion to less than 11, you need to change executeTask for wear
ndk { ndk {
moduleName "BleCommandUtil" moduleName "BleCommandUtil"
} }
} }
kotlinOptions {
jvmTarget = '1.8'
}
lintOptions { lintOptions {
// TODO remove once wear dependency com.google.android.gms:play-services-wearable:7.3.0 // TODO remove once wear dependency com.google.android.gms:play-services-wearable:7.3.0
// has been upgraded (requiring significant code changes), which currently fails release // has been upgraded (requiring significant code changes), which currently fails release
@ -120,7 +154,7 @@ android {
resValue "string", "app_name", "AndroidAPS" resValue "string", "app_name", "AndroidAPS"
versionName version versionName version
manifestPlaceholders = [ manifestPlaceholders = [
appIcon: "@mipmap/ic_launcher", appIcon : "@mipmap/ic_launcher",
appIconRound: "@mipmap/ic_launcher_round" appIconRound: "@mipmap/ic_launcher_round"
] ]
} }
@ -130,7 +164,7 @@ android {
resValue "string", "app_name", "Pumpcontrol" resValue "string", "app_name", "Pumpcontrol"
versionName version + "-pumpcontrol" versionName version + "-pumpcontrol"
manifestPlaceholders = [ manifestPlaceholders = [
appIcon: "@mipmap/ic_pumpcontrol", appIcon : "@mipmap/ic_pumpcontrol",
appIconRound: "@null" appIconRound: "@null"
] ]
} }
@ -140,7 +174,7 @@ android {
resValue "string", "app_name", "NSClient" resValue "string", "app_name", "NSClient"
versionName version + "-nsclient" versionName version + "-nsclient"
manifestPlaceholders = [ manifestPlaceholders = [
appIcon: "@mipmap/ic_yellowowl", appIcon : "@mipmap/ic_yellowowl",
appIconRound: "@null" appIconRound: "@null"
] ]
} }
@ -150,7 +184,7 @@ android {
resValue "string", "app_name", "NSClient2" resValue "string", "app_name", "NSClient2"
versionName version + "-nsclient" versionName version + "-nsclient"
manifestPlaceholders = [ manifestPlaceholders = [
appIcon: "@mipmap/ic_yellowowl", appIcon : "@mipmap/ic_yellowowl",
appIconRound: "@null" appIconRound: "@null"
] ]
} }
@ -161,11 +195,18 @@ android {
} }
testOptions { testOptions {
unitTests.returnDefaultValues = true unitTests {
unitTests.includeAndroidResources = true returnDefaultValues = true
includeAndroidResources = true
all {
maxParallelForks = 10
forkEvery = 20
}
}
} }
useLibrary "org.apache.http.legacy" useLibrary "org.apache.http.legacy"
} }
allprojects { allprojects {
@ -177,31 +218,30 @@ allprojects {
} }
} }
configurations {
libs
}
dependencies { dependencies {
wearApp project(':wear') wearApp project(':wear')
implementation fileTree(include: ['*.jar'], dir: 'libs') implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.google.android.gms:play-services-wearable:16.0.1' implementation 'com.google.android.gms:play-services-wearable:17.0.0'
implementation 'com.google.firebase:firebase-core:16.0.8' implementation 'com.google.firebase:firebase-core:17.0.1'
implementation("com.crashlytics.sdk.android:crashlytics:2.9.9@aar") { implementation("com.crashlytics.sdk.android:crashlytics:2.9.9@aar") {
transitive = true; transitive = true;
} }
libs "MilosKozak:danars-support-lib:master@zip"
implementation "com.android.support:appcompat-v7:${supportLibraryVersion}" implementation 'androidx.appcompat:appcompat:1.0.2'
implementation "com.android.support:support-v13:${supportLibraryVersion}" implementation 'androidx.legacy:legacy-support-v13:1.0.0'
implementation "com.android.support:support-v4:${supportLibraryVersion}" implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation "com.android.support:cardview-v7:${supportLibraryVersion}" implementation 'androidx.cardview:cardview:1.0.0'
implementation "com.android.support:recyclerview-v7:${supportLibraryVersion}" implementation 'androidx.recyclerview:recyclerview:1.0.0'
implementation "com.android.support:gridlayout-v7:${supportLibraryVersion}" implementation 'androidx.gridlayout:gridlayout:1.0.0'
implementation "com.android.support:design:${supportLibraryVersion}" implementation 'com.google.android.material:material:1.0.0'
implementation "com.android.support:percent:${supportLibraryVersion}" implementation 'androidx.percentlayout:percentlayout:1.0.0'
implementation "com.wdullaer:materialdatetimepicker:2.3.0" implementation "com.wdullaer:materialdatetimepicker:2.3.0"
// Otto bus will be replaced by rx
implementation "com.squareup:otto:1.3.7" implementation "com.squareup:otto:1.3.7"
implementation "io.reactivex.rxjava2:rxandroid:2.1.1"
implementation "com.j256.ormlite:ormlite-core:${ormLiteVersion}" implementation "com.j256.ormlite:ormlite-core:${ormLiteVersion}"
implementation "com.j256.ormlite:ormlite-android:${ormLiteVersion}" implementation "com.j256.ormlite:ormlite-android:${ormLiteVersion}"
implementation("com.github.tony19:logback-android-classic:1.1.1-6") { implementation("com.github.tony19:logback-android-classic:1.1.1-6") {
@ -212,7 +252,7 @@ dependencies {
// Graphview cannot be upgraded // Graphview cannot be upgraded
implementation "com.jjoe64:graphview:4.0.1" implementation "com.jjoe64:graphview:4.0.1"
implementation "com.joanzapata.iconify:android-iconify-fontawesome:2.1.1" implementation "com.joanzapata.iconify:android-iconify-fontawesome:2.1.1"
implementation 'com.android.support.constraint:constraint-layout:1.1.3' implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation(name: "android-edittext-validator-v1.3.4-mod", ext: "aar") implementation(name: "android-edittext-validator-v1.3.4-mod", ext: "aar")
implementation 'com.madgag.spongycastle:core:1.58.0.0' implementation 'com.madgag.spongycastle:core:1.58.0.0'
@ -223,7 +263,7 @@ dependencies {
// excluding org.json which is provided by Android // excluding org.json which is provided by Android
exclude group: "org.json", module: "json" exclude group: "org.json", module: "json"
} }
implementation "com.google.code.gson:gson:2.8.2" implementation "com.google.code.gson:gson:2.8.5"
implementation "com.google.guava:guava:24.1-jre" implementation "com.google.guava:guava:24.1-jre"
implementation "net.danlew:android.joda:2.9.9.1" implementation "net.danlew:android.joda:2.9.9.1"
@ -243,24 +283,39 @@ dependencies {
testImplementation "org.powermock:powermock-module-junit4:${powermockVersion}" testImplementation "org.powermock:powermock-module-junit4:${powermockVersion}"
testImplementation "joda-time:joda-time:2.9.9" testImplementation "joda-time:joda-time:2.9.9"
testImplementation "com.google.truth:truth:0.39" testImplementation "com.google.truth:truth:0.39"
testImplementation 'org.robolectric:robolectric:3.8' testImplementation 'org.robolectric:robolectric:4.2.1'
testImplementation "org.skyscreamer:jsonassert:1.5.0" testImplementation "org.skyscreamer:jsonassert:1.5.0"
androidTestImplementation "org.mockito:mockito-core:2.8.47" androidTestImplementation "org.mockito:mockito-core:2.8.47"
androidTestImplementation "com.google.dexmaker:dexmaker:${dexmakerVersion}" androidTestImplementation "com.google.dexmaker:dexmaker:${dexmakerVersion}"
androidTestImplementation "com.google.dexmaker:dexmaker-mockito:${dexmakerVersion}" androidTestImplementation "com.google.dexmaker:dexmaker-mockito:${dexmakerVersion}"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
// new for tidepool
implementation 'com.squareup.okhttp3:okhttp:3.10.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.10.0'
implementation "com.squareup.retrofit2:retrofit:2.4.0"
implementation "com.squareup.retrofit2:adapter-rxjava2:2.4.0"
implementation "com.squareup.retrofit2:converter-gson:2.4.0"
} }
task unzip(type: Copy) {
def zipPath = configurations.libs.find { it.name.startsWith("danars") }
def zipFile = file(zipPath)
def outputDir = file("${buildDir}/unpacked/dist")
from zipTree(zipFile) task downloadZipFile(type: Download) {
src 'https://github.com/MilosKozak/danars-support-lib/archive/master.zip'
dest new File(buildDir, 'danars.zip')
}
task downloadAndUnzipFile(dependsOn: downloadZipFile, type: Copy) {
from zipTree(downloadZipFile.dest)
def outputDir = file("${buildDir}/unpacked/dist")
into outputDir into outputDir
} }
task copyLibs(dependsOn: unzip, type: Copy) {
task copyLibs(dependsOn: downloadAndUnzipFile, type: Copy) {
def src = file("${buildDir}/unpacked/dist/danars-support-lib-master") def src = file("${buildDir}/unpacked/dist/danars-support-lib-master")
def target = file("src/main/jniLibs/") def target = file("src/main/jniLibs/")
@ -274,3 +329,12 @@ task full_clean(type: Delete) {
clean.dependsOn full_clean clean.dependsOn full_clean
preBuild.dependsOn copyLibs preBuild.dependsOn copyLibs
printf('--------------\n')
printf('isMaster: %s\n', isMaster().toString())
printf('allCommited: %s\n', allCommited().toString())
printf('--------------\n')
if (isMaster() && !allCommited()) {
throw new GradleException('There are uncommitted changes or git system is not available. Clone sources again as described in wiki and do not allow gradle update')
}

View file

@ -17,10 +17,11 @@
<uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="com.google.android.permission.PROVIDE_BACKGROUND" /> <uses-permission android:name="com.google.android.permission.PROVIDE_BACKGROUND" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="sugar.free.sightremote.HISTORY_BROADCASTS" /> <uses-permission android:name="com.dexcom.cgm.EXTERNAL_PERMISSION" />
<uses-permission-sdk-23 android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" /> <uses-permission-sdk-23 android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
@ -34,13 +35,15 @@
android:label="@string/app_name" android:label="@string/app_name"
android:roundIcon="${appIconRound}" android:roundIcon="${appIconRound}"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/AppTheme.NoActionBar"> android:theme="@style/AppTheme.NoActionBar"
android:fullBackupContent="true">
<meta-data <meta-data
android:name="com.google.android.gms.car.application" android:name="com.google.android.gms.car.application"
android:resource="@xml/automotive_app_desc" /> android:resource="@xml/automotive_app_desc" />
<activity android:name=".MainActivity"> <activity android:name=".MainActivity">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
@ -85,10 +88,8 @@
<action android:name="com.eveningoutpost.dexdrip.NS_EMULATOR"/> <action android:name="com.eveningoutpost.dexdrip.NS_EMULATOR"/>
<!-- Receiver from glimp --> <!-- Receiver from glimp -->
<action android:name="it.ct.glicemia.ACTION_GLUCOSE_MEASURED"/> <action android:name="it.ct.glicemia.ACTION_GLUCOSE_MEASURED"/>
<!-- Receiver from DexcomG5 --> <!-- Receiver from Dexcom -->
<action android:name="com.dexcom.cgm.DATA"/> <action android:name="com.dexcom.cgm.EXTERNAL_BROADCAST"/>
<action android:name="com.dexcom.cgm.AndroidAPSEVGCallback.BROADCAST"/>
<action android:name="com.dexcom.cgm.g5.AndroidAPSEVGCallback.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 -->
@ -147,7 +148,7 @@
</receiver> </receiver>
<provider <provider
android:name="android.support.v4.content.FileProvider" android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider" android:authorities="${applicationId}.fileprovider"
android:exported="false" android:exported="false"
android:grantUriPermissions="true"> android:grantUriPermissions="true">
@ -281,6 +282,10 @@
android:name=".plugins.pump.insight.activities.InsightPairingInformationActivity" android:name=".plugins.pump.insight.activities.InsightPairingInformationActivity"
android:label="@string/pairing_information" android:label="@string/pairing_information"
android:theme="@style/AppTheme" /> android:theme="@style/AppTheme" />
<activity android:name=".activities.RequestDexcomPermissionActivity" />
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
</application> </application>
</manifest> </manifest>

View file

@ -7,16 +7,16 @@ import android.graphics.Rect;
import android.os.Bundle; import android.os.Bundle;
import android.os.PersistableBundle; import android.os.PersistableBundle;
import android.os.PowerManager; import android.os.PowerManager;
import android.support.annotation.Nullable; import androidx.annotation.Nullable;
import android.support.design.widget.NavigationView; import com.google.android.material.navigation.NavigationView;
import android.support.design.widget.TabLayout; import com.google.android.material.tabs.TabLayout;
import android.support.v4.app.ActivityCompat; import androidx.core.app.ActivityCompat;
import android.support.v4.view.ViewPager; import androidx.viewpager.widget.ViewPager;
import android.support.v4.widget.DrawerLayout; import androidx.drawerlayout.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle; import androidx.appcompat.app.ActionBarDrawerToggle;
import android.support.v7.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import android.support.v7.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import android.support.v7.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import android.text.SpannableString; import android.text.SpannableString;
import android.text.method.LinkMovementMethod; import android.text.method.LinkMovementMethod;
import android.text.util.Linkify; import android.text.util.Linkify;
@ -48,9 +48,12 @@ import info.nightscout.androidaps.events.EventFeatureRunning;
import info.nightscout.androidaps.events.EventPreferenceChange; import info.nightscout.androidaps.events.EventPreferenceChange;
import info.nightscout.androidaps.events.EventRefreshGui; import info.nightscout.androidaps.events.EventRefreshGui;
import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus; import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus;
import info.nightscout.androidaps.plugins.general.versionChecker.VersionCheckerUtilsKt;
import info.nightscout.androidaps.setupwizard.SetupWizardActivity; import info.nightscout.androidaps.setupwizard.SetupWizardActivity;
import info.nightscout.androidaps.tabs.TabPageAdapter; import info.nightscout.androidaps.tabs.TabPageAdapter;
import info.nightscout.androidaps.utils.AndroidPermission; import info.nightscout.androidaps.utils.AndroidPermission;
@ -59,7 +62,6 @@ import info.nightscout.androidaps.utils.LocaleHelper;
import info.nightscout.androidaps.utils.OKDialog; import info.nightscout.androidaps.utils.OKDialog;
import info.nightscout.androidaps.utils.PasswordProtection; import info.nightscout.androidaps.utils.PasswordProtection;
import info.nightscout.androidaps.utils.SP; import info.nightscout.androidaps.utils.SP;
import info.nightscout.androidaps.utils.VersionChecker;
public class MainActivity extends AppCompatActivity { public class MainActivity extends AppCompatActivity {
private static Logger log = LoggerFactory.getLogger(L.CORE); private static Logger log = LoggerFactory.getLogger(L.CORE);
@ -115,7 +117,11 @@ public class MainActivity extends AppCompatActivity {
public void onPageScrollStateChanged(int state) { public void onPageScrollStateChanged(int state) {
} }
}); });
VersionChecker.check();
//Check here if loop plugin is disabled. Else check via constraints
if (!LoopPlugin.getPlugin().isEnabled(PluginType.LOOP))
VersionCheckerUtilsKt.triggerCheckVersion();
FabricPrivacy.setUserStats(); FabricPrivacy.setUserStats();
} }

View file

@ -4,9 +4,10 @@ import android.app.Application;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.res.Resources; import android.content.res.Resources;
import android.os.SystemClock; import android.os.SystemClock;
import android.support.annotation.Nullable;
import android.support.annotation.PluralsRes; import androidx.annotation.Nullable;
import android.support.v4.content.LocalBroadcastManager; import androidx.annotation.PluralsRes;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import com.crashlytics.android.Crashlytics; import com.crashlytics.android.Crashlytics;
import com.google.firebase.analytics.FirebaseAnalytics; import com.google.firebase.analytics.FirebaseAnalytics;
@ -50,6 +51,8 @@ import info.nightscout.androidaps.plugins.general.nsclient.receivers.DBAccessRec
import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin; import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin;
import info.nightscout.androidaps.plugins.general.persistentNotification.PersistentNotificationPlugin; import info.nightscout.androidaps.plugins.general.persistentNotification.PersistentNotificationPlugin;
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin; import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin;
import info.nightscout.androidaps.plugins.general.tidepool.TidepoolPlugin;
import info.nightscout.androidaps.plugins.general.versionChecker.VersionCheckerPlugin;
import info.nightscout.androidaps.plugins.general.wear.WearPlugin; import info.nightscout.androidaps.plugins.general.wear.WearPlugin;
import info.nightscout.androidaps.plugins.general.xdripStatusline.StatuslinePlugin; import info.nightscout.androidaps.plugins.general.xdripStatusline.StatuslinePlugin;
import info.nightscout.androidaps.plugins.insulin.InsulinOrefFreePeakPlugin; import info.nightscout.androidaps.plugins.insulin.InsulinOrefFreePeakPlugin;
@ -71,8 +74,7 @@ import info.nightscout.androidaps.plugins.sensitivity.SensitivityAAPSPlugin;
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref0Plugin; import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref0Plugin;
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin; import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin;
import info.nightscout.androidaps.plugins.sensitivity.SensitivityWeightedAveragePlugin; import info.nightscout.androidaps.plugins.sensitivity.SensitivityWeightedAveragePlugin;
import info.nightscout.androidaps.plugins.source.SourceDexcomG5Plugin; import info.nightscout.androidaps.plugins.source.SourceDexcomPlugin;
import info.nightscout.androidaps.plugins.source.SourceDexcomG6Plugin;
import info.nightscout.androidaps.plugins.source.SourceEversensePlugin; import info.nightscout.androidaps.plugins.source.SourceEversensePlugin;
import info.nightscout.androidaps.plugins.source.SourceGlimpPlugin; import info.nightscout.androidaps.plugins.source.SourceGlimpPlugin;
import info.nightscout.androidaps.plugins.source.SourceMM640gPlugin; import info.nightscout.androidaps.plugins.source.SourceMM640gPlugin;
@ -88,6 +90,8 @@ import info.nightscout.androidaps.services.Intents;
import info.nightscout.androidaps.utils.FabricPrivacy; import info.nightscout.androidaps.utils.FabricPrivacy;
import io.fabric.sdk.android.Fabric; import io.fabric.sdk.android.Fabric;
import static info.nightscout.androidaps.plugins.general.versionChecker.VersionCheckerUtilsKt.triggerCheckVersion;
public class MainApp extends Application { public class MainApp extends Application {
private static Logger log = LoggerFactory.getLogger(L.CORE); private static Logger log = LoggerFactory.getLogger(L.CORE);
@ -119,7 +123,7 @@ public class MainApp extends Application {
log.debug("onCreate"); log.debug("onCreate");
sInstance = this; sInstance = this;
sResources = getResources(); sResources = getResources();
sConstraintsChecker = new ConstraintChecker(this); sConstraintsChecker = new ConstraintChecker();
sDatabaseHelper = OpenHelperManager.getHelper(sInstance, DatabaseHelper.class); sDatabaseHelper = OpenHelperManager.getHelper(sInstance, DatabaseHelper.class);
try { try {
@ -142,12 +146,15 @@ public class MainApp extends Application {
File engineeringModeSemaphore = new File(extFilesDir, "engineering_mode"); File engineeringModeSemaphore = new File(extFilesDir, "engineering_mode");
engineeringMode = engineeringModeSemaphore.exists() && engineeringModeSemaphore.isFile(); engineeringMode = engineeringModeSemaphore.exists() && engineeringModeSemaphore.isFile();
devBranch = BuildConfig.VERSION.contains("dev"); devBranch = BuildConfig.VERSION.contains("-") || BuildConfig.VERSION.matches(".*[a-zA-Z]+.*");
sBus = L.isEnabled(L.EVENTS) && devBranch ? new LoggingBus(ThreadEnforcer.ANY) : new Bus(ThreadEnforcer.ANY); sBus = L.isEnabled(L.EVENTS) && devBranch ? new LoggingBus(ThreadEnforcer.ANY) : new Bus(ThreadEnforcer.ANY);
registerLocalBroadcastReceiver(); registerLocalBroadcastReceiver();
//trigger here to see the new version on app start after an update
triggerCheckVersion();
if (pluginsList == null) { if (pluginsList == null) {
pluginsList = new ArrayList<>(); pluginsList = new ArrayList<>();
// Register all tabs in app here // Register all tabs in app here
@ -179,14 +186,14 @@ public class MainApp extends Application {
if (Config.OTHERPROFILES) pluginsList.add(LocalProfilePlugin.getPlugin()); if (Config.OTHERPROFILES) pluginsList.add(LocalProfilePlugin.getPlugin());
pluginsList.add(TreatmentsPlugin.getPlugin()); pluginsList.add(TreatmentsPlugin.getPlugin());
if (Config.SAFETY) pluginsList.add(SafetyPlugin.getPlugin()); if (Config.SAFETY) pluginsList.add(SafetyPlugin.getPlugin());
if (Config.SAFETY) pluginsList.add(VersionCheckerPlugin.INSTANCE);
if (Config.SAFETY) pluginsList.add(StorageConstraintPlugin.getPlugin()); if (Config.SAFETY) pluginsList.add(StorageConstraintPlugin.getPlugin());
if (Config.APS) pluginsList.add(ObjectivesPlugin.getPlugin()); if (Config.APS) pluginsList.add(ObjectivesPlugin.getPlugin());
pluginsList.add(SourceXdripPlugin.getPlugin()); pluginsList.add(SourceXdripPlugin.getPlugin());
pluginsList.add(SourceNSClientPlugin.getPlugin()); pluginsList.add(SourceNSClientPlugin.getPlugin());
pluginsList.add(SourceMM640gPlugin.getPlugin()); pluginsList.add(SourceMM640gPlugin.getPlugin());
pluginsList.add(SourceGlimpPlugin.getPlugin()); pluginsList.add(SourceGlimpPlugin.getPlugin());
pluginsList.add(SourceDexcomG5Plugin.getPlugin()); pluginsList.add(SourceDexcomPlugin.INSTANCE);
pluginsList.add(SourceDexcomG6Plugin.getPlugin());
pluginsList.add(SourcePoctechPlugin.getPlugin()); pluginsList.add(SourcePoctechPlugin.getPlugin());
pluginsList.add(SourceTomatoPlugin.getPlugin()); pluginsList.add(SourceTomatoPlugin.getPlugin());
pluginsList.add(SourceEversensePlugin.getPlugin()); pluginsList.add(SourceEversensePlugin.getPlugin());
@ -197,6 +204,8 @@ public class MainApp extends Application {
pluginsList.add(StatuslinePlugin.initPlugin(this)); pluginsList.add(StatuslinePlugin.initPlugin(this));
pluginsList.add(PersistentNotificationPlugin.getPlugin()); pluginsList.add(PersistentNotificationPlugin.getPlugin());
pluginsList.add(NSClientPlugin.getPlugin()); pluginsList.add(NSClientPlugin.getPlugin());
if (engineeringMode)
pluginsList.add(TidepoolPlugin.INSTANCE);
pluginsList.add(MaintenancePlugin.initPlugin(this)); pluginsList.add(MaintenancePlugin.initPlugin(this));
pluginsList.add(ConfigBuilderPlugin.getPlugin()); pluginsList.add(ConfigBuilderPlugin.getPlugin());

View file

@ -2,9 +2,9 @@ package info.nightscout.androidaps.activities;
import android.os.Bundle; import android.os.Bundle;
import android.os.SystemClock; import android.os.SystemClock;
import android.support.v4.content.res.ResourcesCompat; import androidx.core.content.res.ResourcesCompat;
import android.support.v7.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import android.support.v7.widget.PopupMenu; import androidx.appcompat.widget.PopupMenu;
import android.text.SpannableString; import android.text.SpannableString;
import android.text.style.ForegroundColorSpan; import android.text.style.ForegroundColorSpan;
import android.view.Menu; import android.view.Menu;
@ -52,7 +52,7 @@ public class HistoryBrowseActivity extends AppCompatActivity {
ImageButton chartButton; ImageButton chartButton;
boolean showBasal = true; boolean showBasal = true;
boolean showIob, showCob, showDev, showRat, showDevslope; boolean showIob, showCob, showDev, showRat, showActPrim, showActSec, showDevslope;
@BindView(R.id.historybrowse_date) @BindView(R.id.historybrowse_date)
@ -285,6 +285,10 @@ public class HistoryBrowseActivity extends AppCompatActivity {
// set manual x bounds to have nice steps // set manual x bounds to have nice steps
graphData.formatAxis(fromTime, toTime); graphData.formatAxis(fromTime, toTime);
if(showActPrim) {
graphData.addActivity(fromTime, toTime, false,1d);
}
// Treatments // Treatments
graphData.addTreatments(fromTime, toTime); graphData.addTreatments(fromTime, toTime);
@ -305,6 +309,7 @@ public class HistoryBrowseActivity extends AppCompatActivity {
boolean useCobForScale = false; boolean useCobForScale = false;
boolean useDevForScale = false; boolean useDevForScale = false;
boolean useRatioForScale = false; boolean useRatioForScale = false;
boolean useIAForScale = false;
boolean useDSForScale = false; boolean useDSForScale = false;
if (showIob) { if (showIob) {
@ -315,6 +320,8 @@ public class HistoryBrowseActivity extends AppCompatActivity {
useDevForScale = true; useDevForScale = true;
} else if (showRat) { } else if (showRat) {
useRatioForScale = true; useRatioForScale = true;
} else if (showActSec) {
useIAForScale = true;
} else if (showDevslope) { } else if (showDevslope) {
useDSForScale = true; useDSForScale = true;
} }
@ -327,6 +334,8 @@ public class HistoryBrowseActivity extends AppCompatActivity {
secondGraphData.addDeviations(fromTime, toTime, useDevForScale, 1d); secondGraphData.addDeviations(fromTime, toTime, useDevForScale, 1d);
if (showRat) if (showRat)
secondGraphData.addRatio(fromTime, toTime, useRatioForScale, 1d); secondGraphData.addRatio(fromTime, toTime, useRatioForScale, 1d);
if (showActSec)
secondGraphData.addActivity(fromTime, toTime, useIAForScale, useIAForScale? 2d: 1d);
if (showDevslope) if (showDevslope)
secondGraphData.addDeviationSlope(fromTime, toTime, useDSForScale, 1d); secondGraphData.addDeviationSlope(fromTime, toTime, useDSForScale, 1d);
@ -337,14 +346,14 @@ public class HistoryBrowseActivity extends AppCompatActivity {
// do GUI update // do GUI update
runOnUiThread(() -> { runOnUiThread(() -> {
if (showIob || showCob || showDev || showRat || showDevslope) { if (showIob || showCob || showDev || showRat || showActSec || showDevslope) {
iobGraph.setVisibility(View.VISIBLE); iobGraph.setVisibility(View.VISIBLE);
} else { } else {
iobGraph.setVisibility(View.GONE); iobGraph.setVisibility(View.GONE);
} }
// finally enforce drawing of graphs // finally enforce drawing of graphs
graphData.performUpdate(); graphData.performUpdate();
if (showIob || showCob || showDev || showRat || showDevslope) if (showIob || showCob || showDev || showRat || showActSec || showDevslope)
secondGraphData.performUpdate(); secondGraphData.performUpdate();
}); });
}).start(); }).start();
@ -353,22 +362,37 @@ public class HistoryBrowseActivity extends AppCompatActivity {
private void setupChartMenu() { private void setupChartMenu() {
chartButton = (ImageButton) findViewById(R.id.overview_chartMenuButton); chartButton = (ImageButton) findViewById(R.id.overview_chartMenuButton);
chartButton.setOnClickListener(v -> { chartButton.setOnClickListener(v -> {
MenuItem item; MenuItem item,dividerItem;
CharSequence title; CharSequence title;
int titleMaxChars = 0;
SpannableString s; SpannableString s;
PopupMenu popup = new PopupMenu(v.getContext(), v); PopupMenu popup = new PopupMenu(v.getContext(), v);
item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.BAS.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_basals)); item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.BAS.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_basals));
title = item.getTitle(); title = item.getTitle();
if (titleMaxChars < title.length()) titleMaxChars = title.length();
s = new SpannableString(title); s = new SpannableString(title);
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.basal, null)), 0, s.length(), 0); s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.basal, null)), 0, s.length(), 0);
item.setTitle(s); item.setTitle(s);
item.setCheckable(true); item.setCheckable(true);
item.setChecked(showBasal); item.setChecked(showBasal);
item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.ACTPRIM.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_activity));
title = item.getTitle();
if (titleMaxChars < title.length()) titleMaxChars = title.length();
s = new SpannableString(title);
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.activity, null)), 0, s.length(), 0);
item.setTitle(s);
item.setCheckable(true);
item.setChecked(showActPrim);
dividerItem = popup.getMenu().add("");
dividerItem.setEnabled(false);
item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.IOB.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_iob)); item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.IOB.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_iob));
title = item.getTitle(); title = item.getTitle();
if (titleMaxChars < title.length()) titleMaxChars = title.length();
s = new SpannableString(title); s = new SpannableString(title);
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.iob, null)), 0, s.length(), 0); s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.iob, null)), 0, s.length(), 0);
item.setTitle(s); item.setTitle(s);
@ -377,6 +401,7 @@ public class HistoryBrowseActivity extends AppCompatActivity {
item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.COB.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_cob)); item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.COB.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_cob));
title = item.getTitle(); title = item.getTitle();
if (titleMaxChars < title.length()) titleMaxChars = title.length();
s = new SpannableString(title); s = new SpannableString(title);
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.cob, null)), 0, s.length(), 0); s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.cob, null)), 0, s.length(), 0);
item.setTitle(s); item.setTitle(s);
@ -385,6 +410,7 @@ public class HistoryBrowseActivity extends AppCompatActivity {
item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.DEV.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_deviations)); item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.DEV.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_deviations));
title = item.getTitle(); title = item.getTitle();
if (titleMaxChars < title.length()) titleMaxChars = title.length();
s = new SpannableString(title); s = new SpannableString(title);
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.deviations, null)), 0, s.length(), 0); s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.deviations, null)), 0, s.length(), 0);
item.setTitle(s); item.setTitle(s);
@ -393,15 +419,27 @@ public class HistoryBrowseActivity extends AppCompatActivity {
item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.SEN.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_sensitivity)); item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.SEN.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_sensitivity));
title = item.getTitle(); title = item.getTitle();
if (titleMaxChars < title.length()) titleMaxChars = title.length();
s = new SpannableString(title); s = new SpannableString(title);
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.ratio, null)), 0, s.length(), 0); s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.ratio, null)), 0, s.length(), 0);
item.setTitle(s); item.setTitle(s);
item.setCheckable(true); item.setCheckable(true);
item.setChecked(showRat); item.setChecked(showRat);
item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.ACTSEC.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_activity));
title = item.getTitle();
if (titleMaxChars < title.length()) titleMaxChars = title.length();
s = new SpannableString(title);
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.activity, null)), 0, s.length(), 0);
item.setTitle(s);
item.setCheckable(true);
item.setChecked(showActSec);
if (MainApp.devBranch) { if (MainApp.devBranch) {
item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.DEVSLOPE.ordinal(), Menu.NONE, "Deviation slope"); item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.DEVSLOPE.ordinal(), Menu.NONE, "Deviation slope");
title = item.getTitle(); title = item.getTitle();
if (titleMaxChars < title.length()) titleMaxChars = title.length();
s = new SpannableString(title); s = new SpannableString(title);
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.devslopepos, null)), 0, s.length(), 0); s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.devslopepos, null)), 0, s.length(), 0);
item.setTitle(s); item.setTitle(s);
@ -409,6 +447,10 @@ public class HistoryBrowseActivity extends AppCompatActivity {
item.setChecked(showDevslope); item.setChecked(showDevslope);
} }
// Fairly good guestimate for required divider text size...
title = new String(new char[titleMaxChars+10]).replace("\0", "_");
dividerItem.setTitle(title);
popup.setOnMenuItemClickListener(item1 -> { popup.setOnMenuItemClickListener(item1 -> {
if (item1.getItemId() == OverviewFragment.CHARTTYPE.BAS.ordinal()) { if (item1.getItemId() == OverviewFragment.CHARTTYPE.BAS.ordinal()) {
showBasal = !item1.isChecked(); showBasal = !item1.isChecked();
@ -420,6 +462,10 @@ public class HistoryBrowseActivity extends AppCompatActivity {
showDev = !item1.isChecked(); showDev = !item1.isChecked();
} else if (item1.getItemId() == OverviewFragment.CHARTTYPE.SEN.ordinal()) { } else if (item1.getItemId() == OverviewFragment.CHARTTYPE.SEN.ordinal()) {
showRat = !item1.isChecked(); showRat = !item1.isChecked();
} else if (item1.getItemId() == OverviewFragment.CHARTTYPE.ACTPRIM.ordinal()) {
showActPrim = !item1.isChecked();
} else if (item1.getItemId() == OverviewFragment.CHARTTYPE.ACTSEC.ordinal()) {
showActSec = !item1.isChecked();
} else if (item1.getItemId() == OverviewFragment.CHARTTYPE.DEVSLOPE.ordinal()) { } else if (item1.getItemId() == OverviewFragment.CHARTTYPE.DEVSLOPE.ordinal()) {
showDevslope = !item1.isChecked(); showDevslope = !item1.isChecked();
} }

View file

@ -15,12 +15,15 @@ import android.text.TextUtils;
import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.events.EventPreferenceChange; import info.nightscout.androidaps.events.EventPreferenceChange;
import info.nightscout.androidaps.events.EventRefreshGui; import info.nightscout.androidaps.events.EventRefreshGui;
import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.plugins.general.careportal.CareportalPlugin; import info.nightscout.androidaps.plugins.general.careportal.CareportalPlugin;
import info.nightscout.androidaps.plugins.constraints.safety.SafetyPlugin; import info.nightscout.androidaps.plugins.constraints.safety.SafetyPlugin;
import info.nightscout.androidaps.plugins.general.tidepool.TidepoolPlugin;
import info.nightscout.androidaps.plugins.general.tidepool.comm.TidepoolUploader;
import info.nightscout.androidaps.plugins.insulin.InsulinOrefFreePeakPlugin; import info.nightscout.androidaps.plugins.insulin.InsulinOrefFreePeakPlugin;
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin; import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin;
import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin; import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin;
@ -39,9 +42,9 @@ import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref0Plugin;
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin; import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin;
import info.nightscout.androidaps.plugins.sensitivity.SensitivityWeightedAveragePlugin; import info.nightscout.androidaps.plugins.sensitivity.SensitivityWeightedAveragePlugin;
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin; import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin;
import info.nightscout.androidaps.plugins.source.SourceDexcomG5Plugin;
import info.nightscout.androidaps.plugins.general.wear.WearPlugin; import info.nightscout.androidaps.plugins.general.wear.WearPlugin;
import info.nightscout.androidaps.plugins.general.xdripStatusline.StatuslinePlugin; import info.nightscout.androidaps.plugins.general.xdripStatusline.StatuslinePlugin;
import info.nightscout.androidaps.plugins.source.SourceDexcomPlugin;
import info.nightscout.androidaps.utils.LocaleHelper; import info.nightscout.androidaps.utils.LocaleHelper;
import info.nightscout.androidaps.utils.OKDialog; import info.nightscout.androidaps.utils.OKDialog;
import info.nightscout.androidaps.utils.SP; import info.nightscout.androidaps.utils.SP;
@ -63,6 +66,7 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
@Override @Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
MainApp.bus().post(new EventPreferenceChange(key)); MainApp.bus().post(new EventPreferenceChange(key));
RxBus.INSTANCE.send(new EventPreferenceChange(key));
if (key.equals("language")) { if (key.equals("language")) {
String lang = sharedPreferences.getString("language", "en"); String lang = sharedPreferences.getString("language", "en");
LocaleHelper.setLocale(getApplicationContext(), lang); LocaleHelper.setLocale(getApplicationContext(), lang);
@ -93,7 +97,7 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
} else if (editTextPref.getText() != null) { } else if (editTextPref.getText() != null) {
((EditTextPreference) pref).setDialogMessage(editTextPref.getDialogMessage()); ((EditTextPreference) pref).setDialogMessage(editTextPref.getDialogMessage());
pref.setSummary(editTextPref.getText()); pref.setSummary(editTextPref.getText());
} else if (pref.getKey().contains("smscommunicator_allowednumbers") && TextUtils.isEmpty(editTextPref.getText().trim())) { } else if (pref.getKey().contains("smscommunicator_allowednumbers") && (editTextPref.getText() == null || TextUtils.isEmpty(editTextPref.getText().trim()))) {
pref.setSummary(MainApp.gs(R.string.smscommunicator_allowednumbers_summary)); pref.setSummary(MainApp.gs(R.string.smscommunicator_allowednumbers_summary));
} }
} }
@ -144,7 +148,7 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
addPreferencesFromResource(R.xml.pref_overview); addPreferencesFromResource(R.xml.pref_overview);
addPreferencesFromResourceIfEnabled(SourceDexcomG5Plugin.getPlugin(), PluginType.BGSOURCE); addPreferencesFromResourceIfEnabled(SourceDexcomPlugin.INSTANCE, PluginType.BGSOURCE);
addPreferencesFromResourceIfEnabled(CareportalPlugin.getPlugin(), PluginType.GENERAL); addPreferencesFromResourceIfEnabled(CareportalPlugin.getPlugin(), PluginType.GENERAL);
addPreferencesFromResourceIfEnabled(SafetyPlugin.getPlugin(), PluginType.CONSTRAINTS); addPreferencesFromResourceIfEnabled(SafetyPlugin.getPlugin(), PluginType.CONSTRAINTS);
if (Config.APS) { if (Config.APS) {
@ -182,6 +186,7 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
addPreferencesFromResourceIfEnabled(InsulinOrefFreePeakPlugin.getPlugin(), PluginType.INSULIN); addPreferencesFromResourceIfEnabled(InsulinOrefFreePeakPlugin.getPlugin(), PluginType.INSULIN);
addPreferencesFromResourceIfEnabled(NSClientPlugin.getPlugin(), PluginType.GENERAL); addPreferencesFromResourceIfEnabled(NSClientPlugin.getPlugin(), PluginType.GENERAL);
addPreferencesFromResourceIfEnabled(TidepoolPlugin.INSTANCE, PluginType.GENERAL);
addPreferencesFromResourceIfEnabled(SmsCommunicatorPlugin.getPlugin(), PluginType.GENERAL); addPreferencesFromResourceIfEnabled(SmsCommunicatorPlugin.getPlugin(), PluginType.GENERAL);
addPreferencesFromResource(R.xml.pref_others); addPreferencesFromResource(R.xml.pref_others);
@ -192,7 +197,7 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
} }
if (Config.NSCLIENT) { if (Config.NSCLIENT) {
PreferenceScreen scrnAdvancedSettings = (PreferenceScreen)findPreference(getString(R.string.key_advancedsettings)); PreferenceScreen scrnAdvancedSettings = (PreferenceScreen) findPreference(getString(R.string.key_advancedsettings));
if (scrnAdvancedSettings != null) { if (scrnAdvancedSettings != null) {
scrnAdvancedSettings.removePreference(getPreference(getString(R.string.key_statuslights_res_warning))); scrnAdvancedSettings.removePreference(getPreference(getString(R.string.key_statuslights_res_warning)));
scrnAdvancedSettings.removePreference(getPreference(getString(R.string.key_statuslights_res_critical))); scrnAdvancedSettings.removePreference(getPreference(getString(R.string.key_statuslights_res_critical)));
@ -203,6 +208,13 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
} }
initSummary(getPreferenceScreen()); initSummary(getPreferenceScreen());
final Preference tidepoolTestLogin = findPreference(MainApp.gs(R.string.key_tidepool_test_login));
if (tidepoolTestLogin != null)
tidepoolTestLogin.setOnPreferenceClickListener(preference -> {
TidepoolUploader.INSTANCE.testLogin(getActivity());
return false;
});
} }
@Override @Override

View file

@ -0,0 +1,25 @@
package info.nightscout.androidaps.activities
import android.os.Build
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import info.nightscout.androidaps.plugins.source.SourceDexcomPlugin
class RequestDexcomPermissionActivity : AppCompatActivity() {
private val requestCode = "AndroidAPS <3".map { it.toInt() }.sum()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(arrayOf(SourceDexcomPlugin.PERMISSION), requestCode)
} else {
finish()
}
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
finish()
}
}

View file

@ -2,9 +2,9 @@ package info.nightscout.androidaps.activities;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable; import androidx.annotation.Nullable;
import android.support.v4.app.Fragment; import androidx.fragment.app.Fragment;
import android.support.v7.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;

View file

@ -4,7 +4,7 @@ import android.app.Activity;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.Rect; import android.graphics.Rect;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.MotionEvent; import android.view.MotionEvent;

View file

@ -1,5 +1,7 @@
package info.nightscout.androidaps.data; package info.nightscout.androidaps.data;
import androidx.annotation.NonNull;
import java.util.ArrayList; import java.util.ArrayList;
import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.Constants;
@ -15,13 +17,6 @@ import info.nightscout.androidaps.interfaces.PluginType;
public class ConstraintChecker implements ConstraintsInterface { public class ConstraintChecker implements ConstraintsInterface {
private MainApp mainApp;
public ConstraintChecker(MainApp mainApp) {
this.mainApp = mainApp;
}
public Constraint<Boolean> isLoopInvokationAllowed() { public Constraint<Boolean> isLoopInvokationAllowed() {
return isLoopInvocationAllowed(new Constraint<>(true)); return isLoopInvocationAllowed(new Constraint<>(true));
} }
@ -79,9 +74,9 @@ public class ConstraintChecker implements ConstraintsInterface {
} }
@Override @Override
public Constraint<Boolean> isLoopInvocationAllowed(Constraint<Boolean> value) { public Constraint<Boolean> isLoopInvocationAllowed(@NonNull Constraint<Boolean> value) {
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); ArrayList<PluginBase> constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
for (PluginBase p : constraintsPlugins) { for (PluginBase p : constraintsPlugins) {
ConstraintsInterface constraint = (ConstraintsInterface) p; ConstraintsInterface constraint = (ConstraintsInterface) p;
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue; if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
@ -91,9 +86,9 @@ public class ConstraintChecker implements ConstraintsInterface {
} }
@Override @Override
public Constraint<Boolean> isClosedLoopAllowed(Constraint<Boolean> value) { public Constraint<Boolean> isClosedLoopAllowed(@NonNull Constraint<Boolean> value) {
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); ArrayList<PluginBase> constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
for (PluginBase p : constraintsPlugins) { for (PluginBase p : constraintsPlugins) {
ConstraintsInterface constraint = (ConstraintsInterface) p; ConstraintsInterface constraint = (ConstraintsInterface) p;
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue; if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
@ -103,9 +98,9 @@ public class ConstraintChecker implements ConstraintsInterface {
} }
@Override @Override
public Constraint<Boolean> isAutosensModeEnabled(Constraint<Boolean> value) { public Constraint<Boolean> isAutosensModeEnabled(@NonNull Constraint<Boolean> value) {
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); ArrayList<PluginBase> constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
for (PluginBase p : constraintsPlugins) { for (PluginBase p : constraintsPlugins) {
ConstraintsInterface constraint = (ConstraintsInterface) p; ConstraintsInterface constraint = (ConstraintsInterface) p;
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue; if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
@ -115,9 +110,9 @@ public class ConstraintChecker implements ConstraintsInterface {
} }
@Override @Override
public Constraint<Boolean> isAMAModeEnabled(Constraint<Boolean> value) { public Constraint<Boolean> isAMAModeEnabled(@NonNull Constraint<Boolean> value) {
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); ArrayList<PluginBase> constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
for (PluginBase p : constraintsPlugins) { for (PluginBase p : constraintsPlugins) {
ConstraintsInterface constrain = (ConstraintsInterface) p; ConstraintsInterface constrain = (ConstraintsInterface) p;
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue; if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
@ -127,9 +122,9 @@ public class ConstraintChecker implements ConstraintsInterface {
} }
@Override @Override
public Constraint<Boolean> isSMBModeEnabled(Constraint<Boolean> value) { public Constraint<Boolean> isSMBModeEnabled(@NonNull Constraint<Boolean> value) {
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); ArrayList<PluginBase> constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
for (PluginBase p : constraintsPlugins) { for (PluginBase p : constraintsPlugins) {
ConstraintsInterface constraint = (ConstraintsInterface) p; ConstraintsInterface constraint = (ConstraintsInterface) p;
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue; if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
@ -139,9 +134,9 @@ public class ConstraintChecker implements ConstraintsInterface {
} }
@Override @Override
public Constraint<Boolean> isUAMEnabled(Constraint<Boolean> value) { public Constraint<Boolean> isUAMEnabled(@NonNull Constraint<Boolean> value) {
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); ArrayList<PluginBase> constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
for (PluginBase p : constraintsPlugins) { for (PluginBase p : constraintsPlugins) {
ConstraintsInterface constraint = (ConstraintsInterface) p; ConstraintsInterface constraint = (ConstraintsInterface) p;
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue; if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
@ -151,8 +146,8 @@ public class ConstraintChecker implements ConstraintsInterface {
} }
@Override @Override
public Constraint<Boolean> isAdvancedFilteringEnabled(Constraint<Boolean> value) { public Constraint<Boolean> isAdvancedFilteringEnabled(@NonNull Constraint<Boolean> value) {
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); ArrayList<PluginBase> constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
for (PluginBase p : constraintsPlugins) { for (PluginBase p : constraintsPlugins) {
ConstraintsInterface constraint = (ConstraintsInterface) p; ConstraintsInterface constraint = (ConstraintsInterface) p;
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue; if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
@ -162,8 +157,8 @@ public class ConstraintChecker implements ConstraintsInterface {
} }
@Override @Override
public Constraint<Boolean> isSuperBolusEnabled(Constraint<Boolean> value) { public Constraint<Boolean> isSuperBolusEnabled(@NonNull Constraint<Boolean> value) {
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); ArrayList<PluginBase> constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
for (PluginBase p : constraintsPlugins) { for (PluginBase p : constraintsPlugins) {
ConstraintsInterface constraint = (ConstraintsInterface) p; ConstraintsInterface constraint = (ConstraintsInterface) p;
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue; if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
@ -173,8 +168,8 @@ public class ConstraintChecker implements ConstraintsInterface {
} }
@Override @Override
public Constraint<Double> applyBasalConstraints(Constraint<Double> absoluteRate, Profile profile) { public Constraint<Double> applyBasalConstraints(@NonNull Constraint<Double> absoluteRate, Profile profile) {
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); ArrayList<PluginBase> constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
for (PluginBase p : constraintsPlugins) { for (PluginBase p : constraintsPlugins) {
ConstraintsInterface constraint = (ConstraintsInterface) p; ConstraintsInterface constraint = (ConstraintsInterface) p;
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue; if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
@ -184,8 +179,8 @@ public class ConstraintChecker implements ConstraintsInterface {
} }
@Override @Override
public Constraint<Integer> applyBasalPercentConstraints(Constraint<Integer> percentRate, Profile profile) { public Constraint<Integer> applyBasalPercentConstraints(@NonNull Constraint<Integer> percentRate, Profile profile) {
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); ArrayList<PluginBase> constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
for (PluginBase p : constraintsPlugins) { for (PluginBase p : constraintsPlugins) {
ConstraintsInterface constrain = (ConstraintsInterface) p; ConstraintsInterface constrain = (ConstraintsInterface) p;
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue; if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
@ -195,8 +190,8 @@ public class ConstraintChecker implements ConstraintsInterface {
} }
@Override @Override
public Constraint<Double> applyBolusConstraints(Constraint<Double> insulin) { public Constraint<Double> applyBolusConstraints(@NonNull Constraint<Double> insulin) {
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); ArrayList<PluginBase> constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
for (PluginBase p : constraintsPlugins) { for (PluginBase p : constraintsPlugins) {
ConstraintsInterface constrain = (ConstraintsInterface) p; ConstraintsInterface constrain = (ConstraintsInterface) p;
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue; if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
@ -206,8 +201,8 @@ public class ConstraintChecker implements ConstraintsInterface {
} }
@Override @Override
public Constraint<Double> applyExtendedBolusConstraints(Constraint<Double> insulin) { public Constraint<Double> applyExtendedBolusConstraints(@NonNull Constraint<Double> insulin) {
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); ArrayList<PluginBase> constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
for (PluginBase p : constraintsPlugins) { for (PluginBase p : constraintsPlugins) {
ConstraintsInterface constrain = (ConstraintsInterface) p; ConstraintsInterface constrain = (ConstraintsInterface) p;
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue; if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
@ -217,8 +212,8 @@ public class ConstraintChecker implements ConstraintsInterface {
} }
@Override @Override
public Constraint<Integer> applyCarbsConstraints(Constraint<Integer> carbs) { public Constraint<Integer> applyCarbsConstraints(@NonNull Constraint<Integer> carbs) {
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); ArrayList<PluginBase> constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
for (PluginBase p : constraintsPlugins) { for (PluginBase p : constraintsPlugins) {
ConstraintsInterface constrain = (ConstraintsInterface) p; ConstraintsInterface constrain = (ConstraintsInterface) p;
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue; if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
@ -228,8 +223,8 @@ public class ConstraintChecker implements ConstraintsInterface {
} }
@Override @Override
public Constraint<Double> applyMaxIOBConstraints(Constraint<Double> maxIob) { public Constraint<Double> applyMaxIOBConstraints(@NonNull Constraint<Double> maxIob) {
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); ArrayList<PluginBase> constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
for (PluginBase p : constraintsPlugins) { for (PluginBase p : constraintsPlugins) {
ConstraintsInterface constrain = (ConstraintsInterface) p; ConstraintsInterface constrain = (ConstraintsInterface) p;
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue; if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;

View file

@ -1,178 +0,0 @@
package info.nightscout.androidaps.data;
import android.support.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
import info.nightscout.androidaps.db.BgReading;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.DecimalFormatter;
import info.nightscout.androidaps.utils.Round;
/**
* Created by mike on 04.01.2017.
*/
public class GlucoseStatus {
private static Logger log = LoggerFactory.getLogger(GlucoseStatus.class);
public double glucose = 0d;
public double delta = 0d;
public double avgdelta = 0d;
public double short_avgdelta = 0d;
public double long_avgdelta = 0d;
public long date = 0L;
public String log() {
return "Glucose: " + DecimalFormatter.to0Decimal(glucose) + " mg/dl " +
"Delta: " + DecimalFormatter.to0Decimal(delta) + " mg/dl" +
"Short avg. delta: " + " " + DecimalFormatter.to2Decimal(short_avgdelta) + " mg/dl " +
"Long avg. delta: " + DecimalFormatter.to2Decimal(long_avgdelta) + " mg/dl";
}
public GlucoseStatus() {
}
public GlucoseStatus round() {
this.glucose = Round.roundTo(this.glucose, 0.1);
this.delta = Round.roundTo(this.delta, 0.01);
this.avgdelta = Round.roundTo(this.avgdelta, 0.01);
this.short_avgdelta = Round.roundTo(this.short_avgdelta, 0.01);
this.long_avgdelta = Round.roundTo(this.long_avgdelta, 0.01);
return this;
}
@Nullable
public static GlucoseStatus getGlucoseStatusData() {
return getGlucoseStatusData(false);
}
@Nullable
public static GlucoseStatus getGlucoseStatusData(boolean allowOldData) {
// load 45min
//long fromtime = DateUtil.now() - 60 * 1000L * 45;
//List<BgReading> data = MainApp.getDbHelper().getBgreadingsDataFromTime(fromtime, false);
List<BgReading> data = IobCobCalculatorPlugin.getPlugin().getBgReadings();
if (data == null) {
if (L.isEnabled(L.GLUCOSE))
log.debug("data=null");
return null;
}
int sizeRecords = data.size();
if (sizeRecords == 0) {
if (L.isEnabled(L.GLUCOSE))
log.debug("sizeRecords==0");
return null;
}
if (data.get(0).date < DateUtil.now() - 7 * 60 * 1000L && !allowOldData) {
if (L.isEnabled(L.GLUCOSE))
log.debug("olddata");
return null;
}
BgReading now = data.get(0);
long now_date = now.date;
double change;
if (sizeRecords == 1) {
GlucoseStatus status = new GlucoseStatus();
status.glucose = now.value;
status.short_avgdelta = 0d;
status.delta = 0d;
status.long_avgdelta = 0d;
status.avgdelta = 0d; // for OpenAPS MA
status.date = now_date;
if (L.isEnabled(L.GLUCOSE))
log.debug("sizeRecords==1");
return status.round();
}
ArrayList<Double> now_value_list = new ArrayList<>();
ArrayList<Double> last_deltas = new ArrayList<>();
ArrayList<Double> short_deltas = new ArrayList<>();
ArrayList<Double> long_deltas = new ArrayList<>();
// Use the latest sgv value in the now calculations
now_value_list.add(now.value);
for (int i = 1; i < sizeRecords; i++) {
if (data.get(i).value > 38) {
BgReading then = data.get(i);
long then_date = then.date;
double avgdelta;
long minutesago;
minutesago = Math.round((now_date - then_date) / (1000d * 60));
// multiply by 5 to get the same units as delta, i.e. mg/dL/5m
change = now.value - then.value;
avgdelta = change / minutesago * 5;
if (L.isEnabled(L.GLUCOSE))
log.debug(then.toString() + " minutesago=" + minutesago + " avgdelta=" + avgdelta);
// use the average of all data points in the last 2.5m for all further "now" calculations
if (0 < minutesago && minutesago < 2.5) {
// Keep and average all values within the last 2.5 minutes
now_value_list.add(then.value);
now.value = average(now_value_list);
// short_deltas are calculated from everything ~5-15 minutes ago
} else if (2.5 < minutesago && minutesago < 17.5) {
//console.error(minutesago, avgdelta);
short_deltas.add(avgdelta);
// last_deltas are calculated from everything ~5 minutes ago
if (2.5 < minutesago && minutesago < 7.5) {
last_deltas.add(avgdelta);
}
// long_deltas are calculated from everything ~20-40 minutes ago
} else if (17.5 < minutesago && minutesago < 42.5) {
long_deltas.add(avgdelta);
} else {
// Do not process any more records after >= 42.5 minutes
break;
}
}
}
GlucoseStatus status = new GlucoseStatus();
status.glucose = now.value;
status.date = now_date;
status.short_avgdelta = average(short_deltas);
if (last_deltas.isEmpty()) {
status.delta = status.short_avgdelta;
} else {
status.delta = average(last_deltas);
}
status.long_avgdelta = average(long_deltas);
status.avgdelta = status.short_avgdelta; // for OpenAPS MA
if (L.isEnabled(L.GLUCOSE))
log.debug(status.log());
return status.round();
}
public static double average(ArrayList<Double> array) {
double sum = 0d;
if (array.size() == 0)
return 0d;
for (Double value : array) {
sum += value;
}
return sum / array.size();
}
}

View file

@ -1,7 +1,7 @@
package info.nightscout.androidaps.data; package info.nightscout.androidaps.data;
import android.support.annotation.Nullable; import androidx.annotation.Nullable;
import android.support.v4.util.LongSparseArray; import androidx.collection.LongSparseArray;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;

View file

@ -1,10 +1,8 @@
package info.nightscout.androidaps.data; package info.nightscout.androidaps.data;
import android.support.annotation.Nullable; import androidx.annotation.Nullable;
import android.support.v4.util.LongSparseArray;
import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.interfaces.Interval; import info.nightscout.androidaps.interfaces.Interval;
/** /**
@ -21,7 +19,7 @@ public class NonOverlappingIntervals<T extends Interval> extends Intervals<T> {
rawData = other.rawData.clone(); rawData = other.rawData.clone();
} }
protected synchronized void merge() { public synchronized void merge() {
for (int index = 0; index < rawData.size() - 1; index++) { for (int index = 0; index < rawData.size() - 1; index++) {
Interval i = rawData.valueAt(index); Interval i = rawData.valueAt(index);
long startOfNewer = rawData.valueAt(index + 1).start(); long startOfNewer = rawData.valueAt(index + 1).start();

View file

@ -1,7 +1,7 @@
package info.nightscout.androidaps.data; package info.nightscout.androidaps.data;
import android.support.annotation.Nullable; import androidx.annotation.Nullable;
import info.nightscout.androidaps.interfaces.Interval; import info.nightscout.androidaps.interfaces.Interval;

View file

@ -1,6 +1,6 @@
package info.nightscout.androidaps.data; package info.nightscout.androidaps.data;
import android.support.v4.util.LongSparseArray; import androidx.collection.LongSparseArray;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
@ -400,6 +400,19 @@ public class Profile {
return getValuesList(isf_v, null, new DecimalFormat("0.0"), getUnits() + MainApp.gs(R.string.profile_per_unit)); return getValuesList(isf_v, null, new DecimalFormat("0.0"), getUnits() + MainApp.gs(R.string.profile_per_unit));
} }
public ProfileValue[] getIsfs() {
if (isf_v == null)
isf_v = convertToSparseArray(ic);
ProfileValue[] ret = new ProfileValue[isf_v.size()];
for (Integer index = 0; index < isf_v.size(); index++) {
Integer tas = (int) isf_v.keyAt(index);
double value = isf_v.valueAt(index);
ret[index] = new ProfileValue(tas, value);
}
return ret;
}
public double getIc() { public double getIc() {
return getIcTimeFromMidnight(secondsFromMidnight()); return getIcTimeFromMidnight(secondsFromMidnight());
} }
@ -420,6 +433,19 @@ public class Profile {
return getValuesList(ic_v, null, new DecimalFormat("0.0"), MainApp.gs(R.string.profile_carbs_per_unit)); return getValuesList(ic_v, null, new DecimalFormat("0.0"), MainApp.gs(R.string.profile_carbs_per_unit));
} }
public ProfileValue[] getIcs() {
if (ic_v == null)
ic_v = convertToSparseArray(ic);
ProfileValue[] ret = new ProfileValue[ic_v.size()];
for (Integer index = 0; index < ic_v.size(); index++) {
Integer tas = (int) ic_v.keyAt(index);
double value = ic_v.valueAt(index);
ret[index] = new ProfileValue(tas, value);
}
return ret;
}
public double getBasal() { public double getBasal() {
return getBasalTimeFromMidnight(secondsFromMidnight()); return getBasalTimeFromMidnight(secondsFromMidnight());
} }
@ -441,8 +467,8 @@ public class Profile {
return getValuesList(basal_v, null, new DecimalFormat("0.00"), MainApp.gs(R.string.profile_ins_units_per_hout)); return getValuesList(basal_v, null, new DecimalFormat("0.00"), MainApp.gs(R.string.profile_ins_units_per_hout));
} }
public class BasalValue { public class ProfileValue {
public BasalValue(int timeAsSeconds, double value) { public ProfileValue(int timeAsSeconds, double value) {
this.timeAsSeconds = timeAsSeconds; this.timeAsSeconds = timeAsSeconds;
this.value = value; this.value = value;
} }
@ -451,15 +477,15 @@ public class Profile {
public double value; public double value;
} }
public synchronized BasalValue[] getBasalValues() { public synchronized ProfileValue[] getBasalValues() {
if (basal_v == null) if (basal_v == null)
basal_v = convertToSparseArray(basal); basal_v = convertToSparseArray(basal);
BasalValue[] ret = new BasalValue[basal_v.size()]; ProfileValue[] ret = new ProfileValue[basal_v.size()];
for (Integer index = 0; index < basal_v.size(); index++) { for (Integer index = 0; index < basal_v.size(); index++) {
Integer tas = (int) basal_v.keyAt(index); Integer tas = (int) basal_v.keyAt(index);
double value = basal_v.valueAt(index); double value = basal_v.valueAt(index);
ret[index] = new BasalValue(tas, value); ret[index] = new ProfileValue(tas, value);
} }
return ret; return ret;
} }
@ -500,6 +526,49 @@ public class Profile {
return getValueToTime(targetHigh_v, timeAsSeconds); return getValueToTime(targetHigh_v, timeAsSeconds);
} }
public class TargetValue {
public TargetValue(int timeAsSeconds, double low, double high) {
this.timeAsSeconds = timeAsSeconds;
this.low = low;
this.high = high;
}
public int timeAsSeconds;
public double low;
public double high;
}
public TargetValue[] getTargets() {
if (targetLow_v == null)
targetLow_v = convertToSparseArray(targetLow);
if (targetHigh_v == null)
targetHigh_v = convertToSparseArray(targetHigh);
TargetValue[] ret = new TargetValue[targetLow_v.size()];
for (Integer index = 0; index < targetLow_v.size(); index++) {
Integer tas = (int) targetLow_v.keyAt(index);
double low = targetLow_v.valueAt(index);
double high = targetHigh_v.valueAt(index);
ret[index] = new TargetValue(tas, low, high);
}
return ret;
}
public ProfileValue[] getSingleTargets() {
if (targetLow_v == null)
targetLow_v = convertToSparseArray(targetLow);
if (targetHigh_v == null)
targetHigh_v = convertToSparseArray(targetHigh);
ProfileValue[] ret = new ProfileValue[targetLow_v.size()];
for (Integer index = 0; index < targetLow_v.size(); index++) {
Integer tas = (int) targetLow_v.keyAt(index);
double target = (targetLow_v.valueAt(index) + targetHigh_v.valueAt(index)) / 2;
ret[index] = new ProfileValue(tas, target);
}
return ret;
}
public String getTargetList() { public String getTargetList() {
if (targetLow_v == null) if (targetLow_v == null)
targetLow_v = convertToSparseArray(targetLow); targetLow_v = convertToSparseArray(targetLow);

View file

@ -1,7 +1,7 @@
package info.nightscout.androidaps.data; package info.nightscout.androidaps.data;
import android.support.annotation.Nullable; import androidx.annotation.Nullable;
import android.support.v4.util.LongSparseArray; import androidx.collection.LongSparseArray;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;

View file

@ -1,7 +1,7 @@
package info.nightscout.androidaps.data; package info.nightscout.androidaps.data;
import android.support.annotation.Nullable; import androidx.annotation.Nullable;
import android.support.v4.util.ArrayMap; import androidx.collection.ArrayMap;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;

View file

@ -12,6 +12,7 @@ import info.nightscout.androidaps.db.BgReading;
import info.nightscout.androidaps.db.TempTarget; import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.androidaps.interfaces.TreatmentsInterface; import info.nightscout.androidaps.interfaces.TreatmentsInterface;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.CobInfo; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.CobInfo;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin; import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin;
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin; import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
@ -49,7 +50,7 @@ public class QuickWizardEntry {
useTemptarget: 0 useTemptarget: 0
} }
*/ */
public QuickWizardEntry() { QuickWizardEntry() {
String emptyData = "{\"buttonText\":\"\",\"carbs\":0,\"validFrom\":0,\"validTo\":86340}"; String emptyData = "{\"buttonText\":\"\",\"carbs\":0,\"validFrom\":0,\"validTo\":86340}";
try { try {
storage = new JSONObject(emptyData); storage = new JSONObject(emptyData);
@ -59,18 +60,17 @@ public class QuickWizardEntry {
position = -1; position = -1;
} }
public QuickWizardEntry(JSONObject entry, int position) { QuickWizardEntry(JSONObject entry, int position) {
storage = entry; storage = entry;
this.position = position; this.position = position;
} }
public Boolean isActive() { Boolean isActive() {
return Profile.secondsFromMidnight() >= validFrom() && Profile.secondsFromMidnight() <= validTo(); return Profile.secondsFromMidnight() >= validFrom() && Profile.secondsFromMidnight() <= validTo();
} }
public BolusWizard doCalc(Profile profile, TempTarget tempTarget, BgReading lastBG, boolean _synchronized) { public BolusWizard doCalc(Profile profile, String profileName, BgReading lastBG, boolean _synchronized) {
BolusWizard wizard = new BolusWizard(); final TempTarget tempTarget = TreatmentsPlugin.getPlugin().getTempTargetFromHistory();
//BG //BG
double bg = 0; double bg = 0;
if (lastBG != null && useBG() == YES) { if (lastBG != null && useBG() == YES) {
@ -85,11 +85,6 @@ public class QuickWizardEntry {
cob = cobInfo.displayCob; cob = cobInfo.displayCob;
} }
// Temp target
if (useTempTarget() == NO) {
tempTarget = null;
}
// Bolus IOB // Bolus IOB
boolean bolusIOB = false; boolean bolusIOB = false;
if (useBolusIOB() == YES) { if (useBolusIOB() == YES) {
@ -129,8 +124,7 @@ public class QuickWizardEntry {
trend = true; trend = true;
} }
wizard.doCalc(profile, tempTarget, carbs(), cob, bg, 0d, bolusIOB, basalIOB, superBolus, trend); return new BolusWizard(profile, profileName, tempTarget, carbs(), cob, bg, 0d, 100, true, useCOB() == YES, bolusIOB, basalIOB, superBolus, useTempTarget() == YES, trend, "QuickWizard");
return wizard;
} }
public String buttonText() { public String buttonText() {

View file

@ -3,7 +3,7 @@ package info.nightscout.androidaps.db;
import android.content.Context; import android.content.Context;
import android.database.DatabaseUtils; import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase;
import android.support.annotation.Nullable; import androidx.annotation.Nullable;
import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper; import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper;
import com.j256.ormlite.dao.CloseableIterator; import com.j256.ormlite.dao.CloseableIterator;
@ -29,6 +29,7 @@ import java.util.concurrent.TimeUnit;
import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.data.OverlappingIntervals; import info.nightscout.androidaps.data.OverlappingIntervals;
import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.ProfileStore; import info.nightscout.androidaps.data.ProfileStore;
@ -45,9 +46,9 @@ import info.nightscout.androidaps.events.EventTempTargetChange;
import info.nightscout.androidaps.interfaces.ProfileInterface; import info.nightscout.androidaps.interfaces.ProfileInterface;
import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryData; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryData;
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
import info.nightscout.androidaps.plugins.pump.danaR.activities.DanaRNSHistorySync; import info.nightscout.androidaps.plugins.pump.danaR.activities.DanaRNSHistorySync;
import info.nightscout.androidaps.plugins.pump.danaR.comm.RecordTypes; import info.nightscout.androidaps.plugins.pump.danaR.comm.RecordTypes;
import info.nightscout.androidaps.plugins.pump.insight.database.InsightBolusID; import info.nightscout.androidaps.plugins.pump.insight.database.InsightBolusID;
@ -83,7 +84,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
public static final String DATABASE_INSIGHT_BOLUS_IDS = "InsightBolusIDs"; public static final String DATABASE_INSIGHT_BOLUS_IDS = "InsightBolusIDs";
public static final String DATABASE_INSIGHT_PUMP_IDS = "InsightPumpIDs"; public static final String DATABASE_INSIGHT_PUMP_IDS = "InsightPumpIDs";
private static final int DATABASE_VERSION = 10; private static final int DATABASE_VERSION = 11;
public static Long earliestDataChange = null; public static Long earliestDataChange = null;
@ -131,6 +132,10 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
TableUtils.createTableIfNotExists(connectionSource, InsightHistoryOffset.class); TableUtils.createTableIfNotExists(connectionSource, InsightHistoryOffset.class);
TableUtils.createTableIfNotExists(connectionSource, InsightBolusID.class); TableUtils.createTableIfNotExists(connectionSource, InsightBolusID.class);
TableUtils.createTableIfNotExists(connectionSource, InsightPumpID.class); TableUtils.createTableIfNotExists(connectionSource, InsightPumpID.class);
database.execSQL("INSERT INTO sqlite_sequence (name, seq) SELECT \"" + DATABASE_INSIGHT_BOLUS_IDS + "\", " + System.currentTimeMillis() + " " +
"WHERE NOT EXISTS (SELECT 1 FROM sqlite_sequence WHERE name = \"" + DATABASE_INSIGHT_BOLUS_IDS + "\")");
database.execSQL("INSERT INTO sqlite_sequence (name, seq) SELECT \"" + DATABASE_INSIGHT_PUMP_IDS + "\", " + System.currentTimeMillis() + " " +
"WHERE NOT EXISTS (SELECT 1 FROM sqlite_sequence WHERE name = \"" + DATABASE_INSIGHT_PUMP_IDS + "\")");
} catch (SQLException e) { } catch (SQLException e) {
log.error("Can't create database", e); log.error("Can't create database", e);
throw new RuntimeException(e); throw new RuntimeException(e);
@ -143,15 +148,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
this.oldVersion = oldVersion; this.oldVersion = oldVersion;
this.newVersion = newVersion; this.newVersion = newVersion;
if (oldVersion == 7 && newVersion == 8) { if (oldVersion < 7) {
log.debug("Upgrading database from v7 to v8");
} else if (oldVersion == 8 && newVersion == 9) {
log.debug("Upgrading database from v8 to v9");
} else if (oldVersion == 9 && newVersion == 10) {
TableUtils.createTableIfNotExists(connectionSource, InsightHistoryOffset.class);
TableUtils.createTableIfNotExists(connectionSource, InsightBolusID.class);
TableUtils.createTableIfNotExists(connectionSource, InsightPumpID.class);
} else {
log.info(DatabaseHelper.class.getName(), "onUpgrade"); log.info(DatabaseHelper.class.getName(), "onUpgrade");
TableUtils.dropTable(connectionSource, TempTarget.class, true); TableUtils.dropTable(connectionSource, TempTarget.class, true);
TableUtils.dropTable(connectionSource, BgReading.class, true); TableUtils.dropTable(connectionSource, BgReading.class, true);
@ -162,6 +159,17 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
TableUtils.dropTable(connectionSource, CareportalEvent.class, true); TableUtils.dropTable(connectionSource, CareportalEvent.class, true);
TableUtils.dropTable(connectionSource, ProfileSwitch.class, true); TableUtils.dropTable(connectionSource, ProfileSwitch.class, true);
onCreate(database, connectionSource); onCreate(database, connectionSource);
} else if (oldVersion < 10) {
TableUtils.createTableIfNotExists(connectionSource, InsightHistoryOffset.class);
TableUtils.createTableIfNotExists(connectionSource, InsightBolusID.class);
TableUtils.createTableIfNotExists(connectionSource, InsightPumpID.class);
database.execSQL("INSERT INTO sqlite_sequence (name, seq) SELECT \"" + DATABASE_INSIGHT_BOLUS_IDS + "\", " + System.currentTimeMillis() + " " +
"WHERE NOT EXISTS (SELECT 1 FROM sqlite_sequence WHERE name = \"" + DATABASE_INSIGHT_BOLUS_IDS + "\")");
database.execSQL("INSERT INTO sqlite_sequence (name, seq) SELECT \"" + DATABASE_INSIGHT_PUMP_IDS + "\", " + System.currentTimeMillis() + " " +
"WHERE NOT EXISTS (SELECT 1 FROM sqlite_sequence WHERE name = \"" + DATABASE_INSIGHT_PUMP_IDS + "\")");
} else if (oldVersion < 11) {
database.execSQL("UPDATE sqlite_sequence SET seq = " + System.currentTimeMillis() + " WHERE name = \"" + DATABASE_INSIGHT_BOLUS_IDS + "\"");
database.execSQL("UPDATE sqlite_sequence SET seq = " + System.currentTimeMillis() + " WHERE name = \"" + DATABASE_INSIGHT_PUMP_IDS + "\"");
} }
} catch (SQLException e) { } catch (SQLException e) {
log.error("Can't drop databases", e); log.error("Can't drop databases", e);
@ -403,6 +411,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
if (L.isEnabled(L.DATABASE)) if (L.isEnabled(L.DATABASE))
log.debug("Firing EventNewBg"); log.debug("Firing EventNewBg");
MainApp.bus().post(new EventNewBG(bgReading)); MainApp.bus().post(new EventNewBG(bgReading));
RxBus.INSTANCE.send(new EventNewBG(bgReading));
scheduledBgPost = null; scheduledBgPost = null;
} }
} }
@ -427,7 +436,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
return null; return null;
for (int i = 0; i < bgList.size(); i++) for (int i = 0; i < bgList.size(); i++)
if (bgList.get(i).value > 39) if (bgList.get(i).value >= 39)
return bgList.get(i); return bgList.get(i);
return null; return null;
} }
@ -589,7 +598,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
} }
} }
// -------------------- TREATMENT HANDLING ------------------- // -------------------- TEMPTARGET HANDLING -------------------
public static void updateEarliestDataChange(long newDate) { public static void updateEarliestDataChange(long newDate) {
if (earliestDataChange == null) { if (earliestDataChange == null) {
@ -620,6 +629,23 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
return new ArrayList<TempTarget>(); return new ArrayList<TempTarget>();
} }
public List<TempTarget> getTemptargetsDataFromTime(long from, long to, boolean ascending) {
try {
Dao<TempTarget, Long> daoTempTargets = getDaoTempTargets();
List<TempTarget> tempTargets;
QueryBuilder<TempTarget, Long> queryBuilder = daoTempTargets.queryBuilder();
queryBuilder.orderBy("date", ascending);
Where where = queryBuilder.where();
where.between("date", from, to);
PreparedQuery<TempTarget> preparedQuery = queryBuilder.prepare();
tempTargets = daoTempTargets.query(preparedQuery);
return tempTargets;
} catch (SQLException e) {
log.error("Unhandled exception", e);
}
return new ArrayList<TempTarget>();
}
public boolean createOrUpdate(TempTarget tempTarget) { public boolean createOrUpdate(TempTarget tempTarget) {
try { try {
TempTarget old; TempTarget old;
@ -943,6 +969,22 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
return new ArrayList<TemporaryBasal>(); return new ArrayList<TemporaryBasal>();
} }
public List<TemporaryBasal> getTemporaryBasalsDataFromTime(long from, long to, boolean ascending) {
try {
List<TemporaryBasal> tempbasals;
QueryBuilder<TemporaryBasal, Long> queryBuilder = getDaoTemporaryBasal().queryBuilder();
queryBuilder.orderBy("date", ascending);
Where where = queryBuilder.where();
where.between("date", from, to);
PreparedQuery<TemporaryBasal> preparedQuery = queryBuilder.prepare();
tempbasals = getDaoTemporaryBasal().query(preparedQuery);
return tempbasals;
} catch (SQLException e) {
log.error("Unhandled exception", e);
}
return new ArrayList<TemporaryBasal>();
}
private static void scheduleTemporaryBasalChange() { private static void scheduleTemporaryBasalChange() {
class PostRunnable implements Runnable { class PostRunnable implements Runnable {
public void run() { public void run() {
@ -1347,6 +1389,23 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
return new ArrayList<>(); return new ArrayList<>();
} }
public List<CareportalEvent> getCareportalEvents(long start, long end, boolean ascending) {
try {
List<CareportalEvent> careportalEvents;
QueryBuilder<CareportalEvent, Long> queryBuilder = getDaoCareportalEvents().queryBuilder();
queryBuilder.orderBy("date", ascending);
Where where = queryBuilder.where();
where.between("date", start, end);
PreparedQuery<CareportalEvent> preparedQuery = queryBuilder.prepare();
careportalEvents = getDaoCareportalEvents().query(preparedQuery);
preprocessOpenAPSOfflineEvents(careportalEvents);
return careportalEvents;
} catch (SQLException e) {
log.error("Unhandled exception", e);
}
return new ArrayList<>();
}
public void preprocessOpenAPSOfflineEvents(List<CareportalEvent> list) { public void preprocessOpenAPSOfflineEvents(List<CareportalEvent> list) {
OverlappingIntervals offlineEvents = new OverlappingIntervals(); OverlappingIntervals offlineEvents = new OverlappingIntervals();
for (int i = 0; i < list.size(); i++) { for (int i = 0; i < list.size(); i++) {
@ -1500,6 +1559,24 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
return new ArrayList<>(); return new ArrayList<>();
} }
public List<ProfileSwitch> getProfileSwitchEventsFromTime(long from, long to, boolean ascending) {
try {
Dao<ProfileSwitch, Long> daoProfileSwitch = getDaoProfileSwitch();
List<ProfileSwitch> profileSwitches;
QueryBuilder<ProfileSwitch, Long> queryBuilder = daoProfileSwitch.queryBuilder();
queryBuilder.orderBy("date", ascending);
queryBuilder.limit(100L);
Where where = queryBuilder.where();
where.between("date", from, to);
PreparedQuery<ProfileSwitch> preparedQuery = queryBuilder.prepare();
profileSwitches = daoProfileSwitch.query(preparedQuery);
return profileSwitches;
} catch (SQLException e) {
log.error("Unhandled exception", e);
}
return new ArrayList<>();
}
public boolean createOrUpdate(ProfileSwitch profileSwitch) { public boolean createOrUpdate(ProfileSwitch profileSwitch) {
try { try {
ProfileSwitch old; ProfileSwitch old;

View file

@ -1,7 +1,7 @@
package info.nightscout.androidaps.db; package info.nightscout.androidaps.db;
import android.graphics.Color; import android.graphics.Color;
import android.support.annotation.Nullable; import androidx.annotation.Nullable;
import com.j256.ormlite.field.DatabaseField; import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.table.DatabaseTable; import com.j256.ormlite.table.DatabaseTable;

View file

@ -1,6 +1,6 @@
package info.nightscout.androidaps.events; package info.nightscout.androidaps.events;
import android.support.annotation.Nullable; import androidx.annotation.Nullable;
import info.nightscout.androidaps.db.BgReading; import info.nightscout.androidaps.db.BgReading;

View file

@ -1,6 +1,6 @@
package info.nightscout.androidaps.events; package info.nightscout.androidaps.events;
import android.support.annotation.Nullable; import androidx.annotation.Nullable;
import info.nightscout.androidaps.plugins.treatments.Treatment; import info.nightscout.androidaps.plugins.treatments.Treatment;

View file

@ -1,7 +1,7 @@
package info.nightscout.androidaps.interfaces; package info.nightscout.androidaps.interfaces;
import android.os.SystemClock; import android.os.SystemClock;
import android.support.v4.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;

View file

@ -1,6 +1,6 @@
package info.nightscout.androidaps.interfaces; package info.nightscout.androidaps.interfaces;
import android.support.annotation.Nullable; import androidx.annotation.Nullable;
import info.nightscout.androidaps.data.ProfileStore; import info.nightscout.androidaps.data.ProfileStore;

View file

@ -53,7 +53,9 @@ public interface PumpInterface {
// Status to be passed to NS // Status to be passed to NS
JSONObject getJSONStatus(Profile profile, String profileName); JSONObject getJSONStatus(Profile profile, String profileName);
String deviceID(); String manufacter();
String model();
String serialNumber();
// Pump capabilities // Pump capabilities
PumpDescription getPumpDescription(); PumpDescription getPumpDescription();

View file

@ -5,6 +5,7 @@ import java.util.List;
import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.data.DetailedBolusInfo;
import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.IobTotal;
import info.nightscout.androidaps.data.MealData; import info.nightscout.androidaps.data.MealData;
import info.nightscout.androidaps.data.NonOverlappingIntervals;
import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.db.ExtendedBolus; import info.nightscout.androidaps.db.ExtendedBolus;
import info.nightscout.androidaps.db.ProfileSwitch; import info.nightscout.androidaps.db.ProfileSwitch;
@ -42,7 +43,7 @@ public interface TreatmentsInterface {
// basal that can be faked by extended boluses // basal that can be faked by extended boluses
boolean isTempBasalInProgress(); boolean isTempBasalInProgress();
TemporaryBasal getTempBasalFromHistory(long time); TemporaryBasal getTempBasalFromHistory(long time);
Intervals<TemporaryBasal> getTemporaryBasalsFromHistory(); NonOverlappingIntervals<TemporaryBasal> getTemporaryBasalsFromHistory();
boolean isInHistoryExtendedBoluslInProgress(); boolean isInHistoryExtendedBoluslInProgress();
ExtendedBolus getExtendedBolusFromHistory(long time); ExtendedBolus getExtendedBolusFromHistory(long time);

View file

@ -87,6 +87,7 @@ public class L {
public static final String DATAFOOD = "DATAFOOD"; public static final String DATAFOOD = "DATAFOOD";
public static final String DATATREATMENTS = "DATATREATMENTS"; public static final String DATATREATMENTS = "DATATREATMENTS";
public static final String NSCLIENT = "NSCLIENT"; public static final String NSCLIENT = "NSCLIENT";
public static final String TIDEPOOL = "TIDEPOOL";
public static final String CONSTRAINTS = "CONSTRAINTS"; public static final String CONSTRAINTS = "CONSTRAINTS";
public static final String PUMP = "PUMP"; public static final String PUMP = "PUMP";
public static final String PUMPQUEUE = "PUMPQUEUE"; public static final String PUMPQUEUE = "PUMPQUEUE";
@ -114,6 +115,7 @@ public class L {
logElements.add(new LogElement(EVENTS, false, true)); logElements.add(new LogElement(EVENTS, false, true));
logElements.add(new LogElement(NOTIFICATION, true)); logElements.add(new LogElement(NOTIFICATION, true));
logElements.add(new LogElement(NSCLIENT, true)); logElements.add(new LogElement(NSCLIENT, true));
logElements.add(new LogElement(TIDEPOOL, true));
logElements.add(new LogElement(OVERVIEW, true)); logElements.add(new LogElement(OVERVIEW, true));
logElements.add(new LogElement(PROFILE, true)); logElements.add(new LogElement(PROFILE, true));
logElements.add(new LogElement(PUMP, true)); logElements.add(new LogElement(PUMP, true));

View file

@ -10,8 +10,8 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Build; import android.os.Build;
import android.os.SystemClock; import android.os.SystemClock;
import android.support.annotation.NonNull; import androidx.annotation.NonNull;
import android.support.v4.app.NotificationCompat; import androidx.core.app.NotificationCompat;
import com.squareup.otto.Subscribe; import com.squareup.otto.Subscribe;
@ -644,14 +644,27 @@ public class LoopPlugin extends PluginBase {
TreatmentsInterface activeTreatments = TreatmentsPlugin.getPlugin(); TreatmentsInterface activeTreatments = TreatmentsPlugin.getPlugin();
LoopPlugin.getPlugin().disconnectTo(System.currentTimeMillis() + durationInMinutes * 60 * 1000L); LoopPlugin.getPlugin().disconnectTo(System.currentTimeMillis() + durationInMinutes * 60 * 1000L);
ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalPercent(0, durationInMinutes, true, profile, new Callback() {
@Override if (pump.getPumpDescription().tempBasalStyle == PumpDescription.ABSOLUTE) {
public void run() { ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalAbsolute(0, durationInMinutes, true, profile, new Callback() {
if (!result.success) { @Override
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.tempbasaldeliveryerror)); public void run() {
if (!result.success) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.tempbasaldeliveryerror));
}
} }
} });
}); } else {
ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalPercent(0, durationInMinutes, true, profile, new Callback() {
@Override
public void run() {
if (!result.success) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.tempbasaldeliveryerror));
}
}
});
}
if (pump.getPumpDescription().isExtendedBolusCapable && activeTreatments.isInHistoryExtendedBoluslInProgress()) { if (pump.getPumpDescription().isExtendedBolusCapable && activeTreatments.isInHistoryExtendedBoluslInProgress()) {
ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelExtended(new Callback() { ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelExtended(new Callback() {
@Override @Override

View file

@ -20,7 +20,7 @@ import java.lang.reflect.InvocationTargetException;
import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.GlucoseStatus; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.IobTotal;
import info.nightscout.androidaps.data.MealData; import info.nightscout.androidaps.data.MealData;
import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.Profile;

View file

@ -6,7 +6,7 @@ import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.GlucoseStatus; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.IobTotal;
import info.nightscout.androidaps.data.MealData; import info.nightscout.androidaps.data.MealData;
import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.Profile;

View file

@ -17,7 +17,7 @@ import java.lang.reflect.InvocationTargetException;
import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.GlucoseStatus; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.IobTotal;
import info.nightscout.androidaps.data.MealData; import info.nightscout.androidaps.data.MealData;
import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.Profile;

View file

@ -6,7 +6,7 @@ import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.GlucoseStatus; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.IobTotal;
import info.nightscout.androidaps.data.MealData; import info.nightscout.androidaps.data.MealData;
import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.Profile;

View file

@ -20,7 +20,7 @@ import java.lang.reflect.InvocationTargetException;
import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.GlucoseStatus; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.IobTotal;
import info.nightscout.androidaps.data.MealData; import info.nightscout.androidaps.data.MealData;
import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.Profile;

View file

@ -6,7 +6,7 @@ import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.GlucoseStatus; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.IobTotal;
import info.nightscout.androidaps.data.MealData; import info.nightscout.androidaps.data.MealData;
import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.Profile;

View file

@ -0,0 +1,23 @@
package info.nightscout.androidaps.plugins.bus
import info.nightscout.androidaps.events.Event
import io.reactivex.Observable
import io.reactivex.schedulers.Schedulers
import io.reactivex.subjects.PublishSubject
// Use object so we have a singleton instance
object RxBus {
private val publisher = PublishSubject.create<Event>()
fun send(event: Event) {
publisher.onNext(event)
}
// Listen should return an Observable and not the publisher
// Using ofType we filter only events that match that class type
fun <T> toObservable(eventType: Class<T>): Observable<T> =
publisher
.subscribeOn(Schedulers.io())
.ofType(eventType)
}

View file

@ -1,6 +1,6 @@
package info.nightscout.androidaps.plugins.common; package info.nightscout.androidaps.plugins.common;
import android.support.v4.app.Fragment; import androidx.fragment.app.Fragment;
import butterknife.Unbinder; import butterknife.Unbinder;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;

View file

@ -3,8 +3,8 @@ package info.nightscout.androidaps.plugins.configBuilder;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull; import androidx.annotation.NonNull;
import android.support.annotation.StringRes; import androidx.annotation.StringRes;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;

View file

@ -1,6 +1,6 @@
package info.nightscout.androidaps.plugins.configBuilder; package info.nightscout.androidaps.plugins.configBuilder;
import android.support.annotation.Nullable; import androidx.annotation.Nullable;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -232,26 +232,32 @@ public class ConfigBuilderPlugin extends PluginBase {
return commandQueue; return commandQueue;
} }
@Nullable
public BgSourceInterface getActiveBgSource() { public BgSourceInterface getActiveBgSource() {
return activeBgSource; return activeBgSource;
} }
@Nullable
public ProfileInterface getActiveProfileInterface() { public ProfileInterface getActiveProfileInterface() {
return activeProfile; return activeProfile;
} }
@Nullable
public InsulinInterface getActiveInsulin() { public InsulinInterface getActiveInsulin() {
return activeInsulin; return activeInsulin;
} }
@Nullable
public APSInterface getActiveAPS() { public APSInterface getActiveAPS() {
return activeAPS; return activeAPS;
} }
@Nullable
public PumpInterface getActivePump() { public PumpInterface getActivePump() {
return activePump; return activePump;
} }
@Nullable
public SensitivityInterface getActiveSensitivity() { public SensitivityInterface getActiveSensitivity() {
return activeSensitivity; return activeSensitivity;
} }

View file

@ -1,6 +1,6 @@
package info.nightscout.androidaps.plugins.configBuilder; package info.nightscout.androidaps.plugins.configBuilder;
import android.support.annotation.Nullable; import androidx.annotation.Nullable;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;

View file

@ -2,7 +2,7 @@ package info.nightscout.androidaps.plugins.configBuilder;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.firebase.analytics.FirebaseAnalytics; import com.google.firebase.analytics.FirebaseAnalytics;
import com.squareup.otto.Subscribe; import com.squareup.otto.Subscribe;

View file

@ -4,11 +4,11 @@ import android.app.Activity;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.support.annotation.NonNull; import androidx.annotation.NonNull;
import android.support.v7.widget.CardView; import androidx.cardview.widget.CardView;
import android.support.v7.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import android.support.v7.widget.LinearSmoothScroller; import androidx.recyclerview.widget.LinearSmoothScroller;
import android.support.v7.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import android.text.Html; import android.text.Html;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;

View file

@ -1,6 +1,6 @@
package info.nightscout.androidaps.plugins.constraints.objectives.objectives; package info.nightscout.androidaps.plugins.constraints.objectives.objectives;
import android.support.annotation.StringRes; import androidx.annotation.StringRes;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;

View file

@ -13,10 +13,10 @@ import info.nightscout.androidaps.interfaces.PluginDescription;
import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.interfaces.PumpDescription; import info.nightscout.androidaps.interfaces.PumpDescription;
import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.aps.openAPSAMA.OpenAPSAMAPlugin; import info.nightscout.androidaps.plugins.aps.openAPSAMA.OpenAPSAMAPlugin;
import info.nightscout.androidaps.plugins.aps.openAPSMA.OpenAPSMAPlugin; import info.nightscout.androidaps.plugins.aps.openAPSMA.OpenAPSMAPlugin;
import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin; import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification;
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification; import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin; import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin;
@ -196,7 +196,7 @@ public class SafetyPlugin extends PluginBase implements ConstraintsInterface {
PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
if (pump != null) { if (pump != null) {
double rounded = Round.roundTo(insulin.value(), pump.getPumpDescription().pumpType.determineCorrectBolusSize(insulin.value())); double rounded = pump.getPumpDescription().pumpType.determineCorrectBolusSize(insulin.value());
insulin.setIfDifferent(rounded, MainApp.gs(R.string.pumplimit), this); insulin.setIfDifferent(rounded, MainApp.gs(R.string.pumplimit), this);
} }
return insulin; return insulin;
@ -213,7 +213,7 @@ public class SafetyPlugin extends PluginBase implements ConstraintsInterface {
PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
if (pump != null) { if (pump != null) {
double rounded = Round.roundTo(insulin.value(), pump.getPumpDescription().pumpType.determineCorrectExtendedBolusSize(insulin.value())); double rounded = pump.getPumpDescription().pumpType.determineCorrectExtendedBolusSize(insulin.value());
insulin.setIfDifferent(rounded, MainApp.gs(R.string.pumplimit), this); insulin.setIfDifferent(rounded, MainApp.gs(R.string.pumplimit), this);
} }
return insulin; return insulin;

View file

@ -5,8 +5,8 @@ import android.app.Activity;
import android.content.Intent; import android.content.Intent;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.Fragment; import androidx.fragment.app.Fragment;
import android.support.v4.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;

View file

@ -3,8 +3,8 @@ package info.nightscout.androidaps.plugins.general.actions.dialogs;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.DialogFragment; import androidx.fragment.app.DialogFragment;
import android.support.v7.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import android.text.Editable; import android.text.Editable;
import android.text.Html; import android.text.Html;
import android.text.TextWatcher; import android.text.TextWatcher;

View file

@ -4,8 +4,8 @@ import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.DialogFragment; import androidx.fragment.app.DialogFragment;
import android.support.v7.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;

View file

@ -3,8 +3,8 @@ package info.nightscout.androidaps.plugins.general.actions.dialogs;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.DialogFragment; import androidx.fragment.app.DialogFragment;
import android.support.v7.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;

View file

@ -4,7 +4,7 @@ package info.nightscout.androidaps.plugins.general.careportal;
import android.app.Activity; import android.app.Activity;
import android.graphics.Color; import android.graphics.Color;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;

View file

@ -3,8 +3,8 @@ package info.nightscout.androidaps.plugins.general.careportal.Dialogs;
import android.app.Activity; import android.app.Activity;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.DialogFragment; import androidx.fragment.app.DialogFragment;
import android.support.v7.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import android.text.Editable; import android.text.Editable;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.text.format.DateFormat; import android.text.format.DateFormat;
@ -39,7 +39,7 @@ import java.util.List;
import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.GlucoseStatus; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.ProfileStore; import info.nightscout.androidaps.data.ProfileStore;
import info.nightscout.androidaps.db.BgReading; import info.nightscout.androidaps.db.BgReading;

View file

@ -4,9 +4,9 @@ import android.app.Activity;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.graphics.Paint; import android.graphics.Paint;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import android.support.v7.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import android.text.Editable; import android.text.Editable;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.view.LayoutInflater; import android.view.LayoutInflater;

View file

@ -3,7 +3,7 @@ package info.nightscout.androidaps.plugins.general.food;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.os.IBinder; import android.os.IBinder;
import android.support.annotation.Nullable; import androidx.annotation.Nullable;
import com.j256.ormlite.android.apptools.OpenHelperManager; import com.j256.ormlite.android.apptools.OpenHelperManager;
import com.j256.ormlite.android.apptools.OrmLiteBaseService; import com.j256.ormlite.android.apptools.OrmLiteBaseService;

View file

@ -8,9 +8,9 @@ import android.content.SharedPreferences;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.os.Environment; import android.os.Environment;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.v4.app.ActivityCompat; import androidx.core.app.ActivityCompat;
import android.support.v4.app.Fragment; import androidx.fragment.app.Fragment;
import android.support.v4.content.ContextCompat; import androidx.core.content.ContextCompat;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;

View file

@ -2,8 +2,8 @@ package info.nightscout.androidaps.plugins.general.maintenance;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.Fragment; import androidx.fragment.app.Fragment;
import android.support.v7.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;

View file

@ -3,7 +3,7 @@ package info.nightscout.androidaps.plugins.general.maintenance;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.support.v4.content.FileProvider; import androidx.core.content.FileProvider;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;

View file

@ -1,7 +1,7 @@
package info.nightscout.androidaps.plugins.general.maintenance.activities; package info.nightscout.androidaps.plugins.general.maintenance.activities;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import android.view.View; import android.view.View;
import android.widget.CheckBox; import android.widget.CheckBox;
import android.widget.LinearLayout; import android.widget.LinearLayout;

View file

@ -22,6 +22,7 @@ import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.events.EventAppExit; import info.nightscout.androidaps.events.EventAppExit;
import info.nightscout.androidaps.events.EventChargingState; import info.nightscout.androidaps.events.EventChargingState;
import info.nightscout.androidaps.events.EventNetworkChange; import info.nightscout.androidaps.events.EventNetworkChange;
@ -213,6 +214,7 @@ public class NSClientPlugin extends PluginBase {
SP.putBoolean(R.string.key_nsclientinternal_paused, newState); SP.putBoolean(R.string.key_nsclientinternal_paused, newState);
paused = newState; paused = newState;
MainApp.bus().post(new EventPreferenceChange(R.string.key_nsclientinternal_paused)); MainApp.bus().post(new EventPreferenceChange(R.string.key_nsclientinternal_paused));
RxBus.INSTANCE.send(new EventPreferenceChange(R.string.key_nsclientinternal_paused));
} }
public UploadQueue queue() { public UploadQueue queue() {

View file

@ -7,8 +7,8 @@ import android.content.pm.ResolveInfo;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.annotation.Nullable; import androidx.annotation.Nullable;
import android.support.v4.content.LocalBroadcastManager; import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.json.JSONArray; import org.json.JSONArray;

View file

@ -10,6 +10,7 @@ import com.squareup.otto.Bus;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.events.EventChargingState; import info.nightscout.androidaps.events.EventChargingState;
import info.nightscout.androidaps.events.EventNetworkChange; import info.nightscout.androidaps.events.EventNetworkChange;
import info.nightscout.androidaps.events.EventPreferenceChange; import info.nightscout.androidaps.events.EventPreferenceChange;
@ -99,6 +100,7 @@ class NsClientReceiverDelegate {
if (newAllowedState != allowed) { if (newAllowedState != allowed) {
allowed = newAllowedState; allowed = newAllowedState;
bus.post(new EventPreferenceChange(R.string.key_nsclientinternal_paused)); bus.post(new EventPreferenceChange(R.string.key_nsclientinternal_paused));
RxBus.INSTANCE.send(new EventPreferenceChange(R.string.key_nsclientinternal_paused));
} }
} }

View file

@ -3,7 +3,7 @@ package info.nightscout.androidaps.plugins.general.nsclient.broadcasts;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager; import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;

View file

@ -3,7 +3,7 @@ package info.nightscout.androidaps.plugins.general.nsclient.broadcasts;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager; import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.json.JSONObject; import org.json.JSONObject;

View file

@ -3,7 +3,7 @@ package info.nightscout.androidaps.plugins.general.nsclient.broadcasts;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager; import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.json.JSONObject; import org.json.JSONObject;

View file

@ -3,7 +3,7 @@ package info.nightscout.androidaps.plugins.general.nsclient.broadcasts;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager; import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.json.JSONArray; import org.json.JSONArray;

View file

@ -3,7 +3,7 @@ package info.nightscout.androidaps.plugins.general.nsclient.broadcasts;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager; import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.json.JSONObject; import org.json.JSONObject;

View file

@ -3,7 +3,7 @@ package info.nightscout.androidaps.plugins.general.nsclient.broadcasts;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager; import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.json.JSONArray; import org.json.JSONArray;

View file

@ -3,7 +3,7 @@ package info.nightscout.androidaps.plugins.general.nsclient.broadcasts;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager; import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.json.JSONArray; import org.json.JSONArray;

View file

@ -3,7 +3,7 @@ package info.nightscout.androidaps.plugins.general.nsclient.broadcasts;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager; import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.json.JSONArray; import org.json.JSONArray;

View file

@ -3,7 +3,7 @@ package info.nightscout.androidaps.plugins.general.nsclient.broadcasts;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager; import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;

View file

@ -3,7 +3,7 @@ package info.nightscout.androidaps.plugins.general.nsclient.broadcasts;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager; import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.json.JSONArray; import org.json.JSONArray;

View file

@ -4,7 +4,7 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager; import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;

View file

@ -2,7 +2,7 @@ package info.nightscout.androidaps.plugins.general.nsclient.broadcasts;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager; import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;

View file

@ -3,7 +3,7 @@ package info.nightscout.androidaps.plugins.general.nsclient.broadcasts;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager; import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.json.JSONObject; import org.json.JSONObject;

View file

@ -3,7 +3,7 @@ package info.nightscout.androidaps.plugins.general.nsclient.data;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable; import androidx.annotation.Nullable;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;

View file

@ -2,7 +2,7 @@ package info.nightscout.androidaps.plugins.general.nsclient.receivers;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.support.v4.content.WakefulBroadcastReceiver; import androidx.legacy.content.WakefulBroadcastReceiver;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart; import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart;

View file

@ -3,7 +3,7 @@ package info.nightscout.androidaps.plugins.general.overview;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.Activity; import android.app.Activity;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.arch.core.util.Function; import androidx.arch.core.util.Function;
import android.content.ActivityNotFoundException; import android.content.ActivityNotFoundException;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
@ -12,14 +12,14 @@ import android.graphics.Color;
import android.graphics.Paint; import android.graphics.Paint;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.support.v4.app.Fragment; import androidx.fragment.app.Fragment;
import android.support.v4.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
import android.support.v4.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import android.support.v4.content.res.ResourcesCompat; import androidx.core.content.res.ResourcesCompat;
import android.support.v7.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import android.support.v7.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import android.support.v7.widget.PopupMenu; import androidx.appcompat.widget.PopupMenu;
import android.support.v7.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import android.text.SpannableString; import android.text.SpannableString;
import android.text.style.ForegroundColorSpan; import android.text.style.ForegroundColorSpan;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
@ -37,12 +37,9 @@ import android.widget.TextView;
import com.jjoe64.graphview.GraphView; import com.jjoe64.graphview.GraphView;
import com.squareup.otto.Subscribe; import com.squareup.otto.Subscribe;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.text.DecimalFormat;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.Locale; import java.util.Locale;
@ -55,8 +52,6 @@ import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.DetailedBolusInfo;
import info.nightscout.androidaps.data.GlucoseStatus;
import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.IobTotal;
import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.QuickWizardEntry; import info.nightscout.androidaps.data.QuickWizardEntry;
@ -94,24 +89,21 @@ import info.nightscout.androidaps.plugins.general.careportal.OptionsToShow;
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload; import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
import info.nightscout.androidaps.plugins.general.nsclient.data.NSDeviceStatus; import info.nightscout.androidaps.plugins.general.nsclient.data.NSDeviceStatus;
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus; import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus;
import info.nightscout.androidaps.plugins.general.overview.activities.QuickWizardListActivity;
import info.nightscout.androidaps.plugins.general.overview.dialogs.CalibrationDialog; import info.nightscout.androidaps.plugins.general.overview.dialogs.CalibrationDialog;
import info.nightscout.androidaps.plugins.general.overview.dialogs.ErrorHelperActivity;
import info.nightscout.androidaps.plugins.general.overview.dialogs.NewCarbsDialog; import info.nightscout.androidaps.plugins.general.overview.dialogs.NewCarbsDialog;
import info.nightscout.androidaps.plugins.general.overview.dialogs.NewInsulinDialog; import info.nightscout.androidaps.plugins.general.overview.dialogs.NewInsulinDialog;
import info.nightscout.androidaps.plugins.general.overview.dialogs.NewTreatmentDialog; import info.nightscout.androidaps.plugins.general.overview.dialogs.NewTreatmentDialog;
import info.nightscout.androidaps.plugins.general.overview.dialogs.WizardDialog; import info.nightscout.androidaps.plugins.general.overview.dialogs.WizardDialog;
import info.nightscout.androidaps.plugins.general.overview.activities.QuickWizardListActivity;
import info.nightscout.androidaps.plugins.general.overview.graphData.GraphData; import info.nightscout.androidaps.plugins.general.overview.graphData.GraphData;
import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationRecyclerViewAdapter;
import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationStore;
import info.nightscout.androidaps.plugins.general.wear.ActionStringHandler; import info.nightscout.androidaps.plugins.general.wear.ActionStringHandler;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensData; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensData;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.CobInfo; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.CobInfo;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensCalculationFinished; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensCalculationFinished;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress;
import info.nightscout.androidaps.plugins.source.SourceDexcomG5Plugin; import info.nightscout.androidaps.plugins.source.SourceDexcomPlugin;
import info.nightscout.androidaps.plugins.source.SourceDexcomG6Plugin;
import info.nightscout.androidaps.plugins.source.SourceXdripPlugin; import info.nightscout.androidaps.plugins.source.SourceXdripPlugin;
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin; import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
import info.nightscout.androidaps.plugins.treatments.fragments.ProfileViewerDialog; import info.nightscout.androidaps.plugins.treatments.fragments.ProfileViewerDialog;
@ -197,7 +189,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
Handler sLoopHandler = new Handler(); Handler sLoopHandler = new Handler();
Runnable sRefreshLoop = null; Runnable sRefreshLoop = null;
public enum CHARTTYPE {PRE, BAS, IOB, COB, DEV, SEN, DEVSLOPE} public enum CHARTTYPE {PRE, BAS, IOB, COB, DEV, SEN, ACTPRIM, ACTSEC, DEVSLOPE}
private static final ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor(); private static final ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor();
private static ScheduledFuture<?> scheduledUpdate = null; private static ScheduledFuture<?> scheduledUpdate = null;
@ -358,14 +350,15 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
else else
predictionsAvailable = false; predictionsAvailable = false;
MenuItem item; MenuItem item,dividerItem;
CharSequence title; CharSequence title;
int titleMaxChars = 0;
SpannableString s; SpannableString s;
PopupMenu popup = new PopupMenu(v.getContext(), v); PopupMenu popup = new PopupMenu(v.getContext(), v);
if (predictionsAvailable) { if (predictionsAvailable) {
item = popup.getMenu().add(Menu.NONE, CHARTTYPE.PRE.ordinal(), Menu.NONE, "Predictions"); item = popup.getMenu().add(Menu.NONE, CHARTTYPE.PRE.ordinal(), Menu.NONE, "Predictions");
title = item.getTitle(); title = item.getTitle();
if (titleMaxChars < title.length()) titleMaxChars = title.length();
s = new SpannableString(title); s = new SpannableString(title);
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.prediction, null)), 0, s.length(), 0); s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.prediction, null)), 0, s.length(), 0);
item.setTitle(s); item.setTitle(s);
@ -375,14 +368,28 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
item = popup.getMenu().add(Menu.NONE, CHARTTYPE.BAS.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_basals)); item = popup.getMenu().add(Menu.NONE, CHARTTYPE.BAS.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_basals));
title = item.getTitle(); title = item.getTitle();
if (titleMaxChars < title.length()) titleMaxChars = title.length();
s = new SpannableString(title); s = new SpannableString(title);
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.basal, null)), 0, s.length(), 0); s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.basal, null)), 0, s.length(), 0);
item.setTitle(s); item.setTitle(s);
item.setCheckable(true); item.setCheckable(true);
item.setChecked(SP.getBoolean("showbasals", true)); item.setChecked(SP.getBoolean("showbasals", true));
item = popup.getMenu().add(Menu.NONE, CHARTTYPE.ACTPRIM.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_activity));
title = item.getTitle();
if (titleMaxChars < title.length()) titleMaxChars = title.length();
s = new SpannableString(title);
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.activity, null)), 0, s.length(), 0);
item.setTitle(s);
item.setCheckable(true);
item.setChecked(SP.getBoolean("showactivityprimary", true));
dividerItem = popup.getMenu().add("");
dividerItem.setEnabled(false);
item = popup.getMenu().add(Menu.NONE, CHARTTYPE.IOB.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_iob)); item = popup.getMenu().add(Menu.NONE, CHARTTYPE.IOB.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_iob));
title = item.getTitle(); title = item.getTitle();
if (titleMaxChars < title.length()) titleMaxChars = title.length();
s = new SpannableString(title); s = new SpannableString(title);
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.iob, null)), 0, s.length(), 0); s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.iob, null)), 0, s.length(), 0);
item.setTitle(s); item.setTitle(s);
@ -391,6 +398,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
item = popup.getMenu().add(Menu.NONE, CHARTTYPE.COB.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_cob)); item = popup.getMenu().add(Menu.NONE, CHARTTYPE.COB.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_cob));
title = item.getTitle(); title = item.getTitle();
if (titleMaxChars < title.length()) titleMaxChars = title.length();
s = new SpannableString(title); s = new SpannableString(title);
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.cob, null)), 0, s.length(), 0); s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.cob, null)), 0, s.length(), 0);
item.setTitle(s); item.setTitle(s);
@ -399,6 +407,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
item = popup.getMenu().add(Menu.NONE, CHARTTYPE.DEV.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_deviations)); item = popup.getMenu().add(Menu.NONE, CHARTTYPE.DEV.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_deviations));
title = item.getTitle(); title = item.getTitle();
if (titleMaxChars < title.length()) titleMaxChars = title.length();
s = new SpannableString(title); s = new SpannableString(title);
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.deviations, null)), 0, s.length(), 0); s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.deviations, null)), 0, s.length(), 0);
item.setTitle(s); item.setTitle(s);
@ -407,15 +416,26 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
item = popup.getMenu().add(Menu.NONE, CHARTTYPE.SEN.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_sensitivity)); item = popup.getMenu().add(Menu.NONE, CHARTTYPE.SEN.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_sensitivity));
title = item.getTitle(); title = item.getTitle();
if (titleMaxChars < title.length()) titleMaxChars = title.length();
s = new SpannableString(title); s = new SpannableString(title);
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.ratio, null)), 0, s.length(), 0); s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.ratio, null)), 0, s.length(), 0);
item.setTitle(s); item.setTitle(s);
item.setCheckable(true); item.setCheckable(true);
item.setChecked(SP.getBoolean("showratios", false)); item.setChecked(SP.getBoolean("showratios", false));
item = popup.getMenu().add(Menu.NONE, CHARTTYPE.ACTSEC.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_activity));
title = item.getTitle();
if (titleMaxChars < title.length()) titleMaxChars = title.length();
s = new SpannableString(title);
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.activity, null)), 0, s.length(), 0);
item.setTitle(s);
item.setCheckable(true);
item.setChecked(SP.getBoolean("showactivitysecondary", true));
if (MainApp.devBranch) { if (MainApp.devBranch) {
item = popup.getMenu().add(Menu.NONE, CHARTTYPE.DEVSLOPE.ordinal(), Menu.NONE, "Deviation slope"); item = popup.getMenu().add(Menu.NONE, CHARTTYPE.DEVSLOPE.ordinal(), Menu.NONE, "Deviation slope");
title = item.getTitle(); title = item.getTitle();
if (titleMaxChars < title.length()) titleMaxChars = title.length();
s = new SpannableString(title); s = new SpannableString(title);
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.devslopepos, null)), 0, s.length(), 0); s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.devslopepos, null)), 0, s.length(), 0);
item.setTitle(s); item.setTitle(s);
@ -423,6 +443,10 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
item.setChecked(SP.getBoolean("showdevslope", false)); item.setChecked(SP.getBoolean("showdevslope", false));
} }
// Fairly good guestimate for required divider text size...
title = new String(new char[titleMaxChars+10]).replace("\0", "_");
dividerItem.setTitle(title);
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override @Override
public boolean onMenuItemClick(MenuItem item) { public boolean onMenuItemClick(MenuItem item) {
@ -438,6 +462,10 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
SP.putBoolean("showdeviations", !item.isChecked()); SP.putBoolean("showdeviations", !item.isChecked());
} else if (item.getItemId() == CHARTTYPE.SEN.ordinal()) { } else if (item.getItemId() == CHARTTYPE.SEN.ordinal()) {
SP.putBoolean("showratios", !item.isChecked()); SP.putBoolean("showratios", !item.isChecked());
} else if (item.getItemId() == CHARTTYPE.ACTPRIM.ordinal()) {
SP.putBoolean("showactivityprimary", !item.isChecked());
} else if (item.getItemId() == CHARTTYPE.ACTSEC.ordinal()) {
SP.putBoolean("showactivitysecondary", !item.isChecked());
} else if (item.getItemId() == CHARTTYPE.DEVSLOPE.ordinal()) { } else if (item.getItemId() == CHARTTYPE.DEVSLOPE.ordinal()) {
SP.putBoolean("showdevslope", !item.isChecked()); SP.putBoolean("showdevslope", !item.isChecked());
} }
@ -663,8 +691,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
@Override @Override
public void onClick(View v) { public void onClick(View v) {
boolean xdrip = SourceXdripPlugin.getPlugin().isEnabled(PluginType.BGSOURCE); boolean xdrip = SourceXdripPlugin.getPlugin().isEnabled(PluginType.BGSOURCE);
boolean g5 = SourceDexcomG5Plugin.getPlugin().isEnabled(PluginType.BGSOURCE); boolean dexcom = SourceDexcomPlugin.INSTANCE.isEnabled(PluginType.BGSOURCE);
boolean g6 = SourceDexcomG6Plugin.getPlugin().isEnabled(PluginType.BGSOURCE);
String units = ProfileFunctions.getInstance().getProfileUnits(); String units = ProfileFunctions.getInstance().getProfileUnits();
FragmentManager manager = getFragmentManager(); FragmentManager manager = getFragmentManager();
@ -687,10 +714,16 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
if (xdrip) { if (xdrip) {
CalibrationDialog calibrationDialog = new CalibrationDialog(); CalibrationDialog calibrationDialog = new CalibrationDialog();
calibrationDialog.show(manager, "CalibrationDialog"); calibrationDialog.show(manager, "CalibrationDialog");
} else if (g5 || g6) { } else if (dexcom) {
try { try {
Intent i = new Intent("com.dexcom.cgm.activities.MeterEntryActivity"); String packageName = SourceDexcomPlugin.INSTANCE.findDexcomPackageName();
startActivity(i); if (packageName != null) {
Intent i = new Intent("com.dexcom.cgm.activities.MeterEntryActivity");
i.setPackage(packageName);
startActivity(i);
} else {
ToastUtils.showToastInUiThread(getActivity(), MainApp.gs(R.string.dexcom_app_not_installed));
}
} catch (ActivityNotFoundException e) { } catch (ActivityNotFoundException e) {
ToastUtils.showToastInUiThread(getActivity(), MainApp.gs(R.string.g5appnotdetected)); ToastUtils.showToastInUiThread(getActivity(), MainApp.gs(R.string.g5appnotdetected));
} }
@ -699,14 +732,14 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
case R.id.overview_cgmbutton: case R.id.overview_cgmbutton:
if (xdrip) if (xdrip)
openCgmApp("com.eveningoutpost.dexdrip"); openCgmApp("com.eveningoutpost.dexdrip");
else if (g5 && units.equals(Constants.MGDL)) else if (dexcom) {
openCgmApp("com.dexcom.cgm.region5.mgdl"); String packageName = SourceDexcomPlugin.INSTANCE.findDexcomPackageName();
else if (g5 && units.equals(Constants.MMOL)) if (packageName != null) {
openCgmApp("com.dexcom.cgm.region5.mmol"); openCgmApp(packageName);
else if (g6 && units.equals(Constants.MGDL)) } else {
openCgmApp("com.dexcom.g6.region3.mgdl"); ToastUtils.showToastInUiThread(getActivity(), MainApp.gs(R.string.dexcom_app_not_installed));
else if (g6 && units.equals(Constants.MMOL)) }
openCgmApp("com.dexcom.g6.region3.mmol"); }
break; break;
case R.id.overview_treatmentbutton: case R.id.overview_treatmentbutton:
NewTreatmentDialog treatmentDialogFragment = new NewTreatmentDialog(); NewTreatmentDialog treatmentDialogFragment = new NewTreatmentDialog();
@ -783,122 +816,25 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
void onClickQuickwizard() { void onClickQuickwizard() {
final BgReading actualBg = DatabaseHelper.actualBg(); final BgReading actualBg = DatabaseHelper.actualBg();
final Profile profile = ProfileFunctions.getInstance().getProfile(); final Profile profile = ProfileFunctions.getInstance().getProfile();
final TempTarget tempTarget = TreatmentsPlugin.getPlugin().getTempTargetFromHistory(); final String profileName = ProfileFunctions.getInstance().getProfileName();
final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
final QuickWizardEntry quickWizardEntry = OverviewPlugin.getPlugin().quickWizard.getActive(); final QuickWizardEntry quickWizardEntry = OverviewPlugin.getPlugin().quickWizard.getActive();
if (quickWizardEntry != null && actualBg != null && profile != null) { if (quickWizardEntry != null && actualBg != null && profile != null && pump != null) {
quickWizardButton.setVisibility(View.VISIBLE); quickWizardButton.setVisibility(View.VISIBLE);
final BolusWizard wizard = quickWizardEntry.doCalc(profile, tempTarget, actualBg, true); final BolusWizard wizard = quickWizardEntry.doCalc(profile, profileName, actualBg, true);
final JSONObject boluscalcJSON = new JSONObject(); if (wizard.getCalculatedTotalInsulin() > 0d && quickWizardEntry.carbs() > 0d) {
try {
boluscalcJSON.put("eventTime", DateUtil.toISOString(new Date()));
boluscalcJSON.put("targetBGLow", wizard.targetBGLow);
boluscalcJSON.put("targetBGHigh", wizard.targetBGHigh);
boluscalcJSON.put("isf", wizard.sens);
boluscalcJSON.put("ic", wizard.ic);
boluscalcJSON.put("iob", -(wizard.insulingFromBolusIOB + wizard.insulingFromBasalsIOB));
boluscalcJSON.put("bolusiobused", true);
boluscalcJSON.put("basaliobused", true);
boluscalcJSON.put("bg", actualBg.valueToUnits(profile.getUnits()));
boluscalcJSON.put("insulinbg", wizard.insulinFromBG);
boluscalcJSON.put("insulinbgused", true);
boluscalcJSON.put("bgdiff", wizard.bgDiff);
boluscalcJSON.put("insulincarbs", wizard.insulinFromCarbs);
boluscalcJSON.put("carbs", quickWizardEntry.carbs());
boluscalcJSON.put("othercorrection", 0d);
boluscalcJSON.put("insulintrend", wizard.insulinFromTrend);
boluscalcJSON.put("insulin", wizard.calculatedTotalInsulin);
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
if (wizard.calculatedTotalInsulin > 0d && quickWizardEntry.carbs() > 0d) {
DecimalFormat formatNumber2decimalplaces = new DecimalFormat("0.00");
String confirmMessage = MainApp.gs(R.string.entertreatmentquestion);
Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(wizard.calculatedTotalInsulin)).value();
Integer carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(quickWizardEntry.carbs())).value(); Integer carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(quickWizardEntry.carbs())).value();
confirmMessage += "\n" + MainApp.gs(R.string.bolus) + ": " + formatNumber2decimalplaces.format(insulinAfterConstraints) + "U"; if (Math.abs(wizard.getInsulinAfterConstraints() - wizard.getCalculatedTotalInsulin()) >= pump.getPumpDescription().pumpType.determineCorrectBolusStepSize(wizard.getInsulinAfterConstraints()) || !carbsAfterConstraints.equals(quickWizardEntry.carbs())) {
confirmMessage += "\n" + MainApp.gs(R.string.carbs) + ": " + carbsAfterConstraints + "g"; OKDialog.show(getContext(), MainApp.gs(R.string.treatmentdeliveryerror), MainApp.gs(R.string.constraints_violation) + "\n" + MainApp.gs(R.string.changeyourinput), null);
if (Math.abs(insulinAfterConstraints - wizard.calculatedTotalInsulin) >= 0.01 || !carbsAfterConstraints.equals(quickWizardEntry.carbs())) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle(MainApp.gs(R.string.treatmentdeliveryerror));
builder.setMessage(MainApp.gs(R.string.constraints_violation) + "\n" + MainApp.gs(R.string.changeyourinput));
builder.setPositiveButton(MainApp.gs(R.string.ok), null);
builder.show();
return; return;
} }
final Double finalInsulinAfterConstraints = insulinAfterConstraints; wizard.confirmAndExecute(getContext());
final Integer finalCarbsAfterConstraints = carbsAfterConstraints;
final Context context = getContext();
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
accepted = false;
builder.setTitle(MainApp.gs(R.string.confirmation));
builder.setMessage(confirmMessage);
builder.setPositiveButton(MainApp.gs(R.string.ok), (dialog, id) -> {
synchronized (builder) {
if (accepted) {
if (L.isEnabled(L.OVERVIEW))
log.debug("guarding: already accepted");
return;
}
accepted = true;
if (Math.abs(insulinAfterConstraints - wizard.calculatedTotalInsulin) >= 0.01 || finalCarbsAfterConstraints > 0) {
if (wizard.superBolus) {
final LoopPlugin loopPlugin = LoopPlugin.getPlugin();
if (loopPlugin.isEnabled(PluginType.LOOP)) {
loopPlugin.superBolusTo(System.currentTimeMillis() + T.hours(2).msecs());
MainApp.bus().post(new EventRefreshOverview("WizardDialog"));
}
ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalPercent(0, 120, true, profile, new Callback() {
@Override
public void run() {
if (!result.success) {
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
i.putExtra("soundid", R.raw.boluserror);
i.putExtra("status", result.comment);
i.putExtra("title", MainApp.gs(R.string.tempbasaldeliveryerror));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MainApp.instance().startActivity(i);
}
}
});
}
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
detailedBolusInfo.eventType = CareportalEvent.BOLUSWIZARD;
detailedBolusInfo.insulin = finalInsulinAfterConstraints;
detailedBolusInfo.carbs = finalCarbsAfterConstraints;
detailedBolusInfo.context = context;
detailedBolusInfo.boluscalc = boluscalcJSON;
detailedBolusInfo.source = Source.USER;
if (finalInsulinAfterConstraints > 0 || ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().storesCarbInfo) {
ConfigBuilderPlugin.getPlugin().getCommandQueue().bolus(detailedBolusInfo, new Callback() {
@Override
public void run() {
if (!result.success) {
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
i.putExtra("soundid", R.raw.boluserror);
i.putExtra("status", result.comment);
i.putExtra("title", MainApp.gs(R.string.treatmentdeliveryerror));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MainApp.instance().startActivity(i);
}
}
});
} else {
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false);
}
}
}
});
builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
builder.show();
} }
} }
} }
@Override @Override
@ -1064,7 +1000,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
timeView.setText(DateUtil.timeString(new Date())); timeView.setText(DateUtil.timeString(new Date()));
} }
updateNotifications(); OverviewPlugin.getPlugin().notificationStore.updateNotifications(notificationsView);
pumpStatusLayout.setVisibility(View.GONE); pumpStatusLayout.setVisibility(View.GONE);
loopStatusLayout.setVisibility(View.GONE); loopStatusLayout.setVisibility(View.GONE);
@ -1083,6 +1019,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
final Profile profile = ProfileFunctions.getInstance().getProfile(); final Profile profile = ProfileFunctions.getInstance().getProfile();
final String profileName = ProfileFunctions.getInstance().getProfileName();
final String units = profile.getUnits(); final String units = profile.getUnits();
final double lowLine = OverviewPlugin.getPlugin().determineLowLine(units); final double lowLine = OverviewPlugin.getPlugin().determineLowLine(units);
@ -1190,10 +1127,10 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
// **** Calibration & CGM buttons **** // **** Calibration & CGM buttons ****
boolean xDripIsBgSource = MainApp.getSpecificPlugin(SourceXdripPlugin.class) != null && MainApp.getSpecificPlugin(SourceXdripPlugin.class).isEnabled(PluginType.BGSOURCE); boolean xDripIsBgSource = MainApp.getSpecificPlugin(SourceXdripPlugin.class) != null && MainApp.getSpecificPlugin(SourceXdripPlugin.class).isEnabled(PluginType.BGSOURCE);
boolean g5IsBgSource = MainApp.getSpecificPlugin(SourceDexcomG5Plugin.class) != null && MainApp.getSpecificPlugin(SourceDexcomG5Plugin.class).isEnabled(PluginType.BGSOURCE); boolean dexcomIsSource = SourceDexcomPlugin.INSTANCE.isEnabled(PluginType.BGSOURCE);
boolean bgAvailable = DatabaseHelper.actualBg() != null; boolean bgAvailable = DatabaseHelper.actualBg() != null;
if (calibrationButton != null) { if (calibrationButton != null) {
if ((xDripIsBgSource || g5IsBgSource) && bgAvailable && SP.getBoolean(R.string.key_show_calibration_button, true)) { if ((xDripIsBgSource || dexcomIsSource) && bgAvailable && SP.getBoolean(R.string.key_show_calibration_button, true)) {
calibrationButton.setVisibility(View.VISIBLE); calibrationButton.setVisibility(View.VISIBLE);
} else { } else {
calibrationButton.setVisibility(View.GONE); calibrationButton.setVisibility(View.GONE);
@ -1202,7 +1139,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
if (cgmButton != null) { if (cgmButton != null) {
if (xDripIsBgSource && SP.getBoolean(R.string.key_show_cgm_button, false)) { if (xDripIsBgSource && SP.getBoolean(R.string.key_show_cgm_button, false)) {
cgmButton.setVisibility(View.VISIBLE); cgmButton.setVisibility(View.VISIBLE);
} else if (g5IsBgSource && SP.getBoolean(R.string.key_show_cgm_button, false)) { } else if (dexcomIsSource && SP.getBoolean(R.string.key_show_cgm_button, false)) {
cgmButton.setVisibility(View.VISIBLE); cgmButton.setVisibility(View.VISIBLE);
} else { } else {
cgmButton.setVisibility(View.GONE); cgmButton.setVisibility(View.GONE);
@ -1280,10 +1217,10 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
if (quickWizardEntry != null && lastBG != null && pump.isInitialized() && !pump.isSuspended()) { if (quickWizardEntry != null && lastBG != null && pump.isInitialized() && !pump.isSuspended()) {
quickWizardButton.setVisibility(View.VISIBLE); quickWizardButton.setVisibility(View.VISIBLE);
String text = quickWizardEntry.buttonText() + "\n" + DecimalFormatter.to0Decimal(quickWizardEntry.carbs()) + "g"; String text = quickWizardEntry.buttonText() + "\n" + DecimalFormatter.to0Decimal(quickWizardEntry.carbs()) + "g";
BolusWizard wizard = quickWizardEntry.doCalc(profile, tempTarget, lastBG, false); BolusWizard wizard = quickWizardEntry.doCalc(profile, profileName, lastBG, false);
text += " " + DecimalFormatter.toPumpSupportedBolus(wizard.calculatedTotalInsulin) + "U"; text += " " + DecimalFormatter.toPumpSupportedBolus(wizard.getCalculatedTotalInsulin()) + "U";
quickWizardButton.setText(text); quickWizardButton.setText(text);
if (wizard.calculatedTotalInsulin <= 0) if (wizard.getCalculatedTotalInsulin() <= 0)
quickWizardButton.setVisibility(View.GONE); quickWizardButton.setVisibility(View.GONE);
} else } else
quickWizardButton.setVisibility(View.GONE); quickWizardButton.setVisibility(View.GONE);
@ -1523,6 +1460,10 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
// set manual x bounds to have nice steps // set manual x bounds to have nice steps
graphData.formatAxis(fromTime, endTime); graphData.formatAxis(fromTime, endTime);
if(SP.getBoolean("showactivityprimary", true)) {
graphData.addActivity(fromTime, endTime, false,1d);
}
// Treatments // Treatments
graphData.addTreatments(fromTime, endTime); graphData.addTreatments(fromTime, endTime);
@ -1548,6 +1489,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
boolean useDevForScale = false; boolean useDevForScale = false;
boolean useRatioForScale = false; boolean useRatioForScale = false;
boolean useDSForScale = false; boolean useDSForScale = false;
boolean useIAForScale = false;
if (SP.getBoolean("showiob", true)) { if (SP.getBoolean("showiob", true)) {
useIobForScale = true; useIobForScale = true;
@ -1557,6 +1499,8 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
useDevForScale = true; useDevForScale = true;
} else if (SP.getBoolean("showratios", false)) { } else if (SP.getBoolean("showratios", false)) {
useRatioForScale = true; useRatioForScale = true;
} else if (SP.getBoolean("showactivitysecondary", false)) {
useIAForScale = true;
} else if (SP.getBoolean("showdevslope", false)) { } else if (SP.getBoolean("showdevslope", false)) {
useDSForScale = true; useDSForScale = true;
} }
@ -1569,6 +1513,8 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
secondGraphData.addDeviations(fromTime, now, useDevForScale, 1d); secondGraphData.addDeviations(fromTime, now, useDevForScale, 1d);
if (SP.getBoolean("showratios", false)) if (SP.getBoolean("showratios", false))
secondGraphData.addRatio(fromTime, now, useRatioForScale, 1d); secondGraphData.addRatio(fromTime, now, useRatioForScale, 1d);
if(SP.getBoolean("showactivitysecondary", true))
secondGraphData.addActivity(fromTime, endTime, useIAForScale,useIAForScale ? 2d: 1d);
if (SP.getBoolean("showdevslope", false) && MainApp.devBranch) if (SP.getBoolean("showdevslope", false) && MainApp.devBranch)
secondGraphData.addDeviationSlope(fromTime, now, useDSForScale, 1d); secondGraphData.addDeviationSlope(fromTime, now, useDSForScale, 1d);
@ -1585,6 +1531,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|| SP.getBoolean("showcob", true) || SP.getBoolean("showcob", true)
|| SP.getBoolean("showdeviations", false) || SP.getBoolean("showdeviations", false)
|| SP.getBoolean("showratios", false) || SP.getBoolean("showratios", false)
|| SP.getBoolean("showactivitysecondary", false)
|| SP.getBoolean("showdevslope", false)) { || SP.getBoolean("showdevslope", false)) {
iobGraph.setVisibility(View.VISIBLE); iobGraph.setVisibility(View.VISIBLE);
} else { } else {
@ -1603,21 +1550,6 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
Profiler.log(log, from, updateGUIStart); Profiler.log(log, from, updateGUIStart);
} }
//Notifications
void updateNotifications() {
NotificationStore nstore = OverviewPlugin.getPlugin().notificationStore;
nstore.removeExpired();
nstore.unSnooze();
if (nstore.store.size() > 0) {
NotificationRecyclerViewAdapter adapter = new NotificationRecyclerViewAdapter(nstore.store);
notificationsView.setAdapter(adapter);
notificationsView.setVisibility(View.VISIBLE);
} else {
notificationsView.setVisibility(View.GONE);
}
}
public static void applyStatuslight(TextView view, String text, double value, double warnThreshold, double urgentThreshold, double invalid, boolean checkAscending) { public static void applyStatuslight(TextView view, String text, double value, double warnThreshold, double urgentThreshold, double invalid, boolean checkAscending) {
Function<Double, Boolean> check = checkAscending ? (Double threshold) -> value >= threshold : (Double threshold) -> value <= threshold; Function<Double, Boolean> check = checkAscending ? (Double threshold) -> value >= threshold : (Double threshold) -> value <= threshold;
if (value != invalid) { if (value != invalid) {

View file

@ -2,11 +2,11 @@ package info.nightscout.androidaps.plugins.general.overview.activities;
import android.app.Activity; import android.app.Activity;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import android.support.v7.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import android.support.v7.widget.CardView; import androidx.cardview.widget.CardView;
import android.support.v7.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;

View file

@ -4,7 +4,7 @@ package info.nightscout.androidaps.plugins.general.overview.dialogs;
import android.app.Activity; import android.app.Activity;
import android.os.Bundle; import android.os.Bundle;
import android.os.SystemClock; import android.os.SystemClock;
import android.support.v4.app.DialogFragment; import androidx.fragment.app.DialogFragment;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;

View file

@ -1,7 +1,7 @@
package info.nightscout.androidaps.plugins.general.overview.dialogs; package info.nightscout.androidaps.plugins.general.overview.dialogs;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
/** /**
* Created by adrian on 09/02/17. * Created by adrian on 09/02/17.

View file

@ -3,7 +3,7 @@ package info.nightscout.androidaps.plugins.general.overview.dialogs;
import android.content.Context; import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.DialogFragment; import androidx.fragment.app.DialogFragment;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -18,7 +18,7 @@ import java.text.DecimalFormat;
import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.GlucoseStatus; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
import info.nightscout.androidaps.utils.NumberPicker; import info.nightscout.androidaps.utils.NumberPicker;

View file

@ -2,7 +2,7 @@ package info.nightscout.androidaps.plugins.general.overview.dialogs;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.DialogFragment; import androidx.fragment.app.DialogFragment;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;

View file

@ -2,8 +2,9 @@ package info.nightscout.androidaps.plugins.general.overview.dialogs;
import android.content.Intent; import android.content.Intent;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.DialogFragment; import androidx.fragment.app.DialogFragment;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -98,7 +99,10 @@ public class ErrorDialog extends DialogFragment implements View.OnClickListener
private void startAlarm() { private void startAlarm() {
Intent alarm = new Intent(MainApp.instance().getApplicationContext(), AlarmSoundService.class); Intent alarm = new Intent(MainApp.instance().getApplicationContext(), AlarmSoundService.class);
alarm.putExtra("soundid", soundId); alarm.putExtra("soundid", soundId);
MainApp.instance().startService(alarm); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
MainApp.instance().startForegroundService(alarm);
else
MainApp.instance().startService(alarm);
} }
private void stopAlarm() { private void stopAlarm() {

View file

@ -1,7 +1,7 @@
package info.nightscout.androidaps.plugins.general.overview.dialogs; package info.nightscout.androidaps.plugins.general.overview.dialogs;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload; import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;

View file

@ -2,8 +2,8 @@ package info.nightscout.androidaps.plugins.general.overview.dialogs;
import android.os.Bundle; import android.os.Bundle;
import android.os.HandlerThread; import android.os.HandlerThread;
import android.support.v4.app.DialogFragment; import androidx.fragment.app.DialogFragment;
import android.support.v7.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import android.text.Editable; import android.text.Editable;
import android.text.Html; import android.text.Html;
import android.text.TextWatcher; import android.text.TextWatcher;

View file

@ -4,8 +4,8 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.os.HandlerThread; import android.os.HandlerThread;
import android.support.v4.app.DialogFragment; import androidx.fragment.app.DialogFragment;
import android.support.v7.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import android.text.Editable; import android.text.Editable;
import android.text.Html; import android.text.Html;
import android.text.TextWatcher; import android.text.TextWatcher;
@ -225,7 +225,7 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener
} }
} }
if (Math.abs(insulinAfterConstraints - insulin) > pump.getPumpDescription().pumpType.determineCorrectBolusSize(insulinAfterConstraints)) if (Math.abs(insulinAfterConstraints - insulin) > pump.getPumpDescription().pumpType.determineCorrectBolusStepSize(insulinAfterConstraints))
actions.add("<font color='" + MainApp.gc(R.color.warning) + "'>" + MainApp.gs(R.string.bolusconstraintapplied) + "</font>"); actions.add("<font color='" + MainApp.gc(R.color.warning) + "'>" + MainApp.gs(R.string.bolusconstraintapplied) + "</font>");
int eatingSoonTTDuration = SP.getInt(R.string.key_eatingsoon_duration, Constants.defaultEatingSoonTTDuration); int eatingSoonTTDuration = SP.getInt(R.string.key_eatingsoon_duration, Constants.defaultEatingSoonTTDuration);

View file

@ -4,8 +4,8 @@ import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.DialogFragment; import androidx.fragment.app.DialogFragment;
import android.support.v7.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import android.text.Editable; import android.text.Editable;
import android.text.Html; import android.text.Html;
import android.text.TextWatcher; import android.text.TextWatcher;
@ -141,7 +141,7 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene
if (recordOnlyCheckbox.isChecked()) { if (recordOnlyCheckbox.isChecked()) {
confirmMessage += "<br/><font color='" + MainApp.gc(R.color.warning) + "'>" + MainApp.gs(R.string.bolusrecordedonly) + "</font>"; confirmMessage += "<br/><font color='" + MainApp.gc(R.color.warning) + "'>" + MainApp.gs(R.string.bolusrecordedonly) + "</font>";
} }
if (Math.abs(insulinAfterConstraints - insulin) > pump.getPumpDescription().pumpType.determineCorrectBolusSize(insulinAfterConstraints) || !Objects.equals(carbsAfterConstraints, carbs)) if (Math.abs(insulinAfterConstraints - insulin) > pump.getPumpDescription().pumpType.determineCorrectBolusStepSize(insulinAfterConstraints) || !Objects.equals(carbsAfterConstraints, carbs))
confirmMessage += "<br/><font color='" + MainApp.gc(R.color.warning) + "'>" + MainApp.gs(R.string.bolusconstraintapplied) + "</font>"; confirmMessage += "<br/><font color='" + MainApp.gc(R.color.warning) + "'>" + MainApp.gs(R.string.bolusconstraintapplied) + "</font>";
} }
if (carbsAfterConstraints > 0) if (carbsAfterConstraints > 0)

View file

@ -2,13 +2,10 @@ package info.nightscout.androidaps.plugins.general.overview.dialogs;
import android.app.Activity; import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.DialogFragment; import androidx.fragment.app.DialogFragment;
import android.support.v7.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import android.text.Editable; import android.text.Editable;
import android.text.Html;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
@ -28,46 +25,35 @@ import android.widget.TextView;
import com.squareup.otto.Subscribe; import com.squareup.otto.Subscribe;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.DetailedBolusInfo;
import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.IobTotal;
import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.ProfileStore; import info.nightscout.androidaps.data.ProfileStore;
import info.nightscout.androidaps.db.BgReading; import info.nightscout.androidaps.db.BgReading;
import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.db.DatabaseHelper; import info.nightscout.androidaps.db.DatabaseHelper;
import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.db.TempTarget; import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.androidaps.events.EventFeatureRunning; import info.nightscout.androidaps.events.EventFeatureRunning;
import info.nightscout.androidaps.events.EventRefreshOverview;
import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.CobInfo; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.CobInfo;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensCalculationFinished; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensCalculationFinished;
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin; import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
import info.nightscout.androidaps.queue.Callback;
import info.nightscout.androidaps.utils.BolusWizard; import info.nightscout.androidaps.utils.BolusWizard;
import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.DecimalFormatter; import info.nightscout.androidaps.utils.DecimalFormatter;
import info.nightscout.androidaps.utils.NumberPicker; import info.nightscout.androidaps.utils.NumberPicker;
import info.nightscout.androidaps.utils.SP; import info.nightscout.androidaps.utils.SP;
import info.nightscout.androidaps.utils.SafeParse; import info.nightscout.androidaps.utils.SafeParse;
import info.nightscout.androidaps.utils.StringUtils;
import info.nightscout.androidaps.utils.ToastUtils; import info.nightscout.androidaps.utils.ToastUtils;
public class WizardDialog extends DialogFragment implements OnClickListener, CompoundButton.OnCheckedChangeListener, Spinner.OnItemSelectedListener { public class WizardDialog extends DialogFragment implements OnClickListener, CompoundButton.OnCheckedChangeListener, Spinner.OnItemSelectedListener {
@ -108,8 +94,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
EditText notesEdit; EditText notesEdit;
Integer calculatedCarbs = 0; Integer calculatedCarbs = 0;
Double calculatedTotalInsulin = 0d; BolusWizard wizard;
JSONObject boluscalcJSON;
Context context; Context context;
@ -311,99 +296,8 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
return; return;
} }
okClicked = true; okClicked = true;
final Profile profile = ProfileFunctions.getInstance().getProfile(); wizard.confirmAndExecute(context);
final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); dismiss();
if (pump != null && profile != null && (calculatedTotalInsulin > 0d || calculatedCarbs > 0d)) {
String confirmMessage = MainApp.gs(R.string.entertreatmentquestion);
Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(calculatedTotalInsulin)).value();
Integer carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(calculatedCarbs)).value();
if (insulinAfterConstraints > 0)
confirmMessage += "<br/>" + MainApp.gs(R.string.bolus) + ": " + "<font color='" + MainApp.gc(R.color.bolus) + "'>" + DecimalFormatter.toPumpSupportedBolus(insulinAfterConstraints) + "U" + "</font>";
if (carbsAfterConstraints > 0)
confirmMessage += "<br/>" + MainApp.gs(R.string.carbs) + ": " + "<font color='" + MainApp.gc(R.color.carbs) + "'>" + carbsAfterConstraints + "g" + "</font>";
if (Math.abs(insulinAfterConstraints - calculatedTotalInsulin) > pump.getPumpDescription().pumpType.determineCorrectBolusSize(insulinAfterConstraints) || !carbsAfterConstraints.equals(calculatedCarbs)) {
confirmMessage += "<br/><font color='" + MainApp.gc(R.color.warning) + "'>" + MainApp.gs(R.string.bolusconstraintapplied) + "</font>";
}
final Double finalInsulinAfterConstraints = insulinAfterConstraints;
final Integer finalCarbsAfterConstraints = carbsAfterConstraints;
final Double bg = SafeParse.stringToDouble(editBg.getText());
final int carbTime = SafeParse.stringToInt(editCarbTime.getText());
final boolean useSuperBolus = superbolusCheckbox.isChecked();
final String finalNotes = notesEdit.getText().toString();
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(MainApp.gs(R.string.confirmation));
builder.setMessage(Html.fromHtml(confirmMessage));
builder.setPositiveButton(MainApp.gs(R.string.ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
synchronized (builder) {
if (accepted) {
log.debug("guarding: already accepted");
return;
}
accepted = true;
if (finalInsulinAfterConstraints > 0 || finalCarbsAfterConstraints > 0) {
if (useSuperBolus) {
final LoopPlugin loopPlugin = LoopPlugin.getPlugin();
if (loopPlugin.isEnabled(PluginType.LOOP)) {
loopPlugin.superBolusTo(System.currentTimeMillis() + 2 * 60L * 60 * 1000);
MainApp.bus().post(new EventRefreshOverview("WizardDialog"));
}
ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalPercent(0, 120, true, profile, new Callback() {
@Override
public void run() {
if (!result.success) {
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
i.putExtra("soundid", R.raw.boluserror);
i.putExtra("status", result.comment);
i.putExtra("title", MainApp.gs(R.string.tempbasaldeliveryerror));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MainApp.instance().startActivity(i);
}
}
});
}
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
detailedBolusInfo.eventType = CareportalEvent.BOLUSWIZARD;
detailedBolusInfo.insulin = finalInsulinAfterConstraints;
detailedBolusInfo.carbs = finalCarbsAfterConstraints;
detailedBolusInfo.context = context;
detailedBolusInfo.glucose = bg;
detailedBolusInfo.glucoseType = "Manual";
detailedBolusInfo.carbTime = carbTime;
detailedBolusInfo.boluscalc = boluscalcJSON;
detailedBolusInfo.source = Source.USER;
detailedBolusInfo.notes = finalNotes;
if (detailedBolusInfo.insulin > 0 || ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().storesCarbInfo) {
ConfigBuilderPlugin.getPlugin().getCommandQueue().bolus(detailedBolusInfo, new Callback() {
@Override
public void run() {
if (!result.success) {
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
i.putExtra("soundid", R.raw.boluserror);
i.putExtra("status", result.comment);
i.putExtra("title", MainApp.gs(R.string.treatmentdeliveryerror));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MainApp.instance().startActivity(i);
}
}
});
} else {
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false);
}
}
}
}
});
builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
builder.show();
dismiss();
}
break; break;
case R.id.cancel: case R.id.cancel:
dismiss(); dismiss();
@ -450,8 +344,8 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
TreatmentsPlugin.getPlugin().updateTotalIOBTempBasals(); TreatmentsPlugin.getPlugin().updateTotalIOBTempBasals();
IobTotal basalIob = TreatmentsPlugin.getPlugin().getLastCalculationTempBasals().round(); IobTotal basalIob = TreatmentsPlugin.getPlugin().getLastCalculationTempBasals().round();
bolusIobInsulin.setText(DecimalFormatter.to2Decimal(-bolusIob.iob) + "U"); bolusIobInsulin.setText(StringUtils.formatInsulin(-bolusIob.iob));
basalIobInsulin.setText(DecimalFormatter.to2Decimal(-basalIob.basaliob) + "U"); basalIobInsulin.setText(StringUtils.formatInsulin(-basalIob.basaliob));
calculateInsulin(); calculateInsulin();
} }
@ -460,13 +354,13 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
ProfileStore profileStore = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getProfile(); ProfileStore profileStore = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getProfile();
if (profileSpinner == null || profileSpinner.getSelectedItem() == null || profileStore == null) if (profileSpinner == null || profileSpinner.getSelectedItem() == null || profileStore == null)
return; // not initialized yet return; // not initialized yet
String selectedAlternativeProfile = profileSpinner.getSelectedItem().toString(); String profileName = profileSpinner.getSelectedItem().toString();
Profile specificProfile; Profile specificProfile;
if (selectedAlternativeProfile.equals(MainApp.gs(R.string.active))) { if (profileName.equals(MainApp.gs(R.string.active))) {
specificProfile = ProfileFunctions.getInstance().getProfile(); specificProfile = ProfileFunctions.getInstance().getProfile();
selectedAlternativeProfile = ProfileFunctions.getInstance().getProfileName(); profileName = ProfileFunctions.getInstance().getProfileName();
} else } else
specificProfile = profileStore.getSpecificProfile(selectedAlternativeProfile); specificProfile = profileStore.getSpecificProfile(profileName);
// Entered values // Entered values
Double c_bg = SafeParse.stringToDouble(editBg.getText()); Double c_bg = SafeParse.stringToDouble(editBg.getText());
@ -494,104 +388,61 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
Double c_cob = 0d; Double c_cob = 0d;
if (cobCheckbox.isChecked()) { if (cobCheckbox.isChecked()) {
CobInfo cobInfo = IobCobCalculatorPlugin.getPlugin().getCobInfo(false, "Wizard COB"); CobInfo cobInfo = IobCobCalculatorPlugin.getPlugin().getCobInfo(false, "Wizard COB");
if (cobInfo != null && cobInfo.displayCob != null) if (cobInfo.displayCob != null)
c_cob = cobInfo.displayCob; c_cob = cobInfo.displayCob;
} }
BolusWizard wizard = new BolusWizard(); wizard = new BolusWizard(specificProfile, profileName, tempTarget, carbsAfterConstraint, c_cob, c_bg, corrAfterConstraint, 100d, bgCheckbox.isChecked(), cobCheckbox.isChecked(), bolusIobCheckbox.isChecked(), basalIobCheckbox.isChecked(), superbolusCheckbox.isChecked(), ttCheckbox.isChecked(), bgtrendCheckbox.isChecked(), notesEdit.getText().toString(), SafeParse.stringToInt(editCarbTime.getText()));
wizard.doCalc(specificProfile, tempTarget, carbsAfterConstraint, c_cob, c_bg, corrAfterConstraint, bolusIobCheckbox.isChecked(), basalIobCheckbox.isChecked(), superbolusCheckbox.isChecked(), bgtrendCheckbox.isChecked());
bg.setText(c_bg + " ISF: " + DecimalFormatter.to1Decimal(wizard.sens)); bg.setText(c_bg + " ISF: " + DecimalFormatter.to1Decimal(wizard.getSens()));
bgInsulin.setText(DecimalFormatter.to2Decimal(wizard.insulinFromBG) + "U"); bgInsulin.setText(StringUtils.formatInsulin(wizard.getInsulinFromBG()));
carbs.setText(DecimalFormatter.to0Decimal(c_carbs) + "g IC: " + DecimalFormatter.to1Decimal(wizard.ic)); carbs.setText(DecimalFormatter.to0Decimal(c_carbs) + "g IC: " + DecimalFormatter.to1Decimal(wizard.getIc()));
carbsInsulin.setText(DecimalFormatter.to2Decimal(wizard.insulinFromCarbs) + "U"); carbsInsulin.setText(StringUtils.formatInsulin(wizard.getInsulinFromCarbs()));
bolusIobInsulin.setText(DecimalFormatter.to2Decimal(wizard.insulingFromBolusIOB) + "U"); bolusIobInsulin.setText(StringUtils.formatInsulin(wizard.getInsulinFromBolusIOB()));
basalIobInsulin.setText(DecimalFormatter.to2Decimal(wizard.insulingFromBasalsIOB) + "U"); basalIobInsulin.setText(StringUtils.formatInsulin(wizard.getInsulinFromBasalsIOB()));
correctionInsulin.setText(DecimalFormatter.to2Decimal(wizard.insulinFromCorrection) + "U"); correctionInsulin.setText(StringUtils.formatInsulin(wizard.getInsulinFromCorrection()));
calculatedTotalInsulin = wizard.calculatedTotalInsulin;
calculatedCarbs = carbsAfterConstraint; calculatedCarbs = carbsAfterConstraint;
// Superbolus // Superbolus
if (superbolusCheckbox.isChecked()) { superbolus.setText(superbolusCheckbox.isChecked() ? MainApp.gs(R.string.twohours) : "");
superbolus.setText("2h"); superbolusInsulin.setText(StringUtils.formatInsulin(wizard.getInsulinFromSuperBolus()));
} else {
superbolus.setText("");
}
superbolusInsulin.setText(DecimalFormatter.to2Decimal(wizard.insulinFromSuperBolus) + "U");
// Trend // Trend
if (bgtrendCheckbox.isChecked()) { if (bgtrendCheckbox.isChecked() && wizard.getGlucoseStatus() != null) {
if (wizard.glucoseStatus != null) { bgTrend.setText(
bgTrend.setText((wizard.glucoseStatus.avgdelta > 0 ? "+" : "") + Profile.toUnitsString(wizard.glucoseStatus.avgdelta * 3, wizard.glucoseStatus.avgdelta * 3 / 18, specificProfile.getUnits()) + " " + specificProfile.getUnits()); (wizard.getTrend() > 0 ? "+" : "")
} else { + Profile.toUnitsString(wizard.getTrend() * 3, wizard.getTrend() * 3 / Constants.MMOLL_TO_MGDL, specificProfile.getUnits())
bgTrend.setText(""); + " " + specificProfile.getUnits());
}
} else { } else {
bgTrend.setText(""); bgTrend.setText("");
} }
bgTrendInsulin.setText(DecimalFormatter.to2Decimal(wizard.insulinFromTrend) + "U"); bgTrendInsulin.setText(StringUtils.formatInsulin(wizard.getInsulinFromTrend()));
// COB // COB
if (cobCheckbox.isChecked()) { if (cobCheckbox.isChecked()) {
cob.setText(DecimalFormatter.to2Decimal(c_cob) + "g IC: " + DecimalFormatter.to1Decimal(wizard.ic)); cob.setText(DecimalFormatter.to2Decimal(c_cob) + "g IC: " + DecimalFormatter.to1Decimal(wizard.getIc()));
cobInsulin.setText(DecimalFormatter.to2Decimal(wizard.insulinFromCOB) + "U"); cobInsulin.setText(StringUtils.formatInsulin(wizard.getInsulinFromCOB()));
} else { } else {
cob.setText(""); cob.setText("");
cobInsulin.setText(""); cobInsulin.setText("");
} }
if (calculatedTotalInsulin > 0d || calculatedCarbs > 0d) { if (wizard.getCalculatedTotalInsulin() > 0d || calculatedCarbs > 0d) {
String insulinText = calculatedTotalInsulin > 0d ? (DecimalFormatter.toPumpSupportedBolus(calculatedTotalInsulin) + "U") : ""; String insulinText = wizard.getCalculatedTotalInsulin() > 0d ? (DecimalFormatter.toPumpSupportedBolus(wizard.getCalculatedTotalInsulin()) + "U") : "";
String carbsText = calculatedCarbs > 0d ? (DecimalFormatter.to0Decimal(calculatedCarbs) + "g") : ""; String carbsText = calculatedCarbs > 0d ? (DecimalFormatter.to0Decimal(calculatedCarbs) + "g") : "";
total.setText(MainApp.gs(R.string.result) + ": " + insulinText + " " + carbsText); total.setText(MainApp.gs(R.string.result) + ": " + insulinText + " " + carbsText);
okButton.setVisibility(View.VISIBLE); okButton.setVisibility(View.VISIBLE);
} else { } else {
// TODO this should also be run when loading the dialog as the OK button is initially visible // TODO this should also be run when loading the dialog as the OK button is initially visible
// but does nothing if neither carbs nor insulin is > 0 // but does nothing if neither carbs nor insulin is > 0
total.setText(MainApp.gs(R.string.missing) + " " + DecimalFormatter.to0Decimal(wizard.carbsEquivalent) + "g"); total.setText(MainApp.gs(R.string.missing) + " " + DecimalFormatter.to0Decimal(wizard.getCarbsEquivalent()) + "g");
okButton.setVisibility(View.INVISIBLE); okButton.setVisibility(View.INVISIBLE);
} }
boluscalcJSON = new JSONObject();
try {
boluscalcJSON.put("profile", selectedAlternativeProfile);
boluscalcJSON.put("notes", notesEdit.getText());
boluscalcJSON.put("eventTime", DateUtil.toISOString(new Date()));
boluscalcJSON.put("targetBGLow", wizard.targetBGLow);
boluscalcJSON.put("targetBGHigh", wizard.targetBGHigh);
boluscalcJSON.put("isf", wizard.sens);
boluscalcJSON.put("ic", wizard.ic);
boluscalcJSON.put("iob", -(wizard.insulingFromBolusIOB + wizard.insulingFromBasalsIOB));
boluscalcJSON.put("bolusiob", wizard.insulingFromBolusIOB);
boluscalcJSON.put("basaliob", wizard.insulingFromBasalsIOB);
boluscalcJSON.put("bolusiobused", bolusIobCheckbox.isChecked());
boluscalcJSON.put("basaliobused", basalIobCheckbox.isChecked());
boluscalcJSON.put("bg", c_bg);
boluscalcJSON.put("insulinbg", wizard.insulinFromBG);
boluscalcJSON.put("insulinbgused", bgCheckbox.isChecked());
boluscalcJSON.put("bgdiff", wizard.bgDiff);
boluscalcJSON.put("insulincarbs", wizard.insulinFromCarbs);
boluscalcJSON.put("carbs", c_carbs);
boluscalcJSON.put("cob", c_cob);
boluscalcJSON.put("cobused", cobCheckbox.isChecked());
boluscalcJSON.put("insulincob", wizard.insulinFromCOB);
boluscalcJSON.put("othercorrection", corrAfterConstraint);
boluscalcJSON.put("insulinsuperbolus", wizard.insulinFromSuperBolus);
boluscalcJSON.put("insulintrend", wizard.insulinFromTrend);
boluscalcJSON.put("insulin", calculatedTotalInsulin);
boluscalcJSON.put("superbolusused", superbolusCheckbox.isChecked());
boluscalcJSON.put("insulinsuperbolus", wizard.insulinFromSuperBolus);
boluscalcJSON.put("trendused", bgtrendCheckbox.isChecked());
boluscalcJSON.put("insulintrend", wizard.insulinFromTrend);
boluscalcJSON.put("trend", bgTrend.getText());
boluscalcJSON.put("ttused", ttCheckbox.isChecked());
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
} }
} }

View file

@ -50,6 +50,7 @@ import info.nightscout.androidaps.plugins.treatments.Treatment;
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin; import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
import info.nightscout.androidaps.utils.DecimalFormatter; import info.nightscout.androidaps.utils.DecimalFormatter;
import info.nightscout.androidaps.utils.Round; import info.nightscout.androidaps.utils.Round;
import info.nightscout.androidaps.utils.SP;
/** /**
* Created by mike on 18.10.2017. * Created by mike on 18.10.2017.
@ -348,6 +349,59 @@ public class GraphData {
? Profile.fromMgdlToUnits(bgReadingsArray.get(0).value, units) : Profile.fromMgdlToUnits(100, units); ? Profile.fromMgdlToUnits(bgReadingsArray.get(0).value, units) : Profile.fromMgdlToUnits(100, units);
} }
public void addActivity(long fromTime, long toTime, boolean useForScale, double scale) {
FixedLineGraphSeries<ScaledDataPoint> actSeriesHist;
List<ScaledDataPoint> actArrayHist = new ArrayList<>();
FixedLineGraphSeries<ScaledDataPoint> actSeriesPred;
List<ScaledDataPoint> actArrayPred = new ArrayList<>();
double now = System.currentTimeMillis();
Scale actScale = new Scale();
IobTotal total = null;
for (long time = fromTime; time <= toTime; time += 5 * 60 * 1000L) {
Profile profile = ProfileFunctions.getInstance().getProfile(time);
double act = 0d;
if (profile == null) continue;
total = iobCobCalculatorPlugin.calculateFromTreatmentsAndTempsSynchronized(time, profile);
act = total.activity;
if(time<=now)
actArrayHist.add(new ScaledDataPoint(time, act, actScale));
else
actArrayPred.add(new ScaledDataPoint(time, act, actScale));
}
ScaledDataPoint[] actData = new ScaledDataPoint[actArrayHist.size()];
actData = actArrayHist.toArray(actData);
actSeriesHist = new FixedLineGraphSeries<>(actData);
actSeriesHist.setDrawBackground(false);
actSeriesHist.setColor(MainApp.gc(R.color.activity));
actSeriesHist.setThickness(3);
addSeries(actSeriesHist);
actData = new ScaledDataPoint[actArrayPred.size()];
actData = actArrayPred.toArray(actData);
actSeriesPred = new FixedLineGraphSeries<>(actData);
Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(3);
paint.setPathEffect(new DashPathEffect(new float[]{4, 4}, 0));
paint.setColor(MainApp.gc(R.color.activity));
actSeriesPred.setCustomPaint(paint);
double maxIAValue = SP.getDouble(R.string.key_scale_insulin_activity, 0.05);
if (useForScale) {
maxY = maxIAValue;
minY = -maxIAValue;
}
actScale.setMultiplier(maxY * scale / maxIAValue);
addSeries(actSeriesPred);
}
// scale in % of vertical size (like 0.3) // scale in % of vertical size (like 0.3)
public void addIob(long fromTime, long toTime, boolean useForScale, double scale) { public void addIob(long fromTime, long toTime, boolean useForScale, double scale) {
FixedLineGraphSeries<ScaledDataPoint> iobSeries; FixedLineGraphSeries<ScaledDataPoint> iobSeries;

View file

@ -3,7 +3,7 @@ package info.nightscout.androidaps.plugins.general.overview.notifications;
import android.app.IntentService; import android.app.IntentService;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.Intent; import android.content.Intent;
import android.support.annotation.Nullable; import androidx.annotation.Nullable;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification; import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification;

View file

@ -74,6 +74,7 @@ public class Notification {
public static final int DST_LOOP_DISABLED = 49; public static final int DST_LOOP_DISABLED = 49;
public static final int DST_IN_24H = 50; public static final int DST_IN_24H = 50;
public static final int DISKFULL = 51; public static final int DISKFULL = 51;
public static final int OLDVERSION = 52;
public int id; public int id;

View file

@ -1,8 +1,8 @@
package info.nightscout.androidaps.plugins.general.overview.notifications; package info.nightscout.androidaps.plugins.general.overview.notifications;
import android.support.v4.content.ContextCompat; import androidx.core.content.ContextCompat;
import android.support.v7.widget.CardView; import androidx.cardview.widget.CardView;
import android.support.v7.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;

View file

@ -11,7 +11,9 @@ import android.media.AudioAttributes;
import android.media.RingtoneManager; import android.media.RingtoneManager;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.support.v4.app.NotificationCompat; import androidx.core.app.NotificationCompat;
import androidx.recyclerview.widget.RecyclerView;
import android.view.View;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -21,7 +23,6 @@ import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.logging.L;
@ -68,14 +69,20 @@ public class NotificationStore {
if (usesChannels && n.soundId != null) { if (usesChannels && n.soundId != null) {
Intent alarm = new Intent(MainApp.instance().getApplicationContext(), AlarmSoundService.class); Intent alarm = new Intent(MainApp.instance().getApplicationContext(), AlarmSoundService.class);
alarm.putExtra("soundid", n.soundId); alarm.putExtra("soundid", n.soundId);
MainApp.instance().startService(alarm); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
MainApp.instance().startForegroundService(alarm);
else
MainApp.instance().startService(alarm);
} }
} else { } else {
if (n.soundId != null) { if (n.soundId != null) {
Intent alarm = new Intent(MainApp.instance().getApplicationContext(), AlarmSoundService.class); Intent alarm = new Intent(MainApp.instance().getApplicationContext(), AlarmSoundService.class);
alarm.putExtra("soundid", n.soundId); alarm.putExtra("soundid", n.soundId);
MainApp.instance().startService(alarm); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
MainApp.instance().startForegroundService(alarm);
else
MainApp.instance().startService(alarm);
} }
} }
@ -97,7 +104,7 @@ public class NotificationStore {
return false; return false;
} }
public synchronized void removeExpired() { private synchronized void removeExpired() {
for (int i = 0; i < store.size(); i++) { for (int i = 0; i < store.size(); i++) {
Notification n = store.get(i); Notification n = store.get(i);
if (n.validTo.getTime() != 0 && n.validTo.getTime() < System.currentTimeMillis()) { if (n.validTo.getTime() != 0 && n.validTo.getTime() < System.currentTimeMillis()) {
@ -107,13 +114,13 @@ public class NotificationStore {
} }
} }
public void snoozeTo(long timeToSnooze) { void snoozeTo(long timeToSnooze) {
if (L.isEnabled(L.NOTIFICATION)) if (L.isEnabled(L.NOTIFICATION))
log.debug("Snoozing alarm until: " + timeToSnooze); log.debug("Snoozing alarm until: " + timeToSnooze);
SP.putLong("snoozedTo", timeToSnooze); SP.putLong("snoozedTo", timeToSnooze);
} }
public void unSnooze() { private void unSnooze() {
if (Notification.isAlarmForStaleData()) { if (Notification.isAlarmForStaleData()) {
Notification notification = new Notification(Notification.NSALARM, MainApp.gs(R.string.nsalarm_staledata), Notification.URGENT); Notification notification = new Notification(Notification.NSALARM, MainApp.gs(R.string.nsalarm_staledata), Notification.URGENT);
SP.putLong("snoozedTo", System.currentTimeMillis()); SP.putLong("snoozedTo", System.currentTimeMillis());
@ -160,4 +167,16 @@ public class NotificationStore {
} }
} }
public synchronized void updateNotifications(RecyclerView notificationsView) {
removeExpired();
unSnooze();
if (store.size() > 0) {
NotificationRecyclerViewAdapter adapter = new NotificationRecyclerViewAdapter(store);
notificationsView.setAdapter(adapter);
notificationsView.setVisibility(View.VISIBLE);
} else {
notificationsView.setVisibility(View.GONE);
}
}
} }

View file

@ -4,7 +4,8 @@ import android.app.Notification;
import android.app.Service; import android.app.Service;
import android.content.Intent; import android.content.Intent;
import android.os.IBinder; import android.os.IBinder;
import android.support.annotation.Nullable;
import androidx.annotation.Nullable;
import com.squareup.otto.Subscribe; import com.squareup.otto.Subscribe;
@ -29,9 +30,8 @@ public class DummyService extends Service {
@Override @Override
public int onStartCommand(Intent intent, int flags, int startId) { public int onStartCommand(Intent intent, int flags, int startId) {
Notification notification = PersistentNotificationPlugin.getPlugin().updateNotification(); super.onStartCommand(intent, flags, startId);
if (notification != null) startForeground(PersistentNotificationPlugin.ONGOING_NOTIFICATION_ID, PersistentNotificationPlugin.getPlugin().updateNotification());
startForeground(PersistentNotificationPlugin.ONGOING_NOTIFICATION_ID, notification);
return START_STICKY; return START_STICKY;
} }
@ -45,6 +45,11 @@ public class DummyService extends Service {
@Override @Override
public void onCreate() { public void onCreate() {
super.onCreate();
// TODO: I guess this was moved here in order to adhere to the 5 seconds rule to call "startForeground" after a Service was called as Foreground service?
// As onCreate() is not called every time a service is started, copied to onStartCommand().
Notification notification = PersistentNotificationPlugin.getPlugin().updateNotification();
startForeground(PersistentNotificationPlugin.ONGOING_NOTIFICATION_ID, notification);
MainApp.bus().register(this); MainApp.bus().register(this);
} }

View file

@ -10,17 +10,19 @@ import android.content.Intent;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.os.Build; import android.os.Build;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.RemoteInput; import androidx.core.app.NotificationCompat;
import android.support.v4.app.TaskStackBuilder; import androidx.core.app.RemoteInput;
import androidx.core.app.TaskStackBuilder;
import com.squareup.otto.Subscribe; import com.squareup.otto.Subscribe;
import javax.annotation.Nonnull;
import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainActivity; import info.nightscout.androidaps.MainActivity;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.GlucoseStatus;
import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.IobTotal;
import info.nightscout.androidaps.db.BgReading; import info.nightscout.androidaps.db.BgReading;
import info.nightscout.androidaps.db.DatabaseHelper; import info.nightscout.androidaps.db.DatabaseHelper;
@ -37,6 +39,7 @@ import info.nightscout.androidaps.interfaces.PluginDescription;
import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensCalculationFinished; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensCalculationFinished;
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin; import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
@ -49,6 +52,7 @@ import info.nightscout.androidaps.utils.DecimalFormatter;
public class PersistentNotificationPlugin extends PluginBase { public class PersistentNotificationPlugin extends PluginBase {
private static PersistentNotificationPlugin plugin; private static PersistentNotificationPlugin plugin;
private Notification notification;
public static PersistentNotificationPlugin getPlugin() { public static PersistentNotificationPlugin getPlugin() {
if (plugin == null) plugin = new PersistentNotificationPlugin(MainApp.instance()); if (plugin == null) plugin = new PersistentNotificationPlugin(MainApp.instance());
@ -72,13 +76,14 @@ public class PersistentNotificationPlugin extends PluginBase {
/// End Android Auto /// End Android Auto
public PersistentNotificationPlugin(Context ctx) { private PersistentNotificationPlugin(Context ctx) {
super(new PluginDescription() super(new PluginDescription()
.mainType(PluginType.GENERAL) .mainType(PluginType.GENERAL)
.neverVisible(true) .neverVisible(true)
.pluginName(R.string.ongoingnotificaction) .pluginName(R.string.ongoingnotificaction)
.enableByDefault(true) .enableByDefault(true)
.alwaysEnabled(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) .alwaysEnabled(true)
.showInList(false)
.description(R.string.description_persistent_notification) .description(R.string.description_persistent_notification)
); );
this.ctx = ctx; this.ctx = ctx;
@ -86,8 +91,8 @@ public class PersistentNotificationPlugin extends PluginBase {
@Override @Override
protected void onStart() { protected void onStart() {
createNotificationChannel(); // make sure channels exist before triggering updates through the bus
MainApp.bus().register(this); MainApp.bus().register(this);
createNotificationChannel();
triggerNotificationUpdate(); triggerNotificationUpdate();
super.onStart(); super.onStart();
} }
@ -111,105 +116,107 @@ public class PersistentNotificationPlugin extends PluginBase {
} }
private void triggerNotificationUpdate() { private void triggerNotificationUpdate() {
MainApp.instance().startService(new Intent(MainApp.instance(), DummyService.class)); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
MainApp.instance().startForegroundService(new Intent(MainApp.instance(), DummyService.class));
else
MainApp.instance().startService(new Intent(MainApp.instance(), DummyService.class));
} }
@Nonnull
Notification updateNotification() { Notification updateNotification() {
if (!isEnabled(PluginType.GENERAL)) { String line1 = null;
return null; String line2 = null;
} String line3 = null;
NotificationCompat.CarExtender.UnreadConversation.Builder unreadConversationBuilder = null;
String line1; if (ConfigBuilderPlugin.getPlugin().getActiveProfileInterface() != null && ProfileFunctions.getInstance().isProfileValid("Notification")) {
String line1_aa; String line1_aa;
String units = ProfileFunctions.getInstance().getProfileUnits();
if (ConfigBuilderPlugin.getPlugin().getActiveProfileInterface() == null || !ProfileFunctions.getInstance().isProfileValid("Notificiation"))
return null;
String units = ProfileFunctions.getInstance().getProfileUnits();
BgReading lastBG = DatabaseHelper.lastBg(); BgReading lastBG = DatabaseHelper.lastBg();
GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData(); GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData();
if (lastBG != null) { if (lastBG != null) {
line1 = line1_aa = lastBG.valueToUnitsToString(units); line1 = line1_aa = lastBG.valueToUnitsToString(units);
if (glucoseStatus != null) { if (glucoseStatus != null) {
line1 += " Δ" + deltastring(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units) line1 += " Δ" + deltastring(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units)
+ " avgΔ" + deltastring(glucoseStatus.avgdelta, glucoseStatus.avgdelta * Constants.MGDL_TO_MMOLL, units); + " avgΔ" + deltastring(glucoseStatus.avgdelta, glucoseStatus.avgdelta * Constants.MGDL_TO_MMOLL, units);
line1_aa += " " + lastBG.directionToSymbol(); line1_aa += " " + lastBG.directionToSymbol();
} else {
line1 += " " +
MainApp.gs(R.string.old_data) +
" ";
line1_aa += line1 + ".";
}
} else { } else {
line1 += " " + line1 = line1_aa = MainApp.gs(R.string.missed_bg_readings);
MainApp.gs(R.string.old_data) +
" ";
line1_aa += line1 + ".";
} }
} else {
line1 = line1_aa = MainApp.gs(R.string.missed_bg_readings); TemporaryBasal activeTemp = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(System.currentTimeMillis());
if (activeTemp != null) {
line1 += " " + activeTemp.toStringShort();
line1_aa += " " + activeTemp.toStringShort() + ".";
}
//IOB
TreatmentsPlugin.getPlugin().updateTotalIOBTreatments();
TreatmentsPlugin.getPlugin().updateTotalIOBTempBasals();
IobTotal bolusIob = TreatmentsPlugin.getPlugin().getLastCalculationTreatments().round();
IobTotal basalIob = TreatmentsPlugin.getPlugin().getLastCalculationTempBasals().round();
line2 = MainApp.gs(R.string.treatments_iob_label_string) + " " + DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U " + MainApp.gs(R.string.cob) + ": " + IobCobCalculatorPlugin.getPlugin().getCobInfo(false, "PersistentNotificationPlugin").generateCOBString();
String line2_aa = MainApp.gs(R.string.treatments_iob_label_string) + " " + DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U. " + MainApp.gs(R.string.cob) + ": " + IobCobCalculatorPlugin.getPlugin().getCobInfo(false, "PersistentNotificationPlugin").generateCOBString() + ".";
line3 = DecimalFormatter.to2Decimal(ConfigBuilderPlugin.getPlugin().getActivePump().getBaseBasalRate()) + " U/h";
String line3_aa = DecimalFormatter.to2Decimal(ConfigBuilderPlugin.getPlugin().getActivePump().getBaseBasalRate()) + " U/h.";
line3 += " - " + ProfileFunctions.getInstance().getProfileName();
line3_aa += " - " + ProfileFunctions.getInstance().getProfileName() + ".";
/// For Android Auto
Intent msgReadIntent = new Intent()
.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
.setAction(READ_ACTION)
.putExtra(CONVERSATION_ID, ONGOING_NOTIFICATION_ID)
.setPackage(PACKAGE);
PendingIntent msgReadPendingIntent =
PendingIntent.getBroadcast(ctx,
ONGOING_NOTIFICATION_ID,
msgReadIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
Intent msgReplyIntent = new Intent()
.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
.setAction(REPLY_ACTION)
.putExtra(CONVERSATION_ID, ONGOING_NOTIFICATION_ID)
.setPackage(PACKAGE);
PendingIntent msgReplyPendingIntent = PendingIntent.getBroadcast(
ctx,
ONGOING_NOTIFICATION_ID,
msgReplyIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
// Build a RemoteInput for receiving voice input from devices
RemoteInput remoteInput = new RemoteInput.Builder(EXTRA_VOICE_REPLY).build();
// Create the UnreadConversation
unreadConversationBuilder =
new NotificationCompat.CarExtender.UnreadConversation.Builder(line1_aa + "\n" + line2_aa)
.setLatestTimestamp(System.currentTimeMillis())
.setReadPendingIntent(msgReadPendingIntent)
.setReplyAction(msgReplyPendingIntent, remoteInput);
/// Add dot to produce a "more natural sounding result"
unreadConversationBuilder.addMessage(line3_aa);
/// End Android Auto
} }
TemporaryBasal activeTemp = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(System.currentTimeMillis());
if (activeTemp != null) {
line1 += " " + activeTemp.toStringShort();
line1_aa += " " + activeTemp.toStringShort() + ".";
}
//IOB
TreatmentsPlugin.getPlugin().updateTotalIOBTreatments();
TreatmentsPlugin.getPlugin().updateTotalIOBTempBasals();
IobTotal bolusIob = TreatmentsPlugin.getPlugin().getLastCalculationTreatments().round();
IobTotal basalIob = TreatmentsPlugin.getPlugin().getLastCalculationTempBasals().round();
String line2 = MainApp.gs(R.string.treatments_iob_label_string) + " " + DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U " + MainApp.gs(R.string.cob) + ": " + IobCobCalculatorPlugin.getPlugin().getCobInfo(false, "PersistentNotificationPlugin").generateCOBString();
String line2_aa = MainApp.gs(R.string.treatments_iob_label_string) + " " + DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U. " + MainApp.gs(R.string.cob) + ": " + IobCobCalculatorPlugin.getPlugin().getCobInfo(false, "PersistentNotificationPlugin").generateCOBString() + ".";
String line3 = DecimalFormatter.to2Decimal(ConfigBuilderPlugin.getPlugin().getActivePump().getBaseBasalRate()) + " U/h";
String line3_aa = DecimalFormatter.to2Decimal(ConfigBuilderPlugin.getPlugin().getActivePump().getBaseBasalRate()) + " U/h.";
line3 += " - " + ProfileFunctions.getInstance().getProfileName();
line3_aa += " - " + ProfileFunctions.getInstance().getProfileName() + ".";
/// For Android Auto
Intent msgReadIntent = new Intent()
.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
.setAction(READ_ACTION)
.putExtra(CONVERSATION_ID, ONGOING_NOTIFICATION_ID)
.setPackage(PACKAGE);
PendingIntent msgReadPendingIntent =
PendingIntent.getBroadcast(ctx,
ONGOING_NOTIFICATION_ID,
msgReadIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
Intent msgReplyIntent = new Intent()
.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
.setAction(REPLY_ACTION)
.putExtra(CONVERSATION_ID, ONGOING_NOTIFICATION_ID)
.setPackage(PACKAGE);
PendingIntent msgReplyPendingIntent = PendingIntent.getBroadcast(
ctx,
ONGOING_NOTIFICATION_ID,
msgReplyIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
// Build a RemoteInput for receiving voice input from devices
RemoteInput remoteInput = new RemoteInput.Builder(EXTRA_VOICE_REPLY).build();
// Create the UnreadConversation
NotificationCompat.CarExtender.UnreadConversation.Builder unreadConversationBuilder =
new NotificationCompat.CarExtender.UnreadConversation.Builder(line1_aa + "\n" + line2_aa)
.setLatestTimestamp(System.currentTimeMillis())
.setReadPendingIntent(msgReadPendingIntent)
.setReplyAction(msgReplyPendingIntent, remoteInput);
/// Add dot to produce a "more natural sounding result"
unreadConversationBuilder.addMessage(line3_aa);
/// End Android Auto
NotificationCompat.Builder builder = new NotificationCompat.Builder(ctx, CHANNEL_ID); NotificationCompat.Builder builder = new NotificationCompat.Builder(ctx, CHANNEL_ID);
builder.setOngoing(true); builder.setOngoing(true);
builder.setOnlyAlertOnce(true); builder.setOnlyAlertOnce(true);
@ -217,12 +224,14 @@ public class PersistentNotificationPlugin extends PluginBase {
builder.setSmallIcon(MainApp.getNotificationIcon()); builder.setSmallIcon(MainApp.getNotificationIcon());
Bitmap largeIcon = BitmapFactory.decodeResource(ctx.getResources(), MainApp.getIcon()); Bitmap largeIcon = BitmapFactory.decodeResource(ctx.getResources(), MainApp.getIcon());
builder.setLargeIcon(largeIcon); builder.setLargeIcon(largeIcon);
builder.setContentTitle(line1); builder.setContentTitle(line1 != null ? line1 : MainApp.gs(R.string.noprofileset));
builder.setContentText(line2); builder.setContentText(line2 != null ? line2 : MainApp.gs(R.string.noprofileset));
builder.setSubText(line3); builder.setSubText(line3 != null ? line3 : MainApp.gs(R.string.noprofileset));
/// Android Auto /// Android Auto
builder.extend(new NotificationCompat.CarExtender() if (unreadConversationBuilder != null) {
.setUnreadConversation(unreadConversationBuilder.build())); builder.extend(new NotificationCompat.CarExtender()
.setUnreadConversation(unreadConversationBuilder.build()));
}
/// End Android Auto /// End Android Auto
@ -242,6 +251,7 @@ public class PersistentNotificationPlugin extends PluginBase {
android.app.Notification notification = builder.build(); android.app.Notification notification = builder.build();
mNotificationManager.notify(ONGOING_NOTIFICATION_ID, notification); mNotificationManager.notify(ONGOING_NOTIFICATION_ID, notification);
this.notification = notification;
return notification; return notification;
} }
@ -261,6 +271,17 @@ public class PersistentNotificationPlugin extends PluginBase {
return deltastring; return deltastring;
} }
/***
* returns the current ongoing notification.
*
* If it does not exist, return a dummy notification. This should only happen if onStart() wasn't called.
*/
public Notification getLastNotification() {
if (notification != null) return notification;
else return new Notification();
}
@Subscribe @Subscribe
public void onStatusEvent(final EventPreferenceChange ev) { public void onStatusEvent(final EventPreferenceChange ev) {

View file

@ -20,7 +20,7 @@ import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.data.DetailedBolusInfo;
import info.nightscout.androidaps.data.GlucoseStatus; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.IobTotal;
import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.ProfileStore; import info.nightscout.androidaps.data.ProfileStore;

View file

@ -0,0 +1,57 @@
package info.nightscout.androidaps.plugins.general.tidepool
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ScrollView
import androidx.fragment.app.Fragment
import info.nightscout.androidaps.R
import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.tidepool.comm.TidepoolUploader
import info.nightscout.androidaps.plugins.general.tidepool.events.EventTidepoolDoUpload
import info.nightscout.androidaps.plugins.general.tidepool.events.EventTidepoolResetData
import info.nightscout.androidaps.plugins.general.tidepool.events.EventTidepoolUpdateGUI
import info.nightscout.androidaps.utils.SP
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable
import kotlinx.android.synthetic.main.tidepool_fragment.*
class TidepoolFragment : Fragment() {
private var disposable: CompositeDisposable = CompositeDisposable()
operator fun CompositeDisposable.plusAssign(disposable: Disposable) {
add(disposable)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.tidepool_fragment, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
tidepool_login.setOnClickListener { TidepoolUploader.doLogin(false) }
tidepool_uploadnow.setOnClickListener { RxBus.send(EventTidepoolDoUpload()) }
tidepool_removeall.setOnClickListener { RxBus.send(EventTidepoolResetData()) }
tidepool_resertstart.setOnClickListener { SP.putLong(R.string.key_tidepool_last_end, 0) }
disposable.add(RxBus
.toObservable(EventTidepoolUpdateGUI::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
TidepoolPlugin.updateLog()
tidepool_log.text = TidepoolPlugin.textLog
tidepool_status.text = TidepoolUploader.connectionStatus.name
tidepool_log.text = TidepoolPlugin.textLog
tidepool_logscrollview.fullScroll(ScrollView.FOCUS_DOWN)
}, {})
)
}
override fun onStop() {
super.onStop()
disposable.clear()
}
}

View file

@ -0,0 +1,147 @@
package info.nightscout.androidaps.plugins.general.tidepool
import android.text.Html
import android.text.Spanned
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.db.BgReading
import info.nightscout.androidaps.events.EventNetworkChange
import info.nightscout.androidaps.events.EventNewBG
import info.nightscout.androidaps.events.EventPreferenceChange
import info.nightscout.androidaps.interfaces.PluginBase
import info.nightscout.androidaps.interfaces.PluginDescription
import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.logging.L
import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.tidepool.comm.TidepoolUploader
import info.nightscout.androidaps.plugins.general.tidepool.events.EventTidepoolDoUpload
import info.nightscout.androidaps.plugins.general.tidepool.events.EventTidepoolResetData
import info.nightscout.androidaps.plugins.general.tidepool.events.EventTidepoolStatus
import info.nightscout.androidaps.plugins.general.tidepool.events.EventTidepoolUpdateGUI
import info.nightscout.androidaps.plugins.general.tidepool.utils.RateLimit
import info.nightscout.androidaps.receivers.ChargingStateReceiver
import info.nightscout.androidaps.receivers.NetworkChangeReceiver
import info.nightscout.androidaps.utils.SP
import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.ToastUtils
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import org.slf4j.LoggerFactory
import java.util.*
object TidepoolPlugin : PluginBase(PluginDescription()
.mainType(PluginType.GENERAL)
.pluginName(R.string.tidepool)
.shortName(R.string.tidepool_shortname)
.fragmentClass(TidepoolFragment::class.qualifiedName)
.preferencesId(R.xml.pref_tidepool)
.description(R.string.description_tidepool)
) {
private val log = LoggerFactory.getLogger(L.TIDEPOOL)
private var disposable: CompositeDisposable = CompositeDisposable()
private val listLog = ArrayList<EventTidepoolStatus>()
@Suppress("DEPRECATION") // API level 24 to replace call
var textLog: Spanned = Html.fromHtml("")
operator fun CompositeDisposable.plusAssign(disposable: Disposable) {
add(disposable)
}
override fun onStart() {
super.onStart()
disposable += RxBus
.toObservable(EventTidepoolDoUpload::class.java)
.observeOn(Schedulers.io())
.subscribe({ doUpload() }, {})
disposable += RxBus
.toObservable(EventTidepoolResetData::class.java)
.observeOn(Schedulers.io())
.subscribe({
if (TidepoolUploader.connectionStatus != TidepoolUploader.ConnectionStatus.CONNECTED) {
log.debug("Not connected for delete Dataset")
} else {
TidepoolUploader.deleteDataSet()
SP.putLong(R.string.key_tidepool_last_end, 0)
TidepoolUploader.doLogin()
}
}, {})
disposable += RxBus
.toObservable(EventTidepoolStatus::class.java)
.observeOn(Schedulers.io())
.subscribe({ event -> addToLog(event) }, {})
disposable += RxBus
.toObservable(EventNewBG::class.java)
.observeOn(Schedulers.io())
.filter { it.bgReading != null } // better would be optional in API level >24
.map { it.bgReading }
.subscribe { bgReading ->
if (bgReading!!.date < TidepoolUploader.getLastEnd())
TidepoolUploader.setLastEnd(bgReading.date)
if (isEnabled(PluginType.GENERAL)
&& (!SP.getBoolean(R.string.key_tidepool_only_while_charging, false) || ChargingStateReceiver.isCharging())
&& (!SP.getBoolean(R.string.key_tidepool_only_while_unmetered, false) || NetworkChangeReceiver.isWifiConnected())
&& RateLimit.rateLimit("tidepool-new-data-upload", T.mins(4).secs().toInt()))
doUpload()
}
disposable += RxBus
.toObservable(EventPreferenceChange::class.java)
.observeOn(Schedulers.io())
.subscribe({ event ->
if (event.isChanged(R.string.key_tidepool_dev_servers)
|| event.isChanged(R.string.key_tidepool_username)
|| event.isChanged(R.string.key_tidepool_password)
)
TidepoolUploader.resetInstance()
}, {})
disposable += RxBus
.toObservable(EventNetworkChange::class.java)
.observeOn(Schedulers.io())
.subscribe({}, {}) // TODO start upload on wifi connect
}
override fun onStop() {
disposable.clear()
super.onStop()
}
private fun doUpload() {
if (TidepoolUploader.connectionStatus == TidepoolUploader.ConnectionStatus.DISCONNECTED)
TidepoolUploader.doLogin(true)
else
TidepoolUploader.doUpload()
}
@Synchronized
private fun addToLog(ev: EventTidepoolStatus) {
synchronized(listLog) {
listLog.add(ev)
// remove the first line if log is too large
if (listLog.size >= Constants.MAX_LOG_LINES) {
listLog.removeAt(0)
}
}
RxBus.send(EventTidepoolUpdateGUI())
}
@Synchronized
fun updateLog() {
try {
val newTextLog = StringBuilder()
synchronized(listLog) {
for (log in listLog) {
newTextLog.append(log.toPreparedHtml())
}
}
@Suppress("DEPRECATION") // API level 24 to replace call
textLog = Html.fromHtml(newTextLog.toString())
} catch (e: OutOfMemoryError) {
ToastUtils.showToastInUiThread(MainApp.instance().applicationContext, "Out of memory!\nStop using this phone !!!", R.raw.error)
}
}
}

View file

@ -0,0 +1,32 @@
package info.nightscout.androidaps.plugins.general.tidepool.comm
import info.nightscout.androidaps.logging.L
import okhttp3.Interceptor
import okhttp3.Response
import okio.Buffer
import org.slf4j.LoggerFactory
import java.io.IOException
class InfoInterceptor(tag: String) : Interceptor {
private val log = LoggerFactory.getLogger(L.TIDEPOOL)
private var tag = "interceptor"
init {
this.tag = tag
}
@Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
request?.body()?.let {
if (L.isEnabled(L.TIDEPOOL)) {
log.debug("Interceptor Body size: " + it.contentLength())
val requestBuffer = Buffer()
it.writeTo(requestBuffer)
log.debug("Interceptor Body: " + requestBuffer.readUtf8())
}
}
return chain.proceed(request)
}
}

View file

@ -0,0 +1,42 @@
package info.nightscout.androidaps.plugins.general.tidepool.comm
import info.nightscout.androidaps.plugins.general.tidepool.messages.AuthReplyMessage
import info.nightscout.androidaps.plugins.general.tidepool.messages.DatasetReplyMessage
import okhttp3.Headers
class Session(val authHeader: String?,
private val sessionTokenHeader: String,
val service: TidepoolApiService?) {
internal var token: String? = null
internal var authReply: AuthReplyMessage? = null
internal var datasetReply: DatasetReplyMessage? = null
internal var start: Long = 0
internal var end: Long = 0
@Volatile
internal var iterations: Int = 0
fun populateHeaders(headers: Headers) {
if (this.token == null) {
this.token = headers.get(sessionTokenHeader)
}
}
fun populateBody(obj: Any?) {
if (obj == null) return
if (obj is AuthReplyMessage) {
authReply = obj
} else if (obj is List<*>) {
val list = obj as? List<*>?
list?.getOrNull(0)?.let {
if (it is DatasetReplyMessage) {
datasetReply = it
}
}
} else if (obj is DatasetReplyMessage) {
datasetReply = obj
}
}
}

View file

@ -0,0 +1,48 @@
package info.nightscout.androidaps.plugins.general.tidepool.comm
import info.nightscout.androidaps.BuildConfig
import info.nightscout.androidaps.plugins.general.tidepool.messages.AuthReplyMessage
import info.nightscout.androidaps.plugins.general.tidepool.messages.DatasetReplyMessage
import info.nightscout.androidaps.plugins.general.tidepool.messages.UploadReplyMessage
import okhttp3.RequestBody
import retrofit2.Call
import retrofit2.http.*
const val SESSION_TOKEN_HEADER: String = "x-tidepool-session-token"
interface TidepoolApiService {
@Headers(
"User-Agent: AAPS- " + BuildConfig.VERSION_NAME,
"X-Tidepool-Client-Name: info.nightscout.androidaps" + BuildConfig.APPLICATION_ID,
"X-Tidepool-Client-Version: 0.1.0"
)
@POST("/auth/login")
fun getLogin(@Header("Authorization") secret: String): Call<AuthReplyMessage>
@DELETE("/v1/users/{userId}/data")
fun deleteAllData(@Header(SESSION_TOKEN_HEADER) token: String, @Path("userId") id: String): Call<DatasetReplyMessage>
@DELETE("/v1/datasets/{dataSetId}")
fun deleteDataSet(@Header(SESSION_TOKEN_HEADER) token: String, @Path("dataSetId") id: String): Call<DatasetReplyMessage>
@GET("/v1/users/{userId}/data_sets")
fun getOpenDataSets(@Header(SESSION_TOKEN_HEADER) token: String,
@Path("userId") id: String,
@Query("client.name") clientName: String,
@Query("size") size: Int): Call<List<DatasetReplyMessage>>
@GET("/v1/datasets/{dataSetId}")
fun getDataSet(@Header(SESSION_TOKEN_HEADER) token: String, @Path("dataSetId") id: String): Call<DatasetReplyMessage>
@POST("/v1/users/{userId}/data_sets")
fun openDataSet(@Header(SESSION_TOKEN_HEADER) token: String, @Path("userId") id: String, @Body body: RequestBody): Call<DatasetReplyMessage>
@POST("/v1/datasets/{sessionId}/data")
fun doUpload(@Header(SESSION_TOKEN_HEADER) token: String, @Path("sessionId") id: String, @Body body: RequestBody): Call<UploadReplyMessage>
@PUT("/v1/datasets/{sessionId}")
fun closeDataSet(@Header(SESSION_TOKEN_HEADER) token: String, @Path("sessionId") id: String, @Body body: RequestBody): Call<DatasetReplyMessage>
}

View file

@ -0,0 +1,35 @@
package info.nightscout.androidaps.plugins.general.tidepool.comm
import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.logging.L
import info.nightscout.androidaps.plugins.general.tidepool.events.EventTidepoolStatus
import org.slf4j.LoggerFactory
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
internal class TidepoolCallback<T>(private val session: Session, val name: String, val onSuccess: () -> Unit, val onFail: () -> Unit) : Callback<T> {
private val log = LoggerFactory.getLogger(L.TIDEPOOL)
override fun onResponse(call: Call<T>, response: Response<T>) {
if (response.isSuccessful && response.body() != null) {
if (L.isEnabled(L.TIDEPOOL)) log.debug("$name success")
session.populateBody(response.body())
session.populateHeaders(response.headers())
onSuccess()
} else {
val msg = name + " was not successful: " + response.code() + " " + response.message()
if (L.isEnabled(L.TIDEPOOL)) log.debug(msg)
RxBus.send(EventTidepoolStatus(msg))
onFail()
}
}
override fun onFailure(call: Call<T>, t: Throwable) {
val msg = "$name Failed: $t"
if (L.isEnabled(L.TIDEPOOL)) log.debug(msg)
RxBus.send(EventTidepoolStatus(msg))
onFail()
}
}

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