Merge pull request #1534 from MilosKozak/aaps20_release
AndroidAPS 2.0 release
This commit is contained in:
commit
4f0f947edd
1071 changed files with 147037 additions and 25721 deletions
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -7,3 +7,9 @@
|
||||||
*.apk
|
*.apk
|
||||||
build/
|
build/
|
||||||
.idea/
|
.idea/
|
||||||
|
app/src/main/jniLibs
|
||||||
|
full/
|
||||||
|
debug/
|
||||||
|
release/
|
||||||
|
app/com.crashlytics.settings.json
|
||||||
|
app/session_analytics.tap
|
16
.travis.yml
16
.travis.yml
|
@ -2,7 +2,7 @@ language: android
|
||||||
jdk: oraclejdk8
|
jdk: oraclejdk8
|
||||||
env:
|
env:
|
||||||
matrix:
|
matrix:
|
||||||
- ANDROID_TARGET=android-23 ANDROID_ABI=x86
|
- ANDROID_TARGET=android-23 ANDROID_ABI=x86 org.gradle.jvmargs=-XX:-OmitStackTraceInFastThrow
|
||||||
android:
|
android:
|
||||||
components:
|
components:
|
||||||
- platform-tools
|
- platform-tools
|
||||||
|
@ -18,7 +18,17 @@ before_install:
|
||||||
|
|
||||||
script:
|
script:
|
||||||
# Unit Test
|
# Unit Test
|
||||||
- ./gradlew test jacocoTestReport
|
- ./gradlew -Pcoverage testFullDebugUnitTest jacocoTestFullDebugUnitTestReport
|
||||||
|
|
||||||
after_success:
|
after_success:
|
||||||
- bash <(curl -s https://codecov.io/bash)
|
- bash <(curl -s https://codecov.io/bash)
|
||||||
|
|
||||||
|
before_cache:
|
||||||
|
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
|
||||||
|
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/
|
||||||
|
|
||||||
|
cache:
|
||||||
|
directories:
|
||||||
|
- $HOME/.gradle/caches/
|
||||||
|
- $HOME/.gradle/wrapper/
|
||||||
|
- $HOME/.android/build-cache
|
|
@ -5,7 +5,10 @@
|
||||||
|
|
||||||
[![Gitter](https://badges.gitter.im/MilosKozak/AndroidAPS.svg)](https://gitter.im/MilosKozak/AndroidAPS?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
[![Gitter](https://badges.gitter.im/MilosKozak/AndroidAPS.svg)](https://gitter.im/MilosKozak/AndroidAPS?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
[![Build status](https://travis-ci.org/MilosKozak/AndroidAPS.svg?branch=master)](https://travis-ci.org/MilosKozak/AndroidAPS)
|
[![Build status](https://travis-ci.org/MilosKozak/AndroidAPS.svg?branch=master)](https://travis-ci.org/MilosKozak/AndroidAPS)
|
||||||
|
[![Crowdin](https://d322cqt584bo4o.cloudfront.net/androidaps/localized.svg)](https://translations.androidaps.org/project/androidaps)
|
||||||
|
[![Documentation Status](https://readthedocs.org/projects/androidaps/badge/?version=latest)](https://androidaps.readthedocs.io/en/latest/?badge=latest)
|
||||||
[![codecov](https://codecov.io/gh/MilosKozak/AndroidAPS/branch/master/graph/badge.svg)](https://codecov.io/gh/MilosKozak/AndroidAPS)
|
[![codecov](https://codecov.io/gh/MilosKozak/AndroidAPS/branch/master/graph/badge.svg)](https://codecov.io/gh/MilosKozak/AndroidAPS)
|
||||||
dev: [![codecov](https://codecov.io/gh/MilosKozak/AndroidAPS/branch/dev/graph/badge.svg)](https://codecov.io/gh/MilosKozak/AndroidAPS)
|
dev: [![codecov](https://codecov.io/gh/MilosKozak/AndroidAPS/branch/dev/graph/badge.svg)](https://codecov.io/gh/MilosKozak/AndroidAPS)
|
||||||
|
|
||||||
|
|
||||||
[![Donate via PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=Y4LHGJJESAVB8)
|
[![Donate via PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=Y4LHGJJESAVB8)
|
||||||
|
|
1
app/.gitignore
vendored
1
app/.gitignore
vendored
|
@ -1 +0,0 @@
|
||||||
/build
|
|
220
app/build.gradle
220
app/build.gradle
|
@ -15,21 +15,21 @@ apply plugin: "jacoco-android"
|
||||||
apply plugin: 'com.jakewharton.butterknife'
|
apply plugin: 'com.jakewharton.butterknife'
|
||||||
|
|
||||||
ext {
|
ext {
|
||||||
supportLibraryVersion = "27.0.2"
|
supportLibraryVersion = "27.1.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"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
maven { url 'https://maven.fabric.io/public' }
|
maven { url 'https://maven.fabric.io/public' }
|
||||||
|
jcenter { url "https://jcenter.bintray.com/" }
|
||||||
}
|
}
|
||||||
|
|
||||||
def generateGitBuild = { ->
|
def generateGitBuild = { ->
|
||||||
|
|
||||||
StringBuilder stringBuilder = new StringBuilder();
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
stringBuilder.append('"')
|
|
||||||
try {
|
try {
|
||||||
def stdout = new ByteArrayOutputStream()
|
def stdout = new ByteArrayOutputStream()
|
||||||
exec {
|
exec {
|
||||||
|
@ -41,25 +41,33 @@ def generateGitBuild = { ->
|
||||||
} catch (ignored) {
|
} catch (ignored) {
|
||||||
stringBuilder.append('NoGitSystemAvailable')
|
stringBuilder.append('NoGitSystemAvailable')
|
||||||
}
|
}
|
||||||
stringBuilder.append('-')
|
|
||||||
stringBuilder.append((new Date()).format('yyyy.MM.dd'))
|
|
||||||
stringBuilder.append('"')
|
|
||||||
return stringBuilder.toString()
|
return stringBuilder.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def generateDate = { ->
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
stringBuilder.append((new Date()).format('yyyy.MM.dd-HH:mm'))
|
||||||
|
return stringBuilder.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.matching { it instanceof Test }.all {
|
||||||
|
testLogging.events = ["failed", "skipped", "started"]
|
||||||
|
testLogging.exceptionFormat = "full"
|
||||||
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 27
|
compileSdkVersion 27
|
||||||
buildToolsVersion "${supportLibraryVersion}"
|
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "info.nightscout.androidaps"
|
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 23
|
targetSdkVersion 25
|
||||||
multiDexEnabled true
|
multiDexEnabled true
|
||||||
versionCode 1500
|
versionCode 1500
|
||||||
version "1.58"
|
version "2.0"
|
||||||
buildConfigField "String", "VERSION", '"' + version + '"'
|
buildConfigField "String", "VERSION", '"' + version + '"'
|
||||||
buildConfigField "String", "BUILDVERSION", generateGitBuild()
|
buildConfigField "String", "BUILDVERSION", '"' + generateGitBuild() + '-' + generateDate() + '"'
|
||||||
|
buildConfigField "String", "HEAD", '"' + generateGitBuild() + '"'
|
||||||
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
|
|
||||||
ndk {
|
ndk {
|
||||||
moduleName "BleCommandUtil"
|
moduleName "BleCommandUtil"
|
||||||
|
@ -69,7 +77,7 @@ android {
|
||||||
// TODO remove once wear dependency com.google.android.gms:play-services-wearable:7.3.0
|
// TODO remove once wear dependency com.google.android.gms:play-services-wearable:7.3.0
|
||||||
// has been upgraded (requiring significant code changes), which currently fails release
|
// has been upgraded (requiring significant code changes), which currently fails release
|
||||||
// build with a deprecation warning
|
// build with a deprecation warning
|
||||||
//abortOnError false
|
abortOnError false
|
||||||
// (disabled entirely to avoid reports on the error, which would still be displayed
|
// (disabled entirely to avoid reports on the error, which would still be displayed
|
||||||
// and it's easy to overlook that it's ignored)
|
// and it's easy to overlook that it's ignored)
|
||||||
checkReleaseBuilds false
|
checkReleaseBuilds false
|
||||||
|
@ -82,82 +90,63 @@ android {
|
||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
}
|
}
|
||||||
debug {
|
debug {
|
||||||
testCoverageEnabled true
|
testCoverageEnabled(project.hasProperty('coverage') ? true : false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
productFlavors {
|
productFlavors {
|
||||||
flavorDimensions "standard"
|
flavorDimensions "standard"
|
||||||
full {
|
full {
|
||||||
|
applicationId "info.nightscout.androidaps"
|
||||||
dimension "standard"
|
dimension "standard"
|
||||||
resValue "string", "app_name", "AndroidAPS"
|
resValue "string", "app_name", "AndroidAPS"
|
||||||
versionName version
|
versionName version
|
||||||
manifestPlaceholders = [
|
manifestPlaceholders = [
|
||||||
appIcon: "@mipmap/blueowl"
|
appIcon: "@mipmap/ic_launcher",
|
||||||
|
appIconRound: "@mipmap/ic_launcher_round"
|
||||||
]
|
]
|
||||||
buildConfigField "boolean", "APS", "true"
|
|
||||||
buildConfigField "boolean", "PUMPDRIVERS", "true"
|
|
||||||
buildConfigField "boolean", "NSCLIENTOLNY", "false"
|
|
||||||
buildConfigField "boolean", "CLOSEDLOOP", "true"
|
|
||||||
buildConfigField "boolean", "G5UPLOADER", "false"
|
|
||||||
buildConfigField "boolean", "PUMPCONTROL", "false"
|
|
||||||
}
|
|
||||||
openloop {
|
|
||||||
dimension "standard"
|
|
||||||
resValue "string", "app_name", "AndroidAPS"
|
|
||||||
versionName version
|
|
||||||
manifestPlaceholders = [
|
|
||||||
appIcon: "@mipmap/blueowl"
|
|
||||||
]
|
|
||||||
buildConfigField "boolean", "APS", "true"
|
|
||||||
buildConfigField "boolean", "PUMPDRIVERS", "true"
|
|
||||||
buildConfigField "boolean", "NSCLIENTOLNY", "false"
|
|
||||||
buildConfigField "boolean", "CLOSEDLOOP", "false"
|
|
||||||
buildConfigField "boolean", "G5UPLOADER", "false"
|
|
||||||
buildConfigField "boolean", "PUMPCONTROL", "false"
|
|
||||||
}
|
}
|
||||||
pumpcontrol {
|
pumpcontrol {
|
||||||
|
applicationId "info.nightscout.androidaps"
|
||||||
dimension "standard"
|
dimension "standard"
|
||||||
resValue "string", "app_name", "AndroidAPS"
|
resValue "string", "app_name", "AndroidAPS"
|
||||||
versionName version
|
versionName version
|
||||||
manifestPlaceholders = [
|
manifestPlaceholders = [
|
||||||
appIcon: "@mipmap/blueowl"
|
appIcon: "@mipmap/blueowl",
|
||||||
|
appIconRound: "@null"
|
||||||
]
|
]
|
||||||
buildConfigField "boolean", "APS", "false"
|
|
||||||
buildConfigField "boolean", "PUMPDRIVERS", "true"
|
|
||||||
buildConfigField "boolean", "NSCLIENTOLNY", "false"
|
|
||||||
buildConfigField "boolean", "CLOSEDLOOP", "false"
|
|
||||||
buildConfigField "boolean", "G5UPLOADER", "false"
|
|
||||||
buildConfigField "boolean", "PUMPCONTROL", "true"
|
|
||||||
}
|
}
|
||||||
nsclient {
|
nsclient {
|
||||||
|
applicationId "info.nightscout.nsclient"
|
||||||
dimension "standard"
|
dimension "standard"
|
||||||
resValue "string", "app_name", "NSClient"
|
resValue "string", "app_name", "NSClient"
|
||||||
versionName version + "-nsclient"
|
versionName version + "-nsclient"
|
||||||
manifestPlaceholders = [
|
manifestPlaceholders = [
|
||||||
appIcon: "@mipmap/yellowowl"
|
appIcon: "@mipmap/yellowowl",
|
||||||
|
appIconRound: "@null"
|
||||||
]
|
]
|
||||||
buildConfigField "boolean", "APS", "false"
|
|
||||||
buildConfigField "boolean", "PUMPDRIVERS", "false"
|
|
||||||
buildConfigField "boolean", "NSCLIENTOLNY", "true"
|
|
||||||
buildConfigField "boolean", "CLOSEDLOOP", "false"
|
|
||||||
buildConfigField "boolean", "G5UPLOADER", "false"
|
|
||||||
buildConfigField "boolean", "PUMPCONTROL", "false"
|
|
||||||
}
|
}
|
||||||
g5uploader {
|
nsclient2 {
|
||||||
|
applicationId "info.nightscout.nsclient2"
|
||||||
dimension "standard"
|
dimension "standard"
|
||||||
resValue "string", "app_name", "NSClient"
|
resValue "string", "app_name", "NSClient2"
|
||||||
versionName version + "-nsclient"
|
versionName version + "-nsclient"
|
||||||
manifestPlaceholders = [
|
manifestPlaceholders = [
|
||||||
appIcon: "@mipmap/yellowowl"
|
appIcon: "@mipmap/yellowowl",
|
||||||
|
appIconRound: "@null"
|
||||||
]
|
]
|
||||||
buildConfigField "boolean", "APS", "false"
|
|
||||||
buildConfigField "boolean", "PUMPDRIVERS", "false"
|
|
||||||
buildConfigField "boolean", "NSCLIENTOLNY", "false"
|
|
||||||
buildConfigField "boolean", "CLOSEDLOOP", "false"
|
|
||||||
buildConfigField "boolean", "G5UPLOADER", "true"
|
|
||||||
buildConfigField "boolean", "PUMPCONTROL", "false"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
|
}
|
||||||
|
|
||||||
|
testOptions {
|
||||||
|
unitTests.returnDefaultValues = true
|
||||||
|
unitTests.includeAndroidResources = true
|
||||||
|
}
|
||||||
|
|
||||||
|
useLibrary "org.apache.http.legacy"
|
||||||
}
|
}
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
|
@ -169,62 +158,101 @@ allprojects {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
configurations {
|
||||||
|
libs
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
wearApp project(':wear')
|
wearApp project(':wear')
|
||||||
|
|
||||||
compile fileTree(include: ['*.jar'], dir: 'libs')
|
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||||
compile("com.crashlytics.sdk.android:crashlytics:2.6.7@aar") {
|
implementation("com.crashlytics.sdk.android:crashlytics:2.6.7@aar") {
|
||||||
transitive = true;
|
transitive = true;
|
||||||
}
|
}
|
||||||
compile("com.crashlytics.sdk.android:answers:1.3.12@aar") {
|
implementation("com.crashlytics.sdk.android:answers:1.3.12@aar") {
|
||||||
transitive = true;
|
transitive = true;
|
||||||
}
|
}
|
||||||
|
libs "MilosKozak:danars-support-lib:master@zip"
|
||||||
|
|
||||||
compile "com.android.support:appcompat-v7:${supportLibraryVersion}"
|
implementation "com.android.support:appcompat-v7:${supportLibraryVersion}"
|
||||||
compile "com.android.support:support-v4:${supportLibraryVersion}"
|
implementation "com.android.support:support-v13:${supportLibraryVersion}"
|
||||||
compile "com.android.support:cardview-v7:${supportLibraryVersion}"
|
implementation "com.android.support:support-v4:${supportLibraryVersion}"
|
||||||
compile "com.android.support:recyclerview-v7:${supportLibraryVersion}"
|
implementation "com.android.support:cardview-v7:${supportLibraryVersion}"
|
||||||
compile "com.android.support:gridlayout-v7:${supportLibraryVersion}"
|
implementation "com.android.support:recyclerview-v7:${supportLibraryVersion}"
|
||||||
compile "com.android.support:design:${supportLibraryVersion}"
|
implementation "com.android.support:gridlayout-v7:${supportLibraryVersion}"
|
||||||
compile "com.android.support:percent:${supportLibraryVersion}"
|
implementation "com.android.support:design:${supportLibraryVersion}"
|
||||||
compile "com.wdullaer:materialdatetimepicker:2.3.0"
|
implementation "com.android.support:percent:${supportLibraryVersion}"
|
||||||
compile "com.squareup:otto:1.3.7"
|
implementation "com.wdullaer:materialdatetimepicker:2.3.0"
|
||||||
compile "com.j256.ormlite:ormlite-core:${ormLiteVersion}"
|
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
|
||||||
compile "com.j256.ormlite:ormlite-android:${ormLiteVersion}"
|
implementation "com.squareup:otto:1.3.7"
|
||||||
compile("com.github.tony19:logback-android-classic:1.1.1-6") {
|
implementation "com.j256.ormlite:ormlite-core:${ormLiteVersion}"
|
||||||
|
implementation "com.j256.ormlite:ormlite-android:${ormLiteVersion}"
|
||||||
|
implementation("com.github.tony19:logback-android-classic:1.1.1-6") {
|
||||||
exclude group: "com.google.android", module: "android"
|
exclude group: "com.google.android", module: "android"
|
||||||
}
|
}
|
||||||
compile "org.apache.commons:commons-lang3:3.6"
|
implementation "org.apache.commons:commons-lang3:3.6"
|
||||||
compile "org.slf4j:slf4j-api:1.7.12"
|
implementation "org.slf4j:slf4j-api:1.7.12"
|
||||||
compile "com.jjoe64:graphview:4.0.1"
|
implementation "com.jjoe64:graphview:4.0.1"
|
||||||
compile "com.joanzapata.iconify:android-iconify-fontawesome:2.1.1"
|
implementation "com.joanzapata.iconify:android-iconify-fontawesome:2.1.1"
|
||||||
compile "com.google.android.gms:play-services-wearable:7.5.0"
|
implementation "com.google.android.gms:play-services-wearable:7.5.0"
|
||||||
compile(name: "android-edittext-validator-v1.3.4-mod", ext: "aar")
|
implementation(name: "android-edittext-validator-v1.3.4-mod", ext: "aar")
|
||||||
compile("com.google.android:flexbox:0.3.0") {
|
implementation(name: "sightparser-release", ext: "aar")
|
||||||
|
|
||||||
|
implementation("com.google.android:flexbox:0.3.0") {
|
||||||
exclude group: "com.android.support"
|
exclude group: "com.android.support"
|
||||||
}
|
}
|
||||||
compile("io.socket:socket.io-client:0.8.3") {
|
implementation("io.socket:socket.io-client:1.0.0") {
|
||||||
// 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"
|
||||||
}
|
}
|
||||||
compile "com.google.code.gson:gson:2.7"
|
implementation "com.google.code.gson:gson:2.7"
|
||||||
compile "com.google.guava:guava:20.0"
|
implementation "com.google.guava:guava:20.0"
|
||||||
|
|
||||||
compile "net.danlew:android.joda:2.9.9.1"
|
implementation "net.danlew:android.joda:2.9.9.1"
|
||||||
|
implementation "uk.com.robust-it:cloning:1.9.9"
|
||||||
|
|
||||||
api "com.jakewharton:butterknife:8.8.1"
|
implementation 'org.mozilla:rhino:1.7.7.2'
|
||||||
annotationProcessor "com.jakewharton:butterknife-compiler:8.8.1"
|
|
||||||
|
|
||||||
testCompile "junit:junit:4.12"
|
implementation "com.jakewharton:butterknife:${butterknifeVersion}"
|
||||||
testCompile "org.json:json:20140107"
|
annotationProcessor "com.jakewharton:butterknife-compiler:${butterknifeVersion}"
|
||||||
testCompile "org.mockito:mockito-core:2.7.22"
|
|
||||||
testCompile "org.powermock:powermock-api-mockito2:${powermockVersion}"
|
|
||||||
testCompile "org.powermock:powermock-module-junit4-rule-agent:${powermockVersion}"
|
|
||||||
testCompile "org.powermock:powermock-module-junit4-rule:${powermockVersion}"
|
|
||||||
testCompile "org.powermock:powermock-module-junit4:${powermockVersion}"
|
|
||||||
testCompile "joda-time:joda-time:2.9.4.2"
|
|
||||||
|
|
||||||
androidTestCompile "org.mockito:mockito-core:2.7.22"
|
testImplementation "junit:junit:4.12"
|
||||||
androidTestCompile "com.google.dexmaker:dexmaker:${dexmakerVersion}"
|
testImplementation "org.json:json:20140107"
|
||||||
androidTestCompile "com.google.dexmaker:dexmaker-mockito:${dexmakerVersion}"
|
testImplementation "org.mockito:mockito-core:2.7.22"
|
||||||
|
testImplementation "org.powermock:powermock-api-mockito2:${powermockVersion}"
|
||||||
|
testImplementation "org.powermock:powermock-module-junit4-rule-agent:${powermockVersion}"
|
||||||
|
testImplementation "org.powermock:powermock-module-junit4-rule:${powermockVersion}"
|
||||||
|
testImplementation "org.powermock:powermock-module-junit4:${powermockVersion}"
|
||||||
|
testImplementation "joda-time:joda-time:2.9.4.2"
|
||||||
|
testImplementation "com.google.truth:truth:0.39"
|
||||||
|
testImplementation 'org.robolectric:robolectric:3.8'
|
||||||
|
testImplementation "org.skyscreamer:jsonassert:1.5.0"
|
||||||
|
|
||||||
|
androidTestImplementation "org.mockito:mockito-core:2.7.22"
|
||||||
|
androidTestImplementation "com.google.dexmaker:dexmaker:${dexmakerVersion}"
|
||||||
|
androidTestImplementation "com.google.dexmaker:dexmaker-mockito:${dexmakerVersion}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
into outputDir
|
||||||
|
}
|
||||||
|
|
||||||
|
task copyLibs(dependsOn: unzip, type: Copy) {
|
||||||
|
def src = file("${buildDir}/unpacked/dist/danars-support-lib-master")
|
||||||
|
def target = file("src/main/jniLibs/")
|
||||||
|
|
||||||
|
from src
|
||||||
|
into target
|
||||||
|
}
|
||||||
|
|
||||||
|
task full_clean(type: Delete) {
|
||||||
|
delete file("src/main/jniLibs")
|
||||||
|
}
|
||||||
|
|
||||||
|
clean.dependsOn full_clean
|
||||||
|
preBuild.dependsOn copyLibs
|
||||||
|
|
Binary file not shown.
BIN
app/libs/sightparser-release.aar
Normal file
BIN
app/libs/sightparser-release.aar
Normal file
Binary file not shown.
|
@ -15,9 +15,11 @@
|
||||||
<uses-permission android:name="android.permission.SEND_MMS" />
|
<uses-permission android:name="android.permission.SEND_MMS" />
|
||||||
<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="android.permission.ACCESS_NETWORK_STATE" />
|
|
||||||
<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.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_WIFI_STATE" />
|
||||||
|
<uses-permission android:name="sugar.free.sightremote.HISTORY_BROADCASTS" />
|
||||||
|
|
||||||
<uses-permission-sdk-23 android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
|
<uses-permission-sdk-23 android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
|
||||||
|
|
||||||
|
@ -28,45 +30,50 @@
|
||||||
android:name=".MainApp"
|
android:name=".MainApp"
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:icon="${appIcon}"
|
android:icon="${appIcon}"
|
||||||
|
android:roundIcon="${appIconRound}"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme">
|
android:theme="@style/AppTheme.NoActionBar">
|
||||||
<activity android:name=".MainActivity">
|
<activity android:name=".MainActivity">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity android:name=".PreferencesActivity" />
|
<activity android:name=".activities.PreferencesActivity" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".plugins.Overview.Dialogs.BolusProgressHelperActivity"
|
android:name=".plugins.Overview.Dialogs.BolusProgressHelperActivity"
|
||||||
android:theme="@style/Theme.AppCompat.Translucent" />
|
android:theme="@style/Theme.AppCompat.Translucent" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".plugins.Overview.Dialogs.ErrorHelperActivity"
|
android:name=".plugins.Overview.Dialogs.ErrorHelperActivity"
|
||||||
android:theme="@style/Theme.AppCompat.Translucent" />
|
android:theme="@style/Theme.AppCompat.Translucent" />
|
||||||
<activity android:name=".AgreementActivity" />
|
<activity android:name=".activities.AgreementActivity" />
|
||||||
<activity android:name=".plugins.PumpDanaR.activities.DanaRHistoryActivity" />
|
<activity android:name=".plugins.PumpDanaR.activities.DanaRHistoryActivity" />
|
||||||
<activity android:name=".plugins.PumpDanaR.activities.DanaRStatsActivity" />
|
<activity android:name=".plugins.PumpDanaR.activities.DanaRUserOptionsActivity" />
|
||||||
|
<activity android:name=".activities.TDDStatsActivity" />
|
||||||
<activity android:name=".plugins.Overview.activities.QuickWizardListActivity">
|
<activity android:name=".plugins.Overview.activities.QuickWizardListActivity">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="info.nightscout.androidaps.plugins.Overview.activities.QuickWizardListActivity" />
|
<action android:name="info.nightscout.androidaps.plugins.Overview.activities.QuickWizardListActivity" />
|
||||||
|
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity android:name=".plugins.PumpDanaRS.activities.BLEScanActivity">
|
<activity android:name=".plugins.PumpDanaRS.activities.BLEScanActivity">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="info.nightscout.androidaps.plugins.PumpDanaRS.activities.BLEScanActivity" />
|
<action android:name="info.nightscout.androidaps.plugins.PumpDanaRS.activities.BLEScanActivity" />
|
||||||
|
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity android:name=".plugins.PumpDanaRS.activities.PairingHelperActivity" />
|
<activity android:name=".plugins.PumpDanaRS.activities.PairingHelperActivity" />
|
||||||
|
<activity android:name=".activities.HistoryBrowseActivity" />
|
||||||
|
|
||||||
<receiver
|
<receiver
|
||||||
android:name=".receivers.DataReceiver"
|
android:name=".receivers.DataReceiver"
|
||||||
android:enabled="true"
|
android:enabled="true"
|
||||||
android:exported="true">
|
android:exported="true">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
|
|
||||||
<!-- Receive new SMS messages -->
|
<!-- Receive new SMS messages -->
|
||||||
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
|
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
|
||||||
<!-- Receiver from xDrip -->
|
<!-- Receiver from xDrip -->
|
||||||
|
@ -77,6 +84,8 @@
|
||||||
<action android:name="it.ct.glicemia.ACTION_GLUCOSE_MEASURED" />
|
<action android:name="it.ct.glicemia.ACTION_GLUCOSE_MEASURED" />
|
||||||
<!-- Receiver from DexcomG5 -->
|
<!-- Receiver from DexcomG5 -->
|
||||||
<action android:name="com.dexcom.cgm.DATA" />
|
<action android:name="com.dexcom.cgm.DATA" />
|
||||||
|
<!-- Receiver from Poctech -->
|
||||||
|
<action android:name="com.china.poctech.data" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
<!-- Receiver keepalive, scheduled every 30 min -->
|
<!-- Receiver keepalive, scheduled every 30 min -->
|
||||||
|
@ -110,9 +119,27 @@
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
|
<!-- Network change local receiver -->
|
||||||
|
<receiver android:name=".receivers.NetworkChangeReceiver">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
|
||||||
|
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
|
||||||
|
</intent-filter>
|
||||||
|
</receiver>
|
||||||
|
|
||||||
|
<provider
|
||||||
|
android:name="android.support.v4.content.FileProvider"
|
||||||
|
android:authorities="${applicationId}.fileprovider"
|
||||||
|
android:exported="false"
|
||||||
|
android:grantUriPermissions="true">
|
||||||
|
<meta-data
|
||||||
|
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||||
|
android:resource="@xml/filepaths" />
|
||||||
|
</provider>
|
||||||
|
|
||||||
<!-- Service processing incomming data -->
|
<!-- Service processing incomming data -->
|
||||||
<service
|
<service
|
||||||
android:name=".Services.DataService"
|
android:name=".services.DataService"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
<service
|
<service
|
||||||
android:name=".plugins.PumpDanaR.services.DanaRExecutionService"
|
android:name=".plugins.PumpDanaR.services.DanaRExecutionService"
|
||||||
|
@ -129,7 +156,7 @@
|
||||||
<service
|
<service
|
||||||
android:name=".plugins.PumpDanaRS.services.DanaRSService"
|
android:name=".plugins.PumpDanaRS.services.DanaRSService"
|
||||||
android:enabled="true"
|
android:enabled="true"
|
||||||
android:exported="true"></service>
|
android:exported="true" />
|
||||||
<service
|
<service
|
||||||
android:name=".plugins.Wear.wearintegration.WatchUpdaterService"
|
android:name=".plugins.Wear.wearintegration.WatchUpdaterService"
|
||||||
android:exported="true">
|
android:exported="true">
|
||||||
|
@ -142,17 +169,28 @@
|
||||||
android:enabled="true"
|
android:enabled="true"
|
||||||
android:exported="true" />
|
android:exported="true" />
|
||||||
<service
|
<service
|
||||||
android:name=".Services.AlarmSoundService"
|
android:name=".services.AlarmSoundService"
|
||||||
android:enabled="true"
|
android:enabled="true"
|
||||||
android:exported="true" />
|
android:exported="true" />
|
||||||
<service
|
<service
|
||||||
android:name=".plugins.Overview.notifications.DismissNotificationService"
|
android:name=".plugins.Overview.notifications.DismissNotificationService"
|
||||||
android:exported="false"></service>
|
android:exported="false" />
|
||||||
|
|
||||||
|
<service android:name=".plugins.Persistentnotification.DummyService" />
|
||||||
|
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="io.fabric.ApiKey"
|
android:name="io.fabric.ApiKey"
|
||||||
android:value="59d462666c664c57b29e1d79ea123e01f8057cfa" />
|
android:value="59d462666c664c57b29e1d79ea123e01f8057cfa" />
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".setupwizard.SetupWizardActivity"
|
||||||
|
android:configChanges="orientation|keyboardHidden|screenSize"
|
||||||
|
android:theme="@style/AppTheme.NoActionBar"
|
||||||
|
android:label="@string/title_activity_setup_wizard" />
|
||||||
|
|
||||||
|
<activity android:name=".activities.SingleFragmentActivity"
|
||||||
|
android:theme="@style/AppTheme" />
|
||||||
|
<activity android:name=".plugins.Maintenance.activities.LogSettingActivity"></activity>
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
|
@ -0,0 +1,20 @@
|
||||||
|
// IRTHandler.aidl
|
||||||
|
package org.monkey.d.ruffy.ruffy.driver;
|
||||||
|
|
||||||
|
// Declare any non-default types here with import statements
|
||||||
|
import org.monkey.d.ruffy.ruffy.driver.display.Menu;
|
||||||
|
|
||||||
|
interface IRTHandler {
|
||||||
|
void log(String message);
|
||||||
|
void fail(String message);
|
||||||
|
|
||||||
|
void requestBluetooth();
|
||||||
|
void rtStopped();
|
||||||
|
void rtStarted();
|
||||||
|
|
||||||
|
void rtClearDisplay();
|
||||||
|
void rtUpdateDisplay(in byte[] quarter, int which);
|
||||||
|
|
||||||
|
void rtDisplayHandleMenu(in Menu menu);
|
||||||
|
void rtDisplayHandleNoMenu();
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
// IRuffyService.aidl
|
||||||
|
package org.monkey.d.ruffy.ruffy.driver;
|
||||||
|
|
||||||
|
// Declare any non-default types here with import statements
|
||||||
|
import org.monkey.d.ruffy.ruffy.driver.IRTHandler;
|
||||||
|
|
||||||
|
interface IRuffyService {
|
||||||
|
|
||||||
|
void setHandler(IRTHandler handler);
|
||||||
|
|
||||||
|
/** Connect to the pump
|
||||||
|
*
|
||||||
|
* @return 0 if successful, -1 otherwise
|
||||||
|
*/
|
||||||
|
int doRTConnect();
|
||||||
|
|
||||||
|
/** Disconnect from the pump */
|
||||||
|
void doRTDisconnect();
|
||||||
|
|
||||||
|
void rtSendKey(byte keyCode, boolean changed);
|
||||||
|
void resetPairing();
|
||||||
|
boolean isConnected();
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
package org.monkey.d.ruffy.ruffy.driver.display;
|
||||||
|
|
||||||
|
parcelable Menu;
|
|
@ -0,0 +1 @@
|
||||||
|
//b916a900c0899ef58ad58c7427d1c30d3c8731f4
|
61
app/src/main/assets/OpenAPSSMB/basal-set-temp.js
Normal file
61
app/src/main/assets/OpenAPSSMB/basal-set-temp.js
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
function reason(rT, msg) {
|
||||||
|
rT.reason = (rT.reason ? rT.reason + '. ' : '') + msg;
|
||||||
|
console.error(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
var tempBasalFunctions = {};
|
||||||
|
|
||||||
|
tempBasalFunctions.getMaxSafeBasal = function getMaxSafeBasal(profile) {
|
||||||
|
|
||||||
|
var max_daily_safety_multiplier = (isNaN(profile.max_daily_safety_multiplier) || profile.max_daily_safety_multiplier == null) ? 3 : profile.max_daily_safety_multiplier;
|
||||||
|
var current_basal_safety_multiplier = (isNaN(profile.current_basal_safety_multiplier) || profile.current_basal_safety_multiplier == null) ? 4 : profile.current_basal_safety_multiplier;
|
||||||
|
|
||||||
|
return Math.min(profile.max_basal, max_daily_safety_multiplier * profile.max_daily_basal, current_basal_safety_multiplier * profile.current_basal);
|
||||||
|
};
|
||||||
|
|
||||||
|
tempBasalFunctions.setTempBasal = function setTempBasal(rate, duration, profile, rT, currenttemp) {
|
||||||
|
//var maxSafeBasal = Math.min(profile.max_basal, 3 * profile.max_daily_basal, 4 * profile.current_basal);
|
||||||
|
|
||||||
|
var maxSafeBasal = tempBasalFunctions.getMaxSafeBasal(profile);
|
||||||
|
var round_basal = require('./round-basal');
|
||||||
|
|
||||||
|
if (rate < 0) {
|
||||||
|
rate = 0;
|
||||||
|
} // if >30m @ 0 required, zero temp will be extended to 30m instead
|
||||||
|
else if (rate > maxSafeBasal) {
|
||||||
|
rate = maxSafeBasal;
|
||||||
|
}
|
||||||
|
|
||||||
|
var suggestedRate = round_basal(rate, profile);
|
||||||
|
if (typeof(currenttemp) !== 'undefined' && typeof(currenttemp.duration) !== 'undefined' && typeof(currenttemp.rate) !== 'undefined' && currenttemp.duration > (duration-10) && currenttemp.duration <= 120 && suggestedRate <= currenttemp.rate * 1.2 && suggestedRate >= currenttemp.rate * 0.8) {
|
||||||
|
rT.reason += " "+currenttemp.duration+"m left and " + currenttemp.rate + " ~ req " + suggestedRate + "U/hr: no temp required";
|
||||||
|
return rT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (suggestedRate === profile.current_basal) {
|
||||||
|
if (profile.skip_neutral_temps) {
|
||||||
|
if (typeof(currenttemp) !== 'undefined' && typeof(currenttemp.duration) !== 'undefined' && currenttemp.duration > 0) {
|
||||||
|
reason(rT, 'Suggested rate is same as profile rate, a temp basal is active, canceling current temp');
|
||||||
|
rT.duration = 0;
|
||||||
|
rT.rate = 0;
|
||||||
|
return rT;
|
||||||
|
} else {
|
||||||
|
reason(rT, 'Suggested rate is same as profile rate, no temp basal is active, doing nothing');
|
||||||
|
return rT;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
reason(rT, 'Setting neutral temp basal of ' + profile.current_basal + 'U/hr');
|
||||||
|
rT.duration = duration;
|
||||||
|
rT.rate = suggestedRate;
|
||||||
|
return rT;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rT.duration = duration;
|
||||||
|
rT.rate = suggestedRate;
|
||||||
|
return rT;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = tempBasalFunctions;
|
1146
app/src/main/assets/OpenAPSSMB/determine-basal.js
Normal file
1146
app/src/main/assets/OpenAPSSMB/determine-basal.js
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,36 +1,39 @@
|
||||||
<configuration>
|
<configuration>
|
||||||
<!-- Create a file appender for a log in the application's data directory -->
|
<!-- Create a file appender for a log in the application's data directory -->
|
||||||
<property name="EXT_FILES_DIR" value="${EXT_DIR:-/sdcard}/Android/data/${PACKAGE_NAME}/files"/>
|
<property name="EXT_FILES_DIR" scope="context"
|
||||||
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
value="${EXT_DIR:-/sdcard}/Android/data/${PACKAGE_NAME}/files" />
|
||||||
<file>${EXT_FILES_DIR}/AndroidAPS.log</file>
|
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
<file>${EXT_FILES_DIR}/AndroidAPS.log</file>
|
||||||
|
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||||
<!-- daily rollover. Make sure the path matches the one in the file element or else
|
<!-- daily rollover. Make sure the path matches the one in the file element or else
|
||||||
the rollover logs are placed in the working directory. -->
|
the rollover logs are placed in the working directory. -->
|
||||||
<fileNamePattern>${EXT_FILES_DIR}/AndroidAPS._%d{yyyy-MM-dd}_%d{HH-mm-ss, aux}_.%i.zip</fileNamePattern>
|
<fileNamePattern>${EXT_FILES_DIR}/AndroidAPS._%d{yyyy-MM-dd}_%d{HH-mm-ss, aux}_.%i.zip
|
||||||
|
</fileNamePattern>
|
||||||
|
|
||||||
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
|
<timeBasedFileNamingAndTriggeringPolicy
|
||||||
|
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
|
||||||
<maxFileSize>5MB</maxFileSize>
|
<maxFileSize>5MB</maxFileSize>
|
||||||
</timeBasedFileNamingAndTriggeringPolicy>
|
</timeBasedFileNamingAndTriggeringPolicy>
|
||||||
<!-- keep 30 days' worth of history -->
|
<!-- keep 30 days' worth of history -->
|
||||||
<maxHistory>120</maxHistory>
|
<maxHistory>120</maxHistory>
|
||||||
</rollingPolicy>
|
</rollingPolicy>
|
||||||
<encoder>
|
<encoder>
|
||||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level [%class:%line]: %msg%n</pattern>
|
<pattern>%d{HH:mm:ss.SSS} [%thread] %.-1level/%logger: [%class{0}.%M\(\):%line]: %msg%n</pattern>
|
||||||
</encoder>
|
</encoder>
|
||||||
</appender>
|
</appender>
|
||||||
|
|
||||||
<appender name="logcat" class="ch.qos.logback.classic.android.LogcatAppender">
|
<appender name="logcat" class="ch.qos.logback.classic.android.LogcatAppender">
|
||||||
<tagEncoder>
|
<tagEncoder>
|
||||||
<pattern>%logger{0}</pattern>
|
<pattern>%logger{0}</pattern>
|
||||||
</tagEncoder>
|
</tagEncoder>
|
||||||
<encoder>
|
<encoder>
|
||||||
<pattern>[%thread] %-5level [%class:%line]: %msg%n</pattern>
|
<pattern>[%thread] [%class{0}.%M\(\):%line]: %msg%n</pattern>
|
||||||
</encoder>
|
</encoder>
|
||||||
</appender>
|
</appender>
|
||||||
|
|
||||||
<!-- Write INFO (and higher-level) messages to the log file -->
|
<!-- Write INFO (and higher-level) messages to the log file -->
|
||||||
<root level="DEBUG">
|
<root level="DEBUG">
|
||||||
<appender-ref ref="file" />
|
<appender-ref ref="file" />
|
||||||
<appender-ref ref="logcat" />
|
<appender-ref ref="logcat" />
|
||||||
</root>
|
</root>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|
BIN
app/src/main/blueowl-web.png
Normal file
BIN
app/src/main/blueowl-web.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 60 KiB |
BIN
app/src/main/ic_launcher-web.png
Normal file
BIN
app/src/main/ic_launcher-web.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 60 KiB |
BIN
app/src/main/ic_launcher_round-web.png
Normal file
BIN
app/src/main/ic_launcher_round-web.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 60 KiB |
|
@ -5,20 +5,23 @@ import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.ConcurrentModificationException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import info.nightscout.androidaps.events.Event;
|
import info.nightscout.androidaps.events.Event;
|
||||||
|
import info.nightscout.androidaps.logging.L;
|
||||||
|
|
||||||
/** Logs events has they're being posted to and dispatched from the event bus.
|
/**
|
||||||
*
|
* Logs events has they're being posted to and dispatched from the event bus.
|
||||||
|
* <p>
|
||||||
* A summary of event-receiver calls that occurred so far is logged
|
* A summary of event-receiver calls that occurred so far is logged
|
||||||
* after 10s (after startup) and then again every 60s.
|
* after 10s (after startup) and then again every 60s.
|
||||||
* */
|
*/
|
||||||
public class LoggingBus extends Bus {
|
public class LoggingBus extends Bus {
|
||||||
private static Logger log = LoggerFactory.getLogger(LoggingBus.class);
|
private static Logger log = LoggerFactory.getLogger(L.EVENTS);
|
||||||
|
|
||||||
private static long everyMinute = System.currentTimeMillis() + 10 * 1000;
|
private static long everyMinute = System.currentTimeMillis() + 10 * 1000;
|
||||||
private Map<String, Set<String>> event2Receiver = new HashMap<>();
|
private Map<String, Set<String>> event2Receiver = new HashMap<>();
|
||||||
|
@ -48,7 +51,10 @@ public class LoggingBus extends Bus {
|
||||||
log.debug(" source: <unknown>");
|
log.debug(" source: <unknown>");
|
||||||
}
|
}
|
||||||
|
|
||||||
super.post(event);
|
try {
|
||||||
|
super.post(event);
|
||||||
|
} catch (IllegalStateException ignored) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -70,16 +76,19 @@ public class LoggingBus extends Bus {
|
||||||
log.debug(" receiver: <unknown>");
|
log.debug(" receiver: <unknown>");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (everyMinute < System.currentTimeMillis()) {
|
try {
|
||||||
log.debug("***************** Event -> receiver pairings seen so far ****************");
|
if (everyMinute < System.currentTimeMillis()) {
|
||||||
for (Map.Entry<String, Set<String>> stringSetEntry : event2Receiver.entrySet()) {
|
log.debug("***************** Event -> receiver pairings seen so far ****************");
|
||||||
log.debug(" " + stringSetEntry.getKey());
|
for (Map.Entry<String, Set<String>> stringSetEntry : event2Receiver.entrySet()) {
|
||||||
for (String s : stringSetEntry.getValue()) {
|
log.debug(" " + stringSetEntry.getKey());
|
||||||
log.debug(" -> " + s);
|
for (String s : stringSetEntry.getValue()) {
|
||||||
|
log.debug(" -> " + s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
log.debug("*************************************************************************");
|
||||||
|
everyMinute = System.currentTimeMillis() + 60 * 1000;
|
||||||
}
|
}
|
||||||
log.debug("*************************************************************************");
|
} catch (ConcurrentModificationException ignored) {
|
||||||
everyMinute = System.currentTimeMillis() + 60 * 1000;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
super.dispatch(event, wrapper);
|
super.dispatch(event, wrapper);
|
||||||
|
|
|
@ -6,40 +6,19 @@ package info.nightscout.androidaps;
|
||||||
public class Config {
|
public class Config {
|
||||||
public static int SUPPORTEDNSVERSION = 1002; // 0.10.00
|
public static int SUPPORTEDNSVERSION = 1002; // 0.10.00
|
||||||
|
|
||||||
// MAIN FUCTIONALITY
|
public static final boolean APS = BuildConfig.FLAVOR.equals("full");
|
||||||
public static final boolean APS = BuildConfig.APS;
|
|
||||||
// PLUGINS
|
|
||||||
public static final boolean NSCLIENT = BuildConfig.NSCLIENTOLNY;
|
|
||||||
public static final boolean G5UPLOADER = BuildConfig.G5UPLOADER;
|
|
||||||
public static final boolean PUMPCONTROL = BuildConfig.PUMPCONTROL;
|
|
||||||
|
|
||||||
public static final boolean DANAR = BuildConfig.PUMPDRIVERS;
|
public static final boolean NSCLIENT = BuildConfig.FLAVOR.equals("nsclient") || BuildConfig.FLAVOR.equals("nsclient2");
|
||||||
|
public static final boolean PUMPCONTROL = BuildConfig.FLAVOR.equals("pumpcontrol");
|
||||||
|
|
||||||
public static final boolean ACTION = !BuildConfig.NSCLIENTOLNY && !BuildConfig.G5UPLOADER;
|
public static final boolean PUMPDRIVERS = BuildConfig.FLAVOR.equals("full") || BuildConfig.FLAVOR.equals("pumpcontrol");
|
||||||
public static final boolean VIRTUALPUMP = !BuildConfig.NSCLIENTOLNY && !BuildConfig.G5UPLOADER;
|
|
||||||
public static final boolean MDI = !BuildConfig.NSCLIENTOLNY && !BuildConfig.G5UPLOADER;
|
|
||||||
public static final boolean OTHERPROFILES = !BuildConfig.NSCLIENTOLNY && !BuildConfig.G5UPLOADER;
|
|
||||||
public static final boolean SAFETY = !BuildConfig.NSCLIENTOLNY && !BuildConfig.G5UPLOADER;
|
|
||||||
|
|
||||||
public static final boolean SMSCOMMUNICATORENABLED = !BuildConfig.NSCLIENTOLNY && !BuildConfig.G5UPLOADER;
|
public static final boolean ACTION = !NSCLIENT;
|
||||||
|
public static final boolean MDI = !NSCLIENT;
|
||||||
|
public static final boolean OTHERPROFILES = !NSCLIENT;
|
||||||
|
public static final boolean SAFETY = !NSCLIENT;
|
||||||
|
|
||||||
|
public static final boolean SMSCOMMUNICATORENABLED = !NSCLIENT;
|
||||||
|
|
||||||
|
|
||||||
public static final boolean detailedLog = true;
|
|
||||||
public static final boolean logFunctionCalls = true;
|
|
||||||
public static final boolean logIncommingData = true;
|
|
||||||
public static final boolean logAPSResult = true;
|
|
||||||
public static final boolean logPumpComm = true;
|
|
||||||
public static final boolean logPrefsChange = true;
|
|
||||||
public static final boolean logConfigBuilder = true;
|
|
||||||
public static final boolean logConstraintsChanges = true;
|
|
||||||
public static final boolean logNSUpload = true;
|
|
||||||
public static final boolean logPumpActions = true;
|
|
||||||
public static final boolean logCongigBuilderActions = true;
|
|
||||||
public static final boolean logAutosensData = false;
|
|
||||||
public static final boolean logEvents = false;
|
|
||||||
|
|
||||||
// DanaR specific
|
|
||||||
public static final boolean logDanaBTComm = true;
|
|
||||||
public static boolean logDanaMessageDetail = true;
|
|
||||||
public static final boolean logDanaSerialEngine = true;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package info.nightscout.androidaps;
|
package info.nightscout.androidaps;
|
||||||
|
|
||||||
import com.j256.ormlite.stmt.query.In;
|
import info.nightscout.utils.T;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by mike on 07.06.2016.
|
* Created by mike on 07.06.2016.
|
||||||
|
@ -12,12 +12,13 @@ public class Constants {
|
||||||
public static final double MMOLL_TO_MGDL = 18; // 18.0182;
|
public static final double MMOLL_TO_MGDL = 18; // 18.0182;
|
||||||
public static final double MGDL_TO_MMOLL = 1 / MMOLL_TO_MGDL;
|
public static final double MGDL_TO_MMOLL = 1 / MMOLL_TO_MGDL;
|
||||||
|
|
||||||
public static final double defaultDIA = 3d;
|
public static final double defaultDIA = 5d;
|
||||||
|
|
||||||
public static final double basalAbsoluteOnlyForCheckLimit = 10101010d;
|
public static final Double REALLYHIGHBASALRATE = 1111111d;
|
||||||
public static final Integer basalPercentOnlyForCheckLimit = 10101010;
|
public static final Integer REALLYHIGHPERCENTBASALRATE = 1111111;
|
||||||
public static final double bolusOnlyForCheckLimit = 10101010d;
|
public static final double REALLYHIGHBOLUS = 1111111d;
|
||||||
public static final Integer carbsOnlyForCheckLimit = 10101010;
|
public static final Integer REALLYHIGHCARBS = 1111111;
|
||||||
|
public static final double REALLYHIGHIOB = 1111111d;
|
||||||
|
|
||||||
public static final Integer notificationID = 556677;
|
public static final Integer notificationID = 556677;
|
||||||
|
|
||||||
|
@ -35,20 +36,20 @@ public class Constants {
|
||||||
public static final int CPP_MIN_TIMESHIFT = -6;
|
public static final int CPP_MIN_TIMESHIFT = -6;
|
||||||
public static final int CPP_MAX_TIMESHIFT = 23;
|
public static final int CPP_MAX_TIMESHIFT = 23;
|
||||||
|
|
||||||
// Very Hard Limits Ranges
|
|
||||||
// First value is the Lowest and second value is the Highest a Limit can define
|
|
||||||
public static final int[] VERY_HARD_LIMIT_MIN_BG = {72,180};
|
|
||||||
public static final int[] VERY_HARD_LIMIT_MAX_BG = {90,270};
|
|
||||||
public static final int[] VERY_HARD_LIMIT_TARGET_BG = {80,200};
|
|
||||||
|
|
||||||
// Very Hard Limits Ranges for Temp Targets
|
|
||||||
public static final int[] VERY_HARD_LIMIT_TEMP_MIN_BG = {72,180};
|
|
||||||
public static final int[] VERY_HARD_LIMIT_TEMP_MAX_BG = {72,270};
|
|
||||||
public static final int[] VERY_HARD_LIMIT_TEMP_TARGET_BG = {72,200};
|
|
||||||
|
|
||||||
//DanaR
|
//DanaR
|
||||||
public static final double dailyLimitWarning = 0.95d;
|
public static final double dailyLimitWarning = 0.95d;
|
||||||
|
|
||||||
|
// Temp targets
|
||||||
|
public static final int defaultActivityTTDuration = 90; // min
|
||||||
|
public static final double defaultActivityTTmgdl = 140d;
|
||||||
|
public static final double defaultActivityTTmmol = 8d;
|
||||||
|
public static final int defaultEatingSoonTTDuration = 45; // min
|
||||||
|
public static final double defaultEatingSoonTTmgdl = 90d;
|
||||||
|
public static final double defaultEatingSoonTTmmol = 5d;
|
||||||
|
public static final int defaultHypoTTDuration = 30; // min
|
||||||
|
public static final double defaultHypoTTmgdl = 120d;
|
||||||
|
public static final double defaultHypoTTmmol = 6.5d;
|
||||||
|
|
||||||
//NSClientInternal
|
//NSClientInternal
|
||||||
public static final int MAX_LOG_LINES = 100;
|
public static final int MAX_LOG_LINES = 100;
|
||||||
|
|
||||||
|
@ -58,8 +59,13 @@ public class Constants {
|
||||||
|
|
||||||
//Autosens
|
//Autosens
|
||||||
public static final double DEVIATION_TO_BE_EQUAL = 2.0;
|
public static final double DEVIATION_TO_BE_EQUAL = 2.0;
|
||||||
|
public static final double DEFAULT_MAX_ABSORPTION_TIME = 6.0;
|
||||||
|
|
||||||
// Pump
|
// Pump
|
||||||
public static final int PUMP_MAX_CONNECTION_TIME_IN_SECONDS = 120 - 1;
|
public static final int PUMP_MAX_CONNECTION_TIME_IN_SECONDS = 120 - 1;
|
||||||
public static final int MIN_WATCHDOG_INTERVAL_IN_SECONDS = 12 * 60;
|
public static final int MIN_WATCHDOG_INTERVAL_IN_SECONDS = 12 * 60;
|
||||||
|
|
||||||
|
//SMS Communicator
|
||||||
|
public static final long SMS_CONFIRM_TIMEOUT = T.mins(5).msecs();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,32 +1,35 @@
|
||||||
package info.nightscout.androidaps;
|
package info.nightscout.androidaps;
|
||||||
|
|
||||||
import android.Manifest;
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.ActivityNotFoundException;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.PersistableBundle;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.provider.Settings;
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.design.widget.NavigationView;
|
||||||
|
import android.support.design.widget.TabLayout;
|
||||||
import android.support.v4.app.ActivityCompat;
|
import android.support.v4.app.ActivityCompat;
|
||||||
import android.support.v4.content.ContextCompat;
|
|
||||||
import android.support.v4.view.ViewPager;
|
import android.support.v4.view.ViewPager;
|
||||||
|
import android.support.v4.widget.DrawerLayout;
|
||||||
|
import android.support.v7.app.ActionBarDrawerToggle;
|
||||||
import android.support.v7.app.AlertDialog;
|
import android.support.v7.app.AlertDialog;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.support.v7.widget.PopupMenu;
|
import android.support.v7.widget.Toolbar;
|
||||||
import android.view.MenuInflater;
|
import android.text.SpannableString;
|
||||||
|
import android.text.method.LinkMovementMethod;
|
||||||
|
import android.text.util.Linkify;
|
||||||
|
import android.util.TypedValue;
|
||||||
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.ImageButton;
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.joanzapata.iconify.Iconify;
|
import com.joanzapata.iconify.Iconify;
|
||||||
import com.joanzapata.iconify.fonts.FontAwesomeModule;
|
import com.joanzapata.iconify.fonts.FontAwesomeModule;
|
||||||
|
@ -35,113 +38,221 @@ import com.squareup.otto.Subscribe;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import info.nightscout.androidaps.Services.AlarmSoundService;
|
import info.nightscout.androidaps.activities.AgreementActivity;
|
||||||
|
import info.nightscout.androidaps.activities.HistoryBrowseActivity;
|
||||||
|
import info.nightscout.androidaps.activities.PreferencesActivity;
|
||||||
|
import info.nightscout.androidaps.activities.SingleFragmentActivity;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
import info.nightscout.androidaps.events.EventAppExit;
|
import info.nightscout.androidaps.events.EventAppExit;
|
||||||
|
import info.nightscout.androidaps.events.EventFeatureRunning;
|
||||||
import info.nightscout.androidaps.events.EventPreferenceChange;
|
import info.nightscout.androidaps.events.EventPreferenceChange;
|
||||||
import info.nightscout.androidaps.events.EventRefreshGui;
|
import info.nightscout.androidaps.events.EventRefreshGui;
|
||||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
import info.nightscout.androidaps.logging.L;
|
||||||
import info.nightscout.androidaps.plugins.Overview.events.EventSetWakeLock;
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions;
|
||||||
import info.nightscout.androidaps.tabs.SlidingTabLayout;
|
import info.nightscout.androidaps.plugins.NSClientInternal.data.NSSettingsStatus;
|
||||||
|
import info.nightscout.androidaps.setupwizard.SetupWizardActivity;
|
||||||
import info.nightscout.androidaps.tabs.TabPageAdapter;
|
import info.nightscout.androidaps.tabs.TabPageAdapter;
|
||||||
import info.nightscout.utils.ImportExportPrefs;
|
import info.nightscout.utils.AndroidPermission;
|
||||||
import info.nightscout.utils.LocaleHelper;
|
import info.nightscout.utils.LocaleHelper;
|
||||||
import info.nightscout.utils.LogDialog;
|
|
||||||
import info.nightscout.utils.OKDialog;
|
import info.nightscout.utils.OKDialog;
|
||||||
import info.nightscout.utils.PasswordProtection;
|
import info.nightscout.utils.PasswordProtection;
|
||||||
import info.nightscout.utils.SP;
|
import info.nightscout.utils.SP;
|
||||||
import info.nightscout.utils.ToastUtils;
|
import info.nightscout.utils.VersionChecker;
|
||||||
|
|
||||||
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
|
public class MainActivity extends AppCompatActivity {
|
||||||
private static Logger log = LoggerFactory.getLogger(MainActivity.class);
|
private static Logger log = LoggerFactory.getLogger(L.CORE);
|
||||||
|
|
||||||
static final int CASE_STORAGE = 0x1;
|
|
||||||
static final int CASE_SMS = 0x2;
|
|
||||||
static final int CASE_LOCATION = 0x3;
|
|
||||||
|
|
||||||
private boolean askForSMS = false;
|
|
||||||
private boolean askForLocation = true;
|
|
||||||
|
|
||||||
ImageButton menuButton;
|
|
||||||
|
|
||||||
protected PowerManager.WakeLock mWakeLock;
|
protected PowerManager.WakeLock mWakeLock;
|
||||||
|
|
||||||
|
private ActionBarDrawerToggle actionBarDrawerToggle;
|
||||||
|
|
||||||
|
private MenuItem pluginPreferencesMenuItem;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
Iconify.with(new FontAwesomeModule());
|
|
||||||
LocaleHelper.onCreate(this, "en");
|
|
||||||
setContentView(R.layout.activity_main);
|
|
||||||
menuButton = (ImageButton) findViewById(R.id.overview_menuButton);
|
|
||||||
menuButton.setOnClickListener(this);
|
|
||||||
|
|
||||||
checkEula();
|
if (L.isEnabled(L.CORE))
|
||||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) {
|
|
||||||
askForPermission(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,
|
|
||||||
Manifest.permission.WRITE_EXTERNAL_STORAGE}, CASE_STORAGE);
|
|
||||||
}
|
|
||||||
askForBatteryOptimizationPermission();
|
|
||||||
doMigrations();
|
|
||||||
if (Config.logFunctionCalls)
|
|
||||||
log.debug("onCreate");
|
log.debug("onCreate");
|
||||||
|
|
||||||
onStatusEvent(new EventSetWakeLock(SP.getBoolean("lockscreen", false)));
|
Iconify.with(new FontAwesomeModule());
|
||||||
|
LocaleHelper.onCreate(this, "en");
|
||||||
|
|
||||||
|
setContentView(R.layout.activity_main);
|
||||||
|
setSupportActionBar(findViewById(R.id.toolbar));
|
||||||
|
getSupportActionBar().setDisplayShowTitleEnabled(false);
|
||||||
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
|
getSupportActionBar().setHomeButtonEnabled(true);
|
||||||
|
|
||||||
|
DrawerLayout drawerLayout = findViewById(R.id.drawer_layout);
|
||||||
|
actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.string.open_navigation, R.string.close_navigation);
|
||||||
|
drawerLayout.addDrawerListener(actionBarDrawerToggle);
|
||||||
|
actionBarDrawerToggle.syncState();
|
||||||
|
|
||||||
|
// initialize screen wake lock
|
||||||
|
onEventPreferenceChange(new EventPreferenceChange(R.string.key_keep_screen_on));
|
||||||
|
|
||||||
|
doMigrations();
|
||||||
|
|
||||||
registerBus();
|
registerBus();
|
||||||
setUpTabs(false);
|
setupTabs();
|
||||||
|
setupViews(false);
|
||||||
|
|
||||||
|
final ViewPager viewPager = findViewById(R.id.pager);
|
||||||
|
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageSelected(int position) {
|
||||||
|
checkPluginPreferences(viewPager);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageScrollStateChanged(int state) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
VersionChecker.check();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkPluginPreferences(ViewPager viewPager) {
|
||||||
|
if (pluginPreferencesMenuItem == null) return;
|
||||||
|
if (((TabPageAdapter) viewPager.getAdapter()).getPluginAt(viewPager.getCurrentItem()).getPreferencesId() != -1)
|
||||||
|
pluginPreferencesMenuItem.setEnabled(true);
|
||||||
|
else pluginPreferencesMenuItem.setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPostCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {
|
||||||
|
super.onPostCreate(savedInstanceState, persistentState);
|
||||||
|
actionBarDrawerToggle.syncState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
if (L.isEnabled(L.CORE))
|
||||||
|
log.debug("onResume");
|
||||||
|
|
||||||
|
if (!SP.getBoolean(R.string.key_setupwizard_processed, false)) {
|
||||||
|
Intent intent = new Intent(this, SetupWizardActivity.class);
|
||||||
|
startActivity(intent);
|
||||||
|
} else {
|
||||||
|
checkEula();
|
||||||
|
}
|
||||||
|
|
||||||
|
AndroidPermission.notifyForStoragePermission(this);
|
||||||
|
AndroidPermission.notifyForBatteryOptimizationPermission(this);
|
||||||
|
if (Config.PUMPDRIVERS) {
|
||||||
|
AndroidPermission.notifyForLocationPermissions(this);
|
||||||
|
AndroidPermission.notifyForSMSPermissions(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
MainApp.bus().post(new EventFeatureRunning(EventFeatureRunning.Feature.MAIN));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
if (L.isEnabled(L.CORE))
|
||||||
|
log.debug("onDestroy");
|
||||||
|
if (mWakeLock != null)
|
||||||
|
if (mWakeLock.isHeld())
|
||||||
|
mWakeLock.release();
|
||||||
|
super.onDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onStatusEvent(final EventSetWakeLock ev) {
|
public void onEventPreferenceChange(final EventPreferenceChange ev) {
|
||||||
final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
|
if (ev.isChanged(R.string.key_keep_screen_on)) {
|
||||||
if (ev.lock) {
|
boolean keepScreenOn = SP.getBoolean(R.string.key_keep_screen_on, false);
|
||||||
mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "AAPS");
|
final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
|
||||||
if (!mWakeLock.isHeld())
|
if (keepScreenOn) {
|
||||||
mWakeLock.acquire();
|
mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "AAPS");
|
||||||
} else {
|
if (!mWakeLock.isHeld())
|
||||||
if (mWakeLock != null && mWakeLock.isHeld())
|
mWakeLock.acquire();
|
||||||
mWakeLock.release();
|
} else {
|
||||||
|
if (mWakeLock != null && mWakeLock.isHeld())
|
||||||
|
mWakeLock.release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onStatusEvent(final EventRefreshGui ev) {
|
public void onStatusEvent(final EventRefreshGui ev) {
|
||||||
String lang = SP.getString("language", "en");
|
String lang = SP.getString(R.string.key_language, "en");
|
||||||
LocaleHelper.setLocale(getApplicationContext(), lang);
|
LocaleHelper.setLocale(getApplicationContext(), lang);
|
||||||
runOnUiThread(new Runnable() {
|
runOnUiThread(() -> {
|
||||||
@Override
|
if (ev.recreate) {
|
||||||
public void run() {
|
recreate();
|
||||||
if(ev.recreate) {
|
} else {
|
||||||
recreate();
|
try { // activity may be destroyed
|
||||||
}else {
|
setupTabs();
|
||||||
try { // activity may be destroyed
|
setupViews(true);
|
||||||
setUpTabs(true);
|
} catch (IllegalStateException e) {
|
||||||
} catch (IllegalStateException e) {
|
log.error("Unhandled exception", e);
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean lockScreen = BuildConfig.NSCLIENTOLNY && SP.getBoolean("lockscreen", false);
|
|
||||||
if (lockScreen)
|
|
||||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
|
||||||
else
|
|
||||||
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean keepScreenOn = Config.NSCLIENT && SP.getBoolean(R.string.key_keep_screen_on, false);
|
||||||
|
if (keepScreenOn)
|
||||||
|
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||||
|
else
|
||||||
|
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUpTabs(boolean switchToLast) {
|
private void setupViews(boolean switchToLast) {
|
||||||
TabPageAdapter pageAdapter = new TabPageAdapter(getSupportFragmentManager(), this);
|
TabPageAdapter pageAdapter = new TabPageAdapter(getSupportFragmentManager(), this);
|
||||||
|
NavigationView navigationView = findViewById(R.id.navigation_view);
|
||||||
|
navigationView.setNavigationItemSelectedListener(menuItem -> {
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
Menu menu = navigationView.getMenu();
|
||||||
|
menu.clear();
|
||||||
for (PluginBase p : MainApp.getPluginsList()) {
|
for (PluginBase p : MainApp.getPluginsList()) {
|
||||||
pageAdapter.registerNewFragment(p);
|
pageAdapter.registerNewFragment(p);
|
||||||
|
if (p.hasFragment() && !p.isFragmentVisible() && p.isEnabled(p.pluginDescription.getType()) && !p.pluginDescription.neverVisible) {
|
||||||
|
MenuItem menuItem = menu.add(p.getName());
|
||||||
|
menuItem.setCheckable(true);
|
||||||
|
menuItem.setOnMenuItemClickListener(item -> {
|
||||||
|
Intent intent = new Intent(this, SingleFragmentActivity.class);
|
||||||
|
intent.putExtra("plugin", MainApp.getPluginsList().indexOf(p));
|
||||||
|
startActivity(intent);
|
||||||
|
((DrawerLayout) findViewById(R.id.drawer_layout)).closeDrawers();
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ViewPager mPager = (ViewPager) findViewById(R.id.pager);
|
ViewPager mPager = findViewById(R.id.pager);
|
||||||
mPager.setAdapter(pageAdapter);
|
mPager.setAdapter(pageAdapter);
|
||||||
SlidingTabLayout mTabs = (SlidingTabLayout) findViewById(R.id.tabs);
|
|
||||||
mTabs.setViewPager(mPager);
|
|
||||||
if (switchToLast)
|
if (switchToLast)
|
||||||
mPager.setCurrentItem(pageAdapter.getCount() - 1, false);
|
mPager.setCurrentItem(pageAdapter.getCount() - 1, false);
|
||||||
|
checkPluginPreferences(mPager);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupTabs() {
|
||||||
|
ViewPager viewPager = findViewById(R.id.pager);
|
||||||
|
TabLayout normalTabs = findViewById(R.id.tabs_normal);
|
||||||
|
normalTabs.setupWithViewPager(viewPager, true);
|
||||||
|
TabLayout compactTabs = findViewById(R.id.tabs_compact);
|
||||||
|
compactTabs.setupWithViewPager(viewPager, true);
|
||||||
|
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||||
|
if (SP.getBoolean("short_tabtitles", false)) {
|
||||||
|
normalTabs.setVisibility(View.GONE);
|
||||||
|
compactTabs.setVisibility(View.VISIBLE);
|
||||||
|
toolbar.setLayoutParams(new LinearLayout.LayoutParams(Toolbar.LayoutParams.MATCH_PARENT, (int) getResources().getDimension(R.dimen.compact_height)));
|
||||||
|
} else {
|
||||||
|
normalTabs.setVisibility(View.VISIBLE);
|
||||||
|
compactTabs.setVisibility(View.GONE);
|
||||||
|
TypedValue typedValue = new TypedValue();
|
||||||
|
if (getTheme().resolveAttribute(R.attr.actionBarSize, typedValue, true)) {
|
||||||
|
toolbar.setLayoutParams(new LinearLayout.LayoutParams(Toolbar.LayoutParams.MATCH_PARENT,
|
||||||
|
TypedValue.complexToDimensionPixelSize(typedValue.data, getResources().getDisplayMetrics())));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerBus() {
|
private void registerBus() {
|
||||||
|
@ -171,7 +282,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
||||||
// Added in 1.57 at 21.01.2018
|
// Added in 1.57 at 21.01.2018
|
||||||
Integer unreachable_threshold = SP.getInt(R.string.key_pump_unreachable_threshold, 30);
|
Integer unreachable_threshold = SP.getInt(R.string.key_pump_unreachable_threshold, 30);
|
||||||
SP.remove(R.string.key_pump_unreachable_threshold);
|
SP.remove(R.string.key_pump_unreachable_threshold);
|
||||||
if(unreachable_threshold < 30) unreachable_threshold = 30;
|
if (unreachable_threshold < 30) unreachable_threshold = 30;
|
||||||
SP.putString(R.string.key_pump_unreachable_threshold, unreachable_threshold.toString());
|
SP.putString(R.string.key_pump_unreachable_threshold, unreachable_threshold.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,7 +290,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
||||||
private void checkUpgradeToProfileTarget() { // TODO: can be removed in the future
|
private void checkUpgradeToProfileTarget() { // TODO: can be removed in the future
|
||||||
boolean oldKeyExists = SP.contains("openapsma_min_bg");
|
boolean oldKeyExists = SP.contains("openapsma_min_bg");
|
||||||
if (oldKeyExists) {
|
if (oldKeyExists) {
|
||||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||||
String oldRange = SP.getDouble("openapsma_min_bg", 0d) + " - " + SP.getDouble("openapsma_max_bg", 0d);
|
String oldRange = SP.getDouble("openapsma_min_bg", 0d) + " - " + SP.getDouble("openapsma_max_bg", 0d);
|
||||||
String newRange = "";
|
String newRange = "";
|
||||||
if (profile != null) {
|
if (profile != null) {
|
||||||
|
@ -199,119 +310,22 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//check for sms permission if enable in prefernces
|
|
||||||
@Subscribe
|
|
||||||
public void onStatusEvent(final EventPreferenceChange ev) {
|
|
||||||
if (ev.isChanged(R.string.key_smscommunicator_remotecommandsallowed)) {
|
|
||||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) {
|
|
||||||
synchronized (this) {
|
|
||||||
if (SP.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)) {
|
|
||||||
setAskForSMS();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private synchronized void setAskForSMS() {
|
|
||||||
askForSMS = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
askForSMSPermissions();
|
|
||||||
askForLocationPermissions();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDestroy() {
|
|
||||||
if (mWakeLock != null)
|
|
||||||
if (mWakeLock.isHeld())
|
|
||||||
mWakeLock.release();
|
|
||||||
super.onDestroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void askForBatteryOptimizationPermission() {
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
||||||
final String packageName = getPackageName();
|
|
||||||
|
|
||||||
final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
|
|
||||||
if (!pm.isIgnoringBatteryOptimizations(packageName)) {
|
|
||||||
log.debug("Requesting ignore battery optimization");
|
|
||||||
|
|
||||||
OKDialog.show(this, getString(R.string.pleaseallowpermission), String.format(getString(R.string.needwhitelisting), getString(R.string.app_name)), new Runnable() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
final Intent intent = new Intent();
|
|
||||||
|
|
||||||
// ignoring battery optimizations required for constant connection
|
|
||||||
intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
|
|
||||||
intent.setData(Uri.parse("package:" + packageName));
|
|
||||||
startActivity(intent);
|
|
||||||
|
|
||||||
} catch (ActivityNotFoundException e) {
|
|
||||||
final String msg = getString(R.string.batteryoptimalizationerror);
|
|
||||||
ToastUtils.showToastInUiThread(getApplicationContext(), msg);
|
|
||||||
log.error(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private synchronized void askForSMSPermissions() {
|
|
||||||
if (askForSMS) { //only when settings were changed an MainActivity resumes.
|
|
||||||
askForSMS = false;
|
|
||||||
if (SP.getBoolean(R.string.smscommunicator_remotecommandsallowed, false)) {
|
|
||||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) {
|
|
||||||
askForPermission(new String[]{Manifest.permission.RECEIVE_SMS,
|
|
||||||
Manifest.permission.SEND_SMS,
|
|
||||||
Manifest.permission.RECEIVE_MMS}, CASE_SMS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private synchronized void askForLocationPermissions() {
|
|
||||||
if (askForLocation) { //only when settings were changed an MainActivity resumes.
|
|
||||||
askForLocation = false;
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
||||||
askForPermission(new String[]{Manifest.permission.ACCESS_FINE_LOCATION,
|
|
||||||
Manifest.permission.ACCESS_FINE_LOCATION,
|
|
||||||
Manifest.permission.ACCESS_FINE_LOCATION}, CASE_LOCATION);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void askForPermission(String[] permission, Integer requestCode) {
|
|
||||||
boolean test = false;
|
|
||||||
for (int i = 0; i < permission.length; i++) {
|
|
||||||
test = test || (ContextCompat.checkSelfPermission(this, permission[i]) != PackageManager.PERMISSION_GRANTED);
|
|
||||||
}
|
|
||||||
if (test) {
|
|
||||||
ActivityCompat.requestPermissions(this, permission, requestCode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
|
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
|
||||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||||
if (permissions.length != 0) {
|
if (permissions.length != 0) {
|
||||||
if (ActivityCompat.checkSelfPermission(this, permissions[0]) == PackageManager.PERMISSION_GRANTED) {
|
if (ActivityCompat.checkSelfPermission(this, permissions[0]) == PackageManager.PERMISSION_GRANTED) {
|
||||||
switch (requestCode) {
|
switch (requestCode) {
|
||||||
case CASE_STORAGE:
|
case AndroidPermission.CASE_STORAGE:
|
||||||
//show dialog after permission is granted
|
//show dialog after permission is granted
|
||||||
AlertDialog.Builder alert = new AlertDialog.Builder(this);
|
AlertDialog.Builder alert = new AlertDialog.Builder(this);
|
||||||
alert.setMessage(R.string.alert_dialog_storage_permission_text);
|
alert.setMessage(R.string.alert_dialog_storage_permission_text);
|
||||||
alert.setPositiveButton(R.string.ok, null);
|
alert.setPositiveButton(R.string.ok, null);
|
||||||
alert.show();
|
alert.show();
|
||||||
break;
|
break;
|
||||||
case CASE_LOCATION:
|
case AndroidPermission.CASE_LOCATION:
|
||||||
case CASE_SMS:
|
case AndroidPermission.CASE_SMS:
|
||||||
|
case AndroidPermission.CASE_BATTERY:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -336,82 +350,70 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(final View v) {
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
final Activity activity = this;
|
getMenuInflater().inflate(R.menu.menu_main, menu);
|
||||||
switch (v.getId()) {
|
pluginPreferencesMenuItem = menu.findItem(R.id.nav_plugin_preferences);
|
||||||
case R.id.overview_menuButton:
|
checkPluginPreferences(findViewById(R.id.pager));
|
||||||
PopupMenu popup = new PopupMenu(v.getContext(), v);
|
return true;
|
||||||
MenuInflater inflater = popup.getMenuInflater();
|
}
|
||||||
inflater.inflate(R.menu.menu_main, popup.getMenu());
|
|
||||||
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
|
@Override
|
||||||
@Override
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
public boolean onMenuItemClick(MenuItem item) {
|
int id = item.getItemId();
|
||||||
int id = item.getItemId();
|
switch (id) {
|
||||||
switch (id) {
|
case R.id.nav_preferences:
|
||||||
case R.id.nav_preferences:
|
PasswordProtection.QueryPassword(this, R.string.settings_password, "settings_password", () -> {
|
||||||
PasswordProtection.QueryPassword(v.getContext(), R.string.settings_password, "settings_password", new Runnable() {
|
Intent i = new Intent(this, PreferencesActivity.class);
|
||||||
@Override
|
i.putExtra("id", -1);
|
||||||
public void run() {
|
startActivity(i);
|
||||||
Intent i = new Intent(v.getContext(), PreferencesActivity.class);
|
}, null);
|
||||||
i.putExtra("id", -1);
|
return true;
|
||||||
startActivity(i);
|
case R.id.nav_historybrowser:
|
||||||
}
|
startActivity(new Intent(this, HistoryBrowseActivity.class));
|
||||||
}, null);
|
return true;
|
||||||
break;
|
case R.id.nav_setupwizard:
|
||||||
case R.id.nav_resetdb:
|
startActivity(new Intent(this, SetupWizardActivity.class));
|
||||||
new AlertDialog.Builder(v.getContext())
|
return true;
|
||||||
.setTitle(R.string.nav_resetdb)
|
case R.id.nav_about:
|
||||||
.setMessage(R.string.reset_db_confirm)
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||||
.setNegativeButton(android.R.string.cancel, null)
|
builder.setTitle(MainApp.gs(R.string.app_name) + " " + BuildConfig.VERSION);
|
||||||
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
if (Config.NSCLIENT)
|
||||||
@Override
|
builder.setIcon(R.mipmap.yellowowl);
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
else
|
||||||
MainApp.getDbHelper().resetDatabases();
|
builder.setIcon(R.mipmap.blueowl);
|
||||||
}
|
String message = "Build: " + BuildConfig.BUILDVERSION + "\n";
|
||||||
})
|
message += "Flavor: " + BuildConfig.FLAVOR + BuildConfig.BUILD_TYPE + "\n";
|
||||||
.create()
|
message += MainApp.gs(R.string.configbuilder_nightscoutversion_label) + " " + NSSettingsStatus.getInstance().nightscoutVersionName;
|
||||||
.show();
|
if (MainApp.engineeringMode)
|
||||||
break;
|
message += "\n" + MainApp.gs(R.string.engineering_mode_enabled);
|
||||||
case R.id.nav_export:
|
message += MainApp.gs(R.string.about_link_urls);
|
||||||
ImportExportPrefs.verifyStoragePermissions(activity);
|
final SpannableString messageSpanned = new SpannableString(message);
|
||||||
ImportExportPrefs.exportSharedPreferences(activity);
|
Linkify.addLinks(messageSpanned, Linkify.WEB_URLS);
|
||||||
break;
|
builder.setMessage(messageSpanned);
|
||||||
case R.id.nav_import:
|
builder.setPositiveButton(MainApp.gs(R.string.ok), null);
|
||||||
ImportExportPrefs.verifyStoragePermissions(activity);
|
AlertDialog alertDialog = builder.create();
|
||||||
ImportExportPrefs.importSharedPreferences(activity);
|
alertDialog.show();
|
||||||
break;
|
((TextView) alertDialog.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance());
|
||||||
case R.id.nav_show_logcat:
|
return true;
|
||||||
LogDialog.showLogcat(v.getContext());
|
case R.id.nav_exit:
|
||||||
break;
|
log.debug("Exiting");
|
||||||
case R.id.nav_about:
|
MainApp.instance().stopKeepAliveService();
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext());
|
MainApp.bus().post(new EventAppExit());
|
||||||
builder.setTitle(getString(R.string.app_name) + " " + BuildConfig.VERSION);
|
MainApp.closeDbHelper();
|
||||||
if (Config.NSCLIENT|| Config.G5UPLOADER)
|
finish();
|
||||||
builder.setIcon(R.mipmap.yellowowl);
|
System.runFinalization();
|
||||||
else
|
System.exit(0);
|
||||||
builder.setIcon(R.mipmap.blueowl);
|
return true;
|
||||||
String message = "Build: " + BuildConfig.BUILDVERSION + "\n";
|
case R.id.nav_plugin_preferences:
|
||||||
message += MainApp.sResources.getString(R.string.configbuilder_nightscoutversion_label) + " " + ConfigBuilderPlugin.nightscoutVersionName;
|
ViewPager viewPager = findViewById(R.id.pager);
|
||||||
builder.setMessage(message);
|
final PluginBase plugin = ((TabPageAdapter) viewPager.getAdapter()).getPluginAt(viewPager.getCurrentItem());
|
||||||
builder.setPositiveButton(MainApp.sResources.getString(R.string.ok), null);
|
PasswordProtection.QueryPassword(this, R.string.settings_password, "settings_password", () -> {
|
||||||
AlertDialog alertDialog = builder.create();
|
Intent i = new Intent(this, PreferencesActivity.class);
|
||||||
alertDialog.show();
|
i.putExtra("id", plugin.getPreferencesId());
|
||||||
break;
|
startActivity(i);
|
||||||
case R.id.nav_exit:
|
}, null);
|
||||||
log.debug("Exiting");
|
return true;
|
||||||
MainApp.instance().stopKeepAliveService();
|
|
||||||
MainApp.bus().post(new EventAppExit());
|
|
||||||
MainApp.closeDbHelper();
|
|
||||||
finish();
|
|
||||||
System.runFinalization();
|
|
||||||
System.exit(0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
popup.show();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
return actionBarDrawerToggle.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,11 +5,11 @@ 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.Nullable;
|
||||||
|
import android.support.annotation.PluralsRes;
|
||||||
import android.support.v4.content.LocalBroadcastManager;
|
import android.support.v4.content.LocalBroadcastManager;
|
||||||
|
|
||||||
import com.crashlytics.android.Crashlytics;
|
import com.crashlytics.android.Crashlytics;
|
||||||
import com.crashlytics.android.answers.Answers;
|
import com.crashlytics.android.answers.Answers;
|
||||||
import com.crashlytics.android.answers.CustomEvent;
|
|
||||||
import com.j256.ormlite.android.apptools.OpenHelperManager;
|
import com.j256.ormlite.android.apptools.OpenHelperManager;
|
||||||
import com.squareup.otto.Bus;
|
import com.squareup.otto.Bus;
|
||||||
import com.squareup.otto.LoggingBus;
|
import com.squareup.otto.LoggingBus;
|
||||||
|
@ -20,63 +20,72 @@ import net.danlew.android.joda.JodaTimeAndroid;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import info.nightscout.androidaps.Services.Intents;
|
import info.nightscout.androidaps.data.ConstraintChecker;
|
||||||
import info.nightscout.androidaps.db.DatabaseHelper;
|
import info.nightscout.androidaps.db.DatabaseHelper;
|
||||||
import info.nightscout.androidaps.interfaces.InsulinInterface;
|
|
||||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||||
|
import info.nightscout.androidaps.interfaces.PluginType;
|
||||||
|
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||||
|
import info.nightscout.androidaps.logging.L;
|
||||||
import info.nightscout.androidaps.plugins.Actions.ActionsFragment;
|
import info.nightscout.androidaps.plugins.Actions.ActionsFragment;
|
||||||
import info.nightscout.androidaps.plugins.Careportal.CareportalPlugin;
|
import info.nightscout.androidaps.plugins.Careportal.CareportalPlugin;
|
||||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderFragment;
|
|
||||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||||
import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin;
|
import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin;
|
||||||
import info.nightscout.androidaps.plugins.ConstraintsSafety.SafetyPlugin;
|
import info.nightscout.androidaps.plugins.ConstraintsSafety.SafetyPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Food.FoodPlugin;
|
import info.nightscout.androidaps.plugins.Food.FoodPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Insulin.InsulinFastactingPlugin;
|
|
||||||
import info.nightscout.androidaps.plugins.Insulin.InsulinFastactingProlongedPlugin;
|
|
||||||
import info.nightscout.androidaps.plugins.Insulin.InsulinOrefFreePeakPlugin;
|
import info.nightscout.androidaps.plugins.Insulin.InsulinOrefFreePeakPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Insulin.InsulinOrefRapidActingPlugin;
|
import info.nightscout.androidaps.plugins.Insulin.InsulinOrefRapidActingPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Insulin.InsulinOrefUltraRapidActingPlugin;
|
import info.nightscout.androidaps.plugins.Insulin.InsulinOrefUltraRapidActingPlugin;
|
||||||
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
|
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.Maintenance.MaintenancePlugin;
|
||||||
import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
|
import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
|
||||||
import info.nightscout.androidaps.plugins.NSClientInternal.NSClientInternalPlugin;
|
import info.nightscout.androidaps.plugins.NSClientInternal.NSClientPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload;
|
||||||
import info.nightscout.androidaps.plugins.NSClientInternal.receivers.AckAlarmReceiver;
|
import info.nightscout.androidaps.plugins.NSClientInternal.receivers.AckAlarmReceiver;
|
||||||
|
import info.nightscout.androidaps.plugins.NSClientInternal.receivers.DBAccessReceiver;
|
||||||
import info.nightscout.androidaps.plugins.OpenAPSAMA.OpenAPSAMAPlugin;
|
import info.nightscout.androidaps.plugins.OpenAPSAMA.OpenAPSAMAPlugin;
|
||||||
import info.nightscout.androidaps.plugins.OpenAPSMA.OpenAPSMAPlugin;
|
import info.nightscout.androidaps.plugins.OpenAPSMA.OpenAPSMAPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.OpenAPSSMB.OpenAPSSMBPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Overview.OverviewPlugin;
|
import info.nightscout.androidaps.plugins.Overview.OverviewPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Persistentnotification.PersistentNotificationPlugin;
|
import info.nightscout.androidaps.plugins.Persistentnotification.PersistentNotificationPlugin;
|
||||||
import info.nightscout.androidaps.plugins.ProfileCircadianPercentage.CircadianPercentageProfileFragment;
|
|
||||||
import info.nightscout.androidaps.plugins.ProfileLocal.LocalProfilePlugin;
|
import info.nightscout.androidaps.plugins.ProfileLocal.LocalProfilePlugin;
|
||||||
import info.nightscout.androidaps.plugins.ProfileNS.NSProfilePlugin;
|
import info.nightscout.androidaps.plugins.ProfileNS.NSProfilePlugin;
|
||||||
import info.nightscout.androidaps.plugins.ProfileSimple.SimpleProfilePlugin;
|
import info.nightscout.androidaps.plugins.ProfileSimple.SimpleProfilePlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.PumpCombo.ComboPlugin;
|
||||||
import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPlugin;
|
import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPlugin;
|
||||||
import info.nightscout.androidaps.plugins.PumpDanaRKorean.DanaRKoreanPlugin;
|
import info.nightscout.androidaps.plugins.PumpDanaRKorean.DanaRKoreanPlugin;
|
||||||
import info.nightscout.androidaps.plugins.PumpDanaRS.DanaRSPlugin;
|
import info.nightscout.androidaps.plugins.PumpDanaRS.DanaRSPlugin;
|
||||||
import info.nightscout.androidaps.plugins.PumpDanaRv2.DanaRv2Plugin;
|
import info.nightscout.androidaps.plugins.PumpDanaRv2.DanaRv2Plugin;
|
||||||
|
import info.nightscout.androidaps.plugins.PumpInsight.InsightPlugin;
|
||||||
import info.nightscout.androidaps.plugins.PumpMDI.MDIPlugin;
|
import info.nightscout.androidaps.plugins.PumpMDI.MDIPlugin;
|
||||||
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
|
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
|
||||||
import info.nightscout.androidaps.plugins.SensitivityAAPS.SensitivityAAPSPlugin;
|
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityAAPSPlugin;
|
||||||
import info.nightscout.androidaps.plugins.SensitivityOref0.SensitivityOref0Plugin;
|
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityOref0Plugin;
|
||||||
import info.nightscout.androidaps.plugins.SensitivityWeightedAverage.SensitivityWeightedAveragePlugin;
|
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityOref1Plugin;
|
||||||
|
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityWeightedAveragePlugin;
|
||||||
import info.nightscout.androidaps.plugins.SmsCommunicator.SmsCommunicatorPlugin;
|
import info.nightscout.androidaps.plugins.SmsCommunicator.SmsCommunicatorPlugin;
|
||||||
import info.nightscout.androidaps.plugins.SourceDexcomG5.SourceDexcomG5Plugin;
|
import info.nightscout.androidaps.plugins.Source.SourceDexcomG5Plugin;
|
||||||
import info.nightscout.androidaps.plugins.SourceGlimp.SourceGlimpPlugin;
|
import info.nightscout.androidaps.plugins.Source.SourceGlimpPlugin;
|
||||||
import info.nightscout.androidaps.plugins.SourceMM640g.SourceMM640gPlugin;
|
import info.nightscout.androidaps.plugins.Source.SourceMM640gPlugin;
|
||||||
import info.nightscout.androidaps.plugins.SourceNSClient.SourceNSClientPlugin;
|
import info.nightscout.androidaps.plugins.Source.SourceNSClientPlugin;
|
||||||
import info.nightscout.androidaps.plugins.SourceXdrip.SourceXdripPlugin;
|
import info.nightscout.androidaps.plugins.Source.SourcePoctechPlugin;
|
||||||
|
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.Wear.WearPlugin;
|
import info.nightscout.androidaps.plugins.Wear.WearPlugin;
|
||||||
import info.nightscout.androidaps.plugins.XDripStatusline.StatuslinePlugin;
|
import info.nightscout.androidaps.plugins.XDripStatusline.StatuslinePlugin;
|
||||||
import info.nightscout.androidaps.receivers.DataReceiver;
|
import info.nightscout.androidaps.receivers.DataReceiver;
|
||||||
import info.nightscout.androidaps.receivers.KeepAliveReceiver;
|
import info.nightscout.androidaps.receivers.KeepAliveReceiver;
|
||||||
import info.nightscout.androidaps.receivers.NSAlarmReceiver;
|
import info.nightscout.androidaps.receivers.NSAlarmReceiver;
|
||||||
import info.nightscout.utils.NSUpload;
|
import info.nightscout.androidaps.services.Intents;
|
||||||
|
import info.nightscout.utils.FabricPrivacy;
|
||||||
|
import info.nightscout.androidaps.plugins.Maintenance.LoggerUtils;
|
||||||
import io.fabric.sdk.android.Fabric;
|
import io.fabric.sdk.android.Fabric;
|
||||||
|
|
||||||
|
|
||||||
public class MainApp extends Application {
|
public class MainApp extends Application {
|
||||||
private static Logger log = LoggerFactory.getLogger(MainApp.class);
|
private static Logger log = LoggerFactory.getLogger(L.CORE);
|
||||||
private static KeepAliveReceiver keepAliveReceiver;
|
private static KeepAliveReceiver keepAliveReceiver;
|
||||||
|
|
||||||
private static Bus sBus;
|
private static Bus sBus;
|
||||||
|
@ -84,29 +93,50 @@ public class MainApp extends Application {
|
||||||
public static Resources sResources;
|
public static Resources sResources;
|
||||||
|
|
||||||
private static DatabaseHelper sDatabaseHelper = null;
|
private static DatabaseHelper sDatabaseHelper = null;
|
||||||
private static ConfigBuilderPlugin sConfigBuilder = null;
|
private static ConstraintChecker sConstraintsChecker = null;
|
||||||
|
|
||||||
private static ArrayList<PluginBase> pluginsList = null;
|
private static ArrayList<PluginBase> pluginsList = null;
|
||||||
|
|
||||||
private static DataReceiver dataReceiver = new DataReceiver();
|
private static DataReceiver dataReceiver = new DataReceiver();
|
||||||
private static NSAlarmReceiver alarmReciever = new NSAlarmReceiver();
|
private static NSAlarmReceiver alarmReciever = new NSAlarmReceiver();
|
||||||
private static AckAlarmReceiver ackAlarmReciever = new AckAlarmReceiver();
|
private static AckAlarmReceiver ackAlarmReciever = new AckAlarmReceiver();
|
||||||
|
private static DBAccessReceiver dbAccessReciever = new DBAccessReceiver();
|
||||||
private LocalBroadcastManager lbm;
|
private LocalBroadcastManager lbm;
|
||||||
|
|
||||||
|
public static boolean devBranch;
|
||||||
|
public static boolean engineeringMode;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
Fabric.with(this, new Crashlytics());
|
log.debug("onCreate");
|
||||||
Fabric.with(this, new Answers());
|
sInstance = this;
|
||||||
|
sResources = getResources();
|
||||||
|
sConstraintsChecker = new ConstraintChecker(this);
|
||||||
|
sDatabaseHelper = OpenHelperManager.getHelper(sInstance, DatabaseHelper.class);
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (FabricPrivacy.fabricEnabled()) {
|
||||||
|
Fabric.with(this, new Crashlytics());
|
||||||
|
Fabric.with(this, new Answers());
|
||||||
|
Crashlytics.setString("BUILDVERSION", BuildConfig.BUILDVERSION);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Error with Fabric init! " + e);
|
||||||
|
}
|
||||||
|
|
||||||
JodaTimeAndroid.init(this);
|
JodaTimeAndroid.init(this);
|
||||||
Crashlytics.setString("BUILDVERSION", BuildConfig.BUILDVERSION);
|
|
||||||
log.info("Version: " + BuildConfig.VERSION_NAME);
|
log.info("Version: " + BuildConfig.VERSION_NAME);
|
||||||
log.info("BuildVersion: " + BuildConfig.BUILDVERSION);
|
log.info("BuildVersion: " + BuildConfig.BUILDVERSION);
|
||||||
|
|
||||||
sBus = Config.logEvents ? new LoggingBus(ThreadEnforcer.ANY) : new Bus(ThreadEnforcer.ANY);
|
String extFilesDir = LoggerUtils.getLogDirectory();
|
||||||
|
File engineeringModeSemaphore = new File(extFilesDir, "engineering_mode");
|
||||||
|
|
||||||
sInstance = this;
|
engineeringMode = engineeringModeSemaphore.exists() && engineeringModeSemaphore.isFile();
|
||||||
sResources = getResources();
|
devBranch = BuildConfig.VERSION.contains("dev");
|
||||||
|
|
||||||
|
sBus = L.isEnabled(L.EVENTS) && devBranch ? new LoggingBus(ThreadEnforcer.ANY) : new Bus(ThreadEnforcer.ANY);
|
||||||
|
|
||||||
registerLocalBroadcastReceiver();
|
registerLocalBroadcastReceiver();
|
||||||
|
|
||||||
|
@ -116,75 +146,63 @@ public class MainApp extends Application {
|
||||||
pluginsList.add(OverviewPlugin.getPlugin());
|
pluginsList.add(OverviewPlugin.getPlugin());
|
||||||
pluginsList.add(IobCobCalculatorPlugin.getPlugin());
|
pluginsList.add(IobCobCalculatorPlugin.getPlugin());
|
||||||
if (Config.ACTION) pluginsList.add(ActionsFragment.getPlugin());
|
if (Config.ACTION) pluginsList.add(ActionsFragment.getPlugin());
|
||||||
pluginsList.add(InsulinFastactingPlugin.getPlugin());
|
|
||||||
pluginsList.add(InsulinFastactingProlongedPlugin.getPlugin());
|
|
||||||
pluginsList.add(InsulinOrefRapidActingPlugin.getPlugin());
|
pluginsList.add(InsulinOrefRapidActingPlugin.getPlugin());
|
||||||
pluginsList.add(InsulinOrefUltraRapidActingPlugin.getPlugin());
|
pluginsList.add(InsulinOrefUltraRapidActingPlugin.getPlugin());
|
||||||
pluginsList.add(InsulinOrefFreePeakPlugin.getPlugin());
|
pluginsList.add(InsulinOrefFreePeakPlugin.getPlugin());
|
||||||
pluginsList.add(SensitivityOref0Plugin.getPlugin());
|
pluginsList.add(SensitivityOref0Plugin.getPlugin());
|
||||||
pluginsList.add(SensitivityAAPSPlugin.getPlugin());
|
pluginsList.add(SensitivityAAPSPlugin.getPlugin());
|
||||||
pluginsList.add(SensitivityWeightedAveragePlugin.getPlugin());
|
pluginsList.add(SensitivityWeightedAveragePlugin.getPlugin());
|
||||||
if (Config.DANAR) pluginsList.add(DanaRPlugin.getPlugin());
|
pluginsList.add(SensitivityOref1Plugin.getPlugin());
|
||||||
if (Config.DANAR) pluginsList.add(DanaRKoreanPlugin.getPlugin());
|
if (Config.PUMPDRIVERS) pluginsList.add(DanaRPlugin.getPlugin());
|
||||||
if (Config.DANAR) pluginsList.add(DanaRv2Plugin.getPlugin());
|
if (Config.PUMPDRIVERS) pluginsList.add(DanaRKoreanPlugin.getPlugin());
|
||||||
if (Config.DANAR) pluginsList.add(DanaRSPlugin.getPlugin());
|
if (Config.PUMPDRIVERS) pluginsList.add(DanaRv2Plugin.getPlugin());
|
||||||
|
if (Config.PUMPDRIVERS) pluginsList.add(DanaRSPlugin.getPlugin());
|
||||||
pluginsList.add(CareportalPlugin.getPlugin());
|
pluginsList.add(CareportalPlugin.getPlugin());
|
||||||
|
if (Config.PUMPDRIVERS && engineeringMode)
|
||||||
|
pluginsList.add(InsightPlugin.getPlugin()); // <-- Enable Insight plugin here
|
||||||
|
if (Config.PUMPDRIVERS) pluginsList.add(ComboPlugin.getPlugin());
|
||||||
if (Config.MDI) pluginsList.add(MDIPlugin.getPlugin());
|
if (Config.MDI) pluginsList.add(MDIPlugin.getPlugin());
|
||||||
if (Config.VIRTUALPUMP) pluginsList.add(VirtualPumpPlugin.getPlugin());
|
pluginsList.add(VirtualPumpPlugin.getPlugin());
|
||||||
if (Config.APS) pluginsList.add(LoopPlugin.getPlugin());
|
if (Config.APS) pluginsList.add(LoopPlugin.getPlugin());
|
||||||
if (Config.APS) pluginsList.add(OpenAPSMAPlugin.getPlugin());
|
if (Config.APS) pluginsList.add(OpenAPSMAPlugin.getPlugin());
|
||||||
if (Config.APS) pluginsList.add(OpenAPSAMAPlugin.getPlugin());
|
if (Config.APS) pluginsList.add(OpenAPSAMAPlugin.getPlugin());
|
||||||
|
if (Config.APS) pluginsList.add(OpenAPSSMBPlugin.getPlugin());
|
||||||
pluginsList.add(NSProfilePlugin.getPlugin());
|
pluginsList.add(NSProfilePlugin.getPlugin());
|
||||||
if (Config.OTHERPROFILES) pluginsList.add(SimpleProfilePlugin.getPlugin());
|
if (Config.OTHERPROFILES) pluginsList.add(SimpleProfilePlugin.getPlugin());
|
||||||
if (Config.OTHERPROFILES) pluginsList.add(LocalProfilePlugin.getPlugin());
|
if (Config.OTHERPROFILES) pluginsList.add(LocalProfilePlugin.getPlugin());
|
||||||
if (Config.OTHERPROFILES)
|
|
||||||
pluginsList.add(CircadianPercentageProfileFragment.getPlugin());
|
|
||||||
pluginsList.add(TreatmentsPlugin.getPlugin());
|
pluginsList.add(TreatmentsPlugin.getPlugin());
|
||||||
if (Config.SAFETY) pluginsList.add(SafetyPlugin.getPlugin());
|
if (Config.SAFETY) pluginsList.add(SafetyPlugin.getPlugin());
|
||||||
if (Config.APS) pluginsList.add(ObjectivesPlugin.getPlugin());
|
if (Config.APS) pluginsList.add(ObjectivesPlugin.getPlugin());
|
||||||
if (!Config.NSCLIENT && !Config.G5UPLOADER)
|
pluginsList.add(SourceXdripPlugin.getPlugin());
|
||||||
pluginsList.add(SourceXdripPlugin.getPlugin());
|
pluginsList.add(SourceNSClientPlugin.getPlugin());
|
||||||
if (!Config.G5UPLOADER)
|
pluginsList.add(SourceMM640gPlugin.getPlugin());
|
||||||
pluginsList.add(SourceNSClientPlugin.getPlugin());
|
pluginsList.add(SourceGlimpPlugin.getPlugin());
|
||||||
if (!Config.NSCLIENT && !Config.G5UPLOADER)
|
pluginsList.add(SourceDexcomG5Plugin.getPlugin());
|
||||||
pluginsList.add(SourceMM640gPlugin.getPlugin());
|
pluginsList.add(SourcePoctechPlugin.getPlugin());
|
||||||
if (!Config.NSCLIENT && !Config.G5UPLOADER)
|
|
||||||
pluginsList.add(SourceGlimpPlugin.getPlugin());
|
|
||||||
if (!Config.NSCLIENT)
|
|
||||||
pluginsList.add(SourceDexcomG5Plugin.getPlugin());
|
|
||||||
if (Config.SMSCOMMUNICATORENABLED) pluginsList.add(SmsCommunicatorPlugin.getPlugin());
|
if (Config.SMSCOMMUNICATORENABLED) pluginsList.add(SmsCommunicatorPlugin.getPlugin());
|
||||||
pluginsList.add(FoodPlugin.getPlugin());
|
pluginsList.add(FoodPlugin.getPlugin());
|
||||||
|
|
||||||
pluginsList.add(WearPlugin.initPlugin(this));
|
pluginsList.add(WearPlugin.initPlugin(this));
|
||||||
pluginsList.add(StatuslinePlugin.initPlugin(this));
|
pluginsList.add(StatuslinePlugin.initPlugin(this));
|
||||||
pluginsList.add(new PersistentNotificationPlugin(this));
|
pluginsList.add(PersistentNotificationPlugin.getPlugin());
|
||||||
pluginsList.add(NSClientInternalPlugin.getPlugin());
|
pluginsList.add(NSClientPlugin.getPlugin());
|
||||||
|
pluginsList.add(MaintenancePlugin.initPlugin(this));
|
||||||
|
|
||||||
pluginsList.add(sConfigBuilder = ConfigBuilderFragment.getPlugin());
|
pluginsList.add(ConfigBuilderPlugin.getPlugin());
|
||||||
|
|
||||||
MainApp.getConfigBuilder().initialize();
|
ConfigBuilderPlugin.getPlugin().initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
NSUpload.uploadAppStart();
|
NSUpload.uploadAppStart();
|
||||||
if (Config.NSCLIENT)
|
|
||||||
Answers.getInstance().logCustom(new CustomEvent("AppStart-NSClient"));
|
|
||||||
else if (Config.G5UPLOADER)
|
|
||||||
Answers.getInstance().logCustom(new CustomEvent("AppStart-G5Uploader"));
|
|
||||||
else if (Config.PUMPCONTROL)
|
|
||||||
Answers.getInstance().logCustom(new CustomEvent("AppStart-PumpControl"));
|
|
||||||
else if (MainApp.getConfigBuilder().isClosedModeEnabled())
|
|
||||||
Answers.getInstance().logCustom(new CustomEvent("AppStart-ClosedLoop"));
|
|
||||||
else
|
|
||||||
Answers.getInstance().logCustom(new CustomEvent("AppStart-OpenLoop"));
|
|
||||||
|
|
||||||
new Thread(new Runnable() {
|
final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
|
||||||
@Override
|
if (pump != null) {
|
||||||
public void run() {
|
new Thread(() -> {
|
||||||
SystemClock.sleep(5000);
|
SystemClock.sleep(5000);
|
||||||
ConfigBuilderPlugin.getCommandQueue().readStatus("Initialization", null);
|
ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("Initialization", null);
|
||||||
startKeepAliveService();
|
startKeepAliveService();
|
||||||
}
|
}).start();
|
||||||
}).start();
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerLocalBroadcastReceiver() {
|
private void registerLocalBroadcastReceiver() {
|
||||||
|
@ -210,6 +228,9 @@ public class MainApp extends Application {
|
||||||
|
|
||||||
//register ack alarm
|
//register ack alarm
|
||||||
lbm.registerReceiver(ackAlarmReciever, new IntentFilter(Intents.ACTION_ACK_ALARM));
|
lbm.registerReceiver(ackAlarmReciever, new IntentFilter(Intents.ACTION_ACK_ALARM));
|
||||||
|
|
||||||
|
//register dbaccess
|
||||||
|
lbm.registerReceiver(dbAccessReciever, new IntentFilter(Intents.ACTION_DATABASE));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startKeepAliveService() {
|
private void startKeepAliveService() {
|
||||||
|
@ -219,12 +240,27 @@ public class MainApp extends Application {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void stopKeepAliveService() {
|
public void stopKeepAliveService() {
|
||||||
if (keepAliveReceiver != null)
|
if (keepAliveReceiver != null)
|
||||||
KeepAliveReceiver.cancelAlarm(this);
|
KeepAliveReceiver.cancelAlarm(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void subscribe(Object subscriber) {
|
||||||
|
try {
|
||||||
|
bus().register(subscriber);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
// already registered
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void unsubscribe(Object subscriber) {
|
||||||
|
try {
|
||||||
|
bus().unregister(subscriber);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
// already unregistered
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static Bus bus() {
|
public static Bus bus() {
|
||||||
return sBus;
|
return sBus;
|
||||||
}
|
}
|
||||||
|
@ -237,14 +273,19 @@ public class MainApp extends Application {
|
||||||
return sResources.getString(id, args);
|
return sResources.getString(id, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String gq(@PluralsRes int id, int quantity, Object... args) {
|
||||||
|
return sResources.getQuantityString(id, quantity, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int gc(int id) {
|
||||||
|
return sResources.getColor(id);
|
||||||
|
}
|
||||||
|
|
||||||
public static MainApp instance() {
|
public static MainApp instance() {
|
||||||
return sInstance;
|
return sInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DatabaseHelper getDbHelper() {
|
public static DatabaseHelper getDbHelper() {
|
||||||
if (sDatabaseHelper == null) {
|
|
||||||
sDatabaseHelper = OpenHelperManager.getHelper(sInstance, DatabaseHelper.class);
|
|
||||||
}
|
|
||||||
return sDatabaseHelper;
|
return sDatabaseHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,15 +296,15 @@ public class MainApp extends Application {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ConfigBuilderPlugin getConfigBuilder() {
|
public static ConstraintChecker getConstraintChecker() {
|
||||||
return sConfigBuilder;
|
return sConstraintsChecker;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ArrayList<PluginBase> getPluginsList() {
|
public static ArrayList<PluginBase> getPluginsList() {
|
||||||
return pluginsList;
|
return pluginsList;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ArrayList<PluginBase> getSpecificPluginsList(int type) {
|
public static ArrayList<PluginBase> getSpecificPluginsList(PluginType type) {
|
||||||
ArrayList<PluginBase> newList = new ArrayList<>();
|
ArrayList<PluginBase> newList = new ArrayList<>();
|
||||||
|
|
||||||
if (pluginsList != null) {
|
if (pluginsList != null) {
|
||||||
|
@ -277,20 +318,7 @@ public class MainApp extends Application {
|
||||||
return newList;
|
return newList;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
public static ArrayList<PluginBase> getSpecificPluginsVisibleInList(PluginType type) {
|
||||||
public static InsulinInterface getInsulinIterfaceById(int id) {
|
|
||||||
if (pluginsList != null) {
|
|
||||||
for (PluginBase p : pluginsList) {
|
|
||||||
if (p.getType() == PluginBase.INSULIN && ((InsulinInterface) p).getId() == id)
|
|
||||||
return (InsulinInterface) p;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.error("InsulinInterface not found");
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ArrayList<PluginBase> getSpecificPluginsVisibleInList(int type) {
|
|
||||||
ArrayList<PluginBase> newList = new ArrayList<>();
|
ArrayList<PluginBase> newList = new ArrayList<>();
|
||||||
|
|
||||||
if (pluginsList != null) {
|
if (pluginsList != null) {
|
||||||
|
@ -319,7 +347,7 @@ public class MainApp extends Application {
|
||||||
return newList;
|
return newList;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ArrayList<PluginBase> getSpecificPluginsVisibleInListByInterface(Class interfaceClass, int type) {
|
public static ArrayList<PluginBase> getSpecificPluginsVisibleInListByInterface(Class interfaceClass, PluginType type) {
|
||||||
ArrayList<PluginBase> newList = new ArrayList<>();
|
ArrayList<PluginBase> newList = new ArrayList<>();
|
||||||
|
|
||||||
if (pluginsList != null) {
|
if (pluginsList != null) {
|
||||||
|
@ -347,9 +375,24 @@ public class MainApp extends Application {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isEngineeringModeOrRelease() {
|
||||||
|
if (!Config.APS)
|
||||||
|
return true;
|
||||||
|
return engineeringMode || !devBranch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isDev() {
|
||||||
|
return devBranch;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTerminate() {
|
public void onTerminate() {
|
||||||
|
if (L.isEnabled(L.CORE))
|
||||||
|
log.debug("onTerminate");
|
||||||
super.onTerminate();
|
super.onTerminate();
|
||||||
sDatabaseHelper.close();
|
if (sDatabaseHelper != null) {
|
||||||
|
sDatabaseHelper.close();
|
||||||
|
sDatabaseHelper = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,622 +0,0 @@
|
||||||
package info.nightscout.androidaps.Services;
|
|
||||||
|
|
||||||
import android.app.IntentService;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.provider.Telephony;
|
|
||||||
|
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONException;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.Config;
|
|
||||||
import info.nightscout.androidaps.MainApp;
|
|
||||||
import info.nightscout.androidaps.R;
|
|
||||||
import info.nightscout.androidaps.data.ProfileStore;
|
|
||||||
import info.nightscout.androidaps.db.BgReading;
|
|
||||||
import info.nightscout.androidaps.db.CareportalEvent;
|
|
||||||
import info.nightscout.androidaps.events.EventNewBasalProfile;
|
|
||||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
|
||||||
import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin;
|
|
||||||
import info.nightscout.androidaps.plugins.NSClientInternal.data.NSDeviceStatus;
|
|
||||||
import info.nightscout.androidaps.plugins.NSClientInternal.data.NSMbg;
|
|
||||||
import info.nightscout.androidaps.plugins.NSClientInternal.data.NSSettingsStatus;
|
|
||||||
import info.nightscout.androidaps.plugins.NSClientInternal.data.NSSgv;
|
|
||||||
import info.nightscout.androidaps.plugins.Overview.OverviewPlugin;
|
|
||||||
import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification;
|
|
||||||
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
|
|
||||||
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
|
|
||||||
import info.nightscout.androidaps.plugins.ProfileNS.NSProfilePlugin;
|
|
||||||
import info.nightscout.androidaps.plugins.ProfileNS.events.EventNSProfileUpdateGUI;
|
|
||||||
import info.nightscout.androidaps.plugins.PumpDanaR.activities.DanaRNSHistorySync;
|
|
||||||
import info.nightscout.androidaps.plugins.SmsCommunicator.events.EventNewSMS;
|
|
||||||
import info.nightscout.androidaps.plugins.SourceDexcomG5.SourceDexcomG5Plugin;
|
|
||||||
import info.nightscout.androidaps.plugins.SourceGlimp.SourceGlimpPlugin;
|
|
||||||
import info.nightscout.androidaps.plugins.SourceMM640g.SourceMM640gPlugin;
|
|
||||||
import info.nightscout.androidaps.plugins.SourceNSClient.SourceNSClientPlugin;
|
|
||||||
import info.nightscout.androidaps.plugins.SourceXdrip.SourceXdripPlugin;
|
|
||||||
import info.nightscout.androidaps.receivers.DataReceiver;
|
|
||||||
import info.nightscout.utils.BundleLogger;
|
|
||||||
import info.nightscout.utils.NSUpload;
|
|
||||||
import info.nightscout.utils.SP;
|
|
||||||
|
|
||||||
|
|
||||||
public class DataService extends IntentService {
|
|
||||||
private static Logger log = LoggerFactory.getLogger(DataService.class);
|
|
||||||
|
|
||||||
boolean xDripEnabled = false;
|
|
||||||
boolean nsClientEnabled = true;
|
|
||||||
boolean mm640gEnabled = false;
|
|
||||||
boolean glimpEnabled = false;
|
|
||||||
boolean dexcomG5Enabled = false;
|
|
||||||
|
|
||||||
public DataService() {
|
|
||||||
super("DataService");
|
|
||||||
registerBus();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onHandleIntent(final Intent intent) {
|
|
||||||
if (Config.logFunctionCalls)
|
|
||||||
log.debug("onHandleIntent " + BundleLogger.log(intent.getExtras()));
|
|
||||||
|
|
||||||
if (ConfigBuilderPlugin.getActiveBgSource().getClass().equals(SourceXdripPlugin.class)) {
|
|
||||||
xDripEnabled = true;
|
|
||||||
nsClientEnabled = false;
|
|
||||||
mm640gEnabled = false;
|
|
||||||
glimpEnabled = false;
|
|
||||||
dexcomG5Enabled = false;
|
|
||||||
} else if (ConfigBuilderPlugin.getActiveBgSource().getClass().equals(SourceNSClientPlugin.class)) {
|
|
||||||
xDripEnabled = false;
|
|
||||||
nsClientEnabled = true;
|
|
||||||
mm640gEnabled = false;
|
|
||||||
glimpEnabled = false;
|
|
||||||
dexcomG5Enabled = false;
|
|
||||||
} else if (ConfigBuilderPlugin.getActiveBgSource().getClass().equals(SourceMM640gPlugin.class)) {
|
|
||||||
xDripEnabled = false;
|
|
||||||
nsClientEnabled = false;
|
|
||||||
mm640gEnabled = true;
|
|
||||||
glimpEnabled = false;
|
|
||||||
dexcomG5Enabled = false;
|
|
||||||
} else if (ConfigBuilderPlugin.getActiveBgSource().getClass().equals(SourceGlimpPlugin.class)) {
|
|
||||||
xDripEnabled = false;
|
|
||||||
nsClientEnabled = false;
|
|
||||||
mm640gEnabled = false;
|
|
||||||
glimpEnabled = true;
|
|
||||||
dexcomG5Enabled = false;
|
|
||||||
} else if (ConfigBuilderPlugin.getActiveBgSource().getClass().equals(SourceDexcomG5Plugin.class)) {
|
|
||||||
xDripEnabled = false;
|
|
||||||
nsClientEnabled = false;
|
|
||||||
mm640gEnabled = false;
|
|
||||||
glimpEnabled = false;
|
|
||||||
dexcomG5Enabled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean isNSProfile = ConfigBuilderPlugin.getActiveProfileInterface().getClass().equals(NSProfilePlugin.class);
|
|
||||||
|
|
||||||
boolean acceptNSData = !SP.getBoolean(R.string.key_ns_upload_only, false);
|
|
||||||
Bundle bundles = intent.getExtras();
|
|
||||||
if (bundles != null && bundles.containsKey("islocal")) {
|
|
||||||
acceptNSData = acceptNSData || bundles.getBoolean("islocal");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (intent != null) {
|
|
||||||
final String action = intent.getAction();
|
|
||||||
if (Intents.ACTION_NEW_BG_ESTIMATE.equals(action)) {
|
|
||||||
if (xDripEnabled) {
|
|
||||||
handleNewDataFromXDrip(intent);
|
|
||||||
}
|
|
||||||
} else if (Intents.NS_EMULATOR.equals(action)) {
|
|
||||||
if (mm640gEnabled) {
|
|
||||||
handleNewDataFromMM640g(intent);
|
|
||||||
}
|
|
||||||
} else if (Intents.GLIMP_BG.equals(action)) {
|
|
||||||
if (glimpEnabled) {
|
|
||||||
handleNewDataFromGlimp(intent);
|
|
||||||
}
|
|
||||||
} else if (Intents.DEXCOMG5_BG.equals(action)) {
|
|
||||||
if (dexcomG5Enabled) {
|
|
||||||
handleNewDataFromDexcomG5(intent);
|
|
||||||
}
|
|
||||||
} else if (Intents.ACTION_NEW_SGV.equals(action)) {
|
|
||||||
// always backfill SGV from NS
|
|
||||||
handleNewDataFromNSClient(intent);
|
|
||||||
// Objectives 0
|
|
||||||
ObjectivesPlugin.bgIsAvailableInNS = true;
|
|
||||||
ObjectivesPlugin.saveProgress();
|
|
||||||
} else if (isNSProfile && Intents.ACTION_NEW_PROFILE.equals(action) || Intents.ACTION_NEW_DEVICESTATUS.equals(action)) {
|
|
||||||
// always handle Profile if NSProfile is enabled without looking at nsUploadOnly
|
|
||||||
handleNewDataFromNSClient(intent);
|
|
||||||
} else if (acceptNSData &&
|
|
||||||
(Intents.ACTION_NEW_TREATMENT.equals(action) ||
|
|
||||||
Intents.ACTION_CHANGED_TREATMENT.equals(action) ||
|
|
||||||
Intents.ACTION_REMOVED_TREATMENT.equals(action) ||
|
|
||||||
Intents.ACTION_NEW_STATUS.equals(action) ||
|
|
||||||
Intents.ACTION_NEW_DEVICESTATUS.equals(action) ||
|
|
||||||
Intents.ACTION_NEW_FOOD.equals(action) ||
|
|
||||||
Intents.ACTION_CHANGED_FOOD.equals(action) ||
|
|
||||||
Intents.ACTION_REMOVED_FOOD.equals(action) ||
|
|
||||||
Intents.ACTION_NEW_CAL.equals(action) ||
|
|
||||||
Intents.ACTION_NEW_MBG.equals(action))
|
|
||||||
) {
|
|
||||||
handleNewDataFromNSClient(intent);
|
|
||||||
} else if (Telephony.Sms.Intents.SMS_RECEIVED_ACTION.equals(action)) {
|
|
||||||
handleNewSMS(intent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Config.logFunctionCalls)
|
|
||||||
log.debug("onHandleIntent exit " + intent);
|
|
||||||
DataReceiver.completeWakefulIntent(intent);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
@Override
|
|
||||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
|
||||||
super.onStartCommand(intent, flags, startId);
|
|
||||||
|
|
||||||
if (Config.logFunctionCalls)
|
|
||||||
log.debug("onStartCommand");
|
|
||||||
|
|
||||||
return START_STICKY;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDestroy() {
|
|
||||||
super.onDestroy();
|
|
||||||
MainApp.bus().unregister(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void registerBus() {
|
|
||||||
try {
|
|
||||||
MainApp.bus().unregister(this);
|
|
||||||
} catch (RuntimeException x) {
|
|
||||||
// Ignore
|
|
||||||
}
|
|
||||||
MainApp.bus().register(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleNewDataFromXDrip(Intent intent) {
|
|
||||||
Bundle bundle = intent.getExtras();
|
|
||||||
if (bundle == null) return;
|
|
||||||
|
|
||||||
BgReading bgReading = new BgReading();
|
|
||||||
|
|
||||||
bgReading.value = bundle.getDouble(Intents.EXTRA_BG_ESTIMATE);
|
|
||||||
bgReading.direction = bundle.getString(Intents.EXTRA_BG_SLOPE_NAME);
|
|
||||||
bgReading.date = bundle.getLong(Intents.EXTRA_TIMESTAMP);
|
|
||||||
bgReading.raw = bundle.getDouble(Intents.EXTRA_RAW);
|
|
||||||
|
|
||||||
MainApp.getDbHelper().createIfNotExists(bgReading, "XDRIP");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleNewDataFromGlimp(Intent intent) {
|
|
||||||
Bundle bundle = intent.getExtras();
|
|
||||||
if (bundle == null) return;
|
|
||||||
|
|
||||||
BgReading bgReading = new BgReading();
|
|
||||||
|
|
||||||
bgReading.value = bundle.getDouble("mySGV");
|
|
||||||
bgReading.direction = bundle.getString("myTrend");
|
|
||||||
bgReading.date = bundle.getLong("myTimestamp");
|
|
||||||
bgReading.raw = 0;
|
|
||||||
|
|
||||||
MainApp.getDbHelper().createIfNotExists(bgReading, "GLIMP");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleNewDataFromDexcomG5(Intent intent) {
|
|
||||||
// onHandleIntent Bundle{ data => [{"m_time":1511939180,"m_trend":"NotComputable","m_value":335}]; android.support.content.wakelockid => 95; }Bundle
|
|
||||||
|
|
||||||
Bundle bundle = intent.getExtras();
|
|
||||||
if (bundle == null) return;
|
|
||||||
|
|
||||||
BgReading bgReading = new BgReading();
|
|
||||||
|
|
||||||
String data = bundle.getString("data");
|
|
||||||
log.debug("Received Dexcom Data", data);
|
|
||||||
|
|
||||||
try {
|
|
||||||
JSONArray jsonArray = new JSONArray(data);
|
|
||||||
log.debug("Received Dexcom Data size:" + jsonArray.length());
|
|
||||||
for(int i = 0; i < jsonArray.length(); i++) {
|
|
||||||
JSONObject json = jsonArray.getJSONObject(i);
|
|
||||||
bgReading.value = json.getInt("m_value");
|
|
||||||
bgReading.direction = json.getString("m_trend");
|
|
||||||
bgReading.date = json.getLong("m_time") * 1000L;
|
|
||||||
bgReading.raw = 0;
|
|
||||||
boolean isNew = MainApp.getDbHelper().createIfNotExists(bgReading, "DexcomG5");
|
|
||||||
if (isNew && SP.getBoolean(R.string.key_dexcomg5_nsupload, false)) {
|
|
||||||
NSUpload.uploadBg(bgReading);
|
|
||||||
}
|
|
||||||
if (isNew && SP.getBoolean(R.string.key_dexcomg5_xdripupload, false)) {
|
|
||||||
NSUpload.sendToXdrip(bgReading);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (JSONException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleNewDataFromMM640g(Intent intent) {
|
|
||||||
Bundle bundle = intent.getExtras();
|
|
||||||
if (bundle == null) return;
|
|
||||||
|
|
||||||
final String collection = bundle.getString("collection");
|
|
||||||
if (collection == null) return;
|
|
||||||
|
|
||||||
if (collection.equals("entries")) {
|
|
||||||
final String data = bundle.getString("data");
|
|
||||||
|
|
||||||
if ((data != null) && (data.length() > 0)) {
|
|
||||||
try {
|
|
||||||
final JSONArray json_array = new JSONArray(data);
|
|
||||||
for (int i = 0; i < json_array.length(); i++) {
|
|
||||||
final JSONObject json_object = json_array.getJSONObject(i);
|
|
||||||
final String type = json_object.getString("type");
|
|
||||||
switch (type) {
|
|
||||||
case "sgv":
|
|
||||||
BgReading bgReading = new BgReading();
|
|
||||||
|
|
||||||
bgReading.value = json_object.getDouble("sgv");
|
|
||||||
bgReading.direction = json_object.getString("direction");
|
|
||||||
bgReading.date = json_object.getLong("date");
|
|
||||||
bgReading.raw = json_object.getDouble("sgv");
|
|
||||||
|
|
||||||
MainApp.getDbHelper().createIfNotExists(bgReading, "MM640g");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
log.debug("Unknown entries type: " + type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (JSONException e) {
|
|
||||||
log.error("Got JSON exception: " + e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleNewDataFromNSClient(Intent intent) {
|
|
||||||
Bundle bundles = intent.getExtras();
|
|
||||||
if (bundles == null) return;
|
|
||||||
if (Config.logIncommingData)
|
|
||||||
log.debug("Got intent: " + intent.getAction());
|
|
||||||
|
|
||||||
|
|
||||||
if (intent.getAction().equals(Intents.ACTION_NEW_STATUS)) {
|
|
||||||
if (bundles.containsKey("nsclientversioncode")) {
|
|
||||||
ConfigBuilderPlugin.nightscoutVersionCode = bundles.getInt("nightscoutversioncode"); // for ver 1.2.3 contains 10203
|
|
||||||
ConfigBuilderPlugin.nightscoutVersionName = bundles.getString("nightscoutversionname");
|
|
||||||
ConfigBuilderPlugin.nsClientVersionCode = bundles.getInt("nsclientversioncode"); // for ver 1.17 contains 117
|
|
||||||
ConfigBuilderPlugin.nsClientVersionName = bundles.getString("nsclientversionname");
|
|
||||||
log.debug("Got versions: NSClient: " + ConfigBuilderPlugin.nsClientVersionName + " Nightscout: " + ConfigBuilderPlugin.nightscoutVersionName);
|
|
||||||
try {
|
|
||||||
if (ConfigBuilderPlugin.nsClientVersionCode < MainApp.instance().getPackageManager().getPackageInfo(MainApp.instance().getPackageName(), 0).versionCode) {
|
|
||||||
Notification notification = new Notification(Notification.OLD_NSCLIENT, MainApp.sResources.getString(R.string.unsupportedclientver), Notification.URGENT);
|
|
||||||
MainApp.bus().post(new EventNewNotification(notification));
|
|
||||||
} else {
|
|
||||||
MainApp.bus().post(new EventDismissNotification(Notification.OLD_NSCLIENT));
|
|
||||||
}
|
|
||||||
} catch (PackageManager.NameNotFoundException e) {
|
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
if (ConfigBuilderPlugin.nightscoutVersionCode < Config.SUPPORTEDNSVERSION) {
|
|
||||||
Notification notification = new Notification(Notification.OLD_NS, MainApp.sResources.getString(R.string.unsupportednsversion), Notification.NORMAL);
|
|
||||||
MainApp.bus().post(new EventNewNotification(notification));
|
|
||||||
} else {
|
|
||||||
MainApp.bus().post(new EventDismissNotification(Notification.OLD_NS));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Notification notification = new Notification(Notification.OLD_NSCLIENT, MainApp.sResources.getString(R.string.unsupportedclientver), Notification.URGENT);
|
|
||||||
MainApp.bus().post(new EventNewNotification(notification));
|
|
||||||
}
|
|
||||||
if (bundles.containsKey("status")) {
|
|
||||||
try {
|
|
||||||
JSONObject statusJson = new JSONObject(bundles.getString("status"));
|
|
||||||
NSSettingsStatus.getInstance().setData(statusJson);
|
|
||||||
if (Config.logIncommingData)
|
|
||||||
log.debug("Received status: " + statusJson.toString());
|
|
||||||
Double targetHigh = NSSettingsStatus.getInstance().getThreshold("bgTargetTop");
|
|
||||||
Double targetlow = NSSettingsStatus.getInstance().getThreshold("bgTargetBottom");
|
|
||||||
if (targetHigh != null)
|
|
||||||
OverviewPlugin.bgTargetHigh = targetHigh;
|
|
||||||
if (targetlow != null)
|
|
||||||
OverviewPlugin.bgTargetLow = targetlow;
|
|
||||||
} catch (JSONException e) {
|
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (intent.getAction().equals(Intents.ACTION_NEW_DEVICESTATUS)) {
|
|
||||||
try {
|
|
||||||
if (bundles.containsKey("devicestatus")) {
|
|
||||||
JSONObject devicestatusJson = new JSONObject(bundles.getString("devicestatus"));
|
|
||||||
NSDeviceStatus.getInstance().setData(devicestatusJson);
|
|
||||||
if (devicestatusJson.has("pump")) {
|
|
||||||
// Objectives 0
|
|
||||||
ObjectivesPlugin.pumpStatusIsAvailableInNS = true;
|
|
||||||
ObjectivesPlugin.saveProgress();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (bundles.containsKey("devicestatuses")) {
|
|
||||||
String devicestatusesstring = bundles.getString("devicestatuses");
|
|
||||||
JSONArray jsonArray = new JSONArray(devicestatusesstring);
|
|
||||||
for (int i = 0; i < jsonArray.length(); i++) {
|
|
||||||
JSONObject devicestatusJson = jsonArray.getJSONObject(i);
|
|
||||||
NSDeviceStatus.getInstance().setData(devicestatusJson);
|
|
||||||
if (devicestatusJson.has("pump")) {
|
|
||||||
// Objectives 0
|
|
||||||
ObjectivesPlugin.pumpStatusIsAvailableInNS = true;
|
|
||||||
ObjectivesPlugin.saveProgress();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Handle profile
|
|
||||||
if (intent.getAction().equals(Intents.ACTION_NEW_PROFILE)) {
|
|
||||||
try {
|
|
||||||
String activeProfile = bundles.getString("activeprofile");
|
|
||||||
String profile = bundles.getString("profile");
|
|
||||||
ProfileStore profileStore = new ProfileStore(new JSONObject(profile));
|
|
||||||
NSProfilePlugin.storeNewProfile(profileStore);
|
|
||||||
MainApp.bus().post(new EventNSProfileUpdateGUI());
|
|
||||||
// if there are no profile switches this should lead to profile update
|
|
||||||
if (MainApp.getConfigBuilder().getProfileSwitchesFromHistory().size() == 0)
|
|
||||||
MainApp.bus().post(new EventNewBasalProfile());
|
|
||||||
if (Config.logIncommingData)
|
|
||||||
log.debug("Received profileStore: " + activeProfile + " " + profile);
|
|
||||||
} catch (JSONException e) {
|
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (intent.getAction().equals(Intents.ACTION_NEW_TREATMENT) || intent.getAction().equals(Intents.ACTION_CHANGED_TREATMENT)) {
|
|
||||||
try {
|
|
||||||
if (bundles.containsKey("treatment")) {
|
|
||||||
String trstring = bundles.getString("treatment");
|
|
||||||
handleAddChangeDataFromNS(trstring);
|
|
||||||
}
|
|
||||||
if (bundles.containsKey("treatments")) {
|
|
||||||
String trstring = bundles.getString("treatments");
|
|
||||||
JSONArray jsonArray = new JSONArray(trstring);
|
|
||||||
for (int i = 0; i < jsonArray.length(); i++) {
|
|
||||||
JSONObject trJson = jsonArray.getJSONObject(i);
|
|
||||||
String trstr = trJson.toString();
|
|
||||||
handleAddChangeDataFromNS(trstr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (intent.getAction().equals(Intents.ACTION_REMOVED_TREATMENT)) {
|
|
||||||
try {
|
|
||||||
if (bundles.containsKey("treatment")) {
|
|
||||||
String trstring = bundles.getString("treatment");
|
|
||||||
JSONObject trJson = new JSONObject(trstring);
|
|
||||||
String _id = trJson.getString("_id");
|
|
||||||
handleRemovedRecordFromNS(_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bundles.containsKey("treatments")) {
|
|
||||||
String trstring = bundles.getString("treatments");
|
|
||||||
JSONArray jsonArray = new JSONArray(trstring);
|
|
||||||
for (int i = 0; i < jsonArray.length(); i++) {
|
|
||||||
JSONObject trJson = jsonArray.getJSONObject(i);
|
|
||||||
String _id = trJson.getString("_id");
|
|
||||||
handleRemovedRecordFromNS(_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (intent.getAction().equals(Intents.ACTION_NEW_SGV)) {
|
|
||||||
try {
|
|
||||||
if (bundles.containsKey("sgv")) {
|
|
||||||
String sgvstring = bundles.getString("sgv");
|
|
||||||
JSONObject sgvJson = new JSONObject(sgvstring);
|
|
||||||
NSSgv nsSgv = new NSSgv(sgvJson);
|
|
||||||
BgReading bgReading = new BgReading(nsSgv);
|
|
||||||
MainApp.getDbHelper().createIfNotExists(bgReading, "NS");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bundles.containsKey("sgvs")) {
|
|
||||||
String sgvstring = bundles.getString("sgvs");
|
|
||||||
JSONArray jsonArray = new JSONArray(sgvstring);
|
|
||||||
for (int i = 0; i < jsonArray.length(); i++) {
|
|
||||||
JSONObject sgvJson = jsonArray.getJSONObject(i);
|
|
||||||
NSSgv nsSgv = new NSSgv(sgvJson);
|
|
||||||
BgReading bgReading = new BgReading(nsSgv);
|
|
||||||
MainApp.getDbHelper().createIfNotExists(bgReading, "NS");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (intent.getAction().equals(Intents.ACTION_NEW_MBG)) {
|
|
||||||
try {
|
|
||||||
if (bundles.containsKey("mbg")) {
|
|
||||||
String mbgstring = bundles.getString("mbg");
|
|
||||||
JSONObject mbgJson = new JSONObject(mbgstring);
|
|
||||||
NSMbg nsMbg = new NSMbg(mbgJson);
|
|
||||||
CareportalEvent careportalEvent = new CareportalEvent(nsMbg);
|
|
||||||
MainApp.getDbHelper().createOrUpdate(careportalEvent);
|
|
||||||
if (Config.logIncommingData)
|
|
||||||
log.debug("Adding/Updating new MBG: " + careportalEvent.log());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bundles.containsKey("mbgs")) {
|
|
||||||
String sgvstring = bundles.getString("mbgs");
|
|
||||||
JSONArray jsonArray = new JSONArray(sgvstring);
|
|
||||||
for (int i = 0; i < jsonArray.length(); i++) {
|
|
||||||
JSONObject mbgJson = jsonArray.getJSONObject(i);
|
|
||||||
NSMbg nsMbg = new NSMbg(mbgJson);
|
|
||||||
CareportalEvent careportalEvent = new CareportalEvent(nsMbg);
|
|
||||||
MainApp.getDbHelper().createOrUpdate(careportalEvent);
|
|
||||||
if (Config.logIncommingData)
|
|
||||||
log.debug("Adding/Updating new MBG: " + careportalEvent.log());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (intent.getAction().equals(Intents.ACTION_NEW_FOOD) || intent.getAction().equals(Intents.ACTION_CHANGED_FOOD)) {
|
|
||||||
try {
|
|
||||||
if (bundles.containsKey("food")) {
|
|
||||||
String trstring = bundles.getString("food");
|
|
||||||
handleAddChangeFoodRecord(new JSONObject(trstring));
|
|
||||||
}
|
|
||||||
if (bundles.containsKey("foods")) {
|
|
||||||
String trstring = bundles.getString("foods");
|
|
||||||
JSONArray jsonArray = new JSONArray(trstring);
|
|
||||||
for (int i = 0; i < jsonArray.length(); i++) {
|
|
||||||
JSONObject trJson = jsonArray.getJSONObject(i);
|
|
||||||
handleAddChangeFoodRecord(trJson);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (intent.getAction().equals(Intents.ACTION_REMOVED_FOOD)) {
|
|
||||||
try {
|
|
||||||
if (bundles.containsKey("food")) {
|
|
||||||
String trstring = bundles.getString("food");
|
|
||||||
JSONObject trJson = new JSONObject(trstring);
|
|
||||||
String _id = trJson.getString("_id");
|
|
||||||
handleRemovedFoodRecord(_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bundles.containsKey("foods")) {
|
|
||||||
String trstring = bundles.getString("foods");
|
|
||||||
JSONArray jsonArray = new JSONArray(trstring);
|
|
||||||
for (int i = 0; i < jsonArray.length(); i++) {
|
|
||||||
JSONObject trJson = jsonArray.getJSONObject(i);
|
|
||||||
String _id = trJson.getString("_id");
|
|
||||||
handleRemovedFoodRecord(_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleRemovedFoodRecord(String _id) {
|
|
||||||
MainApp.getDbHelper().foodHelper.deleteFoodById(_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void handleAddChangeFoodRecord(JSONObject trJson) throws JSONException {
|
|
||||||
MainApp.getDbHelper().foodHelper.createFoodFromJsonIfNotExists(trJson);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleRemovedRecordFromNS(String _id) {
|
|
||||||
MainApp.getDbHelper().deleteTreatmentById(_id);
|
|
||||||
MainApp.getDbHelper().deleteTempTargetById(_id);
|
|
||||||
MainApp.getDbHelper().deleteTempBasalById(_id);
|
|
||||||
MainApp.getDbHelper().deleteExtendedBolusById(_id);
|
|
||||||
MainApp.getDbHelper().deleteCareportalEventById(_id);
|
|
||||||
MainApp.getDbHelper().deleteProfileSwitchById(_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleAddChangeDataFromNS(String trstring) throws JSONException {
|
|
||||||
JSONObject trJson = new JSONObject(trstring);
|
|
||||||
handleDanaRHistoryRecords(trJson); // update record _id in history
|
|
||||||
handleAddChangeTempTargetRecord(trJson);
|
|
||||||
handleAddChangeTempBasalRecord(trJson);
|
|
||||||
handleAddChangeExtendedBolusRecord(trJson);
|
|
||||||
handleAddChangeCareportalEventRecord(trJson);
|
|
||||||
handleAddChangeTreatmentRecord(trJson);
|
|
||||||
handleAddChangeProfileSwitchRecord(trJson);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void handleDanaRHistoryRecords(JSONObject trJson) {
|
|
||||||
if (trJson.has(DanaRNSHistorySync.DANARSIGNATURE)) {
|
|
||||||
MainApp.getDbHelper().updateDanaRHistoryRecordId(trJson);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void handleAddChangeTreatmentRecord(JSONObject trJson) throws JSONException {
|
|
||||||
if (trJson.has("insulin") || trJson.has("carbs")) {
|
|
||||||
MainApp.getDbHelper().createTreatmentFromJsonIfNotExists(trJson);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void handleAddChangeTempTargetRecord(JSONObject trJson) throws JSONException {
|
|
||||||
if (trJson.has("eventType") && trJson.getString("eventType").equals(CareportalEvent.TEMPORARYTARGET)) {
|
|
||||||
MainApp.getDbHelper().createTemptargetFromJsonIfNotExists(trJson);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void handleAddChangeTempBasalRecord(JSONObject trJson) throws JSONException {
|
|
||||||
if (trJson.has("eventType") && trJson.getString("eventType").equals(CareportalEvent.TEMPBASAL)) {
|
|
||||||
MainApp.getDbHelper().createTempBasalFromJsonIfNotExists(trJson);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void handleAddChangeExtendedBolusRecord(JSONObject trJson) throws JSONException {
|
|
||||||
if (trJson.has("eventType") && trJson.getString("eventType").equals(CareportalEvent.COMBOBOLUS)) {
|
|
||||||
MainApp.getDbHelper().createExtendedBolusFromJsonIfNotExists(trJson);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void handleAddChangeCareportalEventRecord(JSONObject trJson) throws JSONException {
|
|
||||||
if (trJson.has("insulin") && trJson.getDouble("insulin") > 0)
|
|
||||||
return;
|
|
||||||
if (trJson.has("carbs") && trJson.getDouble("carbs") > 0)
|
|
||||||
return;
|
|
||||||
if (trJson.has("eventType") && (
|
|
||||||
trJson.getString("eventType").equals(CareportalEvent.SITECHANGE) ||
|
|
||||||
trJson.getString("eventType").equals(CareportalEvent.INSULINCHANGE) ||
|
|
||||||
trJson.getString("eventType").equals(CareportalEvent.SENSORCHANGE) ||
|
|
||||||
trJson.getString("eventType").equals(CareportalEvent.BGCHECK) ||
|
|
||||||
trJson.getString("eventType").equals(CareportalEvent.NOTE) ||
|
|
||||||
trJson.getString("eventType").equals(CareportalEvent.NONE) ||
|
|
||||||
trJson.getString("eventType").equals(CareportalEvent.ANNOUNCEMENT) ||
|
|
||||||
trJson.getString("eventType").equals(CareportalEvent.QUESTION) ||
|
|
||||||
trJson.getString("eventType").equals(CareportalEvent.EXERCISE) ||
|
|
||||||
trJson.getString("eventType").equals(CareportalEvent.OPENAPSOFFLINE) ||
|
|
||||||
trJson.getString("eventType").equals(CareportalEvent.PUMPBATTERYCHANGE)
|
|
||||||
)) {
|
|
||||||
MainApp.getDbHelper().createCareportalEventFromJsonIfNotExists(trJson);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trJson.has("eventType") && trJson.getString("eventType").equals(CareportalEvent.ANNOUNCEMENT)) {
|
|
||||||
long date = trJson.getLong("mills");
|
|
||||||
long now = System.currentTimeMillis();
|
|
||||||
if (date > now - 15 * 60 * 1000L && trJson.has("notes")) {
|
|
||||||
Notification announcement = new Notification(Notification.NSANNOUNCEMENT, trJson.getString("notes"), Notification.ANNOUNCEMENT, 60);
|
|
||||||
MainApp.bus().post(new EventNewNotification(announcement));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void handleAddChangeProfileSwitchRecord(JSONObject trJson) throws JSONException {
|
|
||||||
if (trJson.has("eventType") && trJson.getString("eventType").equals(CareportalEvent.PROFILESWITCH)) {
|
|
||||||
MainApp.getDbHelper().createProfileSwitchFromJsonIfNotExists(trJson);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleNewSMS(Intent intent) {
|
|
||||||
Bundle bundle = intent.getExtras();
|
|
||||||
if (bundle == null) return;
|
|
||||||
MainApp.bus().post(new EventNewSMS(bundle));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
package info.nightscout.androidaps;
|
package info.nightscout.androidaps.activities;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
@ -9,6 +9,8 @@ import android.view.View;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.CheckBox;
|
import android.widget.CheckBox;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.MainActivity;
|
||||||
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.utils.SP;
|
import info.nightscout.utils.SP;
|
||||||
|
|
||||||
public class AgreementActivity extends Activity {
|
public class AgreementActivity extends Activity {
|
|
@ -0,0 +1,435 @@
|
||||||
|
package info.nightscout.androidaps.activities;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.SystemClock;
|
||||||
|
import android.support.v4.content.res.ResourcesCompat;
|
||||||
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
import android.support.v7.widget.PopupMenu;
|
||||||
|
import android.text.SpannableString;
|
||||||
|
import android.text.style.ForegroundColorSpan;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.ImageButton;
|
||||||
|
import android.widget.SeekBar;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.jjoe64.graphview.GraphView;
|
||||||
|
import com.squareup.otto.Subscribe;
|
||||||
|
import com.wdullaer.materialdatetimepicker.date.DatePickerDialog;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import butterknife.BindView;
|
||||||
|
import butterknife.ButterKnife;
|
||||||
|
import butterknife.OnClick;
|
||||||
|
import butterknife.OnLongClick;
|
||||||
|
import info.nightscout.androidaps.MainApp;
|
||||||
|
import info.nightscout.androidaps.R;
|
||||||
|
import info.nightscout.androidaps.data.Profile;
|
||||||
|
import info.nightscout.androidaps.events.EventCustomCalculationFinished;
|
||||||
|
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||||
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions;
|
||||||
|
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished;
|
||||||
|
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventIobCalculationProgress;
|
||||||
|
import info.nightscout.androidaps.plugins.Overview.OverviewFragment;
|
||||||
|
import info.nightscout.androidaps.plugins.Overview.OverviewPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.Overview.graphData.GraphData;
|
||||||
|
import info.nightscout.utils.DateUtil;
|
||||||
|
import info.nightscout.utils.T;
|
||||||
|
|
||||||
|
public class HistoryBrowseActivity extends AppCompatActivity {
|
||||||
|
private static Logger log = LoggerFactory.getLogger(HistoryBrowseActivity.class);
|
||||||
|
|
||||||
|
|
||||||
|
ImageButton chartButton;
|
||||||
|
|
||||||
|
boolean showBasal = true;
|
||||||
|
boolean showIob, showCob, showDev, showRat, showDevslope;
|
||||||
|
|
||||||
|
|
||||||
|
@BindView(R.id.historybrowse_date)
|
||||||
|
Button buttonDate;
|
||||||
|
@BindView(R.id.historybrowse_zoom)
|
||||||
|
Button buttonZoom;
|
||||||
|
@BindView(R.id.historyybrowse_bggraph)
|
||||||
|
GraphView bgGraph;
|
||||||
|
@BindView(R.id.historybrowse_iobgraph)
|
||||||
|
GraphView iobGraph;
|
||||||
|
@BindView(R.id.historybrowse_seekBar)
|
||||||
|
SeekBar seekBar;
|
||||||
|
@BindView(R.id.historybrowse_noprofile)
|
||||||
|
TextView noProfile;
|
||||||
|
@BindView(R.id.overview_iobcalculationprogess)
|
||||||
|
TextView iobCalculationProgressView;
|
||||||
|
|
||||||
|
private int rangeToDisplay = 24; // for graph
|
||||||
|
private long start = 0;
|
||||||
|
|
||||||
|
IobCobCalculatorPlugin iobCobCalculatorPlugin;
|
||||||
|
|
||||||
|
EventCustomCalculationFinished eventCustomCalculationFinished = new EventCustomCalculationFinished();
|
||||||
|
|
||||||
|
public HistoryBrowseActivity() {
|
||||||
|
iobCobCalculatorPlugin = new IobCobCalculatorPlugin();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_historybrowse);
|
||||||
|
|
||||||
|
ButterKnife.bind(this);
|
||||||
|
|
||||||
|
bgGraph.getGridLabelRenderer().setGridColor(MainApp.gc(R.color.graphgrid));
|
||||||
|
bgGraph.getGridLabelRenderer().reloadStyles();
|
||||||
|
iobGraph.getGridLabelRenderer().setGridColor(MainApp.gc(R.color.graphgrid));
|
||||||
|
iobGraph.getGridLabelRenderer().reloadStyles();
|
||||||
|
iobGraph.getGridLabelRenderer().setHorizontalLabelsVisible(false);
|
||||||
|
bgGraph.getGridLabelRenderer().setLabelVerticalWidth(50);
|
||||||
|
iobGraph.getGridLabelRenderer().setLabelVerticalWidth(50);
|
||||||
|
iobGraph.getGridLabelRenderer().setNumVerticalLabels(5);
|
||||||
|
|
||||||
|
setupChartMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
MainApp.bus().unregister(this);
|
||||||
|
iobCobCalculatorPlugin.stopCalculation("onPause");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
MainApp.bus().register(this);
|
||||||
|
// set start of current day
|
||||||
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
calendar.setTimeInMillis(System.currentTimeMillis());
|
||||||
|
calendar.set(Calendar.MILLISECOND, 0);
|
||||||
|
calendar.set(Calendar.SECOND, 0);
|
||||||
|
calendar.set(Calendar.MINUTE, 0);
|
||||||
|
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
||||||
|
start = calendar.getTimeInMillis();
|
||||||
|
runCalculation("onResume");
|
||||||
|
SystemClock.sleep(1000);
|
||||||
|
updateGUI("onResume");
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnClick(R.id.historybrowse_left)
|
||||||
|
void onClickLeft() {
|
||||||
|
start -= T.hours(rangeToDisplay).msecs();
|
||||||
|
updateGUI("onClickLeft");
|
||||||
|
runCalculation("onClickLeft");
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnClick(R.id.historybrowse_right)
|
||||||
|
void onClickRight() {
|
||||||
|
start += T.hours(rangeToDisplay).msecs();
|
||||||
|
updateGUI("onClickRight");
|
||||||
|
runCalculation("onClickRight");
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnClick(R.id.historybrowse_end)
|
||||||
|
void onClickEnd() {
|
||||||
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
calendar.setTimeInMillis(System.currentTimeMillis());
|
||||||
|
calendar.set(Calendar.MILLISECOND, 0);
|
||||||
|
calendar.set(Calendar.SECOND, 0);
|
||||||
|
calendar.set(Calendar.MINUTE, 0);
|
||||||
|
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
||||||
|
start = calendar.getTimeInMillis();
|
||||||
|
updateGUI("onClickEnd");
|
||||||
|
runCalculation("onClickEnd");
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnClick(R.id.historybrowse_zoom)
|
||||||
|
void onClickZoom() {
|
||||||
|
rangeToDisplay += 6;
|
||||||
|
rangeToDisplay = rangeToDisplay > 24 ? 6 : rangeToDisplay;
|
||||||
|
updateGUI("rangeChange");
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnLongClick(R.id.historybrowse_zoom)
|
||||||
|
boolean onLongClickZoom() {
|
||||||
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
calendar.setTimeInMillis(start);
|
||||||
|
calendar.set(Calendar.MILLISECOND, 0);
|
||||||
|
calendar.set(Calendar.SECOND, 0);
|
||||||
|
calendar.set(Calendar.MINUTE, 0);
|
||||||
|
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
||||||
|
start = calendar.getTimeInMillis();
|
||||||
|
updateGUI("resetToMidnight");
|
||||||
|
runCalculation("onLongClickZoom");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnClick(R.id.historybrowse_date)
|
||||||
|
void onClickDate() {
|
||||||
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
calendar.setTime(new Date(start));
|
||||||
|
DatePickerDialog dpd = DatePickerDialog.newInstance(
|
||||||
|
(view, year, monthOfYear, dayOfMonth) -> {
|
||||||
|
Date date = new Date(0);
|
||||||
|
date.setYear(year - 1900);
|
||||||
|
date.setMonth(monthOfYear);
|
||||||
|
date.setDate(dayOfMonth);
|
||||||
|
date.setHours(0);
|
||||||
|
start = date.getTime();
|
||||||
|
updateGUI("onClickDate");
|
||||||
|
runCalculation("onClickDate");
|
||||||
|
},
|
||||||
|
calendar.get(Calendar.YEAR),
|
||||||
|
calendar.get(Calendar.MONTH),
|
||||||
|
calendar.get(Calendar.DAY_OF_MONTH)
|
||||||
|
);
|
||||||
|
dpd.setThemeDark(true);
|
||||||
|
dpd.dismissOnPause(true);
|
||||||
|
dpd.show(getFragmentManager(), "Datepickerdialog");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runCalculation(String from) {
|
||||||
|
long end = start + T.hours(rangeToDisplay).msecs();
|
||||||
|
iobCobCalculatorPlugin.stopCalculation(from);
|
||||||
|
iobCobCalculatorPlugin.clearCache();
|
||||||
|
iobCobCalculatorPlugin.runCalculation(from, end, true, false, eventCustomCalculationFinished);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onStatusEvent(final EventAutosensCalculationFinished e) {
|
||||||
|
if (e.cause == eventCustomCalculationFinished) {
|
||||||
|
log.debug("EventAutosensCalculationFinished");
|
||||||
|
runOnUiThread(() -> {
|
||||||
|
synchronized (HistoryBrowseActivity.this) {
|
||||||
|
updateGUI("EventAutosensCalculationFinished");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onStatusEvent(final EventIobCalculationProgress e) {
|
||||||
|
runOnUiThread(() -> {
|
||||||
|
if (iobCalculationProgressView != null)
|
||||||
|
iobCalculationProgressView.setText(e.progress);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateGUI(String from) {
|
||||||
|
log.debug("updateGUI from: " + from);
|
||||||
|
|
||||||
|
if (noProfile == null || buttonDate == null || buttonZoom == null || bgGraph == null || iobGraph == null || seekBar == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
|
||||||
|
final Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||||
|
|
||||||
|
if (profile == null) {
|
||||||
|
noProfile.setVisibility(View.VISIBLE);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
noProfile.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
final String units = profile.getUnits();
|
||||||
|
final double lowLine = OverviewPlugin.getPlugin().determineLowLine(units);
|
||||||
|
final double highLine = OverviewPlugin.getPlugin().determineHighLine(units);
|
||||||
|
|
||||||
|
buttonDate.setText(DateUtil.dateAndTimeString(start));
|
||||||
|
buttonZoom.setText(String.valueOf(rangeToDisplay));
|
||||||
|
|
||||||
|
final boolean showPrediction = false;
|
||||||
|
|
||||||
|
int hoursToFetch;
|
||||||
|
final long toTime;
|
||||||
|
final long fromTime;
|
||||||
|
//if (showPrediction) {
|
||||||
|
//int predHours = (int) (Math.ceil(((DetermineBasalResultAMA) finalLastRun.constraintsProcessed).getLatestPredictionsTime() - System.currentTimeMillis()) / (60 * 60 * 1000));
|
||||||
|
//predHours = Math.min(2, predHours);
|
||||||
|
//predHours = Math.max(0, predHours);
|
||||||
|
//hoursToFetch = rangeToDisplay - predHours;
|
||||||
|
//toTime = calendar.getTimeInMillis() + 100000; // little bit more to avoid wrong rounding - Graphview specific
|
||||||
|
//fromTime = toTime - hoursToFetch * 60 * 60 * 1000L;
|
||||||
|
//endTime = toTime + predHours * 60 * 60 * 1000L;
|
||||||
|
//} else {
|
||||||
|
fromTime = start + T.secs(100).msecs();
|
||||||
|
toTime = start + T.hours(rangeToDisplay).msecs();
|
||||||
|
//}
|
||||||
|
|
||||||
|
log.debug("Period: " + DateUtil.dateAndTimeString(fromTime) + " - " + DateUtil.dateAndTimeString(toTime));
|
||||||
|
|
||||||
|
final long pointer = System.currentTimeMillis();
|
||||||
|
|
||||||
|
// ------------------ 1st graph
|
||||||
|
|
||||||
|
final GraphData graphData = new GraphData(bgGraph, iobCobCalculatorPlugin);
|
||||||
|
|
||||||
|
// **** In range Area ****
|
||||||
|
graphData.addInRangeArea(fromTime, toTime, lowLine, highLine);
|
||||||
|
|
||||||
|
// **** BG ****
|
||||||
|
if (showPrediction)
|
||||||
|
//graphData.addBgReadings(fromTime, toTime, lowLine, highLine, (DetermineBasalResultAMA) finalLastRun.constraintsProcessed);
|
||||||
|
;
|
||||||
|
else
|
||||||
|
graphData.addBgReadings(fromTime, toTime, lowLine, highLine, null);
|
||||||
|
|
||||||
|
// set manual x bounds to have nice steps
|
||||||
|
graphData.formatAxis(fromTime, toTime);
|
||||||
|
|
||||||
|
// Treatments
|
||||||
|
graphData.addTreatments(fromTime, toTime);
|
||||||
|
|
||||||
|
// add basal data
|
||||||
|
if (pump.getPumpDescription().isTempBasalCapable && showBasal) {
|
||||||
|
graphData.addBasals(fromTime, toTime, lowLine / graphData.maxY / 1.2d);
|
||||||
|
}
|
||||||
|
|
||||||
|
// **** NOW line ****
|
||||||
|
graphData.addNowLine(pointer);
|
||||||
|
|
||||||
|
// ------------------ 2nd graph
|
||||||
|
|
||||||
|
new Thread(() -> {
|
||||||
|
final GraphData secondGraphData = new GraphData(iobGraph, iobCobCalculatorPlugin);
|
||||||
|
|
||||||
|
boolean useIobForScale = false;
|
||||||
|
boolean useCobForScale = false;
|
||||||
|
boolean useDevForScale = false;
|
||||||
|
boolean useRatioForScale = false;
|
||||||
|
boolean useDSForScale = false;
|
||||||
|
|
||||||
|
if (showIob) {
|
||||||
|
useIobForScale = true;
|
||||||
|
} else if (showCob) {
|
||||||
|
useCobForScale = true;
|
||||||
|
} else if (showDev) {
|
||||||
|
useDevForScale = true;
|
||||||
|
} else if (showRat) {
|
||||||
|
useRatioForScale = true;
|
||||||
|
} else if (showDevslope) {
|
||||||
|
useDSForScale = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showIob)
|
||||||
|
secondGraphData.addIob(fromTime, toTime, useIobForScale, 1d);
|
||||||
|
if (showCob)
|
||||||
|
secondGraphData.addCob(fromTime, toTime, useCobForScale, useCobForScale ? 1d : 0.5d);
|
||||||
|
if (showDev)
|
||||||
|
secondGraphData.addDeviations(fromTime, toTime, useDevForScale, 1d);
|
||||||
|
if (showRat)
|
||||||
|
secondGraphData.addRatio(fromTime, toTime, useRatioForScale, 1d);
|
||||||
|
if (showDevslope)
|
||||||
|
secondGraphData.addDeviationSlope(fromTime, toTime, useDSForScale, 1d);
|
||||||
|
|
||||||
|
// **** NOW line ****
|
||||||
|
// set manual x bounds to have nice steps
|
||||||
|
secondGraphData.formatAxis(fromTime, toTime);
|
||||||
|
secondGraphData.addNowLine(pointer);
|
||||||
|
|
||||||
|
// do GUI update
|
||||||
|
runOnUiThread(() -> {
|
||||||
|
if (showIob || showCob || showDev || showRat || showDevslope) {
|
||||||
|
iobGraph.setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
iobGraph.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
// finally enforce drawing of graphs
|
||||||
|
graphData.performUpdate();
|
||||||
|
if (showIob || showCob || showDev || showRat || showDevslope)
|
||||||
|
secondGraphData.performUpdate();
|
||||||
|
});
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupChartMenu() {
|
||||||
|
chartButton = (ImageButton) findViewById(R.id.overview_chartMenuButton);
|
||||||
|
chartButton.setOnClickListener(v -> {
|
||||||
|
MenuItem item;
|
||||||
|
CharSequence title;
|
||||||
|
SpannableString s;
|
||||||
|
PopupMenu popup = new PopupMenu(v.getContext(), v);
|
||||||
|
|
||||||
|
|
||||||
|
item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.BAS.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_basals));
|
||||||
|
title = item.getTitle();
|
||||||
|
s = new SpannableString(title);
|
||||||
|
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.basal, null)), 0, s.length(), 0);
|
||||||
|
item.setTitle(s);
|
||||||
|
item.setCheckable(true);
|
||||||
|
item.setChecked(showBasal);
|
||||||
|
|
||||||
|
item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.IOB.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_iob));
|
||||||
|
title = item.getTitle();
|
||||||
|
s = new SpannableString(title);
|
||||||
|
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.iob, null)), 0, s.length(), 0);
|
||||||
|
item.setTitle(s);
|
||||||
|
item.setCheckable(true);
|
||||||
|
item.setChecked(showIob);
|
||||||
|
|
||||||
|
item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.COB.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_cob));
|
||||||
|
title = item.getTitle();
|
||||||
|
s = new SpannableString(title);
|
||||||
|
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.cob, null)), 0, s.length(), 0);
|
||||||
|
item.setTitle(s);
|
||||||
|
item.setCheckable(true);
|
||||||
|
item.setChecked(showCob);
|
||||||
|
|
||||||
|
item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.DEV.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_deviations));
|
||||||
|
title = item.getTitle();
|
||||||
|
s = new SpannableString(title);
|
||||||
|
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.deviations, null)), 0, s.length(), 0);
|
||||||
|
item.setTitle(s);
|
||||||
|
item.setCheckable(true);
|
||||||
|
item.setChecked(showDev);
|
||||||
|
|
||||||
|
item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.SEN.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_sensitivity));
|
||||||
|
title = item.getTitle();
|
||||||
|
s = new SpannableString(title);
|
||||||
|
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.ratio, null)), 0, s.length(), 0);
|
||||||
|
item.setTitle(s);
|
||||||
|
item.setCheckable(true);
|
||||||
|
item.setChecked(showRat);
|
||||||
|
|
||||||
|
if (MainApp.devBranch) {
|
||||||
|
item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.DEVSLOPE.ordinal(), Menu.NONE, "Deviation slope");
|
||||||
|
title = item.getTitle();
|
||||||
|
s = new SpannableString(title);
|
||||||
|
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.devslopepos, null)), 0, s.length(), 0);
|
||||||
|
item.setTitle(s);
|
||||||
|
item.setCheckable(true);
|
||||||
|
item.setChecked(showDevslope);
|
||||||
|
}
|
||||||
|
|
||||||
|
popup.setOnMenuItemClickListener(item1 -> {
|
||||||
|
if (item1.getItemId() == OverviewFragment.CHARTTYPE.BAS.ordinal()) {
|
||||||
|
showBasal = !item1.isChecked();
|
||||||
|
} else if (item1.getItemId() == OverviewFragment.CHARTTYPE.IOB.ordinal()) {
|
||||||
|
showIob = !item1.isChecked();
|
||||||
|
} else if (item1.getItemId() == OverviewFragment.CHARTTYPE.COB.ordinal()) {
|
||||||
|
showCob = !item1.isChecked();
|
||||||
|
} else if (item1.getItemId() == OverviewFragment.CHARTTYPE.DEV.ordinal()) {
|
||||||
|
showDev = !item1.isChecked();
|
||||||
|
} else if (item1.getItemId() == OverviewFragment.CHARTTYPE.SEN.ordinal()) {
|
||||||
|
showRat = !item1.isChecked();
|
||||||
|
} else if (item1.getItemId() == OverviewFragment.CHARTTYPE.DEVSLOPE.ordinal()) {
|
||||||
|
showDevslope = !item1.isChecked();
|
||||||
|
}
|
||||||
|
updateGUI("onGraphCheckboxesCheckedChanged");
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
chartButton.setImageResource(R.drawable.ic_arrow_drop_up_white_24dp);
|
||||||
|
popup.setOnDismissListener(menu -> chartButton.setImageResource(R.drawable.ic_arrow_drop_down_white_24dp));
|
||||||
|
popup.show();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,11 +1,9 @@
|
||||||
package info.nightscout.androidaps;
|
package info.nightscout.androidaps.activities;
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.preference.EditTextPreference;
|
import android.preference.EditTextPreference;
|
||||||
import android.preference.ListPreference;
|
import android.preference.ListPreference;
|
||||||
import android.preference.MultiSelectListPreference;
|
|
||||||
import android.preference.Preference;
|
import android.preference.Preference;
|
||||||
import android.preference.PreferenceActivity;
|
import android.preference.PreferenceActivity;
|
||||||
import android.preference.PreferenceFragment;
|
import android.preference.PreferenceFragment;
|
||||||
|
@ -13,26 +11,34 @@ import android.preference.PreferenceGroup;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.Config;
|
||||||
|
import info.nightscout.androidaps.MainApp;
|
||||||
|
import info.nightscout.androidaps.R;
|
||||||
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.plugins.Careportal.CareportalPlugin;
|
import info.nightscout.androidaps.plugins.Careportal.CareportalPlugin;
|
||||||
import info.nightscout.androidaps.plugins.ConstraintsSafety.SafetyPlugin;
|
import info.nightscout.androidaps.plugins.ConstraintsSafety.SafetyPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Insulin.InsulinOrefFreePeakPlugin;
|
import info.nightscout.androidaps.plugins.Insulin.InsulinOrefFreePeakPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
|
import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
|
||||||
import info.nightscout.androidaps.plugins.NSClientInternal.NSClientInternalPlugin;
|
import info.nightscout.androidaps.plugins.NSClientInternal.NSClientPlugin;
|
||||||
import info.nightscout.androidaps.plugins.OpenAPSAMA.OpenAPSAMAPlugin;
|
import info.nightscout.androidaps.plugins.OpenAPSAMA.OpenAPSAMAPlugin;
|
||||||
import info.nightscout.androidaps.plugins.OpenAPSMA.OpenAPSMAPlugin;
|
import info.nightscout.androidaps.plugins.OpenAPSMA.OpenAPSMAPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.OpenAPSSMB.OpenAPSSMBPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.PumpCombo.ComboPlugin;
|
||||||
import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPlugin;
|
import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPlugin;
|
||||||
import info.nightscout.androidaps.plugins.PumpDanaRKorean.DanaRKoreanPlugin;
|
import info.nightscout.androidaps.plugins.PumpDanaRKorean.DanaRKoreanPlugin;
|
||||||
import info.nightscout.androidaps.plugins.PumpDanaRS.DanaRSPlugin;
|
import info.nightscout.androidaps.plugins.PumpDanaRS.DanaRSPlugin;
|
||||||
import info.nightscout.androidaps.plugins.PumpDanaRv2.DanaRv2Plugin;
|
import info.nightscout.androidaps.plugins.PumpDanaRv2.DanaRv2Plugin;
|
||||||
|
import info.nightscout.androidaps.plugins.PumpInsight.InsightPlugin;
|
||||||
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
|
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
|
||||||
import info.nightscout.androidaps.plugins.SensitivityAAPS.SensitivityAAPSPlugin;
|
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityAAPSPlugin;
|
||||||
import info.nightscout.androidaps.plugins.SensitivityOref0.SensitivityOref0Plugin;
|
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityOref0Plugin;
|
||||||
import info.nightscout.androidaps.plugins.SensitivityWeightedAverage.SensitivityWeightedAveragePlugin;
|
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityOref1Plugin;
|
||||||
|
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityWeightedAveragePlugin;
|
||||||
import info.nightscout.androidaps.plugins.SmsCommunicator.SmsCommunicatorPlugin;
|
import info.nightscout.androidaps.plugins.SmsCommunicator.SmsCommunicatorPlugin;
|
||||||
import info.nightscout.androidaps.plugins.SourceDexcomG5.SourceDexcomG5Plugin;
|
import info.nightscout.androidaps.plugins.Source.SourceDexcomG5Plugin;
|
||||||
import info.nightscout.androidaps.plugins.Wear.WearPlugin;
|
import info.nightscout.androidaps.plugins.Wear.WearPlugin;
|
||||||
import info.nightscout.androidaps.plugins.XDripStatusline.StatuslinePlugin;
|
import info.nightscout.androidaps.plugins.XDripStatusline.StatuslinePlugin;
|
||||||
import info.nightscout.utils.LocaleHelper;
|
import info.nightscout.utils.LocaleHelper;
|
||||||
|
@ -66,8 +72,8 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
|
||||||
if (key.equals("short_tabtitles")) {
|
if (key.equals("short_tabtitles")) {
|
||||||
MainApp.bus().post(new EventRefreshGui());
|
MainApp.bus().post(new EventRefreshGui());
|
||||||
}
|
}
|
||||||
if (key.equals("openapsama_useautosens") && SP.getBoolean("openapsama_useautosens", false)) {
|
if (key.equals(MainApp.gs(R.string.key_openapsama_useautosens)) && SP.getBoolean(R.string.key_openapsama_useautosens, false)) {
|
||||||
OKDialog.show(this, MainApp.sResources.getString(R.string.configbuilder_sensitivity), MainApp.sResources.getString(R.string.sensitivity_warning), null);
|
OKDialog.show(this, MainApp.gs(R.string.configbuilder_sensitivity), MainApp.gs(R.string.sensitivity_warning), null);
|
||||||
}
|
}
|
||||||
updatePrefSummary(myPreferenceFragment.getPreference(key));
|
updatePrefSummary(myPreferenceFragment.getPreference(key));
|
||||||
}
|
}
|
||||||
|
@ -81,13 +87,13 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
|
||||||
EditTextPreference editTextPref = (EditTextPreference) pref;
|
EditTextPreference editTextPref = (EditTextPreference) pref;
|
||||||
if (pref.getKey().contains("password") || pref.getKey().contains("secret")) {
|
if (pref.getKey().contains("password") || pref.getKey().contains("secret")) {
|
||||||
pref.setSummary("******");
|
pref.setSummary("******");
|
||||||
} else if (pref.getKey().equals(MainApp.sResources.getString(R.string.key_danars_name))) {
|
} else if (pref.getKey().equals(MainApp.gs(R.string.key_danars_name))) {
|
||||||
pref.setSummary(SP.getString(R.string.key_danars_name, ""));
|
pref.setSummary(SP.getString(R.string.key_danars_name, ""));
|
||||||
} else if (editTextPref.getText() != null && !editTextPref.getText().equals("")) {
|
} 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") && TextUtils.isEmpty(editTextPref.getText().trim())) {
|
||||||
pref.setSummary(MainApp.sResources.getString(R.string.smscommunicator_allowednumbers_summary));
|
pref.setSummary(MainApp.gs(R.string.smscommunicator_allowednumbers_summary));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,7 +118,7 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
|
||||||
id = args.getInt("id");
|
id = args.getInt("id");
|
||||||
}
|
}
|
||||||
|
|
||||||
void addPreferencesFromResourceIfEnabled(PluginBase p, int type) {
|
void addPreferencesFromResourceIfEnabled(PluginBase p, PluginType type) {
|
||||||
if (p.isEnabled(type) && p.getPreferencesId() != -1)
|
if (p.isEnabled(type) && p.getPreferencesId() != -1)
|
||||||
addPreferencesFromResource(p.getPreferencesId());
|
addPreferencesFromResource(p.getPreferencesId());
|
||||||
}
|
}
|
||||||
|
@ -127,60 +133,61 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
|
||||||
|
|
||||||
if (id != -1) {
|
if (id != -1) {
|
||||||
addPreferencesFromResource(id);
|
addPreferencesFromResource(id);
|
||||||
addPreferencesFromResource(R.xml.pref_advanced);
|
|
||||||
} else {
|
} else {
|
||||||
if (!Config.NSCLIENT && !Config.G5UPLOADER) {
|
|
||||||
|
if (!Config.NSCLIENT) {
|
||||||
addPreferencesFromResource(R.xml.pref_password);
|
addPreferencesFromResource(R.xml.pref_password);
|
||||||
}
|
}
|
||||||
addPreferencesFromResource(R.xml.pref_age);
|
addPreferencesFromResource(R.xml.pref_age);
|
||||||
addPreferencesFromResource(R.xml.pref_language);
|
addPreferencesFromResource(R.xml.pref_language);
|
||||||
|
|
||||||
if (!Config.NSCLIENT && !Config.G5UPLOADER) {
|
addPreferencesFromResource(R.xml.pref_overview);
|
||||||
addPreferencesFromResource(R.xml.pref_quickwizard);
|
|
||||||
}
|
addPreferencesFromResourceIfEnabled(SourceDexcomG5Plugin.getPlugin(), PluginType.BGSOURCE);
|
||||||
addPreferencesFromResourceIfEnabled(SourceDexcomG5Plugin.getPlugin(), PluginBase.BGSOURCE);
|
addPreferencesFromResourceIfEnabled(CareportalPlugin.getPlugin(), PluginType.GENERAL);
|
||||||
addPreferencesFromResourceIfEnabled(CareportalPlugin.getPlugin(), PluginBase.GENERAL);
|
addPreferencesFromResourceIfEnabled(SafetyPlugin.getPlugin(), PluginType.CONSTRAINTS);
|
||||||
addPreferencesFromResourceIfEnabled(SafetyPlugin.getPlugin(), PluginBase.CONSTRAINTS);
|
|
||||||
if (Config.APS) {
|
if (Config.APS) {
|
||||||
addPreferencesFromResourceIfEnabled(LoopPlugin.getPlugin(), PluginBase.LOOP);
|
addPreferencesFromResourceIfEnabled(LoopPlugin.getPlugin(), PluginType.LOOP);
|
||||||
addPreferencesFromResourceIfEnabled(OpenAPSMAPlugin.getPlugin(), PluginBase.APS);
|
addPreferencesFromResourceIfEnabled(OpenAPSMAPlugin.getPlugin(), PluginType.APS);
|
||||||
addPreferencesFromResourceIfEnabled(OpenAPSAMAPlugin.getPlugin(), PluginBase.APS);
|
addPreferencesFromResourceIfEnabled(OpenAPSAMAPlugin.getPlugin(), PluginType.APS);
|
||||||
|
addPreferencesFromResourceIfEnabled(OpenAPSSMBPlugin.getPlugin(), PluginType.APS);
|
||||||
}
|
}
|
||||||
|
|
||||||
addPreferencesFromResourceIfEnabled(SensitivityAAPSPlugin.getPlugin(), PluginBase.SENSITIVITY);
|
addPreferencesFromResourceIfEnabled(SensitivityAAPSPlugin.getPlugin(), PluginType.SENSITIVITY);
|
||||||
addPreferencesFromResourceIfEnabled(SensitivityWeightedAveragePlugin.getPlugin(), PluginBase.SENSITIVITY);
|
addPreferencesFromResourceIfEnabled(SensitivityWeightedAveragePlugin.getPlugin(), PluginType.SENSITIVITY);
|
||||||
addPreferencesFromResourceIfEnabled(SensitivityOref0Plugin.getPlugin(), PluginBase.SENSITIVITY);
|
addPreferencesFromResourceIfEnabled(SensitivityOref0Plugin.getPlugin(), PluginType.SENSITIVITY);
|
||||||
|
addPreferencesFromResourceIfEnabled(SensitivityOref1Plugin.getPlugin(), PluginType.SENSITIVITY);
|
||||||
|
|
||||||
if (Config.DANAR) {
|
if (Config.PUMPDRIVERS) {
|
||||||
addPreferencesFromResourceIfEnabled(DanaRPlugin.getPlugin(), PluginBase.PUMP);
|
addPreferencesFromResourceIfEnabled(DanaRPlugin.getPlugin(), PluginType.PUMP);
|
||||||
addPreferencesFromResourceIfEnabled(DanaRKoreanPlugin.getPlugin(), PluginBase.PUMP);
|
addPreferencesFromResourceIfEnabled(DanaRKoreanPlugin.getPlugin(), PluginType.PUMP);
|
||||||
addPreferencesFromResourceIfEnabled(DanaRv2Plugin.getPlugin(), PluginBase.PUMP);
|
addPreferencesFromResourceIfEnabled(DanaRv2Plugin.getPlugin(), PluginType.PUMP);
|
||||||
addPreferencesFromResourceIfEnabled(DanaRSPlugin.getPlugin(), PluginBase.PUMP);
|
addPreferencesFromResourceIfEnabled(DanaRSPlugin.getPlugin(), PluginType.PUMP);
|
||||||
|
addPreferencesFromResourceIfEnabled(InsightPlugin.getPlugin(), PluginType.PUMP);
|
||||||
|
addPreferencesFromResourceIfEnabled(ComboPlugin.getPlugin(), PluginType.PUMP);
|
||||||
|
|
||||||
if (DanaRPlugin.getPlugin().isEnabled(PluginBase.PROFILE)
|
if (DanaRPlugin.getPlugin().isEnabled(PluginType.PROFILE)
|
||||||
|| DanaRKoreanPlugin.getPlugin().isEnabled(PluginBase.PROFILE)
|
|| DanaRKoreanPlugin.getPlugin().isEnabled(PluginType.PROFILE)
|
||||||
|| DanaRv2Plugin.getPlugin().isEnabled(PluginBase.PROFILE)
|
|| DanaRv2Plugin.getPlugin().isEnabled(PluginType.PROFILE)
|
||||||
|| DanaRSPlugin.getPlugin().isEnabled(PluginBase.PROFILE)) {
|
|| DanaRSPlugin.getPlugin().isEnabled(PluginType.PROFILE)) {
|
||||||
addPreferencesFromResource(R.xml.pref_danarprofile);
|
addPreferencesFromResource(R.xml.pref_danarprofile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Config.NSCLIENT && !Config.G5UPLOADER) {
|
if (!Config.NSCLIENT) {
|
||||||
addPreferencesFromResourceIfEnabled(VirtualPumpPlugin.getPlugin(), PluginBase.PUMP);
|
addPreferencesFromResourceIfEnabled(VirtualPumpPlugin.getPlugin(), PluginType.PUMP);
|
||||||
}
|
}
|
||||||
|
|
||||||
addPreferencesFromResourceIfEnabled(InsulinOrefFreePeakPlugin.getPlugin(), PluginBase.INSULIN);
|
addPreferencesFromResourceIfEnabled(InsulinOrefFreePeakPlugin.getPlugin(), PluginType.INSULIN);
|
||||||
|
|
||||||
addPreferencesFromResourceIfEnabled(NSClientInternalPlugin.getPlugin(), PluginBase.GENERAL);
|
addPreferencesFromResourceIfEnabled(NSClientPlugin.getPlugin(), PluginType.GENERAL);
|
||||||
addPreferencesFromResourceIfEnabled(SmsCommunicatorPlugin.getPlugin(), PluginBase.GENERAL);
|
addPreferencesFromResourceIfEnabled(SmsCommunicatorPlugin.getPlugin(), PluginType.GENERAL);
|
||||||
|
|
||||||
if (!Config.NSCLIENT && !Config.G5UPLOADER) {
|
addPreferencesFromResource(R.xml.pref_others);
|
||||||
addPreferencesFromResource(R.xml.pref_others);
|
addPreferencesFromResource(R.xml.pref_datachoices);
|
||||||
}
|
|
||||||
addPreferencesFromResource(R.xml.pref_advanced);
|
|
||||||
|
|
||||||
addPreferencesFromResourceIfEnabled(WearPlugin.getPlugin(), PluginBase.GENERAL);
|
addPreferencesFromResourceIfEnabled(WearPlugin.getPlugin(), PluginType.GENERAL);
|
||||||
addPreferencesFromResourceIfEnabled(StatuslinePlugin.getPlugin(), PluginBase.GENERAL);
|
addPreferencesFromResourceIfEnabled(StatuslinePlugin.getPlugin(), PluginType.GENERAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
initSummary(getPreferenceScreen());
|
initSummary(getPreferenceScreen());
|
|
@ -0,0 +1,60 @@
|
||||||
|
package info.nightscout.androidaps.activities;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.v4.app.Fragment;
|
||||||
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.MainApp;
|
||||||
|
import info.nightscout.androidaps.R;
|
||||||
|
import info.nightscout.androidaps.activities.PreferencesActivity;
|
||||||
|
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||||
|
import info.nightscout.utils.PasswordProtection;
|
||||||
|
|
||||||
|
public class SingleFragmentActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
private PluginBase plugin;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_single_fragment);
|
||||||
|
|
||||||
|
this.plugin = MainApp.getPluginsList().get(getIntent().getIntExtra("plugin", -1));
|
||||||
|
setTitle(plugin.getName());
|
||||||
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
|
getSupportActionBar().setDisplayShowHomeEnabled(true);
|
||||||
|
|
||||||
|
if (savedInstanceState == null) {
|
||||||
|
getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout,
|
||||||
|
Fragment.instantiate(this, plugin.pluginDescription.getFragmentClass())).commit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
if (item.getItemId() == android.R.id.home) {
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (item.getItemId() == R.id.nav_plugin_preferences) {
|
||||||
|
PasswordProtection.QueryPassword(this, R.string.settings_password, "settings_password", () -> {
|
||||||
|
Intent i = new Intent(this, PreferencesActivity.class);
|
||||||
|
i.putExtra("id", plugin.getPreferencesId());
|
||||||
|
startActivity(i);
|
||||||
|
}, null);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
|
if (plugin.getPreferencesId() != -1)
|
||||||
|
getMenuInflater().inflate(R.menu.menu_single_fragment, menu);
|
||||||
|
return super.onCreateOptionsMenu(menu);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,11 +1,9 @@
|
||||||
package info.nightscout.androidaps.plugins.PumpDanaR.activities;
|
package info.nightscout.androidaps.activities;
|
||||||
|
|
||||||
import android.app.Activity;
|
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.os.Handler;
|
|
||||||
import android.os.HandlerThread;
|
|
||||||
import android.support.v7.widget.LinearLayoutManager;
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
|
@ -38,18 +36,24 @@ import java.util.List;
|
||||||
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.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
import info.nightscout.androidaps.db.DanaRHistoryRecord;
|
import info.nightscout.androidaps.db.TDD;
|
||||||
import info.nightscout.androidaps.events.EventPumpStatusChanged;
|
import info.nightscout.androidaps.events.EventPumpStatusChanged;
|
||||||
|
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.RecordTypes;
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions;
|
||||||
|
import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPlugin;
|
||||||
import info.nightscout.androidaps.plugins.PumpDanaR.events.EventDanaRSyncStatus;
|
import info.nightscout.androidaps.plugins.PumpDanaR.events.EventDanaRSyncStatus;
|
||||||
|
import info.nightscout.androidaps.plugins.PumpDanaRKorean.DanaRKoreanPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.PumpDanaRS.DanaRSPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.PumpDanaRv2.DanaRv2Plugin;
|
||||||
|
import info.nightscout.androidaps.plugins.PumpInsight.InsightPlugin;
|
||||||
import info.nightscout.androidaps.queue.Callback;
|
import info.nightscout.androidaps.queue.Callback;
|
||||||
import info.nightscout.utils.DecimalFormatter;
|
import info.nightscout.utils.DecimalFormatter;
|
||||||
import info.nightscout.utils.SP;
|
import info.nightscout.utils.SP;
|
||||||
import info.nightscout.utils.SafeParse;
|
import info.nightscout.utils.SafeParse;
|
||||||
|
|
||||||
public class DanaRStatsActivity extends Activity {
|
public class TDDStatsActivity extends Activity {
|
||||||
private static Logger log = LoggerFactory.getLogger(DanaRStatsActivity.class);
|
private static Logger log = LoggerFactory.getLogger(TDDStatsActivity.class);
|
||||||
|
|
||||||
TextView statusView, statsMessage, totalBaseBasal2;
|
TextView statusView, statsMessage, totalBaseBasal2;
|
||||||
EditText totalBaseBasal;
|
EditText totalBaseBasal;
|
||||||
|
@ -60,10 +64,10 @@ public class DanaRStatsActivity extends Activity {
|
||||||
double magicNumber;
|
double magicNumber;
|
||||||
DecimalFormat decimalFormat;
|
DecimalFormat decimalFormat;
|
||||||
|
|
||||||
List<DanaRHistoryRecord> historyList = new ArrayList<>();
|
List<TDD> historyList = new ArrayList<>();
|
||||||
List<DanaRHistoryRecord> dummies;
|
List<TDD> dummies;
|
||||||
|
|
||||||
public DanaRStatsActivity() {
|
public TDDStatsActivity() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +122,7 @@ public class DanaRStatsActivity extends Activity {
|
||||||
|
|
||||||
TBB = SP.getString("TBB", "10.00");
|
TBB = SP.getString("TBB", "10.00");
|
||||||
|
|
||||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||||
if (profile != null) {
|
if (profile != null) {
|
||||||
double cppTBB = profile.baseBasalSum();
|
double cppTBB = profile.baseBasalSum();
|
||||||
TBB = decimalFormat.format(cppTBB);
|
TBB = decimalFormat.format(cppTBB);
|
||||||
|
@ -126,6 +130,9 @@ public class DanaRStatsActivity extends Activity {
|
||||||
}
|
}
|
||||||
totalBaseBasal.setText(TBB);
|
totalBaseBasal.setText(TBB);
|
||||||
|
|
||||||
|
if (!ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().needsManualTDDLoad)
|
||||||
|
reloadButton.setVisibility(View.GONE);
|
||||||
|
|
||||||
// stats table
|
// stats table
|
||||||
tl = (TableLayout) findViewById(R.id.main_table);
|
tl = (TableLayout) findViewById(R.id.main_table);
|
||||||
TableRow tr_head = new TableRow(this);
|
TableRow tr_head = new TableRow(this);
|
||||||
|
@ -135,27 +142,27 @@ public class DanaRStatsActivity extends Activity {
|
||||||
TableLayout.LayoutParams.WRAP_CONTENT));
|
TableLayout.LayoutParams.WRAP_CONTENT));
|
||||||
|
|
||||||
TextView label_date = new TextView(this);
|
TextView label_date = new TextView(this);
|
||||||
label_date.setText(getString(R.string.danar_stats_date));
|
label_date.setText(MainApp.gs(R.string.danar_stats_date));
|
||||||
label_date.setTextColor(Color.WHITE);
|
label_date.setTextColor(Color.WHITE);
|
||||||
tr_head.addView(label_date);
|
tr_head.addView(label_date);
|
||||||
|
|
||||||
TextView label_basalrate = new TextView(this);
|
TextView label_basalrate = new TextView(this);
|
||||||
label_basalrate.setText(getString(R.string.danar_stats_basalrate));
|
label_basalrate.setText(MainApp.gs(R.string.danar_stats_basalrate));
|
||||||
label_basalrate.setTextColor(Color.WHITE);
|
label_basalrate.setTextColor(Color.WHITE);
|
||||||
tr_head.addView(label_basalrate);
|
tr_head.addView(label_basalrate);
|
||||||
|
|
||||||
TextView label_bolus = new TextView(this);
|
TextView label_bolus = new TextView(this);
|
||||||
label_bolus.setText(getString(R.string.danar_stats_bolus));
|
label_bolus.setText(MainApp.gs(R.string.danar_stats_bolus));
|
||||||
label_bolus.setTextColor(Color.WHITE);
|
label_bolus.setTextColor(Color.WHITE);
|
||||||
tr_head.addView(label_bolus);
|
tr_head.addView(label_bolus);
|
||||||
|
|
||||||
TextView label_tdd = new TextView(this);
|
TextView label_tdd = new TextView(this);
|
||||||
label_tdd.setText(getString(R.string.danar_stats_tdd));
|
label_tdd.setText(MainApp.gs(R.string.danar_stats_tdd));
|
||||||
label_tdd.setTextColor(Color.WHITE);
|
label_tdd.setTextColor(Color.WHITE);
|
||||||
tr_head.addView(label_tdd);
|
tr_head.addView(label_tdd);
|
||||||
|
|
||||||
TextView label_ratio = new TextView(this);
|
TextView label_ratio = new TextView(this);
|
||||||
label_ratio.setText(getString(R.string.danar_stats_ratio));
|
label_ratio.setText(MainApp.gs(R.string.danar_stats_ratio));
|
||||||
label_ratio.setTextColor(Color.WHITE);
|
label_ratio.setTextColor(Color.WHITE);
|
||||||
tr_head.addView(label_ratio);
|
tr_head.addView(label_ratio);
|
||||||
|
|
||||||
|
@ -173,17 +180,17 @@ public class DanaRStatsActivity extends Activity {
|
||||||
TableLayout.LayoutParams.WRAP_CONTENT));
|
TableLayout.LayoutParams.WRAP_CONTENT));
|
||||||
|
|
||||||
TextView label_cum_amount_days = new TextView(this);
|
TextView label_cum_amount_days = new TextView(this);
|
||||||
label_cum_amount_days.setText(getString(R.string.danar_stats_amount_days));
|
label_cum_amount_days.setText(MainApp.gs(R.string.danar_stats_amount_days));
|
||||||
label_cum_amount_days.setTextColor(Color.WHITE);
|
label_cum_amount_days.setTextColor(Color.WHITE);
|
||||||
ctr_head.addView(label_cum_amount_days);
|
ctr_head.addView(label_cum_amount_days);
|
||||||
|
|
||||||
TextView label_cum_tdd = new TextView(this);
|
TextView label_cum_tdd = new TextView(this);
|
||||||
label_cum_tdd.setText(getString(R.string.danar_stats_tdd));
|
label_cum_tdd.setText(MainApp.gs(R.string.danar_stats_tdd));
|
||||||
label_cum_tdd.setTextColor(Color.WHITE);
|
label_cum_tdd.setTextColor(Color.WHITE);
|
||||||
ctr_head.addView(label_cum_tdd);
|
ctr_head.addView(label_cum_tdd);
|
||||||
|
|
||||||
TextView label_cum_ratio = new TextView(this);
|
TextView label_cum_ratio = new TextView(this);
|
||||||
label_cum_ratio.setText(getString(R.string.danar_stats_ratio));
|
label_cum_ratio.setText(MainApp.gs(R.string.danar_stats_ratio));
|
||||||
label_cum_ratio.setTextColor(Color.WHITE);
|
label_cum_ratio.setTextColor(Color.WHITE);
|
||||||
ctr_head.addView(label_cum_ratio);
|
ctr_head.addView(label_cum_ratio);
|
||||||
|
|
||||||
|
@ -201,17 +208,17 @@ public class DanaRStatsActivity extends Activity {
|
||||||
TableLayout.LayoutParams.WRAP_CONTENT));
|
TableLayout.LayoutParams.WRAP_CONTENT));
|
||||||
|
|
||||||
TextView label_exp_weight = new TextView(this);
|
TextView label_exp_weight = new TextView(this);
|
||||||
label_exp_weight.setText(getString(R.string.danar_stats_weight));
|
label_exp_weight.setText(MainApp.gs(R.string.danar_stats_weight));
|
||||||
label_exp_weight.setTextColor(Color.WHITE);
|
label_exp_weight.setTextColor(Color.WHITE);
|
||||||
etr_head.addView(label_exp_weight);
|
etr_head.addView(label_exp_weight);
|
||||||
|
|
||||||
TextView label_exp_tdd = new TextView(this);
|
TextView label_exp_tdd = new TextView(this);
|
||||||
label_exp_tdd.setText(getString(R.string.danar_stats_tdd));
|
label_exp_tdd.setText(MainApp.gs(R.string.danar_stats_tdd));
|
||||||
label_exp_tdd.setTextColor(Color.WHITE);
|
label_exp_tdd.setTextColor(Color.WHITE);
|
||||||
etr_head.addView(label_exp_tdd);
|
etr_head.addView(label_exp_tdd);
|
||||||
|
|
||||||
TextView label_exp_ratio = new TextView(this);
|
TextView label_exp_ratio = new TextView(this);
|
||||||
label_exp_ratio.setText(getString(R.string.danar_stats_ratio));
|
label_exp_ratio.setText(MainApp.gs(R.string.danar_stats_ratio));
|
||||||
label_exp_ratio.setTextColor(Color.WHITE);
|
label_exp_ratio.setTextColor(Color.WHITE);
|
||||||
etr_head.addView(label_exp_ratio);
|
etr_head.addView(label_exp_ratio);
|
||||||
|
|
||||||
|
@ -229,13 +236,13 @@ public class DanaRStatsActivity extends Activity {
|
||||||
reloadButton.setVisibility(View.GONE);
|
reloadButton.setVisibility(View.GONE);
|
||||||
statusView.setVisibility(View.VISIBLE);
|
statusView.setVisibility(View.VISIBLE);
|
||||||
statsMessage.setVisibility(View.VISIBLE);
|
statsMessage.setVisibility(View.VISIBLE);
|
||||||
statsMessage.setText(getString(R.string.danar_stats_warning_Message));
|
statsMessage.setText(MainApp.gs(R.string.danar_stats_warning_Message));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
ConfigBuilderPlugin.getCommandQueue().loadHistory(RecordTypes.RECORD_TYPE_DAILY, new Callback() {
|
ConfigBuilderPlugin.getPlugin().getCommandQueue().loadTDDs( new Callback() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
loadDataFromDB(RecordTypes.RECORD_TYPE_DAILY);
|
loadDataFromDB();
|
||||||
runOnUiThread(new Runnable() {
|
runOnUiThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
@ -268,18 +275,18 @@ public class DanaRStatsActivity extends Activity {
|
||||||
} else {
|
} else {
|
||||||
SP.putString("TBB", totalBaseBasal.getText().toString());
|
SP.putString("TBB", totalBaseBasal.getText().toString());
|
||||||
TBB = SP.getString("TBB", "");
|
TBB = SP.getString("TBB", "");
|
||||||
loadDataFromDB(RecordTypes.RECORD_TYPE_DAILY);
|
loadDataFromDB();
|
||||||
InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
|
InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
|
||||||
imm.hideSoftInputFromWindow(totalBaseBasal.getWindowToken(), 0);
|
imm.hideSoftInputFromWindow(totalBaseBasal.getWindowToken(), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
loadDataFromDB(RecordTypes.RECORD_TYPE_DAILY);
|
loadDataFromDB();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadDataFromDB(byte type) {
|
private void loadDataFromDB() {
|
||||||
historyList = MainApp.getDbHelper().getDanaRHistoryRecordsByType(type);
|
historyList = MainApp.getDbHelper().getTDDs();
|
||||||
|
|
||||||
//only use newest 10
|
//only use newest 10
|
||||||
historyList = historyList.subList(0, Math.min(10, historyList.size()));
|
historyList = historyList.subList(0, Math.min(10, historyList.size()));
|
||||||
|
@ -288,24 +295,24 @@ public class DanaRStatsActivity extends Activity {
|
||||||
dummies = new LinkedList();
|
dummies = new LinkedList();
|
||||||
DateFormat df = new SimpleDateFormat("dd.MM.");
|
DateFormat df = new SimpleDateFormat("dd.MM.");
|
||||||
for (int i = 0; i < historyList.size() - 1; i++) {
|
for (int i = 0; i < historyList.size() - 1; i++) {
|
||||||
DanaRHistoryRecord elem1 = historyList.get(i);
|
TDD elem1 = historyList.get(i);
|
||||||
DanaRHistoryRecord elem2 = historyList.get(i + 1);
|
TDD elem2 = historyList.get(i + 1);
|
||||||
|
|
||||||
if (!df.format(new Date(elem1.recordDate)).equals(df.format(new Date(elem2.recordDate + 25 * 60 * 60 * 1000)))) {
|
if (!df.format(new Date(elem1.date)).equals(df.format(new Date(elem2.date + 25 * 60 * 60 * 1000)))) {
|
||||||
DanaRHistoryRecord dummy = new DanaRHistoryRecord();
|
TDD dummy = new TDD();
|
||||||
dummy.recordDate = elem1.recordDate - 24 * 60 * 60 * 1000;
|
dummy.date = elem1.date - 24 * 60 * 60 * 1000;
|
||||||
dummy.recordDailyBasal = elem1.recordDailyBasal / 2;
|
dummy.basal = elem1.basal / 2;
|
||||||
dummy.recordDailyBolus = elem1.recordDailyBolus / 2;
|
dummy.bolus = elem1.bolus / 2;
|
||||||
dummies.add(dummy);
|
dummies.add(dummy);
|
||||||
elem1.recordDailyBasal /= 2;
|
elem1.basal /= 2;
|
||||||
elem1.recordDailyBolus /= 2;
|
elem1.bolus /= 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
historyList.addAll(dummies);
|
historyList.addAll(dummies);
|
||||||
Collections.sort(historyList, new Comparator<DanaRHistoryRecord>() {
|
Collections.sort(historyList, new Comparator<TDD>() {
|
||||||
@Override
|
@Override
|
||||||
public int compare(DanaRHistoryRecord lhs, DanaRHistoryRecord rhs) {
|
public int compare(TDD lhs, TDD rhs) {
|
||||||
return (int) (rhs.recordDate - lhs.recordDate);
|
return (int) (rhs.date - lhs.date);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -333,11 +340,13 @@ public class DanaRStatsActivity extends Activity {
|
||||||
double weighted05 = 0d;
|
double weighted05 = 0d;
|
||||||
double weighted07 = 0d;
|
double weighted07 = 0d;
|
||||||
|
|
||||||
for (DanaRHistoryRecord record : historyList) {
|
|
||||||
double tdd = record.recordDailyBolus + record.recordDailyBasal;
|
//TDD table
|
||||||
|
for (TDD record : historyList) {
|
||||||
|
double tdd = record.getTotal();
|
||||||
|
|
||||||
// Create the table row
|
// Create the table row
|
||||||
TableRow tr = new TableRow(DanaRStatsActivity.this);
|
TableRow tr = new TableRow(TDDStatsActivity.this);
|
||||||
if (i % 2 != 0) tr.setBackgroundColor(Color.DKGRAY);
|
if (i % 2 != 0) tr.setBackgroundColor(Color.DKGRAY);
|
||||||
if (dummies.contains(record)) {
|
if (dummies.contains(record)) {
|
||||||
tr.setBackgroundColor(Color.argb(125, 255, 0, 0));
|
tr.setBackgroundColor(Color.argb(125, 255, 0, 0));
|
||||||
|
@ -348,31 +357,31 @@ public class DanaRStatsActivity extends Activity {
|
||||||
TableLayout.LayoutParams.WRAP_CONTENT));
|
TableLayout.LayoutParams.WRAP_CONTENT));
|
||||||
|
|
||||||
// Here create the TextView dynamically
|
// Here create the TextView dynamically
|
||||||
TextView labelDATE = new TextView(DanaRStatsActivity.this);
|
TextView labelDATE = new TextView(TDDStatsActivity.this);
|
||||||
labelDATE.setId(200 + i);
|
labelDATE.setId(200 + i);
|
||||||
labelDATE.setText(df.format(new Date(record.recordDate)));
|
labelDATE.setText(df.format(new Date(record.date)));
|
||||||
labelDATE.setTextColor(Color.WHITE);
|
labelDATE.setTextColor(Color.WHITE);
|
||||||
tr.addView(labelDATE);
|
tr.addView(labelDATE);
|
||||||
|
|
||||||
TextView labelBASAL = new TextView(DanaRStatsActivity.this);
|
TextView labelBASAL = new TextView(TDDStatsActivity.this);
|
||||||
labelBASAL.setId(300 + i);
|
labelBASAL.setId(300 + i);
|
||||||
labelBASAL.setText(DecimalFormatter.to2Decimal(record.recordDailyBasal) + " U");
|
labelBASAL.setText(DecimalFormatter.to2Decimal(record.basal) + " U");
|
||||||
labelBASAL.setTextColor(Color.WHITE);
|
labelBASAL.setTextColor(Color.WHITE);
|
||||||
tr.addView(labelBASAL);
|
tr.addView(labelBASAL);
|
||||||
|
|
||||||
TextView labelBOLUS = new TextView(DanaRStatsActivity.this);
|
TextView labelBOLUS = new TextView(TDDStatsActivity.this);
|
||||||
labelBOLUS.setId(400 + i);
|
labelBOLUS.setId(400 + i);
|
||||||
labelBOLUS.setText(DecimalFormatter.to2Decimal(record.recordDailyBolus) + " U");
|
labelBOLUS.setText(DecimalFormatter.to2Decimal(record.bolus) + " U");
|
||||||
labelBOLUS.setTextColor(Color.WHITE);
|
labelBOLUS.setTextColor(Color.WHITE);
|
||||||
tr.addView(labelBOLUS);
|
tr.addView(labelBOLUS);
|
||||||
|
|
||||||
TextView labelTDD = new TextView(DanaRStatsActivity.this);
|
TextView labelTDD = new TextView(TDDStatsActivity.this);
|
||||||
labelTDD.setId(500 + i);
|
labelTDD.setId(500 + i);
|
||||||
labelTDD.setText(DecimalFormatter.to2Decimal(tdd) + " U");
|
labelTDD.setText(DecimalFormatter.to2Decimal(tdd) + " U");
|
||||||
labelTDD.setTextColor(Color.WHITE);
|
labelTDD.setTextColor(Color.WHITE);
|
||||||
tr.addView(labelTDD);
|
tr.addView(labelTDD);
|
||||||
|
|
||||||
TextView labelRATIO = new TextView(DanaRStatsActivity.this);
|
TextView labelRATIO = new TextView(TDDStatsActivity.this);
|
||||||
labelRATIO.setId(600 + i);
|
labelRATIO.setId(600 + i);
|
||||||
labelRATIO.setText(Math.round(100 * tdd / magicNumber) + " %");
|
labelRATIO.setText(Math.round(100 * tdd / magicNumber) + " %");
|
||||||
labelRATIO.setTextColor(Color.WHITE);
|
labelRATIO.setTextColor(Color.WHITE);
|
||||||
|
@ -383,11 +392,23 @@ public class DanaRStatsActivity extends Activity {
|
||||||
TableLayout.LayoutParams.MATCH_PARENT,
|
TableLayout.LayoutParams.MATCH_PARENT,
|
||||||
TableLayout.LayoutParams.WRAP_CONTENT));
|
TableLayout.LayoutParams.WRAP_CONTENT));
|
||||||
|
|
||||||
sum = sum + tdd;
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
//cumulative TDDs
|
||||||
|
for (TDD record : historyList) {
|
||||||
|
if(!historyList.isEmpty() && df.format(new Date(record.date)).equals(df.format(new Date()))) {
|
||||||
|
//Today should not be included
|
||||||
|
continue;
|
||||||
|
}
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
|
sum = sum + record.getTotal();
|
||||||
|
|
||||||
// Create the cumtable row
|
// Create the cumtable row
|
||||||
TableRow ctr = new TableRow(DanaRStatsActivity.this);
|
TableRow ctr = new TableRow(TDDStatsActivity.this);
|
||||||
if (i % 2 == 0) ctr.setBackgroundColor(Color.DKGRAY);
|
if (i % 2 == 0) ctr.setBackgroundColor(Color.DKGRAY);
|
||||||
ctr.setId(700 + i);
|
ctr.setId(700 + i);
|
||||||
ctr.setLayoutParams(new TableLayout.LayoutParams(
|
ctr.setLayoutParams(new TableLayout.LayoutParams(
|
||||||
|
@ -395,19 +416,19 @@ public class DanaRStatsActivity extends Activity {
|
||||||
TableLayout.LayoutParams.WRAP_CONTENT));
|
TableLayout.LayoutParams.WRAP_CONTENT));
|
||||||
|
|
||||||
// Here create the TextView dynamically
|
// Here create the TextView dynamically
|
||||||
TextView labelDAYS = new TextView(DanaRStatsActivity.this);
|
TextView labelDAYS = new TextView(TDDStatsActivity.this);
|
||||||
labelDAYS.setId(800 + i);
|
labelDAYS.setId(800 + i);
|
||||||
labelDAYS.setText("" + i);
|
labelDAYS.setText("" + i);
|
||||||
labelDAYS.setTextColor(Color.WHITE);
|
labelDAYS.setTextColor(Color.WHITE);
|
||||||
ctr.addView(labelDAYS);
|
ctr.addView(labelDAYS);
|
||||||
|
|
||||||
TextView labelCUMTDD = new TextView(DanaRStatsActivity.this);
|
TextView labelCUMTDD = new TextView(TDDStatsActivity.this);
|
||||||
labelCUMTDD.setId(900 + i);
|
labelCUMTDD.setId(900 + i);
|
||||||
labelCUMTDD.setText(DecimalFormatter.to2Decimal(sum / i) + " U");
|
labelCUMTDD.setText(DecimalFormatter.to2Decimal(sum / i) + " U");
|
||||||
labelCUMTDD.setTextColor(Color.WHITE);
|
labelCUMTDD.setTextColor(Color.WHITE);
|
||||||
ctr.addView(labelCUMTDD);
|
ctr.addView(labelCUMTDD);
|
||||||
|
|
||||||
TextView labelCUMRATIO = new TextView(DanaRStatsActivity.this);
|
TextView labelCUMRATIO = new TextView(TDDStatsActivity.this);
|
||||||
labelCUMRATIO.setId(1000 + i);
|
labelCUMRATIO.setId(1000 + i);
|
||||||
labelCUMRATIO.setText(Math.round(100 * sum / i / magicNumber) + " %");
|
labelCUMRATIO.setText(Math.round(100 * sum / i / magicNumber) + " %");
|
||||||
labelCUMRATIO.setTextColor(Color.WHITE);
|
labelCUMRATIO.setTextColor(Color.WHITE);
|
||||||
|
@ -419,20 +440,25 @@ public class DanaRStatsActivity extends Activity {
|
||||||
TableLayout.LayoutParams.WRAP_CONTENT));
|
TableLayout.LayoutParams.WRAP_CONTENT));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (historyList.size() < 3 || !(df.format(new Date(historyList.get(0).recordDate)).equals(df.format(new Date(System.currentTimeMillis() - 1000 * 60 * 60 * 24))))) {
|
if (isOldData(historyList) && ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().needsManualTDDLoad) {
|
||||||
statsMessage.setVisibility(View.VISIBLE);
|
statsMessage.setVisibility(View.VISIBLE);
|
||||||
statsMessage.setText(getString(R.string.danar_stats_olddata_Message));
|
statsMessage.setText(MainApp.gs(R.string.danar_stats_olddata_Message));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
tl.setBackgroundColor(Color.TRANSPARENT);
|
tl.setBackgroundColor(Color.TRANSPARENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!historyList.isEmpty() && df.format(new Date(historyList.get(0).date)).equals(df.format(new Date()))) {
|
||||||
|
//Today should not be included
|
||||||
|
historyList.remove(0);
|
||||||
|
}
|
||||||
|
|
||||||
Collections.reverse(historyList);
|
Collections.reverse(historyList);
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
for (DanaRHistoryRecord record : historyList) {
|
for (TDD record : historyList) {
|
||||||
double tdd = record.recordDailyBolus + record.recordDailyBasal;
|
double tdd = record.getTotal();
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
weighted03 = tdd;
|
weighted03 = tdd;
|
||||||
weighted05 = tdd;
|
weighted05 = tdd;
|
||||||
|
@ -447,7 +473,7 @@ public class DanaRStatsActivity extends Activity {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the exptable row
|
// Create the exptable row
|
||||||
TableRow etr = new TableRow(DanaRStatsActivity.this);
|
TableRow etr = new TableRow(TDDStatsActivity.this);
|
||||||
if (i % 2 != 0) etr.setBackgroundColor(Color.DKGRAY);
|
if (i % 2 != 0) etr.setBackgroundColor(Color.DKGRAY);
|
||||||
etr.setId(1100 + i);
|
etr.setId(1100 + i);
|
||||||
etr.setLayoutParams(new TableLayout.LayoutParams(
|
etr.setLayoutParams(new TableLayout.LayoutParams(
|
||||||
|
@ -455,13 +481,13 @@ public class DanaRStatsActivity extends Activity {
|
||||||
TableLayout.LayoutParams.WRAP_CONTENT));
|
TableLayout.LayoutParams.WRAP_CONTENT));
|
||||||
|
|
||||||
// Here create the TextView dynamically
|
// Here create the TextView dynamically
|
||||||
TextView labelWEIGHT = new TextView(DanaRStatsActivity.this);
|
TextView labelWEIGHT = new TextView(TDDStatsActivity.this);
|
||||||
labelWEIGHT.setId(1200 + i);
|
labelWEIGHT.setId(1200 + i);
|
||||||
labelWEIGHT.setText("0.3\n" + "0.5\n" + "0.7");
|
labelWEIGHT.setText("0.3\n" + "0.5\n" + "0.7");
|
||||||
labelWEIGHT.setTextColor(Color.WHITE);
|
labelWEIGHT.setTextColor(Color.WHITE);
|
||||||
etr.addView(labelWEIGHT);
|
etr.addView(labelWEIGHT);
|
||||||
|
|
||||||
TextView labelEXPTDD = new TextView(DanaRStatsActivity.this);
|
TextView labelEXPTDD = new TextView(TDDStatsActivity.this);
|
||||||
labelEXPTDD.setId(1300 + i);
|
labelEXPTDD.setId(1300 + i);
|
||||||
labelEXPTDD.setText(DecimalFormatter.to2Decimal(weighted03)
|
labelEXPTDD.setText(DecimalFormatter.to2Decimal(weighted03)
|
||||||
+ " U\n" + DecimalFormatter.to2Decimal(weighted05)
|
+ " U\n" + DecimalFormatter.to2Decimal(weighted05)
|
||||||
|
@ -469,7 +495,7 @@ public class DanaRStatsActivity extends Activity {
|
||||||
labelEXPTDD.setTextColor(Color.WHITE);
|
labelEXPTDD.setTextColor(Color.WHITE);
|
||||||
etr.addView(labelEXPTDD);
|
etr.addView(labelEXPTDD);
|
||||||
|
|
||||||
TextView labelEXPRATIO = new TextView(DanaRStatsActivity.this);
|
TextView labelEXPRATIO = new TextView(TDDStatsActivity.this);
|
||||||
labelEXPRATIO.setId(1400 + i);
|
labelEXPRATIO.setId(1400 + i);
|
||||||
labelEXPRATIO.setText(Math.round(100 * weighted03 / magicNumber) + " %\n"
|
labelEXPRATIO.setText(Math.round(100 * weighted03 / magicNumber) + " %\n"
|
||||||
+ Math.round(100 * weighted05 / magicNumber) + " %\n"
|
+ Math.round(100 * weighted05 / magicNumber) + " %\n"
|
||||||
|
@ -516,4 +542,19 @@ public class DanaRStatsActivity extends Activity {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static boolean isOldData(List<TDD> historyList) {
|
||||||
|
Object activePump = ConfigBuilderPlugin.getPlugin().getActivePump();
|
||||||
|
PumpInterface dana = MainApp.getSpecificPlugin(DanaRPlugin.class);
|
||||||
|
PumpInterface danaRS = MainApp.getSpecificPlugin(DanaRSPlugin.class);
|
||||||
|
PumpInterface danaV2 = MainApp.getSpecificPlugin(DanaRv2Plugin.class);
|
||||||
|
PumpInterface danaKorean = MainApp.getSpecificPlugin(DanaRKoreanPlugin.class);
|
||||||
|
PumpInterface insight = MainApp.getSpecificPlugin(InsightPlugin.class);
|
||||||
|
|
||||||
|
boolean startsYesterday = activePump == dana || activePump == danaRS || activePump == danaV2 || activePump == danaKorean || activePump == insight;
|
||||||
|
|
||||||
|
DateFormat df = new SimpleDateFormat("dd.MM.");
|
||||||
|
return (historyList.size() < 3 || !(df.format(new Date(historyList.get(0).date)).equals(df.format(new Date(System.currentTimeMillis() - (startsYesterday?1000 * 60 * 60 * 24:0))))));
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,227 @@
|
||||||
|
package info.nightscout.androidaps.data;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.Constants;
|
||||||
|
import info.nightscout.androidaps.MainApp;
|
||||||
|
import info.nightscout.androidaps.interfaces.Constraint;
|
||||||
|
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
|
||||||
|
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||||
|
import info.nightscout.androidaps.interfaces.PluginType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mike on 19.03.2018.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ConstraintChecker implements ConstraintsInterface {
|
||||||
|
|
||||||
|
private MainApp mainApp;
|
||||||
|
|
||||||
|
public ConstraintChecker(MainApp mainApp) {
|
||||||
|
this.mainApp = mainApp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Constraint<Boolean> isLoopInvokationAllowed() {
|
||||||
|
return isLoopInvocationAllowed(new Constraint<>(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Constraint<Boolean> isClosedLoopAllowed() {
|
||||||
|
return isClosedLoopAllowed(new Constraint<>(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Constraint<Boolean> isAutosensModeEnabled() {
|
||||||
|
return isAutosensModeEnabled(new Constraint<>(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Constraint<Boolean> isAMAModeEnabled() {
|
||||||
|
return isAMAModeEnabled(new Constraint<>(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Constraint<Boolean> isSMBModeEnabled() {
|
||||||
|
return isSMBModeEnabled(new Constraint<>(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Constraint<Boolean> isUAMEnabled() {
|
||||||
|
return isUAMEnabled(new Constraint<>(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Constraint<Boolean> isAdvancedFilteringEnabled() {
|
||||||
|
return isAdvancedFilteringEnabled(new Constraint<>(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Constraint<Double> getMaxBasalAllowed(Profile profile) {
|
||||||
|
return applyBasalConstraints(new Constraint<>(Constants.REALLYHIGHBASALRATE), profile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Constraint<Integer> getMaxBasalPercentAllowed(Profile profile) {
|
||||||
|
return applyBasalPercentConstraints(new Constraint<>(Constants.REALLYHIGHPERCENTBASALRATE), profile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Constraint<Double> getMaxBolusAllowed() {
|
||||||
|
return applyBolusConstraints(new Constraint<>(Constants.REALLYHIGHBOLUS));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Constraint<Double> getMaxExtendedBolusAllowed() {
|
||||||
|
return applyExtendedBolusConstraints(new Constraint<>(Constants.REALLYHIGHBOLUS));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Constraint<Integer> getMaxCarbsAllowed() {
|
||||||
|
return applyCarbsConstraints(new Constraint<>(Constants.REALLYHIGHCARBS));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Constraint<Double> getMaxIOBAllowed() {
|
||||||
|
return applyMaxIOBConstraints(new Constraint<>(Constants.REALLYHIGHIOB));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Constraint<Boolean> isLoopInvocationAllowed(Constraint<Boolean> value) {
|
||||||
|
|
||||||
|
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||||
|
for (PluginBase p : constraintsPlugins) {
|
||||||
|
ConstraintsInterface constraint = (ConstraintsInterface) p;
|
||||||
|
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
|
||||||
|
constraint.isLoopInvocationAllowed(value);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Constraint<Boolean> isClosedLoopAllowed(Constraint<Boolean> value) {
|
||||||
|
|
||||||
|
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||||
|
for (PluginBase p : constraintsPlugins) {
|
||||||
|
ConstraintsInterface constraint = (ConstraintsInterface) p;
|
||||||
|
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
|
||||||
|
constraint.isClosedLoopAllowed(value);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Constraint<Boolean> isAutosensModeEnabled(Constraint<Boolean> value) {
|
||||||
|
|
||||||
|
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||||
|
for (PluginBase p : constraintsPlugins) {
|
||||||
|
ConstraintsInterface constraint = (ConstraintsInterface) p;
|
||||||
|
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
|
||||||
|
constraint.isAutosensModeEnabled(value);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Constraint<Boolean> isAMAModeEnabled(Constraint<Boolean> value) {
|
||||||
|
|
||||||
|
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||||
|
for (PluginBase p : constraintsPlugins) {
|
||||||
|
ConstraintsInterface constrain = (ConstraintsInterface) p;
|
||||||
|
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
|
||||||
|
constrain.isAMAModeEnabled(value);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Constraint<Boolean> isSMBModeEnabled(Constraint<Boolean> value) {
|
||||||
|
|
||||||
|
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||||
|
for (PluginBase p : constraintsPlugins) {
|
||||||
|
ConstraintsInterface constraint = (ConstraintsInterface) p;
|
||||||
|
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
|
||||||
|
constraint.isSMBModeEnabled(value);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Constraint<Boolean> isUAMEnabled(Constraint<Boolean> value) {
|
||||||
|
|
||||||
|
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||||
|
for (PluginBase p : constraintsPlugins) {
|
||||||
|
ConstraintsInterface constraint = (ConstraintsInterface) p;
|
||||||
|
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
|
||||||
|
constraint.isUAMEnabled(value);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Constraint<Boolean> isAdvancedFilteringEnabled(Constraint<Boolean> value) {
|
||||||
|
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||||
|
for (PluginBase p : constraintsPlugins) {
|
||||||
|
ConstraintsInterface constraint = (ConstraintsInterface) p;
|
||||||
|
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
|
||||||
|
constraint.isAdvancedFilteringEnabled(value);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Constraint<Double> applyBasalConstraints(Constraint<Double> absoluteRate, Profile profile) {
|
||||||
|
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||||
|
for (PluginBase p : constraintsPlugins) {
|
||||||
|
ConstraintsInterface constraint = (ConstraintsInterface) p;
|
||||||
|
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
|
||||||
|
constraint.applyBasalConstraints(absoluteRate, profile);
|
||||||
|
}
|
||||||
|
return absoluteRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Constraint<Integer> applyBasalPercentConstraints(Constraint<Integer> percentRate, Profile profile) {
|
||||||
|
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||||
|
for (PluginBase p : constraintsPlugins) {
|
||||||
|
ConstraintsInterface constrain = (ConstraintsInterface) p;
|
||||||
|
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
|
||||||
|
constrain.applyBasalPercentConstraints(percentRate, profile);
|
||||||
|
}
|
||||||
|
return percentRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Constraint<Double> applyBolusConstraints(Constraint<Double> insulin) {
|
||||||
|
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||||
|
for (PluginBase p : constraintsPlugins) {
|
||||||
|
ConstraintsInterface constrain = (ConstraintsInterface) p;
|
||||||
|
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
|
||||||
|
constrain.applyBolusConstraints(insulin);
|
||||||
|
}
|
||||||
|
return insulin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Constraint<Double> applyExtendedBolusConstraints(Constraint<Double> insulin) {
|
||||||
|
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||||
|
for (PluginBase p : constraintsPlugins) {
|
||||||
|
ConstraintsInterface constrain = (ConstraintsInterface) p;
|
||||||
|
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
|
||||||
|
constrain.applyExtendedBolusConstraints(insulin);
|
||||||
|
}
|
||||||
|
return insulin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Constraint<Integer> applyCarbsConstraints(Constraint<Integer> carbs) {
|
||||||
|
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||||
|
for (PluginBase p : constraintsPlugins) {
|
||||||
|
ConstraintsInterface constrain = (ConstraintsInterface) p;
|
||||||
|
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
|
||||||
|
constrain.applyCarbsConstraints(carbs);
|
||||||
|
}
|
||||||
|
return carbs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Constraint<Double> applyMaxIOBConstraints(Constraint<Double> maxIob) {
|
||||||
|
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||||
|
for (PluginBase p : constraintsPlugins) {
|
||||||
|
ConstraintsInterface constrain = (ConstraintsInterface) p;
|
||||||
|
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
|
||||||
|
constrain.applyMaxIOBConstraints(maxIob);
|
||||||
|
}
|
||||||
|
return maxIob;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -2,14 +2,15 @@ package info.nightscout.androidaps.data;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
|
import com.rits.cloning.Cloner;
|
||||||
|
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import info.nightscout.androidaps.MainApp;
|
|
||||||
import info.nightscout.androidaps.db.CareportalEvent;
|
import info.nightscout.androidaps.db.CareportalEvent;
|
||||||
import info.nightscout.androidaps.db.Source;
|
import info.nightscout.androidaps.db.Source;
|
||||||
import info.nightscout.androidaps.interfaces.InsulinInterface;
|
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by mike on 29.05.2017.
|
* Created by mike on 29.05.2017.
|
||||||
|
@ -17,6 +18,7 @@ import info.nightscout.androidaps.interfaces.InsulinInterface;
|
||||||
|
|
||||||
public class DetailedBolusInfo {
|
public class DetailedBolusInfo {
|
||||||
public long date = System.currentTimeMillis();
|
public long date = System.currentTimeMillis();
|
||||||
|
public long lastKnownBolusTime;
|
||||||
public String eventType = CareportalEvent.MEALBOLUS;
|
public String eventType = CareportalEvent.MEALBOLUS;
|
||||||
public double insulin = 0;
|
public double insulin = 0;
|
||||||
public double carbs = 0;
|
public double carbs = 0;
|
||||||
|
@ -29,14 +31,38 @@ public class DetailedBolusInfo {
|
||||||
public Context context = null; // context for progress dialog
|
public Context context = null; // context for progress dialog
|
||||||
public long pumpId = 0; // id of record if comming from pump history (not a newly created treatment)
|
public long pumpId = 0; // id of record if comming from pump history (not a newly created treatment)
|
||||||
public boolean isSMB = false; // is a Super-MicroBolus
|
public boolean isSMB = false; // is a Super-MicroBolus
|
||||||
|
public long deliverAt = 0; // SMB should be delivered within 1 min from this time
|
||||||
|
public String notes = null;
|
||||||
|
|
||||||
|
public DetailedBolusInfo copy() {
|
||||||
|
DetailedBolusInfo n = new DetailedBolusInfo();
|
||||||
|
n.date = date;
|
||||||
|
n.eventType = eventType;
|
||||||
|
n.insulin = insulin;
|
||||||
|
n.carbs = carbs;
|
||||||
|
n.source = source;
|
||||||
|
n.isValid = isValid;
|
||||||
|
n.glucose = glucose;
|
||||||
|
n.glucoseType = glucoseType;
|
||||||
|
n.carbTime = carbTime;
|
||||||
|
n.boluscalc = boluscalc;
|
||||||
|
n.context = context;
|
||||||
|
n.pumpId = pumpId;
|
||||||
|
n.isSMB = isSMB;
|
||||||
|
n.deliverAt = deliverAt;
|
||||||
|
n.notes = notes;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return new Date(date).toLocaleString() +
|
return new Date(date).toLocaleString() +
|
||||||
|
" date: " + date +
|
||||||
" insulin: " + insulin +
|
" insulin: " + insulin +
|
||||||
" carbs: " + carbs +
|
" carbs: " + carbs +
|
||||||
" isValid: " + isValid +
|
" isValid: " + isValid +
|
||||||
" carbTime: " + carbTime +
|
" carbTime: " + carbTime +
|
||||||
" isSMB: " + isSMB;
|
" isSMB: " + isSMB +
|
||||||
|
" deliverAt: " + new Date(deliverAt).toLocaleString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import java.util.List;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.db.BgReading;
|
import info.nightscout.androidaps.db.BgReading;
|
||||||
|
import info.nightscout.utils.DateUtil;
|
||||||
import info.nightscout.utils.DecimalFormatter;
|
import info.nightscout.utils.DecimalFormatter;
|
||||||
import info.nightscout.utils.Round;
|
import info.nightscout.utils.Round;
|
||||||
|
|
||||||
|
@ -35,21 +36,15 @@ public class GlucoseStatus {
|
||||||
public double avgdelta = 0d;
|
public double avgdelta = 0d;
|
||||||
public double short_avgdelta = 0d;
|
public double short_avgdelta = 0d;
|
||||||
public double long_avgdelta = 0d;
|
public double long_avgdelta = 0d;
|
||||||
|
public long date = 0L;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return MainApp.sResources.getString(R.string.glucose) + " " + DecimalFormatter.to0Decimal(glucose) + " mg/dl\n" +
|
return MainApp.gs(R.string.glucose) + " " + DecimalFormatter.to0Decimal(glucose) + " mg/dl\n" +
|
||||||
MainApp.sResources.getString(R.string.delta) + " " + DecimalFormatter.to0Decimal(delta) + " mg/dl\n" +
|
MainApp.gs(R.string.delta) + " " + DecimalFormatter.to0Decimal(delta) + " mg/dl\n" +
|
||||||
MainApp.sResources.getString(R.string.short_avgdelta) + " " + DecimalFormatter.to2Decimal(short_avgdelta) + " mg/dl\n" +
|
MainApp.gs(R.string.short_avgdelta) + " " + DecimalFormatter.to2Decimal(short_avgdelta) + " mg/dl\n" +
|
||||||
MainApp.sResources.getString(R.string.long_avgdelta) + " " + DecimalFormatter.to2Decimal(long_avgdelta) + " mg/dl";
|
MainApp.gs(R.string.long_avgdelta) + " " + DecimalFormatter.to2Decimal(long_avgdelta) + " mg/dl";
|
||||||
}
|
|
||||||
|
|
||||||
public Spanned toSpanned() {
|
|
||||||
return Html.fromHtml("<b>" + MainApp.sResources.getString(R.string.glucose) + "</b>: " + DecimalFormatter.to0Decimal(glucose) + " mg/dl<br>" +
|
|
||||||
"<b>" + MainApp.sResources.getString(R.string.delta) + "</b>: " + DecimalFormatter.to0Decimal(delta) + " mg/dl<br>" +
|
|
||||||
"<b>" + MainApp.sResources.getString(R.string.short_avgdelta) + "</b>: " + DecimalFormatter.to2Decimal(short_avgdelta) + " mg/dl<br>" +
|
|
||||||
"<b>" + MainApp.sResources.getString(R.string.long_avgdelta) + "</b>: " + DecimalFormatter.to2Decimal(long_avgdelta) + " mg/dl");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public GlucoseStatus() {
|
public GlucoseStatus() {
|
||||||
|
@ -74,11 +69,15 @@ public class GlucoseStatus {
|
||||||
@Nullable
|
@Nullable
|
||||||
public static GlucoseStatus getGlucoseStatusData(boolean allowOldData) {
|
public static GlucoseStatus getGlucoseStatusData(boolean allowOldData) {
|
||||||
// load 45min
|
// load 45min
|
||||||
long fromtime = (long) (System.currentTimeMillis() - 60 * 1000L * 45);
|
long fromtime = DateUtil.now() - 60 * 1000L * 45;
|
||||||
List<BgReading> data = MainApp.getDbHelper().getBgreadingsDataFromTime(fromtime, false);
|
List<BgReading> data = MainApp.getDbHelper().getBgreadingsDataFromTime(fromtime, false);
|
||||||
|
|
||||||
int sizeRecords = data.size();
|
int sizeRecords = data.size();
|
||||||
if (sizeRecords < 1 || (data.get(0).date < System.currentTimeMillis() - 7 * 60 * 1000L && !allowOldData)) {
|
if (sizeRecords == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.get(0).date < DateUtil.now() - 7 * 60 * 1000L && !allowOldData) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,13 +85,14 @@ public class GlucoseStatus {
|
||||||
long now_date = now.date;
|
long now_date = now.date;
|
||||||
double change;
|
double change;
|
||||||
|
|
||||||
if (sizeRecords < 2) {
|
if (sizeRecords == 1) {
|
||||||
GlucoseStatus status = new GlucoseStatus();
|
GlucoseStatus status = new GlucoseStatus();
|
||||||
status.glucose = now.value;
|
status.glucose = now.value;
|
||||||
status.short_avgdelta = 0d;
|
status.short_avgdelta = 0d;
|
||||||
status.delta = 0d;
|
status.delta = 0d;
|
||||||
status.long_avgdelta = 0d;
|
status.long_avgdelta = 0d;
|
||||||
status.avgdelta = 0d; // for OpenAPS MA
|
status.avgdelta = 0d; // for OpenAPS MA
|
||||||
|
status.date = now_date;
|
||||||
return status.round();
|
return status.round();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,6 +133,7 @@ public class GlucoseStatus {
|
||||||
|
|
||||||
GlucoseStatus status = new GlucoseStatus();
|
GlucoseStatus status = new GlucoseStatus();
|
||||||
status.glucose = now.value;
|
status.glucose = now.value;
|
||||||
|
status.date = now_date;
|
||||||
|
|
||||||
status.short_avgdelta = average(short_deltas);
|
status.short_avgdelta = average(short_deltas);
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,11 @@ import info.nightscout.androidaps.interfaces.Interval;
|
||||||
|
|
||||||
public abstract class Intervals<T extends Interval> {
|
public abstract class Intervals<T extends Interval> {
|
||||||
|
|
||||||
LongSparseArray<T> rawData = new LongSparseArray<T>(); // oldest at index 0
|
LongSparseArray<T> rawData; // oldest at index 0
|
||||||
|
|
||||||
|
public Intervals() {
|
||||||
|
rawData = new LongSparseArray<T>();
|
||||||
|
}
|
||||||
|
|
||||||
public synchronized Intervals reset() {
|
public synchronized Intervals reset() {
|
||||||
rawData = new LongSparseArray<T>();
|
rawData = new LongSparseArray<T>();
|
||||||
|
@ -27,8 +31,7 @@ public abstract class Intervals<T extends Interval> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The List must be sorted by `T.start()` in ascending order
|
* The List must be sorted by `T.start()` in ascending order
|
||||||
*
|
*/
|
||||||
* */
|
|
||||||
public synchronized void add(List<T> list) {
|
public synchronized void add(List<T> list) {
|
||||||
for (T interval : list) {
|
for (T interval : list) {
|
||||||
rawData.put(interval.start(), interval);
|
rawData.put(interval.start(), interval);
|
||||||
|
@ -36,6 +39,10 @@ public abstract class Intervals<T extends Interval> {
|
||||||
merge();
|
merge();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public synchronized void add(T interval) {
|
||||||
|
rawData.put(interval.start(), interval);
|
||||||
|
merge();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public synchronized List<T> getList() {
|
public synchronized List<T> getList() {
|
||||||
|
@ -47,7 +54,7 @@ public abstract class Intervals<T extends Interval> {
|
||||||
|
|
||||||
public synchronized List<T> getReversedList() {
|
public synchronized List<T> getReversedList() {
|
||||||
List<T> list = new ArrayList<>();
|
List<T> list = new ArrayList<>();
|
||||||
for (int i = rawData.size() -1; i>=0; i--)
|
for (int i = rawData.size() - 1; i >= 0; i--)
|
||||||
list.add(rawData.valueAt(i));
|
list.add(rawData.valueAt(i));
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
@ -86,5 +93,4 @@ public abstract class Intervals<T extends Interval> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -7,6 +7,16 @@ public class Iob {
|
||||||
public double iobContrib = 0d;
|
public double iobContrib = 0d;
|
||||||
public double activityContrib = 0d;
|
public double activityContrib = 0d;
|
||||||
|
|
||||||
|
public Iob iobContrib(double iobContrib) {
|
||||||
|
this.iobContrib = iobContrib;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iob activityContrib(double activityContrib) {
|
||||||
|
this.activityContrib = activityContrib;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public Iob plus(Iob iob) {
|
public Iob plus(Iob iob) {
|
||||||
iobContrib += iob.iobContrib;
|
iobContrib += iob.iobContrib;
|
||||||
activityContrib += iob.activityContrib;
|
activityContrib += iob.activityContrib;
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package info.nightscout.androidaps.data;
|
package info.nightscout.androidaps.data;
|
||||||
|
|
||||||
|
import com.rits.cloning.Cloner;
|
||||||
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -21,8 +23,8 @@ public class IobTotal {
|
||||||
public double hightempinsulin;
|
public double hightempinsulin;
|
||||||
|
|
||||||
// oref1
|
// oref1
|
||||||
public double microBolusInsulin;
|
public long lastBolusTime;
|
||||||
public double microBolusIOB;
|
public IobTotal iobWithZeroTemp;
|
||||||
|
|
||||||
public double netInsulin = 0d; // for calculations from temp basals only
|
public double netInsulin = 0d; // for calculations from temp basals only
|
||||||
public double netRatio = 0d; // net ratio at start of temp basal
|
public double netRatio = 0d; // net ratio at start of temp basal
|
||||||
|
@ -31,6 +33,12 @@ public class IobTotal {
|
||||||
|
|
||||||
long time;
|
long time;
|
||||||
|
|
||||||
|
|
||||||
|
public IobTotal copy() {
|
||||||
|
Cloner cloner = new Cloner();
|
||||||
|
return cloner.deepClone(this);
|
||||||
|
}
|
||||||
|
|
||||||
public IobTotal(long time) {
|
public IobTotal(long time) {
|
||||||
this.iob = 0d;
|
this.iob = 0d;
|
||||||
this.activity = 0d;
|
this.activity = 0d;
|
||||||
|
@ -38,8 +46,7 @@ public class IobTotal {
|
||||||
this.basaliob = 0d;
|
this.basaliob = 0d;
|
||||||
this.netbasalinsulin = 0d;
|
this.netbasalinsulin = 0d;
|
||||||
this.hightempinsulin = 0d;
|
this.hightempinsulin = 0d;
|
||||||
this.microBolusInsulin = 0d;
|
this.lastBolusTime = 0;
|
||||||
this.microBolusIOB = 0d;
|
|
||||||
this.time = time;
|
this.time = time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,8 +59,6 @@ public class IobTotal {
|
||||||
hightempinsulin += other.hightempinsulin;
|
hightempinsulin += other.hightempinsulin;
|
||||||
netInsulin += other.netInsulin;
|
netInsulin += other.netInsulin;
|
||||||
extendedBolusInsulin += other.extendedBolusInsulin;
|
extendedBolusInsulin += other.extendedBolusInsulin;
|
||||||
microBolusInsulin += other.microBolusInsulin;
|
|
||||||
microBolusIOB += other.microBolusIOB;
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,11 +67,13 @@ public class IobTotal {
|
||||||
result.iob = bolusIOB.iob + basalIob.basaliob;
|
result.iob = bolusIOB.iob + basalIob.basaliob;
|
||||||
result.activity = bolusIOB.activity + basalIob.activity;
|
result.activity = bolusIOB.activity + basalIob.activity;
|
||||||
result.bolussnooze = bolusIOB.bolussnooze;
|
result.bolussnooze = bolusIOB.bolussnooze;
|
||||||
result.basaliob = basalIob.basaliob;
|
result.basaliob = bolusIOB.basaliob + basalIob.basaliob;
|
||||||
result.netbasalinsulin = basalIob.netbasalinsulin;
|
result.netbasalinsulin = bolusIOB.netbasalinsulin + basalIob.netbasalinsulin;
|
||||||
result.hightempinsulin = basalIob.hightempinsulin;
|
result.hightempinsulin = basalIob.hightempinsulin + bolusIOB.hightempinsulin;
|
||||||
result.microBolusInsulin = bolusIOB.microBolusInsulin + basalIob.microBolusInsulin;
|
result.netInsulin = basalIob.netInsulin + bolusIOB.netInsulin;
|
||||||
result.microBolusIOB = bolusIOB.microBolusIOB + basalIob.microBolusIOB;
|
result.extendedBolusInsulin = basalIob.extendedBolusInsulin + bolusIOB.extendedBolusInsulin;
|
||||||
|
result.lastBolusTime = bolusIOB.lastBolusTime;
|
||||||
|
result.iobWithZeroTemp = basalIob.iobWithZeroTemp;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,8 +84,8 @@ public class IobTotal {
|
||||||
this.basaliob = Round.roundTo(this.basaliob, 0.001);
|
this.basaliob = Round.roundTo(this.basaliob, 0.001);
|
||||||
this.netbasalinsulin = Round.roundTo(this.netbasalinsulin, 0.001);
|
this.netbasalinsulin = Round.roundTo(this.netbasalinsulin, 0.001);
|
||||||
this.hightempinsulin = Round.roundTo(this.hightempinsulin, 0.001);
|
this.hightempinsulin = Round.roundTo(this.hightempinsulin, 0.001);
|
||||||
this.microBolusInsulin = Round.roundTo(this.microBolusInsulin, 0.001);
|
this.netInsulin = Round.roundTo(this.netInsulin, 0.001);
|
||||||
this.microBolusIOB = Round.roundTo(this.microBolusIOB, 0.001);
|
this.extendedBolusInsulin = Round.roundTo(this.extendedBolusInsulin, 0.001);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +109,24 @@ public class IobTotal {
|
||||||
json.put("basaliob", basaliob);
|
json.put("basaliob", basaliob);
|
||||||
json.put("bolussnooze", bolussnooze);
|
json.put("bolussnooze", bolussnooze);
|
||||||
json.put("activity", activity);
|
json.put("activity", activity);
|
||||||
|
json.put("lastBolusTime", lastBolusTime);
|
||||||
json.put("time", DateUtil.toISOString(new Date(time)));
|
json.put("time", DateUtil.toISOString(new Date(time)));
|
||||||
|
/*
|
||||||
|
|
||||||
|
This is requested by SMB determine_basal but by based on Scott's info
|
||||||
|
it's MDT specific safety check only
|
||||||
|
It's causing rounding issues in determine_basal
|
||||||
|
|
||||||
|
JSONObject lastTemp = new JSONObject();
|
||||||
|
lastTemp.put("date", lastTempDate);
|
||||||
|
lastTemp.put("rate", lastTempRate);
|
||||||
|
lastTemp.put("duration", lastTempDuration);
|
||||||
|
json.put("lastTemp", lastTemp);
|
||||||
|
*/
|
||||||
|
if (iobWithZeroTemp != null) {
|
||||||
|
JSONObject iwzt = iobWithZeroTemp.determineBasalJson();
|
||||||
|
json.put("iobWithZeroTemp", iwzt);
|
||||||
|
}
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,4 +7,9 @@ public class MealData {
|
||||||
public double boluses = 0d;
|
public double boluses = 0d;
|
||||||
public double carbs = 0d;
|
public double carbs = 0d;
|
||||||
public double mealCOB = 0.0d;
|
public double mealCOB = 0.0d;
|
||||||
|
public double slopeFromMaxDeviation = 0;
|
||||||
|
public double slopeFromMinDeviation = 999;
|
||||||
|
public long lastBolusTime;
|
||||||
|
public long lastCarbTime = 0L;
|
||||||
|
public double usedMinCarbsImpact = 0d;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,9 @@ package info.nightscout.androidaps.data;
|
||||||
|
|
||||||
|
|
||||||
import android.support.annotation.Nullable;
|
import android.support.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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -11,6 +13,14 @@ import info.nightscout.androidaps.interfaces.Interval;
|
||||||
|
|
||||||
public class NonOverlappingIntervals<T extends Interval> extends Intervals<T> {
|
public class NonOverlappingIntervals<T extends Interval> extends Intervals<T> {
|
||||||
|
|
||||||
|
public NonOverlappingIntervals() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public NonOverlappingIntervals (Intervals<T> other) {
|
||||||
|
rawData = other.rawData.clone();
|
||||||
|
}
|
||||||
|
|
||||||
protected synchronized void merge() {
|
protected 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);
|
||||||
|
@ -27,4 +37,5 @@ public class NonOverlappingIntervals<T extends Interval> extends Intervals<T> {
|
||||||
if (index >= 0) return rawData.valueAt(index);
|
if (index >= 0) return rawData.valueAt(index);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,18 +11,26 @@ import info.nightscout.androidaps.interfaces.Interval;
|
||||||
|
|
||||||
public class OverlappingIntervals<T extends Interval> extends Intervals<T> {
|
public class OverlappingIntervals<T extends Interval> extends Intervals<T> {
|
||||||
|
|
||||||
|
public OverlappingIntervals() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public OverlappingIntervals(Intervals<T> other) {
|
||||||
|
rawData = other.rawData.clone();
|
||||||
|
}
|
||||||
|
|
||||||
protected synchronized void merge() {
|
protected synchronized void merge() {
|
||||||
boolean needToCut = false;
|
boolean needToCut = false;
|
||||||
long cutTime = 0;
|
long cutTime = 0;
|
||||||
|
|
||||||
for (int index = rawData.size()-1; index >= 0; index--) { //begin with newest
|
for (int index = rawData.size() - 1; index >= 0; index--) { //begin with newest
|
||||||
Interval cur = rawData.valueAt(index);
|
Interval cur = rawData.valueAt(index);
|
||||||
if (cur.isEndingEvent()){
|
if (cur.isEndingEvent()) {
|
||||||
needToCut = true;
|
needToCut = true;
|
||||||
cutTime = cur.start();
|
cutTime = cur.start();
|
||||||
} else {
|
} else {
|
||||||
//event that is no EndingEvent might need to be stopped by an ending event
|
//event that is no EndingEvent might need to be stopped by an ending event
|
||||||
if(needToCut&&cur.end() > cutTime){
|
if (needToCut && cur.end() > cutTime) {
|
||||||
cur.cutEndTo(cutTime);
|
cur.cutEndTo(cutTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,9 +39,9 @@ public class OverlappingIntervals<T extends Interval> extends Intervals<T> {
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public synchronized T getValueByInterval(long time) {
|
public synchronized T getValueByInterval(long time) {
|
||||||
for (int index = rawData.size()-1; index >= 0; index--) { //begin with newest
|
for (int index = rawData.size() - 1; index >= 0; index--) { //begin with newest
|
||||||
T cur = rawData.valueAt(index);
|
T cur = rawData.valueAt(index);
|
||||||
if (cur.match(time)){
|
if (cur.match(time)) {
|
||||||
return cur;
|
return cur;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,6 @@ package info.nightscout.androidaps.data;
|
||||||
|
|
||||||
import android.support.v4.util.LongSparseArray;
|
import android.support.v4.util.LongSparseArray;
|
||||||
|
|
||||||
import com.crashlytics.android.Crashlytics;
|
|
||||||
|
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
@ -20,50 +18,78 @@ import info.nightscout.androidaps.R;
|
||||||
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.ConfigBuilder.ConfigBuilderPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification;
|
|
||||||
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
|
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
|
||||||
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
|
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
|
||||||
import info.nightscout.utils.DateUtil;
|
import info.nightscout.utils.DateUtil;
|
||||||
import info.nightscout.utils.DecimalFormatter;
|
import info.nightscout.utils.DecimalFormatter;
|
||||||
import info.nightscout.utils.ToastUtils;
|
import info.nightscout.utils.FabricPrivacy;
|
||||||
|
|
||||||
public class Profile {
|
public class Profile {
|
||||||
private static Logger log = LoggerFactory.getLogger(Profile.class);
|
private static Logger log = LoggerFactory.getLogger(Profile.class);
|
||||||
|
|
||||||
private JSONObject json;
|
private JSONObject json;
|
||||||
private String units = null;
|
private String units;
|
||||||
private double dia = Constants.defaultDIA;
|
private double dia;
|
||||||
private TimeZone timeZone = TimeZone.getDefault();
|
private TimeZone timeZone;
|
||||||
private JSONArray isf;
|
private JSONArray isf;
|
||||||
private LongSparseArray<Double> isf_v = null; // oldest at index 0
|
private LongSparseArray<Double> isf_v; // oldest at index 0
|
||||||
private JSONArray ic;
|
private JSONArray ic;
|
||||||
private LongSparseArray<Double> ic_v = null; // oldest at index 0
|
private LongSparseArray<Double> ic_v; // oldest at index 0
|
||||||
private JSONArray basal;
|
private JSONArray basal;
|
||||||
private LongSparseArray<Double> basal_v = null; // oldest at index 0
|
private LongSparseArray<Double> basal_v; // oldest at index 0
|
||||||
private JSONArray targetLow;
|
private JSONArray targetLow;
|
||||||
private LongSparseArray<Double> targetLow_v = null; // oldest at index 0
|
private LongSparseArray<Double> targetLow_v; // oldest at index 0
|
||||||
private JSONArray targetHigh;
|
private JSONArray targetHigh;
|
||||||
private LongSparseArray<Double> targetHigh_v = null; // oldest at index 0
|
private LongSparseArray<Double> targetHigh_v; // oldest at index 0
|
||||||
|
|
||||||
private int percentage = 100;
|
private int percentage;
|
||||||
private int timeshift = 0;
|
private int timeshift;
|
||||||
|
|
||||||
private boolean isValid = true;
|
protected boolean isValid;
|
||||||
private boolean isValidated = false;
|
protected boolean isValidated;
|
||||||
|
|
||||||
|
// Default constructor for tests
|
||||||
|
protected Profile() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
if (json != null)
|
||||||
|
return json.toString();
|
||||||
|
else
|
||||||
|
return "Profile has no JSON";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constructor from profileStore JSON
|
||||||
public Profile(JSONObject json, String units) {
|
public Profile(JSONObject json, String units) {
|
||||||
this(json, 100, 0);
|
init(json, 100, 0);
|
||||||
if (this.units == null) {
|
if (this.units == null) {
|
||||||
if (units != null)
|
if (units != null)
|
||||||
this.units = units;
|
this.units = units;
|
||||||
else {
|
else {
|
||||||
Crashlytics.log("Profile failover failed too");
|
FabricPrivacy.log("Profile failover failed too");
|
||||||
this.units = Constants.MGDL;
|
this.units = Constants.MGDL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Profile(JSONObject json, int percentage, int timeshift) {
|
public Profile(JSONObject json, int percentage, int timeshift) {
|
||||||
|
init(json, percentage, timeshift);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void init(JSONObject json, int percentage, int timeshift) {
|
||||||
|
units = null;
|
||||||
|
dia = Constants.defaultDIA;
|
||||||
|
timeZone = TimeZone.getDefault();
|
||||||
|
isf_v = null;
|
||||||
|
ic_v = null;
|
||||||
|
basal_v = null;
|
||||||
|
targetLow_v = null;
|
||||||
|
targetHigh_v = null;
|
||||||
|
|
||||||
|
isValid = true;
|
||||||
|
isValidated = false;
|
||||||
|
|
||||||
this.percentage = percentage;
|
this.percentage = percentage;
|
||||||
this.timeshift = timeshift;
|
this.timeshift = timeshift;
|
||||||
this.json = json;
|
this.json = json;
|
||||||
|
@ -77,53 +103,12 @@ public class Profile {
|
||||||
if (json.has("timezone"))
|
if (json.has("timezone"))
|
||||||
timeZone = TimeZone.getTimeZone(json.getString("timezone"));
|
timeZone = TimeZone.getTimeZone(json.getString("timezone"));
|
||||||
isf = json.getJSONArray("sens");
|
isf = json.getJSONArray("sens");
|
||||||
if (getIsf(0) == null) {
|
|
||||||
int defaultISF = units.equals(Constants.MGDL) ? 400 : 20;
|
|
||||||
isf = new JSONArray("[{\"time\":\"00:00\",\"value\":\"" + defaultISF + "\",\"timeAsSeconds\":\"0\"}]");
|
|
||||||
Notification noisf = new Notification(Notification.ISF_MISSING, MainApp.sResources.getString(R.string.isfmissing), Notification.URGENT);
|
|
||||||
MainApp.bus().post(new EventNewNotification(noisf));
|
|
||||||
} else {
|
|
||||||
MainApp.bus().post(new EventDismissNotification(Notification.ISF_MISSING));
|
|
||||||
}
|
|
||||||
ic = json.getJSONArray("carbratio");
|
ic = json.getJSONArray("carbratio");
|
||||||
if (getIc(0) == null) {
|
|
||||||
int defaultIC = 25;
|
|
||||||
ic = new JSONArray("[{\"time\":\"00:00\",\"value\":\"" + defaultIC + "\",\"timeAsSeconds\":\"0\"}]");
|
|
||||||
Notification noic = new Notification(Notification.IC_MISSING, MainApp.sResources.getString(R.string.icmissing), Notification.URGENT);
|
|
||||||
MainApp.bus().post(new EventNewNotification(noic));
|
|
||||||
} else {
|
|
||||||
MainApp.bus().post(new EventDismissNotification(Notification.IC_MISSING));
|
|
||||||
}
|
|
||||||
basal = json.getJSONArray("basal");
|
basal = json.getJSONArray("basal");
|
||||||
if (getBasal(0) == null) {
|
|
||||||
double defaultBasal = 0.1d;
|
|
||||||
basal = new JSONArray("[{\"time\":\"00:00\",\"value\":\"" + defaultBasal + "\",\"timeAsSeconds\":\"0\"}]");
|
|
||||||
Notification nobasal = new Notification(Notification.BASAL_MISSING, MainApp.sResources.getString(R.string.basalmissing), Notification.URGENT);
|
|
||||||
MainApp.bus().post(new EventNewNotification(nobasal));
|
|
||||||
} else {
|
|
||||||
MainApp.bus().post(new EventDismissNotification(Notification.BASAL_MISSING));
|
|
||||||
}
|
|
||||||
targetLow = json.getJSONArray("target_low");
|
targetLow = json.getJSONArray("target_low");
|
||||||
if (getTargetLow(0) == null) {
|
|
||||||
double defaultLow = units.equals(Constants.MGDL) ? 120 : 6;
|
|
||||||
targetLow = new JSONArray("[{\"time\":\"00:00\",\"value\":\"" + defaultLow + "\",\"timeAsSeconds\":\"0\"}]");
|
|
||||||
Notification notarget = new Notification(Notification.TARGET_MISSING, MainApp.sResources.getString(R.string.targetmissing), Notification.URGENT);
|
|
||||||
MainApp.bus().post(new EventNewNotification(notarget));
|
|
||||||
} else {
|
|
||||||
MainApp.bus().post(new EventDismissNotification(Notification.TARGET_MISSING));
|
|
||||||
}
|
|
||||||
targetHigh = json.getJSONArray("target_high");
|
targetHigh = json.getJSONArray("target_high");
|
||||||
if (getTargetHigh(0) == null) {
|
|
||||||
double defaultHigh = units.equals(Constants.MGDL) ? 160 : 8;
|
|
||||||
targetHigh = new JSONArray("[{\"time\":\"00:00\",\"value\":\"" + defaultHigh + "\",\"timeAsSeconds\":\"0\"}]");
|
|
||||||
Notification notarget = new Notification(Notification.TARGET_MISSING, MainApp.sResources.getString(R.string.targetmissing), Notification.URGENT);
|
|
||||||
MainApp.bus().post(new EventNewNotification(notarget));
|
|
||||||
} else {
|
|
||||||
MainApp.bus().post(new EventDismissNotification(Notification.TARGET_MISSING));
|
|
||||||
}
|
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception", e);
|
||||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.invalidprofile));
|
|
||||||
isValid = false;
|
isValid = false;
|
||||||
isValidated = true;
|
isValidated = true;
|
||||||
}
|
}
|
||||||
|
@ -132,7 +117,7 @@ public class Profile {
|
||||||
public String log() {
|
public String log() {
|
||||||
String ret = "\n";
|
String ret = "\n";
|
||||||
for (Integer hour = 0; hour < 24; hour++) {
|
for (Integer hour = 0; hour < 24; hour++) {
|
||||||
double value = getBasal((Integer) (hour * 60 * 60));
|
double value = getBasalTimeFromMidnight((Integer) (hour * 60 * 60));
|
||||||
ret += "NS basal value for " + hour + ":00 is " + value + "\n";
|
ret += "NS basal value for " + hour + ":00 is " + value + "\n";
|
||||||
}
|
}
|
||||||
ret += "NS units: " + getUnits();
|
ret += "NS units: " + getUnits();
|
||||||
|
@ -154,6 +139,10 @@ public class Profile {
|
||||||
}
|
}
|
||||||
|
|
||||||
// mmol or mg/dl
|
// mmol or mg/dl
|
||||||
|
public void setUnits(String units) {
|
||||||
|
this.units = units;
|
||||||
|
}
|
||||||
|
|
||||||
public String getUnits() {
|
public String getUnits() {
|
||||||
return units;
|
return units;
|
||||||
}
|
}
|
||||||
|
@ -163,6 +152,11 @@ public class Profile {
|
||||||
}
|
}
|
||||||
|
|
||||||
private LongSparseArray<Double> convertToSparseArray(JSONArray array) {
|
private LongSparseArray<Double> convertToSparseArray(JSONArray array) {
|
||||||
|
if (array == null) {
|
||||||
|
isValid = false;
|
||||||
|
return new LongSparseArray<>();
|
||||||
|
}
|
||||||
|
|
||||||
double multiplier = getMultiplier(array);
|
double multiplier = getMultiplier(array);
|
||||||
|
|
||||||
LongSparseArray<Double> sparse = new LongSparseArray<>();
|
LongSparseArray<Double> sparse = new LongSparseArray<>();
|
||||||
|
@ -194,6 +188,10 @@ public class Profile {
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized boolean isValid(String from) {
|
public synchronized boolean isValid(String from) {
|
||||||
|
return isValid(from, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized boolean isValid(String from, boolean notify) {
|
||||||
if (!isValid)
|
if (!isValid)
|
||||||
return false;
|
return false;
|
||||||
if (!isValidated) {
|
if (!isValidated) {
|
||||||
|
@ -212,27 +210,40 @@ public class Profile {
|
||||||
if (targetHigh_v == null)
|
if (targetHigh_v == null)
|
||||||
targetHigh_v = convertToSparseArray(targetHigh);
|
targetHigh_v = convertToSparseArray(targetHigh);
|
||||||
validate(targetHigh_v);
|
validate(targetHigh_v);
|
||||||
|
|
||||||
|
if (targetHigh_v.size() != targetLow_v.size()) isValid = false;
|
||||||
|
else for (int i = 0; i < targetHigh_v.size(); i++)
|
||||||
|
if (targetHigh_v.valueAt(i) < targetLow_v.valueAt(i))
|
||||||
|
isValid = false;
|
||||||
|
|
||||||
isValidated = true;
|
isValidated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isValid) {
|
if (isValid) {
|
||||||
// Check for hours alignment
|
// Check for hours alignment
|
||||||
for (int index = 0; index < basal_v.size(); index++) {
|
PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
|
||||||
long secondsFromMidnight = basal_v.keyAt(index);
|
if (pump != null && !pump.getPumpDescription().is30minBasalRatesCapable) {
|
||||||
if (secondsFromMidnight % 3600 != 0) {
|
for (int index = 0; index < basal_v.size(); index++) {
|
||||||
Notification notification = new Notification(Notification.BASAL_PROFILE_NOT_ALIGNED_TO_HOURS, String.format(MainApp.gs(R.string.basalprofilenotaligned), from), Notification.NORMAL);
|
long secondsFromMidnight = basal_v.keyAt(index);
|
||||||
MainApp.bus().post(new EventNewNotification(notification));
|
if (notify && secondsFromMidnight % 3600 != 0) {
|
||||||
|
Notification notification = new Notification(Notification.BASAL_PROFILE_NOT_ALIGNED_TO_HOURS, String.format(MainApp.gs(R.string.basalprofilenotaligned), from), Notification.NORMAL);
|
||||||
|
MainApp.bus().post(new EventNewNotification(notification));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for minimal basal value
|
// Check for minimal basal value
|
||||||
PumpInterface pump = ConfigBuilderPlugin.getActivePump();
|
|
||||||
if (pump != null) {
|
if (pump != null) {
|
||||||
PumpDescription description = pump.getPumpDescription();
|
PumpDescription description = pump.getPumpDescription();
|
||||||
for (int i = 0; i < basal_v.size(); i++) {
|
for (int i = 0; i < basal_v.size(); i++) {
|
||||||
if (basal_v.valueAt(i) < description.basalMinimumRate) {
|
if (basal_v.valueAt(i) < description.basalMinimumRate) {
|
||||||
basal_v.setValueAt(i, description.basalMinimumRate);
|
basal_v.setValueAt(i, description.basalMinimumRate);
|
||||||
MainApp.bus().post(new EventNewNotification(new Notification(Notification.MINIMAL_BASAL_VALUE_REPLACED, String.format(MainApp.gs(R.string.minimalbasalvaluereplaced), from), Notification.NORMAL)));
|
if (notify)
|
||||||
|
sendBelowMinimumNotification(from);
|
||||||
|
} else if (basal_v.valueAt(i) > description.basalMaximumRate) {
|
||||||
|
basal_v.setValueAt(i, description.basalMaximumRate);
|
||||||
|
if (notify)
|
||||||
|
sendAboveMaximumNotification(from);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -242,10 +253,18 @@ public class Profile {
|
||||||
isValidated = false;
|
isValidated = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return isValid;
|
return isValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void sendBelowMinimumNotification(String from) {
|
||||||
|
MainApp.bus().post(new EventNewNotification(new Notification(Notification.MINIMAL_BASAL_VALUE_REPLACED, String.format(MainApp.gs(R.string.minimalbasalvaluereplaced), from), Notification.NORMAL)));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void sendAboveMaximumNotification(String from) {
|
||||||
|
MainApp.bus().post(new EventNewNotification(new Notification(Notification.MAXIMUM_BASAL_VALUE_REPLACED, String.format(MainApp.gs(R.string.maximumbasalvaluereplaced), from), Notification.NORMAL)));
|
||||||
|
}
|
||||||
|
|
||||||
private void validate(LongSparseArray array) {
|
private void validate(LongSparseArray array) {
|
||||||
if (array.size() == 0) {
|
if (array.size() == 0) {
|
||||||
isValid = false;
|
isValid = false;
|
||||||
|
@ -259,6 +278,7 @@ public class Profile {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
private Double getValueToTime(JSONArray array, Integer timeAsSeconds) {
|
private Double getValueToTime(JSONArray array, Integer timeAsSeconds) {
|
||||||
Double lastValue = null;
|
Double lastValue = null;
|
||||||
|
|
||||||
|
@ -278,12 +298,11 @@ public class Profile {
|
||||||
}
|
}
|
||||||
return lastValue;
|
return lastValue;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
Integer getShitfTimeSecs(Integer originalTime) {
|
Integer getShitfTimeSecs(Integer originalTime) {
|
||||||
Integer shiftedTime = originalTime + timeshift * 60 * 60;
|
Integer shiftedTime = originalTime + timeshift * 60 * 60;
|
||||||
shiftedTime = (shiftedTime + 24 * 60 * 60) % (24 * 60 * 60);
|
shiftedTime = (shiftedTime + 24 * 60 * 60) % (24 * 60 * 60);
|
||||||
if (timeshift != 0)
|
|
||||||
log.debug("(Sec) Original time: " + originalTime + " ShiftedTime: " + shiftedTime);
|
|
||||||
return shiftedTime;
|
return shiftedTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,7 +338,7 @@ public class Profile {
|
||||||
return multiplier;
|
return multiplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Double getValueToTime(LongSparseArray<Double> array, Integer timeAsSeconds) {
|
private double getValueToTime(LongSparseArray<Double> array, Integer timeAsSeconds) {
|
||||||
Double lastValue = null;
|
Double lastValue = null;
|
||||||
|
|
||||||
for (Integer index = 0; index < array.size(); index++) {
|
for (Integer index = 0; index < array.size(); index++) {
|
||||||
|
@ -334,7 +353,7 @@ public class Profile {
|
||||||
return lastValue;
|
return lastValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String format_HH_MM(Integer timeAsSeconds) {
|
protected String format_HH_MM(Integer timeAsSeconds) {
|
||||||
String time;
|
String time;
|
||||||
int hour = timeAsSeconds / 60 / 60;
|
int hour = timeAsSeconds / 60 / 60;
|
||||||
int minutes = (timeAsSeconds - hour * 60 * 60) / 60;
|
int minutes = (timeAsSeconds - hour * 60 * 60) / 60;
|
||||||
|
@ -361,51 +380,55 @@ public class Profile {
|
||||||
return retValue;
|
return retValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Double getIsf() {
|
public double getIsf() {
|
||||||
return getIsf(secondsFromMidnight(System.currentTimeMillis()));
|
return getIsfTimeFromMidnight(secondsFromMidnight(System.currentTimeMillis()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Double getIsf(long time) {
|
public double getIsf(long time) {
|
||||||
return getIsf(secondsFromMidnight(time));
|
return getIsfTimeFromMidnight(secondsFromMidnight(time));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Double getIsf(Integer timeAsSeconds) {
|
double getIsfTimeFromMidnight(int timeAsSeconds) {
|
||||||
if (isf_v == null)
|
if (isf_v == null)
|
||||||
isf_v = convertToSparseArray(isf);
|
isf_v = convertToSparseArray(isf);
|
||||||
return getValueToTime(isf_v, timeAsSeconds);
|
return getValueToTime(isf_v, timeAsSeconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getIsfList() {
|
public String getIsfList() {
|
||||||
|
if (isf_v == null)
|
||||||
|
isf_v = convertToSparseArray(isf);
|
||||||
return getValuesList(isf_v, null, new DecimalFormat("0.0"), getUnits() + "/U");
|
return getValuesList(isf_v, null, new DecimalFormat("0.0"), getUnits() + "/U");
|
||||||
}
|
}
|
||||||
|
|
||||||
public Double getIc() {
|
public double getIc() {
|
||||||
return getIc(secondsFromMidnight(System.currentTimeMillis()));
|
return getIcTimeFromMidnight(secondsFromMidnight(System.currentTimeMillis()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Double getIc(long time) {
|
public double getIc(long time) {
|
||||||
return getIc(secondsFromMidnight(time));
|
return getIcTimeFromMidnight(secondsFromMidnight(time));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Double getIc(Integer timeAsSeconds) {
|
public double getIcTimeFromMidnight(int timeAsSeconds) {
|
||||||
if (ic_v == null)
|
if (ic_v == null)
|
||||||
ic_v = convertToSparseArray(ic);
|
ic_v = convertToSparseArray(ic);
|
||||||
return getValueToTime(ic_v, timeAsSeconds);
|
return getValueToTime(ic_v, timeAsSeconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getIcList() {
|
public String getIcList() {
|
||||||
return getValuesList(ic_v, null, new DecimalFormat("0.0"), " g/U");
|
if (ic_v == null)
|
||||||
|
ic_v = convertToSparseArray(ic);
|
||||||
|
return getValuesList(ic_v, null, new DecimalFormat("0.0"), "g/U");
|
||||||
}
|
}
|
||||||
|
|
||||||
public Double getBasal() {
|
public double getBasal() {
|
||||||
return getBasal(secondsFromMidnight(System.currentTimeMillis()));
|
return getBasalTimeFromMidnight(secondsFromMidnight(System.currentTimeMillis()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Double getBasal(long time) {
|
public double getBasal(long time) {
|
||||||
return getBasal(secondsFromMidnight(time));
|
return getBasalTimeFromMidnight(secondsFromMidnight(time));
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized Double getBasal(Integer timeAsSeconds) {
|
public synchronized double getBasalTimeFromMidnight(int timeAsSeconds) {
|
||||||
if (basal_v == null) {
|
if (basal_v == null) {
|
||||||
basal_v = convertToSparseArray(basal);
|
basal_v = convertToSparseArray(basal);
|
||||||
}
|
}
|
||||||
|
@ -413,17 +436,19 @@ public class Profile {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getBasalList() {
|
public String getBasalList() {
|
||||||
return getValuesList(basal_v, null, new DecimalFormat("0.00"), "U");
|
if (basal_v == null)
|
||||||
|
basal_v = convertToSparseArray(basal);
|
||||||
|
return getValuesList(basal_v, null, new DecimalFormat("0.00"), "U/h");
|
||||||
}
|
}
|
||||||
|
|
||||||
public class BasalValue {
|
public class BasalValue {
|
||||||
public BasalValue(Integer timeAsSeconds, Double value) {
|
public BasalValue(int timeAsSeconds, double value) {
|
||||||
this.timeAsSeconds = timeAsSeconds;
|
this.timeAsSeconds = timeAsSeconds;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer timeAsSeconds;
|
public int timeAsSeconds;
|
||||||
public Double value;
|
public double value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized BasalValue[] getBasalValues() {
|
public synchronized BasalValue[] getBasalValues() {
|
||||||
|
@ -433,54 +458,66 @@ public class Profile {
|
||||||
|
|
||||||
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 BasalValue(tas, value);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Double getTargetLow() {
|
public double getTarget() {
|
||||||
return getTargetLow(secondsFromMidnight(System.currentTimeMillis()));
|
return getTarget(secondsFromMidnight(System.currentTimeMillis()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Double getTargetLow(long time) {
|
protected double getTarget(int timeAsSeconds) {
|
||||||
return getTargetLow(secondsFromMidnight(time));
|
return (getTargetLowTimeFromMidnight(timeAsSeconds) + getTargetHighTimeFromMidnight(timeAsSeconds)) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Double getTargetLow(Integer timeAsSeconds) {
|
public double getTargetLow() {
|
||||||
|
return getTargetLowTimeFromMidnight(secondsFromMidnight(System.currentTimeMillis()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getTargetLow(long time) {
|
||||||
|
return getTargetLowTimeFromMidnight(secondsFromMidnight(time));
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getTargetLowTimeFromMidnight(int timeAsSeconds) {
|
||||||
if (targetLow_v == null)
|
if (targetLow_v == null)
|
||||||
targetLow_v = convertToSparseArray(targetLow);
|
targetLow_v = convertToSparseArray(targetLow);
|
||||||
return getValueToTime(targetLow_v, timeAsSeconds);
|
return getValueToTime(targetLow_v, timeAsSeconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Double getTargetHigh() {
|
public double getTargetHigh() {
|
||||||
return getTargetHigh(secondsFromMidnight(System.currentTimeMillis()));
|
return getTargetHighTimeFromMidnight(secondsFromMidnight(System.currentTimeMillis()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Double getTargetHigh(long time) {
|
public double getTargetHigh(long time) {
|
||||||
return getTargetHigh(secondsFromMidnight(time));
|
return getTargetHighTimeFromMidnight(secondsFromMidnight(time));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Double getTargetHigh(Integer timeAsSeconds) {
|
public double getTargetHighTimeFromMidnight(int timeAsSeconds) {
|
||||||
if (targetHigh_v == null)
|
if (targetHigh_v == null)
|
||||||
targetHigh_v = convertToSparseArray(targetHigh);
|
targetHigh_v = convertToSparseArray(targetHigh);
|
||||||
return getValueToTime(targetHigh_v, timeAsSeconds);
|
return getValueToTime(targetHigh_v, timeAsSeconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTargetList() {
|
public String getTargetList() {
|
||||||
|
if (targetLow_v == null)
|
||||||
|
targetLow_v = convertToSparseArray(targetLow);
|
||||||
|
if (targetHigh_v == null)
|
||||||
|
targetHigh_v = convertToSparseArray(targetHigh);
|
||||||
return getValuesList(targetLow_v, targetHigh_v, new DecimalFormat("0.0"), getUnits());
|
return getValuesList(targetLow_v, targetHigh_v, new DecimalFormat("0.0"), getUnits());
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getMaxDailyBasal() {
|
public double getMaxDailyBasal() {
|
||||||
Double max = 0d;
|
double max = 0d;
|
||||||
for (Integer hour = 0; hour < 24; hour++) {
|
for (int hour = 0; hour < 24; hour++) {
|
||||||
double value = getBasal((Integer) (hour * 60 * 60));
|
double value = getBasalTimeFromMidnight((Integer) (hour * 60 * 60));
|
||||||
if (value > max) max = value;
|
if (value > max) max = value;
|
||||||
}
|
}
|
||||||
return max;
|
return max;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Integer secondsFromMidnight() {
|
public static int secondsFromMidnight() {
|
||||||
Calendar c = Calendar.getInstance();
|
Calendar c = Calendar.getInstance();
|
||||||
long now = c.getTimeInMillis();
|
long now = c.getTimeInMillis();
|
||||||
c.set(Calendar.HOUR_OF_DAY, 0);
|
c.set(Calendar.HOUR_OF_DAY, 0);
|
||||||
|
@ -491,7 +528,7 @@ public class Profile {
|
||||||
return (int) (passed / 1000);
|
return (int) (passed / 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Integer secondsFromMidnight(long date) {
|
public static int secondsFromMidnight(long date) {
|
||||||
Calendar c = Calendar.getInstance();
|
Calendar c = Calendar.getInstance();
|
||||||
c.setTimeInMillis(date);
|
c.setTimeInMillis(date);
|
||||||
c.set(Calendar.HOUR_OF_DAY, 0);
|
c.set(Calendar.HOUR_OF_DAY, 0);
|
||||||
|
@ -502,22 +539,22 @@ public class Profile {
|
||||||
return (int) (passed / 1000);
|
return (int) (passed / 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Double toMgdl(Double value, String units) {
|
public static double toMgdl(double value, String units) {
|
||||||
if (units.equals(Constants.MGDL)) return value;
|
if (units.equals(Constants.MGDL)) return value;
|
||||||
else return value * Constants.MMOLL_TO_MGDL;
|
else return value * Constants.MMOLL_TO_MGDL;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Double toMmol(Double value, String units) {
|
public static double toMmol(double value, String units) {
|
||||||
if (units.equals(Constants.MGDL)) return value * Constants.MGDL_TO_MMOLL;
|
if (units.equals(Constants.MGDL)) return value * Constants.MGDL_TO_MMOLL;
|
||||||
else return value;
|
else return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Double fromMgdlToUnits(Double value, String units) {
|
public static double fromMgdlToUnits(double value, String units) {
|
||||||
if (units.equals(Constants.MGDL)) return value;
|
if (units.equals(Constants.MGDL)) return value;
|
||||||
else return value * Constants.MGDL_TO_MMOLL;
|
else return value * Constants.MGDL_TO_MMOLL;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Double toUnits(Double valueInMgdl, Double valueInMmol, String units) {
|
public static double toUnits(Double valueInMgdl, Double valueInMmol, String units) {
|
||||||
if (units.equals(Constants.MGDL)) return valueInMgdl;
|
if (units.equals(Constants.MGDL)) return valueInMgdl;
|
||||||
else return valueInMmol;
|
else return valueInMmol;
|
||||||
}
|
}
|
||||||
|
@ -527,6 +564,12 @@ public class Profile {
|
||||||
else return DecimalFormatter.to1Decimal(valueInMmol);
|
else return DecimalFormatter.to1Decimal(valueInMmol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String toSignedUnitsString(Double valueInMgdl, Double valueInMmol, String units) {
|
||||||
|
if (units.equals(Constants.MGDL))
|
||||||
|
return (valueInMgdl > 0 ? "+" : "") + DecimalFormatter.to0Decimal(valueInMgdl);
|
||||||
|
else return (valueInMmol > 0 ? "+" : "") + DecimalFormatter.to1Decimal(valueInMmol);
|
||||||
|
}
|
||||||
|
|
||||||
// targets are stored in mg/dl but profile vary
|
// targets are stored in mg/dl but profile vary
|
||||||
public static String toTargetRangeString(double low, double high, String sourceUnits, String units) {
|
public static String toTargetRangeString(double low, double high, String sourceUnits, String units) {
|
||||||
double lowMgdl = toMgdl(low, sourceUnits);
|
double lowMgdl = toMgdl(low, sourceUnits);
|
||||||
|
@ -543,7 +586,7 @@ public class Profile {
|
||||||
public double percentageBasalSum() {
|
public double percentageBasalSum() {
|
||||||
double result = 0d;
|
double result = 0d;
|
||||||
for (int i = 0; i < 24; i++) {
|
for (int i = 0; i < 24; i++) {
|
||||||
result += getBasal((Integer) (i * 60 * 60));
|
result += getBasalTimeFromMidnight(i * 60 * 60);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -552,7 +595,7 @@ public class Profile {
|
||||||
public double baseBasalSum() {
|
public double baseBasalSum() {
|
||||||
double result = 0d;
|
double result = 0d;
|
||||||
for (int i = 0; i < 24; i++) {
|
for (int i = 0; i < 24; i++) {
|
||||||
result += getBasal((Integer) (i * 60 * 60)) / getMultiplier(basal_v);
|
result += getBasalTimeFromMidnight(i * 60 * 60) / getMultiplier(basal_v);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,14 @@ package info.nightscout.androidaps.data;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.util.LongSparseArray;
|
import android.support.v4.util.LongSparseArray;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import info.nightscout.androidaps.interfaces.Interval;
|
import info.nightscout.androidaps.interfaces.Interval;
|
||||||
|
import info.nightscout.utils.DateUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by mike on 09.05.2017.
|
* Created by mike on 09.05.2017.
|
||||||
|
@ -16,8 +20,17 @@ import info.nightscout.androidaps.interfaces.Interval;
|
||||||
// When no interval match the lastest record without duration is used
|
// When no interval match the lastest record without duration is used
|
||||||
|
|
||||||
public class ProfileIntervals<T extends Interval> {
|
public class ProfileIntervals<T extends Interval> {
|
||||||
|
private static Logger log = LoggerFactory.getLogger(ProfileIntervals.class);
|
||||||
|
|
||||||
private LongSparseArray<T> rawData = new LongSparseArray<>(); // oldest at index 0
|
private LongSparseArray<T> rawData; // oldest at index 0
|
||||||
|
|
||||||
|
public ProfileIntervals () {
|
||||||
|
rawData = new LongSparseArray<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProfileIntervals (ProfileIntervals<T> other) {
|
||||||
|
rawData = other.rawData.clone();
|
||||||
|
}
|
||||||
|
|
||||||
public synchronized ProfileIntervals reset() {
|
public synchronized ProfileIntervals reset() {
|
||||||
rawData = new LongSparseArray<>();
|
rawData = new LongSparseArray<>();
|
||||||
|
@ -25,8 +38,10 @@ public class ProfileIntervals<T extends Interval> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void add(T newInterval) {
|
public synchronized void add(T newInterval) {
|
||||||
rawData.put(newInterval.start(), newInterval);
|
if (newInterval.isValid()) {
|
||||||
merge();
|
rawData.put(newInterval.start(), newInterval);
|
||||||
|
merge();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void add(List<T> list) {
|
public synchronized void add(List<T> list) {
|
||||||
|
@ -51,6 +66,13 @@ public class ProfileIntervals<T extends Interval> {
|
||||||
public synchronized Interval getValueToTime(long time) {
|
public synchronized Interval getValueToTime(long time) {
|
||||||
int index = binarySearch(time);
|
int index = binarySearch(time);
|
||||||
if (index >= 0) return rawData.valueAt(index);
|
if (index >= 0) return rawData.valueAt(index);
|
||||||
|
// if we request data older than first record, use oldest with zero duration instead
|
||||||
|
for (index = 0; index < rawData.size(); index++) {
|
||||||
|
if (rawData.valueAt(index).durationInMsec() == 0) {
|
||||||
|
//log.debug("Requested profile for time: " + DateUtil.dateAndTimeString(time) + ". Providing oldest record: " + rawData.valueAt(0).toString());
|
||||||
|
return rawData.valueAt(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,4 +129,9 @@ public class ProfileIntervals<T extends Interval> {
|
||||||
public synchronized T getReversed(int index) {
|
public synchronized T getReversed(int index) {
|
||||||
return rawData.valueAt(size() - 1 - index);
|
return rawData.valueAt(size() - 1 - index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return rawData.toString();
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -10,30 +10,31 @@ import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
|
import info.nightscout.androidaps.logging.L;
|
||||||
import info.nightscout.utils.DecimalFormatter;
|
import info.nightscout.utils.DecimalFormatter;
|
||||||
import info.nightscout.utils.Round;
|
import info.nightscout.utils.Round;
|
||||||
|
|
||||||
public class PumpEnactResult extends Object {
|
public class PumpEnactResult {
|
||||||
private static Logger log = LoggerFactory.getLogger(PumpEnactResult.class);
|
private static Logger log = LoggerFactory.getLogger(L.APS);
|
||||||
|
|
||||||
public boolean success = false; // request was processed successfully (but possible no change was needed)
|
public boolean success = false; // request was processed successfully (but possible no change was needed)
|
||||||
public boolean enacted = false; // request was processed successfully and change has been made
|
public boolean enacted = false; // request was processed successfully and change has been made
|
||||||
public String comment = "";
|
public String comment = "";
|
||||||
|
|
||||||
// Result of basal change
|
// Result of basal change
|
||||||
public Integer duration = -1; // duration set [minutes]
|
public int duration = -1; // duration set [minutes]
|
||||||
public Double absolute = -1d; // absolute rate [U/h] , isPercent = false
|
public double absolute = -1d; // absolute rate [U/h] , isPercent = false
|
||||||
public Integer percent = -1; // percent of current basal [%] (100% = current basal), isPercent = true
|
public int percent = -1; // percent of current basal [%] (100% = current basal), isPercent = true
|
||||||
public boolean isPercent = false; // if true percent is used, otherwise absolute
|
public boolean isPercent = false; // if true percent is used, otherwise absolute
|
||||||
public boolean isTempCancel = false; // if true we are caceling temp basal
|
public boolean isTempCancel = false; // if true we are caceling temp basal
|
||||||
// Result of treatment delivery
|
// Result of treatment delivery
|
||||||
public Double bolusDelivered = 0d; // real value of delivered insulin
|
public double bolusDelivered = 0d; // real value of delivered insulin
|
||||||
public Double carbsDelivered = 0d; // real value of delivered carbs
|
public double carbsDelivered = 0d; // real value of delivered carbs
|
||||||
|
|
||||||
public boolean queued = false;
|
public boolean queued = false;
|
||||||
|
|
||||||
public PumpEnactResult success(boolean success) {
|
public PumpEnactResult success(boolean success) {
|
||||||
this.success = success;
|
this.success = success;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,16 +48,21 @@ public class PumpEnactResult extends Object {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PumpEnactResult duration(Integer duration) {
|
public PumpEnactResult duration(int duration) {
|
||||||
this.duration = duration;
|
this.duration = duration;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PumpEnactResult absolute(Double absolute) {
|
public PumpEnactResult absolute(double absolute) {
|
||||||
this.absolute = absolute;
|
this.absolute = absolute;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PumpEnactResult percent(int percent) {
|
||||||
|
this.percent = percent;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public PumpEnactResult isPercent(boolean isPercent) {
|
public PumpEnactResult isPercent(boolean isPercent) {
|
||||||
this.isPercent = isPercent;
|
this.isPercent = isPercent;
|
||||||
return this;
|
return this;
|
||||||
|
@ -67,12 +73,12 @@ public class PumpEnactResult extends Object {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PumpEnactResult bolusDelivered(Double bolusDelivered) {
|
public PumpEnactResult bolusDelivered(double bolusDelivered) {
|
||||||
this.bolusDelivered = bolusDelivered;
|
this.bolusDelivered = bolusDelivered;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PumpEnactResult carbsDelivered(Double carbsDelivered) {
|
public PumpEnactResult carbsDelivered(double carbsDelivered) {
|
||||||
this.carbsDelivered = carbsDelivered;
|
this.carbsDelivered = carbsDelivered;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -82,72 +88,96 @@ public class PumpEnactResult extends Object {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String log() {
|
public String log() {
|
||||||
return "Success: " + success + " Enacted: " + enacted + " Comment: " + comment + " Duration: " + duration + " Absolute: " + absolute + " Percent: " + percent + " IsPercent: " + isPercent + " Queued: " + queued;
|
return "Success: " + success +
|
||||||
|
" Enacted: " + enacted +
|
||||||
|
" Comment: " + comment +
|
||||||
|
" Duration: " + duration +
|
||||||
|
" Absolute: " + absolute +
|
||||||
|
" Percent: " + percent +
|
||||||
|
" IsPercent: " + isPercent +
|
||||||
|
" IsTempCancel: " + isTempCancel +
|
||||||
|
" bolusDelivered: " + bolusDelivered +
|
||||||
|
" carbsDelivered: " + carbsDelivered +
|
||||||
|
" Queued: " + queued;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
String ret = MainApp.sResources.getString(R.string.success) + ": " + success;
|
String ret = MainApp.gs(R.string.success) + ": " + success;
|
||||||
if (enacted) {
|
if (enacted) {
|
||||||
if (isTempCancel) {
|
if (bolusDelivered > 0) {
|
||||||
ret += "\n" + MainApp.sResources.getString(R.string.enacted) + ": " + enacted;
|
ret += "\n" + MainApp.gs(R.string.enacted) + ": " + enacted;
|
||||||
ret += "\n" + MainApp.sResources.getString(R.string.comment) + ": " + comment + "\n" +
|
ret += "\n" + MainApp.gs(R.string.comment) + ": " + comment;
|
||||||
MainApp.sResources.getString(R.string.canceltemp);
|
ret += "\n" + MainApp.gs(R.string.configbuilder_insulin)
|
||||||
|
+ ": " + bolusDelivered + " " + MainApp.gs(R.string.insulin_unit_shortname);
|
||||||
|
} else if (isTempCancel) {
|
||||||
|
ret += "\n" + MainApp.gs(R.string.enacted) + ": " + enacted;
|
||||||
|
if (!comment.isEmpty())
|
||||||
|
ret += "\n" + MainApp.gs(R.string.comment) + ": " + comment;
|
||||||
|
ret += "\n" + MainApp.gs(R.string.canceltemp);
|
||||||
} else if (isPercent) {
|
} else if (isPercent) {
|
||||||
ret += "\n" + MainApp.sResources.getString(R.string.enacted) + ": " + enacted;
|
ret += "\n" + MainApp.gs(R.string.enacted) + ": " + enacted;
|
||||||
ret += "\n" + MainApp.sResources.getString(R.string.comment) + ": " + comment;
|
if (!comment.isEmpty())
|
||||||
ret += "\n" + MainApp.sResources.getString(R.string.duration) + ": " + duration + " min";
|
ret += "\n" + MainApp.gs(R.string.comment) + ": " + comment;
|
||||||
ret += "\n" + MainApp.sResources.getString(R.string.percent) + ": " + percent + "%";
|
ret += "\n" + MainApp.gs(R.string.duration) + ": " + duration + " min";
|
||||||
|
ret += "\n" + MainApp.gs(R.string.percent) + ": " + percent + "%";
|
||||||
} else {
|
} else {
|
||||||
ret += "\n" + MainApp.sResources.getString(R.string.enacted) + ": " + enacted;
|
ret += "\n" + MainApp.gs(R.string.enacted) + ": " + enacted;
|
||||||
ret += "\n" + MainApp.sResources.getString(R.string.comment) + ": " + comment;
|
if (!comment.isEmpty())
|
||||||
ret += "\n" + MainApp.sResources.getString(R.string.duration) + ": " + duration + " min";
|
ret += "\n" + MainApp.gs(R.string.comment) + ": " + comment;
|
||||||
ret += "\n" + MainApp.sResources.getString(R.string.absolute) + ": " + absolute + " U/h";
|
ret += "\n" + MainApp.gs(R.string.duration) + ": " + duration + " min";
|
||||||
|
ret += "\n" + MainApp.gs(R.string.absolute) + ": " + absolute + " U/h";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ret += "\n" + MainApp.sResources.getString(R.string.comment) + ": " + comment;
|
ret += "\n" + MainApp.gs(R.string.comment) + ": " + comment;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Spanned toSpanned() {
|
public String toHtml() {
|
||||||
String ret = MainApp.sResources.getString(R.string.success) + ": " + success;
|
String ret = "<b>" + MainApp.gs(R.string.success) + "</b>: " + success;
|
||||||
if (queued) {
|
if (queued) {
|
||||||
ret = MainApp.sResources.getString(R.string.waitingforpumpresult);
|
ret = MainApp.gs(R.string.waitingforpumpresult);
|
||||||
} else if (enacted) {
|
} else if (enacted) {
|
||||||
if (isTempCancel) {
|
if (bolusDelivered > 0) {
|
||||||
ret += "<br><b>" + MainApp.sResources.getString(R.string.enacted) + "</b>: " + enacted;
|
ret += "<br><b>" + MainApp.gs(R.string.enacted) + "</b>: " + enacted;
|
||||||
ret += "<br><b>" + MainApp.sResources.getString(R.string.comment) + "</b>: " + comment +
|
if (!comment.isEmpty())
|
||||||
"<br>" + MainApp.sResources.getString(R.string.canceltemp);
|
ret += "<br><b>" + MainApp.gs(R.string.comment) + "</b>: " + comment;
|
||||||
} else if (isPercent) {
|
ret += "<br><b>" + MainApp.gs(R.string.smb_shortname) + "</b>: " + bolusDelivered + " " + MainApp.gs(R.string.insulin_unit_shortname);
|
||||||
ret += "<br><b>" + MainApp.sResources.getString(R.string.enacted) + "</b>: " + enacted;
|
} else if (isTempCancel) {
|
||||||
ret += "<br><b>" + MainApp.sResources.getString(R.string.comment) + "</b>: " + comment;
|
ret += "<br><b>" + MainApp.gs(R.string.enacted) + "</b>: " + enacted;
|
||||||
ret += "<br><b>" + MainApp.sResources.getString(R.string.duration) + "</b>: " + duration + " min";
|
ret += "<br><b>" + MainApp.gs(R.string.comment) + "</b>: " + comment +
|
||||||
ret += "<br><b>" + MainApp.sResources.getString(R.string.percent) + "</b>: " + percent + "%";
|
"<br>" + MainApp.gs(R.string.canceltemp);
|
||||||
} else {
|
} else if (isPercent && percent != -1) {
|
||||||
ret += "<br><b>" + MainApp.sResources.getString(R.string.enacted) + "</b>: " + enacted;
|
ret += "<br><b>" + MainApp.gs(R.string.enacted) + "</b>: " + enacted;
|
||||||
ret += "<br><b>" + MainApp.sResources.getString(R.string.comment) + "</b>: " + comment;
|
if (!comment.isEmpty())
|
||||||
ret += "<br><b>" + MainApp.sResources.getString(R.string.duration) + "</b>: " + duration + " min";
|
ret += "<br><b>" + MainApp.gs(R.string.comment) + "</b>: " + comment;
|
||||||
ret += "<br><b>" + MainApp.sResources.getString(R.string.absolute) + "</b>: " + DecimalFormatter.to2Decimal(absolute) + " U/h";
|
ret += "<br><b>" + MainApp.gs(R.string.duration) + "</b>: " + duration + " min";
|
||||||
|
ret += "<br><b>" + MainApp.gs(R.string.percent) + "</b>: " + percent + "%";
|
||||||
|
} else if (absolute != -1) {
|
||||||
|
ret += "<br><b>" + MainApp.gs(R.string.enacted) + "</b>: " + enacted;
|
||||||
|
if (!comment.isEmpty())
|
||||||
|
ret += "<br><b>" + MainApp.gs(R.string.comment) + "</b>: " + comment;
|
||||||
|
ret += "<br><b>" + MainApp.gs(R.string.duration) + "</b>: " + duration + " min";
|
||||||
|
ret += "<br><b>" + MainApp.gs(R.string.absolute) + "</b>: " + DecimalFormatter.to2Decimal(absolute) + " U/h";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ret += "<br><b>" + MainApp.sResources.getString(R.string.comment) + "</b>: " + comment;
|
ret += "<br><b>" + MainApp.gs(R.string.comment) + "</b>: " + comment;
|
||||||
}
|
}
|
||||||
return Html.fromHtml(ret);
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PumpEnactResult() {
|
public JSONObject json(Profile profile) {
|
||||||
}
|
|
||||||
|
|
||||||
public JSONObject json() {
|
|
||||||
JSONObject result = new JSONObject();
|
JSONObject result = new JSONObject();
|
||||||
try {
|
try {
|
||||||
if (isTempCancel) {
|
if (bolusDelivered > 0) {
|
||||||
|
result.put("smb", bolusDelivered);
|
||||||
|
} else if (isTempCancel) {
|
||||||
result.put("rate", 0);
|
result.put("rate", 0);
|
||||||
result.put("duration", 0);
|
result.put("duration", 0);
|
||||||
} else if (isPercent) {
|
} else if (isPercent) {
|
||||||
// Nightscout is expecting absolute value
|
// Nightscout is expecting absolute value
|
||||||
Double abs = Round.roundTo(MainApp.getConfigBuilder().getProfile().getBasal() * percent / 100, 0.01);
|
Double abs = Round.roundTo(profile.getBasal() * percent / 100, 0.01);
|
||||||
result.put("rate", abs);
|
result.put("rate", abs);
|
||||||
result.put("duration", duration);
|
result.put("duration", duration);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -10,6 +10,7 @@ import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
|
import info.nightscout.utils.SP;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by mike on 12.10.2016.
|
* Created by mike on 12.10.2016.
|
||||||
|
@ -25,10 +26,7 @@ public class QuickWizard {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void save() {
|
public void save() {
|
||||||
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext());
|
SP.putString("QuickWizard", storage.toString());
|
||||||
SharedPreferences.Editor editor = preferences.edit();
|
|
||||||
editor.putString("QuickWizard", storage.toString());
|
|
||||||
editor.apply();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int size() {
|
public int size() {
|
||||||
|
|
|
@ -7,15 +7,14 @@ import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import info.nightscout.androidaps.MainApp;
|
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.db.BgReading;
|
import info.nightscout.androidaps.db.BgReading;
|
||||||
import info.nightscout.androidaps.db.TempTarget;
|
import info.nightscout.androidaps.db.TempTarget;
|
||||||
import info.nightscout.androidaps.interfaces.TreatmentsInterface;
|
import info.nightscout.androidaps.interfaces.TreatmentsInterface;
|
||||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
import info.nightscout.androidaps.plugins.IobCobCalculator.CobInfo;
|
||||||
import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensData;
|
|
||||||
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
|
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
|
import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.utils.BolusWizard;
|
import info.nightscout.utils.BolusWizard;
|
||||||
import info.nightscout.utils.DateUtil;
|
import info.nightscout.utils.DateUtil;
|
||||||
import info.nightscout.utils.SP;
|
import info.nightscout.utils.SP;
|
||||||
|
@ -80,14 +79,10 @@ public class QuickWizardEntry {
|
||||||
|
|
||||||
// COB
|
// COB
|
||||||
double cob = 0d;
|
double cob = 0d;
|
||||||
AutosensData autosensData;
|
if (useCOB() == YES) {
|
||||||
if (_synchronized)
|
CobInfo cobInfo = IobCobCalculatorPlugin.getPlugin().getCobInfo(_synchronized, "QuickWizard COB");
|
||||||
autosensData = IobCobCalculatorPlugin.getLastAutosensDataSynchronized("QuickWizard COB");
|
if (cobInfo.displayCob != null)
|
||||||
else
|
cob = cobInfo.displayCob;
|
||||||
autosensData = IobCobCalculatorPlugin.getLastAutosensData("QuickWizard COB");
|
|
||||||
|
|
||||||
if (autosensData != null && useCOB() == YES) {
|
|
||||||
cob = autosensData.cob;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Temp target
|
// Temp target
|
||||||
|
@ -102,7 +97,7 @@ public class QuickWizardEntry {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Basal IOB
|
// Basal IOB
|
||||||
TreatmentsInterface treatments = MainApp.getConfigBuilder();
|
TreatmentsInterface treatments = TreatmentsPlugin.getPlugin();
|
||||||
treatments.updateTotalIOBTempBasals();
|
treatments.updateTotalIOBTempBasals();
|
||||||
IobTotal basalIob = treatments.getLastCalculationTempBasals().round();
|
IobTotal basalIob = treatments.getLastCalculationTempBasals().round();
|
||||||
boolean basalIOB = false;
|
boolean basalIOB = false;
|
||||||
|
@ -119,8 +114,8 @@ public class QuickWizardEntry {
|
||||||
if (useSuperBolus() == YES && SP.getBoolean(R.string.key_usesuperbolus, false)) {
|
if (useSuperBolus() == YES && SP.getBoolean(R.string.key_usesuperbolus, false)) {
|
||||||
superBolus = true;
|
superBolus = true;
|
||||||
}
|
}
|
||||||
final LoopPlugin activeloop = ConfigBuilderPlugin.getActiveLoop();
|
final LoopPlugin loopPlugin = LoopPlugin.getPlugin();
|
||||||
if (activeloop != null && activeloop.isEnabled(activeloop.getType()) && activeloop.isSuperBolus())
|
if (loopPlugin.isEnabled(loopPlugin.getType()) && loopPlugin.isSuperBolus())
|
||||||
superBolus = false;
|
superBolus = false;
|
||||||
|
|
||||||
// Trend
|
// Trend
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package info.nightscout.androidaps.db;
|
package info.nightscout.androidaps.db;
|
||||||
|
|
||||||
|
import android.content.res.Resources;
|
||||||
|
|
||||||
import com.j256.ormlite.field.DatabaseField;
|
import com.j256.ormlite.field.DatabaseField;
|
||||||
import com.j256.ormlite.table.DatabaseTable;
|
import com.j256.ormlite.table.DatabaseTable;
|
||||||
|
|
||||||
|
@ -13,17 +15,18 @@ 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.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
|
import info.nightscout.androidaps.logging.L;
|
||||||
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions;
|
||||||
import info.nightscout.androidaps.plugins.NSClientInternal.data.NSSgv;
|
import info.nightscout.androidaps.plugins.NSClientInternal.data.NSSgv;
|
||||||
import info.nightscout.androidaps.plugins.Overview.OverviewPlugin;
|
import info.nightscout.androidaps.plugins.Overview.OverviewPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Overview.graphExtensions.DataPointWithLabelInterface;
|
import info.nightscout.androidaps.plugins.Overview.graphExtensions.DataPointWithLabelInterface;
|
||||||
import info.nightscout.androidaps.plugins.Overview.graphExtensions.PointsWithLabelGraphSeries;
|
import info.nightscout.androidaps.plugins.Overview.graphExtensions.PointsWithLabelGraphSeries;
|
||||||
import info.nightscout.utils.DateUtil;
|
|
||||||
import info.nightscout.utils.DecimalFormatter;
|
import info.nightscout.utils.DecimalFormatter;
|
||||||
import info.nightscout.utils.SP;
|
import info.nightscout.utils.SP;
|
||||||
|
|
||||||
@DatabaseTable(tableName = DatabaseHelper.DATABASE_BGREADINGS)
|
@DatabaseTable(tableName = DatabaseHelper.DATABASE_BGREADINGS)
|
||||||
public class BgReading implements DataPointWithLabelInterface {
|
public class BgReading implements DataPointWithLabelInterface {
|
||||||
private static Logger log = LoggerFactory.getLogger(BgReading.class);
|
private static Logger log = LoggerFactory.getLogger(L.DATABASE);
|
||||||
|
|
||||||
@DatabaseField(id = true)
|
@DatabaseField(id = true)
|
||||||
public long date;
|
public long date;
|
||||||
|
@ -43,7 +46,11 @@ public class BgReading implements DataPointWithLabelInterface {
|
||||||
@DatabaseField
|
@DatabaseField
|
||||||
public String _id = null; // NS _id
|
public String _id = null; // NS _id
|
||||||
|
|
||||||
public boolean isPrediction = false; // true when drawing predictions as bg points
|
public boolean isCOBPrediction = false; // true when drawing predictions as bg points (COB)
|
||||||
|
public boolean isaCOBPrediction = false; // true when drawing predictions as bg points (aCOB)
|
||||||
|
public boolean isIOBPrediction = false; // true when drawing predictions as bg points (IOB)
|
||||||
|
public boolean isUAMPrediction = false; // true when drawing predictions as bg points (UAM)
|
||||||
|
public boolean isZTPrediction = false; // true when drawing predictions as bg points (ZT)
|
||||||
|
|
||||||
public BgReading() {
|
public BgReading() {
|
||||||
}
|
}
|
||||||
|
@ -137,7 +144,7 @@ public class BgReading implements DataPointWithLabelInterface {
|
||||||
return false;
|
return false;
|
||||||
if (raw != other.raw)
|
if (raw != other.raw)
|
||||||
return false;
|
return false;
|
||||||
if (!direction.equals(other.direction))
|
if (!Objects.equals(direction, other.direction))
|
||||||
return false;
|
return false;
|
||||||
if (!Objects.equals(_id, other._id))
|
if (!Objects.equals(_id, other._id))
|
||||||
return false;
|
return false;
|
||||||
|
@ -155,6 +162,21 @@ public class BgReading implements DataPointWithLabelInterface {
|
||||||
_id = other._id;
|
_id = other._id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BgReading date(long date) {
|
||||||
|
this.date = date;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BgReading date(Date date) {
|
||||||
|
this.date = date.getTime();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BgReading value(double value) {
|
||||||
|
this.value = value;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------ DataPointWithLabelInterface ------------------
|
// ------------------ DataPointWithLabelInterface ------------------
|
||||||
@Override
|
@Override
|
||||||
public double getX() {
|
public double getX() {
|
||||||
|
@ -163,7 +185,7 @@ public class BgReading implements DataPointWithLabelInterface {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getY() {
|
public double getY() {
|
||||||
String units = MainApp.getConfigBuilder().getProfileUnits();
|
String units = ProfileFunctions.getInstance().getProfileUnits();
|
||||||
return valueToUnits(units);
|
return valueToUnits(units);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,34 +206,48 @@ public class BgReading implements DataPointWithLabelInterface {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PointsWithLabelGraphSeries.Shape getShape() {
|
public PointsWithLabelGraphSeries.Shape getShape() {
|
||||||
return PointsWithLabelGraphSeries.Shape.POINT;
|
if (isPrediction())
|
||||||
|
return PointsWithLabelGraphSeries.Shape.PREDICTION;
|
||||||
|
else
|
||||||
|
return PointsWithLabelGraphSeries.Shape.BG;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getSize() {
|
public float getSize() {
|
||||||
boolean isTablet = MainApp.sResources.getBoolean(R.bool.isTablet);
|
return 1;
|
||||||
return isTablet ? 8 : 5;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getColor() {
|
public int getColor() {
|
||||||
String units = MainApp.getConfigBuilder().getProfileUnits();
|
String units = ProfileFunctions.getInstance().getProfileUnits();
|
||||||
Double lowLine = SP.getDouble("low_mark", 0d);
|
Double lowLine = OverviewPlugin.getPlugin().determineLowLine(units);
|
||||||
Double highLine = SP.getDouble("high_mark", 0d);
|
Double highLine = OverviewPlugin.getPlugin().determineHighLine(units);
|
||||||
if (lowLine < 1) {
|
int color = MainApp.gc(R.color.inrange);
|
||||||
lowLine = Profile.fromMgdlToUnits(OverviewPlugin.bgTargetLow, units);
|
if (isPrediction())
|
||||||
}
|
return getPredectionColor();
|
||||||
if (highLine < 1) {
|
|
||||||
highLine = Profile.fromMgdlToUnits(OverviewPlugin.bgTargetHigh, units);
|
|
||||||
}
|
|
||||||
int color = MainApp.sResources.getColor(R.color.inrange);
|
|
||||||
if (isPrediction)
|
|
||||||
color = MainApp.sResources.getColor(R.color.prediction);
|
|
||||||
else if (valueToUnits(units) < lowLine)
|
else if (valueToUnits(units) < lowLine)
|
||||||
color = MainApp.sResources.getColor(R.color.low);
|
color = MainApp.gc(R.color.low);
|
||||||
else if (valueToUnits(units) > highLine)
|
else if (valueToUnits(units) > highLine)
|
||||||
color = MainApp.sResources.getColor(R.color.high);
|
color = MainApp.gc(R.color.high);
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getPredectionColor() {
|
||||||
|
if (isIOBPrediction)
|
||||||
|
return MainApp.gc(R.color.iob);
|
||||||
|
if (isCOBPrediction)
|
||||||
|
return MainApp.gc(R.color.cob);
|
||||||
|
if (isaCOBPrediction)
|
||||||
|
return 0x80FFFFFF & MainApp.gc(R.color.cob);
|
||||||
|
if (isUAMPrediction)
|
||||||
|
return MainApp.gc(R.color.uam);
|
||||||
|
if (isZTPrediction)
|
||||||
|
return MainApp.gc(R.color.zt);
|
||||||
|
return R.color.mdtp_white;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isPrediction() {
|
||||||
|
return isaCOBPrediction || isCOBPrediction || isIOBPrediction || isUAMPrediction || isZTPrediction;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import android.graphics.Color;
|
||||||
import com.j256.ormlite.field.DatabaseField;
|
import com.j256.ormlite.field.DatabaseField;
|
||||||
import com.j256.ormlite.table.DatabaseTable;
|
import com.j256.ormlite.table.DatabaseTable;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -23,16 +24,20 @@ 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.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
|
import info.nightscout.androidaps.interfaces.Interval;
|
||||||
|
import info.nightscout.androidaps.logging.L;
|
||||||
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions;
|
||||||
import info.nightscout.androidaps.plugins.NSClientInternal.data.NSMbg;
|
import info.nightscout.androidaps.plugins.NSClientInternal.data.NSMbg;
|
||||||
import info.nightscout.androidaps.plugins.Overview.OverviewFragment;
|
import info.nightscout.androidaps.plugins.Overview.OverviewFragment;
|
||||||
import info.nightscout.androidaps.plugins.Overview.graphExtensions.DataPointWithLabelInterface;
|
import info.nightscout.androidaps.plugins.Overview.graphExtensions.DataPointWithLabelInterface;
|
||||||
import info.nightscout.androidaps.plugins.Overview.graphExtensions.PointsWithLabelGraphSeries;
|
import info.nightscout.androidaps.plugins.Overview.graphExtensions.PointsWithLabelGraphSeries;
|
||||||
import info.nightscout.utils.DateUtil;
|
import info.nightscout.utils.DateUtil;
|
||||||
|
import info.nightscout.utils.T;
|
||||||
import info.nightscout.utils.Translator;
|
import info.nightscout.utils.Translator;
|
||||||
|
|
||||||
@DatabaseTable(tableName = DatabaseHelper.DATABASE_CAREPORTALEVENTS)
|
@DatabaseTable(tableName = DatabaseHelper.DATABASE_CAREPORTALEVENTS)
|
||||||
public class CareportalEvent implements DataPointWithLabelInterface {
|
public class CareportalEvent implements DataPointWithLabelInterface, Interval {
|
||||||
private static Logger log = LoggerFactory.getLogger(CareportalEvent.class);
|
private static Logger log = LoggerFactory.getLogger(L.DATABASE);
|
||||||
|
|
||||||
@DatabaseField(id = true)
|
@DatabaseField(id = true)
|
||||||
public long date;
|
public long date;
|
||||||
|
@ -86,18 +91,23 @@ public class CareportalEvent implements DataPointWithLabelInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getHoursFromStart() {
|
public long getHoursFromStart() {
|
||||||
return (System.currentTimeMillis() - date) / (60 * 1000);
|
return (System.currentTimeMillis() - date) / (60 * 60 * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String age() {
|
public String age() {
|
||||||
Map<TimeUnit, Long> diff = computeDiff(date, System.currentTimeMillis());
|
Map<TimeUnit, Long> diff = computeDiff(date, System.currentTimeMillis());
|
||||||
if (OverviewFragment.shorttextmode)
|
if (OverviewFragment.shorttextmode)
|
||||||
return diff.get(TimeUnit.DAYS) +"d" + diff.get(TimeUnit.HOURS) + "h";
|
return diff.get(TimeUnit.DAYS) + "d" + diff.get(TimeUnit.HOURS) + "h";
|
||||||
else
|
else
|
||||||
return diff.get(TimeUnit.DAYS) + " " + MainApp.sResources.getString(R.string.days) + " " + diff.get(TimeUnit.HOURS) + " " + MainApp.sResources.getString(R.string.hours);
|
return diff.get(TimeUnit.DAYS) + " " + MainApp.gs(R.string.days) + " " + diff.get(TimeUnit.HOURS) + " " + MainApp.gs(R.string.hours);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String log() {
|
public boolean isOlderThan(double hours) {
|
||||||
|
return getHoursFromStart() > hours;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
return "CareportalEvent{" +
|
return "CareportalEvent{" +
|
||||||
"date= " + date +
|
"date= " + date +
|
||||||
", date= " + DateUtil.dateAndTimeString(date) +
|
", date= " + DateUtil.dateAndTimeString(date) +
|
||||||
|
@ -124,6 +134,19 @@ public class CareportalEvent implements DataPointWithLabelInterface {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static boolean isEvent5minBack(List<CareportalEvent> list, long time) {
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
CareportalEvent event = list.get(i);
|
||||||
|
if (event.date <= time && event.date > (time - T.mins(5).msecs())) {
|
||||||
|
if (L.isEnabled(L.DATABASE))
|
||||||
|
log.debug("Found event for time: " + DateUtil.dateAndTimeFullString(time) + " " + event.toString());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// -------- DataPointWithLabelInterface -------
|
// -------- DataPointWithLabelInterface -------
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -135,7 +158,7 @@ public class CareportalEvent implements DataPointWithLabelInterface {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getY() {
|
public double getY() {
|
||||||
String units = MainApp.getConfigBuilder().getProfileUnits();
|
String units = ProfileFunctions.getInstance().getProfileUnits();
|
||||||
if (eventType.equals(MBG)) {
|
if (eventType.equals(MBG)) {
|
||||||
double mbg = 0d;
|
double mbg = 0d;
|
||||||
try {
|
try {
|
||||||
|
@ -184,7 +207,7 @@ public class CareportalEvent implements DataPointWithLabelInterface {
|
||||||
try {
|
try {
|
||||||
JSONObject object = new JSONObject(json);
|
JSONObject object = new JSONObject(json);
|
||||||
if (object.has("notes"))
|
if (object.has("notes"))
|
||||||
return object.getString("notes");
|
return StringUtils.abbreviate(object.getString("notes"), 40);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
|
@ -204,14 +227,7 @@ public class CareportalEvent implements DataPointWithLabelInterface {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getDuration() {
|
public long getDuration() {
|
||||||
try {
|
return end() - start();
|
||||||
JSONObject object = new JSONObject(json);
|
|
||||||
if (object.has("duration"))
|
|
||||||
return object.getInt("duration") * 60 * 1000L;
|
|
||||||
} catch (JSONException e) {
|
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -242,7 +258,7 @@ public class CareportalEvent implements DataPointWithLabelInterface {
|
||||||
@Override
|
@Override
|
||||||
public int getColor() {
|
public int getColor() {
|
||||||
if (eventType.equals(ANNOUNCEMENT))
|
if (eventType.equals(ANNOUNCEMENT))
|
||||||
return MainApp.sResources.getColor(R.color.notificationAnnouncement);
|
return MainApp.gc(R.color.notificationAnnouncement);
|
||||||
if (eventType.equals(MBG))
|
if (eventType.equals(MBG))
|
||||||
return Color.RED;
|
return Color.RED;
|
||||||
if (eventType.equals(BGCHECK))
|
if (eventType.equals(BGCHECK))
|
||||||
|
@ -250,7 +266,79 @@ public class CareportalEvent implements DataPointWithLabelInterface {
|
||||||
if (eventType.equals(EXERCISE))
|
if (eventType.equals(EXERCISE))
|
||||||
return Color.BLUE;
|
return Color.BLUE;
|
||||||
if (eventType.equals(OPENAPSOFFLINE))
|
if (eventType.equals(OPENAPSOFFLINE))
|
||||||
return Color.GRAY;
|
return Color.GRAY & 0x80FFFFFF;
|
||||||
return Color.GRAY;
|
return Color.GRAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Interval interface
|
||||||
|
Long cuttedEnd = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long durationInMsec() {
|
||||||
|
try {
|
||||||
|
JSONObject object = new JSONObject(json);
|
||||||
|
if (object.has("duration"))
|
||||||
|
return object.getInt("duration") * 60 * 1000L;
|
||||||
|
} catch (JSONException e) {
|
||||||
|
log.error("Unhandled exception", e);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long start() {
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long originalEnd() {
|
||||||
|
return date + durationInMsec();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long end() {
|
||||||
|
if (cuttedEnd != null)
|
||||||
|
return cuttedEnd;
|
||||||
|
return originalEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cutEndTo(long end) {
|
||||||
|
cuttedEnd = end;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean match(long time) {
|
||||||
|
if (start() <= time && end() >= time)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean before(long time) {
|
||||||
|
if (end() < time)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean after(long time) {
|
||||||
|
if (start() > time)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInProgress() {
|
||||||
|
return match(System.currentTimeMillis());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEndingEvent() {
|
||||||
|
return durationInMsec() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValid() {
|
||||||
|
return eventType.equals(OPENAPSOFFLINE);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -10,6 +10,8 @@ import org.json.JSONObject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.logging.L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by mike on 27.02.2016.
|
* Created by mike on 27.02.2016.
|
||||||
* <p>
|
* <p>
|
||||||
|
@ -17,7 +19,7 @@ import org.slf4j.LoggerFactory;
|
||||||
*/
|
*/
|
||||||
@DatabaseTable(tableName = DatabaseHelper.DATABASE_DBREQUESTS)
|
@DatabaseTable(tableName = DatabaseHelper.DATABASE_DBREQUESTS)
|
||||||
public class DbRequest {
|
public class DbRequest {
|
||||||
private static Logger log = LoggerFactory.getLogger(DbRequest.class);
|
private static Logger log = LoggerFactory.getLogger(L.DATABASE);
|
||||||
|
|
||||||
@DatabaseField(id = true)
|
@DatabaseField(id = true)
|
||||||
public String nsClientID = null;
|
public String nsClientID = null;
|
||||||
|
|
|
@ -9,24 +9,26 @@ import android.graphics.Color;
|
||||||
import com.j256.ormlite.field.DatabaseField;
|
import com.j256.ormlite.field.DatabaseField;
|
||||||
import com.j256.ormlite.table.DatabaseTable;
|
import com.j256.ormlite.table.DatabaseTable;
|
||||||
|
|
||||||
|
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.util.Date;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import info.nightscout.androidaps.Constants;
|
import info.nightscout.androidaps.Constants;
|
||||||
import info.nightscout.androidaps.MainApp;
|
|
||||||
import info.nightscout.androidaps.data.Iob;
|
import info.nightscout.androidaps.data.Iob;
|
||||||
import info.nightscout.androidaps.data.IobTotal;
|
import info.nightscout.androidaps.data.IobTotal;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
|
||||||
import info.nightscout.androidaps.interfaces.InsulinInterface;
|
import info.nightscout.androidaps.interfaces.InsulinInterface;
|
||||||
import info.nightscout.androidaps.interfaces.Interval;
|
import info.nightscout.androidaps.interfaces.Interval;
|
||||||
|
import info.nightscout.androidaps.logging.L;
|
||||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Overview.graphExtensions.DataPointWithLabelInterface;
|
import info.nightscout.androidaps.plugins.Overview.graphExtensions.DataPointWithLabelInterface;
|
||||||
import info.nightscout.androidaps.plugins.Overview.graphExtensions.PointsWithLabelGraphSeries;
|
import info.nightscout.androidaps.plugins.Overview.graphExtensions.PointsWithLabelGraphSeries;
|
||||||
|
import info.nightscout.androidaps.plugins.Treatments.Treatment;
|
||||||
import info.nightscout.utils.DateUtil;
|
import info.nightscout.utils.DateUtil;
|
||||||
import info.nightscout.utils.DecimalFormatter;
|
import info.nightscout.utils.DecimalFormatter;
|
||||||
|
import info.nightscout.utils.JsonHelper;
|
||||||
import info.nightscout.utils.Round;
|
import info.nightscout.utils.Round;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,7 +37,7 @@ import info.nightscout.utils.Round;
|
||||||
|
|
||||||
@DatabaseTable(tableName = DatabaseHelper.DATABASE_EXTENDEDBOLUSES)
|
@DatabaseTable(tableName = DatabaseHelper.DATABASE_EXTENDEDBOLUSES)
|
||||||
public class ExtendedBolus implements Interval, DataPointWithLabelInterface {
|
public class ExtendedBolus implements Interval, DataPointWithLabelInterface {
|
||||||
private static Logger log = LoggerFactory.getLogger(ExtendedBolus.class);
|
private static Logger log = LoggerFactory.getLogger(L.DATABASE);
|
||||||
|
|
||||||
@DatabaseField(id = true)
|
@DatabaseField(id = true)
|
||||||
public long date;
|
public long date;
|
||||||
|
@ -57,7 +59,7 @@ public class ExtendedBolus implements Interval, DataPointWithLabelInterface {
|
||||||
public int durationInMinutes = 0; // duration == 0 means end of extended bolus
|
public int durationInMinutes = 0; // duration == 0 means end of extended bolus
|
||||||
|
|
||||||
@DatabaseField
|
@DatabaseField
|
||||||
public int insulinInterfaceID = InsulinInterface.FASTACTINGINSULIN;
|
public int insulinInterfaceID = InsulinInterface.OREF_RAPID_ACTING;
|
||||||
@DatabaseField
|
@DatabaseField
|
||||||
public double dia = Constants.defaultDIA;
|
public double dia = Constants.defaultDIA;
|
||||||
|
|
||||||
|
@ -68,6 +70,36 @@ public class ExtendedBolus implements Interval, DataPointWithLabelInterface {
|
||||||
this.date = date;
|
this.date = date;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ExtendedBolus date(long date) {
|
||||||
|
this.date = date;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExtendedBolus insulin(double insulin) {
|
||||||
|
this.insulin = insulin;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExtendedBolus pumpId(long pumpId) {
|
||||||
|
this.pumpId = pumpId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExtendedBolus source(int source) {
|
||||||
|
this.source = source;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExtendedBolus durationInMinutes(int durationInMinutes) {
|
||||||
|
this.durationInMinutes = durationInMinutes;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExtendedBolus _id(String _id) {
|
||||||
|
this._id = _id;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isEqual(ExtendedBolus other) {
|
public boolean isEqual(ExtendedBolus other) {
|
||||||
if (date != other.date) {
|
if (date != other.date) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -91,6 +123,16 @@ public class ExtendedBolus implements Interval, DataPointWithLabelInterface {
|
||||||
pumpId = t.pumpId;
|
pumpId = t.pumpId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ExtendedBolus createFromJson(JSONObject json) {
|
||||||
|
ExtendedBolus extendedBolus = new ExtendedBolus()
|
||||||
|
.source(Source.NIGHTSCOUT)
|
||||||
|
.date(JsonHelper.safeGetLong(json, "mills"))
|
||||||
|
.durationInMinutes(JsonHelper.safeGetInt(json, "duration"))
|
||||||
|
.insulin(JsonHelper.safeGetDouble(json, "relative") / 60 * JsonHelper.safeGetInt(json, "duration"))
|
||||||
|
._id(JsonHelper.safeGetString(json, "_id"))
|
||||||
|
.pumpId(JsonHelper.safeGetLong(json, "pumpId"));
|
||||||
|
return extendedBolus;
|
||||||
|
}
|
||||||
// -------- Interval interface ---------
|
// -------- Interval interface ---------
|
||||||
|
|
||||||
Long cuttedEnd = null;
|
Long cuttedEnd = null;
|
||||||
|
@ -155,7 +197,7 @@ public class ExtendedBolus implements Interval, DataPointWithLabelInterface {
|
||||||
// -------- Interval interface end ---------
|
// -------- Interval interface end ---------
|
||||||
|
|
||||||
public String log() {
|
public String log() {
|
||||||
return "Bolus{" +
|
return "ExtendedBolus{" +
|
||||||
"date= " + date +
|
"date= " + date +
|
||||||
", date= " + DateUtil.dateAndTimeString(date) +
|
", date= " + DateUtil.dateAndTimeString(date) +
|
||||||
", isValid=" + isValid +
|
", isValid=" + isValid +
|
||||||
|
@ -176,7 +218,7 @@ public class ExtendedBolus implements Interval, DataPointWithLabelInterface {
|
||||||
|
|
||||||
public IobTotal iobCalc(long time) {
|
public IobTotal iobCalc(long time) {
|
||||||
IobTotal result = new IobTotal(time);
|
IobTotal result = new IobTotal(time);
|
||||||
InsulinInterface insulinInterface = ConfigBuilderPlugin.getActiveInsulin();
|
InsulinInterface insulinInterface = ConfigBuilderPlugin.getPlugin().getActiveInsulin();
|
||||||
|
|
||||||
int realDuration = getDurationToTime(time);
|
int realDuration = getDurationToTime(time);
|
||||||
|
|
||||||
|
@ -285,4 +327,5 @@ public class ExtendedBolus implements Interval, DataPointWithLabelInterface {
|
||||||
public int getColor() {
|
public int getColor() {
|
||||||
return Color.CYAN;
|
return Color.CYAN;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,208 +0,0 @@
|
||||||
package info.nightscout.androidaps.db;
|
|
||||||
|
|
||||||
import com.j256.ormlite.android.AndroidConnectionSource;
|
|
||||||
import com.j256.ormlite.dao.Dao;
|
|
||||||
import com.j256.ormlite.stmt.PreparedQuery;
|
|
||||||
import com.j256.ormlite.stmt.QueryBuilder;
|
|
||||||
import com.j256.ormlite.stmt.Where;
|
|
||||||
import com.j256.ormlite.table.TableUtils;
|
|
||||||
|
|
||||||
import org.json.JSONException;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.MainApp;
|
|
||||||
import info.nightscout.androidaps.events.EventFoodDatabaseChanged;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by mike on 24.09.2017.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class FoodHelper {
|
|
||||||
private static Logger log = LoggerFactory.getLogger(FoodHelper.class);
|
|
||||||
|
|
||||||
DatabaseHelper databaseHelper;
|
|
||||||
|
|
||||||
private static final ScheduledExecutorService foodEventWorker = Executors.newSingleThreadScheduledExecutor();
|
|
||||||
private static ScheduledFuture<?> scheduledFoodEventPost = null;
|
|
||||||
|
|
||||||
public FoodHelper(DatabaseHelper databaseHelper) {
|
|
||||||
this.databaseHelper = databaseHelper;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Dao<Food, Long> getDaoFood() throws SQLException {
|
|
||||||
return databaseHelper.getDao(Food.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void resetFood() {
|
|
||||||
try {
|
|
||||||
TableUtils.dropTable(databaseHelper.getConnectionSource(), Food.class, true);
|
|
||||||
TableUtils.createTableIfNotExists(databaseHelper.getConnectionSource(), Food.class);
|
|
||||||
} catch (SQLException e) {
|
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
scheduleFoodChange();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Food> getFoodData() {
|
|
||||||
try {
|
|
||||||
Dao<Food, Long> daoFood = getDaoFood();
|
|
||||||
List<Food> foods;
|
|
||||||
QueryBuilder<Food, Long> queryBuilder = daoFood.queryBuilder();
|
|
||||||
PreparedQuery<Food> preparedQuery = queryBuilder.prepare();
|
|
||||||
foods = daoFood.query(preparedQuery);
|
|
||||||
return foods;
|
|
||||||
} catch (SQLException e) {
|
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
return new ArrayList<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean createOrUpdate(Food food) {
|
|
||||||
try {
|
|
||||||
// find by NS _id
|
|
||||||
if (food._id != null && !food._id.equals("")) {
|
|
||||||
Food old;
|
|
||||||
|
|
||||||
QueryBuilder<Food, Long> queryBuilder = getDaoFood().queryBuilder();
|
|
||||||
Where where = queryBuilder.where();
|
|
||||||
where.eq("_id", food._id);
|
|
||||||
PreparedQuery<Food> preparedQuery = queryBuilder.prepare();
|
|
||||||
List<Food> found = getDaoFood().query(preparedQuery);
|
|
||||||
if (found.size() > 0) {
|
|
||||||
old = found.get(0);
|
|
||||||
if (!old.isEqual(food)) {
|
|
||||||
getDaoFood().delete(old); // need to delete/create because date may change too
|
|
||||||
old.copyFrom(food);
|
|
||||||
getDaoFood().create(old);
|
|
||||||
log.debug("FOOD: Updating record by _id: " + old.toString());
|
|
||||||
scheduleFoodChange();
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
getDaoFood().createOrUpdate(food);
|
|
||||||
log.debug("FOOD: New record: " + food.toString());
|
|
||||||
scheduleFoodChange();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void delete(Food food) {
|
|
||||||
try {
|
|
||||||
getDaoFood().delete(food);
|
|
||||||
scheduleFoodChange();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void scheduleFoodChange() {
|
|
||||||
class PostRunnable implements Runnable {
|
|
||||||
public void run() {
|
|
||||||
log.debug("Firing EventFoodChange");
|
|
||||||
MainApp.bus().post(new EventFoodDatabaseChanged());
|
|
||||||
scheduledFoodEventPost = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// prepare task for execution in 1 sec
|
|
||||||
// cancel waiting task to prevent sending multiple posts
|
|
||||||
if (scheduledFoodEventPost != null)
|
|
||||||
scheduledFoodEventPost.cancel(false);
|
|
||||||
Runnable task = new PostRunnable();
|
|
||||||
final int sec = 1;
|
|
||||||
scheduledFoodEventPost = foodEventWorker.schedule(task, sec, TimeUnit.SECONDS);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
{
|
|
||||||
"_id": "551ee3ad368e06e80856e6a9",
|
|
||||||
"type": "food",
|
|
||||||
"category": "Zakladni",
|
|
||||||
"subcategory": "Napoje",
|
|
||||||
"name": "Mleko",
|
|
||||||
"portion": 250,
|
|
||||||
"carbs": 12,
|
|
||||||
"gi": 1,
|
|
||||||
"created_at": "2015-04-14T06:59:16.500Z",
|
|
||||||
"unit": "ml"
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
public void createFoodFromJsonIfNotExists(JSONObject trJson) {
|
|
||||||
try {
|
|
||||||
Food food = new Food();
|
|
||||||
if (trJson.has("type") && trJson.getString("type").equals("food")) {
|
|
||||||
if (trJson.has("_id"))
|
|
||||||
food._id = trJson.getString("_id");
|
|
||||||
if (trJson.has("category"))
|
|
||||||
food.category = trJson.getString("category");
|
|
||||||
if (trJson.has("subcategory"))
|
|
||||||
food.subcategory = trJson.getString("subcategory");
|
|
||||||
if (trJson.has("name"))
|
|
||||||
food.name = trJson.getString("name");
|
|
||||||
if (trJson.has("unit"))
|
|
||||||
food.units = trJson.getString("unit");
|
|
||||||
if (trJson.has("portion"))
|
|
||||||
food.portion = trJson.getDouble("portion");
|
|
||||||
if (trJson.has("carbs"))
|
|
||||||
food.carbs = trJson.getInt("carbs");
|
|
||||||
if (trJson.has("gi"))
|
|
||||||
food.gi = trJson.getInt("gi");
|
|
||||||
if (trJson.has("energy"))
|
|
||||||
food.energy = trJson.getInt("energy");
|
|
||||||
if (trJson.has("protein"))
|
|
||||||
food.protein = trJson.getInt("protein");
|
|
||||||
if (trJson.has("fat"))
|
|
||||||
food.fat = trJson.getInt("fat");
|
|
||||||
}
|
|
||||||
createOrUpdate(food);
|
|
||||||
} catch (JSONException e) {
|
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void deleteFoodById(String _id) {
|
|
||||||
Food stored = findFoodById(_id);
|
|
||||||
if (stored != null) {
|
|
||||||
log.debug("FOOD: Removing Food record from database: " + stored.toString());
|
|
||||||
delete(stored);
|
|
||||||
scheduleFoodChange();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Food findFoodById(String _id) {
|
|
||||||
try {
|
|
||||||
QueryBuilder<Food, Long> queryBuilder = getDaoFood().queryBuilder();
|
|
||||||
Where where = queryBuilder.where();
|
|
||||||
where.eq("_id", _id);
|
|
||||||
PreparedQuery<Food> preparedQuery = queryBuilder.prepare();
|
|
||||||
List<Food> list = getDaoFood().query(preparedQuery);
|
|
||||||
|
|
||||||
if (list.size() == 1) {
|
|
||||||
return list.get(0);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
package info.nightscout.androidaps.db;
|
||||||
|
|
||||||
|
import java.util.concurrent.ScheduledFuture;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by triplem on 05.01.18.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public interface ICallback {
|
||||||
|
|
||||||
|
void setPost(ScheduledFuture<?> post);
|
||||||
|
|
||||||
|
ScheduledFuture<?> getPost();
|
||||||
|
|
||||||
|
}
|
|
@ -11,12 +11,14 @@ import org.json.JSONObject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
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.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
import info.nightscout.androidaps.interfaces.Interval;
|
import info.nightscout.androidaps.interfaces.Interval;
|
||||||
|
import info.nightscout.androidaps.logging.L;
|
||||||
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
|
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
|
||||||
import info.nightscout.androidaps.plugins.Overview.graphExtensions.DataPointWithLabelInterface;
|
import info.nightscout.androidaps.plugins.Overview.graphExtensions.DataPointWithLabelInterface;
|
||||||
import info.nightscout.androidaps.plugins.Overview.graphExtensions.PointsWithLabelGraphSeries;
|
import info.nightscout.androidaps.plugins.Overview.graphExtensions.PointsWithLabelGraphSeries;
|
||||||
|
@ -24,10 +26,11 @@ import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
|
||||||
import info.nightscout.androidaps.plugins.ProfileLocal.LocalProfilePlugin;
|
import info.nightscout.androidaps.plugins.ProfileLocal.LocalProfilePlugin;
|
||||||
import info.nightscout.utils.DateUtil;
|
import info.nightscout.utils.DateUtil;
|
||||||
import info.nightscout.utils.DecimalFormatter;
|
import info.nightscout.utils.DecimalFormatter;
|
||||||
|
import info.nightscout.utils.T;
|
||||||
|
|
||||||
@DatabaseTable(tableName = DatabaseHelper.DATABASE_PROFILESWITCHES)
|
@DatabaseTable(tableName = DatabaseHelper.DATABASE_PROFILESWITCHES)
|
||||||
public class ProfileSwitch implements Interval, DataPointWithLabelInterface {
|
public class ProfileSwitch implements Interval, DataPointWithLabelInterface {
|
||||||
private static Logger log = LoggerFactory.getLogger(ProfileSwitch.class);
|
private static Logger log = LoggerFactory.getLogger(L.DATABASE);
|
||||||
|
|
||||||
@DatabaseField(id = true)
|
@DatabaseField(id = true)
|
||||||
public long date;
|
public long date;
|
||||||
|
@ -61,6 +64,31 @@ public class ProfileSwitch implements Interval, DataPointWithLabelInterface {
|
||||||
|
|
||||||
private Profile profile = null;
|
private Profile profile = null;
|
||||||
|
|
||||||
|
public ProfileSwitch date(long date) {
|
||||||
|
this.date = date;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProfileSwitch profileName(String profileName) {
|
||||||
|
this.profileName = profileName;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProfileSwitch profile(Profile profile) {
|
||||||
|
this.profile = profile;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProfileSwitch source(int source) {
|
||||||
|
this.source = source;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProfileSwitch duration(int duration) {
|
||||||
|
this.durationInMinutes = duration;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public Profile getProfileObject() {
|
public Profile getProfileObject() {
|
||||||
if (profile == null)
|
if (profile == null)
|
||||||
|
@ -192,6 +220,26 @@ public class ProfileSwitch implements Interval, DataPointWithLabelInterface {
|
||||||
MainApp.bus().post(new EventNewNotification(notification));
|
MainApp.bus().post(new EventNewNotification(notification));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isEvent5minBack(List<ProfileSwitch> list, long time, boolean zeroDurationOnly) {
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
ProfileSwitch event = list.get(i);
|
||||||
|
if (event.date <= time && event.date > (time - T.mins(5).msecs())) {
|
||||||
|
if (zeroDurationOnly) {
|
||||||
|
if (event.durationInMinutes == 0) {
|
||||||
|
if (L.isEnabled(L.DATABASE))
|
||||||
|
log.debug("Found ProfileSwitch event for time: " + DateUtil.dateAndTimeFullString(time) + " " + event.toString());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (L.isEnabled(L.DATABASE))
|
||||||
|
log.debug("Found ProfileSwitch event for time: " + DateUtil.dateAndTimeFullString(time) + " " + event.toString());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// -------- Interval interface end ---------
|
// -------- Interval interface end ---------
|
||||||
|
|
||||||
// ----------------- DataPointInterface --------------------
|
// ----------------- DataPointInterface --------------------
|
||||||
|
|
48
app/src/main/java/info/nightscout/androidaps/db/TDD.java
Normal file
48
app/src/main/java/info/nightscout/androidaps/db/TDD.java
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
package info.nightscout.androidaps.db;
|
||||||
|
|
||||||
|
import com.j256.ormlite.field.DatabaseField;
|
||||||
|
import com.j256.ormlite.table.DatabaseTable;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.logging.L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mike on 20.09.2017.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@DatabaseTable(tableName = DatabaseHelper.DATABASE_TDDS)
|
||||||
|
public class TDD {
|
||||||
|
private static Logger log = LoggerFactory.getLogger(L.DATABASE);
|
||||||
|
|
||||||
|
@DatabaseField(id = true)
|
||||||
|
public long date;
|
||||||
|
|
||||||
|
@DatabaseField
|
||||||
|
public double bolus;
|
||||||
|
|
||||||
|
@DatabaseField
|
||||||
|
public double basal;
|
||||||
|
|
||||||
|
@DatabaseField
|
||||||
|
public double total;
|
||||||
|
|
||||||
|
|
||||||
|
public double getTotal(){
|
||||||
|
return (total > 0d) ? total:(bolus+basal);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public TDD() { }
|
||||||
|
|
||||||
|
public TDD(long date, double bolus, double basal, double total){
|
||||||
|
this.date = date;
|
||||||
|
this.bolus = bolus;
|
||||||
|
this.basal = basal;
|
||||||
|
this.total = total;
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,12 +11,13 @@ import java.util.Objects;
|
||||||
|
|
||||||
import info.nightscout.androidaps.Constants;
|
import info.nightscout.androidaps.Constants;
|
||||||
import info.nightscout.androidaps.interfaces.Interval;
|
import info.nightscout.androidaps.interfaces.Interval;
|
||||||
|
import info.nightscout.androidaps.logging.L;
|
||||||
import info.nightscout.utils.DateUtil;
|
import info.nightscout.utils.DateUtil;
|
||||||
import info.nightscout.utils.DecimalFormatter;
|
import info.nightscout.utils.DecimalFormatter;
|
||||||
|
|
||||||
@DatabaseTable(tableName = DatabaseHelper.DATABASE_TEMPTARGETS)
|
@DatabaseTable(tableName = DatabaseHelper.DATABASE_TEMPTARGETS)
|
||||||
public class TempTarget implements Interval {
|
public class TempTarget implements Interval {
|
||||||
private static Logger log = LoggerFactory.getLogger(TempTarget.class);
|
private static Logger log = LoggerFactory.getLogger(L.DATABASE);
|
||||||
|
|
||||||
@DatabaseField(id = true)
|
@DatabaseField(id = true)
|
||||||
public long date;
|
public long date;
|
||||||
|
@ -41,6 +42,10 @@ public class TempTarget implements Interval {
|
||||||
@DatabaseField
|
@DatabaseField
|
||||||
public int durationInMinutes;
|
public int durationInMinutes;
|
||||||
|
|
||||||
|
public double target() {
|
||||||
|
return (low + high) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isEqual(TempTarget other) {
|
public boolean isEqual(TempTarget other) {
|
||||||
if (date != other.date) {
|
if (date != other.date) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -67,6 +72,41 @@ public class TempTarget implements Interval {
|
||||||
reason = t.reason;
|
reason = t.reason;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TempTarget date(long date) {
|
||||||
|
this.date = date;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TempTarget low(double low) {
|
||||||
|
this.low = low;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TempTarget high(double high) {
|
||||||
|
this.high = high;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TempTarget duration(int duration) {
|
||||||
|
this.durationInMinutes = duration;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TempTarget reason(String reason) {
|
||||||
|
this.reason = reason;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TempTarget _id(String _id) {
|
||||||
|
this._id = _id;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TempTarget source(int source) {
|
||||||
|
this.source = source;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
// -------- Interval interface ---------
|
// -------- Interval interface ---------
|
||||||
|
|
||||||
Long cuttedEnd = null;
|
Long cuttedEnd = null;
|
||||||
|
|
|
@ -6,7 +6,6 @@ import com.j256.ormlite.table.DatabaseTable;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
|
@ -16,7 +15,10 @@ import info.nightscout.androidaps.data.IobTotal;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
import info.nightscout.androidaps.interfaces.InsulinInterface;
|
import info.nightscout.androidaps.interfaces.InsulinInterface;
|
||||||
import info.nightscout.androidaps.interfaces.Interval;
|
import info.nightscout.androidaps.interfaces.Interval;
|
||||||
|
import info.nightscout.androidaps.logging.L;
|
||||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions;
|
||||||
|
import info.nightscout.androidaps.plugins.Treatments.Treatment;
|
||||||
import info.nightscout.utils.DateUtil;
|
import info.nightscout.utils.DateUtil;
|
||||||
import info.nightscout.utils.DecimalFormatter;
|
import info.nightscout.utils.DecimalFormatter;
|
||||||
import info.nightscout.utils.SP;
|
import info.nightscout.utils.SP;
|
||||||
|
@ -27,7 +29,7 @@ import info.nightscout.utils.SP;
|
||||||
|
|
||||||
@DatabaseTable(tableName = DatabaseHelper.DATABASE_TEMPORARYBASALS)
|
@DatabaseTable(tableName = DatabaseHelper.DATABASE_TEMPORARYBASALS)
|
||||||
public class TemporaryBasal implements Interval {
|
public class TemporaryBasal implements Interval {
|
||||||
private static Logger log = LoggerFactory.getLogger(TemporaryBasal.class);
|
private static Logger log = LoggerFactory.getLogger(L.DATABASE);
|
||||||
|
|
||||||
@DatabaseField(id = true)
|
@DatabaseField(id = true)
|
||||||
public long date;
|
public long date;
|
||||||
|
@ -60,12 +62,40 @@ public class TemporaryBasal implements Interval {
|
||||||
public TemporaryBasal() {
|
public TemporaryBasal() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public TemporaryBasal(long date) {
|
public TemporaryBasal date(long date) {
|
||||||
this.date = date;
|
this.date = date;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TemporaryBasal duration(int durationInMinutes) {
|
||||||
|
this.durationInMinutes = durationInMinutes;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TemporaryBasal absolute(double absoluteRate) {
|
||||||
|
this.absoluteRate = absoluteRate;
|
||||||
|
this.isAbsolute = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TemporaryBasal percent(int percentRate) {
|
||||||
|
this.percentRate = percentRate;
|
||||||
|
this.isAbsolute = false;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TemporaryBasal source(int source) {
|
||||||
|
this.source = source;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TemporaryBasal pumpId(long pumpId) {
|
||||||
|
this.pumpId = pumpId;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TemporaryBasal(ExtendedBolus extendedBolus) {
|
public TemporaryBasal(ExtendedBolus extendedBolus) {
|
||||||
double basal = MainApp.getConfigBuilder().getProfile(extendedBolus.date).getBasal(extendedBolus.date);
|
double basal = ProfileFunctions.getInstance().getProfile(extendedBolus.date).getBasal(extendedBolus.date);
|
||||||
this.date = extendedBolus.date;
|
this.date = extendedBolus.date;
|
||||||
this.isValid = extendedBolus.isValid;
|
this.isValid = extendedBolus.isValid;
|
||||||
this.source = extendedBolus.source;
|
this.source = extendedBolus.source;
|
||||||
|
@ -75,6 +105,7 @@ public class TemporaryBasal implements Interval {
|
||||||
this.isFakeExtended = true;
|
this.isFakeExtended = true;
|
||||||
this.netExtendedRate = extendedBolus.absoluteRate();
|
this.netExtendedRate = extendedBolus.absoluteRate();
|
||||||
this.absoluteRate = basal + extendedBolus.absoluteRate();
|
this.absoluteRate = basal + extendedBolus.absoluteRate();
|
||||||
|
this.pumpId = extendedBolus.pumpId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TemporaryBasal clone() {
|
public TemporaryBasal clone() {
|
||||||
|
@ -189,18 +220,17 @@ public class TemporaryBasal implements Interval {
|
||||||
|
|
||||||
// -------- Interval interface end ---------
|
// -------- Interval interface end ---------
|
||||||
|
|
||||||
public IobTotal iobCalc(long time) {
|
public IobTotal iobCalc(long time, Profile profile) {
|
||||||
|
|
||||||
if(isFakeExtended){
|
if (isFakeExtended) {
|
||||||
log.error("iobCalc should only be called on Extended boluses separately");
|
log.error("iobCalc should only be called on Extended boluses separately");
|
||||||
return new IobTotal(time);
|
return new IobTotal(time);
|
||||||
}
|
}
|
||||||
|
|
||||||
IobTotal result = new IobTotal(time);
|
IobTotal result = new IobTotal(time);
|
||||||
Profile profile = MainApp.getConfigBuilder().getProfile(time);
|
InsulinInterface insulinInterface = ConfigBuilderPlugin.getPlugin().getActiveInsulin();
|
||||||
InsulinInterface insulinInterface = ConfigBuilderPlugin.getActiveInsulin();
|
|
||||||
|
|
||||||
int realDuration = getDurationToTime(time);
|
int realDuration = getDurationToTime(time);
|
||||||
double netBasalAmount = 0d;
|
double netBasalAmount = 0d;
|
||||||
|
|
||||||
if (realDuration > 0) {
|
if (realDuration > 0) {
|
||||||
|
@ -262,13 +292,23 @@ public class TemporaryBasal implements Interval {
|
||||||
return (remainingMin < 0) ? 0 : Math.round(remainingMin);
|
return (remainingMin < 0) ? 0 : Math.round(remainingMin);
|
||||||
}
|
}
|
||||||
|
|
||||||
public double tempBasalConvertedToAbsolute(long time) {
|
public double tempBasalConvertedToAbsolute(long time, Profile profile) {
|
||||||
if(isFakeExtended){
|
if (isFakeExtended) {
|
||||||
return MainApp.getConfigBuilder().getProfile(time).getBasal(time) + netExtendedRate;
|
return profile.getBasal(time) + netExtendedRate;
|
||||||
} else if (isAbsolute) {
|
} else if (isAbsolute) {
|
||||||
return absoluteRate;
|
return absoluteRate;
|
||||||
} else {
|
} else {
|
||||||
return MainApp.getConfigBuilder().getProfile(time).getBasal(time) * percentRate / 100;
|
return profile.getBasal(time) * percentRate / 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int tempBasalConvertedToPercent(long time, Profile profile) {
|
||||||
|
if (isFakeExtended) {
|
||||||
|
return (int) ((profile.getBasal(time) + netExtendedRate) / profile.getBasal(time)) * 100;
|
||||||
|
} else if (isAbsolute) {
|
||||||
|
return (int) (absoluteRate / profile.getBasal(time)) * 100;
|
||||||
|
} else {
|
||||||
|
return percentRate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,12 +329,12 @@ public class TemporaryBasal implements Interval {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toStringFull() {
|
public String toStringFull() {
|
||||||
if(isFakeExtended){
|
if (isFakeExtended) {
|
||||||
|
|
||||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||||
Double currentBasalRate = profile.getBasal();
|
Double currentBasalRate = profile.getBasal();
|
||||||
double rate = (currentBasalRate == null)?0d:(currentBasalRate+netExtendedRate);
|
double rate = (currentBasalRate == null) ? 0d : (currentBasalRate + netExtendedRate);
|
||||||
return getCalcuatedPercentageIfNeeded() + DecimalFormatter.to2Decimal(rate) + "U/h ("+DecimalFormatter.to2Decimal(netExtendedRate)+"E) @" +
|
return getCalcuatedPercentageIfNeeded() + DecimalFormatter.to2Decimal(rate) + "U/h (" + DecimalFormatter.to2Decimal(netExtendedRate) + "E) @" +
|
||||||
DateUtil.timeString(date) +
|
DateUtil.timeString(date) +
|
||||||
" " + getRealDuration() + "/" + durationInMinutes + "'";
|
" " + getRealDuration() + "/" + durationInMinutes + "'";
|
||||||
} else if (isAbsolute) {
|
} else if (isAbsolute) {
|
||||||
|
@ -311,48 +351,48 @@ public class TemporaryBasal implements Interval {
|
||||||
public String toStringShort() {
|
public String toStringShort() {
|
||||||
if (isAbsolute || isFakeExtended) {
|
if (isAbsolute || isFakeExtended) {
|
||||||
|
|
||||||
double rate = 0d;
|
double rate = 0d;
|
||||||
if (isFakeExtended) {
|
if (isFakeExtended) {
|
||||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||||
Double currentBasalRate = profile.getBasal();
|
Double currentBasalRate = profile.getBasal();
|
||||||
rate = (currentBasalRate == null)?0d:(currentBasalRate+netExtendedRate);
|
rate = (currentBasalRate == null) ? 0d : (currentBasalRate + netExtendedRate);
|
||||||
} else if (isAbsolute){
|
} else if (isAbsolute) {
|
||||||
rate = absoluteRate;
|
rate = absoluteRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(SP.getBoolean(R.string.key_danar_visualizeextendedaspercentage, false) && SP.getBoolean(R.string.key_danar_useextended, false)){
|
if (SP.getBoolean(R.string.key_danar_visualizeextendedaspercentage, false) && SP.getBoolean(R.string.key_danar_useextended, false)) {
|
||||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||||
if(profile != null) {
|
if (profile != null) {
|
||||||
double basal = profile.getBasal();
|
double basal = profile.getBasal();
|
||||||
if(basal != 0){
|
if (basal != 0) {
|
||||||
return Math.round(rate*100d/basal) + "% ";
|
return Math.round(rate * 100d / basal) + "%";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return DecimalFormatter.to2Decimal(rate) + "U/h ";
|
return DecimalFormatter.to2Decimal(rate) + "U/h";
|
||||||
} else { // percent
|
} else { // percent
|
||||||
return percentRate + "% ";
|
return percentRate + "%";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getCalcuatedPercentageIfNeeded(){
|
private String getCalcuatedPercentageIfNeeded() {
|
||||||
if (isAbsolute || isFakeExtended) {
|
if (isAbsolute || isFakeExtended) {
|
||||||
|
|
||||||
double rate = 0d;
|
double rate = 0d;
|
||||||
if (isFakeExtended) {
|
if (isFakeExtended) {
|
||||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||||
Double currentBasalRate = profile.getBasal();
|
Double currentBasalRate = profile.getBasal();
|
||||||
rate = (currentBasalRate == null)?0d:(currentBasalRate+netExtendedRate);
|
rate = (currentBasalRate == null) ? 0d : (currentBasalRate + netExtendedRate);
|
||||||
} else if (isAbsolute){
|
} else if (isAbsolute) {
|
||||||
rate = absoluteRate;
|
rate = absoluteRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(SP.getBoolean(R.string.key_danar_visualizeextendedaspercentage, false) && SP.getBoolean(R.string.key_danar_useextended, false)){
|
if (SP.getBoolean(R.string.key_danar_visualizeextendedaspercentage, false) && SP.getBoolean(R.string.key_danar_useextended, false)) {
|
||||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||||
if(profile != null) {
|
if (profile != null) {
|
||||||
double basal = profile.getBasal();
|
double basal = profile.getBasal();
|
||||||
if(basal != 0){
|
if (basal != 0) {
|
||||||
return Math.round(rate*100d/basal) + "% ";
|
return Math.round(rate * 100d / basal) + "% ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -363,12 +403,12 @@ public class TemporaryBasal implements Interval {
|
||||||
public String toStringVeryShort() {
|
public String toStringVeryShort() {
|
||||||
if (isAbsolute || isFakeExtended) {
|
if (isAbsolute || isFakeExtended) {
|
||||||
|
|
||||||
double rate = 0d;
|
double rate = 0d;
|
||||||
if (isFakeExtended) {
|
if (isFakeExtended) {
|
||||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||||
Double currentBasalRate = profile.getBasal();
|
Double currentBasalRate = profile.getBasal();
|
||||||
rate = (currentBasalRate == null)?0d:(currentBasalRate+netExtendedRate);
|
rate = (currentBasalRate == null) ? 0d : (currentBasalRate + netExtendedRate);
|
||||||
} else if (isAbsolute){
|
} else if (isAbsolute) {
|
||||||
rate = absoluteRate;
|
rate = absoluteRate;
|
||||||
}
|
}
|
||||||
return DecimalFormatter.to2Decimal(rate) + "U/h ";
|
return DecimalFormatter.to2Decimal(rate) + "U/h ";
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
package info.nightscout.androidaps.events;
|
||||||
|
|
||||||
|
/** Base class for events to update the UI, mostly a specific tab. */
|
||||||
|
public class EventAcceptOpenLoopChange extends Event {
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package info.nightscout.androidaps.events;
|
||||||
|
|
||||||
|
public class EventChargingState {
|
||||||
|
|
||||||
|
public boolean isCharging = false;
|
||||||
|
|
||||||
|
public EventChargingState() {}
|
||||||
|
|
||||||
|
public EventChargingState(boolean isCharging) {
|
||||||
|
this.isCharging = isCharging;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package info.nightscout.androidaps.events;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mike on 13.02.2018.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class EventCustomCalculationFinished extends Event {
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package info.nightscout.androidaps.events;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by jamorham on 07/02/2018.
|
||||||
|
*
|
||||||
|
* Event to indicate that an app feature is being used, for example bolus wizard being opened
|
||||||
|
*
|
||||||
|
* The purpose this has been created for is to enable opportunistic connection to the pump
|
||||||
|
* so that it is already connected before the user wishes to enact a pump function
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class EventFeatureRunning extends Event {
|
||||||
|
|
||||||
|
private Feature feature = Feature.UNKNOWN;
|
||||||
|
|
||||||
|
public EventFeatureRunning() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public EventFeatureRunning(Feature feature) {
|
||||||
|
this.feature = feature;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Feature getFeature() {
|
||||||
|
return feature;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum Feature {
|
||||||
|
UNKNOWN,
|
||||||
|
MAIN,
|
||||||
|
WIZARD,
|
||||||
|
|
||||||
|
JUST_ADD_MORE_HERE
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package info.nightscout.androidaps.events;
|
||||||
|
|
||||||
|
|
||||||
|
import info.nightscout.utils.StringUtils;
|
||||||
|
|
||||||
|
public class EventNetworkChange extends Event {
|
||||||
|
|
||||||
|
public boolean mobileConnected = false;
|
||||||
|
public boolean wifiConnected = false;
|
||||||
|
|
||||||
|
public String ssid = "";
|
||||||
|
public boolean roaming = false;
|
||||||
|
|
||||||
|
public String getSsid() {
|
||||||
|
return StringUtils.removeSurroundingQuotes(ssid);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,17 @@
|
||||||
package info.nightscout.androidaps.events;
|
package info.nightscout.androidaps.events;
|
||||||
|
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.db.BgReading;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by mike on 05.06.2016.
|
* Created by mike on 05.06.2016.
|
||||||
*/
|
*/
|
||||||
public class EventNewBG extends EventLoop {
|
public class EventNewBG extends EventLoop {
|
||||||
|
@Nullable
|
||||||
|
public final BgReading bgReading;
|
||||||
|
|
||||||
|
public EventNewBG(BgReading bgReading) {
|
||||||
|
this.bgReading = bgReading;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
package info.nightscout.androidaps.events;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event which is published with data fetched from NightScout specific for the
|
||||||
|
* Food-class.
|
||||||
|
*
|
||||||
|
* Payload is the from NS retrieved JSON-String which should be handled by all
|
||||||
|
* subscriber.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class EventNsFood extends Event {
|
||||||
|
|
||||||
|
public static final int ADD = 0;
|
||||||
|
public static final int UPDATE = 1;
|
||||||
|
public static final int REMOVE = 2;
|
||||||
|
|
||||||
|
private final int mode;
|
||||||
|
|
||||||
|
private final Bundle payload;
|
||||||
|
|
||||||
|
public EventNsFood(int mode, Bundle payload) {
|
||||||
|
this.mode = mode;
|
||||||
|
this.payload = payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMode() {
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Bundle getPayload() {
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package info.nightscout.androidaps.events;
|
||||||
|
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event which is published with data fetched from NightScout specific for the
|
||||||
|
* Treatment-class.
|
||||||
|
* <p>
|
||||||
|
* Payload is the from NS retrieved JSON-String which should be handled by all
|
||||||
|
* subscriber.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class EventNsTreatment extends Event {
|
||||||
|
|
||||||
|
public static final int ADD = 0;
|
||||||
|
public static final int UPDATE = 1;
|
||||||
|
public static final int REMOVE = 2;
|
||||||
|
|
||||||
|
private final int mode;
|
||||||
|
|
||||||
|
private final JSONObject payload;
|
||||||
|
|
||||||
|
public EventNsTreatment(int mode, JSONObject payload) {
|
||||||
|
this.mode = mode;
|
||||||
|
this.payload = payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMode() {
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject getPayload() {
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,11 +12,11 @@ public class EventPreferenceChange extends Event {
|
||||||
}
|
}
|
||||||
|
|
||||||
public EventPreferenceChange(int resourceID) {
|
public EventPreferenceChange(int resourceID) {
|
||||||
changedKey = MainApp.sResources.getString(resourceID);
|
changedKey = MainApp.gs(resourceID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isChanged(int id) {
|
public boolean isChanged(int id) {
|
||||||
return changedKey.equals(MainApp.sResources.getString(id));
|
return changedKey.equals(MainApp.gs(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isChanged(String id) {
|
public boolean isChanged(String id) {
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
package info.nightscout.androidaps.events;
|
||||||
|
|
||||||
|
public class EventProfileStoreChanged extends Event {
|
||||||
|
}
|
|
@ -10,9 +10,10 @@ import info.nightscout.androidaps.R;
|
||||||
public class EventPumpStatusChanged extends Event {
|
public class EventPumpStatusChanged extends Event {
|
||||||
public static final int CONNECTING = 0;
|
public static final int CONNECTING = 0;
|
||||||
public static final int CONNECTED = 1;
|
public static final int CONNECTED = 1;
|
||||||
public static final int PERFORMING = 2;
|
public static final int HANDSHAKING = 2;
|
||||||
public static final int DISCONNECTING = 3;
|
public static final int PERFORMING = 3;
|
||||||
public static final int DISCONNECTED = 4;
|
public static final int DISCONNECTING = 4;
|
||||||
|
public static final int DISCONNECTED = 5;
|
||||||
|
|
||||||
public int sStatus = DISCONNECTED;
|
public int sStatus = DISCONNECTED;
|
||||||
public int sSecondsElapsed = 0;
|
public int sSecondsElapsed = 0;
|
||||||
|
@ -46,13 +47,15 @@ public class EventPumpStatusChanged extends Event {
|
||||||
|
|
||||||
public String textStatus() {
|
public String textStatus() {
|
||||||
if (sStatus == CONNECTING)
|
if (sStatus == CONNECTING)
|
||||||
return String.format(MainApp.sResources.getString(R.string.danar_history_connectingfor), sSecondsElapsed);
|
return String.format(MainApp.gs(R.string.danar_history_connectingfor), sSecondsElapsed);
|
||||||
|
else if (sStatus == HANDSHAKING)
|
||||||
|
return MainApp.gs(R.string.handshaking);
|
||||||
else if (sStatus == CONNECTED)
|
else if (sStatus == CONNECTED)
|
||||||
return MainApp.sResources.getString(R.string.connected);
|
return MainApp.gs(R.string.connected);
|
||||||
else if (sStatus == PERFORMING)
|
else if (sStatus == PERFORMING)
|
||||||
return sPerfomingAction;
|
return sPerfomingAction;
|
||||||
else if (sStatus == DISCONNECTING)
|
else if (sStatus == DISCONNECTING)
|
||||||
return MainApp.sResources.getString(R.string.disconnecting);
|
return MainApp.gs(R.string.disconnecting);
|
||||||
else if (sStatus == DISCONNECTED)
|
else if (sStatus == DISCONNECTED)
|
||||||
return "";
|
return "";
|
||||||
return "";
|
return "";
|
||||||
|
|
|
@ -1,7 +1,17 @@
|
||||||
package info.nightscout.androidaps.events;
|
package info.nightscout.androidaps.events;
|
||||||
|
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.plugins.Treatments.Treatment;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by mike on 04.06.2016.
|
* Created by mike on 04.06.2016.
|
||||||
*/
|
*/
|
||||||
public class EventTreatmentChange extends EventLoop {
|
public class EventTreatmentChange extends EventLoop {
|
||||||
|
@Nullable
|
||||||
|
public final Treatment treatment;
|
||||||
|
|
||||||
|
public EventTreatmentChange(Treatment treatment) {
|
||||||
|
this.treatment = treatment;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
package info.nightscout.androidaps.interfaces;
|
package info.nightscout.androidaps.interfaces;
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.plugins.Loop.APSResult;
|
import info.nightscout.androidaps.plugins.Loop.APSResult;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -9,7 +7,7 @@ import info.nightscout.androidaps.plugins.Loop.APSResult;
|
||||||
*/
|
*/
|
||||||
public interface APSInterface {
|
public interface APSInterface {
|
||||||
public APSResult getLastAPSResult();
|
public APSResult getLastAPSResult();
|
||||||
public Date getLastAPSRun();
|
public long getLastAPSRun();
|
||||||
|
|
||||||
public void invoke(String initiator);
|
public void invoke(String initiator, boolean tempBasalFallback);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
package info.nightscout.androidaps.interfaces;
|
package info.nightscout.androidaps.interfaces;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by mike on 20.06.2016.
|
* Created by mike on 20.06.2016.
|
||||||
*/
|
*/
|
||||||
public interface BgSourceInterface {
|
public interface BgSourceInterface {
|
||||||
|
boolean advancedFilteringSupported();
|
||||||
|
|
||||||
|
void handleNewData(Intent intent);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,144 @@
|
||||||
|
package info.nightscout.androidaps.interfaces;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.logging.L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mike on 19.03.2018.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class Constraint<T extends Comparable> {
|
||||||
|
private static Logger log = LoggerFactory.getLogger(L.CONSTRAINTS);
|
||||||
|
|
||||||
|
T value;
|
||||||
|
T originalValue;
|
||||||
|
|
||||||
|
List<String> reasons = new ArrayList<>();
|
||||||
|
List<String> mostLimiting = new ArrayList<>();
|
||||||
|
|
||||||
|
public Constraint(T value) {
|
||||||
|
this.value = value;
|
||||||
|
this.originalValue = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T value() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T originalValue() {
|
||||||
|
return originalValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Constraint<T> set(T value) {
|
||||||
|
this.value = value;
|
||||||
|
this.originalValue = value;
|
||||||
|
if (L.isEnabled(L.CONSTRAINTS))
|
||||||
|
log.debug("Setting value " + value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Constraint<T> set(T value, String reason, Object from) {
|
||||||
|
if (L.isEnabled(L.CONSTRAINTS))
|
||||||
|
log.debug("Setting value " + this.value + " -> " + value + " (" + reason + ")[" + translateFrom(from) + "]");
|
||||||
|
this.value = value;
|
||||||
|
addReason(reason, from);
|
||||||
|
addMostLimingReason(reason, from);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Constraint<T> setIfDifferent(T value, String reason, Object from) {
|
||||||
|
if (!this.value.equals(value)) {
|
||||||
|
if (L.isEnabled(L.CONSTRAINTS))
|
||||||
|
log.debug("Setting because of different value " + this.value + " -> " + value + " (" + reason + ")[" + translateFrom(from) + "]");
|
||||||
|
this.value = value;
|
||||||
|
addReason(reason, from);
|
||||||
|
addMostLimingReason(reason, from);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Constraint<T> setIfSmaller(T value, String reason, Object from) {
|
||||||
|
if (value.compareTo(this.value) < 0) {
|
||||||
|
if (L.isEnabled(L.CONSTRAINTS))
|
||||||
|
log.debug("Setting because of smaller value " + this.value + " -> " + value + " (" + reason + ")[" + translateFrom(from) + "]");
|
||||||
|
this.value = value;
|
||||||
|
mostLimiting.clear();
|
||||||
|
addMostLimingReason(reason, from);
|
||||||
|
}
|
||||||
|
if (value.compareTo(this.originalValue) < 0) {
|
||||||
|
addReason(reason, from);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Constraint<T> setIfGreater(T value, String reason, Object from) {
|
||||||
|
if (value.compareTo(this.value) > 0) {
|
||||||
|
if (L.isEnabled(L.CONSTRAINTS))
|
||||||
|
log.debug("Setting because of greater value " + this.value + " -> " + value + " (" + reason + ")[" + translateFrom(from) + "]");
|
||||||
|
this.value = value;
|
||||||
|
mostLimiting.clear();
|
||||||
|
addMostLimingReason(reason, from);
|
||||||
|
}
|
||||||
|
if (value.compareTo(this.originalValue) > 0) {
|
||||||
|
addReason(reason, from);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String translateFrom(Object from) {
|
||||||
|
return from.getClass().getSimpleName().replace("Plugin", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Constraint addReason(String reason, Object from) {
|
||||||
|
reasons.add(translateFrom(from) + ": " + reason);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Constraint addMostLimingReason(String reason, Object from) {
|
||||||
|
mostLimiting.add(translateFrom(from) + ": " + reason);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getReasons() {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
int count = 0;
|
||||||
|
for (String r : reasons) {
|
||||||
|
if (count++ != 0) sb.append("\n");
|
||||||
|
sb.append(r);
|
||||||
|
}
|
||||||
|
if (L.isEnabled(L.CONSTRAINTS))
|
||||||
|
log.debug("Limiting origial value: " + originalValue + " to " + value + ". Reason: " + sb.toString());
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getReasonList() {
|
||||||
|
return reasons;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMostLimitedReasons() {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
int count = 0;
|
||||||
|
for (String r : mostLimiting) {
|
||||||
|
if (count++ != 0) sb.append("\n");
|
||||||
|
sb.append(r);
|
||||||
|
}
|
||||||
|
if (L.isEnabled(L.CONSTRAINTS))
|
||||||
|
log.debug("Limiting origial value: " + originalValue + " to " + value + ". Reason: " + sb.toString());
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getMostLimitedReasonList() {
|
||||||
|
return mostLimiting;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void copyReasons(Constraint<?> another) {
|
||||||
|
for (String s : another.getReasonList()) {
|
||||||
|
reasons.add(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,30 +1,62 @@
|
||||||
package info.nightscout.androidaps.interfaces;
|
package info.nightscout.androidaps.interfaces;
|
||||||
|
|
||||||
import info.nightscout.androidaps.plugins.Loop.APSResult;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by mike on 15.06.2016.
|
* Created by mike on 15.06.2016.
|
||||||
*/
|
*/
|
||||||
public interface ConstraintsInterface {
|
public interface ConstraintsInterface {
|
||||||
|
|
||||||
boolean isLoopEnabled();
|
default Constraint<Boolean> isLoopInvocationAllowed(Constraint<Boolean> value) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
boolean isClosedModeEnabled();
|
default Constraint<Boolean> isClosedLoopAllowed(Constraint<Boolean> value) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
boolean isAutosensModeEnabled();
|
default Constraint<Boolean> isAutosensModeEnabled(Constraint<Boolean> value) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
boolean isAMAModeEnabled();
|
default Constraint<Boolean> isAMAModeEnabled(Constraint<Boolean> value) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
boolean isSMBModeEnabled();
|
default Constraint<Boolean> isSMBModeEnabled(Constraint<Boolean> value) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
Double applyBasalConstraints(Double absoluteRate);
|
default Constraint<Boolean> isUAMEnabled(Constraint<Boolean> value) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
Integer applyBasalConstraints(Integer percentRate);
|
default Constraint<Boolean> isAdvancedFilteringEnabled(Constraint<Boolean> value) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
Double applyBolusConstraints(Double insulin);
|
default Constraint<Double> applyBasalConstraints(Constraint<Double> absoluteRate, Profile profile) {
|
||||||
|
return absoluteRate;
|
||||||
|
}
|
||||||
|
|
||||||
Integer applyCarbsConstraints(Integer carbs);
|
default Constraint<Integer> applyBasalPercentConstraints(Constraint<Integer> percentRate, Profile profile) {
|
||||||
|
return percentRate;
|
||||||
|
}
|
||||||
|
|
||||||
Double applyMaxIOBConstraints(Double maxIob);
|
default Constraint<Double> applyBolusConstraints(Constraint<Double> insulin) {
|
||||||
|
return insulin;
|
||||||
|
}
|
||||||
|
|
||||||
|
default Constraint<Double> applyExtendedBolusConstraints(Constraint<Double> insulin) {
|
||||||
|
return insulin;
|
||||||
|
}
|
||||||
|
|
||||||
|
default Constraint<Integer> applyCarbsConstraints(Constraint<Integer> carbs) {
|
||||||
|
return carbs;
|
||||||
|
}
|
||||||
|
|
||||||
|
default Constraint<Double> applyMaxIOBConstraints(Constraint<Double> maxIob) {
|
||||||
|
return maxIob;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,4 +9,5 @@ import info.nightscout.androidaps.data.PumpEnactResult;
|
||||||
public interface DanaRInterface {
|
public interface DanaRInterface {
|
||||||
PumpEnactResult loadHistory(byte type); // for history browser
|
PumpEnactResult loadHistory(byte type); // for history browser
|
||||||
PumpEnactResult loadEvents(); // events history to build treatments from
|
PumpEnactResult loadEvents(); // events history to build treatments from
|
||||||
|
PumpEnactResult setUserOptions(); // like AnyDana does
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +1,23 @@
|
||||||
package info.nightscout.androidaps.interfaces;
|
package info.nightscout.androidaps.interfaces;
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.data.Iob;
|
import info.nightscout.androidaps.data.Iob;
|
||||||
import info.nightscout.androidaps.db.Treatment;
|
import info.nightscout.androidaps.plugins.Treatments.Treatment;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by mike on 17.04.2017.
|
* Created by mike on 17.04.2017.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public interface InsulinInterface {
|
public interface InsulinInterface {
|
||||||
final int FASTACTINGINSULIN = 0;
|
// int FASTACTINGINSULIN = 0; // old model no longer available
|
||||||
final int FASTACTINGINSULINPROLONGED = 1;
|
// int FASTACTINGINSULINPROLONGED = 1; // old model no longer available
|
||||||
final int OREF_RAPID_ACTING = 2;
|
int OREF_RAPID_ACTING = 2;
|
||||||
final int OREF_ULTRA_RAPID_ACTING = 3;
|
int OREF_ULTRA_RAPID_ACTING = 3;
|
||||||
final int OREF_FREE_PEAK = 4;
|
int OREF_FREE_PEAK = 4;
|
||||||
|
|
||||||
|
|
||||||
int getId();
|
int getId();
|
||||||
String getFriendlyName();
|
String getFriendlyName();
|
||||||
String getComment();
|
String getComment();
|
||||||
double getDia();
|
double getDia();
|
||||||
public Iob iobCalcForTreatment(Treatment treatment, long time, double dia);
|
Iob iobCalcForTreatment(Treatment treatment, long time, double dia);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,34 +1,184 @@
|
||||||
package info.nightscout.androidaps.interfaces;
|
package info.nightscout.androidaps.interfaces;
|
||||||
|
|
||||||
import java.util.Date;
|
import android.os.SystemClock;
|
||||||
|
import android.support.v4.app.FragmentActivity;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.MainApp;
|
||||||
|
import info.nightscout.androidaps.logging.L;
|
||||||
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderFragment;
|
||||||
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||||
|
import info.nightscout.androidaps.queue.CommandQueue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by mike on 09.06.2016.
|
* Created by mike on 09.06.2016.
|
||||||
*/
|
*/
|
||||||
public interface PluginBase {
|
public abstract class PluginBase {
|
||||||
int GENERAL = 1;
|
private static Logger log = LoggerFactory.getLogger(L.CORE);
|
||||||
int TREATMENT = 2;
|
|
||||||
int SENSITIVITY = 3;
|
|
||||||
int PROFILE = 4;
|
|
||||||
int APS = 5;
|
|
||||||
int PUMP = 6;
|
|
||||||
int CONSTRAINTS = 7;
|
|
||||||
int LOOP = 8;
|
|
||||||
int BGSOURCE = 9;
|
|
||||||
int INSULIN = 10;
|
|
||||||
int LAST = 11; // keep always highest number
|
|
||||||
|
|
||||||
int getType();
|
public enum State {
|
||||||
String getFragmentClass();
|
NOT_INITIALIZED,
|
||||||
|
ENABLED,
|
||||||
|
DISABLED
|
||||||
|
}
|
||||||
|
|
||||||
String getName();
|
private State state = State.NOT_INITIALIZED;
|
||||||
String getNameShort();
|
private boolean isFragmentVisible = false;
|
||||||
boolean isEnabled(int type);
|
public PluginDescription pluginDescription;
|
||||||
boolean isVisibleInTabs(int type);
|
|
||||||
boolean canBeHidden(int type);
|
|
||||||
boolean hasFragment();
|
// Specific plugin with more Interfaces
|
||||||
boolean showInList(int type);
|
protected boolean isProfileInterfaceEnabled = false;
|
||||||
void setFragmentEnabled(int type, boolean fragmentEnabled);
|
|
||||||
void setFragmentVisible(int type, boolean fragmentVisible);
|
public PluginBase(PluginDescription pluginDescription) {
|
||||||
int getPreferencesId();
|
this.pluginDescription = pluginDescription;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default always calls invoke
|
||||||
|
// Plugins that have special constraints if they get switched to may override this method
|
||||||
|
public void switchAllowed(ConfigBuilderFragment.PluginViewHolder.PluginSwitcher pluginSwitcher, FragmentActivity activity) {
|
||||||
|
pluginSwitcher.invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
// public PluginType getType() {
|
||||||
|
// return mainType;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public String getFragmentClass() {
|
||||||
|
// return fragmentClass;
|
||||||
|
// }
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
if (pluginDescription.pluginName == -1)
|
||||||
|
return "UKNOWN";
|
||||||
|
else
|
||||||
|
return MainApp.gs(pluginDescription.pluginName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNameShort() {
|
||||||
|
if (pluginDescription.shortName == -1)
|
||||||
|
return getName();
|
||||||
|
String name = MainApp.gs(pluginDescription.shortName);
|
||||||
|
if (!name.trim().isEmpty()) //only if translation exists
|
||||||
|
return name;
|
||||||
|
// use long name as fallback
|
||||||
|
return getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
if (pluginDescription.description == -1) return null;
|
||||||
|
else return MainApp.gs(pluginDescription.description);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PluginType getType() {
|
||||||
|
return pluginDescription.mainType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPreferencesId() {
|
||||||
|
return pluginDescription.preferencesId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAdvancedPreferencesId() {
|
||||||
|
return pluginDescription.advancedPreferencesId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEnabled(PluginType type) {
|
||||||
|
if (pluginDescription.alwaysEnabled && type == pluginDescription.mainType)
|
||||||
|
return true;
|
||||||
|
if (pluginDescription.mainType == PluginType.CONSTRAINTS && type == PluginType.CONSTRAINTS)
|
||||||
|
return true;
|
||||||
|
if (type == pluginDescription.mainType)
|
||||||
|
return state == State.ENABLED && specialEnableCondition();
|
||||||
|
if (type == PluginType.CONSTRAINTS && pluginDescription.mainType == PluginType.PUMP && isEnabled(PluginType.PUMP))
|
||||||
|
return true;
|
||||||
|
if (type == PluginType.PROFILE && pluginDescription.mainType == PluginType.PUMP)
|
||||||
|
return isProfileInterfaceEnabled;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasFragment() {
|
||||||
|
return pluginDescription.fragmentClass != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* So far plugin can have it's main type + ConstraintInterface + ProfileInterface
|
||||||
|
* ConstraintInterface is enabled if main plugin is enabled
|
||||||
|
* ProfileInterface can be enabled only if main iterface is enable
|
||||||
|
*/
|
||||||
|
|
||||||
|
public void setPluginEnabled(PluginType type, boolean newState) {
|
||||||
|
if (type == pluginDescription.mainType) {
|
||||||
|
if (newState == true) { // enabling plugin
|
||||||
|
if (state != State.ENABLED) {
|
||||||
|
onStateChange(type, state, State.ENABLED);
|
||||||
|
state = State.ENABLED;
|
||||||
|
if (L.isEnabled(L.CORE))
|
||||||
|
log.debug("Starting: " + getName());
|
||||||
|
onStart();
|
||||||
|
}
|
||||||
|
} else { // disabling plugin
|
||||||
|
if (state == State.ENABLED) {
|
||||||
|
onStateChange(type, state, State.DISABLED);
|
||||||
|
state = State.DISABLED;
|
||||||
|
onStop();
|
||||||
|
if (L.isEnabled(L.CORE))
|
||||||
|
log.debug("Stopping: " + getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (type == PluginType.PROFILE) {
|
||||||
|
isProfileInterfaceEnabled = newState;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFragmentVisible(PluginType type, boolean fragmentVisible) {
|
||||||
|
if (type == pluginDescription.mainType) {
|
||||||
|
isFragmentVisible = fragmentVisible && specialEnableCondition();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFragmentVisible() {
|
||||||
|
if (pluginDescription.alwayVisible)
|
||||||
|
return true;
|
||||||
|
if (pluginDescription.neverVisible)
|
||||||
|
return false;
|
||||||
|
return isFragmentVisible;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean showInList(PluginType type) {
|
||||||
|
if (pluginDescription.mainType == type)
|
||||||
|
return pluginDescription.showInList && specialShowInListCondition();
|
||||||
|
|
||||||
|
if (type == PluginType.PROFILE && pluginDescription.mainType == PluginType.PUMP)
|
||||||
|
return isEnabled(PluginType.PUMP);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean specialEnableCondition() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean specialShowInListCondition() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onStart() {
|
||||||
|
if (getType() == PluginType.PUMP) {
|
||||||
|
new Thread(() -> {
|
||||||
|
SystemClock.sleep(3000);
|
||||||
|
CommandQueue commandQueue = ConfigBuilderPlugin.getPlugin().getCommandQueue();
|
||||||
|
if (commandQueue != null)
|
||||||
|
commandQueue.readStatus("Pump driver changed.", null);
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onStop() {
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onStateChange(PluginType type, State oldState, State newState) {
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,90 @@
|
||||||
|
package info.nightscout.androidaps.interfaces;
|
||||||
|
|
||||||
|
public class PluginDescription {
|
||||||
|
PluginType mainType = PluginType.GENERAL;
|
||||||
|
String fragmentClass = null;
|
||||||
|
public boolean alwayVisible = false;
|
||||||
|
public boolean neverVisible = false;
|
||||||
|
public boolean alwaysEnabled = false;
|
||||||
|
boolean showInList = true;
|
||||||
|
int pluginName = -1;
|
||||||
|
int shortName = -1;
|
||||||
|
int description = -1;
|
||||||
|
int preferencesId = -1;
|
||||||
|
int advancedPreferencesId = -1;
|
||||||
|
public boolean enableByDefault = false;
|
||||||
|
public boolean visibleByDefault = false;
|
||||||
|
|
||||||
|
public PluginDescription mainType(PluginType mainType) {
|
||||||
|
this.mainType = mainType;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PluginDescription fragmentClass(String fragmentClass) {
|
||||||
|
this.fragmentClass = fragmentClass;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PluginDescription alwaysEnabled(boolean alwaysEnabled) {
|
||||||
|
this.alwaysEnabled = alwaysEnabled;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PluginDescription alwayVisible(boolean alwayVisible) {
|
||||||
|
this.alwayVisible = alwayVisible;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PluginDescription neverVisible(boolean neverVisible) {
|
||||||
|
this.neverVisible = neverVisible;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PluginDescription showInList(boolean showInList) {
|
||||||
|
this.showInList = showInList;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PluginDescription pluginName(int pluginName) {
|
||||||
|
this.pluginName = pluginName;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PluginDescription shortName(int shortName) {
|
||||||
|
this.shortName = shortName;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PluginDescription preferencesId(int preferencesId) {
|
||||||
|
this.preferencesId = preferencesId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PluginDescription advancedPreferencesId(int advancedPreferencesId) {
|
||||||
|
this.advancedPreferencesId = advancedPreferencesId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PluginDescription enableByDefault(boolean enableByDefault) {
|
||||||
|
this.enableByDefault = enableByDefault;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PluginDescription visibleByDefault(boolean visibleByDefault) {
|
||||||
|
this.visibleByDefault = visibleByDefault;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PluginDescription description(int description) {
|
||||||
|
this.description = description;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFragmentClass() {
|
||||||
|
return fragmentClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PluginType getType() {
|
||||||
|
return mainType;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package info.nightscout.androidaps.interfaces;
|
||||||
|
|
||||||
|
public enum PluginType {
|
||||||
|
GENERAL,
|
||||||
|
TREATMENT,
|
||||||
|
SENSITIVITY,
|
||||||
|
PROFILE,
|
||||||
|
APS,
|
||||||
|
PUMP,
|
||||||
|
CONSTRAINTS,
|
||||||
|
LOOP,
|
||||||
|
BGSOURCE,
|
||||||
|
INSULIN
|
||||||
|
}
|
|
@ -1,40 +1,139 @@
|
||||||
package info.nightscout.androidaps.interfaces;
|
package info.nightscout.androidaps.interfaces;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.plugins.PumpCommon.defs.PumpCapability;
|
||||||
|
import info.nightscout.androidaps.plugins.PumpCommon.defs.PumpTempBasalType;
|
||||||
|
import info.nightscout.androidaps.plugins.PumpCommon.defs.PumpType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by mike on 08.12.2016.
|
* Created by mike on 08.12.2016.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class PumpDescription {
|
public class PumpDescription {
|
||||||
|
public PumpType pumpType = PumpType.GenericAAPS;
|
||||||
|
|
||||||
|
public PumpDescription () {
|
||||||
|
resetSettings();
|
||||||
|
}
|
||||||
|
|
||||||
public static final int NONE = 0;
|
public static final int NONE = 0;
|
||||||
public static final int PERCENT = 0x01;
|
public static final int PERCENT = 0x01;
|
||||||
public static final int ABSOLUTE = 0x02;
|
public static final int ABSOLUTE = 0x02;
|
||||||
|
|
||||||
public boolean isBolusCapable = true;
|
public boolean isBolusCapable;
|
||||||
public double bolusStep = 0.1d;
|
public double bolusStep;
|
||||||
|
|
||||||
public boolean isExtendedBolusCapable = true;
|
public boolean isExtendedBolusCapable;
|
||||||
public double extendedBolusStep = 0.1d;
|
public double extendedBolusStep;
|
||||||
public double extendedBolusDurationStep = 30;
|
public double extendedBolusDurationStep;
|
||||||
public double extendedBolusMaxDuration = 12 * 60;
|
public double extendedBolusMaxDuration;
|
||||||
|
|
||||||
public boolean isTempBasalCapable = true;
|
public boolean isTempBasalCapable;
|
||||||
public int tempBasalStyle = PERCENT;
|
public int tempBasalStyle;
|
||||||
|
|
||||||
public int maxTempPercent = 200;
|
public int maxTempPercent;
|
||||||
public int tempPercentStep = 10;
|
public int tempPercentStep;
|
||||||
|
|
||||||
public double maxTempAbsolute = 10;
|
public double maxTempAbsolute;
|
||||||
public double tempAbsoluteStep = 0.05d;
|
public double tempAbsoluteStep;
|
||||||
|
|
||||||
public int tempDurationStep = 60;
|
public int tempDurationStep;
|
||||||
public int tempMaxDuration = 12 * 60;
|
public boolean tempDurationStep15mAllowed;
|
||||||
|
public boolean tempDurationStep30mAllowed;
|
||||||
|
public int tempMaxDuration;
|
||||||
|
|
||||||
|
public boolean isSetBasalProfileCapable;
|
||||||
|
public double basalStep;
|
||||||
|
public double basalMinimumRate;
|
||||||
|
public double basalMaximumRate;
|
||||||
|
|
||||||
|
public boolean isRefillingCapable;
|
||||||
|
|
||||||
|
public boolean storesCarbInfo;
|
||||||
|
|
||||||
|
public boolean is30minBasalRatesCapable;
|
||||||
|
|
||||||
|
public boolean supportsTDDs;
|
||||||
|
public boolean needsManualTDDLoad;
|
||||||
|
|
||||||
|
|
||||||
public boolean isSetBasalProfileCapable = true;
|
public void resetSettings() {
|
||||||
public double basalStep = 0.01d;
|
isBolusCapable = true;
|
||||||
public double basalMinimumRate = 0.04d;
|
bolusStep = 0.1d;
|
||||||
|
|
||||||
public boolean isRefillingCapable = false;
|
isExtendedBolusCapable = true;
|
||||||
|
extendedBolusStep = 0.1d;
|
||||||
|
extendedBolusDurationStep = 30;
|
||||||
|
extendedBolusMaxDuration = 12 * 60;
|
||||||
|
|
||||||
|
isTempBasalCapable = true;
|
||||||
|
tempBasalStyle = PERCENT;
|
||||||
|
maxTempPercent = 200;
|
||||||
|
tempPercentStep = 10;
|
||||||
|
maxTempAbsolute = 10;
|
||||||
|
tempAbsoluteStep = 0.05d;
|
||||||
|
tempDurationStep = 60;
|
||||||
|
tempMaxDuration = 12 * 60;
|
||||||
|
tempDurationStep15mAllowed = false;
|
||||||
|
tempDurationStep30mAllowed = false;
|
||||||
|
|
||||||
|
isSetBasalProfileCapable = true;
|
||||||
|
basalStep = 0.01d;
|
||||||
|
basalMinimumRate = 0.04d;
|
||||||
|
basalMaximumRate = 25d;
|
||||||
|
is30minBasalRatesCapable = false;
|
||||||
|
|
||||||
|
isRefillingCapable = false;
|
||||||
|
storesCarbInfo = true;
|
||||||
|
|
||||||
|
supportsTDDs = false;
|
||||||
|
needsManualTDDLoad = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPumpDescription(PumpType pumpType) {
|
||||||
|
resetSettings();
|
||||||
|
this.pumpType = pumpType;
|
||||||
|
|
||||||
|
PumpCapability pumpCapability = pumpType.getPumpCapability();
|
||||||
|
|
||||||
|
isBolusCapable = pumpCapability.hasCapability(PumpCapability.Bolus);
|
||||||
|
bolusStep = pumpType.getBolusSize();
|
||||||
|
|
||||||
|
isExtendedBolusCapable = pumpCapability.hasCapability(PumpCapability.ExtendedBolus);
|
||||||
|
extendedBolusStep = pumpType.getExtendedBolusSettings().getStep();
|
||||||
|
extendedBolusDurationStep = pumpType.getExtendedBolusSettings().getDurationStep();
|
||||||
|
extendedBolusMaxDuration = pumpType.getExtendedBolusSettings().getMaxDuration();
|
||||||
|
|
||||||
|
isTempBasalCapable = pumpCapability.hasCapability(PumpCapability.TempBasal);
|
||||||
|
|
||||||
|
if (pumpType.getPumpTempBasalType() == PumpTempBasalType.Percent) {
|
||||||
|
tempBasalStyle = PERCENT;
|
||||||
|
maxTempPercent = pumpType.getTbrSettings().getMaxDose().intValue();
|
||||||
|
tempPercentStep = (int) pumpType.getTbrSettings().getStep();
|
||||||
|
} else {
|
||||||
|
tempBasalStyle = ABSOLUTE;
|
||||||
|
maxTempAbsolute = pumpType.getTbrSettings().getMaxDose();
|
||||||
|
tempAbsoluteStep = pumpType.getTbrSettings().getStep();
|
||||||
|
}
|
||||||
|
|
||||||
|
tempDurationStep = pumpType.getTbrSettings().getDurationStep();
|
||||||
|
tempMaxDuration = pumpType.getTbrSettings().getMaxDuration();
|
||||||
|
|
||||||
|
tempDurationStep15mAllowed = pumpType.getSpecialBasalDurations()
|
||||||
|
.hasCapability(PumpCapability.BasalRate_Duration15minAllowed);
|
||||||
|
tempDurationStep30mAllowed = pumpType.getSpecialBasalDurations()
|
||||||
|
.hasCapability(PumpCapability.BasalRate_Duration30minAllowed);
|
||||||
|
|
||||||
|
isSetBasalProfileCapable = pumpCapability.hasCapability(PumpCapability.BasalProfileSet);
|
||||||
|
basalStep = pumpType.getBaseBasalStep();
|
||||||
|
basalMinimumRate = pumpType.getBaseBasalMinValue();
|
||||||
|
|
||||||
|
isRefillingCapable = pumpCapability.hasCapability(PumpCapability.Refill);
|
||||||
|
storesCarbInfo = pumpCapability.hasCapability(PumpCapability.StoreCarbInfo);
|
||||||
|
|
||||||
|
supportsTDDs = pumpCapability.hasCapability(PumpCapability.TDD);
|
||||||
|
needsManualTDDLoad = pumpCapability.hasCapability(PumpCapability.ManualTDDLoad);
|
||||||
|
|
||||||
|
is30minBasalRatesCapable = pumpCapability.hasCapability(PumpCapability.BasalRate30min);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean storesCarbInfo = true;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,22 +2,22 @@ package info.nightscout.androidaps.interfaces;
|
||||||
|
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.data.DetailedBolusInfo;
|
import info.nightscout.androidaps.data.DetailedBolusInfo;
|
||||||
import info.nightscout.androidaps.data.PumpEnactResult;
|
|
||||||
import info.nightscout.androidaps.data.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
|
import info.nightscout.androidaps.data.PumpEnactResult;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by mike on 04.06.2016.
|
* Created by mike on 04.06.2016.
|
||||||
*/
|
*/
|
||||||
public interface PumpInterface {
|
public interface PumpInterface {
|
||||||
|
|
||||||
boolean isInitialized();
|
boolean isInitialized(); // true if pump status has been read and is ready to accept commands
|
||||||
boolean isSuspended();
|
boolean isSuspended(); // true if suspended (not delivering insulin)
|
||||||
boolean isBusy();
|
boolean isBusy(); // if true pump is not ready to accept commands right now
|
||||||
boolean isConnected();
|
boolean isConnected(); // true if BT connection is established
|
||||||
boolean isConnecting();
|
boolean isConnecting(); // true if BT connection is in progress
|
||||||
|
boolean isHandshakeInProgress(); // true if BT is connected but initial handshake is still in progress
|
||||||
|
void finishHandshaking(); // set initial handshake completed
|
||||||
|
|
||||||
void connect(String reason);
|
void connect(String reason);
|
||||||
void disconnect(String reason);
|
void disconnect(String reason);
|
||||||
|
@ -29,14 +29,14 @@ public interface PumpInterface {
|
||||||
PumpEnactResult setNewBasalProfile(Profile profile);
|
PumpEnactResult setNewBasalProfile(Profile profile);
|
||||||
boolean isThisProfileSet(Profile profile);
|
boolean isThisProfileSet(Profile profile);
|
||||||
|
|
||||||
Date lastDataTime();
|
long lastDataTime();
|
||||||
|
|
||||||
double getBaseBasalRate(); // base basal rate, not temp basal
|
double getBaseBasalRate(); // base basal rate, not temp basal
|
||||||
|
|
||||||
PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo);
|
PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo);
|
||||||
void stopBolusDelivering();
|
void stopBolusDelivering();
|
||||||
PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, boolean enforceNew);
|
PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, Profile profile, boolean enforceNew);
|
||||||
PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes, boolean enforceNew);
|
PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes, Profile profile, boolean enforceNew);
|
||||||
PumpEnactResult setExtendedBolus(Double insulin, Integer durationInMinutes);
|
PumpEnactResult setExtendedBolus(Double insulin, Integer durationInMinutes);
|
||||||
//some pumps might set a very short temp close to 100% as cancelling a temp can be noisy
|
//some pumps might set a very short temp close to 100% as cancelling a temp can be noisy
|
||||||
//when the cancel request is requested by the user (forced), the pump should always do a real cancel
|
//when the cancel request is requested by the user (forced), the pump should always do a real cancel
|
||||||
|
@ -44,7 +44,7 @@ public interface PumpInterface {
|
||||||
PumpEnactResult cancelExtendedBolus();
|
PumpEnactResult cancelExtendedBolus();
|
||||||
|
|
||||||
// Status to be passed to NS
|
// Status to be passed to NS
|
||||||
JSONObject getJSONStatus();
|
JSONObject getJSONStatus(Profile profile, String profileName);
|
||||||
String deviceID();
|
String deviceID();
|
||||||
|
|
||||||
// Pump capabilities
|
// Pump capabilities
|
||||||
|
@ -54,4 +54,7 @@ public interface PumpInterface {
|
||||||
String shortStatus(boolean veryShort);
|
String shortStatus(boolean veryShort);
|
||||||
|
|
||||||
boolean isFakingTempsByExtendedBoluses();
|
boolean isFakingTempsByExtendedBoluses();
|
||||||
|
|
||||||
|
PumpEnactResult loadTDDs();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,17 @@
|
||||||
package info.nightscout.androidaps.interfaces;
|
package info.nightscout.androidaps.interfaces;
|
||||||
|
|
||||||
import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensResult;
|
import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensResult;
|
||||||
|
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by mike on 24.06.2017.
|
* Created by mike on 24.06.2017.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public interface SensitivityInterface {
|
public interface SensitivityInterface {
|
||||||
AutosensResult detectSensitivity(long fromTime, long toTime);
|
|
||||||
|
double MIN_HOURS = 1;
|
||||||
|
double MIN_HOURS_FULL_AUTOSENS = 4;
|
||||||
|
|
||||||
|
AutosensResult detectSensitivity(IobCobCalculatorPlugin plugin, long fromTime, long toTime);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,11 +5,12 @@ 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.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;
|
||||||
import info.nightscout.androidaps.db.TempTarget;
|
import info.nightscout.androidaps.db.TempTarget;
|
||||||
import info.nightscout.androidaps.db.TemporaryBasal;
|
import info.nightscout.androidaps.db.TemporaryBasal;
|
||||||
import info.nightscout.androidaps.db.Treatment;
|
import info.nightscout.androidaps.plugins.Treatments.Treatment;
|
||||||
import info.nightscout.androidaps.data.Intervals;
|
import info.nightscout.androidaps.data.Intervals;
|
||||||
import info.nightscout.androidaps.data.ProfileIntervals;
|
import info.nightscout.androidaps.data.ProfileIntervals;
|
||||||
|
|
||||||
|
@ -24,12 +25,13 @@ public interface TreatmentsInterface {
|
||||||
IobTotal getLastCalculationTreatments();
|
IobTotal getLastCalculationTreatments();
|
||||||
IobTotal getCalculationToTimeTreatments(long time);
|
IobTotal getCalculationToTimeTreatments(long time);
|
||||||
IobTotal getLastCalculationTempBasals();
|
IobTotal getLastCalculationTempBasals();
|
||||||
IobTotal getCalculationToTimeTempBasals(long time);
|
IobTotal getCalculationToTimeTempBasals(long time, Profile profile);
|
||||||
|
|
||||||
MealData getMealData();
|
MealData getMealData();
|
||||||
|
|
||||||
List<Treatment> getTreatmentsFromHistory();
|
List<Treatment> getTreatmentsFromHistory();
|
||||||
List<Treatment> getTreatments5MinBackFromHistory(long time);
|
List<Treatment> getTreatments5MinBackFromHistory(long time);
|
||||||
|
long getLastBolusTime();
|
||||||
|
|
||||||
// real basals (not faked by extended bolus)
|
// real basals (not faked by extended bolus)
|
||||||
boolean isInHistoryRealTempBasalInProgress();
|
boolean isInHistoryRealTempBasalInProgress();
|
||||||
|
@ -40,8 +42,6 @@ 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);
|
||||||
double getTempBasalAbsoluteRateHistory();
|
|
||||||
double getTempBasalRemainingMinutesFromHistory();
|
|
||||||
Intervals<TemporaryBasal> getTemporaryBasalsFromHistory();
|
Intervals<TemporaryBasal> getTemporaryBasalsFromHistory();
|
||||||
|
|
||||||
boolean isInHistoryExtendedBoluslInProgress();
|
boolean isInHistoryExtendedBoluslInProgress();
|
||||||
|
@ -50,11 +50,12 @@ public interface TreatmentsInterface {
|
||||||
|
|
||||||
boolean addToHistoryExtendedBolus(ExtendedBolus extendedBolus);
|
boolean addToHistoryExtendedBolus(ExtendedBolus extendedBolus);
|
||||||
|
|
||||||
boolean addToHistoryTreatment(DetailedBolusInfo detailedBolusInfo);
|
boolean addToHistoryTreatment(DetailedBolusInfo detailedBolusInfo, boolean allowUpdate);
|
||||||
|
|
||||||
TempTarget getTempTargetFromHistory();
|
TempTarget getTempTargetFromHistory();
|
||||||
TempTarget getTempTargetFromHistory(long time);
|
TempTarget getTempTargetFromHistory(long time);
|
||||||
Intervals<TempTarget> getTempTargetsFromHistory();
|
Intervals<TempTarget> getTempTargetsFromHistory();
|
||||||
|
void addToHistoryTempTarget(TempTarget tempTarget);
|
||||||
|
|
||||||
ProfileSwitch getProfileSwitchFromHistory(long time);
|
ProfileSwitch getProfileSwitchFromHistory(long time);
|
||||||
ProfileIntervals<ProfileSwitch> getProfileSwitchesFromHistory();
|
ProfileIntervals<ProfileSwitch> getProfileSwitchesFromHistory();
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package info.nightscout.utils;
|
package info.nightscout.androidaps.logging;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
123
app/src/main/java/info/nightscout/androidaps/logging/L.java
Normal file
123
app/src/main/java/info/nightscout/androidaps/logging/L.java
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
package info.nightscout.androidaps.logging;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import info.nightscout.utils.SP;
|
||||||
|
|
||||||
|
public class L {
|
||||||
|
|
||||||
|
public static class LogElement {
|
||||||
|
public String name;
|
||||||
|
boolean defaultValue;
|
||||||
|
public boolean enabled;
|
||||||
|
boolean requiresRestart = false;
|
||||||
|
|
||||||
|
LogElement(String name, boolean defaultValue) {
|
||||||
|
this.name = name;
|
||||||
|
this.defaultValue = defaultValue;
|
||||||
|
enabled = SP.getBoolean(getSPName(), defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
LogElement(String name, boolean defaultValue, boolean requiresRestart) {
|
||||||
|
this.name = name;
|
||||||
|
this.defaultValue = defaultValue;
|
||||||
|
this.requiresRestart = requiresRestart;
|
||||||
|
enabled = SP.getBoolean(getSPName(), defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
LogElement(boolean defaultValue) {
|
||||||
|
this.name = "NONEXISTING";
|
||||||
|
this.defaultValue = defaultValue;
|
||||||
|
enabled = defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getSPName() {
|
||||||
|
return "log_" + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnabled(boolean enabled) {
|
||||||
|
this.enabled = enabled;
|
||||||
|
SP.putBoolean(getSPName(), enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
void resetToDefault() {
|
||||||
|
setEnabled(defaultValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<LogElement> logElements;
|
||||||
|
|
||||||
|
static {
|
||||||
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static LogElement findByName(String name) {
|
||||||
|
for (LogElement element : logElements) {
|
||||||
|
if (element.name.equals(name))
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
return new LogElement(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isEnabled(String name) {
|
||||||
|
return findByName(name).enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<LogElement> getLogElements() {
|
||||||
|
return logElements;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void resetToDefaults() {
|
||||||
|
for (LogElement element : logElements) {
|
||||||
|
element.resetToDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static final String CORE = "CORE";
|
||||||
|
public static final String AUTOSENS = "AUTOSENS";
|
||||||
|
public static final String EVENTS = "EVENTS";
|
||||||
|
public static final String BGSOURCE = "BGSOURCE";
|
||||||
|
public static final String OVERVIEW = "OVERVIEW";
|
||||||
|
public static final String NOTIFICATION = "NOTIFICATION";
|
||||||
|
public static final String DATASERVICE = "DATASERVICE";
|
||||||
|
public static final String DATABASE = "DATABASE";
|
||||||
|
public static final String DATAFOOD = "DATAFOOD";
|
||||||
|
public static final String DATATREATMENTS = "DATATREATMENTS";
|
||||||
|
public static final String NSCLIENT = "NSCLIENT";
|
||||||
|
public static final String CONSTRAINTS = "CONSTRAINTS";
|
||||||
|
public static final String PUMP = "PUMP";
|
||||||
|
public static final String PUMPQUEUE = "PUMPQUEUE";
|
||||||
|
public static final String PUMPCOMM = "PUMPCOMM";
|
||||||
|
public static final String PUMPBTCOMM = "PUMPBTCOMM";
|
||||||
|
public static final String APS = "APS";
|
||||||
|
public static final String PROFILE = "PROFILE";
|
||||||
|
public static final String CONFIGBUILDER = "CONFIGBUILDER";
|
||||||
|
public static final String UI = "UI";
|
||||||
|
|
||||||
|
private static void initialize() {
|
||||||
|
logElements = new ArrayList<>();
|
||||||
|
logElements.add(new LogElement(APS, true));
|
||||||
|
logElements.add(new LogElement(AUTOSENS, false));
|
||||||
|
logElements.add(new LogElement(BGSOURCE, true));
|
||||||
|
logElements.add(new LogElement(CONFIGBUILDER, false));
|
||||||
|
logElements.add(new LogElement(CONSTRAINTS, true));
|
||||||
|
logElements.add(new LogElement(CORE, true));
|
||||||
|
logElements.add(new LogElement(DATABASE, true));
|
||||||
|
logElements.add(new LogElement(DATAFOOD, false));
|
||||||
|
logElements.add(new LogElement(DATASERVICE, true));
|
||||||
|
logElements.add(new LogElement(DATATREATMENTS, true));
|
||||||
|
logElements.add(new LogElement(EVENTS, false, true));
|
||||||
|
logElements.add(new LogElement(NOTIFICATION, true));
|
||||||
|
logElements.add(new LogElement(NSCLIENT, true));
|
||||||
|
logElements.add(new LogElement(OVERVIEW, true));
|
||||||
|
logElements.add(new LogElement(PROFILE, true));
|
||||||
|
logElements.add(new LogElement(PUMP, true));
|
||||||
|
logElements.add(new LogElement(PUMPBTCOMM, false));
|
||||||
|
logElements.add(new LogElement(PUMPCOMM, true));
|
||||||
|
logElements.add(new LogElement(PUMPQUEUE, true));
|
||||||
|
logElements.add(new LogElement(UI, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2,6 +2,7 @@ package info.nightscout.androidaps.plugins.Actions;
|
||||||
|
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.support.v4.app.FragmentManager;
|
import android.support.v4.app.FragmentManager;
|
||||||
|
@ -9,14 +10,14 @@ import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import com.crashlytics.android.Crashlytics;
|
|
||||||
import com.crashlytics.android.answers.Answers;
|
|
||||||
import com.crashlytics.android.answers.CustomEvent;
|
import com.crashlytics.android.answers.CustomEvent;
|
||||||
import com.squareup.otto.Subscribe;
|
import com.squareup.otto.Subscribe;
|
||||||
|
|
||||||
import info.nightscout.androidaps.Config;
|
import info.nightscout.androidaps.Config;
|
||||||
|
import info.nightscout.androidaps.activities.HistoryBrowseActivity;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
|
import info.nightscout.androidaps.activities.TDDStatsActivity;
|
||||||
import info.nightscout.androidaps.db.ExtendedBolus;
|
import info.nightscout.androidaps.db.ExtendedBolus;
|
||||||
import info.nightscout.androidaps.db.TemporaryBasal;
|
import info.nightscout.androidaps.db.TemporaryBasal;
|
||||||
import info.nightscout.androidaps.events.EventExtendedBolusChange;
|
import info.nightscout.androidaps.events.EventExtendedBolusChange;
|
||||||
|
@ -32,6 +33,9 @@ import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialo
|
||||||
import info.nightscout.androidaps.plugins.Careportal.OptionsToShow;
|
import info.nightscout.androidaps.plugins.Careportal.OptionsToShow;
|
||||||
import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
|
import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
|
||||||
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.Treatments.TreatmentsPlugin;
|
||||||
|
import info.nightscout.utils.FabricPrivacy;
|
||||||
import info.nightscout.utils.SingleClickButton;
|
import info.nightscout.utils.SingleClickButton;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -52,6 +56,8 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL
|
||||||
SingleClickButton tempBasal;
|
SingleClickButton tempBasal;
|
||||||
SingleClickButton tempBasalCancel;
|
SingleClickButton tempBasalCancel;
|
||||||
SingleClickButton fill;
|
SingleClickButton fill;
|
||||||
|
SingleClickButton tddStats;
|
||||||
|
SingleClickButton history;
|
||||||
|
|
||||||
public ActionsFragment() {
|
public ActionsFragment() {
|
||||||
super();
|
super();
|
||||||
|
@ -71,6 +77,8 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL
|
||||||
tempBasal = (SingleClickButton) view.findViewById(R.id.actions_settempbasal);
|
tempBasal = (SingleClickButton) view.findViewById(R.id.actions_settempbasal);
|
||||||
tempBasalCancel = (SingleClickButton) view.findViewById(R.id.actions_canceltempbasal);
|
tempBasalCancel = (SingleClickButton) view.findViewById(R.id.actions_canceltempbasal);
|
||||||
fill = (SingleClickButton) view.findViewById(R.id.actions_fill);
|
fill = (SingleClickButton) view.findViewById(R.id.actions_fill);
|
||||||
|
tddStats = view.findViewById(R.id.actions_tddstats);
|
||||||
|
history = view.findViewById(R.id.actions_historybrowser);
|
||||||
|
|
||||||
profileSwitch.setOnClickListener(this);
|
profileSwitch.setOnClickListener(this);
|
||||||
tempTarget.setOnClickListener(this);
|
tempTarget.setOnClickListener(this);
|
||||||
|
@ -79,11 +87,13 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL
|
||||||
tempBasal.setOnClickListener(this);
|
tempBasal.setOnClickListener(this);
|
||||||
tempBasalCancel.setOnClickListener(this);
|
tempBasalCancel.setOnClickListener(this);
|
||||||
fill.setOnClickListener(this);
|
fill.setOnClickListener(this);
|
||||||
|
history.setOnClickListener(this);
|
||||||
|
tddStats.setOnClickListener(this);
|
||||||
|
|
||||||
updateGUI();
|
updateGUI();
|
||||||
return view;
|
return view;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Crashlytics.logException(e);
|
FabricPrivacy.logException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -116,9 +126,14 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL
|
||||||
activity.runOnUiThread(new Runnable() {
|
activity.runOnUiThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (MainApp.getConfigBuilder().getActiveProfileInterface().getProfile() == null) {
|
if (ConfigBuilderPlugin.getPlugin().getActiveProfileInterface() != null && ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getProfile() != null) {
|
||||||
tempTarget.setVisibility(View.GONE);
|
profileSwitch.setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
profileSwitch.setVisibility(View.GONE);
|
profileSwitch.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ProfileFunctions.getInstance().getProfile() == null) {
|
||||||
|
tempTarget.setVisibility(View.GONE);
|
||||||
extendedBolus.setVisibility(View.GONE);
|
extendedBolus.setVisibility(View.GONE);
|
||||||
extendedBolusCancel.setVisibility(View.GONE);
|
extendedBolusCancel.setVisibility(View.GONE);
|
||||||
tempBasal.setVisibility(View.GONE);
|
tempBasal.setVisibility(View.GONE);
|
||||||
|
@ -126,22 +141,25 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL
|
||||||
fill.setVisibility(View.GONE);
|
fill.setVisibility(View.GONE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
|
|
||||||
if (!pump.getPumpDescription().isSetBasalProfileCapable || !pump.isInitialized() || pump.isSuspended())
|
final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
|
||||||
|
final boolean basalprofileEnabled = MainApp.isEngineeringModeOrRelease()
|
||||||
|
&& pump.getPumpDescription().isSetBasalProfileCapable;
|
||||||
|
|
||||||
|
if (!basalprofileEnabled || !pump.isInitialized() || pump.isSuspended())
|
||||||
profileSwitch.setVisibility(View.GONE);
|
profileSwitch.setVisibility(View.GONE);
|
||||||
else
|
else
|
||||||
profileSwitch.setVisibility(View.VISIBLE);
|
profileSwitch.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
|
|
||||||
if (!pump.getPumpDescription().isExtendedBolusCapable || !pump.isInitialized() || pump.isSuspended() || pump.isFakingTempsByExtendedBoluses()) {
|
if (!pump.getPumpDescription().isExtendedBolusCapable || !pump.isInitialized() || pump.isSuspended() || pump.isFakingTempsByExtendedBoluses()) {
|
||||||
extendedBolus.setVisibility(View.GONE);
|
extendedBolus.setVisibility(View.GONE);
|
||||||
extendedBolusCancel.setVisibility(View.GONE);
|
extendedBolusCancel.setVisibility(View.GONE);
|
||||||
} else {
|
} else {
|
||||||
if (MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) {
|
ExtendedBolus activeExtendedBolus = TreatmentsPlugin.getPlugin().getExtendedBolusFromHistory(System.currentTimeMillis());
|
||||||
|
if (activeExtendedBolus != null) {
|
||||||
extendedBolus.setVisibility(View.GONE);
|
extendedBolus.setVisibility(View.GONE);
|
||||||
extendedBolusCancel.setVisibility(View.VISIBLE);
|
extendedBolusCancel.setVisibility(View.VISIBLE);
|
||||||
ExtendedBolus running = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis());
|
extendedBolusCancel.setText(MainApp.gs(R.string.cancel) + " " + activeExtendedBolus.toString());
|
||||||
extendedBolusCancel.setText(MainApp.instance().getString(R.string.cancel) + " " + running.toString());
|
|
||||||
} else {
|
} else {
|
||||||
extendedBolus.setVisibility(View.VISIBLE);
|
extendedBolus.setVisibility(View.VISIBLE);
|
||||||
extendedBolusCancel.setVisibility(View.GONE);
|
extendedBolusCancel.setVisibility(View.GONE);
|
||||||
|
@ -153,11 +171,11 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL
|
||||||
tempBasal.setVisibility(View.GONE);
|
tempBasal.setVisibility(View.GONE);
|
||||||
tempBasalCancel.setVisibility(View.GONE);
|
tempBasalCancel.setVisibility(View.GONE);
|
||||||
} else {
|
} else {
|
||||||
if (MainApp.getConfigBuilder().isTempBasalInProgress()) {
|
final TemporaryBasal activeTemp = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(System.currentTimeMillis());
|
||||||
|
if (activeTemp != null) {
|
||||||
tempBasal.setVisibility(View.GONE);
|
tempBasal.setVisibility(View.GONE);
|
||||||
tempBasalCancel.setVisibility(View.VISIBLE);
|
tempBasalCancel.setVisibility(View.VISIBLE);
|
||||||
final TemporaryBasal activeTemp = MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis());
|
tempBasalCancel.setText(MainApp.gs(R.string.cancel) + " " + activeTemp.toStringShort());
|
||||||
tempBasalCancel.setText(MainApp.instance().getString(R.string.cancel) + " " + activeTemp.toStringShort());
|
|
||||||
} else {
|
} else {
|
||||||
tempBasal.setVisibility(View.VISIBLE);
|
tempBasal.setVisibility(View.VISIBLE);
|
||||||
tempBasalCancel.setVisibility(View.GONE);
|
tempBasalCancel.setVisibility(View.GONE);
|
||||||
|
@ -173,6 +191,9 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL
|
||||||
tempTarget.setVisibility(View.GONE);
|
tempTarget.setVisibility(View.GONE);
|
||||||
else
|
else
|
||||||
tempTarget.setVisibility(View.VISIBLE);
|
tempTarget.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
|
if (!ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().supportsTDDs) tddStats.setVisibility(View.GONE);
|
||||||
|
else tddStats.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -201,15 +222,15 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL
|
||||||
newExtendedDialog.show(manager, "NewExtendedDialog");
|
newExtendedDialog.show(manager, "NewExtendedDialog");
|
||||||
break;
|
break;
|
||||||
case R.id.actions_extendedbolus_cancel:
|
case R.id.actions_extendedbolus_cancel:
|
||||||
if (MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) {
|
if (TreatmentsPlugin.getPlugin().isInHistoryExtendedBoluslInProgress()) {
|
||||||
ConfigBuilderPlugin.getCommandQueue().cancelExtended(null);
|
ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelExtended(null);
|
||||||
Answers.getInstance().logCustom(new CustomEvent("CancelExtended"));
|
FabricPrivacy.getInstance().logCustom(new CustomEvent("CancelExtended"));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case R.id.actions_canceltempbasal:
|
case R.id.actions_canceltempbasal:
|
||||||
if (MainApp.getConfigBuilder().isTempBasalInProgress()) {
|
if (TreatmentsPlugin.getPlugin().isTempBasalInProgress()) {
|
||||||
ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, null);
|
ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(true, null);
|
||||||
Answers.getInstance().logCustom(new CustomEvent("CancelTemp"));
|
FabricPrivacy.getInstance().logCustom(new CustomEvent("CancelTemp"));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case R.id.actions_settempbasal:
|
case R.id.actions_settempbasal:
|
||||||
|
@ -220,6 +241,12 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL
|
||||||
FillDialog fillDialog = new FillDialog();
|
FillDialog fillDialog = new FillDialog();
|
||||||
fillDialog.show(manager, "FillDialog");
|
fillDialog.show(manager, "FillDialog");
|
||||||
break;
|
break;
|
||||||
|
case R.id.actions_historybrowser:
|
||||||
|
startActivity(new Intent(getContext(), HistoryBrowseActivity.class));
|
||||||
|
break;
|
||||||
|
case R.id.actions_tddstats:
|
||||||
|
startActivity(new Intent(getContext(), TDDStatsActivity.class));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,82 +1,23 @@
|
||||||
package info.nightscout.androidaps.plugins.Actions;
|
package info.nightscout.androidaps.plugins.Actions;
|
||||||
|
|
||||||
import info.nightscout.androidaps.MainApp;
|
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||||
|
import info.nightscout.androidaps.interfaces.PluginDescription;
|
||||||
|
import info.nightscout.androidaps.interfaces.PluginType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by mike on 05.11.2016.
|
* Created by mike on 05.11.2016.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class ActionsPlugin implements PluginBase {
|
public class ActionsPlugin extends PluginBase {
|
||||||
|
|
||||||
private boolean fragmentEnabled = true;
|
public ActionsPlugin() {
|
||||||
private boolean fragmentVisible = true;
|
super(new PluginDescription()
|
||||||
|
.mainType(PluginType.GENERAL)
|
||||||
@Override
|
.fragmentClass(ActionsFragment.class.getName())
|
||||||
public int getType() {
|
.pluginName(R.string.actions)
|
||||||
return PluginBase.GENERAL;
|
.shortName(R.string.actions_shortname)
|
||||||
|
.description(R.string.description_actions)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getFragmentClass() {
|
|
||||||
return ActionsFragment.class.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return MainApp.sResources.getString(R.string.actions);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getNameShort() {
|
|
||||||
String name = MainApp.sResources.getString(R.string.actions_shortname);
|
|
||||||
if (!name.trim().isEmpty()){
|
|
||||||
//only if translation exists
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
// use long name as fallback
|
|
||||||
return getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled(int type) {
|
|
||||||
return type == GENERAL && fragmentEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isVisibleInTabs(int type) {
|
|
||||||
return type == GENERAL && fragmentVisible;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canBeHidden(int type) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasFragment() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean showInList(int type) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setFragmentEnabled(int type, boolean fragmentEnabled) {
|
|
||||||
if (type == GENERAL) this.fragmentEnabled = fragmentEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setFragmentVisible(int type, boolean fragmentVisible) {
|
|
||||||
if (type == GENERAL) this.fragmentVisible = fragmentVisible;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getPreferencesId() {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
package info.nightscout.androidaps.plugins.Actions.dialogs;
|
package info.nightscout.androidaps.plugins.Actions.dialogs;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
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 android.support.v4.app.DialogFragment;
|
||||||
import android.support.v7.app.AlertDialog;
|
import android.support.v7.app.AlertDialog;
|
||||||
|
import android.text.Editable;
|
||||||
|
import android.text.Html;
|
||||||
|
import android.text.TextWatcher;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
import android.view.View.OnClickListener;
|
||||||
|
@ -13,169 +15,239 @@ import android.view.ViewGroup;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
|
import android.widget.CheckBox;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
|
||||||
import com.crashlytics.android.answers.Answers;
|
|
||||||
import com.crashlytics.android.answers.CustomEvent;
|
import com.crashlytics.android.answers.CustomEvent;
|
||||||
|
import com.google.common.base.Joiner;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.text.DecimalFormat;
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import info.nightscout.androidaps.Constants;
|
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.data.DetailedBolusInfo;
|
import info.nightscout.androidaps.data.DetailedBolusInfo;
|
||||||
|
import info.nightscout.androidaps.db.CareportalEvent;
|
||||||
import info.nightscout.androidaps.db.Source;
|
import info.nightscout.androidaps.db.Source;
|
||||||
|
import info.nightscout.androidaps.interfaces.Constraint;
|
||||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity;
|
import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity;
|
||||||
import info.nightscout.androidaps.queue.Callback;
|
import info.nightscout.androidaps.queue.Callback;
|
||||||
import info.nightscout.utils.DecimalFormatter;
|
import info.nightscout.utils.DecimalFormatter;
|
||||||
|
import info.nightscout.utils.FabricPrivacy;
|
||||||
|
import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload;
|
||||||
import info.nightscout.utils.NumberPicker;
|
import info.nightscout.utils.NumberPicker;
|
||||||
import info.nightscout.utils.SP;
|
import info.nightscout.utils.SP;
|
||||||
import info.nightscout.utils.SafeParse;
|
import info.nightscout.utils.SafeParse;
|
||||||
|
import info.nightscout.utils.ToastUtils;
|
||||||
|
|
||||||
|
import static info.nightscout.utils.DateUtil.now;
|
||||||
|
|
||||||
public class FillDialog extends DialogFragment implements OnClickListener {
|
public class FillDialog extends DialogFragment implements OnClickListener {
|
||||||
private static Logger log = LoggerFactory.getLogger(FillDialog.class);
|
private static Logger log = LoggerFactory.getLogger(FillDialog.class);
|
||||||
|
|
||||||
Button deliverButton;
|
private CheckBox pumpSiteChangeCheckbox;
|
||||||
|
private CheckBox insulinCartridgeChangeCheckbox;
|
||||||
|
|
||||||
|
private NumberPicker editInsulin;
|
||||||
|
|
||||||
double amount1 = 0d;
|
double amount1 = 0d;
|
||||||
double amount2 = 0d;
|
double amount2 = 0d;
|
||||||
double amount3 = 0d;
|
double amount3 = 0d;
|
||||||
|
|
||||||
NumberPicker editInsulin;
|
private EditText notesEdit;
|
||||||
|
|
||||||
public FillDialog() {
|
//one shot guards
|
||||||
|
private boolean accepted;
|
||||||
|
private boolean okClicked;
|
||||||
|
|
||||||
|
final private TextWatcher textWatcher = new TextWatcher() {
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable s) {
|
||||||
|
validateInputs();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private void validateInputs() {
|
||||||
|
int time = editInsulin.getValue().intValue();
|
||||||
|
if (Math.abs(time) > 12 * 60) {
|
||||||
|
editInsulin.setValue(0d);
|
||||||
|
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.constraintapllied));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
View view = inflater.inflate(R.layout.actions_fill_dialog, null, false);
|
View view = inflater.inflate(R.layout.actions_fill_dialog, container, false);
|
||||||
|
|
||||||
deliverButton = (Button) view.findViewById(R.id.treatments_newtreatment_deliverbutton);
|
view.findViewById(R.id.ok).setOnClickListener(this);
|
||||||
|
view.findViewById(R.id.cancel).setOnClickListener(this);
|
||||||
|
|
||||||
deliverButton.setOnClickListener(this);
|
|
||||||
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
|
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
|
||||||
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
|
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
|
||||||
|
|
||||||
Double maxInsulin = MainApp.getConfigBuilder().applyBolusConstraints(Constants.bolusOnlyForCheckLimit);
|
pumpSiteChangeCheckbox = view.findViewById(R.id.fill_catheter_change);
|
||||||
double bolusstep = ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep;
|
insulinCartridgeChangeCheckbox = view.findViewById(R.id.fill_cartridge_change);
|
||||||
editInsulin = (NumberPicker) view.findViewById(R.id.treatments_newtreatment_insulinamount);
|
|
||||||
editInsulin.setParams(0d, 0d, maxInsulin, bolusstep, new DecimalFormat("0.00"), false);
|
|
||||||
|
|
||||||
//setup preset buttons
|
Double maxInsulin = MainApp.getConstraintChecker().getMaxBolusAllowed().value();
|
||||||
Button button1 = (Button) view.findViewById(R.id.fill_preset_button1);
|
double bolusstep = ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().bolusStep;
|
||||||
Button button2 = (Button) view.findViewById(R.id.fill_preset_button2);
|
editInsulin = view.findViewById(R.id.fill_insulinamount);
|
||||||
Button button3 = (Button) view.findViewById(R.id.fill_preset_button3);
|
editInsulin.setParams(0d, 0d, maxInsulin, bolusstep, DecimalFormatter.pumpSupportedBolusFormat(), false, textWatcher);
|
||||||
View divider = view.findViewById(R.id.fill_preset_divider);
|
|
||||||
|
|
||||||
|
|
||||||
|
Button preset1Button = view.findViewById(R.id.fill_preset_button1);
|
||||||
amount1 = SP.getDouble("fill_button1", 0.3);
|
amount1 = SP.getDouble("fill_button1", 0.3);
|
||||||
amount2 = SP.getDouble("fill_button2", 0d);
|
|
||||||
amount3 = SP.getDouble("fill_button3", 0d);
|
|
||||||
|
|
||||||
if (amount1 > 0) {
|
if (amount1 > 0) {
|
||||||
button1.setVisibility(View.VISIBLE);
|
preset1Button.setVisibility(View.VISIBLE);
|
||||||
button1.setText(DecimalFormatter.to2Decimal(amount1) + "U");
|
preset1Button.setText(DecimalFormatter.toPumpSupportedBolus(amount1)); // + "U");
|
||||||
button1.setOnClickListener(this);
|
preset1Button.setOnClickListener(this);
|
||||||
} else {
|
} else {
|
||||||
button1.setVisibility(View.GONE);
|
preset1Button.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
Button preset2Button = view.findViewById(R.id.fill_preset_button2);
|
||||||
|
amount2 = SP.getDouble("fill_button2", 0d);
|
||||||
if (amount2 > 0) {
|
if (amount2 > 0) {
|
||||||
button2.setVisibility(View.VISIBLE);
|
preset2Button.setVisibility(View.VISIBLE);
|
||||||
button2.setText(DecimalFormatter.to2Decimal(amount2) + "U");
|
preset2Button.setText(DecimalFormatter.toPumpSupportedBolus(amount2)); // + "U");
|
||||||
button2.setOnClickListener(this);
|
preset2Button.setOnClickListener(this);
|
||||||
} else {
|
} else {
|
||||||
button2.setVisibility(View.GONE);
|
preset2Button.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
Button preset3Button = view.findViewById(R.id.fill_preset_button3);
|
||||||
|
amount3 = SP.getDouble("fill_button3", 0d);
|
||||||
if (amount3 > 0) {
|
if (amount3 > 0) {
|
||||||
button3.setVisibility(View.VISIBLE);
|
preset3Button.setVisibility(View.VISIBLE);
|
||||||
button3.setText(DecimalFormatter.to2Decimal(amount3) + "U");
|
preset3Button.setText(DecimalFormatter.toPumpSupportedBolus(amount3)); // + "U");
|
||||||
button3.setOnClickListener(this);
|
preset3Button.setOnClickListener(this);
|
||||||
} else {
|
} else {
|
||||||
button3.setVisibility(View.GONE);
|
preset3Button.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (button1.getVisibility() == View.GONE && button2.getVisibility() == View.GONE && button3.getVisibility() == View.GONE) {
|
LinearLayout notesLayout = view.findViewById(R.id.fill_notes_layout);
|
||||||
divider.setVisibility(View.GONE);
|
notesLayout.setVisibility(SP.getBoolean(R.string.key_show_notes_entry_dialogs, false) ? View.VISIBLE : View.GONE);
|
||||||
}
|
notesEdit = view.findViewById(R.id.fill_notes);
|
||||||
|
|
||||||
setCancelable(true);
|
setCancelable(true);
|
||||||
getDialog().setCanceledOnTouchOutside(false);
|
getDialog().setCanceledOnTouchOutside(false);
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
if (getDialog() != null)
|
|
||||||
getDialog().getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
switch (view.getId()) {
|
switch (view.getId()) {
|
||||||
case R.id.treatments_newtreatment_deliverbutton:
|
case R.id.ok:
|
||||||
Double insulin = SafeParse.stringToDouble(editInsulin.getText().toString());
|
confirmAndDeliver();
|
||||||
confirmAndDeliver(insulin);
|
break;
|
||||||
|
case R.id.cancel:
|
||||||
|
dismiss();
|
||||||
break;
|
break;
|
||||||
case R.id.fill_preset_button1:
|
case R.id.fill_preset_button1:
|
||||||
confirmAndDeliver(amount1);
|
editInsulin.setValue(amount1);
|
||||||
break;
|
break;
|
||||||
case R.id.fill_preset_button2:
|
case R.id.fill_preset_button2:
|
||||||
confirmAndDeliver(amount2);
|
editInsulin.setValue(amount2);
|
||||||
break;
|
break;
|
||||||
case R.id.fill_preset_button3:
|
case R.id.fill_preset_button3:
|
||||||
confirmAndDeliver(amount3);
|
editInsulin.setValue(amount3);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void confirmAndDeliver(Double insulin) {
|
private synchronized void confirmAndDeliver() {
|
||||||
|
if (okClicked) {
|
||||||
|
log.debug("guarding: ok already clicked");
|
||||||
|
dismiss();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
okClicked = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
Double insulin = SafeParse.stringToDouble(editInsulin.getText());
|
||||||
|
|
||||||
String confirmMessage = getString(R.string.fillwarning) + "\n";
|
List<String> confirmMessage = new LinkedList<>();
|
||||||
|
|
||||||
Double insulinAfterConstraints = MainApp.getConfigBuilder().applyBolusConstraints(insulin);
|
Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(insulin)).value();
|
||||||
confirmMessage += getString(R.string.bolus) + ": " + insulinAfterConstraints + "U";
|
if (insulinAfterConstraints > 0) {
|
||||||
if (insulinAfterConstraints - insulin != 0)
|
confirmMessage.add(MainApp.gs(R.string.fillwarning));
|
||||||
confirmMessage += "\n" + getString(R.string.constraintapllied);
|
confirmMessage.add("");
|
||||||
|
confirmMessage.add(MainApp.gs(R.string.bolus) + ": " + "<font color='" + MainApp.gc(R.color.colorCarbsButton) + "'>" + DecimalFormatter.toPumpSupportedBolus(insulinAfterConstraints) + "U" + "</font>");
|
||||||
|
if (Math.abs(insulinAfterConstraints - insulin) > 0.01d)
|
||||||
|
confirmMessage.add("<font color='" + MainApp.gc(R.color.low) + "'>" + MainApp.gs(R.string.bolusconstraintapplied) + "</font>");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pumpSiteChangeCheckbox.isChecked())
|
||||||
|
confirmMessage.add("" + "<font color='" + MainApp.gc(R.color.actionsConfirm) + "'>" + MainApp.gs(R.string.record_pump_site_change) + "</font>");
|
||||||
|
|
||||||
|
if (insulinCartridgeChangeCheckbox.isChecked())
|
||||||
|
confirmMessage.add("" + "<font color='" + MainApp.gc(R.color.actionsConfirm) + "'>" + MainApp.gs(R.string.record_insulin_cartridge_change) + "</font>");
|
||||||
|
|
||||||
|
final String notes = notesEdit.getText().toString();
|
||||||
|
if (!notes.isEmpty()) {
|
||||||
|
confirmMessage.add(MainApp.gs(R.string.careportal_newnstreatment_notes_label) + ": " + notes);
|
||||||
|
}
|
||||||
|
|
||||||
final Double finalInsulinAfterConstraints = insulinAfterConstraints;
|
final Double finalInsulinAfterConstraints = insulinAfterConstraints;
|
||||||
|
|
||||||
final Context context = getContext();
|
final Context context = getContext();
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||||
|
|
||||||
builder.setTitle(this.getContext().getString(R.string.confirmation));
|
builder.setTitle(MainApp.gs(R.string.confirmation));
|
||||||
builder.setMessage(confirmMessage);
|
if (insulinAfterConstraints > 0 || pumpSiteChangeCheckbox.isChecked() || insulinCartridgeChangeCheckbox.isChecked()) {
|
||||||
builder.setPositiveButton(getString(R.string.primefill), new DialogInterface.OnClickListener() {
|
builder.setMessage(Html.fromHtml(Joiner.on("<br/>").join(confirmMessage)));
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
builder.setPositiveButton(MainApp.gs(R.string.primefill), (dialog, id) -> {
|
||||||
if (finalInsulinAfterConstraints > 0) {
|
synchronized (builder) {
|
||||||
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
|
if (accepted) {
|
||||||
detailedBolusInfo.insulin = finalInsulinAfterConstraints;
|
log.debug("guarding: already accepted");
|
||||||
detailedBolusInfo.context = context;
|
return;
|
||||||
detailedBolusInfo.source = Source.USER;
|
}
|
||||||
detailedBolusInfo.isValid = false; // do not count it in IOB (for pump history)
|
accepted = true;
|
||||||
ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() {
|
|
||||||
@Override
|
if (finalInsulinAfterConstraints > 0) {
|
||||||
public void run() {
|
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
|
||||||
if (!result.success) {
|
detailedBolusInfo.insulin = finalInsulinAfterConstraints;
|
||||||
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
|
detailedBolusInfo.context = context;
|
||||||
i.putExtra("soundid", R.raw.boluserror);
|
detailedBolusInfo.source = Source.USER;
|
||||||
i.putExtra("status", result.comment);
|
detailedBolusInfo.isValid = false; // do not count it in IOB (for pump history)
|
||||||
i.putExtra("title", MainApp.sResources.getString(R.string.treatmentdeliveryerror));
|
detailedBolusInfo.notes = notes;
|
||||||
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
ConfigBuilderPlugin.getPlugin().getCommandQueue().bolus(detailedBolusInfo, new Callback() {
|
||||||
MainApp.instance().startActivity(i);
|
@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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
FabricPrivacy.getInstance().logCustom(new CustomEvent("Fill"));
|
||||||
Answers.getInstance().logCustom(new CustomEvent("Fill"));
|
}
|
||||||
|
if (pumpSiteChangeCheckbox.isChecked())
|
||||||
|
NSUpload.uploadEvent(CareportalEvent.SITECHANGE, now(), notes);
|
||||||
|
if (insulinCartridgeChangeCheckbox.isChecked())
|
||||||
|
NSUpload.uploadEvent(CareportalEvent.INSULINCHANGE, now() + 1000, notes);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
} else {
|
||||||
builder.setNegativeButton(getString(R.string.cancel), null);
|
builder.setMessage(MainApp.gs(R.string.no_action_selected));
|
||||||
|
}
|
||||||
|
builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
|
||||||
builder.show();
|
builder.show();
|
||||||
dismiss();
|
dismiss();
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
|
|
|
@ -10,20 +10,21 @@ import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import com.crashlytics.android.answers.Answers;
|
|
||||||
import com.crashlytics.android.answers.CustomEvent;
|
import com.crashlytics.android.answers.CustomEvent;
|
||||||
|
|
||||||
|
import org.mozilla.javascript.tools.jsc.Main;
|
||||||
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 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.interfaces.Constraint;
|
||||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity;
|
import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity;
|
||||||
import info.nightscout.androidaps.queue.Callback;
|
import info.nightscout.androidaps.queue.Callback;
|
||||||
|
import info.nightscout.utils.FabricPrivacy;
|
||||||
import info.nightscout.utils.NumberPicker;
|
import info.nightscout.utils.NumberPicker;
|
||||||
import info.nightscout.utils.SafeParse;
|
import info.nightscout.utils.SafeParse;
|
||||||
|
|
||||||
|
@ -39,16 +40,16 @@ public class NewExtendedBolusDialog extends DialogFragment implements View.OnCli
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
getDialog().setTitle(getString(R.string.overview_extendedbolus_button));
|
getDialog().setTitle(MainApp.gs(R.string.overview_extendedbolus_button));
|
||||||
|
|
||||||
View view = inflater.inflate(R.layout.overview_newextendedbolus_dialog, container, false);
|
View view = inflater.inflate(R.layout.overview_newextendedbolus_dialog, container, false);
|
||||||
|
|
||||||
Double maxInsulin = MainApp.getConfigBuilder().applyBolusConstraints(Constants.bolusOnlyForCheckLimit);
|
Double maxInsulin = MainApp.getConstraintChecker().getMaxExtendedBolusAllowed().value();
|
||||||
editInsulin = (NumberPicker) view.findViewById(R.id.overview_newextendedbolus_insulin);
|
editInsulin = (NumberPicker) view.findViewById(R.id.overview_newextendedbolus_insulin);
|
||||||
editInsulin.setParams(0d, 0d, maxInsulin, 0.1d, new DecimalFormat("0.00"), false);
|
editInsulin.setParams(0d, 0d, maxInsulin, 0.1d, new DecimalFormat("0.00"), false);
|
||||||
|
|
||||||
double extendedDurationStep = ConfigBuilderPlugin.getActivePump().getPumpDescription().extendedBolusDurationStep;
|
double extendedDurationStep = ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().extendedBolusDurationStep;
|
||||||
double extendedMaxDuration = ConfigBuilderPlugin.getActivePump().getPumpDescription().extendedBolusMaxDuration;
|
double extendedMaxDuration = ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().extendedBolusMaxDuration;
|
||||||
editDuration = (NumberPicker) view.findViewById(R.id.overview_newextendedbolus_duration);
|
editDuration = (NumberPicker) view.findViewById(R.id.overview_newextendedbolus_duration);
|
||||||
editDuration.setParams(extendedDurationStep, extendedDurationStep, extendedMaxDuration, extendedDurationStep, new DecimalFormat("0"), false);
|
editDuration.setParams(extendedDurationStep, extendedDurationStep, extendedMaxDuration, extendedDurationStep, new DecimalFormat("0"), false);
|
||||||
|
|
||||||
|
@ -68,13 +69,13 @@ public class NewExtendedBolusDialog extends DialogFragment implements View.OnCli
|
||||||
Double insulin = SafeParse.stringToDouble(editInsulin.getText());
|
Double insulin = SafeParse.stringToDouble(editInsulin.getText());
|
||||||
int durationInMinutes = SafeParse.stringToInt(editDuration.getText());
|
int durationInMinutes = SafeParse.stringToInt(editDuration.getText());
|
||||||
|
|
||||||
String confirmMessage = getString(R.string.setextendedbolusquestion);
|
String confirmMessage = MainApp.gs(R.string.setextendedbolusquestion);
|
||||||
|
|
||||||
Double insulinAfterConstraint = MainApp.getConfigBuilder().applyBolusConstraints(insulin);
|
Double insulinAfterConstraint = MainApp.getConstraintChecker().applyExtendedBolusConstraints(new Constraint<>(insulin)).value();
|
||||||
confirmMessage += " " + insulinAfterConstraint + " U ";
|
confirmMessage += " " + insulinAfterConstraint + " U ";
|
||||||
confirmMessage += getString(R.string.duration) + " " + durationInMinutes + "min ?";
|
confirmMessage += MainApp.gs(R.string.duration) + " " + durationInMinutes + "min ?";
|
||||||
if (insulinAfterConstraint - insulin != 0d)
|
if (Math.abs(insulinAfterConstraint - insulin) > 0.01d)
|
||||||
confirmMessage += "\n" + getString(R.string.constraintapllied);
|
confirmMessage += "\n" + MainApp.gs(R.string.constraintapllied);
|
||||||
insulin = insulinAfterConstraint;
|
insulin = insulinAfterConstraint;
|
||||||
|
|
||||||
final Double finalInsulin = insulin;
|
final Double finalInsulin = insulin;
|
||||||
|
@ -82,27 +83,27 @@ public class NewExtendedBolusDialog extends DialogFragment implements View.OnCli
|
||||||
|
|
||||||
final Context context = getContext();
|
final Context context = getContext();
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||||
builder.setTitle(context.getString(R.string.confirmation));
|
builder.setTitle(MainApp.gs(R.string.confirmation));
|
||||||
builder.setMessage(confirmMessage);
|
builder.setMessage(confirmMessage);
|
||||||
builder.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
|
builder.setPositiveButton(MainApp.gs(R.string.ok), new DialogInterface.OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
ConfigBuilderPlugin.getCommandQueue().extendedBolus(finalInsulin, finalDurationInMinutes, new Callback() {
|
ConfigBuilderPlugin.getPlugin().getCommandQueue().extendedBolus(finalInsulin, finalDurationInMinutes, new Callback() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
|
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
|
||||||
i.putExtra("soundid", R.raw.boluserror);
|
i.putExtra("soundid", R.raw.boluserror);
|
||||||
i.putExtra("status", result.comment);
|
i.putExtra("status", result.comment);
|
||||||
i.putExtra("title", MainApp.sResources.getString(R.string.treatmentdeliveryerror));
|
i.putExtra("title", MainApp.gs(R.string.treatmentdeliveryerror));
|
||||||
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
MainApp.instance().startActivity(i);
|
MainApp.instance().startActivity(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Answers.getInstance().logCustom(new CustomEvent("ExtendedBolus"));
|
FabricPrivacy.getInstance().logCustom(new CustomEvent("ExtendedBolus"));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
builder.setNegativeButton(getString(R.string.cancel), null);
|
builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
|
||||||
builder.show();
|
builder.show();
|
||||||
dismiss();
|
dismiss();
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package info.nightscout.androidaps.plugins.Actions.dialogs;
|
package info.nightscout.androidaps.plugins.Actions.dialogs;
|
||||||
|
|
||||||
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;
|
||||||
|
@ -13,7 +12,6 @@ import android.widget.LinearLayout;
|
||||||
import android.widget.RadioButton;
|
import android.widget.RadioButton;
|
||||||
import android.widget.RadioGroup;
|
import android.widget.RadioGroup;
|
||||||
|
|
||||||
import com.crashlytics.android.answers.Answers;
|
|
||||||
import com.crashlytics.android.answers.CustomEvent;
|
import com.crashlytics.android.answers.CustomEvent;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -24,10 +22,13 @@ import java.text.DecimalFormat;
|
||||||
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.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
|
import info.nightscout.androidaps.interfaces.Constraint;
|
||||||
import info.nightscout.androidaps.interfaces.PumpDescription;
|
import info.nightscout.androidaps.interfaces.PumpDescription;
|
||||||
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.Overview.Dialogs.ErrorHelperActivity;
|
import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity;
|
||||||
import info.nightscout.androidaps.queue.Callback;
|
import info.nightscout.androidaps.queue.Callback;
|
||||||
|
import info.nightscout.utils.FabricPrivacy;
|
||||||
import info.nightscout.utils.NumberPicker;
|
import info.nightscout.utils.NumberPicker;
|
||||||
import info.nightscout.utils.SafeParse;
|
import info.nightscout.utils.SafeParse;
|
||||||
|
|
||||||
|
@ -52,7 +53,7 @@ public class NewTempBasalDialog extends DialogFragment implements View.OnClickLi
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
getDialog().setTitle(getString(R.string.overview_tempbasal_button));
|
getDialog().setTitle(MainApp.gs(R.string.overview_tempbasal_button));
|
||||||
|
|
||||||
View view = inflater.inflate(R.layout.overview_newtempbasal_dialog, container, false);
|
View view = inflater.inflate(R.layout.overview_newtempbasal_dialog, container, false);
|
||||||
|
|
||||||
|
@ -63,14 +64,14 @@ public class NewTempBasalDialog extends DialogFragment implements View.OnClickLi
|
||||||
absoluteRadio = (RadioButton) view.findViewById(R.id.overview_newtempbasal_absolute_radio);
|
absoluteRadio = (RadioButton) view.findViewById(R.id.overview_newtempbasal_absolute_radio);
|
||||||
typeSelectorLayout = (LinearLayout) view.findViewById(R.id.overview_newtempbasal_typeselector_layout);
|
typeSelectorLayout = (LinearLayout) view.findViewById(R.id.overview_newtempbasal_typeselector_layout);
|
||||||
|
|
||||||
PumpDescription pumpDescription = ConfigBuilderPlugin.getActivePump().getPumpDescription();
|
PumpDescription pumpDescription = ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription();
|
||||||
|
|
||||||
basalPercent = (NumberPicker) view.findViewById(R.id.overview_newtempbasal_basalpercentinput);
|
basalPercent = (NumberPicker) view.findViewById(R.id.overview_newtempbasal_basalpercentinput);
|
||||||
double maxTempPercent = pumpDescription.maxTempPercent;
|
double maxTempPercent = pumpDescription.maxTempPercent;
|
||||||
double tempPercentStep = pumpDescription.tempPercentStep;
|
double tempPercentStep = pumpDescription.tempPercentStep;
|
||||||
basalPercent.setParams(100d, 0d, maxTempPercent, tempPercentStep, new DecimalFormat("0"), true);
|
basalPercent.setParams(100d, 0d, maxTempPercent, tempPercentStep, new DecimalFormat("0"), true);
|
||||||
|
|
||||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||||
Double currentBasal = profile != null ? profile.getBasal() : 0d;
|
Double currentBasal = profile != null ? profile.getBasal() : 0d;
|
||||||
basalAbsolute = (NumberPicker) view.findViewById(R.id.overview_newtempbasal_basalabsoluteinput);
|
basalAbsolute = (NumberPicker) view.findViewById(R.id.overview_newtempbasal_basalabsoluteinput);
|
||||||
basalAbsolute.setParams(currentBasal, 0d, pumpDescription.maxTempAbsolute, pumpDescription.tempAbsoluteStep, new DecimalFormat("0.00"), true);
|
basalAbsolute.setParams(currentBasal, 0d, pumpDescription.maxTempAbsolute, pumpDescription.tempAbsoluteStep, new DecimalFormat("0.00"), true);
|
||||||
|
@ -118,21 +119,25 @@ public class NewTempBasalDialog extends DialogFragment implements View.OnClickLi
|
||||||
final boolean setAsPercent = percentRadio.isChecked();
|
final boolean setAsPercent = percentRadio.isChecked();
|
||||||
int durationInMinutes = SafeParse.stringToInt(duration.getText());
|
int durationInMinutes = SafeParse.stringToInt(duration.getText());
|
||||||
|
|
||||||
String confirmMessage = getString(R.string.setbasalquestion);
|
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||||
|
if (profile == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
String confirmMessage = MainApp.gs(R.string.setbasalquestion);
|
||||||
if (setAsPercent) {
|
if (setAsPercent) {
|
||||||
int basalPercentInput = SafeParse.stringToInt(basalPercent.getText());
|
int basalPercentInput = SafeParse.stringToInt(basalPercent.getText());
|
||||||
percent = MainApp.getConfigBuilder().applyBasalConstraints(basalPercentInput);
|
percent = MainApp.getConstraintChecker().applyBasalPercentConstraints(new Constraint<>(basalPercentInput), profile).value();
|
||||||
confirmMessage += "\n" + percent + "% ";
|
confirmMessage += "\n" + percent + "% ";
|
||||||
confirmMessage += "\n" + getString(R.string.duration) + " " + durationInMinutes + "min ?";
|
confirmMessage += "\n" + MainApp.gs(R.string.duration) + " " + durationInMinutes + "min ?";
|
||||||
if (percent != basalPercentInput)
|
if (percent != basalPercentInput)
|
||||||
confirmMessage += "\n" + getString(R.string.constraintapllied);
|
confirmMessage += "\n" + MainApp.gs(R.string.constraintapllied);
|
||||||
} else {
|
} else {
|
||||||
Double basalAbsoluteInput = SafeParse.stringToDouble(basalAbsolute.getText());
|
Double basalAbsoluteInput = SafeParse.stringToDouble(basalAbsolute.getText());
|
||||||
absolute = MainApp.getConfigBuilder().applyBasalConstraints(basalAbsoluteInput);
|
absolute = MainApp.getConstraintChecker().applyBasalConstraints(new Constraint<>(basalAbsoluteInput), profile).value();
|
||||||
confirmMessage += "\n" + absolute + " U/h ";
|
confirmMessage += "\n" + absolute + " U/h ";
|
||||||
confirmMessage += "\n" + getString(R.string.duration) + " " + durationInMinutes + "min ?";
|
confirmMessage += "\n" + MainApp.gs(R.string.duration) + " " + durationInMinutes + "min ?";
|
||||||
if (absolute - basalAbsoluteInput != 0d)
|
if (Math.abs(absolute - basalAbsoluteInput) > 0.01d)
|
||||||
confirmMessage += "\n" + getString(R.string.constraintapllied);
|
confirmMessage += "\n" + MainApp.gs(R.string.constraintapllied);
|
||||||
}
|
}
|
||||||
|
|
||||||
final int finalBasalPercent = percent;
|
final int finalBasalPercent = percent;
|
||||||
|
@ -140,9 +145,9 @@ public class NewTempBasalDialog extends DialogFragment implements View.OnClickLi
|
||||||
final int finalDurationInMinutes = durationInMinutes;
|
final int finalDurationInMinutes = durationInMinutes;
|
||||||
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
|
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
|
||||||
builder.setTitle(this.getContext().getString(R.string.confirmation));
|
builder.setTitle(MainApp.gs(R.string.confirmation));
|
||||||
builder.setMessage(confirmMessage);
|
builder.setMessage(confirmMessage);
|
||||||
builder.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
|
builder.setPositiveButton(MainApp.gs(R.string.ok), new DialogInterface.OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
Callback callback = new Callback() {
|
Callback callback = new Callback() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -151,21 +156,21 @@ public class NewTempBasalDialog extends DialogFragment implements View.OnClickLi
|
||||||
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
|
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
|
||||||
i.putExtra("soundid", R.raw.boluserror);
|
i.putExtra("soundid", R.raw.boluserror);
|
||||||
i.putExtra("status", result.comment);
|
i.putExtra("status", result.comment);
|
||||||
i.putExtra("title", MainApp.sResources.getString(R.string.tempbasaldeliveryerror));
|
i.putExtra("title", MainApp.gs(R.string.tempbasaldeliveryerror));
|
||||||
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
MainApp.instance().startActivity(i);
|
MainApp.instance().startActivity(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (setAsPercent) {
|
if (setAsPercent) {
|
||||||
ConfigBuilderPlugin.getCommandQueue().tempBasalPercent(finalBasalPercent, finalDurationInMinutes, true, callback);
|
ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalPercent(finalBasalPercent, finalDurationInMinutes, true, profile, callback);
|
||||||
} else {
|
} else {
|
||||||
ConfigBuilderPlugin.getCommandQueue().tempBasalAbsolute(finalBasal, finalDurationInMinutes, true, callback);
|
ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalAbsolute(finalBasal, finalDurationInMinutes, true, profile, callback);
|
||||||
}
|
}
|
||||||
Answers.getInstance().logCustom(new CustomEvent("TempBasal"));
|
FabricPrivacy.getInstance().logCustom(new CustomEvent("TempBasal"));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
builder.setNegativeButton(getString(R.string.cancel), null);
|
builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
|
||||||
builder.show();
|
builder.show();
|
||||||
dismiss();
|
dismiss();
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package info.nightscout.androidaps.plugins.Careportal;
|
||||||
|
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.graphics.Color;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.app.FragmentManager;
|
import android.support.v4.app.FragmentManager;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
@ -10,10 +11,11 @@ import android.view.ViewGroup;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.crashlytics.android.Crashlytics;
|
|
||||||
import com.squareup.otto.Subscribe;
|
import com.squareup.otto.Subscribe;
|
||||||
|
|
||||||
import info.nightscout.androidaps.BuildConfig;
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
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;
|
||||||
|
@ -23,9 +25,12 @@ import info.nightscout.androidaps.events.EventCareportalEventChange;
|
||||||
import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialog;
|
import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialog;
|
||||||
import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
|
import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
|
||||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.NSClientInternal.data.NSSettingsStatus;
|
||||||
import info.nightscout.androidaps.plugins.Overview.OverviewFragment;
|
import info.nightscout.androidaps.plugins.Overview.OverviewFragment;
|
||||||
|
import info.nightscout.utils.FabricPrivacy;
|
||||||
|
|
||||||
public class CareportalFragment extends SubscriberFragment implements View.OnClickListener {
|
public class CareportalFragment extends SubscriberFragment implements View.OnClickListener {
|
||||||
|
private static Logger log = LoggerFactory.getLogger(CareportalFragment.class);
|
||||||
|
|
||||||
TextView iage;
|
TextView iage;
|
||||||
TextView cage;
|
TextView cage;
|
||||||
|
@ -96,7 +101,7 @@ public class CareportalFragment extends SubscriberFragment implements View.OnCli
|
||||||
noProfileView = view.findViewById(R.id.profileview_noprofile);
|
noProfileView = view.findViewById(R.id.profileview_noprofile);
|
||||||
butonsLayout = (LinearLayout) view.findViewById(R.id.careportal_buttons);
|
butonsLayout = (LinearLayout) view.findViewById(R.id.careportal_buttons);
|
||||||
|
|
||||||
ProfileStore profileStore = ConfigBuilderPlugin.getActiveProfileInterface().getProfile();
|
ProfileStore profileStore = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface() != null ? ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getProfile() : null;
|
||||||
if (profileStore == null) {
|
if (profileStore == null) {
|
||||||
noProfileView.setVisibility(View.VISIBLE);
|
noProfileView.setVisibility(View.VISIBLE);
|
||||||
butonsLayout.setVisibility(View.GONE);
|
butonsLayout.setVisibility(View.GONE);
|
||||||
|
@ -105,13 +110,13 @@ public class CareportalFragment extends SubscriberFragment implements View.OnCli
|
||||||
butonsLayout.setVisibility(View.VISIBLE);
|
butonsLayout.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Config.NSCLIENT || Config.G5UPLOADER)
|
if (Config.NSCLIENT)
|
||||||
statsLayout.setVisibility(View.GONE); // visible on overview
|
statsLayout.setVisibility(View.GONE); // visible on overview
|
||||||
|
|
||||||
updateGUI();
|
updateGUI();
|
||||||
return view;
|
return view;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Crashlytics.logException(e);
|
FabricPrivacy.logException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -208,31 +213,55 @@ public class CareportalFragment extends SubscriberFragment implements View.OnCli
|
||||||
public static void updateAge(Activity activity, final TextView sage, final TextView iage, final TextView cage, final TextView pbage) {
|
public static void updateAge(Activity activity, final TextView sage, final TextView iage, final TextView cage, final TextView pbage) {
|
||||||
if (activity != null) {
|
if (activity != null) {
|
||||||
activity.runOnUiThread(
|
activity.runOnUiThread(
|
||||||
new Runnable() {
|
() -> {
|
||||||
@Override
|
CareportalEvent careportalEvent;
|
||||||
public void run() {
|
NSSettingsStatus nsSettings = new NSSettingsStatus().getInstance();
|
||||||
CareportalEvent careportalEvent;
|
|
||||||
String notavailable = OverviewFragment.shorttextmode ? "-" : MainApp.sResources.getString(R.string.notavailable);
|
double iageUrgent = nsSettings.getExtendedWarnValue("iage", "urgent", 96);
|
||||||
if (sage != null) {
|
double iageWarn = nsSettings.getExtendedWarnValue("iage", "warn", 72);
|
||||||
careportalEvent = MainApp.getDbHelper().getLastCareportalEvent(CareportalEvent.SENSORCHANGE);
|
handleAge(iage, CareportalEvent.INSULINCHANGE, iageWarn, iageUrgent);
|
||||||
sage.setText(careportalEvent != null ? careportalEvent.age() : notavailable);
|
|
||||||
}
|
double cageUrgent = nsSettings.getExtendedWarnValue("cage", "urgent", 72);
|
||||||
if (iage != null) {
|
double cageWarn = nsSettings.getExtendedWarnValue("cage", "warn", 48);
|
||||||
careportalEvent = MainApp.getDbHelper().getLastCareportalEvent(CareportalEvent.INSULINCHANGE);
|
handleAge(cage, CareportalEvent.SITECHANGE, cageWarn, cageUrgent);
|
||||||
iage.setText(careportalEvent != null ? careportalEvent.age() : notavailable);
|
|
||||||
}
|
double sageUrgent = nsSettings.getExtendedWarnValue("sage", "urgent", 166);
|
||||||
if (cage != null) {
|
double sageWarn = nsSettings.getExtendedWarnValue("sage", "warn", 164);
|
||||||
careportalEvent = MainApp.getDbHelper().getLastCareportalEvent(CareportalEvent.SITECHANGE);
|
handleAge(sage, CareportalEvent.SENSORCHANGE, sageWarn, sageUrgent);
|
||||||
cage.setText(careportalEvent != null ? careportalEvent.age() : notavailable);
|
|
||||||
}
|
double pbageUrgent = nsSettings.getExtendedWarnValue("pgage", "urgent", 360);
|
||||||
if (pbage != null) {
|
double pbageWarn = nsSettings.getExtendedWarnValue("pgage", "warn", 240);
|
||||||
careportalEvent = MainApp.getDbHelper().getLastCareportalEvent(CareportalEvent.PUMPBATTERYCHANGE);
|
handleAge(pbage, CareportalEvent.PUMPBATTERYCHANGE, pbageWarn, pbageUrgent);
|
||||||
pbage.setText(careportalEvent != null ? careportalEvent.age() : notavailable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int determineTextColor(CareportalEvent careportalEvent, double warnThreshold, double urgentThreshold) {
|
||||||
|
if (careportalEvent.isOlderThan(urgentThreshold)) {
|
||||||
|
return MainApp.gc(R.color.low);
|
||||||
|
} else if (careportalEvent.isOlderThan(warnThreshold)) {
|
||||||
|
return MainApp.gc(R.color.high);
|
||||||
|
} else {
|
||||||
|
return Color.WHITE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TextView handleAge(final TextView age, String eventType, double warnThreshold, double urgentThreshold) {
|
||||||
|
String notavailable = OverviewFragment.shorttextmode ? "-" : MainApp.gs(R.string.notavailable);
|
||||||
|
|
||||||
|
if (age != null) {
|
||||||
|
CareportalEvent careportalEvent = MainApp.getDbHelper().getLastCareportalEvent(eventType);
|
||||||
|
if (careportalEvent != null) {
|
||||||
|
age.setTextColor(CareportalFragment.determineTextColor(careportalEvent, warnThreshold, urgentThreshold));
|
||||||
|
age.setText(careportalEvent.age());
|
||||||
|
} else {
|
||||||
|
age.setText(notavailable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return age;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
package info.nightscout.androidaps.plugins.Careportal;
|
package info.nightscout.androidaps.plugins.Careportal;
|
||||||
|
|
||||||
import info.nightscout.androidaps.Config;
|
import info.nightscout.androidaps.Config;
|
||||||
import info.nightscout.androidaps.MainApp;
|
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||||
|
import info.nightscout.androidaps.interfaces.PluginDescription;
|
||||||
|
import info.nightscout.androidaps.interfaces.PluginType;
|
||||||
|
|
||||||
public class CareportalPlugin implements PluginBase {
|
public class CareportalPlugin extends PluginBase {
|
||||||
|
|
||||||
private boolean fragmentEnabled = true;
|
|
||||||
private boolean fragmentVisible = true;
|
|
||||||
|
|
||||||
static CareportalPlugin careportalPlugin;
|
static CareportalPlugin careportalPlugin;
|
||||||
|
|
||||||
|
@ -19,70 +17,16 @@ public class CareportalPlugin implements PluginBase {
|
||||||
return careportalPlugin;
|
return careportalPlugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public CareportalPlugin() {
|
||||||
public int getType() {
|
super(new PluginDescription()
|
||||||
return PluginBase.GENERAL;
|
.mainType(PluginType.GENERAL)
|
||||||
}
|
.fragmentClass(CareportalFragment.class.getName())
|
||||||
|
.pluginName(R.string.careportal)
|
||||||
@Override
|
.shortName(R.string.careportal_shortname)
|
||||||
public String getFragmentClass() {
|
.visibleByDefault(true)
|
||||||
return CareportalFragment.class.getName();
|
.enableByDefault(true)
|
||||||
}
|
.description(R.string.description_careportal)
|
||||||
|
);
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return MainApp.sResources.getString(R.string.careportal);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getNameShort() {
|
|
||||||
String name = MainApp.sResources.getString(R.string.careportal_shortname);
|
|
||||||
if (!name.trim().isEmpty()){
|
|
||||||
//only if translation exists
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
// use long name as fallback
|
|
||||||
return getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled(int type) {
|
|
||||||
return type == GENERAL && fragmentEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isVisibleInTabs(int type) {
|
|
||||||
return type == GENERAL && fragmentVisible;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canBeHidden(int type) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasFragment() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean showInList(int type) {
|
|
||||||
return !Config.NSCLIENT && !Config.G5UPLOADER;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setFragmentEnabled(int type, boolean fragmentEnabled) {
|
|
||||||
if (type == GENERAL) this.fragmentEnabled = fragmentEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setFragmentVisible(int type, boolean fragmentVisible) {
|
|
||||||
if (type == GENERAL) this.fragmentVisible = fragmentVisible;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getPreferencesId() {
|
|
||||||
return R.xml.pref_careportal;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,6 @@ package info.nightscout.androidaps.plugins.Careportal.Dialogs;
|
||||||
|
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.app.DialogFragment;
|
import android.support.v4.app.DialogFragment;
|
||||||
import android.support.v7.app.AlertDialog;
|
import android.support.v7.app.AlertDialog;
|
||||||
|
@ -16,15 +14,14 @@ import android.view.ViewGroup;
|
||||||
import android.widget.AdapterView;
|
import android.widget.AdapterView;
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.CompoundButton;
|
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.RadioButton;
|
import android.widget.RadioButton;
|
||||||
import android.widget.Spinner;
|
import android.widget.Spinner;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.crashlytics.android.answers.Answers;
|
|
||||||
import com.crashlytics.android.answers.CustomEvent;
|
import com.crashlytics.android.answers.CustomEvent;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import com.wdullaer.materialdatetimepicker.date.DatePickerDialog;
|
import com.wdullaer.materialdatetimepicker.date.DatePickerDialog;
|
||||||
import com.wdullaer.materialdatetimepicker.time.RadialPickerLayout;
|
import com.wdullaer.materialdatetimepicker.time.RadialPickerLayout;
|
||||||
import com.wdullaer.materialdatetimepicker.time.TimePickerDialog;
|
import com.wdullaer.materialdatetimepicker.time.TimePickerDialog;
|
||||||
|
@ -38,6 +35,7 @@ import java.text.DecimalFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import info.nightscout.androidaps.Constants;
|
import info.nightscout.androidaps.Constants;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
|
@ -45,17 +43,21 @@ import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.data.GlucoseStatus;
|
import info.nightscout.androidaps.data.GlucoseStatus;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
import info.nightscout.androidaps.data.ProfileStore;
|
import info.nightscout.androidaps.data.ProfileStore;
|
||||||
|
import info.nightscout.androidaps.db.BgReading;
|
||||||
import info.nightscout.androidaps.db.CareportalEvent;
|
import info.nightscout.androidaps.db.CareportalEvent;
|
||||||
import info.nightscout.androidaps.db.ProfileSwitch;
|
import info.nightscout.androidaps.db.ProfileSwitch;
|
||||||
import info.nightscout.androidaps.db.Source;
|
import info.nightscout.androidaps.db.Source;
|
||||||
import info.nightscout.androidaps.db.TempTarget;
|
import info.nightscout.androidaps.db.TempTarget;
|
||||||
import info.nightscout.androidaps.events.EventNewBasalProfile;
|
|
||||||
import info.nightscout.androidaps.plugins.Careportal.OptionsToShow;
|
import info.nightscout.androidaps.plugins.Careportal.OptionsToShow;
|
||||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity;
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions;
|
||||||
import info.nightscout.androidaps.queue.Callback;
|
import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload;
|
||||||
|
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.utils.DateUtil;
|
import info.nightscout.utils.DateUtil;
|
||||||
import info.nightscout.utils.NSUpload;
|
import info.nightscout.utils.DefaultValueHelper;
|
||||||
|
import info.nightscout.utils.FabricPrivacy;
|
||||||
|
import info.nightscout.utils.HardLimits;
|
||||||
|
import info.nightscout.utils.JsonHelper;
|
||||||
import info.nightscout.utils.NumberPicker;
|
import info.nightscout.utils.NumberPicker;
|
||||||
import info.nightscout.utils.SP;
|
import info.nightscout.utils.SP;
|
||||||
import info.nightscout.utils.SafeParse;
|
import info.nightscout.utils.SafeParse;
|
||||||
|
@ -70,8 +72,8 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
|
||||||
private static String event;
|
private static String event;
|
||||||
|
|
||||||
Profile profile;
|
Profile profile;
|
||||||
ProfileStore profileStore;
|
public ProfileStore profileStore;
|
||||||
String units;
|
String units = Constants.MGDL;
|
||||||
|
|
||||||
TextView eventTypeText;
|
TextView eventTypeText;
|
||||||
LinearLayout layoutPercent;
|
LinearLayout layoutPercent;
|
||||||
|
@ -105,13 +107,19 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
|
||||||
|
|
||||||
Date eventTime;
|
Date eventTime;
|
||||||
|
|
||||||
|
private static Integer seconds = null;
|
||||||
|
|
||||||
public void setOptions(OptionsToShow options, int event) {
|
public void setOptions(OptionsToShow options, int event) {
|
||||||
this.options = options;
|
this.options = options;
|
||||||
this.event = MainApp.sResources.getString(event);
|
this.event = MainApp.gs(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NewNSTreatmentDialog() {
|
public NewNSTreatmentDialog() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
|
if (seconds == null) {
|
||||||
|
seconds = Double.valueOf(Math.random() * 59).intValue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -130,7 +138,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
if (options == null) return null;
|
if (options == null) return null;
|
||||||
getDialog().setTitle(getString(options.eventName));
|
getDialog().setTitle(MainApp.gs(options.eventName));
|
||||||
setStyle(DialogFragment.STYLE_NORMAL, getTheme());
|
setStyle(DialogFragment.STYLE_NORMAL, getTheme());
|
||||||
View view = inflater.inflate(R.layout.careportal_newnstreatment_dialog, container, false);
|
View view = inflater.inflate(R.layout.careportal_newnstreatment_dialog, container, false);
|
||||||
|
|
||||||
|
@ -165,53 +173,67 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
|
||||||
view.findViewById(R.id.cancel).setOnClickListener(this);
|
view.findViewById(R.id.cancel).setOnClickListener(this);
|
||||||
|
|
||||||
// profile
|
// profile
|
||||||
profile = MainApp.getConfigBuilder().getProfile();
|
profile = ProfileFunctions.getInstance().getProfile();
|
||||||
profileStore = ConfigBuilderPlugin.getActiveProfileInterface().getProfile();
|
profileStore = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getProfile();
|
||||||
ArrayList<CharSequence> profileList;
|
if (profileStore == null) {
|
||||||
units = profile != null ? profile.getUnits() : Constants.MGDL;
|
if (options.eventType == R.id.careportal_profileswitch) {
|
||||||
profileList = profileStore.getProfileList();
|
log.error("Profile switch called but plugin doesn't contain valid profile");
|
||||||
ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>(getContext(),
|
}
|
||||||
R.layout.spinner_centered, profileList);
|
} else {
|
||||||
profileSpinner.setAdapter(adapter);
|
ArrayList<CharSequence> profileList;
|
||||||
// set selected to actual profile
|
units = profile != null ? profile.getUnits() : Constants.MGDL;
|
||||||
for (int p = 0; p < profileList.size(); p++) {
|
profileList = profileStore.getProfileList();
|
||||||
if (profileList.get(p).equals(MainApp.getConfigBuilder().getProfileName(false)))
|
ArrayAdapter<CharSequence> adapter = new ArrayAdapter<>(getContext(),
|
||||||
profileSpinner.setSelection(p);
|
R.layout.spinner_centered, profileList);
|
||||||
|
profileSpinner.setAdapter(adapter);
|
||||||
|
// set selected to actual profile
|
||||||
|
for (int p = 0; p < profileList.size(); p++) {
|
||||||
|
if (profileList.get(p).equals(ProfileFunctions.getInstance().getProfileName(false)))
|
||||||
|
profileSpinner.setSelection(p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
final Double bg = Profile.fromMgdlToUnits(GlucoseStatus.getGlucoseStatusData() != null ? GlucoseStatus.getGlucoseStatusData().glucose : 0d, units);
|
||||||
final Double bg = Profile.fromMgdlToUnits(GlucoseStatus.getGlucoseStatusData() != null ? GlucoseStatus.getGlucoseStatusData().glucose : 0d, profile != null ? profile.getUnits() : Constants.MGDL);
|
|
||||||
|
|
||||||
// temp target
|
// temp target
|
||||||
final ArrayList<CharSequence> reasonList = new ArrayList<CharSequence>();
|
final List<String> reasonList = Lists.newArrayList(
|
||||||
reasonList.add(MainApp.sResources.getString(R.string.manual));
|
MainApp.gs(R.string.manual),
|
||||||
reasonList.add(MainApp.sResources.getString(R.string.eatingsoon));
|
MainApp.gs(R.string.eatingsoon),
|
||||||
reasonList.add(MainApp.sResources.getString(R.string.activity));
|
MainApp.gs(R.string.activity),
|
||||||
ArrayAdapter<CharSequence> adapterReason = new ArrayAdapter<CharSequence>(getContext(),
|
MainApp.gs(R.string.hypo));
|
||||||
|
ArrayAdapter<String> adapterReason = new ArrayAdapter<>(getContext(),
|
||||||
R.layout.spinner_centered, reasonList);
|
R.layout.spinner_centered, reasonList);
|
||||||
reasonSpinner.setAdapter(adapterReason);
|
reasonSpinner.setAdapter(adapterReason);
|
||||||
reasonSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
reasonSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||||
double defaultDuration = 0;
|
double defaultDuration;
|
||||||
double defaultTarget = 0;
|
double defaultTarget = 0;
|
||||||
if (profile != null) {
|
if (profile != null && editTemptarget.getValue() == bg) {
|
||||||
defaultTarget = bg.doubleValue();
|
defaultTarget = bg;
|
||||||
|
} else {
|
||||||
|
//prevent changes on screen rotate
|
||||||
|
defaultTarget = editTemptarget.getValue();
|
||||||
}
|
}
|
||||||
boolean erase = false;
|
boolean erase = false;
|
||||||
|
|
||||||
if (MainApp.sResources.getString(R.string.eatingsoon).equals(reasonList.get(position))) {
|
String units = ProfileFunctions.getInstance().getProfileUnits();
|
||||||
defaultDuration = SP.getDouble(R.string.key_eatingsoon_duration, 0d);
|
DefaultValueHelper helper = new DefaultValueHelper();
|
||||||
defaultTarget = SP.getDouble(R.string.key_eatingsoon_target, 0d);
|
if (MainApp.gs(R.string.eatingsoon).equals(reasonList.get(position))) {
|
||||||
;
|
defaultDuration = helper.determineEatingSoonTTDuration();
|
||||||
} else if (MainApp.sResources.getString(R.string.activity).equals(reasonList.get(position))) {
|
defaultTarget = helper.determineEatingSoonTT(units);
|
||||||
defaultDuration = SP.getDouble(R.string.key_activity_duration, 0d);
|
} else if (MainApp.gs(R.string.activity).equals(reasonList.get(position))) {
|
||||||
;
|
defaultDuration = helper.determineActivityTTDuration();
|
||||||
defaultTarget = SP.getDouble(R.string.key_activity_target, 0d);
|
defaultTarget = helper.determineActivityTT(units);
|
||||||
;
|
} else if (MainApp.gs(R.string.hypo).equals(reasonList.get(position))) {
|
||||||
|
defaultDuration = helper.determineHypoTTDuration();
|
||||||
|
defaultTarget = helper.determineHypoTT(units);
|
||||||
|
} else if (editDuration.getValue() != 0) {
|
||||||
|
defaultDuration = editDuration.getValue();
|
||||||
} else {
|
} else {
|
||||||
defaultDuration = 0;
|
defaultDuration = 0;
|
||||||
erase = true;
|
erase = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (defaultTarget != 0 || erase) {
|
if (defaultTarget != 0 || erase) {
|
||||||
editTemptarget.setValue(defaultTarget);
|
editTemptarget.setValue(defaultTarget);
|
||||||
}
|
}
|
||||||
|
@ -243,32 +265,33 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
|
||||||
if (sensorRadioButton.isChecked()) meterRadioButton.setChecked(true);
|
if (sensorRadioButton.isChecked()) meterRadioButton.setChecked(true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
editBg = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_bginput);
|
editBg = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_bginput);
|
||||||
editTemptarget = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_temptarget);
|
editTemptarget = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_temptarget);
|
||||||
if (profile == null) {
|
if (profile == null) {
|
||||||
editBg.setParams(bg, 0d, 500d, 0.1d, new DecimalFormat("0.0"), false, bgTextWatcher);
|
editBg.setParams(bg, 0d, 500d, 0.1d, new DecimalFormat("0.0"), false, bgTextWatcher);
|
||||||
editTemptarget.setParams(bg, 0d, 500d, 0.1d, new DecimalFormat("0.0"), false);
|
editTemptarget.setParams(bg, 0d, 500d, 0.1d, new DecimalFormat("0.0"), false);
|
||||||
} else if (profile.getUnits().equals(Constants.MMOL)) {
|
} else if (units.equals(Constants.MMOL)) {
|
||||||
editBg.setParams(bg, 0d, 30d, 0.1d, new DecimalFormat("0.0"), false, bgTextWatcher);
|
editBg.setParams(bg, 0d, 30d, 0.1d, new DecimalFormat("0.0"), false, bgTextWatcher);
|
||||||
editTemptarget.setParams(bg, 0d, 30d, 0.1d, new DecimalFormat("0.0"), false);
|
editTemptarget.setParams(bg, 0d, 30d, 0.1d, new DecimalFormat("0.0"), false);
|
||||||
} else {
|
} else {
|
||||||
editBg.setParams(bg, 0d, 500d, 1d, new DecimalFormat("0"), false, bgTextWatcher);
|
editBg.setParams(bg, 0d, 500d, 1d, new DecimalFormat("0"), false, bgTextWatcher);
|
||||||
editTemptarget.setParams(bg, 0d, 500d, 1d, new DecimalFormat("0"), false);
|
editTemptarget.setParams(bg, 0d, 500d, 1d, new DecimalFormat("0"), false);
|
||||||
}
|
}
|
||||||
sensorRadioButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
|
||||||
@Override
|
sensorRadioButton.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
Double bg1 = Profile.fromMgdlToUnits(GlucoseStatus.getGlucoseStatusData() != null ? GlucoseStatus.getGlucoseStatusData().glucose : 0d, units);
|
||||||
Double bg = Profile.fromMgdlToUnits(GlucoseStatus.getGlucoseStatusData() != null ? GlucoseStatus.getGlucoseStatusData().glucose : 0d, profile.getUnits());
|
if (savedInstanceState != null && savedInstanceState.getDouble("editBg") != bg1) {
|
||||||
editBg.setValue(bg);
|
editBg.setValue(savedInstanceState.getDouble("editBg"));
|
||||||
|
} else {
|
||||||
|
editBg.setValue(bg1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Integer maxCarbs = MainApp.getConfigBuilder().applyCarbsConstraints(Constants.carbsOnlyForCheckLimit);
|
Integer maxCarbs = MainApp.getConstraintChecker().getMaxCarbsAllowed().value();
|
||||||
editCarbs = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_carbsinput);
|
editCarbs = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_carbsinput);
|
||||||
editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false);
|
editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false);
|
||||||
|
|
||||||
Double maxInsulin = MainApp.getConfigBuilder().applyBolusConstraints(Constants.bolusOnlyForCheckLimit);
|
Double maxInsulin = MainApp.getConstraintChecker().getMaxBolusAllowed().value();
|
||||||
editInsulin = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_insulininput);
|
editInsulin = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_insulininput);
|
||||||
editInsulin.setParams(0d, 0d, maxInsulin, 0.05d, new DecimalFormat("0.00"), false);
|
editInsulin.setParams(0d, 0d, maxInsulin, 0.05d, new DecimalFormat("0.00"), false);
|
||||||
|
|
||||||
|
@ -295,9 +318,11 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Integer maxPercent = MainApp.getConfigBuilder().applyBasalConstraints(Constants.basalPercentOnlyForCheckLimit);
|
Integer maxPercent = 200;
|
||||||
|
if (profile != null)
|
||||||
|
maxPercent = MainApp.getConstraintChecker().getMaxBasalPercentAllowed(profile).value();
|
||||||
editPercent = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_percentinput);
|
editPercent = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_percentinput);
|
||||||
editPercent.setParams(0d, 0d, (double) maxPercent, 5d, new DecimalFormat("0"), true, percentTextWatcher);
|
editPercent.setParams(0d, -100d, (double) maxPercent, 5d, new DecimalFormat("0"), true, percentTextWatcher);
|
||||||
|
|
||||||
TextWatcher absoluteTextWatcher = new TextWatcher() {
|
TextWatcher absoluteTextWatcher = new TextWatcher() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -317,7 +342,9 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Double maxAbsolute = MainApp.getConfigBuilder().applyBasalConstraints(Constants.basalAbsoluteOnlyForCheckLimit);
|
Double maxAbsolute = HardLimits.maxBasal();
|
||||||
|
if (profile != null)
|
||||||
|
maxAbsolute = MainApp.getConstraintChecker().getMaxBasalAllowed(profile).value();
|
||||||
editAbsolute = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_absoluteinput);
|
editAbsolute = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_absoluteinput);
|
||||||
editAbsolute.setParams(0d, 0d, maxAbsolute, 0.05d, new DecimalFormat("0.00"), true, absoluteTextWatcher);
|
editAbsolute.setParams(0d, 0d, maxAbsolute, 0.05d, new DecimalFormat("0.00"), true, absoluteTextWatcher);
|
||||||
|
|
||||||
|
@ -330,19 +357,19 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
|
||||||
editTimeshift = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_timeshift);
|
editTimeshift = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_timeshift);
|
||||||
editTimeshift.setParams(0d, (double) Constants.CPP_MIN_TIMESHIFT, (double) Constants.CPP_MAX_TIMESHIFT, 1d, new DecimalFormat("0"), false);
|
editTimeshift.setParams(0d, (double) Constants.CPP_MIN_TIMESHIFT, (double) Constants.CPP_MAX_TIMESHIFT, 1d, new DecimalFormat("0"), false);
|
||||||
|
|
||||||
ProfileSwitch ps = MainApp.getConfigBuilder().getProfileSwitchFromHistory(System.currentTimeMillis());
|
ProfileSwitch ps = TreatmentsPlugin.getPlugin().getProfileSwitchFromHistory(DateUtil.now());
|
||||||
if (ps != null && ps.isCPP) {
|
if (ps != null && ps.isCPP) {
|
||||||
final int percentage = ps.percentage;
|
final int percentage = ps.percentage;
|
||||||
final int timeshift = ps.timeshift;
|
final int timeshift = ps.timeshift;
|
||||||
reuseButton.setText(reuseButton.getText() + " " + percentage + "% " + timeshift + "h");
|
reuseButton.setText(reuseButton.getText() + " " + percentage + "% " + timeshift + "h");
|
||||||
reuseButton.setOnClickListener(new View.OnClickListener() {
|
reuseButton.setOnClickListener(v -> {
|
||||||
@Override
|
editPercentage.setValue((double) percentage);
|
||||||
public void onClick(View v) {
|
editTimeshift.setValue((double) timeshift);
|
||||||
editPercentage.setValue((double) percentage);
|
|
||||||
editTimeshift.setValue((double) timeshift);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (ps == null) {
|
||||||
|
options.duration = false;
|
||||||
|
}
|
||||||
|
|
||||||
showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_eventtime_layout), options.date);
|
showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_eventtime_layout), options.date);
|
||||||
showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_bg_layout), options.bg);
|
showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_bg_layout), options.bg);
|
||||||
|
@ -362,6 +389,25 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
|
||||||
|
|
||||||
setCancelable(true);
|
setCancelable(true);
|
||||||
getDialog().setCanceledOnTouchOutside(false);
|
getDialog().setCanceledOnTouchOutside(false);
|
||||||
|
//recovering state if there is something
|
||||||
|
// only numberPickers and editTexts
|
||||||
|
if (savedInstanceState != null) {
|
||||||
|
editBg.setValue(savedInstanceState.getDouble("editBg"));
|
||||||
|
editTemptarget.setValue(savedInstanceState.getDouble("editTemptarget"));
|
||||||
|
notesEdit.setText(savedInstanceState.getString("notesEdit"));
|
||||||
|
editCarbs.setValue(savedInstanceState.getDouble("editCarbs"));
|
||||||
|
editCarbs.setValue(savedInstanceState.getDouble("editCarbs"));
|
||||||
|
editInsulin.setValue(savedInstanceState.getDouble("editInsulin"));
|
||||||
|
editDuration.setValue(savedInstanceState.getDouble("editDuration"));
|
||||||
|
editPercent.setValue(savedInstanceState.getDouble("editPercent"));
|
||||||
|
editAbsolute.setValue(savedInstanceState.getDouble("editAbsolute"));
|
||||||
|
editCarbTime.setValue(savedInstanceState.getDouble("editCarbTime"));
|
||||||
|
editPercentage.setValue(savedInstanceState.getDouble("editPercentage"));
|
||||||
|
editTimeshift.setValue(savedInstanceState.getDouble("editTimeshift"));
|
||||||
|
// time and date
|
||||||
|
dateButton.setText(savedInstanceState.getString("dateButton"));
|
||||||
|
timeButton.setText(savedInstanceState.getString("timeButton"));
|
||||||
|
}
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -393,7 +439,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
|
||||||
tpd.show(context.getFragmentManager(), "Timepickerdialog");
|
tpd.show(context.getFragmentManager(), "Timepickerdialog");
|
||||||
break;
|
break;
|
||||||
case R.id.ok:
|
case R.id.ok:
|
||||||
createNSTreatment();
|
confirmNSTreatmentCreation();
|
||||||
dismiss();
|
dismiss();
|
||||||
break;
|
break;
|
||||||
case R.id.cancel:
|
case R.id.cancel:
|
||||||
|
@ -407,20 +453,32 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
|
||||||
else layout.setVisibility(View.GONE);
|
else layout.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateBGforDateTime() {
|
||||||
|
long millis = eventTime.getTime() - (150 * 1000L); // 2,5 * 60 * 1000
|
||||||
|
List<BgReading> data = MainApp.getDbHelper().getBgreadingsDataFromTime(millis, true);
|
||||||
|
if ((data.size() > 0) &&
|
||||||
|
(data.get(0).date > millis - 7 * 60 * 1000L) &&
|
||||||
|
(data.get(0).date < millis + 7 * 60 * 1000L)) {
|
||||||
|
editBg.setValue(Profile.fromMgdlToUnits(data.get(0).value, units));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDateSet(DatePickerDialog view, int year, int monthOfYear, int dayOfMonth) {
|
public void onDateSet(DatePickerDialog view, int year, int monthOfYear, int dayOfMonth) {
|
||||||
eventTime.setYear(year - 1900);
|
eventTime.setYear(year - 1900);
|
||||||
eventTime.setMonth(monthOfYear);
|
eventTime.setMonth(monthOfYear);
|
||||||
eventTime.setDate(dayOfMonth);
|
eventTime.setDate(dayOfMonth);
|
||||||
dateButton.setText(DateUtil.dateString(eventTime));
|
dateButton.setText(DateUtil.dateString(eventTime));
|
||||||
|
updateBGforDateTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTimeSet(RadialPickerLayout view, int hourOfDay, int minute, int second) {
|
public void onTimeSet(RadialPickerLayout view, int hourOfDay, int minute, int second) {
|
||||||
eventTime.setHours(hourOfDay);
|
eventTime.setHours(hourOfDay);
|
||||||
eventTime.setMinutes(minute);
|
eventTime.setMinutes(minute);
|
||||||
eventTime.setSeconds(second);
|
eventTime.setSeconds(this.seconds++); // randomize seconds to prevent creating record of the same time, if user choose time manually
|
||||||
timeButton.setText(DateUtil.timeString(eventTime));
|
timeButton.setText(DateUtil.timeString(eventTime));
|
||||||
|
updateBGforDateTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -545,224 +603,221 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
|
||||||
|
|
||||||
String buildConfirmText(JSONObject data) {
|
String buildConfirmText(JSONObject data) {
|
||||||
String ret = "";
|
String ret = "";
|
||||||
try {
|
if (data.has("eventType")) {
|
||||||
if (data.has("eventType")) {
|
ret += MainApp.gs(R.string.careportal_newnstreatment_eventtype);
|
||||||
ret += getString(R.string.careportal_newnstreatment_eventtype);
|
ret += ": ";
|
||||||
ret += ": ";
|
ret += Translator.translate(JsonHelper.safeGetString(data, "eventType", ""));
|
||||||
ret += Translator.translate(data.getString("eventType"));
|
ret += "\n";
|
||||||
ret += "\n";
|
}
|
||||||
}
|
if (data.has("glucose")) {
|
||||||
if (data.has("glucose")) {
|
ret += MainApp.gs(R.string.treatments_wizard_bg_label);
|
||||||
ret += getString(R.string.treatments_wizard_bg_label);
|
ret += ": ";
|
||||||
ret += ": ";
|
ret += JsonHelper.safeGetObject(data, "glucose", "");
|
||||||
ret += data.get("glucose");
|
ret += " " + units + "\n";
|
||||||
ret += " " + units + "\n";
|
}
|
||||||
}
|
if (data.has("glucoseType")) {
|
||||||
if (data.has("glucoseType")) {
|
ret += MainApp.gs(R.string.careportal_newnstreatment_glucosetype);
|
||||||
ret += getString(R.string.careportal_newnstreatment_glucosetype);
|
ret += ": ";
|
||||||
ret += ": ";
|
ret += Translator.translate(JsonHelper.safeGetString(data, "glucoseType", ""));
|
||||||
ret += Translator.translate(data.getString("glucoseType"));
|
ret += "\n";
|
||||||
ret += "\n";
|
}
|
||||||
}
|
if (data.has("carbs")) {
|
||||||
if (data.has("carbs")) {
|
ret += MainApp.gs(R.string.careportal_newnstreatment_carbs_label);
|
||||||
ret += getString(R.string.careportal_newnstreatment_carbs_label);
|
ret += ": ";
|
||||||
ret += ": ";
|
ret += JsonHelper.safeGetObject(data, "carbs", "");
|
||||||
ret += data.get("carbs");
|
ret += " g\n";
|
||||||
ret += " g\n";
|
}
|
||||||
}
|
if (data.has("insulin")) {
|
||||||
if (data.has("insulin")) {
|
ret += MainApp.gs(R.string.careportal_newnstreatment_insulin_label);
|
||||||
ret += getString(R.string.careportal_newnstreatment_insulin_label);
|
ret += ": ";
|
||||||
ret += ": ";
|
ret += JsonHelper.safeGetObject(data, "insulin", "");
|
||||||
ret += data.get("insulin");
|
ret += " U\n";
|
||||||
ret += " U\n";
|
}
|
||||||
}
|
if (data.has("duration")) {
|
||||||
if (data.has("duration")) {
|
ret += MainApp.gs(R.string.careportal_newnstreatment_duration_label);
|
||||||
ret += getString(R.string.careportal_newnstreatment_duration_label);
|
ret += ": ";
|
||||||
ret += ": ";
|
ret += JsonHelper.safeGetObject(data, "duration", "");
|
||||||
ret += data.get("duration");
|
ret += " min\n";
|
||||||
ret += " min\n";
|
}
|
||||||
}
|
if (data.has("percent")) {
|
||||||
if (data.has("percent")) {
|
ret += MainApp.gs(R.string.careportal_newnstreatment_percent_label);
|
||||||
ret += getString(R.string.careportal_newnstreatment_percent_label);
|
ret += ": ";
|
||||||
ret += ": ";
|
ret += JsonHelper.safeGetObject(data, "percent", "");
|
||||||
ret += data.get("percent");
|
ret += " %\n";
|
||||||
ret += " %\n";
|
}
|
||||||
}
|
if (data.has("absolute")) {
|
||||||
if (data.has("absolute")) {
|
ret += MainApp.gs(R.string.careportal_newnstreatment_absolute_label);
|
||||||
ret += getString(R.string.careportal_newnstreatment_absolute_label);
|
ret += ": ";
|
||||||
ret += ": ";
|
ret += JsonHelper.safeGetObject(data, "absolute", "");
|
||||||
ret += data.get("absolute");
|
ret += " U/h\n";
|
||||||
ret += " U/h\n";
|
}
|
||||||
}
|
if (data.has("preBolus")) {
|
||||||
if (data.has("preBolus")) {
|
ret += MainApp.gs(R.string.careportal_newnstreatment_carbtime_label);
|
||||||
ret += getString(R.string.careportal_newnstreatment_carbtime_label);
|
ret += ": ";
|
||||||
ret += ": ";
|
ret += JsonHelper.safeGetObject(data, "preBolus", "");
|
||||||
ret += data.get("preBolus");
|
ret += " min\n";
|
||||||
ret += " min\n";
|
}
|
||||||
}
|
if (data.has("notes")) {
|
||||||
if (data.has("notes")) {
|
ret += MainApp.gs(R.string.careportal_newnstreatment_notes_label);
|
||||||
ret += getString(R.string.careportal_newnstreatment_notes_label);
|
ret += ": ";
|
||||||
ret += ": ";
|
ret += JsonHelper.safeGetObject(data, "notes", "");
|
||||||
ret += data.get("notes");
|
ret += "\n";
|
||||||
ret += "\n";
|
}
|
||||||
}
|
if (data.has("profile")) {
|
||||||
if (data.has("profile")) {
|
ret += MainApp.gs(R.string.careportal_newnstreatment_profile_label);
|
||||||
ret += getString(R.string.careportal_newnstreatment_profile_label);
|
ret += ": ";
|
||||||
ret += ": ";
|
ret += JsonHelper.safeGetObject(data, "profile", "");
|
||||||
ret += data.get("profile");
|
ret += "\n";
|
||||||
ret += "\n";
|
}
|
||||||
}
|
if (data.has("percentage")) {
|
||||||
if (data.has("percentage")) {
|
ret += MainApp.gs(R.string.careportal_newnstreatment_percentage_label);
|
||||||
ret += getString(R.string.careportal_newnstreatment_percentage_label);
|
ret += ": ";
|
||||||
ret += ": ";
|
ret += JsonHelper.safeGetObject(data, "percentage", "");
|
||||||
ret += data.get("percentage");
|
ret += " %\n";
|
||||||
ret += " %\n";
|
}
|
||||||
}
|
if (data.has("timeshift")) {
|
||||||
if (data.has("timeshift")) {
|
ret += MainApp.gs(R.string.careportal_newnstreatment_timeshift_label);
|
||||||
ret += getString(R.string.careportal_newnstreatment_timeshift_label);
|
ret += ": ";
|
||||||
ret += ": ";
|
ret += JsonHelper.safeGetObject(data, "timeshift", "");
|
||||||
ret += data.get("timeshift");
|
ret += " h\n";
|
||||||
ret += " h\n";
|
}
|
||||||
}
|
if (data.has("targetBottom") && data.has("targetTop")) {
|
||||||
if (data.has("targetBottom") && data.has("targetTop")) {
|
ret += MainApp.gs(R.string.target_range);
|
||||||
ret += getString(R.string.target_range);
|
ret += " ";
|
||||||
ret += " ";
|
ret += JsonHelper.safeGetObject(data, "targetBottom", "");
|
||||||
ret += data.get("targetBottom");
|
ret += " - ";
|
||||||
ret += " - ";
|
ret += JsonHelper.safeGetObject(data, "targetTop", "");
|
||||||
ret += data.get("targetTop");
|
ret += "\n";
|
||||||
ret += "\n";
|
}
|
||||||
}
|
if (data.has("created_at")) {
|
||||||
if (data.has("created_at")) {
|
ret += MainApp.gs(R.string.careportal_newnstreatment_eventtime_label);
|
||||||
ret += getString(R.string.careportal_newnstreatment_eventtime_label);
|
ret += ": ";
|
||||||
ret += ": ";
|
ret += eventTime.toLocaleString();
|
||||||
ret += eventTime.toLocaleString();
|
ret += "\n";
|
||||||
ret += "\n";
|
}
|
||||||
}
|
if (data.has("enteredBy")) {
|
||||||
if (data.has("enteredBy")) {
|
ret += MainApp.gs(R.string.careportal_newnstreatment_enteredby_title);
|
||||||
ret += getString(R.string.careportal_newnstreatment_enteredby_title);
|
ret += ": ";
|
||||||
ret += ": ";
|
ret += JsonHelper.safeGetObject(data, "enteredBy", "");
|
||||||
ret += data.get("enteredBy");
|
ret += "\n";
|
||||||
ret += "\n";
|
|
||||||
}
|
|
||||||
} catch (JSONException e) {
|
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void createNSTreatment() {
|
void confirmNSTreatmentCreation() {
|
||||||
final JSONObject data = gatherData();
|
if (context != null) {
|
||||||
String confirmText = buildConfirmText(data);
|
final JSONObject data = gatherData();
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
|
final String confirmText = buildConfirmText(data);
|
||||||
builder.setTitle(getContext().getString(R.string.confirmation));
|
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||||
builder.setMessage(confirmText);
|
builder.setTitle(MainApp.gs(R.string.confirmation));
|
||||||
builder.setPositiveButton(getContext().getString(R.string.ok), new DialogInterface.OnClickListener() {
|
builder.setMessage(confirmText);
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
builder.setPositiveButton(MainApp.gs(R.string.ok), (dialog, id) -> createNSTreatment(data));
|
||||||
if (options.executeProfileSwitch) {
|
builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
|
||||||
if (data.has("profile")) {
|
builder.show();
|
||||||
try {
|
}
|
||||||
doProfileSwitch(profileStore, data.getString("profile"), data.getInt("duration"), data.getInt("percentage"), data.getInt("timeshift"));
|
|
||||||
} catch (JSONException e) {
|
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (options.executeTempTarget) {
|
|
||||||
try {
|
|
||||||
if ((data.has("targetBottom") && data.has("targetTop")) || (data.has("duration") && data.getInt("duration") == 0)) {
|
|
||||||
TempTarget tempTarget = new TempTarget();
|
|
||||||
tempTarget.date = eventTime.getTime();
|
|
||||||
tempTarget.durationInMinutes = data.getInt("duration");
|
|
||||||
tempTarget.reason = data.getString("reason");
|
|
||||||
tempTarget.source = Source.USER;
|
|
||||||
if (tempTarget.durationInMinutes != 0) {
|
|
||||||
tempTarget.low = Profile.toMgdl(data.getDouble("targetBottom"), profile.getUnits());
|
|
||||||
tempTarget.high = Profile.toMgdl(data.getDouble("targetTop"), profile.getUnits());
|
|
||||||
} else {
|
|
||||||
tempTarget.low = 0;
|
|
||||||
tempTarget.high = 0;
|
|
||||||
}
|
|
||||||
log.debug("Creating new TempTarget db record: " + tempTarget.toString());
|
|
||||||
MainApp.getDbHelper().createOrUpdate(tempTarget);
|
|
||||||
NSUpload.uploadCareportalEntryToNS(data);
|
|
||||||
Answers.getInstance().logCustom(new CustomEvent("TempTarget"));
|
|
||||||
}
|
|
||||||
} catch (JSONException e) {
|
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
NSUpload.uploadCareportalEntryToNS(data);
|
|
||||||
Answers.getInstance().logCustom(new CustomEvent("NSTreatment"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
builder.setNegativeButton(getContext().getString(R.string.cancel), null);
|
|
||||||
builder.show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void doProfileSwitch(final ProfileStore profileStore, final String profileName, final int duration, final int percentage, final int timeshift) {
|
|
||||||
|
public void createNSTreatment(JSONObject data) {
|
||||||
|
if (options.executeProfileSwitch) {
|
||||||
|
if (data.has("profile")) {
|
||||||
|
doProfileSwitch(profileStore, JsonHelper.safeGetString(data, "profile"), JsonHelper.safeGetInt(data, "duration"), JsonHelper.safeGetInt(data, "percentage"), JsonHelper.safeGetInt(data, "timeshift"));
|
||||||
|
}
|
||||||
|
} else if (options.executeTempTarget) {
|
||||||
|
final int duration = JsonHelper.safeGetInt(data, "duration");
|
||||||
|
final double targetBottom = JsonHelper.safeGetDouble(data, "targetBottom");
|
||||||
|
final double targetTop = JsonHelper.safeGetDouble(data, "targetTop");
|
||||||
|
final String reason = JsonHelper.safeGetString(data, "reason", "");
|
||||||
|
if ((targetBottom != 0d && targetTop != 0d) || duration == 0) {
|
||||||
|
TempTarget tempTarget = new TempTarget()
|
||||||
|
.date(eventTime.getTime())
|
||||||
|
.duration(duration)
|
||||||
|
.reason(reason)
|
||||||
|
.source(Source.USER);
|
||||||
|
if (tempTarget.durationInMinutes != 0) {
|
||||||
|
tempTarget.low(Profile.toMgdl(targetBottom, units))
|
||||||
|
.high(Profile.toMgdl(targetTop, units));
|
||||||
|
} else {
|
||||||
|
tempTarget.low(0).high(0);
|
||||||
|
}
|
||||||
|
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget);
|
||||||
|
FabricPrivacy.getInstance().logCustom(new CustomEvent("TempTarget"));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (JsonHelper.safeGetString(data, "eventType").equals(CareportalEvent.PROFILESWITCH)) {
|
||||||
|
ProfileSwitch profileSwitch = prepareProfileSwitch(
|
||||||
|
profileStore,
|
||||||
|
JsonHelper.safeGetString(data, "profile"),
|
||||||
|
JsonHelper.safeGetInt(data, "duration"),
|
||||||
|
JsonHelper.safeGetInt(data, "percentage"),
|
||||||
|
JsonHelper.safeGetInt(data, "timeshift"),
|
||||||
|
eventTime.getTime()
|
||||||
|
);
|
||||||
|
NSUpload.uploadProfileSwitch(profileSwitch);
|
||||||
|
} else {
|
||||||
|
NSUpload.uploadCareportalEntryToNS(data);
|
||||||
|
}
|
||||||
|
FabricPrivacy.getInstance().logCustom(new CustomEvent("NSTreatment"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ProfileSwitch prepareProfileSwitch(final ProfileStore profileStore, final String profileName, final int duration, final int percentage, final int timeshift, long date) {
|
||||||
ProfileSwitch profileSwitch = new ProfileSwitch();
|
ProfileSwitch profileSwitch = new ProfileSwitch();
|
||||||
profileSwitch.date = System.currentTimeMillis();
|
profileSwitch.date = date;
|
||||||
profileSwitch.source = Source.USER;
|
profileSwitch.source = Source.USER;
|
||||||
profileSwitch.profileName = profileName;
|
profileSwitch.profileName = profileName;
|
||||||
profileSwitch.profileJson = profileStore.getSpecificProfile(profileName).getData().toString();
|
profileSwitch.profileJson = profileStore.getSpecificProfile(profileName).getData().toString();
|
||||||
profileSwitch.profilePlugin = ConfigBuilderPlugin.getActiveProfileInterface().getClass().getName();
|
profileSwitch.profilePlugin = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getClass().getName();
|
||||||
profileSwitch.durationInMinutes = duration;
|
profileSwitch.durationInMinutes = duration;
|
||||||
profileSwitch.isCPP = percentage != 100 || timeshift != 0;
|
profileSwitch.isCPP = percentage != 100 || timeshift != 0;
|
||||||
profileSwitch.timeshift = timeshift;
|
profileSwitch.timeshift = timeshift;
|
||||||
profileSwitch.percentage = percentage;
|
profileSwitch.percentage = percentage;
|
||||||
MainApp.getConfigBuilder().addToHistoryProfileSwitch(profileSwitch);
|
return profileSwitch;
|
||||||
|
}
|
||||||
|
|
||||||
ConfigBuilderPlugin.getCommandQueue().setProfile(profileSwitch.getProfileObject(), new Callback() {
|
public static void doProfileSwitch(final ProfileStore profileStore, final String profileName, final int duration, final int percentage, final int timeshift) {
|
||||||
@Override
|
ProfileSwitch profileSwitch = prepareProfileSwitch(profileStore, profileName, duration, percentage, timeshift, System.currentTimeMillis());
|
||||||
public void run() {
|
TreatmentsPlugin.getPlugin().addToHistoryProfileSwitch(profileSwitch);
|
||||||
if (!result.success) {
|
FabricPrivacy.getInstance().logCustom(new CustomEvent("ProfileSwitch"));
|
||||||
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
|
|
||||||
i.putExtra("soundid", R.raw.boluserror);
|
|
||||||
i.putExtra("status", result.comment);
|
|
||||||
i.putExtra("title", MainApp.sResources.getString(R.string.failedupdatebasalprofile));
|
|
||||||
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
|
||||||
MainApp.instance().startActivity(i);
|
|
||||||
}
|
|
||||||
MainApp.bus().post(new EventNewBasalProfile());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Answers.getInstance().logCustom(new CustomEvent("ProfileSwitch"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void doProfileSwitch(final int duration, final int percentage, final int timeshift) {
|
public static void doProfileSwitch(final int duration, final int percentage, final int timeshift) {
|
||||||
ProfileSwitch profileSwitch = MainApp.getConfigBuilder().getProfileSwitchFromHistory(System.currentTimeMillis());
|
ProfileSwitch profileSwitch = TreatmentsPlugin.getPlugin().getProfileSwitchFromHistory(System.currentTimeMillis());
|
||||||
if (profileSwitch != null) {
|
if (profileSwitch != null) {
|
||||||
profileSwitch = new ProfileSwitch();
|
profileSwitch = new ProfileSwitch();
|
||||||
profileSwitch.date = System.currentTimeMillis();
|
profileSwitch.date = System.currentTimeMillis();
|
||||||
profileSwitch.source = Source.USER;
|
profileSwitch.source = Source.USER;
|
||||||
profileSwitch.profileName = MainApp.getConfigBuilder().getProfileName(System.currentTimeMillis(), false);
|
profileSwitch.profileName = ProfileFunctions.getInstance().getProfileName(System.currentTimeMillis(), false);
|
||||||
profileSwitch.profileJson = MainApp.getConfigBuilder().getProfile().getData().toString();
|
profileSwitch.profileJson = ProfileFunctions.getInstance().getProfile().getData().toString();
|
||||||
profileSwitch.profilePlugin = ConfigBuilderPlugin.getActiveProfileInterface().getClass().getName();
|
profileSwitch.profilePlugin = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getClass().getName();
|
||||||
profileSwitch.durationInMinutes = duration;
|
profileSwitch.durationInMinutes = duration;
|
||||||
profileSwitch.isCPP = percentage != 100 || timeshift != 0;
|
profileSwitch.isCPP = percentage != 100 || timeshift != 0;
|
||||||
profileSwitch.timeshift = timeshift;
|
profileSwitch.timeshift = timeshift;
|
||||||
profileSwitch.percentage = percentage;
|
profileSwitch.percentage = percentage;
|
||||||
MainApp.getConfigBuilder().addToHistoryProfileSwitch(profileSwitch);
|
TreatmentsPlugin.getPlugin().addToHistoryProfileSwitch(profileSwitch);
|
||||||
|
FabricPrivacy.getInstance().logCustom(new CustomEvent("ProfileSwitch"));
|
||||||
ConfigBuilderPlugin.getCommandQueue().setProfile(profileSwitch.getProfileObject(), 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.sResources.getString(R.string.failedupdatebasalprofile));
|
|
||||||
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
|
||||||
MainApp.instance().startActivity(i);
|
|
||||||
}
|
|
||||||
MainApp.bus().post(new EventNewBasalProfile());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Answers.getInstance().logCustom(new CustomEvent("ProfileSwitch"));
|
|
||||||
} else {
|
} else {
|
||||||
log.error("No profile switch existing");
|
log.error("No profile switch existing");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSaveInstanceState(Bundle savedInstanceState) {
|
||||||
|
savedInstanceState.putString("notesEdit", notesEdit.getText().toString());
|
||||||
|
savedInstanceState.putString("dateButton", dateButton.getText().toString());
|
||||||
|
savedInstanceState.putString("timeButton", timeButton.getText().toString());
|
||||||
|
savedInstanceState.putDouble("editBg", editBg.getValue());
|
||||||
|
savedInstanceState.putDouble("editCarbs", editCarbs.getValue());
|
||||||
|
savedInstanceState.putDouble("editInsulin", editInsulin.getValue());
|
||||||
|
savedInstanceState.putDouble("editDuration", editDuration.getValue());
|
||||||
|
savedInstanceState.putDouble("editPercent", editPercent.getValue());
|
||||||
|
savedInstanceState.putDouble("editAbsolute", editAbsolute.getValue());
|
||||||
|
savedInstanceState.putDouble("editCarbTime", editCarbTime.getValue());
|
||||||
|
savedInstanceState.putDouble("editTemptarget", editTemptarget.getValue());
|
||||||
|
savedInstanceState.putDouble("editPercentage", editPercentage.getValue());
|
||||||
|
savedInstanceState.putDouble("editTimeshift", editTimeshift.getValue());
|
||||||
|
super.onSaveInstanceState(savedInstanceState);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ abstract public class SubscriberFragment extends Fragment {
|
||||||
updateGUI();
|
updateGUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void onDestroyView() {
|
@Override public synchronized void onDestroyView() {
|
||||||
super.onDestroyView();
|
super.onDestroyView();
|
||||||
if (unbinder != null)
|
if (unbinder != null)
|
||||||
unbinder.unbind();
|
unbinder.unbind();
|
||||||
|
|
|
@ -1,30 +1,32 @@
|
||||||
package info.nightscout.androidaps.plugins.ConfigBuilder;
|
package info.nightscout.androidaps.plugins.ConfigBuilder;
|
||||||
|
|
||||||
|
|
||||||
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.Fragment;
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.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;
|
||||||
import android.widget.ArrayAdapter;
|
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.CheckBox;
|
import android.widget.CheckBox;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageButton;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.ListAdapter;
|
import android.widget.RadioButton;
|
||||||
import android.widget.ListView;
|
import android.widget.ScrollView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.crashlytics.android.Crashlytics;
|
|
||||||
import com.crashlytics.android.answers.Answers;
|
|
||||||
import com.crashlytics.android.answers.CustomEvent;
|
import com.crashlytics.android.answers.CustomEvent;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import butterknife.BindView;
|
||||||
|
import butterknife.ButterKnife;
|
||||||
|
import butterknife.OnClick;
|
||||||
|
import butterknife.Unbinder;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.PreferencesActivity;
|
import info.nightscout.androidaps.activities.PreferencesActivity;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.events.EventConfigBuilderChange;
|
import info.nightscout.androidaps.events.EventConfigBuilderChange;
|
||||||
import info.nightscout.androidaps.events.EventRefreshGui;
|
import info.nightscout.androidaps.events.EventRefreshGui;
|
||||||
|
@ -33,353 +35,129 @@ import info.nightscout.androidaps.interfaces.BgSourceInterface;
|
||||||
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
|
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
|
||||||
import info.nightscout.androidaps.interfaces.InsulinInterface;
|
import info.nightscout.androidaps.interfaces.InsulinInterface;
|
||||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||||
|
import info.nightscout.androidaps.interfaces.PluginType;
|
||||||
import info.nightscout.androidaps.interfaces.ProfileInterface;
|
import info.nightscout.androidaps.interfaces.ProfileInterface;
|
||||||
import info.nightscout.androidaps.interfaces.PumpInterface;
|
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||||
import info.nightscout.androidaps.interfaces.SensitivityInterface;
|
import info.nightscout.androidaps.interfaces.SensitivityInterface;
|
||||||
import info.nightscout.androidaps.plugins.Insulin.InsulinFastactingPlugin;
|
import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
|
||||||
|
import info.nightscout.androidaps.plugins.Insulin.InsulinOrefRapidActingPlugin;
|
||||||
import info.nightscout.androidaps.plugins.ProfileNS.NSProfilePlugin;
|
import info.nightscout.androidaps.plugins.ProfileNS.NSProfilePlugin;
|
||||||
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
|
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
|
||||||
import info.nightscout.androidaps.plugins.SensitivityOref0.SensitivityOref0Plugin;
|
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityOref0Plugin;
|
||||||
|
import info.nightscout.utils.FabricPrivacy;
|
||||||
import info.nightscout.utils.PasswordProtection;
|
import info.nightscout.utils.PasswordProtection;
|
||||||
|
|
||||||
|
|
||||||
public class ConfigBuilderFragment extends Fragment {
|
public class ConfigBuilderFragment extends SubscriberFragment {
|
||||||
|
|
||||||
static ConfigBuilderPlugin configBuilderPlugin = new ConfigBuilderPlugin();
|
private List<PluginViewHolder> pluginViewHolders = new ArrayList<>();
|
||||||
|
|
||||||
static public ConfigBuilderPlugin getPlugin() {
|
@BindView(R.id.categories)
|
||||||
return configBuilderPlugin;
|
LinearLayout categories;
|
||||||
}
|
|
||||||
|
|
||||||
ListView insulinListView;
|
@BindView(R.id.main_layout)
|
||||||
ListView sensitivityListView;
|
ScrollView mainLayout;
|
||||||
ListView bgsourceListView;
|
@BindView(R.id.unlock)
|
||||||
TextView bgsourceLabel;
|
|
||||||
ListView pumpListView;
|
|
||||||
TextView pumpLabel;
|
|
||||||
ListView loopListView;
|
|
||||||
TextView loopLabel;
|
|
||||||
ListView treatmentsListView;
|
|
||||||
TextView treatmentsLabel;
|
|
||||||
ListView profileListView;
|
|
||||||
TextView profileLabel;
|
|
||||||
ListView apsListView;
|
|
||||||
TextView apsLabel;
|
|
||||||
ListView constraintsListView;
|
|
||||||
TextView constraintsLabel;
|
|
||||||
ListView generalListView;
|
|
||||||
|
|
||||||
LinearLayout mainLayout;
|
|
||||||
Button unlock;
|
Button unlock;
|
||||||
|
|
||||||
PluginCustomAdapter insulinDataAdapter = null;
|
|
||||||
PluginCustomAdapter sensivityDataAdapter = null;
|
|
||||||
PluginCustomAdapter bgsourceDataAdapter = null;
|
|
||||||
PluginCustomAdapter pumpDataAdapter = null;
|
|
||||||
PluginCustomAdapter loopDataAdapter = null;
|
|
||||||
PluginCustomAdapter treatmentDataAdapter = null;
|
|
||||||
PluginCustomAdapter profileDataAdapter = null;
|
|
||||||
PluginCustomAdapter apsDataAdapter = null;
|
|
||||||
PluginCustomAdapter constraintsDataAdapter = null;
|
|
||||||
PluginCustomAdapter generalDataAdapter = null;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
try {
|
try {
|
||||||
View view = inflater.inflate(R.layout.configbuilder_fragment, container, false);
|
View view = inflater.inflate(R.layout.configbuilder_fragment, container, false);
|
||||||
|
unbinder = ButterKnife.bind(this, view);
|
||||||
|
|
||||||
insulinListView = (ListView) view.findViewById(R.id.configbuilder_insulinlistview);
|
if (PasswordProtection.isLocked("settings_password"))
|
||||||
sensitivityListView = (ListView) view.findViewById(R.id.configbuilder_sensitivitylistview);
|
|
||||||
bgsourceListView = (ListView) view.findViewById(R.id.configbuilder_bgsourcelistview);
|
|
||||||
bgsourceLabel = (TextView) view.findViewById(R.id.configbuilder_bgsourcelabel);
|
|
||||||
pumpListView = (ListView) view.findViewById(R.id.configbuilder_pumplistview);
|
|
||||||
pumpLabel = (TextView) view.findViewById(R.id.configbuilder_pumplabel);
|
|
||||||
loopListView = (ListView) view.findViewById(R.id.configbuilder_looplistview);
|
|
||||||
loopLabel = (TextView) view.findViewById(R.id.configbuilder_looplabel);
|
|
||||||
treatmentsListView = (ListView) view.findViewById(R.id.configbuilder_treatmentslistview);
|
|
||||||
treatmentsLabel = (TextView) view.findViewById(R.id.configbuilder_treatmentslabel);
|
|
||||||
profileListView = (ListView) view.findViewById(R.id.configbuilder_profilelistview);
|
|
||||||
profileLabel = (TextView) view.findViewById(R.id.configbuilder_profilelabel);
|
|
||||||
apsListView = (ListView) view.findViewById(R.id.configbuilder_apslistview);
|
|
||||||
apsLabel = (TextView) view.findViewById(R.id.configbuilder_apslabel);
|
|
||||||
constraintsListView = (ListView) view.findViewById(R.id.configbuilder_constraintslistview);
|
|
||||||
constraintsLabel = (TextView) view.findViewById(R.id.configbuilder_constraintslabel);
|
|
||||||
generalListView = (ListView) view.findViewById(R.id.configbuilder_generallistview);
|
|
||||||
|
|
||||||
mainLayout = (LinearLayout) view.findViewById(R.id.configbuilder_mainlayout);
|
|
||||||
unlock = (Button) view.findViewById(R.id.configbuilder_unlock);
|
|
||||||
|
|
||||||
setViews();
|
|
||||||
|
|
||||||
if (PasswordProtection.isLocked("settings_password")) {
|
|
||||||
mainLayout.setVisibility(View.GONE);
|
mainLayout.setVisibility(View.GONE);
|
||||||
unlock.setOnClickListener(new View.OnClickListener() {
|
else unlock.setVisibility(View.GONE);
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
createViews();
|
||||||
PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
mainLayout.setVisibility(View.VISIBLE);
|
|
||||||
unlock.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
}, null);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
unlock.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
return view;
|
return view;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Crashlytics.logException(e);
|
FabricPrivacy.logException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setViews() {
|
@OnClick(R.id.unlock)
|
||||||
insulinDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInListByInterface(InsulinInterface.class, PluginBase.INSULIN), PluginBase.INSULIN);
|
void onClickUnlock() {
|
||||||
insulinListView.setAdapter(insulinDataAdapter);
|
PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", () -> {
|
||||||
setListViewHeightBasedOnChildren(insulinListView);
|
mainLayout.setVisibility(View.VISIBLE);
|
||||||
bgsourceDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInListByInterface(BgSourceInterface.class, PluginBase.BGSOURCE), PluginBase.BGSOURCE);
|
unlock.setVisibility(View.GONE);
|
||||||
bgsourceListView.setAdapter(bgsourceDataAdapter);
|
}, null);
|
||||||
if (MainApp.getSpecificPluginsVisibleInList(PluginBase.BGSOURCE).size() == 0)
|
|
||||||
bgsourceLabel.setVisibility(View.GONE);
|
|
||||||
setListViewHeightBasedOnChildren(bgsourceListView);
|
|
||||||
pumpDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInList(PluginBase.PUMP), PluginBase.PUMP);
|
|
||||||
pumpListView.setAdapter(pumpDataAdapter);
|
|
||||||
if (MainApp.getSpecificPluginsVisibleInList(PluginBase.PUMP).size() == 0)
|
|
||||||
pumpLabel.setVisibility(View.GONE);
|
|
||||||
setListViewHeightBasedOnChildren(pumpListView);
|
|
||||||
loopDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInList(PluginBase.LOOP), PluginBase.LOOP);
|
|
||||||
loopListView.setAdapter(loopDataAdapter);
|
|
||||||
setListViewHeightBasedOnChildren(loopListView);
|
|
||||||
if (MainApp.getSpecificPluginsVisibleInList(PluginBase.LOOP).size() == 0)
|
|
||||||
loopLabel.setVisibility(View.GONE);
|
|
||||||
treatmentDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInList(PluginBase.TREATMENT), PluginBase.TREATMENT);
|
|
||||||
treatmentsListView.setAdapter(treatmentDataAdapter);
|
|
||||||
setListViewHeightBasedOnChildren(treatmentsListView);
|
|
||||||
if (MainApp.getSpecificPluginsVisibleInList(PluginBase.TREATMENT).size() == 0)
|
|
||||||
treatmentsLabel.setVisibility(View.GONE);
|
|
||||||
profileDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInListByInterface(ProfileInterface.class, PluginBase.PROFILE), PluginBase.PROFILE);
|
|
||||||
profileListView.setAdapter(profileDataAdapter);
|
|
||||||
if (MainApp.getSpecificPluginsVisibleInList(PluginBase.PROFILE).size() == 0)
|
|
||||||
profileLabel.setVisibility(View.GONE);
|
|
||||||
setListViewHeightBasedOnChildren(profileListView);
|
|
||||||
apsDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInList(PluginBase.APS), PluginBase.APS);
|
|
||||||
apsListView.setAdapter(apsDataAdapter);
|
|
||||||
setListViewHeightBasedOnChildren(apsListView);
|
|
||||||
if (MainApp.getSpecificPluginsVisibleInList(PluginBase.APS).size() == 0)
|
|
||||||
apsLabel.setVisibility(View.GONE);
|
|
||||||
sensivityDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInListByInterface(SensitivityInterface.class, PluginBase.SENSITIVITY), PluginBase.SENSITIVITY);
|
|
||||||
sensitivityListView.setAdapter(sensivityDataAdapter);
|
|
||||||
setListViewHeightBasedOnChildren(sensitivityListView);
|
|
||||||
constraintsDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInListByInterface(ConstraintsInterface.class, PluginBase.CONSTRAINTS), PluginBase.CONSTRAINTS);
|
|
||||||
constraintsListView.setAdapter(constraintsDataAdapter);
|
|
||||||
setListViewHeightBasedOnChildren(constraintsListView);
|
|
||||||
if (MainApp.getSpecificPluginsVisibleInList(PluginBase.CONSTRAINTS).size() == 0)
|
|
||||||
constraintsLabel.setVisibility(View.GONE);
|
|
||||||
generalDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInList(PluginBase.GENERAL), PluginBase.GENERAL);
|
|
||||||
generalListView.setAdapter(generalDataAdapter);
|
|
||||||
setListViewHeightBasedOnChildren(generalListView);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
@Override
|
||||||
* ConfigBuilderFragment code
|
public void onDestroyView() {
|
||||||
*/
|
super.onDestroyView();
|
||||||
|
for (PluginViewHolder pluginViewHolder : pluginViewHolders) pluginViewHolder.unbind();
|
||||||
private class PluginCustomAdapter extends ArrayAdapter<PluginBase> {
|
pluginViewHolders.clear();
|
||||||
|
|
||||||
private ArrayList<PluginBase> pluginList;
|
|
||||||
final private int type;
|
|
||||||
|
|
||||||
public PluginCustomAdapter(Context context, int textViewResourceId,
|
|
||||||
ArrayList<PluginBase> pluginList, int type) {
|
|
||||||
super(context, textViewResourceId, pluginList);
|
|
||||||
this.pluginList = new ArrayList<>();
|
|
||||||
this.pluginList.addAll(pluginList);
|
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class PluginViewHolder {
|
|
||||||
TextView name;
|
|
||||||
CheckBox checkboxEnabled;
|
|
||||||
CheckBox checkboxVisible;
|
|
||||||
ImageView settings;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View getView(int position, View view, ViewGroup parent) {
|
|
||||||
|
|
||||||
PluginViewHolder holder = null;
|
|
||||||
PluginBase plugin = pluginList.get(position);
|
|
||||||
|
|
||||||
if (view == null) {
|
|
||||||
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.configbuilder_simpleitem, null);
|
|
||||||
|
|
||||||
holder = new PluginViewHolder();
|
|
||||||
holder.name = (TextView) view.findViewById(R.id.configbuilder_simpleitem_name);
|
|
||||||
holder.checkboxEnabled = (CheckBox) view.findViewById(R.id.configbuilder_simpleitem_checkboxenabled);
|
|
||||||
holder.checkboxVisible = (CheckBox) view.findViewById(R.id.configbuilder_simpleitem_checkboxvisible);
|
|
||||||
holder.settings = (ImageView) view.findViewById(R.id.configbuilder_simpleitem_settings);
|
|
||||||
|
|
||||||
if (plugin.isEnabled(type) && plugin.getPreferencesId() != -1)
|
|
||||||
holder.settings.setVisibility(View.VISIBLE);
|
|
||||||
else
|
|
||||||
holder.settings.setVisibility(View.INVISIBLE);
|
|
||||||
|
|
||||||
view.setTag(holder);
|
|
||||||
|
|
||||||
holder.checkboxEnabled.setOnClickListener(new View.OnClickListener() {
|
|
||||||
public void onClick(View v) {
|
|
||||||
CheckBox cb = (CheckBox) v;
|
|
||||||
PluginBase plugin = (PluginBase) cb.getTag();
|
|
||||||
plugin.setFragmentEnabled(type, cb.isChecked());
|
|
||||||
plugin.setFragmentVisible(type, cb.isChecked());
|
|
||||||
onEnabledCategoryChanged(plugin, type);
|
|
||||||
configBuilderPlugin.storeSettings();
|
|
||||||
MainApp.bus().post(new EventRefreshGui());
|
|
||||||
MainApp.bus().post(new EventConfigBuilderChange());
|
|
||||||
getPlugin().logPluginStatus();
|
|
||||||
Answers.getInstance().logCustom(new CustomEvent("ConfigurationChange"));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
holder.checkboxVisible.setOnClickListener(new View.OnClickListener() {
|
|
||||||
public void onClick(View v) {
|
|
||||||
CheckBox cb = (CheckBox) v;
|
|
||||||
PluginBase plugin = (PluginBase) cb.getTag();
|
|
||||||
plugin.setFragmentVisible(type, cb.isChecked());
|
|
||||||
configBuilderPlugin.storeSettings();
|
|
||||||
MainApp.bus().post(new EventRefreshGui());
|
|
||||||
getPlugin().logPluginStatus();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
holder.settings.setOnClickListener(new View.OnClickListener() {
|
|
||||||
public void onClick(View v) {
|
|
||||||
final PluginBase plugin = (PluginBase) v.getTag();
|
|
||||||
PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
Intent i = new Intent(getContext(), PreferencesActivity.class);
|
|
||||||
i.putExtra("id", plugin.getPreferencesId());
|
|
||||||
startActivity(i);
|
|
||||||
}
|
|
||||||
}, null);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
holder.name.setOnLongClickListener(new View.OnLongClickListener() {
|
|
||||||
@Override
|
|
||||||
public boolean onLongClick(View v) {
|
|
||||||
final PluginBase plugin = (PluginBase) v.getTag();
|
|
||||||
PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
Intent i = new Intent(getContext(), PreferencesActivity.class);
|
|
||||||
i.putExtra("id", plugin.getPreferencesId());
|
|
||||||
startActivity(i);
|
|
||||||
}
|
|
||||||
}, null);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
} else {
|
|
||||||
holder = (PluginViewHolder) view.getTag();
|
|
||||||
}
|
|
||||||
|
|
||||||
holder.name.setText(plugin.getName());
|
|
||||||
holder.checkboxEnabled.setChecked(plugin.isEnabled(type));
|
|
||||||
holder.checkboxVisible.setChecked(plugin.isVisibleInTabs(type));
|
|
||||||
holder.name.setTag(plugin);
|
|
||||||
holder.checkboxEnabled.setTag(plugin);
|
|
||||||
holder.checkboxVisible.setTag(plugin);
|
|
||||||
holder.settings.setTag(plugin);
|
|
||||||
|
|
||||||
if (!plugin.canBeHidden(type)) {
|
|
||||||
holder.checkboxEnabled.setEnabled(false);
|
|
||||||
holder.checkboxVisible.setEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!plugin.isEnabled(type)) {
|
|
||||||
holder.checkboxVisible.setEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!plugin.hasFragment()) {
|
|
||||||
holder.checkboxVisible.setVisibility(View.INVISIBLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hide enabled control and force enabled plugin if there is only one plugin available
|
|
||||||
if (type == PluginBase.INSULIN || type == PluginBase.PUMP || type == PluginBase.TREATMENT || type == PluginBase.PROFILE || type == PluginBase.SENSITIVITY)
|
|
||||||
if (pluginList.size() < 2) {
|
|
||||||
holder.checkboxEnabled.setEnabled(false);
|
|
||||||
plugin.setFragmentEnabled(type, true);
|
|
||||||
getPlugin().storeSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Constraints cannot be disabled
|
|
||||||
if (type == PluginBase.CONSTRAINTS)
|
|
||||||
holder.checkboxEnabled.setEnabled(false);
|
|
||||||
|
|
||||||
// Hide disabled profiles by default
|
|
||||||
if (type == PluginBase.PROFILE) {
|
|
||||||
if (!plugin.isEnabled(type)) {
|
|
||||||
holder.checkboxVisible.setEnabled(false);
|
|
||||||
holder.checkboxVisible.setChecked(false);
|
|
||||||
} else {
|
|
||||||
holder.checkboxVisible.setEnabled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disable profile control for pump profiles if pump is not enabled
|
|
||||||
if (type == PluginBase.PROFILE) {
|
|
||||||
if (PumpInterface.class.isAssignableFrom(plugin.getClass())) {
|
|
||||||
if (!plugin.isEnabled(PluginBase.PUMP)) {
|
|
||||||
holder.checkboxEnabled.setEnabled(false);
|
|
||||||
holder.checkboxEnabled.setChecked(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (plugin.isEnabled(type)) {
|
|
||||||
view.setBackgroundColor(MainApp.sResources.getColor(R.color.configBuilderSelectedBackground));
|
|
||||||
}
|
|
||||||
|
|
||||||
return view;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void onEnabledCategoryChanged(PluginBase changedPlugin, int type) {
|
@Override
|
||||||
|
protected void updateGUI() {
|
||||||
|
for (PluginViewHolder pluginViewHolder : pluginViewHolders) pluginViewHolder.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createViews() {
|
||||||
|
createViewsForPlugins(R.string.configbuilder_profile, R.string.configbuilder_profile_description, PluginType.PROFILE, MainApp.getSpecificPluginsVisibleInListByInterface(ProfileInterface.class, PluginType.PROFILE));
|
||||||
|
createViewsForPlugins(R.string.configbuilder_insulin, R.string.configbuilder_insulin_description, PluginType.INSULIN, MainApp.getSpecificPluginsVisibleInListByInterface(InsulinInterface.class, PluginType.INSULIN));
|
||||||
|
createViewsForPlugins(R.string.configbuilder_bgsource, R.string.configbuilder_bgsource_description, PluginType.BGSOURCE, MainApp.getSpecificPluginsVisibleInListByInterface(BgSourceInterface.class, PluginType.BGSOURCE));
|
||||||
|
createViewsForPlugins(R.string.configbuilder_pump, R.string.configbuilder_pump_description, PluginType.PUMP, MainApp.getSpecificPluginsVisibleInList(PluginType.PUMP));
|
||||||
|
createViewsForPlugins(R.string.configbuilder_sensitivity, R.string.configbuilder_sensitivity_description, PluginType.SENSITIVITY, MainApp.getSpecificPluginsVisibleInListByInterface(SensitivityInterface.class, PluginType.SENSITIVITY));
|
||||||
|
createViewsForPlugins(R.string.configbuilder_aps, R.string.configbuilder_aps_description, PluginType.APS, MainApp.getSpecificPluginsVisibleInList(PluginType.APS));
|
||||||
|
createViewsForPlugins(R.string.configbuilder_loop, R.string.configbuilder_loop_description, PluginType.LOOP, MainApp.getSpecificPluginsVisibleInList(PluginType.LOOP));
|
||||||
|
createViewsForPlugins(R.string.constraints, R.string.configbuilder_constraints_description, PluginType.CONSTRAINTS, MainApp.getSpecificPluginsVisibleInListByInterface(ConstraintsInterface.class, PluginType.CONSTRAINTS));
|
||||||
|
createViewsForPlugins(R.string.configbuilder_treatments, R.string.configbuilder_treatments_description, PluginType.TREATMENT, MainApp.getSpecificPluginsVisibleInList(PluginType.TREATMENT));
|
||||||
|
createViewsForPlugins(R.string.configbuilder_general, R.string.configbuilder_general_description, PluginType.GENERAL, MainApp.getSpecificPluginsVisibleInList(PluginType.GENERAL));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createViewsForPlugins(@StringRes int title, @StringRes int description, PluginType pluginType, List<PluginBase> plugins) {
|
||||||
|
if (plugins.size() == 0) return;
|
||||||
|
LinearLayout parent = (LinearLayout) getLayoutInflater().inflate(R.layout.configbuilder_single_category, null);
|
||||||
|
((TextView) parent.findViewById(R.id.category_title)).setText(MainApp.gs(title));
|
||||||
|
((TextView) parent.findViewById(R.id.category_description)).setText(MainApp.gs(description));
|
||||||
|
LinearLayout pluginContainer = parent.findViewById(R.id.category_plugins);
|
||||||
|
for (PluginBase plugin: plugins) {
|
||||||
|
PluginViewHolder pluginViewHolder = new PluginViewHolder(pluginType, plugin);
|
||||||
|
pluginContainer.addView(pluginViewHolder.getBaseView());
|
||||||
|
pluginViewHolders.add(pluginViewHolder);
|
||||||
|
}
|
||||||
|
categories.addView(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean areMultipleSelectionsAllowed(PluginType type) {
|
||||||
|
return type == PluginType.GENERAL || type == PluginType.CONSTRAINTS ||type == PluginType.LOOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void processOnEnabledCategoryChanged(PluginBase changedPlugin, PluginType type) {
|
||||||
ArrayList<PluginBase> pluginsInCategory = null;
|
ArrayList<PluginBase> pluginsInCategory = null;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
// Multiple selection allowed
|
// Multiple selection allowed
|
||||||
case PluginBase.GENERAL:
|
case GENERAL:
|
||||||
case PluginBase.CONSTRAINTS:
|
case CONSTRAINTS:
|
||||||
case PluginBase.LOOP:
|
case LOOP:
|
||||||
break;
|
break;
|
||||||
// Single selection allowed
|
// Single selection allowed
|
||||||
case PluginBase.INSULIN:
|
case INSULIN:
|
||||||
pluginsInCategory = MainApp.getSpecificPluginsListByInterface(InsulinInterface.class);
|
pluginsInCategory = MainApp.getSpecificPluginsListByInterface(InsulinInterface.class);
|
||||||
break;
|
break;
|
||||||
case PluginBase.SENSITIVITY:
|
case SENSITIVITY:
|
||||||
pluginsInCategory = MainApp.getSpecificPluginsListByInterface(SensitivityInterface.class);
|
pluginsInCategory = MainApp.getSpecificPluginsListByInterface(SensitivityInterface.class);
|
||||||
break;
|
break;
|
||||||
case PluginBase.APS:
|
case APS:
|
||||||
pluginsInCategory = MainApp.getSpecificPluginsListByInterface(APSInterface.class);
|
pluginsInCategory = MainApp.getSpecificPluginsListByInterface(APSInterface.class);
|
||||||
break;
|
break;
|
||||||
case PluginBase.PROFILE:
|
case PROFILE:
|
||||||
pluginsInCategory = MainApp.getSpecificPluginsListByInterface(ProfileInterface.class);
|
pluginsInCategory = MainApp.getSpecificPluginsListByInterface(ProfileInterface.class);
|
||||||
break;
|
break;
|
||||||
case PluginBase.BGSOURCE:
|
case BGSOURCE:
|
||||||
pluginsInCategory = MainApp.getSpecificPluginsListByInterface(BgSourceInterface.class);
|
pluginsInCategory = MainApp.getSpecificPluginsListByInterface(BgSourceInterface.class);
|
||||||
break;
|
break;
|
||||||
case PluginBase.TREATMENT:
|
case TREATMENT:
|
||||||
case PluginBase.PUMP:
|
case PUMP:
|
||||||
pluginsInCategory = MainApp.getSpecificPluginsListByInterface(PumpInterface.class);
|
pluginsInCategory = MainApp.getSpecificPluginsListByInterface(PumpInterface.class);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -390,50 +168,119 @@ public class ConfigBuilderFragment extends Fragment {
|
||||||
if (p.getName().equals(changedPlugin.getName())) {
|
if (p.getName().equals(changedPlugin.getName())) {
|
||||||
// this is new selected
|
// this is new selected
|
||||||
} else {
|
} else {
|
||||||
p.setFragmentEnabled(type, false);
|
p.setPluginEnabled(type, false);
|
||||||
p.setFragmentVisible(type, false);
|
p.setFragmentVisible(type, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { // enable first plugin in list
|
} else { // enable first plugin in list
|
||||||
if (type == PluginBase.PUMP)
|
if (type == PluginType.PUMP)
|
||||||
MainApp.getSpecificPlugin(VirtualPumpPlugin.class).setFragmentEnabled(type, true);
|
VirtualPumpPlugin.getPlugin().setPluginEnabled(type, true);
|
||||||
else if (type == PluginBase.INSULIN)
|
else if (type == PluginType.INSULIN)
|
||||||
MainApp.getSpecificPlugin(InsulinFastactingPlugin.class).setFragmentEnabled(type, true);
|
InsulinOrefRapidActingPlugin.getPlugin().setPluginEnabled(type, true);
|
||||||
else if (type == PluginBase.SENSITIVITY)
|
else if (type == PluginType.SENSITIVITY)
|
||||||
MainApp.getSpecificPlugin(SensitivityOref0Plugin.class).setFragmentEnabled(type, true);
|
SensitivityOref0Plugin.getPlugin().setPluginEnabled(type, true);
|
||||||
else if (type == PluginBase.PROFILE)
|
else if (type == PluginType.PROFILE)
|
||||||
MainApp.getSpecificPlugin(NSProfilePlugin.class).setFragmentEnabled(type, true);
|
NSProfilePlugin.getPlugin().setPluginEnabled(type, true);
|
||||||
else
|
else
|
||||||
pluginsInCategory.get(0).setFragmentEnabled(type, true);
|
pluginsInCategory.get(0).setPluginEnabled(type, true);
|
||||||
}
|
}
|
||||||
setViews();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/****
|
public class PluginViewHolder {
|
||||||
* Method for Setting the Height of the ListView dynamically.
|
|
||||||
* *** Hack to fix the issue of not showing all the items of the ListView
|
|
||||||
* *** when placed inside a ScrollView
|
|
||||||
****/
|
|
||||||
public static void setListViewHeightBasedOnChildren(ListView listView) {
|
|
||||||
ListAdapter listAdapter = listView.getAdapter();
|
|
||||||
if (listAdapter == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
int desiredWidth = View.MeasureSpec.makeMeasureSpec(listView.getWidth(), View.MeasureSpec.UNSPECIFIED);
|
private Unbinder unbinder;
|
||||||
int totalHeight = 0;
|
private PluginType pluginType;
|
||||||
View view = null;
|
private PluginBase plugin;
|
||||||
for (int i = 0; i < listAdapter.getCount(); i++) {
|
|
||||||
view = listAdapter.getView(i, view, listView);
|
|
||||||
if (i == 0)
|
|
||||||
view.setLayoutParams(new ViewGroup.LayoutParams(desiredWidth, ViewGroup.LayoutParams.WRAP_CONTENT));
|
|
||||||
|
|
||||||
view.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
|
LinearLayout baseView;
|
||||||
totalHeight += view.getMeasuredHeight();
|
@BindView(R.id.plugin_enabled_exclusive)
|
||||||
|
RadioButton enabledExclusive;
|
||||||
|
@BindView(R.id.plugin_enabled_inclusive)
|
||||||
|
CheckBox enabledInclusive;
|
||||||
|
@BindView(R.id.plugin_name)
|
||||||
|
TextView pluginName;
|
||||||
|
@BindView(R.id.plugin_description)
|
||||||
|
TextView pluginDescription;
|
||||||
|
@BindView(R.id.plugin_preferences)
|
||||||
|
ImageButton pluginPreferences;
|
||||||
|
@BindView(R.id.plugin_visibility)
|
||||||
|
CheckBox pluginVisibility;
|
||||||
|
|
||||||
|
public PluginViewHolder(PluginType pluginType, PluginBase plugin) {
|
||||||
|
this.pluginType = pluginType;
|
||||||
|
this.plugin = plugin;
|
||||||
|
baseView = (LinearLayout) getLayoutInflater().inflate(R.layout.configbuilder_single_plugin, null);
|
||||||
|
unbinder = ButterKnife.bind(this, baseView);
|
||||||
|
update();
|
||||||
}
|
}
|
||||||
ViewGroup.LayoutParams params = listView.getLayoutParams();
|
|
||||||
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
|
|
||||||
listView.setLayoutParams(params);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public LinearLayout getBaseView() {
|
||||||
|
return baseView;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update() {
|
||||||
|
enabledExclusive.setVisibility(areMultipleSelectionsAllowed(pluginType) ? View.GONE : View.VISIBLE);
|
||||||
|
enabledInclusive.setVisibility(areMultipleSelectionsAllowed(pluginType) ? View.VISIBLE : View.GONE);
|
||||||
|
enabledExclusive.setChecked(plugin.isEnabled(pluginType));
|
||||||
|
enabledInclusive.setChecked(plugin.isEnabled(pluginType));
|
||||||
|
enabledInclusive.setEnabled(!plugin.pluginDescription.alwaysEnabled);
|
||||||
|
enabledExclusive.setEnabled(!plugin.pluginDescription.alwaysEnabled);
|
||||||
|
pluginName.setText(plugin.getName());
|
||||||
|
if (plugin.getDescription() == null) pluginDescription.setVisibility(View.GONE);
|
||||||
|
else {
|
||||||
|
pluginDescription.setVisibility(View.VISIBLE);
|
||||||
|
pluginDescription.setText(plugin.getDescription());
|
||||||
|
}
|
||||||
|
pluginPreferences.setVisibility(plugin.getPreferencesId() == -1 || !plugin.isEnabled(pluginType) ? View.INVISIBLE : View.VISIBLE);
|
||||||
|
pluginVisibility.setVisibility(plugin.hasFragment() ? View.VISIBLE : View.INVISIBLE);
|
||||||
|
pluginVisibility.setEnabled(!(plugin.pluginDescription.neverVisible || plugin.pluginDescription.alwayVisible) && plugin.isEnabled(pluginType));
|
||||||
|
pluginVisibility.setChecked(plugin.isFragmentVisible());
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnClick(R.id.plugin_visibility)
|
||||||
|
void onVisibilityChanged() {
|
||||||
|
plugin.setFragmentVisible(pluginType, pluginVisibility.isChecked());
|
||||||
|
ConfigBuilderPlugin.getPlugin().storeSettings("CheckedCheckboxVisible");
|
||||||
|
MainApp.bus().post(new EventRefreshGui());
|
||||||
|
ConfigBuilderPlugin.getPlugin().logPluginStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnClick({R.id.plugin_enabled_exclusive, R.id.plugin_enabled_inclusive})
|
||||||
|
void onEnabledChanged() {
|
||||||
|
plugin.switchAllowed(new PluginSwitcher(), getActivity());
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnClick(R.id.plugin_preferences)
|
||||||
|
void onPluginPreferencesClicked() {
|
||||||
|
PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", () -> {
|
||||||
|
Intent i = new Intent(getContext(), PreferencesActivity.class);
|
||||||
|
i.putExtra("id", plugin.getPreferencesId());
|
||||||
|
startActivity(i);
|
||||||
|
}, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unbind() {
|
||||||
|
unbinder.unbind();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PluginSwitcher {
|
||||||
|
public void invoke() {
|
||||||
|
boolean enabled = enabledExclusive.getVisibility() == View.VISIBLE ? enabledExclusive.isChecked() : enabledInclusive.isChecked();
|
||||||
|
plugin.setPluginEnabled(pluginType, enabled);
|
||||||
|
plugin.setFragmentVisible(pluginType, enabled);
|
||||||
|
processOnEnabledCategoryChanged(plugin, pluginType);
|
||||||
|
updateGUI();
|
||||||
|
ConfigBuilderPlugin.getPlugin().storeSettings("CheckedCheckboxEnabled");
|
||||||
|
MainApp.bus().post(new EventRefreshGui());
|
||||||
|
MainApp.bus().post(new EventConfigBuilderChange());
|
||||||
|
ConfigBuilderPlugin.getPlugin().logPluginStatus();
|
||||||
|
FabricPrivacy.getInstance().logCustom(new CustomEvent("ConfigurationChange"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cancel(){
|
||||||
|
updateGUI();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -6,46 +6,39 @@ import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import info.nightscout.androidaps.data.DetailedBolusInfo;
|
import info.nightscout.androidaps.data.DetailedBolusInfo;
|
||||||
|
import info.nightscout.androidaps.logging.L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by mike on 08.08.2017.
|
* Created by mike on 08.08.2017.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class DetailedBolusInfoStorage {
|
public class DetailedBolusInfoStorage {
|
||||||
private static Logger log = LoggerFactory.getLogger(DetailedBolusInfoStorage.class);
|
private static Logger log = LoggerFactory.getLogger(L.PUMP);
|
||||||
private static List<DetailedBolusInfo> store = new ArrayList<>();
|
private static List<DetailedBolusInfo> store = new ArrayList<>();
|
||||||
|
|
||||||
public static void add(DetailedBolusInfo detailedBolusInfo) {
|
public static synchronized void add(DetailedBolusInfo detailedBolusInfo) {
|
||||||
log.debug("Stored bolus info: " + detailedBolusInfo);
|
log.debug("Stored bolus info: " + detailedBolusInfo);
|
||||||
store.add(detailedBolusInfo);
|
store.add(detailedBolusInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static DetailedBolusInfo findDetailedBolusInfo(long bolustime) {
|
public static synchronized DetailedBolusInfo findDetailedBolusInfo(long bolustime) {
|
||||||
DetailedBolusInfo found = null;
|
DetailedBolusInfo found = null;
|
||||||
for (int i = 0; i < store.size(); i++) {
|
for (int i = 0; i < store.size(); i++) {
|
||||||
long infoTime = store.get(i).date;
|
long infoTime = store.get(i).date;
|
||||||
log.debug("Existing bolus info: " + store.get(i));
|
if (L.isEnabled(L.PUMP))
|
||||||
|
log.debug("Existing bolus info: " + store.get(i));
|
||||||
if (bolustime > infoTime - 60 * 1000 && bolustime < infoTime + 60 * 1000) {
|
if (bolustime > infoTime - 60 * 1000 && bolustime < infoTime + 60 * 1000) {
|
||||||
found = store.get(i);
|
found = store.get(i);
|
||||||
|
if (L.isEnabled(L.PUMP))
|
||||||
|
log.debug("Using & removing bolus info: " + store.get(i));
|
||||||
|
store.remove(i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void remove(long bolustime) {
|
|
||||||
for (int i = 0; i < store.size(); i++) {
|
|
||||||
long infoTime = store.get(i).date;
|
|
||||||
if (bolustime > infoTime - 60 * 1000 && bolustime < infoTime + 60 * 1000) {
|
|
||||||
log.debug("Removing bolus info: " + store.get(i));
|
|
||||||
store.remove(i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,142 @@
|
||||||
|
package info.nightscout.androidaps.plugins.ConfigBuilder;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.crashlytics.android.answers.CustomEvent;
|
||||||
|
import com.squareup.otto.Subscribe;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.BuildConfig;
|
||||||
|
import info.nightscout.androidaps.Constants;
|
||||||
|
import info.nightscout.androidaps.MainApp;
|
||||||
|
import info.nightscout.androidaps.R;
|
||||||
|
import info.nightscout.androidaps.data.Profile;
|
||||||
|
import info.nightscout.androidaps.data.ProfileStore;
|
||||||
|
import info.nightscout.androidaps.db.ProfileSwitch;
|
||||||
|
import info.nightscout.androidaps.events.EventNewBasalProfile;
|
||||||
|
import info.nightscout.androidaps.events.EventProfileSwitchChange;
|
||||||
|
import info.nightscout.androidaps.interfaces.ProfileInterface;
|
||||||
|
import info.nightscout.androidaps.interfaces.TreatmentsInterface;
|
||||||
|
import info.nightscout.androidaps.logging.L;
|
||||||
|
import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity;
|
||||||
|
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||||
|
import info.nightscout.androidaps.queue.Callback;
|
||||||
|
import info.nightscout.utils.FabricPrivacy;
|
||||||
|
|
||||||
|
public class ProfileFunctions {
|
||||||
|
private static Logger log = LoggerFactory.getLogger(L.PROFILE);
|
||||||
|
|
||||||
|
private static ProfileFunctions profileFunctions = null;
|
||||||
|
|
||||||
|
public static ProfileFunctions getInstance() {
|
||||||
|
if (profileFunctions == null)
|
||||||
|
profileFunctions = new ProfileFunctions();
|
||||||
|
return profileFunctions;
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
ProfileFunctions.getInstance(); // register to bus at start
|
||||||
|
}
|
||||||
|
|
||||||
|
ProfileFunctions() {
|
||||||
|
MainApp.bus().register(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onProfileSwitch(EventProfileSwitchChange ignored) {
|
||||||
|
if (L.isEnabled(L.PROFILE))
|
||||||
|
log.debug("onProfileSwitch");
|
||||||
|
ConfigBuilderPlugin.getPlugin().getCommandQueue().setProfile(getProfile(), 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.failedupdatebasalprofile));
|
||||||
|
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
|
MainApp.instance().startActivity(i);
|
||||||
|
}
|
||||||
|
MainApp.bus().post(new EventNewBasalProfile());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProfileName() {
|
||||||
|
return getProfileName(System.currentTimeMillis());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProfileName(boolean customized) {
|
||||||
|
return getProfileName(System.currentTimeMillis(), customized);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProfileName(long time) {
|
||||||
|
return getProfileName(time, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProfileName(long time, boolean customized) {
|
||||||
|
TreatmentsInterface activeTreatments = TreatmentsPlugin.getPlugin();
|
||||||
|
ProfileInterface activeProfile = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface();
|
||||||
|
|
||||||
|
ProfileSwitch profileSwitch = activeTreatments.getProfileSwitchFromHistory(time);
|
||||||
|
if (profileSwitch != null) {
|
||||||
|
if (profileSwitch.profileJson != null) {
|
||||||
|
return customized ? profileSwitch.getCustomizedName() : profileSwitch.profileName;
|
||||||
|
} else {
|
||||||
|
ProfileStore profileStore = activeProfile.getProfile();
|
||||||
|
if (profileStore != null) {
|
||||||
|
Profile profile = profileStore.getSpecificProfile(profileSwitch.profileName);
|
||||||
|
if (profile != null)
|
||||||
|
return profileSwitch.profileName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return MainApp.gs(R.string.noprofileselected);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isProfileValid(String from) {
|
||||||
|
return getProfile() != null && getProfile().isValid(from);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public Profile getProfile() {
|
||||||
|
return getProfile(System.currentTimeMillis());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProfileUnits() {
|
||||||
|
Profile profile = getProfile();
|
||||||
|
return profile != null ? profile.getUnits() : Constants.MGDL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public Profile getProfile(long time) {
|
||||||
|
TreatmentsInterface activeTreatments = TreatmentsPlugin.getPlugin();
|
||||||
|
ProfileInterface activeProfile = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface();
|
||||||
|
|
||||||
|
//log.debug("Profile for: " + new Date(time).toLocaleString() + " : " + getProfileName(time));
|
||||||
|
ProfileSwitch profileSwitch = activeTreatments.getProfileSwitchFromHistory(time);
|
||||||
|
if (profileSwitch != null) {
|
||||||
|
if (profileSwitch.profileJson != null) {
|
||||||
|
return profileSwitch.getProfileObject();
|
||||||
|
} else if (activeProfile.getProfile() != null) {
|
||||||
|
Profile profile = activeProfile.getProfile().getSpecificProfile(profileSwitch.profileName);
|
||||||
|
if (profile != null)
|
||||||
|
return profile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (activeTreatments.getProfileSwitchesFromHistory().size() > 0) {
|
||||||
|
FabricPrivacy.getInstance().logCustom(new CustomEvent("CatchedError")
|
||||||
|
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
|
||||||
|
.putCustomAttribute("version", BuildConfig.VERSION)
|
||||||
|
.putCustomAttribute("time", time)
|
||||||
|
.putCustomAttribute("getProfileSwitchesFromHistory", activeTreatments.getProfileSwitchesFromHistory().toString())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
log.error("getProfile at the end: returning null");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,12 +1,15 @@
|
||||||
package info.nightscout.androidaps.plugins.ConstraintsObjectives;
|
package info.nightscout.androidaps.plugins.ConstraintsObjectives;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.app.Fragment;
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
import android.support.v7.widget.CardView;
|
import android.support.v7.widget.CardView;
|
||||||
import android.support.v7.widget.LinearLayoutManager;
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
|
import android.support.v7.widget.LinearSmoothScroller;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
|
import android.text.Html;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
@ -15,153 +18,28 @@ import android.widget.CheckBox;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.crashlytics.android.Crashlytics;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
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.Common.SubscriberFragment;
|
||||||
|
import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective;
|
||||||
|
import info.nightscout.utils.FabricPrivacy;
|
||||||
|
|
||||||
public class ObjectivesFragment extends Fragment {
|
public class ObjectivesFragment extends SubscriberFragment {
|
||||||
private static Logger log = LoggerFactory.getLogger(ObjectivesFragment.class);
|
|
||||||
|
|
||||||
RecyclerView recyclerView;
|
RecyclerView recyclerView;
|
||||||
LinearLayoutManager llm;
|
|
||||||
CheckBox enableFake;
|
CheckBox enableFake;
|
||||||
LinearLayout fake_layout;
|
|
||||||
TextView reset;
|
TextView reset;
|
||||||
|
ObjectivesAdapter objectivesAdapter = new ObjectivesAdapter();
|
||||||
|
Handler handler = new Handler(Looper.getMainLooper());
|
||||||
|
|
||||||
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ObjectiveViewHolder> {
|
private Runnable objectiveUpdater = new Runnable() {
|
||||||
|
|
||||||
List<ObjectivesPlugin.Objective> objectives;
|
|
||||||
|
|
||||||
RecyclerViewAdapter(List<ObjectivesPlugin.Objective> objectives) {
|
|
||||||
this.objectives = objectives;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ObjectiveViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
|
public void run() {
|
||||||
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.objectives_item, viewGroup, false);
|
handler.postDelayed(this, 60 * 1000);
|
||||||
return new ObjectiveViewHolder(v);
|
updateGUI();
|
||||||
}
|
}
|
||||||
|
};
|
||||||
@Override
|
|
||||||
public void onBindViewHolder(ObjectiveViewHolder holder, int position) {
|
|
||||||
ObjectivesPlugin.Objective o = objectives.get(position);
|
|
||||||
ObjectivesPlugin.RequirementResult requirementsMet = ObjectivesPlugin.getPlugin().requirementsMet(position);
|
|
||||||
Context context = MainApp.instance().getApplicationContext();
|
|
||||||
holder.position.setText(String.valueOf(position + 1));
|
|
||||||
holder.objective.setText(o.objective);
|
|
||||||
holder.gate.setText(o.gate);
|
|
||||||
holder.duration.setText(context.getString(R.string.objectives_minimalduration) + " " + o.durationInDays + " " + context.getString(R.string.days));
|
|
||||||
holder.progress.setText(requirementsMet.comment);
|
|
||||||
holder.started.setText(o.started.toLocaleString());
|
|
||||||
holder.accomplished.setText(o.accomplished.toLocaleString());
|
|
||||||
|
|
||||||
holder.startButton.setTag(o);
|
|
||||||
holder.verifyButton.setTag(o);
|
|
||||||
|
|
||||||
holder.startButton.setOnClickListener(new View.OnClickListener() {
|
|
||||||
public void onClick(View v) {
|
|
||||||
ObjectivesPlugin.Objective o = (ObjectivesPlugin.Objective) v.getTag();
|
|
||||||
o.started = new Date();
|
|
||||||
updateGUI();
|
|
||||||
ObjectivesPlugin.saveProgress();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
holder.verifyButton.setOnClickListener(new View.OnClickListener() {
|
|
||||||
public void onClick(View v) {
|
|
||||||
ObjectivesPlugin.Objective o = (ObjectivesPlugin.Objective) v.getTag();
|
|
||||||
if (ObjectivesPlugin.getPlugin().requirementsMet(o.num).done || enableFake.isChecked()) {
|
|
||||||
o.accomplished = new Date();
|
|
||||||
updateGUI();
|
|
||||||
ObjectivesPlugin.saveProgress();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Long now = System.currentTimeMillis();
|
|
||||||
if (position > 0 && objectives.get(position - 1).accomplished.getTime() == 0) {
|
|
||||||
// Phase 0: previous not completed
|
|
||||||
holder.startedLayout.setVisibility(View.GONE);
|
|
||||||
holder.durationLayout.setVisibility(View.GONE);
|
|
||||||
holder.progressLayout.setVisibility(View.GONE);
|
|
||||||
holder.verifyLayout.setVisibility(View.GONE);
|
|
||||||
} else if (o.started.getTime() == 0) {
|
|
||||||
// Phase 1: not started
|
|
||||||
holder.durationLayout.setVisibility(View.GONE);
|
|
||||||
holder.progressLayout.setVisibility(View.GONE);
|
|
||||||
holder.verifyLayout.setVisibility(View.GONE);
|
|
||||||
holder.started.setVisibility(View.GONE);
|
|
||||||
} else if (o.started.getTime() > 0 && !enableFake.isChecked() && o.accomplished.getTime() == 0 && !(o.started.getTime() + o.durationInDays * 24 * 60 * 60 * 1000 < now && requirementsMet.done)) {
|
|
||||||
// Phase 2: started, waiting for duration and met requirements
|
|
||||||
holder.startButton.setEnabled(false);
|
|
||||||
holder.verifyLayout.setVisibility(View.GONE);
|
|
||||||
} else if (o.accomplished.getTime() == 0) {
|
|
||||||
// Phase 3: started, after duration, requirements met
|
|
||||||
holder.startButton.setEnabled(false);
|
|
||||||
holder.accomplished.setVisibility(View.INVISIBLE);
|
|
||||||
} else {
|
|
||||||
// Phase 4: verified
|
|
||||||
holder.gateLayout.setVisibility(View.GONE);
|
|
||||||
holder.startedLayout.setVisibility(View.GONE);
|
|
||||||
holder.durationLayout.setVisibility(View.GONE);
|
|
||||||
holder.progressLayout.setVisibility(View.GONE);
|
|
||||||
holder.verifyButton.setVisibility(View.INVISIBLE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getItemCount() {
|
|
||||||
return objectives.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
|
|
||||||
super.onAttachedToRecyclerView(recyclerView);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ObjectiveViewHolder extends RecyclerView.ViewHolder {
|
|
||||||
CardView cv;
|
|
||||||
TextView position;
|
|
||||||
TextView objective;
|
|
||||||
LinearLayout gateLayout;
|
|
||||||
TextView gate;
|
|
||||||
TextView duration;
|
|
||||||
LinearLayout durationLayout;
|
|
||||||
TextView progress;
|
|
||||||
LinearLayout progressLayout;
|
|
||||||
TextView started;
|
|
||||||
Button startButton;
|
|
||||||
LinearLayout startedLayout;
|
|
||||||
TextView accomplished;
|
|
||||||
Button verifyButton;
|
|
||||||
LinearLayout verifyLayout;
|
|
||||||
|
|
||||||
ObjectiveViewHolder(View itemView) {
|
|
||||||
super(itemView);
|
|
||||||
cv = (CardView) itemView.findViewById(R.id.objectives_cardview);
|
|
||||||
position = (TextView) itemView.findViewById(R.id.objectives_position);
|
|
||||||
objective = (TextView) itemView.findViewById(R.id.objectives_objective);
|
|
||||||
durationLayout = (LinearLayout) itemView.findViewById(R.id.objectives_duration_linearlayout);
|
|
||||||
duration = (TextView) itemView.findViewById(R.id.objectives_duration);
|
|
||||||
progressLayout = (LinearLayout) itemView.findViewById(R.id.objectives_progresslayout);
|
|
||||||
progress = (TextView) itemView.findViewById(R.id.objectives_progress);
|
|
||||||
gateLayout = (LinearLayout) itemView.findViewById(R.id.objectives_gate_linearlayout);
|
|
||||||
gate = (TextView) itemView.findViewById(R.id.objectives_gate);
|
|
||||||
startedLayout = (LinearLayout) itemView.findViewById(R.id.objectives_start_linearlayout);
|
|
||||||
started = (TextView) itemView.findViewById(R.id.objectives_started);
|
|
||||||
startButton = (Button) itemView.findViewById(R.id.objectives_start);
|
|
||||||
verifyLayout = (LinearLayout) itemView.findViewById(R.id.objectives_verify_linearlayout);
|
|
||||||
accomplished = (TextView) itemView.findViewById(R.id.objectives_accomplished);
|
|
||||||
verifyButton = (Button) itemView.findViewById(R.id.objectives_verify);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
|
@ -169,60 +47,164 @@ public class ObjectivesFragment extends Fragment {
|
||||||
try {
|
try {
|
||||||
View view = inflater.inflate(R.layout.objectives_fragment, container, false);
|
View view = inflater.inflate(R.layout.objectives_fragment, container, false);
|
||||||
|
|
||||||
recyclerView = (RecyclerView) view.findViewById(R.id.objectives_recyclerview);
|
recyclerView = view.findViewById(R.id.objectives_recyclerview);
|
||||||
recyclerView.setHasFixedSize(true);
|
recyclerView.setLayoutManager(new LinearLayoutManager(view.getContext()));
|
||||||
llm = new LinearLayoutManager(view.getContext());
|
recyclerView.setAdapter(objectivesAdapter);
|
||||||
recyclerView.setLayoutManager(llm);
|
enableFake = view.findViewById(R.id.objectives_fake);
|
||||||
enableFake = (CheckBox) view.findViewById(R.id.objectives_fake);
|
reset = view.findViewById(R.id.objectives_reset);
|
||||||
fake_layout = (LinearLayout) view.findViewById(R.id.objectives_fake_layout);
|
enableFake.setOnClickListener(v -> updateGUI());
|
||||||
reset = (TextView) view.findViewById(R.id.objectives_reset);
|
reset.setOnClickListener(v -> {
|
||||||
enableFake.setOnClickListener(new View.OnClickListener() {
|
ObjectivesPlugin.getPlugin().reset();
|
||||||
public void onClick(View v) {
|
ObjectivesPlugin.getPlugin().saveProgress();
|
||||||
updateGUI();
|
recyclerView.getAdapter().notifyDataSetChanged();
|
||||||
}
|
scrollToCurrentObjective();
|
||||||
});
|
});
|
||||||
reset.setOnClickListener(new View.OnClickListener() {
|
scrollToCurrentObjective();
|
||||||
public void onClick(View v) {
|
startUpdateTimer();
|
||||||
ObjectivesPlugin.getPlugin().initializeData();
|
|
||||||
ObjectivesPlugin.saveProgress();
|
|
||||||
updateGUI();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add correct translations to array after app is initialized
|
|
||||||
ObjectivesPlugin.objectives.get(0).objective = MainApp.sResources.getString(R.string.objectives_0_objective);
|
|
||||||
ObjectivesPlugin.objectives.get(1).objective = MainApp.sResources.getString(R.string.objectives_1_objective);
|
|
||||||
ObjectivesPlugin.objectives.get(2).objective = MainApp.sResources.getString(R.string.objectives_2_objective);
|
|
||||||
ObjectivesPlugin.objectives.get(3).objective = MainApp.sResources.getString(R.string.objectives_3_objective);
|
|
||||||
ObjectivesPlugin.objectives.get(4).objective = MainApp.sResources.getString(R.string.objectives_4_objective);
|
|
||||||
ObjectivesPlugin.objectives.get(5).objective = MainApp.sResources.getString(R.string.objectives_5_objective);
|
|
||||||
ObjectivesPlugin.objectives.get(6).objective = MainApp.sResources.getString(R.string.objectives_6_objective);
|
|
||||||
ObjectivesPlugin.objectives.get(7).objective = MainApp.sResources.getString(R.string.objectives_7_objective);
|
|
||||||
ObjectivesPlugin.objectives.get(0).gate = MainApp.sResources.getString(R.string.objectives_0_gate);
|
|
||||||
ObjectivesPlugin.objectives.get(1).gate = MainApp.sResources.getString(R.string.objectives_1_gate);
|
|
||||||
ObjectivesPlugin.objectives.get(2).gate = MainApp.sResources.getString(R.string.objectives_2_gate);
|
|
||||||
ObjectivesPlugin.objectives.get(3).gate = MainApp.sResources.getString(R.string.objectives_3_gate);
|
|
||||||
ObjectivesPlugin.objectives.get(4).gate = MainApp.sResources.getString(R.string.objectives_4_gate);
|
|
||||||
ObjectivesPlugin.objectives.get(5).gate = MainApp.sResources.getString(R.string.objectives_5_gate);
|
|
||||||
updateGUI();
|
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Crashlytics.logException(e);
|
FabricPrivacy.logException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateGUI() {
|
@Override
|
||||||
|
public synchronized void onDestroyView() {
|
||||||
|
super.onDestroyView();
|
||||||
|
handler.removeCallbacks(objectiveUpdater);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startUpdateTimer() {
|
||||||
|
handler.removeCallbacks(objectiveUpdater);
|
||||||
|
for (Objective objective : ObjectivesPlugin.getPlugin().getObjectives()) {
|
||||||
|
if (objective.isStarted() && !objective.isAccomplished()) {
|
||||||
|
long timeTillNextMinute = (System.currentTimeMillis() - objective.getStartedOn().getTime()) % (60 * 1000);
|
||||||
|
handler.postDelayed(objectiveUpdater, timeTillNextMinute);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void scrollToCurrentObjective() {
|
||||||
|
for (int i = 0; i < ObjectivesPlugin.getPlugin().getObjectives().size(); i++) {
|
||||||
|
Objective objective = ObjectivesPlugin.getPlugin().getObjectives().get(i);
|
||||||
|
if (!objective.isStarted() || !objective.isAccomplished()) {
|
||||||
|
RecyclerView.SmoothScroller smoothScroller = new LinearSmoothScroller(getContext()) {
|
||||||
|
@Override
|
||||||
|
protected int getVerticalSnapPreference() {
|
||||||
|
return LinearSmoothScroller.SNAP_TO_START;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int calculateTimeForScrolling(int dx) {
|
||||||
|
return super.calculateTimeForScrolling(dx) * 4;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
smoothScroller.setTargetPosition(i);
|
||||||
|
recyclerView.getLayoutManager().startSmoothScroll(smoothScroller);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ObjectivesAdapter extends RecyclerView.Adapter<ObjectivesAdapter.ViewHolder> {
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
|
return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.objectives_item, parent, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||||
|
Objective objective = ObjectivesPlugin.getPlugin().getObjectives().get(position);
|
||||||
|
holder.title.setText(MainApp.gs(R.string.nth_objective, position + 1));
|
||||||
|
if (objective.getObjective() != 0) {
|
||||||
|
holder.objective.setVisibility(View.VISIBLE);
|
||||||
|
holder.objective.setText(MainApp.gs(objective.getObjective()));
|
||||||
|
} else holder.objective.setVisibility(View.GONE);
|
||||||
|
if (objective.getGate() != 0) {
|
||||||
|
holder.gate.setVisibility(View.VISIBLE);
|
||||||
|
holder.gate.setText(MainApp.gs(objective.getGate()));
|
||||||
|
} else holder.gate.setVisibility(View.GONE);
|
||||||
|
if (!objective.isStarted()) {
|
||||||
|
holder.gate.setTextColor(0xFFFFFFFF);
|
||||||
|
holder.verify.setVisibility(View.GONE);
|
||||||
|
holder.progress.setVisibility(View.GONE);
|
||||||
|
if (position == 0 || ObjectivesPlugin.getPlugin().getObjectives().get(position - 1).isAccomplished())
|
||||||
|
holder.start.setVisibility(View.VISIBLE);
|
||||||
|
else holder.start.setVisibility(View.GONE);
|
||||||
|
} else if (objective.isAccomplished()) {
|
||||||
|
holder.gate.setTextColor(0xFF4CAF50);
|
||||||
|
holder.verify.setVisibility(View.GONE);
|
||||||
|
holder.progress.setVisibility(View.GONE);
|
||||||
|
holder.start.setVisibility(View.GONE);
|
||||||
|
} else if (objective.isStarted()) {
|
||||||
|
holder.gate.setTextColor(0xFFFFFFFF);
|
||||||
|
holder.verify.setVisibility(View.VISIBLE);
|
||||||
|
holder.verify.setEnabled(objective.isCompleted() || enableFake.isChecked());
|
||||||
|
holder.start.setVisibility(View.GONE);
|
||||||
|
holder.progress.setVisibility(View.VISIBLE);
|
||||||
|
holder.progress.removeAllViews();
|
||||||
|
for (Objective.Task task : objective.getTasks()) {
|
||||||
|
if (task.shouldBeIgnored()) continue;
|
||||||
|
TextView textView = new TextView(holder.progress.getContext());
|
||||||
|
textView.setTextColor(0xFFFFFFFF);
|
||||||
|
String basicHTML = "%2$s: <font color=\"%1$s\"><b>%3$s</b></font>";
|
||||||
|
String formattedHTML = String.format(basicHTML, task.isCompleted() ? "#4CAF50" : "#FF9800", MainApp.gs(task.getTask()), task.getProgress());
|
||||||
|
textView.setText(Html.fromHtml(formattedHTML));
|
||||||
|
holder.progress.addView(textView, LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
holder.verify.setOnClickListener((view) -> {
|
||||||
|
objective.setAccomplishedOn(new Date());
|
||||||
|
notifyDataSetChanged();
|
||||||
|
scrollToCurrentObjective();
|
||||||
|
startUpdateTimer();
|
||||||
|
});
|
||||||
|
holder.start.setOnClickListener((view) -> {
|
||||||
|
objective.setStartedOn(new Date());
|
||||||
|
notifyDataSetChanged();
|
||||||
|
scrollToCurrentObjective();
|
||||||
|
startUpdateTimer();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return ObjectivesPlugin.getPlugin().getObjectives().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
|
||||||
|
public CardView cardView;
|
||||||
|
public TextView title;
|
||||||
|
public TextView objective;
|
||||||
|
public TextView gate;
|
||||||
|
public LinearLayout progress;
|
||||||
|
public Button verify;
|
||||||
|
public Button start;
|
||||||
|
|
||||||
|
public ViewHolder(View itemView) {
|
||||||
|
super(itemView);
|
||||||
|
cardView = (CardView) itemView;
|
||||||
|
title = itemView.findViewById(R.id.objective_title);
|
||||||
|
objective = itemView.findViewById(R.id.objective_objective);
|
||||||
|
gate = itemView.findViewById(R.id.objective_gate);
|
||||||
|
progress = itemView.findViewById(R.id.objective_progress);
|
||||||
|
verify = itemView.findViewById(R.id.objective_verify);
|
||||||
|
start = itemView.findViewById(R.id.objective_start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateGUI() {
|
||||||
Activity activity = getActivity();
|
Activity activity = getActivity();
|
||||||
if (activity != null)
|
if (activity != null)
|
||||||
activity.runOnUiThread(new Runnable() {
|
activity.runOnUiThread(() -> {
|
||||||
@Override
|
objectivesAdapter.notifyDataSetChanged();
|
||||||
public void run() {
|
|
||||||
RecyclerViewAdapter adapter = new RecyclerViewAdapter(ObjectivesPlugin.objectives);
|
|
||||||
recyclerView.setAdapter(adapter);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,38 +1,47 @@
|
||||||
package info.nightscout.androidaps.plugins.ConstraintsObjectives;
|
package info.nightscout.androidaps.plugins.ConstraintsObjectives;
|
||||||
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.preference.PreferenceManager;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import info.nightscout.androidaps.BuildConfig;
|
|
||||||
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.db.DatabaseHelper;
|
import info.nightscout.androidaps.interfaces.Constraint;
|
||||||
import info.nightscout.androidaps.interfaces.APSInterface;
|
|
||||||
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
|
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
|
||||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||||
|
import info.nightscout.androidaps.interfaces.PluginDescription;
|
||||||
|
import info.nightscout.androidaps.interfaces.PluginType;
|
||||||
|
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||||
|
import info.nightscout.androidaps.logging.L;
|
||||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||||
import info.nightscout.androidaps.plugins.ConstraintsSafety.SafetyPlugin;
|
import info.nightscout.androidaps.plugins.ConstraintsObjectives.events.EventObjectivesSaved;
|
||||||
import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
|
import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective;
|
||||||
import info.nightscout.androidaps.plugins.NSClientInternal.NSClientInternalPlugin;
|
import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective1;
|
||||||
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
|
import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective2;
|
||||||
|
import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective3;
|
||||||
|
import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective4;
|
||||||
|
import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective5;
|
||||||
|
import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective6;
|
||||||
|
import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective7;
|
||||||
|
import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective8;
|
||||||
import info.nightscout.utils.SP;
|
import info.nightscout.utils.SP;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by mike on 05.08.2016.
|
* Created by mike on 05.08.2016.
|
||||||
*/
|
*/
|
||||||
public class ObjectivesPlugin implements PluginBase, ConstraintsInterface {
|
public class ObjectivesPlugin extends PluginBase implements ConstraintsInterface {
|
||||||
private static Logger log = LoggerFactory.getLogger(ObjectivesPlugin.class);
|
private static Logger log = LoggerFactory.getLogger(L.CONSTRAINTS);
|
||||||
|
|
||||||
private static ObjectivesPlugin objectivesPlugin;
|
private static ObjectivesPlugin objectivesPlugin;
|
||||||
|
|
||||||
|
public List<Objective> objectives = new ArrayList<>();
|
||||||
|
public boolean bgIsAvailableInNS = false;
|
||||||
|
public boolean pumpStatusIsAvailableInNS = false;
|
||||||
|
public Integer manualEnacts = 0;
|
||||||
|
|
||||||
public static ObjectivesPlugin getPlugin() {
|
public static ObjectivesPlugin getPlugin() {
|
||||||
if (objectivesPlugin == null) {
|
if (objectivesPlugin == null) {
|
||||||
objectivesPlugin = new ObjectivesPlugin();
|
objectivesPlugin = new ObjectivesPlugin();
|
||||||
|
@ -40,245 +49,58 @@ public class ObjectivesPlugin implements PluginBase, ConstraintsInterface {
|
||||||
return objectivesPlugin;
|
return objectivesPlugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<Objective> objectives;
|
|
||||||
|
|
||||||
private boolean fragmentVisible = true;
|
|
||||||
|
|
||||||
private ObjectivesPlugin() {
|
private ObjectivesPlugin() {
|
||||||
initializeData();
|
super(new PluginDescription()
|
||||||
|
.mainType(PluginType.CONSTRAINTS)
|
||||||
|
.fragmentClass(ObjectivesFragment.class.getName())
|
||||||
|
.alwaysEnabled(!Config.NSCLIENT)
|
||||||
|
.showInList(!Config.NSCLIENT)
|
||||||
|
.pluginName(R.string.objectives)
|
||||||
|
.shortName(R.string.objectives_shortname)
|
||||||
|
.description(R.string.description_objectives)
|
||||||
|
);
|
||||||
|
setupObjectives();
|
||||||
loadProgress();
|
loadProgress();
|
||||||
MainApp.bus().register(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getFragmentClass() {
|
public boolean specialEnableCondition() {
|
||||||
return ObjectivesFragment.class.getName();
|
PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
|
||||||
|
return pump == null || pump.getPumpDescription().isTempBasalCapable;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void setupObjectives() {
|
||||||
public int getType() {
|
objectives.add(new Objective1());
|
||||||
return PluginBase.CONSTRAINTS;
|
objectives.add(new Objective2());
|
||||||
|
objectives.add(new Objective3());
|
||||||
|
objectives.add(new Objective4());
|
||||||
|
objectives.add(new Objective5());
|
||||||
|
objectives.add(new Objective6());
|
||||||
|
objectives.add(new Objective7());
|
||||||
|
objectives.add(new Objective8());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void reset() {
|
||||||
public String getName() {
|
for (Objective objective : objectives) {
|
||||||
return MainApp.instance().getString(R.string.objectives);
|
objective.setStartedOn(null);
|
||||||
}
|
objective.setAccomplishedOn(null);
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getNameShort() {
|
|
||||||
String name = MainApp.sResources.getString(R.string.objectives_shortname);
|
|
||||||
if (!name.trim().isEmpty()) {
|
|
||||||
//only if translation exists
|
|
||||||
return name;
|
|
||||||
}
|
}
|
||||||
// use long name as fallback
|
|
||||||
return getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled(int type) {
|
|
||||||
return type == CONSTRAINTS && ConfigBuilderPlugin.getActivePump().getPumpDescription().isTempBasalCapable;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isVisibleInTabs(int type) {
|
|
||||||
return type == CONSTRAINTS && fragmentVisible && !Config.NSCLIENT && !Config.G5UPLOADER;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canBeHidden(int type) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasFragment() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean showInList(int type) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setFragmentEnabled(int type, boolean fragmentEnabled) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setFragmentVisible(int type, boolean fragmentVisible) {
|
|
||||||
if (type == CONSTRAINTS) this.fragmentVisible = fragmentVisible;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getPreferencesId() {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
class Objective {
|
|
||||||
Integer num;
|
|
||||||
String objective;
|
|
||||||
String gate;
|
|
||||||
Date started;
|
|
||||||
Integer durationInDays;
|
|
||||||
Date accomplished;
|
|
||||||
|
|
||||||
Objective(Integer num, String objective, String gate, Date started, Integer durationInDays, Date accomplished) {
|
|
||||||
this.num = num;
|
|
||||||
this.objective = objective;
|
|
||||||
this.gate = gate;
|
|
||||||
this.started = started;
|
|
||||||
this.durationInDays = durationInDays;
|
|
||||||
this.accomplished = accomplished;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Objective 0
|
|
||||||
public static boolean bgIsAvailableInNS = false;
|
|
||||||
public static boolean pumpStatusIsAvailableInNS = false;
|
|
||||||
// Objective 1
|
|
||||||
public static Integer manualEnacts = 0;
|
|
||||||
private static final Integer manualEnactsNeeded = 20;
|
|
||||||
|
|
||||||
class RequirementResult {
|
|
||||||
boolean done = false;
|
|
||||||
String comment = "";
|
|
||||||
|
|
||||||
RequirementResult(boolean done, String comment) {
|
|
||||||
this.done = done;
|
|
||||||
this.comment = comment;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String yesOrNo(boolean yes) {
|
|
||||||
if (yes) return "☺";
|
|
||||||
else return "---";
|
|
||||||
}
|
|
||||||
|
|
||||||
RequirementResult requirementsMet(Integer objNum) {
|
|
||||||
switch (objNum) {
|
|
||||||
case 0:
|
|
||||||
boolean isVirtualPump = VirtualPumpPlugin.getPlugin().isEnabled(PluginBase.PUMP);
|
|
||||||
boolean vpUploadEnabled = SP.getBoolean("virtualpump_uploadstatus", false);
|
|
||||||
boolean vpUploadNeeded = !isVirtualPump || vpUploadEnabled;
|
|
||||||
boolean hasBGData = DatabaseHelper.lastBg() != null;
|
|
||||||
|
|
||||||
boolean apsEnabled = false;
|
|
||||||
APSInterface usedAPS = ConfigBuilderPlugin.getActiveAPS();
|
|
||||||
if (usedAPS != null && ((PluginBase) usedAPS).isEnabled(PluginBase.APS))
|
|
||||||
apsEnabled = true;
|
|
||||||
|
|
||||||
return new RequirementResult(hasBGData && bgIsAvailableInNS && pumpStatusIsAvailableInNS && NSClientInternalPlugin.getPlugin().hasWritePermission() && LoopPlugin.getPlugin().isEnabled(PluginBase.LOOP) && apsEnabled && vpUploadNeeded,
|
|
||||||
MainApp.sResources.getString(R.string.objectives_bgavailableinns) + ": " + yesOrNo(bgIsAvailableInNS)
|
|
||||||
+ "\n" + MainApp.sResources.getString(R.string.nsclienthaswritepermission) + ": " + yesOrNo(NSClientInternalPlugin.getPlugin().hasWritePermission())
|
|
||||||
+ (isVirtualPump ? "\n" + MainApp.sResources.getString(R.string.virtualpump_uploadstatus_title) + ": " + yesOrNo(vpUploadEnabled) : "")
|
|
||||||
+ "\n" + MainApp.sResources.getString(R.string.objectives_pumpstatusavailableinns) + ": " + yesOrNo(pumpStatusIsAvailableInNS)
|
|
||||||
+ "\n" + MainApp.sResources.getString(R.string.hasbgdata) + ": " + yesOrNo(hasBGData)
|
|
||||||
+ "\n" + MainApp.sResources.getString(R.string.loopenabled) + ": " + yesOrNo(LoopPlugin.getPlugin().isEnabled(PluginBase.LOOP))
|
|
||||||
+ "\n" + MainApp.sResources.getString(R.string.apsselected) + ": " + yesOrNo(apsEnabled)
|
|
||||||
);
|
|
||||||
case 1:
|
|
||||||
return new RequirementResult(manualEnacts >= manualEnactsNeeded,
|
|
||||||
MainApp.sResources.getString(R.string.objectives_manualenacts) + ": " + manualEnacts + "/" + manualEnactsNeeded);
|
|
||||||
case 2:
|
|
||||||
return new RequirementResult(true, "");
|
|
||||||
case 3:
|
|
||||||
boolean closedModeEnabled = SafetyPlugin.getPlugin().isClosedModeEnabled();
|
|
||||||
return new RequirementResult(closedModeEnabled, MainApp.sResources.getString(R.string.closedmodeenabled) + ": " + yesOrNo(closedModeEnabled));
|
|
||||||
case 4:
|
|
||||||
double maxIOB = MainApp.getConfigBuilder().applyMaxIOBConstraints(1000d);
|
|
||||||
boolean maxIobSet = maxIOB > 0;
|
|
||||||
return new RequirementResult(maxIobSet, MainApp.sResources.getString(R.string.maxiobset) + ": " + yesOrNo(maxIobSet));
|
|
||||||
default:
|
|
||||||
return new RequirementResult(true, "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void initializeData() {
|
|
||||||
bgIsAvailableInNS = false;
|
bgIsAvailableInNS = false;
|
||||||
pumpStatusIsAvailableInNS = false;
|
pumpStatusIsAvailableInNS = false;
|
||||||
manualEnacts = 0;
|
manualEnacts = 0;
|
||||||
|
saveProgress();
|
||||||
objectives = new ArrayList<>();
|
|
||||||
objectives.add(new Objective(0,
|
|
||||||
MainApp.sResources.getString(R.string.objectives_0_objective),
|
|
||||||
MainApp.sResources.getString(R.string.objectives_0_gate),
|
|
||||||
new Date(0),
|
|
||||||
0, // 0 day
|
|
||||||
new Date(0)));
|
|
||||||
objectives.add(new Objective(1,
|
|
||||||
MainApp.sResources.getString(R.string.objectives_1_objective),
|
|
||||||
MainApp.sResources.getString(R.string.objectives_1_gate),
|
|
||||||
new Date(0),
|
|
||||||
7, // 7 days
|
|
||||||
new Date(0)));
|
|
||||||
objectives.add(new Objective(2,
|
|
||||||
MainApp.sResources.getString(R.string.objectives_2_objective),
|
|
||||||
MainApp.sResources.getString(R.string.objectives_2_gate),
|
|
||||||
new Date(0),
|
|
||||||
0, // 0 days
|
|
||||||
new Date(0)));
|
|
||||||
objectives.add(new Objective(3,
|
|
||||||
MainApp.sResources.getString(R.string.objectives_3_objective),
|
|
||||||
MainApp.sResources.getString(R.string.objectives_3_gate),
|
|
||||||
new Date(0),
|
|
||||||
5, // 5 days
|
|
||||||
new Date(0)));
|
|
||||||
objectives.add(new Objective(4,
|
|
||||||
MainApp.sResources.getString(R.string.objectives_4_objective),
|
|
||||||
MainApp.sResources.getString(R.string.objectives_4_gate),
|
|
||||||
new Date(0),
|
|
||||||
1,
|
|
||||||
new Date(0)));
|
|
||||||
objectives.add(new Objective(5,
|
|
||||||
MainApp.sResources.getString(R.string.objectives_5_objective),
|
|
||||||
MainApp.sResources.getString(R.string.objectives_5_gate),
|
|
||||||
new Date(0),
|
|
||||||
7,
|
|
||||||
new Date(0)));
|
|
||||||
objectives.add(new Objective(6,
|
|
||||||
MainApp.sResources.getString(R.string.objectives_6_objective),
|
|
||||||
"",
|
|
||||||
new Date(0),
|
|
||||||
28,
|
|
||||||
new Date(0)));
|
|
||||||
objectives.add(new Objective(7,
|
|
||||||
MainApp.sResources.getString(R.string.objectives_7_objective),
|
|
||||||
"",
|
|
||||||
new Date(0),
|
|
||||||
28,
|
|
||||||
new Date(0)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void saveProgress() {
|
public void saveProgress() {
|
||||||
if (objectives != null) {
|
SP.putBoolean("Objectives" + "bgIsAvailableInNS", bgIsAvailableInNS);
|
||||||
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext());
|
SP.putBoolean("Objectives" + "pumpStatusIsAvailableInNS", pumpStatusIsAvailableInNS);
|
||||||
SharedPreferences.Editor editor = settings.edit();
|
SP.putString("Objectives" + "manualEnacts", Integer.toString(manualEnacts));
|
||||||
for (int num = 0; num < objectives.size(); num++) {
|
if (L.isEnabled(L.CONSTRAINTS))
|
||||||
Objective o = objectives.get(num);
|
log.debug("Objectives stored");
|
||||||
editor.putString("Objectives" + num + "started", Long.toString(o.started.getTime()));
|
MainApp.bus().post(new EventObjectivesSaved());
|
||||||
editor.putString("Objectives" + num + "accomplished", Long.toString(o.accomplished.getTime()));
|
|
||||||
}
|
|
||||||
editor.putBoolean("Objectives" + "bgIsAvailableInNS", bgIsAvailableInNS);
|
|
||||||
editor.putBoolean("Objectives" + "pumpStatusIsAvailableInNS", pumpStatusIsAvailableInNS);
|
|
||||||
editor.putString("Objectives" + "manualEnacts", Integer.toString(manualEnacts));
|
|
||||||
editor.apply();
|
|
||||||
if (Config.logPrefsChange)
|
|
||||||
log.debug("Objectives stored");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadProgress() {
|
private void loadProgress() {
|
||||||
for (int num = 0; num < objectives.size(); num++) {
|
|
||||||
Objective o = objectives.get(num);
|
|
||||||
try {
|
|
||||||
o.started = new Date(SP.getLong("Objectives" + num + "started", 0L));
|
|
||||||
o.accomplished = new Date(SP.getLong("Objectives" + num + "accomplished", 0L));
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bgIsAvailableInNS = SP.getBoolean("Objectives" + "bgIsAvailableInNS", false);
|
bgIsAvailableInNS = SP.getBoolean("Objectives" + "bgIsAvailableInNS", false);
|
||||||
pumpStatusIsAvailableInNS = SP.getBoolean("Objectives" + "pumpStatusIsAvailableInNS", false);
|
pumpStatusIsAvailableInNS = SP.getBoolean("Objectives" + "pumpStatusIsAvailableInNS", false);
|
||||||
try {
|
try {
|
||||||
|
@ -286,68 +108,57 @@ public class ObjectivesPlugin implements PluginBase, ConstraintsInterface {
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
if (Config.logPrefsChange)
|
if (L.isEnabled(L.CONSTRAINTS))
|
||||||
log.debug("Objectives loaded");
|
log.debug("Objectives loaded");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Objective> getObjectives() {
|
||||||
|
return objectives;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constraints interface
|
* Constraints interface
|
||||||
**/
|
**/
|
||||||
@Override
|
@Override
|
||||||
public boolean isLoopEnabled() {
|
public Constraint<Boolean> isLoopInvocationAllowed(Constraint<Boolean> value) {
|
||||||
return objectives.get(0).started.getTime() > 0;
|
if (!objectives.get(0).isStarted())
|
||||||
|
value.set(false, String.format(MainApp.gs(R.string.objectivenotstarted), 1), this);
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isClosedModeEnabled() {
|
public Constraint<Boolean> isClosedLoopAllowed(Constraint<Boolean> value) {
|
||||||
return objectives.get(3).started.getTime() > 0;
|
if (!objectives.get(3).isStarted())
|
||||||
|
value.set(false, String.format(MainApp.gs(R.string.objectivenotstarted), 4), this);
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAutosensModeEnabled() {
|
public Constraint<Boolean> isAutosensModeEnabled(Constraint<Boolean> value) {
|
||||||
return objectives.get(5).started.getTime() > 0;
|
if (!objectives.get(5).isStarted())
|
||||||
|
value.set(false, String.format(MainApp.gs(R.string.objectivenotstarted), 6), this);
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAMAModeEnabled() {
|
public Constraint<Boolean> isAMAModeEnabled(Constraint<Boolean> value) {
|
||||||
return objectives.get(6).started.getTime() > 0;
|
if (!objectives.get(6).isStarted())
|
||||||
|
value.set(false, String.format(MainApp.gs(R.string.objectivenotstarted), 7), this);
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSMBModeEnabled() {
|
public Constraint<Boolean> isSMBModeEnabled(Constraint<Boolean> value) {
|
||||||
return objectives.get(7).started.getTime() > 0;
|
if (!objectives.get(7).isStarted())
|
||||||
|
value.set(false, String.format(MainApp.gs(R.string.objectivenotstarted), 8), this);
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Double applyMaxIOBConstraints(Double maxIob) {
|
public Constraint<Double> applyMaxIOBConstraints(Constraint<Double> maxIob) {
|
||||||
if (objectives.get(3).started.getTime() > 0 && objectives.get(3).accomplished.getTime() == 0) {
|
if (objectives.get(3).isStarted() && !objectives.get(3).isAccomplished())
|
||||||
if (Config.logConstraintsChanges)
|
maxIob.set(0d, String.format(MainApp.gs(R.string.objectivenotfinished), 4), this);
|
||||||
log.debug("Limiting maxIOB " + maxIob + " to " + 0 + "U");
|
return maxIob;
|
||||||
return 0d;
|
|
||||||
} else {
|
|
||||||
return maxIob;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Double applyBasalConstraints(Double absoluteRate) {
|
|
||||||
return absoluteRate;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer applyBasalConstraints(Integer percentRate) {
|
|
||||||
return percentRate;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Double applyBolusConstraints(Double insulin) {
|
|
||||||
return insulin;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer applyCarbsConstraints(Integer carbs) {
|
|
||||||
return carbs;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
package info.nightscout.androidaps.plugins.ConstraintsObjectives.events;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.events.Event;
|
||||||
|
|
||||||
|
public class EventObjectivesSaved extends Event {
|
||||||
|
}
|
|
@ -0,0 +1,141 @@
|
||||||
|
package info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives;
|
||||||
|
|
||||||
|
import android.support.annotation.StringRes;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.MainApp;
|
||||||
|
import info.nightscout.androidaps.R;
|
||||||
|
import info.nightscout.utils.SP;
|
||||||
|
import info.nightscout.utils.T;
|
||||||
|
|
||||||
|
public abstract class Objective {
|
||||||
|
|
||||||
|
private int number;
|
||||||
|
@StringRes
|
||||||
|
private int objective;
|
||||||
|
@StringRes
|
||||||
|
private int gate;
|
||||||
|
private Date startedOn;
|
||||||
|
private Date accomplishedOn;
|
||||||
|
private List<Task> tasks = new ArrayList<>();
|
||||||
|
|
||||||
|
public Objective(int number, @StringRes int objective, @StringRes int gate) {
|
||||||
|
this.number = number;
|
||||||
|
this.objective = objective;
|
||||||
|
this.gate = gate;
|
||||||
|
startedOn = new Date(SP.getLong("Objectives" + number + "started", 0L));
|
||||||
|
if (startedOn.getTime() == 0L) startedOn = null;
|
||||||
|
accomplishedOn = new Date(SP.getLong("Objectives" + number + "accomplished", 0L));
|
||||||
|
if (accomplishedOn.getTime() == 0L) accomplishedOn = null;
|
||||||
|
setupTasks(tasks);
|
||||||
|
for (Task task : tasks) task.objective = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCompleted() {
|
||||||
|
for (Task task : tasks) {
|
||||||
|
if (!task.shouldBeIgnored() && !task.isCompleted())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAccomplished() {
|
||||||
|
return accomplishedOn != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isStarted() {
|
||||||
|
return startedOn != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getStartedOn() {
|
||||||
|
return startedOn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getObjective() {
|
||||||
|
return objective;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getGate() {
|
||||||
|
return gate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStartedOn(Date startedOn) {
|
||||||
|
this.startedOn = startedOn;
|
||||||
|
SP.putLong("Objectives" + number + "started", startedOn == null ? 0 : startedOn.getTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAccomplishedOn(Date accomplishedOn) {
|
||||||
|
this.accomplishedOn = accomplishedOn;
|
||||||
|
SP.putLong("Objectives" + number + "accomplished", accomplishedOn == null ? 0 : accomplishedOn.getTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setupTasks(List<Task> tasks) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Task> getTasks() {
|
||||||
|
return tasks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class Task {
|
||||||
|
@StringRes
|
||||||
|
private int task;
|
||||||
|
private Objective objective;
|
||||||
|
|
||||||
|
public Task(@StringRes int task) {
|
||||||
|
this.task = task;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTask() {
|
||||||
|
return task;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Objective getObjective() {
|
||||||
|
return objective;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract boolean isCompleted();
|
||||||
|
|
||||||
|
public String getProgress() {
|
||||||
|
return MainApp.gs(isCompleted() ? R.string.completed_well_done : R.string.not_completed_yet);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean shouldBeIgnored() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MinimumDurationTask extends Task {
|
||||||
|
|
||||||
|
private long minimumDuration;
|
||||||
|
|
||||||
|
public MinimumDurationTask(long minimumDuration) {
|
||||||
|
super(R.string.time_elapsed);
|
||||||
|
this.minimumDuration = minimumDuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCompleted() {
|
||||||
|
return getObjective().isStarted() && System.currentTimeMillis() - getObjective().getStartedOn().getTime() >= minimumDuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getProgress() {
|
||||||
|
return getDurationText(System.currentTimeMillis() - getObjective().getStartedOn().getTime())
|
||||||
|
+ " / " + getDurationText(minimumDuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getDurationText(long duration) {
|
||||||
|
int days = (int) Math.floor((double) duration / T.days(1).msecs());
|
||||||
|
int hours = (int) Math.floor((double) duration / T.hours(1).msecs());
|
||||||
|
int minutes = (int) Math.floor((double) duration / T.mins(1).msecs());
|
||||||
|
if (days > 0) return MainApp.gq(R.plurals.objective_days, days, days);
|
||||||
|
else if (hours > 0) return MainApp.gq(R.plurals.objective_hours, hours, hours);
|
||||||
|
else return MainApp.gq(R.plurals.objective_minutes, minutes, minutes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
package info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.R;
|
||||||
|
import info.nightscout.androidaps.db.DatabaseHelper;
|
||||||
|
import info.nightscout.androidaps.interfaces.APSInterface;
|
||||||
|
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||||
|
import info.nightscout.androidaps.interfaces.PluginType;
|
||||||
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.NSClientInternal.NSClientPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||||
|
import info.nightscout.utils.DateUtil;
|
||||||
|
import info.nightscout.utils.SP;
|
||||||
|
|
||||||
|
public class Objective1 extends Objective {
|
||||||
|
|
||||||
|
public Objective1() {
|
||||||
|
super(0, R.string.objectives_0_objective, R.string.objectives_0_gate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setupTasks(List<Task> tasks) {
|
||||||
|
tasks.add(new Task(R.string.objectives_bgavailableinns) {
|
||||||
|
@Override
|
||||||
|
public boolean isCompleted() {
|
||||||
|
return ObjectivesPlugin.getPlugin().bgIsAvailableInNS;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
tasks.add(new Task(R.string.nsclienthaswritepermission) {
|
||||||
|
@Override
|
||||||
|
public boolean isCompleted() {
|
||||||
|
return NSClientPlugin.getPlugin().hasWritePermission();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
tasks.add(new Task(R.string.virtualpump_uploadstatus_title) {
|
||||||
|
@Override
|
||||||
|
public boolean isCompleted() {
|
||||||
|
return SP.getBoolean("virtualpump_uploadstatus", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldBeIgnored() {
|
||||||
|
return !VirtualPumpPlugin.getPlugin().isEnabled(PluginType.PUMP);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
tasks.add(new Task(R.string.objectives_pumpstatusavailableinns) {
|
||||||
|
@Override
|
||||||
|
public boolean isCompleted() {
|
||||||
|
return ObjectivesPlugin.getPlugin().pumpStatusIsAvailableInNS;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
tasks.add(new Task(R.string.hasbgdata) {
|
||||||
|
@Override
|
||||||
|
public boolean isCompleted() {
|
||||||
|
return DatabaseHelper.lastBg() != null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
tasks.add(new Task(R.string.loopenabled) {
|
||||||
|
@Override
|
||||||
|
public boolean isCompleted() {
|
||||||
|
return LoopPlugin.getPlugin().isEnabled(PluginType.LOOP);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
tasks.add(new Task(R.string.apsselected) {
|
||||||
|
@Override
|
||||||
|
public boolean isCompleted() {
|
||||||
|
APSInterface usedAPS = ConfigBuilderPlugin.getPlugin().getActiveAPS();
|
||||||
|
if (usedAPS != null && ((PluginBase) usedAPS).isEnabled(PluginType.APS))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
tasks.add(new Task(R.string.activate_profile) {
|
||||||
|
@Override
|
||||||
|
public boolean isCompleted() {
|
||||||
|
return TreatmentsPlugin.getPlugin().getProfileSwitchFromHistory(DateUtil.now()) != null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.MainApp;
|
||||||
|
import info.nightscout.androidaps.R;
|
||||||
|
import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin;
|
||||||
|
import info.nightscout.utils.T;
|
||||||
|
|
||||||
|
public class Objective2 extends Objective {
|
||||||
|
|
||||||
|
public final int MANUAL_ENACTS_NEEDED = 20;
|
||||||
|
|
||||||
|
public Objective2() {
|
||||||
|
super(1, R.string.objectives_1_objective, R.string.objectives_1_gate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setupTasks(List<Task> tasks) {
|
||||||
|
tasks.add(new MinimumDurationTask(T.days(7).msecs()));
|
||||||
|
tasks.add(new Task(R.string.objectives_manualenacts) {
|
||||||
|
@Override
|
||||||
|
public boolean isCompleted() {
|
||||||
|
return ObjectivesPlugin.getPlugin().manualEnacts >= MANUAL_ENACTS_NEEDED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getProgress() {
|
||||||
|
if (ObjectivesPlugin.getPlugin().manualEnacts >= MANUAL_ENACTS_NEEDED)
|
||||||
|
return MainApp.gs(R.string.completed_well_done);
|
||||||
|
else
|
||||||
|
return ObjectivesPlugin.getPlugin().manualEnacts + " / " + MANUAL_ENACTS_NEEDED;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue