Merge branch 'dev' into IA-in-BG-graph
This commit is contained in:
commit
72ff3e1e7f
278 changed files with 3771 additions and 1770 deletions
|
@ -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
|
||||||
|
|
101
app/build.gradle
101
app/build.gradle
|
@ -6,23 +6,30 @@ 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-extensions'
|
|
||||||
apply plugin: 'kotlin-android'
|
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"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -97,11 +104,11 @@ tasks.matching { it instanceof Test }.all {
|
||||||
}
|
}
|
||||||
|
|
||||||
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.4-dev"
|
version "2.4-dev"
|
||||||
|
@ -109,7 +116,7 @@ android {
|
||||||
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 {
|
||||||
|
@ -188,8 +195,15 @@ 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"
|
||||||
|
@ -204,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") {
|
||||||
|
@ -239,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'
|
||||||
|
|
||||||
|
@ -250,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"
|
||||||
|
@ -270,25 +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-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/")
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,7 @@ 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.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;
|
||||||
|
@ -72,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;
|
||||||
|
@ -145,7 +146,7 @@ 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);
|
||||||
|
|
||||||
|
@ -192,8 +193,7 @@ public class MainApp extends Application {
|
||||||
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());
|
||||||
|
@ -204,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());
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
package info.nightscout.androidaps.data;
|
package info.nightscout.androidaps.data;
|
||||||
|
|
||||||
import android.support.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.Constants;
|
import info.nightscout.androidaps.Constants;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.interfaces.Constraint;
|
import info.nightscout.androidaps.interfaces.Constraint;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -50,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);
|
||||||
|
@ -60,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) {
|
||||||
|
@ -86,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) {
|
||||||
|
@ -130,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() {
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -410,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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -434,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;
|
||||||
}
|
}
|
||||||
|
@ -596,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) {
|
||||||
|
@ -627,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;
|
||||||
|
@ -950,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() {
|
||||||
|
@ -1354,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++) {
|
||||||
|
@ -1507,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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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.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.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;
|
||||||
|
@ -699,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();
|
||||||
|
@ -723,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));
|
||||||
}
|
}
|
||||||
|
@ -735,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();
|
||||||
|
@ -819,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
|
||||||
|
@ -1100,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);
|
||||||
|
@ -1119,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);
|
||||||
|
@ -1226,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);
|
||||||
|
@ -1238,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);
|
||||||
|
@ -1316,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);
|
||||||
|
@ -1649,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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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.plugins.iob.iobCobCalculator.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) {
|
||||||
|
|
|
@ -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()
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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>
|
||||||
|
|
||||||
|
}
|
|
@ -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()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,314 @@
|
||||||
|
package info.nightscout.androidaps.plugins.general.tidepool.comm
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.os.PowerManager
|
||||||
|
import android.os.SystemClock
|
||||||
|
import info.nightscout.androidaps.BuildConfig
|
||||||
|
import info.nightscout.androidaps.MainApp
|
||||||
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.logging.L
|
||||||
|
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||||
|
import info.nightscout.androidaps.plugins.general.tidepool.events.EventTidepoolStatus
|
||||||
|
import info.nightscout.androidaps.plugins.general.tidepool.messages.*
|
||||||
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
|
import info.nightscout.androidaps.utils.OKDialog
|
||||||
|
import info.nightscout.androidaps.utils.SP
|
||||||
|
import info.nightscout.androidaps.utils.T
|
||||||
|
import okhttp3.MediaType
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
import okhttp3.RequestBody
|
||||||
|
import okhttp3.logging.HttpLoggingInterceptor
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
import retrofit2.Retrofit
|
||||||
|
import retrofit2.converter.gson.GsonConverterFactory
|
||||||
|
|
||||||
|
object TidepoolUploader {
|
||||||
|
|
||||||
|
private val log = LoggerFactory.getLogger(L.TIDEPOOL)
|
||||||
|
|
||||||
|
private var wl: PowerManager.WakeLock? = null
|
||||||
|
|
||||||
|
private const val INTEGRATION_BASE_URL = "https://int-api.tidepool.org"
|
||||||
|
private const val PRODUCTION_BASE_URL = "https://api.tidepool.org"
|
||||||
|
|
||||||
|
internal const val VERSION = "0.0.1"
|
||||||
|
|
||||||
|
private var retrofit: Retrofit? = null
|
||||||
|
|
||||||
|
private var session: Session? = null
|
||||||
|
|
||||||
|
enum class ConnectionStatus {
|
||||||
|
DISCONNECTED, CONNECTING, CONNECTED, FAILED
|
||||||
|
}
|
||||||
|
|
||||||
|
val PUMPTYPE = "Tandem"
|
||||||
|
|
||||||
|
var connectionStatus: ConnectionStatus = TidepoolUploader.ConnectionStatus.DISCONNECTED
|
||||||
|
|
||||||
|
fun getRetrofitInstance(): Retrofit? {
|
||||||
|
if (retrofit == null) {
|
||||||
|
|
||||||
|
val httpLoggingInterceptor = HttpLoggingInterceptor()
|
||||||
|
httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
|
||||||
|
|
||||||
|
val client = OkHttpClient.Builder()
|
||||||
|
.addInterceptor(httpLoggingInterceptor)
|
||||||
|
.addInterceptor(InfoInterceptor(TidepoolUploader::class.java.name))
|
||||||
|
.build()
|
||||||
|
|
||||||
|
retrofit = Retrofit.Builder()
|
||||||
|
.baseUrl(if (SP.getBoolean(R.string.key_tidepool_dev_servers, false)) INTEGRATION_BASE_URL else PRODUCTION_BASE_URL)
|
||||||
|
.client(client)
|
||||||
|
.addConverterFactory(GsonConverterFactory.create())
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
return retrofit
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createSession(): Session {
|
||||||
|
val service = getRetrofitInstance()?.create(TidepoolApiService::class.java)
|
||||||
|
return Session(AuthRequestMessage.getAuthRequestHeader(), SESSION_TOKEN_HEADER, service)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: call on preference change
|
||||||
|
fun resetInstance() {
|
||||||
|
retrofit = null
|
||||||
|
if (L.isEnabled(L.TIDEPOOL))
|
||||||
|
log.debug("Instance reset")
|
||||||
|
connectionStatus = TidepoolUploader.ConnectionStatus.DISCONNECTED
|
||||||
|
}
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
|
fun doLogin(doUpload: Boolean = false) {
|
||||||
|
if (connectionStatus == TidepoolUploader.ConnectionStatus.CONNECTED || connectionStatus == TidepoolUploader.ConnectionStatus.CONNECTING) {
|
||||||
|
if (L.isEnabled(L.TIDEPOOL))
|
||||||
|
log.debug("Already connected")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// TODO failure backoff
|
||||||
|
extendWakeLock(30000)
|
||||||
|
session = createSession()
|
||||||
|
val authHeader = session?.authHeader
|
||||||
|
if (authHeader != null) {
|
||||||
|
connectionStatus = TidepoolUploader.ConnectionStatus.CONNECTING
|
||||||
|
RxBus.send(EventTidepoolStatus(("Connecting")))
|
||||||
|
val call = session?.service?.getLogin(authHeader)
|
||||||
|
|
||||||
|
call?.enqueue(TidepoolCallback<AuthReplyMessage>(session!!, "Login", {
|
||||||
|
startSession(session!!, doUpload)
|
||||||
|
}, {
|
||||||
|
connectionStatus = TidepoolUploader.ConnectionStatus.FAILED
|
||||||
|
loginFailed()
|
||||||
|
}))
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
if (L.isEnabled(L.TIDEPOOL)) log.debug("Cannot do login as user credentials have not been set correctly")
|
||||||
|
connectionStatus = TidepoolUploader.ConnectionStatus.FAILED
|
||||||
|
RxBus.send(EventTidepoolStatus(("Invalid credentials")))
|
||||||
|
releaseWakeLock()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testLogin(rootContext: Context) {
|
||||||
|
val session = createSession()
|
||||||
|
session.authHeader?.let {
|
||||||
|
val call = session.service?.getLogin(it)
|
||||||
|
|
||||||
|
call?.enqueue(TidepoolCallback<AuthReplyMessage>(session, "Login", {
|
||||||
|
OKDialog.show(rootContext, MainApp.gs(R.string.tidepool), "Successfully logged into Tidepool.", null)
|
||||||
|
}, {
|
||||||
|
OKDialog.show(rootContext, MainApp.gs(R.string.tidepool), "Failed to log into Tidepool.\nCheck that your user name and password are correct.", null)
|
||||||
|
}))
|
||||||
|
|
||||||
|
}
|
||||||
|
?: OKDialog.show(rootContext, MainApp.gs(R.string.tidepool), "Cannot do login as user credentials have not been set correctly", null)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loginFailed() {
|
||||||
|
releaseWakeLock()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun startSession(session: Session, doUpload: Boolean = false) {
|
||||||
|
extendWakeLock(30000)
|
||||||
|
if (session.authReply?.userid != null) {
|
||||||
|
// See if we already have an open data set to write to
|
||||||
|
val datasetCall = session.service!!.getOpenDataSets(session.token!!,
|
||||||
|
session.authReply!!.userid!!, BuildConfig.APPLICATION_ID, 1)
|
||||||
|
|
||||||
|
datasetCall.enqueue(TidepoolCallback<List<DatasetReplyMessage>>(session, "Get Open Datasets", {
|
||||||
|
if (session.datasetReply == null) {
|
||||||
|
RxBus.send(EventTidepoolStatus(("Creating new dataset")))
|
||||||
|
val call = session.service.openDataSet(session.token!!, session.authReply!!.userid!!, OpenDatasetRequestMessage().getBody())
|
||||||
|
call.enqueue(TidepoolCallback<DatasetReplyMessage>(session, "Open New Dataset", {
|
||||||
|
connectionStatus = TidepoolUploader.ConnectionStatus.CONNECTED
|
||||||
|
RxBus.send(EventTidepoolStatus(("New dataset OK")))
|
||||||
|
if (doUpload) doUpload()
|
||||||
|
else
|
||||||
|
releaseWakeLock()
|
||||||
|
}, {
|
||||||
|
RxBus.send(EventTidepoolStatus(("New dataset FAILED")))
|
||||||
|
connectionStatus = TidepoolUploader.ConnectionStatus.FAILED
|
||||||
|
releaseWakeLock()
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
if (L.isEnabled(L.TIDEPOOL))
|
||||||
|
log.debug("Existing Dataset: " + session.datasetReply!!.getUploadId())
|
||||||
|
// TODO: Wouldn't need to do this if we could block on the above `call.enqueue`.
|
||||||
|
// ie, do the openDataSet conditionally, and then do `doUpload` either way.
|
||||||
|
connectionStatus = TidepoolUploader.ConnectionStatus.CONNECTED
|
||||||
|
RxBus.send(EventTidepoolStatus(("Appending to existing dataset")))
|
||||||
|
if (doUpload) doUpload()
|
||||||
|
else
|
||||||
|
releaseWakeLock()
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
connectionStatus = TidepoolUploader.ConnectionStatus.FAILED
|
||||||
|
RxBus.send(EventTidepoolStatus(("Open dataset FAILED")))
|
||||||
|
releaseWakeLock()
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
log.error("Got login response but cannot determine userId - cannot proceed")
|
||||||
|
connectionStatus = TidepoolUploader.ConnectionStatus.FAILED
|
||||||
|
RxBus.send(EventTidepoolStatus(("Error userId")))
|
||||||
|
releaseWakeLock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
|
fun doUpload() {
|
||||||
|
session.let { session ->
|
||||||
|
if (session == null) {
|
||||||
|
log.error("Session is null, cannot proceed")
|
||||||
|
releaseWakeLock()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
extendWakeLock(60000)
|
||||||
|
session.iterations++
|
||||||
|
val chunk = UploadChunk.getNext(session)
|
||||||
|
when {
|
||||||
|
chunk == null -> {
|
||||||
|
log.error("Upload chunk is null, cannot proceed")
|
||||||
|
releaseWakeLock()
|
||||||
|
}
|
||||||
|
|
||||||
|
chunk.length == 2 -> {
|
||||||
|
if (L.isEnabled(L.TIDEPOOL)) log.debug("Empty dataset - marking as succeeded")
|
||||||
|
RxBus.send(EventTidepoolStatus(("No data to upload")))
|
||||||
|
releaseWakeLock()
|
||||||
|
unploadNext()
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
val body = RequestBody.create(MediaType.parse("application/json"), chunk)
|
||||||
|
|
||||||
|
RxBus.send(EventTidepoolStatus(("Uploading")))
|
||||||
|
val call = session.service!!.doUpload(session.token!!, session.datasetReply!!.getUploadId()!!, body)
|
||||||
|
call.enqueue(TidepoolCallback<UploadReplyMessage>(session, "Data Upload", {
|
||||||
|
setLastEnd(session.end)
|
||||||
|
RxBus.send(EventTidepoolStatus(("Upload completed OK")))
|
||||||
|
releaseWakeLock()
|
||||||
|
unploadNext()
|
||||||
|
}, {
|
||||||
|
RxBus.send(EventTidepoolStatus(("Upload FAILED")))
|
||||||
|
releaseWakeLock()
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun unploadNext() {
|
||||||
|
if (getLastEnd() < DateUtil.now() - T.mins(1).msecs()) {
|
||||||
|
SystemClock.sleep(3000)
|
||||||
|
if (L.isEnabled(L.TIDEPOOL))
|
||||||
|
log.debug("Restarting doUpload. Last: " + DateUtil.dateAndTimeString(getLastEnd()))
|
||||||
|
doUpload()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun deleteDataSet() {
|
||||||
|
if (session?.datasetReply?.id != null) {
|
||||||
|
extendWakeLock(60000)
|
||||||
|
val call = session!!.service?.deleteDataSet(session!!.token!!, session!!.datasetReply!!.id!!)
|
||||||
|
call?.enqueue(TidepoolCallback(session!!, "Delete Dataset", {
|
||||||
|
connectionStatus = TidepoolUploader.ConnectionStatus.DISCONNECTED
|
||||||
|
RxBus.send(EventTidepoolStatus(("Dataset removed OK")))
|
||||||
|
releaseWakeLock()
|
||||||
|
}, {
|
||||||
|
connectionStatus = TidepoolUploader.ConnectionStatus.DISCONNECTED
|
||||||
|
RxBus.send(EventTidepoolStatus(("Dataset remove FAILED")))
|
||||||
|
releaseWakeLock()
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
log.error("Got login response but cannot determine datasetId - cannot proceed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun deleteAllData() {
|
||||||
|
val session = this.session
|
||||||
|
val token = session?.token
|
||||||
|
val userid = session?.authReply?.userid
|
||||||
|
try {
|
||||||
|
requireNotNull(session)
|
||||||
|
requireNotNull(token)
|
||||||
|
requireNotNull(userid)
|
||||||
|
extendWakeLock(60000)
|
||||||
|
val call = session.service?.deleteAllData(token, userid)
|
||||||
|
call?.enqueue(TidepoolCallback(session, "Delete all data", {
|
||||||
|
connectionStatus = TidepoolUploader.ConnectionStatus.DISCONNECTED
|
||||||
|
RxBus.send(EventTidepoolStatus(("All data removed OK")))
|
||||||
|
releaseWakeLock()
|
||||||
|
}, {
|
||||||
|
connectionStatus = TidepoolUploader.ConnectionStatus.DISCONNECTED
|
||||||
|
RxBus.send(EventTidepoolStatus(("All data remove FAILED")))
|
||||||
|
releaseWakeLock()
|
||||||
|
}))
|
||||||
|
} catch (e: IllegalArgumentException) {
|
||||||
|
log.error("Got login response but cannot determine userId - cannot proceed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getLastEnd(): Long {
|
||||||
|
val result = SP.getLong(R.string.key_tidepool_last_end, 0)
|
||||||
|
return Math.max(result, DateUtil.now() - T.months(2).msecs())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setLastEnd(time: Long) {
|
||||||
|
if (time > getLastEnd()) {
|
||||||
|
SP.putLong(R.string.key_tidepool_last_end, time)
|
||||||
|
val friendlyEnd = DateUtil.dateAndTimeString(time)
|
||||||
|
RxBus.send(EventTidepoolStatus(("Marking uploaded data up to $friendlyEnd")))
|
||||||
|
if (L.isEnabled(L.TIDEPOOL)) log.debug("Updating last end to: " + DateUtil.dateAndTimeString(time))
|
||||||
|
} else {
|
||||||
|
if (L.isEnabled(L.TIDEPOOL)) log.debug("Cannot set last end to: " + DateUtil.dateAndTimeString(time) + " vs " + DateUtil.dateAndTimeString(getLastEnd()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
|
private fun extendWakeLock(ms: Long) {
|
||||||
|
if (wl == null) {
|
||||||
|
val pm = MainApp.instance().getSystemService(Context.POWER_SERVICE) as PowerManager
|
||||||
|
wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "AndroidAPS:TidepoolUploader")
|
||||||
|
wl?.acquire(ms)
|
||||||
|
} else {
|
||||||
|
releaseWakeLock() // lets not get too messy
|
||||||
|
wl?.acquire(ms)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
|
private fun releaseWakeLock() {
|
||||||
|
wl?.let {
|
||||||
|
if (it.isHeld) {
|
||||||
|
try {
|
||||||
|
it.release()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
log.error("Error releasing wakelock: $e")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,130 @@
|
||||||
|
package info.nightscout.androidaps.plugins.general.tidepool.comm
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.MainApp
|
||||||
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.logging.L
|
||||||
|
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||||
|
import info.nightscout.androidaps.plugins.general.tidepool.elements.*
|
||||||
|
import info.nightscout.androidaps.plugins.general.tidepool.events.EventTidepoolStatus
|
||||||
|
import info.nightscout.androidaps.plugins.general.tidepool.utils.GsonInstance
|
||||||
|
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
||||||
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
|
import info.nightscout.androidaps.utils.SP
|
||||||
|
import info.nightscout.androidaps.utils.T
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
object UploadChunk {
|
||||||
|
|
||||||
|
private val MAX_UPLOAD_SIZE = T.days(7).msecs() // don't change this
|
||||||
|
|
||||||
|
private val log = LoggerFactory.getLogger(L.TIDEPOOL)
|
||||||
|
|
||||||
|
fun getNext(session: Session?): String? {
|
||||||
|
if (session == null)
|
||||||
|
return null
|
||||||
|
|
||||||
|
session.start = TidepoolUploader.getLastEnd()
|
||||||
|
session.end = Math.min(session.start + MAX_UPLOAD_SIZE, DateUtil.now())
|
||||||
|
|
||||||
|
val result = get(session.start, session.end)
|
||||||
|
if (result.length < 3) {
|
||||||
|
if (L.isEnabled(L.TIDEPOOL)) log.debug("No records in this time period, setting start to best end time")
|
||||||
|
TidepoolUploader.setLastEnd(Math.max(session.end, getOldestRecordTimeStamp()))
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun get(start: Long, end: Long): String {
|
||||||
|
|
||||||
|
if (L.isEnabled(L.TIDEPOOL)) log.debug("Syncing data between: " + DateUtil.dateAndTimeString(start) + " -> " + DateUtil.dateAndTimeString(end))
|
||||||
|
if (end <= start) {
|
||||||
|
if (L.isEnabled(L.TIDEPOOL)) log.debug("End is <= start: " + DateUtil.dateAndTimeString(start) + " " + DateUtil.dateAndTimeString(end))
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if (end - start > MAX_UPLOAD_SIZE) {
|
||||||
|
if (L.isEnabled(L.TIDEPOOL)) log.debug("More than max range - rejecting")
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
val records = LinkedList<BaseElement>()
|
||||||
|
|
||||||
|
if (SP.getBoolean(R.string.key_tidepool_upload_bolus, true))
|
||||||
|
records.addAll(getTreatments(start, end))
|
||||||
|
if (SP.getBoolean(R.string.key_tidepool_upload_bg, true))
|
||||||
|
records.addAll(getBloodTests(start, end))
|
||||||
|
if (SP.getBoolean(R.string.key_tidepool_upload_tbr, true))
|
||||||
|
records.addAll(getBasals(start, end))
|
||||||
|
if (SP.getBoolean(R.string.key_tidepool_upload_cgm, true))
|
||||||
|
records.addAll(getBgReadings(start, end))
|
||||||
|
if (SP.getBoolean(R.string.key_tidepool_upload_profile, true))
|
||||||
|
records.addAll(getProfiles(start, end))
|
||||||
|
|
||||||
|
return GsonInstance.defaultGsonInstance().toJson(records)
|
||||||
|
}
|
||||||
|
|
||||||
|
// numeric limits must match max time windows
|
||||||
|
|
||||||
|
private fun getOldestRecordTimeStamp(): Long {
|
||||||
|
// TODO we could make sure we include records older than the first bg record for completeness
|
||||||
|
|
||||||
|
val start: Long = 0
|
||||||
|
val end = DateUtil.now()
|
||||||
|
|
||||||
|
val bgReadingList = MainApp.getDbHelper().getBgreadingsDataFromTime(start, end, true)
|
||||||
|
return if (bgReadingList.size > 0)
|
||||||
|
bgReadingList[0].date
|
||||||
|
else -1
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getTreatments(start: Long, end: Long): List<BaseElement> {
|
||||||
|
val result = LinkedList<BaseElement>()
|
||||||
|
val treatments = TreatmentsPlugin.getPlugin().service.getTreatmentDataFromTime(start, end, true)
|
||||||
|
for (treatment in treatments) {
|
||||||
|
if (treatment.carbs > 0) {
|
||||||
|
result.add(WizardElement(treatment))
|
||||||
|
} else if (treatment.insulin > 0) {
|
||||||
|
result.add(BolusElement(treatment))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getBloodTests(start: Long, end: Long): List<BloodGlucoseElement> {
|
||||||
|
val readings = MainApp.getDbHelper().getCareportalEvents(start, end, true)
|
||||||
|
val selection = BloodGlucoseElement.fromCareportalEvents(readings)
|
||||||
|
if (selection.isNotEmpty())
|
||||||
|
RxBus.send(EventTidepoolStatus("${selection.size} BGs selected for upload"))
|
||||||
|
return selection
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun getBgReadings(start: Long, end: Long): List<SensorGlucoseElement> {
|
||||||
|
val readings = MainApp.getDbHelper().getBgreadingsDataFromTime(start, end, true)
|
||||||
|
val selection = SensorGlucoseElement.fromBgReadings(readings)
|
||||||
|
if (selection.isNotEmpty())
|
||||||
|
RxBus.send(EventTidepoolStatus("${selection.size} CGMs selected for upload"))
|
||||||
|
return selection
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getBasals(start: Long, end: Long): List<BasalElement> {
|
||||||
|
val tbrs = TreatmentsPlugin.getPlugin().temporaryBasalsFromHistory
|
||||||
|
tbrs.merge()
|
||||||
|
val selection = BasalElement.fromTemporaryBasals(tbrs, start, end) // TODO do not upload running TBR
|
||||||
|
if (selection.isNotEmpty())
|
||||||
|
RxBus.send(EventTidepoolStatus("${selection.size} TBRs selected for upload"))
|
||||||
|
return selection
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getProfiles(start: Long, end: Long): List<ProfileElement> {
|
||||||
|
val pss = MainApp.getDbHelper().getProfileSwitchEventsFromTime(start, end, true)
|
||||||
|
val selection = LinkedList<ProfileElement>()
|
||||||
|
for (ps in pss) {
|
||||||
|
ProfileElement.newInstanceOrNull(ps)?.let { selection.add(it) }
|
||||||
|
}
|
||||||
|
if (selection.size > 0)
|
||||||
|
RxBus.send(EventTidepoolStatus("${selection.size} ProfileSwitches selected for upload"))
|
||||||
|
return selection
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
package info.nightscout.androidaps.plugins.general.tidepool.elements
|
||||||
|
|
||||||
|
import com.google.gson.annotations.Expose
|
||||||
|
import info.nightscout.androidaps.data.Intervals
|
||||||
|
import info.nightscout.androidaps.db.TemporaryBasal
|
||||||
|
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class BasalElement(tbr: TemporaryBasal)
|
||||||
|
: BaseElement(tbr.date, UUID.nameUUIDFromBytes(("AAPS-basal" + tbr.date).toByteArray()).toString()) {
|
||||||
|
|
||||||
|
internal var timestamp: Long = 0 // not exposed
|
||||||
|
|
||||||
|
@Expose
|
||||||
|
internal var deliveryType = "automated"
|
||||||
|
@Expose
|
||||||
|
internal var duration: Long = 0
|
||||||
|
@Expose
|
||||||
|
internal var rate = -1.0
|
||||||
|
@Expose
|
||||||
|
internal var scheduleName = "AAPS"
|
||||||
|
@Expose
|
||||||
|
internal var clockDriftOffset: Long = 0
|
||||||
|
@Expose
|
||||||
|
internal var conversionOffset: Long = 0
|
||||||
|
|
||||||
|
init {
|
||||||
|
type = "basal"
|
||||||
|
timestamp = tbr.date
|
||||||
|
rate = tbr.tempBasalConvertedToAbsolute(tbr.date, ProfileFunctions.getInstance().getProfile(tbr.date))
|
||||||
|
duration = tbr.end() - tbr.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
internal fun fromTemporaryBasals(tbrList: Intervals<TemporaryBasal>, start: Long, end: Long): List<BasalElement> {
|
||||||
|
val results = LinkedList<BasalElement>()
|
||||||
|
for (tbr in tbrList.list) {
|
||||||
|
if (tbr.date >= start && tbr.date <= end && tbr.durationInMinutes != 0)
|
||||||
|
results.add(BasalElement(tbr))
|
||||||
|
}
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package info.nightscout.androidaps.plugins.general.tidepool.elements
|
||||||
|
|
||||||
|
import com.google.gson.annotations.Expose
|
||||||
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
|
|
||||||
|
open class BaseElement(timestamp: Long, uuid: String) {
|
||||||
|
@Expose
|
||||||
|
var deviceTime: String = ""
|
||||||
|
@Expose
|
||||||
|
var time: String = ""
|
||||||
|
@Expose
|
||||||
|
var timezoneOffset: Int = 0
|
||||||
|
@Expose
|
||||||
|
var type: String? = null
|
||||||
|
@Expose
|
||||||
|
var origin: Origin? = null
|
||||||
|
|
||||||
|
init {
|
||||||
|
deviceTime = DateUtil.toISONoZone(timestamp)
|
||||||
|
time = DateUtil.toISOAsUTC(timestamp)
|
||||||
|
timezoneOffset = DateUtil.getTimeZoneOffsetMinutes(timestamp) // TODO
|
||||||
|
origin = Origin(uuid)
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class Origin internal constructor(@field:Expose
|
||||||
|
internal var id: String)
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package info.nightscout.androidaps.plugins.general.tidepool.elements
|
||||||
|
|
||||||
|
import com.google.gson.annotations.Expose
|
||||||
|
import info.nightscout.androidaps.Constants
|
||||||
|
import info.nightscout.androidaps.data.Profile
|
||||||
|
import info.nightscout.androidaps.db.CareportalEvent
|
||||||
|
import info.nightscout.androidaps.utils.JsonHelper
|
||||||
|
import org.json.JSONObject
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class BloodGlucoseElement(careportalEvent: CareportalEvent)
|
||||||
|
: BaseElement(careportalEvent.date, UUID.nameUUIDFromBytes(("AAPS-bg" + careportalEvent.date).toByteArray()).toString()) {
|
||||||
|
|
||||||
|
@Expose
|
||||||
|
var subType: String = "manual"
|
||||||
|
@Expose
|
||||||
|
var units: String = "mg/dL"
|
||||||
|
@Expose
|
||||||
|
var value: Int = 0
|
||||||
|
|
||||||
|
init {
|
||||||
|
type = "cbg"
|
||||||
|
subType = "manual" // TODO
|
||||||
|
val json = if (careportalEvent.json != null) JSONObject(careportalEvent.json) else JSONObject()
|
||||||
|
value = Profile.toMgdl(JsonHelper.safeGetDouble(json, "glucose"), JsonHelper.safeGetString(json, "units", Constants.MGDL)).toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
fun fromCareportalEvents(careportalList: List<CareportalEvent>): List<BloodGlucoseElement> {
|
||||||
|
val results = LinkedList<BloodGlucoseElement>()
|
||||||
|
for (bt in careportalList) {
|
||||||
|
if (bt.eventType == CareportalEvent.MBG || bt.eventType == CareportalEvent.BGCHECK) {
|
||||||
|
val bge = BloodGlucoseElement(bt)
|
||||||
|
if (bge.value > 0)
|
||||||
|
results.add(BloodGlucoseElement(bt))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
package info.nightscout.androidaps.plugins.general.tidepool.elements
|
||||||
|
|
||||||
|
import com.google.gson.annotations.Expose
|
||||||
|
import info.nightscout.androidaps.plugins.treatments.Treatment
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class BolusElement(treatment: Treatment)
|
||||||
|
: BaseElement(treatment.date, UUID.nameUUIDFromBytes(("AAPS-bolus" + treatment.date).toByteArray()).toString()) {
|
||||||
|
|
||||||
|
@Expose
|
||||||
|
var subType = "normal"
|
||||||
|
@Expose
|
||||||
|
var normal: Double = 0.0
|
||||||
|
@Expose
|
||||||
|
var expectedNormal: Double = 0.0
|
||||||
|
|
||||||
|
init {
|
||||||
|
type = "bolus"
|
||||||
|
normal = treatment.insulin
|
||||||
|
expectedNormal = treatment.insulin
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,111 @@
|
||||||
|
package info.nightscout.androidaps.plugins.general.tidepool.elements
|
||||||
|
|
||||||
|
import com.google.gson.annotations.Expose
|
||||||
|
import info.nightscout.androidaps.data.Profile
|
||||||
|
import info.nightscout.androidaps.db.ProfileSwitch
|
||||||
|
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
|
||||||
|
import info.nightscout.androidaps.plugins.general.tidepool.comm.TidepoolUploader
|
||||||
|
import info.nightscout.androidaps.utils.InstanceId
|
||||||
|
import java.util.*
|
||||||
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
|
class ProfileElement private constructor(ps: ProfileSwitch)
|
||||||
|
: BaseElement(ps.date, UUID.nameUUIDFromBytes(("AAPS-profile" + ps.date).toByteArray()).toString()) {
|
||||||
|
|
||||||
|
@Expose
|
||||||
|
internal var activeSchedule = "Normal"
|
||||||
|
@Expose
|
||||||
|
internal var basalSchedules: BasalProfile = BasalProfile()
|
||||||
|
@Expose
|
||||||
|
internal var units: Units = Units()
|
||||||
|
@Expose
|
||||||
|
internal var bgTargets: TargetProfile = TargetProfile()
|
||||||
|
@Expose
|
||||||
|
internal var carbRatios: IcProfile = IcProfile()
|
||||||
|
@Expose
|
||||||
|
internal var insulinSensitivities: IsfProfile = IsfProfile()
|
||||||
|
@Expose
|
||||||
|
internal var deviceId: String = TidepoolUploader.PUMPTYPE + ":" + (ConfigBuilderPlugin.getPlugin().activePump?.serialNumber()
|
||||||
|
?: InstanceId.instanceId())
|
||||||
|
@Expose
|
||||||
|
internal var deviceSerialNumber: String = ConfigBuilderPlugin.getPlugin().activePump?.serialNumber()
|
||||||
|
?: InstanceId.instanceId()
|
||||||
|
@Expose
|
||||||
|
internal var clockDriftOffset: Long = 0
|
||||||
|
@Expose
|
||||||
|
internal var conversionOffset: Long = 0
|
||||||
|
|
||||||
|
init {
|
||||||
|
type = "pumpSettings"
|
||||||
|
val profile: Profile? = ps.profileObject
|
||||||
|
checkNotNull(profile)
|
||||||
|
for (br in profile.basalValues)
|
||||||
|
basalSchedules.Normal.add(BasalRate(br.timeAsSeconds * 1000, br.value))
|
||||||
|
for (target in profile.singleTargets)
|
||||||
|
bgTargets.Normal.add(Target(target.timeAsSeconds * 1000, Profile.toMgdl(target.value, profile.units)))
|
||||||
|
for (ic in profile.ics)
|
||||||
|
carbRatios.Normal.add(Ratio(ic.timeAsSeconds * 1000, ic.value))
|
||||||
|
for (isf in profile.isfs)
|
||||||
|
insulinSensitivities.Normal.add(Ratio(isf.timeAsSeconds * 1000, Profile.toMgdl(isf.value, profile.units)))
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class BasalProfile internal constructor(
|
||||||
|
@field:Expose
|
||||||
|
internal var Normal: ArrayList<BasalRate> = ArrayList() // must be the same var name as activeSchedule
|
||||||
|
)
|
||||||
|
|
||||||
|
inner class BasalRate internal constructor(
|
||||||
|
@field:Expose
|
||||||
|
internal var start: Int,
|
||||||
|
@field:Expose
|
||||||
|
internal var rate: Double
|
||||||
|
)
|
||||||
|
|
||||||
|
inner class Units internal constructor(
|
||||||
|
@field:Expose
|
||||||
|
internal var carb: String = "grams",
|
||||||
|
@field:Expose
|
||||||
|
internal var bg: String = "mg/dL"
|
||||||
|
)
|
||||||
|
|
||||||
|
inner class TargetProfile internal constructor(
|
||||||
|
@field:Expose
|
||||||
|
internal var Normal: ArrayList<Target> = ArrayList() // must be the same var name as activeSchedule
|
||||||
|
)
|
||||||
|
|
||||||
|
inner class Target internal constructor(
|
||||||
|
@field:Expose
|
||||||
|
internal var start: Int,
|
||||||
|
@field:Expose
|
||||||
|
internal var target: Double
|
||||||
|
)
|
||||||
|
|
||||||
|
inner class IcProfile internal constructor(
|
||||||
|
@field:Expose
|
||||||
|
internal var Normal: ArrayList<Ratio> = ArrayList() // must be the same var name as activeSchedule
|
||||||
|
)
|
||||||
|
|
||||||
|
inner class IsfProfile internal constructor(
|
||||||
|
@field:Expose
|
||||||
|
internal var Normal: ArrayList<Ratio> = ArrayList() // must be the same var name as activeSchedule
|
||||||
|
)
|
||||||
|
|
||||||
|
inner class Ratio internal constructor(
|
||||||
|
@field:Expose
|
||||||
|
internal var start: Int,
|
||||||
|
@field:Expose
|
||||||
|
internal var amount: Double
|
||||||
|
)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
fun newInstanceOrNull(ps: ProfileSwitch): ProfileElement? = try {
|
||||||
|
ProfileElement(ps)
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
package info.nightscout.androidaps.plugins.general.tidepool.elements
|
||||||
|
|
||||||
|
import com.google.gson.annotations.Expose
|
||||||
|
import info.nightscout.androidaps.db.BgReading
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class SensorGlucoseElement(bgReading: BgReading)
|
||||||
|
: BaseElement(bgReading.date, UUID.nameUUIDFromBytes(("AAPS-cgm" + bgReading.date).toByteArray()).toString()) {
|
||||||
|
|
||||||
|
@Expose
|
||||||
|
internal var units: String = "mg/dL"
|
||||||
|
@Expose
|
||||||
|
internal var value: Int = 0
|
||||||
|
|
||||||
|
init {
|
||||||
|
this.type = "cbg"
|
||||||
|
value = bgReading.value.toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
internal fun fromBgReadings(bgReadingList: List<BgReading>): List<SensorGlucoseElement> {
|
||||||
|
val results = LinkedList<SensorGlucoseElement>()
|
||||||
|
for (bgReading in bgReadingList) {
|
||||||
|
results.add(SensorGlucoseElement(bgReading))
|
||||||
|
}
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
package info.nightscout.androidaps.plugins.general.tidepool.elements
|
||||||
|
|
||||||
|
import com.google.gson.annotations.Expose
|
||||||
|
import info.nightscout.androidaps.plugins.treatments.Treatment
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class WizardElement(treatment: Treatment)
|
||||||
|
: BaseElement(treatment.date, UUID.nameUUIDFromBytes(("AAPS-wizard" + treatment.date).toByteArray()).toString()) {
|
||||||
|
|
||||||
|
@Expose
|
||||||
|
var units = "mg/dL"
|
||||||
|
@Expose
|
||||||
|
var carbInput: Double = 0.toDouble()
|
||||||
|
@Expose
|
||||||
|
var insulinCarbRatio: Double = 0.toDouble()
|
||||||
|
@Expose
|
||||||
|
var bolus: BolusElement? = null
|
||||||
|
|
||||||
|
init {
|
||||||
|
type = "wizard"
|
||||||
|
carbInput = treatment.carbs
|
||||||
|
insulinCarbRatio = treatment.ic
|
||||||
|
if (treatment.insulin > 0) {
|
||||||
|
bolus = BolusElement(treatment)
|
||||||
|
} else {
|
||||||
|
val fake = Treatment()
|
||||||
|
fake.insulin = 0.0001
|
||||||
|
fake.date = treatment.date
|
||||||
|
bolus = BolusElement(fake) // fake insulin record
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO fill the rest
|
||||||
|
{
|
||||||
|
"type": "wizard",
|
||||||
|
"bgInput": 16.152676653942503,
|
||||||
|
"bgTarget": {
|
||||||
|
"low": 3.6079861941795968,
|
||||||
|
"high": 6.938434988806917
|
||||||
|
},
|
||||||
|
"bolus": "22239d4d592b48ae920b28971cceb48b",
|
||||||
|
"carbInput": 57,
|
||||||
|
"insulinCarbRatio": 24,
|
||||||
|
"insulinOnBoard": 24.265,
|
||||||
|
"insulinSensitivity": 4.329583433015516,
|
||||||
|
"recommended": {
|
||||||
|
"carb": 2.5,
|
||||||
|
"correction": 2.25,
|
||||||
|
"net": 0
|
||||||
|
},
|
||||||
|
"units": "mmol/L",
|
||||||
|
"_active": true,
|
||||||
|
"_groupId": "abcdef",
|
||||||
|
"_schemaVersion": 0,
|
||||||
|
"_version": 0,
|
||||||
|
"clockDriftOffset": 0,
|
||||||
|
"conversionOffset": 0,
|
||||||
|
"createdTime": "2018-05-14T08:17:14.353Z",
|
||||||
|
"deviceId": "DevId0987654321",
|
||||||
|
"deviceTime": "2018-05-14T18:17:09",
|
||||||
|
"guid": "18d90ea0-5915-4e95-a8b2-cb22819ce696",
|
||||||
|
"id": "087c94ccdae84eb5a76b8205a244ec6b",
|
||||||
|
"time": "2018-05-14T08:17:09.353Z",
|
||||||
|
"timezoneOffset": 600,
|
||||||
|
"uploadId": "SampleUploadId"
|
||||||
|
}
|
||||||
|
*/
|
|
@ -0,0 +1,5 @@
|
||||||
|
package info.nightscout.androidaps.plugins.general.tidepool.events
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.events.Event
|
||||||
|
|
||||||
|
class EventTidepoolDoUpload : Event()
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue