commit
8dd5fdfdd5
376 changed files with 15810 additions and 8622 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -8,3 +8,6 @@
|
||||||
build/
|
build/
|
||||||
.idea/
|
.idea/
|
||||||
app/src/main/jniLibs
|
app/src/main/jniLibs
|
||||||
|
full/
|
||||||
|
debug/
|
||||||
|
release/
|
|
@ -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,7 @@ before_install:
|
||||||
|
|
||||||
script:
|
script:
|
||||||
# Unit Test
|
# Unit Test
|
||||||
- ./gradlew test jacocoTestReport
|
- ./gradlew -Pcoverage test jacocoTestReport
|
||||||
|
|
||||||
after_success:
|
after_success:
|
||||||
- bash <(curl -s https://codecov.io/bash)
|
- bash <(curl -s https://codecov.io/bash)
|
1
app/.gitignore
vendored
1
app/.gitignore
vendored
|
@ -1 +0,0 @@
|
||||||
/build
|
|
137
app/build.gradle
137
app/build.gradle
|
@ -16,14 +16,17 @@ apply plugin: 'com.jakewharton.butterknife'
|
||||||
|
|
||||||
ext {
|
ext {
|
||||||
supportLibraryVersion = "27.0.2"
|
supportLibraryVersion = "27.0.2"
|
||||||
|
sdkBuildVersion = "27.0.3"
|
||||||
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 = { ->
|
||||||
|
@ -47,19 +50,25 @@ def generateGitBuild = { ->
|
||||||
return stringBuilder.toString()
|
return stringBuilder.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tasks.matching {it instanceof Test}.all {
|
||||||
|
testLogging.events = ["failed", "skipped"]
|
||||||
|
testLogging.exceptionFormat = "full"
|
||||||
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 27
|
compileSdkVersion 27
|
||||||
buildToolsVersion "${supportLibraryVersion}"
|
buildToolsVersion "${sdkBuildVersion}"
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "info.nightscout.androidaps"
|
applicationId "info.nightscout.androidaps"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 23
|
targetSdkVersion 27
|
||||||
multiDexEnabled true
|
multiDexEnabled true
|
||||||
versionCode 1500
|
versionCode 1500
|
||||||
version "1.59-dev"
|
version "1.60c-dev"
|
||||||
buildConfigField "String", "VERSION", '"' + version + '"'
|
buildConfigField "String", "VERSION", '"' + version + '"'
|
||||||
buildConfigField "String", "BUILDVERSION", generateGitBuild()
|
buildConfigField "String", "BUILDVERSION", generateGitBuild()
|
||||||
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
|
|
||||||
ndk {
|
ndk {
|
||||||
moduleName "BleCommandUtil"
|
moduleName "BleCommandUtil"
|
||||||
|
@ -69,7 +78,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,7 +91,7 @@ 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 {
|
||||||
|
@ -97,21 +106,6 @@ android {
|
||||||
buildConfigField "boolean", "APS", "true"
|
buildConfigField "boolean", "APS", "true"
|
||||||
buildConfigField "boolean", "PUMPDRIVERS", "true"
|
buildConfigField "boolean", "PUMPDRIVERS", "true"
|
||||||
buildConfigField "boolean", "NSCLIENTOLNY", "false"
|
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", "G5UPLOADER", "false"
|
||||||
buildConfigField "boolean", "PUMPCONTROL", "false"
|
buildConfigField "boolean", "PUMPCONTROL", "false"
|
||||||
}
|
}
|
||||||
|
@ -125,7 +119,6 @@ android {
|
||||||
buildConfigField "boolean", "APS", "false"
|
buildConfigField "boolean", "APS", "false"
|
||||||
buildConfigField "boolean", "PUMPDRIVERS", "true"
|
buildConfigField "boolean", "PUMPDRIVERS", "true"
|
||||||
buildConfigField "boolean", "NSCLIENTOLNY", "false"
|
buildConfigField "boolean", "NSCLIENTOLNY", "false"
|
||||||
buildConfigField "boolean", "CLOSEDLOOP", "false"
|
|
||||||
buildConfigField "boolean", "G5UPLOADER", "false"
|
buildConfigField "boolean", "G5UPLOADER", "false"
|
||||||
buildConfigField "boolean", "PUMPCONTROL", "true"
|
buildConfigField "boolean", "PUMPCONTROL", "true"
|
||||||
}
|
}
|
||||||
|
@ -139,7 +132,6 @@ android {
|
||||||
buildConfigField "boolean", "APS", "false"
|
buildConfigField "boolean", "APS", "false"
|
||||||
buildConfigField "boolean", "PUMPDRIVERS", "false"
|
buildConfigField "boolean", "PUMPDRIVERS", "false"
|
||||||
buildConfigField "boolean", "NSCLIENTOLNY", "true"
|
buildConfigField "boolean", "NSCLIENTOLNY", "true"
|
||||||
buildConfigField "boolean", "CLOSEDLOOP", "false"
|
|
||||||
buildConfigField "boolean", "G5UPLOADER", "false"
|
buildConfigField "boolean", "G5UPLOADER", "false"
|
||||||
buildConfigField "boolean", "PUMPCONTROL", "false"
|
buildConfigField "boolean", "PUMPCONTROL", "false"
|
||||||
}
|
}
|
||||||
|
@ -153,7 +145,6 @@ android {
|
||||||
buildConfigField "boolean", "APS", "false"
|
buildConfigField "boolean", "APS", "false"
|
||||||
buildConfigField "boolean", "PUMPDRIVERS", "false"
|
buildConfigField "boolean", "PUMPDRIVERS", "false"
|
||||||
buildConfigField "boolean", "NSCLIENTOLNY", "false"
|
buildConfigField "boolean", "NSCLIENTOLNY", "false"
|
||||||
buildConfigField "boolean", "CLOSEDLOOP", "false"
|
|
||||||
buildConfigField "boolean", "G5UPLOADER", "true"
|
buildConfigField "boolean", "G5UPLOADER", "true"
|
||||||
buildConfigField "boolean", "PUMPCONTROL", "false"
|
buildConfigField "boolean", "PUMPCONTROL", "false"
|
||||||
}
|
}
|
||||||
|
@ -165,8 +156,9 @@ android {
|
||||||
|
|
||||||
testOptions {
|
testOptions {
|
||||||
unitTests.returnDefaultValues = true
|
unitTests.returnDefaultValues = true
|
||||||
|
unitTests.includeAndroidResources = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
|
@ -177,75 +169,82 @@ 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;
|
||||||
}
|
}
|
||||||
compile 'MilosKozak:danars-support-lib:master@zip'
|
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-v4:${supportLibraryVersion}"
|
||||||
compile "com.android.support:cardview-v7:${supportLibraryVersion}"
|
implementation "com.android.support:cardview-v7:${supportLibraryVersion}"
|
||||||
compile "com.android.support:recyclerview-v7:${supportLibraryVersion}"
|
implementation "com.android.support:recyclerview-v7:${supportLibraryVersion}"
|
||||||
compile "com.android.support:gridlayout-v7:${supportLibraryVersion}"
|
implementation "com.android.support:gridlayout-v7:${supportLibraryVersion}"
|
||||||
compile "com.android.support:design:${supportLibraryVersion}"
|
implementation "com.android.support:design:${supportLibraryVersion}"
|
||||||
compile "com.android.support:percent:${supportLibraryVersion}"
|
implementation "com.android.support:percent:${supportLibraryVersion}"
|
||||||
compile "com.wdullaer:materialdatetimepicker:2.3.0"
|
implementation "com.wdullaer:materialdatetimepicker:2.3.0"
|
||||||
compile 'com.android.support.constraint:constraint-layout:1.0.2'
|
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
|
||||||
compile "com.squareup:otto:1.3.7"
|
implementation "com.squareup:otto:1.3.7"
|
||||||
compile "com.j256.ormlite:ormlite-core:${ormLiteVersion}"
|
implementation "com.j256.ormlite:ormlite-core:${ormLiteVersion}"
|
||||||
compile "com.j256.ormlite:ormlite-android:${ormLiteVersion}"
|
implementation "com.j256.ormlite:ormlite-android:${ormLiteVersion}"
|
||||||
compile("com.github.tony19:logback-android-classic:1.1.1-6") {
|
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(name: "sightparser-release", ext: "aar")
|
implementation(name: "sightparser-release", ext: "aar")
|
||||||
|
|
||||||
compile("com.google.android:flexbox:0.3.0") {
|
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:0.8.3") {
|
||||||
// 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"
|
||||||
|
|
||||||
compile 'org.mozilla:rhino:1.7.7.2'
|
implementation 'org.mozilla:rhino:1.7.7.2'
|
||||||
|
|
||||||
api "com.jakewharton:butterknife:8.8.1"
|
implementation "com.jakewharton:butterknife:${butterknifeVersion}"
|
||||||
annotationProcessor "com.jakewharton:butterknife-compiler:8.8.1"
|
annotationProcessor "com.jakewharton:butterknife-compiler:${butterknifeVersion}"
|
||||||
|
|
||||||
testCompile "junit:junit:4.12"
|
testImplementation "junit:junit:4.12"
|
||||||
testCompile "org.json:json:20140107"
|
testImplementation "org.json:json:20140107"
|
||||||
testCompile "org.mockito:mockito-core:2.7.22"
|
testImplementation "org.mockito:mockito-core:2.7.22"
|
||||||
testCompile "org.powermock:powermock-api-mockito2:${powermockVersion}"
|
testImplementation "org.powermock:powermock-api-mockito2:${powermockVersion}"
|
||||||
testCompile "org.powermock:powermock-module-junit4-rule-agent:${powermockVersion}"
|
testImplementation "org.powermock:powermock-module-junit4-rule-agent:${powermockVersion}"
|
||||||
testCompile "org.powermock:powermock-module-junit4-rule:${powermockVersion}"
|
testImplementation "org.powermock:powermock-module-junit4-rule:${powermockVersion}"
|
||||||
testCompile "org.powermock:powermock-module-junit4:${powermockVersion}"
|
testImplementation "org.powermock:powermock-module-junit4:${powermockVersion}"
|
||||||
testCompile "joda-time:joda-time:2.9.4.2"
|
testImplementation "joda-time:joda-time:2.9.4.2"
|
||||||
testCompile "com.google.truth:truth:0.39"
|
testImplementation "com.google.truth:truth:0.39"
|
||||||
|
testImplementation 'org.robolectric:robolectric:3.8'
|
||||||
|
testImplementation "org.skyscreamer:jsonassert:1.5.0"
|
||||||
|
|
||||||
androidTestCompile "org.mockito:mockito-core:2.7.22"
|
androidTestImplementation "org.mockito:mockito-core:2.7.22"
|
||||||
androidTestCompile "com.google.dexmaker:dexmaker:${dexmakerVersion}"
|
androidTestImplementation "com.google.dexmaker:dexmaker:${dexmakerVersion}"
|
||||||
androidTestCompile "com.google.dexmaker:dexmaker-mockito:${dexmakerVersion}"
|
androidTestImplementation "com.google.dexmaker:dexmaker-mockito:${dexmakerVersion}"
|
||||||
}
|
}
|
||||||
|
|
||||||
task unzip(type: Copy) {
|
task unzip(type: Copy) {
|
||||||
def zipPath = configurations.compile.find {it.name.startsWith("danars") }
|
def zipPath = configurations.libs.find {it.name.startsWith("danars") }
|
||||||
def zipFile = file(zipPath)
|
def zipFile = file(zipPath)
|
||||||
def outputDir = file("${buildDir}/unpacked/dist")
|
def outputDir = file("${buildDir}/unpacked/dist")
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
android:theme="@style/Theme.AppCompat.Translucent" />
|
android:theme="@style/Theme.AppCompat.Translucent" />
|
||||||
<activity android:name=".AgreementActivity" />
|
<activity android:name=".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=".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" />
|
||||||
|
|
|
@ -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
|
|
@ -1,6 +1,6 @@
|
||||||
<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 scope="context" name="EXT_FILES_DIR" value="${EXT_DIR:-/sdcard}/Android/data/${PACKAGE_NAME}/files"/>
|
||||||
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
<file>${EXT_FILES_DIR}/AndroidAPS.log</file>
|
<file>${EXT_FILES_DIR}/AndroidAPS.log</file>
|
||||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||||
|
|
|
@ -13,10 +13,9 @@ public class Config {
|
||||||
public static final boolean G5UPLOADER = BuildConfig.G5UPLOADER;
|
public static final boolean G5UPLOADER = BuildConfig.G5UPLOADER;
|
||||||
public static final boolean PUMPCONTROL = BuildConfig.PUMPCONTROL;
|
public static final boolean PUMPCONTROL = BuildConfig.PUMPCONTROL;
|
||||||
|
|
||||||
public static final boolean DANAR = BuildConfig.PUMPDRIVERS;
|
public static final boolean HWPUMPS = BuildConfig.PUMPDRIVERS;
|
||||||
|
|
||||||
public static final boolean ACTION = !BuildConfig.NSCLIENTOLNY && !BuildConfig.G5UPLOADER;
|
public static final boolean ACTION = !BuildConfig.NSCLIENTOLNY && !BuildConfig.G5UPLOADER;
|
||||||
public static final boolean VIRTUALPUMP = !BuildConfig.NSCLIENTOLNY && !BuildConfig.G5UPLOADER;
|
|
||||||
public static final boolean MDI = !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 OTHERPROFILES = !BuildConfig.NSCLIENTOLNY && !BuildConfig.G5UPLOADER;
|
||||||
public static final boolean SAFETY = !BuildConfig.NSCLIENTOLNY && !BuildConfig.G5UPLOADER;
|
public static final boolean SAFETY = !BuildConfig.NSCLIENTOLNY && !BuildConfig.G5UPLOADER;
|
||||||
|
@ -44,4 +43,6 @@ public class Config {
|
||||||
public static final boolean logDanaBTComm = true;
|
public static final boolean logDanaBTComm = true;
|
||||||
public static boolean logDanaMessageDetail = true;
|
public static boolean logDanaMessageDetail = true;
|
||||||
public static final boolean logDanaSerialEngine = true;
|
public static final boolean logDanaSerialEngine = true;
|
||||||
|
|
||||||
|
public static final boolean enableComboBetaFeatures = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
@ -14,10 +14,11 @@ public class Constants {
|
||||||
|
|
||||||
public static final double defaultDIA = 3d;
|
public static final double defaultDIA = 3d;
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
|
@ -41,10 +42,13 @@ public class Constants {
|
||||||
// Temp targets
|
// Temp targets
|
||||||
public static final int defaultActivityTTDuration = 90; // min
|
public static final int defaultActivityTTDuration = 90; // min
|
||||||
public static final double defaultActivityTTmgdl = 90d;
|
public static final double defaultActivityTTmgdl = 90d;
|
||||||
public static final double defaultActivityTTmmol = 5d;
|
public static final double defaultActivityTTmmol = 8d;
|
||||||
public static final int defaultEatingSoonTTDuration = 45; // min
|
public static final int defaultEatingSoonTTDuration = 45; // min
|
||||||
public static final double defaultEatingSoonTTmgdl = 140d;
|
public static final double defaultEatingSoonTTmgdl = 140d;
|
||||||
public static final double defaultEatingSoonTTmmol = 8d;
|
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;
|
||||||
|
@ -59,4 +63,7 @@ public class Constants {
|
||||||
// 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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,18 @@ package info.nightscout.androidaps;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.v4.content.res.ResourcesCompat;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
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.view.View;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.CheckBox;
|
import android.widget.ImageButton;
|
||||||
import android.widget.SeekBar;
|
import android.widget.SeekBar;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.jjoe64.graphview.GraphView;
|
import com.jjoe64.graphview.GraphView;
|
||||||
import com.squareup.otto.Subscribe;
|
import com.squareup.otto.Subscribe;
|
||||||
|
@ -26,6 +33,7 @@ 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.IobCobCalculator.IobCobCalculatorPlugin;
|
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
|
||||||
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished;
|
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished;
|
||||||
|
import info.nightscout.androidaps.plugins.Overview.OverviewFragment;
|
||||||
import info.nightscout.androidaps.plugins.Overview.OverviewPlugin;
|
import info.nightscout.androidaps.plugins.Overview.OverviewPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Overview.graphData.GraphData;
|
import info.nightscout.androidaps.plugins.Overview.graphData.GraphData;
|
||||||
import info.nightscout.utils.DateUtil;
|
import info.nightscout.utils.DateUtil;
|
||||||
|
@ -34,6 +42,13 @@ import info.nightscout.utils.SP;
|
||||||
public class HistoryBrowseActivity extends AppCompatActivity {
|
public class HistoryBrowseActivity extends AppCompatActivity {
|
||||||
private static Logger log = LoggerFactory.getLogger(HistoryBrowseActivity.class);
|
private static Logger log = LoggerFactory.getLogger(HistoryBrowseActivity.class);
|
||||||
|
|
||||||
|
|
||||||
|
ImageButton chartButton;
|
||||||
|
|
||||||
|
boolean showBasal = true;
|
||||||
|
boolean showIob, showCob, showDev, showRat;
|
||||||
|
|
||||||
|
|
||||||
@BindView(R.id.historybrowse_date)
|
@BindView(R.id.historybrowse_date)
|
||||||
Button buttonDate;
|
Button buttonDate;
|
||||||
@BindView(R.id.historybrowse_zoom)
|
@BindView(R.id.historybrowse_zoom)
|
||||||
|
@ -44,19 +59,8 @@ public class HistoryBrowseActivity extends AppCompatActivity {
|
||||||
GraphView iobGraph;
|
GraphView iobGraph;
|
||||||
@BindView(R.id.historybrowse_seekBar)
|
@BindView(R.id.historybrowse_seekBar)
|
||||||
SeekBar seekBar;
|
SeekBar seekBar;
|
||||||
|
@BindView(R.id.historybrowse_noprofile)
|
||||||
@BindView(R.id.overview_showprediction)
|
TextView noProfile;
|
||||||
CheckBox showPredictionCheckbox;
|
|
||||||
@BindView(R.id.overview_showbasals)
|
|
||||||
CheckBox showBasalsCheckbox;
|
|
||||||
@BindView(R.id.overview_showiob)
|
|
||||||
CheckBox showIobCheckbox;
|
|
||||||
@BindView(R.id.overview_showcob)
|
|
||||||
CheckBox showCobCheckbox;
|
|
||||||
@BindView(R.id.overview_showdeviations)
|
|
||||||
CheckBox showDeviationsCheckbox;
|
|
||||||
@BindView(R.id.overview_showratios)
|
|
||||||
CheckBox showRatiosCheckbox;
|
|
||||||
|
|
||||||
private int rangeToDisplay = 24; // for graph
|
private int rangeToDisplay = 24; // for graph
|
||||||
private long start;
|
private long start;
|
||||||
|
@ -85,6 +89,8 @@ public class HistoryBrowseActivity extends AppCompatActivity {
|
||||||
iobGraph.getGridLabelRenderer().setLabelVerticalWidth(50);
|
iobGraph.getGridLabelRenderer().setLabelVerticalWidth(50);
|
||||||
iobGraph.getGridLabelRenderer().setNumVerticalLabels(5);
|
iobGraph.getGridLabelRenderer().setNumVerticalLabels(5);
|
||||||
|
|
||||||
|
setupChartMenu();
|
||||||
|
|
||||||
// set start of current day
|
// set start of current day
|
||||||
Calendar calendar = Calendar.getInstance();
|
Calendar calendar = Calendar.getInstance();
|
||||||
calendar.setTimeInMillis(System.currentTimeMillis());
|
calendar.setTimeInMillis(System.currentTimeMillis());
|
||||||
|
@ -162,15 +168,6 @@ public class HistoryBrowseActivity extends AppCompatActivity {
|
||||||
void onClickDate() {
|
void onClickDate() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClick({R.id.overview_showbasals, R.id.overview_showprediction, R.id.overview_showiob, R.id.overview_showcob, R.id.overview_showdeviations, R.id.overview_showratios})
|
|
||||||
void onClickDate(View view) {
|
|
||||||
//((CheckBox) view).toggle();
|
|
||||||
updateGUI("checkboxToggle");
|
|
||||||
iobCobCalculatorPlugin.clearCache();
|
|
||||||
iobCobCalculatorPlugin.runCalculation("onClickDate", start, true, eventCustomCalculationFinished);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onStatusEvent(final EventAutosensCalculationFinished e) {
|
public void onStatusEvent(final EventAutosensCalculationFinished e) {
|
||||||
Activity activity = this;
|
Activity activity = this;
|
||||||
|
@ -188,6 +185,14 @@ public class HistoryBrowseActivity extends AppCompatActivity {
|
||||||
void updateGUI(String from) {
|
void updateGUI(String from) {
|
||||||
final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
|
final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
|
||||||
final Profile profile = MainApp.getConfigBuilder().getProfile();
|
final Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||||
|
|
||||||
|
if (profile == null) {
|
||||||
|
noProfile.setVisibility(View.VISIBLE);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
noProfile.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
final String units = profile.getUnits();
|
final String units = profile.getUnits();
|
||||||
|
|
||||||
double lowLineSetting = SP.getDouble("low_mark", Profile.fromMgdlToUnits(OverviewPlugin.bgTargetLow, units));
|
double lowLineSetting = SP.getDouble("low_mark", Profile.fromMgdlToUnits(OverviewPlugin.bgTargetLow, units));
|
||||||
|
@ -247,7 +252,7 @@ public class HistoryBrowseActivity extends AppCompatActivity {
|
||||||
graphData.addTreatments(fromTime, toTime);
|
graphData.addTreatments(fromTime, toTime);
|
||||||
|
|
||||||
// add basal data
|
// add basal data
|
||||||
if (pump.getPumpDescription().isTempBasalCapable && showBasalsCheckbox.isChecked()) {
|
if (pump.getPumpDescription().isTempBasalCapable && showBasal) {
|
||||||
graphData.addBasals(fromTime, toTime, lowLine / graphData.maxY / 1.2d);
|
graphData.addBasals(fromTime, toTime, lowLine / graphData.maxY / 1.2d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,23 +268,23 @@ public class HistoryBrowseActivity extends AppCompatActivity {
|
||||||
boolean useDevForScale = false;
|
boolean useDevForScale = false;
|
||||||
boolean useRatioForScale = false;
|
boolean useRatioForScale = false;
|
||||||
|
|
||||||
if (showIobCheckbox.isChecked()) {
|
if (showIob) {
|
||||||
useIobForScale = true;
|
useIobForScale = true;
|
||||||
} else if (showCobCheckbox.isChecked()) {
|
} else if (showCob) {
|
||||||
useCobForScale = true;
|
useCobForScale = true;
|
||||||
} else if (showDeviationsCheckbox.isChecked()) {
|
} else if (showDev) {
|
||||||
useDevForScale = true;
|
useDevForScale = true;
|
||||||
} else if (showRatiosCheckbox.isChecked()) {
|
} else if (showRat) {
|
||||||
useRatioForScale = true;
|
useRatioForScale = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (showIobCheckbox.isChecked())
|
if (showIob)
|
||||||
secondGraphData.addIob(fromTime, toTime, useIobForScale, 1d);
|
secondGraphData.addIob(fromTime, toTime, useIobForScale, 1d);
|
||||||
if (showCobCheckbox.isChecked())
|
if (showCob)
|
||||||
secondGraphData.addCob(fromTime, toTime, useCobForScale, useCobForScale ? 1d : 0.5d);
|
secondGraphData.addCob(fromTime, toTime, useCobForScale, useCobForScale ? 1d : 0.5d);
|
||||||
if (showDeviationsCheckbox.isChecked())
|
if (showDev)
|
||||||
secondGraphData.addDeviations(fromTime, toTime, useDevForScale, 1d);
|
secondGraphData.addDeviations(fromTime, toTime, useDevForScale, 1d);
|
||||||
if (showRatiosCheckbox.isChecked())
|
if (showRat)
|
||||||
secondGraphData.addRatio(fromTime, toTime, useRatioForScale, 1d);
|
secondGraphData.addRatio(fromTime, toTime, useRatioForScale, 1d);
|
||||||
|
|
||||||
// **** NOW line ****
|
// **** NOW line ****
|
||||||
|
@ -288,7 +293,7 @@ public class HistoryBrowseActivity extends AppCompatActivity {
|
||||||
secondGraphData.addNowLine(pointer);
|
secondGraphData.addNowLine(pointer);
|
||||||
|
|
||||||
// do GUI update
|
// do GUI update
|
||||||
if (showIobCheckbox.isChecked() || showCobCheckbox.isChecked() || showDeviationsCheckbox.isChecked() || showRatiosCheckbox.isChecked()) {
|
if (showIob || showCob || showDev || showRat) {
|
||||||
iobGraph.setVisibility(View.VISIBLE);
|
iobGraph.setVisibility(View.VISIBLE);
|
||||||
} else {
|
} else {
|
||||||
iobGraph.setVisibility(View.GONE);
|
iobGraph.setVisibility(View.GONE);
|
||||||
|
@ -297,4 +302,90 @@ public class HistoryBrowseActivity extends AppCompatActivity {
|
||||||
graphData.performUpdate();
|
graphData.performUpdate();
|
||||||
secondGraphData.performUpdate();
|
secondGraphData.performUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setupChartMenu() {
|
||||||
|
chartButton = (ImageButton) findViewById(R.id.overview_chartMenuButton);
|
||||||
|
chartButton.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View 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);
|
||||||
|
|
||||||
|
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onMenuItemClick(MenuItem item) {
|
||||||
|
if (item.getItemId() == OverviewFragment.CHARTTYPE.BAS.ordinal()) {
|
||||||
|
showBasal = !item.isChecked();
|
||||||
|
|
||||||
|
} else if (item.getItemId() == OverviewFragment.CHARTTYPE.IOB.ordinal()) {
|
||||||
|
showIob = !item.isChecked();
|
||||||
|
|
||||||
|
} else if (item.getItemId() == OverviewFragment.CHARTTYPE.COB.ordinal()) {
|
||||||
|
showCob = !item.isChecked();
|
||||||
|
|
||||||
|
} else if (item.getItemId() == OverviewFragment.CHARTTYPE.DEV.ordinal()) {
|
||||||
|
showDev = !item.isChecked();
|
||||||
|
|
||||||
|
} else if (item.getItemId() == OverviewFragment.CHARTTYPE.SEN.ordinal()) {
|
||||||
|
showRat = !item.isChecked();
|
||||||
|
}
|
||||||
|
updateGUI("onGraphCheckboxesCheckedChanged");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
chartButton.setImageResource(R.drawable.ic_arrow_drop_up_white_24dp);
|
||||||
|
popup.setOnDismissListener(new PopupMenu.OnDismissListener() {
|
||||||
|
@Override
|
||||||
|
public void onDismiss(PopupMenu menu) {
|
||||||
|
chartButton.setImageResource(R.drawable.ic_arrow_drop_down_white_24dp);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
popup.show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,9 @@ import android.support.v4.view.ViewPager;
|
||||||
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.PopupMenu;
|
||||||
|
import android.text.SpannableString;
|
||||||
|
import android.text.method.LinkMovementMethod;
|
||||||
|
import android.text.util.Linkify;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
|
@ -27,6 +30,7 @@ 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.ImageButton;
|
||||||
|
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;
|
||||||
|
@ -42,6 +46,7 @@ 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.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.Food.FoodPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Overview.events.EventSetWakeLock;
|
import info.nightscout.androidaps.plugins.Overview.events.EventSetWakeLock;
|
||||||
import info.nightscout.androidaps.tabs.SlidingTabLayout;
|
import info.nightscout.androidaps.tabs.SlidingTabLayout;
|
||||||
import info.nightscout.androidaps.tabs.TabPageAdapter;
|
import info.nightscout.androidaps.tabs.TabPageAdapter;
|
||||||
|
@ -371,6 +376,9 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
MainApp.getDbHelper().resetDatabases();
|
MainApp.getDbHelper().resetDatabases();
|
||||||
|
// should be handled by Plugin-Interface and
|
||||||
|
// additional service interface and plugin registry
|
||||||
|
MainApp.getSpecificPlugin(FoodPlugin.class).getService().resetFood();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.create()
|
.create()
|
||||||
|
@ -396,10 +404,16 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
||||||
builder.setIcon(R.mipmap.blueowl);
|
builder.setIcon(R.mipmap.blueowl);
|
||||||
String message = "Build: " + BuildConfig.BUILDVERSION + "\n";
|
String message = "Build: " + BuildConfig.BUILDVERSION + "\n";
|
||||||
message += MainApp.sResources.getString(R.string.configbuilder_nightscoutversion_label) + " " + ConfigBuilderPlugin.nightscoutVersionName;
|
message += MainApp.sResources.getString(R.string.configbuilder_nightscoutversion_label) + " " + ConfigBuilderPlugin.nightscoutVersionName;
|
||||||
builder.setMessage(message);
|
if (MainApp.engineeringMode)
|
||||||
|
message += "\n" + MainApp.gs(R.string.engineering_mode_enabled);
|
||||||
|
message += getString(R.string.about_link_urls);
|
||||||
|
final SpannableString messageSpanned = new SpannableString(message);
|
||||||
|
Linkify.addLinks(messageSpanned, Linkify.WEB_URLS);
|
||||||
|
builder.setMessage(messageSpanned);
|
||||||
builder.setPositiveButton(MainApp.sResources.getString(R.string.ok), null);
|
builder.setPositiveButton(MainApp.sResources.getString(R.string.ok), null);
|
||||||
AlertDialog alertDialog = builder.create();
|
AlertDialog alertDialog = builder.create();
|
||||||
alertDialog.show();
|
alertDialog.show();
|
||||||
|
((TextView)alertDialog.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance());
|
||||||
break;
|
break;
|
||||||
case R.id.nav_exit:
|
case R.id.nav_exit:
|
||||||
log.debug("Exiting");
|
log.debug("Exiting");
|
||||||
|
|
|
@ -20,52 +20,56 @@ 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 ch.qos.logback.classic.LoggerContext;
|
||||||
import info.nightscout.androidaps.Services.Intents;
|
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.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.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.receivers.AckAlarmReceiver;
|
import info.nightscout.androidaps.plugins.NSClientInternal.receivers.AckAlarmReceiver;
|
||||||
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.OpenAPSSMB.OpenAPSSMBPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Overview.OverviewPlugin;
|
import info.nightscout.androidaps.plugins.Overview.OverviewPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
|
||||||
|
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
|
||||||
import info.nightscout.androidaps.plugins.Persistentnotification.PersistentNotificationPlugin;
|
import info.nightscout.androidaps.plugins.Persistentnotification.PersistentNotificationPlugin;
|
||||||
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.InsightPumpPlugin;
|
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.SensitivityAAPS.SensitivityAAPSPlugin;
|
||||||
import info.nightscout.androidaps.plugins.SensitivityOref0.SensitivityOref0Plugin;
|
import info.nightscout.androidaps.plugins.SensitivityOref0.SensitivityOref0Plugin;
|
||||||
import info.nightscout.androidaps.plugins.SensitivityWeightedAverage.SensitivityWeightedAveragePlugin;
|
import info.nightscout.androidaps.plugins.SensitivityWeightedAverage.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.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;
|
||||||
|
@ -87,6 +91,7 @@ public class MainApp extends Application {
|
||||||
|
|
||||||
private static DatabaseHelper sDatabaseHelper = null;
|
private static DatabaseHelper sDatabaseHelper = null;
|
||||||
private static ConfigBuilderPlugin sConfigBuilder = null;
|
private static ConfigBuilderPlugin sConfigBuilder = null;
|
||||||
|
private static ConstraintChecker sConstraintsChecker = null;
|
||||||
|
|
||||||
private static ArrayList<PluginBase> pluginsList = null;
|
private static ArrayList<PluginBase> pluginsList = null;
|
||||||
|
|
||||||
|
@ -95,11 +100,16 @@ public class MainApp extends Application {
|
||||||
private static AckAlarmReceiver ackAlarmReciever = new AckAlarmReceiver();
|
private static AckAlarmReceiver ackAlarmReciever = new AckAlarmReceiver();
|
||||||
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();
|
||||||
sInstance = this;
|
sInstance = this;
|
||||||
sResources = getResources();
|
sResources = getResources();
|
||||||
|
sConstraintsChecker = new ConstraintChecker(this);
|
||||||
|
sDatabaseHelper = OpenHelperManager.getHelper(sInstance, DatabaseHelper.class);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (FabricPrivacy.fabricEnabled()) {
|
if (FabricPrivacy.fabricEnabled()) {
|
||||||
|
@ -116,6 +126,12 @@ public class MainApp extends Application {
|
||||||
log.info("Version: " + BuildConfig.VERSION_NAME);
|
log.info("Version: " + BuildConfig.VERSION_NAME);
|
||||||
log.info("BuildVersion: " + BuildConfig.BUILDVERSION);
|
log.info("BuildVersion: " + BuildConfig.BUILDVERSION);
|
||||||
|
|
||||||
|
String extFilesDir = this.getLogDirectory();
|
||||||
|
File engineeringModeSemaphore = new File(extFilesDir, "engineering_mode");
|
||||||
|
|
||||||
|
engineeringMode = engineeringModeSemaphore.exists() && engineeringModeSemaphore.isFile();
|
||||||
|
devBranch = BuildConfig.VERSION.contains("dev");
|
||||||
|
|
||||||
sBus = Config.logEvents ? new LoggingBus(ThreadEnforcer.ANY) : new Bus(ThreadEnforcer.ANY);
|
sBus = Config.logEvents ? new LoggingBus(ThreadEnforcer.ANY) : new Bus(ThreadEnforcer.ANY);
|
||||||
|
|
||||||
registerLocalBroadcastReceiver();
|
registerLocalBroadcastReceiver();
|
||||||
|
@ -126,22 +142,23 @@ 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());
|
if (Config.HWPUMPS) pluginsList.add(DanaRPlugin.getPlugin());
|
||||||
if (Config.DANAR) pluginsList.add(DanaRKoreanPlugin.getPlugin());
|
if (Config.HWPUMPS) pluginsList.add(DanaRKoreanPlugin.getPlugin());
|
||||||
if (Config.DANAR) pluginsList.add(DanaRv2Plugin.getPlugin());
|
if (Config.HWPUMPS) pluginsList.add(DanaRv2Plugin.getPlugin());
|
||||||
if (Config.DANAR) pluginsList.add(DanaRSPlugin.getPlugin());
|
if (Config.HWPUMPS) pluginsList.add(DanaRSPlugin.getPlugin());
|
||||||
pluginsList.add(CareportalPlugin.getPlugin());
|
pluginsList.add(CareportalPlugin.getPlugin());
|
||||||
// if (Config.DANAR) pluginsList.add(InsightPumpPlugin.getPlugin()); // <-- Enable Insight plugin here
|
if (Config.HWPUMPS && engineeringMode)
|
||||||
|
pluginsList.add(InsightPlugin.getPlugin()); // <-- Enable Insight plugin here
|
||||||
|
if (Config.HWPUMPS && engineeringMode)
|
||||||
|
pluginsList.add(ComboPlugin.getPlugin()); // <-- Enable Combo plugin here
|
||||||
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());
|
||||||
|
@ -168,33 +185,38 @@ public class MainApp extends Application {
|
||||||
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(new PersistentNotificationPlugin(this));
|
||||||
pluginsList.add(NSClientInternalPlugin.getPlugin());
|
pluginsList.add(NSClientPlugin.getPlugin());
|
||||||
|
|
||||||
pluginsList.add(sConfigBuilder = ConfigBuilderFragment.getPlugin());
|
pluginsList.add(sConfigBuilder = ConfigBuilderPlugin.getPlugin());
|
||||||
|
|
||||||
MainApp.getConfigBuilder().initialize();
|
MainApp.getConfigBuilder().initialize();
|
||||||
}
|
}
|
||||||
NSUpload.uploadAppStart();
|
NSUpload.uploadAppStart();
|
||||||
|
|
||||||
if (Config.NSCLIENT)
|
if (Config.NSCLIENT)
|
||||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("AppStart-NSClient"));
|
FabricPrivacy.getInstance().logCustom(new CustomEvent("AppStart-NSClient"));
|
||||||
else if (Config.G5UPLOADER)
|
else if (Config.G5UPLOADER)
|
||||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("AppStart-G5Uploader"));
|
FabricPrivacy.getInstance().logCustom(new CustomEvent("AppStart-G5Uploader"));
|
||||||
else if (Config.PUMPCONTROL)
|
else if (Config.PUMPCONTROL)
|
||||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("AppStart-PumpControl"));
|
FabricPrivacy.getInstance().logCustom(new CustomEvent("AppStart-PumpControl"));
|
||||||
else if (MainApp.getConfigBuilder().isClosedModeEnabled())
|
else if (MainApp.getConstraintChecker().isClosedLoopAllowed().value())
|
||||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("AppStart-ClosedLoop"));
|
FabricPrivacy.getInstance().logCustom(new CustomEvent("AppStart-ClosedLoop"));
|
||||||
else
|
else
|
||||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("AppStart-OpenLoop"));
|
FabricPrivacy.getInstance().logCustom(new CustomEvent("AppStart-OpenLoop"));
|
||||||
|
|
||||||
new Thread(new Runnable() {
|
final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
|
||||||
@Override
|
if (pump != null) {
|
||||||
public void run() {
|
new Thread(() -> {
|
||||||
SystemClock.sleep(5000);
|
SystemClock.sleep(5000);
|
||||||
ConfigBuilderPlugin.getCommandQueue().readStatus("Initialization", null);
|
ConfigBuilderPlugin.getCommandQueue().readStatus("Initialization", null);
|
||||||
startKeepAliveService();
|
startKeepAliveService();
|
||||||
}
|
}).start();
|
||||||
}).start();
|
}
|
||||||
|
|
||||||
|
if (!isEngineeringModeOrRelease()) {
|
||||||
|
Notification n = new Notification(Notification.TOAST_ALARM, gs(R.string.closed_loop_disabled_on_dev_branch), Notification.NORMAL);
|
||||||
|
bus().post(new EventNewNotification(n));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerLocalBroadcastReceiver() {
|
private void registerLocalBroadcastReceiver() {
|
||||||
|
@ -256,9 +278,6 @@ public class MainApp extends Application {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DatabaseHelper getDbHelper() {
|
public static DatabaseHelper getDbHelper() {
|
||||||
if (sDatabaseHelper == null) {
|
|
||||||
sDatabaseHelper = OpenHelperManager.getHelper(sInstance, DatabaseHelper.class);
|
|
||||||
}
|
|
||||||
return sDatabaseHelper;
|
return sDatabaseHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,11 +292,15 @@ public class MainApp extends Application {
|
||||||
return sConfigBuilder;
|
return sConfigBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ConstraintChecker getConstraintChecker() {
|
||||||
|
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) {
|
||||||
|
@ -291,20 +314,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) {
|
||||||
|
@ -333,7 +343,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) {
|
||||||
|
@ -361,9 +371,23 @@ public class MainApp extends Application {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isEngineeringModeOrRelease() {
|
||||||
|
if (!BuildConfig.APS)
|
||||||
|
return true;
|
||||||
|
return engineeringMode || !devBranch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLogDirectory() {
|
||||||
|
LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
|
||||||
|
return lc.getProperty("EXT_FILES_DIR");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTerminate() {
|
public void onTerminate() {
|
||||||
super.onTerminate();
|
super.onTerminate();
|
||||||
sDatabaseHelper.close();
|
if (sDatabaseHelper != null) {
|
||||||
|
sDatabaseHelper.close();
|
||||||
|
sDatabaseHelper = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
package info.nightscout.androidaps;
|
package info.nightscout.androidaps;
|
||||||
|
|
||||||
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;
|
||||||
|
@ -16,14 +14,15 @@ import android.text.TextUtils;
|
||||||
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.OpenAPSSMB.OpenAPSSMBPlugin;
|
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.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;
|
||||||
|
@ -33,7 +32,7 @@ import info.nightscout.androidaps.plugins.SensitivityAAPS.SensitivityAAPSPlugin;
|
||||||
import info.nightscout.androidaps.plugins.SensitivityOref0.SensitivityOref0Plugin;
|
import info.nightscout.androidaps.plugins.SensitivityOref0.SensitivityOref0Plugin;
|
||||||
import info.nightscout.androidaps.plugins.SensitivityWeightedAverage.SensitivityWeightedAveragePlugin;
|
import info.nightscout.androidaps.plugins.SensitivityWeightedAverage.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;
|
||||||
|
@ -67,7 +66,7 @@ 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.sResources.getString(R.string.configbuilder_sensitivity), MainApp.sResources.getString(R.string.sensitivity_warning), null);
|
||||||
}
|
}
|
||||||
updatePrefSummary(myPreferenceFragment.getPreference(key));
|
updatePrefSummary(myPreferenceFragment.getPreference(key));
|
||||||
|
@ -113,7 +112,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());
|
||||||
}
|
}
|
||||||
|
@ -141,50 +140,50 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
|
||||||
if (!Config.NSCLIENT && !Config.G5UPLOADER) {
|
if (!Config.NSCLIENT && !Config.G5UPLOADER) {
|
||||||
addPreferencesFromResource(R.xml.pref_quickwizard);
|
addPreferencesFromResource(R.xml.pref_quickwizard);
|
||||||
}
|
}
|
||||||
addPreferencesFromResourceIfEnabled(SourceDexcomG5Plugin.getPlugin(), PluginBase.BGSOURCE);
|
addPreferencesFromResourceIfEnabled(SourceDexcomG5Plugin.getPlugin(), PluginType.BGSOURCE);
|
||||||
addPreferencesFromResourceIfEnabled(CareportalPlugin.getPlugin(), PluginBase.GENERAL);
|
addPreferencesFromResourceIfEnabled(CareportalPlugin.getPlugin(), PluginType.GENERAL);
|
||||||
addPreferencesFromResourceIfEnabled(SafetyPlugin.getPlugin(), PluginBase.CONSTRAINTS);
|
addPreferencesFromResourceIfEnabled(SafetyPlugin.getPlugin(), PluginType.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(), PluginBase.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);
|
||||||
|
|
||||||
if (Config.DANAR) {
|
if (Config.HWPUMPS) {
|
||||||
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);
|
||||||
|
|
||||||
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 && !Config.G5UPLOADER) {
|
||||||
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) {
|
if (!Config.NSCLIENT && !Config.G5UPLOADER) {
|
||||||
addPreferencesFromResource(R.xml.pref_others);
|
addPreferencesFromResource(R.xml.pref_others);
|
||||||
}
|
}
|
||||||
addPreferencesFromResource(R.xml.pref_advanced);
|
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());
|
||||||
|
|
|
@ -18,7 +18,7 @@ import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.data.ProfileStore;
|
import info.nightscout.androidaps.data.ProfileStore;
|
||||||
import info.nightscout.androidaps.db.BgReading;
|
import info.nightscout.androidaps.db.BgReading;
|
||||||
import info.nightscout.androidaps.db.CareportalEvent;
|
import info.nightscout.androidaps.db.CareportalEvent;
|
||||||
import info.nightscout.androidaps.events.EventNewBasalProfile;
|
import info.nightscout.androidaps.events.EventNsFood;
|
||||||
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.NSClientInternal.data.NSDeviceStatus;
|
import info.nightscout.androidaps.plugins.NSClientInternal.data.NSDeviceStatus;
|
||||||
|
@ -33,11 +33,11 @@ import info.nightscout.androidaps.plugins.ProfileNS.NSProfilePlugin;
|
||||||
import info.nightscout.androidaps.plugins.ProfileNS.events.EventNSProfileUpdateGUI;
|
import info.nightscout.androidaps.plugins.ProfileNS.events.EventNSProfileUpdateGUI;
|
||||||
import info.nightscout.androidaps.plugins.PumpDanaR.activities.DanaRNSHistorySync;
|
import info.nightscout.androidaps.plugins.PumpDanaR.activities.DanaRNSHistorySync;
|
||||||
import info.nightscout.androidaps.plugins.SmsCommunicator.events.EventNewSMS;
|
import info.nightscout.androidaps.plugins.SmsCommunicator.events.EventNewSMS;
|
||||||
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.SourceXdripPlugin;
|
||||||
import info.nightscout.androidaps.receivers.DataReceiver;
|
import info.nightscout.androidaps.receivers.DataReceiver;
|
||||||
import info.nightscout.utils.BundleLogger;
|
import info.nightscout.utils.BundleLogger;
|
||||||
import info.nightscout.utils.NSUpload;
|
import info.nightscout.utils.NSUpload;
|
||||||
|
@ -62,32 +62,37 @@ public class DataService extends IntentService {
|
||||||
protected void onHandleIntent(final Intent intent) {
|
protected void onHandleIntent(final Intent intent) {
|
||||||
if (Config.logFunctionCalls)
|
if (Config.logFunctionCalls)
|
||||||
log.debug("onHandleIntent " + BundleLogger.log(intent.getExtras()));
|
log.debug("onHandleIntent " + BundleLogger.log(intent.getExtras()));
|
||||||
|
if (ConfigBuilderPlugin.getPlugin().getActiveBgSource() == null) {
|
||||||
if (ConfigBuilderPlugin.getActiveBgSource().getClass().equals(SourceXdripPlugin.class)) {
|
|
||||||
xDripEnabled = true;
|
xDripEnabled = true;
|
||||||
nsClientEnabled = false;
|
nsClientEnabled = false;
|
||||||
mm640gEnabled = false;
|
mm640gEnabled = false;
|
||||||
glimpEnabled = false;
|
glimpEnabled = false;
|
||||||
dexcomG5Enabled = false;
|
dexcomG5Enabled = false;
|
||||||
} else if (ConfigBuilderPlugin.getActiveBgSource().getClass().equals(SourceNSClientPlugin.class)) {
|
} else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceXdripPlugin.class)) {
|
||||||
|
xDripEnabled = true;
|
||||||
|
nsClientEnabled = false;
|
||||||
|
mm640gEnabled = false;
|
||||||
|
glimpEnabled = false;
|
||||||
|
dexcomG5Enabled = false;
|
||||||
|
} else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceNSClientPlugin.class)) {
|
||||||
xDripEnabled = false;
|
xDripEnabled = false;
|
||||||
nsClientEnabled = true;
|
nsClientEnabled = true;
|
||||||
mm640gEnabled = false;
|
mm640gEnabled = false;
|
||||||
glimpEnabled = false;
|
glimpEnabled = false;
|
||||||
dexcomG5Enabled = false;
|
dexcomG5Enabled = false;
|
||||||
} else if (ConfigBuilderPlugin.getActiveBgSource().getClass().equals(SourceMM640gPlugin.class)) {
|
} else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceMM640gPlugin.class)) {
|
||||||
xDripEnabled = false;
|
xDripEnabled = false;
|
||||||
nsClientEnabled = false;
|
nsClientEnabled = false;
|
||||||
mm640gEnabled = true;
|
mm640gEnabled = true;
|
||||||
glimpEnabled = false;
|
glimpEnabled = false;
|
||||||
dexcomG5Enabled = false;
|
dexcomG5Enabled = false;
|
||||||
} else if (ConfigBuilderPlugin.getActiveBgSource().getClass().equals(SourceGlimpPlugin.class)) {
|
} else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceGlimpPlugin.class)) {
|
||||||
xDripEnabled = false;
|
xDripEnabled = false;
|
||||||
nsClientEnabled = false;
|
nsClientEnabled = false;
|
||||||
mm640gEnabled = false;
|
mm640gEnabled = false;
|
||||||
glimpEnabled = true;
|
glimpEnabled = true;
|
||||||
dexcomG5Enabled = false;
|
dexcomG5Enabled = false;
|
||||||
} else if (ConfigBuilderPlugin.getActiveBgSource().getClass().equals(SourceDexcomG5Plugin.class)) {
|
} else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceDexcomG5Plugin.class)) {
|
||||||
xDripEnabled = false;
|
xDripEnabled = false;
|
||||||
nsClientEnabled = false;
|
nsClientEnabled = false;
|
||||||
mm640gEnabled = false;
|
mm640gEnabled = false;
|
||||||
|
@ -95,7 +100,7 @@ public class DataService extends IntentService {
|
||||||
dexcomG5Enabled = true;
|
dexcomG5Enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isNSProfile = ConfigBuilderPlugin.getActiveProfileInterface().getClass().equals(NSProfilePlugin.class);
|
boolean isNSProfile = MainApp.getConfigBuilder().getActiveProfileInterface() != null && MainApp.getConfigBuilder().getActiveProfileInterface().getClass().equals(NSProfilePlugin.class);
|
||||||
|
|
||||||
boolean acceptNSData = !SP.getBoolean(R.string.key_ns_upload_only, false);
|
boolean acceptNSData = !SP.getBoolean(R.string.key_ns_upload_only, false);
|
||||||
Bundle bundles = intent.getExtras();
|
Bundle bundles = intent.getExtras();
|
||||||
|
@ -123,8 +128,8 @@ public class DataService extends IntentService {
|
||||||
handleNewDataFromDexcomG5(intent);
|
handleNewDataFromDexcomG5(intent);
|
||||||
}
|
}
|
||||||
} else if (Intents.ACTION_NEW_SGV.equals(action)) {
|
} else if (Intents.ACTION_NEW_SGV.equals(action)) {
|
||||||
// always backfill SGV from NS
|
if (nsClientEnabled || SP.getBoolean(R.string.ns_autobackfill, true))
|
||||||
handleNewDataFromNSClient(intent);
|
handleNewDataFromNSClient(intent);
|
||||||
// Objectives 0
|
// Objectives 0
|
||||||
ObjectivesPlugin.bgIsAvailableInNS = true;
|
ObjectivesPlugin.bgIsAvailableInNS = true;
|
||||||
ObjectivesPlugin.saveProgress();
|
ObjectivesPlugin.saveProgress();
|
||||||
|
@ -222,7 +227,7 @@ public class DataService extends IntentService {
|
||||||
try {
|
try {
|
||||||
JSONArray jsonArray = new JSONArray(data);
|
JSONArray jsonArray = new JSONArray(data);
|
||||||
log.debug("Received Dexcom Data size:" + jsonArray.length());
|
log.debug("Received Dexcom Data size:" + jsonArray.length());
|
||||||
for(int i = 0; i < jsonArray.length(); i++) {
|
for (int i = 0; i < jsonArray.length(); i++) {
|
||||||
JSONObject json = jsonArray.getJSONObject(i);
|
JSONObject json = jsonArray.getJSONObject(i);
|
||||||
bgReading.value = json.getInt("m_value");
|
bgReading.value = json.getInt("m_value");
|
||||||
bgReading.direction = json.getString("m_trend");
|
bgReading.direction = json.getString("m_trend");
|
||||||
|
@ -365,11 +370,8 @@ public class DataService extends IntentService {
|
||||||
String activeProfile = bundles.getString("activeprofile");
|
String activeProfile = bundles.getString("activeprofile");
|
||||||
String profile = bundles.getString("profile");
|
String profile = bundles.getString("profile");
|
||||||
ProfileStore profileStore = new ProfileStore(new JSONObject(profile));
|
ProfileStore profileStore = new ProfileStore(new JSONObject(profile));
|
||||||
NSProfilePlugin.storeNewProfile(profileStore);
|
NSProfilePlugin.getPlugin().storeNewProfile(profileStore);
|
||||||
MainApp.bus().post(new EventNSProfileUpdateGUI());
|
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)
|
if (Config.logIncommingData)
|
||||||
log.debug("Received profileStore: " + activeProfile + " " + profile);
|
log.debug("Received profileStore: " + activeProfile + " " + profile);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
|
@ -474,57 +476,19 @@ public class DataService extends IntentService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (intent.getAction().equals(Intents.ACTION_NEW_FOOD) || intent.getAction().equals(Intents.ACTION_CHANGED_FOOD)) {
|
if (intent.getAction().equals(Intents.ACTION_NEW_FOOD)
|
||||||
try {
|
|| intent.getAction().equals(Intents.ACTION_CHANGED_FOOD)) {
|
||||||
if (bundles.containsKey("food")) {
|
int mode = Intents.ACTION_NEW_FOOD.equals(intent.getAction()) ? EventNsFood.ADD : EventNsFood.UPDATE;
|
||||||
String trstring = bundles.getString("food");
|
EventNsFood evt = new EventNsFood(mode, bundles);
|
||||||
handleAddChangeFoodRecord(new JSONObject(trstring));
|
MainApp.bus().post(evt);
|
||||||
}
|
|
||||||
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)) {
|
if (intent.getAction().equals(Intents.ACTION_REMOVED_FOOD)) {
|
||||||
try {
|
EventNsFood evt = new EventNsFood(EventNsFood.REMOVE, bundles);
|
||||||
if (bundles.containsKey("food")) {
|
MainApp.bus().post(evt);
|
||||||
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) {
|
private void handleRemovedRecordFromNS(String _id) {
|
||||||
MainApp.getDbHelper().deleteTreatmentById(_id);
|
MainApp.getDbHelper().deleteTreatmentById(_id);
|
||||||
MainApp.getDbHelper().deleteTempTargetById(_id);
|
MainApp.getDbHelper().deleteTempTargetById(_id);
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
package info.nightscout.androidaps.plugins.PumpDanaR.activities;
|
package info.nightscout.androidaps;
|
||||||
|
|
||||||
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;
|
||||||
|
@ -35,21 +33,26 @@ import java.util.Date;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import info.nightscout.androidaps.MainApp;
|
|
||||||
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.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.DanaRPlugin;
|
||||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.RecordTypes;
|
import info.nightscout.androidaps.plugins.PumpDanaR.comm.RecordTypes;
|
||||||
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 +63,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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,10 +235,10 @@ public class DanaRStatsActivity extends Activity {
|
||||||
statsMessage.setText(getString(R.string.danar_stats_warning_Message));
|
statsMessage.setText(getString(R.string.danar_stats_warning_Message));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
ConfigBuilderPlugin.getCommandQueue().loadHistory(RecordTypes.RECORD_TYPE_DAILY, new Callback() {
|
ConfigBuilderPlugin.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 +271,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 +291,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 +336,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 +353,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 +388,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 +412,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,7 +436,7 @@ 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)) {
|
||||||
statsMessage.setVisibility(View.VISIBLE);
|
statsMessage.setVisibility(View.VISIBLE);
|
||||||
statsMessage.setText(getString(R.string.danar_stats_olddata_Message));
|
statsMessage.setText(getString(R.string.danar_stats_olddata_Message));
|
||||||
|
|
||||||
|
@ -427,12 +444,17 @@ public class DanaRStatsActivity extends Activity {
|
||||||
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 +469,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 +477,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 +491,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 +538,19 @@ public class DanaRStatsActivity extends Activity {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static boolean isOldData(List<TDD> historyList) {
|
||||||
|
Object activePump = MainApp.getConfigBuilder().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,198 @@
|
||||||
|
package info.nightscout.androidaps.data;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.Constants;
|
||||||
|
import info.nightscout.androidaps.MainApp;
|
||||||
|
import info.nightscout.androidaps.interfaces.BgSourceInterface;
|
||||||
|
import info.nightscout.androidaps.interfaces.Constraint;
|
||||||
|
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
|
||||||
|
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||||
|
import info.nightscout.androidaps.interfaces.PluginType;
|
||||||
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 isLoopInvokationAllowed(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> 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<Integer> getMaxCarbsAllowed() {
|
||||||
|
return applyCarbsConstraints(new Constraint<>(Constants.REALLYHIGHCARBS));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Constraint<Double> getMaxIOBAllowed() {
|
||||||
|
return applyMaxIOBConstraints(new Constraint<>(Constants.REALLYHIGHIOB));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Constraint<Boolean> isLoopInvokationAllowed(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.isLoopInvokationAllowed(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> 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<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,14 @@ 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;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by mike on 29.05.2017.
|
* Created by mike on 29.05.2017.
|
||||||
|
@ -31,6 +31,25 @@ public class DetailedBolusInfo {
|
||||||
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 long deliverAt = 0; // SMB should be delivered within 1 min from this time
|
||||||
|
|
||||||
|
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;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return new Date(date).toLocaleString() +
|
return new Date(date).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;
|
||||||
|
|
||||||
|
@ -40,17 +41,10 @@ public class GlucoseStatus {
|
||||||
|
|
||||||
@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() {
|
||||||
|
@ -75,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -35,20 +37,9 @@ public class IobTotal {
|
||||||
long time;
|
long time;
|
||||||
|
|
||||||
|
|
||||||
public IobTotal clone() {
|
public IobTotal copy() {
|
||||||
IobTotal copy = new IobTotal(time);
|
Cloner cloner = new Cloner();
|
||||||
copy.iob = iob;
|
return cloner.deepClone(this);
|
||||||
copy.activity = activity;
|
|
||||||
copy.bolussnooze = bolussnooze;
|
|
||||||
copy.basaliob = basaliob;
|
|
||||||
copy.netbasalinsulin = netbasalinsulin;
|
|
||||||
copy.hightempinsulin = hightempinsulin;
|
|
||||||
copy.lastBolusTime = lastBolusTime;
|
|
||||||
copy.lastTempDate = lastTempDate;
|
|
||||||
copy.lastTempDuration = lastTempDuration;
|
|
||||||
copy.lastTempRate = lastTempRate;
|
|
||||||
copy.iobWithZeroTemp = iobWithZeroTemp;
|
|
||||||
return copy;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IobTotal(long time) {
|
public IobTotal(long time) {
|
||||||
|
@ -82,6 +73,8 @@ public class IobTotal {
|
||||||
result.basaliob = bolusIOB.basaliob + basalIob.basaliob;
|
result.basaliob = bolusIOB.basaliob + basalIob.basaliob;
|
||||||
result.netbasalinsulin = bolusIOB.netbasalinsulin + basalIob.netbasalinsulin;
|
result.netbasalinsulin = bolusIOB.netbasalinsulin + basalIob.netbasalinsulin;
|
||||||
result.hightempinsulin = basalIob.hightempinsulin + bolusIOB.hightempinsulin;
|
result.hightempinsulin = basalIob.hightempinsulin + bolusIOB.hightempinsulin;
|
||||||
|
result.netInsulin = basalIob.netInsulin + bolusIOB.netInsulin;
|
||||||
|
result.extendedBolusInsulin = basalIob.extendedBolusInsulin + bolusIOB.extendedBolusInsulin;
|
||||||
result.lastBolusTime = bolusIOB.lastBolusTime;
|
result.lastBolusTime = bolusIOB.lastBolusTime;
|
||||||
result.lastTempDate = basalIob.lastTempDate;
|
result.lastTempDate = basalIob.lastTempDate;
|
||||||
result.lastTempRate = basalIob.lastTempRate;
|
result.lastTempRate = basalIob.lastTempRate;
|
||||||
|
@ -97,6 +90,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.netInsulin = Round.roundTo(this.netInsulin, 0.001);
|
||||||
|
this.extendedBolusInsulin = Round.roundTo(this.extendedBolusInsulin, 0.001);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
@ -19,41 +17,43 @@ import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
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.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.FabricPrivacy;
|
import info.nightscout.utils.FabricPrivacy;
|
||||||
import info.nightscout.utils.ToastUtils;
|
|
||||||
|
|
||||||
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() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
@ -65,6 +65,22 @@ public class Profile {
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
@ -78,53 +94,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;
|
||||||
}
|
}
|
||||||
|
@ -133,7 +108,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();
|
||||||
|
@ -155,6 +130,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;
|
||||||
}
|
}
|
||||||
|
@ -164,6 +143,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<>();
|
||||||
|
@ -218,22 +202,24 @@ public class Profile {
|
||||||
|
|
||||||
if (isValid) {
|
if (isValid) {
|
||||||
// Check for hours alignment
|
// Check for hours alignment
|
||||||
for (int index = 0; index < basal_v.size(); index++) {
|
PumpInterface pump = MainApp.getConfigBuilder().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 (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)));
|
sendBelowMinimumNotification(from);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -247,6 +233,10 @@ public class Profile {
|
||||||
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)));
|
||||||
|
}
|
||||||
|
|
||||||
private void validate(LongSparseArray array) {
|
private void validate(LongSparseArray array) {
|
||||||
if (array.size() == 0) {
|
if (array.size() == 0) {
|
||||||
isValid = false;
|
isValid = false;
|
||||||
|
@ -260,6 +250,7 @@ public class Profile {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
private Double getValueToTime(JSONArray array, Integer timeAsSeconds) {
|
private Double getValueToTime(JSONArray array, Integer timeAsSeconds) {
|
||||||
Double lastValue = null;
|
Double lastValue = null;
|
||||||
|
|
||||||
|
@ -279,6 +270,7 @@ 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;
|
||||||
|
@ -320,7 +312,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++) {
|
||||||
|
@ -335,7 +327,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;
|
||||||
|
@ -362,51 +354,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);
|
||||||
}
|
}
|
||||||
|
@ -416,17 +412,17 @@ public class Profile {
|
||||||
public String getBasalList() {
|
public String getBasalList() {
|
||||||
if (basal_v == null)
|
if (basal_v == null)
|
||||||
basal_v = convertToSparseArray(basal);
|
basal_v = convertToSparseArray(basal);
|
||||||
return getValuesList(basal_v, null, new DecimalFormat("0.00"), "U");
|
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() {
|
||||||
|
@ -436,7 +432,7 @@ 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;
|
||||||
|
@ -446,52 +442,56 @@ public class Profile {
|
||||||
return getTarget(secondsFromMidnight(System.currentTimeMillis()));
|
return getTarget(secondsFromMidnight(System.currentTimeMillis()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private double getTarget(Integer time) {
|
protected double getTarget(int timeAsSeconds) {
|
||||||
return (getTargetLow(time) + getTargetHigh(time))/2;
|
return (getTargetLowTimeFromMidnight(timeAsSeconds) + getTargetHighTimeFromMidnight(timeAsSeconds))/2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Double getTargetLow() {
|
public double getTargetLow() {
|
||||||
return getTargetLow(secondsFromMidnight(System.currentTimeMillis()));
|
return getTargetLowTimeFromMidnight(secondsFromMidnight(System.currentTimeMillis()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Double getTargetLow(long time) {
|
public double getTargetLow(long time) {
|
||||||
return getTargetLow(secondsFromMidnight(time));
|
return getTargetLowTimeFromMidnight(secondsFromMidnight(time));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Double getTargetLow(Integer timeAsSeconds) {
|
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);
|
||||||
|
@ -502,7 +502,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);
|
||||||
|
@ -513,22 +513,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;
|
||||||
}
|
}
|
||||||
|
@ -554,7 +554,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;
|
||||||
}
|
}
|
||||||
|
@ -563,7 +563,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();
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -13,7 +13,7 @@ import info.nightscout.androidaps.R;
|
||||||
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(PumpEnactResult.class);
|
||||||
|
|
||||||
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)
|
||||||
|
@ -21,19 +21,19 @@ public class PumpEnactResult extends Object {
|
||||||
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,20 +47,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(Integer percent) {
|
public PumpEnactResult percent(int percent) {
|
||||||
this.percent = percent;
|
this.percent = percent;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PumpEnactResult isPercent(boolean isPercent) {
|
public PumpEnactResult isPercent(boolean isPercent) {
|
||||||
this.isPercent = isPercent;
|
this.isPercent = isPercent;
|
||||||
return this;
|
return this;
|
||||||
|
@ -71,12 +72,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;
|
||||||
}
|
}
|
||||||
|
@ -86,75 +87,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.smb_shortname)
|
||||||
|
+ ": " + 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 = "<b>" + MainApp.sResources.getString(R.string.success) + "</b>: " + 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) {
|
|
||||||
ret += "<br><b>" + MainApp.sResources.getString(R.string.enacted) + "</b>: " + enacted;
|
|
||||||
ret += "<br><b>" + MainApp.sResources.getString(R.string.comment) + "</b>: " + comment +
|
|
||||||
"<br>" + MainApp.sResources.getString(R.string.canceltemp);
|
|
||||||
} else if (isPercent && percent != -1) {
|
|
||||||
ret += "<br><b>" + MainApp.sResources.getString(R.string.enacted) + "</b>: " + enacted;
|
|
||||||
ret += "<br><b>" + MainApp.sResources.getString(R.string.comment) + "</b>: " + comment;
|
|
||||||
ret += "<br><b>" + MainApp.sResources.getString(R.string.duration) + "</b>: " + duration + " min";
|
|
||||||
ret += "<br><b>" + MainApp.sResources.getString(R.string.percent) + "</b>: " + percent + "%";
|
|
||||||
} else if (absolute != -1) {
|
|
||||||
ret += "<br><b>" + MainApp.sResources.getString(R.string.enacted) + "</b>: " + enacted;
|
|
||||||
ret += "<br><b>" + MainApp.sResources.getString(R.string.comment) + "</b>: " + comment;
|
|
||||||
ret += "<br><b>" + MainApp.sResources.getString(R.string.duration) + "</b>: " + duration + " min";
|
|
||||||
ret += "<br><b>" + MainApp.sResources.getString(R.string.absolute) + "</b>: " + DecimalFormatter.to2Decimal(absolute) + " U/h";
|
|
||||||
}
|
|
||||||
if (bolusDelivered > 0) {
|
if (bolusDelivered > 0) {
|
||||||
ret += "<br><b>" + MainApp.sResources.getString(R.string.bolus) + "</b>: " + DecimalFormatter.to2Decimal(bolusDelivered) + " U";
|
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.smb_shortname) + "</b>: " + bolusDelivered + " " + MainApp.gs(R.string.insulin_unit_shortname);
|
||||||
|
} else if (isTempCancel) {
|
||||||
|
ret += "<br><b>" + MainApp.gs(R.string.enacted) + "</b>: " + enacted;
|
||||||
|
ret += "<br><b>" + MainApp.gs(R.string.comment) + "</b>: " + comment +
|
||||||
|
"<br>" + MainApp.gs(R.string.canceltemp);
|
||||||
|
} else if (isPercent && percent != -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.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 {
|
||||||
|
|
|
@ -7,7 +7,6 @@ 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;
|
||||||
|
@ -16,6 +15,7 @@ import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||||
import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensData;
|
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;
|
||||||
|
@ -102,7 +102,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;
|
||||||
|
|
|
@ -35,7 +35,6 @@ import info.nightscout.androidaps.data.Profile;
|
||||||
import info.nightscout.androidaps.data.ProfileStore;
|
import info.nightscout.androidaps.data.ProfileStore;
|
||||||
import info.nightscout.androidaps.events.EventCareportalEventChange;
|
import info.nightscout.androidaps.events.EventCareportalEventChange;
|
||||||
import info.nightscout.androidaps.events.EventExtendedBolusChange;
|
import info.nightscout.androidaps.events.EventExtendedBolusChange;
|
||||||
import info.nightscout.androidaps.events.EventFoodDatabaseChanged;
|
|
||||||
import info.nightscout.androidaps.events.EventNewBG;
|
import info.nightscout.androidaps.events.EventNewBG;
|
||||||
import info.nightscout.androidaps.events.EventProfileSwitchChange;
|
import info.nightscout.androidaps.events.EventProfileSwitchChange;
|
||||||
import info.nightscout.androidaps.events.EventRefreshOverview;
|
import info.nightscout.androidaps.events.EventRefreshOverview;
|
||||||
|
@ -50,11 +49,21 @@ import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventNewHistor
|
||||||
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.androidaps.plugins.PumpDanaR.activities.DanaRNSHistorySync;
|
import info.nightscout.androidaps.plugins.PumpDanaR.activities.DanaRNSHistorySync;
|
||||||
|
import info.nightscout.androidaps.plugins.PumpDanaR.comm.RecordTypes;
|
||||||
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
|
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
|
||||||
import info.nightscout.utils.DateUtil;
|
import info.nightscout.utils.DateUtil;
|
||||||
import info.nightscout.utils.NSUpload;
|
import info.nightscout.utils.NSUpload;
|
||||||
import info.nightscout.utils.PercentageSplitter;
|
import info.nightscout.utils.PercentageSplitter;
|
||||||
|
import info.nightscout.utils.ToastUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This Helper contains all resource to provide a central DB management functionality. Only methods handling
|
||||||
|
* data-structure (and not the DB content) should be contained in here (meaning DDL and not SQL).
|
||||||
|
* <p>
|
||||||
|
* This class can safely be called from Services, but should not call Services to avoid circular dependencies.
|
||||||
|
* One major issue with this (right now) are the scheduled events, which are put into the service. Therefor all
|
||||||
|
* direct calls to the corresponding methods (eg. resetDatabases) should be done by a central service.
|
||||||
|
*/
|
||||||
public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
private static Logger log = LoggerFactory.getLogger(DatabaseHelper.class);
|
private static Logger log = LoggerFactory.getLogger(DatabaseHelper.class);
|
||||||
|
|
||||||
|
@ -68,7 +77,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
public static final String DATABASE_DBREQUESTS = "DBRequests";
|
public static final String DATABASE_DBREQUESTS = "DBRequests";
|
||||||
public static final String DATABASE_CAREPORTALEVENTS = "CareportalEvents";
|
public static final String DATABASE_CAREPORTALEVENTS = "CareportalEvents";
|
||||||
public static final String DATABASE_PROFILESWITCHES = "ProfileSwitches";
|
public static final String DATABASE_PROFILESWITCHES = "ProfileSwitches";
|
||||||
public static final String DATABASE_FOODS = "Foods";
|
public static final String DATABASE_TDDS = "TDDs";
|
||||||
|
|
||||||
private static final int DATABASE_VERSION = 8;
|
private static final int DATABASE_VERSION = 8;
|
||||||
|
|
||||||
|
@ -95,7 +104,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
private static final ScheduledExecutorService profileSwitchEventWorker = Executors.newSingleThreadScheduledExecutor();
|
private static final ScheduledExecutorService profileSwitchEventWorker = Executors.newSingleThreadScheduledExecutor();
|
||||||
private static ScheduledFuture<?> scheduledProfileSwitchEventPost = null;
|
private static ScheduledFuture<?> scheduledProfileSwitchEventPost = null;
|
||||||
|
|
||||||
public FoodHelper foodHelper = new FoodHelper(this);
|
private int oldVersion = 0;
|
||||||
|
private int newVersion = 0;
|
||||||
|
|
||||||
public DatabaseHelper(Context context) {
|
public DatabaseHelper(Context context) {
|
||||||
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||||
|
@ -116,7 +126,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
TableUtils.createTableIfNotExists(connectionSource, ExtendedBolus.class);
|
TableUtils.createTableIfNotExists(connectionSource, ExtendedBolus.class);
|
||||||
TableUtils.createTableIfNotExists(connectionSource, CareportalEvent.class);
|
TableUtils.createTableIfNotExists(connectionSource, CareportalEvent.class);
|
||||||
TableUtils.createTableIfNotExists(connectionSource, ProfileSwitch.class);
|
TableUtils.createTableIfNotExists(connectionSource, ProfileSwitch.class);
|
||||||
TableUtils.createTableIfNotExists(connectionSource, Food.class);
|
TableUtils.createTableIfNotExists(connectionSource, TDD.class);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
log.error("Can't create database", e);
|
log.error("Can't create database", e);
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
|
@ -126,6 +136,9 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
@Override
|
@Override
|
||||||
public void onUpgrade(SQLiteDatabase database, ConnectionSource connectionSource, int oldVersion, int newVersion) {
|
public void onUpgrade(SQLiteDatabase database, ConnectionSource connectionSource, int oldVersion, int newVersion) {
|
||||||
try {
|
try {
|
||||||
|
this.oldVersion = oldVersion;
|
||||||
|
this.newVersion = newVersion;
|
||||||
|
|
||||||
if (oldVersion == 7 && newVersion == 8) {
|
if (oldVersion == 7 && newVersion == 8) {
|
||||||
log.debug("Upgrading database from v7 to v8");
|
log.debug("Upgrading database from v7 to v8");
|
||||||
TableUtils.dropTable(connectionSource, Treatment.class, true);
|
TableUtils.dropTable(connectionSource, Treatment.class, true);
|
||||||
|
@ -141,7 +154,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
TableUtils.dropTable(connectionSource, ExtendedBolus.class, true);
|
TableUtils.dropTable(connectionSource, ExtendedBolus.class, true);
|
||||||
TableUtils.dropTable(connectionSource, CareportalEvent.class, true);
|
TableUtils.dropTable(connectionSource, CareportalEvent.class, true);
|
||||||
TableUtils.dropTable(connectionSource, ProfileSwitch.class, true);
|
TableUtils.dropTable(connectionSource, ProfileSwitch.class, true);
|
||||||
TableUtils.dropTable(connectionSource, Food.class, true);
|
|
||||||
onCreate(database, connectionSource);
|
onCreate(database, connectionSource);
|
||||||
}
|
}
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
|
@ -150,6 +162,14 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getOldVersion() {
|
||||||
|
return oldVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNewVersion() {
|
||||||
|
return newVersion;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close the database connections and clear any cached DAOs.
|
* Close the database connections and clear any cached DAOs.
|
||||||
*/
|
*/
|
||||||
|
@ -210,6 +230,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
TableUtils.dropTable(connectionSource, ExtendedBolus.class, true);
|
TableUtils.dropTable(connectionSource, ExtendedBolus.class, true);
|
||||||
TableUtils.dropTable(connectionSource, CareportalEvent.class, true);
|
TableUtils.dropTable(connectionSource, CareportalEvent.class, true);
|
||||||
TableUtils.dropTable(connectionSource, ProfileSwitch.class, true);
|
TableUtils.dropTable(connectionSource, ProfileSwitch.class, true);
|
||||||
|
TableUtils.dropTable(connectionSource, TDD.class, true);
|
||||||
TableUtils.createTableIfNotExists(connectionSource, TempTarget.class);
|
TableUtils.createTableIfNotExists(connectionSource, TempTarget.class);
|
||||||
TableUtils.createTableIfNotExists(connectionSource, Treatment.class);
|
TableUtils.createTableIfNotExists(connectionSource, Treatment.class);
|
||||||
TableUtils.createTableIfNotExists(connectionSource, BgReading.class);
|
TableUtils.createTableIfNotExists(connectionSource, BgReading.class);
|
||||||
|
@ -219,7 +240,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
TableUtils.createTableIfNotExists(connectionSource, ExtendedBolus.class);
|
TableUtils.createTableIfNotExists(connectionSource, ExtendedBolus.class);
|
||||||
TableUtils.createTableIfNotExists(connectionSource, CareportalEvent.class);
|
TableUtils.createTableIfNotExists(connectionSource, CareportalEvent.class);
|
||||||
TableUtils.createTableIfNotExists(connectionSource, ProfileSwitch.class);
|
TableUtils.createTableIfNotExists(connectionSource, ProfileSwitch.class);
|
||||||
foodHelper.resetFood();
|
TableUtils.createTableIfNotExists(connectionSource, TDD.class);
|
||||||
updateEarliestDataChange(0);
|
updateEarliestDataChange(0);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception", e);
|
||||||
|
@ -232,7 +253,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
scheduleTemporaryTargetChange();
|
scheduleTemporaryTargetChange();
|
||||||
scheduleCareportalEventChange();
|
scheduleCareportalEventChange();
|
||||||
scheduleProfileSwitchChange();
|
scheduleProfileSwitchChange();
|
||||||
foodHelper.scheduleFoodChange();
|
|
||||||
new java.util.Timer().schedule(
|
new java.util.Timer().schedule(
|
||||||
new java.util.TimerTask() {
|
new java.util.TimerTask() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -308,6 +328,15 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
scheduleProfileSwitchChange();
|
scheduleProfileSwitchChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void resetTDDs() {
|
||||||
|
try {
|
||||||
|
TableUtils.dropTable(connectionSource, TDD.class, true);
|
||||||
|
TableUtils.createTableIfNotExists(connectionSource, TDD.class);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error("Unhandled exception", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------ getDao -------------------------------------------
|
// ------------------ getDao -------------------------------------------
|
||||||
|
|
||||||
private Dao<TempTarget, Long> getDaoTempTargets() throws SQLException {
|
private Dao<TempTarget, Long> getDaoTempTargets() throws SQLException {
|
||||||
|
@ -326,6 +355,10 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
return getDao(DanaRHistoryRecord.class);
|
return getDao(DanaRHistoryRecord.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Dao<TDD, String> getDaoTDD() throws SQLException {
|
||||||
|
return getDao(TDD.class);
|
||||||
|
}
|
||||||
|
|
||||||
private Dao<DbRequest, String> getDaoDbRequest() throws SQLException {
|
private Dao<DbRequest, String> getDaoDbRequest() throws SQLException {
|
||||||
return getDao(DbRequest.class);
|
return getDao(DbRequest.class);
|
||||||
}
|
}
|
||||||
|
@ -479,6 +512,34 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
return new ArrayList<BgReading>();
|
return new ArrayList<BgReading>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------- TDD handling -----------------------
|
||||||
|
public void createOrUpdateTDD(TDD tdd){
|
||||||
|
try {
|
||||||
|
Dao<TDD, String> dao = getDaoTDD();
|
||||||
|
dao.createOrUpdate(tdd);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
ToastUtils.showToastInUiThread(MainApp.instance(), "createOrUpdate-Exception");
|
||||||
|
log.error("Unhandled exception", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<TDD> getTDDs() {
|
||||||
|
List<TDD> tddList;
|
||||||
|
try {
|
||||||
|
QueryBuilder<TDD, String> queryBuilder = getDaoTDD().queryBuilder();
|
||||||
|
queryBuilder.orderBy("date", false);
|
||||||
|
queryBuilder.limit(10L);
|
||||||
|
PreparedQuery<TDD> preparedQuery = queryBuilder.prepare();
|
||||||
|
tddList = getDaoTDD().query(preparedQuery);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error("Unhandled exception", e);
|
||||||
|
tddList = new ArrayList<>();
|
||||||
|
}
|
||||||
|
return tddList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ------------- DbRequests handling -------------------
|
// ------------- DbRequests handling -------------------
|
||||||
|
|
||||||
public void create(DbRequest dbr) {
|
public void create(DbRequest dbr) {
|
||||||
|
@ -558,6 +619,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
List<Treatment> trList = getDaoTreatments().query(preparedQuery);
|
List<Treatment> trList = getDaoTreatments().query(preparedQuery);
|
||||||
if (trList.size() > 0) {
|
if (trList.size() > 0) {
|
||||||
// do nothing, pump history record cannot be changed
|
// do nothing, pump history record cannot be changed
|
||||||
|
log.debug("TREATMENT: Pump record already found in database: " + treatment.toString());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
getDaoTreatments().create(treatment);
|
getDaoTreatments().create(treatment);
|
||||||
|
@ -877,14 +939,14 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
public void createTemptargetFromJsonIfNotExists(JSONObject trJson) {
|
public void createTemptargetFromJsonIfNotExists(JSONObject trJson) {
|
||||||
try {
|
try {
|
||||||
String units = MainApp.getConfigBuilder().getProfileUnits();
|
String units = MainApp.getConfigBuilder().getProfileUnits();
|
||||||
TempTarget tempTarget = new TempTarget();
|
TempTarget tempTarget = new TempTarget()
|
||||||
tempTarget.date = trJson.getLong("mills");
|
.date(trJson.getLong("mills"))
|
||||||
tempTarget.durationInMinutes = trJson.getInt("duration");
|
.duration(trJson.getInt("duration"))
|
||||||
tempTarget.low = Profile.toMgdl(trJson.getDouble("targetBottom"), units);
|
.low(Profile.toMgdl(trJson.getDouble("targetBottom"), units))
|
||||||
tempTarget.high = Profile.toMgdl(trJson.getDouble("targetTop"), units);
|
.high(Profile.toMgdl(trJson.getDouble("targetTop"), units))
|
||||||
tempTarget.reason = trJson.getString("reason");
|
.reason(trJson.getString("reason"))
|
||||||
tempTarget._id = trJson.getString("_id");
|
._id(trJson.getString("_id"))
|
||||||
tempTarget.source = Source.NIGHTSCOUT;
|
.source(Source.NIGHTSCOUT);
|
||||||
createOrUpdate(tempTarget);
|
createOrUpdate(tempTarget);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception", e);
|
||||||
|
@ -924,6 +986,12 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
public void createOrUpdate(DanaRHistoryRecord record) {
|
public void createOrUpdate(DanaRHistoryRecord record) {
|
||||||
try {
|
try {
|
||||||
getDaoDanaRHistory().createOrUpdate(record);
|
getDaoDanaRHistory().createOrUpdate(record);
|
||||||
|
|
||||||
|
//If it is a TDD, store it for stats also.
|
||||||
|
if(record.recordCode == RecordTypes.RECORD_TYPE_DAILY){
|
||||||
|
createOrUpdateTDD(new TDD(record.recordDate, record.recordDailyBolus, record.recordDailyBasal, 0));
|
||||||
|
}
|
||||||
|
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
|
@ -1153,10 +1221,10 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
}
|
}
|
||||||
createOrUpdate(extendedBolus);
|
createOrUpdate(extendedBolus);
|
||||||
} else {
|
} else {
|
||||||
TemporaryBasal tempBasal = new TemporaryBasal();
|
TemporaryBasal tempBasal = new TemporaryBasal()
|
||||||
tempBasal.date = trJson.getLong("mills");
|
.date(trJson.getLong("mills"))
|
||||||
tempBasal.source = Source.NIGHTSCOUT;
|
.source(Source.NIGHTSCOUT)
|
||||||
tempBasal.pumpId = trJson.has("pumpId") ? trJson.getLong("pumpId") : 0;
|
.pumpId(trJson.has("pumpId") ? trJson.getLong("pumpId") : 0);
|
||||||
if (trJson.has("duration")) {
|
if (trJson.has("duration")) {
|
||||||
tempBasal.durationInMinutes = trJson.getInt("duration");
|
tempBasal.durationInMinutes = trJson.getInt("duration");
|
||||||
}
|
}
|
||||||
|
@ -1569,14 +1637,14 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
List<ProfileSwitch> profileSwitches;
|
List<ProfileSwitch> profileSwitches;
|
||||||
QueryBuilder<ProfileSwitch, Long> queryBuilder = daoProfileSwitch.queryBuilder();
|
QueryBuilder<ProfileSwitch, Long> queryBuilder = daoProfileSwitch.queryBuilder();
|
||||||
queryBuilder.orderBy("date", ascending);
|
queryBuilder.orderBy("date", ascending);
|
||||||
queryBuilder.limit(20L);
|
queryBuilder.limit(100L);
|
||||||
PreparedQuery<ProfileSwitch> preparedQuery = queryBuilder.prepare();
|
PreparedQuery<ProfileSwitch> preparedQuery = queryBuilder.prepare();
|
||||||
profileSwitches = daoProfileSwitch.query(preparedQuery);
|
profileSwitches = daoProfileSwitch.query(preparedQuery);
|
||||||
return profileSwitches;
|
return profileSwitches;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return new ArrayList<ProfileSwitch>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean createOrUpdate(ProfileSwitch profileSwitch) {
|
public boolean createOrUpdate(ProfileSwitch profileSwitch) {
|
||||||
|
@ -1693,7 +1761,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
if (trJson.has("profileJson"))
|
if (trJson.has("profileJson"))
|
||||||
profileSwitch.profileJson = trJson.getString("profileJson");
|
profileSwitch.profileJson = trJson.getString("profileJson");
|
||||||
else {
|
else {
|
||||||
ProfileStore store = ConfigBuilderPlugin.getActiveProfileInterface().getProfile();
|
ProfileStore store = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile();
|
||||||
Profile profile = store.getSpecificProfile(profileSwitch.profileName);
|
Profile profile = store.getSpecificProfile(profileSwitch.profileName);
|
||||||
if (profile != null) {
|
if (profile != null) {
|
||||||
profileSwitch.profileJson = profile.getData().toString();
|
profileSwitch.profileJson = profile.getData().toString();
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
}
|
|
@ -61,6 +61,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)
|
||||||
|
|
46
app/src/main/java/info/nightscout/androidaps/db/TDD.java
Normal file
46
app/src/main/java/info/nightscout/androidaps/db/TDD.java
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mike on 20.09.2017.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@DatabaseTable(tableName = DatabaseHelper.DATABASE_TDDS)
|
||||||
|
public class TDD {
|
||||||
|
private static Logger log = LoggerFactory.getLogger(TDD.class);
|
||||||
|
|
||||||
|
@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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -71,6 +71,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;
|
||||||
|
|
|
@ -60,8 +60,36 @@ 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) {
|
||||||
|
@ -262,13 +290,13 @@ 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -128,7 +128,7 @@ public class Treatment implements DataPointWithLabelInterface {
|
||||||
@Override
|
@Override
|
||||||
public String getLabel() {
|
public String getLabel() {
|
||||||
String label = "";
|
String label = "";
|
||||||
if (insulin > 0) label += DecimalFormatter.to2Decimal(insulin) + "U";
|
if (insulin > 0) label += DecimalFormatter.toPumpSupportedBolus(insulin) + "U";
|
||||||
if (carbs > 0)
|
if (carbs > 0)
|
||||||
label += "~" + DecimalFormatter.to0Decimal(carbs) + "g";
|
label += "~" + DecimalFormatter.to0Decimal(carbs) + "g";
|
||||||
return label;
|
return label;
|
||||||
|
@ -149,7 +149,7 @@ public class Treatment implements DataPointWithLabelInterface {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getSize() {
|
public float getSize() {
|
||||||
return 10;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -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,117 @@
|
||||||
|
package info.nightscout.androidaps.interfaces;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mike on 19.03.2018.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class Constraint<T extends Comparable> {
|
||||||
|
private static Logger log = LoggerFactory.getLogger(Constraint.class);
|
||||||
|
|
||||||
|
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;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Constraint<T> set(T value, String reason, Object 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) {
|
||||||
|
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) {
|
||||||
|
this.value = value;
|
||||||
|
mostLimiting.clear();
|
||||||
|
addMostLimingReason(reason, from);
|
||||||
|
}
|
||||||
|
if (value.compareTo(this.originalValue) > 0) {
|
||||||
|
addReason(reason, from);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Constraint addReason(String reason, Object from) {
|
||||||
|
reasons.add(from.getClass().getSimpleName().replace("Plugin", "") + ": " + reason);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Constraint addMostLimingReason(String reason, Object from) {
|
||||||
|
mostLimiting.add(from.getClass().getSimpleName().replace("Plugin", "") + ": " + 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);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
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,54 @@
|
||||||
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> isLoopInvokationAllowed(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> isAdvancedFilteringEnabled(Constraint<Boolean> value) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
Integer applyBasalConstraints(Integer percentRate);
|
default Constraint<Double> applyBasalConstraints(Constraint<Double> absoluteRate, Profile profile) {
|
||||||
|
return absoluteRate;
|
||||||
|
}
|
||||||
|
|
||||||
Double applyBolusConstraints(Double insulin);
|
default Constraint<Integer> applyBasalPercentConstraints(Constraint<Integer> percentRate, Profile profile) {
|
||||||
|
return percentRate;
|
||||||
|
}
|
||||||
|
|
||||||
Integer applyCarbsConstraints(Integer carbs);
|
default Constraint<Double> applyBolusConstraints(Constraint<Double> insulin) {
|
||||||
|
return insulin;
|
||||||
|
}
|
||||||
|
|
||||||
Double applyMaxIOBConstraints(Double maxIob);
|
default Constraint<Integer> applyCarbsConstraints(Constraint<Integer> carbs) {
|
||||||
|
return carbs;
|
||||||
|
}
|
||||||
|
|
||||||
|
default Constraint<Double> applyMaxIOBConstraints(Constraint<Double> maxIob) {
|
||||||
|
return maxIob;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package info.nightscout.androidaps.interfaces;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import info.nightscout.androidaps.data.Iob;
|
import info.nightscout.androidaps.data.Iob;
|
||||||
|
import info.nightscout.androidaps.data.Profile;
|
||||||
import info.nightscout.androidaps.db.Treatment;
|
import info.nightscout.androidaps.db.Treatment;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,34 +1,168 @@
|
||||||
package info.nightscout.androidaps.interfaces;
|
package info.nightscout.androidaps.interfaces;
|
||||||
|
|
||||||
import java.util.Date;
|
import android.os.SystemClock;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.MainApp;
|
||||||
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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(PluginBase.class);
|
||||||
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 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;
|
||||||
|
log.debug("Starting: " + getName());
|
||||||
|
onStart();
|
||||||
|
}
|
||||||
|
} else { // disabling plugin
|
||||||
|
if (state == State.ENABLED) {
|
||||||
|
onStateChange(type, state, State.ENABLED);
|
||||||
|
state = State.DISABLED;
|
||||||
|
onStop();
|
||||||
|
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);
|
||||||
|
try {
|
||||||
|
ConfigBuilderPlugin.getCommandQueue().readStatus("Pump driver changed.", null);
|
||||||
|
} catch (Exception ignored) { // Thread fail to start in tests
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onStop() {
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onStateChange(PluginType type, State oldState, State newState) {
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
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 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 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
|
||||||
|
}
|
|
@ -39,4 +39,6 @@ public class PumpDescription {
|
||||||
public boolean isRefillingCapable = false;
|
public boolean isRefillingCapable = false;
|
||||||
|
|
||||||
public boolean storesCarbInfo = true;
|
public boolean storesCarbInfo = true;
|
||||||
|
|
||||||
|
public boolean is30minBasalRatesCapable = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,8 @@ import org.json.JSONObject;
|
||||||
import java.util.Date;
|
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.
|
||||||
|
@ -35,8 +35,8 @@ public interface PumpInterface {
|
||||||
|
|
||||||
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();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,8 +41,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();
|
||||||
|
|
|
@ -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,13 +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.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.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.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;
|
||||||
|
@ -31,6 +33,7 @@ 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.Treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.utils.FabricPrivacy;
|
import info.nightscout.utils.FabricPrivacy;
|
||||||
import info.nightscout.utils.SingleClickButton;
|
import info.nightscout.utils.SingleClickButton;
|
||||||
|
|
||||||
|
@ -52,6 +55,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 +76,9 @@ 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,6 +87,8 @@ 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;
|
||||||
|
@ -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 (MainApp.getConfigBuilder().getActiveProfileInterface().getProfile() != null) {
|
||||||
tempTarget.setVisibility(View.GONE);
|
profileSwitch.setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
profileSwitch.setVisibility(View.GONE);
|
profileSwitch.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MainApp.getConfigBuilder().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,18 +141,21 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL
|
||||||
fill.setVisibility(View.GONE);
|
fill.setVisibility(View.GONE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
|
final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
|
||||||
if (!pump.getPumpDescription().isSetBasalProfileCapable || !pump.isInitialized() || pump.isSuspended())
|
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 {
|
||||||
ExtendedBolus activeExtendedBolus = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis());
|
ExtendedBolus activeExtendedBolus = TreatmentsPlugin.getPlugin().getExtendedBolusFromHistory(System.currentTimeMillis());
|
||||||
if (activeExtendedBolus != null) {
|
if (activeExtendedBolus != null) {
|
||||||
extendedBolus.setVisibility(View.GONE);
|
extendedBolus.setVisibility(View.GONE);
|
||||||
extendedBolusCancel.setVisibility(View.VISIBLE);
|
extendedBolusCancel.setVisibility(View.VISIBLE);
|
||||||
|
@ -153,7 +171,7 @@ 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 {
|
||||||
final TemporaryBasal activeTemp = MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis());
|
final TemporaryBasal activeTemp = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(System.currentTimeMillis());
|
||||||
if (activeTemp != null) {
|
if (activeTemp != null) {
|
||||||
tempBasal.setVisibility(View.GONE);
|
tempBasal.setVisibility(View.GONE);
|
||||||
tempBasalCancel.setVisibility(View.VISIBLE);
|
tempBasalCancel.setVisibility(View.VISIBLE);
|
||||||
|
@ -201,13 +219,13 @@ 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.getCommandQueue().cancelExtended(null);
|
||||||
FabricPrivacy.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.getCommandQueue().cancelTempBasal(true, null);
|
||||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("CancelTemp"));
|
FabricPrivacy.getInstance().logCustom(new CustomEvent("CancelTemp"));
|
||||||
}
|
}
|
||||||
|
@ -220,6 +238,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,22 @@
|
||||||
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)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@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,11 @@
|
||||||
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.Html;
|
||||||
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,24 +13,31 @@ 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 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 info.nightscout.androidaps.Constants;
|
import info.nightscout.androidaps.Constants;
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
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.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.utils.FabricPrivacy;
|
||||||
|
import info.nightscout.utils.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;
|
||||||
|
@ -38,13 +45,13 @@ import info.nightscout.utils.SafeParse;
|
||||||
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;
|
|
||||||
|
|
||||||
double amount1 = 0d;
|
double amount1 = 0d;
|
||||||
double amount2 = 0d;
|
double amount2 = 0d;
|
||||||
double amount3 = 0d;
|
double amount3 = 0d;
|
||||||
|
|
||||||
NumberPicker editInsulin;
|
NumberPicker editInsulin;
|
||||||
|
CheckBox pumpSiteChangeCheckbox;
|
||||||
|
CheckBox insulinCartridgeChangeCheckbox;
|
||||||
|
|
||||||
public FillDialog() {
|
public FillDialog() {
|
||||||
}
|
}
|
||||||
|
@ -54,22 +61,24 @@ public class FillDialog extends DialogFragment implements OnClickListener {
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
View view = inflater.inflate(R.layout.actions_fill_dialog, null, false);
|
View view = inflater.inflate(R.layout.actions_fill_dialog, null, 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.catheter_change);
|
||||||
|
insulinCartridgeChangeCheckbox = view.findViewById(R.id.cartridge_change);
|
||||||
|
|
||||||
|
Double maxInsulin = MainApp.getConstraintChecker().getMaxBolusAllowed().value();
|
||||||
double bolusstep = ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep;
|
double bolusstep = ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep;
|
||||||
editInsulin = (NumberPicker) view.findViewById(R.id.treatments_newtreatment_insulinamount);
|
editInsulin = view.findViewById(R.id.treatments_newtreatment_insulinamount);
|
||||||
editInsulin.setParams(0d, 0d, maxInsulin, bolusstep, new DecimalFormat("0.00"), false);
|
editInsulin.setParams(0d, 0d, maxInsulin, bolusstep, DecimalFormatter.pumpSupportedBolusFormat(), false);
|
||||||
|
|
||||||
//setup preset buttons
|
//setup preset buttons
|
||||||
Button button1 = (Button) view.findViewById(R.id.fill_preset_button1);
|
Button button1 = (Button) view.findViewById(R.id.fill_preset_button1);
|
||||||
Button button2 = (Button) view.findViewById(R.id.fill_preset_button2);
|
Button button2 = (Button) view.findViewById(R.id.fill_preset_button2);
|
||||||
Button button3 = (Button) view.findViewById(R.id.fill_preset_button3);
|
Button button3 = (Button) view.findViewById(R.id.fill_preset_button3);
|
||||||
View divider = view.findViewById(R.id.fill_preset_divider);
|
|
||||||
|
|
||||||
amount1 = SP.getDouble("fill_button1", 0.3);
|
amount1 = SP.getDouble("fill_button1", 0.3);
|
||||||
amount2 = SP.getDouble("fill_button2", 0d);
|
amount2 = SP.getDouble("fill_button2", 0d);
|
||||||
|
@ -77,103 +86,109 @@ public class FillDialog extends DialogFragment implements OnClickListener {
|
||||||
|
|
||||||
if (amount1 > 0) {
|
if (amount1 > 0) {
|
||||||
button1.setVisibility(View.VISIBLE);
|
button1.setVisibility(View.VISIBLE);
|
||||||
button1.setText(DecimalFormatter.to2Decimal(amount1) + "U");
|
button1.setText(DecimalFormatter.toPumpSupportedBolus(amount1)); // + "U");
|
||||||
button1.setOnClickListener(this);
|
button1.setOnClickListener(this);
|
||||||
} else {
|
} else {
|
||||||
button1.setVisibility(View.GONE);
|
button1.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
if (amount2 > 0) {
|
if (amount2 > 0) {
|
||||||
button2.setVisibility(View.VISIBLE);
|
button2.setVisibility(View.VISIBLE);
|
||||||
button2.setText(DecimalFormatter.to2Decimal(amount2) + "U");
|
button2.setText(DecimalFormatter.toPumpSupportedBolus(amount2)); // + "U");
|
||||||
button2.setOnClickListener(this);
|
button2.setOnClickListener(this);
|
||||||
} else {
|
} else {
|
||||||
button2.setVisibility(View.GONE);
|
button2.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
if (amount3 > 0) {
|
if (amount3 > 0) {
|
||||||
button3.setVisibility(View.VISIBLE);
|
button3.setVisibility(View.VISIBLE);
|
||||||
button3.setText(DecimalFormatter.to2Decimal(amount3) + "U");
|
button3.setText(DecimalFormatter.toPumpSupportedBolus(amount3)); // + "U");
|
||||||
button3.setOnClickListener(this);
|
button3.setOnClickListener(this);
|
||||||
} else {
|
} else {
|
||||||
button3.setVisibility(View.GONE);
|
button3.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (button1.getVisibility() == View.GONE && button2.getVisibility() == View.GONE && button3.getVisibility() == View.GONE) {
|
|
||||||
divider.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
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 void confirmAndDeliver() {
|
||||||
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) + "'>" + insulinAfterConstraints + "U" + "</font>");
|
||||||
|
if (!insulinAfterConstraints.equals(insulin))
|
||||||
|
confirmMessage.add("<font color='" + MainApp.sResources.getColor(R.color.low) + "'>" + MainApp.gs(R.string.bolusconstraintapplied) + "</font>");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pumpSiteChangeCheckbox.isChecked())
|
||||||
|
confirmMessage.add("" + "<font color='" + MainApp.sResources.getColor(R.color.high) + "'>" + getString(R.string.record_pump_site_change) + "</font>");
|
||||||
|
|
||||||
|
if (insulinCartridgeChangeCheckbox.isChecked())
|
||||||
|
confirmMessage.add("" + "<font color='" + MainApp.sResources.getColor(R.color.high) + "'>" + getString(R.string.record_insulin_cartridge_change) + "</font>");
|
||||||
|
|
||||||
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));
|
if (confirmMessage.isEmpty())
|
||||||
builder.setMessage(confirmMessage);
|
confirmMessage.add(MainApp.gs(R.string.no_action_selected));
|
||||||
builder.setPositiveButton(getString(R.string.primefill), new DialogInterface.OnClickListener() {
|
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
builder.setTitle(MainApp.gs(R.string.confirmation));
|
||||||
if (finalInsulinAfterConstraints > 0) {
|
builder.setMessage(Html.fromHtml(Joiner.on("<br/>").join(confirmMessage)));
|
||||||
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
|
builder.setPositiveButton(getString(R.string.primefill), (dialog, id) -> {
|
||||||
detailedBolusInfo.insulin = finalInsulinAfterConstraints;
|
if (finalInsulinAfterConstraints > 0) {
|
||||||
detailedBolusInfo.context = context;
|
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
|
||||||
detailedBolusInfo.source = Source.USER;
|
detailedBolusInfo.insulin = finalInsulinAfterConstraints;
|
||||||
detailedBolusInfo.isValid = false; // do not count it in IOB (for pump history)
|
detailedBolusInfo.context = context;
|
||||||
ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() {
|
detailedBolusInfo.source = Source.USER;
|
||||||
@Override
|
detailedBolusInfo.isValid = false; // do not count it in IOB (for pump history)
|
||||||
public void run() {
|
ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() {
|
||||||
if (!result.success) {
|
@Override
|
||||||
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
|
public void run() {
|
||||||
i.putExtra("soundid", R.raw.boluserror);
|
if (!result.success) {
|
||||||
i.putExtra("status", result.comment);
|
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
|
||||||
i.putExtra("title", MainApp.sResources.getString(R.string.treatmentdeliveryerror));
|
i.putExtra("soundid", R.raw.boluserror);
|
||||||
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
i.putExtra("status", result.comment);
|
||||||
MainApp.instance().startActivity(i);
|
i.putExtra("title", MainApp.sResources.getString(R.string.treatmentdeliveryerror));
|
||||||
}
|
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
|
MainApp.instance().startActivity(i);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("Fill"));
|
});
|
||||||
}
|
FabricPrivacy.getInstance().logCustom(new CustomEvent("Fill"));
|
||||||
}
|
}
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
if (pumpSiteChangeCheckbox.isChecked()) NSUpload.uploadEvent(CareportalEvent.SITECHANGE, now);
|
||||||
|
if (insulinCartridgeChangeCheckbox.isChecked()) NSUpload.uploadEvent(CareportalEvent.INSULINCHANGE, now + 1000);
|
||||||
});
|
});
|
||||||
builder.setNegativeButton(getString(R.string.cancel), null);
|
builder.setNegativeButton(getString(R.string.cancel), null);
|
||||||
builder.show();
|
builder.show();
|
||||||
|
|
|
@ -17,9 +17,9 @@ 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;
|
||||||
|
@ -43,7 +43,7 @@ public class NewExtendedBolusDialog extends DialogFragment implements View.OnCli
|
||||||
|
|
||||||
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().getMaxBolusAllowed().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);
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ public class NewExtendedBolusDialog extends DialogFragment implements View.OnCli
|
||||||
|
|
||||||
String confirmMessage = getString(R.string.setextendedbolusquestion);
|
String confirmMessage = getString(R.string.setextendedbolusquestion);
|
||||||
|
|
||||||
Double insulinAfterConstraint = MainApp.getConfigBuilder().applyBolusConstraints(insulin);
|
Double insulinAfterConstraint = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(insulin)).value();
|
||||||
confirmMessage += " " + insulinAfterConstraint + " U ";
|
confirmMessage += " " + insulinAfterConstraint + " U ";
|
||||||
confirmMessage += getString(R.string.duration) + " " + durationInMinutes + "min ?";
|
confirmMessage += getString(R.string.duration) + " " + durationInMinutes + "min ?";
|
||||||
if (insulinAfterConstraint - insulin != 0d)
|
if (insulinAfterConstraint - insulin != 0d)
|
||||||
|
|
|
@ -22,6 +22,7 @@ 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.Overview.Dialogs.ErrorHelperActivity;
|
import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity;
|
||||||
|
@ -117,17 +118,21 @@ 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());
|
||||||
|
|
||||||
|
Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||||
|
if (profile == null)
|
||||||
|
return;
|
||||||
|
|
||||||
String confirmMessage = getString(R.string.setbasalquestion);
|
String confirmMessage = getString(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" + getString(R.string.duration) + " " + durationInMinutes + "min ?";
|
||||||
if (percent != basalPercentInput)
|
if (percent != basalPercentInput)
|
||||||
confirmMessage += "\n" + getString(R.string.constraintapllied);
|
confirmMessage += "\n" + getString(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" + getString(R.string.duration) + " " + durationInMinutes + "min ?";
|
||||||
if (absolute - basalAbsoluteInput != 0d)
|
if (absolute - basalAbsoluteInput != 0d)
|
||||||
|
@ -157,9 +162,9 @@ public class NewTempBasalDialog extends DialogFragment implements View.OnClickLi
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (setAsPercent) {
|
if (setAsPercent) {
|
||||||
ConfigBuilderPlugin.getCommandQueue().tempBasalPercent(finalBasalPercent, finalDurationInMinutes, true, callback);
|
ConfigBuilderPlugin.getCommandQueue().tempBasalPercent(finalBasalPercent, finalDurationInMinutes, true, profile, callback);
|
||||||
} else {
|
} else {
|
||||||
ConfigBuilderPlugin.getCommandQueue().tempBasalAbsolute(finalBasal, finalDurationInMinutes, true, callback);
|
ConfigBuilderPlugin.getCommandQueue().tempBasalAbsolute(finalBasal, finalDurationInMinutes, true, profile, callback);
|
||||||
}
|
}
|
||||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("TempBasal"));
|
FabricPrivacy.getInstance().logCustom(new CustomEvent("TempBasal"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,7 +96,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 = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile();
|
||||||
if (profileStore == null) {
|
if (profileStore == null) {
|
||||||
noProfileView.setVisibility(View.VISIBLE);
|
noProfileView.setVisibility(View.VISIBLE);
|
||||||
butonsLayout.setVisibility(View.GONE);
|
butonsLayout.setVisibility(View.GONE);
|
||||||
|
|
|
@ -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,13 @@ 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() {
|
);
|
||||||
return CareportalFragment.class.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ package info.nightscout.androidaps.plugins.Careportal.Dialogs;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.DialogInterface;
|
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;
|
||||||
|
@ -50,13 +49,11 @@ 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.Treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity;
|
|
||||||
import info.nightscout.androidaps.queue.Callback;
|
|
||||||
import info.nightscout.utils.FabricPrivacy;
|
|
||||||
import info.nightscout.utils.DateUtil;
|
import info.nightscout.utils.DateUtil;
|
||||||
|
import info.nightscout.utils.FabricPrivacy;
|
||||||
|
import info.nightscout.utils.HardLimits;
|
||||||
import info.nightscout.utils.NSUpload;
|
import info.nightscout.utils.NSUpload;
|
||||||
import info.nightscout.utils.NumberPicker;
|
import info.nightscout.utils.NumberPicker;
|
||||||
import info.nightscout.utils.SP;
|
import info.nightscout.utils.SP;
|
||||||
|
@ -73,7 +70,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
|
||||||
|
|
||||||
Profile profile;
|
Profile profile;
|
||||||
ProfileStore profileStore;
|
ProfileStore profileStore;
|
||||||
String units;
|
String units = Constants.MGDL;
|
||||||
|
|
||||||
TextView eventTypeText;
|
TextView eventTypeText;
|
||||||
LinearLayout layoutPercent;
|
LinearLayout layoutPercent;
|
||||||
|
@ -107,6 +104,8 @@ 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.sResources.getString(event);
|
||||||
|
@ -114,6 +113,10 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
|
||||||
|
|
||||||
public NewNSTreatmentDialog() {
|
public NewNSTreatmentDialog() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
|
if (seconds == null) {
|
||||||
|
seconds = new Double(Math.random() * 59).intValue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -168,20 +171,25 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
|
||||||
|
|
||||||
// profile
|
// profile
|
||||||
profile = MainApp.getConfigBuilder().getProfile();
|
profile = MainApp.getConfigBuilder().getProfile();
|
||||||
profileStore = ConfigBuilderPlugin.getActiveProfileInterface().getProfile();
|
profileStore = MainApp.getConfigBuilder().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(MainApp.getConfigBuilder().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 ArrayList<CharSequence> reasonList = new ArrayList<CharSequence>();
|
||||||
|
@ -266,11 +274,11 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
@ -297,7 +305,9 @@ 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, 0d, (double) maxPercent, 5d, new DecimalFormat("0"), true, percentTextWatcher);
|
||||||
|
|
||||||
|
@ -319,7 +329,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);
|
||||||
|
|
||||||
|
@ -332,19 +344,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);
|
||||||
|
@ -413,8 +425,8 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
|
||||||
long millis = eventTime.getTime() - (150 * 1000L); // 2,5 * 60 * 1000
|
long millis = eventTime.getTime() - (150 * 1000L); // 2,5 * 60 * 1000
|
||||||
List<BgReading> data = MainApp.getDbHelper().getBgreadingsDataFromTime(millis, true);
|
List<BgReading> data = MainApp.getDbHelper().getBgreadingsDataFromTime(millis, true);
|
||||||
if ((data.size() > 0) &&
|
if ((data.size() > 0) &&
|
||||||
(data.get(0).date > millis - 7 * 60 * 1000L) &&
|
(data.get(0).date > millis - 7 * 60 * 1000L) &&
|
||||||
(data.get(0).date < millis + 7 * 60 * 1000L)) {
|
(data.get(0).date < millis + 7 * 60 * 1000L)) {
|
||||||
editBg.setValue(Profile.fromMgdlToUnits(data.get(0).value, profile != null ? profile.getUnits() : Constants.MGDL));
|
editBg.setValue(Profile.fromMgdlToUnits(data.get(0).value, profile != null ? profile.getUnits() : Constants.MGDL));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -432,7 +444,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
|
||||||
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();
|
updateBGforDateTime();
|
||||||
}
|
}
|
||||||
|
@ -684,17 +696,16 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
|
||||||
} else if (options.executeTempTarget) {
|
} else if (options.executeTempTarget) {
|
||||||
try {
|
try {
|
||||||
if ((data.has("targetBottom") && data.has("targetTop")) || (data.has("duration") && data.getInt("duration") == 0)) {
|
if ((data.has("targetBottom") && data.has("targetTop")) || (data.has("duration") && data.getInt("duration") == 0)) {
|
||||||
TempTarget tempTarget = new TempTarget();
|
TempTarget tempTarget = new TempTarget()
|
||||||
tempTarget.date = eventTime.getTime();
|
.date(eventTime.getTime())
|
||||||
tempTarget.durationInMinutes = data.getInt("duration");
|
.duration(data.getInt("duration"))
|
||||||
tempTarget.reason = data.getString("reason");
|
.reason(data.getString("reason"))
|
||||||
tempTarget.source = Source.USER;
|
.source(Source.USER);
|
||||||
if (tempTarget.durationInMinutes != 0) {
|
if (tempTarget.durationInMinutes != 0) {
|
||||||
tempTarget.low = Profile.toMgdl(data.getDouble("targetBottom"), profile.getUnits());
|
tempTarget.low(Profile.toMgdl(data.getDouble("targetBottom"), profile.getUnits()))
|
||||||
tempTarget.high = Profile.toMgdl(data.getDouble("targetTop"), profile.getUnits());
|
.high(Profile.toMgdl(data.getDouble("targetTop"), profile.getUnits()));
|
||||||
} else {
|
} else {
|
||||||
tempTarget.low = 0;
|
tempTarget.low(0).high(0);
|
||||||
tempTarget.high = 0;
|
|
||||||
}
|
}
|
||||||
log.debug("Creating new TempTarget db record: " + tempTarget.toString());
|
log.debug("Creating new TempTarget db record: " + tempTarget.toString());
|
||||||
MainApp.getDbHelper().createOrUpdate(tempTarget);
|
MainApp.getDbHelper().createOrUpdate(tempTarget);
|
||||||
|
@ -720,59 +731,29 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
|
||||||
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 = MainApp.getConfigBuilder().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);
|
||||||
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("ProfileSwitch"));
|
FabricPrivacy.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 = MainApp.getConfigBuilder().getProfileName(System.currentTimeMillis(), false);
|
||||||
profileSwitch.profileJson = MainApp.getConfigBuilder().getProfile().getData().toString();
|
profileSwitch.profileJson = MainApp.getConfigBuilder().getProfile().getData().toString();
|
||||||
profileSwitch.profilePlugin = ConfigBuilderPlugin.getActiveProfileInterface().getClass().getName();
|
profileSwitch.profilePlugin = MainApp.getConfigBuilder().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);
|
||||||
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("ProfileSwitch"));
|
FabricPrivacy.getInstance().logCustom(new CustomEvent("ProfileSwitch"));
|
||||||
} else {
|
} else {
|
||||||
log.error("No profile switch existing");
|
log.error("No profile switch existing");
|
||||||
|
|
|
@ -4,7 +4,7 @@ package info.nightscout.androidaps.plugins.ConfigBuilder;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.annotation.NonNull;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
@ -17,11 +17,14 @@ import android.widget.ListAdapter;
|
||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
|
||||||
import com.crashlytics.android.answers.CustomEvent;
|
import com.crashlytics.android.answers.CustomEvent;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import butterknife.BindView;
|
||||||
|
import butterknife.ButterKnife;
|
||||||
|
import butterknife.OnClick;
|
||||||
|
import info.nightscout.androidaps.Config;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.PreferencesActivity;
|
import info.nightscout.androidaps.PreferencesActivity;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
|
@ -32,10 +35,12 @@ 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.SensitivityOref0.SensitivityOref0Plugin;
|
||||||
|
@ -43,33 +48,46 @@ 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();
|
|
||||||
|
|
||||||
static public ConfigBuilderPlugin getPlugin() {
|
|
||||||
return configBuilderPlugin;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@BindView(R.id.configbuilder_insulinlistview)
|
||||||
ListView insulinListView;
|
ListView insulinListView;
|
||||||
|
@BindView(R.id.configbuilder_sensitivitylistview)
|
||||||
ListView sensitivityListView;
|
ListView sensitivityListView;
|
||||||
|
@BindView(R.id.configbuilder_bgsourcelistview)
|
||||||
ListView bgsourceListView;
|
ListView bgsourceListView;
|
||||||
|
@BindView(R.id.configbuilder_bgsourcelabel)
|
||||||
TextView bgsourceLabel;
|
TextView bgsourceLabel;
|
||||||
|
@BindView(R.id.configbuilder_pumplistview)
|
||||||
ListView pumpListView;
|
ListView pumpListView;
|
||||||
|
@BindView(R.id.configbuilder_pumplabel)
|
||||||
TextView pumpLabel;
|
TextView pumpLabel;
|
||||||
|
@BindView(R.id.configbuilder_looplistview)
|
||||||
ListView loopListView;
|
ListView loopListView;
|
||||||
|
@BindView(R.id.configbuilder_looplabel)
|
||||||
TextView loopLabel;
|
TextView loopLabel;
|
||||||
|
@BindView(R.id.configbuilder_treatmentslistview)
|
||||||
ListView treatmentsListView;
|
ListView treatmentsListView;
|
||||||
|
@BindView(R.id.configbuilder_treatmentslabel)
|
||||||
TextView treatmentsLabel;
|
TextView treatmentsLabel;
|
||||||
|
@BindView(R.id.configbuilder_profilelistview)
|
||||||
ListView profileListView;
|
ListView profileListView;
|
||||||
|
@BindView(R.id.configbuilder_profilelabel)
|
||||||
TextView profileLabel;
|
TextView profileLabel;
|
||||||
|
@BindView(R.id.configbuilder_apslistview)
|
||||||
ListView apsListView;
|
ListView apsListView;
|
||||||
|
@BindView(R.id.configbuilder_apslabel)
|
||||||
TextView apsLabel;
|
TextView apsLabel;
|
||||||
|
@BindView(R.id.configbuilder_constraintslistview)
|
||||||
ListView constraintsListView;
|
ListView constraintsListView;
|
||||||
|
@BindView(R.id.configbuilder_constraintslabel)
|
||||||
TextView constraintsLabel;
|
TextView constraintsLabel;
|
||||||
|
@BindView(R.id.configbuilder_generallistview)
|
||||||
ListView generalListView;
|
ListView generalListView;
|
||||||
|
|
||||||
|
@BindView(R.id.configbuilder_mainlayout)
|
||||||
LinearLayout mainLayout;
|
LinearLayout mainLayout;
|
||||||
|
@BindView(R.id.configbuilder_unlock)
|
||||||
Button unlock;
|
Button unlock;
|
||||||
|
|
||||||
PluginCustomAdapter insulinDataAdapter = null;
|
PluginCustomAdapter insulinDataAdapter = null;
|
||||||
|
@ -84,51 +102,17 @@ public class ConfigBuilderFragment extends Fragment {
|
||||||
PluginCustomAdapter generalDataAdapter = 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);
|
||||||
|
|
||||||
insulinListView = (ListView) view.findViewById(R.id.configbuilder_insulinlistview);
|
unbinder = ButterKnife.bind(this, view);
|
||||||
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);
|
if (PasswordProtection.isLocked("settings_password"))
|
||||||
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
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
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);
|
unlock.setVisibility(View.GONE);
|
||||||
}
|
|
||||||
return view;
|
return view;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
FabricPrivacy.logException(e);
|
FabricPrivacy.logException(e);
|
||||||
|
@ -137,52 +121,64 @@ public class ConfigBuilderFragment extends Fragment {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setViews() {
|
@OnClick(R.id.configbuilder_unlock)
|
||||||
insulinDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInListByInterface(InsulinInterface.class, PluginBase.INSULIN), PluginBase.INSULIN);
|
public void onClickUnlock() {
|
||||||
|
PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", () -> {
|
||||||
|
mainLayout.setVisibility(View.VISIBLE);
|
||||||
|
unlock.setVisibility(View.GONE);
|
||||||
|
}, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void updateGUI() {
|
||||||
|
|
||||||
|
insulinDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInListByInterface(InsulinInterface.class, PluginType.INSULIN), PluginType.INSULIN);
|
||||||
insulinListView.setAdapter(insulinDataAdapter);
|
insulinListView.setAdapter(insulinDataAdapter);
|
||||||
setListViewHeightBasedOnChildren(insulinListView);
|
setListViewHeightBasedOnChildren(insulinListView);
|
||||||
bgsourceDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInListByInterface(BgSourceInterface.class, PluginBase.BGSOURCE), PluginBase.BGSOURCE);
|
bgsourceDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInListByInterface(BgSourceInterface.class, PluginType.BGSOURCE), PluginType.BGSOURCE);
|
||||||
bgsourceListView.setAdapter(bgsourceDataAdapter);
|
bgsourceListView.setAdapter(bgsourceDataAdapter);
|
||||||
if (MainApp.getSpecificPluginsVisibleInList(PluginBase.BGSOURCE).size() == 0)
|
if (MainApp.getSpecificPluginsVisibleInList(PluginType.BGSOURCE).size() == 0)
|
||||||
bgsourceLabel.setVisibility(View.GONE);
|
bgsourceLabel.setVisibility(View.GONE);
|
||||||
setListViewHeightBasedOnChildren(bgsourceListView);
|
setListViewHeightBasedOnChildren(bgsourceListView);
|
||||||
pumpDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInList(PluginBase.PUMP), PluginBase.PUMP);
|
pumpDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInList(PluginType.PUMP), PluginType.PUMP);
|
||||||
pumpListView.setAdapter(pumpDataAdapter);
|
pumpListView.setAdapter(pumpDataAdapter);
|
||||||
if (MainApp.getSpecificPluginsVisibleInList(PluginBase.PUMP).size() == 0)
|
if (MainApp.getSpecificPluginsVisibleInList(PluginType.PUMP).size() == 0 || Config.NSCLIENT || Config.G5UPLOADER) {
|
||||||
pumpLabel.setVisibility(View.GONE);
|
pumpLabel.setVisibility(View.GONE);
|
||||||
|
pumpListView.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
setListViewHeightBasedOnChildren(pumpListView);
|
setListViewHeightBasedOnChildren(pumpListView);
|
||||||
loopDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInList(PluginBase.LOOP), PluginBase.LOOP);
|
loopDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInList(PluginType.LOOP), PluginType.LOOP);
|
||||||
loopListView.setAdapter(loopDataAdapter);
|
loopListView.setAdapter(loopDataAdapter);
|
||||||
setListViewHeightBasedOnChildren(loopListView);
|
setListViewHeightBasedOnChildren(loopListView);
|
||||||
if (MainApp.getSpecificPluginsVisibleInList(PluginBase.LOOP).size() == 0)
|
if (MainApp.getSpecificPluginsVisibleInList(PluginType.LOOP).size() == 0)
|
||||||
loopLabel.setVisibility(View.GONE);
|
loopLabel.setVisibility(View.GONE);
|
||||||
treatmentDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInList(PluginBase.TREATMENT), PluginBase.TREATMENT);
|
treatmentDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInList(PluginType.TREATMENT), PluginType.TREATMENT);
|
||||||
treatmentsListView.setAdapter(treatmentDataAdapter);
|
treatmentsListView.setAdapter(treatmentDataAdapter);
|
||||||
setListViewHeightBasedOnChildren(treatmentsListView);
|
setListViewHeightBasedOnChildren(treatmentsListView);
|
||||||
if (MainApp.getSpecificPluginsVisibleInList(PluginBase.TREATMENT).size() == 0)
|
if (MainApp.getSpecificPluginsVisibleInList(PluginType.TREATMENT).size() == 0)
|
||||||
treatmentsLabel.setVisibility(View.GONE);
|
treatmentsLabel.setVisibility(View.GONE);
|
||||||
profileDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInListByInterface(ProfileInterface.class, PluginBase.PROFILE), PluginBase.PROFILE);
|
profileDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInListByInterface(ProfileInterface.class, PluginType.PROFILE), PluginType.PROFILE);
|
||||||
profileListView.setAdapter(profileDataAdapter);
|
profileListView.setAdapter(profileDataAdapter);
|
||||||
if (MainApp.getSpecificPluginsVisibleInList(PluginBase.PROFILE).size() == 0)
|
if (MainApp.getSpecificPluginsVisibleInList(PluginType.PROFILE).size() == 0)
|
||||||
profileLabel.setVisibility(View.GONE);
|
profileLabel.setVisibility(View.GONE);
|
||||||
setListViewHeightBasedOnChildren(profileListView);
|
setListViewHeightBasedOnChildren(profileListView);
|
||||||
apsDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInList(PluginBase.APS), PluginBase.APS);
|
apsDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInList(PluginType.APS), PluginType.APS);
|
||||||
apsListView.setAdapter(apsDataAdapter);
|
apsListView.setAdapter(apsDataAdapter);
|
||||||
setListViewHeightBasedOnChildren(apsListView);
|
setListViewHeightBasedOnChildren(apsListView);
|
||||||
if (MainApp.getSpecificPluginsVisibleInList(PluginBase.APS).size() == 0)
|
if (MainApp.getSpecificPluginsVisibleInList(PluginType.APS).size() == 0)
|
||||||
apsLabel.setVisibility(View.GONE);
|
apsLabel.setVisibility(View.GONE);
|
||||||
sensivityDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInListByInterface(SensitivityInterface.class, PluginBase.SENSITIVITY), PluginBase.SENSITIVITY);
|
sensivityDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInListByInterface(SensitivityInterface.class, PluginType.SENSITIVITY), PluginType.SENSITIVITY);
|
||||||
sensitivityListView.setAdapter(sensivityDataAdapter);
|
sensitivityListView.setAdapter(sensivityDataAdapter);
|
||||||
setListViewHeightBasedOnChildren(sensitivityListView);
|
setListViewHeightBasedOnChildren(sensitivityListView);
|
||||||
constraintsDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInListByInterface(ConstraintsInterface.class, PluginBase.CONSTRAINTS), PluginBase.CONSTRAINTS);
|
constraintsDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInListByInterface(ConstraintsInterface.class, PluginType.CONSTRAINTS), PluginType.CONSTRAINTS);
|
||||||
constraintsListView.setAdapter(constraintsDataAdapter);
|
constraintsListView.setAdapter(constraintsDataAdapter);
|
||||||
setListViewHeightBasedOnChildren(constraintsListView);
|
setListViewHeightBasedOnChildren(constraintsListView);
|
||||||
if (MainApp.getSpecificPluginsVisibleInList(PluginBase.CONSTRAINTS).size() == 0)
|
if (MainApp.getSpecificPluginsVisibleInList(PluginType.CONSTRAINTS).size() == 0)
|
||||||
constraintsLabel.setVisibility(View.GONE);
|
constraintsLabel.setVisibility(View.GONE);
|
||||||
generalDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInList(PluginBase.GENERAL), PluginBase.GENERAL);
|
generalDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInList(PluginType.GENERAL), PluginType.GENERAL);
|
||||||
generalListView.setAdapter(generalDataAdapter);
|
generalListView.setAdapter(generalDataAdapter);
|
||||||
setListViewHeightBasedOnChildren(generalListView);
|
setListViewHeightBasedOnChildren(generalListView);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -192,10 +188,10 @@ public class ConfigBuilderFragment extends Fragment {
|
||||||
private class PluginCustomAdapter extends ArrayAdapter<PluginBase> {
|
private class PluginCustomAdapter extends ArrayAdapter<PluginBase> {
|
||||||
|
|
||||||
private ArrayList<PluginBase> pluginList;
|
private ArrayList<PluginBase> pluginList;
|
||||||
final private int type;
|
final private PluginType type;
|
||||||
|
|
||||||
public PluginCustomAdapter(Context context, int textViewResourceId,
|
PluginCustomAdapter(Context context, int textViewResourceId,
|
||||||
ArrayList<PluginBase> pluginList, int type) {
|
ArrayList<PluginBase> pluginList, PluginType type) {
|
||||||
super(context, textViewResourceId, pluginList);
|
super(context, textViewResourceId, pluginList);
|
||||||
this.pluginList = new ArrayList<>();
|
this.pluginList = new ArrayList<>();
|
||||||
this.pluginList.addAll(pluginList);
|
this.pluginList.addAll(pluginList);
|
||||||
|
@ -209,10 +205,11 @@ public class ConfigBuilderFragment extends Fragment {
|
||||||
ImageView settings;
|
ImageView settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public View getView(int position, View view, ViewGroup parent) {
|
public View getView(int position, View view, @NonNull ViewGroup parent) {
|
||||||
|
|
||||||
PluginViewHolder holder = null;
|
PluginViewHolder holder;
|
||||||
PluginBase plugin = pluginList.get(position);
|
PluginBase plugin = pluginList.get(position);
|
||||||
|
|
||||||
if (view == null) {
|
if (view == null) {
|
||||||
|
@ -231,60 +228,45 @@ public class ConfigBuilderFragment extends Fragment {
|
||||||
|
|
||||||
view.setTag(holder);
|
view.setTag(holder);
|
||||||
|
|
||||||
holder.checkboxEnabled.setOnClickListener(new View.OnClickListener() {
|
holder.checkboxEnabled.setOnClickListener(v -> {
|
||||||
public void onClick(View v) {
|
CheckBox cb = (CheckBox) v;
|
||||||
CheckBox cb = (CheckBox) v;
|
PluginBase plugin1 = (PluginBase) cb.getTag();
|
||||||
PluginBase plugin = (PluginBase) cb.getTag();
|
plugin1.setPluginEnabled(type, cb.isChecked());
|
||||||
plugin.setFragmentEnabled(type, cb.isChecked());
|
plugin1.setFragmentVisible(type, cb.isChecked());
|
||||||
plugin.setFragmentVisible(type, cb.isChecked());
|
onEnabledCategoryChanged(plugin1, type);
|
||||||
onEnabledCategoryChanged(plugin, type);
|
ConfigBuilderPlugin.getPlugin().storeSettings("CheckedCheckboxEnabled");
|
||||||
configBuilderPlugin.storeSettings();
|
MainApp.bus().post(new EventRefreshGui());
|
||||||
MainApp.bus().post(new EventRefreshGui());
|
MainApp.bus().post(new EventConfigBuilderChange());
|
||||||
MainApp.bus().post(new EventConfigBuilderChange());
|
ConfigBuilderPlugin.getPlugin().logPluginStatus();
|
||||||
getPlugin().logPluginStatus();
|
FabricPrivacy.getInstance().logCustom(new CustomEvent("ConfigurationChange"));
|
||||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("ConfigurationChange"));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
holder.checkboxVisible.setOnClickListener(new View.OnClickListener() {
|
holder.checkboxVisible.setOnClickListener(v -> {
|
||||||
public void onClick(View v) {
|
CheckBox cb = (CheckBox) v;
|
||||||
CheckBox cb = (CheckBox) v;
|
PluginBase plugin12 = (PluginBase) cb.getTag();
|
||||||
PluginBase plugin = (PluginBase) cb.getTag();
|
plugin12.setFragmentVisible(type, cb.isChecked());
|
||||||
plugin.setFragmentVisible(type, cb.isChecked());
|
ConfigBuilderPlugin.getPlugin().storeSettings("CheckedCheckboxVisible");
|
||||||
configBuilderPlugin.storeSettings();
|
MainApp.bus().post(new EventRefreshGui());
|
||||||
MainApp.bus().post(new EventRefreshGui());
|
ConfigBuilderPlugin.getPlugin().logPluginStatus();
|
||||||
getPlugin().logPluginStatus();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
holder.settings.setOnClickListener(new View.OnClickListener() {
|
holder.settings.setOnClickListener(v -> {
|
||||||
public void onClick(View v) {
|
final PluginBase plugin13 = (PluginBase) v.getTag();
|
||||||
final PluginBase plugin = (PluginBase) v.getTag();
|
PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", () -> {
|
||||||
PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", new Runnable() {
|
Intent i = new Intent(getContext(), PreferencesActivity.class);
|
||||||
@Override
|
i.putExtra("id", plugin13.getPreferencesId());
|
||||||
public void run() {
|
startActivity(i);
|
||||||
Intent i = new Intent(getContext(), PreferencesActivity.class);
|
}, null);
|
||||||
i.putExtra("id", plugin.getPreferencesId());
|
|
||||||
startActivity(i);
|
|
||||||
}
|
|
||||||
}, null);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
holder.name.setOnLongClickListener(new View.OnLongClickListener() {
|
holder.name.setOnLongClickListener(v -> {
|
||||||
@Override
|
final PluginBase plugin14 = (PluginBase) v.getTag();
|
||||||
public boolean onLongClick(View v) {
|
PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", () -> {
|
||||||
final PluginBase plugin = (PluginBase) v.getTag();
|
Intent i = new Intent(getContext(), PreferencesActivity.class);
|
||||||
PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", new Runnable() {
|
i.putExtra("id", plugin14.getPreferencesId());
|
||||||
@Override
|
startActivity(i);
|
||||||
public void run() {
|
}, null);
|
||||||
Intent i = new Intent(getContext(), PreferencesActivity.class);
|
return false;
|
||||||
i.putExtra("id", plugin.getPreferencesId());
|
|
||||||
startActivity(i);
|
|
||||||
}
|
|
||||||
}, null);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -293,15 +275,18 @@ public class ConfigBuilderFragment extends Fragment {
|
||||||
|
|
||||||
holder.name.setText(plugin.getName());
|
holder.name.setText(plugin.getName());
|
||||||
holder.checkboxEnabled.setChecked(plugin.isEnabled(type));
|
holder.checkboxEnabled.setChecked(plugin.isEnabled(type));
|
||||||
holder.checkboxVisible.setChecked(plugin.isVisibleInTabs(type));
|
holder.checkboxVisible.setChecked(plugin.isFragmentVisible());
|
||||||
holder.name.setTag(plugin);
|
holder.name.setTag(plugin);
|
||||||
holder.checkboxEnabled.setTag(plugin);
|
holder.checkboxEnabled.setTag(plugin);
|
||||||
holder.checkboxVisible.setTag(plugin);
|
holder.checkboxVisible.setTag(plugin);
|
||||||
holder.settings.setTag(plugin);
|
holder.settings.setTag(plugin);
|
||||||
|
|
||||||
if (!plugin.canBeHidden(type)) {
|
if (plugin.pluginDescription.alwaysEnabled) {
|
||||||
|
holder.checkboxEnabled.setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (plugin.pluginDescription.alwayVisible) {
|
||||||
holder.checkboxEnabled.setEnabled(false);
|
holder.checkboxEnabled.setEnabled(false);
|
||||||
holder.checkboxVisible.setEnabled(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!plugin.isEnabled(type)) {
|
if (!plugin.isEnabled(type)) {
|
||||||
|
@ -313,19 +298,19 @@ public class ConfigBuilderFragment extends Fragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hide enabled control and force enabled plugin if there is only one plugin available
|
// 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 (type == PluginType.INSULIN || type == PluginType.PUMP || type == PluginType.SENSITIVITY)
|
||||||
if (pluginList.size() < 2) {
|
if (pluginList.size() < 2) {
|
||||||
holder.checkboxEnabled.setEnabled(false);
|
holder.checkboxEnabled.setEnabled(false);
|
||||||
plugin.setFragmentEnabled(type, true);
|
plugin.setPluginEnabled(type, true);
|
||||||
getPlugin().storeSettings();
|
ConfigBuilderPlugin.getPlugin().storeSettings("ForceEnable");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constraints cannot be disabled
|
// Constraints cannot be disabled
|
||||||
if (type == PluginBase.CONSTRAINTS)
|
if (type == PluginType.CONSTRAINTS)
|
||||||
holder.checkboxEnabled.setEnabled(false);
|
holder.checkboxEnabled.setEnabled(false);
|
||||||
|
|
||||||
// Hide disabled profiles by default
|
// Hide disabled profiles by default
|
||||||
if (type == PluginBase.PROFILE) {
|
if (type == PluginType.PROFILE) {
|
||||||
if (!plugin.isEnabled(type)) {
|
if (!plugin.isEnabled(type)) {
|
||||||
holder.checkboxVisible.setEnabled(false);
|
holder.checkboxVisible.setEnabled(false);
|
||||||
holder.checkboxVisible.setChecked(false);
|
holder.checkboxVisible.setChecked(false);
|
||||||
|
@ -335,9 +320,9 @@ public class ConfigBuilderFragment extends Fragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable profile control for pump profiles if pump is not enabled
|
// Disable profile control for pump profiles if pump is not enabled
|
||||||
if (type == PluginBase.PROFILE) {
|
if (type == PluginType.PROFILE) {
|
||||||
if (PumpInterface.class.isAssignableFrom(plugin.getClass())) {
|
if (PumpInterface.class.isAssignableFrom(plugin.getClass())) {
|
||||||
if (!plugin.isEnabled(PluginBase.PUMP)) {
|
if (!plugin.isEnabled(PluginType.PUMP)) {
|
||||||
holder.checkboxEnabled.setEnabled(false);
|
holder.checkboxEnabled.setEnabled(false);
|
||||||
holder.checkboxEnabled.setChecked(false);
|
holder.checkboxEnabled.setChecked(false);
|
||||||
}
|
}
|
||||||
|
@ -354,32 +339,32 @@ public class ConfigBuilderFragment extends Fragment {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void onEnabledCategoryChanged(PluginBase changedPlugin, int type) {
|
void onEnabledCategoryChanged(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,23 +375,23 @@ 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();
|
updateGUI();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -24,9 +24,10 @@ 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.utils.FabricPrivacy;
|
import info.nightscout.utils.FabricPrivacy;
|
||||||
|
|
||||||
public class ObjectivesFragment extends Fragment {
|
public class ObjectivesFragment extends SubscriberFragment {
|
||||||
private static Logger log = LoggerFactory.getLogger(ObjectivesFragment.class);
|
private static Logger log = LoggerFactory.getLogger(ObjectivesFragment.class);
|
||||||
|
|
||||||
RecyclerView recyclerView;
|
RecyclerView recyclerView;
|
||||||
|
@ -214,15 +215,13 @@ public class ObjectivesFragment extends Fragment {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateGUI() {
|
@Override
|
||||||
|
public void updateGUI() {
|
||||||
Activity activity = getActivity();
|
Activity activity = getActivity();
|
||||||
if (activity != null)
|
if (activity != null)
|
||||||
activity.runOnUiThread(new Runnable() {
|
activity.runOnUiThread(() -> {
|
||||||
@Override
|
RecyclerViewAdapter adapter = new RecyclerViewAdapter(ObjectivesPlugin.objectives);
|
||||||
public void run() {
|
recyclerView.setAdapter(adapter);
|
||||||
RecyclerViewAdapter adapter = new RecyclerViewAdapter(ObjectivesPlugin.objectives);
|
|
||||||
recyclerView.setAdapter(adapter);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,25 +10,30 @@ import java.util.ArrayList;
|
||||||
import java.util.Date;
|
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.db.DatabaseHelper;
|
||||||
import info.nightscout.androidaps.interfaces.APSInterface;
|
import info.nightscout.androidaps.interfaces.APSInterface;
|
||||||
|
import info.nightscout.androidaps.interfaces.Constraint;
|
||||||
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.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||||
import info.nightscout.androidaps.plugins.ConstraintsSafety.SafetyPlugin;
|
import info.nightscout.androidaps.plugins.ConstraintsSafety.SafetyPlugin;
|
||||||
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.PumpVirtual.VirtualPumpPlugin;
|
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||||
|
import info.nightscout.utils.DateUtil;
|
||||||
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(ObjectivesPlugin.class);
|
||||||
|
|
||||||
private static ObjectivesPlugin objectivesPlugin;
|
private static ObjectivesPlugin objectivesPlugin;
|
||||||
|
@ -42,80 +47,26 @@ public class ObjectivesPlugin implements PluginBase, ConstraintsInterface {
|
||||||
|
|
||||||
public static List<Objective> objectives;
|
public static List<Objective> objectives;
|
||||||
|
|
||||||
private boolean fragmentVisible = true;
|
|
||||||
|
|
||||||
private ObjectivesPlugin() {
|
private ObjectivesPlugin() {
|
||||||
|
super(new PluginDescription()
|
||||||
|
.mainType(PluginType.CONSTRAINTS)
|
||||||
|
.fragmentClass(ObjectivesFragment.class.getName())
|
||||||
|
.alwaysEnabled(!Config.NSCLIENT && !Config.G5UPLOADER)
|
||||||
|
.showInList(!Config.NSCLIENT && !Config.G5UPLOADER)
|
||||||
|
.pluginName(R.string.objectives)
|
||||||
|
.shortName(R.string.objectives_shortname)
|
||||||
|
);
|
||||||
initializeData();
|
initializeData();
|
||||||
loadProgress();
|
loadProgress();
|
||||||
MainApp.bus().register(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getFragmentClass() {
|
public boolean specialEnableCondition() {
|
||||||
return ObjectivesFragment.class.getName();
|
PumpInterface pump = ConfigBuilderPlugin.getActivePump();
|
||||||
|
return pump == null || pump.getPumpDescription().isTempBasalCapable;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public class Objective {
|
||||||
public int getType() {
|
|
||||||
return PluginBase.CONSTRAINTS;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return MainApp.instance().getString(R.string.objectives);
|
|
||||||
}
|
|
||||||
|
|
||||||
@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;
|
Integer num;
|
||||||
String objective;
|
String objective;
|
||||||
String gate;
|
String gate;
|
||||||
|
@ -131,6 +82,18 @@ public class ObjectivesPlugin implements PluginBase, ConstraintsInterface {
|
||||||
this.durationInDays = durationInDays;
|
this.durationInDays = durationInDays;
|
||||||
this.accomplished = accomplished;
|
this.accomplished = accomplished;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setStarted(Date started) {
|
||||||
|
this.started = started;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isStarted() {
|
||||||
|
return started.getTime() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isFinished() {
|
||||||
|
return accomplished.getTime() != 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Objective 0
|
// Objective 0
|
||||||
|
@ -158,37 +121,41 @@ public class ObjectivesPlugin implements PluginBase, ConstraintsInterface {
|
||||||
RequirementResult requirementsMet(Integer objNum) {
|
RequirementResult requirementsMet(Integer objNum) {
|
||||||
switch (objNum) {
|
switch (objNum) {
|
||||||
case 0:
|
case 0:
|
||||||
boolean isVirtualPump = VirtualPumpPlugin.getPlugin().isEnabled(PluginBase.PUMP);
|
boolean isVirtualPump = VirtualPumpPlugin.getPlugin().isEnabled(PluginType.PUMP);
|
||||||
boolean vpUploadEnabled = SP.getBoolean("virtualpump_uploadstatus", false);
|
boolean vpUploadEnabled = SP.getBoolean("virtualpump_uploadstatus", false);
|
||||||
boolean vpUploadNeeded = !isVirtualPump || vpUploadEnabled;
|
boolean vpUploadNeeded = !isVirtualPump || vpUploadEnabled;
|
||||||
boolean hasBGData = DatabaseHelper.lastBg() != null;
|
boolean hasBGData = DatabaseHelper.lastBg() != null;
|
||||||
|
|
||||||
boolean apsEnabled = false;
|
boolean apsEnabled = false;
|
||||||
APSInterface usedAPS = ConfigBuilderPlugin.getActiveAPS();
|
APSInterface usedAPS = ConfigBuilderPlugin.getActiveAPS();
|
||||||
if (usedAPS != null && ((PluginBase) usedAPS).isEnabled(PluginBase.APS))
|
if (usedAPS != null && ((PluginBase) usedAPS).isEnabled(PluginType.APS))
|
||||||
apsEnabled = true;
|
apsEnabled = true;
|
||||||
|
|
||||||
return new RequirementResult(hasBGData && bgIsAvailableInNS && pumpStatusIsAvailableInNS && NSClientInternalPlugin.getPlugin().hasWritePermission() && LoopPlugin.getPlugin().isEnabled(PluginBase.LOOP) && apsEnabled && vpUploadNeeded,
|
boolean profileSwitchExists = TreatmentsPlugin.getPlugin().getProfileSwitchFromHistory(DateUtil.now()) != null;
|
||||||
MainApp.sResources.getString(R.string.objectives_bgavailableinns) + ": " + yesOrNo(bgIsAvailableInNS)
|
|
||||||
+ "\n" + MainApp.sResources.getString(R.string.nsclienthaswritepermission) + ": " + yesOrNo(NSClientInternalPlugin.getPlugin().hasWritePermission())
|
return new RequirementResult(hasBGData && bgIsAvailableInNS && pumpStatusIsAvailableInNS && NSClientPlugin.getPlugin().hasWritePermission() && LoopPlugin.getPlugin().isEnabled(PluginType.LOOP) && apsEnabled && vpUploadNeeded && profileSwitchExists,
|
||||||
+ (isVirtualPump ? "\n" + MainApp.sResources.getString(R.string.virtualpump_uploadstatus_title) + ": " + yesOrNo(vpUploadEnabled) : "")
|
MainApp.gs(R.string.objectives_bgavailableinns) + ": " + yesOrNo(bgIsAvailableInNS)
|
||||||
+ "\n" + MainApp.sResources.getString(R.string.objectives_pumpstatusavailableinns) + ": " + yesOrNo(pumpStatusIsAvailableInNS)
|
+ "\n" + MainApp.gs(R.string.nsclienthaswritepermission) + ": " + yesOrNo(NSClientPlugin.getPlugin().hasWritePermission())
|
||||||
+ "\n" + MainApp.sResources.getString(R.string.hasbgdata) + ": " + yesOrNo(hasBGData)
|
+ (isVirtualPump ? "\n" + MainApp.gs(R.string.virtualpump_uploadstatus_title) + ": " + yesOrNo(vpUploadEnabled) : "")
|
||||||
+ "\n" + MainApp.sResources.getString(R.string.loopenabled) + ": " + yesOrNo(LoopPlugin.getPlugin().isEnabled(PluginBase.LOOP))
|
+ "\n" + MainApp.gs(R.string.objectives_pumpstatusavailableinns) + ": " + yesOrNo(pumpStatusIsAvailableInNS)
|
||||||
+ "\n" + MainApp.sResources.getString(R.string.apsselected) + ": " + yesOrNo(apsEnabled)
|
+ "\n" + MainApp.gs(R.string.hasbgdata) + ": " + yesOrNo(hasBGData)
|
||||||
|
+ "\n" + MainApp.gs(R.string.loopenabled) + ": " + yesOrNo(LoopPlugin.getPlugin().isEnabled(PluginType.LOOP))
|
||||||
|
+ "\n" + MainApp.gs(R.string.apsselected) + ": " + yesOrNo(apsEnabled)
|
||||||
|
+ "\n" + MainApp.gs(R.string.activate_profile) + ": " + yesOrNo(profileSwitchExists)
|
||||||
);
|
);
|
||||||
case 1:
|
case 1:
|
||||||
return new RequirementResult(manualEnacts >= manualEnactsNeeded,
|
return new RequirementResult(manualEnacts >= manualEnactsNeeded,
|
||||||
MainApp.sResources.getString(R.string.objectives_manualenacts) + ": " + manualEnacts + "/" + manualEnactsNeeded);
|
MainApp.gs(R.string.objectives_manualenacts) + ": " + manualEnacts + "/" + manualEnactsNeeded);
|
||||||
case 2:
|
case 2:
|
||||||
return new RequirementResult(true, "");
|
return new RequirementResult(true, "");
|
||||||
case 3:
|
case 3:
|
||||||
boolean closedModeEnabled = SafetyPlugin.getPlugin().isClosedModeEnabled();
|
Constraint<Boolean> closedLoopEnabled = new Constraint<>(true);
|
||||||
return new RequirementResult(closedModeEnabled, MainApp.sResources.getString(R.string.closedmodeenabled) + ": " + yesOrNo(closedModeEnabled));
|
SafetyPlugin.getPlugin().isClosedLoopAllowed(closedLoopEnabled);
|
||||||
|
return new RequirementResult(closedLoopEnabled.value(), MainApp.gs(R.string.closedmodeenabled) + ": " + yesOrNo(closedLoopEnabled.value()));
|
||||||
case 4:
|
case 4:
|
||||||
double maxIOB = MainApp.getConfigBuilder().applyMaxIOBConstraints(1000d);
|
double maxIOB = MainApp.getConstraintChecker().getMaxIOBAllowed().value();
|
||||||
boolean maxIobSet = maxIOB > 0;
|
boolean maxIobSet = maxIOB > 0;
|
||||||
return new RequirementResult(maxIobSet, MainApp.sResources.getString(R.string.maxiobset) + ": " + yesOrNo(maxIobSet));
|
return new RequirementResult(maxIobSet, MainApp.gs(R.string.maxiobset) + ": " + yesOrNo(maxIobSet));
|
||||||
default:
|
default:
|
||||||
return new RequirementResult(true, "");
|
return new RequirementResult(true, "");
|
||||||
}
|
}
|
||||||
|
@ -202,49 +169,49 @@ public class ObjectivesPlugin implements PluginBase, ConstraintsInterface {
|
||||||
|
|
||||||
objectives = new ArrayList<>();
|
objectives = new ArrayList<>();
|
||||||
objectives.add(new Objective(0,
|
objectives.add(new Objective(0,
|
||||||
MainApp.sResources.getString(R.string.objectives_0_objective),
|
MainApp.gs(R.string.objectives_0_objective),
|
||||||
MainApp.sResources.getString(R.string.objectives_0_gate),
|
MainApp.gs(R.string.objectives_0_gate),
|
||||||
new Date(0),
|
new Date(0),
|
||||||
0, // 0 day
|
0, // 0 day
|
||||||
new Date(0)));
|
new Date(0)));
|
||||||
objectives.add(new Objective(1,
|
objectives.add(new Objective(1,
|
||||||
MainApp.sResources.getString(R.string.objectives_1_objective),
|
MainApp.gs(R.string.objectives_1_objective),
|
||||||
MainApp.sResources.getString(R.string.objectives_1_gate),
|
MainApp.gs(R.string.objectives_1_gate),
|
||||||
new Date(0),
|
new Date(0),
|
||||||
7, // 7 days
|
7, // 7 days
|
||||||
new Date(0)));
|
new Date(0)));
|
||||||
objectives.add(new Objective(2,
|
objectives.add(new Objective(2,
|
||||||
MainApp.sResources.getString(R.string.objectives_2_objective),
|
MainApp.gs(R.string.objectives_2_objective),
|
||||||
MainApp.sResources.getString(R.string.objectives_2_gate),
|
MainApp.gs(R.string.objectives_2_gate),
|
||||||
new Date(0),
|
new Date(0),
|
||||||
0, // 0 days
|
0, // 0 days
|
||||||
new Date(0)));
|
new Date(0)));
|
||||||
objectives.add(new Objective(3,
|
objectives.add(new Objective(3,
|
||||||
MainApp.sResources.getString(R.string.objectives_3_objective),
|
MainApp.gs(R.string.objectives_3_objective),
|
||||||
MainApp.sResources.getString(R.string.objectives_3_gate),
|
MainApp.gs(R.string.objectives_3_gate),
|
||||||
new Date(0),
|
new Date(0),
|
||||||
5, // 5 days
|
5, // 5 days
|
||||||
new Date(0)));
|
new Date(0)));
|
||||||
objectives.add(new Objective(4,
|
objectives.add(new Objective(4,
|
||||||
MainApp.sResources.getString(R.string.objectives_4_objective),
|
MainApp.gs(R.string.objectives_4_objective),
|
||||||
MainApp.sResources.getString(R.string.objectives_4_gate),
|
MainApp.gs(R.string.objectives_4_gate),
|
||||||
new Date(0),
|
new Date(0),
|
||||||
1,
|
1,
|
||||||
new Date(0)));
|
new Date(0)));
|
||||||
objectives.add(new Objective(5,
|
objectives.add(new Objective(5,
|
||||||
MainApp.sResources.getString(R.string.objectives_5_objective),
|
MainApp.gs(R.string.objectives_5_objective),
|
||||||
MainApp.sResources.getString(R.string.objectives_5_gate),
|
MainApp.gs(R.string.objectives_5_gate),
|
||||||
new Date(0),
|
new Date(0),
|
||||||
7,
|
7,
|
||||||
new Date(0)));
|
new Date(0)));
|
||||||
objectives.add(new Objective(6,
|
objectives.add(new Objective(6,
|
||||||
MainApp.sResources.getString(R.string.objectives_6_objective),
|
MainApp.gs(R.string.objectives_6_objective),
|
||||||
"",
|
"",
|
||||||
new Date(0),
|
new Date(0),
|
||||||
28,
|
28,
|
||||||
new Date(0)));
|
new Date(0)));
|
||||||
objectives.add(new Objective(7,
|
objectives.add(new Objective(7,
|
||||||
MainApp.sResources.getString(R.string.objectives_7_objective),
|
MainApp.gs(R.string.objectives_7_objective),
|
||||||
"",
|
"",
|
||||||
new Date(0),
|
new Date(0),
|
||||||
28,
|
28,
|
||||||
|
@ -294,60 +261,45 @@ public class ObjectivesPlugin implements PluginBase, ConstraintsInterface {
|
||||||
* Constraints interface
|
* Constraints interface
|
||||||
**/
|
**/
|
||||||
@Override
|
@Override
|
||||||
public boolean isLoopEnabled() {
|
public Constraint<Boolean> isLoopInvokationAllowed(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).isFinished())
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,20 @@
|
||||||
package info.nightscout.androidaps.plugins.ConstraintsSafety;
|
package info.nightscout.androidaps.plugins.ConstraintsSafety;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.BuildConfig;
|
|
||||||
import info.nightscout.androidaps.Config;
|
|
||||||
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.ConstraintChecker;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
|
import info.nightscout.androidaps.interfaces.BgSourceInterface;
|
||||||
|
import info.nightscout.androidaps.interfaces.Constraint;
|
||||||
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.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.OpenAPSAMA.OpenAPSAMAPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.OpenAPSMA.OpenAPSMAPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.OpenAPSSMB.OpenAPSSMBPlugin;
|
||||||
|
import info.nightscout.utils.DecimalFormatter;
|
||||||
import info.nightscout.utils.HardLimits;
|
import info.nightscout.utils.HardLimits;
|
||||||
import info.nightscout.utils.Round;
|
import info.nightscout.utils.Round;
|
||||||
import info.nightscout.utils.SP;
|
import info.nightscout.utils.SP;
|
||||||
|
@ -21,8 +22,7 @@ import info.nightscout.utils.SP;
|
||||||
/**
|
/**
|
||||||
* Created by mike on 05.08.2016.
|
* Created by mike on 05.08.2016.
|
||||||
*/
|
*/
|
||||||
public class SafetyPlugin implements PluginBase, ConstraintsInterface {
|
public class SafetyPlugin extends PluginBase implements ConstraintsInterface {
|
||||||
private static Logger log = LoggerFactory.getLogger(SafetyPlugin.class);
|
|
||||||
|
|
||||||
static SafetyPlugin plugin = null;
|
static SafetyPlugin plugin = null;
|
||||||
|
|
||||||
|
@ -32,201 +32,144 @@ public class SafetyPlugin implements PluginBase, ConstraintsInterface {
|
||||||
return plugin;
|
return plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public SafetyPlugin() {
|
||||||
public String getFragmentClass() {
|
super(new PluginDescription()
|
||||||
return null;
|
.mainType(PluginType.CONSTRAINTS)
|
||||||
}
|
.neverVisible(true)
|
||||||
|
.alwaysEnabled(true)
|
||||||
@Override
|
.showInList(false)
|
||||||
public int getType() {
|
.pluginName(R.string.safety)
|
||||||
return PluginBase.CONSTRAINTS;
|
.preferencesId(R.xml.pref_safety)
|
||||||
}
|
);
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return MainApp.instance().getString(R.string.safety);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getNameShort() {
|
|
||||||
// use long name as fallback (no tabs)
|
|
||||||
return getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled(int type) {
|
|
||||||
return type == CONSTRAINTS;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isVisibleInTabs(int type) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canBeHidden(int type) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasFragment() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean showInList(int type) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setFragmentEnabled(int type, boolean fragmentEnabled) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setFragmentVisible(int type, boolean fragmentVisible) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getPreferencesId() {
|
|
||||||
return R.xml.pref_safety;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isLoopEnabled() {
|
|
||||||
return ConfigBuilderPlugin.getActivePump().getPumpDescription().isTempBasalCapable;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constraints interface
|
* Constraints interface
|
||||||
**/
|
**/
|
||||||
@Override
|
@Override
|
||||||
public boolean isClosedModeEnabled() {
|
public Constraint<Boolean> isLoopInvokationAllowed(Constraint<Boolean> value) {
|
||||||
|
if (!ConfigBuilderPlugin.getActivePump().getPumpDescription().isTempBasalCapable)
|
||||||
|
value.set(false, MainApp.gs(R.string.pumpisnottempbasalcapable), this);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Constraint<Boolean> isClosedLoopAllowed(Constraint<Boolean> value) {
|
||||||
|
if (!MainApp.isEngineeringModeOrRelease())
|
||||||
|
value.set(false, MainApp.gs(R.string.closed_loop_disabled_on_dev_branch), this);
|
||||||
|
|
||||||
String mode = SP.getString("aps_mode", "open");
|
String mode = SP.getString("aps_mode", "open");
|
||||||
return mode.equals("closed") && BuildConfig.CLOSEDLOOP;
|
if (!mode.equals("closed"))
|
||||||
|
value.set(false, MainApp.gs(R.string.closedmodedisabledinpreferences), this);
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAutosensModeEnabled() {
|
public Constraint<Boolean> isAutosensModeEnabled(Constraint<Boolean> value) {
|
||||||
return true;
|
boolean enabled = SP.getBoolean(R.string.key_openapsama_useautosens, false);
|
||||||
|
if (!enabled)
|
||||||
|
value.set(false, MainApp.gs(R.string.autosensdisabledinpreferences), this);
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAMAModeEnabled() {
|
public Constraint<Boolean> isSMBModeEnabled(Constraint<Boolean> value) {
|
||||||
return true;
|
boolean enabled = SP.getBoolean(R.string.key_use_smb, false);
|
||||||
|
if (!enabled)
|
||||||
|
value.set(false, MainApp.gs(R.string.smbdisabledinpreferences), this);
|
||||||
|
ConstraintChecker constraintChecker = MainApp.getConstraintChecker();
|
||||||
|
Constraint<Boolean> closedLoop = constraintChecker.isClosedLoopAllowed();
|
||||||
|
if (!closedLoop.value())
|
||||||
|
value.set(false, MainApp.gs(R.string.smbnotallowedinopenloopmode), this);
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSMBModeEnabled() {
|
public Constraint<Boolean> isAdvancedFilteringEnabled(Constraint<Boolean> value) {
|
||||||
return true;
|
BgSourceInterface bgSource = MainApp.getConfigBuilder().getActiveBgSource();
|
||||||
|
|
||||||
|
if (bgSource != null) {
|
||||||
|
if (!bgSource.advancedFilteringSupported())
|
||||||
|
value.set(false, MainApp.gs(R.string.smbalwaysdisabled), this);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Double applyBasalConstraints(Double absoluteRate) {
|
public Constraint<Double> applyBasalConstraints(Constraint<Double> absoluteRate, Profile profile) {
|
||||||
Double origAbsoluteRate = absoluteRate;
|
|
||||||
Double maxBasal = SP.getDouble("openapsma_max_basal", 1d);
|
|
||||||
|
|
||||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
absoluteRate.setIfGreater(0d, String.format(MainApp.gs(R.string.limitingbasalratio), 0d, MainApp.gs(R.string.itmustbepositivevalue)), this);
|
||||||
if (profile == null) return absoluteRate;
|
|
||||||
if (absoluteRate < 0) absoluteRate = 0d;
|
double maxBasal = SP.getDouble(R.string.key_openapsma_max_basal, 1d);
|
||||||
|
absoluteRate.setIfSmaller(maxBasal, String.format(MainApp.gs(R.string.limitingbasalratio), maxBasal, MainApp.gs(R.string.maxvalueinpreferences)), this);
|
||||||
|
|
||||||
Double maxBasalMult = SP.getDouble("openapsama_current_basal_safety_multiplier", 4d);
|
|
||||||
Integer maxBasalFromDaily = SP.getInt("openapsama_max_daily_safety_multiplier", 3);
|
|
||||||
// Check percentRate but absolute rate too, because we know real current basal in pump
|
// Check percentRate but absolute rate too, because we know real current basal in pump
|
||||||
Double origRate = absoluteRate;
|
Double maxBasalMult = SP.getDouble(R.string.key_openapsama_current_basal_safety_multiplier, 4d);
|
||||||
if (absoluteRate > maxBasal) {
|
double maxFromBasalMult = Math.floor(maxBasalMult * profile.getBasal() * 100) / 100;
|
||||||
absoluteRate = maxBasal;
|
absoluteRate.setIfSmaller(maxFromBasalMult, String.format(MainApp.gs(R.string.limitingbasalratio), maxFromBasalMult, MainApp.gs(R.string.maxbasalmultiplier)), this);
|
||||||
if (Config.logConstraintsChanges && origAbsoluteRate != Constants.basalAbsoluteOnlyForCheckLimit)
|
|
||||||
log.debug("Limiting rate " + origRate + " by maxBasal preference to " + absoluteRate + "U/h");
|
Double maxBasalFromDaily = SP.getDouble(R.string.key_openapsama_max_daily_safety_multiplier, 3d);
|
||||||
}
|
double maxFromDaily = Math.floor(profile.getMaxDailyBasal() * maxBasalFromDaily * 100) / 100;
|
||||||
if (absoluteRate > maxBasalMult * profile.getBasal()) {
|
absoluteRate.setIfSmaller(maxFromDaily, String.format(MainApp.gs(R.string.limitingbasalratio), maxFromDaily, MainApp.gs(R.string.maxdailybasalmultiplier)), this);
|
||||||
absoluteRate = Math.floor(maxBasalMult * profile.getBasal() * 100) / 100;
|
|
||||||
if (Config.logConstraintsChanges && origAbsoluteRate != Constants.basalAbsoluteOnlyForCheckLimit)
|
absoluteRate.setIfSmaller(HardLimits.maxBasal(), String.format(MainApp.gs(R.string.limitingbasalratio), HardLimits.maxBasal(), MainApp.gs(R.string.hardlimit)), this);
|
||||||
log.debug("Limiting rate " + origRate + " by maxBasalMult to " + absoluteRate + "U/h");
|
|
||||||
}
|
|
||||||
if (absoluteRate > profile.getMaxDailyBasal() * maxBasalFromDaily) {
|
|
||||||
absoluteRate = profile.getMaxDailyBasal() * maxBasalFromDaily;
|
|
||||||
if (Config.logConstraintsChanges && origAbsoluteRate != Constants.basalAbsoluteOnlyForCheckLimit)
|
|
||||||
log.debug("Limiting rate " + origRate + " by 3 * maxDailyBasal to " + absoluteRate + "U/h");
|
|
||||||
}
|
|
||||||
return absoluteRate;
|
return absoluteRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Integer applyBasalConstraints(Integer percentRate) {
|
public Constraint<Integer> applyBasalPercentConstraints(Constraint<Integer> percentRate, Profile profile) {
|
||||||
Integer origPercentRate = percentRate;
|
|
||||||
Double maxBasal = SP.getDouble("openapsma_max_basal", 1d);
|
|
||||||
|
|
||||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
|
||||||
if (profile == null) return percentRate;
|
|
||||||
Double currentBasal = profile.getBasal();
|
Double currentBasal = profile.getBasal();
|
||||||
|
Double absoluteRate = currentBasal * ((double) percentRate.originalValue() / 100);
|
||||||
|
|
||||||
Double absoluteRate = currentBasal * ((double) percentRate / 100);
|
percentRate.addReason("Percent rate " + percentRate.originalValue() + "% recalculated to " + DecimalFormatter.to2Decimal(absoluteRate) + " U/h with current basal " + DecimalFormatter.to2Decimal(currentBasal) + " U/h", this);
|
||||||
|
|
||||||
if (Config.logConstraintsChanges)
|
Constraint<Double> absoluteConstraint = new Constraint<>(absoluteRate);
|
||||||
log.debug("Percent rate " + percentRate + "% recalculated to " + absoluteRate + "U/h with current basal " + currentBasal + "U/h");
|
applyBasalConstraints(absoluteConstraint, profile);
|
||||||
|
percentRate.copyReasons(absoluteConstraint);
|
||||||
|
|
||||||
if (absoluteRate < 0) absoluteRate = 0d;
|
Integer percentRateAfterConst = Double.valueOf(absoluteConstraint.value() / currentBasal * 100).intValue();
|
||||||
|
|
||||||
Double maxBasalMult = SP.getDouble("openapsama_current_basal_safety_multiplier", 4d);
|
|
||||||
Integer maxBasalFromDaily = SP.getInt("openapsama_max_daily_safety_multiplier", 3);
|
|
||||||
// Check percentRate but absolute rate too, because we know real current basal in pump
|
|
||||||
Double origRate = absoluteRate;
|
|
||||||
if (absoluteRate > maxBasal) {
|
|
||||||
absoluteRate = maxBasal;
|
|
||||||
if (Config.logConstraintsChanges && !Objects.equals(origPercentRate, Constants.basalPercentOnlyForCheckLimit))
|
|
||||||
log.debug("Limiting rate " + origRate + " by maxBasal preference to " + absoluteRate + "U/h");
|
|
||||||
}
|
|
||||||
if (absoluteRate > maxBasalMult * profile.getBasal()) {
|
|
||||||
absoluteRate = Math.floor(maxBasalMult * profile.getBasal() * 100) / 100;
|
|
||||||
if (Config.logConstraintsChanges && !Objects.equals(origPercentRate, Constants.basalPercentOnlyForCheckLimit))
|
|
||||||
log.debug("Limiting rate " + origRate + " by maxBasalMult to " + absoluteRate + "U/h");
|
|
||||||
}
|
|
||||||
if (absoluteRate > profile.getMaxDailyBasal() * maxBasalFromDaily) {
|
|
||||||
absoluteRate = profile.getMaxDailyBasal() * maxBasalFromDaily;
|
|
||||||
if (Config.logConstraintsChanges && !Objects.equals(origPercentRate, Constants.basalPercentOnlyForCheckLimit))
|
|
||||||
log.debug("Limiting rate " + origRate + " by 3 * maxDailyBasal to " + absoluteRate + "U/h");
|
|
||||||
}
|
|
||||||
|
|
||||||
Integer percentRateAfterConst = new Double(absoluteRate / currentBasal * 100).intValue();
|
|
||||||
if (percentRateAfterConst < 100)
|
if (percentRateAfterConst < 100)
|
||||||
percentRateAfterConst = Round.ceilTo((double) percentRateAfterConst, 10d).intValue();
|
percentRateAfterConst = Round.ceilTo((double) percentRateAfterConst, 10d).intValue();
|
||||||
else percentRateAfterConst = Round.floorTo((double) percentRateAfterConst, 10d).intValue();
|
else percentRateAfterConst = Round.floorTo((double) percentRateAfterConst, 10d).intValue();
|
||||||
|
|
||||||
if (Config.logConstraintsChanges && !Objects.equals(origPercentRate, Constants.basalPercentOnlyForCheckLimit))
|
percentRate.set(percentRateAfterConst, String.format(MainApp.gs(R.string.limitingpercentrate), percentRateAfterConst, MainApp.gs(R.string.pumplimit)), this);
|
||||||
log.debug("Recalculated percent rate " + percentRate + "% to " + percentRateAfterConst + "%");
|
|
||||||
return percentRateAfterConst;
|
return percentRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Double applyBolusConstraints(Double insulin) {
|
public Constraint<Double> applyBolusConstraints(Constraint<Double> insulin) {
|
||||||
try {
|
insulin.setIfGreater(0d, String.format(MainApp.gs(R.string.limitingbolus), 0d, MainApp.gs(R.string.itmustbepositivevalue)), this);
|
||||||
Double maxBolus = SP.getDouble("treatmentssafety_maxbolus", 3d);
|
|
||||||
|
|
||||||
if (insulin < 0) insulin = 0d;
|
Double maxBolus = SP.getDouble(R.string.key_treatmentssafety_maxbolus, 3d);
|
||||||
if (insulin > maxBolus) insulin = maxBolus;
|
insulin.setIfSmaller(maxBolus, String.format(MainApp.gs(R.string.limitingbolus), maxBolus, MainApp.gs(R.string.maxvalueinpreferences)), this);
|
||||||
} catch (Exception e) {
|
|
||||||
insulin = 0d;
|
insulin.setIfSmaller(HardLimits.maxBolus(), String.format(MainApp.gs(R.string.limitingbolus), HardLimits.maxBolus(), MainApp.gs(R.string.hardlimit)), this);
|
||||||
}
|
|
||||||
if (insulin > HardLimits.maxBolus()) insulin = HardLimits.maxBolus();
|
|
||||||
return insulin;
|
return insulin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Integer applyCarbsConstraints(Integer carbs) {
|
public Constraint<Integer> applyCarbsConstraints(Constraint<Integer> carbs) {
|
||||||
try {
|
carbs.setIfGreater(0, String.format(MainApp.gs(R.string.limitingcarbs), 0, MainApp.gs(R.string.itmustbepositivevalue)), this);
|
||||||
Integer maxCarbs = SP.getInt("treatmentssafety_maxcarbs", 48);
|
|
||||||
|
Integer maxCarbs = SP.getInt(R.string.key_treatmentssafety_maxcarbs, 48);
|
||||||
|
carbs.setIfSmaller(maxCarbs, String.format(MainApp.gs(R.string.limitingcarbs), maxCarbs, MainApp.gs(R.string.maxvalueinpreferences)), this);
|
||||||
|
|
||||||
if (carbs < 0) carbs = 0;
|
|
||||||
if (carbs > maxCarbs) carbs = maxCarbs;
|
|
||||||
} catch (Exception e) {
|
|
||||||
carbs = 0;
|
|
||||||
}
|
|
||||||
return carbs;
|
return carbs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Double applyMaxIOBConstraints(Double maxIob) {
|
public Constraint<Double> applyMaxIOBConstraints(Constraint<Double> maxIob) {
|
||||||
|
double maxIobPref = SP.getDouble(R.string.key_openapsma_max_iob, 1.5d);
|
||||||
|
maxIob.setIfSmaller(maxIobPref, String.format(MainApp.gs(R.string.limitingiob), maxIobPref, MainApp.gs(R.string.maxvalueinpreferences)), this);
|
||||||
|
|
||||||
|
if (OpenAPSMAPlugin.getPlugin().isEnabled(PluginType.APS))
|
||||||
|
maxIob.setIfSmaller(HardLimits.maxIobAMA(), String.format(MainApp.gs(R.string.limitingiob), HardLimits.maxIobAMA(), MainApp.gs(R.string.hardlimit)), this);
|
||||||
|
if (OpenAPSAMAPlugin.getPlugin().isEnabled(PluginType.APS))
|
||||||
|
maxIob.setIfSmaller(HardLimits.maxIobAMA(), String.format(MainApp.gs(R.string.limitingiob), HardLimits.maxIobAMA(), MainApp.gs(R.string.hardlimit)), this);
|
||||||
|
if (OpenAPSSMBPlugin.getPlugin().isEnabled(PluginType.APS))
|
||||||
|
maxIob.setIfSmaller(HardLimits.maxIobSMB(), String.format(MainApp.gs(R.string.limitingiob), HardLimits.maxIobSMB(), MainApp.gs(R.string.hardlimit)), this);
|
||||||
return maxIob;
|
return maxIob;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,27 @@
|
||||||
package info.nightscout.androidaps.db;
|
package info.nightscout.androidaps.plugins.Food;
|
||||||
|
|
||||||
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.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import info.nightscout.utils.JsonHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by mike on 20.09.2017.
|
* Created by mike on 20.09.2017.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@DatabaseTable(tableName = Food.TABLE_FOODS)
|
||||||
@DatabaseTable(tableName = DatabaseHelper.DATABASE_FOODS)
|
|
||||||
public class Food {
|
public class Food {
|
||||||
private static Logger log = LoggerFactory.getLogger(Food.class);
|
private static Logger log = LoggerFactory.getLogger(Food.class);
|
||||||
|
|
||||||
|
public static final String TABLE_FOODS = "Foods";
|
||||||
|
|
||||||
@DatabaseField(id = true)
|
@DatabaseField(id = true)
|
||||||
public long key;
|
public long key;
|
||||||
|
|
||||||
|
@ -64,6 +69,25 @@ public class Food {
|
||||||
key = System.currentTimeMillis();
|
key = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Food createFromJson(JSONObject json) throws JSONException {
|
||||||
|
Food food = new Food();
|
||||||
|
if ("food".equals(JsonHelper.safeGetString(json, "type"))) {
|
||||||
|
food._id = JsonHelper.safeGetString(json, "_id");
|
||||||
|
food.category = JsonHelper.safeGetString(json, "category");
|
||||||
|
food.subcategory = JsonHelper.safeGetString(json, "subcategory");
|
||||||
|
food.name = JsonHelper.safeGetString(json, "name");
|
||||||
|
food.units = JsonHelper.safeGetString(json, "unit");
|
||||||
|
food.portion = JsonHelper.safeGetDouble(json, "portion");
|
||||||
|
food.carbs = JsonHelper.safeGetInt(json, "carbs");
|
||||||
|
food.gi = JsonHelper.safeGetInt(json, "gi");
|
||||||
|
food.energy = JsonHelper.safeGetInt(json, "energy");
|
||||||
|
food.protein = JsonHelper.safeGetInt(json, "protein");
|
||||||
|
food.fat = JsonHelper.safeGetInt(json, "fat");
|
||||||
|
}
|
||||||
|
|
||||||
|
return food;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isEqual(Food other) {
|
public boolean isEqual(Food other) {
|
||||||
if (portion != other.portion)
|
if (portion != other.portion)
|
||||||
return false;
|
return false;
|
||||||
|
@ -104,4 +128,22 @@ public class Food {
|
||||||
units = other.units;
|
units = other.units;
|
||||||
gi = other.gi;
|
gi = other.gi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("_id=" + _id + ";");
|
||||||
|
sb.append("isValid=" + isValid + ";");
|
||||||
|
sb.append("name=" + name + ";");
|
||||||
|
sb.append("category=" + category + ";");
|
||||||
|
sb.append("subcategory=" + subcategory + ";");
|
||||||
|
sb.append("portion=" + portion + ";");
|
||||||
|
sb.append("carbs=" + carbs + ";");
|
||||||
|
sb.append("protein=" + protein + ";");
|
||||||
|
sb.append("energy=" + energy + ";");
|
||||||
|
sb.append("units=" + units + ";");
|
||||||
|
sb.append("gi=" + gi + ";");
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -26,10 +26,10 @@ import org.slf4j.LoggerFactory;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
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.Food;
|
|
||||||
import info.nightscout.androidaps.events.EventFoodDatabaseChanged;
|
import info.nightscout.androidaps.events.EventFoodDatabaseChanged;
|
||||||
import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
|
import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
|
||||||
import info.nightscout.utils.FabricPrivacy;
|
import info.nightscout.utils.FabricPrivacy;
|
||||||
|
@ -121,7 +121,8 @@ public class FoodFragment extends SubscriberFragment {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
RecyclerViewAdapter adapter = new RecyclerViewAdapter(MainApp.getDbHelper().foodHelper.getFoodData());
|
RecyclerViewAdapter adapter = new RecyclerViewAdapter(MainApp
|
||||||
|
.getSpecificPlugin(FoodPlugin.class).getService().getFoodData());
|
||||||
recyclerView.setAdapter(adapter);
|
recyclerView.setAdapter(adapter);
|
||||||
|
|
||||||
loadData();
|
loadData();
|
||||||
|
@ -144,20 +145,19 @@ public class FoodFragment extends SubscriberFragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadData() {
|
void loadData() {
|
||||||
unfiltered = MainApp.getDbHelper().foodHelper.getFoodData();
|
unfiltered = MainApp.getSpecificPlugin(FoodPlugin.class).getService().getFoodData();
|
||||||
}
|
}
|
||||||
|
|
||||||
void fillCategories() {
|
void fillCategories() {
|
||||||
categories = new ArrayList<>();
|
Set<CharSequence> catSet = new HashSet<>();
|
||||||
|
|
||||||
for (Food f : unfiltered) {
|
for (Food f : unfiltered) {
|
||||||
if (f.category != null && !f.category.equals(""))
|
if (f.category != null && !f.category.equals(""))
|
||||||
categories.add(f.category);
|
catSet.add(f.category);
|
||||||
}
|
}
|
||||||
|
|
||||||
// make it unique
|
// make it unique
|
||||||
categories = new ArrayList<>(new HashSet<>(categories));
|
categories = new ArrayList<>(catSet);
|
||||||
|
|
||||||
categories.add(0, MainApp.sResources.getString(R.string.none));
|
categories.add(0, MainApp.sResources.getString(R.string.none));
|
||||||
|
|
||||||
ArrayAdapter<CharSequence> adapterCategories = new ArrayAdapter<>(getContext(),
|
ArrayAdapter<CharSequence> adapterCategories = new ArrayAdapter<>(getContext(),
|
||||||
|
@ -167,19 +167,19 @@ public class FoodFragment extends SubscriberFragment {
|
||||||
|
|
||||||
void fillSubcategories() {
|
void fillSubcategories() {
|
||||||
String categoryFilter = category.getSelectedItem().toString();
|
String categoryFilter = category.getSelectedItem().toString();
|
||||||
subcategories = new ArrayList<>();
|
|
||||||
|
Set<CharSequence> subCatSet = new HashSet<>();
|
||||||
|
|
||||||
if (!categoryFilter.equals(EMPTY)) {
|
if (!categoryFilter.equals(EMPTY)) {
|
||||||
for (Food f : unfiltered) {
|
for (Food f : unfiltered) {
|
||||||
if (f.category != null && f.category.equals(categoryFilter))
|
if (f.category != null && f.category.equals(categoryFilter))
|
||||||
if (f.subcategory != null && !f.subcategory.equals(""))
|
if (f.subcategory != null && !f.subcategory.equals(""))
|
||||||
subcategories.add(f.subcategory);
|
subCatSet.add(f.subcategory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// make it unique
|
// make it unique
|
||||||
subcategories = new ArrayList<>(new HashSet<>(subcategories));
|
subcategories = new ArrayList<>(subCatSet);
|
||||||
|
|
||||||
subcategories.add(0, MainApp.sResources.getString(R.string.none));
|
subcategories.add(0, MainApp.sResources.getString(R.string.none));
|
||||||
|
|
||||||
ArrayAdapter<CharSequence> adapterSubcategories = new ArrayAdapter<>(getContext(),
|
ArrayAdapter<CharSequence> adapterSubcategories = new ArrayAdapter<>(getContext(),
|
||||||
|
@ -299,7 +299,7 @@ public class FoodFragment extends SubscriberFragment {
|
||||||
if (_id != null && !_id.equals("")) {
|
if (_id != null && !_id.equals("")) {
|
||||||
NSUpload.removeFoodFromNS(_id);
|
NSUpload.removeFoodFromNS(_id);
|
||||||
}
|
}
|
||||||
MainApp.getDbHelper().foodHelper.delete(food);
|
MainApp.getSpecificPlugin(FoodPlugin.class).getService().delete(food);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
builder.setNegativeButton(MainApp.sResources.getString(R.string.cancel), null);
|
builder.setNegativeButton(MainApp.sResources.getString(R.string.cancel), null);
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
package info.nightscout.androidaps.plugins.Food;
|
package info.nightscout.androidaps.plugins.Food;
|
||||||
|
|
||||||
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.08.2016.
|
* Created by mike on 05.08.2016.
|
||||||
*/
|
*/
|
||||||
public class FoodPlugin implements PluginBase {
|
public class FoodPlugin extends PluginBase {
|
||||||
private boolean fragmentEnabled = true;
|
|
||||||
private boolean fragmentVisible = false;
|
|
||||||
|
|
||||||
private static FoodPlugin plugin = null;
|
private static FoodPlugin plugin = null;
|
||||||
|
|
||||||
|
@ -19,67 +18,20 @@ public class FoodPlugin implements PluginBase {
|
||||||
return plugin;
|
return plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private FoodService service;
|
||||||
public String getFragmentClass() {
|
|
||||||
return FoodFragment.class.getName();
|
private FoodPlugin() {
|
||||||
|
super(new PluginDescription()
|
||||||
|
.mainType(PluginType.GENERAL)
|
||||||
|
.fragmentClass(FoodFragment.class.getName())
|
||||||
|
.pluginName(R.string.food)
|
||||||
|
.shortName(R.string.food_short)
|
||||||
|
);
|
||||||
|
this.service = new FoodService();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public FoodService getService() {
|
||||||
public int getType() {
|
return this.service;
|
||||||
return PluginBase.GENERAL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return MainApp.instance().getString(R.string.food);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getNameShort() {
|
|
||||||
// use long name as fallback (not visible in tabs)
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,368 @@
|
||||||
|
package info.nightscout.androidaps.plugins.Food;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.j256.ormlite.android.apptools.OpenHelperManager;
|
||||||
|
import com.j256.ormlite.android.apptools.OrmLiteBaseService;
|
||||||
|
import com.j256.ormlite.dao.Dao;
|
||||||
|
import com.j256.ormlite.dao.DaoManager;
|
||||||
|
import com.j256.ormlite.support.ConnectionSource;
|
||||||
|
import com.j256.ormlite.table.TableUtils;
|
||||||
|
import com.squareup.otto.Subscribe;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
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.db.DatabaseHelper;
|
||||||
|
import info.nightscout.androidaps.db.ICallback;
|
||||||
|
import info.nightscout.androidaps.events.Event;
|
||||||
|
import info.nightscout.androidaps.events.EventFoodDatabaseChanged;
|
||||||
|
import info.nightscout.androidaps.events.EventNsFood;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mike on 24.09.2017.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class FoodService extends OrmLiteBaseService<DatabaseHelper> {
|
||||||
|
private static Logger log = LoggerFactory.getLogger(FoodService.class);
|
||||||
|
|
||||||
|
private static final ScheduledExecutorService foodEventWorker = Executors.newSingleThreadScheduledExecutor();
|
||||||
|
private static ScheduledFuture<?> scheduledFoodEventPost = null;
|
||||||
|
|
||||||
|
public FoodService() {
|
||||||
|
onCreate();
|
||||||
|
dbInitialize();
|
||||||
|
MainApp.bus().register(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is a simple re-implementation of the database create and up/downgrade functionality
|
||||||
|
* in SQLiteOpenHelper#getDatabaseLocked method.
|
||||||
|
* <p>
|
||||||
|
* It is implemented to be able to late initialize separate plugins of the application.
|
||||||
|
*/
|
||||||
|
protected void dbInitialize() {
|
||||||
|
DatabaseHelper helper = OpenHelperManager.getHelper(this, DatabaseHelper.class);
|
||||||
|
int newVersion = helper.getNewVersion();
|
||||||
|
int oldVersion = helper.getOldVersion();
|
||||||
|
|
||||||
|
if (oldVersion > newVersion) {
|
||||||
|
onDowngrade(this.getConnectionSource(), oldVersion, newVersion);
|
||||||
|
} else {
|
||||||
|
onUpgrade(this.getConnectionSource(), oldVersion, newVersion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dao<Food, Long> getDao() {
|
||||||
|
try {
|
||||||
|
return DaoManager.createDao(this.getConnectionSource(), Food.class);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error("Cannot create Dao for Food.class");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void handleNsEvent(EventNsFood event) {
|
||||||
|
int mode = event.getMode();
|
||||||
|
Bundle payload = event.getPayload();
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (payload.containsKey("food")) {
|
||||||
|
JSONObject json = new JSONObject(payload.getString("food"));
|
||||||
|
if (mode == EventNsFood.ADD || mode == EventNsFood.UPDATE) {
|
||||||
|
this.createFoodFromJsonIfNotExists(json);
|
||||||
|
} else {
|
||||||
|
this.deleteNS(json);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (payload.containsKey("foods")) {
|
||||||
|
JSONArray array = new JSONArray(payload.getString("foods"));
|
||||||
|
if (mode == EventNsFood.ADD || mode == EventNsFood.UPDATE) {
|
||||||
|
this.createFoodFromJsonIfNotExists(array);
|
||||||
|
} else {
|
||||||
|
this.deleteNS(array);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (JSONException e) {
|
||||||
|
log.error("Unhandled Exception", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
super.onCreate();
|
||||||
|
try {
|
||||||
|
log.info("onCreate");
|
||||||
|
TableUtils.createTableIfNotExists(this.getConnectionSource(), Food.class);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error("Can't create database", e);
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onUpgrade(ConnectionSource connectionSource, int oldVersion, int newVersion) {
|
||||||
|
if (oldVersion == 7 && newVersion == 8) {
|
||||||
|
log.debug("Upgrading database from v7 to v8");
|
||||||
|
} else {
|
||||||
|
log.info("onUpgrade");
|
||||||
|
// this.resetFood();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onDowngrade(ConnectionSource connectionSource, int oldVersion, int newVersion) {
|
||||||
|
// this method is not supported right now
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetFood() {
|
||||||
|
try {
|
||||||
|
TableUtils.dropTable(this.getConnectionSource(), Food.class, true);
|
||||||
|
TableUtils.createTableIfNotExists(this.getConnectionSource(), Food.class);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error("Unhandled exception", e);
|
||||||
|
}
|
||||||
|
scheduleFoodChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A place to centrally register events to be posted, if any data changed.
|
||||||
|
* This should be implemented in an abstract service-class.
|
||||||
|
* <p>
|
||||||
|
* We do need to make sure, that ICallback is extended to be able to handle multiple
|
||||||
|
* events, or handle a list of events.
|
||||||
|
* <p>
|
||||||
|
* on some methods the earliestDataChange event is handled separatly, in that it is checked if it is
|
||||||
|
* set to null by another event already (eg. scheduleExtendedBolusChange).
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
|
* @param eventWorker
|
||||||
|
* @param callback
|
||||||
|
*/
|
||||||
|
private void scheduleEvent(final Event event, ScheduledExecutorService eventWorker,
|
||||||
|
final ICallback callback) {
|
||||||
|
|
||||||
|
class PostRunnable implements Runnable {
|
||||||
|
public void run() {
|
||||||
|
log.debug("Firing EventFoodChange");
|
||||||
|
MainApp.bus().post(event);
|
||||||
|
callback.setPost(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// prepare task for execution in 1 sec
|
||||||
|
// cancel waiting task to prevent sending multiple posts
|
||||||
|
if (callback.getPost() != null)
|
||||||
|
callback.getPost().cancel(false);
|
||||||
|
Runnable task = new PostRunnable();
|
||||||
|
final int sec = 1;
|
||||||
|
callback.setPost(eventWorker.schedule(task, sec, TimeUnit.SECONDS));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedule a foodChange Event.
|
||||||
|
*/
|
||||||
|
public void scheduleFoodChange() {
|
||||||
|
this.scheduleEvent(new EventFoodDatabaseChanged(), foodEventWorker, new ICallback() {
|
||||||
|
@Override
|
||||||
|
public void setPost(ScheduledFuture<?> post) {
|
||||||
|
scheduledFoodEventPost = post;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ScheduledFuture<?> getPost() {
|
||||||
|
return scheduledFoodEventPost;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Food> getFoodData() {
|
||||||
|
try {
|
||||||
|
return this.getDao().queryForAll();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error("Unhandled exception", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
"_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 json) {
|
||||||
|
try {
|
||||||
|
Food food = Food.createFromJson(json);
|
||||||
|
this.createFoodFromJsonIfNotExists(food);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
log.error("Unhandled exception", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void createFoodFromJsonIfNotExists(JSONArray array) {
|
||||||
|
try {
|
||||||
|
for (int n = 0; n < array.length(); n++) {
|
||||||
|
JSONObject json = array.getJSONObject(n);
|
||||||
|
Food food = Food.createFromJson(json);
|
||||||
|
this.createFoodFromJsonIfNotExists(food);
|
||||||
|
}
|
||||||
|
} catch (JSONException e) {
|
||||||
|
log.error("Unhandled exception", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void createFoodFromJsonIfNotExists(Food food) {
|
||||||
|
this.createOrUpdateByNS(food);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteNS(JSONObject json) {
|
||||||
|
try {
|
||||||
|
String _id = json.getString("_id");
|
||||||
|
this.deleteByNSId(_id);
|
||||||
|
} catch (JSONException | SQLException e) {
|
||||||
|
log.error("Unhandled exception", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteNS(JSONArray array) {
|
||||||
|
try {
|
||||||
|
for (int n = 0; n < array.length(); n++) {
|
||||||
|
JSONObject json = array.getJSONObject(n);
|
||||||
|
this.deleteNS(json);
|
||||||
|
}
|
||||||
|
} catch (JSONException e) {
|
||||||
|
log.error("Unhandled exception", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* deletes an entry by its NS Id.
|
||||||
|
* <p>
|
||||||
|
* Basically a convenience method for findByNSId and delete.
|
||||||
|
*
|
||||||
|
* @param _id
|
||||||
|
*/
|
||||||
|
public void deleteByNSId(String _id) throws SQLException {
|
||||||
|
Food stored = this.findByNSId(_id);
|
||||||
|
if (stored != null) {
|
||||||
|
log.debug("FOOD: Removing Food record from database: " + stored.toString());
|
||||||
|
this.delete(stored);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* deletes the food and sends the foodChange Event
|
||||||
|
* <p>
|
||||||
|
* should be moved ot a Service
|
||||||
|
*
|
||||||
|
* @param food
|
||||||
|
*/
|
||||||
|
public void delete(Food food) {
|
||||||
|
try {
|
||||||
|
this.getDao().delete(food);
|
||||||
|
this.scheduleFoodChange();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error("Unhandled exception", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create of update a food record by the NS (Nightscout) Id.
|
||||||
|
*
|
||||||
|
* @param food
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean createOrUpdateByNS(Food food) {
|
||||||
|
// find by NS _id
|
||||||
|
if (food._id != null && !food._id.equals("")) {
|
||||||
|
Food old = this.findByNSId(food._id);
|
||||||
|
|
||||||
|
if (old != null) {
|
||||||
|
if (!old.isEqual(food)) {
|
||||||
|
this.delete(old); // need to delete/create because date may change too
|
||||||
|
old.copyFrom(food);
|
||||||
|
this.create(old);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.createOrUpdate(food);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void createOrUpdate(Food food) {
|
||||||
|
try {
|
||||||
|
this.getDao().createOrUpdate(food);
|
||||||
|
log.debug("FOOD: Created or Updated: " + food.toString());
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error("Unable to createOrUpdate Food", e);
|
||||||
|
}
|
||||||
|
this.scheduleFoodChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void create(Food food) {
|
||||||
|
try {
|
||||||
|
this.getDao().create(food);
|
||||||
|
log.debug("FOOD: New record: " + food.toString());
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error("Unable to create Food", e);
|
||||||
|
}
|
||||||
|
this.scheduleFoodChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* finds food by its NS Id.
|
||||||
|
*
|
||||||
|
* @param _id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Food findByNSId(String _id) {
|
||||||
|
try {
|
||||||
|
List<Food> list = this.getDao().queryForEq("_id", _id);
|
||||||
|
|
||||||
|
if (list.size() == 1) { // really? if there are more then one result, then we do not return anything...
|
||||||
|
return list.get(0);
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error("Unhandled exception", e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public IBinder onBind(Intent intent) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,136 +0,0 @@
|
||||||
package info.nightscout.androidaps.plugins.Insulin;
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.Constants;
|
|
||||||
import info.nightscout.androidaps.MainApp;
|
|
||||||
import info.nightscout.androidaps.R;
|
|
||||||
import info.nightscout.androidaps.data.Iob;
|
|
||||||
import info.nightscout.androidaps.db.Treatment;
|
|
||||||
import info.nightscout.androidaps.interfaces.InsulinInterface;
|
|
||||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by mike on 17.04.2017.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class InsulinFastactingPlugin implements PluginBase, InsulinInterface {
|
|
||||||
|
|
||||||
private boolean fragmentEnabled = true;
|
|
||||||
private boolean fragmentVisible = false;
|
|
||||||
|
|
||||||
private static InsulinFastactingPlugin plugin = null;
|
|
||||||
|
|
||||||
public static InsulinFastactingPlugin getPlugin() {
|
|
||||||
if (plugin == null)
|
|
||||||
plugin = new InsulinFastactingPlugin();
|
|
||||||
return plugin;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getType() {
|
|
||||||
return INSULIN;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getFragmentClass() {
|
|
||||||
return InsulinFragment.class.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return MainApp.sResources.getString(R.string.fastactinginsulin);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getNameShort() {
|
|
||||||
return MainApp.sResources.getString(R.string.insulin_shortname);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled(int type) {
|
|
||||||
return type == INSULIN && fragmentEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isVisibleInTabs(int type) {
|
|
||||||
return type == INSULIN && 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 == INSULIN) this.fragmentEnabled = fragmentEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setFragmentVisible(int type, boolean fragmentVisible) {
|
|
||||||
if (type == INSULIN) this.fragmentVisible = fragmentVisible;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getPreferencesId() {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Insulin interface
|
|
||||||
@Override
|
|
||||||
public int getId() {
|
|
||||||
return FASTACTINGINSULIN;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getFriendlyName() {
|
|
||||||
return MainApp.sResources.getString(R.string.fastactinginsulin);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getComment() {
|
|
||||||
return MainApp.sResources.getString(R.string.fastactinginsulincomment);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public double getDia() {
|
|
||||||
return MainApp.getConfigBuilder().getProfile() != null ? MainApp.getConfigBuilder().getProfile().getDia() : Constants.defaultDIA;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iob iobCalcForTreatment(Treatment treatment, long time, double dia) {
|
|
||||||
Iob result = new Iob();
|
|
||||||
|
|
||||||
double scaleFactor = 3.0 / dia;
|
|
||||||
double peak = 75d;
|
|
||||||
double end = 180d;
|
|
||||||
|
|
||||||
if (treatment.insulin != 0d) {
|
|
||||||
long bolusTime = treatment.date;
|
|
||||||
double minAgo = scaleFactor * (time - bolusTime) / 1000d / 60d;
|
|
||||||
|
|
||||||
if (minAgo < peak) {
|
|
||||||
double x1 = minAgo / 5d + 1;
|
|
||||||
result.iobContrib = treatment.insulin * (1 - 0.001852 * x1 * x1 + 0.001852 * x1);
|
|
||||||
// units: BG (mg/dL) = (BG/U) * U insulin * scalar
|
|
||||||
result.activityContrib = treatment.insulin * (2 / dia / 60 / peak) * minAgo;
|
|
||||||
|
|
||||||
} else if (minAgo < end) {
|
|
||||||
double x2 = (minAgo - 75) / 5;
|
|
||||||
result.iobContrib = treatment.insulin * (0.001323 * x2 * x2 - 0.054233 * x2 + 0.55556);
|
|
||||||
result.activityContrib = treatment.insulin * (2 / dia / 60 - (minAgo - peak) * 2 / dia / 60 / (60 * 3 - peak));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,141 +0,0 @@
|
||||||
package info.nightscout.androidaps.plugins.Insulin;
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.Constants;
|
|
||||||
import info.nightscout.androidaps.MainApp;
|
|
||||||
import info.nightscout.androidaps.R;
|
|
||||||
import info.nightscout.androidaps.data.Iob;
|
|
||||||
import info.nightscout.androidaps.db.Treatment;
|
|
||||||
import info.nightscout.androidaps.interfaces.InsulinInterface;
|
|
||||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by mike on 17.04.2017.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class InsulinFastactingProlongedPlugin implements PluginBase, InsulinInterface {
|
|
||||||
|
|
||||||
private boolean fragmentEnabled = false;
|
|
||||||
private boolean fragmentVisible = false;
|
|
||||||
|
|
||||||
private static InsulinFastactingProlongedPlugin plugin = null;
|
|
||||||
|
|
||||||
public static InsulinFastactingProlongedPlugin getPlugin() {
|
|
||||||
if (plugin == null)
|
|
||||||
plugin = new InsulinFastactingProlongedPlugin();
|
|
||||||
return plugin;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getType() {
|
|
||||||
return INSULIN;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getFragmentClass() {
|
|
||||||
return InsulinFragment.class.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return MainApp.sResources.getString(R.string.fastactinginsulinprolonged);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getNameShort() {
|
|
||||||
return MainApp.sResources.getString(R.string.insulin_shortname);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled(int type) {
|
|
||||||
return type == INSULIN && fragmentEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isVisibleInTabs(int type) {
|
|
||||||
return type == INSULIN && 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 == INSULIN) this.fragmentEnabled = fragmentEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setFragmentVisible(int type, boolean fragmentVisible) {
|
|
||||||
if (type == INSULIN) this.fragmentVisible = fragmentVisible;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getPreferencesId() {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Insulin interface
|
|
||||||
@Override
|
|
||||||
public int getId() {
|
|
||||||
return FASTACTINGINSULINPROLONGED;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getFriendlyName() {
|
|
||||||
return MainApp.sResources.getString(R.string.fastactinginsulinprolonged);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getComment() {
|
|
||||||
return MainApp.sResources.getString(R.string.fastactinginsulincomment);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public double getDia() {
|
|
||||||
return MainApp.getConfigBuilder().getProfile() != null ? MainApp.getConfigBuilder().getProfile().getDia() : Constants.defaultDIA;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iob iobCalcForTreatment(Treatment treatment, long time, double dia) {
|
|
||||||
Iob result = new Iob();
|
|
||||||
|
|
||||||
//Double scaleFactor = 3.0 / dia;
|
|
||||||
double peak = 75d * dia / 6.0;
|
|
||||||
double tail = 180d * dia / 6.0;
|
|
||||||
double end = 360d * dia / 6.0;
|
|
||||||
double Total = 2 * peak + (tail - peak) * 5 / 2 + (end - tail) / 2;
|
|
||||||
|
|
||||||
if (treatment.insulin != 0d) {
|
|
||||||
long bolusTime = treatment.date;
|
|
||||||
double minAgo = (time - bolusTime) / 1000d / 60d;
|
|
||||||
|
|
||||||
if (minAgo < peak) {
|
|
||||||
double x1 = 6 / dia * minAgo / 5d + 1;
|
|
||||||
result.iobContrib = treatment.insulin * (1 - 0.0012595 * x1 * x1 + 0.0012595 * x1);
|
|
||||||
// units: BG (mg/dL) = (BG/U) * U insulin * scalar
|
|
||||||
result.activityContrib = treatment.insulin * ((2 * peak / Total) * 2 / peak / peak * minAgo);
|
|
||||||
} else if (minAgo < tail) {
|
|
||||||
double x2 = (6 / dia * (minAgo - peak)) / 5;
|
|
||||||
result.iobContrib = treatment.insulin * (0.00074 * x2 * x2 - 0.0403 * x2 + 0.69772);
|
|
||||||
result.activityContrib = treatment.insulin * (-((2 * peak / Total) * 2 / peak * 3 / 4) / (tail - peak) * (minAgo - peak) + (2 * peak / Total) * 2 / peak);
|
|
||||||
} else if (minAgo < end) {
|
|
||||||
double x3 = (6 / dia * (minAgo - tail)) / 5;
|
|
||||||
result.iobContrib = treatment.insulin * (0.0001323 * x3 * x3 - 0.0097 * x3 + 0.17776);
|
|
||||||
result.activityContrib = treatment.insulin * (-((2 * peak / Total) * 2 / peak * 1 / 4) / (end - tail) * (minAgo - tail) + (2 * peak / Total) * 2 / peak / 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -8,42 +8,28 @@ import info.nightscout.androidaps.data.Iob;
|
||||||
import info.nightscout.androidaps.db.Treatment;
|
import info.nightscout.androidaps.db.Treatment;
|
||||||
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.plugins.Overview.notifications.Notification;
|
import info.nightscout.androidaps.interfaces.PluginDescription;
|
||||||
|
import info.nightscout.androidaps.interfaces.PluginType;
|
||||||
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
|
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
|
||||||
|
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by adrian on 13.08.2017.
|
* Created by adrian on 13.08.2017.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public abstract class InsulinOrefBasePlugin implements PluginBase, InsulinInterface {
|
public abstract class InsulinOrefBasePlugin extends PluginBase implements InsulinInterface {
|
||||||
|
|
||||||
public static double MIN_DIA = 5;
|
public static double MIN_DIA = 5;
|
||||||
|
|
||||||
long lastWarned = 0;
|
long lastWarned = 0;
|
||||||
|
|
||||||
@Override
|
public InsulinOrefBasePlugin() {
|
||||||
public int getType() {
|
super(new PluginDescription()
|
||||||
return INSULIN;
|
.mainType(PluginType.INSULIN)
|
||||||
}
|
.fragmentClass(InsulinFragment.class.getName())
|
||||||
|
.pluginName(R.string.fastactinginsulin)
|
||||||
@Override
|
.shortName(R.string.insulin_shortname)
|
||||||
public String getNameShort() {
|
);
|
||||||
return MainApp.sResources.getString(R.string.insulin_shortname);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canBeHidden(int type) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasFragment() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean showInList(int type) {
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bus getBus() {
|
public Bus getBus() {
|
||||||
|
@ -53,7 +39,7 @@ public abstract class InsulinOrefBasePlugin implements PluginBase, InsulinInterf
|
||||||
@Override
|
@Override
|
||||||
public double getDia() {
|
public double getDia() {
|
||||||
double dia = getUserDefinedDia();
|
double dia = getUserDefinedDia();
|
||||||
if(dia >= MIN_DIA){
|
if (dia >= MIN_DIA) {
|
||||||
return dia;
|
return dia;
|
||||||
} else {
|
} else {
|
||||||
sendShortDiaNotification(dia);
|
sendShortDiaNotification(dia);
|
||||||
|
@ -62,7 +48,7 @@ public abstract class InsulinOrefBasePlugin implements PluginBase, InsulinInterf
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendShortDiaNotification(double dia) {
|
void sendShortDiaNotification(double dia) {
|
||||||
if((System.currentTimeMillis() - lastWarned) > 60*1000) {
|
if ((System.currentTimeMillis() - lastWarned) > 60 * 1000) {
|
||||||
lastWarned = System.currentTimeMillis();
|
lastWarned = System.currentTimeMillis();
|
||||||
Notification notification = new Notification(Notification.SHORT_DIA, String.format(this.getNotificationPattern(), dia, MIN_DIA), Notification.URGENT);
|
Notification notification = new Notification(Notification.SHORT_DIA, String.format(this.getNotificationPattern(), dia, MIN_DIA), Notification.URGENT);
|
||||||
this.getBus().post(new EventNewNotification(notification));
|
this.getBus().post(new EventNewNotification(notification));
|
||||||
|
@ -92,7 +78,7 @@ public abstract class InsulinOrefBasePlugin implements PluginBase, InsulinInterf
|
||||||
long bolusTime = treatment.date;
|
long bolusTime = treatment.date;
|
||||||
double t = (time - bolusTime) / 1000d / 60d;
|
double t = (time - bolusTime) / 1000d / 60d;
|
||||||
|
|
||||||
double td = getDia()*60; //getDIA() always >= MIN_DIA
|
double td = getDia() * 60; //getDIA() always >= MIN_DIA
|
||||||
double tp = peak;
|
double tp = peak;
|
||||||
|
|
||||||
// force the IOB to 0 if over DIA hours have passed
|
// force the IOB to 0 if over DIA hours have passed
|
||||||
|
@ -109,9 +95,9 @@ public abstract class InsulinOrefBasePlugin implements PluginBase, InsulinInterf
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getComment() {
|
public String getComment() {
|
||||||
String comment = commentStandardText();
|
String comment = commentStandardText();
|
||||||
double userDia = getUserDefinedDia();
|
double userDia = getUserDefinedDia();
|
||||||
if(userDia < MIN_DIA){
|
if (userDia < MIN_DIA) {
|
||||||
comment += "\n" + String.format(MainApp.sResources.getString(R.string.dia_too_short), userDia, MIN_DIA);
|
comment += "\n" + String.format(MainApp.sResources.getString(R.string.dia_too_short), userDia, MIN_DIA);
|
||||||
}
|
}
|
||||||
return comment;
|
return comment;
|
||||||
|
|
|
@ -10,9 +10,6 @@ import info.nightscout.utils.SP;
|
||||||
|
|
||||||
public class InsulinOrefFreePeakPlugin extends InsulinOrefBasePlugin {
|
public class InsulinOrefFreePeakPlugin extends InsulinOrefBasePlugin {
|
||||||
|
|
||||||
private boolean fragmentEnabled = false;
|
|
||||||
private boolean fragmentVisible = false;
|
|
||||||
|
|
||||||
private static InsulinOrefFreePeakPlugin plugin = null;
|
private static InsulinOrefFreePeakPlugin plugin = null;
|
||||||
|
|
||||||
public static InsulinOrefFreePeakPlugin getPlugin() {
|
public static InsulinOrefFreePeakPlugin getPlugin() {
|
||||||
|
@ -21,24 +18,20 @@ public class InsulinOrefFreePeakPlugin extends InsulinOrefBasePlugin {
|
||||||
return plugin;
|
return plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final int DEFAULT_PEAK = 75;
|
private static final int DEFAULT_PEAK = 75;
|
||||||
|
|
||||||
|
private InsulinOrefFreePeakPlugin() {
|
||||||
|
super();
|
||||||
|
pluginDescription
|
||||||
|
.pluginName(R.string.free_peak_oref)
|
||||||
|
.preferencesId(R.xml.pref_insulinoreffreepeak);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getId() {
|
public int getId() {
|
||||||
return OREF_FREE_PEAK;
|
return OREF_FREE_PEAK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return MainApp.sResources.getString(R.string.free_peak_oref);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getFragmentClass() {
|
|
||||||
return InsulinFragment.class.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getFriendlyName() {
|
public String getFriendlyName() {
|
||||||
return MainApp.sResources.getString(R.string.free_peak_oref);
|
return MainApp.sResources.getString(R.string.free_peak_oref);
|
||||||
}
|
}
|
||||||
|
@ -48,31 +41,6 @@ public class InsulinOrefFreePeakPlugin extends InsulinOrefBasePlugin {
|
||||||
return MainApp.sResources.getString(R.string.insulin_peak_time) + ": " + getPeak();
|
return MainApp.sResources.getString(R.string.insulin_peak_time) + ": " + getPeak();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled(int type) {
|
|
||||||
return type == INSULIN && fragmentEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isVisibleInTabs(int type) {
|
|
||||||
return type == INSULIN && fragmentVisible;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setFragmentEnabled(int type, boolean fragmentEnabled) {
|
|
||||||
if (type == INSULIN) this.fragmentEnabled = fragmentEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setFragmentVisible(int type, boolean fragmentVisible) {
|
|
||||||
if (type == INSULIN) this.fragmentVisible = fragmentVisible;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getPreferencesId() {
|
|
||||||
return R.xml.pref_insulinoreffreepeak;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
int getPeak() {
|
int getPeak() {
|
||||||
return SP.getInt(R.string.key_insulin_oref_peak, DEFAULT_PEAK);
|
return SP.getInt(R.string.key_insulin_oref_peak, DEFAULT_PEAK);
|
||||||
|
|
|
@ -9,9 +9,6 @@ import info.nightscout.androidaps.R;
|
||||||
|
|
||||||
public class InsulinOrefRapidActingPlugin extends InsulinOrefBasePlugin {
|
public class InsulinOrefRapidActingPlugin extends InsulinOrefBasePlugin {
|
||||||
|
|
||||||
private boolean fragmentEnabled = false;
|
|
||||||
private boolean fragmentVisible = false;
|
|
||||||
|
|
||||||
private static InsulinOrefRapidActingPlugin plugin = null;
|
private static InsulinOrefRapidActingPlugin plugin = null;
|
||||||
|
|
||||||
public static InsulinOrefRapidActingPlugin getPlugin() {
|
public static InsulinOrefRapidActingPlugin getPlugin() {
|
||||||
|
@ -20,23 +17,19 @@ public class InsulinOrefRapidActingPlugin extends InsulinOrefBasePlugin {
|
||||||
return plugin;
|
return plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final int PEAK = 75;
|
private static final int PEAK = 75;
|
||||||
|
|
||||||
|
private InsulinOrefRapidActingPlugin() {
|
||||||
|
super();
|
||||||
|
pluginDescription
|
||||||
|
.pluginName(R.string.rapid_acting_oref);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getId() {
|
public int getId() {
|
||||||
return OREF_RAPID_ACTING;
|
return OREF_RAPID_ACTING;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return MainApp.sResources.getString(R.string.rapid_acting_oref);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getFragmentClass() {
|
|
||||||
return InsulinFragment.class.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getFriendlyName() {
|
public String getFriendlyName() {
|
||||||
return MainApp.sResources.getString(R.string.rapid_acting_oref);
|
return MainApp.sResources.getString(R.string.rapid_acting_oref);
|
||||||
|
@ -47,31 +40,6 @@ public class InsulinOrefRapidActingPlugin extends InsulinOrefBasePlugin {
|
||||||
return MainApp.sResources.getString(R.string.fastactinginsulincomment);
|
return MainApp.sResources.getString(R.string.fastactinginsulincomment);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled(int type) {
|
|
||||||
return type == INSULIN && fragmentEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isVisibleInTabs(int type) {
|
|
||||||
return type == INSULIN && fragmentVisible;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setFragmentEnabled(int type, boolean fragmentEnabled) {
|
|
||||||
if (type == INSULIN) this.fragmentEnabled = fragmentEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setFragmentVisible(int type, boolean fragmentVisible) {
|
|
||||||
if (type == INSULIN) this.fragmentVisible = fragmentVisible;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getPreferencesId() {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
int getPeak() {
|
int getPeak() {
|
||||||
return PEAK;
|
return PEAK;
|
||||||
|
|
|
@ -9,9 +9,6 @@ import info.nightscout.androidaps.R;
|
||||||
|
|
||||||
public class InsulinOrefUltraRapidActingPlugin extends InsulinOrefBasePlugin {
|
public class InsulinOrefUltraRapidActingPlugin extends InsulinOrefBasePlugin {
|
||||||
|
|
||||||
private boolean fragmentEnabled = false;
|
|
||||||
private boolean fragmentVisible = false;
|
|
||||||
|
|
||||||
private static InsulinOrefUltraRapidActingPlugin plugin = null;
|
private static InsulinOrefUltraRapidActingPlugin plugin = null;
|
||||||
|
|
||||||
public static InsulinOrefUltraRapidActingPlugin getPlugin() {
|
public static InsulinOrefUltraRapidActingPlugin getPlugin() {
|
||||||
|
@ -20,7 +17,13 @@ public class InsulinOrefUltraRapidActingPlugin extends InsulinOrefBasePlugin {
|
||||||
return plugin;
|
return plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final int PEAK = 55;
|
private static final int PEAK = 55;
|
||||||
|
|
||||||
|
private InsulinOrefUltraRapidActingPlugin() {
|
||||||
|
super();
|
||||||
|
pluginDescription
|
||||||
|
.pluginName(R.string.ultrarapid_oref);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getId() {
|
public int getId() {
|
||||||
|
@ -32,11 +35,6 @@ public class InsulinOrefUltraRapidActingPlugin extends InsulinOrefBasePlugin {
|
||||||
return MainApp.sResources.getString(R.string.ultrarapid_oref);
|
return MainApp.sResources.getString(R.string.ultrarapid_oref);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getFragmentClass() {
|
|
||||||
return InsulinFragment.class.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getFriendlyName() {
|
public String getFriendlyName() {
|
||||||
return MainApp.sResources.getString(R.string.ultrarapid_oref);
|
return MainApp.sResources.getString(R.string.ultrarapid_oref);
|
||||||
|
@ -47,31 +45,6 @@ public class InsulinOrefUltraRapidActingPlugin extends InsulinOrefBasePlugin {
|
||||||
return MainApp.sResources.getString(R.string.ultrafastactinginsulincomment);
|
return MainApp.sResources.getString(R.string.ultrafastactinginsulincomment);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled(int type) {
|
|
||||||
return type == INSULIN && fragmentEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isVisibleInTabs(int type) {
|
|
||||||
return type == INSULIN && fragmentVisible;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setFragmentEnabled(int type, boolean fragmentEnabled) {
|
|
||||||
if (type == INSULIN) this.fragmentEnabled = fragmentEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setFragmentVisible(int type, boolean fragmentVisible) {
|
|
||||||
if (type == INSULIN) this.fragmentVisible = fragmentVisible;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getPreferencesId() {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
int getPeak() {
|
int getPeak() {
|
||||||
return PEAK;
|
return PEAK;
|
||||||
|
|
|
@ -12,6 +12,7 @@ import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
import info.nightscout.androidaps.db.Treatment;
|
import info.nightscout.androidaps.db.Treatment;
|
||||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||||
|
import info.nightscout.androidaps.interfaces.PluginType;
|
||||||
import info.nightscout.androidaps.plugins.SensitivityAAPS.SensitivityAAPSPlugin;
|
import info.nightscout.androidaps.plugins.SensitivityAAPS.SensitivityAAPSPlugin;
|
||||||
import info.nightscout.androidaps.plugins.SensitivityWeightedAverage.SensitivityWeightedAveragePlugin;
|
import info.nightscout.androidaps.plugins.SensitivityWeightedAverage.SensitivityWeightedAveragePlugin;
|
||||||
import info.nightscout.utils.SP;
|
import info.nightscout.utils.SP;
|
||||||
|
@ -33,7 +34,7 @@ public class AutosensData {
|
||||||
time = t.date;
|
time = t.date;
|
||||||
carbs = t.carbs;
|
carbs = t.carbs;
|
||||||
remaining = t.carbs;
|
remaining = t.carbs;
|
||||||
if (SensitivityAAPSPlugin.getPlugin().isEnabled(PluginBase.SENSITIVITY) || SensitivityWeightedAveragePlugin.getPlugin().isEnabled(PluginBase.SENSITIVITY)) {
|
if (SensitivityAAPSPlugin.getPlugin().isEnabled(PluginType.SENSITIVITY) || SensitivityWeightedAveragePlugin.getPlugin().isEnabled(PluginType.SENSITIVITY)) {
|
||||||
double maxAbsorptionHours = SP.getDouble(R.string.key_absorption_maxtime, 4d);
|
double maxAbsorptionHours = SP.getDouble(R.string.key_absorption_maxtime, 4d);
|
||||||
Profile profile = MainApp.getConfigBuilder().getProfile(t.date);
|
Profile profile = MainApp.getConfigBuilder().getProfile(t.date);
|
||||||
double sens = Profile.toMgdl(profile.getIsf(t.date), profile.getUnits());
|
double sens = Profile.toMgdl(profile.getIsf(t.date), profile.getUnits());
|
||||||
|
@ -64,7 +65,8 @@ public class AutosensData {
|
||||||
public double slopeFromMaxDeviation = 0;
|
public double slopeFromMaxDeviation = 0;
|
||||||
public double slopeFromMinDeviation = 999;
|
public double slopeFromMinDeviation = 999;
|
||||||
|
|
||||||
public String log(long time) {
|
@Override
|
||||||
|
public String toString() {
|
||||||
return "AutosensData: " + new Date(time).toLocaleString() + " " + pastSensitivity + " Delta=" + delta + " avgDelta=" + avgDelta + " Bgi=" + bgi + " Deviation=" + deviation + " avgDeviation=" + avgDeviation + " Absorbed=" + absorbed + " CarbsFromBolus=" + carbsFromBolus + " COB=" + cob + " autosensRatio=" + autosensRatio + " slopeFromMaxDeviation=" + slopeFromMaxDeviation + " slopeFromMinDeviation =" + slopeFromMinDeviation ;
|
return "AutosensData: " + new Date(time).toLocaleString() + " " + pastSensitivity + " Delta=" + delta + " avgDelta=" + avgDelta + " Bgi=" + bgi + " Deviation=" + deviation + " avgDeviation=" + avgDeviation + " Absorbed=" + absorbed + " CarbsFromBolus=" + carbsFromBolus + " COB=" + cob + " autosensRatio=" + autosensRatio + " slopeFromMaxDeviation=" + slopeFromMaxDeviation + " slopeFromMinDeviation =" + slopeFromMinDeviation ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,17 +29,28 @@ import info.nightscout.androidaps.events.EventNewBG;
|
||||||
import info.nightscout.androidaps.events.EventNewBasalProfile;
|
import info.nightscout.androidaps.events.EventNewBasalProfile;
|
||||||
import info.nightscout.androidaps.events.EventPreferenceChange;
|
import info.nightscout.androidaps.events.EventPreferenceChange;
|
||||||
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.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||||
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventNewHistoryData;
|
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventNewHistoryData;
|
||||||
import info.nightscout.androidaps.plugins.OpenAPSSMB.OpenAPSSMBPlugin;
|
import info.nightscout.androidaps.plugins.OpenAPSSMB.OpenAPSSMBPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.utils.DateUtil;
|
import info.nightscout.utils.DateUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by mike on 24.04.2017.
|
* Created by mike on 24.04.2017.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class IobCobCalculatorPlugin implements PluginBase {
|
public class IobCobCalculatorPlugin extends PluginBase {
|
||||||
private static Logger log = LoggerFactory.getLogger(IobCobCalculatorPlugin.class);
|
private Logger log = LoggerFactory.getLogger(IobCobCalculatorPlugin.class);
|
||||||
|
|
||||||
|
private static IobCobCalculatorPlugin plugin = null;
|
||||||
|
|
||||||
|
public static IobCobCalculatorPlugin getPlugin() {
|
||||||
|
if (plugin == null)
|
||||||
|
plugin = new IobCobCalculatorPlugin();
|
||||||
|
return plugin;
|
||||||
|
}
|
||||||
|
|
||||||
private LongSparseArray<IobTotal> iobTable = new LongSparseArray<>(); // oldest at index 0
|
private LongSparseArray<IobTotal> iobTable = new LongSparseArray<>(); // oldest at index 0
|
||||||
private LongSparseArray<AutosensData> autosensDataTable = new LongSparseArray<>(); // oldest at index 0
|
private LongSparseArray<AutosensData> autosensDataTable = new LongSparseArray<>(); // oldest at index 0
|
||||||
|
@ -55,12 +66,26 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
||||||
boolean stopCalculationTrigger = false;
|
boolean stopCalculationTrigger = false;
|
||||||
private IobCobThread thread = null;
|
private IobCobThread thread = null;
|
||||||
|
|
||||||
private static IobCobCalculatorPlugin plugin = null;
|
public IobCobCalculatorPlugin() {
|
||||||
|
super(new PluginDescription()
|
||||||
|
.mainType(PluginType.GENERAL)
|
||||||
|
.pluginName(R.string.iobcobcalculator)
|
||||||
|
.showInList(false)
|
||||||
|
.neverVisible(true)
|
||||||
|
.alwaysEnabled(true)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public static IobCobCalculatorPlugin getPlugin() {
|
@Override
|
||||||
if (plugin == null)
|
protected void onStart() {
|
||||||
plugin = new IobCobCalculatorPlugin();
|
MainApp.bus().register(this);
|
||||||
return plugin;
|
super.onStart();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStop() {
|
||||||
|
super.onStop();
|
||||||
|
MainApp.bus().unregister(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LongSparseArray<AutosensData> getAutosensDataTable() {
|
public LongSparseArray<AutosensData> getAutosensDataTable() {
|
||||||
|
@ -71,70 +96,6 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
||||||
return bucketed_data;
|
return bucketed_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getType() {
|
|
||||||
return GENERAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getFragmentClass() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "IOB COB Calculator";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getNameShort() {
|
|
||||||
return "IOC";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled(int type) {
|
|
||||||
return type == GENERAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isVisibleInTabs(int type) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canBeHidden(int type) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasFragment() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean showInList(int type) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setFragmentEnabled(int type, boolean fragmentEnabled) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setFragmentVisible(int type, boolean fragmentVisible) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getPreferencesId() {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IobCobCalculatorPlugin() {
|
|
||||||
MainApp.bus().register(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public List<BgReading> getBucketedData(long fromTime) {
|
public List<BgReading> getBucketedData(long fromTime) {
|
||||||
//log.debug("Locking getBucketedData");
|
//log.debug("Locking getBucketedData");
|
||||||
|
@ -323,10 +284,10 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
||||||
log.debug("Bucketed data created. Size: " + bucketed_data.size());
|
log.debug("Bucketed data created. Size: " + bucketed_data.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long oldestDataAvailable() {
|
public long oldestDataAvailable() {
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
|
|
||||||
long oldestDataAvailable = MainApp.getConfigBuilder().oldestDataAvailable();
|
long oldestDataAvailable = TreatmentsPlugin.getPlugin().oldestDataAvailable();
|
||||||
long getBGDataFrom = Math.max(oldestDataAvailable, (long) (now - 60 * 60 * 1000L * (24 + MainApp.getConfigBuilder().getProfile().getDia())));
|
long getBGDataFrom = Math.max(oldestDataAvailable, (long) (now - 60 * 60 * 1000L * (24 + MainApp.getConfigBuilder().getProfile().getDia())));
|
||||||
log.debug("Limiting data to oldest available temps: " + new Date(oldestDataAvailable).toString());
|
log.debug("Limiting data to oldest available temps: " + new Date(oldestDataAvailable).toString());
|
||||||
return getBGDataFrom;
|
return getBGDataFrom;
|
||||||
|
@ -347,16 +308,15 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
||||||
} else {
|
} else {
|
||||||
//log.debug(">>> calculateFromTreatmentsAndTemps Cache miss " + new Date(time).toLocaleString());
|
//log.debug(">>> calculateFromTreatmentsAndTemps Cache miss " + new Date(time).toLocaleString());
|
||||||
}
|
}
|
||||||
IobTotal bolusIob = MainApp.getConfigBuilder().getCalculationToTimeTreatments(time).round();
|
IobTotal bolusIob = TreatmentsPlugin.getPlugin().getCalculationToTimeTreatments(time).round();
|
||||||
IobTotal basalIob = MainApp.getConfigBuilder().getCalculationToTimeTempBasals(time).round();
|
IobTotal basalIob = TreatmentsPlugin.getPlugin().getCalculationToTimeTempBasals(time).round();
|
||||||
if (OpenAPSSMBPlugin.getPlugin().isEnabled(PluginBase.APS)) {
|
if (OpenAPSSMBPlugin.getPlugin().isEnabled(PluginType.APS)) {
|
||||||
// Add expected zere temp basal for next 240 mins
|
// Add expected zere temp basal for next 240 mins
|
||||||
IobTotal basalIobWithZeroTemp = basalIob.clone();
|
IobTotal basalIobWithZeroTemp = basalIob.copy();
|
||||||
TemporaryBasal t = new TemporaryBasal();
|
TemporaryBasal t = new TemporaryBasal()
|
||||||
t.date = now + 60 * 1000L;
|
.date(now + 60 * 1000L)
|
||||||
t.durationInMinutes = 240;
|
.duration(240)
|
||||||
t.isAbsolute = true;
|
.absolute(0);
|
||||||
t.absoluteRate = 0;
|
|
||||||
if (t.date < time) {
|
if (t.date < time) {
|
||||||
IobTotal calc = t.iobCalc(time);
|
IobTotal calc = t.iobCalc(time);
|
||||||
basalIobWithZeroTemp.plus(calc);
|
basalIobWithZeroTemp.plus(calc);
|
||||||
|
@ -389,11 +349,12 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
||||||
BasalData retval = basalDataTable.get(time);
|
BasalData retval = basalDataTable.get(time);
|
||||||
if (retval == null) {
|
if (retval == null) {
|
||||||
retval = new BasalData();
|
retval = new BasalData();
|
||||||
TemporaryBasal tb = MainApp.getConfigBuilder().getTempBasalFromHistory(time);
|
Profile profile = MainApp.getConfigBuilder().getProfile(time);
|
||||||
retval.basal = MainApp.getConfigBuilder().getProfile(time).getBasal(time);
|
TemporaryBasal tb = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(time);
|
||||||
|
retval.basal = profile.getBasal(time);
|
||||||
if (tb != null) {
|
if (tb != null) {
|
||||||
retval.isTempBasalRunning = true;
|
retval.isTempBasalRunning = true;
|
||||||
retval.tempBasalAbsolute = tb.tempBasalConvertedToAbsolute(time);
|
retval.tempBasalAbsolute = tb.tempBasalConvertedToAbsolute(time, profile);
|
||||||
} else {
|
} else {
|
||||||
retval.isTempBasalRunning = false;
|
retval.isTempBasalRunning = false;
|
||||||
retval.tempBasalAbsolute = retval.basal;
|
retval.tempBasalAbsolute = retval.basal;
|
||||||
|
@ -447,7 +408,7 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
||||||
log.debug("AUTOSENSDATA null: autosensDataTable empty (" + reason + ")");
|
log.debug("AUTOSENSDATA null: autosensDataTable empty (" + reason + ")");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
AutosensData data = null;
|
AutosensData data;
|
||||||
try {
|
try {
|
||||||
data = autosensDataTable.valueAt(autosensDataTable.size() - 1);
|
data = autosensDataTable.valueAt(autosensDataTable.size() - 1);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -461,8 +422,6 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
||||||
log.debug("AUTOSENSDATA null: data is old (" + reason + ") size()=" + autosensDataTable.size() + " lastdata=" + DateUtil.dateAndTimeString(data.time));
|
log.debug("AUTOSENSDATA null: data is old (" + reason + ") size()=" + autosensDataTable.size() + " lastdata=" + DateUtil.dateAndTimeString(data.time));
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
if (data == null)
|
|
||||||
log.debug("AUTOSENSDATA null: data == null (" + " " + reason + ") size()=" + autosensDataTable.size() + " lastdata=" + DateUtil.dateAndTimeString(data.time));
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,8 @@ import android.content.Context;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.support.v4.util.LongSparseArray;
|
import android.support.v4.util.LongSparseArray;
|
||||||
|
|
||||||
|
import com.crashlytics.android.answers.CustomEvent;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -11,6 +13,7 @@ import java.util.ArrayList;
|
||||||
import java.util.Date;
|
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.Constants;
|
import info.nightscout.androidaps.Constants;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
|
@ -20,15 +23,16 @@ import info.nightscout.androidaps.db.BgReading;
|
||||||
import info.nightscout.androidaps.db.Treatment;
|
import info.nightscout.androidaps.db.Treatment;
|
||||||
import info.nightscout.androidaps.events.Event;
|
import info.nightscout.androidaps.events.Event;
|
||||||
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished;
|
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished;
|
||||||
import info.nightscout.androidaps.queue.QueueThread;
|
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.utils.DateUtil;
|
import info.nightscout.utils.DateUtil;
|
||||||
|
import info.nightscout.utils.FabricPrivacy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by mike on 23.01.2018.
|
* Created by mike on 23.01.2018.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class IobCobThread extends Thread {
|
public class IobCobThread extends Thread {
|
||||||
private static Logger log = LoggerFactory.getLogger(QueueThread.class);
|
private static Logger log = LoggerFactory.getLogger(IobCobThread.class);
|
||||||
private final Event cause;
|
private final Event cause;
|
||||||
|
|
||||||
private IobCobCalculatorPlugin iobCobCalculatorPlugin;
|
private IobCobCalculatorPlugin iobCobCalculatorPlugin;
|
||||||
|
@ -59,7 +63,7 @@ public class IobCobThread extends Thread {
|
||||||
log.debug("Aborting calculation thread (ConfigBuilder not ready): " + from);
|
log.debug("Aborting calculation thread (ConfigBuilder not ready): " + from);
|
||||||
return; // app still initializing
|
return; // app still initializing
|
||||||
}
|
}
|
||||||
if (MainApp.getConfigBuilder().getProfile() == null) {
|
if (!MainApp.getConfigBuilder().isProfileValid("IobCobThread")) {
|
||||||
log.debug("Aborting calculation thread (No profile): " + from);
|
log.debug("Aborting calculation thread (No profile): " + from);
|
||||||
return; // app still initializing
|
return; // app still initializing
|
||||||
}
|
}
|
||||||
|
@ -110,11 +114,6 @@ public class IobCobThread extends Thread {
|
||||||
return; // profile not set yet
|
return; // profile not set yet
|
||||||
}
|
}
|
||||||
|
|
||||||
if (profile.getIsf(bgTime) == null) {
|
|
||||||
log.debug("Aborting calculation thread (no ISF): " + from);
|
|
||||||
return; // profile not set yet
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Config.logAutosensData)
|
if (Config.logAutosensData)
|
||||||
log.debug("Processing calculation thread: " + from + " (" + i + "/" + bucketed_data.size() + ")");
|
log.debug("Processing calculation thread: " + from + " (" + i + "/" + bucketed_data.size() + ")");
|
||||||
|
|
||||||
|
@ -145,9 +144,8 @@ public class IobCobThread extends Thread {
|
||||||
double deviation = delta - bgi;
|
double deviation = delta - bgi;
|
||||||
double avgDeviation = Math.round((avgDelta - bgi) * 1000) / 1000;
|
double avgDeviation = Math.round((avgDelta - bgi) * 1000) / 1000;
|
||||||
|
|
||||||
double currentDeviation;
|
double slopeFromMaxDeviation = 0;
|
||||||
double slopeFromMaxDeviation = 0;
|
double slopeFromMinDeviation = 999;
|
||||||
double slopeFromMinDeviation = 999;
|
|
||||||
double maxDeviation = 0;
|
double maxDeviation = 0;
|
||||||
double minDeviation = 999;
|
double minDeviation = 999;
|
||||||
|
|
||||||
|
@ -156,28 +154,40 @@ public class IobCobThread extends Thread {
|
||||||
long hourago = bgTime + 10 * 1000 - 60 * 60 * 1000L;
|
long hourago = bgTime + 10 * 1000 - 60 * 60 * 1000L;
|
||||||
AutosensData hourAgoData = iobCobCalculatorPlugin.getAutosensData(hourago);
|
AutosensData hourAgoData = iobCobCalculatorPlugin.getAutosensData(hourago);
|
||||||
if (hourAgoData != null) {
|
if (hourAgoData != null) {
|
||||||
currentDeviation = hourAgoData.avgDeviation;
|
|
||||||
int initialIndex = autosensDataTable.indexOfKey(hourAgoData.time);
|
int initialIndex = autosensDataTable.indexOfKey(hourAgoData.time);
|
||||||
|
log.debug(">>>>> bucketed_data.size()=" + bucketed_data.size() + " i=" + i + "hourAgoData=" + hourAgoData.toString());
|
||||||
|
int past = 1;
|
||||||
|
try {
|
||||||
|
for (; past < 12; past++) {
|
||||||
|
AutosensData ad = autosensDataTable.valueAt(initialIndex + past);
|
||||||
|
double deviationSlope = (ad.avgDeviation - avgDeviation) / (ad.time - bgTime) * 1000 * 60 * 5;
|
||||||
|
if (ad.avgDeviation > maxDeviation) {
|
||||||
|
slopeFromMaxDeviation = Math.min(0, deviationSlope);
|
||||||
|
maxDeviation = ad.avgDeviation;
|
||||||
|
}
|
||||||
|
if (ad.avgDeviation < minDeviation) {
|
||||||
|
slopeFromMinDeviation = Math.max(0, deviationSlope);
|
||||||
|
minDeviation = ad.avgDeviation;
|
||||||
|
}
|
||||||
|
|
||||||
for (int past = 1; past < 12; past++) {
|
//if (Config.logAutosensData)
|
||||||
AutosensData ad = autosensDataTable.valueAt(initialIndex + past);
|
// log.debug("Deviations: " + new Date(bgTime) + new Date(ad.time) + " avgDeviation=" + avgDeviation + " deviationSlope=" + deviationSlope + " slopeFromMaxDeviation=" + slopeFromMaxDeviation + " slopeFromMinDeviation=" + slopeFromMinDeviation);
|
||||||
double deviationSlope = (ad.avgDeviation - currentDeviation) / (ad.time - bgTime) * 1000 * 60 * 5;
|
|
||||||
if (ad.avgDeviation > maxDeviation) {
|
|
||||||
slopeFromMaxDeviation = Math.min(0, deviationSlope);
|
|
||||||
maxDeviation = ad.avgDeviation;
|
|
||||||
}
|
}
|
||||||
if (avgDeviation < minDeviation) {
|
} catch (Exception e) {
|
||||||
slopeFromMinDeviation = Math.max(0, deviationSlope);
|
log.error("Unhandled exception", e);
|
||||||
minDeviation = avgDeviation;
|
FabricPrivacy.logException(e);
|
||||||
}
|
FabricPrivacy.getInstance().logCustom(new CustomEvent("CatchedError")
|
||||||
|
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
|
||||||
//if (Config.logAutosensData)
|
.putCustomAttribute("version", BuildConfig.VERSION)
|
||||||
// log.debug("Deviations: " + new Date(bgTime) + new Date(ad.time) + " avgDeviation=" + avgDeviation + " deviationSlope=" + deviationSlope + " slopeFromMaxDeviation=" + slopeFromMaxDeviation + " slopeFromMinDeviation=" + slopeFromMinDeviation);
|
.putCustomAttribute("autosensDataTable", iobCobCalculatorPlugin.getAutosensDataTable().toString())
|
||||||
|
.putCustomAttribute("for_data", ">>>>> bucketed_data.size()=" + bucketed_data.size() + " i=" + i + "hourAgoData=" + hourAgoData.toString())
|
||||||
|
.putCustomAttribute("past", past)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Treatment> recentTreatments = MainApp.getConfigBuilder().getTreatments5MinBackFromHistory(bgTime);
|
List<Treatment> recentTreatments = TreatmentsPlugin.getPlugin().getTreatments5MinBackFromHistory(bgTime);
|
||||||
for (int ir = 0; ir < recentTreatments.size(); ir++) {
|
for (int ir = 0; ir < recentTreatments.size(); ir++) {
|
||||||
autosensData.carbsFromBolus += recentTreatments.get(ir).carbs;
|
autosensData.carbsFromBolus += recentTreatments.get(ir).carbs;
|
||||||
autosensData.activeCarbsList.add(new AutosensData.CarbsInPast(recentTreatments.get(ir)));
|
autosensData.activeCarbsList.add(new AutosensData.CarbsInPast(recentTreatments.get(ir)));
|
||||||
|
@ -235,7 +245,7 @@ public class IobCobThread extends Thread {
|
||||||
log.debug("Running detectSensitivity from: " + DateUtil.dateAndTimeString(oldestTimeWithData) + " to: " + DateUtil.dateAndTimeString(bgTime));
|
log.debug("Running detectSensitivity from: " + DateUtil.dateAndTimeString(oldestTimeWithData) + " to: " + DateUtil.dateAndTimeString(bgTime));
|
||||||
autosensData.autosensRatio = iobCobCalculatorPlugin.detectSensitivity(oldestTimeWithData, bgTime).ratio;
|
autosensData.autosensRatio = iobCobCalculatorPlugin.detectSensitivity(oldestTimeWithData, bgTime).ratio;
|
||||||
if (Config.logAutosensData)
|
if (Config.logAutosensData)
|
||||||
log.debug(autosensData.log(bgTime));
|
log.debug(autosensData.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MainApp.bus().post(new EventAutosensCalculationFinished(cause));
|
MainApp.bus().post(new EventAutosensCalculationFinished(cause));
|
||||||
|
|
|
@ -17,6 +17,7 @@ import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.data.IobTotal;
|
import info.nightscout.androidaps.data.IobTotal;
|
||||||
import info.nightscout.androidaps.db.BgReading;
|
import info.nightscout.androidaps.db.BgReading;
|
||||||
|
import info.nightscout.androidaps.interfaces.Constraint;
|
||||||
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.utils.DecimalFormatter;
|
import info.nightscout.utils.DecimalFormatter;
|
||||||
|
@ -31,7 +32,7 @@ public class APSResult {
|
||||||
public String reason;
|
public String reason;
|
||||||
public double rate;
|
public double rate;
|
||||||
public int duration;
|
public int duration;
|
||||||
public boolean tempBasalReqested = false;
|
public boolean tempBasalRequested = false;
|
||||||
public boolean bolusRequested = false;
|
public boolean bolusRequested = false;
|
||||||
public IobTotal iob;
|
public IobTotal iob;
|
||||||
public JSONObject json = new JSONObject();
|
public JSONObject json = new JSONObject();
|
||||||
|
@ -39,6 +40,11 @@ public class APSResult {
|
||||||
public double smb = 0d; // super micro bolus in units
|
public double smb = 0d; // super micro bolus in units
|
||||||
public long deliverAt = 0;
|
public long deliverAt = 0;
|
||||||
|
|
||||||
|
public Constraint<Double> inputConstraints;
|
||||||
|
|
||||||
|
public Constraint<Double> rateConstraint;
|
||||||
|
public Constraint<Double> smbConstraint;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
|
final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
|
||||||
|
@ -56,7 +62,7 @@ public class APSResult {
|
||||||
|
|
||||||
// smb
|
// smb
|
||||||
if (smb != 0)
|
if (smb != 0)
|
||||||
ret += ("SMB: " + DecimalFormatter.to2Decimal(smb) + " U\n");
|
ret += ("SMB: " + DecimalFormatter.toPumpSupportedBolus(smb) + " U\n");
|
||||||
|
|
||||||
// reason
|
// reason
|
||||||
ret += MainApp.sResources.getString(R.string.reason) + ": " + reason;
|
ret += MainApp.sResources.getString(R.string.reason) + ": " + reason;
|
||||||
|
@ -76,12 +82,12 @@ public class APSResult {
|
||||||
ret = MainApp.sResources.getString(R.string.let_temp_basal_run) + "<br>";
|
ret = MainApp.sResources.getString(R.string.let_temp_basal_run) + "<br>";
|
||||||
else
|
else
|
||||||
ret = "<b>" + MainApp.sResources.getString(R.string.rate) + "</b>: " + DecimalFormatter.to2Decimal(rate) + " U/h " +
|
ret = "<b>" + MainApp.sResources.getString(R.string.rate) + "</b>: " + DecimalFormatter.to2Decimal(rate) + " U/h " +
|
||||||
"(" + DecimalFormatter.to2Decimal(rate / pump.getBaseBasalRate() * 100) + "%) <br>" +
|
"(" + DecimalFormatter.to2Decimal(rate / pump.getBaseBasalRate() * 100) + "%) <br>" +
|
||||||
"<b>" + MainApp.sResources.getString(R.string.duration) + "</b>: " + DecimalFormatter.to2Decimal(duration) + " min<br>";
|
"<b>" + MainApp.sResources.getString(R.string.duration) + "</b>: " + DecimalFormatter.to2Decimal(duration) + " min<br>";
|
||||||
|
|
||||||
// smb
|
// smb
|
||||||
if (smb != 0)
|
if (smb != 0)
|
||||||
ret += ("<b>" + "SMB" + "</b>: " + DecimalFormatter.to2Decimal(smb) + " U<br>");
|
ret += ("<b>" + "SMB" + "</b>: " + DecimalFormatter.toPumpSupportedBolus(smb) + " U<br>");
|
||||||
|
|
||||||
// reason
|
// reason
|
||||||
ret += "<b>" + MainApp.sResources.getString(R.string.reason) + "</b>: " + reason.replace("<", "<").replace(">", ">");
|
ret += "<b>" + MainApp.sResources.getString(R.string.reason) + "</b>: " + reason.replace("<", "<").replace(">", ">");
|
||||||
|
@ -98,9 +104,15 @@ public class APSResult {
|
||||||
newResult.reason = reason;
|
newResult.reason = reason;
|
||||||
newResult.rate = rate;
|
newResult.rate = rate;
|
||||||
newResult.duration = duration;
|
newResult.duration = duration;
|
||||||
newResult.tempBasalReqested = tempBasalReqested;
|
newResult.tempBasalRequested = tempBasalRequested;
|
||||||
newResult.bolusRequested = bolusRequested;
|
newResult.bolusRequested = bolusRequested;
|
||||||
newResult.iob = iob;
|
newResult.iob = iob;
|
||||||
|
newResult.json = json;
|
||||||
|
newResult.hasPredictions = hasPredictions;
|
||||||
|
newResult.smb = smb;
|
||||||
|
newResult.deliverAt = deliverAt;
|
||||||
|
newResult.rateConstraint = rateConstraint;
|
||||||
|
newResult.smbConstraint = smbConstraint;
|
||||||
return newResult;
|
return newResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,6 +228,6 @@ public class APSResult {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isChangeRequested() {
|
public boolean isChangeRequested() {
|
||||||
return tempBasalReqested || bolusRequested;
|
return tempBasalRequested || bolusRequested;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package info.nightscout.androidaps.plugins.Loop;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
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,23 +16,38 @@ import com.squareup.otto.Subscribe;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import butterknife.BindView;
|
||||||
|
import butterknife.ButterKnife;
|
||||||
|
import butterknife.OnClick;
|
||||||
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.Common.SubscriberFragment;
|
import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
|
||||||
import info.nightscout.androidaps.plugins.Loop.events.EventLoopSetLastRunGui;
|
import info.nightscout.androidaps.plugins.Loop.events.EventLoopSetLastRunGui;
|
||||||
import info.nightscout.androidaps.plugins.Loop.events.EventLoopUpdateGui;
|
import info.nightscout.androidaps.plugins.Loop.events.EventLoopUpdateGui;
|
||||||
import info.nightscout.utils.FabricPrivacy;
|
import info.nightscout.utils.FabricPrivacy;
|
||||||
|
|
||||||
public class LoopFragment extends SubscriberFragment implements View.OnClickListener {
|
public class LoopFragment extends SubscriberFragment {
|
||||||
private static Logger log = LoggerFactory.getLogger(LoopFragment.class);
|
private static Logger log = LoggerFactory.getLogger(LoopFragment.class);
|
||||||
|
|
||||||
|
@BindView(R.id.loop_run)
|
||||||
Button runNowButton;
|
Button runNowButton;
|
||||||
|
@BindView(R.id.loop_lastrun)
|
||||||
TextView lastRunView;
|
TextView lastRunView;
|
||||||
|
@BindView(R.id.loop_lastenact)
|
||||||
TextView lastEnactView;
|
TextView lastEnactView;
|
||||||
|
@BindView(R.id.loop_source)
|
||||||
TextView sourceView;
|
TextView sourceView;
|
||||||
|
@BindView(R.id.loop_request)
|
||||||
TextView requestView;
|
TextView requestView;
|
||||||
|
@BindView(R.id.loop_constraintsprocessed)
|
||||||
TextView constraintsProcessedView;
|
TextView constraintsProcessedView;
|
||||||
TextView setByPumpView;
|
@BindView(R.id.loop_constraints)
|
||||||
|
TextView constraintsView;
|
||||||
|
@BindView(R.id.loop_tbrsetbypump)
|
||||||
|
TextView tbrSetByPumpView;
|
||||||
|
@BindView(R.id.loop_smbsetbypump)
|
||||||
|
TextView smbSetByPumpView;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -39,41 +55,19 @@ public class LoopFragment extends SubscriberFragment implements View.OnClickList
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
try {
|
try {
|
||||||
View view = inflater.inflate(R.layout.loop_fragment, container, false);
|
View view = inflater.inflate(R.layout.loop_fragment, container, false);
|
||||||
|
unbinder = ButterKnife.bind(this, view);
|
||||||
lastRunView = (TextView) view.findViewById(R.id.loop_lastrun);
|
|
||||||
lastEnactView = (TextView) view.findViewById(R.id.loop_lastenact);
|
|
||||||
sourceView = (TextView) view.findViewById(R.id.loop_source);
|
|
||||||
requestView = (TextView) view.findViewById(R.id.loop_request);
|
|
||||||
constraintsProcessedView = (TextView) view.findViewById(R.id.loop_constraintsprocessed);
|
|
||||||
setByPumpView = (TextView) view.findViewById(R.id.loop_setbypump);
|
|
||||||
runNowButton = (Button) view.findViewById(R.id.loop_run);
|
|
||||||
runNowButton.setOnClickListener(this);
|
|
||||||
|
|
||||||
updateGUI();
|
|
||||||
return view;
|
return view;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
FabricPrivacy.logException(e);
|
FabricPrivacy.logException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@OnClick(R.id.loop_run)
|
||||||
public void onClick(View view) {
|
void onRunClick() {
|
||||||
switch (view.getId()) {
|
lastRunView.setText(MainApp.sResources.getString(R.string.executing));
|
||||||
case R.id.loop_run:
|
new Thread(() -> LoopPlugin.getPlugin().invoke("Loop button", true)).start();
|
||||||
lastRunView.setText(MainApp.sResources.getString(R.string.executing));
|
FabricPrivacy.getInstance().logCustom(new CustomEvent("Loop_Run"));
|
||||||
Thread thread = new Thread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
LoopPlugin.getPlugin().invoke("Loop button", true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
thread.start();
|
|
||||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("Loop_Run"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
|
@ -86,12 +80,7 @@ public class LoopFragment extends SubscriberFragment implements View.OnClickList
|
||||||
clearGUI();
|
clearGUI();
|
||||||
final Activity activity = getActivity();
|
final Activity activity = getActivity();
|
||||||
if (activity != null)
|
if (activity != null)
|
||||||
activity.runOnUiThread(new Runnable() {
|
activity.runOnUiThread(() -> lastRunView.setText(ev.text));
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
lastRunView.setText(ev.text);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -99,17 +88,27 @@ public class LoopFragment extends SubscriberFragment implements View.OnClickList
|
||||||
protected void updateGUI() {
|
protected void updateGUI() {
|
||||||
Activity activity = getActivity();
|
Activity activity = getActivity();
|
||||||
if (activity != null)
|
if (activity != null)
|
||||||
activity.runOnUiThread(new Runnable() {
|
activity.runOnUiThread(() -> {
|
||||||
@Override
|
LoopPlugin.LastRun lastRun = LoopPlugin.lastRun;
|
||||||
public void run() {
|
if (lastRun != null) {
|
||||||
if (LoopPlugin.lastRun != null) {
|
requestView.setText(lastRun.request != null ? lastRun.request.toSpanned() : "");
|
||||||
requestView.setText(LoopPlugin.lastRun.request != null ? LoopPlugin.lastRun.request.toSpanned() : "");
|
constraintsProcessedView.setText(lastRun.constraintsProcessed != null ? lastRun.constraintsProcessed.toSpanned() : "");
|
||||||
constraintsProcessedView.setText(LoopPlugin.lastRun.constraintsProcessed != null ? LoopPlugin.lastRun.constraintsProcessed.toSpanned() : "");
|
sourceView.setText(lastRun.source != null ? lastRun.source : "");
|
||||||
setByPumpView.setText(LoopPlugin.lastRun.setByPump != null ? LoopPlugin.lastRun.setByPump.toSpanned() : "");
|
lastRunView.setText(lastRun.lastAPSRun != null && lastRun.lastAPSRun.getTime() != 0 ? lastRun.lastAPSRun.toLocaleString() : "");
|
||||||
sourceView.setText(LoopPlugin.lastRun.source != null ? LoopPlugin.lastRun.source : "");
|
lastEnactView.setText(lastRun.lastEnact != null && lastRun.lastEnact.getTime() != 0 ? lastRun.lastEnact.toLocaleString() : "");
|
||||||
lastRunView.setText(LoopPlugin.lastRun.lastAPSRun != null && LoopPlugin.lastRun.lastAPSRun.getTime() != 0 ? LoopPlugin.lastRun.lastAPSRun.toLocaleString() : "");
|
tbrSetByPumpView.setText(lastRun.tbrSetByPump != null ? Html.fromHtml(lastRun.tbrSetByPump.toHtml()) : "");
|
||||||
lastEnactView.setText(LoopPlugin.lastRun.lastEnact != null && LoopPlugin.lastRun.lastEnact.getTime() != 0 ? LoopPlugin.lastRun.lastEnact.toLocaleString() : "");
|
smbSetByPumpView.setText(lastRun.smbSetByPump != null ? Html.fromHtml(lastRun.smbSetByPump.toHtml()) : "");
|
||||||
|
|
||||||
|
String constraints = "";
|
||||||
|
if (lastRun.constraintsProcessed != null) {
|
||||||
|
Constraint<Double> allConstraints = new Constraint<>(0d);
|
||||||
|
if (lastRun.constraintsProcessed.rateConstraint != null)
|
||||||
|
allConstraints.copyReasons(lastRun.constraintsProcessed.rateConstraint);
|
||||||
|
if (lastRun.constraintsProcessed.smbConstraint != null)
|
||||||
|
allConstraints.copyReasons(lastRun.constraintsProcessed.smbConstraint);
|
||||||
|
constraints = allConstraints.getMostLimitedReasons();
|
||||||
}
|
}
|
||||||
|
constraintsView.setText(constraints);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -117,16 +116,14 @@ public class LoopFragment extends SubscriberFragment implements View.OnClickList
|
||||||
void clearGUI() {
|
void clearGUI() {
|
||||||
Activity activity = getActivity();
|
Activity activity = getActivity();
|
||||||
if (activity != null)
|
if (activity != null)
|
||||||
activity.runOnUiThread(new Runnable() {
|
activity.runOnUiThread(() -> {
|
||||||
@Override
|
requestView.setText("");
|
||||||
public void run() {
|
constraintsProcessedView.setText("");
|
||||||
requestView.setText("");
|
sourceView.setText("");
|
||||||
constraintsProcessedView.setText("");
|
lastRunView.setText("");
|
||||||
setByPumpView.setText("");
|
lastEnactView.setText("");
|
||||||
sourceView.setText("");
|
tbrSetByPumpView.setText("");
|
||||||
lastRunView.setText("");
|
smbSetByPumpView.setText("");
|
||||||
lastEnactView.setText("");
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,16 +21,18 @@ import info.nightscout.androidaps.Constants;
|
||||||
import info.nightscout.androidaps.MainActivity;
|
import info.nightscout.androidaps.MainActivity;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
|
import info.nightscout.androidaps.data.Profile;
|
||||||
import info.nightscout.androidaps.data.PumpEnactResult;
|
import info.nightscout.androidaps.data.PumpEnactResult;
|
||||||
import info.nightscout.androidaps.events.EventNewBG;
|
import info.nightscout.androidaps.events.EventNewBG;
|
||||||
import info.nightscout.androidaps.events.EventTreatmentChange;
|
import info.nightscout.androidaps.events.EventTreatmentChange;
|
||||||
import info.nightscout.androidaps.interfaces.APSInterface;
|
import info.nightscout.androidaps.interfaces.APSInterface;
|
||||||
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
|
import info.nightscout.androidaps.interfaces.Constraint;
|
||||||
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.interfaces.PumpInterface;
|
||||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||||
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished;
|
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished;
|
||||||
import info.nightscout.androidaps.plugins.Loop.events.EventLoopResult;
|
|
||||||
import info.nightscout.androidaps.plugins.Loop.events.EventLoopSetLastRunGui;
|
import info.nightscout.androidaps.plugins.Loop.events.EventLoopSetLastRunGui;
|
||||||
import info.nightscout.androidaps.plugins.Loop.events.EventLoopUpdateGui;
|
import info.nightscout.androidaps.plugins.Loop.events.EventLoopUpdateGui;
|
||||||
import info.nightscout.androidaps.plugins.Loop.events.EventNewOpenLoopNotification;
|
import info.nightscout.androidaps.plugins.Loop.events.EventNewOpenLoopNotification;
|
||||||
|
@ -43,10 +45,10 @@ import info.nightscout.utils.SP;
|
||||||
/**
|
/**
|
||||||
* Created by mike on 05.08.2016.
|
* Created by mike on 05.08.2016.
|
||||||
*/
|
*/
|
||||||
public class LoopPlugin implements PluginBase {
|
public class LoopPlugin extends PluginBase {
|
||||||
private static Logger log = LoggerFactory.getLogger(LoopPlugin.class);
|
private static Logger log = LoggerFactory.getLogger(LoopPlugin.class);
|
||||||
|
|
||||||
private static LoopPlugin loopPlugin;
|
protected static LoopPlugin loopPlugin;
|
||||||
|
|
||||||
public static LoopPlugin getPlugin() {
|
public static LoopPlugin getPlugin() {
|
||||||
if (loopPlugin == null) {
|
if (loopPlugin == null) {
|
||||||
|
@ -55,9 +57,6 @@ public class LoopPlugin implements PluginBase {
|
||||||
return loopPlugin;
|
return loopPlugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean fragmentEnabled = false;
|
|
||||||
private boolean fragmentVisible = false;
|
|
||||||
|
|
||||||
private long loopSuspendedTill = 0L; // end of manual loop suspend
|
private long loopSuspendedTill = 0L; // end of manual loop suspend
|
||||||
private boolean isSuperBolus = false;
|
private boolean isSuperBolus = false;
|
||||||
private boolean isDisconnected = false;
|
private boolean isDisconnected = false;
|
||||||
|
@ -65,7 +64,8 @@ public class LoopPlugin implements PluginBase {
|
||||||
public class LastRun {
|
public class LastRun {
|
||||||
public APSResult request = null;
|
public APSResult request = null;
|
||||||
public APSResult constraintsProcessed = null;
|
public APSResult constraintsProcessed = null;
|
||||||
public PumpEnactResult setByPump = null;
|
public PumpEnactResult tbrSetByPump = null;
|
||||||
|
public PumpEnactResult smbSetByPump = null;
|
||||||
public String source = null;
|
public String source = null;
|
||||||
public Date lastAPSRun = null;
|
public Date lastAPSRun = null;
|
||||||
public Date lastEnact = null;
|
public Date lastEnact = null;
|
||||||
|
@ -75,83 +75,39 @@ public class LoopPlugin implements PluginBase {
|
||||||
static public LastRun lastRun = null;
|
static public LastRun lastRun = null;
|
||||||
|
|
||||||
public LoopPlugin() {
|
public LoopPlugin() {
|
||||||
MainApp.bus().register(this);
|
super(new PluginDescription()
|
||||||
|
.mainType(PluginType.LOOP)
|
||||||
|
.fragmentClass(LoopFragment.class.getName())
|
||||||
|
.pluginName(R.string.loop)
|
||||||
|
.shortName(R.string.loop_shortname)
|
||||||
|
.preferencesId(R.xml.pref_closedmode)
|
||||||
|
);
|
||||||
loopSuspendedTill = SP.getLong("loopSuspendedTill", 0L);
|
loopSuspendedTill = SP.getLong("loopSuspendedTill", 0L);
|
||||||
isSuperBolus = SP.getBoolean("isSuperBolus", false);
|
isSuperBolus = SP.getBoolean("isSuperBolus", false);
|
||||||
isDisconnected = SP.getBoolean("isDisconnected", false);
|
isDisconnected = SP.getBoolean("isDisconnected", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getFragmentClass() {
|
protected void onStart() {
|
||||||
return LoopFragment.class.getName();
|
MainApp.bus().register(this);
|
||||||
|
super.onStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getType() {
|
protected void onStop() {
|
||||||
return PluginBase.LOOP;
|
super.onStop();
|
||||||
|
MainApp.bus().unregister(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public boolean specialEnableCondition() {
|
||||||
return MainApp.instance().getString(R.string.loop);
|
PumpInterface pump = ConfigBuilderPlugin.getActivePump();
|
||||||
}
|
return pump == null || pump.getPumpDescription().isTempBasalCapable;
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getNameShort() {
|
|
||||||
String name = MainApp.sResources.getString(R.string.loop_shortname);
|
|
||||||
if (!name.trim().isEmpty()) {
|
|
||||||
//only if translation exists
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
// use long name as fallback
|
|
||||||
return getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled(int type) {
|
|
||||||
boolean pumpCapable = ConfigBuilderPlugin.getActivePump() == null || ConfigBuilderPlugin.getActivePump().getPumpDescription().isTempBasalCapable;
|
|
||||||
return type == LOOP && fragmentEnabled && pumpCapable;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isVisibleInTabs(int type) {
|
|
||||||
boolean pumpCapable = ConfigBuilderPlugin.getActivePump() == null || ConfigBuilderPlugin.getActivePump().getPumpDescription().isTempBasalCapable;
|
|
||||||
return type == LOOP && fragmentVisible && pumpCapable;
|
|
||||||
}
|
|
||||||
|
|
||||||
@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 == LOOP) this.fragmentEnabled = fragmentEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setFragmentVisible(int type, boolean fragmentVisible) {
|
|
||||||
if (type == LOOP) this.fragmentVisible = fragmentVisible;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getPreferencesId() {
|
|
||||||
return R.xml.pref_closedmode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onStatusEvent(final EventTreatmentChange ev) {
|
public void onStatusEvent(final EventTreatmentChange ev) {
|
||||||
if (ev.treatment == null || !ev.treatment.isSMB){
|
if (ev.treatment == null || !ev.treatment.isSMB) {
|
||||||
invoke("EventTreatmentChange", true);
|
invoke("EventTreatmentChange", true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -254,19 +210,23 @@ public class LoopPlugin implements PluginBase {
|
||||||
try {
|
try {
|
||||||
if (Config.logFunctionCalls)
|
if (Config.logFunctionCalls)
|
||||||
log.debug("invoke from " + initiator);
|
log.debug("invoke from " + initiator);
|
||||||
ConstraintsInterface constraintsInterface = MainApp.getConfigBuilder();
|
Constraint<Boolean> loopEnabled = MainApp.getConstraintChecker().isLoopInvokationAllowed();
|
||||||
if (!constraintsInterface.isLoopEnabled()) {
|
|
||||||
log.debug(MainApp.sResources.getString(R.string.loopdisabled));
|
if (!loopEnabled.value()) {
|
||||||
MainApp.bus().post(new EventLoopSetLastRunGui(MainApp.sResources.getString(R.string.loopdisabled)));
|
String message = MainApp.sResources.getString(R.string.loopdisabled) + "\n" + loopEnabled.getReasons();
|
||||||
|
log.debug(message);
|
||||||
|
MainApp.bus().post(new EventLoopSetLastRunGui(message));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
|
final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
|
||||||
APSResult result = null;
|
APSResult result = null;
|
||||||
|
|
||||||
if (!isEnabled(PluginBase.LOOP))
|
if (!isEnabled(PluginType.LOOP))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (MainApp.getConfigBuilder().getProfile() == null) {
|
Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||||
|
|
||||||
|
if (!MainApp.getConfigBuilder().isProfileValid("Loop")) {
|
||||||
log.debug(MainApp.sResources.getString(R.string.noprofileselected));
|
log.debug(MainApp.sResources.getString(R.string.noprofileselected));
|
||||||
MainApp.bus().post(new EventLoopSetLastRunGui(MainApp.sResources.getString(R.string.noprofileselected)));
|
MainApp.bus().post(new EventLoopSetLastRunGui(MainApp.sResources.getString(R.string.noprofileselected)));
|
||||||
return;
|
return;
|
||||||
|
@ -276,7 +236,7 @@ public class LoopPlugin implements PluginBase {
|
||||||
if (pump.getBaseBasalRate() < 0.01d) return;
|
if (pump.getBaseBasalRate() < 0.01d) return;
|
||||||
|
|
||||||
APSInterface usedAPS = ConfigBuilderPlugin.getActiveAPS();
|
APSInterface usedAPS = ConfigBuilderPlugin.getActiveAPS();
|
||||||
if (usedAPS != null && ((PluginBase) usedAPS).isEnabled(PluginBase.APS)) {
|
if (usedAPS != null && ((PluginBase) usedAPS).isEnabled(PluginType.APS)) {
|
||||||
usedAPS.invoke(initiator);
|
usedAPS.invoke(initiator);
|
||||||
result = usedAPS.getLastAPSResult();
|
result = usedAPS.getLastAPSResult();
|
||||||
}
|
}
|
||||||
|
@ -289,8 +249,10 @@ public class LoopPlugin implements PluginBase {
|
||||||
|
|
||||||
// check rate for constrais
|
// check rate for constrais
|
||||||
final APSResult resultAfterConstraints = result.clone();
|
final APSResult resultAfterConstraints = result.clone();
|
||||||
resultAfterConstraints.rate = constraintsInterface.applyBasalConstraints(resultAfterConstraints.rate);
|
resultAfterConstraints.rateConstraint = new Constraint<>(resultAfterConstraints.rate);
|
||||||
resultAfterConstraints.smb = constraintsInterface.applyBolusConstraints(resultAfterConstraints.smb);
|
resultAfterConstraints.rate = MainApp.getConstraintChecker().applyBasalConstraints(resultAfterConstraints.rateConstraint, profile).value();
|
||||||
|
resultAfterConstraints.smbConstraint = new Constraint<>(resultAfterConstraints.smb);
|
||||||
|
resultAfterConstraints.smb = MainApp.getConstraintChecker().applyBolusConstraints(resultAfterConstraints.smbConstraint).value();
|
||||||
|
|
||||||
// safety check for multiple SMBs
|
// safety check for multiple SMBs
|
||||||
long lastBolusTime = TreatmentsPlugin.getPlugin().getLastBolusTime();
|
long lastBolusTime = TreatmentsPlugin.getPlugin().getLastBolusTime();
|
||||||
|
@ -304,7 +266,8 @@ public class LoopPlugin implements PluginBase {
|
||||||
lastRun.constraintsProcessed = resultAfterConstraints;
|
lastRun.constraintsProcessed = resultAfterConstraints;
|
||||||
lastRun.lastAPSRun = new Date();
|
lastRun.lastAPSRun = new Date();
|
||||||
lastRun.source = ((PluginBase) usedAPS).getName();
|
lastRun.source = ((PluginBase) usedAPS).getName();
|
||||||
lastRun.setByPump = null;
|
lastRun.tbrSetByPump = null;
|
||||||
|
lastRun.smbSetByPump = null;
|
||||||
|
|
||||||
NSUpload.uploadDeviceStatus();
|
NSUpload.uploadDeviceStatus();
|
||||||
|
|
||||||
|
@ -320,31 +283,41 @@ public class LoopPlugin implements PluginBase {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
MainApp.bus().post(new EventLoopResult(resultAfterConstraints));
|
Constraint<Boolean> closedLoopEnabled = MainApp.getConstraintChecker().isClosedLoopAllowed();
|
||||||
|
|
||||||
if (constraintsInterface.isClosedModeEnabled()) {
|
if (closedLoopEnabled.value()) {
|
||||||
if (result.isChangeRequested()) {
|
if (result.isChangeRequested()) {
|
||||||
final PumpEnactResult waiting = new PumpEnactResult();
|
final PumpEnactResult waiting = new PumpEnactResult();
|
||||||
final PumpEnactResult previousResult = lastRun.setByPump;
|
|
||||||
waiting.queued = true;
|
waiting.queued = true;
|
||||||
lastRun.setByPump = waiting;
|
if (resultAfterConstraints.tempBasalRequested)
|
||||||
|
lastRun.tbrSetByPump = waiting;
|
||||||
|
if (resultAfterConstraints.bolusRequested)
|
||||||
|
lastRun.smbSetByPump = waiting;
|
||||||
MainApp.bus().post(new EventLoopUpdateGui());
|
MainApp.bus().post(new EventLoopUpdateGui());
|
||||||
MainApp.getConfigBuilder().applyAPSRequest(resultAfterConstraints, new Callback() {
|
FabricPrivacy.getInstance().logCustom(new CustomEvent("APSRequest"));
|
||||||
|
MainApp.getConfigBuilder().applyTBRRequest(resultAfterConstraints, profile, new Callback() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("APSRequest"));
|
|
||||||
if (result.enacted || result.success) {
|
if (result.enacted || result.success) {
|
||||||
lastRun.setByPump = result;
|
lastRun.tbrSetByPump = result;
|
||||||
|
lastRun.lastEnact = lastRun.lastAPSRun;
|
||||||
|
}
|
||||||
|
MainApp.bus().post(new EventLoopUpdateGui());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
MainApp.getConfigBuilder().applySMBRequest(resultAfterConstraints, new Callback() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (result.enacted || result.success) {
|
||||||
|
lastRun.smbSetByPump = result;
|
||||||
lastRun.lastEnact = lastRun.lastAPSRun;
|
lastRun.lastEnact = lastRun.lastAPSRun;
|
||||||
} else {
|
|
||||||
lastRun.setByPump = previousResult;
|
|
||||||
}
|
}
|
||||||
MainApp.bus().post(new EventLoopUpdateGui());
|
MainApp.bus().post(new EventLoopUpdateGui());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
lastRun.setByPump = null;
|
lastRun.tbrSetByPump = null;
|
||||||
lastRun.source = null;
|
lastRun.smbSetByPump = null;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (result.isChangeRequested() && allowNotification) {
|
if (result.isChangeRequested() && allowNotification) {
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
package info.nightscout.androidaps.plugins.Loop.events;
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.plugins.Loop.APSResult;
|
|
||||||
|
|
||||||
public class EventLoopResult {
|
|
||||||
public final APSResult apsResult;
|
|
||||||
|
|
||||||
public EventLoopResult(APSResult apsResult) {
|
|
||||||
this.apsResult = apsResult;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.app.Fragment;
|
|
||||||
import android.text.Html;
|
import android.text.Html;
|
||||||
import android.text.Spanned;
|
import android.text.Spanned;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
@ -34,8 +33,8 @@ import info.nightscout.androidaps.plugins.NSClientInternal.events.EventNSClientU
|
||||||
import info.nightscout.utils.FabricPrivacy;
|
import info.nightscout.utils.FabricPrivacy;
|
||||||
import info.nightscout.utils.SP;
|
import info.nightscout.utils.SP;
|
||||||
|
|
||||||
public class NSClientInternalFragment extends SubscriberFragment implements View.OnClickListener, CompoundButton.OnCheckedChangeListener {
|
public class NSClientFragment extends SubscriberFragment implements View.OnClickListener, CompoundButton.OnCheckedChangeListener {
|
||||||
private static Logger log = LoggerFactory.getLogger(NSClientInternalFragment.class);
|
private static Logger log = LoggerFactory.getLogger(NSClientFragment.class);
|
||||||
|
|
||||||
private TextView logTextView;
|
private TextView logTextView;
|
||||||
private TextView queueTextView;
|
private TextView queueTextView;
|
||||||
|
@ -58,10 +57,10 @@ public class NSClientInternalFragment extends SubscriberFragment implements View
|
||||||
|
|
||||||
logScrollview = (ScrollView) view.findViewById(R.id.nsclientinternal_logscrollview);
|
logScrollview = (ScrollView) view.findViewById(R.id.nsclientinternal_logscrollview);
|
||||||
autoscrollCheckbox = (CheckBox) view.findViewById(R.id.nsclientinternal_autoscroll);
|
autoscrollCheckbox = (CheckBox) view.findViewById(R.id.nsclientinternal_autoscroll);
|
||||||
autoscrollCheckbox.setChecked(NSClientInternalPlugin.getPlugin().autoscroll);
|
autoscrollCheckbox.setChecked(NSClientPlugin.getPlugin().autoscroll);
|
||||||
autoscrollCheckbox.setOnCheckedChangeListener(this);
|
autoscrollCheckbox.setOnCheckedChangeListener(this);
|
||||||
pausedCheckbox = (CheckBox) view.findViewById(R.id.nsclientinternal_paused);
|
pausedCheckbox = (CheckBox) view.findViewById(R.id.nsclientinternal_paused);
|
||||||
pausedCheckbox.setChecked(NSClientInternalPlugin.getPlugin().paused);
|
pausedCheckbox.setChecked(NSClientPlugin.getPlugin().paused);
|
||||||
pausedCheckbox.setOnCheckedChangeListener(this);
|
pausedCheckbox.setOnCheckedChangeListener(this);
|
||||||
logTextView = (TextView) view.findViewById(R.id.nsclientinternal_log);
|
logTextView = (TextView) view.findViewById(R.id.nsclientinternal_log);
|
||||||
queueTextView = (TextView) view.findViewById(R.id.nsclientinternal_queue);
|
queueTextView = (TextView) view.findViewById(R.id.nsclientinternal_queue);
|
||||||
|
@ -101,11 +100,11 @@ public class NSClientInternalFragment extends SubscriberFragment implements View
|
||||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("NSClientRestart"));
|
FabricPrivacy.getInstance().logCustom(new CustomEvent("NSClientRestart"));
|
||||||
break;
|
break;
|
||||||
case R.id.nsclientinternal_delivernow:
|
case R.id.nsclientinternal_delivernow:
|
||||||
NSClientInternalPlugin.getPlugin().resend("GUI");
|
NSClientPlugin.getPlugin().resend("GUI");
|
||||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("NSClientDeliverNow"));
|
FabricPrivacy.getInstance().logCustom(new CustomEvent("NSClientDeliverNow"));
|
||||||
break;
|
break;
|
||||||
case R.id.nsclientinternal_clearlog:
|
case R.id.nsclientinternal_clearlog:
|
||||||
NSClientInternalPlugin.getPlugin().clearLog();
|
NSClientPlugin.getPlugin().clearLog();
|
||||||
break;
|
break;
|
||||||
case R.id.nsclientinternal_clearqueue:
|
case R.id.nsclientinternal_clearqueue:
|
||||||
final Context context = getContext();
|
final Context context = getContext();
|
||||||
|
@ -124,7 +123,7 @@ public class NSClientInternalFragment extends SubscriberFragment implements View
|
||||||
builder.show();
|
builder.show();
|
||||||
break;
|
break;
|
||||||
case R.id.nsclientinternal_showqueue:
|
case R.id.nsclientinternal_showqueue:
|
||||||
MainApp.bus().post(new EventNSClientNewLog("QUEUE", NSClientInternalPlugin.getPlugin().queue().textList()));
|
MainApp.bus().post(new EventNSClientNewLog("QUEUE", NSClientPlugin.getPlugin().queue().textList()));
|
||||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("NSClientShowQueue"));
|
FabricPrivacy.getInstance().logCustom(new CustomEvent("NSClientShowQueue"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -135,14 +134,14 @@ public class NSClientInternalFragment extends SubscriberFragment implements View
|
||||||
switch (buttonView.getId()) {
|
switch (buttonView.getId()) {
|
||||||
case R.id.nsclientinternal_paused:
|
case R.id.nsclientinternal_paused:
|
||||||
SP.putBoolean(R.string.key_nsclientinternal_paused, isChecked);
|
SP.putBoolean(R.string.key_nsclientinternal_paused, isChecked);
|
||||||
NSClientInternalPlugin.getPlugin().paused = isChecked;
|
NSClientPlugin.getPlugin().paused = isChecked;
|
||||||
MainApp.bus().post(new EventPreferenceChange(R.string.key_nsclientinternal_paused));
|
MainApp.bus().post(new EventPreferenceChange(R.string.key_nsclientinternal_paused));
|
||||||
updateGUI();
|
updateGUI();
|
||||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("NSClientPause"));
|
FabricPrivacy.getInstance().logCustom(new CustomEvent("NSClientPause"));
|
||||||
break;
|
break;
|
||||||
case R.id.nsclientinternal_autoscroll:
|
case R.id.nsclientinternal_autoscroll:
|
||||||
SP.putBoolean(R.string.key_nsclientinternal_autoscroll, isChecked);
|
SP.putBoolean(R.string.key_nsclientinternal_autoscroll, isChecked);
|
||||||
NSClientInternalPlugin.getPlugin().autoscroll = isChecked;
|
NSClientPlugin.getPlugin().autoscroll = isChecked;
|
||||||
updateGUI();
|
updateGUI();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -160,15 +159,15 @@ public class NSClientInternalFragment extends SubscriberFragment implements View
|
||||||
activity.runOnUiThread(new Runnable() {
|
activity.runOnUiThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
NSClientInternalPlugin.updateLog();
|
NSClientPlugin.getPlugin().updateLog();
|
||||||
logTextView.setText(NSClientInternalPlugin.textLog);
|
logTextView.setText(NSClientPlugin.getPlugin().textLog);
|
||||||
if (NSClientInternalPlugin.getPlugin().autoscroll) {
|
if (NSClientPlugin.getPlugin().autoscroll) {
|
||||||
logScrollview.fullScroll(ScrollView.FOCUS_DOWN);
|
logScrollview.fullScroll(ScrollView.FOCUS_DOWN);
|
||||||
}
|
}
|
||||||
urlTextView.setText(NSClientInternalPlugin.getPlugin().url());
|
urlTextView.setText(NSClientPlugin.getPlugin().url());
|
||||||
Spanned queuetext = Html.fromHtml(MainApp.sResources.getString(R.string.queue) + " <b>" + UploadQueue.size() + "</b>");
|
Spanned queuetext = Html.fromHtml(MainApp.sResources.getString(R.string.queue) + " <b>" + UploadQueue.size() + "</b>");
|
||||||
queueTextView.setText(queuetext);
|
queueTextView.setText(queuetext);
|
||||||
statusTextView.setText(NSClientInternalPlugin.getPlugin().status);
|
statusTextView.setText(NSClientPlugin.getPlugin().status);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
|
@ -18,12 +18,15 @@ import org.slf4j.LoggerFactory;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
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.Constants;
|
import info.nightscout.androidaps.Constants;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.events.EventAppExit;
|
import info.nightscout.androidaps.events.EventAppExit;
|
||||||
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.plugins.NSClientInternal.events.EventNSClientNewLog;
|
import info.nightscout.androidaps.plugins.NSClientInternal.events.EventNSClientNewLog;
|
||||||
import info.nightscout.androidaps.plugins.NSClientInternal.events.EventNSClientStatus;
|
import info.nightscout.androidaps.plugins.NSClientInternal.events.EventNSClientStatus;
|
||||||
import info.nightscout.androidaps.plugins.NSClientInternal.events.EventNSClientUpdateGUI;
|
import info.nightscout.androidaps.plugins.NSClientInternal.events.EventNSClientUpdateGUI;
|
||||||
|
@ -31,25 +34,22 @@ import info.nightscout.androidaps.plugins.NSClientInternal.services.NSClientServ
|
||||||
import info.nightscout.utils.SP;
|
import info.nightscout.utils.SP;
|
||||||
import info.nightscout.utils.ToastUtils;
|
import info.nightscout.utils.ToastUtils;
|
||||||
|
|
||||||
public class NSClientInternalPlugin implements PluginBase {
|
public class NSClientPlugin extends PluginBase {
|
||||||
private static Logger log = LoggerFactory.getLogger(NSClientInternalPlugin.class);
|
private static Logger log = LoggerFactory.getLogger(NSClientPlugin.class);
|
||||||
|
|
||||||
static NSClientInternalPlugin nsClientInternalPlugin;
|
static NSClientPlugin nsClientPlugin;
|
||||||
|
|
||||||
static public NSClientInternalPlugin getPlugin() {
|
static public NSClientPlugin getPlugin() {
|
||||||
if (nsClientInternalPlugin == null) {
|
if (nsClientPlugin == null) {
|
||||||
nsClientInternalPlugin = new NSClientInternalPlugin();
|
nsClientPlugin = new NSClientPlugin();
|
||||||
}
|
}
|
||||||
return nsClientInternalPlugin;
|
return nsClientPlugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean fragmentEnabled = true;
|
public Handler handler;
|
||||||
private boolean fragmentVisible = true;
|
|
||||||
|
|
||||||
static public Handler handler;
|
private final List<EventNSClientNewLog> listLog = new ArrayList<>();
|
||||||
|
Spanned textLog = Html.fromHtml("");
|
||||||
private static List<EventNSClientNewLog> listLog = new ArrayList<>();
|
|
||||||
static Spanned textLog = Html.fromHtml("");
|
|
||||||
|
|
||||||
public boolean paused = false;
|
public boolean paused = false;
|
||||||
boolean autoscroll = true;
|
boolean autoscroll = true;
|
||||||
|
@ -58,86 +58,42 @@ public class NSClientInternalPlugin implements PluginBase {
|
||||||
|
|
||||||
public NSClientService nsClientService = null;
|
public NSClientService nsClientService = null;
|
||||||
|
|
||||||
NSClientInternalPlugin() {
|
public NSClientPlugin() {
|
||||||
MainApp.bus().register(this);
|
super(new PluginDescription()
|
||||||
|
.mainType(PluginType.GENERAL)
|
||||||
|
.fragmentClass(NSClientFragment.class.getName())
|
||||||
|
.pluginName(R.string.nsclientinternal)
|
||||||
|
.shortName(R.string.nsclientinternal_shortname)
|
||||||
|
.preferencesId(R.xml.pref_nsclientinternal)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (Config.NSCLIENT || Config.G5UPLOADER) {
|
||||||
|
pluginDescription.alwaysEnabled(true).visibleByDefault(true);
|
||||||
|
}
|
||||||
paused = SP.getBoolean(R.string.key_nsclientinternal_paused, false);
|
paused = SP.getBoolean(R.string.key_nsclientinternal_paused, false);
|
||||||
autoscroll = SP.getBoolean(R.string.key_nsclientinternal_autoscroll, true);
|
autoscroll = SP.getBoolean(R.string.key_nsclientinternal_autoscroll, true);
|
||||||
|
|
||||||
if (handler == null) {
|
if (handler == null) {
|
||||||
HandlerThread handlerThread = new HandlerThread(NSClientInternalPlugin.class.getSimpleName() + "Handler");
|
HandlerThread handlerThread = new HandlerThread(NSClientPlugin.class.getSimpleName() + "Handler");
|
||||||
handlerThread.start();
|
handlerThread.start();
|
||||||
handler = new Handler(handlerThread.getLooper());
|
handler = new Handler(handlerThread.getLooper());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStart() {
|
||||||
|
MainApp.bus().register(this);
|
||||||
Context context = MainApp.instance().getApplicationContext();
|
Context context = MainApp.instance().getApplicationContext();
|
||||||
Intent intent = new Intent(context, NSClientService.class);
|
Intent intent = new Intent(context, NSClientService.class);
|
||||||
context.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
|
context.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
|
||||||
|
super.onStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getType() {
|
protected void onStop() {
|
||||||
return PluginBase.GENERAL;
|
MainApp.bus().unregister(this);
|
||||||
}
|
Context context = MainApp.instance().getApplicationContext();
|
||||||
|
context.unbindService(mConnection);
|
||||||
@Override
|
|
||||||
public String getFragmentClass() {
|
|
||||||
return NSClientInternalFragment.class.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return MainApp.sResources.getString(R.string.nsclientinternal);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getNameShort() {
|
|
||||||
String name = MainApp.sResources.getString(R.string.nsclientinternal_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_nsclientinternal;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ServiceConnection mConnection = new ServiceConnection() {
|
private ServiceConnection mConnection = new ServiceConnection() {
|
||||||
|
@ -150,7 +106,8 @@ public class NSClientInternalPlugin implements PluginBase {
|
||||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||||
log.debug("Service is connected");
|
log.debug("Service is connected");
|
||||||
NSClientService.LocalBinder mLocalBinder = (NSClientService.LocalBinder) service;
|
NSClientService.LocalBinder mLocalBinder = (NSClientService.LocalBinder) service;
|
||||||
nsClientService = mLocalBinder.getServiceInstance();
|
if (mLocalBinder != null) // is null when running in roboelectric
|
||||||
|
nsClientService = mLocalBinder.getServiceInstance();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -177,7 +134,9 @@ public class NSClientInternalPlugin implements PluginBase {
|
||||||
handler.post(new Runnable() {
|
handler.post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
listLog = new ArrayList<>();
|
synchronized (listLog) {
|
||||||
|
listLog.clear();
|
||||||
|
}
|
||||||
MainApp.bus().post(new EventNSClientUpdateGUI());
|
MainApp.bus().post(new EventNSClientUpdateGUI());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -187,22 +146,25 @@ public class NSClientInternalPlugin implements PluginBase {
|
||||||
handler.post(new Runnable() {
|
handler.post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
listLog.add(ev);
|
synchronized (listLog) {
|
||||||
// remove the first line if log is too large
|
listLog.add(ev);
|
||||||
if (listLog.size() >= Constants.MAX_LOG_LINES) {
|
// remove the first line if log is too large
|
||||||
listLog.remove(0);
|
if (listLog.size() >= Constants.MAX_LOG_LINES) {
|
||||||
|
listLog.remove(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
MainApp.bus().post(new EventNSClientUpdateGUI());
|
MainApp.bus().post(new EventNSClientUpdateGUI());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static synchronized void updateLog() {
|
synchronized void updateLog() {
|
||||||
try {
|
try {
|
||||||
StringBuilder newTextLog = new StringBuilder();
|
StringBuilder newTextLog = new StringBuilder();
|
||||||
List<EventNSClientNewLog> temporaryList = new ArrayList<>(listLog);
|
synchronized (listLog) {
|
||||||
for (EventNSClientNewLog log : temporaryList) {
|
for (EventNSClientNewLog log : listLog) {
|
||||||
newTextLog.append(log.toPreparedHtml());
|
newTextLog.append(log.toPreparedHtml());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
textLog = Html.fromHtml(newTextLog.toString());
|
textLog = Html.fromHtml(newTextLog.toString());
|
||||||
} catch (OutOfMemoryError e) {
|
} catch (OutOfMemoryError e) {
|
|
@ -48,7 +48,7 @@ public class UploadQueue {
|
||||||
public void run() {
|
public void run() {
|
||||||
log.debug("QUEUE adding: " + dbr.data);
|
log.debug("QUEUE adding: " + dbr.data);
|
||||||
MainApp.getDbHelper().create(dbr);
|
MainApp.getDbHelper().create(dbr);
|
||||||
NSClientInternalPlugin plugin = MainApp.getSpecificPlugin(NSClientInternalPlugin.class);
|
NSClientPlugin plugin = NSClientPlugin.getPlugin();
|
||||||
if (plugin != null) {
|
if (plugin != null) {
|
||||||
plugin.resend("newdata");
|
plugin.resend("newdata");
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,19 +6,14 @@ import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
|
|
||||||
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 info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.db.DbRequest;
|
|
||||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||||
import info.nightscout.androidaps.plugins.NSClientInternal.NSClientInternalPlugin;
|
import info.nightscout.androidaps.interfaces.PluginType;
|
||||||
import info.nightscout.androidaps.plugins.NSClientInternal.UploadQueue;
|
import info.nightscout.androidaps.plugins.NSClientInternal.NSClientPlugin;
|
||||||
import info.nightscout.androidaps.plugins.NSClientInternal.data.AlarmAck;
|
import info.nightscout.androidaps.plugins.NSClientInternal.data.AlarmAck;
|
||||||
import info.nightscout.androidaps.plugins.NSClientInternal.services.NSClientService;
|
import info.nightscout.androidaps.plugins.NSClientInternal.services.NSClientService;
|
||||||
import info.nightscout.utils.SP;
|
import info.nightscout.utils.SP;
|
||||||
|
@ -32,8 +27,8 @@ public class AckAlarmReceiver extends BroadcastReceiver {
|
||||||
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
||||||
PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
|
PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
|
||||||
AckAlarmReceiver.class.getSimpleName());
|
AckAlarmReceiver.class.getSimpleName());
|
||||||
NSClientInternalPlugin nsClientInternalPlugin = MainApp.getSpecificPlugin(NSClientInternalPlugin.class);
|
NSClientPlugin nsClientPlugin = MainApp.getSpecificPlugin(NSClientPlugin.class);
|
||||||
if (!nsClientInternalPlugin.isEnabled(PluginBase.GENERAL)) {
|
if (!nsClientPlugin.isEnabled(PluginType.GENERAL)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (SP.getBoolean(R.string.key_ns_noupload, false)) {
|
if (SP.getBoolean(R.string.key_ns_noupload, false)) {
|
||||||
|
@ -53,7 +48,7 @@ public class AckAlarmReceiver extends BroadcastReceiver {
|
||||||
ack.group = bundles.getString("group");
|
ack.group = bundles.getString("group");
|
||||||
ack.silenceTime = bundles.getLong("silenceTime");
|
ack.silenceTime = bundles.getLong("silenceTime");
|
||||||
|
|
||||||
NSClientService nsClientService = nsClientInternalPlugin.nsClientService;
|
NSClientService nsClientService = nsClientPlugin.nsClientService;
|
||||||
if (nsClientService != null)
|
if (nsClientService != null)
|
||||||
nsClientService.sendAlarmAck(ack);
|
nsClientService.sendAlarmAck(ack);
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,8 @@ 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.db.DbRequest;
|
import info.nightscout.androidaps.db.DbRequest;
|
||||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
import info.nightscout.androidaps.interfaces.PluginType;
|
||||||
import info.nightscout.androidaps.plugins.NSClientInternal.NSClientInternalPlugin;
|
import info.nightscout.androidaps.plugins.NSClientInternal.NSClientPlugin;
|
||||||
import info.nightscout.androidaps.plugins.NSClientInternal.UploadQueue;
|
import info.nightscout.androidaps.plugins.NSClientInternal.UploadQueue;
|
||||||
import info.nightscout.androidaps.plugins.NSClientInternal.broadcasts.BroadcastTreatment;
|
import info.nightscout.androidaps.plugins.NSClientInternal.broadcasts.BroadcastTreatment;
|
||||||
import info.nightscout.utils.DateUtil;
|
import info.nightscout.utils.DateUtil;
|
||||||
|
@ -94,7 +94,7 @@ public class DBAccessReceiver extends BroadcastReceiver {
|
||||||
UploadQueue.add(dbr);
|
UploadQueue.add(dbr);
|
||||||
}
|
}
|
||||||
if (collection.equals("treatments")) {
|
if (collection.equals("treatments")) {
|
||||||
genereateTreatmentOfflineBroadcast(dbr);
|
generateTreatmentOfflineBroadcast(dbr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,11 +105,11 @@ public class DBAccessReceiver extends BroadcastReceiver {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean shouldUpload() {
|
public boolean shouldUpload() {
|
||||||
NSClientInternalPlugin nsClientInternalPlugin = MainApp.getSpecificPlugin(NSClientInternalPlugin.class);
|
NSClientPlugin nsClientPlugin = MainApp.getSpecificPlugin(NSClientPlugin.class);
|
||||||
return nsClientInternalPlugin.isEnabled(PluginBase.GENERAL) && !SP.getBoolean(R.string.key_ns_noupload, false);
|
return nsClientPlugin.isEnabled(PluginType.GENERAL) && !SP.getBoolean(R.string.key_ns_noupload, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void genereateTreatmentOfflineBroadcast(DbRequest request) {
|
public void generateTreatmentOfflineBroadcast(DbRequest request) {
|
||||||
if (request.action.equals("dbAdd")) {
|
if (request.action.equals("dbAdd")) {
|
||||||
try {
|
try {
|
||||||
JSONObject data = new JSONObject(request.data);
|
JSONObject data = new JSONObject(request.data);
|
||||||
|
|
|
@ -34,7 +34,8 @@ import info.nightscout.androidaps.events.EventAppExit;
|
||||||
import info.nightscout.androidaps.events.EventConfigBuilderChange;
|
import info.nightscout.androidaps.events.EventConfigBuilderChange;
|
||||||
import info.nightscout.androidaps.events.EventPreferenceChange;
|
import info.nightscout.androidaps.events.EventPreferenceChange;
|
||||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||||
import info.nightscout.androidaps.plugins.NSClientInternal.NSClientInternalPlugin;
|
import info.nightscout.androidaps.interfaces.PluginType;
|
||||||
|
import info.nightscout.androidaps.plugins.NSClientInternal.NSClientPlugin;
|
||||||
import info.nightscout.androidaps.plugins.NSClientInternal.UploadQueue;
|
import info.nightscout.androidaps.plugins.NSClientInternal.UploadQueue;
|
||||||
import info.nightscout.androidaps.plugins.NSClientInternal.acks.NSAddAck;
|
import info.nightscout.androidaps.plugins.NSClientInternal.acks.NSAddAck;
|
||||||
import info.nightscout.androidaps.plugins.NSClientInternal.acks.NSAuthAck;
|
import info.nightscout.androidaps.plugins.NSClientInternal.acks.NSAuthAck;
|
||||||
|
@ -63,6 +64,7 @@ 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.FabricPrivacy;
|
import info.nightscout.utils.FabricPrivacy;
|
||||||
|
import info.nightscout.utils.JsonHelper;
|
||||||
import info.nightscout.utils.SP;
|
import info.nightscout.utils.SP;
|
||||||
import io.socket.client.IO;
|
import io.socket.client.IO;
|
||||||
import io.socket.client.Socket;
|
import io.socket.client.Socket;
|
||||||
|
@ -179,7 +181,7 @@ public class NSClientService extends Service {
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onStatusEvent(EventConfigBuilderChange ev) {
|
public void onStatusEvent(EventConfigBuilderChange ev) {
|
||||||
if (nsEnabled != MainApp.getSpecificPlugin(NSClientInternalPlugin.class).isEnabled(PluginBase.GENERAL)) {
|
if (nsEnabled != MainApp.getSpecificPlugin(NSClientPlugin.class).isEnabled(PluginType.GENERAL)) {
|
||||||
latestDateInReceivedData = 0;
|
latestDateInReceivedData = 0;
|
||||||
destroy();
|
destroy();
|
||||||
initialize();
|
initialize();
|
||||||
|
@ -201,7 +203,7 @@ public class NSClientService extends Service {
|
||||||
nsAPIhashCode = Hashing.sha1().hashString(nsAPISecret, Charsets.UTF_8).toString();
|
nsAPIhashCode = Hashing.sha1().hashString(nsAPISecret, Charsets.UTF_8).toString();
|
||||||
|
|
||||||
MainApp.bus().post(new EventNSClientStatus("Initializing"));
|
MainApp.bus().post(new EventNSClientStatus("Initializing"));
|
||||||
if (MainApp.getSpecificPlugin(NSClientInternalPlugin.class).paused) {
|
if (MainApp.getSpecificPlugin(NSClientPlugin.class).paused) {
|
||||||
MainApp.bus().post(new EventNSClientNewLog("NSCLIENT", "paused"));
|
MainApp.bus().post(new EventNSClientNewLog("NSCLIENT", "paused"));
|
||||||
MainApp.bus().post(new EventNSClientStatus("Paused"));
|
MainApp.bus().post(new EventNSClientStatus("Paused"));
|
||||||
} else if (!nsEnabled) {
|
} else if (!nsEnabled) {
|
||||||
|
@ -312,7 +314,7 @@ public class NSClientService extends Service {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void readPreferences() {
|
public void readPreferences() {
|
||||||
nsEnabled = MainApp.getSpecificPlugin(NSClientInternalPlugin.class).isEnabled(PluginBase.GENERAL);
|
nsEnabled = MainApp.getSpecificPlugin(NSClientPlugin.class).isEnabled(PluginType.GENERAL);
|
||||||
nsURL = SP.getString(R.string.key_nsclientinternal_url, "");
|
nsURL = SP.getString(R.string.key_nsclientinternal_url, "");
|
||||||
nsAPISecret = SP.getString(R.string.key_nsclientinternal_api_secret, "");
|
nsAPISecret = SP.getString(R.string.key_nsclientinternal_api_secret, "");
|
||||||
nsDevice = SP.getString("careportal_enteredby", "");
|
nsDevice = SP.getString("careportal_enteredby", "");
|
||||||
|
@ -351,7 +353,7 @@ public class NSClientService extends Service {
|
||||||
}
|
}
|
||||||
if (Config.detailedLog)
|
if (Config.detailedLog)
|
||||||
try {
|
try {
|
||||||
MainApp.bus().post(new EventNSClientNewLog("ANNOUNCEMENT", data.has("message") ? data.getString("message") : "received"));
|
MainApp.bus().post(new EventNSClientNewLog("ANNOUNCEMENT", JsonHelper.safeGetString(data, "message", "received")));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
FabricPrivacy.logException(e);
|
FabricPrivacy.logException(e);
|
||||||
}
|
}
|
||||||
|
@ -573,22 +575,18 @@ public class NSClientService extends Service {
|
||||||
MainApp.bus().post(new EventNSClientNewLog("DATA", "received " + foods.length() + " foods"));
|
MainApp.bus().post(new EventNSClientNewLog("DATA", "received " + foods.length() + " foods"));
|
||||||
for (Integer index = 0; index < foods.length(); index++) {
|
for (Integer index = 0; index < foods.length(); index++) {
|
||||||
JSONObject jsonFood = foods.getJSONObject(index);
|
JSONObject jsonFood = foods.getJSONObject(index);
|
||||||
NSTreatment treatment = new NSTreatment(jsonFood);
|
|
||||||
|
|
||||||
// remove from upload queue if Ack is failing
|
// remove from upload queue if Ack is failing
|
||||||
UploadQueue.removeID(jsonFood);
|
UploadQueue.removeID(jsonFood);
|
||||||
//Find latest date in treatment
|
|
||||||
if (treatment.getMills() != null && treatment.getMills() < System.currentTimeMillis())
|
|
||||||
if (treatment.getMills() > latestDateInReceivedData)
|
|
||||||
latestDateInReceivedData = treatment.getMills();
|
|
||||||
|
|
||||||
if (treatment.getAction() == null) {
|
String action = JsonHelper.safeGetString(jsonFood, "action");
|
||||||
|
|
||||||
|
if (action == null) {
|
||||||
addedFoods.put(jsonFood);
|
addedFoods.put(jsonFood);
|
||||||
} else if (treatment.getAction().equals("update")) {
|
} else if (action.equals("update")) {
|
||||||
updatedFoods.put(jsonFood);
|
updatedFoods.put(jsonFood);
|
||||||
} else if (treatment.getAction().equals("remove")) {
|
} else if (action.equals("remove")) {
|
||||||
if (treatment.getMills() != null && treatment.getMills() > System.currentTimeMillis() - 24 * 60 * 60 * 1000L) // handle 1 day old deletions only
|
removedFoods.put(jsonFood);
|
||||||
removedFoods.put(jsonFood);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (removedFoods.length() > 0) {
|
if (removedFoods.length() > 0) {
|
||||||
|
@ -601,18 +599,6 @@ public class NSClientService extends Service {
|
||||||
BroadcastFood.handleNewFood(addedFoods, MainApp.instance().getApplicationContext(), isDelta);
|
BroadcastFood.handleNewFood(addedFoods, MainApp.instance().getApplicationContext(), isDelta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (data.has("")) {
|
|
||||||
JSONArray foods = data.getJSONArray("food");
|
|
||||||
if (foods.length() > 0) {
|
|
||||||
MainApp.bus().post(new EventNSClientNewLog("DATA", "received " + foods.length() + " foods"));
|
|
||||||
for (Integer index = 0; index < foods.length(); index++) {
|
|
||||||
JSONObject jsonFood = foods.getJSONObject(index);
|
|
||||||
// remove from upload queue if Ack is failing
|
|
||||||
UploadQueue.removeID(jsonFood);
|
|
||||||
}
|
|
||||||
BroadcastDeviceStatus.handleNewFoods(foods, MainApp.instance().getApplicationContext(), isDelta);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (data.has("mbgs")) {
|
if (data.has("mbgs")) {
|
||||||
JSONArray mbgs = data.getJSONArray("mbgs");
|
JSONArray mbgs = data.getJSONArray("mbgs");
|
||||||
if (mbgs.length() > 0)
|
if (mbgs.length() > 0)
|
||||||
|
|
|
@ -21,6 +21,7 @@ import java.lang.reflect.InvocationTargetException;
|
||||||
import info.nightscout.androidaps.Config;
|
import info.nightscout.androidaps.Config;
|
||||||
import info.nightscout.androidaps.Constants;
|
import info.nightscout.androidaps.Constants;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.data.GlucoseStatus;
|
import info.nightscout.androidaps.data.GlucoseStatus;
|
||||||
import info.nightscout.androidaps.data.IobTotal;
|
import info.nightscout.androidaps.data.IobTotal;
|
||||||
import info.nightscout.androidaps.data.MealData;
|
import info.nightscout.androidaps.data.MealData;
|
||||||
|
@ -30,6 +31,7 @@ import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugi
|
||||||
import info.nightscout.androidaps.plugins.Loop.ScriptReader;
|
import info.nightscout.androidaps.plugins.Loop.ScriptReader;
|
||||||
import info.nightscout.androidaps.plugins.OpenAPSMA.LoggerCallback;
|
import info.nightscout.androidaps.plugins.OpenAPSMA.LoggerCallback;
|
||||||
import info.nightscout.androidaps.plugins.OpenAPSSMB.SMBDefaults;
|
import info.nightscout.androidaps.plugins.OpenAPSSMB.SMBDefaults;
|
||||||
|
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.utils.SP;
|
import info.nightscout.utils.SP;
|
||||||
|
|
||||||
public class DetermineBasalAdapterAMAJS {
|
public class DetermineBasalAdapterAMAJS {
|
||||||
|
@ -204,9 +206,9 @@ public class DetermineBasalAdapterAMAJS {
|
||||||
mProfile.put("max_bg", maxBg);
|
mProfile.put("max_bg", maxBg);
|
||||||
mProfile.put("target_bg", targetBg);
|
mProfile.put("target_bg", targetBg);
|
||||||
mProfile.put("carb_ratio", profile.getIc());
|
mProfile.put("carb_ratio", profile.getIc());
|
||||||
mProfile.put("sens", Profile.toMgdl(profile.getIsf().doubleValue(), units));
|
mProfile.put("sens", Profile.toMgdl(profile.getIsf(), units));
|
||||||
mProfile.put("max_daily_safety_multiplier", SP.getInt("openapsama_max_daily_safety_multiplier", 3));
|
mProfile.put("max_daily_safety_multiplier", SP.getInt(R.string.key_openapsama_max_daily_safety_multiplier, 3));
|
||||||
mProfile.put("current_basal_safety_multiplier", SP.getDouble("openapsama_current_basal_safety_multiplier", 4d));
|
mProfile.put("current_basal_safety_multiplier", SP.getDouble(R.string.key_openapsama_current_basal_safety_multiplier, 4d));
|
||||||
mProfile.put("skip_neutral_temps", true);
|
mProfile.put("skip_neutral_temps", true);
|
||||||
mProfile.put("current_basal", basalrate);
|
mProfile.put("current_basal", basalrate);
|
||||||
mProfile.put("temptargetSet", tempTargetSet);
|
mProfile.put("temptargetSet", tempTargetSet);
|
||||||
|
@ -218,14 +220,16 @@ public class DetermineBasalAdapterAMAJS {
|
||||||
mProfile.put("out_units", "mmol/L");
|
mProfile.put("out_units", "mmol/L");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
TemporaryBasal tb = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(now);
|
||||||
|
|
||||||
mCurrentTemp = new JSONObject();
|
mCurrentTemp = new JSONObject();
|
||||||
mCurrentTemp.put("temp", "absolute");
|
mCurrentTemp.put("temp", "absolute");
|
||||||
mCurrentTemp.put("duration", MainApp.getConfigBuilder().getTempBasalRemainingMinutesFromHistory());
|
mCurrentTemp.put("duration", tb != null ? tb.getPlannedRemainingMinutes() : 0);
|
||||||
mCurrentTemp.put("rate", MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory());
|
mCurrentTemp.put("rate", tb != null ? tb.tempBasalConvertedToAbsolute(now, profile) : 0d);
|
||||||
|
|
||||||
// as we have non default temps longer than 30 mintues
|
// as we have non default temps longer than 30 mintues
|
||||||
TemporaryBasal tempBasal = MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis());
|
TemporaryBasal tempBasal = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(System.currentTimeMillis());
|
||||||
if (tempBasal != null) {
|
if (tempBasal != null) {
|
||||||
mCurrentTemp.put("minutesrunning", tempBasal.getRealDuration());
|
mCurrentTemp.put("minutesrunning", tempBasal.getRealDuration());
|
||||||
}
|
}
|
||||||
|
@ -248,18 +252,18 @@ public class DetermineBasalAdapterAMAJS {
|
||||||
mMealData.put("boluses", mealData.boluses);
|
mMealData.put("boluses", mealData.boluses);
|
||||||
mMealData.put("mealCOB", mealData.mealCOB);
|
mMealData.put("mealCOB", mealData.mealCOB);
|
||||||
|
|
||||||
if (MainApp.getConfigBuilder().isAMAModeEnabled()) {
|
if (MainApp.getConstraintChecker().isAutosensModeEnabled().value()) {
|
||||||
mAutosensData = new JSONObject();
|
mAutosensData = new JSONObject();
|
||||||
mAutosensData.put("ratio", autosensDataRatio);
|
mAutosensData.put("ratio", autosensDataRatio);
|
||||||
} else {
|
} else {
|
||||||
mAutosensData = null;
|
mAutosensData = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Object makeParam(JSONObject jsonObject, Context rhino, Scriptable scope) {
|
public Object makeParam(JSONObject jsonObject, Context rhino, Scriptable scope) {
|
||||||
|
|
||||||
if(jsonObject == null) return Undefined.instance;
|
if (jsonObject == null) return Undefined.instance;
|
||||||
|
|
||||||
Object param = NativeJSON.parse(rhino, scope, jsonObject.toString(), new Callable() {
|
Object param = NativeJSON.parse(rhino, scope, jsonObject.toString(), new Callable() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -271,8 +275,8 @@ public class DetermineBasalAdapterAMAJS {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object makeParamArray(JSONArray jsonArray, Context rhino, Scriptable scope) {
|
public Object makeParamArray(JSONArray jsonArray, Context rhino, Scriptable scope) {
|
||||||
//Object param = NativeJSON.parse(rhino, scope, "{myarray: " + jsonArray.toString() + " }", new Callable() {
|
//Object param = NativeJSON.parse(rhino, scope, "{myarray: " + jsonArray.toString() + " }", new Callable() {
|
||||||
Object param = NativeJSON.parse(rhino, scope, jsonArray.toString(), new Callable() {
|
Object param = NativeJSON.parse(rhino, scope, jsonArray.toString(), new Callable() {
|
||||||
@Override
|
@Override
|
||||||
public Object call(Context context, Scriptable scriptable, Scriptable scriptable1, Object[] objects) {
|
public Object call(Context context, Scriptable scriptable, Scriptable scriptable1, Object[] objects) {
|
||||||
return objects[1];
|
return objects[1];
|
||||||
|
|
|
@ -22,7 +22,7 @@ public class DetermineBasalResultAMA extends APSResult {
|
||||||
json = j;
|
json = j;
|
||||||
if (result.containsKey("error")) {
|
if (result.containsKey("error")) {
|
||||||
reason = result.get("error").toString();
|
reason = result.get("error").toString();
|
||||||
tempBasalReqested = false;
|
tempBasalRequested = false;
|
||||||
rate = -1;
|
rate = -1;
|
||||||
duration = -1;
|
duration = -1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -32,17 +32,17 @@ public class DetermineBasalResultAMA extends APSResult {
|
||||||
if (result.containsKey("rate")) {
|
if (result.containsKey("rate")) {
|
||||||
rate = (Double) result.get("rate");
|
rate = (Double) result.get("rate");
|
||||||
if (rate < 0d) rate = 0d;
|
if (rate < 0d) rate = 0d;
|
||||||
tempBasalReqested = true;
|
tempBasalRequested = true;
|
||||||
} else {
|
} else {
|
||||||
rate = -1;
|
rate = -1;
|
||||||
tempBasalReqested = false;
|
tempBasalRequested = false;
|
||||||
}
|
}
|
||||||
if (result.containsKey("duration")) {
|
if (result.containsKey("duration")) {
|
||||||
duration = ((Double) result.get("duration")).intValue();
|
duration = ((Double) result.get("duration")).intValue();
|
||||||
//changeRequested as above
|
//changeRequested as above
|
||||||
} else {
|
} else {
|
||||||
duration = -1;
|
duration = -1;
|
||||||
tempBasalReqested = false;
|
tempBasalRequested = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bolusRequested = false;
|
bolusRequested = false;
|
||||||
|
@ -58,7 +58,7 @@ public class DetermineBasalResultAMA extends APSResult {
|
||||||
newResult.reason = reason;
|
newResult.reason = reason;
|
||||||
newResult.rate = rate;
|
newResult.rate = rate;
|
||||||
newResult.duration = duration;
|
newResult.duration = duration;
|
||||||
newResult.tempBasalReqested = tempBasalReqested;
|
newResult.tempBasalRequested = tempBasalRequested;
|
||||||
newResult.rate = rate;
|
newResult.rate = rate;
|
||||||
newResult.duration = duration;
|
newResult.duration = duration;
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,11 @@ import info.nightscout.androidaps.data.IobTotal;
|
||||||
import info.nightscout.androidaps.data.MealData;
|
import info.nightscout.androidaps.data.MealData;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
import info.nightscout.androidaps.db.TempTarget;
|
import info.nightscout.androidaps.db.TempTarget;
|
||||||
|
import info.nightscout.androidaps.db.TemporaryBasal;
|
||||||
import info.nightscout.androidaps.interfaces.APSInterface;
|
import info.nightscout.androidaps.interfaces.APSInterface;
|
||||||
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.interfaces.PumpInterface;
|
||||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||||
import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensResult;
|
import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensResult;
|
||||||
|
@ -25,16 +28,16 @@ import info.nightscout.androidaps.plugins.Loop.APSResult;
|
||||||
import info.nightscout.androidaps.plugins.Loop.ScriptReader;
|
import info.nightscout.androidaps.plugins.Loop.ScriptReader;
|
||||||
import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateGui;
|
import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateGui;
|
||||||
import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateResultGui;
|
import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateResultGui;
|
||||||
|
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.utils.DateUtil;
|
import info.nightscout.utils.DateUtil;
|
||||||
import info.nightscout.utils.HardLimits;
|
import info.nightscout.utils.HardLimits;
|
||||||
import info.nightscout.utils.Profiler;
|
import info.nightscout.utils.Profiler;
|
||||||
import info.nightscout.utils.Round;
|
import info.nightscout.utils.Round;
|
||||||
import info.nightscout.utils.SP;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by mike on 05.08.2016.
|
* Created by mike on 05.08.2016.
|
||||||
*/
|
*/
|
||||||
public class OpenAPSAMAPlugin implements PluginBase, APSInterface {
|
public class OpenAPSAMAPlugin extends PluginBase implements APSInterface {
|
||||||
private static Logger log = LoggerFactory.getLogger(OpenAPSAMAPlugin.class);
|
private static Logger log = LoggerFactory.getLogger(OpenAPSAMAPlugin.class);
|
||||||
|
|
||||||
private static OpenAPSAMAPlugin openAPSAMAPlugin;
|
private static OpenAPSAMAPlugin openAPSAMAPlugin;
|
||||||
|
@ -52,75 +55,26 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface {
|
||||||
DetermineBasalResultAMA lastAPSResult = null;
|
DetermineBasalResultAMA lastAPSResult = null;
|
||||||
AutosensResult lastAutosensResult = null;
|
AutosensResult lastAutosensResult = null;
|
||||||
|
|
||||||
private boolean fragmentEnabled = false;
|
public OpenAPSAMAPlugin() {
|
||||||
private boolean fragmentVisible = false;
|
super(new PluginDescription()
|
||||||
|
.mainType(PluginType.APS)
|
||||||
@Override
|
.fragmentClass(OpenAPSAMAFragment.class.getName())
|
||||||
public String getName() {
|
.pluginName(R.string.openapsama)
|
||||||
return MainApp.instance().getString(R.string.openapsama);
|
.shortName(R.string.oaps_shortname)
|
||||||
|
.preferencesId(R.xml.pref_openapsama)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getNameShort() {
|
public boolean specialEnableCondition() {
|
||||||
String name = MainApp.sResources.getString(R.string.oaps_shortname);
|
PumpInterface pump = ConfigBuilderPlugin.getActivePump();
|
||||||
if (!name.trim().isEmpty()) {
|
return pump == null || pump.getPumpDescription().isTempBasalCapable;
|
||||||
//only if translation exists
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
// use long name as fallback
|
|
||||||
return getName();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnabled(int type) {
|
public boolean specialShowInListCondition() {
|
||||||
boolean pumpCapable = ConfigBuilderPlugin.getActivePump() == null || ConfigBuilderPlugin.getActivePump().getPumpDescription().isTempBasalCapable;
|
PumpInterface pump = ConfigBuilderPlugin.getActivePump();
|
||||||
return type == APS && fragmentEnabled && pumpCapable;
|
return pump == null || pump.getPumpDescription().isTempBasalCapable;
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isVisibleInTabs(int type) {
|
|
||||||
boolean pumpCapable = ConfigBuilderPlugin.getActivePump() == null || ConfigBuilderPlugin.getActivePump().getPumpDescription().isTempBasalCapable;
|
|
||||||
return type == APS && fragmentVisible && pumpCapable;
|
|
||||||
}
|
|
||||||
|
|
||||||
@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 setFragmentVisible(int type, boolean fragmentVisible) {
|
|
||||||
if (type == APS) this.fragmentVisible = fragmentVisible;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getPreferencesId() {
|
|
||||||
return R.xml.pref_openapsama;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setFragmentEnabled(int type, boolean fragmentEnabled) {
|
|
||||||
if (type == APS) this.fragmentEnabled = fragmentEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getType() {
|
|
||||||
return PluginBase.APS;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getFragmentClass() {
|
|
||||||
return OpenAPSAMAFragment.class.getName();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -156,7 +110,7 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isEnabled(PluginBase.APS)) {
|
if (!isEnabled(PluginType.APS)) {
|
||||||
MainApp.bus().post(new EventOpenAPSUpdateResultGui(MainApp.instance().getString(R.string.openapsma_disabled)));
|
MainApp.bus().post(new EventOpenAPSUpdateResultGui(MainApp.instance().getString(R.string.openapsma_disabled)));
|
||||||
if (Config.logAPSResult)
|
if (Config.logAPSResult)
|
||||||
log.debug(MainApp.instance().getString(R.string.openapsma_disabled));
|
log.debug(MainApp.instance().getString(R.string.openapsma_disabled));
|
||||||
|
@ -172,8 +126,7 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface {
|
||||||
|
|
||||||
String units = profile.getUnits();
|
String units = profile.getUnits();
|
||||||
|
|
||||||
double maxIob = SP.getDouble("openapsma_max_iob", 1.5d);
|
double maxBasal = MainApp.getConstraintChecker().getMaxBasalAllowed(profile).value();
|
||||||
double maxBasal = SP.getDouble("openapsma_max_basal", 1d);
|
|
||||||
double minBg = Profile.toMgdl(profile.getTargetLow(), units);
|
double minBg = Profile.toMgdl(profile.getTargetLow(), units);
|
||||||
double maxBg = Profile.toMgdl(profile.getTargetHigh(), units);
|
double maxBg = Profile.toMgdl(profile.getTargetHigh(), units);
|
||||||
double targetBg = Profile.toMgdl(profile.getTarget(), units);
|
double targetBg = Profile.toMgdl(profile.getTarget(), units);
|
||||||
|
@ -187,17 +140,17 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface {
|
||||||
Profiler.log(log, "calculateIobArrayInDia()", startPart);
|
Profiler.log(log, "calculateIobArrayInDia()", startPart);
|
||||||
|
|
||||||
startPart = new Date();
|
startPart = new Date();
|
||||||
MealData mealData = MainApp.getConfigBuilder().getMealData();
|
MealData mealData = TreatmentsPlugin.getPlugin().getMealData();
|
||||||
Profiler.log(log, "getMealData()", startPart);
|
Profiler.log(log, "getMealData()", startPart);
|
||||||
|
|
||||||
maxIob = MainApp.getConfigBuilder().applyMaxIOBConstraints(maxIob);
|
double maxIob = MainApp.getConstraintChecker().getMaxIOBAllowed().value();
|
||||||
|
|
||||||
minBg = HardLimits.verifyHardLimits(minBg, "minBg", HardLimits.VERY_HARD_LIMIT_MIN_BG[0], HardLimits.VERY_HARD_LIMIT_MIN_BG[1]);
|
minBg = HardLimits.verifyHardLimits(minBg, "minBg", HardLimits.VERY_HARD_LIMIT_MIN_BG[0], HardLimits.VERY_HARD_LIMIT_MIN_BG[1]);
|
||||||
maxBg = HardLimits.verifyHardLimits(maxBg, "maxBg", HardLimits.VERY_HARD_LIMIT_MAX_BG[0], HardLimits.VERY_HARD_LIMIT_MAX_BG[1]);
|
maxBg = HardLimits.verifyHardLimits(maxBg, "maxBg", HardLimits.VERY_HARD_LIMIT_MAX_BG[0], HardLimits.VERY_HARD_LIMIT_MAX_BG[1]);
|
||||||
targetBg = HardLimits.verifyHardLimits(targetBg, "targetBg", HardLimits.VERY_HARD_LIMIT_TARGET_BG[0], HardLimits.VERY_HARD_LIMIT_TARGET_BG[1]);
|
targetBg = HardLimits.verifyHardLimits(targetBg, "targetBg", HardLimits.VERY_HARD_LIMIT_TARGET_BG[0], HardLimits.VERY_HARD_LIMIT_TARGET_BG[1]);
|
||||||
|
|
||||||
boolean isTempTarget = false;
|
boolean isTempTarget = false;
|
||||||
TempTarget tempTarget = MainApp.getConfigBuilder().getTempTargetFromHistory(System.currentTimeMillis());
|
TempTarget tempTarget = TreatmentsPlugin.getPlugin().getTempTargetFromHistory(System.currentTimeMillis());
|
||||||
if (tempTarget != null) {
|
if (tempTarget != null) {
|
||||||
isTempTarget = true;
|
isTempTarget = true;
|
||||||
minBg = HardLimits.verifyHardLimits(tempTarget.low, "minBg", HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[1]);
|
minBg = HardLimits.verifyHardLimits(tempTarget.low, "minBg", HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[1]);
|
||||||
|
@ -206,23 +159,20 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
maxIob = HardLimits.verifyHardLimits(maxIob, "maxIob", 0, HardLimits.maxIobAMA());
|
|
||||||
maxBasal = HardLimits.verifyHardLimits(maxBasal, "max_basal", 0.1, HardLimits.maxBasal());
|
|
||||||
|
|
||||||
if (!HardLimits.checkOnlyHardLimits(profile.getDia(), "dia", HardLimits.MINDIA, HardLimits.MAXDIA))
|
if (!HardLimits.checkOnlyHardLimits(profile.getDia(), "dia", HardLimits.MINDIA, HardLimits.MAXDIA))
|
||||||
return;
|
return;
|
||||||
if (!HardLimits.checkOnlyHardLimits(profile.getIc(profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC))
|
if (!HardLimits.checkOnlyHardLimits(profile.getIcTimeFromMidnight(profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC))
|
||||||
return;
|
return;
|
||||||
if (!HardLimits.checkOnlyHardLimits(Profile.toMgdl(profile.getIsf().doubleValue(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF))
|
if (!HardLimits.checkOnlyHardLimits(Profile.toMgdl(profile.getIsf(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF))
|
||||||
return;
|
return;
|
||||||
if (!HardLimits.checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.1, HardLimits.maxBasal()))
|
if (!HardLimits.checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.05, HardLimits.maxBasal()))
|
||||||
return;
|
return;
|
||||||
if (!HardLimits.checkOnlyHardLimits(pump.getBaseBasalRate(), "current_basal", 0.01, HardLimits.maxBasal()))
|
if (!HardLimits.checkOnlyHardLimits(pump.getBaseBasalRate(), "current_basal", 0.01, HardLimits.maxBasal()))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
startPart = new Date();
|
startPart = new Date();
|
||||||
if (MainApp.getConfigBuilder().isAMAModeEnabled()) {
|
if (MainApp.getConstraintChecker().isAutosensModeEnabled().value()) {
|
||||||
lastAutosensResult = IobCobCalculatorPlugin.getPlugin().detectSensitivityWithLock(IobCobCalculatorPlugin.oldestDataAvailable(), System.currentTimeMillis());
|
lastAutosensResult = IobCobCalculatorPlugin.getPlugin().detectSensitivityWithLock(IobCobCalculatorPlugin.getPlugin().oldestDataAvailable(), System.currentTimeMillis());
|
||||||
} else {
|
} else {
|
||||||
lastAutosensResult = new AutosensResult();
|
lastAutosensResult = new AutosensResult();
|
||||||
}
|
}
|
||||||
|
@ -244,16 +194,18 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface {
|
||||||
DetermineBasalResultAMA determineBasalResultAMA = determineBasalAdapterAMAJS.invoke();
|
DetermineBasalResultAMA determineBasalResultAMA = determineBasalAdapterAMAJS.invoke();
|
||||||
Profiler.log(log, "AMA calculation", start);
|
Profiler.log(log, "AMA calculation", start);
|
||||||
// Fix bug determine basal
|
// Fix bug determine basal
|
||||||
if (determineBasalResultAMA.rate == 0d && determineBasalResultAMA.duration == 0 && !MainApp.getConfigBuilder().isTempBasalInProgress())
|
if (determineBasalResultAMA.rate == 0d && determineBasalResultAMA.duration == 0 && !TreatmentsPlugin.getPlugin().isTempBasalInProgress())
|
||||||
determineBasalResultAMA.tempBasalReqested = false;
|
determineBasalResultAMA.tempBasalRequested = false;
|
||||||
// limit requests on openloop mode
|
// limit requests on openloop mode
|
||||||
if (!MainApp.getConfigBuilder().isClosedModeEnabled()) {
|
if (!MainApp.getConstraintChecker().isClosedLoopAllowed().value()) {
|
||||||
if (MainApp.getConfigBuilder().isTempBasalInProgress() && determineBasalResultAMA.rate == 0 && determineBasalResultAMA.duration == 0) {
|
long now = System.currentTimeMillis();
|
||||||
|
TemporaryBasal activeTemp = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(now);
|
||||||
|
if (activeTemp != null && determineBasalResultAMA.rate == 0 && determineBasalResultAMA.duration == 0) {
|
||||||
// going to cancel
|
// going to cancel
|
||||||
} else if (MainApp.getConfigBuilder().isTempBasalInProgress() && Math.abs(determineBasalResultAMA.rate - MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory()) < 0.1) {
|
} else if (activeTemp != null && Math.abs(determineBasalResultAMA.rate - activeTemp.tempBasalConvertedToAbsolute(now, profile)) < 0.1) {
|
||||||
determineBasalResultAMA.tempBasalReqested = false;
|
determineBasalResultAMA.tempBasalRequested = false;
|
||||||
} else if (!MainApp.getConfigBuilder().isTempBasalInProgress() && Math.abs(determineBasalResultAMA.rate - ConfigBuilderPlugin.getActivePump().getBaseBasalRate()) < 0.1)
|
} else if (activeTemp == null && Math.abs(determineBasalResultAMA.rate - ConfigBuilderPlugin.getActivePump().getBaseBasalRate()) < 0.1)
|
||||||
determineBasalResultAMA.tempBasalReqested = false;
|
determineBasalResultAMA.tempBasalRequested = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
determineBasalResultAMA.iob = iobArray[0];
|
determineBasalResultAMA.iob = iobArray[0];
|
||||||
|
|
|
@ -18,12 +18,13 @@ import java.lang.reflect.InvocationTargetException;
|
||||||
|
|
||||||
import info.nightscout.androidaps.Config;
|
import info.nightscout.androidaps.Config;
|
||||||
import info.nightscout.androidaps.Constants;
|
import info.nightscout.androidaps.Constants;
|
||||||
import info.nightscout.androidaps.MainApp;
|
|
||||||
import info.nightscout.androidaps.data.GlucoseStatus;
|
import info.nightscout.androidaps.data.GlucoseStatus;
|
||||||
import info.nightscout.androidaps.data.IobTotal;
|
import info.nightscout.androidaps.data.IobTotal;
|
||||||
import info.nightscout.androidaps.data.MealData;
|
import info.nightscout.androidaps.data.MealData;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
|
import info.nightscout.androidaps.db.TemporaryBasal;
|
||||||
import info.nightscout.androidaps.plugins.Loop.ScriptReader;
|
import info.nightscout.androidaps.plugins.Loop.ScriptReader;
|
||||||
|
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.utils.SP;
|
import info.nightscout.utils.SP;
|
||||||
|
|
||||||
public class DetermineBasalAdapterMAJS {
|
public class DetermineBasalAdapterMAJS {
|
||||||
|
@ -171,7 +172,7 @@ public class DetermineBasalAdapterMAJS {
|
||||||
mProfile.put("max_bg", maxBg);
|
mProfile.put("max_bg", maxBg);
|
||||||
mProfile.put("target_bg", targetBg);
|
mProfile.put("target_bg", targetBg);
|
||||||
mProfile.put("carb_ratio", profile.getIc());
|
mProfile.put("carb_ratio", profile.getIc());
|
||||||
mProfile.put("sens", Profile.toMgdl(profile.getIsf().doubleValue(), units));
|
mProfile.put("sens", Profile.toMgdl(profile.getIsf(), units));
|
||||||
|
|
||||||
mProfile.put("current_basal", basalRate);
|
mProfile.put("current_basal", basalRate);
|
||||||
|
|
||||||
|
@ -179,9 +180,12 @@ public class DetermineBasalAdapterMAJS {
|
||||||
mProfile.put("out_units", "mmol/L");
|
mProfile.put("out_units", "mmol/L");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
TemporaryBasal tb = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(now);
|
||||||
|
|
||||||
mCurrentTemp = new JSONObject();
|
mCurrentTemp = new JSONObject();
|
||||||
mCurrentTemp.put("duration", MainApp.getConfigBuilder().getTempBasalRemainingMinutesFromHistory());
|
mCurrentTemp.put("duration", tb != null ? tb.getPlannedRemainingMinutes() : 0);
|
||||||
mCurrentTemp.put("rate", MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory());
|
mCurrentTemp.put("rate", tb != null ? tb.tempBasalConvertedToAbsolute(now, profile) : 0d);
|
||||||
|
|
||||||
mIobData = new JSONObject();
|
mIobData = new JSONObject();
|
||||||
mIobData.put("iob", iobData.iob); //netIob
|
mIobData.put("iob", iobData.iob); //netIob
|
||||||
|
|
|
@ -20,7 +20,7 @@ public class DetermineBasalResultMA extends APSResult {
|
||||||
json = j;
|
json = j;
|
||||||
if (result.containsKey("error")) {
|
if (result.containsKey("error")) {
|
||||||
reason = (String) result.get("error");
|
reason = (String) result.get("error");
|
||||||
tempBasalReqested = false;
|
tempBasalRequested = false;
|
||||||
rate = -1;
|
rate = -1;
|
||||||
duration = -1;
|
duration = -1;
|
||||||
mealAssist = "";
|
mealAssist = "";
|
||||||
|
@ -31,17 +31,17 @@ public class DetermineBasalResultMA extends APSResult {
|
||||||
if (result.containsKey("rate")) {
|
if (result.containsKey("rate")) {
|
||||||
rate = (Double) result.get("rate");
|
rate = (Double) result.get("rate");
|
||||||
if (rate < 0d) rate = 0d;
|
if (rate < 0d) rate = 0d;
|
||||||
tempBasalReqested = true;
|
tempBasalRequested = true;
|
||||||
} else {
|
} else {
|
||||||
rate = -1;
|
rate = -1;
|
||||||
tempBasalReqested = false;
|
tempBasalRequested = false;
|
||||||
}
|
}
|
||||||
if (result.containsKey("duration")) {
|
if (result.containsKey("duration")) {
|
||||||
duration = ((Double) result.get("duration")).intValue();
|
duration = ((Double) result.get("duration")).intValue();
|
||||||
//changeRequested as above
|
//changeRequested as above
|
||||||
} else {
|
} else {
|
||||||
duration = -1;
|
duration = -1;
|
||||||
tempBasalReqested = false;
|
tempBasalRequested = false;
|
||||||
}
|
}
|
||||||
if (result.containsKey("mealAssist")) {
|
if (result.containsKey("mealAssist")) {
|
||||||
mealAssist = result.get("mealAssist").toString();
|
mealAssist = result.get("mealAssist").toString();
|
||||||
|
@ -58,10 +58,10 @@ public class DetermineBasalResultMA extends APSResult {
|
||||||
newResult.reason = new String(reason);
|
newResult.reason = new String(reason);
|
||||||
newResult.rate = rate;
|
newResult.rate = rate;
|
||||||
newResult.duration = duration;
|
newResult.duration = duration;
|
||||||
newResult.tempBasalReqested = isChangeRequested();
|
newResult.tempBasalRequested = isChangeRequested();
|
||||||
newResult.rate = rate;
|
newResult.rate = rate;
|
||||||
newResult.duration = duration;
|
newResult.duration = duration;
|
||||||
newResult.tempBasalReqested = isChangeRequested();
|
newResult.tempBasalRequested = isChangeRequested();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
newResult.json = new JSONObject(json.toString());
|
newResult.json = new JSONObject(json.toString());
|
||||||
|
|
|
@ -15,20 +15,22 @@ import info.nightscout.androidaps.data.IobTotal;
|
||||||
import info.nightscout.androidaps.data.MealData;
|
import info.nightscout.androidaps.data.MealData;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
import info.nightscout.androidaps.db.TempTarget;
|
import info.nightscout.androidaps.db.TempTarget;
|
||||||
|
import info.nightscout.androidaps.db.TemporaryBasal;
|
||||||
import info.nightscout.androidaps.interfaces.APSInterface;
|
import info.nightscout.androidaps.interfaces.APSInterface;
|
||||||
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.interfaces.PumpInterface;
|
||||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Loop.APSResult;
|
import info.nightscout.androidaps.plugins.Loop.APSResult;
|
||||||
import info.nightscout.androidaps.plugins.Loop.ScriptReader;
|
import info.nightscout.androidaps.plugins.Loop.ScriptReader;
|
||||||
import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateGui;
|
import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateGui;
|
||||||
import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateResultGui;
|
import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateResultGui;
|
||||||
|
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.utils.DateUtil;
|
import info.nightscout.utils.DateUtil;
|
||||||
import info.nightscout.utils.HardLimits;
|
import info.nightscout.utils.HardLimits;
|
||||||
import info.nightscout.utils.Profiler;
|
import info.nightscout.utils.Profiler;
|
||||||
import info.nightscout.utils.Round;
|
import info.nightscout.utils.Round;
|
||||||
import info.nightscout.utils.SP;
|
|
||||||
import info.nightscout.utils.SafeParse;
|
|
||||||
|
|
||||||
import static info.nightscout.utils.HardLimits.checkOnlyHardLimits;
|
import static info.nightscout.utils.HardLimits.checkOnlyHardLimits;
|
||||||
import static info.nightscout.utils.HardLimits.verifyHardLimits;
|
import static info.nightscout.utils.HardLimits.verifyHardLimits;
|
||||||
|
@ -36,7 +38,7 @@ import static info.nightscout.utils.HardLimits.verifyHardLimits;
|
||||||
/**
|
/**
|
||||||
* Created by mike on 05.08.2016.
|
* Created by mike on 05.08.2016.
|
||||||
*/
|
*/
|
||||||
public class OpenAPSMAPlugin implements PluginBase, APSInterface {
|
public class OpenAPSMAPlugin extends PluginBase implements APSInterface {
|
||||||
private static Logger log = LoggerFactory.getLogger(OpenAPSMAPlugin.class);
|
private static Logger log = LoggerFactory.getLogger(OpenAPSMAPlugin.class);
|
||||||
|
|
||||||
private static OpenAPSMAPlugin openAPSMAPlugin;
|
private static OpenAPSMAPlugin openAPSMAPlugin;
|
||||||
|
@ -53,75 +55,26 @@ public class OpenAPSMAPlugin implements PluginBase, APSInterface {
|
||||||
Date lastAPSRun = null;
|
Date lastAPSRun = null;
|
||||||
DetermineBasalResultMA lastAPSResult = null;
|
DetermineBasalResultMA lastAPSResult = null;
|
||||||
|
|
||||||
private boolean fragmentEnabled = false;
|
public OpenAPSMAPlugin() {
|
||||||
private boolean fragmentVisible = false;
|
super(new PluginDescription()
|
||||||
|
.mainType(PluginType.APS)
|
||||||
@Override
|
.fragmentClass(OpenAPSMAFragment.class.getName())
|
||||||
public String getName() {
|
.pluginName(R.string.openapsma)
|
||||||
return MainApp.instance().getString(R.string.openapsma);
|
.shortName(R.string.oaps_shortname)
|
||||||
|
.preferencesId(R.xml.pref_openapsma)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getNameShort() {
|
public boolean specialEnableCondition() {
|
||||||
String name = MainApp.sResources.getString(R.string.oaps_shortname);
|
PumpInterface pump = ConfigBuilderPlugin.getActivePump();
|
||||||
if (!name.trim().isEmpty()) {
|
return pump == null || pump.getPumpDescription().isTempBasalCapable;
|
||||||
//only if translation exists
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
// use long name as fallback
|
|
||||||
return getName();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnabled(int type) {
|
public boolean specialShowInListCondition() {
|
||||||
boolean pumpCapable = ConfigBuilderPlugin.getActivePump() == null || ConfigBuilderPlugin.getActivePump().getPumpDescription().isTempBasalCapable;
|
PumpInterface pump = ConfigBuilderPlugin.getActivePump();
|
||||||
return type == APS && fragmentEnabled && pumpCapable;
|
return pump == null || pump.getPumpDescription().isTempBasalCapable;
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isVisibleInTabs(int type) {
|
|
||||||
boolean pumpCapable = ConfigBuilderPlugin.getActivePump() == null || ConfigBuilderPlugin.getActivePump().getPumpDescription().isTempBasalCapable;
|
|
||||||
return type == APS && fragmentVisible && pumpCapable;
|
|
||||||
}
|
|
||||||
|
|
||||||
@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 setFragmentVisible(int type, boolean fragmentVisible) {
|
|
||||||
if (type == APS) this.fragmentVisible = fragmentVisible;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getPreferencesId() {
|
|
||||||
return R.xml.pref_openapsma;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setFragmentEnabled(int type, boolean fragmentEnabled) {
|
|
||||||
if (type == APS) this.fragmentEnabled = fragmentEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getType() {
|
|
||||||
return PluginBase.APS;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getFragmentClass() {
|
|
||||||
return OpenAPSMAFragment.class.getName();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -157,7 +110,7 @@ public class OpenAPSMAPlugin implements PluginBase, APSInterface {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isEnabled(PluginBase.APS)) {
|
if (!isEnabled(PluginType.APS)) {
|
||||||
MainApp.bus().post(new EventOpenAPSUpdateResultGui(MainApp.instance().getString(R.string.openapsma_disabled)));
|
MainApp.bus().post(new EventOpenAPSUpdateResultGui(MainApp.instance().getString(R.string.openapsma_disabled)));
|
||||||
if (Config.logAPSResult)
|
if (Config.logAPSResult)
|
||||||
log.debug(MainApp.instance().getString(R.string.openapsma_disabled));
|
log.debug(MainApp.instance().getString(R.string.openapsma_disabled));
|
||||||
|
@ -173,10 +126,8 @@ public class OpenAPSMAPlugin implements PluginBase, APSInterface {
|
||||||
|
|
||||||
String units = profile.getUnits();
|
String units = profile.getUnits();
|
||||||
|
|
||||||
Date now = new Date();
|
double maxBasal = MainApp.getConstraintChecker().getMaxBasalAllowed(profile).value();
|
||||||
|
|
||||||
double maxIob = SP.getDouble("openapsma_max_iob", 1.5d);
|
|
||||||
double maxBasal = SafeParse.stringToDouble(SP.getString("openapsma_max_basal", "1"));
|
|
||||||
double minBg = Profile.toMgdl(profile.getTargetLow(), units);
|
double minBg = Profile.toMgdl(profile.getTargetLow(), units);
|
||||||
double maxBg = Profile.toMgdl(profile.getTargetHigh(), units);
|
double maxBg = Profile.toMgdl(profile.getTargetHigh(), units);
|
||||||
double targetBg = Profile.toMgdl(profile.getTarget(), units);
|
double targetBg = Profile.toMgdl(profile.getTarget(), units);
|
||||||
|
@ -185,39 +136,36 @@ public class OpenAPSMAPlugin implements PluginBase, APSInterface {
|
||||||
maxBg = Round.roundTo(maxBg, 0.1d);
|
maxBg = Round.roundTo(maxBg, 0.1d);
|
||||||
|
|
||||||
Date start = new Date();
|
Date start = new Date();
|
||||||
MainApp.getConfigBuilder().updateTotalIOBTreatments();
|
TreatmentsPlugin.getPlugin().updateTotalIOBTreatments();
|
||||||
MainApp.getConfigBuilder().updateTotalIOBTempBasals();
|
TreatmentsPlugin.getPlugin().updateTotalIOBTempBasals();
|
||||||
IobTotal bolusIob = MainApp.getConfigBuilder().getLastCalculationTreatments();
|
IobTotal bolusIob = TreatmentsPlugin.getPlugin().getLastCalculationTreatments();
|
||||||
IobTotal basalIob = MainApp.getConfigBuilder().getLastCalculationTempBasals();
|
IobTotal basalIob = TreatmentsPlugin.getPlugin().getLastCalculationTempBasals();
|
||||||
|
|
||||||
IobTotal iobTotal = IobTotal.combine(bolusIob, basalIob).round();
|
IobTotal iobTotal = IobTotal.combine(bolusIob, basalIob).round();
|
||||||
|
|
||||||
MealData mealData = MainApp.getConfigBuilder().getMealData();
|
MealData mealData = TreatmentsPlugin.getPlugin().getMealData();
|
||||||
|
|
||||||
maxIob = MainApp.getConfigBuilder().applyMaxIOBConstraints(maxIob);
|
double maxIob = MainApp.getConstraintChecker().getMaxIOBAllowed().value();
|
||||||
Profiler.log(log, "MA data gathering", start);
|
Profiler.log(log, "MA data gathering", start);
|
||||||
|
|
||||||
minBg = verifyHardLimits(minBg, "minBg", HardLimits.VERY_HARD_LIMIT_MIN_BG[0], HardLimits.VERY_HARD_LIMIT_MIN_BG[1]);
|
minBg = verifyHardLimits(minBg, "minBg", HardLimits.VERY_HARD_LIMIT_MIN_BG[0], HardLimits.VERY_HARD_LIMIT_MIN_BG[1]);
|
||||||
maxBg = verifyHardLimits(maxBg, "maxBg", HardLimits.VERY_HARD_LIMIT_MAX_BG[0], HardLimits.VERY_HARD_LIMIT_MAX_BG[1]);
|
maxBg = verifyHardLimits(maxBg, "maxBg", HardLimits.VERY_HARD_LIMIT_MAX_BG[0], HardLimits.VERY_HARD_LIMIT_MAX_BG[1]);
|
||||||
targetBg = verifyHardLimits(targetBg, "targetBg", HardLimits.VERY_HARD_LIMIT_TARGET_BG[0], HardLimits.VERY_HARD_LIMIT_TARGET_BG[1]);
|
targetBg = verifyHardLimits(targetBg, "targetBg", HardLimits.VERY_HARD_LIMIT_TARGET_BG[0], HardLimits.VERY_HARD_LIMIT_TARGET_BG[1]);
|
||||||
|
|
||||||
TempTarget tempTarget = MainApp.getConfigBuilder().getTempTargetFromHistory(System.currentTimeMillis());
|
TempTarget tempTarget = TreatmentsPlugin.getPlugin().getTempTargetFromHistory(System.currentTimeMillis());
|
||||||
if (tempTarget != null) {
|
if (tempTarget != null) {
|
||||||
minBg = verifyHardLimits(tempTarget.low, "minBg", HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[1]);
|
minBg = verifyHardLimits(tempTarget.low, "minBg", HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[1]);
|
||||||
maxBg = verifyHardLimits(tempTarget.high, "maxBg", HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[1]);
|
maxBg = verifyHardLimits(tempTarget.high, "maxBg", HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[1]);
|
||||||
targetBg = verifyHardLimits(tempTarget.target(), "targetBg", HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[1]);
|
targetBg = verifyHardLimits(tempTarget.target(), "targetBg", HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
maxIob = verifyHardLimits(maxIob, "maxIob", 0, HardLimits.maxIobAMA());
|
|
||||||
maxBasal = verifyHardLimits(maxBasal, "max_basal", 0.1, HardLimits.maxBasal());
|
|
||||||
|
|
||||||
if (!checkOnlyHardLimits(profile.getDia(), "dia", HardLimits.MINDIA, HardLimits.MAXDIA))
|
if (!checkOnlyHardLimits(profile.getDia(), "dia", HardLimits.MINDIA, HardLimits.MAXDIA))
|
||||||
return;
|
return;
|
||||||
if (!checkOnlyHardLimits(profile.getIc(profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC))
|
if (!checkOnlyHardLimits(profile.getIcTimeFromMidnight(profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC))
|
||||||
return;
|
return;
|
||||||
if (!checkOnlyHardLimits(Profile.toMgdl(profile.getIsf().doubleValue(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF))
|
if (!checkOnlyHardLimits(Profile.toMgdl(profile.getIsf(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF))
|
||||||
return;
|
return;
|
||||||
if (!checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.1, HardLimits.maxBasal()))
|
if (!checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.05, HardLimits.maxBasal()))
|
||||||
return;
|
return;
|
||||||
if (!checkOnlyHardLimits(pump.getBaseBasalRate(), "current_basal", 0.01, HardLimits.maxBasal()))
|
if (!checkOnlyHardLimits(pump.getBaseBasalRate(), "current_basal", 0.01, HardLimits.maxBasal()))
|
||||||
return;
|
return;
|
||||||
|
@ -231,18 +179,21 @@ public class OpenAPSMAPlugin implements PluginBase, APSInterface {
|
||||||
Profiler.log(log, "MA calculation", start);
|
Profiler.log(log, "MA calculation", start);
|
||||||
|
|
||||||
|
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
|
||||||
DetermineBasalResultMA determineBasalResultMA = determineBasalAdapterMAJS.invoke();
|
DetermineBasalResultMA determineBasalResultMA = determineBasalAdapterMAJS.invoke();
|
||||||
// Fix bug determinef basal
|
// Fix bug determinef basal
|
||||||
if (determineBasalResultMA.rate == 0d && determineBasalResultMA.duration == 0 && !MainApp.getConfigBuilder().isTempBasalInProgress())
|
if (determineBasalResultMA.rate == 0d && determineBasalResultMA.duration == 0 && !TreatmentsPlugin.getPlugin().isTempBasalInProgress())
|
||||||
determineBasalResultMA.tempBasalReqested = false;
|
determineBasalResultMA.tempBasalRequested = false;
|
||||||
// limit requests on openloop mode
|
// limit requests on openloop mode
|
||||||
if (!MainApp.getConfigBuilder().isClosedModeEnabled()) {
|
if (!MainApp.getConstraintChecker().isClosedLoopAllowed().value()) {
|
||||||
if (MainApp.getConfigBuilder().isTempBasalInProgress() && determineBasalResultMA.rate == 0 && determineBasalResultMA.duration == 0) {
|
TemporaryBasal activeTemp = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(now);
|
||||||
|
if (activeTemp != null && determineBasalResultMA.rate == 0 && determineBasalResultMA.duration == 0) {
|
||||||
// going to cancel
|
// going to cancel
|
||||||
} else if (MainApp.getConfigBuilder().isTempBasalInProgress() && Math.abs(determineBasalResultMA.rate - MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory()) < 0.1) {
|
} else if (activeTemp != null && Math.abs(determineBasalResultMA.rate - activeTemp.tempBasalConvertedToAbsolute(now, profile)) < 0.1) {
|
||||||
determineBasalResultMA.tempBasalReqested = false;
|
determineBasalResultMA.tempBasalRequested = false;
|
||||||
} else if (!MainApp.getConfigBuilder().isTempBasalInProgress() && Math.abs(determineBasalResultMA.rate - ConfigBuilderPlugin.getActivePump().getBaseBasalRate()) < 0.1)
|
} else if (activeTemp == null && Math.abs(determineBasalResultMA.rate - ConfigBuilderPlugin.getActivePump().getBaseBasalRate()) < 0.1)
|
||||||
determineBasalResultMA.tempBasalReqested = false;
|
determineBasalResultMA.tempBasalRequested = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
determineBasalResultMA.iob = iobTotal;
|
determineBasalResultMA.iob = iobTotal;
|
||||||
|
@ -255,7 +206,7 @@ public class OpenAPSMAPlugin implements PluginBase, APSInterface {
|
||||||
|
|
||||||
lastDetermineBasalAdapterMAJS = determineBasalAdapterMAJS;
|
lastDetermineBasalAdapterMAJS = determineBasalAdapterMAJS;
|
||||||
lastAPSResult = determineBasalResultMA;
|
lastAPSResult = determineBasalResultMA;
|
||||||
lastAPSRun = now;
|
lastAPSRun = new Date(now);
|
||||||
MainApp.bus().post(new EventOpenAPSUpdateGui());
|
MainApp.bus().post(new EventOpenAPSUpdateGui());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,12 +27,10 @@ import info.nightscout.androidaps.data.IobTotal;
|
||||||
import info.nightscout.androidaps.data.MealData;
|
import info.nightscout.androidaps.data.MealData;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
import info.nightscout.androidaps.db.TemporaryBasal;
|
import info.nightscout.androidaps.db.TemporaryBasal;
|
||||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
|
||||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
|
||||||
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
|
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Loop.ScriptReader;
|
import info.nightscout.androidaps.plugins.Loop.ScriptReader;
|
||||||
import info.nightscout.androidaps.plugins.OpenAPSMA.LoggerCallback;
|
import info.nightscout.androidaps.plugins.OpenAPSMA.LoggerCallback;
|
||||||
import info.nightscout.androidaps.plugins.SourceDexcomG5.SourceDexcomG5Plugin;
|
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.utils.SP;
|
import info.nightscout.utils.SP;
|
||||||
import info.nightscout.utils.SafeParse;
|
import info.nightscout.utils.SafeParse;
|
||||||
|
|
||||||
|
@ -48,6 +46,7 @@ public class DetermineBasalAdapterSMBJS {
|
||||||
private JSONObject mCurrentTemp;
|
private JSONObject mCurrentTemp;
|
||||||
private JSONObject mAutosensData = null;
|
private JSONObject mAutosensData = null;
|
||||||
private boolean mMicrobolusAllowed;
|
private boolean mMicrobolusAllowed;
|
||||||
|
private boolean mSMBAlwaysAllowed;
|
||||||
|
|
||||||
private String storedCurrentTemp = null;
|
private String storedCurrentTemp = null;
|
||||||
private String storedIobData = null;
|
private String storedIobData = null;
|
||||||
|
@ -57,6 +56,7 @@ public class DetermineBasalAdapterSMBJS {
|
||||||
private String storedMeal_data = null;
|
private String storedMeal_data = null;
|
||||||
private String storedAutosens_data = null;
|
private String storedAutosens_data = null;
|
||||||
private String storedMicroBolusAllowed = null;
|
private String storedMicroBolusAllowed = null;
|
||||||
|
private String storedSMBAlwaysAllowed = null;
|
||||||
|
|
||||||
private String scriptDebug = "";
|
private String scriptDebug = "";
|
||||||
|
|
||||||
|
@ -84,6 +84,7 @@ public class DetermineBasalAdapterSMBJS {
|
||||||
log.debug("Autosens data: " + (storedAutosens_data = "undefined"));
|
log.debug("Autosens data: " + (storedAutosens_data = "undefined"));
|
||||||
log.debug("Reservoir data: " + "undefined");
|
log.debug("Reservoir data: " + "undefined");
|
||||||
log.debug("MicroBolusAllowed: " + (storedMicroBolusAllowed = "" + mMicrobolusAllowed));
|
log.debug("MicroBolusAllowed: " + (storedMicroBolusAllowed = "" + mMicrobolusAllowed));
|
||||||
|
log.debug("SMBAlwaysAllowed: " + (storedSMBAlwaysAllowed = "" + mSMBAlwaysAllowed));
|
||||||
|
|
||||||
DetermineBasalResultSMB determineBasalResultSMB = null;
|
DetermineBasalResultSMB determineBasalResultSMB = null;
|
||||||
|
|
||||||
|
@ -212,7 +213,8 @@ public class DetermineBasalAdapterSMBJS {
|
||||||
MealData mealData,
|
MealData mealData,
|
||||||
double autosensDataRatio,
|
double autosensDataRatio,
|
||||||
boolean tempTargetSet,
|
boolean tempTargetSet,
|
||||||
boolean microBolusAllowed
|
boolean microBolusAllowed,
|
||||||
|
boolean smbAlwaysAllowed
|
||||||
) throws JSONException {
|
) throws JSONException {
|
||||||
|
|
||||||
String units = profile.getUnits();
|
String units = profile.getUnits();
|
||||||
|
@ -220,7 +222,7 @@ public class DetermineBasalAdapterSMBJS {
|
||||||
mProfile = new JSONObject();
|
mProfile = new JSONObject();
|
||||||
|
|
||||||
mProfile.put("max_iob", maxIob);
|
mProfile.put("max_iob", maxIob);
|
||||||
mProfile.put("dia", profile.getDia());
|
//mProfile.put("dia", profile.getDia());
|
||||||
mProfile.put("type", "current");
|
mProfile.put("type", "current");
|
||||||
mProfile.put("max_daily_basal", profile.getMaxDailyBasal());
|
mProfile.put("max_daily_basal", profile.getMaxDailyBasal());
|
||||||
mProfile.put("max_basal", maxBasal);
|
mProfile.put("max_basal", maxBasal);
|
||||||
|
@ -228,9 +230,9 @@ public class DetermineBasalAdapterSMBJS {
|
||||||
mProfile.put("max_bg", maxBg);
|
mProfile.put("max_bg", maxBg);
|
||||||
mProfile.put("target_bg", targetBg);
|
mProfile.put("target_bg", targetBg);
|
||||||
mProfile.put("carb_ratio", profile.getIc());
|
mProfile.put("carb_ratio", profile.getIc());
|
||||||
mProfile.put("sens", Profile.toMgdl(profile.getIsf().doubleValue(), units));
|
mProfile.put("sens", Profile.toMgdl(profile.getIsf(), units));
|
||||||
mProfile.put("max_daily_safety_multiplier", SP.getInt("openapsama_max_daily_safety_multiplier", 3));
|
mProfile.put("max_daily_safety_multiplier", SP.getInt(R.string.key_openapsama_max_daily_safety_multiplier, 3));
|
||||||
mProfile.put("current_basal_safety_multiplier", SP.getDouble("openapsama_current_basal_safety_multiplier", 4d));
|
mProfile.put("current_basal_safety_multiplier", SP.getDouble(R.string.key_openapsama_current_basal_safety_multiplier, 4d));
|
||||||
|
|
||||||
mProfile.put("high_temptarget_raises_sensitivity", SMBDefaults.high_temptarget_raises_sensitivity);
|
mProfile.put("high_temptarget_raises_sensitivity", SMBDefaults.high_temptarget_raises_sensitivity);
|
||||||
mProfile.put("low_temptarget_lowers_sensitivity", SMBDefaults.low_temptarget_lowers_sensitivity);
|
mProfile.put("low_temptarget_lowers_sensitivity", SMBDefaults.low_temptarget_lowers_sensitivity);
|
||||||
|
@ -242,15 +244,16 @@ public class DetermineBasalAdapterSMBJS {
|
||||||
mProfile.put("maxCOB", SMBDefaults.maxCOB);
|
mProfile.put("maxCOB", SMBDefaults.maxCOB);
|
||||||
mProfile.put("skip_neutral_temps", SMBDefaults.skip_neutral_temps);
|
mProfile.put("skip_neutral_temps", SMBDefaults.skip_neutral_temps);
|
||||||
//TODO: align with max-absorption model in AMA sensitivity
|
//TODO: align with max-absorption model in AMA sensitivity
|
||||||
mProfile.put("min_5m_carbimpact", SP.getDouble("openapsama_min_5m_carbimpact", SMBDefaults.min_5m_carbimpact));;
|
mProfile.put("min_5m_carbimpact", SP.getDouble("openapsama_min_5m_carbimpact", SMBDefaults.min_5m_carbimpact));
|
||||||
|
;
|
||||||
mProfile.put("remainingCarbsCap", SMBDefaults.remainingCarbsCap);
|
mProfile.put("remainingCarbsCap", SMBDefaults.remainingCarbsCap);
|
||||||
mProfile.put("enableUAM", SP.getBoolean(R.string.key_use_uam, false));
|
mProfile.put("enableUAM", SP.getBoolean(R.string.key_use_uam, false));
|
||||||
mProfile.put("A52_risk_enable", SMBDefaults.A52_risk_enable);
|
mProfile.put("A52_risk_enable", SMBDefaults.A52_risk_enable);
|
||||||
mProfile.put("enableSMB_with_COB", SP.getBoolean(R.string.key_use_smb, false) && SP.getBoolean(R.string.key_enableSMB_with_COB, false));
|
mProfile.put("enableSMB_with_COB", SP.getBoolean(R.string.key_enableSMB_with_COB, false));
|
||||||
mProfile.put("enableSMB_with_temptarget", SP.getBoolean(R.string.key_use_smb, false) && SP.getBoolean(R.string.key_enableSMB_with_temptarget, false));
|
mProfile.put("enableSMB_with_temptarget", SP.getBoolean(R.string.key_enableSMB_with_temptarget, false));
|
||||||
mProfile.put("allowSMB_with_high_temptarget", SP.getBoolean(R.string.key_use_smb, false) && SP.getBoolean(R.string.key_allowSMB_with_high_temptarget, false));
|
mProfile.put("allowSMB_with_high_temptarget", SP.getBoolean(R.string.key_allowSMB_with_high_temptarget, false));
|
||||||
mProfile.put("enableSMB_always", SP.getBoolean(R.string.key_use_smb, false) && SP.getBoolean(R.string.key_enableSMB_always, false) && ConfigBuilderPlugin.getActiveBgSource().advancedFilteringSupported());
|
mProfile.put("enableSMB_always", SP.getBoolean(R.string.key_enableSMB_always, false) && smbAlwaysAllowed);
|
||||||
mProfile.put("enableSMB_after_carbs", SP.getBoolean(R.string.key_use_smb, false) && SP.getBoolean(R.string.key_enableSMB_after_carbs, false) && ConfigBuilderPlugin.getActiveBgSource().advancedFilteringSupported());
|
mProfile.put("enableSMB_after_carbs", SP.getBoolean(R.string.key_enableSMB_after_carbs, false) && smbAlwaysAllowed);
|
||||||
mProfile.put("maxSMBBasalMinutes", SP.getInt("key_smbmaxminutes", SMBDefaults.maxSMBBasalMinutes));
|
mProfile.put("maxSMBBasalMinutes", SP.getInt("key_smbmaxminutes", SMBDefaults.maxSMBBasalMinutes));
|
||||||
mProfile.put("carbsReqThreshold", SMBDefaults.carbsReqThreshold);
|
mProfile.put("carbsReqThreshold", SMBDefaults.carbsReqThreshold);
|
||||||
|
|
||||||
|
@ -263,13 +266,16 @@ public class DetermineBasalAdapterSMBJS {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
TemporaryBasal tb = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(now);
|
||||||
|
|
||||||
mCurrentTemp = new JSONObject();
|
mCurrentTemp = new JSONObject();
|
||||||
mCurrentTemp.put("temp", "absolute");
|
mCurrentTemp.put("temp", "absolute");
|
||||||
mCurrentTemp.put("duration", MainApp.getConfigBuilder().getTempBasalRemainingMinutesFromHistory());
|
mCurrentTemp.put("duration", tb != null ? tb.getPlannedRemainingMinutes() : 0);
|
||||||
mCurrentTemp.put("rate", MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory());
|
mCurrentTemp.put("rate", tb != null ? tb.tempBasalConvertedToAbsolute(now, profile) : 0d);
|
||||||
|
|
||||||
// as we have non default temps longer than 30 mintues
|
// as we have non default temps longer than 30 mintues
|
||||||
TemporaryBasal tempBasal = MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis());
|
TemporaryBasal tempBasal = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(System.currentTimeMillis());
|
||||||
if (tempBasal != null) {
|
if (tempBasal != null) {
|
||||||
mCurrentTemp.put("minutesrunning", tempBasal.getRealDuration());
|
mCurrentTemp.put("minutesrunning", tempBasal.getRealDuration());
|
||||||
}
|
}
|
||||||
|
@ -298,7 +304,7 @@ public class DetermineBasalAdapterSMBJS {
|
||||||
mMealData.put("lastCarbTime", mealData.lastCarbTime);
|
mMealData.put("lastCarbTime", mealData.lastCarbTime);
|
||||||
|
|
||||||
|
|
||||||
if (MainApp.getConfigBuilder().isAMAModeEnabled()) {
|
if (MainApp.getConstraintChecker().isAutosensModeEnabled().value()) {
|
||||||
mAutosensData = new JSONObject();
|
mAutosensData = new JSONObject();
|
||||||
mAutosensData.put("ratio", autosensDataRatio);
|
mAutosensData.put("ratio", autosensDataRatio);
|
||||||
} else {
|
} else {
|
||||||
|
@ -306,6 +312,7 @@ public class DetermineBasalAdapterSMBJS {
|
||||||
mAutosensData.put("ratio", 1.0);
|
mAutosensData.put("ratio", 1.0);
|
||||||
}
|
}
|
||||||
mMicrobolusAllowed = microBolusAllowed;
|
mMicrobolusAllowed = microBolusAllowed;
|
||||||
|
mSMBAlwaysAllowed = smbAlwaysAllowed;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ public class DetermineBasalResultSMB extends APSResult {
|
||||||
if (result.has("carbsReq")) carbsReq = result.getDouble("carbsReq");
|
if (result.has("carbsReq")) carbsReq = result.getDouble("carbsReq");
|
||||||
|
|
||||||
if (result.has("rate") && result.has("duration")) {
|
if (result.has("rate") && result.has("duration")) {
|
||||||
tempBasalReqested = true;
|
tempBasalRequested = true;
|
||||||
rate = result.getDouble("rate");
|
rate = result.getDouble("rate");
|
||||||
if (rate < 0d) rate = 0d;
|
if (rate < 0d) rate = 0d;
|
||||||
duration = result.getInt("duration");
|
duration = result.getInt("duration");
|
||||||
|
@ -74,7 +74,7 @@ public class DetermineBasalResultSMB extends APSResult {
|
||||||
newResult.reason = reason;
|
newResult.reason = reason;
|
||||||
newResult.rate = rate;
|
newResult.rate = rate;
|
||||||
newResult.duration = duration;
|
newResult.duration = duration;
|
||||||
newResult.tempBasalReqested = tempBasalReqested;
|
newResult.tempBasalRequested = tempBasalRequested;
|
||||||
newResult.bolusRequested = bolusRequested;
|
newResult.bolusRequested = bolusRequested;
|
||||||
newResult.rate = rate;
|
newResult.rate = rate;
|
||||||
newResult.duration = duration;
|
newResult.duration = duration;
|
||||||
|
|
|
@ -16,6 +16,9 @@ import org.json.JSONException;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import butterknife.BindView;
|
||||||
|
import butterknife.ButterKnife;
|
||||||
|
import butterknife.OnClick;
|
||||||
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.Common.SubscriberFragment;
|
||||||
|
@ -24,19 +27,32 @@ import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateRes
|
||||||
import info.nightscout.utils.FabricPrivacy;
|
import info.nightscout.utils.FabricPrivacy;
|
||||||
import info.nightscout.utils.JSONFormatter;
|
import info.nightscout.utils.JSONFormatter;
|
||||||
|
|
||||||
public class OpenAPSSMBFragment extends SubscriberFragment implements View.OnClickListener {
|
public class OpenAPSSMBFragment extends SubscriberFragment {
|
||||||
private static Logger log = LoggerFactory.getLogger(OpenAPSSMBFragment.class);
|
private static Logger log = LoggerFactory.getLogger(OpenAPSSMBFragment.class);
|
||||||
|
|
||||||
|
@BindView(R.id.openapsma_run)
|
||||||
Button run;
|
Button run;
|
||||||
|
@BindView(R.id.openapsma_lastrun)
|
||||||
TextView lastRunView;
|
TextView lastRunView;
|
||||||
|
@BindView(R.id.openapsma_constraints)
|
||||||
|
TextView constraintsView;
|
||||||
|
@BindView(R.id.openapsma_glucosestatus)
|
||||||
TextView glucoseStatusView;
|
TextView glucoseStatusView;
|
||||||
|
@BindView(R.id.openapsma_currenttemp)
|
||||||
TextView currentTempView;
|
TextView currentTempView;
|
||||||
|
@BindView(R.id.openapsma_iobdata)
|
||||||
TextView iobDataView;
|
TextView iobDataView;
|
||||||
|
@BindView(R.id.openapsma_profile)
|
||||||
TextView profileView;
|
TextView profileView;
|
||||||
|
@BindView(R.id.openapsma_mealdata)
|
||||||
TextView mealDataView;
|
TextView mealDataView;
|
||||||
|
@BindView(R.id.openapsma_autosensdata)
|
||||||
TextView autosensDataView;
|
TextView autosensDataView;
|
||||||
|
@BindView(R.id.openapsma_result)
|
||||||
TextView resultView;
|
TextView resultView;
|
||||||
|
@BindView(R.id.openapsma_scriptdebugdata)
|
||||||
TextView scriptdebugView;
|
TextView scriptdebugView;
|
||||||
|
@BindView(R.id.openapsma_request)
|
||||||
TextView requestView;
|
TextView requestView;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -44,32 +60,14 @@ public class OpenAPSSMBFragment extends SubscriberFragment implements View.OnCli
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
View view = inflater.inflate(R.layout.openapsama_fragment, container, false);
|
View view = inflater.inflate(R.layout.openapsama_fragment, container, false);
|
||||||
|
|
||||||
run = (Button) view.findViewById(R.id.openapsma_run);
|
unbinder = ButterKnife.bind(this, view);
|
||||||
run.setOnClickListener(this);
|
|
||||||
lastRunView = (TextView) view.findViewById(R.id.openapsma_lastrun);
|
|
||||||
glucoseStatusView = (TextView) view.findViewById(R.id.openapsma_glucosestatus);
|
|
||||||
currentTempView = (TextView) view.findViewById(R.id.openapsma_currenttemp);
|
|
||||||
iobDataView = (TextView) view.findViewById(R.id.openapsma_iobdata);
|
|
||||||
profileView = (TextView) view.findViewById(R.id.openapsma_profile);
|
|
||||||
mealDataView = (TextView) view.findViewById(R.id.openapsma_mealdata);
|
|
||||||
autosensDataView = (TextView) view.findViewById(R.id.openapsma_autosensdata);
|
|
||||||
scriptdebugView = (TextView) view.findViewById(R.id.openapsma_scriptdebugdata);
|
|
||||||
resultView = (TextView) view.findViewById(R.id.openapsma_result);
|
|
||||||
requestView = (TextView) view.findViewById(R.id.openapsma_request);
|
|
||||||
|
|
||||||
updateGUI();
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@OnClick(R.id.openapsma_run)
|
||||||
public void onClick(View view) {
|
public void onRunClick() {
|
||||||
switch (view.getId()) {
|
OpenAPSSMBPlugin.getPlugin().invoke("OpenAPSSMB button");
|
||||||
case R.id.openapsma_run:
|
FabricPrivacy.getInstance().logCustom(new CustomEvent("OpenAPS_SMB_Run"));
|
||||||
OpenAPSSMBPlugin.getPlugin().invoke("OpenAPSSMB button");
|
|
||||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("OpenAPS_SMB_Run"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
|
@ -97,24 +95,26 @@ public class OpenAPSSMBFragment extends SubscriberFragment implements View.OnCli
|
||||||
}
|
}
|
||||||
DetermineBasalAdapterSMBJS determineBasalAdapterSMBJS = plugin.lastDetermineBasalAdapterSMBJS;
|
DetermineBasalAdapterSMBJS determineBasalAdapterSMBJS = plugin.lastDetermineBasalAdapterSMBJS;
|
||||||
if (determineBasalAdapterSMBJS != null) {
|
if (determineBasalAdapterSMBJS != null) {
|
||||||
glucoseStatusView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getGlucoseStatusParam()));
|
glucoseStatusView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getGlucoseStatusParam()).toString().trim());
|
||||||
currentTempView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getCurrentTempParam()));
|
currentTempView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getCurrentTempParam()).toString().trim());
|
||||||
try {
|
try {
|
||||||
JSONArray iobArray = new JSONArray(determineBasalAdapterSMBJS.getIobDataParam());
|
JSONArray iobArray = new JSONArray(determineBasalAdapterSMBJS.getIobDataParam());
|
||||||
iobDataView.setText(String.format(MainApp.sResources.getString(R.string.array_of_elements), iobArray.length()) + "\n" + JSONFormatter.format(iobArray.getString(0)));
|
iobDataView.setText((String.format(MainApp.sResources.getString(R.string.array_of_elements), iobArray.length()) + "\n" + JSONFormatter.format(iobArray.getString(0))).trim());
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
iobDataView.setText("JSONException");
|
iobDataView.setText("JSONException see log for details");
|
||||||
}
|
}
|
||||||
profileView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getProfileParam()));
|
profileView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getProfileParam()).toString().trim());
|
||||||
mealDataView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getMealDataParam()));
|
mealDataView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getMealDataParam()).toString().trim());
|
||||||
scriptdebugView.setText(determineBasalAdapterSMBJS.getScriptDebug());
|
scriptdebugView.setText(determineBasalAdapterSMBJS.getScriptDebug().trim());
|
||||||
|
if (lastAPSResult != null && lastAPSResult.inputConstraints != null)
|
||||||
|
constraintsView.setText(lastAPSResult.inputConstraints.getReasons().trim());
|
||||||
}
|
}
|
||||||
if (plugin.lastAPSRun != null) {
|
if (plugin.lastAPSRun != null) {
|
||||||
lastRunView.setText(plugin.lastAPSRun.toLocaleString());
|
lastRunView.setText(plugin.lastAPSRun.toLocaleString().trim());
|
||||||
}
|
}
|
||||||
if (plugin.lastAutosensResult != null) {
|
if (plugin.lastAutosensResult != null) {
|
||||||
autosensDataView.setText(JSONFormatter.format(plugin.lastAutosensResult.json()));
|
autosensDataView.setText(JSONFormatter.format(plugin.lastAutosensResult.json()).toString().trim());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -15,8 +15,12 @@ import info.nightscout.androidaps.data.IobTotal;
|
||||||
import info.nightscout.androidaps.data.MealData;
|
import info.nightscout.androidaps.data.MealData;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
import info.nightscout.androidaps.db.TempTarget;
|
import info.nightscout.androidaps.db.TempTarget;
|
||||||
|
import info.nightscout.androidaps.db.TemporaryBasal;
|
||||||
import info.nightscout.androidaps.interfaces.APSInterface;
|
import info.nightscout.androidaps.interfaces.APSInterface;
|
||||||
|
import info.nightscout.androidaps.interfaces.Constraint;
|
||||||
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.interfaces.PumpInterface;
|
||||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||||
import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensResult;
|
import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensResult;
|
||||||
|
@ -25,34 +29,22 @@ import info.nightscout.androidaps.plugins.Loop.APSResult;
|
||||||
import info.nightscout.androidaps.plugins.Loop.ScriptReader;
|
import info.nightscout.androidaps.plugins.Loop.ScriptReader;
|
||||||
import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateGui;
|
import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateGui;
|
||||||
import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateResultGui;
|
import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateResultGui;
|
||||||
|
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.utils.DateUtil;
|
import info.nightscout.utils.DateUtil;
|
||||||
import info.nightscout.utils.HardLimits;
|
import info.nightscout.utils.HardLimits;
|
||||||
import info.nightscout.utils.NSUpload;
|
import info.nightscout.utils.NSUpload;
|
||||||
import info.nightscout.utils.Profiler;
|
import info.nightscout.utils.Profiler;
|
||||||
import info.nightscout.utils.Round;
|
import info.nightscout.utils.Round;
|
||||||
import info.nightscout.utils.SP;
|
|
||||||
import info.nightscout.utils.ToastUtils;
|
import info.nightscout.utils.ToastUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by mike on 05.08.2016.
|
* Created by mike on 05.08.2016.
|
||||||
*/
|
*/
|
||||||
public class OpenAPSSMBPlugin implements PluginBase, APSInterface {
|
public class OpenAPSSMBPlugin extends PluginBase implements APSInterface {
|
||||||
private static Logger log = LoggerFactory.getLogger(OpenAPSSMBPlugin.class);
|
private static Logger log = LoggerFactory.getLogger(OpenAPSSMBPlugin.class);
|
||||||
|
|
||||||
// last values
|
|
||||||
DetermineBasalAdapterSMBJS lastDetermineBasalAdapterSMBJS = null;
|
|
||||||
Date lastAPSRun = null;
|
|
||||||
DetermineBasalResultSMB lastAPSResult = null;
|
|
||||||
AutosensResult lastAutosensResult = null;
|
|
||||||
|
|
||||||
boolean fragmentEnabled = false;
|
|
||||||
boolean fragmentVisible = true;
|
|
||||||
|
|
||||||
private static OpenAPSSMBPlugin openAPSSMBPlugin;
|
private static OpenAPSSMBPlugin openAPSSMBPlugin;
|
||||||
|
|
||||||
private OpenAPSSMBPlugin() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static OpenAPSSMBPlugin getPlugin() {
|
public static OpenAPSSMBPlugin getPlugin() {
|
||||||
if (openAPSSMBPlugin == null) {
|
if (openAPSSMBPlugin == null) {
|
||||||
openAPSSMBPlugin = new OpenAPSSMBPlugin();
|
openAPSSMBPlugin = new OpenAPSSMBPlugin();
|
||||||
|
@ -60,72 +52,32 @@ public class OpenAPSSMBPlugin implements PluginBase, APSInterface {
|
||||||
return openAPSSMBPlugin;
|
return openAPSSMBPlugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// last values
|
||||||
public String getName() {
|
DetermineBasalAdapterSMBJS lastDetermineBasalAdapterSMBJS = null;
|
||||||
return MainApp.instance().getString(R.string.openapssmb);
|
Date lastAPSRun = null;
|
||||||
|
DetermineBasalResultSMB lastAPSResult = null;
|
||||||
|
AutosensResult lastAutosensResult = null;
|
||||||
|
|
||||||
|
private OpenAPSSMBPlugin() {
|
||||||
|
super(new PluginDescription()
|
||||||
|
.mainType(PluginType.APS)
|
||||||
|
.fragmentClass(OpenAPSSMBFragment.class.getName())
|
||||||
|
.pluginName(R.string.openapssmb)
|
||||||
|
.shortName(R.string.smb_shortname)
|
||||||
|
.preferencesId(R.xml.pref_openapssmb)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getNameShort() {
|
public boolean specialEnableCondition() {
|
||||||
String name = MainApp.sResources.getString(R.string.smb_shortname);
|
PumpInterface pump = ConfigBuilderPlugin.getActivePump();
|
||||||
if (!name.trim().isEmpty()) {
|
return pump == null || pump.getPumpDescription().isTempBasalCapable;
|
||||||
//only if translation exists
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
// use long name as fallback
|
|
||||||
return getName();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnabled(int type) {
|
public boolean specialShowInListCondition() {
|
||||||
boolean pumpCapable = ConfigBuilderPlugin.getActivePump() == null || ConfigBuilderPlugin.getActivePump().getPumpDescription().isTempBasalCapable;
|
PumpInterface pump = ConfigBuilderPlugin.getActivePump();
|
||||||
return type == APS && fragmentEnabled && pumpCapable;
|
return pump == null || pump.getPumpDescription().isTempBasalCapable;
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isVisibleInTabs(int type) {
|
|
||||||
boolean pumpCapable = ConfigBuilderPlugin.getActivePump() == null || ConfigBuilderPlugin.getActivePump().getPumpDescription().isTempBasalCapable;
|
|
||||||
return type == APS && fragmentVisible && pumpCapable;
|
|
||||||
}
|
|
||||||
|
|
||||||
@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 setFragmentVisible(int type, boolean fragmentVisible) {
|
|
||||||
if (type == APS) this.fragmentVisible = fragmentVisible;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getPreferencesId() {
|
|
||||||
return R.xml.pref_openapssmb;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setFragmentEnabled(int type, boolean fragmentEnabled) {
|
|
||||||
if (type == APS) this.fragmentEnabled = fragmentEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getType() {
|
|
||||||
return PluginBase.APS;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getFragmentClass() {
|
|
||||||
return OpenAPSSMBFragment.class.getName();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -161,7 +113,7 @@ public class OpenAPSSMBPlugin implements PluginBase, APSInterface {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isEnabled(PluginBase.APS)) {
|
if (!isEnabled(PluginType.APS)) {
|
||||||
MainApp.bus().post(new EventOpenAPSUpdateResultGui(MainApp.instance().getString(R.string.openapsma_disabled)));
|
MainApp.bus().post(new EventOpenAPSUpdateResultGui(MainApp.instance().getString(R.string.openapsma_disabled)));
|
||||||
if (Config.logAPSResult)
|
if (Config.logAPSResult)
|
||||||
log.debug(MainApp.instance().getString(R.string.openapsma_disabled));
|
log.debug(MainApp.instance().getString(R.string.openapsma_disabled));
|
||||||
|
@ -177,8 +129,11 @@ public class OpenAPSSMBPlugin implements PluginBase, APSInterface {
|
||||||
|
|
||||||
String units = profile.getUnits();
|
String units = profile.getUnits();
|
||||||
|
|
||||||
double maxIob = SP.getDouble("openapsma_max_iob", 1.5d);
|
Constraint<Double> inputConstraints = new Constraint<>(0d); // fake. only for collecting all results
|
||||||
double maxBasal = SP.getDouble("openapsma_max_basal", 1d);
|
|
||||||
|
Constraint<Double> maxBasalConstraint = MainApp.getConstraintChecker().getMaxBasalAllowed(profile);
|
||||||
|
inputConstraints.copyReasons(maxBasalConstraint);
|
||||||
|
double maxBasal = maxBasalConstraint.value();
|
||||||
double minBg = Profile.toMgdl(profile.getTargetLow(), units);
|
double minBg = Profile.toMgdl(profile.getTargetLow(), units);
|
||||||
double maxBg = Profile.toMgdl(profile.getTargetHigh(), units);
|
double maxBg = Profile.toMgdl(profile.getTargetHigh(), units);
|
||||||
double targetBg = Profile.toMgdl(profile.getTarget(), units);
|
double targetBg = Profile.toMgdl(profile.getTarget(), units);
|
||||||
|
@ -192,17 +147,17 @@ public class OpenAPSSMBPlugin implements PluginBase, APSInterface {
|
||||||
Profiler.log(log, "calculateIobArrayInDia()", startPart);
|
Profiler.log(log, "calculateIobArrayInDia()", startPart);
|
||||||
|
|
||||||
startPart = new Date();
|
startPart = new Date();
|
||||||
MealData mealData = MainApp.getConfigBuilder().getMealData();
|
MealData mealData = TreatmentsPlugin.getPlugin().getMealData();
|
||||||
Profiler.log(log, "getMealData()", startPart);
|
Profiler.log(log, "getMealData()", startPart);
|
||||||
|
|
||||||
maxIob = MainApp.getConfigBuilder().applyMaxIOBConstraints(maxIob);
|
double maxIob = MainApp.getConstraintChecker().getMaxIOBAllowed().value();
|
||||||
|
|
||||||
minBg = verifyHardLimits(minBg, "minBg", HardLimits.VERY_HARD_LIMIT_MIN_BG[0], HardLimits.VERY_HARD_LIMIT_MIN_BG[1]);
|
minBg = verifyHardLimits(minBg, "minBg", HardLimits.VERY_HARD_LIMIT_MIN_BG[0], HardLimits.VERY_HARD_LIMIT_MIN_BG[1]);
|
||||||
maxBg = verifyHardLimits(maxBg, "maxBg", HardLimits.VERY_HARD_LIMIT_MAX_BG[0], HardLimits.VERY_HARD_LIMIT_MAX_BG[1]);
|
maxBg = verifyHardLimits(maxBg, "maxBg", HardLimits.VERY_HARD_LIMIT_MAX_BG[0], HardLimits.VERY_HARD_LIMIT_MAX_BG[1]);
|
||||||
targetBg = verifyHardLimits(targetBg, "targetBg", HardLimits.VERY_HARD_LIMIT_TARGET_BG[0], HardLimits.VERY_HARD_LIMIT_TARGET_BG[1]);
|
targetBg = verifyHardLimits(targetBg, "targetBg", HardLimits.VERY_HARD_LIMIT_TARGET_BG[0], HardLimits.VERY_HARD_LIMIT_TARGET_BG[1]);
|
||||||
|
|
||||||
boolean isTempTarget = false;
|
boolean isTempTarget = false;
|
||||||
TempTarget tempTarget = MainApp.getConfigBuilder().getTempTargetFromHistory(System.currentTimeMillis());
|
TempTarget tempTarget = TreatmentsPlugin.getPlugin().getTempTargetFromHistory(System.currentTimeMillis());
|
||||||
if (tempTarget != null) {
|
if (tempTarget != null) {
|
||||||
isTempTarget = true;
|
isTempTarget = true;
|
||||||
minBg = verifyHardLimits(tempTarget.low, "minBg", HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[1]);
|
minBg = verifyHardLimits(tempTarget.low, "minBg", HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[1]);
|
||||||
|
@ -211,23 +166,32 @@ public class OpenAPSSMBPlugin implements PluginBase, APSInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
maxIob = verifyHardLimits(maxIob, "maxIob", 0, HardLimits.maxIobSMB());
|
if (!checkOnlyHardLimits(profile.getDia(), "dia", HardLimits.MINDIA, HardLimits.MAXDIA))
|
||||||
maxBasal = verifyHardLimits(maxBasal, "max_basal", 0.1, HardLimits.maxBasal());
|
|
||||||
|
|
||||||
if (!checkOnlyHardLimits(profile.getDia(), "dia", HardLimits.MINDIA, HardLimits.MAXDIA)) return;
|
|
||||||
if (!checkOnlyHardLimits(profile.getIc(profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC))
|
|
||||||
return;
|
return;
|
||||||
if (!checkOnlyHardLimits(Profile.toMgdl(profile.getIsf().doubleValue(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF))
|
if (!checkOnlyHardLimits(profile.getIcTimeFromMidnight(profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC))
|
||||||
|
return;
|
||||||
|
if (!checkOnlyHardLimits(Profile.toMgdl(profile.getIsf(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF))
|
||||||
|
return;
|
||||||
|
if (!checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.05, HardLimits.maxBasal()))
|
||||||
|
return;
|
||||||
|
if (!checkOnlyHardLimits(pump.getBaseBasalRate(), "current_basal", 0.01, HardLimits.maxBasal()))
|
||||||
return;
|
return;
|
||||||
if (!checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.1, HardLimits.maxBasal())) return;
|
|
||||||
if (!checkOnlyHardLimits(pump.getBaseBasalRate(), "current_basal", 0.01, HardLimits.maxBasal())) return;
|
|
||||||
|
|
||||||
startPart = new Date();
|
startPart = new Date();
|
||||||
if (MainApp.getConfigBuilder().isAMAModeEnabled()) {
|
if (MainApp.getConstraintChecker().isAutosensModeEnabled().value()) {
|
||||||
lastAutosensResult = IobCobCalculatorPlugin.getPlugin().detectSensitivityWithLock(IobCobCalculatorPlugin.oldestDataAvailable(), System.currentTimeMillis());
|
lastAutosensResult = IobCobCalculatorPlugin.getPlugin().detectSensitivityWithLock(IobCobCalculatorPlugin.getPlugin().oldestDataAvailable(), System.currentTimeMillis());
|
||||||
} else {
|
} else {
|
||||||
lastAutosensResult = new AutosensResult();
|
lastAutosensResult = new AutosensResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Constraint<Boolean> smbAllowed = new Constraint<>(true);
|
||||||
|
MainApp.getConstraintChecker().isSMBModeEnabled(smbAllowed);
|
||||||
|
inputConstraints.copyReasons(smbAllowed);
|
||||||
|
|
||||||
|
Constraint<Boolean> smbAlwaysEnabled = new Constraint<>(true);
|
||||||
|
MainApp.getConstraintChecker().isAdvancedFilteringEnabled(smbAlwaysEnabled);
|
||||||
|
inputConstraints.copyReasons(smbAlwaysEnabled);
|
||||||
|
|
||||||
Profiler.log(log, "detectSensitivityandCarbAbsorption()", startPart);
|
Profiler.log(log, "detectSensitivityandCarbAbsorption()", startPart);
|
||||||
Profiler.log(log, "SMB data gathering", start);
|
Profiler.log(log, "SMB data gathering", start);
|
||||||
|
|
||||||
|
@ -236,33 +200,34 @@ public class OpenAPSSMBPlugin implements PluginBase, APSInterface {
|
||||||
determineBasalAdapterSMBJS.setData(profile, maxIob, maxBasal, minBg, maxBg, targetBg, ConfigBuilderPlugin.getActivePump().getBaseBasalRate(), iobArray, glucoseStatus, mealData,
|
determineBasalAdapterSMBJS.setData(profile, maxIob, maxBasal, minBg, maxBg, targetBg, ConfigBuilderPlugin.getActivePump().getBaseBasalRate(), iobArray, glucoseStatus, mealData,
|
||||||
lastAutosensResult.ratio, //autosensDataRatio
|
lastAutosensResult.ratio, //autosensDataRatio
|
||||||
isTempTarget,
|
isTempTarget,
|
||||||
true //microBolusAllowed
|
smbAllowed.value(),
|
||||||
|
smbAlwaysEnabled.value()
|
||||||
);
|
);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
log.error(e.getMessage());
|
log.error(e.getMessage());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
|
||||||
DetermineBasalResultSMB determineBasalResultSMB = determineBasalAdapterSMBJS.invoke();
|
DetermineBasalResultSMB determineBasalResultSMB = determineBasalAdapterSMBJS.invoke();
|
||||||
Profiler.log(log, "SMB calculation", start);
|
Profiler.log(log, "SMB calculation", start);
|
||||||
// TODO still needed with oref1?
|
// TODO still needed with oref1?
|
||||||
// Fix bug determine basal
|
// Fix bug determine basal
|
||||||
if (determineBasalResultSMB.rate == 0d && determineBasalResultSMB.duration == 0 && !MainApp.getConfigBuilder().isTempBasalInProgress())
|
if (determineBasalResultSMB.rate == 0d && determineBasalResultSMB.duration == 0 && !TreatmentsPlugin.getPlugin().isTempBasalInProgress())
|
||||||
determineBasalResultSMB.tempBasalReqested = false;
|
determineBasalResultSMB.tempBasalRequested = false;
|
||||||
// limit requests on openloop mode
|
// limit requests on openloop mode
|
||||||
if (!MainApp.getConfigBuilder().isClosedModeEnabled()) {
|
if (!MainApp.getConstraintChecker().isClosedLoopAllowed().value()) {
|
||||||
if (MainApp.getConfigBuilder().isTempBasalInProgress() && determineBasalResultSMB.rate == 0 && determineBasalResultSMB.duration == 0) {
|
TemporaryBasal activeTemp = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(now);
|
||||||
|
if (activeTemp != null && determineBasalResultSMB.rate == 0 && determineBasalResultSMB.duration == 0) {
|
||||||
// going to cancel
|
// going to cancel
|
||||||
} else if (MainApp.getConfigBuilder().isTempBasalInProgress() && Math.abs(determineBasalResultSMB.rate - MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory()) < 0.1) {
|
} else if (activeTemp != null && Math.abs(determineBasalResultSMB.rate - activeTemp.tempBasalConvertedToAbsolute(now, profile)) < 0.1) {
|
||||||
determineBasalResultSMB.tempBasalReqested = false;
|
determineBasalResultSMB.tempBasalRequested = false;
|
||||||
} else if (!MainApp.getConfigBuilder().isTempBasalInProgress() && Math.abs(determineBasalResultSMB.rate - pump.getBaseBasalRate()) < 0.1) {
|
} else if (activeTemp == null && Math.abs(determineBasalResultSMB.rate - ConfigBuilderPlugin.getActivePump().getBaseBasalRate()) < 0.1)
|
||||||
determineBasalResultSMB.tempBasalReqested = false;
|
determineBasalResultSMB.tempBasalRequested = false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
determineBasalResultSMB.iob = iobArray[0];
|
determineBasalResultSMB.iob = iobArray[0];
|
||||||
Date now = new Date();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
determineBasalResultSMB.json.put("timestamp", DateUtil.toISOString(now));
|
determineBasalResultSMB.json.put("timestamp", DateUtil.toISOString(now));
|
||||||
|
@ -270,9 +235,11 @@ public class OpenAPSSMBPlugin implements PluginBase, APSInterface {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
determineBasalResultSMB.inputConstraints = inputConstraints;
|
||||||
|
|
||||||
lastDetermineBasalAdapterSMBJS = determineBasalAdapterSMBJS;
|
lastDetermineBasalAdapterSMBJS = determineBasalAdapterSMBJS;
|
||||||
lastAPSResult = determineBasalResultSMB;
|
lastAPSResult = determineBasalResultSMB;
|
||||||
lastAPSRun = now;
|
lastAPSRun = new Date(now);
|
||||||
MainApp.bus().post(new EventOpenAPSUpdateGui());
|
MainApp.bus().post(new EventOpenAPSUpdateGui());
|
||||||
|
|
||||||
//deviceStatus.suggested = determineBasalResultAMA.json;
|
//deviceStatus.suggested = determineBasalResultAMA.json;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package info.nightscout.androidaps.plugins.Overview.Dialogs;
|
package info.nightscout.androidaps.plugins.Overview.Dialogs;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.HandlerThread;
|
import android.os.HandlerThread;
|
||||||
import android.support.v4.app.DialogFragment;
|
import android.support.v4.app.DialogFragment;
|
||||||
|
@ -16,21 +17,23 @@ 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.CompoundButton;
|
||||||
import android.widget.EditText;
|
import android.widget.RadioButton;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.google.common.base.Joiner;
|
||||||
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;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import info.nightscout.androidaps.Constants;
|
import info.nightscout.androidaps.Constants;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
|
@ -40,8 +43,9 @@ import info.nightscout.androidaps.data.Profile;
|
||||||
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.db.TempTarget;
|
import info.nightscout.androidaps.db.TempTarget;
|
||||||
|
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.Loop.LoopPlugin;
|
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.androidaps.queue.Callback;
|
import info.nightscout.androidaps.queue.Callback;
|
||||||
import info.nightscout.utils.DateUtil;
|
import info.nightscout.utils.DateUtil;
|
||||||
import info.nightscout.utils.DecimalFormatter;
|
import info.nightscout.utils.DecimalFormatter;
|
||||||
|
@ -50,10 +54,9 @@ import info.nightscout.utils.SP;
|
||||||
import info.nightscout.utils.SafeParse;
|
import info.nightscout.utils.SafeParse;
|
||||||
import info.nightscout.utils.ToastUtils;
|
import info.nightscout.utils.ToastUtils;
|
||||||
|
|
||||||
public class NewCarbsDialog extends DialogFragment implements OnClickListener, DatePickerDialog.OnDateSetListener, TimePickerDialog.OnTimeSetListener {
|
public class NewCarbsDialog extends DialogFragment implements OnClickListener, DatePickerDialog.OnDateSetListener, TimePickerDialog.OnTimeSetListener, CompoundButton.OnCheckedChangeListener {
|
||||||
private static Logger log = LoggerFactory.getLogger(NewCarbsDialog.class);
|
private static Logger log = LoggerFactory.getLogger(NewCarbsDialog.class);
|
||||||
|
|
||||||
private EditText foodText;
|
|
||||||
private NumberPicker editCarbs;
|
private NumberPicker editCarbs;
|
||||||
|
|
||||||
private TextView dateButton;
|
private TextView dateButton;
|
||||||
|
@ -66,12 +69,13 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
|
||||||
private Button fav2Button;
|
private Button fav2Button;
|
||||||
private Button fav3Button;
|
private Button fav3Button;
|
||||||
|
|
||||||
private static final double FAV1_DEFAULT = 5;
|
private static final int FAV1_DEFAULT = 5;
|
||||||
private static final double FAV2_DEFAULT = 10;
|
private static final int FAV2_DEFAULT = 10;
|
||||||
private static final double FAV3_DEFAULT = 20;
|
private static final int FAV3_DEFAULT = 20;
|
||||||
private CheckBox suspendLoopCheckbox;
|
private RadioButton startActivityTTCheckbox;
|
||||||
private CheckBox startActivityTTCheckbox;
|
private RadioButton startEatingSoonTTCheckbox;
|
||||||
private CheckBox startEatingSoonTTCheckbox;
|
private RadioButton startHypoTTCheckbox;
|
||||||
|
private boolean togglingTT;
|
||||||
|
|
||||||
private Integer maxCarbs;
|
private Integer maxCarbs;
|
||||||
|
|
||||||
|
@ -118,16 +122,18 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
|
||||||
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);
|
||||||
|
|
||||||
maxCarbs = MainApp.getConfigBuilder().applyCarbsConstraints(Constants.carbsOnlyForCheckLimit);
|
maxCarbs = MainApp.getConstraintChecker().getMaxCarbsAllowed().value();
|
||||||
|
|
||||||
foodText = view.findViewById(R.id.newcarb_food);
|
|
||||||
|
|
||||||
editCarbs = view.findViewById(R.id.newcarb_carbsamount);
|
editCarbs = view.findViewById(R.id.newcarb_carbsamount);
|
||||||
|
|
||||||
editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false, textWatcher);
|
editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false, textWatcher);
|
||||||
|
|
||||||
startActivityTTCheckbox = view.findViewById(R.id.newcarbs_activity_tt);
|
startActivityTTCheckbox = view.findViewById(R.id.newcarbs_activity_tt);
|
||||||
startEatingSoonTTCheckbox = view.findViewById(R.id.carbs_eating_soon_tt);
|
startActivityTTCheckbox.setOnCheckedChangeListener(this);
|
||||||
|
startEatingSoonTTCheckbox = view.findViewById(R.id.newcarbs_eating_soon_tt);
|
||||||
|
startEatingSoonTTCheckbox.setOnCheckedChangeListener(this);
|
||||||
|
startHypoTTCheckbox = view.findViewById(R.id.newcarbs_hypo_tt);
|
||||||
|
startHypoTTCheckbox.setOnCheckedChangeListener(this);
|
||||||
|
|
||||||
dateButton = view.findViewById(R.id.newcarbs_eventdate);
|
dateButton = view.findViewById(R.id.newcarbs_eventdate);
|
||||||
timeButton = view.findViewById(R.id.newcarb_eventtime);
|
timeButton = view.findViewById(R.id.newcarb_eventtime);
|
||||||
|
@ -139,34 +145,27 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
|
||||||
dateButton.setOnClickListener(this);
|
dateButton.setOnClickListener(this);
|
||||||
timeButton.setOnClickListener(this);
|
timeButton.setOnClickListener(this);
|
||||||
|
|
||||||
//To be able to select only one TT at a time
|
|
||||||
startEatingSoonTTCheckbox.setOnClickListener(this);
|
|
||||||
startActivityTTCheckbox.setOnClickListener(this);
|
|
||||||
|
|
||||||
// TODO prefilling carbs, maybe
|
|
||||||
// TODO maybe update suggested carbs to target TT when checked
|
|
||||||
// APSResult lastAPSResult = ConfigBuilderPlugin.getActiveAPS().getLastAPSResult();
|
|
||||||
// if (lastAPSResult != null && lastAPSResult instanceof DetermineBasalResultSMB && ((DetermineBasalResultSMB) lastAPSResult).carbsReq > 0) {
|
|
||||||
// editCarbs.setValue(((DetermineBasalResultSMB) lastAPSResult).carbsReq);
|
|
||||||
// }
|
|
||||||
|
|
||||||
fav1Button = view.findViewById(R.id.newcarbs_plus1);
|
fav1Button = view.findViewById(R.id.newcarbs_plus1);
|
||||||
fav1Button.setOnClickListener(this);
|
fav1Button.setOnClickListener(this);
|
||||||
fav1Button.setText("+" + SP.getString(R.string.key_carbs_button_increment_1, String.valueOf(FAV1_DEFAULT)));
|
fav1Button.setText(toSignedString(SP.getInt(R.string.key_carbs_button_increment_1, FAV1_DEFAULT)));
|
||||||
|
|
||||||
fav2Button = view.findViewById(R.id.newcarbs_plus2);
|
fav2Button = view.findViewById(R.id.newcarbs_plus2);
|
||||||
fav2Button.setOnClickListener(this);
|
fav2Button.setOnClickListener(this);
|
||||||
fav2Button.setText("+" + SP.getString(R.string.key_carbs_button_increment_2, String.valueOf(FAV2_DEFAULT)));
|
fav2Button.setText(toSignedString(SP.getInt(R.string.key_carbs_button_increment_2, FAV2_DEFAULT)));
|
||||||
|
|
||||||
fav3Button = view.findViewById(R.id.newcarbs_plus3);
|
fav3Button = view.findViewById(R.id.newcarbs_plus3);
|
||||||
fav3Button.setOnClickListener(this);
|
fav3Button.setOnClickListener(this);
|
||||||
fav3Button.setText("+" + SP.getString(R.string.key_carbs_button_increment_3, String.valueOf(FAV3_DEFAULT)));
|
fav3Button.setText(toSignedString(SP.getInt(R.string.key_carbs_button_increment_3, FAV3_DEFAULT)));
|
||||||
|
|
||||||
suspendLoopCheckbox = view.findViewById(R.id.newcarbs_suspend_loop);
|
|
||||||
|
|
||||||
setCancelable(true);
|
setCancelable(true);
|
||||||
getDialog().setCanceledOnTouchOutside(false);
|
getDialog().setCanceledOnTouchOutside(false);
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String toSignedString(int value) {
|
||||||
|
return value > 0 ? "+" + value : String.valueOf(value);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void onClick(View view) {
|
public synchronized void onClick(View view) {
|
||||||
Calendar calendar = Calendar.getInstance();
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
@ -201,27 +200,99 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
|
||||||
tpd.show(getActivity().getFragmentManager(), "Timepickerdialog");
|
tpd.show(getActivity().getFragmentManager(), "Timepickerdialog");
|
||||||
break;
|
break;
|
||||||
case R.id.newcarbs_plus1:
|
case R.id.newcarbs_plus1:
|
||||||
editCarbs.setValue(editCarbs.getValue()
|
editCarbs.setValue(Math.max(0, editCarbs.getValue()
|
||||||
+ SP.getDouble(R.string.key_carbs_button_increment_1, FAV1_DEFAULT));
|
+ SP.getInt(R.string.key_carbs_button_increment_1, FAV1_DEFAULT)));
|
||||||
validateInputs();
|
validateInputs();
|
||||||
break;
|
break;
|
||||||
case R.id.newcarbs_plus2:
|
case R.id.newcarbs_plus2:
|
||||||
editCarbs.setValue(editCarbs.getValue()
|
editCarbs.setValue(Math.max(0, editCarbs.getValue()
|
||||||
+ SP.getDouble(R.string.key_carbs_button_increment_2, FAV2_DEFAULT));
|
+ SP.getInt(R.string.key_carbs_button_increment_2, FAV2_DEFAULT)));
|
||||||
validateInputs();
|
validateInputs();
|
||||||
break;
|
break;
|
||||||
case R.id.newcarbs_plus3:
|
case R.id.newcarbs_plus3:
|
||||||
editCarbs.setValue(editCarbs.getValue()
|
editCarbs.setValue(Math.max(0, editCarbs.getValue()
|
||||||
+ SP.getDouble(R.string.key_carbs_button_increment_3, FAV3_DEFAULT));
|
+ SP.getInt(R.string.key_carbs_button_increment_3, FAV3_DEFAULT)));
|
||||||
validateInputs();
|
validateInputs();
|
||||||
break;
|
break;
|
||||||
case R.id.newcarbs_activity_tt:
|
case R.id.newcarbs_activity_tt:
|
||||||
startEatingSoonTTCheckbox.setChecked(false);
|
if (togglingTT) {
|
||||||
break;
|
togglingTT = false;
|
||||||
case R.id.carbs_eating_soon_tt:
|
break;
|
||||||
|
}
|
||||||
|
startActivityTTCheckbox.setOnClickListener(null);
|
||||||
|
startActivityTTCheckbox.setOnCheckedChangeListener(null);
|
||||||
startActivityTTCheckbox.setChecked(false);
|
startActivityTTCheckbox.setChecked(false);
|
||||||
|
startActivityTTCheckbox.setOnCheckedChangeListener(this);
|
||||||
break;
|
break;
|
||||||
|
case R.id.newcarbs_eating_soon_tt:
|
||||||
|
if (togglingTT) {
|
||||||
|
togglingTT = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
startEatingSoonTTCheckbox.setOnClickListener(null);
|
||||||
|
startEatingSoonTTCheckbox.setOnCheckedChangeListener(null);
|
||||||
|
startEatingSoonTTCheckbox.setChecked(false);
|
||||||
|
startEatingSoonTTCheckbox.setOnCheckedChangeListener(this);
|
||||||
|
break;
|
||||||
|
case R.id.newcarbs_hypo_tt:
|
||||||
|
if (togglingTT) {
|
||||||
|
togglingTT = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
startHypoTTCheckbox.setOnClickListener(null);
|
||||||
|
startHypoTTCheckbox.setOnCheckedChangeListener(null);
|
||||||
|
startHypoTTCheckbox.setChecked(false);
|
||||||
|
startHypoTTCheckbox.setOnCheckedChangeListener(this);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||||
|
// Logic to disable a selected radio when pressed. When a checked radio
|
||||||
|
// is pressed, no CheckChanged event is trigger, so register a Click event
|
||||||
|
// when checking a radio. Since Click events come after CheckChanged events,
|
||||||
|
// the Click event is triggered immediately after this. Thus, set toggingTT
|
||||||
|
// var to true, so that the first Click event fired after this is ignored.
|
||||||
|
// Radios remove themselves from Click events once unchecked.
|
||||||
|
// Since radios are not in a group, manually update their state.
|
||||||
|
switch (buttonView.getId()) {
|
||||||
|
case R.id.newcarbs_activity_tt:
|
||||||
|
togglingTT = true;
|
||||||
|
startActivityTTCheckbox.setOnClickListener(this);
|
||||||
|
|
||||||
|
startEatingSoonTTCheckbox.setOnCheckedChangeListener(null);
|
||||||
|
startEatingSoonTTCheckbox.setChecked(false);
|
||||||
|
startEatingSoonTTCheckbox.setOnCheckedChangeListener(this);
|
||||||
|
|
||||||
|
startHypoTTCheckbox.setOnCheckedChangeListener(null);
|
||||||
|
startHypoTTCheckbox.setChecked(false);
|
||||||
|
startHypoTTCheckbox.setOnCheckedChangeListener(this);
|
||||||
|
break;
|
||||||
|
case R.id.newcarbs_eating_soon_tt:
|
||||||
|
togglingTT = true;
|
||||||
|
startEatingSoonTTCheckbox.setOnClickListener(this);
|
||||||
|
|
||||||
|
startActivityTTCheckbox.setOnCheckedChangeListener(null);
|
||||||
|
startActivityTTCheckbox.setChecked(false);
|
||||||
|
startActivityTTCheckbox.setOnCheckedChangeListener(this);
|
||||||
|
|
||||||
|
startHypoTTCheckbox.setOnCheckedChangeListener(null);
|
||||||
|
startHypoTTCheckbox.setChecked(false);
|
||||||
|
startHypoTTCheckbox.setOnCheckedChangeListener(this);
|
||||||
|
break;
|
||||||
|
case R.id.newcarbs_hypo_tt:
|
||||||
|
togglingTT = true;
|
||||||
|
startHypoTTCheckbox.setOnClickListener(this);
|
||||||
|
|
||||||
|
startActivityTTCheckbox.setOnCheckedChangeListener(null);
|
||||||
|
startActivityTTCheckbox.setChecked(false);
|
||||||
|
startActivityTTCheckbox.setOnCheckedChangeListener(this);
|
||||||
|
|
||||||
|
startEatingSoonTTCheckbox.setOnCheckedChangeListener(null);
|
||||||
|
startEatingSoonTTCheckbox.setChecked(false);
|
||||||
|
startEatingSoonTTCheckbox.setOnCheckedChangeListener(this);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,18 +304,14 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
|
||||||
}
|
}
|
||||||
okClicked = true;
|
okClicked = true;
|
||||||
try {
|
try {
|
||||||
final String food = StringUtils.trimToNull(foodText.getText().toString());
|
|
||||||
final Integer carbs = SafeParse.stringToInt(editCarbs.getText());
|
final Integer carbs = SafeParse.stringToInt(editCarbs.getText());
|
||||||
Integer carbsAfterConstraints = MainApp.getConfigBuilder().applyCarbsConstraints(carbs);
|
Integer carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(carbs)).value();
|
||||||
|
|
||||||
String confirmMessage = "";
|
List<String> actions = new LinkedList<>();
|
||||||
if (carbs > 0)
|
if (carbs > 0)
|
||||||
confirmMessage += MainApp.gs(R.string.carbs) + ": " + "<font color='" + MainApp.gc(R.color.colorCarbsButton) + "'>" + carbsAfterConstraints + "g" + "</font>";
|
actions.add(MainApp.gs(R.string.carbs) + ": " + "<font color='" + MainApp.gc(R.color.colorCarbsButton) + "'>" + carbsAfterConstraints + "g" + "</font>");
|
||||||
if (!carbsAfterConstraints.equals(carbs))
|
if (!carbsAfterConstraints.equals(carbs))
|
||||||
confirmMessage += "<br/><font color='" + MainApp.gc(R.color.low) + "'>" + MainApp.gs(R.string.carbsconstraintapplied) + "</font>";
|
actions.add("<font color='" + MainApp.gc(R.color.low) + "'>" + MainApp.gs(R.string.carbsconstraintapplied) + "</font>");
|
||||||
if (suspendLoopCheckbox.isChecked()) {
|
|
||||||
confirmMessage += "<br/>" + MainApp.gs(R.string.loop) + ": " + "<font color='" + MainApp.gc(R.color.low) + "'>" + MainApp.gs(R.string.suspendloopfor30min) + "</font>";
|
|
||||||
}
|
|
||||||
|
|
||||||
final Profile currentProfile = MainApp.getConfigBuilder().getProfile();
|
final Profile currentProfile = MainApp.getConfigBuilder().getProfile();
|
||||||
if (currentProfile == null)
|
if (currentProfile == null)
|
||||||
|
@ -258,109 +325,123 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
|
||||||
int eatingSoonTTDuration = SP.getInt(R.string.key_eatingsoon_duration, Constants.defaultEatingSoonTTDuration);
|
int eatingSoonTTDuration = SP.getInt(R.string.key_eatingsoon_duration, Constants.defaultEatingSoonTTDuration);
|
||||||
eatingSoonTTDuration = eatingSoonTTDuration > 0 ? eatingSoonTTDuration : Constants.defaultEatingSoonTTDuration;
|
eatingSoonTTDuration = eatingSoonTTDuration > 0 ? eatingSoonTTDuration : Constants.defaultEatingSoonTTDuration;
|
||||||
double eatingSoonTT = SP.getDouble(R.string.key_eatingsoon_target, currentProfile.getUnits().equals(Constants.MMOL) ? Constants.defaultEatingSoonTTmmol : Constants.defaultEatingSoonTTmgdl);
|
double eatingSoonTT = SP.getDouble(R.string.key_eatingsoon_target, currentProfile.getUnits().equals(Constants.MMOL) ? Constants.defaultEatingSoonTTmmol : Constants.defaultEatingSoonTTmgdl);
|
||||||
eatingSoonTT = eatingSoonTT > 0 ? Profile.toMgdl(eatingSoonTT, currentProfile.getUnits()) : currentProfile.getUnits().equals(Constants.MMOL) ? Constants.defaultEatingSoonTTmmol : Constants.defaultEatingSoonTTmgdl;
|
eatingSoonTT = eatingSoonTT > 0 ? eatingSoonTT : currentProfile.getUnits().equals(Constants.MMOL) ? Constants.defaultEatingSoonTTmmol : Constants.defaultEatingSoonTTmgdl;
|
||||||
|
|
||||||
|
int hypoTTDuration = SP.getInt(R.string.key_hypo_duration, Constants.defaultHypoTTDuration);
|
||||||
|
hypoTTDuration = hypoTTDuration > 0 ? hypoTTDuration : Constants.defaultHypoTTDuration;
|
||||||
|
double hypoTT = SP.getDouble(R.string.key_hypo_target, currentProfile.getUnits().equals(Constants.MMOL) ? Constants.defaultHypoTTmmol : Constants.defaultHypoTTmgdl);
|
||||||
|
hypoTT = hypoTT > 0 ? hypoTT : currentProfile.getUnits().equals(Constants.MMOL) ? Constants.defaultHypoTTmmol : Constants.defaultHypoTTmgdl;
|
||||||
|
|
||||||
if (startActivityTTCheckbox.isChecked()) {
|
if (startActivityTTCheckbox.isChecked()) {
|
||||||
if (currentProfile.getUnits().equals(Constants.MMOL)) {
|
if (currentProfile.getUnits().equals(Constants.MMOL)) {
|
||||||
confirmMessage += "<br/>" + MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.high) + "'>" + DecimalFormatter.to1Decimal(activityTT) + " mmol/l (" + ((int) activityTTDuration) + " min)</font>";
|
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.high) + "'>" + DecimalFormatter.to1Decimal(activityTT) + " mmol/l (" + activityTTDuration + " min)</font>");
|
||||||
} else
|
} else
|
||||||
confirmMessage += "<br/>" + MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.high) + "'>" + DecimalFormatter.to0Decimal(activityTT) + " mg/dl (" + ((int) activityTTDuration) + " min)</font>";
|
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.high) + "'>" + DecimalFormatter.to0Decimal(activityTT) + " mg/dl (" + activityTTDuration + " min)</font>");
|
||||||
|
|
||||||
}
|
}
|
||||||
if (startEatingSoonTTCheckbox.isChecked() && !startActivityTTCheckbox.isChecked()) {
|
if (startEatingSoonTTCheckbox.isChecked()) {
|
||||||
if (currentProfile.getUnits().equals(Constants.MMOL)) {
|
if (currentProfile.getUnits().equals(Constants.MMOL)) {
|
||||||
confirmMessage += "<br/>" + MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.high) + "'>" + DecimalFormatter.to1Decimal(eatingSoonTT) + " mmol/l (" + eatingSoonTTDuration + " min)</font>";
|
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.high) + "'>" + DecimalFormatter.to1Decimal(eatingSoonTT) + " mmol/l (" + eatingSoonTTDuration + " min)</font>");
|
||||||
} else
|
} else
|
||||||
confirmMessage += "<br/>" + MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.high) + "'>" + DecimalFormatter.to0Decimal(eatingSoonTT) + " mg/dl (" + eatingSoonTTDuration + " min)</font>";
|
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.high) + "'>" + DecimalFormatter.to0Decimal(eatingSoonTT) + " mg/dl (" + eatingSoonTTDuration + " min)</font>");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
if (startHypoTTCheckbox.isChecked()) {
|
||||||
|
if (currentProfile.getUnits().equals(Constants.MMOL)) {
|
||||||
|
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.high) + "'>" + DecimalFormatter.to1Decimal(hypoTT) + " mmol/l (" + hypoTTDuration + " min)</font>");
|
||||||
|
} else
|
||||||
|
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.high) + "'>" + DecimalFormatter.to0Decimal(hypoTT) + " mg/dl (" + hypoTTDuration + " min)</font>");
|
||||||
|
}
|
||||||
|
|
||||||
final double finalActivityTT = activityTT;
|
final double finalActivityTT = activityTT;
|
||||||
final double finalEatigSoonTT = eatingSoonTT;
|
|
||||||
final int finalActivityTTDuration = activityTTDuration;
|
final int finalActivityTTDuration = activityTTDuration;
|
||||||
|
final double finalEatigSoonTT = eatingSoonTT;
|
||||||
final int finalEatingSoonTTDuration = eatingSoonTTDuration;
|
final int finalEatingSoonTTDuration = eatingSoonTTDuration;
|
||||||
|
final double finalHypoTT = hypoTT;
|
||||||
if (StringUtils.isNoneEmpty(food)) {
|
final int finalHypoTTDuration = hypoTTDuration;
|
||||||
confirmMessage += "<br/>" + "Food: " + food;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!initialEventTime.equals(eventTime)) {
|
if (!initialEventTime.equals(eventTime)) {
|
||||||
confirmMessage += "<br/> Time: " + DateUtil.dateAndTimeString(eventTime);
|
actions.add("Time: " + DateUtil.dateAndTimeString(eventTime));
|
||||||
}
|
}
|
||||||
if (confirmMessage.length() > 0) {
|
|
||||||
|
|
||||||
final int finalCarbsAfterConstraints = carbsAfterConstraints;
|
final int finalCarbsAfterConstraints = carbsAfterConstraints;
|
||||||
|
|
||||||
final Context context = getContext();
|
final Context context = getContext();
|
||||||
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||||
|
|
||||||
builder.setTitle(MainApp.gs(R.string.confirmation));
|
builder.setTitle(MainApp.gs(R.string.confirmation));
|
||||||
if (confirmMessage.startsWith("<br/>"))
|
builder.setMessage(actions.isEmpty()
|
||||||
confirmMessage = confirmMessage.substring("<br/>".length());
|
? MainApp.gs(R.string.no_action_selected)
|
||||||
|
: Html.fromHtml(Joiner.on("<br/>").join(actions)));
|
||||||
|
builder.setPositiveButton(MainApp.gs(R.string.ok), actions.isEmpty() ? null : (dialog, id) -> {
|
||||||
|
synchronized (builder) {
|
||||||
|
if (accepted) {
|
||||||
|
log.debug("guarding: already accepted");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
accepted = true;
|
||||||
|
|
||||||
builder.setMessage(Html.fromHtml(confirmMessage));
|
if (startActivityTTCheckbox.isChecked()) {
|
||||||
builder.setPositiveButton(MainApp.gs(R.string.ok), (dialog, id) -> {
|
TempTarget tempTarget = new TempTarget()
|
||||||
synchronized (builder) {
|
.date(System.currentTimeMillis())
|
||||||
if (accepted) {
|
.duration(finalActivityTTDuration)
|
||||||
log.debug("guarding: already accepted");
|
.reason(MainApp.gs(R.string.activity))
|
||||||
return;
|
.source(Source.USER)
|
||||||
}
|
.low(Profile.toMgdl(finalActivityTT, currentProfile.getUnits()))
|
||||||
accepted = true;
|
.high(Profile.toMgdl(finalActivityTT, currentProfile.getUnits()));
|
||||||
|
MainApp.getDbHelper().createOrUpdate(tempTarget);
|
||||||
|
} else if (startEatingSoonTTCheckbox.isChecked()) {
|
||||||
|
TempTarget tempTarget = new TempTarget()
|
||||||
|
.date(System.currentTimeMillis())
|
||||||
|
.duration(finalEatingSoonTTDuration)
|
||||||
|
.reason(MainApp.gs(R.string.eatingsoon))
|
||||||
|
.source(Source.USER)
|
||||||
|
.low(Profile.toMgdl(finalEatigSoonTT, currentProfile.getUnits()))
|
||||||
|
.high(Profile.toMgdl(finalEatigSoonTT, currentProfile.getUnits()));
|
||||||
|
MainApp.getDbHelper().createOrUpdate(tempTarget);
|
||||||
|
} else if (startHypoTTCheckbox.isChecked()) {
|
||||||
|
TempTarget tempTarget = new TempTarget()
|
||||||
|
.date(System.currentTimeMillis())
|
||||||
|
.duration(finalHypoTTDuration)
|
||||||
|
.reason(MainApp.gs(R.string.hypo))
|
||||||
|
.source(Source.USER)
|
||||||
|
.low(Profile.toMgdl(finalHypoTT, currentProfile.getUnits()))
|
||||||
|
.high(Profile.toMgdl(finalHypoTT, currentProfile.getUnits()));
|
||||||
|
MainApp.getDbHelper().createOrUpdate(tempTarget);
|
||||||
|
}
|
||||||
|
|
||||||
if (suspendLoopCheckbox.isChecked()) {
|
if (finalCarbsAfterConstraints > 0) {
|
||||||
final LoopPlugin activeloop = ConfigBuilderPlugin.getActiveLoop();
|
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
|
||||||
activeloop.suspendTo(System.currentTimeMillis() + 30L * 60 * 1000);
|
detailedBolusInfo.date = eventTime.getTime();
|
||||||
ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, new Callback() {
|
detailedBolusInfo.eventType = CareportalEvent.CARBCORRECTION;
|
||||||
|
detailedBolusInfo.carbs = finalCarbsAfterConstraints;
|
||||||
|
detailedBolusInfo.context = context;
|
||||||
|
detailedBolusInfo.source = Source.USER;
|
||||||
|
if (ConfigBuilderPlugin.getActivePump().getPumpDescription().storesCarbInfo) {
|
||||||
|
ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.tempbasaldeliveryerror));
|
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
|
||||||
|
i.putExtra("soundid", R.raw.boluserror);
|
||||||
|
i.putExtra("status", result.comment);
|
||||||
|
i.putExtra("title", MainApp.gs(R.string.treatmentdeliveryerror));
|
||||||
|
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
|
MainApp.instance().startActivity(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
} else {
|
||||||
|
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo);
|
||||||
if (startActivityTTCheckbox.isChecked()) {
|
|
||||||
TempTarget tempTarget = new TempTarget();
|
|
||||||
tempTarget.date = System.currentTimeMillis();
|
|
||||||
tempTarget.durationInMinutes = finalActivityTTDuration;
|
|
||||||
tempTarget.reason = MainApp.gs(R.string.activity);
|
|
||||||
tempTarget.source = Source.USER;
|
|
||||||
tempTarget.low = Profile.toMgdl(finalActivityTT, currentProfile.getUnits());
|
|
||||||
tempTarget.high = Profile.toMgdl(finalActivityTT, currentProfile.getUnits());
|
|
||||||
MainApp.getDbHelper().createOrUpdate(tempTarget);
|
|
||||||
} else if (startEatingSoonTTCheckbox.isChecked()) {
|
|
||||||
TempTarget tempTarget = new TempTarget();
|
|
||||||
tempTarget.date = System.currentTimeMillis();
|
|
||||||
tempTarget.durationInMinutes = finalEatingSoonTTDuration;
|
|
||||||
tempTarget.reason = MainApp.gs(R.string.eatingsoon);
|
|
||||||
tempTarget.source = Source.USER;
|
|
||||||
tempTarget.low = Profile.toMgdl(finalEatigSoonTT, currentProfile.getUnits());
|
|
||||||
tempTarget.high = Profile.toMgdl(finalEatigSoonTT, currentProfile.getUnits());
|
|
||||||
MainApp.getDbHelper().createOrUpdate(tempTarget);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (finalCarbsAfterConstraints > 0 || food != null) {
|
|
||||||
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
|
|
||||||
detailedBolusInfo.date = eventTime.getTime();
|
|
||||||
detailedBolusInfo.eventType = CareportalEvent.CARBCORRECTION;
|
|
||||||
detailedBolusInfo.carbs = finalCarbsAfterConstraints;
|
|
||||||
// detailedBolusInfo.food = food;
|
|
||||||
detailedBolusInfo.context = context;
|
|
||||||
detailedBolusInfo.source = Source.USER;
|
|
||||||
MainApp.getConfigBuilder().addToHistoryTreatment(detailedBolusInfo);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
|
});
|
||||||
builder.show();
|
builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
|
||||||
dismiss();
|
builder.show();
|
||||||
} else
|
dismiss();
|
||||||
dismiss();
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -20,8 +20,8 @@ import android.widget.Button;
|
||||||
import android.widget.CheckBox;
|
import android.widget.CheckBox;
|
||||||
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.base.Joiner;
|
||||||
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;
|
||||||
|
@ -29,9 +29,10 @@ import com.wdullaer.materialdatetimepicker.time.TimePickerDialog;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.text.DecimalFormat;
|
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import info.nightscout.androidaps.Constants;
|
import info.nightscout.androidaps.Constants;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
|
@ -41,11 +42,13 @@ import info.nightscout.androidaps.data.Profile;
|
||||||
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.db.TempTarget;
|
import info.nightscout.androidaps.db.TempTarget;
|
||||||
|
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.Loop.APSResult;
|
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.androidaps.plugins.OpenAPSSMB.DetermineBasalResultSMB;
|
|
||||||
import info.nightscout.androidaps.queue.Callback;
|
import info.nightscout.androidaps.queue.Callback;
|
||||||
import info.nightscout.utils.DateUtil;
|
import info.nightscout.utils.DateUtil;
|
||||||
|
import info.nightscout.utils.DecimalFormatter;
|
||||||
|
import info.nightscout.utils.FabricPrivacy;
|
||||||
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;
|
||||||
|
@ -103,7 +106,7 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener,
|
||||||
Double insulin = SafeParse.stringToDouble(editInsulin.getText());
|
Double insulin = SafeParse.stringToDouble(editInsulin.getText());
|
||||||
if (insulin > maxInsulin) {
|
if (insulin > maxInsulin) {
|
||||||
editInsulin.setValue(0d);
|
editInsulin.setValue(0d);
|
||||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), getString(R.string.bolusconstraintapplied));
|
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.bolusconstraintapplied));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,11 +121,11 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener,
|
||||||
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);
|
||||||
|
|
||||||
maxInsulin = MainApp.getConfigBuilder().applyBolusConstraints(Constants.bolusOnlyForCheckLimit);
|
maxInsulin = MainApp.getConstraintChecker().getMaxBolusAllowed().value();
|
||||||
|
|
||||||
editInsulin = (NumberPicker) view.findViewById(R.id.treatments_newinsulin_amount);
|
editInsulin = (NumberPicker) view.findViewById(R.id.treatments_newinsulin_amount);
|
||||||
|
|
||||||
editInsulin.setParams(0d, 0d, maxInsulin, ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep, new DecimalFormat("0.00"), false, textWatcher);
|
editInsulin.setParams(0d, 0d, maxInsulin, ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep, DecimalFormatter.pumpSupportedBolusFormat(), false, textWatcher);
|
||||||
|
|
||||||
dateButton = (TextView) view.findViewById(R.id.newinsulin_eventdate);
|
dateButton = (TextView) view.findViewById(R.id.newinsulin_eventdate);
|
||||||
timeButton = (TextView) view.findViewById(R.id.newinsulin_eventtime);
|
timeButton = (TextView) view.findViewById(R.id.newinsulin_eventtime);
|
||||||
|
@ -134,25 +137,18 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener,
|
||||||
dateButton.setOnClickListener(this);
|
dateButton.setOnClickListener(this);
|
||||||
timeButton.setOnClickListener(this);
|
timeButton.setOnClickListener(this);
|
||||||
|
|
||||||
/*
|
|
||||||
// This makes it to easy to just bolus insulinReq, which is almost always too much
|
|
||||||
APSResult lastAPSResult = ConfigBuilderPlugin.getActiveAPS().getLastAPSResult();
|
|
||||||
if (lastAPSResult != null && lastAPSResult instanceof DetermineBasalResultSMB && ((DetermineBasalResultSMB) lastAPSResult).insulinReq > 0) {
|
|
||||||
editInsulin.setValue(((DetermineBasalResultSMB )lastAPSResult).insulinReq);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
plus1Button = (Button) view.findViewById(R.id.newinsulin_plus05);
|
plus1Button = (Button) view.findViewById(R.id.newinsulin_plus05);
|
||||||
plus1Button.setOnClickListener(this);
|
plus1Button.setOnClickListener(this);
|
||||||
plus1Button.setText("+" + SP.getString(MainApp.gs(R.string.key_insulin_button_increment_1), String.valueOf(PLUS1_DEFAULT)));
|
plus1Button.setText(toSignedString(SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_1), PLUS1_DEFAULT)));
|
||||||
plus2Button = (Button) view.findViewById(R.id.newinsulin_plus10);
|
plus2Button = (Button) view.findViewById(R.id.newinsulin_plus10);
|
||||||
plus2Button.setOnClickListener(this);
|
plus2Button.setOnClickListener(this);
|
||||||
plus2Button.setText("+" + SP.getString(MainApp.gs(R.string.key_insulin_button_increment_2), String.valueOf(PLUS2_DEFAULT)));
|
plus2Button.setText(toSignedString(SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_2), PLUS2_DEFAULT)));
|
||||||
plus3Button = (Button) view.findViewById(R.id.newinsulin_plus20);
|
plus3Button = (Button) view.findViewById(R.id.newinsulin_plus20);
|
||||||
plus3Button.setOnClickListener(this);
|
plus3Button.setOnClickListener(this);
|
||||||
plus3Button.setText("+" + SP.getString(MainApp.gs(R.string.key_insulin_button_increment_3), String.valueOf(PLUS3_DEFAULT)));
|
plus3Button.setText(toSignedString(SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_3), PLUS3_DEFAULT)));
|
||||||
|
|
||||||
startESMCheckbox = (CheckBox) view.findViewById(R.id.newinsulin_start_eating_soon_tt);
|
startESMCheckbox = (CheckBox) view.findViewById(R.id.newinsulin_start_eating_soon_tt);
|
||||||
|
|
||||||
recordOnlyCheckbox = (CheckBox) view.findViewById(R.id.newinsulin_record_only);
|
recordOnlyCheckbox = (CheckBox) view.findViewById(R.id.newinsulin_record_only);
|
||||||
recordOnlyCheckbox.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
recordOnlyCheckbox.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||||
if (dateButton != null) dateButton.setEnabled(isChecked);
|
if (dateButton != null) dateButton.setEnabled(isChecked);
|
||||||
|
@ -164,6 +160,11 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener,
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String toSignedString(double value) {
|
||||||
|
String formatted = DecimalFormatter.toPumpSupportedBolus(value);
|
||||||
|
return value > 0 ? "+" + formatted : formatted;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void onClick(View view) {
|
public synchronized void onClick(View view) {
|
||||||
Calendar calendar = Calendar.getInstance();
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
@ -197,72 +198,69 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener,
|
||||||
tpd.dismissOnPause(true);
|
tpd.dismissOnPause(true);
|
||||||
tpd.show(getActivity().getFragmentManager(), "Timepickerdialog");
|
tpd.show(getActivity().getFragmentManager(), "Timepickerdialog");
|
||||||
break;
|
break;
|
||||||
case R.id.newinsulin_start_eating_soon_tt:
|
|
||||||
final Profile profile = MainApp.getConfigBuilder().getProfile();
|
|
||||||
double tt = SP.getDouble(R.string.key_eatingsoon_target, 0d);
|
|
||||||
double ttBgAdd = (tt - profile.getTargetLow()) / profile.getIsf();
|
|
||||||
editInsulin.setValue(editInsulin.getValue() + (startESMCheckbox.isChecked() ? ttBgAdd : -ttBgAdd));
|
|
||||||
break;
|
|
||||||
case R.id.newinsulin_plus05:
|
case R.id.newinsulin_plus05:
|
||||||
editInsulin.setValue(editInsulin.getValue()
|
editInsulin.setValue(Math.max(0, editInsulin.getValue()
|
||||||
+ SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_1), PLUS1_DEFAULT));
|
+ SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_1), PLUS1_DEFAULT)));
|
||||||
validateInputs();
|
validateInputs();
|
||||||
break;
|
break;
|
||||||
case R.id.newinsulin_plus10:
|
case R.id.newinsulin_plus10:
|
||||||
editInsulin.setValue(editInsulin.getValue()
|
editInsulin.setValue(Math.max(0, editInsulin.getValue()
|
||||||
+ SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_2), PLUS2_DEFAULT));
|
+ SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_2), PLUS2_DEFAULT)));
|
||||||
validateInputs();
|
validateInputs();
|
||||||
break;
|
break;
|
||||||
case R.id.newinsulin_plus20:
|
case R.id.newinsulin_plus20:
|
||||||
editInsulin.setValue(editInsulin.getValue()
|
editInsulin.setValue(Math.max(0, editInsulin.getValue()
|
||||||
+ SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_3), PLUS3_DEFAULT));
|
+ SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_3), PLUS3_DEFAULT)));
|
||||||
validateInputs();
|
validateInputs();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void submit() {
|
private void submit() {
|
||||||
if (okClicked){
|
if (okClicked) {
|
||||||
log.debug("guarding: ok already clicked");
|
log.debug("guarding: ok already clicked");
|
||||||
dismiss();
|
dismiss();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
okClicked = true;
|
okClicked = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Double insulin = SafeParse.stringToDouble(editInsulin.getText());
|
Double insulin = SafeParse.stringToDouble(editInsulin.getText());
|
||||||
Double insulinAfterConstraints = MainApp.getConfigBuilder().applyBolusConstraints(insulin);
|
Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(insulin)).value();
|
||||||
|
|
||||||
String confirmMessage = "";
|
List<String> actions = new LinkedList<>();
|
||||||
if (insulin > 0) {
|
if (insulin > 0) {
|
||||||
confirmMessage += getString(R.string.bolus) + ": " + "<font color='" + MainApp.sResources.getColor(R.color.colorCarbsButton) + "'>" + insulinAfterConstraints + "U" + "</font>";
|
actions.add(MainApp.gs(R.string.bolus) + ": " + "<font color='" + MainApp.gc(R.color.colorCarbsButton) + "'>" + insulinAfterConstraints + "U" + "</font>");
|
||||||
if (recordOnlyCheckbox.isChecked()) {
|
if (recordOnlyCheckbox.isChecked()) {
|
||||||
confirmMessage += "<br/><font color='" + MainApp.sResources.getColor(R.color.low) + "'>" + "Bolus will be recorded only</font>";
|
actions.add("<font color='" + MainApp.gc(R.color.low) + "'>" + MainApp.gs(R.string.bolusrecordedonly) + "</font>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!insulinAfterConstraints.equals(insulin))
|
if (!insulinAfterConstraints.equals(insulin))
|
||||||
confirmMessage += "<br/><font color='" + MainApp.sResources.getColor(R.color.low) + "'>" + getString(R.string.bolusconstraintapplied) + "</font>";
|
actions.add("<font color='" + MainApp.sResources.getColor(R.color.low) + "'>" + MainApp.gs(R.string.bolusconstraintapplied) + "</font>");
|
||||||
|
|
||||||
double prefTTDuration = SP.getDouble(R.string.key_eatingsoon_duration, 45d);
|
double prefTTDuration = SP.getDouble(R.string.key_eatingsoon_duration, 45d);
|
||||||
double ttDuration = prefTTDuration > 0 ? prefTTDuration : 45d;
|
double ttDuration = prefTTDuration > 0 ? prefTTDuration : 45d;
|
||||||
double prefTT = SP.getDouble(R.string.key_eatingsoon_target, 80d);
|
double prefTT = SP.getDouble(R.string.key_eatingsoon_target, 80d);
|
||||||
double tt = prefTT > 0 ? prefTT : 80d;
|
|
||||||
Profile currentProfile = MainApp.getConfigBuilder().getProfile();
|
Profile currentProfile = MainApp.getConfigBuilder().getProfile();
|
||||||
if(currentProfile == null)
|
if (currentProfile == null)
|
||||||
return;
|
return;
|
||||||
if(currentProfile.getUnits().equals(Constants.MMOL))
|
double tt;
|
||||||
tt = prefTT > 0 ? Profile.toMgdl(prefTT, Constants.MMOL) : 80d;
|
if (currentProfile.getUnits().equals(Constants.MMOL))
|
||||||
|
tt = prefTT > 0 ? Profile.toMgdl(prefTT, Constants.MMOL) : 80d;
|
||||||
else
|
else
|
||||||
tt = prefTT > 0 ? prefTT : 80d;
|
tt = prefTT > 0 ? prefTT : 80d;
|
||||||
final double finalTT = tt;
|
final double finalTT = tt;
|
||||||
|
|
||||||
if (startESMCheckbox.isChecked()) {
|
if (startESMCheckbox.isChecked()) {
|
||||||
if(currentProfile.getUnits().equals("mmol")){
|
if (currentProfile.getUnits().equals("mmol")) {
|
||||||
confirmMessage += "<br/>" + "TT: " + "<font color='" + MainApp.sResources.getColor(R.color.high) + "'>" + Profile.toMmol(tt, Constants.MGDL) + " mmol for " + ((int) ttDuration) + " min </font>";
|
actions.add("TT: " + "<font color='" + MainApp.sResources.getColor(R.color.high) + "'>" + Profile.toMmol(tt, Constants.MGDL) + " mmol for " + ((int) ttDuration) + " min </font>");
|
||||||
} else
|
} else
|
||||||
confirmMessage += "<br/>" + "TT: " + "<font color='" + MainApp.sResources.getColor(R.color.high) + "'>" + ((int) tt) + "mg/dl for " + ((int) ttDuration) + " min </font>";
|
actions.add("TT: " + "<font color='" + MainApp.sResources.getColor(R.color.high) + "'>" + ((int) tt) + "mg/dl for " + ((int) ttDuration) + " min </font>");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!initialEventTime.equals(eventTime)) {
|
if (!initialEventTime.equals(eventTime)) {
|
||||||
confirmMessage += "<br/>Time: " + DateUtil.dateAndTimeString(eventTime);
|
actions.add("Time: " + DateUtil.dateAndTimeString(eventTime));
|
||||||
}
|
}
|
||||||
|
|
||||||
final double finalInsulinAfterConstraints = insulinAfterConstraints;
|
final double finalInsulinAfterConstraints = insulinAfterConstraints;
|
||||||
|
@ -270,11 +268,11 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener,
|
||||||
final Context context = getContext();
|
final Context context = getContext();
|
||||||
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||||
|
|
||||||
builder.setTitle(this.getContext().getString(R.string.confirmation));
|
builder.setTitle(MainApp.gs(R.string.confirmation));
|
||||||
if (confirmMessage.startsWith("<br/>"))
|
builder.setMessage(actions.isEmpty()
|
||||||
confirmMessage = confirmMessage.substring("<br/>".length());
|
? MainApp.gs(R.string.no_action_selected)
|
||||||
builder.setMessage(Html.fromHtml(confirmMessage));
|
: Html.fromHtml(Joiner.on("<br/>").join(actions)));
|
||||||
builder.setPositiveButton(getString(R.string.ok), (dialog, id) -> {
|
builder.setPositiveButton(MainApp.gs(R.string.ok), actions.isEmpty() ? null : (dialog, id) -> {
|
||||||
synchronized (builder) {
|
synchronized (builder) {
|
||||||
if (accepted) {
|
if (accepted) {
|
||||||
log.debug("guarding: already accepted");
|
log.debug("guarding: already accepted");
|
||||||
|
@ -283,13 +281,13 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener,
|
||||||
accepted = true;
|
accepted = true;
|
||||||
|
|
||||||
if (startESMCheckbox.isChecked()) {
|
if (startESMCheckbox.isChecked()) {
|
||||||
TempTarget tempTarget = new TempTarget();
|
TempTarget tempTarget = new TempTarget()
|
||||||
tempTarget.date = System.currentTimeMillis();
|
.date(System.currentTimeMillis())
|
||||||
tempTarget.durationInMinutes = (int) ttDuration;
|
.duration((int) ttDuration)
|
||||||
tempTarget.reason = "Eating soon";
|
.reason("Eating soon")
|
||||||
tempTarget.source = Source.USER;
|
.source(Source.USER)
|
||||||
tempTarget.low = (int) finalTT;
|
.low((int) finalTT)
|
||||||
tempTarget.high = (int) finalTT;
|
.high((int) finalTT);
|
||||||
MainApp.getDbHelper().createOrUpdate(tempTarget);
|
MainApp.getDbHelper().createOrUpdate(tempTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,7 +301,7 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener,
|
||||||
detailedBolusInfo.date = eventTime.getTime();
|
detailedBolusInfo.date = eventTime.getTime();
|
||||||
detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS;
|
detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS;
|
||||||
detailedBolusInfo.insulin = finalInsulinAfterConstraints;
|
detailedBolusInfo.insulin = finalInsulinAfterConstraints;
|
||||||
MainApp.getConfigBuilder().addToHistoryTreatment(detailedBolusInfo);
|
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo);
|
||||||
} else {
|
} else {
|
||||||
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
|
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
|
||||||
detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS;
|
detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS;
|
||||||
|
@ -317,17 +315,17 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener,
|
||||||
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("Bolus"));
|
FabricPrivacy.getInstance().logCustom(new CustomEvent("Bolus"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
builder.setNegativeButton(getString(R.string.cancel), null);
|
builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
|
||||||
builder.show();
|
builder.show();
|
||||||
dismiss();
|
dismiss();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
|
@ -15,6 +15,7 @@ import android.view.View.OnClickListener;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
|
import android.widget.CheckBox;
|
||||||
|
|
||||||
import com.crashlytics.android.answers.CustomEvent;
|
import com.crashlytics.android.answers.CustomEvent;
|
||||||
|
|
||||||
|
@ -30,7 +31,9 @@ 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.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.Treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.androidaps.queue.Callback;
|
import info.nightscout.androidaps.queue.Callback;
|
||||||
import info.nightscout.utils.FabricPrivacy;
|
import info.nightscout.utils.FabricPrivacy;
|
||||||
import info.nightscout.utils.NumberPicker;
|
import info.nightscout.utils.NumberPicker;
|
||||||
|
@ -50,6 +53,8 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene
|
||||||
private boolean accepted;
|
private boolean accepted;
|
||||||
private boolean okClicked;
|
private boolean okClicked;
|
||||||
|
|
||||||
|
private CheckBox recordOnlyCheckbox;
|
||||||
|
|
||||||
public NewTreatmentDialog() {
|
public NewTreatmentDialog() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,12 +77,12 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene
|
||||||
Integer carbs = SafeParse.stringToInt(editCarbs.getText());
|
Integer carbs = SafeParse.stringToInt(editCarbs.getText());
|
||||||
if (carbs > maxCarbs) {
|
if (carbs > maxCarbs) {
|
||||||
editCarbs.setValue(0d);
|
editCarbs.setValue(0d);
|
||||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), getString(R.string.carbsconstraintapplied));
|
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.carbsconstraintapplied));
|
||||||
}
|
}
|
||||||
Double insulin = SafeParse.stringToDouble(editInsulin.getText());
|
Double insulin = SafeParse.stringToDouble(editInsulin.getText());
|
||||||
if (insulin > maxInsulin) {
|
if (insulin > maxInsulin) {
|
||||||
editInsulin.setValue(0d);
|
editInsulin.setValue(0d);
|
||||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), getString(R.string.bolusconstraintapplied));
|
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.bolusconstraintapplied));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,8 +97,8 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene
|
||||||
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);
|
||||||
|
|
||||||
maxCarbs = MainApp.getConfigBuilder().applyCarbsConstraints(Constants.carbsOnlyForCheckLimit);
|
maxCarbs = MainApp.getConstraintChecker().getMaxCarbsAllowed().value();
|
||||||
maxInsulin = MainApp.getConfigBuilder().applyBolusConstraints(Constants.bolusOnlyForCheckLimit);
|
maxInsulin = MainApp.getConstraintChecker().getMaxBolusAllowed().value();
|
||||||
|
|
||||||
editCarbs = (NumberPicker) view.findViewById(R.id.treatments_newtreatment_carbsamount);
|
editCarbs = (NumberPicker) view.findViewById(R.id.treatments_newtreatment_carbsamount);
|
||||||
editInsulin = (NumberPicker) view.findViewById(R.id.treatments_newtreatment_insulinamount);
|
editInsulin = (NumberPicker) view.findViewById(R.id.treatments_newtreatment_insulinamount);
|
||||||
|
@ -101,6 +106,8 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene
|
||||||
editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false, textWatcher);
|
editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false, textWatcher);
|
||||||
editInsulin.setParams(0d, 0d, maxInsulin, ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep, new DecimalFormat("0.00"), false, textWatcher);
|
editInsulin.setParams(0d, 0d, maxInsulin, ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep, new DecimalFormat("0.00"), false, textWatcher);
|
||||||
|
|
||||||
|
recordOnlyCheckbox = (CheckBox) view.findViewById(R.id.newtreatment_record_only);
|
||||||
|
|
||||||
setCancelable(true);
|
setCancelable(true);
|
||||||
getDialog().setCanceledOnTouchOutside(false);
|
getDialog().setCanceledOnTouchOutside(false);
|
||||||
return view;
|
return view;
|
||||||
|
@ -121,15 +128,21 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene
|
||||||
Double insulin = SafeParse.stringToDouble(editInsulin.getText());
|
Double insulin = SafeParse.stringToDouble(editInsulin.getText());
|
||||||
final Integer carbs = SafeParse.stringToInt(editCarbs.getText());
|
final Integer carbs = SafeParse.stringToInt(editCarbs.getText());
|
||||||
|
|
||||||
String confirmMessage = getString(R.string.entertreatmentquestion) + "<br/>";
|
String confirmMessage = MainApp.gs(R.string.entertreatmentquestion) + "<br/>";
|
||||||
|
|
||||||
Double insulinAfterConstraints = MainApp.getConfigBuilder().applyBolusConstraints(insulin);
|
Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(insulin)).value();
|
||||||
Integer carbsAfterConstraints = MainApp.getConfigBuilder().applyCarbsConstraints(carbs);
|
Integer carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(carbs)).value();
|
||||||
|
|
||||||
confirmMessage += getString(R.string.bolus) + ": " + "<font color='" + MainApp.sResources.getColor(R.color.bolus) + "'>" + insulinAfterConstraints + "U" + "</font>";
|
if (insulin > 0) {
|
||||||
confirmMessage += "<br/>" + getString(R.string.carbs) + ": " + carbsAfterConstraints + "g";
|
confirmMessage += MainApp.gs(R.string.bolus) + ": " + "<font color='" + MainApp.gc(R.color.colorCarbsButton) + "'>" + insulinAfterConstraints + "U" + "</font>";
|
||||||
|
if (recordOnlyCheckbox.isChecked()) {
|
||||||
|
confirmMessage += "<br/><font color='" + MainApp.gc(R.color.low) + "'>" + MainApp.gs(R.string.bolusrecordedonly) + "</font>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (carbsAfterConstraints > 0)
|
||||||
|
confirmMessage += "<br/>" + MainApp.gs(R.string.carbs) + ": " + carbsAfterConstraints + "g";
|
||||||
if (insulinAfterConstraints - insulin != 0 || !Objects.equals(carbsAfterConstraints, carbs))
|
if (insulinAfterConstraints - insulin != 0 || !Objects.equals(carbsAfterConstraints, carbs))
|
||||||
confirmMessage += "<br/>" + getString(R.string.constraintapllied);
|
confirmMessage += "<br/>" + MainApp.gs(R.string.constraintapllied);
|
||||||
|
|
||||||
|
|
||||||
final double finalInsulinAfterConstraints = insulinAfterConstraints;
|
final double finalInsulinAfterConstraints = insulinAfterConstraints;
|
||||||
|
@ -138,9 +151,9 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene
|
||||||
final Context context = getContext();
|
final Context context = getContext();
|
||||||
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||||
|
|
||||||
builder.setTitle(this.getContext().getString(R.string.confirmation));
|
builder.setTitle(MainApp.gs(R.string.confirmation));
|
||||||
builder.setMessage(Html.fromHtml(confirmMessage));
|
builder.setMessage(Html.fromHtml(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) {
|
||||||
synchronized (builder) {
|
synchronized (builder) {
|
||||||
if (accepted) {
|
if (accepted) {
|
||||||
|
@ -158,7 +171,7 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene
|
||||||
detailedBolusInfo.carbs = finalCarbsAfterConstraints;
|
detailedBolusInfo.carbs = finalCarbsAfterConstraints;
|
||||||
detailedBolusInfo.context = context;
|
detailedBolusInfo.context = context;
|
||||||
detailedBolusInfo.source = Source.USER;
|
detailedBolusInfo.source = Source.USER;
|
||||||
if (detailedBolusInfo.insulin > 0 || ConfigBuilderPlugin.getActivePump().getPumpDescription().storesCarbInfo) {
|
if (!(recordOnlyCheckbox.isChecked() && (detailedBolusInfo.insulin > 0 || ConfigBuilderPlugin.getActivePump().getPumpDescription().storesCarbInfo))) {
|
||||||
ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() {
|
ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
@ -166,23 +179,21 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
MainApp.getConfigBuilder().addToHistoryTreatment(detailedBolusInfo);
|
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo);
|
||||||
}
|
}
|
||||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("Bolus"));
|
FabricPrivacy.getInstance().logCustom(new CustomEvent("Bolus"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
builder.setNegativeButton(
|
builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
|
||||||
|
|
||||||
getString(R.string.cancel), null);
|
|
||||||
builder.show();
|
builder.show();
|
||||||
|
|
||||||
dismiss();
|
dismiss();
|
||||||
|
|
|
@ -52,16 +52,18 @@ import info.nightscout.androidaps.db.TempTarget;
|
||||||
import info.nightscout.androidaps.events.EventFeatureRunning;
|
import info.nightscout.androidaps.events.EventFeatureRunning;
|
||||||
import info.nightscout.androidaps.events.EventNewBG;
|
import info.nightscout.androidaps.events.EventNewBG;
|
||||||
import info.nightscout.androidaps.events.EventRefreshOverview;
|
import info.nightscout.androidaps.events.EventRefreshOverview;
|
||||||
|
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.IobCobCalculator.AutosensData;
|
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.IobCobCalculator.events.EventAutosensCalculationFinished;
|
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished;
|
||||||
import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
|
import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.androidaps.queue.Callback;
|
import info.nightscout.androidaps.queue.Callback;
|
||||||
import info.nightscout.utils.FabricPrivacy;
|
|
||||||
import info.nightscout.utils.BolusWizard;
|
import info.nightscout.utils.BolusWizard;
|
||||||
import info.nightscout.utils.DateUtil;
|
import info.nightscout.utils.DateUtil;
|
||||||
import info.nightscout.utils.DecimalFormatter;
|
import info.nightscout.utils.DecimalFormatter;
|
||||||
|
import info.nightscout.utils.FabricPrivacy;
|
||||||
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;
|
||||||
|
@ -236,13 +238,13 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
|
||||||
|
|
||||||
superbolusCheckbox.setVisibility(SP.getBoolean(R.string.key_usesuperbolus, false) ? View.VISIBLE : View.GONE);
|
superbolusCheckbox.setVisibility(SP.getBoolean(R.string.key_usesuperbolus, false) ? View.VISIBLE : View.GONE);
|
||||||
|
|
||||||
Integer maxCarbs = MainApp.getConfigBuilder().applyCarbsConstraints(Constants.carbsOnlyForCheckLimit);
|
Integer maxCarbs = MainApp.getConstraintChecker().getMaxCarbsAllowed().value();
|
||||||
Double maxCorrection = MainApp.getConfigBuilder().applyBolusConstraints(Constants.bolusOnlyForCheckLimit);
|
Double maxCorrection = MainApp.getConstraintChecker().getMaxBolusAllowed().value();
|
||||||
|
|
||||||
editBg.setParams(0d, 0d, 500d, 0.1d, new DecimalFormat("0.0"), false, textWatcher);
|
editBg.setParams(0d, 0d, 500d, 0.1d, new DecimalFormat("0.0"), false, textWatcher);
|
||||||
editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false, textWatcher);
|
editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false, textWatcher);
|
||||||
double bolusstep = ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep;
|
double bolusstep = ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep;
|
||||||
editCorr.setParams(0d, -maxCorrection, maxCorrection, bolusstep, new DecimalFormat("0.00"), false, textWatcher);
|
editCorr.setParams(0d, -maxCorrection, maxCorrection, bolusstep, DecimalFormatter.pumpSupportedBolusFormat(), false, textWatcher);
|
||||||
editCarbTime.setParams(0d, -60d, 60d, 5d, new DecimalFormat("0"), false);
|
editCarbTime.setParams(0d, -60d, 60d, 5d, new DecimalFormat("0"), false);
|
||||||
initDialog();
|
initDialog();
|
||||||
|
|
||||||
|
@ -254,24 +256,18 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
|
||||||
@Override
|
@Override
|
||||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||||
saveCheckedStates();
|
saveCheckedStates();
|
||||||
ttCheckbox.setEnabled(bgCheckbox.isChecked() && MainApp.getConfigBuilder().getTempTargetFromHistory() != null);
|
ttCheckbox.setEnabled(bgCheckbox.isChecked() && TreatmentsPlugin.getPlugin().getTempTargetFromHistory() != null);
|
||||||
calculateInsulin();
|
calculateInsulin();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void saveCheckedStates() {
|
private void saveCheckedStates() {
|
||||||
//SP.putBoolean(getString(R.string.key_wizard_include_bg), bgCheckbox.isChecked());
|
|
||||||
SP.putBoolean(getString(R.string.key_wizard_include_cob), cobCheckbox.isChecked());
|
SP.putBoolean(getString(R.string.key_wizard_include_cob), cobCheckbox.isChecked());
|
||||||
SP.putBoolean(getString(R.string.key_wizard_include_trend_bg), bgtrendCheckbox.isChecked());
|
SP.putBoolean(getString(R.string.key_wizard_include_trend_bg), bgtrendCheckbox.isChecked());
|
||||||
//SP.putBoolean(getString(R.string.key_wizard_include_bolus_iob), bolusIobCheckbox.isChecked());
|
|
||||||
//SP.putBoolean(getString(R.string.key_wizard_include_basal_iob), basalIobCheckbox.isChecked());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadCheckedStates() {
|
private void loadCheckedStates() {
|
||||||
//bgCheckbox.setChecked(SP.getBoolean(getString(R.string.key_wizard_include_bg), true));
|
|
||||||
bgtrendCheckbox.setChecked(SP.getBoolean(getString(R.string.key_wizard_include_trend_bg), false));
|
bgtrendCheckbox.setChecked(SP.getBoolean(getString(R.string.key_wizard_include_trend_bg), false));
|
||||||
cobCheckbox.setChecked(SP.getBoolean(getString(R.string.key_wizard_include_cob), false));
|
cobCheckbox.setChecked(SP.getBoolean(getString(R.string.key_wizard_include_cob), false));
|
||||||
//bolusIobCheckbox.setChecked(SP.getBoolean(getString(R.string.key_wizard_include_bolus_iob), true));
|
|
||||||
//basalIobCheckbox.setChecked(SP.getBoolean(getString(R.string.key_wizard_include_basal_iob), true));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -296,13 +292,15 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
okClicked = true;
|
okClicked = true;
|
||||||
if (calculatedTotalInsulin > 0d || calculatedCarbs > 0d) {
|
final Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||||
|
|
||||||
|
if (profile != null && (calculatedTotalInsulin > 0d || calculatedCarbs > 0d)) {
|
||||||
DecimalFormat formatNumber2decimalplaces = new DecimalFormat("0.00");
|
DecimalFormat formatNumber2decimalplaces = new DecimalFormat("0.00");
|
||||||
|
|
||||||
String confirmMessage = getString(R.string.entertreatmentquestion);
|
String confirmMessage = getString(R.string.entertreatmentquestion);
|
||||||
|
|
||||||
Double insulinAfterConstraints = MainApp.getConfigBuilder().applyBolusConstraints(calculatedTotalInsulin);
|
Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(calculatedTotalInsulin)).value();
|
||||||
Integer carbsAfterConstraints = MainApp.getConfigBuilder().applyCarbsConstraints(calculatedCarbs);
|
Integer carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(calculatedCarbs)).value();
|
||||||
|
|
||||||
confirmMessage += "<br/>" + getString(R.string.bolus) + ": " + "<font color='" + MainApp.sResources.getColor(R.color.bolus) + "'>" + formatNumber2decimalplaces.format(insulinAfterConstraints) + "U" + "</font>";
|
confirmMessage += "<br/>" + getString(R.string.bolus) + ": " + "<font color='" + MainApp.sResources.getColor(R.color.bolus) + "'>" + formatNumber2decimalplaces.format(insulinAfterConstraints) + "U" + "</font>";
|
||||||
confirmMessage += "<br/>" + getString(R.string.carbs) + ": " + carbsAfterConstraints + "g";
|
confirmMessage += "<br/>" + getString(R.string.carbs) + ": " + carbsAfterConstraints + "g";
|
||||||
|
@ -341,7 +339,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
|
||||||
activeloop.superBolusTo(System.currentTimeMillis() + 2 * 60L * 60 * 1000);
|
activeloop.superBolusTo(System.currentTimeMillis() + 2 * 60L * 60 * 1000);
|
||||||
MainApp.bus().post(new EventRefreshOverview("WizardDialog"));
|
MainApp.bus().post(new EventRefreshOverview("WizardDialog"));
|
||||||
}
|
}
|
||||||
ConfigBuilderPlugin.getCommandQueue().tempBasalPercent(0, 120, true, new Callback() {
|
ConfigBuilderPlugin.getCommandQueue().tempBasalPercent(0, 120, true, profile, new Callback() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
|
@ -380,7 +378,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
MainApp.getConfigBuilder().addToHistoryTreatment(detailedBolusInfo);
|
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo);
|
||||||
}
|
}
|
||||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("Wizard"));
|
FabricPrivacy.getInstance().logCustom(new CustomEvent("Wizard"));
|
||||||
}
|
}
|
||||||
|
@ -400,10 +398,11 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
|
||||||
|
|
||||||
private void initDialog() {
|
private void initDialog() {
|
||||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||||
ProfileStore profileStore = ConfigBuilderPlugin.getActiveProfileInterface().getProfile();
|
ProfileStore profileStore = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile();
|
||||||
|
|
||||||
if (profile == null) {
|
if (profile == null) {
|
||||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.noprofile));
|
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.noprofile));
|
||||||
|
dismiss();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -428,13 +427,13 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
|
||||||
} else {
|
} else {
|
||||||
editBg.setValue(0d);
|
editBg.setValue(0d);
|
||||||
}
|
}
|
||||||
ttCheckbox.setEnabled(MainApp.getConfigBuilder().getTempTargetFromHistory() != null);
|
ttCheckbox.setEnabled(TreatmentsPlugin.getPlugin().getTempTargetFromHistory() != null);
|
||||||
|
|
||||||
// IOB calculation
|
// IOB calculation
|
||||||
MainApp.getConfigBuilder().updateTotalIOBTreatments();
|
TreatmentsPlugin.getPlugin().updateTotalIOBTreatments();
|
||||||
IobTotal bolusIob = MainApp.getConfigBuilder().getLastCalculationTreatments().round();
|
IobTotal bolusIob = TreatmentsPlugin.getPlugin().getLastCalculationTreatments().round();
|
||||||
MainApp.getConfigBuilder().updateTotalIOBTempBasals();
|
TreatmentsPlugin.getPlugin().updateTotalIOBTempBasals();
|
||||||
IobTotal basalIob = MainApp.getConfigBuilder().getLastCalculationTempBasals().round();
|
IobTotal basalIob = TreatmentsPlugin.getPlugin().getLastCalculationTempBasals().round();
|
||||||
|
|
||||||
bolusIobInsulin.setText(DecimalFormatter.to2Decimal(-bolusIob.iob) + "U");
|
bolusIobInsulin.setText(DecimalFormatter.to2Decimal(-bolusIob.iob) + "U");
|
||||||
basalIobInsulin.setText(DecimalFormatter.to2Decimal(-basalIob.basaliob) + "U");
|
basalIobInsulin.setText(DecimalFormatter.to2Decimal(-basalIob.basaliob) + "U");
|
||||||
|
@ -443,27 +442,29 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
|
||||||
}
|
}
|
||||||
|
|
||||||
private void calculateInsulin() {
|
private void calculateInsulin() {
|
||||||
ProfileStore profile = ConfigBuilderPlugin.getActiveProfileInterface().getProfile();
|
ProfileStore profileStore = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile();
|
||||||
if (profileSpinner == null || profileSpinner.getSelectedItem() == null)
|
if (profileSpinner == null || profileSpinner.getSelectedItem() == null || profileStore == null)
|
||||||
return; // not initialized yet
|
return; // not initialized yet
|
||||||
String selectedAlternativeProfile = profileSpinner.getSelectedItem().toString();
|
String selectedAlternativeProfile = profileSpinner.getSelectedItem().toString();
|
||||||
Profile specificProfile;
|
Profile specificProfile;
|
||||||
if (selectedAlternativeProfile.equals(MainApp.sResources.getString(R.string.active)))
|
if (selectedAlternativeProfile.equals(MainApp.sResources.getString(R.string.active)))
|
||||||
specificProfile = MainApp.getConfigBuilder().getProfile();
|
specificProfile = MainApp.getConfigBuilder().getProfile();
|
||||||
else
|
else
|
||||||
specificProfile = profile.getSpecificProfile(selectedAlternativeProfile);
|
specificProfile = profileStore.getSpecificProfile(selectedAlternativeProfile);
|
||||||
|
|
||||||
// Entered values
|
// Entered values
|
||||||
Double c_bg = SafeParse.stringToDouble(editBg.getText());
|
Double c_bg = SafeParse.stringToDouble(editBg.getText());
|
||||||
Integer c_carbs = SafeParse.stringToInt(editCarbs.getText());
|
Integer c_carbs = SafeParse.stringToInt(editCarbs.getText());
|
||||||
Double c_correction = SafeParse.stringToDouble(editCorr.getText());
|
Double c_correction = SafeParse.stringToDouble(editCorr.getText());
|
||||||
Double corrAfterConstraint = MainApp.getConfigBuilder().applyBolusConstraints(c_correction);
|
Double corrAfterConstraint = c_correction;
|
||||||
|
if (c_correction > 0)
|
||||||
|
c_correction = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(c_correction)).value();
|
||||||
if (c_correction - corrAfterConstraint != 0) { // c_correction != corrAfterConstraint doesn't work
|
if (c_correction - corrAfterConstraint != 0) { // c_correction != corrAfterConstraint doesn't work
|
||||||
editCorr.setValue(0d);
|
editCorr.setValue(0d);
|
||||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), getString(R.string.bolusconstraintapplied));
|
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), getString(R.string.bolusconstraintapplied));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Integer carbsAfterConstraint = MainApp.getConfigBuilder().applyCarbsConstraints(c_carbs);
|
Integer carbsAfterConstraint = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(c_carbs)).value();
|
||||||
if (c_carbs - carbsAfterConstraint != 0) {
|
if (c_carbs - carbsAfterConstraint != 0) {
|
||||||
editCarbs.setValue(0d);
|
editCarbs.setValue(0d);
|
||||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), getString(R.string.carbsconstraintapplied));
|
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), getString(R.string.carbsconstraintapplied));
|
||||||
|
@ -471,14 +472,14 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
|
||||||
}
|
}
|
||||||
|
|
||||||
c_bg = bgCheckbox.isChecked() ? c_bg : 0d;
|
c_bg = bgCheckbox.isChecked() ? c_bg : 0d;
|
||||||
TempTarget tempTarget = ttCheckbox.isChecked() ? MainApp.getConfigBuilder().getTempTargetFromHistory() : null;
|
TempTarget tempTarget = ttCheckbox.isChecked() ? TreatmentsPlugin.getPlugin().getTempTargetFromHistory() : null;
|
||||||
|
|
||||||
// COB
|
// COB
|
||||||
Double c_cob = 0d;
|
Double c_cob = 0d;
|
||||||
if (cobCheckbox.isChecked()) {
|
if (cobCheckbox.isChecked()) {
|
||||||
AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getLastAutosensData("Wizard COB");
|
AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getLastAutosensData("Wizard COB");
|
||||||
|
|
||||||
if(autosensData != null) {
|
if (autosensData != null) {
|
||||||
c_cob = autosensData.cob;
|
c_cob = autosensData.cob;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -530,7 +531,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
|
||||||
}
|
}
|
||||||
|
|
||||||
if (calculatedTotalInsulin > 0d || calculatedCarbs > 0d) {
|
if (calculatedTotalInsulin > 0d || calculatedCarbs > 0d) {
|
||||||
String insulinText = calculatedTotalInsulin > 0d ? (DecimalFormatter.to2Decimal(calculatedTotalInsulin) + "U") : "";
|
String insulinText = calculatedTotalInsulin > 0d ? (DecimalFormatter.toPumpSupportedBolus(calculatedTotalInsulin) + "U") : "";
|
||||||
String carbsText = calculatedCarbs > 0d ? (DecimalFormatter.to0Decimal(calculatedCarbs) + "g") : "";
|
String carbsText = calculatedCarbs > 0d ? (DecimalFormatter.to0Decimal(calculatedCarbs) + "g") : "";
|
||||||
total.setText(MainApp.gs(R.string.result) + ": " + insulinText + " " + carbsText);
|
total.setText(MainApp.gs(R.string.result) + ": " + insulinText + " " + carbsText);
|
||||||
okButton.setVisibility(View.VISIBLE);
|
okButton.setVisibility(View.VISIBLE);
|
||||||
|
|
|
@ -16,21 +16,27 @@ import android.support.v4.app.Fragment;
|
||||||
import android.support.v4.app.FragmentActivity;
|
import android.support.v4.app.FragmentActivity;
|
||||||
import android.support.v4.app.FragmentManager;
|
import android.support.v4.app.FragmentManager;
|
||||||
import android.support.v4.content.ContextCompat;
|
import android.support.v4.content.ContextCompat;
|
||||||
|
import android.support.v4.content.res.ResourcesCompat;
|
||||||
import android.support.v7.app.AlertDialog;
|
import android.support.v7.app.AlertDialog;
|
||||||
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.PopupMenu;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
|
import android.text.SpannableString;
|
||||||
|
import android.text.style.ForegroundColorSpan;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
import android.view.ContextMenu;
|
import android.view.ContextMenu;
|
||||||
import android.view.HapticFeedbackConstants;
|
import android.view.HapticFeedbackConstants;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.CheckBox;
|
import android.widget.CheckBox;
|
||||||
import android.widget.CompoundButton;
|
import android.widget.CompoundButton;
|
||||||
|
import android.widget.ImageButton;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
@ -78,7 +84,8 @@ import info.nightscout.androidaps.events.EventRefreshOverview;
|
||||||
import info.nightscout.androidaps.events.EventTempBasalChange;
|
import info.nightscout.androidaps.events.EventTempBasalChange;
|
||||||
import info.nightscout.androidaps.events.EventTempTargetChange;
|
import info.nightscout.androidaps.events.EventTempTargetChange;
|
||||||
import info.nightscout.androidaps.events.EventTreatmentChange;
|
import info.nightscout.androidaps.events.EventTreatmentChange;
|
||||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
import info.nightscout.androidaps.interfaces.Constraint;
|
||||||
|
import info.nightscout.androidaps.interfaces.PluginType;
|
||||||
import info.nightscout.androidaps.interfaces.PumpDescription;
|
import info.nightscout.androidaps.interfaces.PumpDescription;
|
||||||
import info.nightscout.androidaps.interfaces.PumpInterface;
|
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||||
import info.nightscout.androidaps.plugins.Careportal.CareportalFragment;
|
import info.nightscout.androidaps.plugins.Careportal.CareportalFragment;
|
||||||
|
@ -105,8 +112,9 @@ import info.nightscout.androidaps.plugins.Overview.events.EventSetWakeLock;
|
||||||
import info.nightscout.androidaps.plugins.Overview.graphData.GraphData;
|
import info.nightscout.androidaps.plugins.Overview.graphData.GraphData;
|
||||||
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
|
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
|
||||||
import info.nightscout.androidaps.plugins.Overview.notifications.NotificationStore;
|
import info.nightscout.androidaps.plugins.Overview.notifications.NotificationStore;
|
||||||
import info.nightscout.androidaps.plugins.SourceDexcomG5.SourceDexcomG5Plugin;
|
import info.nightscout.androidaps.plugins.Source.SourceDexcomG5Plugin;
|
||||||
import info.nightscout.androidaps.plugins.SourceXdrip.SourceXdripPlugin;
|
import info.nightscout.androidaps.plugins.Source.SourceXdripPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Treatments.fragments.ProfileViewerDialog;
|
import info.nightscout.androidaps.plugins.Treatments.fragments.ProfileViewerDialog;
|
||||||
import info.nightscout.androidaps.queue.Callback;
|
import info.nightscout.androidaps.queue.Callback;
|
||||||
import info.nightscout.utils.BolusWizard;
|
import info.nightscout.utils.BolusWizard;
|
||||||
|
@ -120,7 +128,7 @@ import info.nightscout.utils.SP;
|
||||||
import info.nightscout.utils.SingleClickButton;
|
import info.nightscout.utils.SingleClickButton;
|
||||||
import info.nightscout.utils.ToastUtils;
|
import info.nightscout.utils.ToastUtils;
|
||||||
|
|
||||||
public class OverviewFragment extends Fragment implements View.OnClickListener, CompoundButton.OnCheckedChangeListener, View.OnLongClickListener {
|
public class OverviewFragment extends Fragment implements View.OnClickListener, View.OnLongClickListener {
|
||||||
private static Logger log = LoggerFactory.getLogger(OverviewFragment.class);
|
private static Logger log = LoggerFactory.getLogger(OverviewFragment.class);
|
||||||
|
|
||||||
TextView timeView;
|
TextView timeView;
|
||||||
|
@ -144,25 +152,13 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
LinearLayout pumpStatusLayout;
|
LinearLayout pumpStatusLayout;
|
||||||
GraphView bgGraph;
|
GraphView bgGraph;
|
||||||
GraphView iobGraph;
|
GraphView iobGraph;
|
||||||
|
ImageButton chartButton;
|
||||||
|
|
||||||
TextView iage;
|
TextView iage;
|
||||||
TextView cage;
|
TextView cage;
|
||||||
TextView sage;
|
TextView sage;
|
||||||
TextView pbage;
|
TextView pbage;
|
||||||
|
|
||||||
TextView showPredictionLabel;
|
|
||||||
CheckBox showPredictionCheckbox;
|
|
||||||
TextView showBasalsLabel;
|
|
||||||
CheckBox showBasalsCheckbox;
|
|
||||||
TextView showIobLabel;
|
|
||||||
CheckBox showIobCheckbox;
|
|
||||||
TextView showCobLabel;
|
|
||||||
CheckBox showCobCheckbox;
|
|
||||||
TextView showDeviationsLabel;
|
|
||||||
CheckBox showDeviationsCheckbox;
|
|
||||||
TextView showRatiosLabel;
|
|
||||||
CheckBox showRatiosCheckbox;
|
|
||||||
|
|
||||||
RecyclerView notificationsView;
|
RecyclerView notificationsView;
|
||||||
LinearLayoutManager llm;
|
LinearLayoutManager llm;
|
||||||
|
|
||||||
|
@ -193,6 +189,10 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
|
|
||||||
final Object updateSync = new Object();
|
final Object updateSync = new Object();
|
||||||
|
|
||||||
|
public enum CHARTTYPE {PRE, BAS, IOB, COB, DEV, SEN}
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
private static final ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor();
|
private static final ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor();
|
||||||
private static ScheduledFuture<?> scheduledUpdate = null;
|
private static ScheduledFuture<?> scheduledUpdate = null;
|
||||||
|
|
||||||
|
@ -286,50 +286,33 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
|
|
||||||
acceptTempLayout = (LinearLayout) view.findViewById(R.id.overview_accepttemplayout);
|
acceptTempLayout = (LinearLayout) view.findViewById(R.id.overview_accepttemplayout);
|
||||||
|
|
||||||
showPredictionCheckbox = (CheckBox) view.findViewById(R.id.overview_showprediction);
|
|
||||||
showBasalsCheckbox = (CheckBox) view.findViewById(R.id.overview_showbasals);
|
|
||||||
showIobCheckbox = (CheckBox) view.findViewById(R.id.overview_showiob);
|
|
||||||
showCobCheckbox = (CheckBox) view.findViewById(R.id.overview_showcob);
|
|
||||||
showDeviationsCheckbox = (CheckBox) view.findViewById(R.id.overview_showdeviations);
|
|
||||||
showRatiosCheckbox = (CheckBox) view.findViewById(R.id.overview_showratios);
|
|
||||||
showPredictionCheckbox.setChecked(SP.getBoolean("showprediction", false));
|
|
||||||
showBasalsCheckbox.setChecked(SP.getBoolean("showbasals", true));
|
|
||||||
showIobCheckbox.setChecked(SP.getBoolean("showiob", false));
|
|
||||||
showCobCheckbox.setChecked(SP.getBoolean("showcob", false));
|
|
||||||
showDeviationsCheckbox.setChecked(SP.getBoolean("showdeviations", false));
|
|
||||||
showRatiosCheckbox.setChecked(SP.getBoolean("showratios", false));
|
|
||||||
showPredictionCheckbox.setOnCheckedChangeListener(this);
|
|
||||||
showBasalsCheckbox.setOnCheckedChangeListener(this);
|
|
||||||
showIobCheckbox.setOnCheckedChangeListener(this);
|
|
||||||
showCobCheckbox.setOnCheckedChangeListener(this);
|
|
||||||
showDeviationsCheckbox.setOnCheckedChangeListener(this);
|
|
||||||
showRatiosCheckbox.setOnCheckedChangeListener(this);
|
|
||||||
|
|
||||||
showPredictionLabel = (TextView) view.findViewById(R.id.overview_showprediction_label);
|
|
||||||
showPredictionLabel.setOnClickListener(this);
|
|
||||||
showBasalsLabel = (TextView) view.findViewById(R.id.overview_showbasals_label);
|
|
||||||
showBasalsLabel.setOnClickListener(this);
|
|
||||||
showIobLabel = (TextView) view.findViewById(R.id.overview_showiob_label);
|
|
||||||
showIobLabel.setOnClickListener(this);
|
|
||||||
showCobLabel = (TextView) view.findViewById(R.id.overview_showcob_label);
|
|
||||||
showCobLabel.setOnClickListener(this);
|
|
||||||
showDeviationsLabel = (TextView) view.findViewById(R.id.overview_showdeviations_label);
|
|
||||||
showDeviationsLabel.setOnClickListener(this);
|
|
||||||
showRatiosLabel = (TextView) view.findViewById(R.id.overview_showratios_label);
|
|
||||||
showRatiosLabel.setOnClickListener(this);
|
|
||||||
|
|
||||||
notificationsView = (RecyclerView) view.findViewById(R.id.overview_notifications);
|
notificationsView = (RecyclerView) view.findViewById(R.id.overview_notifications);
|
||||||
notificationsView.setHasFixedSize(true);
|
notificationsView.setHasFixedSize(true);
|
||||||
llm = new LinearLayoutManager(view.getContext());
|
llm = new LinearLayoutManager(view.getContext());
|
||||||
notificationsView.setLayoutManager(llm);
|
notificationsView.setLayoutManager(llm);
|
||||||
|
|
||||||
|
int axisWidth = 50;
|
||||||
|
|
||||||
|
if (dm.densityDpi <= 120)
|
||||||
|
axisWidth = 3;
|
||||||
|
else if (dm.densityDpi <= 160)
|
||||||
|
axisWidth = 10;
|
||||||
|
else if (dm.densityDpi <= 320)
|
||||||
|
axisWidth = 35;
|
||||||
|
else if (dm.densityDpi <= 420)
|
||||||
|
axisWidth = 50;
|
||||||
|
else if (dm.densityDpi <= 560)
|
||||||
|
axisWidth = 70;
|
||||||
|
else
|
||||||
|
axisWidth = 80;
|
||||||
|
|
||||||
bgGraph.getGridLabelRenderer().setGridColor(MainApp.sResources.getColor(R.color.graphgrid));
|
bgGraph.getGridLabelRenderer().setGridColor(MainApp.sResources.getColor(R.color.graphgrid));
|
||||||
bgGraph.getGridLabelRenderer().reloadStyles();
|
bgGraph.getGridLabelRenderer().reloadStyles();
|
||||||
iobGraph.getGridLabelRenderer().setGridColor(MainApp.sResources.getColor(R.color.graphgrid));
|
iobGraph.getGridLabelRenderer().setGridColor(MainApp.sResources.getColor(R.color.graphgrid));
|
||||||
iobGraph.getGridLabelRenderer().reloadStyles();
|
iobGraph.getGridLabelRenderer().reloadStyles();
|
||||||
iobGraph.getGridLabelRenderer().setHorizontalLabelsVisible(false);
|
iobGraph.getGridLabelRenderer().setHorizontalLabelsVisible(false);
|
||||||
bgGraph.getGridLabelRenderer().setLabelVerticalWidth(50);
|
bgGraph.getGridLabelRenderer().setLabelVerticalWidth(axisWidth);
|
||||||
iobGraph.getGridLabelRenderer().setLabelVerticalWidth(50);
|
iobGraph.getGridLabelRenderer().setLabelVerticalWidth(axisWidth);
|
||||||
iobGraph.getGridLabelRenderer().setNumVerticalLabels(5);
|
iobGraph.getGridLabelRenderer().setNumVerticalLabels(5);
|
||||||
|
|
||||||
rangeToDisplay = SP.getInt(R.string.key_rangetodisplay, 6);
|
rangeToDisplay = SP.getInt(R.string.key_rangetodisplay, 6);
|
||||||
|
@ -345,6 +328,8 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
setupChartMenu(view);
|
||||||
|
|
||||||
lockScreen = (CheckBox) view.findViewById(R.id.overview_lockscreen);
|
lockScreen = (CheckBox) view.findViewById(R.id.overview_lockscreen);
|
||||||
if (lockScreen != null) {
|
if (lockScreen != null) {
|
||||||
lockScreen.setChecked(SP.getBoolean("lockscreen", false));
|
lockScreen.setChecked(SP.getBoolean("lockscreen", false));
|
||||||
|
@ -366,6 +351,106 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setupChartMenu(View view) {
|
||||||
|
chartButton = (ImageButton) view.findViewById(R.id.overview_chartMenuButton);
|
||||||
|
chartButton.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
final LoopPlugin.LastRun finalLastRun = LoopPlugin.lastRun;
|
||||||
|
final boolean predictionsAvailable = finalLastRun != null && finalLastRun.request.hasPredictions;
|
||||||
|
|
||||||
|
MenuItem item;
|
||||||
|
CharSequence title;
|
||||||
|
SpannableString s;
|
||||||
|
PopupMenu popup = new PopupMenu(v.getContext(), v);
|
||||||
|
|
||||||
|
if (predictionsAvailable) {
|
||||||
|
item = popup.getMenu().add(Menu.NONE, CHARTTYPE.PRE.ordinal(), Menu.NONE, "Predictions");
|
||||||
|
title = item.getTitle();
|
||||||
|
s = new SpannableString(title);
|
||||||
|
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.prediction, null)), 0, s.length(), 0);
|
||||||
|
item.setTitle(s);
|
||||||
|
item.setCheckable(true);
|
||||||
|
item.setChecked(SP.getBoolean("showprediction", true));
|
||||||
|
}
|
||||||
|
|
||||||
|
item = popup.getMenu().add(Menu.NONE, 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(SP.getBoolean("showbasals", true));
|
||||||
|
|
||||||
|
item = popup.getMenu().add(Menu.NONE, 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(SP.getBoolean("showiob", true));
|
||||||
|
|
||||||
|
item = popup.getMenu().add(Menu.NONE, 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(SP.getBoolean("showcob", true));
|
||||||
|
|
||||||
|
item = popup.getMenu().add(Menu.NONE, 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(SP.getBoolean("showdeviations", false));
|
||||||
|
|
||||||
|
item = popup.getMenu().add(Menu.NONE, 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(SP.getBoolean("showratios", false));
|
||||||
|
|
||||||
|
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onMenuItemClick(MenuItem item) {
|
||||||
|
if (item.getItemId() == CHARTTYPE.PRE.ordinal()) {
|
||||||
|
SP.putBoolean("showprediction", !item.isChecked());
|
||||||
|
|
||||||
|
} else if (item.getItemId() == CHARTTYPE.BAS.ordinal()) {
|
||||||
|
SP.putBoolean("showbasals", !item.isChecked());
|
||||||
|
|
||||||
|
} else if (item.getItemId() == CHARTTYPE.IOB.ordinal()) {
|
||||||
|
SP.putBoolean("showiob", !item.isChecked());
|
||||||
|
|
||||||
|
} else if (item.getItemId() == CHARTTYPE.COB.ordinal()) {
|
||||||
|
SP.putBoolean("showcob", !item.isChecked());
|
||||||
|
|
||||||
|
} else if (item.getItemId() == CHARTTYPE.DEV.ordinal()) {
|
||||||
|
SP.putBoolean("showdeviations", !item.isChecked());
|
||||||
|
|
||||||
|
} else if (item.getItemId() == CHARTTYPE.SEN.ordinal()) {
|
||||||
|
SP.putBoolean("showratios", !item.isChecked());
|
||||||
|
}
|
||||||
|
scheduleUpdateGUI("onGraphCheckboxesCheckedChanged");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
chartButton.setImageResource(R.drawable.ic_arrow_drop_up_white_24dp);
|
||||||
|
popup.setOnDismissListener(new PopupMenu.OnDismissListener() {
|
||||||
|
@Override
|
||||||
|
public void onDismiss(PopupMenu menu) {
|
||||||
|
chartButton.setImageResource(R.drawable.ic_arrow_drop_down_white_24dp);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
popup.show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
|
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
|
||||||
|
@ -373,10 +458,10 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
if (v == apsModeView) {
|
if (v == apsModeView) {
|
||||||
final LoopPlugin activeloop = ConfigBuilderPlugin.getActiveLoop();
|
final LoopPlugin activeloop = ConfigBuilderPlugin.getActiveLoop();
|
||||||
final PumpDescription pumpDescription = ConfigBuilderPlugin.getActivePump().getPumpDescription();
|
final PumpDescription pumpDescription = ConfigBuilderPlugin.getActivePump().getPumpDescription();
|
||||||
if (activeloop == null)
|
if (activeloop == null || !MainApp.getConfigBuilder().isProfileValid("ContexMenuCreation"))
|
||||||
return;
|
return;
|
||||||
menu.setHeaderTitle(MainApp.sResources.getString(R.string.loop));
|
menu.setHeaderTitle(MainApp.sResources.getString(R.string.loop));
|
||||||
if (activeloop.isEnabled(PluginBase.LOOP)) {
|
if (activeloop.isEnabled(PluginType.LOOP)) {
|
||||||
menu.add(MainApp.sResources.getString(R.string.disableloop));
|
menu.add(MainApp.sResources.getString(R.string.disableloop));
|
||||||
if (!activeloop.isSuspended()) {
|
if (!activeloop.isSuspended()) {
|
||||||
menu.add(MainApp.sResources.getString(R.string.suspendloopfor1h));
|
menu.add(MainApp.sResources.getString(R.string.suspendloopfor1h));
|
||||||
|
@ -394,51 +479,27 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
menu.add(MainApp.sResources.getString(R.string.resume));
|
menu.add(MainApp.sResources.getString(R.string.resume));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!activeloop.isEnabled(PluginBase.LOOP))
|
if (!activeloop.isEnabled(PluginType.LOOP))
|
||||||
menu.add(MainApp.sResources.getString(R.string.enableloop));
|
menu.add(MainApp.sResources.getString(R.string.enableloop));
|
||||||
} else if (v == activeProfileView) {
|
} else if (v == activeProfileView) {
|
||||||
menu.setHeaderTitle(MainApp.sResources.getString(R.string.profile));
|
menu.setHeaderTitle(MainApp.sResources.getString(R.string.profile));
|
||||||
menu.add(MainApp.sResources.getString(R.string.danar_viewprofile));
|
menu.add(MainApp.sResources.getString(R.string.danar_viewprofile));
|
||||||
menu.add(MainApp.sResources.getString(R.string.careportal_profileswitch));
|
if (MainApp.getConfigBuilder().getActiveProfileInterface().getProfile() != null) {
|
||||||
|
menu.add(MainApp.sResources.getString(R.string.careportal_profileswitch));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
|
||||||
switch (buttonView.getId()) {
|
|
||||||
case R.id.overview_showprediction:
|
|
||||||
case R.id.overview_showbasals:
|
|
||||||
case R.id.overview_showiob:
|
|
||||||
break;
|
|
||||||
case R.id.overview_showcob:
|
|
||||||
showDeviationsCheckbox.setOnCheckedChangeListener(null);
|
|
||||||
showDeviationsCheckbox.setChecked(false);
|
|
||||||
showDeviationsCheckbox.setOnCheckedChangeListener(this);
|
|
||||||
break;
|
|
||||||
case R.id.overview_showdeviations:
|
|
||||||
showCobCheckbox.setOnCheckedChangeListener(null);
|
|
||||||
showCobCheckbox.setChecked(false);
|
|
||||||
showCobCheckbox.setOnCheckedChangeListener(this);
|
|
||||||
break;
|
|
||||||
case R.id.overview_showratios:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
SP.putBoolean("showiob", showIobCheckbox.isChecked());
|
|
||||||
SP.putBoolean("showprediction", showPredictionCheckbox.isChecked());
|
|
||||||
SP.putBoolean("showbasals", showBasalsCheckbox.isChecked());
|
|
||||||
SP.putBoolean("showcob", showCobCheckbox.isChecked());
|
|
||||||
SP.putBoolean("showdeviations", showDeviationsCheckbox.isChecked());
|
|
||||||
SP.putBoolean("showratios", showRatiosCheckbox.isChecked());
|
|
||||||
scheduleUpdateGUI("onGraphCheckboxesCheckedChanged");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onContextItemSelected(MenuItem item) {
|
public boolean onContextItemSelected(MenuItem item) {
|
||||||
|
final Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||||
|
if (profile == null)
|
||||||
|
return true;
|
||||||
final LoopPlugin activeloop = ConfigBuilderPlugin.getActiveLoop();
|
final LoopPlugin activeloop = ConfigBuilderPlugin.getActiveLoop();
|
||||||
if (item.getTitle().equals(MainApp.sResources.getString(R.string.disableloop))) {
|
if (item.getTitle().equals(MainApp.sResources.getString(R.string.disableloop))) {
|
||||||
activeloop.setFragmentEnabled(PluginBase.LOOP, false);
|
activeloop.setPluginEnabled(PluginType.LOOP, false);
|
||||||
activeloop.setFragmentVisible(PluginBase.LOOP, false);
|
activeloop.setFragmentVisible(PluginType.LOOP, false);
|
||||||
MainApp.getConfigBuilder().storeSettings();
|
MainApp.getConfigBuilder().storeSettings("DisablingLoop");
|
||||||
updateGUI("suspendmenu");
|
updateGUI("suspendmenu");
|
||||||
MainApp.getConfigBuilder().getCommandQueue().cancelTempBasal(true, new Callback() {
|
MainApp.getConfigBuilder().getCommandQueue().cancelTempBasal(true, new Callback() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -451,9 +512,9 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
NSUpload.uploadOpenAPSOffline(24 * 60); // upload 24h, we don't know real duration
|
NSUpload.uploadOpenAPSOffline(24 * 60); // upload 24h, we don't know real duration
|
||||||
return true;
|
return true;
|
||||||
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.enableloop))) {
|
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.enableloop))) {
|
||||||
activeloop.setFragmentEnabled(PluginBase.LOOP, true);
|
activeloop.setPluginEnabled(PluginType.LOOP, true);
|
||||||
activeloop.setFragmentVisible(PluginBase.LOOP, true);
|
activeloop.setFragmentVisible(PluginType.LOOP, true);
|
||||||
MainApp.getConfigBuilder().storeSettings();
|
MainApp.getConfigBuilder().storeSettings("EnablingLoop");
|
||||||
updateGUI("suspendmenu");
|
updateGUI("suspendmenu");
|
||||||
NSUpload.uploadOpenAPSOffline(0);
|
NSUpload.uploadOpenAPSOffline(0);
|
||||||
return true;
|
return true;
|
||||||
|
@ -487,23 +548,23 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
updateGUI("suspendmenu");
|
updateGUI("suspendmenu");
|
||||||
return true;
|
return true;
|
||||||
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor15m))) {
|
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor15m))) {
|
||||||
MainApp.getConfigBuilder().disconnectPump(15);
|
MainApp.getConfigBuilder().disconnectPump(15, profile);
|
||||||
updateGUI("suspendmenu");
|
updateGUI("suspendmenu");
|
||||||
return true;
|
return true;
|
||||||
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor30m))) {
|
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor30m))) {
|
||||||
MainApp.getConfigBuilder().disconnectPump(30);
|
MainApp.getConfigBuilder().disconnectPump(30, profile);
|
||||||
updateGUI("suspendmenu");
|
updateGUI("suspendmenu");
|
||||||
return true;
|
return true;
|
||||||
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor1h))) {
|
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor1h))) {
|
||||||
MainApp.getConfigBuilder().disconnectPump(60);
|
MainApp.getConfigBuilder().disconnectPump(60, profile);
|
||||||
updateGUI("suspendmenu");
|
updateGUI("suspendmenu");
|
||||||
return true;
|
return true;
|
||||||
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor2h))) {
|
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor2h))) {
|
||||||
MainApp.getConfigBuilder().disconnectPump(120);
|
MainApp.getConfigBuilder().disconnectPump(120, profile);
|
||||||
updateGUI("suspendmenu");
|
updateGUI("suspendmenu");
|
||||||
return true;
|
return true;
|
||||||
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor3h))) {
|
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor3h))) {
|
||||||
MainApp.getConfigBuilder().disconnectPump(180);
|
MainApp.getConfigBuilder().disconnectPump(180, profile);
|
||||||
updateGUI("suspendmenu");
|
updateGUI("suspendmenu");
|
||||||
return true;
|
return true;
|
||||||
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.careportal_profileswitch))) {
|
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.careportal_profileswitch))) {
|
||||||
|
@ -523,8 +584,8 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
boolean xdrip = MainApp.getSpecificPlugin(SourceXdripPlugin.class) != null && MainApp.getSpecificPlugin(SourceXdripPlugin.class).isEnabled(PluginBase.BGSOURCE);
|
boolean xdrip = MainApp.getSpecificPlugin(SourceXdripPlugin.class) != null && MainApp.getSpecificPlugin(SourceXdripPlugin.class).isEnabled(PluginType.BGSOURCE);
|
||||||
boolean g5 = MainApp.getSpecificPlugin(SourceDexcomG5Plugin.class) != null && MainApp.getSpecificPlugin(SourceDexcomG5Plugin.class).isEnabled(PluginBase.BGSOURCE);
|
boolean g5 = MainApp.getSpecificPlugin(SourceDexcomG5Plugin.class) != null && MainApp.getSpecificPlugin(SourceDexcomG5Plugin.class).isEnabled(PluginType.BGSOURCE);
|
||||||
String units = MainApp.getConfigBuilder().getProfileUnits();
|
String units = MainApp.getConfigBuilder().getProfileUnits();
|
||||||
|
|
||||||
FragmentManager manager = getFragmentManager();
|
FragmentManager manager = getFragmentManager();
|
||||||
|
@ -574,24 +635,6 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
if (ConfigBuilderPlugin.getActivePump().isSuspended() || !ConfigBuilderPlugin.getActivePump().isInitialized())
|
if (ConfigBuilderPlugin.getActivePump().isSuspended() || !ConfigBuilderPlugin.getActivePump().isInitialized())
|
||||||
ConfigBuilderPlugin.getCommandQueue().readStatus("RefreshClicked", null);
|
ConfigBuilderPlugin.getCommandQueue().readStatus("RefreshClicked", null);
|
||||||
break;
|
break;
|
||||||
case R.id.overview_showprediction_label:
|
|
||||||
showPredictionCheckbox.toggle();
|
|
||||||
break;
|
|
||||||
case R.id.overview_showbasals_label:
|
|
||||||
showBasalsCheckbox.toggle();
|
|
||||||
break;
|
|
||||||
case R.id.overview_showiob_label:
|
|
||||||
showIobCheckbox.toggle();
|
|
||||||
break;
|
|
||||||
case R.id.overview_showcob_label:
|
|
||||||
showCobCheckbox.toggle();
|
|
||||||
break;
|
|
||||||
case R.id.overview_showdeviations_label:
|
|
||||||
showDeviationsCheckbox.toggle();
|
|
||||||
break;
|
|
||||||
case R.id.overview_showratios_label:
|
|
||||||
showRatiosCheckbox.toggle();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -627,7 +670,9 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onClickAcceptTemp() {
|
private void onClickAcceptTemp() {
|
||||||
if (ConfigBuilderPlugin.getActiveLoop() != null) {
|
Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||||
|
|
||||||
|
if (ConfigBuilderPlugin.getActiveLoop() != null && profile != null) {
|
||||||
ConfigBuilderPlugin.getActiveLoop().invoke("Accept temp button", false);
|
ConfigBuilderPlugin.getActiveLoop().invoke("Accept temp button", false);
|
||||||
final LoopPlugin.LastRun finalLastRun = LoopPlugin.lastRun;
|
final LoopPlugin.LastRun finalLastRun = LoopPlugin.lastRun;
|
||||||
if (finalLastRun != null && finalLastRun.lastAPSRun != null && finalLastRun.constraintsProcessed.isChangeRequested()) {
|
if (finalLastRun != null && finalLastRun.lastAPSRun != null && finalLastRun.constraintsProcessed.isChangeRequested()) {
|
||||||
|
@ -638,11 +683,11 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
hideTempRecommendation();
|
hideTempRecommendation();
|
||||||
clearNotification();
|
clearNotification();
|
||||||
MainApp.getConfigBuilder().applyAPSRequest(finalLastRun.constraintsProcessed, new Callback() {
|
MainApp.getConfigBuilder().applyTBRRequest(finalLastRun.constraintsProcessed, profile, new Callback() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (result.enacted) {
|
if (result.enacted) {
|
||||||
finalLastRun.setByPump = result;
|
finalLastRun.tbrSetByPump = result;
|
||||||
finalLastRun.lastEnact = new Date();
|
finalLastRun.lastEnact = new Date();
|
||||||
finalLastRun.lastOpenModeAccept = new Date();
|
finalLastRun.lastOpenModeAccept = new Date();
|
||||||
NSUpload.uploadDeviceStatus();
|
NSUpload.uploadDeviceStatus();
|
||||||
|
@ -667,10 +712,10 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
void onClickQuickwizard() {
|
void onClickQuickwizard() {
|
||||||
final BgReading actualBg = DatabaseHelper.actualBg();
|
final BgReading actualBg = DatabaseHelper.actualBg();
|
||||||
final Profile profile = MainApp.getConfigBuilder().getProfile();
|
final Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||||
final TempTarget tempTarget = MainApp.getConfigBuilder().getTempTargetFromHistory();
|
final TempTarget tempTarget = TreatmentsPlugin.getPlugin().getTempTargetFromHistory();
|
||||||
|
|
||||||
final QuickWizardEntry quickWizardEntry = OverviewPlugin.getPlugin().quickWizard.getActive();
|
final QuickWizardEntry quickWizardEntry = OverviewPlugin.getPlugin().quickWizard.getActive();
|
||||||
if (quickWizardEntry != null && actualBg != null) {
|
if (quickWizardEntry != null && actualBg != null && profile != null) {
|
||||||
quickWizardButton.setVisibility(View.VISIBLE);
|
quickWizardButton.setVisibility(View.VISIBLE);
|
||||||
final BolusWizard wizard = quickWizardEntry.doCalc(profile, tempTarget, actualBg, true);
|
final BolusWizard wizard = quickWizardEntry.doCalc(profile, tempTarget, actualBg, true);
|
||||||
|
|
||||||
|
@ -700,8 +745,8 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
DecimalFormat formatNumber2decimalplaces = new DecimalFormat("0.00");
|
DecimalFormat formatNumber2decimalplaces = new DecimalFormat("0.00");
|
||||||
String confirmMessage = getString(R.string.entertreatmentquestion);
|
String confirmMessage = getString(R.string.entertreatmentquestion);
|
||||||
|
|
||||||
Double insulinAfterConstraints = MainApp.getConfigBuilder().applyBolusConstraints(wizard.calculatedTotalInsulin);
|
Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(wizard.calculatedTotalInsulin)).value();
|
||||||
Integer carbsAfterConstraints = MainApp.getConfigBuilder().applyCarbsConstraints(quickWizardEntry.carbs());
|
Integer carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(quickWizardEntry.carbs())).value();
|
||||||
|
|
||||||
confirmMessage += "\n" + getString(R.string.bolus) + ": " + formatNumber2decimalplaces.format(insulinAfterConstraints) + "U";
|
confirmMessage += "\n" + getString(R.string.bolus) + ": " + formatNumber2decimalplaces.format(insulinAfterConstraints) + "U";
|
||||||
confirmMessage += "\n" + getString(R.string.carbs) + ": " + carbsAfterConstraints + "g";
|
confirmMessage += "\n" + getString(R.string.carbs) + ": " + carbsAfterConstraints + "g";
|
||||||
|
@ -737,7 +782,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
activeloop.superBolusTo(System.currentTimeMillis() + 2 * 60L * 60 * 1000);
|
activeloop.superBolusTo(System.currentTimeMillis() + 2 * 60L * 60 * 1000);
|
||||||
MainApp.bus().post(new EventRefreshOverview("WizardDialog"));
|
MainApp.bus().post(new EventRefreshOverview("WizardDialog"));
|
||||||
}
|
}
|
||||||
ConfigBuilderPlugin.getCommandQueue().tempBasalPercent(0, 120, true, new Callback() {
|
ConfigBuilderPlugin.getCommandQueue().tempBasalPercent(0, 120, true, profile, new Callback() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
|
@ -946,7 +991,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
if (timeView != null) { //must not exists
|
if (timeView != null) { //must not exists
|
||||||
timeView.setText(DateUtil.timeString(new Date()));
|
timeView.setText(DateUtil.timeString(new Date()));
|
||||||
}
|
}
|
||||||
if (MainApp.getConfigBuilder().getProfile() == null) {// app not initialized yet
|
if (!MainApp.getConfigBuilder().isProfileValid("Overview")) {
|
||||||
pumpStatusView.setText(R.string.noprofileset);
|
pumpStatusView.setText(R.string.noprofileset);
|
||||||
pumpStatusLayout.setVisibility(View.VISIBLE);
|
pumpStatusLayout.setVisibility(View.VISIBLE);
|
||||||
loopStatusLayout.setVisibility(View.GONE);
|
loopStatusLayout.setVisibility(View.GONE);
|
||||||
|
@ -962,16 +1007,9 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
|
|
||||||
final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
|
final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
|
||||||
|
|
||||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
final Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||||
String units = profile.getUnits();
|
|
||||||
|
|
||||||
if (units == null) {
|
|
||||||
pumpStatusView.setText(R.string.noprofileset);
|
|
||||||
pumpStatusLayout.setVisibility(View.VISIBLE);
|
|
||||||
loopStatusLayout.setVisibility(View.GONE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
final String units = profile.getUnits();
|
||||||
final double lowLine = OverviewPlugin.getPlugin().determineLowLine(units);
|
final double lowLine = OverviewPlugin.getPlugin().determineLowLine(units);
|
||||||
final double highLine = OverviewPlugin.getPlugin().determineHighLine(units);
|
final double highLine = OverviewPlugin.getPlugin().determineHighLine(units);
|
||||||
|
|
||||||
|
@ -1000,6 +1038,8 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Constraint<Boolean> closedLoopEnabled = MainApp.getConstraintChecker().isClosedLoopAllowed();
|
||||||
|
|
||||||
// open loop mode
|
// open loop mode
|
||||||
final LoopPlugin.LastRun finalLastRun = LoopPlugin.lastRun;
|
final LoopPlugin.LastRun finalLastRun = LoopPlugin.lastRun;
|
||||||
if (Config.APS && pump.getPumpDescription().isTempBasalCapable) {
|
if (Config.APS && pump.getPumpDescription().isTempBasalCapable) {
|
||||||
|
@ -1020,7 +1060,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
apsModeView.setText(MainApp.sResources.getString(R.string.pumpsuspended));
|
apsModeView.setText(MainApp.sResources.getString(R.string.pumpsuspended));
|
||||||
apsModeView.setTextColor(Color.WHITE);
|
apsModeView.setTextColor(Color.WHITE);
|
||||||
} else if (activeloop != null && activeloop.isEnabled(activeloop.getType())) {
|
} else if (activeloop != null && activeloop.isEnabled(activeloop.getType())) {
|
||||||
if (MainApp.getConfigBuilder().isClosedModeEnabled()) {
|
if (closedLoopEnabled.value()) {
|
||||||
apsModeView.setText(MainApp.sResources.getString(R.string.closedloop));
|
apsModeView.setText(MainApp.sResources.getString(R.string.closedloop));
|
||||||
} else {
|
} else {
|
||||||
apsModeView.setText(MainApp.sResources.getString(R.string.openloop));
|
apsModeView.setText(MainApp.sResources.getString(R.string.openloop));
|
||||||
|
@ -1035,7 +1075,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
}
|
}
|
||||||
|
|
||||||
// temp target
|
// temp target
|
||||||
TempTarget tempTarget = MainApp.getConfigBuilder().getTempTargetFromHistory();
|
TempTarget tempTarget = TreatmentsPlugin.getPlugin().getTempTargetFromHistory();
|
||||||
if (tempTarget != null) {
|
if (tempTarget != null) {
|
||||||
tempTargetView.setTextColor(Color.BLACK);
|
tempTargetView.setTextColor(Color.BLACK);
|
||||||
tempTargetView.setBackgroundColor(MainApp.sResources.getColor(R.color.tempTargetBackground));
|
tempTargetView.setBackgroundColor(MainApp.sResources.getColor(R.color.tempTargetBackground));
|
||||||
|
@ -1050,7 +1090,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
|
|
||||||
// **** Temp button ****
|
// **** Temp button ****
|
||||||
if (acceptTempLayout != null) {
|
if (acceptTempLayout != null) {
|
||||||
boolean showAcceptButton = !MainApp.getConfigBuilder().isClosedModeEnabled(); // Open mode needed
|
boolean showAcceptButton = !closedLoopEnabled.value(); // Open mode needed
|
||||||
showAcceptButton = showAcceptButton && finalLastRun != null && finalLastRun.lastAPSRun != null; // aps result must exist
|
showAcceptButton = showAcceptButton && finalLastRun != null && finalLastRun.lastAPSRun != null; // aps result must exist
|
||||||
showAcceptButton = showAcceptButton && (finalLastRun.lastOpenModeAccept == null || finalLastRun.lastOpenModeAccept.getTime() < finalLastRun.lastAPSRun.getTime()); // never accepted or before last result
|
showAcceptButton = showAcceptButton && (finalLastRun.lastOpenModeAccept == null || finalLastRun.lastOpenModeAccept.getTime() < finalLastRun.lastAPSRun.getTime()); // never accepted or before last result
|
||||||
showAcceptButton = showAcceptButton && finalLastRun.constraintsProcessed.isChangeRequested(); // change is requested
|
showAcceptButton = showAcceptButton && finalLastRun.constraintsProcessed.isChangeRequested(); // change is requested
|
||||||
|
@ -1064,8 +1104,8 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
}
|
}
|
||||||
|
|
||||||
// **** Calibration & CGM buttons ****
|
// **** Calibration & CGM buttons ****
|
||||||
boolean xDripIsBgSource = MainApp.getSpecificPlugin(SourceXdripPlugin.class) != null && MainApp.getSpecificPlugin(SourceXdripPlugin.class).isEnabled(PluginBase.BGSOURCE);
|
boolean xDripIsBgSource = MainApp.getSpecificPlugin(SourceXdripPlugin.class) != null && MainApp.getSpecificPlugin(SourceXdripPlugin.class).isEnabled(PluginType.BGSOURCE);
|
||||||
boolean g5IsBgSource = MainApp.getSpecificPlugin(SourceDexcomG5Plugin.class) != null && MainApp.getSpecificPlugin(SourceDexcomG5Plugin.class).isEnabled(PluginBase.BGSOURCE);
|
boolean g5IsBgSource = MainApp.getSpecificPlugin(SourceDexcomG5Plugin.class) != null && MainApp.getSpecificPlugin(SourceDexcomG5Plugin.class).isEnabled(PluginType.BGSOURCE);
|
||||||
boolean bgAvailable = DatabaseHelper.actualBg() != null;
|
boolean bgAvailable = DatabaseHelper.actualBg() != null;
|
||||||
if (calibrationButton != null) {
|
if (calibrationButton != null) {
|
||||||
if ((xDripIsBgSource || g5IsBgSource) && bgAvailable && SP.getBoolean(R.string.key_show_calibration_button, true)) {
|
if ((xDripIsBgSource || g5IsBgSource) && bgAvailable && SP.getBoolean(R.string.key_show_calibration_button, true)) {
|
||||||
|
@ -1084,18 +1124,18 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final TemporaryBasal activeTemp = MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis());
|
final TemporaryBasal activeTemp = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(System.currentTimeMillis());
|
||||||
String basalText = "";
|
String basalText = "";
|
||||||
if (shorttextmode) {
|
if (shorttextmode) {
|
||||||
if (activeTemp != null) {
|
if (activeTemp != null) {
|
||||||
basalText = "T: " + activeTemp.toStringVeryShort();
|
basalText = "T: " + activeTemp.toStringVeryShort();
|
||||||
} else {
|
} else {
|
||||||
basalText = DecimalFormatter.to2Decimal(MainApp.getConfigBuilder().getProfile().getBasal()) + "U/h";
|
basalText = DecimalFormatter.to2Decimal(profile.getBasal()) + "U/h";
|
||||||
}
|
}
|
||||||
baseBasalView.setOnClickListener(new View.OnClickListener() {
|
baseBasalView.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
String fullText = MainApp.sResources.getString(R.string.pump_basebasalrate_label) + ": " + DecimalFormatter.to2Decimal(MainApp.getConfigBuilder().getProfile().getBasal()) + "U/h\n";
|
String fullText = MainApp.sResources.getString(R.string.pump_basebasalrate_label) + ": " + DecimalFormatter.to2Decimal(profile.getBasal()) + "U/h\n";
|
||||||
if (activeTemp != null) {
|
if (activeTemp != null) {
|
||||||
fullText += MainApp.sResources.getString(R.string.pump_tempbasal_label) + ": " + activeTemp.toStringFull();
|
fullText += MainApp.sResources.getString(R.string.pump_tempbasal_label) + ": " + activeTemp.toStringFull();
|
||||||
}
|
}
|
||||||
|
@ -1108,7 +1148,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
basalText = activeTemp.toStringFull() + " ";
|
basalText = activeTemp.toStringFull() + " ";
|
||||||
}
|
}
|
||||||
if (Config.NSCLIENT || Config.G5UPLOADER)
|
if (Config.NSCLIENT || Config.G5UPLOADER)
|
||||||
basalText += "(" + DecimalFormatter.to2Decimal(MainApp.getConfigBuilder().getProfile().getBasal()) + " U/h)";
|
basalText += "(" + DecimalFormatter.to2Decimal(profile.getBasal()) + " U/h)";
|
||||||
else if (pump.getPumpDescription().isTempBasalCapable) {
|
else if (pump.getPumpDescription().isTempBasalCapable) {
|
||||||
basalText += "(" + DecimalFormatter.to2Decimal(pump.getBaseBasalRate()) + "U/h)";
|
basalText += "(" + DecimalFormatter.to2Decimal(pump.getBaseBasalRate()) + "U/h)";
|
||||||
}
|
}
|
||||||
|
@ -1122,7 +1162,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
|
|
||||||
baseBasalView.setText(basalText);
|
baseBasalView.setText(basalText);
|
||||||
|
|
||||||
final ExtendedBolus extendedBolus = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis());
|
final ExtendedBolus extendedBolus = TreatmentsPlugin.getPlugin().getExtendedBolusFromHistory(System.currentTimeMillis());
|
||||||
String extendedBolusText = "";
|
String extendedBolusText = "";
|
||||||
if (extendedBolusView != null) { // must not exists in all layouts
|
if (extendedBolusView != null) { // must not exists in all layouts
|
||||||
if (shorttextmode) {
|
if (shorttextmode) {
|
||||||
|
@ -1144,7 +1184,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
extendedBolusView.setText(extendedBolusText);
|
extendedBolusView.setText(extendedBolusText);
|
||||||
}
|
}
|
||||||
if (extendedBolusText.equals(""))
|
if (extendedBolusText.equals(""))
|
||||||
extendedBolusView.setVisibility(View.GONE);
|
extendedBolusView.setVisibility(View.INVISIBLE);
|
||||||
else
|
else
|
||||||
extendedBolusView.setVisibility(View.VISIBLE);
|
extendedBolusView.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
@ -1172,7 +1212,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
quickWizardButton.setVisibility(View.VISIBLE);
|
quickWizardButton.setVisibility(View.VISIBLE);
|
||||||
String text = quickWizardEntry.buttonText() + "\n" + DecimalFormatter.to0Decimal(quickWizardEntry.carbs()) + "g";
|
String text = quickWizardEntry.buttonText() + "\n" + DecimalFormatter.to0Decimal(quickWizardEntry.carbs()) + "g";
|
||||||
BolusWizard wizard = quickWizardEntry.doCalc(profile, tempTarget, lastBG, false);
|
BolusWizard wizard = quickWizardEntry.doCalc(profile, tempTarget, lastBG, false);
|
||||||
text += " " + DecimalFormatter.to2Decimal(wizard.calculatedTotalInsulin) + "U";
|
text += " " + DecimalFormatter.toPumpSupportedBolus(wizard.calculatedTotalInsulin) + "U";
|
||||||
quickWizardButton.setText(text);
|
quickWizardButton.setText(text);
|
||||||
if (wizard.calculatedTotalInsulin <= 0)
|
if (wizard.calculatedTotalInsulin <= 0)
|
||||||
quickWizardButton.setVisibility(View.GONE);
|
quickWizardButton.setVisibility(View.GONE);
|
||||||
|
@ -1182,8 +1222,8 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
// **** Various treatment buttons ****
|
// **** Various treatment buttons ****
|
||||||
if (carbsButton != null) {
|
if (carbsButton != null) {
|
||||||
if (SP.getBoolean(R.string.key_show_carbs_button, true)
|
if (SP.getBoolean(R.string.key_show_carbs_button, true)
|
||||||
&& !ConfigBuilderPlugin.getActivePump().getPumpDescription().storesCarbInfo ||
|
&& (!ConfigBuilderPlugin.getActivePump().getPumpDescription().storesCarbInfo ||
|
||||||
(pump.isInitialized() && !pump.isSuspended())) {
|
(pump.isInitialized() && !pump.isSuspended()))) {
|
||||||
carbsButton.setVisibility(View.VISIBLE);
|
carbsButton.setVisibility(View.VISIBLE);
|
||||||
} else {
|
} else {
|
||||||
carbsButton.setVisibility(View.GONE);
|
carbsButton.setVisibility(View.GONE);
|
||||||
|
@ -1225,15 +1265,13 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
flag &= ~Paint.STRIKE_THRU_TEXT_FLAG;
|
flag &= ~Paint.STRIKE_THRU_TEXT_FLAG;
|
||||||
bgView.setPaintFlags(flag);
|
bgView.setPaintFlags(flag);
|
||||||
|
|
||||||
Long agoMsec = System.currentTimeMillis() - lastBG.date;
|
timeAgoView.setText(DateUtil.minAgo(lastBG.date));
|
||||||
int agoMin = (int) (agoMsec / 60d / 1000d);
|
|
||||||
timeAgoView.setText(String.format(MainApp.sResources.getString(R.string.minago), agoMin));
|
|
||||||
|
|
||||||
// iob
|
// iob
|
||||||
MainApp.getConfigBuilder().updateTotalIOBTreatments();
|
TreatmentsPlugin.getPlugin().updateTotalIOBTreatments();
|
||||||
MainApp.getConfigBuilder().updateTotalIOBTempBasals();
|
TreatmentsPlugin.getPlugin().updateTotalIOBTempBasals();
|
||||||
final IobTotal bolusIob = MainApp.getConfigBuilder().getLastCalculationTreatments().round();
|
final IobTotal bolusIob = TreatmentsPlugin.getPlugin().getLastCalculationTreatments().round();
|
||||||
final IobTotal basalIob = MainApp.getConfigBuilder().getLastCalculationTempBasals().round();
|
final IobTotal basalIob = TreatmentsPlugin.getPlugin().getLastCalculationTempBasals().round();
|
||||||
|
|
||||||
if (shorttextmode) {
|
if (shorttextmode) {
|
||||||
String iobtext = DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U";
|
String iobtext = DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U";
|
||||||
|
@ -1269,14 +1307,6 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean predictionsAvailable = finalLastRun != null && finalLastRun.request.hasPredictions;
|
final boolean predictionsAvailable = finalLastRun != null && finalLastRun.request.hasPredictions;
|
||||||
if (predictionsAvailable) {
|
|
||||||
showPredictionCheckbox.setVisibility(View.VISIBLE);
|
|
||||||
showPredictionLabel.setVisibility(View.VISIBLE);
|
|
||||||
} else {
|
|
||||||
showPredictionCheckbox.setVisibility(View.GONE);
|
|
||||||
showPredictionLabel.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// pump status from ns
|
// pump status from ns
|
||||||
if (pumpDeviceStatusView != null) {
|
if (pumpDeviceStatusView != null) {
|
||||||
pumpDeviceStatusView.setText(NSDeviceStatus.getInstance().getPumpStatus());
|
pumpDeviceStatusView.setText(NSDeviceStatus.getInstance().getPumpStatus());
|
||||||
|
@ -1327,7 +1357,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
final long toTime;
|
final long toTime;
|
||||||
final long fromTime;
|
final long fromTime;
|
||||||
final long endTime;
|
final long endTime;
|
||||||
if (predictionsAvailable && showPredictionCheckbox.isChecked()) {
|
if (predictionsAvailable && SP.getBoolean("showprediction", false)) {
|
||||||
int predHours = (int) (Math.ceil(finalLastRun.constraintsProcessed.getLatestPredictionsTime() - System.currentTimeMillis()) / (60 * 60 * 1000));
|
int predHours = (int) (Math.ceil(finalLastRun.constraintsProcessed.getLatestPredictionsTime() - System.currentTimeMillis()) / (60 * 60 * 1000));
|
||||||
predHours = Math.min(2, predHours);
|
predHours = Math.min(2, predHours);
|
||||||
predHours = Math.max(0, predHours);
|
predHours = Math.max(0, predHours);
|
||||||
|
@ -1354,7 +1384,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
graphData.addInRangeArea(fromTime, endTime, lowLine, highLine);
|
graphData.addInRangeArea(fromTime, endTime, lowLine, highLine);
|
||||||
|
|
||||||
// **** BG ****
|
// **** BG ****
|
||||||
if (predictionsAvailable && showPredictionCheckbox.isChecked())
|
if (predictionsAvailable && SP.getBoolean("showprediction", false))
|
||||||
graphData.addBgReadings(fromTime, toTime, lowLine, highLine, finalLastRun.constraintsProcessed);
|
graphData.addBgReadings(fromTime, toTime, lowLine, highLine, finalLastRun.constraintsProcessed);
|
||||||
else
|
else
|
||||||
graphData.addBgReadings(fromTime, toTime, lowLine, highLine, null);
|
graphData.addBgReadings(fromTime, toTime, lowLine, highLine, null);
|
||||||
|
@ -1366,12 +1396,12 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
graphData.addTreatments(fromTime, endTime);
|
graphData.addTreatments(fromTime, endTime);
|
||||||
|
|
||||||
// add basal data
|
// add basal data
|
||||||
if (pump.getPumpDescription().isTempBasalCapable && showBasalsCheckbox.isChecked()) {
|
if (pump.getPumpDescription().isTempBasalCapable && SP.getBoolean("showbasals", true)) {
|
||||||
graphData.addBasals(fromTime, now, lowLine / graphData.maxY / 1.2d);
|
graphData.addBasals(fromTime, now, lowLine / graphData.maxY / 1.2d);
|
||||||
}
|
}
|
||||||
|
|
||||||
// add target line
|
// add target line
|
||||||
graphData.addTargetLine(fromTime, toTime);
|
graphData.addTargetLine(fromTime, toTime, profile);
|
||||||
|
|
||||||
// **** NOW line ****
|
// **** NOW line ****
|
||||||
graphData.addNowLine(now);
|
graphData.addNowLine(now);
|
||||||
|
@ -1387,25 +1417,25 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
boolean useRatioForScale = false;
|
boolean useRatioForScale = false;
|
||||||
boolean useDSForScale = false;
|
boolean useDSForScale = false;
|
||||||
|
|
||||||
if (showIobCheckbox.isChecked()) {
|
if (SP.getBoolean("showiob", true)) {
|
||||||
useIobForScale = true;
|
useIobForScale = true;
|
||||||
} else if (showCobCheckbox.isChecked()) {
|
} else if (SP.getBoolean("showcob", true)) {
|
||||||
useCobForScale = true;
|
useCobForScale = true;
|
||||||
} else if (showDeviationsCheckbox.isChecked()) {
|
} else if (SP.getBoolean("showdeviations", false)) {
|
||||||
useDevForScale = true;
|
useDevForScale = true;
|
||||||
} else if (showRatiosCheckbox.isChecked()) {
|
} else if (SP.getBoolean("showratios", false)) {
|
||||||
useRatioForScale = true;
|
useRatioForScale = true;
|
||||||
} else if (Config.displayDeviationSlope) {
|
} else if (Config.displayDeviationSlope) {
|
||||||
useDSForScale = true;
|
useDSForScale = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (showIobCheckbox.isChecked())
|
if (SP.getBoolean("showiob", true))
|
||||||
secondGraphData.addIob(fromTime, now, useIobForScale, 1d);
|
secondGraphData.addIob(fromTime, now, useIobForScale, 1d);
|
||||||
if (showCobCheckbox.isChecked())
|
if (SP.getBoolean("showcob", true))
|
||||||
secondGraphData.addCob(fromTime, now, useCobForScale, useCobForScale ? 1d : 0.5d);
|
secondGraphData.addCob(fromTime, now, useCobForScale, useCobForScale ? 1d : 0.5d);
|
||||||
if (showDeviationsCheckbox.isChecked())
|
if (SP.getBoolean("showdeviations", false))
|
||||||
secondGraphData.addDeviations(fromTime, now, useDevForScale, 1d);
|
secondGraphData.addDeviations(fromTime, now, useDevForScale, 1d);
|
||||||
if (showRatiosCheckbox.isChecked())
|
if (SP.getBoolean("showratios", false))
|
||||||
secondGraphData.addRatio(fromTime, now, useRatioForScale, 1d);
|
secondGraphData.addRatio(fromTime, now, useRatioForScale, 1d);
|
||||||
if (Config.displayDeviationSlope)
|
if (Config.displayDeviationSlope)
|
||||||
secondGraphData.addDeviationSlope(fromTime, now, useDSForScale, 1d);
|
secondGraphData.addDeviationSlope(fromTime, now, useDSForScale, 1d);
|
||||||
|
@ -1421,7 +1451,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
activity.runOnUiThread(new Runnable() {
|
activity.runOnUiThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (showIobCheckbox.isChecked() || showCobCheckbox.isChecked() || showDeviationsCheckbox.isChecked() || showRatiosCheckbox.isChecked() || Config.displayDeviationSlope) {
|
if (SP.getBoolean("showiob", true) || SP.getBoolean("showcob", true) || SP.getBoolean("showdeviations", false) || SP.getBoolean("showratios", false) || Config.displayDeviationSlope) {
|
||||||
iobGraph.setVisibility(View.VISIBLE);
|
iobGraph.setVisibility(View.VISIBLE);
|
||||||
} else {
|
} else {
|
||||||
iobGraph.setVisibility(View.GONE);
|
iobGraph.setVisibility(View.GONE);
|
||||||
|
|
|
@ -13,6 +13,8 @@ import info.nightscout.androidaps.data.Profile;
|
||||||
import info.nightscout.androidaps.data.QuickWizard;
|
import info.nightscout.androidaps.data.QuickWizard;
|
||||||
import info.nightscout.androidaps.events.EventRefreshOverview;
|
import info.nightscout.androidaps.events.EventRefreshOverview;
|
||||||
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.plugins.Overview.events.EventDismissNotification;
|
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.NotificationStore;
|
import info.nightscout.androidaps.plugins.Overview.notifications.NotificationStore;
|
||||||
|
@ -21,7 +23,7 @@ import info.nightscout.utils.SP;
|
||||||
/**
|
/**
|
||||||
* Created by mike on 05.08.2016.
|
* Created by mike on 05.08.2016.
|
||||||
*/
|
*/
|
||||||
public class OverviewPlugin implements PluginBase {
|
public class OverviewPlugin extends PluginBase {
|
||||||
private static Logger log = LoggerFactory.getLogger(OverviewPlugin.class);
|
private static Logger log = LoggerFactory.getLogger(OverviewPlugin.class);
|
||||||
|
|
||||||
private static OverviewPlugin overviewPlugin = new OverviewPlugin();
|
private static OverviewPlugin overviewPlugin = new OverviewPlugin();
|
||||||
|
@ -40,82 +42,34 @@ public class OverviewPlugin implements PluginBase {
|
||||||
public NotificationStore notificationStore = new NotificationStore();
|
public NotificationStore notificationStore = new NotificationStore();
|
||||||
|
|
||||||
public OverviewPlugin() {
|
public OverviewPlugin() {
|
||||||
|
super(new PluginDescription()
|
||||||
|
.mainType(PluginType.GENERAL)
|
||||||
|
.fragmentClass(OverviewFragment.class.getName())
|
||||||
|
.alwayVisible(true)
|
||||||
|
.alwaysEnabled(true)
|
||||||
|
.pluginName(R.string.overview)
|
||||||
|
.shortName(R.string.overview_shortname)
|
||||||
|
.preferencesId(R.xml.pref_overview)
|
||||||
|
);
|
||||||
String storedData = SP.getString("QuickWizard", "[]");
|
String storedData = SP.getString("QuickWizard", "[]");
|
||||||
try {
|
try {
|
||||||
quickWizard.setData(new JSONArray(storedData));
|
quickWizard.setData(new JSONArray(storedData));
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStart() {
|
||||||
MainApp.bus().register(this);
|
MainApp.bus().register(this);
|
||||||
|
super.onStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getFragmentClass() {
|
protected void onStop() {
|
||||||
return OverviewFragment.class.getName();
|
MainApp.bus().unregister(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return MainApp.instance().getString(R.string.overview);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getNameShort() {
|
|
||||||
String name = MainApp.sResources.getString(R.string.overview_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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isVisibleInTabs(int type) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canBeHidden(int type) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasFragment() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean showInList(int type) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setFragmentEnabled(int type, boolean fragmentEnabled) {
|
|
||||||
// Always enabled
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setFragmentVisible(int type, boolean fragmentVisible) {
|
|
||||||
// Always visible
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getPreferencesId() {
|
|
||||||
return R.xml.pref_overview;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getType() {
|
|
||||||
return PluginBase.GENERAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onStatusEvent(final EventNewNotification n) {
|
public void onStatusEvent(final EventNewNotification n) {
|
||||||
notificationStore.add(n.notification);
|
notificationStore.add(n.notification);
|
||||||
|
@ -128,14 +82,6 @@ public class OverviewPlugin implements PluginBase {
|
||||||
MainApp.bus().post(new EventRefreshOverview("EventDismissNotification"));
|
MainApp.bus().post(new EventRefreshOverview("EventDismissNotification"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public double determineHighLine() {
|
|
||||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
|
||||||
if (profile == null) {
|
|
||||||
return bgTargetHigh;
|
|
||||||
}
|
|
||||||
return determineHighLine(profile.getUnits());
|
|
||||||
}
|
|
||||||
|
|
||||||
public double determineHighLine(String units) {
|
public double determineHighLine(String units) {
|
||||||
double highLineSetting = SP.getDouble("high_mark", Profile.fromMgdlToUnits(OverviewPlugin.bgTargetHigh, units));
|
double highLineSetting = SP.getDouble("high_mark", Profile.fromMgdlToUnits(OverviewPlugin.bgTargetHigh, units));
|
||||||
if (highLineSetting < 1)
|
if (highLineSetting < 1)
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue