Merge Upstream
This commit is contained in:
commit
0ea13b5671
334 changed files with 13264 additions and 9371 deletions
11
.gitignore
vendored
11
.gitignore
vendored
|
@ -6,10 +6,17 @@
|
||||||
/captures
|
/captures
|
||||||
*.apk
|
*.apk
|
||||||
build/
|
build/
|
||||||
.idea/
|
.idea/*
|
||||||
|
!.idea/codeStyles/
|
||||||
app/src/main/jniLibs
|
app/src/main/jniLibs
|
||||||
full/
|
full/
|
||||||
debug/
|
debug/
|
||||||
release/
|
release/
|
||||||
app/com.crashlytics.settings.json
|
app/com.crashlytics.settings.json
|
||||||
app/session_analytics.tap
|
app/session_analytics.tap
|
||||||
|
.project
|
||||||
|
.settings/org.eclipse.buildship.core.prefs
|
||||||
|
app/.classpath
|
||||||
|
app/.settings/org.eclipse.buildship.core.prefs
|
||||||
|
wear/.classpath
|
||||||
|
wear/.settings/org.eclipse.buildship.core.prefs
|
||||||
|
|
137
.idea/codeStyles/Project.xml
Normal file
137
.idea/codeStyles/Project.xml
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<code_scheme name="Project" version="173">
|
||||||
|
<option name="AUTODETECT_INDENTS" value="false" />
|
||||||
|
<AndroidXmlCodeStyleSettings>
|
||||||
|
<option name="ARRANGEMENT_SETTINGS_MIGRATED_TO_191" value="true" />
|
||||||
|
</AndroidXmlCodeStyleSettings>
|
||||||
|
<JetCodeStyleSettings>
|
||||||
|
<option name="ALIGN_IN_COLUMNS_CASE_BRANCH" value="true" />
|
||||||
|
<option name="NAME_COUNT_TO_USE_STAR_IMPORT" value="6" />
|
||||||
|
<option name="NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS" value="6" />
|
||||||
|
<option name="BLANK_LINES_AROUND_BLOCK_WHEN_BRANCHES" value="1" />
|
||||||
|
</JetCodeStyleSettings>
|
||||||
|
<codeStyleSettings language="XML">
|
||||||
|
<indentOptions>
|
||||||
|
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||||
|
</indentOptions>
|
||||||
|
<arrangement>
|
||||||
|
<rules>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>xmlns:android</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>xmlns:.*</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
<order>BY_NAME</order>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>.*:id</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>.*:name</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>name</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>style</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>.*</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
<order>BY_NAME</order>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>.*</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
<order>ANDROID_ATTRIBUTE_ORDER</order>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>.*</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>.*</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
<order>BY_NAME</order>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
</rules>
|
||||||
|
</arrangement>
|
||||||
|
</codeStyleSettings>
|
||||||
|
<codeStyleSettings language="kotlin">
|
||||||
|
<option name="LINE_COMMENT_AT_FIRST_COLUMN" value="false" />
|
||||||
|
<option name="LINE_COMMENT_ADD_SPACE" value="true" />
|
||||||
|
<option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1" />
|
||||||
|
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
|
||||||
|
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1" />
|
||||||
|
<option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1" />
|
||||||
|
<indentOptions>
|
||||||
|
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||||
|
</indentOptions>
|
||||||
|
</codeStyleSettings>
|
||||||
|
</code_scheme>
|
||||||
|
</component>
|
5
.idea/codeStyles/codeStyleConfig.xml
Normal file
5
.idea/codeStyles/codeStyleConfig.xml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<state>
|
||||||
|
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||||
|
</state>
|
||||||
|
</component>
|
|
@ -226,6 +226,8 @@ dependencies {
|
||||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||||
implementation 'com.google.android.gms:play-services-wearable:17.0.0'
|
implementation 'com.google.android.gms:play-services-wearable:17.0.0'
|
||||||
implementation 'com.google.firebase:firebase-core:17.2.1'
|
implementation 'com.google.firebase:firebase-core:17.2.1'
|
||||||
|
implementation 'com.google.firebase:firebase-auth:19.2.0'
|
||||||
|
implementation 'com.google.firebase:firebase-database:19.2.0'
|
||||||
implementation('com.crashlytics.sdk.android:crashlytics:2.10.1@aar') {
|
implementation('com.crashlytics.sdk.android:crashlytics:2.10.1@aar') {
|
||||||
transitive = true;
|
transitive = true;
|
||||||
}
|
}
|
||||||
|
@ -264,7 +266,10 @@ dependencies {
|
||||||
exclude group: "org.json", module: "json"
|
exclude group: "org.json", module: "json"
|
||||||
}
|
}
|
||||||
implementation "com.google.code.gson:gson:2.8.6"
|
implementation "com.google.code.gson:gson:2.8.6"
|
||||||
implementation "com.google.guava:guava:24.1-jre"
|
implementation ("com.google.guava:guava:24.1-jre") {
|
||||||
|
exclude group: "com.google.code.findbugs", module: "jsr305"
|
||||||
|
}
|
||||||
|
implementation 'com.google.code.findbugs:jsr305:3.0.2'
|
||||||
|
|
||||||
implementation "net.danlew:android.joda:2.10.3"
|
implementation "net.danlew:android.joda:2.10.3"
|
||||||
|
|
||||||
|
@ -282,6 +287,7 @@ dependencies {
|
||||||
testImplementation "joda-time:joda-time:2.10.5"
|
testImplementation "joda-time:joda-time:2.10.5"
|
||||||
testImplementation("com.google.truth:truth:0.39") {
|
testImplementation("com.google.truth:truth:0.39") {
|
||||||
exclude group: "com.google.guava", module: "guava"
|
exclude group: "com.google.guava", module: "guava"
|
||||||
|
exclude group: "com.google.code.findbugs", module: "jsr305"
|
||||||
}
|
}
|
||||||
testImplementation "org.skyscreamer:jsonassert:1.5.0"
|
testImplementation "org.skyscreamer:jsonassert:1.5.0"
|
||||||
testImplementation "org.hamcrest:hamcrest-all:1.3"
|
testImplementation "org.hamcrest:hamcrest-all:1.3"
|
||||||
|
@ -291,9 +297,6 @@ dependencies {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
androidTestImplementation "org.mockito:mockito-core:2.8.47"
|
|
||||||
androidTestImplementation "com.google.dexmaker:dexmaker:${dexmakerVersion}"
|
|
||||||
androidTestImplementation "com.google.dexmaker:dexmaker-mockito:${dexmakerVersion}"
|
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||||
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
|
||||||
|
|
||||||
|
@ -305,6 +308,13 @@ dependencies {
|
||||||
implementation "com.squareup.retrofit2:adapter-rxjava2:2.6.2"
|
implementation "com.squareup.retrofit2:adapter-rxjava2:2.6.2"
|
||||||
implementation "com.squareup.retrofit2:converter-gson:2.6.2"
|
implementation "com.squareup.retrofit2:converter-gson:2.6.2"
|
||||||
|
|
||||||
|
// Phone checker
|
||||||
|
implementation 'com.scottyab:rootbeer-lib:0.0.7'
|
||||||
|
|
||||||
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0-alpha03'
|
||||||
|
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
|
||||||
|
androidTestImplementation 'androidx.test:rules:1.3.0-alpha03'
|
||||||
|
androidTestImplementation 'com.google.code.findbugs:jsr305:3.0.2'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,12 @@
|
||||||
"package_name": "info.nightscout.aapspumpcontrol"
|
"package_name": "info.nightscout.aapspumpcontrol"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"oauth_client": [],
|
"oauth_client": [
|
||||||
|
{
|
||||||
|
"client_id": "477603612366-a925drvlvs7qn7gt73r585erbqto8c79.apps.googleusercontent.com",
|
||||||
|
"client_type": 3
|
||||||
|
}
|
||||||
|
],
|
||||||
"api_key": [
|
"api_key": [
|
||||||
{
|
{
|
||||||
"current_key": "AIzaSyDcZpDRMaGjdhihXp531cVYM6LkEL8KbgM"
|
"current_key": "AIzaSyDcZpDRMaGjdhihXp531cVYM6LkEL8KbgM"
|
||||||
|
@ -37,7 +42,12 @@
|
||||||
"package_name": "info.nightscout.androidaps"
|
"package_name": "info.nightscout.androidaps"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"oauth_client": [],
|
"oauth_client": [
|
||||||
|
{
|
||||||
|
"client_id": "477603612366-a925drvlvs7qn7gt73r585erbqto8c79.apps.googleusercontent.com",
|
||||||
|
"client_type": 3
|
||||||
|
}
|
||||||
|
],
|
||||||
"api_key": [
|
"api_key": [
|
||||||
{
|
{
|
||||||
"current_key": "AIzaSyDcZpDRMaGjdhihXp531cVYM6LkEL8KbgM"
|
"current_key": "AIzaSyDcZpDRMaGjdhihXp531cVYM6LkEL8KbgM"
|
||||||
|
@ -61,7 +71,12 @@
|
||||||
"package_name": "info.nightscout.nsclient"
|
"package_name": "info.nightscout.nsclient"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"oauth_client": [],
|
"oauth_client": [
|
||||||
|
{
|
||||||
|
"client_id": "477603612366-a925drvlvs7qn7gt73r585erbqto8c79.apps.googleusercontent.com",
|
||||||
|
"client_type": 3
|
||||||
|
}
|
||||||
|
],
|
||||||
"api_key": [
|
"api_key": [
|
||||||
{
|
{
|
||||||
"current_key": "AIzaSyDcZpDRMaGjdhihXp531cVYM6LkEL8KbgM"
|
"current_key": "AIzaSyDcZpDRMaGjdhihXp531cVYM6LkEL8KbgM"
|
||||||
|
@ -85,7 +100,12 @@
|
||||||
"package_name": "info.nightscout.nsclient2"
|
"package_name": "info.nightscout.nsclient2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"oauth_client": [],
|
"oauth_client": [
|
||||||
|
{
|
||||||
|
"client_id": "477603612366-a925drvlvs7qn7gt73r585erbqto8c79.apps.googleusercontent.com",
|
||||||
|
"client_type": 3
|
||||||
|
}
|
||||||
|
],
|
||||||
"api_key": [
|
"api_key": [
|
||||||
{
|
{
|
||||||
"current_key": "AIzaSyDcZpDRMaGjdhihXp531cVYM6LkEL8KbgM"
|
"current_key": "AIzaSyDcZpDRMaGjdhihXp531cVYM6LkEL8KbgM"
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
package info.nightscout.androidaps;
|
|
||||||
|
|
||||||
import android.app.Application;
|
|
||||||
import android.test.ApplicationTestCase;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
|
|
||||||
*/
|
|
||||||
public class ApplicationTest extends ApplicationTestCase<Application> {
|
|
||||||
public ApplicationTest() {
|
|
||||||
super(Application.class);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
package info.nightscout.androidaps
|
||||||
|
|
||||||
|
import androidx.test.espresso.ViewAction
|
||||||
|
import androidx.test.espresso.ViewInteraction
|
||||||
|
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||||
|
import androidx.test.espresso.matcher.ViewMatchers
|
||||||
|
|
||||||
|
fun ViewInteraction.isDisplayed(): Boolean {
|
||||||
|
try {
|
||||||
|
check(matches(ViewMatchers.isDisplayed()))
|
||||||
|
return true
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun ViewInteraction.waitAndPerform(viewActions: ViewAction): ViewInteraction? {
|
||||||
|
val startTime = System.currentTimeMillis()
|
||||||
|
while (!isDisplayed()) {
|
||||||
|
Thread.sleep(100)
|
||||||
|
if (System.currentTimeMillis() - startTime >= 5000) {
|
||||||
|
throw AssertionError("View not visible after 5000 milliseconds")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return perform(viewActions)
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,222 @@
|
||||||
|
package info.nightscout.androidaps
|
||||||
|
|
||||||
|
|
||||||
|
import android.os.SystemClock
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.test.espresso.Espresso.onData
|
||||||
|
import androidx.test.espresso.Espresso.onView
|
||||||
|
import androidx.test.espresso.action.ViewActions
|
||||||
|
import androidx.test.espresso.action.ViewActions.click
|
||||||
|
import androidx.test.espresso.action.ViewActions.scrollTo
|
||||||
|
import androidx.test.espresso.matcher.ViewMatchers.*
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import androidx.test.filters.LargeTest
|
||||||
|
import androidx.test.rule.ActivityTestRule
|
||||||
|
import androidx.test.rule.GrantPermissionRule
|
||||||
|
import info.nightscout.androidaps.data.Profile
|
||||||
|
import info.nightscout.androidaps.interfaces.PluginType
|
||||||
|
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
|
||||||
|
import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin
|
||||||
|
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
|
||||||
|
import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesPlugin
|
||||||
|
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin
|
||||||
|
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
|
||||||
|
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin
|
||||||
|
import info.nightscout.androidaps.plugins.source.RandomBgPlugin
|
||||||
|
import info.nightscout.androidaps.setupwizard.SetupWizardActivity
|
||||||
|
import info.nightscout.androidaps.utils.HardLimits
|
||||||
|
import info.nightscout.androidaps.utils.SP
|
||||||
|
import info.nightscout.androidaps.utils.isRunningTest
|
||||||
|
import org.hamcrest.CoreMatchers.allOf
|
||||||
|
import org.hamcrest.Description
|
||||||
|
import org.hamcrest.Matcher
|
||||||
|
import org.hamcrest.Matchers
|
||||||
|
import org.hamcrest.TypeSafeMatcher
|
||||||
|
import org.junit.Assert
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Rule
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
|
||||||
|
@LargeTest
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class SetupWizardActivityTest {
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
@JvmField
|
||||||
|
var mActivityTestRule = ActivityTestRule(SetupWizardActivity::class.java)
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
@JvmField
|
||||||
|
var mGrantPermissionRule =
|
||||||
|
GrantPermissionRule.grant(
|
||||||
|
android.Manifest.permission.ACCESS_FINE_LOCATION,
|
||||||
|
android.Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS,
|
||||||
|
android.Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||||
|
)
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun clear() {
|
||||||
|
SP.clear()
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
|
||||||
|
To run from command line
|
||||||
|
gradlew connectedFullDebugAndroidTest
|
||||||
|
|
||||||
|
do not run when your production phone is connected !!!
|
||||||
|
|
||||||
|
do this before for running in emulator
|
||||||
|
adb shell settings put global window_animation_scale 0 &
|
||||||
|
adb shell settings put global transition_animation_scale 0 &
|
||||||
|
adb shell settings put global animator_duration_scale 0 &
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun setupWizardActivityTest() {
|
||||||
|
Assert.assertTrue(isRunningTest())
|
||||||
|
// Welcome page
|
||||||
|
onView(withId(R.id.next_button)).perform(click())
|
||||||
|
// Language selection
|
||||||
|
onView(withText("English")).perform(scrollTo(), click())
|
||||||
|
onView(withId(R.id.next_button)).waitAndPerform(click())
|
||||||
|
// Agreement page
|
||||||
|
onView(withText("I UNDERSTAND AND AGREE")).perform(scrollTo(), click())
|
||||||
|
onView(withId(R.id.next_button)).waitAndPerform(click())
|
||||||
|
// Loction permission
|
||||||
|
var askButton = onView(withText("Ask for permission"))
|
||||||
|
if (askButton.isDisplayed()) {
|
||||||
|
askButton.perform(scrollTo(), click())
|
||||||
|
onView(withId(R.id.next_button)).waitAndPerform(click())
|
||||||
|
}
|
||||||
|
// Store permission
|
||||||
|
askButton = onView(withText("Ask for permission"))
|
||||||
|
if (askButton.isDisplayed()) {
|
||||||
|
askButton.perform(scrollTo(), click())
|
||||||
|
onView(withText("OK")).perform(click())
|
||||||
|
onView(withId(R.id.next_button)).waitAndPerform(click())
|
||||||
|
}
|
||||||
|
// Units selection
|
||||||
|
onView(withText("mmol/L")).perform(scrollTo(), click())
|
||||||
|
onView(withId(R.id.next_button)).perform(click())
|
||||||
|
// Display target selection
|
||||||
|
onView(withText("4.2")).perform(scrollTo(), ViewActions.replaceText("5"))
|
||||||
|
onView(withText("10.0")).perform(scrollTo(), ViewActions.replaceText("11"))
|
||||||
|
onView(withId(R.id.next_button)).perform(click())
|
||||||
|
// NSClient
|
||||||
|
onView(withId(R.id.next_button)).perform(click())
|
||||||
|
// Age selection
|
||||||
|
onView(withText("Adult")).perform(scrollTo(), click())
|
||||||
|
onView(withId(R.id.next_button)).waitAndPerform(click())
|
||||||
|
// Insulin selection
|
||||||
|
onView(withText("Ultra-Rapid Oref")).perform(scrollTo(), click())
|
||||||
|
onView(withId(R.id.next_button)).waitAndPerform(click())
|
||||||
|
// BG source selection
|
||||||
|
onView(withText("Random BG")).perform(scrollTo(), click())
|
||||||
|
onView(withId(R.id.next_button)).waitAndPerform(click())
|
||||||
|
// Profile selection
|
||||||
|
onView(withText("Local Profile")).perform(scrollTo(), click())
|
||||||
|
onView(withId(R.id.next_button)).waitAndPerform(click())
|
||||||
|
// Local profile - DIA
|
||||||
|
onView(withTagValue(Matchers.`is`("LP_DIA"))).perform(scrollTo(), ViewActions.replaceText("6.0"))
|
||||||
|
// Local profile - IC
|
||||||
|
onView(withId(R.id.ic_tab)).perform(scrollTo(), click())
|
||||||
|
onView(Matchers.allOf(withTagValue(Matchers.`is`("IC-1-0")), isDisplayed()))
|
||||||
|
.perform(ViewActions.replaceText("2"), ViewActions.closeSoftKeyboard())
|
||||||
|
// Local profile - ISF
|
||||||
|
onView(withId(R.id.isf_tab)).perform(scrollTo(), click())
|
||||||
|
onView(Matchers.allOf(withTagValue(Matchers.`is`("ISF-1-0")), isDisplayed()))
|
||||||
|
.perform(ViewActions.replaceText("3"), ViewActions.closeSoftKeyboard())
|
||||||
|
// Local profile - BAS
|
||||||
|
onView(withId(R.id.basal_tab)).perform(scrollTo(), click())
|
||||||
|
onView(childAtPosition(Matchers.allOf(withId(R.id.localprofile_basal), childAtPosition(withClassName(Matchers.`is`("android.widget.LinearLayout")), 6)), 2))
|
||||||
|
.perform(scrollTo(), click())
|
||||||
|
onView(Matchers.allOf(withTagValue(Matchers.`is`("BASAL-1-0")), isDisplayed()))
|
||||||
|
.perform(ViewActions.replaceText("1.1"), ViewActions.closeSoftKeyboard())
|
||||||
|
onView(Matchers.allOf(withTagValue(Matchers.`is`("BASAL-1-1")), isDisplayed()))
|
||||||
|
.perform(ViewActions.replaceText("1.2"), ViewActions.closeSoftKeyboard())
|
||||||
|
onView(Matchers.allOf(withId(R.id.timelistedit_time), childAtPosition(childAtPosition(withId(R.id.localprofile_basal), 2), 0)))
|
||||||
|
.perform(scrollTo(), click())
|
||||||
|
onData(Matchers.anything()).inAdapterView(childAtPosition(withClassName(Matchers.`is`("android.widget.PopupWindow\$PopupBackgroundView")), 0)).atPosition(13)
|
||||||
|
.perform(click())
|
||||||
|
// Local profile - TARGET
|
||||||
|
onView(withId(R.id.target_tab)).perform(scrollTo(), click())
|
||||||
|
onView(Matchers.allOf(withTagValue(Matchers.`is`("TARGET-1-0")), isDisplayed()))
|
||||||
|
.perform(ViewActions.replaceText("6"), ViewActions.closeSoftKeyboard())
|
||||||
|
onView(Matchers.allOf(withTagValue(Matchers.`is`("TARGET-2-0")), isDisplayed()))
|
||||||
|
.perform(ViewActions.replaceText("6.5"), ViewActions.closeSoftKeyboard())
|
||||||
|
onView(withText("Save")).perform(scrollTo(), click())
|
||||||
|
onView(Matchers.allOf(withId(R.id.localprofile_profileswitch), isDisplayed()))
|
||||||
|
.perform(scrollTo(), click())
|
||||||
|
onView(allOf(withId(R.id.ok), isDisplayed())).perform(click())
|
||||||
|
onView(Matchers.allOf(withText("OK"), isDisplayed())).perform(click())
|
||||||
|
onView(withId(R.id.next_button)).waitAndPerform(click())
|
||||||
|
// Profile switch
|
||||||
|
askButton = onView(withText("Do Profile Switch"))
|
||||||
|
if (askButton.isDisplayed()) {
|
||||||
|
askButton.perform(scrollTo(), click())
|
||||||
|
onView(allOf(withId(R.id.ok), isDisplayed())).perform(click())
|
||||||
|
onView(Matchers.allOf(withText("OK"), isDisplayed())).perform(click())
|
||||||
|
while (ProfileFunctions.getInstance().profile == null) SystemClock.sleep(100)
|
||||||
|
onView(withId(R.id.next_button)).waitAndPerform(click())
|
||||||
|
}
|
||||||
|
// Pump
|
||||||
|
onView(withText("Virtual Pump")).perform(scrollTo(), click())
|
||||||
|
onView(withId(R.id.next_button)).waitAndPerform(click())
|
||||||
|
// APS
|
||||||
|
onView(withText("OpenAPS SMB")).perform(scrollTo(), click())
|
||||||
|
onView(withId(R.id.next_button)).waitAndPerform(click())
|
||||||
|
// Open Closed Loop
|
||||||
|
onView(withText("Closed Loop")).perform(scrollTo(), click())
|
||||||
|
onView(withId(R.id.next_button)).waitAndPerform(click())
|
||||||
|
// Loop
|
||||||
|
askButton = onView(withText("Enable loop"))
|
||||||
|
if (askButton.isDisplayed()) {
|
||||||
|
askButton.perform(scrollTo(), click())
|
||||||
|
onView(withId(R.id.next_button)).waitAndPerform(click())
|
||||||
|
}
|
||||||
|
// Sensitivity
|
||||||
|
onView(withText("Sensitivity Oref1")).perform(scrollTo(), click())
|
||||||
|
onView(withId(R.id.next_button)).waitAndPerform(click())
|
||||||
|
// Objectives
|
||||||
|
onView(allOf(withText("Start"), isDisplayed())).perform(scrollTo(), click())
|
||||||
|
onView(withId(R.id.finish_button)).waitAndPerform(click())
|
||||||
|
|
||||||
|
// Verify settings
|
||||||
|
Assert.assertEquals(Constants.MMOL, ProfileFunctions.getSystemUnits())
|
||||||
|
Assert.assertEquals(17.0, HardLimits.maxBolus(), 0.0001) // Adult
|
||||||
|
Assert.assertTrue(RandomBgPlugin.isEnabled(PluginType.BGSOURCE))
|
||||||
|
Assert.assertTrue(LocalProfilePlugin.isEnabled(PluginType.PROFILE))
|
||||||
|
val p = ProfileFunctions.getInstance().profile
|
||||||
|
Assert.assertNotNull(p)
|
||||||
|
Assert.assertEquals(2.0, p!!.ic, 0.0001)
|
||||||
|
Assert.assertEquals(3.0 * Constants.MMOLL_TO_MGDL, p.isfMgdl, 0.0001)
|
||||||
|
Assert.assertEquals(1.1, p.getBasalTimeFromMidnight(0), 0.0001)
|
||||||
|
Assert.assertEquals(6.0 * Constants.MMOLL_TO_MGDL, p.targetLowMgdl, 0.0001)
|
||||||
|
Assert.assertTrue(VirtualPumpPlugin.getPlugin().isEnabled(PluginType.PUMP))
|
||||||
|
Assert.assertTrue(OpenAPSSMBPlugin.getPlugin().isEnabled(PluginType.APS))
|
||||||
|
Assert.assertTrue(LoopPlugin.getPlugin().isEnabled(PluginType.LOOP))
|
||||||
|
Assert.assertTrue(SensitivityOref1Plugin.getPlugin().isEnabled(PluginType.SENSITIVITY))
|
||||||
|
Assert.assertTrue(ObjectivesPlugin.objectives[0].isStarted)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun childAtPosition(
|
||||||
|
parentMatcher: Matcher<View>, position: Int): Matcher<View> {
|
||||||
|
|
||||||
|
return object : TypeSafeMatcher<View>() {
|
||||||
|
override fun describeTo(description: Description) {
|
||||||
|
description.appendText("Child at position $position in parent ")
|
||||||
|
parentMatcher.describeTo(description)
|
||||||
|
}
|
||||||
|
|
||||||
|
public override fun matchesSafely(view: View): Boolean {
|
||||||
|
val parent = view.parent
|
||||||
|
return parent is ViewGroup && parentMatcher.matches(parent)
|
||||||
|
&& view == parent.getChildAt(position)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -51,12 +51,11 @@
|
||||||
</activity>
|
</activity>
|
||||||
<activity android:name=".activities.PreferencesActivity" />
|
<activity android:name=".activities.PreferencesActivity" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".plugins.general.overview.dialogs.BolusProgressHelperActivity"
|
android:name=".activities.BolusProgressHelperActivity"
|
||||||
android:theme="@style/Theme.AppCompat.Translucent" />
|
android:theme="@style/Theme.AppCompat.Translucent" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".plugins.general.overview.dialogs.ErrorHelperActivity"
|
android:name=".activities.ErrorHelperActivity"
|
||||||
android:theme="@style/Theme.AppCompat.Translucent" />
|
android:theme="@style/Theme.AppCompat.Translucent" />
|
||||||
<activity android:name=".activities.AgreementActivity" />
|
|
||||||
<activity android:name=".plugins.pump.danaR.activities.DanaRHistoryActivity" />
|
<activity android:name=".plugins.pump.danaR.activities.DanaRHistoryActivity" />
|
||||||
<activity android:name=".plugins.pump.danaR.activities.DanaRUserOptionsActivity" />
|
<activity android:name=".plugins.pump.danaR.activities.DanaRUserOptionsActivity" />
|
||||||
<activity android:name=".activities.TDDStatsActivity" />
|
<activity android:name=".activities.TDDStatsActivity" />
|
||||||
|
@ -76,6 +75,8 @@
|
||||||
</activity>
|
</activity>
|
||||||
<activity android:name=".plugins.pump.danaRS.activities.PairingHelperActivity" />
|
<activity android:name=".plugins.pump.danaRS.activities.PairingHelperActivity" />
|
||||||
<activity android:name=".activities.HistoryBrowseActivity" />
|
<activity android:name=".activities.HistoryBrowseActivity" />
|
||||||
|
<activity android:name=".activities.SurveyActivity" />
|
||||||
|
<activity android:name=".activities.StatsActivity" />
|
||||||
|
|
||||||
<!-- Receive new BG readings from other local apps -->
|
<!-- Receive new BG readings from other local apps -->
|
||||||
<receiver
|
<receiver
|
||||||
|
@ -114,7 +115,7 @@
|
||||||
|
|
||||||
<!-- Auto start -->
|
<!-- Auto start -->
|
||||||
<receiver
|
<receiver
|
||||||
android:name=".plugins.general.nsclient.receivers.AutoStartReceiver"
|
android:name=".receivers.AutoStartReceiver"
|
||||||
android:enabled="true"
|
android:enabled="true"
|
||||||
android:exported="true">
|
android:exported="true">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
|
@ -122,16 +123,6 @@
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
<!-- NSClient -->
|
|
||||||
<receiver
|
|
||||||
android:name=".plugins.general.nsclient.receivers.DBAccessReceiver"
|
|
||||||
android:enabled="true"
|
|
||||||
android:exported="true">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="info.nightscout.client.DBACCESS" />
|
|
||||||
</intent-filter>
|
|
||||||
</receiver>
|
|
||||||
|
|
||||||
<!-- Network change local receiver -->
|
<!-- Network change local receiver -->
|
||||||
<receiver android:name=".receivers.NetworkChangeReceiver">
|
<receiver android:name=".receivers.NetworkChangeReceiver">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
|
|
|
@ -25,8 +25,6 @@ public class Constants {
|
||||||
public static final int hoursToKeepInDatabase = 72;
|
public static final int hoursToKeepInDatabase = 72;
|
||||||
public static final int daysToKeepHistoryInDatabase = 30;
|
public static final int daysToKeepHistoryInDatabase = 30;
|
||||||
|
|
||||||
public static final long keepAliveMsecs = 5 * 60 * 1000L;
|
|
||||||
|
|
||||||
// SMS COMMUNICATOR
|
// SMS COMMUNICATOR
|
||||||
public static final long remoteBolusMinDistance = 15 * 60 * 1000L;
|
public static final long remoteBolusMinDistance = 15 * 60 * 1000L;
|
||||||
|
|
||||||
|
@ -78,4 +76,15 @@ public class Constants {
|
||||||
//Storage [MB]
|
//Storage [MB]
|
||||||
public static final long MINIMUM_FREE_SPACE = 200;
|
public static final long MINIMUM_FREE_SPACE = 200;
|
||||||
|
|
||||||
|
// Overview
|
||||||
|
public static final double LOWMARK = 76.0;
|
||||||
|
public static final double HIGHMARK = 180.0;
|
||||||
|
|
||||||
|
// STATISTICS
|
||||||
|
public static final double STATS_TARGET_LOW_MMOL = 3.9;
|
||||||
|
public static final double STATS_TARGET_HIGH_MMOL = 7.8;
|
||||||
|
public static final double STATS_RANGE_LOW_MMOL = 3.9;
|
||||||
|
public static final double STATS_RANGE_HIGH_MMOL = 10.0;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@ import info.nightscout.androidaps.activities.HistoryBrowseActivity;
|
||||||
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity;
|
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity;
|
||||||
import info.nightscout.androidaps.activities.PreferencesActivity;
|
import info.nightscout.androidaps.activities.PreferencesActivity;
|
||||||
import info.nightscout.androidaps.activities.SingleFragmentActivity;
|
import info.nightscout.androidaps.activities.SingleFragmentActivity;
|
||||||
|
import info.nightscout.androidaps.activities.StatsActivity;
|
||||||
import info.nightscout.androidaps.events.EventAppExit;
|
import info.nightscout.androidaps.events.EventAppExit;
|
||||||
import info.nightscout.androidaps.events.EventPreferenceChange;
|
import info.nightscout.androidaps.events.EventPreferenceChange;
|
||||||
import info.nightscout.androidaps.events.EventRebuildTabs;
|
import info.nightscout.androidaps.events.EventRebuildTabs;
|
||||||
|
@ -56,6 +57,7 @@ import info.nightscout.androidaps.tabs.TabPageAdapter;
|
||||||
import info.nightscout.androidaps.utils.AndroidPermission;
|
import info.nightscout.androidaps.utils.AndroidPermission;
|
||||||
import info.nightscout.androidaps.utils.FabricPrivacy;
|
import info.nightscout.androidaps.utils.FabricPrivacy;
|
||||||
import info.nightscout.androidaps.utils.LocaleHelper;
|
import info.nightscout.androidaps.utils.LocaleHelper;
|
||||||
|
import info.nightscout.androidaps.utils.OKDialog;
|
||||||
import info.nightscout.androidaps.utils.PasswordProtection;
|
import info.nightscout.androidaps.utils.PasswordProtection;
|
||||||
import info.nightscout.androidaps.utils.SP;
|
import info.nightscout.androidaps.utils.SP;
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
|
@ -90,8 +92,6 @@ public class MainActivity extends NoSplashAppCompatActivity {
|
||||||
// initialize screen wake lock
|
// initialize screen wake lock
|
||||||
processPreferenceChange(new EventPreferenceChange(R.string.key_keep_screen_on));
|
processPreferenceChange(new EventPreferenceChange(R.string.key_keep_screen_on));
|
||||||
|
|
||||||
doMigrations();
|
|
||||||
|
|
||||||
final ViewPager viewPager = findViewById(R.id.pager);
|
final ViewPager viewPager = findViewById(R.id.pager);
|
||||||
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
|
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -137,7 +137,7 @@ public class MainActivity extends NoSplashAppCompatActivity {
|
||||||
.subscribe(this::processPreferenceChange, FabricPrivacy::logException)
|
.subscribe(this::processPreferenceChange, FabricPrivacy::logException)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!SP.getBoolean(R.string.key_setupwizard_processed, false) || !SP.contains(R.string.key_units)) {
|
if (!SP.getBoolean(R.string.key_setupwizard_processed, false)) {
|
||||||
Intent intent = new Intent(this, SetupWizardActivity.class);
|
Intent intent = new Intent(this, SetupWizardActivity.class);
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
}
|
}
|
||||||
|
@ -231,17 +231,6 @@ public class MainActivity extends NoSplashAppCompatActivity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doMigrations() {
|
|
||||||
|
|
||||||
// guarantee that the unreachable threshold is at least 30 and of type String
|
|
||||||
// Added in 1.57 at 21.01.2018
|
|
||||||
int unreachable_threshold = SP.getInt(R.string.key_pump_unreachable_threshold, 30);
|
|
||||||
SP.remove(R.string.key_pump_unreachable_threshold);
|
|
||||||
if (unreachable_threshold < 30) unreachable_threshold = 30;
|
|
||||||
SP.putString(R.string.key_pump_unreachable_threshold, Integer.toString(unreachable_threshold));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||||
|
@ -250,10 +239,7 @@ public class MainActivity extends NoSplashAppCompatActivity {
|
||||||
switch (requestCode) {
|
switch (requestCode) {
|
||||||
case AndroidPermission.CASE_STORAGE:
|
case AndroidPermission.CASE_STORAGE:
|
||||||
//show dialog after permission is granted
|
//show dialog after permission is granted
|
||||||
AlertDialog.Builder alert = new AlertDialog.Builder(this);
|
OKDialog.show(this, "", MainApp.gs(R.string.alert_dialog_storage_permission_text));
|
||||||
alert.setMessage(R.string.alert_dialog_storage_permission_text);
|
|
||||||
alert.setPositiveButton(R.string.ok, null);
|
|
||||||
alert.show();
|
|
||||||
break;
|
break;
|
||||||
case AndroidPermission.CASE_LOCATION:
|
case AndroidPermission.CASE_LOCATION:
|
||||||
case AndroidPermission.CASE_SMS:
|
case AndroidPermission.CASE_SMS:
|
||||||
|
@ -327,9 +313,7 @@ public class MainActivity extends NoSplashAppCompatActivity {
|
||||||
return true;
|
return true;
|
||||||
case R.id.nav_exit:
|
case R.id.nav_exit:
|
||||||
log.debug("Exiting");
|
log.debug("Exiting");
|
||||||
MainApp.instance().stopKeepAliveService();
|
|
||||||
RxBus.INSTANCE.send(new EventAppExit());
|
RxBus.INSTANCE.send(new EventAppExit());
|
||||||
MainApp.closeDbHelper();
|
|
||||||
finish();
|
finish();
|
||||||
System.runFinalization();
|
System.runFinalization();
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
|
@ -343,6 +327,14 @@ public class MainActivity extends NoSplashAppCompatActivity {
|
||||||
startActivity(i);
|
startActivity(i);
|
||||||
}, null);
|
}, null);
|
||||||
return true;
|
return true;
|
||||||
|
/*
|
||||||
|
case R.id.nav_survey:
|
||||||
|
startActivity(new Intent(this, SurveyActivity.class));
|
||||||
|
return true;
|
||||||
|
*/
|
||||||
|
case R.id.nav_stats:
|
||||||
|
startActivity(new Intent(this, StatsActivity.class));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return actionBarDrawerToggle.onOptionsItemSelected(item);
|
return actionBarDrawerToggle.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
package info.nightscout.androidaps;
|
package info.nightscout.androidaps;
|
||||||
|
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.content.BroadcastReceiver;
|
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
|
|
||||||
|
import androidx.annotation.ColorRes;
|
||||||
import androidx.annotation.PluralsRes;
|
import androidx.annotation.PluralsRes;
|
||||||
|
import androidx.annotation.StringRes;
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||||
|
|
||||||
import com.crashlytics.android.Crashlytics;
|
import com.crashlytics.android.Crashlytics;
|
||||||
|
@ -15,6 +17,7 @@ import com.j256.ormlite.android.apptools.OpenHelperManager;
|
||||||
|
|
||||||
import net.danlew.android.joda.JodaTimeAndroid;
|
import net.danlew.android.joda.JodaTimeAndroid;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -22,6 +25,7 @@ import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import info.nightscout.androidaps.data.ConstraintChecker;
|
import info.nightscout.androidaps.data.ConstraintChecker;
|
||||||
|
import info.nightscout.androidaps.data.Profile;
|
||||||
import info.nightscout.androidaps.db.DatabaseHelper;
|
import info.nightscout.androidaps.db.DatabaseHelper;
|
||||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||||
import info.nightscout.androidaps.interfaces.PluginType;
|
import info.nightscout.androidaps.interfaces.PluginType;
|
||||||
|
@ -32,6 +36,7 @@ import info.nightscout.androidaps.plugins.aps.openAPSAMA.OpenAPSAMAPlugin;
|
||||||
import info.nightscout.androidaps.plugins.aps.openAPSMA.OpenAPSMAPlugin;
|
import info.nightscout.androidaps.plugins.aps.openAPSMA.OpenAPSMAPlugin;
|
||||||
import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin;
|
import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin;
|
||||||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
|
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
|
||||||
import info.nightscout.androidaps.plugins.constraints.dstHelper.DstHelperPlugin;
|
import info.nightscout.androidaps.plugins.constraints.dstHelper.DstHelperPlugin;
|
||||||
import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesPlugin;
|
import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesPlugin;
|
||||||
import info.nightscout.androidaps.plugins.constraints.safety.SafetyPlugin;
|
import info.nightscout.androidaps.plugins.constraints.safety.SafetyPlugin;
|
||||||
|
@ -46,8 +51,6 @@ import info.nightscout.androidaps.plugins.general.maintenance.LoggerUtils;
|
||||||
import info.nightscout.androidaps.plugins.general.maintenance.MaintenancePlugin;
|
import info.nightscout.androidaps.plugins.general.maintenance.MaintenancePlugin;
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin;
|
import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin;
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
|
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.receivers.AckAlarmReceiver;
|
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.receivers.DBAccessReceiver;
|
|
||||||
import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin;
|
import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin;
|
||||||
import info.nightscout.androidaps.plugins.general.persistentNotification.PersistentNotificationPlugin;
|
import info.nightscout.androidaps.plugins.general.persistentNotification.PersistentNotificationPlugin;
|
||||||
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin;
|
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin;
|
||||||
|
@ -72,6 +75,7 @@ import info.nightscout.androidaps.plugins.sensitivity.SensitivityAAPSPlugin;
|
||||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref0Plugin;
|
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref0Plugin;
|
||||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin;
|
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin;
|
||||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityWeightedAveragePlugin;
|
import info.nightscout.androidaps.plugins.sensitivity.SensitivityWeightedAveragePlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.source.RandomBgPlugin;
|
||||||
import info.nightscout.androidaps.plugins.source.SourceDexcomPlugin;
|
import info.nightscout.androidaps.plugins.source.SourceDexcomPlugin;
|
||||||
import info.nightscout.androidaps.plugins.source.SourceEversensePlugin;
|
import info.nightscout.androidaps.plugins.source.SourceEversensePlugin;
|
||||||
import info.nightscout.androidaps.plugins.source.SourceGlimpPlugin;
|
import info.nightscout.androidaps.plugins.source.SourceGlimpPlugin;
|
||||||
|
@ -86,8 +90,10 @@ import info.nightscout.androidaps.receivers.KeepAliveReceiver;
|
||||||
import info.nightscout.androidaps.receivers.NSAlarmReceiver;
|
import info.nightscout.androidaps.receivers.NSAlarmReceiver;
|
||||||
import info.nightscout.androidaps.receivers.TimeDateOrTZChangeReceiver;
|
import info.nightscout.androidaps.receivers.TimeDateOrTZChangeReceiver;
|
||||||
import info.nightscout.androidaps.services.Intents;
|
import info.nightscout.androidaps.services.Intents;
|
||||||
|
import info.nightscout.androidaps.utils.ActivityMonitor;
|
||||||
import info.nightscout.androidaps.utils.FabricPrivacy;
|
import info.nightscout.androidaps.utils.FabricPrivacy;
|
||||||
import info.nightscout.androidaps.utils.LocaleHelper;
|
import info.nightscout.androidaps.utils.LocaleHelper;
|
||||||
|
import info.nightscout.androidaps.utils.SP;
|
||||||
import io.fabric.sdk.android.Fabric;
|
import io.fabric.sdk.android.Fabric;
|
||||||
|
|
||||||
import static info.nightscout.androidaps.plugins.constraints.versionChecker.VersionCheckerUtilsKt.triggerCheckVersion;
|
import static info.nightscout.androidaps.plugins.constraints.versionChecker.VersionCheckerUtilsKt.triggerCheckVersion;
|
||||||
|
@ -95,7 +101,6 @@ import static info.nightscout.androidaps.plugins.constraints.versionChecker.Vers
|
||||||
|
|
||||||
public class MainApp extends Application {
|
public class MainApp extends Application {
|
||||||
private static Logger log = LoggerFactory.getLogger(L.CORE);
|
private static Logger log = LoggerFactory.getLogger(L.CORE);
|
||||||
private static KeepAliveReceiver keepAliveReceiver;
|
|
||||||
|
|
||||||
private static MainApp sInstance;
|
private static MainApp sInstance;
|
||||||
public static Resources sResources;
|
public static Resources sResources;
|
||||||
|
@ -108,11 +113,7 @@ public class MainApp extends Application {
|
||||||
private static ArrayList<PluginBase> pluginsList = null;
|
private static ArrayList<PluginBase> pluginsList = null;
|
||||||
|
|
||||||
private static DataReceiver dataReceiver = new DataReceiver();
|
private static DataReceiver dataReceiver = new DataReceiver();
|
||||||
private static NSAlarmReceiver alarmReciever = new NSAlarmReceiver();
|
private static NSAlarmReceiver alarmReceiver = new NSAlarmReceiver();
|
||||||
private static AckAlarmReceiver ackAlarmReciever = new AckAlarmReceiver();
|
|
||||||
private static DBAccessReceiver dbAccessReciever = new DBAccessReceiver();
|
|
||||||
private LocalBroadcastManager lbm;
|
|
||||||
BroadcastReceiver btReceiver;
|
|
||||||
TimeDateOrTZChangeReceiver timeDateOrTZChangeReceiver;
|
TimeDateOrTZChangeReceiver timeDateOrTZChangeReceiver;
|
||||||
|
|
||||||
public static boolean devBranch;
|
public static boolean devBranch;
|
||||||
|
@ -145,6 +146,8 @@ public class MainApp extends Application {
|
||||||
log.error("Error with Fabric init! " + e);
|
log.error("Error with Fabric init! " + e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
registerActivityLifecycleCallbacks(ActivityMonitor.INSTANCE);
|
||||||
|
|
||||||
mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
|
mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
|
||||||
mFirebaseAnalytics.setAnalyticsCollectionEnabled(!Boolean.getBoolean("disableFirebase"));
|
mFirebaseAnalytics.setAnalyticsCollectionEnabled(!Boolean.getBoolean("disableFirebase"));
|
||||||
|
|
||||||
|
@ -164,7 +167,6 @@ public class MainApp extends Application {
|
||||||
|
|
||||||
//trigger here to see the new version on app start after an update
|
//trigger here to see the new version on app start after an update
|
||||||
triggerCheckVersion();
|
triggerCheckVersion();
|
||||||
//setBTReceiver();
|
|
||||||
|
|
||||||
if (pluginsList == null) {
|
if (pluginsList == null) {
|
||||||
pluginsList = new ArrayList<>();
|
pluginsList = new ArrayList<>();
|
||||||
|
@ -188,7 +190,7 @@ public class MainApp extends Application {
|
||||||
if (Config.PUMPDRIVERS) pluginsList.add(MedtronicPumpPlugin.getPlugin());
|
if (Config.PUMPDRIVERS) pluginsList.add(MedtronicPumpPlugin.getPlugin());
|
||||||
if (!Config.NSCLIENT) pluginsList.add(MDIPlugin.getPlugin());
|
if (!Config.NSCLIENT) pluginsList.add(MDIPlugin.getPlugin());
|
||||||
pluginsList.add(VirtualPumpPlugin.getPlugin());
|
pluginsList.add(VirtualPumpPlugin.getPlugin());
|
||||||
pluginsList.add(CareportalPlugin.getPlugin());
|
if (Config.NSCLIENT) pluginsList.add(CareportalPlugin.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());
|
||||||
|
@ -209,6 +211,7 @@ public class MainApp extends Application {
|
||||||
pluginsList.add(SourcePoctechPlugin.getPlugin());
|
pluginsList.add(SourcePoctechPlugin.getPlugin());
|
||||||
pluginsList.add(SourceTomatoPlugin.getPlugin());
|
pluginsList.add(SourceTomatoPlugin.getPlugin());
|
||||||
pluginsList.add(SourceEversensePlugin.getPlugin());
|
pluginsList.add(SourceEversensePlugin.getPlugin());
|
||||||
|
pluginsList.add(RandomBgPlugin.INSTANCE);
|
||||||
if (!Config.NSCLIENT) pluginsList.add(SmsCommunicatorPlugin.INSTANCE);
|
if (!Config.NSCLIENT) pluginsList.add(SmsCommunicatorPlugin.INSTANCE);
|
||||||
pluginsList.add(FoodPlugin.getPlugin());
|
pluginsList.add(FoodPlugin.getPlugin());
|
||||||
|
|
||||||
|
@ -235,13 +238,40 @@ public class MainApp extends Application {
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
SystemClock.sleep(5000);
|
SystemClock.sleep(5000);
|
||||||
ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("Initialization", null);
|
ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("Initialization", null);
|
||||||
startKeepAliveService();
|
|
||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
new Thread(() -> KeepAliveReceiver.setAlarm(this)).start();
|
||||||
|
doMigrations();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doMigrations() {
|
||||||
|
|
||||||
|
// guarantee that the unreachable threshold is at least 30 and of type String
|
||||||
|
// Added in 1.57 at 21.01.2018
|
||||||
|
int unreachable_threshold = SP.getInt(R.string.key_pump_unreachable_threshold, 30);
|
||||||
|
SP.remove(R.string.key_pump_unreachable_threshold);
|
||||||
|
if (unreachable_threshold < 30) unreachable_threshold = 30;
|
||||||
|
SP.putString(R.string.key_pump_unreachable_threshold, Integer.toString(unreachable_threshold));
|
||||||
|
|
||||||
|
// 2.5 -> 2.6
|
||||||
|
if (!SP.contains(R.string.key_units)) {
|
||||||
|
String newUnits = Constants.MGDL;
|
||||||
|
Profile p = ProfileFunctions.getInstance().getProfile();
|
||||||
|
if (p != null && p.getData() != null && p.getData().has("units")) {
|
||||||
|
try {
|
||||||
|
newUnits = p.getData().getString("units");
|
||||||
|
} catch (JSONException e) {
|
||||||
|
log.error("Unhandled exception", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SP.putString(R.string.key_units, newUnits);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void registerLocalBroadcastReceiver() {
|
private void registerLocalBroadcastReceiver() {
|
||||||
lbm = LocalBroadcastManager.getInstance(this);
|
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
|
||||||
lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_NEW_TREATMENT));
|
lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_NEW_TREATMENT));
|
||||||
lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_CHANGED_TREATMENT));
|
lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_CHANGED_TREATMENT));
|
||||||
lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_REMOVED_TREATMENT));
|
lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_REMOVED_TREATMENT));
|
||||||
|
@ -256,39 +286,21 @@ public class MainApp extends Application {
|
||||||
lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_NEW_CAL));
|
lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_NEW_CAL));
|
||||||
|
|
||||||
//register alarms
|
//register alarms
|
||||||
lbm.registerReceiver(alarmReciever, new IntentFilter(Intents.ACTION_ALARM));
|
lbm.registerReceiver(alarmReceiver, new IntentFilter(Intents.ACTION_ALARM));
|
||||||
lbm.registerReceiver(alarmReciever, new IntentFilter(Intents.ACTION_ANNOUNCEMENT));
|
lbm.registerReceiver(alarmReceiver, new IntentFilter(Intents.ACTION_ANNOUNCEMENT));
|
||||||
lbm.registerReceiver(alarmReciever, new IntentFilter(Intents.ACTION_CLEAR_ALARM));
|
lbm.registerReceiver(alarmReceiver, new IntentFilter(Intents.ACTION_CLEAR_ALARM));
|
||||||
lbm.registerReceiver(alarmReciever, new IntentFilter(Intents.ACTION_URGENT_ALARM));
|
lbm.registerReceiver(alarmReceiver, new IntentFilter(Intents.ACTION_URGENT_ALARM));
|
||||||
|
|
||||||
//register ack alarm
|
|
||||||
lbm.registerReceiver(ackAlarmReciever, new IntentFilter(Intents.ACTION_ACK_ALARM));
|
|
||||||
|
|
||||||
//register dbaccess
|
|
||||||
lbm.registerReceiver(dbAccessReciever, new IntentFilter(Intents.ACTION_DATABASE));
|
|
||||||
|
|
||||||
this.timeDateOrTZChangeReceiver = new TimeDateOrTZChangeReceiver();
|
this.timeDateOrTZChangeReceiver = new TimeDateOrTZChangeReceiver();
|
||||||
this.timeDateOrTZChangeReceiver.registerBroadcasts(this);
|
this.timeDateOrTZChangeReceiver.registerBroadcasts(this);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startKeepAliveService() {
|
public static String gs(@StringRes int id) {
|
||||||
if (keepAliveReceiver == null) {
|
|
||||||
keepAliveReceiver = new KeepAliveReceiver();
|
|
||||||
keepAliveReceiver.setAlarm(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void stopKeepAliveService() {
|
|
||||||
if (keepAliveReceiver != null)
|
|
||||||
KeepAliveReceiver.cancelAlarm(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String gs(int id) {
|
|
||||||
return sResources.getString(id);
|
return sResources.getString(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String gs(int id, Object... args) {
|
public static String gs(@StringRes int id, Object... args) {
|
||||||
return sResources.getString(id, args);
|
return sResources.getString(id, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,8 +308,8 @@ public class MainApp extends Application {
|
||||||
return sResources.getQuantityString(id, quantity, args);
|
return sResources.getQuantityString(id, quantity, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int gc(int id) {
|
public static int gc(@ColorRes int id) {
|
||||||
return sResources.getColor(id);
|
return ContextCompat.getColor(instance(), id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MainApp instance() {
|
public static MainApp instance() {
|
||||||
|
@ -308,13 +320,6 @@ public class MainApp extends Application {
|
||||||
return sDatabaseHelper;
|
return sDatabaseHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void closeDbHelper() {
|
|
||||||
if (sDatabaseHelper != null) {
|
|
||||||
sDatabaseHelper.close();
|
|
||||||
sDatabaseHelper = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static FirebaseAnalytics getFirebaseAnalytics() {
|
public static FirebaseAnalytics getFirebaseAnalytics() {
|
||||||
return mFirebaseAnalytics;
|
return mFirebaseAnalytics;
|
||||||
}
|
}
|
||||||
|
@ -417,20 +422,12 @@ public class MainApp extends Application {
|
||||||
public void onTerminate() {
|
public void onTerminate() {
|
||||||
if (L.isEnabled(L.CORE))
|
if (L.isEnabled(L.CORE))
|
||||||
log.debug("onTerminate");
|
log.debug("onTerminate");
|
||||||
super.onTerminate();
|
|
||||||
if (sDatabaseHelper != null) {
|
|
||||||
sDatabaseHelper.close();
|
|
||||||
sDatabaseHelper = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (btReceiver != null) {
|
if (timeDateOrTZChangeReceiver != null)
|
||||||
unregisterReceiver(btReceiver);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (timeDateOrTZChangeReceiver != null) {
|
|
||||||
unregisterReceiver(timeDateOrTZChangeReceiver);
|
unregisterReceiver(timeDateOrTZChangeReceiver);
|
||||||
}
|
unregisterActivityLifecycleCallbacks(ActivityMonitor.INSTANCE);
|
||||||
|
KeepAliveReceiver.cancelAlarm(this);
|
||||||
|
super.onTerminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int dpToPx(int dp) {
|
public static int dpToPx(int dp) {
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
package info.nightscout.androidaps.activities
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import info.nightscout.androidaps.dialogs.BolusProgressDialog
|
||||||
|
|
||||||
|
class BolusProgressHelperActivity : DialogAppCompatActivity() {
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
BolusProgressDialog()
|
||||||
|
.setHelperActivity(this)
|
||||||
|
.setInsulin(intent.getDoubleExtra("insulin", 0.0))
|
||||||
|
.show(supportFragmentManager, "BolusProgress")
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package info.nightscout.androidaps.activities
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import info.nightscout.androidaps.utils.LocaleHelper
|
||||||
|
|
||||||
|
open class DialogAppCompatActivity : AppCompatActivity() {
|
||||||
|
public override fun attachBaseContext(newBase: Context) {
|
||||||
|
super.attachBaseContext(LocaleHelper.wrap(newBase))
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,12 +1,12 @@
|
||||||
package info.nightscout.androidaps.plugins.general.overview.dialogs
|
package info.nightscout.androidaps.activities
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import info.nightscout.androidaps.R
|
import info.nightscout.androidaps.R
|
||||||
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity
|
import info.nightscout.androidaps.dialogs.ErrorDialog
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
|
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
|
||||||
import info.nightscout.androidaps.utils.SP
|
import info.nightscout.androidaps.utils.SP
|
||||||
|
|
||||||
class ErrorHelperActivity : NoSplashAppCompatActivity() {
|
class ErrorHelperActivity : DialogAppCompatActivity() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
@ -89,7 +89,7 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (key.equals(MainApp.gs(R.string.key_openapsama_useautosens)) && SP.getBoolean(R.string.key_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.gs(R.string.configbuilder_sensitivity), MainApp.gs(R.string.sensitivity_warning), null);
|
OKDialog.show(this, MainApp.gs(R.string.configbuilder_sensitivity), MainApp.gs(R.string.sensitivity_warning));
|
||||||
}
|
}
|
||||||
updatePrefSummary(myPreferenceFragment.findPreference(key));
|
updatePrefSummary(myPreferenceFragment.findPreference(key));
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ package info.nightscout.androidaps.activities
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import info.nightscout.androidaps.plugins.source.SourceDexcomPlugin
|
import info.nightscout.androidaps.plugins.source.SourceDexcomPlugin
|
||||||
|
|
||||||
class RequestDexcomPermissionActivity : NoSplashAppCompatActivity() {
|
class RequestDexcomPermissionActivity : DialogAppCompatActivity() {
|
||||||
|
|
||||||
private val requestCode = "AndroidAPS <3".map { it.toInt() }.sum()
|
private val requestCode = "AndroidAPS <3".map { it.toInt() }.sum()
|
||||||
|
|
||||||
|
|
|
@ -1,60 +0,0 @@
|
||||||
package info.nightscout.androidaps.activities;
|
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.MainApp;
|
|
||||||
import info.nightscout.androidaps.R;
|
|
||||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
|
||||||
import info.nightscout.androidaps.utils.PasswordProtection;
|
|
||||||
|
|
||||||
public class SingleFragmentActivity extends AppCompatActivity {
|
|
||||||
|
|
||||||
private PluginBase plugin;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
setContentView(R.layout.activity_single_fragment);
|
|
||||||
|
|
||||||
this.plugin = MainApp.getPluginsList().get(getIntent().getIntExtra("plugin", -1));
|
|
||||||
setTitle(plugin.getName());
|
|
||||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
|
||||||
getSupportActionBar().setDisplayShowHomeEnabled(true);
|
|
||||||
|
|
||||||
if (savedInstanceState == null) {
|
|
||||||
getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout,
|
|
||||||
Fragment.instantiate(this, plugin.pluginDescription.getFragmentClass())).commit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
|
||||||
if (item.getItemId() == android.R.id.home) {
|
|
||||||
finish();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (item.getItemId() == R.id.nav_plugin_preferences) {
|
|
||||||
PasswordProtection.QueryPassword(this, R.string.settings_password, "settings_password", () -> {
|
|
||||||
Intent i = new Intent(this, PreferencesActivity.class);
|
|
||||||
i.putExtra("id", plugin.getPreferencesId());
|
|
||||||
startActivity(i);
|
|
||||||
}, null);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
|
||||||
if (plugin.getPreferencesId() != -1)
|
|
||||||
getMenuInflater().inflate(R.menu.menu_single_fragment, menu);
|
|
||||||
return super.onCreateOptionsMenu(menu);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
package info.nightscout.androidaps.activities
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.Menu
|
||||||
|
import android.view.MenuItem
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import info.nightscout.androidaps.MainApp
|
||||||
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.interfaces.PluginBase
|
||||||
|
import info.nightscout.androidaps.utils.LocaleHelper
|
||||||
|
import info.nightscout.androidaps.utils.PasswordProtection
|
||||||
|
|
||||||
|
class SingleFragmentActivity : AppCompatActivity() {
|
||||||
|
private var plugin: PluginBase? = null
|
||||||
|
public override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.activity_single_fragment)
|
||||||
|
plugin = MainApp.getPluginsList()[intent.getIntExtra("plugin", -1)]
|
||||||
|
title = plugin?.name
|
||||||
|
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||||
|
supportActionBar?.setDisplayShowHomeEnabled(true)
|
||||||
|
if (savedInstanceState == null) {
|
||||||
|
supportFragmentManager.beginTransaction().replace(R.id.frame_layout,
|
||||||
|
supportFragmentManager.fragmentFactory.instantiate(ClassLoader.getSystemClassLoader(), plugin?.pluginDescription?.fragmentClass!!)).commit()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
|
if (item.itemId == android.R.id.home) {
|
||||||
|
finish()
|
||||||
|
return true
|
||||||
|
} else if (item.itemId == R.id.nav_plugin_preferences) {
|
||||||
|
PasswordProtection.QueryPassword(this, R.string.settings_password, "settings_password", Runnable {
|
||||||
|
val i = Intent(this, PreferencesActivity::class.java)
|
||||||
|
i.putExtra("id", plugin?.preferencesId)
|
||||||
|
startActivity(i)
|
||||||
|
}, null)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||||
|
if (plugin?.preferencesId != -1) menuInflater.inflate(R.menu.menu_single_fragment, menu)
|
||||||
|
return super.onCreateOptionsMenu(menu)
|
||||||
|
}
|
||||||
|
|
||||||
|
public override fun attachBaseContext(newBase: Context) {
|
||||||
|
super.attachBaseContext(LocaleHelper.wrap(newBase))
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package info.nightscout.androidaps.activities
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import info.nightscout.androidaps.MainApp
|
||||||
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.utils.ActivityMonitor
|
||||||
|
import info.nightscout.androidaps.utils.OKDialog
|
||||||
|
import info.nightscout.androidaps.utils.TddCalculator
|
||||||
|
import info.nightscout.androidaps.utils.TirCalculator
|
||||||
|
import kotlinx.android.synthetic.main.stats_activity.*
|
||||||
|
|
||||||
|
class StatsActivity : NoSplashAppCompatActivity() {
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.stats_activity)
|
||||||
|
|
||||||
|
stats_tdds.text = TddCalculator.stats()
|
||||||
|
stats_tir.text = TirCalculator.stats()
|
||||||
|
stats_activity.text = ActivityMonitor.stats()
|
||||||
|
|
||||||
|
ok.setOnClickListener { finish() }
|
||||||
|
stats_reset.setOnClickListener {
|
||||||
|
OKDialog.showConfirmation(this, MainApp.gs(R.string.doyouwantresetstats), Runnable {
|
||||||
|
ActivityMonitor.reset()
|
||||||
|
recreate()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,110 @@
|
||||||
|
package info.nightscout.androidaps.activities
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.widget.ArrayAdapter
|
||||||
|
import com.google.firebase.auth.FirebaseAuth
|
||||||
|
import com.google.firebase.database.FirebaseDatabase
|
||||||
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.data.defaultProfile.DefaultProfile
|
||||||
|
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
|
||||||
|
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
|
||||||
|
import info.nightscout.androidaps.dialogs.ProfileViewerDialog
|
||||||
|
import info.nightscout.androidaps.utils.*
|
||||||
|
import kotlinx.android.synthetic.main.survey_activity.*
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
|
||||||
|
class SurveyActivity : NoSplashAppCompatActivity() {
|
||||||
|
private val log = LoggerFactory.getLogger(SurveyActivity::class.java)
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.survey_activity)
|
||||||
|
|
||||||
|
survey_id.text = InstanceId.instanceId()
|
||||||
|
|
||||||
|
val profileStore = ConfigBuilderPlugin.getPlugin().activeProfileInterface?.profile
|
||||||
|
val profileList = profileStore?.getProfileList() ?: return
|
||||||
|
survey_spinner.adapter = ArrayAdapter(this, R.layout.spinner_centered, profileList)
|
||||||
|
|
||||||
|
survey_tdds.text = TddCalculator.stats()
|
||||||
|
survey_tir.text = TirCalculator.stats()
|
||||||
|
survey_activity.text = ActivityMonitor.stats()
|
||||||
|
|
||||||
|
survey_profile.setOnClickListener {
|
||||||
|
val age = SafeParse.stringToDouble(survey_age.text.toString())
|
||||||
|
val weight = SafeParse.stringToDouble(survey_weight.text.toString())
|
||||||
|
val tdd = SafeParse.stringToDouble(survey_tdd.text.toString())
|
||||||
|
if (age < 1 || age > 120) {
|
||||||
|
ToastUtils.showToastInUiThread(this, R.string.invalidage)
|
||||||
|
return@setOnClickListener
|
||||||
|
}
|
||||||
|
if ((weight < 5 || weight > 150) && tdd == 0.0) {
|
||||||
|
ToastUtils.showToastInUiThread(this, R.string.invalidweight)
|
||||||
|
return@setOnClickListener
|
||||||
|
}
|
||||||
|
if ((tdd < 5 || tdd > 150) && weight == 0.0) {
|
||||||
|
ToastUtils.showToastInUiThread(this, R.string.invalidweight)
|
||||||
|
return@setOnClickListener
|
||||||
|
}
|
||||||
|
val profile = DefaultProfile().profile(age, tdd, weight, ProfileFunctions.getSystemUnits())
|
||||||
|
val args = Bundle()
|
||||||
|
args.putLong("time", DateUtil.now())
|
||||||
|
args.putInt("mode", ProfileViewerDialog.Mode.CUSTOM_PROFILE.ordinal)
|
||||||
|
args.putString("customProfile", profile.data.toString())
|
||||||
|
args.putString("customProfileUnits", profile.units)
|
||||||
|
args.putString("customProfileName", "Age: $age TDD: $tdd Weight: $weight")
|
||||||
|
val pvd = ProfileViewerDialog()
|
||||||
|
pvd.arguments = args
|
||||||
|
pvd.show(supportFragmentManager, "ProfileViewDialog")
|
||||||
|
}
|
||||||
|
|
||||||
|
survey_submit.setOnClickListener {
|
||||||
|
val r = FirebaseRecord()
|
||||||
|
r.id = InstanceId.instanceId()
|
||||||
|
r.age = SafeParse.stringToInt(survey_age.text.toString())
|
||||||
|
r.weight = SafeParse.stringToInt(survey_weight.text.toString())
|
||||||
|
if (r.age < 1 || r.age > 120) {
|
||||||
|
ToastUtils.showToastInUiThread(this, R.string.invalidage)
|
||||||
|
return@setOnClickListener
|
||||||
|
}
|
||||||
|
if (r.weight < 5 || r.weight > 150) {
|
||||||
|
ToastUtils.showToastInUiThread(this, R.string.invalidweight)
|
||||||
|
return@setOnClickListener
|
||||||
|
}
|
||||||
|
|
||||||
|
if (survey_spinner.selectedItem == null)
|
||||||
|
return@setOnClickListener
|
||||||
|
val profileName = survey_spinner.selectedItem.toString()
|
||||||
|
val specificProfile = profileStore.getSpecificProfile(profileName)
|
||||||
|
|
||||||
|
r.profileJson = specificProfile.toString()
|
||||||
|
|
||||||
|
val auth = FirebaseAuth.getInstance()
|
||||||
|
auth.signInAnonymously()
|
||||||
|
.addOnCompleteListener(this) { task ->
|
||||||
|
if (task.isSuccessful) {
|
||||||
|
log.debug("signInAnonymously:success")
|
||||||
|
val user = auth.currentUser // TODO: do we need this, seems unused?
|
||||||
|
|
||||||
|
val database = FirebaseDatabase.getInstance().reference
|
||||||
|
database.child("survey").child(r.id).setValue(r)
|
||||||
|
} else {
|
||||||
|
log.error("signInAnonymously:failure", task.exception)
|
||||||
|
ToastUtils.showToastInUiThread(this, "Authentication failed.")
|
||||||
|
//updateUI(null)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class FirebaseRecord {
|
||||||
|
var id = ""
|
||||||
|
var age: Int = 0
|
||||||
|
var weight: Int = 0
|
||||||
|
var profileJson = "ghfg"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -397,7 +397,7 @@ public class Profile {
|
||||||
return toMgdl(getIsfTimeFromMidnight(secondsFromMidnight(time)), units);
|
return toMgdl(getIsfTimeFromMidnight(secondsFromMidnight(time)), units);
|
||||||
}
|
}
|
||||||
|
|
||||||
double getIsfTimeFromMidnight(int timeAsSeconds) {
|
public 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);
|
||||||
|
@ -589,7 +589,7 @@ public class Profile {
|
||||||
public double getMaxDailyBasal() {
|
public double getMaxDailyBasal() {
|
||||||
double max = 0d;
|
double max = 0d;
|
||||||
for (int hour = 0; hour < 24; hour++) {
|
for (int hour = 0; hour < 24; hour++) {
|
||||||
double value = getBasalTimeFromMidnight((Integer) (hour * 60 * 60));
|
double value = getBasalTimeFromMidnight(hour * 60 * 60);
|
||||||
if (value > max) max = value;
|
if (value > max) max = value;
|
||||||
}
|
}
|
||||||
return max;
|
return max;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package info.nightscout.androidaps.data
|
package info.nightscout.androidaps.data
|
||||||
|
|
||||||
import androidx.collection.ArrayMap
|
import androidx.collection.ArrayMap
|
||||||
|
import info.nightscout.androidaps.utils.JsonHelper
|
||||||
import org.json.JSONException
|
import org.json.JSONException
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
|
@ -40,21 +41,19 @@ class ProfileStore(val data: JSONObject) {
|
||||||
|
|
||||||
fun getSpecificProfile(profileName: String): Profile? {
|
fun getSpecificProfile(profileName: String): Profile? {
|
||||||
var profile: Profile? = null
|
var profile: Profile? = null
|
||||||
try {
|
getStore()?.let { store ->
|
||||||
getStore()?.let { store ->
|
if (store.has(profileName)) {
|
||||||
if (store.has(profileName)) {
|
profile = cachedObjects[profileName]
|
||||||
profile = cachedObjects[profileName]
|
if (profile == null) {
|
||||||
if (profile == null) {
|
JsonHelper.safeGetJSONObject(store, profileName, null)?.let { profileObject ->
|
||||||
val profileObject = store.getJSONObject(profileName)
|
// take units from profile and if N/A from store
|
||||||
if (profileObject != null && profileObject.has("units")) {
|
JsonHelper.safeGetStringAllowNull(profileObject, "units", JsonHelper.safeGetString(data, "units"))?.let { units ->
|
||||||
profile = Profile(profileObject, profileObject.getString("units"))
|
profile = Profile(profileObject, units)
|
||||||
cachedObjects[profileName] = profile
|
cachedObjects[profileName] = profile
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e: JSONException) {
|
|
||||||
log.error("Unhandled exception", e)
|
|
||||||
}
|
}
|
||||||
return profile
|
return profile
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,7 +125,8 @@ public class QuickWizardEntry {
|
||||||
trend = true;
|
trend = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new BolusWizard(profile, profileName, tempTarget, carbs(), cob, bg, 0d, 100, true, useCOB() == YES, bolusIOB, basalIOB, superBolus, useTempTarget() == YES, trend, "QuickWizard");
|
double percentage = SP.getDouble(R.string.key_boluswizard_percentage, 100.0);
|
||||||
|
return new BolusWizard(profile, profileName, tempTarget, carbs(), cob, bg, 0d, percentage, true, useCOB() == YES, bolusIOB, basalIOB, superBolus, useTempTarget() == YES, trend, "QuickWizard");
|
||||||
}
|
}
|
||||||
|
|
||||||
public String buttonText() {
|
public String buttonText() {
|
||||||
|
|
|
@ -0,0 +1,145 @@
|
||||||
|
package info.nightscout.androidaps.data.defaultProfile
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.data.Profile
|
||||||
|
import info.nightscout.androidaps.utils.Round
|
||||||
|
import org.json.JSONArray
|
||||||
|
import org.json.JSONObject
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
|
class DefaultProfile {
|
||||||
|
var oneToFive: TreeMap<Double, Array<Double>> = TreeMap()
|
||||||
|
var sixToEleven: TreeMap<Double, Array<Double>> = TreeMap()
|
||||||
|
var twelveToSeventeen: TreeMap<Double, Array<Double>> = TreeMap()
|
||||||
|
var eighteenToTwentyfor: TreeMap<Double, Array<Double>> = TreeMap()
|
||||||
|
|
||||||
|
fun profile(age: Double, tdd: Double, weight: Double, units: String): Profile {
|
||||||
|
val profile = JSONObject()
|
||||||
|
if (age >= 1 && age < 6) {
|
||||||
|
val _tdd = if (tdd == 0.0) 0.6 * weight else tdd
|
||||||
|
closest(oneToFive, _tdd * 0.3)?.let { array -> profile.put("basal", arrayToJson(array)) }
|
||||||
|
val ic = Round.roundTo(250.0 / _tdd, 1.0)
|
||||||
|
profile.put("carbratio", singleValueArray(ic, arrayOf( 0.0, -4.0, -1.0, -2.0, -4.0, 0.0, -4.0)))
|
||||||
|
val isf = Round.roundTo(200.0 / _tdd, 0.1)
|
||||||
|
profile.put("sens", singleValueArray(isf, arrayOf( 0.0, -2.0, -0.0, -0.0, -2.0, 0.0, -2.0)))
|
||||||
|
} else if (age >= 6 && age < 12) {
|
||||||
|
val _tdd = if (tdd == 0.0) 0.8 * weight else tdd
|
||||||
|
closest(sixToEleven, _tdd * 0.4)?.let { array -> profile.put("basal", arrayToJson(array)) }
|
||||||
|
val ic = Round.roundTo(375.0 / _tdd, 1.0)
|
||||||
|
profile.put("carbratio", singleValueArray(ic, arrayOf( 0.0, -3.0, 0.0, -1.0, -3.0, 0.0, -2.0)))
|
||||||
|
val isf = Round.roundTo(170.0 / _tdd, 0.1)
|
||||||
|
profile.put("sens", singleValueArray(isf, arrayOf( 0.0, -1.0, -0.0, -0.0, -1.0, 0.0, -1.0)))
|
||||||
|
} else if (age >= 12 && age < 17) {
|
||||||
|
val _tdd = if (tdd == 0.0) 1.0 * weight else tdd
|
||||||
|
closest(twelveToSeventeen, _tdd * 0.5)?.let { array -> profile.put("basal", arrayToJson(array)) }
|
||||||
|
val ic = Round.roundTo(500.0 / _tdd, 1.0)
|
||||||
|
profile.put("carbratio", singleValueArray(ic, arrayOf( 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, -1.0)))
|
||||||
|
val isf = Round.roundTo(100.0 / _tdd, 0.1)
|
||||||
|
profile.put("sens", singleValueArray(isf, arrayOf( 0.2, 0.0, 0.2, 0.2, 0.0, 0.2, 0.2)))
|
||||||
|
} else if (age >= 18) {
|
||||||
|
|
||||||
|
}
|
||||||
|
profile.put("dia", 5.0)
|
||||||
|
profile.put("carbs_hr", 20) // not used
|
||||||
|
profile.put("delay", 5.0) // not used
|
||||||
|
profile.put("timezone", TimeZone.getDefault().getID())
|
||||||
|
profile.put("target_high", JSONArray().put(JSONObject().put("time", "00:00").put("value", Profile.fromMgdlToUnits(108.0, units))))
|
||||||
|
profile.put("target_low", JSONArray().put(JSONObject().put("time", "00:00").put("value", Profile.fromMgdlToUnits(108.0, units))))
|
||||||
|
return Profile(profile, units)
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
oneToFive[1.00] = arrayOf(0.050, 0.050, 0.050, 0.050, 0.050, 0.050, 0.075, 0.075, 0.075, 0.050, 0.050, 0.050, 0.050, 0.050, 0.075, 0.075, 0.050, 0.050, 0.050, 0.075, 0.075, 0.075, 0.050, 0.050)
|
||||||
|
oneToFive[1.13] = arrayOf(0.050, 0.050, 0.050, 0.050, 0.050, 0.050, 0.075, 0.075, 0.075, 0.050, 0.050, 0.050, 0.050, 0.050, 0.075, 0.075, 0.050, 0.050, 0.050, 0.075, 0.075, 0.075, 0.050, 0.050)
|
||||||
|
oneToFive[1.25] = arrayOf(0.050, 0.050, 0.050, 0.050, 0.050, 0.050, 0.075, 0.075, 0.075, 0.050, 0.050, 0.050, 0.050, 0.050, 0.075, 0.075, 0.050, 0.050, 0.050, 0.075, 0.075, 0.100, 0.050, 0.050)
|
||||||
|
oneToFive[1.38] = arrayOf(0.050, 0.050, 0.050, 0.050, 0.050, 0.050, 0.075, 0.075, 0.075, 0.050, 0.050, 0.050, 0.050, 0.050, 0.075, 0.075, 0.050, 0.050, 0.050, 0.075, 0.075, 0.100, 0.050, 0.050)
|
||||||
|
oneToFive[1.50] = arrayOf(0.050, 0.050, 0.050, 0.050, 0.050, 0.050, 0.075, 0.075, 0.075, 0.050, 0.050, 0.050, 0.050, 0.050, 0.075, 0.075, 0.050, 0.050, 0.050, 0.075, 0.100, 0.100, 0.050, 0.050)
|
||||||
|
oneToFive[1.75] = arrayOf(0.050, 0.050, 0.050, 0.050, 0.050, 0.050, 0.075, 0.075, 0.100, 0.050, 0.050, 0.050, 0.060, 0.060, 0.075, 0.075, 0.050, 0.050, 0.050, 0.100, 0.125, 0.100, 0.050, 0.050)
|
||||||
|
oneToFive[2.00] = arrayOf(0.050, 0.050, 0.050, 0.050, 0.050, 0.050, 0.075, 0.075, 0.100, 0.075, 0.050, 0.050, 0.065, 0.065, 0.075, 0.075, 0.050, 0.050, 0.050, 0.100, 0.125, 0.100, 0.050, 0.050)
|
||||||
|
oneToFive[2.25] = arrayOf(0.050, 0.050, 0.050, 0.050, 0.075, 0.075, 0.100, 0.100, 0.100, 0.075, 0.060, 0.060, 0.070, 0.070, 0.100, 0.100, 0.050, 0.050, 0.050, 0.125, 0.150, 0.125, 0.065, 0.050)
|
||||||
|
oneToFive[2.50] = arrayOf(0.050, 0.050, 0.050, 0.050, 0.075, 0.075, 0.100, 0.125, 0.125, 0.100, 0.065, 0.065, 0.075, 0.075, 0.125, 0.125, 0.060, 0.060, 0.060, 0.150, 0.150, 0.150, 0.070, 0.060)
|
||||||
|
oneToFive[2.75] = arrayOf(0.075, 0.075, 0.075, 0.100, 0.100, 0.100, 0.125, 0.150, 0.125, 0.100, 0.070, 0.070, 0.080, 0.080, 0.150, 0.150, 0.070, 0.070, 0.070, 0.175, 0.175, 0.175, 0.080, 0.070)
|
||||||
|
oneToFive[3.25] = arrayOf(0.100, 0.100, 0.100, 0.125, 0.125, 0.125, 0.150, 0.150, 0.150, 0.100, 0.080, 0.080, 0.100, 0.100, 0.175, 0.175, 0.075, 0.075, 0.075, 0.200, 0.200, 0.200, 0.090, 0.080)
|
||||||
|
oneToFive[3.75] = arrayOf(0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.175, 0.175, 0.175, 0.100, 0.085, 0.085, 0.110, 0.110, 0.185, 0.185, 0.080, 0.080, 0.080, 0.225, 0.225, 0.225, 0.100, 0.090)
|
||||||
|
oneToFive[4.25] = arrayOf(0.125, 0.125, 0.130, 0.140, 0.140, 0.140, 0.200, 0.200, 0.200, 0.125, 0.090, 0.090, 0.120, 0.120, 0.200, 0.200, 0.100, 0.100, 0.100, 0.250, 0.250, 0.250, 0.125, 0.100)
|
||||||
|
oneToFive[4.75] = arrayOf(0.125, 0.130, 0.135, 0.150, 0.150, 0.150, 0.200, 0.225, 0.200, 0.125, 0.100, 0.100, 0.125, 0.125, 0.250, 0.200, 0.110, 0.125, 0.125, 0.275, 0.275, 0.275, 0.130, 0.125)
|
||||||
|
oneToFive[5.25] = arrayOf(0.150, 0.150, 0.150, 0.170, 0.170, 0.170, 0.225, 0.225, 0.225, 0.130, 0.125, 0.125, 0.140, 0.140, 0.250, 0.250, 0.150, 0.150, 0.150, 0.300, 0.300, 0.300, 0.150, 0.150)
|
||||||
|
oneToFive[6.00] = arrayOf(0.170, 0.170, 0.175, 0.200, 0.200, 0.200, 0.250, 0.250, 0.250, 0.150, 0.125, 0.125, 0.150, 0.150, 0.275, 0.275, 0.170, 0.150, 0.150, 0.350, 0.350, 0.350, 0.175, 0.150)
|
||||||
|
oneToFive[6.75] = arrayOf(0.200, 0.200, 0.200, 0.225, 0.225, 0.225, 0.275, 0.275, 0.275, 0.200, 0.130, 0.130, 0.175, 0.175, 0.300, 0.300, 0.170, 0.175, 0.175, 0.375, 0.375, 0.375, 0.200, 0.175)
|
||||||
|
oneToFive[7.50] = arrayOf(0.225, 0.230, 0.235, 0.250, 0.250, 0.250, 0.300, 0.300, 0.300, 0.250, 0.150, 0.150, 0.200, 0.200, 0.325, 0.325, 0.200, 0.200, 0.200, 0.400, 0.450, 0.400, 0.350, 0.200)
|
||||||
|
|
||||||
|
sixToEleven[5.26] = arrayOf(0.18, 0.18, 0.18, 0.20, 0.20, 0.23, 0.25, 0.25, 0.25, 0.18, 0.15, 0.13, 0.15, 0.15, 0.25, 0.25, 0.20, 0.15, 0.18, 0.25, 0.25, 0.25, 0.23, 0.20)
|
||||||
|
sixToEleven[5.61] = arrayOf(0.18, 0.20, 0.20, 0.23, 0.23, 0.25, 0.28, 0.28, 0.25, 0.20, 0.15, 0.13, 0.15, 0.18, 0.25, 0.25, 0.20, 0.15, 0.18, 0.28, 0.25, 0.25, 0.23, 0.20)
|
||||||
|
sixToEleven[5.93] = arrayOf(0.20, 0.20, 0.23, 0.25, 0.25, 0.25, 0.30, 0.30, 0.30, 0.25, 0.15, 0.15, 0.18, 0.18, 0.28, 0.28, 0.20, 0.20, 0.20, 0.28, 0.28, 0.28, 0.25, 0.23)
|
||||||
|
sixToEleven[6.26] = arrayOf(0.20, 0.23, 0.23, 0.25, 0.25, 0.28, 0.33, 0.30, 0.30, 0.25, 0.18, 0.15, 0.18, 0.18, 0.28, 0.28, 0.23, 0.20, 0.20, 0.28, 0.30, 0.28, 0.25, 0.23)
|
||||||
|
sixToEleven[6.60] = arrayOf(0.23, 0.23, 0.25, 0.25, 0.25, 0.28, 0.33, 0.33, 0.33, 0.28, 0.18, 0.15, 0.18, 0.18, 0.30, 0.28, 0.23, 0.23, 0.20, 0.30, 0.30, 0.30, 0.25, 0.25)
|
||||||
|
sixToEleven[7.26] = arrayOf(0.23, 0.25, 0.28, 0.28, 0.30, 0.33, 0.38, 0.35, 0.35, 0.30, 0.18, 0.18, 0.18, 0.19, 0.33, 0.30, 0.25, 0.23, 0.23, 0.33, 0.33, 0.33, 0.30, 0.25)
|
||||||
|
sixToEleven[7.92] = arrayOf(0.25, 0.25, 0.28, 0.30, 0.33, 0.35, 0.38, 0.38, 0.38, 0.35, 0.20, 0.20, 0.23, 0.25, 0.35, 0.33, 0.30, 0.25, 0.25, 0.35, 0.35, 0.35, 0.33, 0.28)
|
||||||
|
sixToEleven[8.57] = arrayOf(0.28, 0.28, 0.30, 0.30, 0.33, 0.38, 0.40, 0.43, 0.40, 0.38, 0.25, 0.25, 0.25, 0.28, 0.38, 0.38, 0.33, 0.28, 0.28, 0.38, 0.40, 0.38, 0.35, 0.30)
|
||||||
|
sixToEleven[9.24] = arrayOf(0.30, 0.33, 0.35, 0.38, 0.40, 0.40, 0.43, 0.45, 0.43, 0.40, 0.30, 0.25, 0.28, 0.28, 0.38, 0.40, 0.33, 0.30, 0.30, 0.40, 0.43, 0.40, 0.38, 0.35)
|
||||||
|
sixToEleven[9.89] = arrayOf(0.35, 0.35, 0.38, 0.40, 0.40, 0.43, 0.45, 0.48, 0.45, 0.40, 0.30, 0.25, 0.28, 0.30, 0.40, 0.43, 0.35, 0.33, 0.33, 0.43, 0.45, 0.43, 0.40, 0.38)
|
||||||
|
sixToEleven[10.56] = arrayOf(0.38, 0.38, 0.40, 0.43, 0.45, 0.45, 0.48, 0.50, 0.48, 0.40, 0.35, 0.25, 0.30, 0.33, 0.43, 0.45, 0.35, 0.35, 0.35, 0.45, 0.48, 0.45, 0.43, 0.40)
|
||||||
|
sixToEleven[11.21] = arrayOf(0.40, 0.43, 0.43, 0.45, 0.48, 0.50, 0.53, 0.55, 0.50, 0.40, 0.35, 0.30, 0.33, 0.33, 0.45, 0.48, 0.38, 0.35, 0.37, 0.50, 0.50, 0.48, 0.45, 0.43)
|
||||||
|
sixToEleven[11.88] = arrayOf(0.43, 0.43, 0.45, 0.45, 0.48, 0.50, 0.55, 0.58, 0.50, 0.40, 0.35, 0.33, 0.33, 0.33, 0.48, 0.50, 0.40, 0.38, 0.38, 0.53, 0.53, 0.50, 0.48, 0.45)
|
||||||
|
sixToEleven[12.53] = arrayOf(0.45, 0.45, 0.48, 0.50, 0.53, 0.55, 0.60, 0.60, 0.60, 0.45, 0.40, 0.35, 0.35, 0.38, 0.50, 0.53, 0.40, 0.38, 0.38, 0.55, 0.58, 0.55, 0.50, 0.48)
|
||||||
|
sixToEleven[13.19] = arrayOf(0.48, 0.48, 0.50, 0.55, 0.58, 0.60, 0.65, 0.65, 0.65, 0.50, 0.45, 0.36, 0.38, 0.40, 0.55, 0.55, 0.45, 0.40, 0.40, 0.60, 0.60, 0.58, 0.55, 0.50)
|
||||||
|
sixToEleven[14.18] = arrayOf(0.53, 0.53, 0.55, 0.60, 0.65, 0.68, 0.70, 0.70, 0.68, 0.60, 0.55, 0.40, 0.40, 0.45, 0.60, 0.60, 0.50, 0.45, 0.45, 0.63, 0.65, 0.63, 0.60, 0.60)
|
||||||
|
sixToEleven[15.17] = arrayOf(0.55, 0.58, 0.60, 0.65, 0.70, 0.70, 0.75, 0.75, 0.70, 0.65, 0.60, 0.42, 0.42, 0.45, 0.65, 0.65, 0.60, 0.50, 0.50, 0.68, 0.68, 0.65, 0.63, 0.63)
|
||||||
|
sixToEleven[16.50] = arrayOf(0.60, 0.63, 0.65, 0.70, 0.70, 0.70, 0.80, 0.80, 0.80, 0.70, 0.60, 0.45, 0.45, 0.50, 0.65, 0.70, 0.60, 0.55, 0.55, 0.75, 0.75, 0.70, 0.65, 0.65)
|
||||||
|
|
||||||
|
twelveToSeventeen[10.70] = arrayOf(0.30, 0.30, 0.30, 0.30, 0.40, 0.40, 0.60, 0.60, 0.60, 0.40, 0.35, 0.30, 0.30, 0.35, 0.45, 0.50, 0.40, 0.30, 0.30, 0.40, 0.50, 0.40, 0.40, 0.30)
|
||||||
|
twelveToSeventeen[11.10] = arrayOf(0.30, 0.30, 0.30, 0.35, 0.40, 0.45, 0.60, 0.60, 0.60, 0.40, 0.40, 0.30, 0.35, 0.40, 0.50, 0.50, 0.30, 0.30, 0.30, 0.50, 0.50, 0.50, 0.30, 0.30)
|
||||||
|
twelveToSeventeen[11.60] = arrayOf(0.30, 0.30, 0.35, 0.45, 0.45, 0.50, 0.65, 0.65, 0.65, 0.45, 0.40, 0.40, 0.40, 0.40, 0.50, 0.55, 0.55, 0.45, 0.45, 0.50, 0.50, 0.50, 0.40, 0.40)
|
||||||
|
twelveToSeventeen[13.00] = arrayOf(0.40, 0.40, 0.40, 0.50, 0.55, 0.60, 0.70, 0.70, 0.70, 0.60, 0.50, 0.40, 0.40, 0.40, 0.50, 0.60, 0.60, 0.50, 0.50, 0.60, 0.60, 0.60, 0.40, 0.30)
|
||||||
|
twelveToSeventeen[15.60] = arrayOf(0.45, 0.50, 0.50, 0.60, 0.65, 0.70, 0.80, 0.80, 0.80, 0.70, 0.60, 0.60, 0.50, 0.50, 0.60, 0.70, 0.70, 0.60, 0.60, 0.60, 0.70, 0.70, 0.50, 0.50)
|
||||||
|
twelveToSeventeen[17.00] = arrayOf(0.50, 0.55, 0.60, 0.70, 0.75, 0.80, 1.00, 1.00, 1.00, 0.80, 0.70, 0.60, 0.60, 0.60, 0.70, 0.80, 0.80, 0.65, 0.65, 0.65, 0.70, 0.70, 0.60, 0.60)
|
||||||
|
twelveToSeventeen[18.00] = arrayOf(0.60, 0.65, 0.70, 0.80, 0.85, 0.90, 1.10, 1.10, 1.10, 0.90, 0.80, 0.60, 0.60, 0.60, 0.70, 0.80, 0.80, 0.70, 0.65, 0.70, 0.75, 0.70, 0.60, 0.60)
|
||||||
|
twelveToSeventeen[20.20] = arrayOf(0.70, 0.75, 0.80, 0.90, 0.95, 1.00, 1.10, 1.10, 1.10, 0.90, 0.80, 0.70, 0.70, 0.70, 0.80, 0.90, 0.90, 0.75, 0.75, 0.75, 0.80, 0.80, 0.70, 0.70)
|
||||||
|
twelveToSeventeen[21.60] = arrayOf(0.75, 0.80, 0.90, 0.90, 1.00, 1.00, 1.20, 1.20, 1.20, 0.90, 0.80, 0.70, 0.70, 0.70, 0.90, 1.00, 1.00, 0.80, 0.80, 0.80, 0.80, 0.80, 0.70, 0.70)
|
||||||
|
twelveToSeventeen[23.80] = arrayOf(0.75, 0.80, 0.90, 1.00, 1.10, 1.10, 1.20, 1.20, 1.20, 1.00, 0.90, 0.80, 0.80, 0.80, 0.90, 1.10, 1.10, 0.90, 0.90, 0.90, 1.00, 1.00, 0.80, 0.80)
|
||||||
|
twelveToSeventeen[26.10] = arrayOf(0.80, 0.80, 0.90, 1.00, 1.20, 1.20, 1.30, 1.30, 1.30, 1.10, 1.00, 0.90, 0.90, 0.90, 1.00, 1.20, 1.10, 0.90, 0.90, 1.00, 1.00, 1.00, 0.90, 0.90)
|
||||||
|
twelveToSeventeen[28.00] = arrayOf(0.90, 0.90, 1.00, 1.10, 1.10, 1.20, 1.30, 1.30, 1.30, 1.20, 1.00, 1.00, 1.00, 1.00, 1.20, 1.20, 1.20, 1.00, 1.00, 1.10, 1.10, 1.10, 0.90, 0.90)
|
||||||
|
twelveToSeventeen[30.10] = arrayOf(1.00, 1.00, 1.10, 1.20, 1.30, 1.40, 1.50, 1.50, 1.50, 1.30, 1.20, 1.00, 1.00, 1.00, 1.30, 1.40, 1.40, 1.00, 1.00, 1.15, 1.15, 1.10, 1.00, 1.00)
|
||||||
|
twelveToSeventeen[32.60] = arrayOf(1.10, 1.10, 1.20, 1.20, 1.40, 1.50, 1.50, 1.50, 1.50, 1.30, 1.20, 1.10, 1.10, 1.10, 1.40, 1.50, 1.40, 1.10, 1.10, 1.20, 1.20, 1.20, 1.10, 1.10)
|
||||||
|
twelveToSeventeen[35.20] = arrayOf(1.20, 1.20, 1.30, 1.40, 1.50, 1.60, 1.70, 1.70, 1.50, 1.40, 1.20, 1.10, 1.10, 1.10, 1.40, 1.50, 1.60, 1.40, 1.20, 1.20, 1.30, 1.30, 1.20, 1.20)
|
||||||
|
twelveToSeventeen[39.00] = arrayOf(1.30, 1.30, 1.40, 1.60, 1.60, 1.60, 1.90, 1.90, 1.90, 1.50, 1.30, 1.20, 1.20, 1.30, 1.50, 1.60, 1.70, 1.80, 1.50, 1.50, 1.60, 1.60, 1.30, 1.30)
|
||||||
|
twelveToSeventeen[42.80] = arrayOf(1.40, 1.40, 1.50, 1.70, 1.80, 1.80, 2.00, 2.00, 2.00, 1.80, 1.80, 1.50, 1.50, 1.50, 1.60, 1.70, 1.80, 1.90, 1.60, 1.60, 1.70, 1.70, 1.50, 1.50)
|
||||||
|
twelveToSeventeen[47.30] = arrayOf(1.50, 1.50, 1.70, 1.70, 2.00, 2.00, 2.20, 2.30, 2.20, 2.00, 1.80, 1.60, 1.60, 1.60, 1.80, 2.00, 2.10, 1.90, 1.80, 1.80, 2.00, 2.00, 1.60, 1.60)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun closest(map: TreeMap<Double, Array<Double>>, key: Double): Array<Double>? {
|
||||||
|
val low = map.floorEntry(key)
|
||||||
|
val high = map.ceilingEntry(key)
|
||||||
|
var res: Array<Double>? = null
|
||||||
|
if (low != null && high != null) {
|
||||||
|
res = if (Math.abs(key - low.key) < Math.abs(key - high.key))
|
||||||
|
low.value
|
||||||
|
else
|
||||||
|
high.value
|
||||||
|
} else if (low != null || high != null) {
|
||||||
|
res = if (low != null) low.value else high.value
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
fun arrayToJson(b: Array<Double>): JSONArray {
|
||||||
|
val basals = JSONArray()
|
||||||
|
for (i in 0..23) {
|
||||||
|
val time = String.format(Locale.ENGLISH, "%02d:00", i)
|
||||||
|
basals.put(JSONObject().put("time", time).put("value", b[i].toString()))
|
||||||
|
}
|
||||||
|
return basals
|
||||||
|
}
|
||||||
|
|
||||||
|
fun singleValueArray(value: Double, sample: Array<Double>): JSONArray {
|
||||||
|
val array = JSONArray()
|
||||||
|
array.put(JSONObject().put("time", "00:00").put("value", value + sample[0]))
|
||||||
|
array.put(JSONObject().put("time", "06:00").put("value", value + sample[1]))
|
||||||
|
array.put(JSONObject().put("time", "09:00").put("value", value + sample[2]))
|
||||||
|
array.put(JSONObject().put("time", "11:00").put("value", value + sample[3]))
|
||||||
|
array.put(JSONObject().put("time", "14:00").put("value", value + sample[4]))
|
||||||
|
array.put(JSONObject().put("time", "16:00").put("value", value + sample[5]))
|
||||||
|
array.put(JSONObject().put("time", "19:00").put("value", value + sample[6]))
|
||||||
|
return array
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ package info.nightscout.androidaps.db;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.database.DatabaseUtils;
|
import android.database.DatabaseUtils;
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper;
|
import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper;
|
||||||
|
@ -32,7 +33,7 @@ import java.util.concurrent.TimeUnit;
|
||||||
import info.nightscout.androidaps.Constants;
|
import info.nightscout.androidaps.Constants;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBus;
|
import info.nightscout.androidaps.plugins.bus.RxBus;
|
||||||
import info.nightscout.androidaps.data.OverlappingIntervals;
|
import info.nightscout.androidaps.data.NonOverlappingIntervals;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
import info.nightscout.androidaps.data.ProfileStore;
|
import info.nightscout.androidaps.data.ProfileStore;
|
||||||
import info.nightscout.androidaps.events.EventCareportalEventChange;
|
import info.nightscout.androidaps.events.EventCareportalEventChange;
|
||||||
|
@ -193,15 +194,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
return newVersion;
|
return newVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Close the database connections and clear any cached DAOs.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
super.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public long size(String database) {
|
public long size(String database) {
|
||||||
return DatabaseUtils.queryNumEntries(getReadableDatabase(), database);
|
return DatabaseUtils.queryNumEntries(getReadableDatabase(), database);
|
||||||
}
|
}
|
||||||
|
@ -558,12 +550,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
|
|
||||||
// ------------- DbRequests handling -------------------
|
// ------------- DbRequests handling -------------------
|
||||||
|
|
||||||
public void create(DbRequest dbr) {
|
public void create(DbRequest dbr) throws SQLException {
|
||||||
try {
|
|
||||||
getDaoDbRequest().create(dbr);
|
getDaoDbRequest().create(dbr);
|
||||||
} catch (SQLException e) {
|
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int delete(DbRequest dbr) {
|
public int delete(DbRequest dbr) {
|
||||||
|
@ -772,8 +760,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
TempTarget tempTarget = new TempTarget()
|
TempTarget tempTarget = new TempTarget()
|
||||||
.date(trJson.getLong("mills"))
|
.date(trJson.getLong("mills"))
|
||||||
.duration(JsonHelper.safeGetInt(trJson, "duration"))
|
.duration(JsonHelper.safeGetInt(trJson, "duration"))
|
||||||
.low(Profile.toMgdl(trJson.getDouble("targetBottom"), units))
|
.low(Profile.toMgdl(JsonHelper.safeGetDouble(trJson, "targetBottom"), units))
|
||||||
.high(Profile.toMgdl(trJson.getDouble("targetTop"), units))
|
.high(Profile.toMgdl(JsonHelper.safeGetDouble(trJson, "targetTop"), units))
|
||||||
.reason(JsonHelper.safeGetString(trJson, "reason", ""))
|
.reason(JsonHelper.safeGetString(trJson, "reason", ""))
|
||||||
._id(trJson.getString("_id"))
|
._id(trJson.getString("_id"))
|
||||||
.source(Source.NIGHTSCOUT);
|
.source(Source.NIGHTSCOUT);
|
||||||
|
@ -1425,7 +1413,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
QueryBuilder<CareportalEvent, Long> queryBuilder = getDaoCareportalEvents().queryBuilder();
|
QueryBuilder<CareportalEvent, Long> queryBuilder = getDaoCareportalEvents().queryBuilder();
|
||||||
queryBuilder.orderBy("date", false);
|
queryBuilder.orderBy("date", false);
|
||||||
Where where = queryBuilder.where();
|
Where where = queryBuilder.where();
|
||||||
where.eq("eventType", event);
|
where.eq("eventType", event).and().isNotNull("json");
|
||||||
queryBuilder.limit(1L);
|
queryBuilder.limit(1L);
|
||||||
PreparedQuery<CareportalEvent> preparedQuery = queryBuilder.prepare();
|
PreparedQuery<CareportalEvent> preparedQuery = queryBuilder.prepare();
|
||||||
careportalEvents = getDaoCareportalEvents().query(preparedQuery);
|
careportalEvents = getDaoCareportalEvents().query(preparedQuery);
|
||||||
|
@ -1445,10 +1433,10 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
QueryBuilder<CareportalEvent, Long> queryBuilder = getDaoCareportalEvents().queryBuilder();
|
QueryBuilder<CareportalEvent, Long> queryBuilder = getDaoCareportalEvents().queryBuilder();
|
||||||
queryBuilder.orderBy("date", ascending);
|
queryBuilder.orderBy("date", ascending);
|
||||||
Where where = queryBuilder.where();
|
Where where = queryBuilder.where();
|
||||||
where.ge("date", mills);
|
where.ge("date", mills).and().isNotNull("json").and().isNotNull("eventType");
|
||||||
PreparedQuery<CareportalEvent> preparedQuery = queryBuilder.prepare();
|
PreparedQuery<CareportalEvent> preparedQuery = queryBuilder.prepare();
|
||||||
careportalEvents = getDaoCareportalEvents().query(preparedQuery);
|
careportalEvents = getDaoCareportalEvents().query(preparedQuery);
|
||||||
preprocessOpenAPSOfflineEvents(careportalEvents);
|
careportalEvents = preprocessOpenAPSOfflineEvents(careportalEvents);
|
||||||
return careportalEvents;
|
return careportalEvents;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception", e);
|
||||||
|
@ -1462,10 +1450,10 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
QueryBuilder<CareportalEvent, Long> queryBuilder = getDaoCareportalEvents().queryBuilder();
|
QueryBuilder<CareportalEvent, Long> queryBuilder = getDaoCareportalEvents().queryBuilder();
|
||||||
queryBuilder.orderBy("date", ascending);
|
queryBuilder.orderBy("date", ascending);
|
||||||
Where where = queryBuilder.where();
|
Where where = queryBuilder.where();
|
||||||
where.between("date", start, end);
|
where.between("date", start, end).and().isNotNull("json").and().isNotNull("eventType");
|
||||||
PreparedQuery<CareportalEvent> preparedQuery = queryBuilder.prepare();
|
PreparedQuery<CareportalEvent> preparedQuery = queryBuilder.prepare();
|
||||||
careportalEvents = getDaoCareportalEvents().query(preparedQuery);
|
careportalEvents = getDaoCareportalEvents().query(preparedQuery);
|
||||||
preprocessOpenAPSOfflineEvents(careportalEvents);
|
careportalEvents = preprocessOpenAPSOfflineEvents(careportalEvents);
|
||||||
return careportalEvents;
|
return careportalEvents;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception", e);
|
||||||
|
@ -1473,14 +1461,16 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void preprocessOpenAPSOfflineEvents(List<CareportalEvent> list) {
|
public List<CareportalEvent> preprocessOpenAPSOfflineEvents(List<CareportalEvent> list) {
|
||||||
OverlappingIntervals offlineEvents = new OverlappingIntervals();
|
NonOverlappingIntervals offlineEvents = new NonOverlappingIntervals();
|
||||||
|
List<CareportalEvent> other = new ArrayList<>();
|
||||||
for (int i = 0; i < list.size(); i++) {
|
for (int i = 0; i < list.size(); i++) {
|
||||||
CareportalEvent event = list.get(i);
|
CareportalEvent event = list.get(i);
|
||||||
if (!event.eventType.equals(CareportalEvent.OPENAPSOFFLINE)) continue;
|
if (event.eventType.equals(CareportalEvent.OPENAPSOFFLINE)) offlineEvents.add(event);
|
||||||
offlineEvents.add(event);
|
else other.add(event);
|
||||||
}
|
}
|
||||||
|
other.addAll(offlineEvents.getList());
|
||||||
|
return other;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<CareportalEvent> getCareportalEventsFromTime(long mills, String type, boolean ascending) {
|
public List<CareportalEvent> getCareportalEventsFromTime(long mills, String type, boolean ascending) {
|
||||||
|
@ -1489,10 +1479,10 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
QueryBuilder<CareportalEvent, Long> queryBuilder = getDaoCareportalEvents().queryBuilder();
|
QueryBuilder<CareportalEvent, Long> queryBuilder = getDaoCareportalEvents().queryBuilder();
|
||||||
queryBuilder.orderBy("date", ascending);
|
queryBuilder.orderBy("date", ascending);
|
||||||
Where where = queryBuilder.where();
|
Where where = queryBuilder.where();
|
||||||
where.ge("date", mills).and().eq("eventType", type);
|
where.ge("date", mills).and().eq("eventType", type).and().isNotNull("json");
|
||||||
PreparedQuery<CareportalEvent> preparedQuery = queryBuilder.prepare();
|
PreparedQuery<CareportalEvent> preparedQuery = queryBuilder.prepare();
|
||||||
careportalEvents = getDaoCareportalEvents().query(preparedQuery);
|
careportalEvents = getDaoCareportalEvents().query(preparedQuery);
|
||||||
preprocessOpenAPSOfflineEvents(careportalEvents);
|
careportalEvents = preprocessOpenAPSOfflineEvents(careportalEvents);
|
||||||
return careportalEvents;
|
return careportalEvents;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception", e);
|
||||||
|
@ -1505,9 +1495,11 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
List<CareportalEvent> careportalEvents;
|
List<CareportalEvent> careportalEvents;
|
||||||
QueryBuilder<CareportalEvent, Long> queryBuilder = getDaoCareportalEvents().queryBuilder();
|
QueryBuilder<CareportalEvent, Long> queryBuilder = getDaoCareportalEvents().queryBuilder();
|
||||||
queryBuilder.orderBy("date", ascending);
|
queryBuilder.orderBy("date", ascending);
|
||||||
|
Where where = queryBuilder.where();
|
||||||
|
where.isNotNull("json").and().isNotNull("eventType");
|
||||||
PreparedQuery<CareportalEvent> preparedQuery = queryBuilder.prepare();
|
PreparedQuery<CareportalEvent> preparedQuery = queryBuilder.prepare();
|
||||||
careportalEvents = getDaoCareportalEvents().query(preparedQuery);
|
careportalEvents = getDaoCareportalEvents().query(preparedQuery);
|
||||||
preprocessOpenAPSOfflineEvents(careportalEvents);
|
careportalEvents = preprocessOpenAPSOfflineEvents(careportalEvents);
|
||||||
return careportalEvents;
|
return careportalEvents;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception", e);
|
||||||
|
@ -1592,15 +1584,23 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
|
|
||||||
// ---------------- ProfileSwitch handling ---------------
|
// ---------------- ProfileSwitch handling ---------------
|
||||||
|
|
||||||
public List<ProfileSwitch> getProfileSwitchData(boolean ascending) {
|
public List<ProfileSwitch> getProfileSwitchData(long from, boolean ascending) {
|
||||||
try {
|
try {
|
||||||
Dao<ProfileSwitch, Long> daoProfileSwitch = getDaoProfileSwitch();
|
Dao<ProfileSwitch, Long> daoProfileSwitch = getDaoProfileSwitch();
|
||||||
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(100L);
|
queryBuilder.limit(100L);
|
||||||
|
Where where = queryBuilder.where();
|
||||||
|
where.ge("date", from);
|
||||||
PreparedQuery<ProfileSwitch> preparedQuery = queryBuilder.prepare();
|
PreparedQuery<ProfileSwitch> preparedQuery = queryBuilder.prepare();
|
||||||
profileSwitches = daoProfileSwitch.query(preparedQuery);
|
profileSwitches = daoProfileSwitch.query(preparedQuery);
|
||||||
|
//add last one without duration
|
||||||
|
ProfileSwitch last = getLastProfileSwitchWithoutDuration();
|
||||||
|
if (last != null) {
|
||||||
|
if (!profileSwitches.contains(last))
|
||||||
|
profileSwitches.add(last);
|
||||||
|
}
|
||||||
return profileSwitches;
|
return profileSwitches;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception", e);
|
||||||
|
@ -1608,6 +1608,28 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private ProfileSwitch getLastProfileSwitchWithoutDuration() {
|
||||||
|
try {
|
||||||
|
Dao<ProfileSwitch, Long> daoProfileSwitch = getDaoProfileSwitch();
|
||||||
|
List<ProfileSwitch> profileSwitches;
|
||||||
|
QueryBuilder<ProfileSwitch, Long> queryBuilder = daoProfileSwitch.queryBuilder();
|
||||||
|
queryBuilder.orderBy("date", false);
|
||||||
|
queryBuilder.limit(1L);
|
||||||
|
Where where = queryBuilder.where();
|
||||||
|
where.eq("durationInMinutes", 0);
|
||||||
|
PreparedQuery<ProfileSwitch> preparedQuery = queryBuilder.prepare();
|
||||||
|
profileSwitches = daoProfileSwitch.query(preparedQuery);
|
||||||
|
if (profileSwitches.size() > 0)
|
||||||
|
return profileSwitches.get(0);
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error("Unhandled exception", e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public List<ProfileSwitch> getProfileSwitchEventsFromTime(long mills, boolean ascending) {
|
public List<ProfileSwitch> getProfileSwitchEventsFromTime(long mills, boolean ascending) {
|
||||||
try {
|
try {
|
||||||
Dao<ProfileSwitch, Long> daoProfileSwitch = getDaoProfileSwitch();
|
Dao<ProfileSwitch, Long> daoProfileSwitch = getDaoProfileSwitch();
|
||||||
|
|
|
@ -11,6 +11,7 @@ import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import info.nightscout.androidaps.logging.L;
|
import info.nightscout.androidaps.logging.L;
|
||||||
|
import info.nightscout.androidaps.utils.DateUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by mike on 27.02.2016.
|
* Created by mike on 27.02.2016.
|
||||||
|
@ -40,36 +41,49 @@ public class DbRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
// dbAdd
|
// dbAdd
|
||||||
public DbRequest(String action, String collection, String nsClientID, JSONObject data) {
|
public DbRequest(String action, String collection, JSONObject data) {
|
||||||
this.action = action;
|
this.action = action;
|
||||||
this.collection = collection;
|
this.collection = collection;
|
||||||
|
this.nsClientID = "" + DateUtil.now();
|
||||||
|
try {
|
||||||
|
data.put("NSCLIENT_ID", nsClientID);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
this.data = data.toString();
|
this.data = data.toString();
|
||||||
this.nsClientID = nsClientID;
|
|
||||||
this._id = "";
|
this._id = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
// dbUpdate, dbUpdateUnset
|
// dbUpdate, dbUpdateUnset
|
||||||
public DbRequest(String action, String collection, String nsClientID, String _id, JSONObject data) {
|
public DbRequest(String action, String collection, String _id, JSONObject data) {
|
||||||
this.action = action;
|
this.action = action;
|
||||||
this.collection = collection;
|
this.collection = collection;
|
||||||
|
this.nsClientID = "" + DateUtil.now();
|
||||||
|
try {
|
||||||
|
data.put("NSCLIENT_ID", nsClientID);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
this.data = data.toString();
|
this.data = data.toString();
|
||||||
this.nsClientID = nsClientID;
|
|
||||||
this._id = _id;
|
this._id = _id;
|
||||||
}
|
}
|
||||||
|
|
||||||
// dbRemove
|
// dbRemove
|
||||||
public DbRequest(String action, String collection, String nsClientID, String _id) {
|
public DbRequest(String action, String collection,
|
||||||
|
String _id) {
|
||||||
|
JSONObject data = new JSONObject();
|
||||||
this.action = action;
|
this.action = action;
|
||||||
this.collection = collection;
|
this.collection = collection;
|
||||||
this.data = new JSONObject().toString();
|
this.nsClientID = "" + DateUtil.now();
|
||||||
this.nsClientID = nsClientID;
|
try {
|
||||||
|
data.put("NSCLIENT_ID", nsClientID);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
this.data = data.toString();
|
||||||
this._id = _id;
|
this._id = _id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String hash() {
|
|
||||||
return Hashing.sha1().hashString(action + collection + _id + data.toString(), Charsets.UTF_8).toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public JSONObject toJSON() {
|
public JSONObject toJSON() {
|
||||||
JSONObject object = new JSONObject();
|
JSONObject object = new JSONObject();
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -325,8 +325,8 @@ public class ExtendedBolus implements Interval, DataPointWithLabelInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toStringMedium() {
|
public String toStringMedium() {
|
||||||
return "E " + DecimalFormatter.to2Decimal(absoluteRate()) + "U/h ("
|
return DecimalFormatter.to2Decimal(absoluteRate()) + "U/h "
|
||||||
+ getRealDuration() + "/" + durationInMinutes + ") ";
|
+ getRealDuration() + "/" + durationInMinutes + "'";
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toStringTotal() {
|
public String toStringTotal() {
|
||||||
|
|
|
@ -6,8 +6,11 @@ import com.j256.ormlite.table.DatabaseTable;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.MainApp;
|
||||||
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.logging.L;
|
import info.nightscout.androidaps.logging.L;
|
||||||
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil;
|
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil;
|
||||||
|
import info.nightscout.androidaps.utils.DateUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by mike on 20.09.2017.
|
* Created by mike on 20.09.2017.
|
||||||
|
@ -56,4 +59,12 @@ public class TDD {
|
||||||
", total=" + total +
|
", total=" + total +
|
||||||
']';
|
']';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String toText() {
|
||||||
|
return MainApp.gs(R.string.tddformat, DateUtil.dateStringShort(date), total, bolus, basal);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toText(int days) {
|
||||||
|
return MainApp.gs(R.string.tddformat, String.format("%d ", days) + MainApp.gs(R.string.days), total, bolus, basal);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,159 @@
|
||||||
|
package info.nightscout.androidaps.dialogs
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.os.SystemClock
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.view.Window
|
||||||
|
import android.view.WindowManager
|
||||||
|
import androidx.fragment.app.DialogFragment
|
||||||
|
import info.nightscout.androidaps.MainApp
|
||||||
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.activities.BolusProgressHelperActivity
|
||||||
|
import info.nightscout.androidaps.events.EventPumpStatusChanged
|
||||||
|
import info.nightscout.androidaps.logging.L
|
||||||
|
import info.nightscout.androidaps.plugins.bus.RxBus.toObservable
|
||||||
|
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissBolusProgressIfRunning
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress
|
||||||
|
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||||
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
|
import kotlinx.android.synthetic.main.dialog_bolusprogress.*
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
|
||||||
|
class BolusProgressDialog : DialogFragment() {
|
||||||
|
private val log = LoggerFactory.getLogger(L.UI)
|
||||||
|
private val disposable = CompositeDisposable()
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val DEFAULT_STATE = MainApp.gs(R.string.waitingforpump)
|
||||||
|
@JvmField
|
||||||
|
var bolusEnded = false
|
||||||
|
@JvmField
|
||||||
|
var stopPressed = false
|
||||||
|
}
|
||||||
|
|
||||||
|
private var running = true
|
||||||
|
private var amount = 0.0
|
||||||
|
private var state: String? = null
|
||||||
|
private var helpActivity: BolusProgressHelperActivity? = null
|
||||||
|
|
||||||
|
fun setInsulin(amount: Double): BolusProgressDialog {
|
||||||
|
this.amount = amount
|
||||||
|
bolusEnded = false
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setHelperActivity(activity: BolusProgressHelperActivity): BolusProgressDialog {
|
||||||
|
helpActivity = activity
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?): View? {
|
||||||
|
dialog?.window?.requestFeature(Window.FEATURE_NO_TITLE)
|
||||||
|
dialog?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN)
|
||||||
|
isCancelable = false
|
||||||
|
dialog?.setCanceledOnTouchOutside(false)
|
||||||
|
return inflater.inflate(R.layout.dialog_bolusprogress, container, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
overview_bolusprogress_title.text = String.format(MainApp.gs(R.string.overview_bolusprogress_goingtodeliver), amount)
|
||||||
|
overview_bolusprogress_stop.setOnClickListener {
|
||||||
|
if (L.isEnabled(L.UI)) log.debug("Stop bolus delivery button pressed")
|
||||||
|
stopPressed = true
|
||||||
|
overview_bolusprogress_stoppressed.visibility = View.VISIBLE
|
||||||
|
overview_bolusprogress_stop.visibility = View.INVISIBLE
|
||||||
|
ConfigBuilderPlugin.getPlugin().commandQueue.cancelAllBoluses()
|
||||||
|
}
|
||||||
|
overview_bolusprogress_progressbar.max = 100
|
||||||
|
state = savedInstanceState?.getString("state", DEFAULT_STATE) ?: DEFAULT_STATE
|
||||||
|
overview_bolusprogress_status.text = state
|
||||||
|
stopPressed = false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStart() {
|
||||||
|
super.onStart()
|
||||||
|
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
if (L.isEnabled(L.UI)) log.debug("onResume")
|
||||||
|
if (!ConfigBuilderPlugin.getPlugin().commandQueue.bolusInQueue())
|
||||||
|
bolusEnded = true
|
||||||
|
|
||||||
|
if (bolusEnded) dismiss()
|
||||||
|
else running = true
|
||||||
|
|
||||||
|
disposable.add(toObservable(EventPumpStatusChanged::class.java)
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe({ overview_bolusprogress_status.text = it.getStatus() }) { FabricPrivacy.logException(it) }
|
||||||
|
)
|
||||||
|
disposable.add(toObservable(EventDismissBolusProgressIfRunning::class.java)
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe({ if (running) dismiss() }) { FabricPrivacy.logException(it) }
|
||||||
|
)
|
||||||
|
disposable.add(toObservable(EventOverviewBolusProgress::class.java)
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe({
|
||||||
|
if (L.isEnabled(L.UI)) log.debug("Status: " + it.status + " Percent: " + it.percent)
|
||||||
|
overview_bolusprogress_status.text = it.status
|
||||||
|
overview_bolusprogress_progressbar.progress = it.percent
|
||||||
|
if (it.percent == 100) {
|
||||||
|
overview_bolusprogress_stop.visibility = View.INVISIBLE
|
||||||
|
scheduleDismiss()
|
||||||
|
}
|
||||||
|
state = it.status
|
||||||
|
}) { FabricPrivacy.logException(it) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun dismiss() {
|
||||||
|
if (L.isEnabled(L.UI)) log.debug("dismiss")
|
||||||
|
try {
|
||||||
|
super.dismiss()
|
||||||
|
} catch (e: IllegalStateException) {
|
||||||
|
// dialog not running yet. onResume will try again. Set bolusEnded to make extra
|
||||||
|
// sure onResume will catch this
|
||||||
|
bolusEnded = true
|
||||||
|
log.error("Unhandled exception", e)
|
||||||
|
}
|
||||||
|
helpActivity?.finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPause() {
|
||||||
|
super.onPause()
|
||||||
|
if (L.isEnabled(L.UI)) log.debug("onPause")
|
||||||
|
running = false
|
||||||
|
disposable.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSaveInstanceState(outState: Bundle) {
|
||||||
|
super.onSaveInstanceState(outState)
|
||||||
|
outState.putString("state", state)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun scheduleDismiss() {
|
||||||
|
if (L.isEnabled(L.UI)) log.debug("scheduleDismiss")
|
||||||
|
Thread(Runnable {
|
||||||
|
SystemClock.sleep(5000)
|
||||||
|
bolusEnded = true
|
||||||
|
val activity: Activity? = activity
|
||||||
|
activity?.runOnUiThread {
|
||||||
|
if (running) {
|
||||||
|
if (L.isEnabled(L.UI)) log.debug("executing")
|
||||||
|
try {
|
||||||
|
dismiss()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
log.error("Unhandled exception", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).start()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
package info.nightscout.androidaps.dialogs
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import com.google.common.base.Joiner
|
||||||
|
import info.nightscout.androidaps.Constants
|
||||||
|
import info.nightscout.androidaps.MainApp
|
||||||
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.data.Profile
|
||||||
|
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
|
||||||
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
|
||||||
|
import info.nightscout.androidaps.utils.HtmlHelper
|
||||||
|
import info.nightscout.androidaps.utils.OKDialog
|
||||||
|
import info.nightscout.androidaps.utils.XdripCalibrations
|
||||||
|
import kotlinx.android.synthetic.main.dialog_calibration.*
|
||||||
|
import kotlinx.android.synthetic.main.okcancel.*
|
||||||
|
import java.text.DecimalFormat
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class CalibrationDialog : DialogFragmentWithDate() {
|
||||||
|
|
||||||
|
override fun onSaveInstanceState(savedInstanceState: Bundle) {
|
||||||
|
super.onSaveInstanceState(savedInstanceState)
|
||||||
|
savedInstanceState.putDouble("overview_calibration_bg", overview_calibration_bg.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?): View? {
|
||||||
|
onCreateViewGeneral()
|
||||||
|
return inflater.inflate(R.layout.dialog_calibration, container, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
val units = ProfileFunctions.getSystemUnits()
|
||||||
|
val bg = Profile.fromMgdlToUnits(GlucoseStatus.getGlucoseStatusData()?.glucose
|
||||||
|
?: 0.0, units)
|
||||||
|
if (units == Constants.MMOL)
|
||||||
|
overview_calibration_bg.setParams(savedInstanceState?.getDouble("overview_calibration_bg")
|
||||||
|
?: bg, 2.0, 30.0, 0.1, DecimalFormat("0.0"), false, ok)
|
||||||
|
else
|
||||||
|
overview_calibration_bg.setParams(savedInstanceState?.getDouble("overview_calibration_bg")
|
||||||
|
?: bg, 36.0, 500.0, 1.0, DecimalFormat("0"), false, ok)
|
||||||
|
overview_calibration_units.text = if (units == Constants.MMOL) MainApp.gs(R.string.mmol) else MainApp.gs(R.string.mgdl)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun submit() :Boolean {
|
||||||
|
val units = ProfileFunctions.getSystemUnits()
|
||||||
|
val unitLabel = if (units == Constants.MMOL) MainApp.gs(R.string.mmol) else MainApp.gs(R.string.mgdl)
|
||||||
|
val actions: LinkedList<String?> = LinkedList()
|
||||||
|
val bg = overview_calibration_bg.value
|
||||||
|
actions.add(MainApp.gs(R.string.treatments_wizard_bg_label) + ": " + Profile.toCurrentUnitsString(bg) + " " + unitLabel)
|
||||||
|
if (bg > 0) {
|
||||||
|
activity?.let { activity ->
|
||||||
|
OKDialog.showConfirmation(activity, MainApp.gs(R.string.overview_calibration), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), Runnable {
|
||||||
|
XdripCalibrations.confirmAndSendCalibration(bg, context)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
activity?.let { activity ->
|
||||||
|
OKDialog.show(activity, MainApp.gs(R.string.overview_calibration), MainApp.gs(R.string.no_action_selected))
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,223 @@
|
||||||
|
package info.nightscout.androidaps.dialogs
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.text.Editable
|
||||||
|
import android.text.TextWatcher
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import com.google.common.base.Joiner
|
||||||
|
import info.nightscout.androidaps.Constants
|
||||||
|
import info.nightscout.androidaps.MainApp
|
||||||
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.data.Profile
|
||||||
|
import info.nightscout.androidaps.db.CareportalEvent
|
||||||
|
import info.nightscout.androidaps.db.DatabaseHelper
|
||||||
|
import info.nightscout.androidaps.db.Source
|
||||||
|
import info.nightscout.androidaps.db.TempTarget
|
||||||
|
import info.nightscout.androidaps.interfaces.Constraint
|
||||||
|
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
|
||||||
|
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
|
||||||
|
import info.nightscout.androidaps.plugins.treatments.CarbsGenerator
|
||||||
|
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
||||||
|
import info.nightscout.androidaps.utils.*
|
||||||
|
import kotlinx.android.synthetic.main.dialog_carbs.*
|
||||||
|
import kotlinx.android.synthetic.main.notes.*
|
||||||
|
import kotlinx.android.synthetic.main.okcancel.*
|
||||||
|
import java.text.DecimalFormat
|
||||||
|
import java.util.*
|
||||||
|
import kotlin.math.max
|
||||||
|
|
||||||
|
class CarbsDialog : DialogFragmentWithDate() {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val FAV1_DEFAULT = 5
|
||||||
|
private const val FAV2_DEFAULT = 10
|
||||||
|
private const val FAV3_DEFAULT = 20
|
||||||
|
}
|
||||||
|
|
||||||
|
private val maxCarbs = MainApp.getConstraintChecker().maxCarbsAllowed.value().toDouble()
|
||||||
|
|
||||||
|
private val textWatcher: TextWatcher = object : TextWatcher {
|
||||||
|
override fun afterTextChanged(s: Editable) {
|
||||||
|
validateInputs()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
|
||||||
|
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun validateInputs() {
|
||||||
|
val time = overview_carbs_time.value.toInt()
|
||||||
|
if (time > 12 * 60 || time < -12 * 60) {
|
||||||
|
overview_carbs_time.value = 0.0
|
||||||
|
ToastUtils.showToastInUiThread(MainApp.instance().applicationContext, MainApp.gs(R.string.constraintapllied))
|
||||||
|
}
|
||||||
|
if (overview_carbs_duration.value > 10) {
|
||||||
|
overview_carbs_duration.value = 0.0
|
||||||
|
ToastUtils.showToastInUiThread(MainApp.instance().applicationContext, MainApp.gs(R.string.constraintapllied))
|
||||||
|
}
|
||||||
|
if (overview_carbs_carbs.value.toInt() > maxCarbs) {
|
||||||
|
overview_carbs_carbs.value = 0.0
|
||||||
|
ToastUtils.showToastInUiThread(MainApp.instance().applicationContext, MainApp.gs(R.string.carbsconstraintapplied))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSaveInstanceState(savedInstanceState: Bundle) {
|
||||||
|
super.onSaveInstanceState(savedInstanceState)
|
||||||
|
savedInstanceState.putDouble("overview_carbs_time", overview_carbs_time.value)
|
||||||
|
savedInstanceState.putDouble("overview_carbs_duration", overview_carbs_duration.value)
|
||||||
|
savedInstanceState.putDouble("overview_carbs_carbs", overview_carbs_carbs.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?): View? {
|
||||||
|
onCreateViewGeneral()
|
||||||
|
return inflater.inflate(R.layout.dialog_carbs, container, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
overview_carbs_time.setParams(savedInstanceState?.getDouble("overview_carbs_time")
|
||||||
|
?: 0.0, -12 * 60.0, 12 * 60.0, 5.0, DecimalFormat("0"), false, ok, textWatcher)
|
||||||
|
|
||||||
|
overview_carbs_duration.setParams(savedInstanceState?.getDouble("overview_carbs_duration")
|
||||||
|
?: 0.0, 0.0, 10.0, 1.0, DecimalFormat("0"), false, ok, textWatcher)
|
||||||
|
|
||||||
|
overview_carbs_carbs.setParams(savedInstanceState?.getDouble("overview_carbs_carbs")
|
||||||
|
?: 0.0, 0.0, maxCarbs, 1.0, DecimalFormat("0"), false, ok, textWatcher)
|
||||||
|
|
||||||
|
overview_carbs_plus1.text = toSignedString(SP.getInt(R.string.key_carbs_button_increment_1, FAV1_DEFAULT))
|
||||||
|
overview_carbs_plus1.setOnClickListener {
|
||||||
|
overview_carbs_carbs.value = max(0.0, overview_carbs_carbs.value
|
||||||
|
+ SP.getInt(R.string.key_carbs_button_increment_1, FAV1_DEFAULT))
|
||||||
|
validateInputs()
|
||||||
|
}
|
||||||
|
|
||||||
|
overview_carbs_plus2.text = toSignedString(SP.getInt(R.string.key_carbs_button_increment_2, FAV2_DEFAULT))
|
||||||
|
overview_carbs_plus2.setOnClickListener {
|
||||||
|
overview_carbs_carbs.value = max(0.0, overview_carbs_carbs.value
|
||||||
|
+ SP.getInt(R.string.key_carbs_button_increment_2, FAV2_DEFAULT))
|
||||||
|
validateInputs()
|
||||||
|
}
|
||||||
|
|
||||||
|
overview_carbs_plus3.text = toSignedString(SP.getInt(R.string.key_carbs_button_increment_3, FAV3_DEFAULT))
|
||||||
|
overview_carbs_plus3.setOnClickListener {
|
||||||
|
overview_carbs_carbs.value = max(0.0, overview_carbs_carbs.value
|
||||||
|
+ SP.getInt(R.string.key_carbs_button_increment_3, FAV3_DEFAULT))
|
||||||
|
validateInputs()
|
||||||
|
}
|
||||||
|
|
||||||
|
DatabaseHelper.actualBg()?.let { bgReading ->
|
||||||
|
if (bgReading.value < 72)
|
||||||
|
overview_carbs_hypo_tt.setChecked(true)
|
||||||
|
}
|
||||||
|
overview_carbs_hypo_tt.setOnClickListener {
|
||||||
|
overview_carbs_activity_tt.isChecked = false
|
||||||
|
overview_carbs_eating_soon_tt.isChecked = false
|
||||||
|
}
|
||||||
|
overview_carbs_activity_tt.setOnClickListener {
|
||||||
|
overview_carbs_hypo_tt.isChecked = false
|
||||||
|
overview_carbs_eating_soon_tt.isChecked = false
|
||||||
|
}
|
||||||
|
overview_carbs_eating_soon_tt.setOnClickListener {
|
||||||
|
overview_carbs_hypo_tt.isChecked = false
|
||||||
|
overview_carbs_activity_tt.isChecked = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun toSignedString(value: Int): String {
|
||||||
|
return if (value > 0) "+$value" else value.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun submit(): Boolean {
|
||||||
|
val carbs = overview_carbs_carbs.value.toInt()
|
||||||
|
val carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(Constraint(carbs)).value()
|
||||||
|
val units = ProfileFunctions.getSystemUnits()
|
||||||
|
val activityTTDuration = DefaultValueHelper.determineActivityTTDuration()
|
||||||
|
val activityTT = DefaultValueHelper.determineActivityTT()
|
||||||
|
val eatingSoonTTDuration = DefaultValueHelper.determineEatingSoonTTDuration()
|
||||||
|
val eatingSoonTT = DefaultValueHelper.determineEatingSoonTT()
|
||||||
|
val hypoTTDuration = DefaultValueHelper.determineHypoTTDuration()
|
||||||
|
val hypoTT = DefaultValueHelper.determineHypoTT()
|
||||||
|
val actions: LinkedList<String?> = LinkedList()
|
||||||
|
val unitLabel = if (units == Constants.MMOL) MainApp.gs(R.string.mmol) else MainApp.gs(R.string.mgdl)
|
||||||
|
|
||||||
|
val activitySelected = overview_carbs_activity_tt.isChecked
|
||||||
|
if (activitySelected)
|
||||||
|
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.tempTargetConfirmation) + "'>" + DecimalFormatter.to1Decimal(activityTT) + " " + unitLabel + " (" + activityTTDuration + " " + MainApp.gs(R.string.unit_minute_short) + ")</font>")
|
||||||
|
val eatingSoonSelected = overview_carbs_eating_soon_tt.isChecked
|
||||||
|
if (eatingSoonSelected)
|
||||||
|
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.tempTargetConfirmation) + "'>" + DecimalFormatter.to1Decimal(eatingSoonTT) + " " + unitLabel + " (" + eatingSoonTTDuration + " " + MainApp.gs(R.string.unit_minute_short) + ")</font>")
|
||||||
|
val hypoSelected = overview_carbs_hypo_tt.isChecked
|
||||||
|
if (hypoSelected)
|
||||||
|
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.tempTargetConfirmation) + "'>" + DecimalFormatter.to1Decimal(hypoTT) + " " + unitLabel + " (" + hypoTTDuration + " " + MainApp.gs(R.string.unit_minute_short) + ")</font>")
|
||||||
|
|
||||||
|
val timeOffset = overview_carbs_time.value.toInt()
|
||||||
|
val time = eventTime + timeOffset * 1000 * 60
|
||||||
|
if (timeOffset != 0)
|
||||||
|
actions.add(MainApp.gs(R.string.time) + ": " + DateUtil.dateAndTimeString(time))
|
||||||
|
val duration = overview_carbs_duration.value.toInt()
|
||||||
|
if (duration > 0)
|
||||||
|
actions.add(MainApp.gs(R.string.duration) + ": " + duration + MainApp.gs(R.string.shorthour))
|
||||||
|
if (carbsAfterConstraints > 0) {
|
||||||
|
actions.add(MainApp.gs(R.string.carbs) + ": " + "<font color='" + MainApp.gc(R.color.carbs) + "'>" + MainApp.gs(R.string.format_carbs, carbsAfterConstraints) + "</font>")
|
||||||
|
if (carbsAfterConstraints != carbs)
|
||||||
|
actions.add("<font color='" + MainApp.gc(R.color.warning) + "'>" + MainApp.gs(R.string.carbsconstraintapplied) + "</font>")
|
||||||
|
}
|
||||||
|
val notes = notes.text.toString()
|
||||||
|
if (notes.isNotEmpty())
|
||||||
|
actions.add(MainApp.gs(R.string.careportal_newnstreatment_notes_label) + ": " + notes)
|
||||||
|
|
||||||
|
if (eventTimeChanged)
|
||||||
|
actions.add(MainApp.gs(R.string.time) + ": " + DateUtil.dateAndTimeString(eventTime))
|
||||||
|
|
||||||
|
if (carbsAfterConstraints > 0 || activitySelected || eatingSoonSelected || hypoSelected) {
|
||||||
|
activity?.let { activity ->
|
||||||
|
OKDialog.showConfirmation(activity, MainApp.gs(R.string.carbs), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), Runnable {
|
||||||
|
if (activitySelected) {
|
||||||
|
val tempTarget = TempTarget()
|
||||||
|
.date(eventTime)
|
||||||
|
.duration(activityTTDuration)
|
||||||
|
.reason(MainApp.gs(R.string.activity))
|
||||||
|
.source(Source.USER)
|
||||||
|
.low(Profile.toMgdl(activityTT, ProfileFunctions.getSystemUnits()))
|
||||||
|
.high(Profile.toMgdl(activityTT, ProfileFunctions.getSystemUnits()))
|
||||||
|
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget)
|
||||||
|
} else if (eatingSoonSelected) {
|
||||||
|
val tempTarget = TempTarget()
|
||||||
|
.date(eventTime)
|
||||||
|
.duration(eatingSoonTTDuration)
|
||||||
|
.reason(MainApp.gs(R.string.eatingsoon))
|
||||||
|
.source(Source.USER)
|
||||||
|
.low(Profile.toMgdl(eatingSoonTT, ProfileFunctions.getSystemUnits()))
|
||||||
|
.high(Profile.toMgdl(eatingSoonTT, ProfileFunctions.getSystemUnits()))
|
||||||
|
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget)
|
||||||
|
} else if (hypoSelected) {
|
||||||
|
val tempTarget = TempTarget()
|
||||||
|
.date(eventTime)
|
||||||
|
.duration(hypoTTDuration)
|
||||||
|
.reason(MainApp.gs(R.string.hypo))
|
||||||
|
.source(Source.USER)
|
||||||
|
.low(Profile.toMgdl(hypoTT, ProfileFunctions.getSystemUnits()))
|
||||||
|
.high(Profile.toMgdl(hypoTT, ProfileFunctions.getSystemUnits()))
|
||||||
|
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget)
|
||||||
|
}
|
||||||
|
if (carbsAfterConstraints > 0) {
|
||||||
|
if (duration == 0) {
|
||||||
|
CarbsGenerator.createCarb(carbsAfterConstraints, time, CareportalEvent.CARBCORRECTION, notes)
|
||||||
|
} else {
|
||||||
|
CarbsGenerator.generateCarbs(carbsAfterConstraints, time, duration, notes)
|
||||||
|
NSUpload.uploadEvent(CareportalEvent.NOTE, time - 2000, MainApp.gs(R.string.generated_ecarbs_note, carbsAfterConstraints, duration, timeOffset))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, null)
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
activity?.let { activity ->
|
||||||
|
OKDialog.show(activity, MainApp.gs(R.string.carbs), MainApp.gs(R.string.no_action_selected))
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,189 @@
|
||||||
|
package info.nightscout.androidaps.dialogs
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.text.Editable
|
||||||
|
import android.text.TextWatcher
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.Button
|
||||||
|
import androidx.annotation.StringRes
|
||||||
|
import com.google.common.base.Joiner
|
||||||
|
import info.nightscout.androidaps.Constants
|
||||||
|
import info.nightscout.androidaps.MainApp
|
||||||
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.data.Profile
|
||||||
|
import info.nightscout.androidaps.db.CareportalEvent
|
||||||
|
import info.nightscout.androidaps.db.Source
|
||||||
|
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
|
||||||
|
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
|
||||||
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
|
||||||
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
|
import info.nightscout.androidaps.utils.HtmlHelper
|
||||||
|
import info.nightscout.androidaps.utils.OKDialog
|
||||||
|
import info.nightscout.androidaps.utils.SP
|
||||||
|
import info.nightscout.androidaps.utils.Translator
|
||||||
|
import kotlinx.android.synthetic.main.dialog_care.*
|
||||||
|
import kotlinx.android.synthetic.main.notes.*
|
||||||
|
import kotlinx.android.synthetic.main.okcancel.*
|
||||||
|
import org.json.JSONObject
|
||||||
|
import java.text.DecimalFormat
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class CareDialog : DialogFragmentWithDate() {
|
||||||
|
|
||||||
|
enum class EventType {
|
||||||
|
BGCHECK,
|
||||||
|
SENSOR_INSERT,
|
||||||
|
BATTERY_CHANGE,
|
||||||
|
NOTE,
|
||||||
|
EXERCISE
|
||||||
|
}
|
||||||
|
|
||||||
|
private var options: EventType = EventType.BGCHECK
|
||||||
|
@StringRes
|
||||||
|
private var event: Int = R.string.none
|
||||||
|
|
||||||
|
fun setOptions(options: EventType, @StringRes event: Int): CareDialog {
|
||||||
|
this.options = options
|
||||||
|
this.event = event
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSaveInstanceState(savedInstanceState: Bundle) {
|
||||||
|
super.onSaveInstanceState(savedInstanceState)
|
||||||
|
savedInstanceState.putDouble("actions_care_bg", actions_care_bg.value)
|
||||||
|
savedInstanceState.putDouble("actions_care_duration", actions_care_duration.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?): View? {
|
||||||
|
onCreateViewGeneral()
|
||||||
|
return inflater.inflate(R.layout.dialog_care, container, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
actions_care_icon.setImageResource(when (options) {
|
||||||
|
EventType.BGCHECK -> R.drawable.icon_cp_bgcheck
|
||||||
|
EventType.SENSOR_INSERT -> R.drawable.icon_cp_cgm_insert
|
||||||
|
EventType.BATTERY_CHANGE -> R.drawable.icon_cp_pump_battery
|
||||||
|
EventType.NOTE -> R.drawable.icon_cp_note
|
||||||
|
EventType.EXERCISE -> R.drawable.icon_cp_exercise
|
||||||
|
})
|
||||||
|
actions_care_title.text = MainApp.gs(when (options) {
|
||||||
|
EventType.BGCHECK -> R.string.careportal_bgcheck
|
||||||
|
EventType.SENSOR_INSERT -> R.string.careportal_cgmsensorinsert
|
||||||
|
EventType.BATTERY_CHANGE -> R.string.careportal_pumpbatterychange
|
||||||
|
EventType.NOTE -> R.string.careportal_note
|
||||||
|
EventType.EXERCISE -> R.string.careportal_exercise
|
||||||
|
})
|
||||||
|
|
||||||
|
when (options) {
|
||||||
|
EventType.BGCHECK -> {
|
||||||
|
action_care_duration_layout.visibility = View.GONE
|
||||||
|
}
|
||||||
|
EventType.SENSOR_INSERT,
|
||||||
|
EventType.BATTERY_CHANGE -> {
|
||||||
|
action_care_bg_layout.visibility = View.GONE
|
||||||
|
actions_care_bgsource.visibility = View.GONE
|
||||||
|
action_care_duration_layout.visibility = View.GONE
|
||||||
|
}
|
||||||
|
EventType.NOTE,
|
||||||
|
EventType.EXERCISE -> {
|
||||||
|
action_care_bg_layout.visibility = View.GONE
|
||||||
|
actions_care_bgsource.visibility = View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val bg = Profile.fromMgdlToUnits(GlucoseStatus.getGlucoseStatusData()?.glucose
|
||||||
|
?: 0.0, ProfileFunctions.getSystemUnits())
|
||||||
|
val bgTextWatcher: TextWatcher = object : TextWatcher {
|
||||||
|
override fun afterTextChanged(s: Editable) {}
|
||||||
|
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
|
||||||
|
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
|
||||||
|
if (actions_care_sensor.isChecked) actions_care_meter.isChecked = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ProfileFunctions.getSystemUnits() == Constants.MMOL) {
|
||||||
|
actions_care_bgunits.text = MainApp.gs(R.string.mmol)
|
||||||
|
actions_care_bg.setParams(savedInstanceState?.getDouble("actions_care_bg")
|
||||||
|
?: bg, 2.0, 30.0, 0.1, DecimalFormat("0.0"), false, ok, bgTextWatcher)
|
||||||
|
} else {
|
||||||
|
actions_care_bgunits.text = MainApp.gs(R.string.mgdl)
|
||||||
|
actions_care_bg.setParams(savedInstanceState?.getDouble("actions_care_bg")
|
||||||
|
?: bg, 36.0, 500.0, 1.0, DecimalFormat("0"), false, ok, bgTextWatcher)
|
||||||
|
}
|
||||||
|
actions_care_duration.setParams(savedInstanceState?.getDouble("actions_care_duration")
|
||||||
|
?: 0.0, 0.0, Constants.MAX_PROFILE_SWITCH_DURATION, 10.0, DecimalFormat("0"), false, ok)
|
||||||
|
if (options == EventType.NOTE)
|
||||||
|
notes_layout?.visibility = View.VISIBLE // independent to preferences
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun submit(): Boolean {
|
||||||
|
val enteredBy = SP.getString("careportal_enteredby", "")
|
||||||
|
val unitResId = if (ProfileFunctions.getSystemUnits() == Constants.MGDL) R.string.mgdl else R.string.mmol
|
||||||
|
|
||||||
|
val json = JSONObject()
|
||||||
|
val actions: LinkedList<String> = LinkedList()
|
||||||
|
if (options == EventType.BGCHECK) {
|
||||||
|
val type =
|
||||||
|
when {
|
||||||
|
actions_care_meter.isChecked -> "Finger"
|
||||||
|
actions_care_sensor.isChecked -> "Sensor"
|
||||||
|
else -> "Manual"
|
||||||
|
}
|
||||||
|
actions.add(MainApp.gs(R.string.careportal_newnstreatment_glucosetype) + ": " + Translator.translate(type))
|
||||||
|
actions.add(MainApp.gs(R.string.treatments_wizard_bg_label) + ": " + Profile.toCurrentUnitsString(actions_care_bg.value) + " " + MainApp.gs(unitResId))
|
||||||
|
json.put("glucose", actions_care_bg.value)
|
||||||
|
json.put("glucoseType", type)
|
||||||
|
}
|
||||||
|
if (options == EventType.NOTE || options == EventType.EXERCISE) {
|
||||||
|
actions.add(MainApp.gs(R.string.careportal_newnstreatment_duration_label) + ": " + MainApp.gs(R.string.format_mins, actions_care_duration.value.toInt()))
|
||||||
|
json.put("duration", actions_care_duration.value.toInt())
|
||||||
|
}
|
||||||
|
val notes = notes.text.toString()
|
||||||
|
if (notes.isNotEmpty()) {
|
||||||
|
actions.add(MainApp.gs(R.string.careportal_newnstreatment_notes_label) + ": " + notes)
|
||||||
|
json.put("notes", notes)
|
||||||
|
}
|
||||||
|
eventTime -= eventTime % 1000
|
||||||
|
|
||||||
|
if (eventTimeChanged)
|
||||||
|
actions.add(MainApp.gs(R.string.time) + ": " + DateUtil.dateAndTimeString(eventTime))
|
||||||
|
|
||||||
|
json.put("created_at", DateUtil.toISOString(eventTime))
|
||||||
|
json.put("mills", eventTime)
|
||||||
|
json.put("eventType", when (options) {
|
||||||
|
EventType.BGCHECK -> CareportalEvent.BGCHECK
|
||||||
|
EventType.SENSOR_INSERT -> CareportalEvent.SENSORCHANGE
|
||||||
|
EventType.BATTERY_CHANGE -> CareportalEvent.PUMPBATTERYCHANGE
|
||||||
|
EventType.NOTE -> CareportalEvent.NOTE
|
||||||
|
EventType.EXERCISE -> CareportalEvent.EXERCISE
|
||||||
|
})
|
||||||
|
json.put("units", ProfileFunctions.getSystemUnits())
|
||||||
|
if (enteredBy.isNotEmpty())
|
||||||
|
json.put("enteredBy", enteredBy)
|
||||||
|
|
||||||
|
activity?.let { activity ->
|
||||||
|
OKDialog.showConfirmation(activity, MainApp.gs(event), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), Runnable {
|
||||||
|
val careportalEvent = CareportalEvent()
|
||||||
|
careportalEvent.date = eventTime
|
||||||
|
careportalEvent.source = Source.USER
|
||||||
|
careportalEvent.eventType = when (options) {
|
||||||
|
EventType.BGCHECK -> CareportalEvent.BGCHECK
|
||||||
|
EventType.SENSOR_INSERT -> CareportalEvent.SENSORCHANGE
|
||||||
|
EventType.BATTERY_CHANGE -> CareportalEvent.PUMPBATTERYCHANGE
|
||||||
|
EventType.NOTE -> CareportalEvent.NOTE
|
||||||
|
EventType.EXERCISE -> CareportalEvent.EXERCISE
|
||||||
|
}
|
||||||
|
careportalEvent.json = json.toString()
|
||||||
|
MainApp.getDbHelper().createOrUpdate(careportalEvent)
|
||||||
|
NSUpload.uploadCareportalEntryToNS(json)
|
||||||
|
}, null)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,124 @@
|
||||||
|
package info.nightscout.androidaps.dialogs
|
||||||
|
|
||||||
|
import android.app.DatePickerDialog
|
||||||
|
import android.app.TimePickerDialog
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.text.format.DateFormat
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.view.Window
|
||||||
|
import android.view.WindowManager
|
||||||
|
import androidx.fragment.app.DialogFragment
|
||||||
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
|
import info.nightscout.androidaps.utils.SP
|
||||||
|
import info.nightscout.androidaps.utils.toVisibility
|
||||||
|
import kotlinx.android.synthetic.main.datetime.*
|
||||||
|
import kotlinx.android.synthetic.main.notes.*
|
||||||
|
import kotlinx.android.synthetic.main.okcancel.*
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
abstract class DialogFragmentWithDate : DialogFragment() {
|
||||||
|
private val log = LoggerFactory.getLogger(DialogFragmentWithDate::class.java)
|
||||||
|
|
||||||
|
var eventTime = DateUtil.now()
|
||||||
|
var eventTimeChanged = false
|
||||||
|
|
||||||
|
//one shot guards
|
||||||
|
private var okClicked: Boolean = false
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private var seconds: Int = (Math.random() * 59.0).toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStart() {
|
||||||
|
super.onStart()
|
||||||
|
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSaveInstanceState(savedInstanceState: Bundle) {
|
||||||
|
super.onSaveInstanceState(savedInstanceState)
|
||||||
|
savedInstanceState.putLong("eventTime", eventTime)
|
||||||
|
savedInstanceState.putBoolean("eventTimeChanged", eventTimeChanged)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onCreateViewGeneral() {
|
||||||
|
dialog?.window?.requestFeature(Window.FEATURE_NO_TITLE)
|
||||||
|
dialog?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN)
|
||||||
|
isCancelable = true
|
||||||
|
dialog?.setCanceledOnTouchOutside(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
eventTime = savedInstanceState?.getLong("eventTime") ?: DateUtil.now()
|
||||||
|
eventTimeChanged = savedInstanceState?.getBoolean("eventTimeChanged") ?: false
|
||||||
|
overview_eventdate?.text = DateUtil.dateString(eventTime)
|
||||||
|
overview_eventtime?.text = DateUtil.timeString(eventTime)
|
||||||
|
|
||||||
|
// create an OnDateSetListener
|
||||||
|
val dateSetListener = DatePickerDialog.OnDateSetListener { _, year, monthOfYear, dayOfMonth ->
|
||||||
|
val cal = Calendar.getInstance()
|
||||||
|
cal.timeInMillis = eventTime
|
||||||
|
cal.set(Calendar.YEAR, year)
|
||||||
|
cal.set(Calendar.MONTH, monthOfYear)
|
||||||
|
cal.set(Calendar.DAY_OF_MONTH, dayOfMonth)
|
||||||
|
eventTime = cal.timeInMillis
|
||||||
|
eventTimeChanged = true
|
||||||
|
overview_eventdate?.text = DateUtil.dateString(eventTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
overview_eventdate?.setOnClickListener {
|
||||||
|
context?.let {
|
||||||
|
val cal = Calendar.getInstance()
|
||||||
|
cal.timeInMillis = eventTime
|
||||||
|
DatePickerDialog(it, dateSetListener,
|
||||||
|
cal.get(Calendar.YEAR),
|
||||||
|
cal.get(Calendar.MONTH),
|
||||||
|
cal.get(Calendar.DAY_OF_MONTH)
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// create an OnTimeSetListener
|
||||||
|
val timeSetListener = TimePickerDialog.OnTimeSetListener { _, hour, minute ->
|
||||||
|
val cal = Calendar.getInstance()
|
||||||
|
cal.timeInMillis = eventTime
|
||||||
|
cal.set(Calendar.HOUR_OF_DAY, hour)
|
||||||
|
cal.set(Calendar.MINUTE, minute)
|
||||||
|
cal.set(Calendar.SECOND, seconds++) // randomize seconds to prevent creating record of the same time, if user choose time manually
|
||||||
|
eventTime = cal.timeInMillis
|
||||||
|
eventTimeChanged = true
|
||||||
|
overview_eventtime?.text = DateUtil.timeString(eventTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
overview_eventtime?.setOnClickListener {
|
||||||
|
context?.let {
|
||||||
|
val cal = Calendar.getInstance()
|
||||||
|
cal.timeInMillis = eventTime
|
||||||
|
TimePickerDialog(it, timeSetListener,
|
||||||
|
cal.get(Calendar.HOUR_OF_DAY),
|
||||||
|
cal.get(Calendar.MINUTE),
|
||||||
|
DateFormat.is24HourFormat(context)
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
notes_layout?.visibility = SP.getBoolean(R.string.key_show_notes_entry_dialogs, false).toVisibility()
|
||||||
|
|
||||||
|
ok.setOnClickListener {
|
||||||
|
synchronized(okClicked) {
|
||||||
|
if (okClicked) {
|
||||||
|
log.debug("guarding: ok already clicked")
|
||||||
|
} else {
|
||||||
|
okClicked = true
|
||||||
|
if (submit()) dismiss()
|
||||||
|
else okClicked = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cancel.setOnClickListener { dismiss() }
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract fun submit(): Boolean
|
||||||
|
}
|
|
@ -1,5 +1,4 @@
|
||||||
package info.nightscout.androidaps.plugins.general.overview.dialogs
|
package info.nightscout.androidaps.dialogs
|
||||||
|
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
@ -7,11 +6,14 @@ import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import android.view.Window
|
||||||
|
import android.view.WindowManager
|
||||||
import androidx.fragment.app.DialogFragment
|
import androidx.fragment.app.DialogFragment
|
||||||
import info.nightscout.androidaps.MainApp
|
import info.nightscout.androidaps.MainApp
|
||||||
import info.nightscout.androidaps.R
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.activities.ErrorHelperActivity
|
||||||
import info.nightscout.androidaps.services.AlarmSoundService
|
import info.nightscout.androidaps.services.AlarmSoundService
|
||||||
import kotlinx.android.synthetic.main.overview_error_dialog.*
|
import kotlinx.android.synthetic.main.dialog_error.*
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
|
|
||||||
class ErrorDialog : DialogFragment() {
|
class ErrorDialog : DialogFragment() {
|
||||||
|
@ -24,20 +26,23 @@ class ErrorDialog : DialogFragment() {
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?): View? {
|
savedInstanceState: Bundle?): View? {
|
||||||
dialog?.setTitle(title)
|
dialog?.window?.requestFeature(Window.FEATURE_NO_TITLE)
|
||||||
isCancelable = false
|
dialog?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN)
|
||||||
|
isCancelable = true
|
||||||
|
dialog?.setCanceledOnTouchOutside(false)
|
||||||
|
|
||||||
savedInstanceState?.let { bundle ->
|
savedInstanceState?.let { bundle ->
|
||||||
bundle.getString("status")?.let { status = it }
|
bundle.getString("status")?.let { status = it }
|
||||||
bundle.getString("title")?.let { title = it }
|
bundle.getString("title")?.let { title = it }
|
||||||
sound = bundle.getInt("sound", R.raw.error)
|
sound = bundle.getInt("sound", R.raw.error)
|
||||||
}
|
}
|
||||||
return inflater.inflate(R.layout.overview_error_dialog, container, false)
|
return inflater.inflate(R.layout.dialog_error, container, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
error_title.text = title
|
||||||
overview_error_ok.setOnClickListener {
|
overview_error_ok.setOnClickListener {
|
||||||
log.debug("Error dialog ok button pressed")
|
log.debug("Error dialog ok button pressed")
|
||||||
dismiss()
|
dismiss()
|
||||||
|
@ -56,9 +61,13 @@ class ErrorDialog : DialogFragment() {
|
||||||
bundle.putInt("sound", sound)
|
bundle.putInt("sound", sound)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onStart() {
|
||||||
|
super.onStart()
|
||||||
|
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
|
||||||
overview_error_status.text = status
|
overview_error_status.text = status
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,5 +90,5 @@ class ErrorDialog : DialogFragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun stopAlarm() =
|
private fun stopAlarm() =
|
||||||
MainApp.instance().stopService(Intent(MainApp.instance().applicationContext, AlarmSoundService::class.java))
|
MainApp.instance().stopService(Intent(MainApp.instance().applicationContext, AlarmSoundService::class.java))
|
||||||
}
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
package info.nightscout.androidaps.dialogs
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import com.google.common.base.Joiner
|
||||||
|
import info.nightscout.androidaps.MainApp
|
||||||
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.activities.ErrorHelperActivity
|
||||||
|
import info.nightscout.androidaps.interfaces.Constraint
|
||||||
|
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
|
||||||
|
import info.nightscout.androidaps.queue.Callback
|
||||||
|
import info.nightscout.androidaps.utils.HtmlHelper
|
||||||
|
import info.nightscout.androidaps.utils.OKDialog
|
||||||
|
import info.nightscout.androidaps.utils.SafeParse
|
||||||
|
import kotlinx.android.synthetic.main.dialog_extendedbolus.*
|
||||||
|
import kotlinx.android.synthetic.main.okcancel.*
|
||||||
|
import java.text.DecimalFormat
|
||||||
|
import java.util.*
|
||||||
|
import kotlin.math.abs
|
||||||
|
|
||||||
|
class ExtendedBolusDialog : DialogFragmentWithDate() {
|
||||||
|
|
||||||
|
override fun onSaveInstanceState(savedInstanceState: Bundle) {
|
||||||
|
super.onSaveInstanceState(savedInstanceState)
|
||||||
|
savedInstanceState.putDouble("actions_extendedbolus_insulin", actions_extendedbolus_insulin.value)
|
||||||
|
savedInstanceState.putDouble("actions_extendedbolus_duration", actions_extendedbolus_duration.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?): View? {
|
||||||
|
onCreateViewGeneral()
|
||||||
|
return inflater.inflate(R.layout.dialog_extendedbolus, container, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
val pumpDescription = ConfigBuilderPlugin.getPlugin().activePump?.pumpDescription ?: return
|
||||||
|
|
||||||
|
val maxInsulin = MainApp.getConstraintChecker().maxExtendedBolusAllowed.value()
|
||||||
|
val extendedStep = pumpDescription.extendedBolusStep
|
||||||
|
actions_extendedbolus_insulin.setParams(savedInstanceState?.getDouble("actions_extendedbolus_insulin")
|
||||||
|
?: extendedStep, extendedStep, maxInsulin, extendedStep, DecimalFormat("0.00"), false, ok)
|
||||||
|
|
||||||
|
val extendedDurationStep = pumpDescription.extendedBolusDurationStep
|
||||||
|
val extendedMaxDuration = pumpDescription.extendedBolusMaxDuration
|
||||||
|
actions_extendedbolus_duration.setParams(savedInstanceState?.getDouble("actions_extendedbolus_duration")
|
||||||
|
?: extendedDurationStep, extendedDurationStep, extendedMaxDuration, extendedDurationStep, DecimalFormat("0"), false, ok)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun submit(): Boolean {
|
||||||
|
val insulin = SafeParse.stringToDouble(actions_extendedbolus_insulin.text)
|
||||||
|
val durationInMinutes = SafeParse.stringToInt(actions_extendedbolus_duration.text)
|
||||||
|
val actions: LinkedList<String> = LinkedList()
|
||||||
|
val insulinAfterConstraint = MainApp.getConstraintChecker().applyExtendedBolusConstraints(Constraint(insulin)).value()
|
||||||
|
actions.add(MainApp.gs(R.string.formatinsulinunits, insulinAfterConstraint))
|
||||||
|
actions.add(MainApp.gs(R.string.duration) + ": " + MainApp.gs(R.string.format_mins, durationInMinutes))
|
||||||
|
if (abs(insulinAfterConstraint - insulin) > 0.01)
|
||||||
|
actions.add("<font color='" + MainApp.gc(R.color.warning) + "'>" + MainApp.gs(R.string.constraintapllied) + "</font>")
|
||||||
|
|
||||||
|
activity?.let { activity ->
|
||||||
|
OKDialog.showConfirmation(activity, MainApp.gs(R.string.extended_bolus), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), Runnable {
|
||||||
|
ConfigBuilderPlugin.getPlugin().commandQueue.extendedBolus(insulinAfterConstraint, durationInMinutes, object : Callback() {
|
||||||
|
override fun run() {
|
||||||
|
if (!result.success) {
|
||||||
|
val i = Intent(MainApp.instance(), ErrorHelperActivity::class.java)
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}, null)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,169 @@
|
||||||
|
package info.nightscout.androidaps.dialogs
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import com.google.common.base.Joiner
|
||||||
|
import info.nightscout.androidaps.MainApp
|
||||||
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.activities.ErrorHelperActivity
|
||||||
|
import info.nightscout.androidaps.data.DetailedBolusInfo
|
||||||
|
import info.nightscout.androidaps.db.CareportalEvent
|
||||||
|
import info.nightscout.androidaps.db.Source
|
||||||
|
import info.nightscout.androidaps.interfaces.Constraint
|
||||||
|
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
|
||||||
|
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
|
||||||
|
import info.nightscout.androidaps.queue.Callback
|
||||||
|
import info.nightscout.androidaps.utils.*
|
||||||
|
import kotlinx.android.synthetic.main.dialog_fill.*
|
||||||
|
import kotlinx.android.synthetic.main.notes.*
|
||||||
|
import kotlinx.android.synthetic.main.okcancel.*
|
||||||
|
import org.json.JSONException
|
||||||
|
import org.json.JSONObject
|
||||||
|
import java.util.*
|
||||||
|
import kotlin.math.abs
|
||||||
|
|
||||||
|
class FillDialog : DialogFragmentWithDate() {
|
||||||
|
|
||||||
|
override fun onSaveInstanceState(savedInstanceState: Bundle) {
|
||||||
|
super.onSaveInstanceState(savedInstanceState)
|
||||||
|
savedInstanceState.putDouble("fill_insulinamount", fill_insulinamount.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?): View? {
|
||||||
|
onCreateViewGeneral()
|
||||||
|
return inflater.inflate(R.layout.dialog_fill, container, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
val maxInsulin = MainApp.getConstraintChecker().maxBolusAllowed.value()
|
||||||
|
val bolusStep = ConfigBuilderPlugin.getPlugin().activePump!!.pumpDescription.bolusStep
|
||||||
|
fill_insulinamount.setParams(savedInstanceState?.getDouble("fill_insulinamount")
|
||||||
|
?: 0.0, 0.0, maxInsulin, bolusStep, DecimalFormatter.pumpSupportedBolusFormat(), true, ok)
|
||||||
|
val amount1 = SP.getDouble("fill_button1", 0.3)
|
||||||
|
if (amount1 > 0) {
|
||||||
|
fill_preset_button1.visibility = View.VISIBLE
|
||||||
|
fill_preset_button1.text = DecimalFormatter.toPumpSupportedBolus(amount1) // + "U");
|
||||||
|
fill_preset_button1.setOnClickListener { fill_insulinamount.value = amount1 }
|
||||||
|
} else {
|
||||||
|
fill_preset_button1.visibility = View.GONE
|
||||||
|
}
|
||||||
|
val amount2 = SP.getDouble("fill_button2", 0.0)
|
||||||
|
if (amount2 > 0) {
|
||||||
|
fill_preset_button2.visibility = View.VISIBLE
|
||||||
|
fill_preset_button2.text = DecimalFormatter.toPumpSupportedBolus(amount2) // + "U");
|
||||||
|
fill_preset_button2.setOnClickListener { fill_insulinamount.value = amount2 }
|
||||||
|
} else {
|
||||||
|
fill_preset_button2.visibility = View.GONE
|
||||||
|
}
|
||||||
|
val amount3 = SP.getDouble("fill_button3", 0.0)
|
||||||
|
if (amount3 > 0) {
|
||||||
|
fill_preset_button3.visibility = View.VISIBLE
|
||||||
|
fill_preset_button3.text = DecimalFormatter.toPumpSupportedBolus(amount3) // + "U");
|
||||||
|
fill_preset_button3.setOnClickListener { fill_insulinamount.value = amount3 }
|
||||||
|
} else {
|
||||||
|
fill_preset_button3.visibility = View.GONE
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun submit(): Boolean {
|
||||||
|
val insulin = SafeParse.stringToDouble(fill_insulinamount.text)
|
||||||
|
val actions: LinkedList<String?> = LinkedList()
|
||||||
|
|
||||||
|
val insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(Constraint(insulin)).value()
|
||||||
|
if (insulinAfterConstraints > 0) {
|
||||||
|
actions.add(MainApp.gs(R.string.fillwarning))
|
||||||
|
actions.add("")
|
||||||
|
actions.add(MainApp.gs(R.string.bolus) + ": " + "<font color='" + MainApp.gc(R.color.colorInsulinButton) + "'>" + DecimalFormatter.toPumpSupportedBolus(insulinAfterConstraints) + MainApp.gs(R.string.insulin_unit_shortname) + "</font>")
|
||||||
|
if (abs(insulinAfterConstraints - insulin) > 0.01)
|
||||||
|
actions.add(MainApp.gs(R.string.bolusconstraintappliedwarning, MainApp.gc(R.color.warning), insulin, insulinAfterConstraints))
|
||||||
|
}
|
||||||
|
val siteChange = fill_catheter_change.isChecked
|
||||||
|
if (siteChange)
|
||||||
|
actions.add("" + "<font color='" + MainApp.gc(R.color.actionsConfirm) + "'>" + MainApp.gs(R.string.record_pump_site_change) + "</font>")
|
||||||
|
val insulinChange = fill_cartridge_change.isChecked
|
||||||
|
if (insulinChange)
|
||||||
|
actions.add("" + "<font color='" + MainApp.gc(R.color.actionsConfirm) + "'>" + MainApp.gs(R.string.record_insulin_cartridge_change) + "</font>")
|
||||||
|
val notes = notes.text.toString()
|
||||||
|
if (notes.isNotEmpty())
|
||||||
|
actions.add(MainApp.gs(R.string.careportal_newnstreatment_notes_label) + ": " + notes)
|
||||||
|
eventTime -= eventTime % 1000
|
||||||
|
|
||||||
|
if (eventTimeChanged)
|
||||||
|
actions.add(MainApp.gs(R.string.time) + ": " + DateUtil.dateAndTimeString(eventTime))
|
||||||
|
|
||||||
|
if (insulinAfterConstraints > 0 || fill_catheter_change.isChecked || fill_cartridge_change.isChecked) {
|
||||||
|
activity?.let { activity ->
|
||||||
|
OKDialog.showConfirmation(activity, MainApp.gs(R.string.primefill), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), Runnable {
|
||||||
|
if (insulinAfterConstraints > 0) {
|
||||||
|
requestPrimeBolus(insulinAfterConstraints, notes)
|
||||||
|
}
|
||||||
|
if (siteChange) {
|
||||||
|
generateCareportalEvent(CareportalEvent.SITECHANGE, eventTime, notes)
|
||||||
|
}
|
||||||
|
if (insulinChange) {
|
||||||
|
// add a second for case of both checked
|
||||||
|
generateCareportalEvent(CareportalEvent.INSULINCHANGE, eventTime + 1000, notes)
|
||||||
|
}
|
||||||
|
}, null)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
activity?.let { activity ->
|
||||||
|
OKDialog.show(activity, MainApp.gs(R.string.primefill), MainApp.gs(R.string.no_action_selected))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dismiss()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun requestPrimeBolus(insulin: Double, notes: String) {
|
||||||
|
val detailedBolusInfo = DetailedBolusInfo()
|
||||||
|
detailedBolusInfo.insulin = insulin
|
||||||
|
detailedBolusInfo.context = context
|
||||||
|
detailedBolusInfo.source = Source.USER
|
||||||
|
detailedBolusInfo.isValid = false // do not count it in IOB (for pump history)
|
||||||
|
detailedBolusInfo.notes = notes
|
||||||
|
ConfigBuilderPlugin.getPlugin().commandQueue.bolus(detailedBolusInfo, object : Callback() {
|
||||||
|
override fun run() {
|
||||||
|
if (!result.success) {
|
||||||
|
val i = Intent(MainApp.instance(), ErrorHelperActivity::class.java)
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generateCareportalEvent(eventType: String, time: Long, notes: String) {
|
||||||
|
val careportalEvent = CareportalEvent()
|
||||||
|
careportalEvent.source = Source.USER
|
||||||
|
careportalEvent.date = time
|
||||||
|
careportalEvent.json = generateJson(eventType, time, notes).toString()
|
||||||
|
careportalEvent.eventType = eventType
|
||||||
|
MainApp.getDbHelper().createOrUpdate(careportalEvent)
|
||||||
|
NSUpload.uploadEvent(eventType, time, notes)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generateJson(careportalEvent: String, time: Long, notes: String): JSONObject {
|
||||||
|
val data = JSONObject()
|
||||||
|
try {
|
||||||
|
data.put("eventType", careportalEvent)
|
||||||
|
data.put("created_at", DateUtil.toISOString(time))
|
||||||
|
data.put("mills", time)
|
||||||
|
data.put("enteredBy", SP.getString("careportal_enteredby", MainApp.gs(R.string.app_name)))
|
||||||
|
if (notes.isNotEmpty()) data.put("notes", notes)
|
||||||
|
} catch (ignored: JSONException) {
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,193 @@
|
||||||
|
package info.nightscout.androidaps.dialogs
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.text.Editable
|
||||||
|
import android.text.TextWatcher
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import com.google.common.base.Joiner
|
||||||
|
import info.nightscout.androidaps.Constants
|
||||||
|
import info.nightscout.androidaps.MainApp
|
||||||
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.activities.ErrorHelperActivity
|
||||||
|
import info.nightscout.androidaps.data.DetailedBolusInfo
|
||||||
|
import info.nightscout.androidaps.data.Profile
|
||||||
|
import info.nightscout.androidaps.db.CareportalEvent
|
||||||
|
import info.nightscout.androidaps.db.Source
|
||||||
|
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.ProfileFunctions
|
||||||
|
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
||||||
|
import info.nightscout.androidaps.queue.Callback
|
||||||
|
import info.nightscout.androidaps.utils.*
|
||||||
|
import kotlinx.android.synthetic.main.dialog_insulin.*
|
||||||
|
import kotlinx.android.synthetic.main.notes.*
|
||||||
|
import kotlinx.android.synthetic.main.okcancel.*
|
||||||
|
import java.text.DecimalFormat
|
||||||
|
import java.util.*
|
||||||
|
import kotlin.math.abs
|
||||||
|
import kotlin.math.max
|
||||||
|
|
||||||
|
class InsulinDialog : DialogFragmentWithDate() {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val PLUS1_DEFAULT = 0.5
|
||||||
|
private const val PLUS2_DEFAULT = 1.0
|
||||||
|
private const val PLUS3_DEFAULT = 2.0
|
||||||
|
}
|
||||||
|
|
||||||
|
private val maxInsulin = MainApp.getConstraintChecker().maxBolusAllowed.value()
|
||||||
|
|
||||||
|
private val textWatcher: TextWatcher = object : TextWatcher {
|
||||||
|
override fun afterTextChanged(s: Editable) {
|
||||||
|
validateInputs()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
|
||||||
|
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun validateInputs() {
|
||||||
|
if (abs(overview_insulin_time.value.toInt()) > 12 * 60) {
|
||||||
|
overview_insulin_time.value = 0.0
|
||||||
|
ToastUtils.showToastInUiThread(MainApp.instance().applicationContext, MainApp.gs(R.string.constraintapllied))
|
||||||
|
}
|
||||||
|
if (overview_insulin_amount.value > maxInsulin) {
|
||||||
|
overview_insulin_amount.value = 0.0
|
||||||
|
ToastUtils.showToastInUiThread(MainApp.instance().applicationContext, MainApp.gs(R.string.bolusconstraintapplied))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSaveInstanceState(savedInstanceState: Bundle) {
|
||||||
|
super.onSaveInstanceState(savedInstanceState)
|
||||||
|
savedInstanceState.putDouble("overview_insulin_time", overview_insulin_time.value)
|
||||||
|
savedInstanceState.putDouble("overview_insulin_amount", overview_insulin_amount.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?): View? {
|
||||||
|
onCreateViewGeneral()
|
||||||
|
return inflater.inflate(R.layout.dialog_insulin, container, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
overview_insulin_time.setParams(savedInstanceState?.getDouble("overview_insulin_time")
|
||||||
|
?: 0.0, -12 * 60.0, 12 * 60.0, 5.0, DecimalFormat("0"), false, ok, textWatcher)
|
||||||
|
overview_insulin_amount.setParams(savedInstanceState?.getDouble("overview_insulin_amount")
|
||||||
|
?: 0.0, 0.0, maxInsulin, ConfigBuilderPlugin.getPlugin().activePump!!.pumpDescription.bolusStep, DecimalFormatter.pumpSupportedBolusFormat(), false, ok, textWatcher)
|
||||||
|
|
||||||
|
overview_insulin_plus05.text = toSignedString(SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_1), PLUS1_DEFAULT))
|
||||||
|
overview_insulin_plus05.setOnClickListener {
|
||||||
|
overview_insulin_amount.value = max(0.0, overview_insulin_amount.value
|
||||||
|
+ SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_1), PLUS1_DEFAULT))
|
||||||
|
validateInputs()
|
||||||
|
}
|
||||||
|
overview_insulin_plus10.text = toSignedString(SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_2), PLUS2_DEFAULT))
|
||||||
|
overview_insulin_plus10.setOnClickListener {
|
||||||
|
overview_insulin_amount.value = max(0.0, overview_insulin_amount.value
|
||||||
|
+ SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_2), PLUS2_DEFAULT))
|
||||||
|
validateInputs()
|
||||||
|
}
|
||||||
|
overview_insulin_plus20.text = toSignedString(SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_3), PLUS3_DEFAULT))
|
||||||
|
overview_insulin_plus20.setOnClickListener {
|
||||||
|
overview_insulin_amount.value = Math.max(0.0, overview_insulin_amount.value
|
||||||
|
+ SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_3), PLUS3_DEFAULT))
|
||||||
|
validateInputs()
|
||||||
|
}
|
||||||
|
|
||||||
|
overview_insulin_time_layout.visibility = View.GONE
|
||||||
|
overview_insulin_record_only.setOnCheckedChangeListener { _, isChecked: Boolean ->
|
||||||
|
overview_insulin_time_layout.visibility = isChecked.toVisibility()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun toSignedString(value: Double): String {
|
||||||
|
val formatted = DecimalFormatter.toPumpSupportedBolus(value)
|
||||||
|
return if (value > 0) "+$formatted" else formatted
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun submit(): Boolean {
|
||||||
|
val pumpDescription = ConfigBuilderPlugin.getPlugin().activePump?.pumpDescription
|
||||||
|
?: return false
|
||||||
|
val insulin = SafeParse.stringToDouble(overview_insulin_amount.text)
|
||||||
|
val insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(Constraint(insulin)).value()
|
||||||
|
val actions: LinkedList<String?> = LinkedList()
|
||||||
|
val units = ProfileFunctions.getSystemUnits()
|
||||||
|
val unitLabel = if (units == Constants.MMOL) MainApp.gs(R.string.mmol) else MainApp.gs(R.string.mgdl)
|
||||||
|
val recordOnlyChecked = overview_insulin_record_only.isChecked
|
||||||
|
val eatingSoonChecked = overview_insulin_start_eating_soon_tt.isChecked
|
||||||
|
|
||||||
|
if (insulinAfterConstraints > 0) {
|
||||||
|
actions.add(MainApp.gs(R.string.bolus) + ": " + "<font color='" + MainApp.gc(R.color.bolus) + "'>" + DecimalFormatter.toPumpSupportedBolus(insulinAfterConstraints) + MainApp.gs(R.string.insulin_unit_shortname) + "</font>")
|
||||||
|
if (recordOnlyChecked)
|
||||||
|
actions.add("<font color='" + MainApp.gc(R.color.warning) + "'>" + MainApp.gs(R.string.bolusrecordedonly) + "</font>")
|
||||||
|
if (abs(insulinAfterConstraints - insulin) > pumpDescription.pumpType.determineCorrectBolusStepSize(insulinAfterConstraints))
|
||||||
|
actions.add(MainApp.gs(R.string.bolusconstraintappliedwarning, MainApp.gc(R.color.warning), insulin, insulinAfterConstraints))
|
||||||
|
}
|
||||||
|
val eatingSoonTTDuration = DefaultValueHelper.determineEatingSoonTTDuration()
|
||||||
|
val eatingSoonTT = DefaultValueHelper.determineEatingSoonTT()
|
||||||
|
if (eatingSoonChecked)
|
||||||
|
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.tempTargetConfirmation) + "'>" + DecimalFormatter.to1Decimal(eatingSoonTT) + " " + unitLabel + " (" + eatingSoonTTDuration + " " + MainApp.gs(R.string.unit_minute_short) + ")</font>")
|
||||||
|
|
||||||
|
val timeOffset = overview_insulin_time.value.toInt()
|
||||||
|
val time = DateUtil.now() + T.mins(timeOffset.toLong()).msecs()
|
||||||
|
if (timeOffset != 0)
|
||||||
|
actions.add(MainApp.gs(R.string.time) + ": " + DateUtil.dateAndTimeString(time))
|
||||||
|
|
||||||
|
val notes = notes.text.toString()
|
||||||
|
if (notes.isNotEmpty())
|
||||||
|
actions.add(MainApp.gs(R.string.careportal_newnstreatment_notes_label) + ": " + notes)
|
||||||
|
|
||||||
|
if (insulinAfterConstraints > 0 || eatingSoonChecked) {
|
||||||
|
activity?.let { activity ->
|
||||||
|
OKDialog.showConfirmation(activity, MainApp.gs(R.string.bolus), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), Runnable {
|
||||||
|
if (eatingSoonChecked) {
|
||||||
|
val tempTarget = TempTarget()
|
||||||
|
.date(System.currentTimeMillis())
|
||||||
|
.duration(eatingSoonTTDuration)
|
||||||
|
.reason(MainApp.gs(R.string.eatingsoon))
|
||||||
|
.source(Source.USER)
|
||||||
|
.low(Profile.toMgdl(eatingSoonTT, ProfileFunctions.getSystemUnits()))
|
||||||
|
.high(Profile.toMgdl(eatingSoonTT, ProfileFunctions.getSystemUnits()))
|
||||||
|
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget)
|
||||||
|
}
|
||||||
|
if (insulinAfterConstraints > 0) {
|
||||||
|
val detailedBolusInfo = DetailedBolusInfo()
|
||||||
|
detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS
|
||||||
|
detailedBolusInfo.insulin = insulinAfterConstraints
|
||||||
|
detailedBolusInfo.context = context
|
||||||
|
detailedBolusInfo.source = Source.USER
|
||||||
|
detailedBolusInfo.notes = notes
|
||||||
|
if (recordOnlyChecked) {
|
||||||
|
detailedBolusInfo.date = time
|
||||||
|
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false)
|
||||||
|
} else {
|
||||||
|
detailedBolusInfo.date = DateUtil.now()
|
||||||
|
ConfigBuilderPlugin.getPlugin().commandQueue.bolus(detailedBolusInfo, object : Callback() {
|
||||||
|
override fun run() {
|
||||||
|
if (!result.success) {
|
||||||
|
val i = Intent(MainApp.instance(), ErrorHelperActivity::class.java)
|
||||||
|
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
|
||||||
|
activity?.let { activity ->
|
||||||
|
OKDialog.show(activity, MainApp.gs(R.string.bolus), MainApp.gs(R.string.no_action_selected))
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,105 @@
|
||||||
|
package info.nightscout.androidaps.dialogs
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.ArrayAdapter
|
||||||
|
import com.google.common.base.Joiner
|
||||||
|
import info.nightscout.androidaps.Constants
|
||||||
|
import info.nightscout.androidaps.MainApp
|
||||||
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
|
||||||
|
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
|
||||||
|
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
||||||
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
|
import info.nightscout.androidaps.utils.HtmlHelper
|
||||||
|
import info.nightscout.androidaps.utils.OKDialog
|
||||||
|
import kotlinx.android.synthetic.main.dialog_profileswitch.*
|
||||||
|
import kotlinx.android.synthetic.main.notes.*
|
||||||
|
import kotlinx.android.synthetic.main.okcancel.*
|
||||||
|
import java.text.DecimalFormat
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class ProfileSwitchDialog : DialogFragmentWithDate() {
|
||||||
|
|
||||||
|
override fun onSaveInstanceState(savedInstanceState: Bundle) {
|
||||||
|
super.onSaveInstanceState(savedInstanceState)
|
||||||
|
savedInstanceState.putDouble("overview_profileswitch_duration", overview_profileswitch_duration.value)
|
||||||
|
savedInstanceState.putDouble("overview_profileswitch_percentage", overview_profileswitch_percentage.value)
|
||||||
|
savedInstanceState.putDouble("overview_profileswitch_timeshift", overview_profileswitch_timeshift.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?): View? {
|
||||||
|
onCreateViewGeneral()
|
||||||
|
return inflater.inflate(R.layout.dialog_profileswitch, container, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
overview_profileswitch_duration.setParams(savedInstanceState?.getDouble("overview_profileswitch_duration")
|
||||||
|
?: 0.0, 0.0, Constants.MAX_PROFILE_SWITCH_DURATION, 10.0, DecimalFormat("0"), false, ok)
|
||||||
|
overview_profileswitch_percentage.setParams(savedInstanceState?.getDouble("overview_profileswitch_percentage")
|
||||||
|
?: 100.0, Constants.CPP_MIN_PERCENTAGE.toDouble(), Constants.CPP_MAX_PERCENTAGE.toDouble(), 1.0, DecimalFormat("0"), false, ok)
|
||||||
|
overview_profileswitch_timeshift.setParams(savedInstanceState?.getDouble("overview_profileswitch_timeshift")
|
||||||
|
?: 0.0, Constants.CPP_MIN_TIMESHIFT.toDouble(), Constants.CPP_MAX_TIMESHIFT.toDouble(), 1.0, DecimalFormat("0"), false, ok)
|
||||||
|
|
||||||
|
// profile
|
||||||
|
context?.let { context ->
|
||||||
|
val profileStore = ConfigBuilderPlugin.getPlugin().activeProfileInterface?.profile
|
||||||
|
?: return
|
||||||
|
val profileList = profileStore.getProfileList()
|
||||||
|
val adapter = ArrayAdapter(context, R.layout.spinner_centered, profileList)
|
||||||
|
overview_profileswitch_profile.adapter = adapter
|
||||||
|
// set selected to actual profile
|
||||||
|
for (p in profileList.indices)
|
||||||
|
if (profileList[p] == ProfileFunctions.getInstance().getProfileName(false))
|
||||||
|
overview_profileswitch_profile.setSelection(p)
|
||||||
|
} ?: return
|
||||||
|
|
||||||
|
TreatmentsPlugin.getPlugin().getProfileSwitchFromHistory(DateUtil.now())?.let { ps ->
|
||||||
|
if (ps.isCPP) {
|
||||||
|
overview_profileswitch_reuselayout.visibility = View.VISIBLE
|
||||||
|
overview_profileswitch_reusebutton.text = MainApp.gs(R.string.reuse) + " " + ps.percentage + "% " + ps.timeshift + "h"
|
||||||
|
overview_profileswitch_reusebutton.setOnClickListener {
|
||||||
|
overview_profileswitch_percentage.value = ps.percentage.toDouble()
|
||||||
|
overview_profileswitch_timeshift.value = ps.timeshift.toDouble()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
overview_profileswitch_reuselayout.visibility = View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun submit(): Boolean {
|
||||||
|
val profileStore = ConfigBuilderPlugin.getPlugin().activeProfileInterface?.profile
|
||||||
|
?: return false
|
||||||
|
|
||||||
|
val actions: LinkedList<String> = LinkedList()
|
||||||
|
val duration = overview_profileswitch_duration.value
|
||||||
|
if (duration > 0)
|
||||||
|
actions.add(MainApp.gs(R.string.duration) + ": " + MainApp.gs(R.string.format_hours, duration))
|
||||||
|
val profile = overview_profileswitch_profile.selectedItem.toString()
|
||||||
|
actions.add(MainApp.gs(R.string.profile) + ": " + profile)
|
||||||
|
val percent = overview_profileswitch_percentage.value.toInt()
|
||||||
|
if (percent != 100)
|
||||||
|
actions.add(MainApp.gs(R.string.percent) + ": " + percent + "%")
|
||||||
|
val timeShift = overview_profileswitch_timeshift.value.toInt()
|
||||||
|
if (timeShift != 0)
|
||||||
|
actions.add(MainApp.gs(R.string.careportal_newnstreatment_timeshift_label) + ": " + MainApp.gs(R.string.format_hours, timeShift.toDouble()))
|
||||||
|
val notes = notes.text.toString()
|
||||||
|
if (notes.isNotEmpty())
|
||||||
|
actions.add(MainApp.gs(R.string.careportal_newnstreatment_notes_label) + ": " + notes)
|
||||||
|
if (eventTimeChanged)
|
||||||
|
actions.add(MainApp.gs(R.string.time) + ": " + DateUtil.dateAndTimeString(eventTime))
|
||||||
|
|
||||||
|
activity?.let { activity ->
|
||||||
|
OKDialog.showConfirmation(activity, MainApp.gs(R.string.careportal_profileswitch), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), Runnable {
|
||||||
|
ProfileFunctions.doProfileSwitch(profileStore, profile, duration.toInt(), percent, timeShift, eventTime)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,29 +1,34 @@
|
||||||
package info.nightscout.androidaps.plugins.treatments.fragments
|
package info.nightscout.androidaps.dialogs
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import android.view.Window
|
||||||
|
import android.view.WindowManager
|
||||||
import androidx.fragment.app.DialogFragment
|
import androidx.fragment.app.DialogFragment
|
||||||
|
import info.nightscout.androidaps.Constants
|
||||||
import info.nightscout.androidaps.MainApp
|
import info.nightscout.androidaps.MainApp
|
||||||
import info.nightscout.androidaps.R
|
import info.nightscout.androidaps.R
|
||||||
import info.nightscout.androidaps.data.Profile
|
import info.nightscout.androidaps.data.Profile
|
||||||
import info.nightscout.androidaps.interfaces.ProfileInterface
|
|
||||||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
|
|
||||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
||||||
import info.nightscout.androidaps.utils.DateUtil
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
import kotlinx.android.synthetic.main.close.*
|
import kotlinx.android.synthetic.main.close.*
|
||||||
import kotlinx.android.synthetic.main.profileviewer_fragment.*
|
import kotlinx.android.synthetic.main.dialog_profileviewer.*
|
||||||
|
import org.json.JSONObject
|
||||||
|
|
||||||
class ProfileViewerDialog : DialogFragment() {
|
class ProfileViewerDialog : DialogFragment() {
|
||||||
private var time: Long = 0
|
private var time: Long = 0
|
||||||
|
|
||||||
enum class Mode(val i: Int) {
|
enum class Mode(val i: Int) {
|
||||||
RUNNING_PROFILE(1),
|
RUNNING_PROFILE(1),
|
||||||
PUMP_PROFILE(2)
|
CUSTOM_PROFILE(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
private var mode: Mode = Mode.RUNNING_PROFILE;
|
private var mode: Mode = Mode.RUNNING_PROFILE
|
||||||
|
private var customProfileJson: String = ""
|
||||||
|
private var customProfileName: String = ""
|
||||||
|
private var customProfileUnits: String = Constants.MGDL
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?): View? {
|
savedInstanceState: Bundle?): View? {
|
||||||
|
@ -31,19 +36,23 @@ class ProfileViewerDialog : DialogFragment() {
|
||||||
(savedInstanceState ?: arguments)?.let { bundle ->
|
(savedInstanceState ?: arguments)?.let { bundle ->
|
||||||
time = bundle.getLong("time", 0)
|
time = bundle.getLong("time", 0)
|
||||||
mode = Mode.values()[bundle.getInt("mode", Mode.RUNNING_PROFILE.ordinal)]
|
mode = Mode.values()[bundle.getInt("mode", Mode.RUNNING_PROFILE.ordinal)]
|
||||||
|
customProfileJson = bundle.getString("customProfile", "")
|
||||||
|
customProfileUnits = bundle.getString("customProfileUnits", Constants.MGDL)
|
||||||
|
customProfileName = bundle.getString("customProfileName", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
return inflater.inflate(R.layout.profileviewer_fragment, container, false)
|
dialog?.window?.requestFeature(Window.FEATURE_NO_TITLE)
|
||||||
|
dialog?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN)
|
||||||
|
isCancelable = true
|
||||||
|
dialog?.setCanceledOnTouchOutside(false)
|
||||||
|
|
||||||
|
return inflater.inflate(R.layout.dialog_profileviewer, container, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
close.setOnClickListener { dismiss() }
|
close.setOnClickListener { dismiss() }
|
||||||
profileview_reload.setOnClickListener {
|
|
||||||
ConfigBuilderPlugin.getPlugin().commandQueue.readStatus("ProfileViewDialog", null)
|
|
||||||
dismiss()
|
|
||||||
}
|
|
||||||
|
|
||||||
val profile: Profile?
|
val profile: Profile?
|
||||||
val profileName: String?
|
val profileName: String?
|
||||||
|
@ -53,15 +62,14 @@ class ProfileViewerDialog : DialogFragment() {
|
||||||
profile = TreatmentsPlugin.getPlugin().getProfileSwitchFromHistory(time)?.profileObject
|
profile = TreatmentsPlugin.getPlugin().getProfileSwitchFromHistory(time)?.profileObject
|
||||||
profileName = TreatmentsPlugin.getPlugin().getProfileSwitchFromHistory(time)?.customizedName
|
profileName = TreatmentsPlugin.getPlugin().getProfileSwitchFromHistory(time)?.customizedName
|
||||||
date = DateUtil.dateAndTimeString(TreatmentsPlugin.getPlugin().getProfileSwitchFromHistory(time)?.date
|
date = DateUtil.dateAndTimeString(TreatmentsPlugin.getPlugin().getProfileSwitchFromHistory(time)?.date
|
||||||
?: 0)
|
?: 0)
|
||||||
profileview_reload.visibility = View.GONE
|
|
||||||
profileview_datelayout.visibility = View.VISIBLE
|
profileview_datelayout.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
Mode.PUMP_PROFILE -> {
|
|
||||||
profile = (ConfigBuilderPlugin.getPlugin().activePump as ProfileInterface?)?.profile?.getDefaultProfile()
|
Mode.CUSTOM_PROFILE -> {
|
||||||
profileName = (ConfigBuilderPlugin.getPlugin().activePump as ProfileInterface?)?.profileName
|
profile = Profile(JSONObject(customProfileJson), customProfileUnits)
|
||||||
|
profileName = customProfileName
|
||||||
date = ""
|
date = ""
|
||||||
profileview_reload.visibility = View.VISIBLE
|
|
||||||
profileview_datelayout.visibility = View.GONE
|
profileview_datelayout.visibility = View.GONE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,15 +91,18 @@ class ProfileViewerDialog : DialogFragment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onStart() {
|
||||||
|
super.onStart()
|
||||||
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
|
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
|
||||||
super.onResume()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSaveInstanceState(bundle: Bundle) {
|
override fun onSaveInstanceState(bundle: Bundle) {
|
||||||
super.onSaveInstanceState(bundle)
|
super.onSaveInstanceState(bundle)
|
||||||
bundle.putLong("time", time)
|
bundle.putLong("time", time)
|
||||||
bundle.putInt("mode", mode.ordinal)
|
bundle.putInt("mode", mode.ordinal)
|
||||||
|
bundle.putString("customProfile", customProfileJson)
|
||||||
|
bundle.putString("customProfileName", customProfileName)
|
||||||
|
bundle.putString("customProfileUnits", customProfileUnits)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,115 @@
|
||||||
|
package info.nightscout.androidaps.dialogs
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import com.google.common.base.Joiner
|
||||||
|
import info.nightscout.androidaps.MainApp
|
||||||
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.activities.ErrorHelperActivity
|
||||||
|
import info.nightscout.androidaps.interfaces.Constraint
|
||||||
|
import info.nightscout.androidaps.interfaces.PumpDescription
|
||||||
|
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
|
||||||
|
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
|
||||||
|
import info.nightscout.androidaps.queue.Callback
|
||||||
|
import info.nightscout.androidaps.utils.HtmlHelper
|
||||||
|
import info.nightscout.androidaps.utils.OKDialog
|
||||||
|
import info.nightscout.androidaps.utils.SafeParse
|
||||||
|
import kotlinx.android.synthetic.main.dialog_tempbasal.*
|
||||||
|
import kotlinx.android.synthetic.main.okcancel.*
|
||||||
|
import java.text.DecimalFormat
|
||||||
|
import java.util.*
|
||||||
|
import kotlin.math.abs
|
||||||
|
|
||||||
|
class TempBasalDialog : DialogFragmentWithDate() {
|
||||||
|
private var isPercentPump = true
|
||||||
|
|
||||||
|
override fun onSaveInstanceState(savedInstanceState: Bundle) {
|
||||||
|
super.onSaveInstanceState(savedInstanceState)
|
||||||
|
savedInstanceState.putDouble("actions_tempbasal_duration", actions_tempbasal_duration.value)
|
||||||
|
savedInstanceState.putDouble("actions_tempbasal_basalpercentinput", actions_tempbasal_basalpercentinput.value)
|
||||||
|
savedInstanceState.putDouble("actions_tempbasal_basalabsoluteinput", actions_tempbasal_basalabsoluteinput.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?): View? {
|
||||||
|
onCreateViewGeneral()
|
||||||
|
return inflater.inflate(R.layout.dialog_tempbasal, container, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
val pumpDescription = ConfigBuilderPlugin.getPlugin().activePump?.pumpDescription ?: return
|
||||||
|
val profile = ProfileFunctions.getInstance().profile ?: return
|
||||||
|
|
||||||
|
val maxTempPercent = pumpDescription.maxTempPercent.toDouble()
|
||||||
|
val tempPercentStep = pumpDescription.tempPercentStep.toDouble()
|
||||||
|
|
||||||
|
actions_tempbasal_basalpercentinput.setParams(savedInstanceState?.getDouble("actions_tempbasal_basalpercentinput")
|
||||||
|
?: 100.0, 0.0, maxTempPercent, tempPercentStep, DecimalFormat("0"), true, ok)
|
||||||
|
|
||||||
|
actions_tempbasal_basalabsoluteinput.setParams(savedInstanceState?.getDouble("actions_tempbasal_basalabsoluteinput")
|
||||||
|
?: profile.basal, 0.0, pumpDescription.maxTempAbsolute, pumpDescription.tempAbsoluteStep, DecimalFormat("0.00"), true, ok)
|
||||||
|
|
||||||
|
val tempDurationStep = pumpDescription.tempDurationStep.toDouble()
|
||||||
|
val tempMaxDuration = pumpDescription.tempMaxDuration.toDouble()
|
||||||
|
actions_tempbasal_duration.setParams(savedInstanceState?.getDouble("actions_tempbasal_duration")
|
||||||
|
?: tempDurationStep, tempDurationStep, tempMaxDuration, tempDurationStep, DecimalFormat("0"), false, ok)
|
||||||
|
|
||||||
|
isPercentPump = pumpDescription.tempBasalStyle and PumpDescription.PERCENT == PumpDescription.PERCENT
|
||||||
|
if (isPercentPump) {
|
||||||
|
actions_tempbasal_percent_layout.visibility = View.VISIBLE
|
||||||
|
actions_tempbasal_absolute_layout.visibility = View.GONE
|
||||||
|
} else {
|
||||||
|
actions_tempbasal_percent_layout.visibility = View.GONE
|
||||||
|
actions_tempbasal_absolute_layout.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun submit(): Boolean {
|
||||||
|
var percent = 0
|
||||||
|
var absolute = 0.0
|
||||||
|
val durationInMinutes = SafeParse.stringToInt(actions_tempbasal_duration.text)
|
||||||
|
val profile = ProfileFunctions.getInstance().profile ?: return false
|
||||||
|
val actions: LinkedList<String> = LinkedList()
|
||||||
|
if (isPercentPump) {
|
||||||
|
val basalPercentInput = SafeParse.stringToInt(actions_tempbasal_basalpercentinput.text)
|
||||||
|
percent = MainApp.getConstraintChecker().applyBasalPercentConstraints(Constraint(basalPercentInput), profile).value()
|
||||||
|
actions.add(MainApp.gs(R.string.pump_tempbasal_label)+ ": $percent%")
|
||||||
|
actions.add(MainApp.gs(R.string.duration) + ": " + MainApp.gs(R.string.format_mins, durationInMinutes))
|
||||||
|
if (percent != basalPercentInput) actions.add(MainApp.gs(R.string.constraintapllied))
|
||||||
|
} else {
|
||||||
|
val basalAbsoluteInput = SafeParse.stringToDouble(actions_tempbasal_basalabsoluteinput.text)
|
||||||
|
absolute = MainApp.getConstraintChecker().applyBasalConstraints(Constraint(basalAbsoluteInput), profile).value()
|
||||||
|
actions.add(MainApp.gs(R.string.pump_tempbasal_label)+ ": " + MainApp.gs(R.string.pump_basebasalrate, absolute))
|
||||||
|
actions.add(MainApp.gs(R.string.duration) + ": " + MainApp.gs(R.string.format_mins, durationInMinutes))
|
||||||
|
if (abs(absolute - basalAbsoluteInput) > 0.01)
|
||||||
|
actions.add("<font color='" + MainApp.gc(R.color.warning) + "'>" + MainApp.gs(R.string.constraintapllied) + "</font>")
|
||||||
|
}
|
||||||
|
activity?.let { activity ->
|
||||||
|
OKDialog.showConfirmation(activity, MainApp.gs(R.string.pump_tempbasal_label), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), Runnable {
|
||||||
|
val callback: Callback = object : Callback() {
|
||||||
|
override fun run() {
|
||||||
|
if (!result.success) {
|
||||||
|
val i = Intent(MainApp.instance(), ErrorHelperActivity::class.java)
|
||||||
|
i.putExtra("soundid", R.raw.boluserror)
|
||||||
|
i.putExtra("status", result.comment)
|
||||||
|
i.putExtra("title", MainApp.gs(R.string.tempbasaldeliveryerror))
|
||||||
|
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||||
|
MainApp.instance().startActivity(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isPercentPump) {
|
||||||
|
ConfigBuilderPlugin.getPlugin().commandQueue.tempBasalPercent(percent, durationInMinutes, true, profile, callback)
|
||||||
|
} else {
|
||||||
|
ConfigBuilderPlugin.getPlugin().commandQueue.tempBasalAbsolute(absolute, durationInMinutes, true, profile, callback)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,152 @@
|
||||||
|
package info.nightscout.androidaps.dialogs
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.AdapterView
|
||||||
|
import android.widget.ArrayAdapter
|
||||||
|
import com.google.common.base.Joiner
|
||||||
|
import com.google.common.collect.Lists
|
||||||
|
import info.nightscout.androidaps.Constants
|
||||||
|
import info.nightscout.androidaps.MainApp
|
||||||
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.data.Profile
|
||||||
|
import info.nightscout.androidaps.db.Source
|
||||||
|
import info.nightscout.androidaps.db.TempTarget
|
||||||
|
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
|
||||||
|
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
||||||
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
|
import info.nightscout.androidaps.utils.DefaultValueHelper
|
||||||
|
import info.nightscout.androidaps.utils.HtmlHelper
|
||||||
|
import info.nightscout.androidaps.utils.OKDialog
|
||||||
|
import info.nightscout.androidaps.utils.SP
|
||||||
|
import kotlinx.android.synthetic.main.dialog_temptarget.*
|
||||||
|
import kotlinx.android.synthetic.main.okcancel.*
|
||||||
|
import java.text.DecimalFormat
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class TempTargetDialog : DialogFragmentWithDate() {
|
||||||
|
|
||||||
|
override fun onSaveInstanceState(savedInstanceState: Bundle) {
|
||||||
|
super.onSaveInstanceState(savedInstanceState)
|
||||||
|
savedInstanceState.putDouble("overview_temptarget_duration", overview_temptarget_duration.value)
|
||||||
|
savedInstanceState.putDouble("overview_temptarget_temptarget", overview_temptarget_temptarget.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?): View? {
|
||||||
|
onCreateViewGeneral()
|
||||||
|
return inflater.inflate(R.layout.dialog_temptarget, container, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
overview_temptarget_duration.setParams(savedInstanceState?.getDouble("overview_temptarget_duration")
|
||||||
|
?: 0.0, 0.0, Constants.MAX_PROFILE_SWITCH_DURATION, 10.0, DecimalFormat("0"), false, ok)
|
||||||
|
|
||||||
|
if (ProfileFunctions.getSystemUnits() == Constants.MMOL)
|
||||||
|
overview_temptarget_temptarget.setParams(
|
||||||
|
savedInstanceState?.getDouble("overview_temptarget_temptarget")
|
||||||
|
?: Constants.MIN_TT_MMOL,
|
||||||
|
Constants.MIN_TT_MMOL, Constants.MAX_TT_MMOL, 0.1, DecimalFormat("0.0"), false, ok)
|
||||||
|
else
|
||||||
|
overview_temptarget_temptarget.setParams(
|
||||||
|
savedInstanceState?.getDouble("overview_temptarget_temptarget")
|
||||||
|
?: Constants.MIN_TT_MGDL,
|
||||||
|
Constants.MIN_TT_MGDL, Constants.MAX_TT_MGDL, 1.0, DecimalFormat("0"), false, ok)
|
||||||
|
|
||||||
|
val units = ProfileFunctions.getSystemUnits()
|
||||||
|
overview_temptarget_units.text = if (units == Constants.MMOL) MainApp.gs(R.string.mmol) else MainApp.gs(R.string.mgdl)
|
||||||
|
// temp target
|
||||||
|
context?.let { context ->
|
||||||
|
val reasonList: List<String> = Lists.newArrayList(
|
||||||
|
MainApp.gs(R.string.manual),
|
||||||
|
MainApp.gs(R.string.cancel),
|
||||||
|
MainApp.gs(R.string.eatingsoon),
|
||||||
|
MainApp.gs(R.string.activity),
|
||||||
|
MainApp.gs(R.string.hypo)
|
||||||
|
)
|
||||||
|
val adapterReason = ArrayAdapter(context, R.layout.spinner_centered, reasonList)
|
||||||
|
overview_temptarget_reason.adapter = adapterReason
|
||||||
|
overview_temptarget_reason.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
||||||
|
override fun onItemSelected(parent: AdapterView<*>?, view: View, position: Int, id: Long) {
|
||||||
|
val defaultDuration: Double
|
||||||
|
val defaultTarget: Double
|
||||||
|
when (reasonList[position]) {
|
||||||
|
MainApp.gs(R.string.eatingsoon) -> {
|
||||||
|
defaultDuration = DefaultValueHelper.determineEatingSoonTTDuration().toDouble()
|
||||||
|
defaultTarget = DefaultValueHelper.determineEatingSoonTT()
|
||||||
|
}
|
||||||
|
|
||||||
|
MainApp.gs(R.string.activity) -> {
|
||||||
|
defaultDuration = DefaultValueHelper.determineActivityTTDuration().toDouble()
|
||||||
|
defaultTarget = DefaultValueHelper.determineActivityTT()
|
||||||
|
}
|
||||||
|
|
||||||
|
MainApp.gs(R.string.hypo) -> {
|
||||||
|
defaultDuration = DefaultValueHelper.determineHypoTTDuration().toDouble()
|
||||||
|
defaultTarget = DefaultValueHelper.determineHypoTT()
|
||||||
|
}
|
||||||
|
|
||||||
|
MainApp.gs(R.string.cancel) -> {
|
||||||
|
defaultDuration = 0.0
|
||||||
|
defaultTarget = 0.0
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
defaultDuration = overview_temptarget_duration.value
|
||||||
|
defaultTarget = overview_temptarget_temptarget.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
overview_temptarget_temptarget.value = defaultTarget
|
||||||
|
overview_temptarget_duration.value = defaultDuration
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onNothingSelected(parent: AdapterView<*>?) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun submit(): Boolean {
|
||||||
|
val actions: LinkedList<String> = LinkedList()
|
||||||
|
val reason = overview_temptarget_reason.selectedItem.toString()
|
||||||
|
val unitResId = if (ProfileFunctions.getSystemUnits() == Constants.MGDL) R.string.mgdl else R.string.mmol
|
||||||
|
val target = overview_temptarget_temptarget.value
|
||||||
|
val duration = overview_temptarget_duration.value
|
||||||
|
if (target != 0.0 && duration != 0.0) {
|
||||||
|
actions.add(MainApp.gs(R.string.reason) + ": " + reason)
|
||||||
|
actions.add(MainApp.gs(R.string.nsprofileview_target_label) + ": " + Profile.toCurrentUnitsString(target) + " " + MainApp.gs(unitResId))
|
||||||
|
actions.add(MainApp.gs(R.string.duration) + ": " + MainApp.gs(R.string.format_hours, duration))
|
||||||
|
} else {
|
||||||
|
actions.add(MainApp.gs(R.string.stoptemptarget))
|
||||||
|
}
|
||||||
|
if (eventTimeChanged)
|
||||||
|
actions.add(MainApp.gs(R.string.time) + ": " + DateUtil.dateAndTimeString(eventTime))
|
||||||
|
|
||||||
|
activity?.let { activity ->
|
||||||
|
OKDialog.showConfirmation(activity, MainApp.gs(R.string.careportal_temporarytarget), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), Runnable {
|
||||||
|
if (target == 0.0 || duration == 0.0) {
|
||||||
|
val tempTarget = TempTarget()
|
||||||
|
.date(eventTime)
|
||||||
|
.duration(0)
|
||||||
|
.low(0.0).high(0.0)
|
||||||
|
.source(Source.USER)
|
||||||
|
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget)
|
||||||
|
} else {
|
||||||
|
val tempTarget = TempTarget()
|
||||||
|
.date(eventTime)
|
||||||
|
.duration(duration.toInt())
|
||||||
|
.reason(reason)
|
||||||
|
.source(Source.USER)
|
||||||
|
.low(Profile.toMgdl(target, ProfileFunctions.getSystemUnits()))
|
||||||
|
.high(Profile.toMgdl(target, ProfileFunctions.getSystemUnits()))
|
||||||
|
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget)
|
||||||
|
}
|
||||||
|
if (duration == 10.0) SP.putBoolean(R.string.key_objectiveusetemptarget, true)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,132 @@
|
||||||
|
package info.nightscout.androidaps.dialogs
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.text.Editable
|
||||||
|
import android.text.TextWatcher
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import com.google.common.base.Joiner
|
||||||
|
import info.nightscout.androidaps.MainApp
|
||||||
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.activities.ErrorHelperActivity
|
||||||
|
import info.nightscout.androidaps.data.DetailedBolusInfo
|
||||||
|
import info.nightscout.androidaps.db.CareportalEvent
|
||||||
|
import info.nightscout.androidaps.db.Source
|
||||||
|
import info.nightscout.androidaps.interfaces.Constraint
|
||||||
|
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
|
||||||
|
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
||||||
|
import info.nightscout.androidaps.queue.Callback
|
||||||
|
import info.nightscout.androidaps.utils.DecimalFormatter
|
||||||
|
import info.nightscout.androidaps.utils.HtmlHelper
|
||||||
|
import info.nightscout.androidaps.utils.OKDialog
|
||||||
|
import info.nightscout.androidaps.utils.SafeParse
|
||||||
|
import info.nightscout.androidaps.utils.ToastUtils
|
||||||
|
import kotlinx.android.synthetic.main.dialog_treatment.*
|
||||||
|
import kotlinx.android.synthetic.main.okcancel.*
|
||||||
|
import java.text.DecimalFormat
|
||||||
|
import java.util.*
|
||||||
|
import kotlin.math.abs
|
||||||
|
|
||||||
|
class TreatmentDialog : DialogFragmentWithDate() {
|
||||||
|
private var maxCarbs = MainApp.getConstraintChecker().maxCarbsAllowed.value().toDouble()
|
||||||
|
private var maxInsulin = MainApp.getConstraintChecker().maxBolusAllowed.value()
|
||||||
|
|
||||||
|
private val textWatcher: TextWatcher = object : TextWatcher {
|
||||||
|
override fun afterTextChanged(s: Editable) {}
|
||||||
|
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
|
||||||
|
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
|
||||||
|
validateInputs()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun validateInputs() {
|
||||||
|
if (SafeParse.stringToInt(overview_treatment_carbs.text) > maxCarbs) {
|
||||||
|
overview_treatment_carbs.value = 0.0
|
||||||
|
ToastUtils.showToastInUiThread(MainApp.instance().applicationContext, MainApp.gs(R.string.carbsconstraintapplied))
|
||||||
|
}
|
||||||
|
if (SafeParse.stringToDouble(overview_treatment_insulin.text) > maxInsulin) {
|
||||||
|
overview_treatment_insulin.value = 0.0
|
||||||
|
ToastUtils.showToastInUiThread(MainApp.instance().applicationContext, MainApp.gs(R.string.bolusconstraintapplied))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSaveInstanceState(savedInstanceState: Bundle) {
|
||||||
|
super.onSaveInstanceState(savedInstanceState)
|
||||||
|
savedInstanceState.putDouble("overview_treatment_carbs", overview_treatment_carbs.value)
|
||||||
|
savedInstanceState.putDouble("overview_treatment_insulin", overview_treatment_insulin.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?): View? {
|
||||||
|
onCreateViewGeneral()
|
||||||
|
return inflater.inflate(R.layout.dialog_treatment, container, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
val pumpDescription = ConfigBuilderPlugin.getPlugin().activePump?.pumpDescription ?: return
|
||||||
|
overview_treatment_carbs.setParams(savedInstanceState?.getDouble("overview_treatment_carbs")
|
||||||
|
?: 0.0, 0.0, maxCarbs, 1.0, DecimalFormat("0"), false, ok, textWatcher)
|
||||||
|
overview_treatment_insulin.setParams(savedInstanceState?.getDouble("overview_treatment_insulin")
|
||||||
|
?: 0.0, 0.0, maxInsulin, pumpDescription.bolusStep, DecimalFormatter.pumpSupportedBolusFormat(), false, ok, textWatcher)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun submit(): Boolean {
|
||||||
|
val pumpDescription = ConfigBuilderPlugin.getPlugin().activePump?.pumpDescription
|
||||||
|
?: return false
|
||||||
|
val insulin = SafeParse.stringToDouble(overview_treatment_insulin.text)
|
||||||
|
val carbs = SafeParse.stringToInt(overview_treatment_carbs.text)
|
||||||
|
val recordOnlyChecked = overview_treatment_record_only.isChecked
|
||||||
|
val actions: LinkedList<String?> = LinkedList()
|
||||||
|
val insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(Constraint(insulin)).value()
|
||||||
|
val carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(Constraint(carbs)).value()
|
||||||
|
|
||||||
|
if (insulinAfterConstraints > 0) {
|
||||||
|
actions.add(MainApp.gs(R.string.bolus) + ": " + "<font color='" + MainApp.gc(R.color.bolus) + "'>" + DecimalFormatter.toPumpSupportedBolus(insulinAfterConstraints) + MainApp.gs(R.string.insulin_unit_shortname) + "</font>")
|
||||||
|
if (recordOnlyChecked)
|
||||||
|
actions.add("<font color='" + MainApp.gc(R.color.warning) + "'>" + MainApp.gs(R.string.bolusrecordedonly) + "</font>")
|
||||||
|
if (abs(insulinAfterConstraints - insulin) > pumpDescription.pumpType.determineCorrectBolusStepSize(insulinAfterConstraints))
|
||||||
|
actions.add(MainApp.gs(R.string.bolusconstraintappliedwarning, MainApp.gc(R.color.warning), insulin, insulinAfterConstraints))
|
||||||
|
}
|
||||||
|
if (carbsAfterConstraints > 0) {
|
||||||
|
actions.add(MainApp.gs(R.string.carbs) + ": " + "<font color='" + MainApp.gc(R.color.carbs) + "'>" + MainApp.gs(R.string.format_carbs, carbsAfterConstraints) + "</font>")
|
||||||
|
if (carbsAfterConstraints != carbs)
|
||||||
|
actions.add("<font color='" + MainApp.gc(R.color.warning) + "'>" + MainApp.gs(R.string.carbsconstraintapplied) + "</font>")
|
||||||
|
}
|
||||||
|
if (insulinAfterConstraints > 0 || carbsAfterConstraints > 0) {
|
||||||
|
activity?.let { activity ->
|
||||||
|
OKDialog.showConfirmation(activity, MainApp.gs(R.string.overview_treatment_label), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), Runnable {
|
||||||
|
val detailedBolusInfo = DetailedBolusInfo()
|
||||||
|
if (insulinAfterConstraints == 0.0) detailedBolusInfo.eventType = CareportalEvent.CARBCORRECTION
|
||||||
|
if (carbsAfterConstraints == 0) detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS
|
||||||
|
detailedBolusInfo.insulin = insulinAfterConstraints
|
||||||
|
detailedBolusInfo.carbs = carbsAfterConstraints.toDouble()
|
||||||
|
detailedBolusInfo.context = context
|
||||||
|
detailedBolusInfo.source = Source.USER
|
||||||
|
if (!(recordOnlyChecked && (detailedBolusInfo.insulin > 0 || pumpDescription.storesCarbInfo))) {
|
||||||
|
ConfigBuilderPlugin.getPlugin().commandQueue.bolus(detailedBolusInfo, object : Callback() {
|
||||||
|
override fun run() {
|
||||||
|
if (!result.success) {
|
||||||
|
val i = Intent(MainApp.instance(), ErrorHelperActivity::class.java)
|
||||||
|
i.putExtra("soundid", R.raw.boluserror)
|
||||||
|
i.putExtra("status", result.comment)
|
||||||
|
i.putExtra("title", MainApp.gs(R.string.treatmentdeliveryerror))
|
||||||
|
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||||
|
MainApp.instance().startActivity(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else
|
||||||
|
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
activity?.let { activity ->
|
||||||
|
OKDialog.show(activity, MainApp.gs(R.string.overview_treatment_label), MainApp.gs(R.string.no_action_selected))
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,10 +1,13 @@
|
||||||
package info.nightscout.androidaps.plugins.general.overview.dialogs
|
package info.nightscout.androidaps.dialogs
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.Editable
|
import android.text.Editable
|
||||||
import android.text.TextWatcher
|
import android.text.TextWatcher
|
||||||
import android.view.*
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.view.Window
|
||||||
|
import android.view.WindowManager
|
||||||
import android.widget.AdapterView
|
import android.widget.AdapterView
|
||||||
import android.widget.AdapterView.OnItemSelectedListener
|
import android.widget.AdapterView.OnItemSelectedListener
|
||||||
import android.widget.ArrayAdapter
|
import android.widget.ArrayAdapter
|
||||||
|
@ -26,7 +29,7 @@ import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
||||||
import info.nightscout.androidaps.utils.*
|
import info.nightscout.androidaps.utils.*
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
import io.reactivex.disposables.CompositeDisposable
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
import kotlinx.android.synthetic.main.overview_wizard_dialog.*
|
import kotlinx.android.synthetic.main.dialog_wizard.*
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import java.text.DecimalFormat
|
import java.text.DecimalFormat
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
@ -36,16 +39,13 @@ class WizardDialog : DialogFragment() {
|
||||||
private val log = LoggerFactory.getLogger(WizardDialog::class.java)
|
private val log = LoggerFactory.getLogger(WizardDialog::class.java)
|
||||||
|
|
||||||
private var wizard: BolusWizard? = null
|
private var wizard: BolusWizard? = null
|
||||||
private var parentContext: Context? = null
|
|
||||||
|
|
||||||
//one shot guards
|
//one shot guards
|
||||||
private var okClicked: Boolean = false
|
private var okClicked: Boolean = false
|
||||||
|
|
||||||
private val textWatcher = object : TextWatcher {
|
private val textWatcher = object : TextWatcher {
|
||||||
override fun afterTextChanged(s: Editable) {}
|
override fun afterTextChanged(s: Editable) {}
|
||||||
|
|
||||||
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
|
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
|
||||||
|
|
||||||
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
|
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
|
||||||
calculateInsulin()
|
calculateInsulin()
|
||||||
}
|
}
|
||||||
|
@ -53,21 +53,11 @@ class WizardDialog : DialogFragment() {
|
||||||
|
|
||||||
private var disposable: CompositeDisposable = CompositeDisposable()
|
private var disposable: CompositeDisposable = CompositeDisposable()
|
||||||
|
|
||||||
override fun onAttach(context: Context) {
|
|
||||||
super.onAttach(context)
|
|
||||||
this.parentContext = context
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
super.onStart()
|
super.onStart()
|
||||||
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDetach() {
|
|
||||||
super.onDetach()
|
|
||||||
this.parentContext = null
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onSaveInstanceState(savedInstanceState: Bundle) {
|
override fun onSaveInstanceState(savedInstanceState: Bundle) {
|
||||||
super.onSaveInstanceState(savedInstanceState)
|
super.onSaveInstanceState(savedInstanceState)
|
||||||
savedInstanceState.putDouble("treatments_wizard_bg_input", treatments_wizard_bg_input.value)
|
savedInstanceState.putDouble("treatments_wizard_bg_input", treatments_wizard_bg_input.value)
|
||||||
|
@ -83,28 +73,28 @@ class WizardDialog : DialogFragment() {
|
||||||
isCancelable = true
|
isCancelable = true
|
||||||
dialog?.setCanceledOnTouchOutside(false)
|
dialog?.setCanceledOnTouchOutside(false)
|
||||||
|
|
||||||
return inflater.inflate(R.layout.overview_wizard_dialog, container, false)
|
return inflater.inflate(R.layout.dialog_wizard, container, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
loadCheckedStates()
|
loadCheckedStates()
|
||||||
processCobCheckBox()
|
processCobCheckBox()
|
||||||
treatments_wizard_sbcheckbox.visibility = if (SP.getBoolean(R.string.key_usesuperbolus, false)) View.VISIBLE else View.GONE
|
treatments_wizard_sbcheckbox.visibility = SP.getBoolean(R.string.key_usesuperbolus, false).toVisibility()
|
||||||
treatments_wizard_notes_layout.visibility = if (SP.getBoolean(R.string.key_show_notes_entry_dialogs, false)) View.VISIBLE else View.GONE
|
treatments_wizard_notes_layout.visibility = SP.getBoolean(R.string.key_show_notes_entry_dialogs, false).toVisibility()
|
||||||
|
|
||||||
val maxCarbs = MainApp.getConstraintChecker().maxCarbsAllowed.value()
|
val maxCarbs = MainApp.getConstraintChecker().maxCarbsAllowed.value()
|
||||||
val maxCorrection = MainApp.getConstraintChecker().maxBolusAllowed.value()
|
val maxCorrection = MainApp.getConstraintChecker().maxBolusAllowed.value()
|
||||||
|
|
||||||
treatments_wizard_bg_input.setParams(savedInstanceState?.getDouble("treatments_wizard_bg_input")
|
treatments_wizard_bg_input.setParams(savedInstanceState?.getDouble("treatments_wizard_bg_input")
|
||||||
?: 0.0, 0.0, 500.0, 0.1, DecimalFormat("0.0"), false, ok, textWatcher)
|
?: 0.0, 0.0, 500.0, 0.1, DecimalFormat("0.0"), false, ok, textWatcher)
|
||||||
treatments_wizard_carbs_input.setParams(savedInstanceState?.getDouble("treatments_wizard_carbs_input")
|
treatments_wizard_carbs_input.setParams(savedInstanceState?.getDouble("treatments_wizard_carbs_input")
|
||||||
?: 0.0, 0.0, maxCarbs.toDouble(), 1.0, DecimalFormat("0"), false, ok, textWatcher)
|
?: 0.0, 0.0, maxCarbs.toDouble(), 1.0, DecimalFormat("0"), false, ok, textWatcher)
|
||||||
val bolusStep = ConfigBuilderPlugin.getPlugin().activePump?.pumpDescription?.bolusStep
|
val bolusStep = ConfigBuilderPlugin.getPlugin().activePump?.pumpDescription?.bolusStep
|
||||||
?: 0.1
|
?: 0.1
|
||||||
treatments_wizard_correction_input.setParams(savedInstanceState?.getDouble("treatments_wizard_correction_input")
|
treatments_wizard_correction_input.setParams(savedInstanceState?.getDouble("treatments_wizard_correction_input")
|
||||||
?: 0.0, -maxCorrection, maxCorrection, bolusStep, DecimalFormatter.pumpSupportedBolusFormat(), false, ok, textWatcher)
|
?: 0.0, -maxCorrection, maxCorrection, bolusStep, DecimalFormatter.pumpSupportedBolusFormat(), false, ok, textWatcher)
|
||||||
treatments_wizard_carb_time_input.setParams(savedInstanceState?.getDouble("treatments_wizard_carb_time_input")
|
treatments_wizard_carb_time_input.setParams(savedInstanceState?.getDouble("treatments_wizard_carb_time_input")
|
||||||
?: 0.0, -60.0, 60.0, 5.0, DecimalFormat("0"), false, ok, textWatcher)
|
?: 0.0, -60.0, 60.0, 5.0, DecimalFormat("0"), false, ok, textWatcher)
|
||||||
initDialog()
|
initDialog()
|
||||||
|
|
||||||
treatments_wizard_percent_used.text = MainApp.gs(R.string.format_percent, SP.getInt(R.string.key_boluswizard_percentage, 100))
|
treatments_wizard_percent_used.text = MainApp.gs(R.string.format_percent, SP.getInt(R.string.key_boluswizard_percentage, 100))
|
||||||
|
@ -115,7 +105,7 @@ class WizardDialog : DialogFragment() {
|
||||||
} else {
|
} else {
|
||||||
okClicked = true
|
okClicked = true
|
||||||
calculateInsulin()
|
calculateInsulin()
|
||||||
parentContext?.let { context ->
|
context?.let { context ->
|
||||||
wizard?.confirmAndExecute(context)
|
wizard?.confirmAndExecute(context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -124,23 +114,23 @@ class WizardDialog : DialogFragment() {
|
||||||
// cancel button
|
// cancel button
|
||||||
cancel.setOnClickListener { dismiss() }
|
cancel.setOnClickListener { dismiss() }
|
||||||
// checkboxes
|
// checkboxes
|
||||||
treatments_wizard_bgcheckbox.setOnCheckedChangeListener { buttonView, _ -> onCheckedChanged(buttonView) }
|
treatments_wizard_bgcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||||
treatments_wizard_ttcheckbox.setOnCheckedChangeListener { buttonView, _ -> onCheckedChanged(buttonView) }
|
treatments_wizard_ttcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||||
treatments_wizard_cobcheckbox.setOnCheckedChangeListener { buttonView, _ -> onCheckedChanged(buttonView) }
|
treatments_wizard_cobcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||||
treatments_wizard_basaliobcheckbox.setOnCheckedChangeListener { buttonView, _ -> onCheckedChanged(buttonView) }
|
treatments_wizard_basaliobcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||||
treatments_wizard_bolusiobcheckbox.setOnCheckedChangeListener { buttonView, _ -> onCheckedChanged(buttonView) }
|
treatments_wizard_bolusiobcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||||
treatments_wizard_bgtrendcheckbox.setOnCheckedChangeListener { buttonView, _ -> onCheckedChanged(buttonView) }
|
treatments_wizard_bgtrendcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||||
treatments_wizard_sbcheckbox.setOnCheckedChangeListener { buttonView, _ -> onCheckedChanged(buttonView) }
|
treatments_wizard_sbcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||||
|
|
||||||
val showCalc = SP.getBoolean(MainApp.gs(R.string.key_wizard_calculation_visible), false)
|
val showCalc = SP.getBoolean(MainApp.gs(R.string.key_wizard_calculation_visible), false)
|
||||||
treatments_wizard_delimiter.visibility = if (showCalc) View.VISIBLE else View.GONE
|
treatments_wizard_delimiter.visibility = showCalc.toVisibility()
|
||||||
treatments_wizard_resulttable.visibility = if (showCalc) View.VISIBLE else View.GONE
|
treatments_wizard_resulttable.visibility = showCalc.toVisibility()
|
||||||
treatments_wizard_calculationcheckbox.isChecked = showCalc
|
treatments_wizard_calculationcheckbox.isChecked = showCalc
|
||||||
treatments_wizard_calculationcheckbox.setOnCheckedChangeListener { _, isChecked ->
|
treatments_wizard_calculationcheckbox.setOnCheckedChangeListener { _, isChecked ->
|
||||||
run {
|
run {
|
||||||
SP.putBoolean(MainApp.gs(R.string.key_wizard_calculation_visible), isChecked)
|
SP.putBoolean(MainApp.gs(R.string.key_wizard_calculation_visible), isChecked)
|
||||||
treatments_wizard_delimiter.visibility = if (isChecked) View.VISIBLE else View.GONE
|
treatments_wizard_delimiter.visibility = isChecked.toVisibility()
|
||||||
treatments_wizard_resulttable.visibility = if (isChecked) View.VISIBLE else View.GONE
|
treatments_wizard_resulttable.visibility = isChecked.toVisibility()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// profile spinner
|
// profile spinner
|
||||||
|
@ -157,13 +147,13 @@ class WizardDialog : DialogFragment() {
|
||||||
}
|
}
|
||||||
// bus
|
// bus
|
||||||
disposable.add(RxBus
|
disposable.add(RxBus
|
||||||
.toObservable(EventAutosensCalculationFinished::class.java)
|
.toObservable(EventAutosensCalculationFinished::class.java)
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe({
|
.subscribe({
|
||||||
activity?.runOnUiThread { calculateInsulin() }
|
activity?.runOnUiThread { calculateInsulin() }
|
||||||
}, {
|
}, {
|
||||||
FabricPrivacy.logException(it)
|
FabricPrivacy.logException(it)
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -173,7 +163,7 @@ class WizardDialog : DialogFragment() {
|
||||||
disposable.clear()
|
disposable.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onCheckedChanged(buttonView: CompoundButton) {
|
private fun onCheckedChanged(buttonView: CompoundButton, @Suppress("UNUSED_PARAMETER") state: Boolean) {
|
||||||
saveCheckedStates()
|
saveCheckedStates()
|
||||||
treatments_wizard_ttcheckbox.isEnabled = treatments_wizard_bgcheckbox.isChecked && TreatmentsPlugin.getPlugin().tempTargetFromHistory != null
|
treatments_wizard_ttcheckbox.isEnabled = treatments_wizard_bgcheckbox.isChecked && TreatmentsPlugin.getPlugin().tempTargetFromHistory != null
|
||||||
if (buttonView.id == treatments_wizard_cobcheckbox.id)
|
if (buttonView.id == treatments_wizard_cobcheckbox.id)
|
||||||
|
@ -221,7 +211,6 @@ class WizardDialog : DialogFragment() {
|
||||||
treatments_wizard_profile.adapter = adapter
|
treatments_wizard_profile.adapter = adapter
|
||||||
} ?: return
|
} ?: return
|
||||||
|
|
||||||
|
|
||||||
val units = ProfileFunctions.getSystemUnits()
|
val units = ProfileFunctions.getSystemUnits()
|
||||||
treatments_wizard_bgunits.text = units
|
treatments_wizard_bgunits.text = units
|
||||||
if (units == Constants.MGDL)
|
if (units == Constants.MGDL)
|
||||||
|
@ -250,7 +239,7 @@ class WizardDialog : DialogFragment() {
|
||||||
|
|
||||||
calculateInsulin()
|
calculateInsulin()
|
||||||
|
|
||||||
treatments_wizard_percent_used.visibility = if (SP.getInt(R.string.key_boluswizard_percentage, 100) != 100) View.VISIBLE else View.GONE
|
treatments_wizard_percent_used.visibility = (SP.getInt(R.string.key_boluswizard_percentage, 100) != 100).toVisibility()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun calculateInsulin() {
|
private fun calculateInsulin() {
|
||||||
|
@ -291,15 +280,15 @@ class WizardDialog : DialogFragment() {
|
||||||
val carbTime = SafeParse.stringToInt(treatments_wizard_carb_time_input.text)
|
val carbTime = SafeParse.stringToInt(treatments_wizard_carb_time_input.text)
|
||||||
|
|
||||||
wizard = BolusWizard(specificProfile, profileName, tempTarget, carbsAfterConstraint, cob, bg, correction,
|
wizard = BolusWizard(specificProfile, profileName, tempTarget, carbsAfterConstraint, cob, bg, correction,
|
||||||
SP.getInt(R.string.key_boluswizard_percentage, 100).toDouble(),
|
SP.getInt(R.string.key_boluswizard_percentage, 100).toDouble(),
|
||||||
treatments_wizard_bgcheckbox.isChecked,
|
treatments_wizard_bgcheckbox.isChecked,
|
||||||
treatments_wizard_cobcheckbox.isChecked,
|
treatments_wizard_cobcheckbox.isChecked,
|
||||||
treatments_wizard_bolusiobcheckbox.isChecked,
|
treatments_wizard_bolusiobcheckbox.isChecked,
|
||||||
treatments_wizard_basaliobcheckbox.isChecked,
|
treatments_wizard_basaliobcheckbox.isChecked,
|
||||||
treatments_wizard_sbcheckbox.isChecked,
|
treatments_wizard_sbcheckbox.isChecked,
|
||||||
treatments_wizard_ttcheckbox.isChecked,
|
treatments_wizard_ttcheckbox.isChecked,
|
||||||
treatments_wizard_bgtrendcheckbox.isChecked,
|
treatments_wizard_bgtrendcheckbox.isChecked,
|
||||||
treatment_wizard_notes.text.toString(), carbTime)
|
treatment_wizard_notes.text.toString(), carbTime)
|
||||||
|
|
||||||
wizard?.let { wizard ->
|
wizard?.let { wizard ->
|
||||||
treatments_wizard_bg.text = String.format(MainApp.gs(R.string.format_bg_isf), BgReading().value(Profile.toMgdl(bg, ProfileFunctions.getSystemUnits())).valueToUnitsToString(ProfileFunctions.getSystemUnits()), wizard.sens)
|
treatments_wizard_bg.text = String.format(MainApp.gs(R.string.format_bg_isf), BgReading().value(Profile.toMgdl(bg, ProfileFunctions.getSystemUnits())).valueToUnitsToString(ProfileFunctions.getSystemUnits()), wizard.sens)
|
||||||
|
@ -320,8 +309,8 @@ class WizardDialog : DialogFragment() {
|
||||||
// Trend
|
// Trend
|
||||||
if (treatments_wizard_bgtrendcheckbox.isChecked && wizard.glucoseStatus != null) {
|
if (treatments_wizard_bgtrendcheckbox.isChecked && wizard.glucoseStatus != null) {
|
||||||
treatments_wizard_bgtrend.text = ((if (wizard.trend > 0) "+" else "")
|
treatments_wizard_bgtrend.text = ((if (wizard.trend > 0) "+" else "")
|
||||||
+ Profile.toUnitsString(wizard.trend * 3, wizard.trend * 3 / Constants.MMOLL_TO_MGDL, ProfileFunctions.getSystemUnits())
|
+ Profile.toUnitsString(wizard.trend * 3, wizard.trend * 3 / Constants.MMOLL_TO_MGDL, ProfileFunctions.getSystemUnits())
|
||||||
+ " " + ProfileFunctions.getSystemUnits())
|
+ " " + ProfileFunctions.getSystemUnits())
|
||||||
} else {
|
} else {
|
||||||
treatments_wizard_bgtrend.text = ""
|
treatments_wizard_bgtrend.text = ""
|
||||||
}
|
}
|
|
@ -4,7 +4,6 @@ import android.os.SystemClock;
|
||||||
import android.preference.Preference;
|
import android.preference.Preference;
|
||||||
import android.preference.PreferenceFragment;
|
import android.preference.PreferenceFragment;
|
||||||
|
|
||||||
import androidx.appcompat.app.AlertDialog;
|
|
||||||
import androidx.fragment.app.FragmentActivity;
|
import androidx.fragment.app.FragmentActivity;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
@ -20,6 +19,7 @@ import info.nightscout.androidaps.plugins.bus.RxBus;
|
||||||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
|
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
|
||||||
import info.nightscout.androidaps.plugins.configBuilder.EventConfigBuilderUpdateGui;
|
import info.nightscout.androidaps.plugins.configBuilder.EventConfigBuilderUpdateGui;
|
||||||
import info.nightscout.androidaps.queue.CommandQueue;
|
import info.nightscout.androidaps.queue.CommandQueue;
|
||||||
|
import info.nightscout.androidaps.utils.OKDialog;
|
||||||
import info.nightscout.androidaps.utils.SP;
|
import info.nightscout.androidaps.utils.SP;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -58,20 +58,16 @@ public abstract class PluginBase {
|
||||||
if (allowHardwarePump || activity == null) {
|
if (allowHardwarePump || activity == null) {
|
||||||
performPluginSwitch(newState, type);
|
performPluginSwitch(newState, type);
|
||||||
} else {
|
} else {
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
OKDialog.showConfirmation(activity, MainApp.gs(R.string.allow_hardware_pump_text), () -> {
|
||||||
builder.setMessage(R.string.allow_hardware_pump_text)
|
performPluginSwitch(newState, type);
|
||||||
.setPositiveButton(R.string.yes, (dialog, id) -> {
|
SP.putBoolean("allow_hardware_pump", true);
|
||||||
performPluginSwitch(newState, type);
|
if (L.isEnabled(L.PUMP))
|
||||||
SP.putBoolean("allow_hardware_pump", true);
|
log.debug("First time HW pump allowed!");
|
||||||
if (L.isEnabled(L.PUMP))
|
}, () -> {
|
||||||
log.debug("First time HW pump allowed!");
|
RxBus.INSTANCE.send(new EventConfigBuilderUpdateGui());
|
||||||
})
|
if (L.isEnabled(L.PUMP))
|
||||||
.setNegativeButton(R.string.cancel, (dialog, id) -> {
|
log.debug("User does not allow switching to HW pump!");
|
||||||
RxBus.INSTANCE.send(new EventConfigBuilderUpdateGui());
|
});
|
||||||
if (L.isEnabled(L.PUMP))
|
|
||||||
log.debug("User does not allow switching to HW pump!");
|
|
||||||
});
|
|
||||||
builder.create().show();
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
performPluginSwitch(newState, type);
|
performPluginSwitch(newState, type);
|
||||||
|
|
|
@ -29,8 +29,8 @@ public class PluginDescription {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PluginDescription alwaysVisible(boolean alwayVisible) {
|
public PluginDescription alwaysVisible(boolean alwaysVisible) {
|
||||||
this.alwaysVisible = alwayVisible;
|
this.alwaysVisible = alwaysVisible;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ public interface TreatmentsInterface {
|
||||||
MealData getMealData();
|
MealData getMealData();
|
||||||
|
|
||||||
List<Treatment> getTreatmentsFromHistory();
|
List<Treatment> getTreatmentsFromHistory();
|
||||||
List<Treatment> getTreatments5MinBackFromHistory(long time);
|
List<Treatment> getCarbTreatments5MinBackFromHistory(long time);
|
||||||
List<Treatment> getTreatmentsFromHistoryAfterTimestamp(long timestamp);
|
List<Treatment> getTreatmentsFromHistoryAfterTimestamp(long timestamp);
|
||||||
long getLastBolusTime();
|
long getLastBolusTime();
|
||||||
|
|
||||||
|
|
|
@ -381,13 +381,11 @@ public class DeviceStatus {
|
||||||
try {
|
try {
|
||||||
if (device != null) record.put("device", device);
|
if (device != null) record.put("device", device);
|
||||||
if (pump != null) record.put("pump", pump);
|
if (pump != null) record.put("pump", pump);
|
||||||
if (suggested != null) {
|
JSONObject openaps = new JSONObject();
|
||||||
JSONObject openaps = new JSONObject();
|
if (enacted != null) openaps.put("enacted", enacted);
|
||||||
if (enacted != null) openaps.put("enacted", enacted);
|
if (suggested != null) openaps.put("suggested", suggested);
|
||||||
if (suggested != null) openaps.put("suggested", suggested);
|
if (iob != null) openaps.put("iob", iob);
|
||||||
if (iob != null) openaps.put("iob", iob);
|
record.put("openaps", openaps);
|
||||||
record.put("openaps", openaps);
|
|
||||||
}
|
|
||||||
if (uploaderBattery != 0) record.put("uploaderBattery", uploaderBattery);
|
if (uploaderBattery != 0) record.put("uploaderBattery", uploaderBattery);
|
||||||
if (created_at != null) record.put("created_at", created_at);
|
if (created_at != null) record.put("created_at", created_at);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package info.nightscout.androidaps.plugins.aps.loop
|
package info.nightscout.androidaps.plugins.aps.loop
|
||||||
|
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
@ -12,7 +11,11 @@ import info.nightscout.androidaps.interfaces.Constraint
|
||||||
import info.nightscout.androidaps.plugins.aps.loop.events.EventLoopSetLastRunGui
|
import info.nightscout.androidaps.plugins.aps.loop.events.EventLoopSetLastRunGui
|
||||||
import info.nightscout.androidaps.plugins.aps.loop.events.EventLoopUpdateGui
|
import info.nightscout.androidaps.plugins.aps.loop.events.EventLoopUpdateGui
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||||
import info.nightscout.androidaps.utils.*
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
|
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||||
|
import info.nightscout.androidaps.utils.HtmlHelper
|
||||||
|
import info.nightscout.androidaps.utils.SP
|
||||||
|
import info.nightscout.androidaps.utils.plusAssign
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
import io.reactivex.disposables.CompositeDisposable
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
import kotlinx.android.synthetic.main.loop_fragment.*
|
import kotlinx.android.synthetic.main.loop_fragment.*
|
||||||
|
@ -39,23 +42,21 @@ class LoopFragment : Fragment() {
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
disposable += RxBus
|
disposable += RxBus
|
||||||
.toObservable(EventLoopUpdateGui::class.java)
|
.toObservable(EventLoopUpdateGui::class.java)
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe({
|
.subscribe({
|
||||||
updateGUI()
|
updateGUI()
|
||||||
}, {
|
}, {
|
||||||
FabricPrivacy.logException(it)
|
FabricPrivacy.logException(it)
|
||||||
})
|
})
|
||||||
|
|
||||||
disposable += RxBus
|
disposable += RxBus
|
||||||
.toObservable(EventLoopSetLastRunGui::class.java)
|
.toObservable(EventLoopSetLastRunGui::class.java)
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe({
|
.subscribe({
|
||||||
clearGUI()
|
clearGUI()
|
||||||
loop_lastrun.text = it.text
|
loop_lastrun?.text = it.text
|
||||||
}, {
|
}, { FabricPrivacy.logException(it) })
|
||||||
FabricPrivacy.logException(it)
|
|
||||||
})
|
|
||||||
|
|
||||||
updateGUI()
|
updateGUI()
|
||||||
SP.putBoolean(R.string.key_objectiveuseloop, true)
|
SP.putBoolean(R.string.key_objectiveuseloop, true)
|
||||||
|
@ -71,39 +72,38 @@ class LoopFragment : Fragment() {
|
||||||
fun updateGUI() {
|
fun updateGUI() {
|
||||||
if (loop_request == null) return
|
if (loop_request == null) return
|
||||||
LoopPlugin.lastRun?.let {
|
LoopPlugin.lastRun?.let {
|
||||||
loop_request.text = it.request?.toSpanned() ?: ""
|
loop_request?.text = it.request?.toSpanned() ?: ""
|
||||||
loop_constraintsprocessed.text = it.constraintsProcessed?.toSpanned() ?: ""
|
loop_constraintsprocessed?.text = it.constraintsProcessed?.toSpanned() ?: ""
|
||||||
loop_source.text = it.source ?: ""
|
loop_source?.text = it.source ?: ""
|
||||||
loop_lastrun.text = it.lastAPSRun?.let { lastRun -> DateUtil.dateAndTimeString(lastRun.time) }
|
loop_lastrun?.text = it.lastAPSRun?.let { lastRun -> DateUtil.dateAndTimeString(lastRun.time) }
|
||||||
?: ""
|
?: ""
|
||||||
loop_lastenact.text = it.lastAPSRun?.let { lastEnact -> DateUtil.dateAndTimeString(lastEnact.time) }
|
loop_lastenact?.text = it.lastAPSRun?.let { lastEnact -> DateUtil.dateAndTimeString(lastEnact.time) }
|
||||||
?: ""
|
?: ""
|
||||||
loop_tbrsetbypump.text = it.tbrSetByPump?.let { tbrSetByPump -> HtmlHelper.fromHtml(tbrSetByPump.toHtml()) }
|
loop_tbrsetbypump?.text = it.tbrSetByPump?.let { tbrSetByPump -> HtmlHelper.fromHtml(tbrSetByPump.toHtml()) }
|
||||||
?: ""
|
?: ""
|
||||||
loop_smbsetbypump.text = it.smbSetByPump?.let { smbSetByPump -> HtmlHelper.fromHtml(smbSetByPump.toHtml()) }
|
loop_smbsetbypump?.text = it.smbSetByPump?.let { smbSetByPump -> HtmlHelper.fromHtml(smbSetByPump.toHtml()) }
|
||||||
?: ""
|
?: ""
|
||||||
|
|
||||||
val constraints =
|
val constraints =
|
||||||
it.constraintsProcessed?.let { constraintsProcessed ->
|
it.constraintsProcessed?.let { constraintsProcessed ->
|
||||||
val allConstraints = Constraint(0.0)
|
val allConstraints = Constraint(0.0)
|
||||||
constraintsProcessed.rateConstraint?.let { rateConstraint -> allConstraints.copyReasons(rateConstraint) }
|
constraintsProcessed.rateConstraint?.let { rateConstraint -> allConstraints.copyReasons(rateConstraint) }
|
||||||
constraintsProcessed.smbConstraint?.let { smbConstraint -> allConstraints.copyReasons(smbConstraint) }
|
constraintsProcessed.smbConstraint?.let { smbConstraint -> allConstraints.copyReasons(smbConstraint) }
|
||||||
allConstraints.mostLimitedReasons
|
allConstraints.mostLimitedReasons
|
||||||
} ?: ""
|
} ?: ""
|
||||||
loop_constraints.text = constraints
|
loop_constraints?.text = constraints
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
private fun clearGUI() {
|
private fun clearGUI() {
|
||||||
if (loop_request == null) return
|
loop_request?.text = ""
|
||||||
loop_request.text = ""
|
loop_constraints?.text = ""
|
||||||
loop_constraints.text = ""
|
loop_constraintsprocessed?.text = ""
|
||||||
loop_constraintsprocessed.text = ""
|
loop_source?.text = ""
|
||||||
loop_source.text = ""
|
loop_lastrun?.text = ""
|
||||||
loop_lastrun.text = ""
|
loop_lastenact?.text = ""
|
||||||
loop_lastenact.text = ""
|
loop_tbrsetbypump?.text = ""
|
||||||
loop_tbrsetbypump.text = ""
|
loop_smbsetbypump?.text = ""
|
||||||
loop_smbsetbypump.text = ""
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ import info.nightscout.androidaps.plugins.bus.RxBus;
|
||||||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
|
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
|
||||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
|
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
|
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
|
||||||
import info.nightscout.androidaps.plugins.general.overview.dialogs.ErrorHelperActivity;
|
import info.nightscout.androidaps.activities.ErrorHelperActivity;
|
||||||
import info.nightscout.androidaps.plugins.general.wear.ActionStringHandler;
|
import info.nightscout.androidaps.plugins.general.wear.ActionStringHandler;
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensCalculationFinished;
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensCalculationFinished;
|
||||||
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin;
|
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin;
|
||||||
|
@ -60,7 +60,6 @@ import info.nightscout.androidaps.queue.commands.Command;
|
||||||
import info.nightscout.androidaps.utils.FabricPrivacy;
|
import info.nightscout.androidaps.utils.FabricPrivacy;
|
||||||
import info.nightscout.androidaps.utils.SP;
|
import info.nightscout.androidaps.utils.SP;
|
||||||
import info.nightscout.androidaps.utils.T;
|
import info.nightscout.androidaps.utils.T;
|
||||||
import info.nightscout.androidaps.utils.ToastUtils;
|
|
||||||
import io.reactivex.disposables.CompositeDisposable;
|
import io.reactivex.disposables.CompositeDisposable;
|
||||||
import io.reactivex.schedulers.Schedulers;
|
import io.reactivex.schedulers.Schedulers;
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,11 @@ package info.nightscout.androidaps.plugins.configBuilder
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.*
|
import android.widget.CheckBox
|
||||||
|
import android.widget.ImageButton
|
||||||
|
import android.widget.LinearLayout
|
||||||
|
import android.widget.RadioButton
|
||||||
|
import android.widget.TextView
|
||||||
import info.nightscout.androidaps.R
|
import info.nightscout.androidaps.R
|
||||||
import info.nightscout.androidaps.activities.PreferencesActivity
|
import info.nightscout.androidaps.activities.PreferencesActivity
|
||||||
import info.nightscout.androidaps.events.EventRebuildTabs
|
import info.nightscout.androidaps.events.EventRebuildTabs
|
||||||
|
@ -10,6 +14,7 @@ import info.nightscout.androidaps.interfaces.PluginBase
|
||||||
import info.nightscout.androidaps.interfaces.PluginType
|
import info.nightscout.androidaps.interfaces.PluginType
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||||
import info.nightscout.androidaps.utils.PasswordProtection
|
import info.nightscout.androidaps.utils.PasswordProtection
|
||||||
|
import info.nightscout.androidaps.utils.toVisibility
|
||||||
|
|
||||||
class PluginViewHolder internal constructor(private val fragment: ConfigBuilderFragment,
|
class PluginViewHolder internal constructor(private val fragment: ConfigBuilderFragment,
|
||||||
private val pluginType: PluginType,
|
private val pluginType: PluginType,
|
||||||
|
@ -56,8 +61,8 @@ class PluginViewHolder internal constructor(private val fragment: ConfigBuilderF
|
||||||
}
|
}
|
||||||
|
|
||||||
fun update() {
|
fun update() {
|
||||||
enabledExclusive.visibility = if (areMultipleSelectionsAllowed(pluginType)) View.GONE else View.VISIBLE
|
enabledExclusive.visibility = areMultipleSelectionsAllowed(pluginType).not().toVisibility()
|
||||||
enabledInclusive.visibility = if (areMultipleSelectionsAllowed(pluginType)) View.VISIBLE else View.GONE
|
enabledInclusive.visibility = areMultipleSelectionsAllowed(pluginType).toVisibility()
|
||||||
enabledExclusive.isChecked = plugin.isEnabled(pluginType)
|
enabledExclusive.isChecked = plugin.isEnabled(pluginType)
|
||||||
enabledInclusive.isChecked = plugin.isEnabled(pluginType)
|
enabledInclusive.isChecked = plugin.isEnabled(pluginType)
|
||||||
enabledInclusive.isEnabled = !plugin.pluginDescription.alwaysEnabled
|
enabledInclusive.isEnabled = !plugin.pluginDescription.alwaysEnabled
|
||||||
|
@ -70,7 +75,7 @@ class PluginViewHolder internal constructor(private val fragment: ConfigBuilderF
|
||||||
pluginDescription.text = plugin.description
|
pluginDescription.text = plugin.description
|
||||||
}
|
}
|
||||||
pluginPreferences.visibility = if (plugin.preferencesId == -1 || !plugin.isEnabled(pluginType)) View.INVISIBLE else View.VISIBLE
|
pluginPreferences.visibility = if (plugin.preferencesId == -1 || !plugin.isEnabled(pluginType)) View.INVISIBLE else View.VISIBLE
|
||||||
pluginVisibility.visibility = if (plugin.hasFragment()) View.VISIBLE else View.INVISIBLE
|
pluginVisibility.visibility = plugin.hasFragment().toVisibility()
|
||||||
pluginVisibility.isEnabled = !(plugin.pluginDescription.neverVisible || plugin.pluginDescription.alwaysVisible) && plugin.isEnabled(pluginType)
|
pluginVisibility.isEnabled = !(plugin.pluginDescription.neverVisible || plugin.pluginDescription.alwaysVisible) && plugin.isEnabled(pluginType)
|
||||||
pluginVisibility.isChecked = plugin.isFragmentVisible
|
pluginVisibility.isChecked = plugin.isFragmentVisible
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ import info.nightscout.androidaps.interfaces.ProfileInterface;
|
||||||
import info.nightscout.androidaps.interfaces.TreatmentsInterface;
|
import info.nightscout.androidaps.interfaces.TreatmentsInterface;
|
||||||
import info.nightscout.androidaps.logging.L;
|
import info.nightscout.androidaps.logging.L;
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBus;
|
import info.nightscout.androidaps.plugins.bus.RxBus;
|
||||||
import info.nightscout.androidaps.plugins.general.overview.dialogs.ErrorHelperActivity;
|
import info.nightscout.androidaps.activities.ErrorHelperActivity;
|
||||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
|
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.androidaps.queue.Callback;
|
import info.nightscout.androidaps.queue.Callback;
|
||||||
import info.nightscout.androidaps.utils.DateUtil;
|
import info.nightscout.androidaps.utils.DateUtil;
|
||||||
|
@ -170,8 +170,8 @@ public class ProfileFunctions {
|
||||||
return profileSwitch;
|
return profileSwitch;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void doProfileSwitch(final ProfileStore profileStore, final String profileName, final int duration, final int percentage, final int timeshift) {
|
public static void doProfileSwitch(final ProfileStore profileStore, final String profileName, final int duration, final int percentage, final int timeshift, final long date) {
|
||||||
ProfileSwitch profileSwitch = prepareProfileSwitch(profileStore, profileName, duration, percentage, timeshift, System.currentTimeMillis());
|
ProfileSwitch profileSwitch = prepareProfileSwitch(profileStore, profileName, duration, percentage, timeshift, date);
|
||||||
TreatmentsPlugin.getPlugin().addToHistoryProfileSwitch(profileSwitch);
|
TreatmentsPlugin.getPlugin().addToHistoryProfileSwitch(profileSwitch);
|
||||||
if (percentage == 90 && duration == 10)
|
if (percentage == 90 && duration == 10)
|
||||||
SP.putBoolean(R.string.key_objectiveuseprofileswitch, true);
|
SP.putBoolean(R.string.key_objectiveuseprofileswitch, true);
|
||||||
|
|
|
@ -28,6 +28,7 @@ import info.nightscout.androidaps.plugins.constraints.objectives.events.EventNtp
|
||||||
import info.nightscout.androidaps.plugins.constraints.objectives.events.EventObjectivesUpdateGui
|
import info.nightscout.androidaps.plugins.constraints.objectives.events.EventObjectivesUpdateGui
|
||||||
import info.nightscout.androidaps.plugins.constraints.objectives.objectives.Objective.ExamTask
|
import info.nightscout.androidaps.plugins.constraints.objectives.objectives.Objective.ExamTask
|
||||||
import info.nightscout.androidaps.receivers.NetworkChangeReceiver
|
import info.nightscout.androidaps.receivers.NetworkChangeReceiver
|
||||||
|
import info.nightscout.androidaps.setupwizard.events.EventSWUpdate
|
||||||
import info.nightscout.androidaps.utils.*
|
import info.nightscout.androidaps.utils.*
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
import io.reactivex.disposables.CompositeDisposable
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
|
@ -71,13 +72,13 @@ class ObjectivesFragment : Fragment() {
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
disposable.add(RxBus
|
disposable.add(RxBus
|
||||||
.toObservable(EventObjectivesUpdateGui::class.java)
|
.toObservable(EventObjectivesUpdateGui::class.java)
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe({
|
.subscribe({
|
||||||
objectives_recyclerview.adapter?.notifyDataSetChanged()
|
objectives_recyclerview.adapter?.notifyDataSetChanged()
|
||||||
}, {
|
}, {
|
||||||
FabricPrivacy.logException(it)
|
FabricPrivacy.logException(it)
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,6 +218,7 @@ class ObjectivesFragment : Fragment() {
|
||||||
scrollToCurrentObjective()
|
scrollToCurrentObjective()
|
||||||
startUpdateTimer()
|
startUpdateTimer()
|
||||||
RxBus.send(EventObjectivesUpdateGui())
|
RxBus.send(EventObjectivesUpdateGui())
|
||||||
|
RxBus.send(EventSWUpdate(false))
|
||||||
} else {
|
} else {
|
||||||
// move out of UI thread
|
// move out of UI thread
|
||||||
Thread {
|
Thread {
|
||||||
|
@ -234,6 +236,7 @@ class ObjectivesFragment : Fragment() {
|
||||||
RxBus.send(EventNtpStatus(MainApp.gs(R.string.success), 100))
|
RxBus.send(EventNtpStatus(MainApp.gs(R.string.success), 100))
|
||||||
SystemClock.sleep(1000)
|
SystemClock.sleep(1000)
|
||||||
RxBus.send(EventObjectivesUpdateGui())
|
RxBus.send(EventObjectivesUpdateGui())
|
||||||
|
RxBus.send(EventSWUpdate(false))
|
||||||
SystemClock.sleep(100)
|
SystemClock.sleep(100)
|
||||||
scrollToCurrentObjective()
|
scrollToCurrentObjective()
|
||||||
} else {
|
} else {
|
||||||
|
@ -254,6 +257,7 @@ class ObjectivesFragment : Fragment() {
|
||||||
scrollToCurrentObjective()
|
scrollToCurrentObjective()
|
||||||
startUpdateTimer()
|
startUpdateTimer()
|
||||||
RxBus.send(EventObjectivesUpdateGui())
|
RxBus.send(EventObjectivesUpdateGui())
|
||||||
|
RxBus.send(EventSWUpdate(false))
|
||||||
} else
|
} else
|
||||||
// move out of UI thread
|
// move out of UI thread
|
||||||
Thread {
|
Thread {
|
||||||
|
@ -270,6 +274,7 @@ class ObjectivesFragment : Fragment() {
|
||||||
RxBus.send(EventNtpStatus(MainApp.gs(R.string.success), 100))
|
RxBus.send(EventNtpStatus(MainApp.gs(R.string.success), 100))
|
||||||
SystemClock.sleep(1000)
|
SystemClock.sleep(1000)
|
||||||
RxBus.send(EventObjectivesUpdateGui())
|
RxBus.send(EventObjectivesUpdateGui())
|
||||||
|
RxBus.send(EventSWUpdate(false))
|
||||||
SystemClock.sleep(100)
|
SystemClock.sleep(100)
|
||||||
scrollToCurrentObjective()
|
scrollToCurrentObjective()
|
||||||
} else {
|
} else {
|
||||||
|
@ -280,16 +285,20 @@ class ObjectivesFragment : Fragment() {
|
||||||
}.start()
|
}.start()
|
||||||
}
|
}
|
||||||
holder.unStart.setOnClickListener {
|
holder.unStart.setOnClickListener {
|
||||||
OKDialog.showConfirmation(activity, MainApp.gs(R.string.doyouwantresetstart)) {
|
activity?.let { activity ->
|
||||||
objective.startedOn = 0
|
OKDialog.showConfirmation(activity, MainApp.gs(R.string.objectives), MainApp.gs(R.string.doyouwantresetstart), Runnable {
|
||||||
scrollToCurrentObjective()
|
objective.startedOn = 0
|
||||||
RxBus.send(EventObjectivesUpdateGui())
|
scrollToCurrentObjective()
|
||||||
|
RxBus.send(EventObjectivesUpdateGui())
|
||||||
|
RxBus.send(EventSWUpdate(false))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
holder.unFinish.setOnClickListener {
|
holder.unFinish.setOnClickListener {
|
||||||
objective.accomplishedOn = 0
|
objective.accomplishedOn = 0
|
||||||
scrollToCurrentObjective()
|
scrollToCurrentObjective()
|
||||||
RxBus.send(EventObjectivesUpdateGui())
|
RxBus.send(EventObjectivesUpdateGui())
|
||||||
|
RxBus.send(EventSWUpdate(false))
|
||||||
}
|
}
|
||||||
if (objective.hasSpecialInput && !objective.isAccomplished && objective.isStarted && objective.specialActionEnabled()) {
|
if (objective.hasSpecialInput && !objective.isAccomplished && objective.isStarted && objective.specialActionEnabled()) {
|
||||||
// generate random request code if none exists
|
// generate random request code if none exists
|
||||||
|
@ -313,7 +322,6 @@ class ObjectivesFragment : Fragment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun getItemCount(): Int {
|
override fun getItemCount(): Int {
|
||||||
return ObjectivesPlugin.objectives.size
|
return ObjectivesPlugin.objectives.size
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,9 +122,9 @@ object ObjectivesPlugin : PluginBase(PluginDescription()
|
||||||
SP.putLong("Objectives_" + "smb" + "_started", DateUtil.now())
|
SP.putLong("Objectives_" + "smb" + "_started", DateUtil.now())
|
||||||
SP.putLong("Objectives_" + "smb" + "_accomplished", DateUtil.now())
|
SP.putLong("Objectives_" + "smb" + "_accomplished", DateUtil.now())
|
||||||
setupObjectives()
|
setupObjectives()
|
||||||
OKDialog.show(activity, "", MainApp.gs(R.string.codeaccepted), null)
|
OKDialog.show(activity, MainApp.gs(R.string.objectives), MainApp.gs(R.string.codeaccepted))
|
||||||
} else {
|
} else {
|
||||||
OKDialog.show(activity, "", MainApp.gs(R.string.codeinvalid), null)
|
OKDialog.show(activity, MainApp.gs(R.string.objectives), MainApp.gs(R.string.codeinvalid))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ import info.nightscout.androidaps.plugins.constraints.objectives.events.EventNtp
|
||||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
import io.reactivex.disposables.CompositeDisposable
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
import kotlinx.android.synthetic.main.overview_bolusprogress_dialog.*
|
import kotlinx.android.synthetic.main.dialog_bolusprogress.*
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
|
|
||||||
class NtpProgressDialog : DialogFragment() {
|
class NtpProgressDialog : DialogFragment() {
|
||||||
|
@ -33,16 +33,17 @@ class NtpProgressDialog : DialogFragment() {
|
||||||
state = savedInstanceState?.getString("state", DEFAULT_STATE) ?: DEFAULT_STATE
|
state = savedInstanceState?.getString("state", DEFAULT_STATE) ?: DEFAULT_STATE
|
||||||
percent = savedInstanceState?.getInt("percent", 0) ?: 0
|
percent = savedInstanceState?.getInt("percent", 0) ?: 0
|
||||||
|
|
||||||
return inflater.inflate(R.layout.overview_bolusprogress_dialog, container, false)
|
return inflater.inflate(R.layout.dialog_bolusprogress, container, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
overview_bolusprogress_stop.setOnClickListener { dismiss() }
|
overview_bolusprogress_stop.setOnClickListener { dismiss() }
|
||||||
overview_bolusprogress_status.setText(state)
|
overview_bolusprogress_status.text = state
|
||||||
overview_bolusprogress_progressbar.setMax(100)
|
overview_bolusprogress_progressbar.max = 100
|
||||||
overview_bolusprogress_progressbar.setProgress(percent)
|
overview_bolusprogress_progressbar.progress = percent
|
||||||
overview_bolusprogress_stop.text = MainApp.gs(R.string.close)
|
overview_bolusprogress_stop.text = MainApp.gs(R.string.close)
|
||||||
|
overview_bolusprogress_title.text = MainApp.gs(R.string.please_wait)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
package info.nightscout.androidaps.plugins.constraints.phoneChecker
|
||||||
|
|
||||||
|
import android.os.Build
|
||||||
|
import com.scottyab.rootbeer.RootBeer
|
||||||
|
import info.nightscout.androidaps.MainApp
|
||||||
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.interfaces.ConstraintsInterface
|
||||||
|
import info.nightscout.androidaps.interfaces.PluginBase
|
||||||
|
import info.nightscout.androidaps.interfaces.PluginDescription
|
||||||
|
import info.nightscout.androidaps.interfaces.PluginType
|
||||||
|
|
||||||
|
object PhoneCheckerPlugin : PluginBase(PluginDescription()
|
||||||
|
.mainType(PluginType.CONSTRAINTS)
|
||||||
|
.neverVisible(true)
|
||||||
|
.alwaysEnabled(true)
|
||||||
|
.showInList(false)
|
||||||
|
.pluginName(R.string.phonechecker)
|
||||||
|
), ConstraintsInterface {
|
||||||
|
|
||||||
|
var phoneRooted: Boolean = false
|
||||||
|
var devMode: Boolean = false
|
||||||
|
val phoneModel: String = Build.MODEL
|
||||||
|
val manufacturer: String = Build.MANUFACTURER
|
||||||
|
|
||||||
|
private fun isDevModeEnabled(): Boolean {
|
||||||
|
return android.provider.Settings.Secure.getInt(MainApp.instance().contentResolver,
|
||||||
|
android.provider.Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStart() {
|
||||||
|
super.onStart()
|
||||||
|
phoneRooted = RootBeer(MainApp.instance()).isRootedWithoutBusyBoxCheck()
|
||||||
|
devMode = isDevModeEnabled()
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,6 +21,7 @@ import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
|
||||||
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification;
|
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification;
|
||||||
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
|
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
|
||||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin;
|
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin;
|
||||||
|
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.androidaps.utils.DecimalFormatter;
|
import info.nightscout.androidaps.utils.DecimalFormatter;
|
||||||
import info.nightscout.androidaps.utils.HardLimits;
|
import info.nightscout.androidaps.utils.HardLimits;
|
||||||
import info.nightscout.androidaps.utils.Round;
|
import info.nightscout.androidaps.utils.Round;
|
||||||
|
@ -73,7 +74,10 @@ public class SafetyPlugin extends PluginBase implements ConstraintsInterface {
|
||||||
}
|
}
|
||||||
value.set(false, MainApp.gs(R.string.closed_loop_disabled_on_dev_branch), this);
|
value.set(false, MainApp.gs(R.string.closed_loop_disabled_on_dev_branch), this);
|
||||||
}
|
}
|
||||||
|
PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
|
||||||
|
if (pump != null && !pump.isFakingTempsByExtendedBoluses() && TreatmentsPlugin.getPlugin().isInHistoryExtendedBoluslInProgress()) {
|
||||||
|
value.set(false, MainApp.gs(R.string.closed_loop_disabled_with_eb), this);
|
||||||
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,19 @@
|
||||||
package info.nightscout.androidaps.plugins.constraints.versionChecker
|
package info.nightscout.androidaps.plugins.constraints.versionChecker
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.BuildConfig
|
||||||
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.*
|
import info.nightscout.androidaps.interfaces.Constraint
|
||||||
|
import info.nightscout.androidaps.interfaces.ConstraintsInterface
|
||||||
|
import info.nightscout.androidaps.interfaces.PluginBase
|
||||||
|
import info.nightscout.androidaps.interfaces.PluginDescription
|
||||||
|
import info.nightscout.androidaps.interfaces.PluginType
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||||
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
|
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
|
||||||
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
|
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
|
||||||
import info.nightscout.androidaps.utils.SP
|
import info.nightscout.androidaps.utils.SP
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Usually we would have a class here.
|
* Usually we would have a class here.
|
||||||
|
@ -16,16 +22,23 @@ import java.util.concurrent.TimeUnit
|
||||||
* */
|
* */
|
||||||
|
|
||||||
object VersionCheckerPlugin : PluginBase(PluginDescription()
|
object VersionCheckerPlugin : PluginBase(PluginDescription()
|
||||||
.mainType(PluginType.CONSTRAINTS)
|
.mainType(PluginType.CONSTRAINTS)
|
||||||
.neverVisible(true)
|
.neverVisible(true)
|
||||||
.alwaysEnabled(true)
|
.alwaysEnabled(true)
|
||||||
.showInList(false)
|
.showInList(false)
|
||||||
.pluginName(R.string.versionChecker)), ConstraintsInterface {
|
.pluginName(R.string.versionChecker)), ConstraintsInterface {
|
||||||
|
|
||||||
|
private val gracePeriod: GracePeriod
|
||||||
|
get() = if ((BuildConfig.VERSION_NAME.contains("RC", ignoreCase = true))) {
|
||||||
|
GracePeriod.RC
|
||||||
|
} else {
|
||||||
|
GracePeriod.RELEASE
|
||||||
|
}
|
||||||
|
|
||||||
override fun isClosedLoopAllowed(value: Constraint<Boolean>): Constraint<Boolean> {
|
override fun isClosedLoopAllowed(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||||
checkWarning()
|
checkWarning()
|
||||||
triggerCheckVersion()
|
triggerCheckVersion()
|
||||||
return if (isOldVersion(GRACE_PERIOD_VERY_OLD))
|
return if (isOldVersion(gracePeriod.veryOld.daysToMillis()))
|
||||||
value.set(false, MainApp.gs(R.string.very_old_version), this)
|
value.set(false, MainApp.gs(R.string.very_old_version), this)
|
||||||
else
|
else
|
||||||
value
|
value
|
||||||
|
@ -33,41 +46,49 @@ object VersionCheckerPlugin : PluginBase(PluginDescription()
|
||||||
|
|
||||||
private fun checkWarning() {
|
private fun checkWarning() {
|
||||||
val now = System.currentTimeMillis()
|
val now = System.currentTimeMillis()
|
||||||
|
|
||||||
if (!SP.contains(R.string.key_last_versionchecker_plugin_warning)) {
|
if (!SP.contains(R.string.key_last_versionchecker_plugin_warning)) {
|
||||||
SP.putLong(R.string.key_last_versionchecker_plugin_warning, now)
|
SP.putLong(R.string.key_last_versionchecker_plugin_warning, now)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (isOldVersion(GRACE_PERIOD_WARNING) && shouldWarnAgain(now)) {
|
if (isOldVersion(gracePeriod.warning.daysToMillis()) && shouldWarnAgain(now)) {
|
||||||
// store last notification time
|
// store last notification time
|
||||||
SP.putLong(R.string.key_last_versionchecker_plugin_warning, now)
|
SP.putLong(R.string.key_last_versionchecker_plugin_warning, now)
|
||||||
|
|
||||||
//notify
|
//notify
|
||||||
val message = MainApp.gs(R.string.new_version_warning, Math.round((now - SP.getLong(R.string.key_last_time_this_version_detected, now)) / TimeUnit.DAYS.toMillis(1).toDouble()))
|
val message = MainApp.gs(R.string.new_version_warning,
|
||||||
|
((now - SP.getLong(R.string.key_last_time_this_version_detected, now)) / 1L.daysToMillis().toDouble()).roundToInt(),
|
||||||
|
gracePeriod.old,
|
||||||
|
gracePeriod.veryOld
|
||||||
|
)
|
||||||
val notification = Notification(Notification.OLDVERSION, message, Notification.NORMAL)
|
val notification = Notification(Notification.OLDVERSION, message, Notification.NORMAL)
|
||||||
RxBus.send(EventNewNotification(notification))
|
RxBus.send(EventNewNotification(notification))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun shouldWarnAgain(now: Long) =
|
private fun shouldWarnAgain(now: Long) =
|
||||||
now > SP.getLong(R.string.key_last_versionchecker_plugin_warning, 0) + WARN_EVERY
|
now > SP.getLong(R.string.key_last_versionchecker_plugin_warning, 0) + WARN_EVERY
|
||||||
|
|
||||||
override fun applyMaxIOBConstraints(maxIob: Constraint<Double>): Constraint<Double> =
|
override fun applyMaxIOBConstraints(maxIob: Constraint<Double>): Constraint<Double> =
|
||||||
if (isOldVersion(GRACE_PERIOD_OLD))
|
if (isOldVersion(gracePeriod.old.daysToMillis()))
|
||||||
maxIob.set(0.toDouble(), MainApp.gs(R.string.old_version), this)
|
maxIob.set(0.toDouble(), MainApp.gs(R.string.old_version), this)
|
||||||
else
|
else
|
||||||
maxIob
|
maxIob
|
||||||
|
|
||||||
private fun isOldVersion(gracePeriod: Long): Boolean {
|
private fun isOldVersion(gracePeriod: Long): Boolean {
|
||||||
val now = System.currentTimeMillis()
|
val now = System.currentTimeMillis()
|
||||||
return now > SP.getLong(R.string.key_last_time_this_version_detected, 0) + gracePeriod
|
return now > SP.getLong(R.string.key_last_time_this_version_detected, 0) + gracePeriod
|
||||||
}
|
}
|
||||||
|
|
||||||
val WARN_EVERY = TimeUnit.DAYS.toMillis(1)
|
private val WARN_EVERY = TimeUnit.DAYS.toMillis(1)
|
||||||
val GRACE_PERIOD_WARNING = TimeUnit.DAYS.toMillis(30)
|
|
||||||
val GRACE_PERIOD_OLD = TimeUnit.DAYS.toMillis(60)
|
|
||||||
val GRACE_PERIOD_VERY_OLD = TimeUnit.DAYS.toMillis(90)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum class GracePeriod(val warning: Long, val old: Long, val veryOld: Long) {
|
||||||
|
RELEASE(30, 60, 90),
|
||||||
|
RC(1, 7, 14)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Long.daysToMillis() = TimeUnit.DAYS.toMillis(this)
|
||||||
|
|
|
@ -7,6 +7,7 @@ import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import info.nightscout.androidaps.Config
|
import info.nightscout.androidaps.Config
|
||||||
import info.nightscout.androidaps.MainApp
|
import info.nightscout.androidaps.MainApp
|
||||||
|
@ -18,17 +19,21 @@ import info.nightscout.androidaps.plugins.bus.RxBus
|
||||||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
|
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
|
||||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
|
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
|
||||||
import info.nightscout.androidaps.plugins.general.actions.defs.CustomAction
|
import info.nightscout.androidaps.plugins.general.actions.defs.CustomAction
|
||||||
import info.nightscout.androidaps.plugins.general.actions.dialogs.FillDialog
|
import info.nightscout.androidaps.dialogs.CareDialog
|
||||||
import info.nightscout.androidaps.plugins.general.actions.dialogs.NewExtendedBolusDialog
|
import info.nightscout.androidaps.dialogs.ExtendedBolusDialog
|
||||||
import info.nightscout.androidaps.plugins.general.actions.dialogs.NewTempBasalDialog
|
import info.nightscout.androidaps.dialogs.FillDialog
|
||||||
|
import info.nightscout.androidaps.dialogs.TempBasalDialog
|
||||||
import info.nightscout.androidaps.plugins.general.careportal.CareportalFragment
|
import info.nightscout.androidaps.plugins.general.careportal.CareportalFragment
|
||||||
import info.nightscout.androidaps.plugins.general.careportal.Dialogs.NewNSTreatmentDialog
|
import info.nightscout.androidaps.activities.ErrorHelperActivity
|
||||||
|
import info.nightscout.androidaps.dialogs.ProfileSwitchDialog
|
||||||
|
import info.nightscout.androidaps.dialogs.TempTargetDialog
|
||||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
||||||
import info.nightscout.androidaps.queue.Callback
|
import info.nightscout.androidaps.queue.Callback
|
||||||
import info.nightscout.androidaps.utils.*
|
import info.nightscout.androidaps.utils.*
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
import io.reactivex.disposables.CompositeDisposable
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
import kotlinx.android.synthetic.main.actions_fragment.*
|
import kotlinx.android.synthetic.main.actions_fragment.*
|
||||||
|
import kotlinx.android.synthetic.main.careportal_stats_fragment.*
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class ActionsFragment : Fragment() {
|
class ActionsFragment : Fragment() {
|
||||||
|
@ -47,39 +52,50 @@ class ActionsFragment : Fragment() {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
actions_profileswitch.setOnClickListener {
|
actions_profileswitch.setOnClickListener {
|
||||||
val newDialog = NewNSTreatmentDialog()
|
fragmentManager?.let { ProfileSwitchDialog().show(it, "Actions") }
|
||||||
val profileSwitch = CareportalFragment.PROFILESWITCH
|
|
||||||
profileSwitch.executeProfileSwitch = true
|
|
||||||
newDialog.setOptions(profileSwitch, R.string.careportal_profileswitch)
|
|
||||||
fragmentManager?.let { newDialog.show(it, "NewNSTreatmentDialog") }
|
|
||||||
}
|
}
|
||||||
actions_temptarget.setOnClickListener {
|
actions_temptarget.setOnClickListener {
|
||||||
val newTTDialog = NewNSTreatmentDialog()
|
fragmentManager?.let { TempTargetDialog().show(it, "Actions") }
|
||||||
val temptarget = CareportalFragment.TEMPTARGET
|
|
||||||
temptarget.executeTempTarget = true
|
|
||||||
newTTDialog.setOptions(temptarget, R.string.careportal_temporarytarget)
|
|
||||||
fragmentManager?.let { newTTDialog.show(it, "NewNSTreatmentDialog") }
|
|
||||||
}
|
}
|
||||||
actions_extendedbolus.setOnClickListener {
|
actions_extendedbolus.setOnClickListener {
|
||||||
fragmentManager?.let { NewExtendedBolusDialog().show(it, "NewExtendedDialog") }
|
context?.let { context ->
|
||||||
|
OKDialog.showConfirmation(context, MainApp.gs(R.string.extended_bolus), MainApp.gs(R.string.ebstopsloop),
|
||||||
|
Runnable {
|
||||||
|
fragmentManager?.let { ExtendedBolusDialog().show(it, "Actions") }
|
||||||
|
}, null)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
actions_extendedbolus_cancel.setOnClickListener {
|
actions_extendedbolus_cancel.setOnClickListener {
|
||||||
if (TreatmentsPlugin.getPlugin().isInHistoryExtendedBoluslInProgress) {
|
if (TreatmentsPlugin.getPlugin().isInHistoryExtendedBoluslInProgress) {
|
||||||
ConfigBuilderPlugin.getPlugin().commandQueue.cancelExtended(object : Callback() {
|
ConfigBuilderPlugin.getPlugin().commandQueue.cancelExtended(object : Callback() {
|
||||||
override fun run() {
|
override fun run() {
|
||||||
if (!result.success)
|
if (!result.success) {
|
||||||
ToastUtils.showToastInUiThread(MainApp.instance().applicationContext, MainApp.gs(R.string.extendedbolusdeliveryerror))
|
val i = Intent(MainApp.instance(), ErrorHelperActivity::class.java)
|
||||||
|
i.putExtra("soundid", R.raw.boluserror)
|
||||||
|
i.putExtra("status", result.comment)
|
||||||
|
i.putExtra("title", MainApp.gs(R.string.extendedbolusdeliveryerror))
|
||||||
|
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||||
|
MainApp.instance().startActivity(i)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
actions_settempbasal.setOnClickListener { fragmentManager?.let { NewTempBasalDialog().show(it, "NewTempDialog") } }
|
actions_settempbasal.setOnClickListener {
|
||||||
|
fragmentManager?.let { TempBasalDialog().show(it, "Actions") }
|
||||||
|
}
|
||||||
actions_canceltempbasal.setOnClickListener {
|
actions_canceltempbasal.setOnClickListener {
|
||||||
if (TreatmentsPlugin.getPlugin().isTempBasalInProgress) {
|
if (TreatmentsPlugin.getPlugin().isTempBasalInProgress) {
|
||||||
ConfigBuilderPlugin.getPlugin().commandQueue.cancelTempBasal(true, object : Callback() {
|
ConfigBuilderPlugin.getPlugin().commandQueue.cancelTempBasal(true, object : Callback() {
|
||||||
override fun run() {
|
override fun run() {
|
||||||
if (!result.success)
|
if (!result.success) {
|
||||||
ToastUtils.showToastInUiThread(MainApp.instance().applicationContext, MainApp.gs(R.string.tempbasaldeliveryerror))
|
val i = Intent(MainApp.instance(), ErrorHelperActivity::class.java)
|
||||||
|
i.putExtra("soundid", R.raw.boluserror)
|
||||||
|
i.putExtra("status", result.comment)
|
||||||
|
i.putExtra("title", MainApp.gs(R.string.tempbasaldeliveryerror))
|
||||||
|
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||||
|
MainApp.instance().startActivity(i)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -87,6 +103,21 @@ class ActionsFragment : Fragment() {
|
||||||
actions_fill.setOnClickListener { fragmentManager?.let { FillDialog().show(it, "FillDialog") } }
|
actions_fill.setOnClickListener { fragmentManager?.let { FillDialog().show(it, "FillDialog") } }
|
||||||
actions_historybrowser.setOnClickListener { startActivity(Intent(context, HistoryBrowseActivity::class.java)) }
|
actions_historybrowser.setOnClickListener { startActivity(Intent(context, HistoryBrowseActivity::class.java)) }
|
||||||
actions_tddstats.setOnClickListener { startActivity(Intent(context, TDDStatsActivity::class.java)) }
|
actions_tddstats.setOnClickListener { startActivity(Intent(context, TDDStatsActivity::class.java)) }
|
||||||
|
actions_bgcheck.setOnClickListener {
|
||||||
|
fragmentManager?.let { CareDialog().setOptions(CareDialog.EventType.BGCHECK, R.string.careportal_bgcheck).show(it, "Actions") }
|
||||||
|
}
|
||||||
|
actions_cgmsensorinsert.setOnClickListener {
|
||||||
|
fragmentManager?.let { CareDialog().setOptions(CareDialog.EventType.SENSOR_INSERT, R.string.careportal_cgmsensorinsert).show(it, "Actions") }
|
||||||
|
}
|
||||||
|
actions_pumpbatterychange.setOnClickListener {
|
||||||
|
fragmentManager?.let { CareDialog().setOptions(CareDialog.EventType.BATTERY_CHANGE, R.string.careportal_pumpbatterychange).show(it, "Actions") }
|
||||||
|
}
|
||||||
|
actions_note.setOnClickListener {
|
||||||
|
fragmentManager?.let { CareDialog().setOptions(CareDialog.EventType.NOTE, R.string.careportal_note).show(it, "Actions") }
|
||||||
|
}
|
||||||
|
actions_exercise.setOnClickListener {
|
||||||
|
fragmentManager?.let { CareDialog().setOptions(CareDialog.EventType.EXERCISE, R.string.careportal_exercise).show(it, "Actions") }
|
||||||
|
}
|
||||||
|
|
||||||
SP.putBoolean(R.string.key_objectiveuseactions, true)
|
SP.putBoolean(R.string.key_objectiveuseactions, true)
|
||||||
}
|
}
|
||||||
|
@ -97,43 +128,27 @@ class ActionsFragment : Fragment() {
|
||||||
disposable += RxBus
|
disposable += RxBus
|
||||||
.toObservable(EventInitializationChanged::class.java)
|
.toObservable(EventInitializationChanged::class.java)
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe({
|
.subscribe({ updateGui() }, { FabricPrivacy.logException(it) })
|
||||||
updateGui()
|
|
||||||
}, {
|
|
||||||
FabricPrivacy.logException(it)
|
|
||||||
})
|
|
||||||
disposable += RxBus
|
disposable += RxBus
|
||||||
.toObservable(EventRefreshOverview::class.java)
|
.toObservable(EventRefreshOverview::class.java)
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe({
|
.subscribe({ updateGui() }, { FabricPrivacy.logException(it) })
|
||||||
updateGui()
|
|
||||||
}, {
|
|
||||||
FabricPrivacy.logException(it)
|
|
||||||
})
|
|
||||||
disposable += RxBus
|
disposable += RxBus
|
||||||
.toObservable(EventExtendedBolusChange::class.java)
|
.toObservable(EventExtendedBolusChange::class.java)
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe({
|
.subscribe({ updateGui() }, { FabricPrivacy.logException(it) })
|
||||||
updateGui()
|
|
||||||
}, {
|
|
||||||
FabricPrivacy.logException(it)
|
|
||||||
})
|
|
||||||
disposable += RxBus
|
disposable += RxBus
|
||||||
.toObservable(EventTempBasalChange::class.java)
|
.toObservable(EventTempBasalChange::class.java)
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe({
|
.subscribe({ updateGui() }, { FabricPrivacy.logException(it) })
|
||||||
updateGui()
|
|
||||||
}, {
|
|
||||||
FabricPrivacy.logException(it)
|
|
||||||
})
|
|
||||||
disposable += RxBus
|
disposable += RxBus
|
||||||
.toObservable(EventCustomActionsChanged::class.java)
|
.toObservable(EventCustomActionsChanged::class.java)
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe({
|
.subscribe({ updateGui() }, { FabricPrivacy.logException(it) })
|
||||||
updateGui()
|
disposable += RxBus
|
||||||
}, {
|
.toObservable(EventCareportalEventChange::class.java)
|
||||||
FabricPrivacy.logException(it)
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
})
|
.subscribe({ updateGui() }, { FabricPrivacy.logException(it) })
|
||||||
updateGui()
|
updateGui()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,7 +179,7 @@ class ActionsFragment : Fragment() {
|
||||||
|
|
||||||
actions_profileswitch?.visibility = if (!basalProfileEnabled || !pump.isInitialized || pump.isSuspended) View.GONE else View.VISIBLE
|
actions_profileswitch?.visibility = if (!basalProfileEnabled || !pump.isInitialized || pump.isSuspended) View.GONE else View.VISIBLE
|
||||||
|
|
||||||
if (!pump.pumpDescription.isExtendedBolusCapable || !pump.isInitialized || pump.isSuspended || pump.isFakingTempsByExtendedBoluses || Config.APS) {
|
if (!pump.pumpDescription.isExtendedBolusCapable || !pump.isInitialized || pump.isSuspended || pump.isFakingTempsByExtendedBoluses) {
|
||||||
actions_extendedbolus?.visibility = View.GONE
|
actions_extendedbolus?.visibility = View.GONE
|
||||||
actions_extendedbolus_cancel?.visibility = View.GONE
|
actions_extendedbolus_cancel?.visibility = View.GONE
|
||||||
} else {
|
} else {
|
||||||
|
@ -172,7 +187,7 @@ class ActionsFragment : Fragment() {
|
||||||
if (activeExtendedBolus != null) {
|
if (activeExtendedBolus != null) {
|
||||||
actions_extendedbolus?.visibility = View.GONE
|
actions_extendedbolus?.visibility = View.GONE
|
||||||
actions_extendedbolus_cancel?.visibility = View.VISIBLE
|
actions_extendedbolus_cancel?.visibility = View.VISIBLE
|
||||||
actions_extendedbolus_cancel?.text = MainApp.gs(R.string.cancel) + " " + activeExtendedBolus.toString()
|
actions_extendedbolus_cancel?.text = MainApp.gs(R.string.cancel) + " " + activeExtendedBolus.toStringMedium()
|
||||||
} else {
|
} else {
|
||||||
actions_extendedbolus?.visibility = View.VISIBLE
|
actions_extendedbolus?.visibility = View.VISIBLE
|
||||||
actions_extendedbolus_cancel?.visibility = View.GONE
|
actions_extendedbolus_cancel?.visibility = View.GONE
|
||||||
|
@ -198,8 +213,11 @@ class ActionsFragment : Fragment() {
|
||||||
if (!pump.pumpDescription.isRefillingCapable || !pump.isInitialized || pump.isSuspended) View.GONE
|
if (!pump.pumpDescription.isRefillingCapable || !pump.isInitialized || pump.isSuspended) View.GONE
|
||||||
else View.VISIBLE
|
else View.VISIBLE
|
||||||
|
|
||||||
actions_temptarget?.visibility = if (!Config.APS) View.GONE else View.VISIBLE
|
actions_temptarget?.visibility = Config.APS.toVisibility()
|
||||||
actions_tddstats?.visibility = if (!pump.pumpDescription.supportsTDDs) View.GONE else View.VISIBLE
|
actions_tddstats?.visibility = pump.pumpDescription.supportsTDDs.toVisibility()
|
||||||
|
activity?.let { activity ->
|
||||||
|
CareportalFragment.updateAge(activity, careportal_sensorage, careportal_insulinage, careportal_canulaage, careportal_pbage)
|
||||||
|
}
|
||||||
checkPumpCustomActions()
|
checkPumpCustomActions()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,8 +242,7 @@ class ActionsFragment : Fragment() {
|
||||||
val action = this.pumpCustomActions[b.text.toString()]
|
val action = this.pumpCustomActions[b.text.toString()]
|
||||||
ConfigBuilderPlugin.getPlugin().activePump!!.executeCustomAction(action!!.customActionType)
|
ConfigBuilderPlugin.getPlugin().activePump!!.executeCustomAction(action!!.customActionType)
|
||||||
}
|
}
|
||||||
|
val top = activity?.let { ContextCompat.getDrawable(it, customAction.iconResourceId) }
|
||||||
val top = resources.getDrawable(customAction.iconResourceId)
|
|
||||||
btn.setCompoundDrawablesWithIntrinsicBounds(null, top, null, null)
|
btn.setCompoundDrawablesWithIntrinsicBounds(null, top, null, null)
|
||||||
|
|
||||||
action_buttons_layout?.addView(btn)
|
action_buttons_layout?.addView(btn)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package info.nightscout.androidaps.plugins.general.actions
|
package info.nightscout.androidaps.plugins.general.actions
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.Config
|
||||||
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.PluginDescription
|
||||||
|
@ -8,6 +9,8 @@ import info.nightscout.androidaps.interfaces.PluginType
|
||||||
object ActionsPlugin : PluginBase(PluginDescription()
|
object ActionsPlugin : PluginBase(PluginDescription()
|
||||||
.mainType(PluginType.GENERAL)
|
.mainType(PluginType.GENERAL)
|
||||||
.fragmentClass(ActionsFragment::class.qualifiedName)
|
.fragmentClass(ActionsFragment::class.qualifiedName)
|
||||||
|
.enableByDefault(Config.APS || Config.PUMPCONTROL)
|
||||||
|
.visibleByDefault(Config.APS || Config.PUMPCONTROL)
|
||||||
.pluginName(R.string.actions)
|
.pluginName(R.string.actions)
|
||||||
.shortName(R.string.actions_shortname)
|
.shortName(R.string.actions_shortname)
|
||||||
.description(R.string.description_actions))
|
.description(R.string.description_actions))
|
||||||
|
|
|
@ -1,63 +0,0 @@
|
||||||
package info.nightscout.androidaps.plugins.general.actions.defs;
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.R;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by andy on 9/20/18.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class CustomAction {
|
|
||||||
|
|
||||||
private int name;
|
|
||||||
private String iconName;
|
|
||||||
private CustomActionType customActionType;
|
|
||||||
private int iconResourceId;
|
|
||||||
private boolean enabled = true;
|
|
||||||
|
|
||||||
|
|
||||||
public CustomAction(int nameResourceId, CustomActionType actionType) {
|
|
||||||
this(nameResourceId, actionType, R.drawable.icon_actions_profileswitch, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public CustomAction(int nameResourceId, CustomActionType actionType, int iconResourceId) {
|
|
||||||
this(nameResourceId, actionType, iconResourceId, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CustomAction(int nameResourceId, CustomActionType actionType, boolean enabled) {
|
|
||||||
this(nameResourceId, actionType, R.drawable.icon_actions_profileswitch, enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CustomAction(int nameResourceId, CustomActionType actionType, int iconResourceId, boolean enabled) {
|
|
||||||
this.name = nameResourceId;
|
|
||||||
this.customActionType = actionType;
|
|
||||||
this.iconResourceId = iconResourceId;
|
|
||||||
this.enabled = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public int getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public CustomActionType getCustomActionType() {
|
|
||||||
return customActionType;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public int getIconResourceId() {
|
|
||||||
return iconResourceId;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public boolean isEnabled() {
|
|
||||||
return enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void setEnabled(boolean enabled) {
|
|
||||||
this.enabled = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
package info.nightscout.androidaps.plugins.general.actions.defs
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.R
|
||||||
|
|
||||||
|
class CustomAction @JvmOverloads constructor(val name: Int, val customActionType: CustomActionType?, val iconResourceId: Int = R.drawable.icon_actions_profileswitch, var isEnabled: Boolean = true) {
|
||||||
|
|
||||||
|
constructor(nameResourceId: Int, actionType: CustomActionType?, enabled: Boolean) :
|
||||||
|
this(nameResourceId, actionType, R.drawable.icon_actions_profileswitch, enabled)
|
||||||
|
|
||||||
|
}
|
|
@ -1,11 +0,0 @@
|
||||||
package info.nightscout.androidaps.plugins.general.actions.defs;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by andy on 9/20/18.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public interface CustomActionType {
|
|
||||||
|
|
||||||
String getKey();
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
package info.nightscout.androidaps.plugins.general.actions.defs
|
||||||
|
|
||||||
|
interface CustomActionType {
|
||||||
|
val key: String?
|
||||||
|
}
|
|
@ -1,255 +0,0 @@
|
||||||
package info.nightscout.androidaps.plugins.general.actions.dialogs;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import androidx.fragment.app.DialogFragment;
|
|
||||||
import androidx.appcompat.app.AlertDialog;
|
|
||||||
import android.text.Editable;
|
|
||||||
import android.text.Html;
|
|
||||||
import android.text.TextWatcher;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.View.OnClickListener;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.view.Window;
|
|
||||||
import android.view.WindowManager;
|
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.CheckBox;
|
|
||||||
import android.widget.EditText;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
|
|
||||||
import com.google.common.base.Joiner;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.MainApp;
|
|
||||||
import info.nightscout.androidaps.R;
|
|
||||||
import info.nightscout.androidaps.data.DetailedBolusInfo;
|
|
||||||
import info.nightscout.androidaps.db.CareportalEvent;
|
|
||||||
import info.nightscout.androidaps.db.Source;
|
|
||||||
import info.nightscout.androidaps.interfaces.Constraint;
|
|
||||||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
|
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
|
|
||||||
import info.nightscout.androidaps.plugins.general.overview.dialogs.ErrorHelperActivity;
|
|
||||||
import info.nightscout.androidaps.queue.Callback;
|
|
||||||
import info.nightscout.androidaps.utils.DecimalFormatter;
|
|
||||||
import info.nightscout.androidaps.utils.NumberPicker;
|
|
||||||
import info.nightscout.androidaps.utils.SP;
|
|
||||||
import info.nightscout.androidaps.utils.SafeParse;
|
|
||||||
import info.nightscout.androidaps.utils.ToastUtils;
|
|
||||||
|
|
||||||
import static info.nightscout.androidaps.utils.DateUtil.now;
|
|
||||||
|
|
||||||
public class FillDialog extends DialogFragment implements OnClickListener {
|
|
||||||
private static Logger log = LoggerFactory.getLogger(FillDialog.class);
|
|
||||||
|
|
||||||
private CheckBox pumpSiteChangeCheckbox;
|
|
||||||
private CheckBox insulinCartridgeChangeCheckbox;
|
|
||||||
|
|
||||||
private NumberPicker editInsulin;
|
|
||||||
|
|
||||||
double amount1 = 0d;
|
|
||||||
double amount2 = 0d;
|
|
||||||
double amount3 = 0d;
|
|
||||||
|
|
||||||
private EditText notesEdit;
|
|
||||||
|
|
||||||
//one shot guards
|
|
||||||
private boolean accepted;
|
|
||||||
private boolean okClicked;
|
|
||||||
|
|
||||||
final private TextWatcher textWatcher = new TextWatcher() {
|
|
||||||
@Override
|
|
||||||
public void afterTextChanged(Editable s) {
|
|
||||||
validateInputs();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private void validateInputs() {
|
|
||||||
int time = editInsulin.getValue().intValue();
|
|
||||||
if (Math.abs(time) > 12 * 60) {
|
|
||||||
editInsulin.setValue(0d);
|
|
||||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.constraintapllied));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
|
||||||
Bundle savedInstanceState) {
|
|
||||||
View view = inflater.inflate(R.layout.actions_fill_dialog, container, false);
|
|
||||||
|
|
||||||
view.findViewById(R.id.ok).setOnClickListener(this);
|
|
||||||
view.findViewById(R.id.cancel).setOnClickListener(this);
|
|
||||||
|
|
||||||
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
|
|
||||||
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
|
|
||||||
|
|
||||||
pumpSiteChangeCheckbox = view.findViewById(R.id.fill_catheter_change);
|
|
||||||
insulinCartridgeChangeCheckbox = view.findViewById(R.id.fill_cartridge_change);
|
|
||||||
|
|
||||||
Double maxInsulin = MainApp.getConstraintChecker().getMaxBolusAllowed().value();
|
|
||||||
double bolusstep = ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().bolusStep;
|
|
||||||
editInsulin = view.findViewById(R.id.fill_insulinamount);
|
|
||||||
editInsulin.setParams(0d, 0d, maxInsulin, bolusstep, DecimalFormatter.pumpSupportedBolusFormat(), false, view.findViewById(R.id.ok), textWatcher);
|
|
||||||
|
|
||||||
|
|
||||||
Button preset1Button = view.findViewById(R.id.fill_preset_button1);
|
|
||||||
amount1 = SP.getDouble("fill_button1", 0.3);
|
|
||||||
if (amount1 > 0) {
|
|
||||||
preset1Button.setVisibility(View.VISIBLE);
|
|
||||||
preset1Button.setText(DecimalFormatter.toPumpSupportedBolus(amount1)); // + "U");
|
|
||||||
preset1Button.setOnClickListener(this);
|
|
||||||
} else {
|
|
||||||
preset1Button.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
Button preset2Button = view.findViewById(R.id.fill_preset_button2);
|
|
||||||
amount2 = SP.getDouble("fill_button2", 0d);
|
|
||||||
if (amount2 > 0) {
|
|
||||||
preset2Button.setVisibility(View.VISIBLE);
|
|
||||||
preset2Button.setText(DecimalFormatter.toPumpSupportedBolus(amount2)); // + "U");
|
|
||||||
preset2Button.setOnClickListener(this);
|
|
||||||
} else {
|
|
||||||
preset2Button.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
Button preset3Button = view.findViewById(R.id.fill_preset_button3);
|
|
||||||
amount3 = SP.getDouble("fill_button3", 0d);
|
|
||||||
if (amount3 > 0) {
|
|
||||||
preset3Button.setVisibility(View.VISIBLE);
|
|
||||||
preset3Button.setText(DecimalFormatter.toPumpSupportedBolus(amount3)); // + "U");
|
|
||||||
preset3Button.setOnClickListener(this);
|
|
||||||
} else {
|
|
||||||
preset3Button.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
LinearLayout notesLayout = view.findViewById(R.id.fill_notes_layout);
|
|
||||||
notesLayout.setVisibility(SP.getBoolean(R.string.key_show_notes_entry_dialogs, false) ? View.VISIBLE : View.GONE);
|
|
||||||
notesEdit = view.findViewById(R.id.fill_notes);
|
|
||||||
|
|
||||||
setCancelable(true);
|
|
||||||
getDialog().setCanceledOnTouchOutside(false);
|
|
||||||
return view;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(View view) {
|
|
||||||
switch (view.getId()) {
|
|
||||||
case R.id.ok:
|
|
||||||
confirmAndDeliver();
|
|
||||||
break;
|
|
||||||
case R.id.cancel:
|
|
||||||
dismiss();
|
|
||||||
break;
|
|
||||||
case R.id.fill_preset_button1:
|
|
||||||
editInsulin.setValue(amount1);
|
|
||||||
break;
|
|
||||||
case R.id.fill_preset_button2:
|
|
||||||
editInsulin.setValue(amount2);
|
|
||||||
break;
|
|
||||||
case R.id.fill_preset_button3:
|
|
||||||
editInsulin.setValue(amount3);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private synchronized void confirmAndDeliver() {
|
|
||||||
if (okClicked) {
|
|
||||||
log.debug("guarding: ok already clicked");
|
|
||||||
dismiss();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
okClicked = true;
|
|
||||||
|
|
||||||
try {
|
|
||||||
Double insulin = SafeParse.stringToDouble(editInsulin.getText());
|
|
||||||
|
|
||||||
List<String> confirmMessage = new LinkedList<>();
|
|
||||||
|
|
||||||
Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(insulin)).value();
|
|
||||||
if (insulinAfterConstraints > 0) {
|
|
||||||
confirmMessage.add(MainApp.gs(R.string.fillwarning));
|
|
||||||
confirmMessage.add("");
|
|
||||||
confirmMessage.add(MainApp.gs(R.string.bolus) + ": " + "<font color='" + MainApp.gc(R.color.colorCarbsButton) + "'>" + DecimalFormatter.toPumpSupportedBolus(insulinAfterConstraints) + "U" + "</font>");
|
|
||||||
if (Math.abs(insulinAfterConstraints - insulin) > 0.01d)
|
|
||||||
confirmMessage.add(MainApp.gs(R.string.bolusconstraintappliedwarning, MainApp.gc(R.color.warning), insulin, insulinAfterConstraints));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pumpSiteChangeCheckbox.isChecked())
|
|
||||||
confirmMessage.add("" + "<font color='" + MainApp.gc(R.color.actionsConfirm) + "'>" + MainApp.gs(R.string.record_pump_site_change) + "</font>");
|
|
||||||
|
|
||||||
if (insulinCartridgeChangeCheckbox.isChecked())
|
|
||||||
confirmMessage.add("" + "<font color='" + MainApp.gc(R.color.actionsConfirm) + "'>" + MainApp.gs(R.string.record_insulin_cartridge_change) + "</font>");
|
|
||||||
|
|
||||||
final String notes = notesEdit.getText().toString();
|
|
||||||
if (!notes.isEmpty()) {
|
|
||||||
confirmMessage.add(MainApp.gs(R.string.careportal_newnstreatment_notes_label) + ": " + notes);
|
|
||||||
}
|
|
||||||
|
|
||||||
final Double finalInsulinAfterConstraints = insulinAfterConstraints;
|
|
||||||
|
|
||||||
final Context context = getContext();
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
|
||||||
|
|
||||||
builder.setTitle(MainApp.gs(R.string.confirmation));
|
|
||||||
if (insulinAfterConstraints > 0 || pumpSiteChangeCheckbox.isChecked() || insulinCartridgeChangeCheckbox.isChecked()) {
|
|
||||||
builder.setMessage(Html.fromHtml(Joiner.on("<br/>").join(confirmMessage)));
|
|
||||||
builder.setPositiveButton(MainApp.gs(R.string.primefill), (dialog, id) -> {
|
|
||||||
synchronized (builder) {
|
|
||||||
if (accepted) {
|
|
||||||
log.debug("guarding: already accepted");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
accepted = true;
|
|
||||||
|
|
||||||
if (finalInsulinAfterConstraints > 0) {
|
|
||||||
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
|
|
||||||
detailedBolusInfo.insulin = finalInsulinAfterConstraints;
|
|
||||||
detailedBolusInfo.context = context;
|
|
||||||
detailedBolusInfo.source = Source.USER;
|
|
||||||
detailedBolusInfo.isValid = false; // do not count it in IOB (for pump history)
|
|
||||||
detailedBolusInfo.notes = notes;
|
|
||||||
ConfigBuilderPlugin.getPlugin().getCommandQueue().bolus(detailedBolusInfo, new Callback() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (!result.success) {
|
|
||||||
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
|
|
||||||
i.putExtra("soundid", R.raw.boluserror);
|
|
||||||
i.putExtra("status", result.comment);
|
|
||||||
i.putExtra("title", MainApp.gs(R.string.treatmentdeliveryerror));
|
|
||||||
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
|
||||||
MainApp.instance().startActivity(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (pumpSiteChangeCheckbox.isChecked())
|
|
||||||
NSUpload.uploadEvent(CareportalEvent.SITECHANGE, now(), notes);
|
|
||||||
if (insulinCartridgeChangeCheckbox.isChecked())
|
|
||||||
NSUpload.uploadEvent(CareportalEvent.INSULINCHANGE, now() + 1000, notes);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
builder.setMessage(MainApp.gs(R.string.no_action_selected));
|
|
||||||
}
|
|
||||||
builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
|
|
||||||
builder.show();
|
|
||||||
dismiss();
|
|
||||||
} catch (RuntimeException e) {
|
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,115 +0,0 @@
|
||||||
package info.nightscout.androidaps.plugins.general.actions.dialogs;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import androidx.fragment.app.DialogFragment;
|
|
||||||
import androidx.appcompat.app.AlertDialog;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.text.DecimalFormat;
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.MainApp;
|
|
||||||
import info.nightscout.androidaps.R;
|
|
||||||
import info.nightscout.androidaps.interfaces.Constraint;
|
|
||||||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
|
|
||||||
import info.nightscout.androidaps.plugins.general.overview.dialogs.ErrorHelperActivity;
|
|
||||||
import info.nightscout.androidaps.queue.Callback;
|
|
||||||
import info.nightscout.androidaps.utils.NumberPicker;
|
|
||||||
import info.nightscout.androidaps.utils.SafeParse;
|
|
||||||
|
|
||||||
public class NewExtendedBolusDialog extends DialogFragment implements View.OnClickListener {
|
|
||||||
private static Logger log = LoggerFactory.getLogger(NewExtendedBolusDialog.class);
|
|
||||||
|
|
||||||
NumberPicker editInsulin;
|
|
||||||
NumberPicker editDuration;
|
|
||||||
|
|
||||||
public NewExtendedBolusDialog() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
|
||||||
Bundle savedInstanceState) {
|
|
||||||
getDialog().setTitle(MainApp.gs(R.string.overview_extendedbolus_button));
|
|
||||||
|
|
||||||
View view = inflater.inflate(R.layout.overview_newextendedbolus_dialog, container, false);
|
|
||||||
|
|
||||||
Double maxInsulin = MainApp.getConstraintChecker().getMaxExtendedBolusAllowed().value();
|
|
||||||
editInsulin = (NumberPicker) view.findViewById(R.id.overview_newextendedbolus_insulin);
|
|
||||||
editInsulin.setParams(0d, 0d, maxInsulin, 0.1d, new DecimalFormat("0.00"), false, view.findViewById(R.id.ok));
|
|
||||||
|
|
||||||
double extendedDurationStep = ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().extendedBolusDurationStep;
|
|
||||||
double extendedMaxDuration = ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().extendedBolusMaxDuration;
|
|
||||||
editDuration = (NumberPicker) view.findViewById(R.id.overview_newextendedbolus_duration);
|
|
||||||
editDuration.setParams(extendedDurationStep, extendedDurationStep, extendedMaxDuration, extendedDurationStep, new DecimalFormat("0"), false, view.findViewById(R.id.ok));
|
|
||||||
|
|
||||||
view.findViewById(R.id.ok).setOnClickListener(this);
|
|
||||||
view.findViewById(R.id.cancel).setOnClickListener(this);
|
|
||||||
|
|
||||||
setCancelable(true);
|
|
||||||
getDialog().setCanceledOnTouchOutside(false);
|
|
||||||
return view;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(View view) {
|
|
||||||
switch (view.getId()) {
|
|
||||||
case R.id.ok:
|
|
||||||
try {
|
|
||||||
Double insulin = SafeParse.stringToDouble(editInsulin.getText());
|
|
||||||
int durationInMinutes = SafeParse.stringToInt(editDuration.getText());
|
|
||||||
|
|
||||||
String confirmMessage = MainApp.gs(R.string.setextendedbolusquestion);
|
|
||||||
|
|
||||||
Double insulinAfterConstraint = MainApp.getConstraintChecker().applyExtendedBolusConstraints(new Constraint<>(insulin)).value();
|
|
||||||
confirmMessage += " " + insulinAfterConstraint + " U ";
|
|
||||||
confirmMessage += MainApp.gs(R.string.duration) + " " + durationInMinutes + "min ?";
|
|
||||||
if (Math.abs(insulinAfterConstraint - insulin) > 0.01d)
|
|
||||||
confirmMessage += "\n" + MainApp.gs(R.string.constraintapllied);
|
|
||||||
insulin = insulinAfterConstraint;
|
|
||||||
|
|
||||||
final Double finalInsulin = insulin;
|
|
||||||
final int finalDurationInMinutes = durationInMinutes;
|
|
||||||
|
|
||||||
final Context context = getContext();
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
|
||||||
builder.setTitle(MainApp.gs(R.string.confirmation));
|
|
||||||
builder.setMessage(confirmMessage);
|
|
||||||
builder.setPositiveButton(MainApp.gs(R.string.ok), new DialogInterface.OnClickListener() {
|
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
|
||||||
ConfigBuilderPlugin.getPlugin().getCommandQueue().extendedBolus(finalInsulin, finalDurationInMinutes, new Callback() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (!result.success) {
|
|
||||||
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
|
|
||||||
i.putExtra("soundid", R.raw.boluserror);
|
|
||||||
i.putExtra("status", result.comment);
|
|
||||||
i.putExtra("title", MainApp.gs(R.string.treatmentdeliveryerror));
|
|
||||||
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
|
||||||
MainApp.instance().startActivity(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
|
|
||||||
builder.show();
|
|
||||||
dismiss();
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case R.id.cancel:
|
|
||||||
dismiss();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,196 +0,0 @@
|
||||||
package info.nightscout.androidaps.plugins.general.actions.dialogs;
|
|
||||||
|
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import androidx.fragment.app.DialogFragment;
|
|
||||||
import androidx.appcompat.app.AlertDialog;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.RadioButton;
|
|
||||||
import android.widget.RadioGroup;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.text.DecimalFormat;
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.MainApp;
|
|
||||||
import info.nightscout.androidaps.R;
|
|
||||||
import info.nightscout.androidaps.data.Profile;
|
|
||||||
import info.nightscout.androidaps.interfaces.Constraint;
|
|
||||||
import info.nightscout.androidaps.interfaces.PumpDescription;
|
|
||||||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
|
|
||||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
|
|
||||||
import info.nightscout.androidaps.plugins.general.overview.dialogs.ErrorHelperActivity;
|
|
||||||
import info.nightscout.androidaps.queue.Callback;
|
|
||||||
import info.nightscout.androidaps.utils.NumberPicker;
|
|
||||||
import info.nightscout.androidaps.utils.SafeParse;
|
|
||||||
|
|
||||||
public class NewTempBasalDialog extends DialogFragment implements View.OnClickListener, RadioGroup.OnCheckedChangeListener {
|
|
||||||
private static Logger log = LoggerFactory.getLogger(NewTempBasalDialog.class);
|
|
||||||
|
|
||||||
RadioButton percentRadio;
|
|
||||||
RadioButton absoluteRadio;
|
|
||||||
RadioGroup basalTypeRadioGroup;
|
|
||||||
LinearLayout typeSelectorLayout;
|
|
||||||
|
|
||||||
LinearLayout percentLayout;
|
|
||||||
LinearLayout absoluteLayout;
|
|
||||||
|
|
||||||
NumberPicker basalPercent;
|
|
||||||
NumberPicker basalAbsolute;
|
|
||||||
NumberPicker duration;
|
|
||||||
|
|
||||||
public NewTempBasalDialog() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
|
||||||
Bundle savedInstanceState) {
|
|
||||||
getDialog().setTitle(MainApp.gs(R.string.overview_tempbasal_button));
|
|
||||||
|
|
||||||
View view = inflater.inflate(R.layout.overview_newtempbasal_dialog, container, false);
|
|
||||||
|
|
||||||
percentLayout = (LinearLayout) view.findViewById(R.id.overview_newtempbasal_percent_layout);
|
|
||||||
absoluteLayout = (LinearLayout) view.findViewById(R.id.overview_newtempbasal_absolute_layout);
|
|
||||||
percentRadio = (RadioButton) view.findViewById(R.id.overview_newtempbasal_percent_radio);
|
|
||||||
basalTypeRadioGroup = (RadioGroup) view.findViewById(R.id.overview_newtempbasal_radiogroup);
|
|
||||||
absoluteRadio = (RadioButton) view.findViewById(R.id.overview_newtempbasal_absolute_radio);
|
|
||||||
typeSelectorLayout = (LinearLayout) view.findViewById(R.id.overview_newtempbasal_typeselector_layout);
|
|
||||||
|
|
||||||
PumpDescription pumpDescription = ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription();
|
|
||||||
|
|
||||||
basalPercent = (NumberPicker) view.findViewById(R.id.overview_newtempbasal_basalpercentinput);
|
|
||||||
double maxTempPercent = pumpDescription.maxTempPercent;
|
|
||||||
double tempPercentStep = pumpDescription.tempPercentStep;
|
|
||||||
basalPercent.setParams(100d, 0d, maxTempPercent, tempPercentStep, new DecimalFormat("0"), true, view.findViewById(R.id.ok));
|
|
||||||
|
|
||||||
Profile profile = ProfileFunctions.getInstance().getProfile();
|
|
||||||
Double currentBasal = profile != null ? profile.getBasal() : 0d;
|
|
||||||
basalAbsolute = (NumberPicker) view.findViewById(R.id.overview_newtempbasal_basalabsoluteinput);
|
|
||||||
basalAbsolute.setParams(currentBasal, 0d, pumpDescription.maxTempAbsolute, pumpDescription.tempAbsoluteStep, new DecimalFormat("0.00"), true, view.findViewById(R.id.ok));
|
|
||||||
|
|
||||||
double tempDurationStep = pumpDescription.tempDurationStep;
|
|
||||||
double tempMaxDuration = pumpDescription.tempMaxDuration;
|
|
||||||
duration = (NumberPicker) view.findViewById(R.id.overview_newtempbasal_duration);
|
|
||||||
duration.setParams(tempDurationStep, tempDurationStep, tempMaxDuration, tempDurationStep, new DecimalFormat("0"), false, view.findViewById(R.id.ok));
|
|
||||||
|
|
||||||
if ((pumpDescription.tempBasalStyle & PumpDescription.PERCENT) == PumpDescription.PERCENT && (pumpDescription.tempBasalStyle & PumpDescription.ABSOLUTE) == PumpDescription.ABSOLUTE) {
|
|
||||||
// Both allowed
|
|
||||||
typeSelectorLayout.setVisibility(View.VISIBLE);
|
|
||||||
} else {
|
|
||||||
typeSelectorLayout.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((pumpDescription.tempBasalStyle & PumpDescription.PERCENT) == PumpDescription.PERCENT) {
|
|
||||||
percentRadio.setChecked(true);
|
|
||||||
absoluteRadio.setChecked(false);
|
|
||||||
percentLayout.setVisibility(View.VISIBLE);
|
|
||||||
absoluteLayout.setVisibility(View.GONE);
|
|
||||||
} else if ((pumpDescription.tempBasalStyle & PumpDescription.ABSOLUTE) == PumpDescription.ABSOLUTE) {
|
|
||||||
percentRadio.setChecked(false);
|
|
||||||
absoluteRadio.setChecked(true);
|
|
||||||
percentLayout.setVisibility(View.GONE);
|
|
||||||
absoluteLayout.setVisibility(View.VISIBLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
view.findViewById(R.id.ok).setOnClickListener(this);
|
|
||||||
view.findViewById(R.id.cancel).setOnClickListener(this);
|
|
||||||
basalTypeRadioGroup.setOnCheckedChangeListener(this);
|
|
||||||
|
|
||||||
setCancelable(true);
|
|
||||||
getDialog().setCanceledOnTouchOutside(false);
|
|
||||||
return view;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(View view) {
|
|
||||||
switch (view.getId()) {
|
|
||||||
case R.id.ok:
|
|
||||||
try {
|
|
||||||
int percent = 0;
|
|
||||||
Double absolute = 0d;
|
|
||||||
final boolean setAsPercent = percentRadio.isChecked();
|
|
||||||
int durationInMinutes = SafeParse.stringToInt(duration.getText());
|
|
||||||
|
|
||||||
Profile profile = ProfileFunctions.getInstance().getProfile();
|
|
||||||
if (profile == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
String confirmMessage = MainApp.gs(R.string.setbasalquestion);
|
|
||||||
if (setAsPercent) {
|
|
||||||
int basalPercentInput = SafeParse.stringToInt(basalPercent.getText());
|
|
||||||
percent = MainApp.getConstraintChecker().applyBasalPercentConstraints(new Constraint<>(basalPercentInput), profile).value();
|
|
||||||
confirmMessage += "\n" + percent + "% ";
|
|
||||||
confirmMessage += "\n" + MainApp.gs(R.string.duration) + " " + durationInMinutes + "min ?";
|
|
||||||
if (percent != basalPercentInput)
|
|
||||||
confirmMessage += "\n" + MainApp.gs(R.string.constraintapllied);
|
|
||||||
} else {
|
|
||||||
Double basalAbsoluteInput = SafeParse.stringToDouble(basalAbsolute.getText());
|
|
||||||
absolute = MainApp.getConstraintChecker().applyBasalConstraints(new Constraint<>(basalAbsoluteInput), profile).value();
|
|
||||||
confirmMessage += "\n" + absolute + " U/h ";
|
|
||||||
confirmMessage += "\n" + MainApp.gs(R.string.duration) + " " + durationInMinutes + "min ?";
|
|
||||||
if (Math.abs(absolute - basalAbsoluteInput) > 0.01d)
|
|
||||||
confirmMessage += "\n" + MainApp.gs(R.string.constraintapllied);
|
|
||||||
}
|
|
||||||
|
|
||||||
final int finalBasalPercent = percent;
|
|
||||||
final Double finalBasal = absolute;
|
|
||||||
final int finalDurationInMinutes = durationInMinutes;
|
|
||||||
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
|
|
||||||
builder.setTitle(MainApp.gs(R.string.confirmation));
|
|
||||||
builder.setMessage(confirmMessage);
|
|
||||||
builder.setPositiveButton(MainApp.gs(R.string.ok), new DialogInterface.OnClickListener() {
|
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
|
||||||
Callback callback = new Callback() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (!result.success) {
|
|
||||||
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
|
|
||||||
i.putExtra("soundid", R.raw.boluserror);
|
|
||||||
i.putExtra("status", result.comment);
|
|
||||||
i.putExtra("title", MainApp.gs(R.string.tempbasaldeliveryerror));
|
|
||||||
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
|
||||||
MainApp.instance().startActivity(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (setAsPercent) {
|
|
||||||
ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalPercent(finalBasalPercent, finalDurationInMinutes, true, profile, callback);
|
|
||||||
} else {
|
|
||||||
ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalAbsolute(finalBasal, finalDurationInMinutes, true, profile, callback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
|
|
||||||
builder.show();
|
|
||||||
dismiss();
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case R.id.cancel:
|
|
||||||
dismiss();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCheckedChanged(RadioGroup group, int checkedId) {
|
|
||||||
switch (checkedId) {
|
|
||||||
case R.id.overview_newtempbasal_percent_radio:
|
|
||||||
percentLayout.setVisibility(View.VISIBLE);
|
|
||||||
absoluteLayout.setVisibility(View.GONE);
|
|
||||||
break;
|
|
||||||
case R.id.overview_newtempbasal_absolute_radio:
|
|
||||||
percentLayout.setVisibility(View.GONE);
|
|
||||||
absoluteLayout.setVisibility(View.VISIBLE);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +1,7 @@
|
||||||
package info.nightscout.androidaps.plugins.general.automation
|
package info.nightscout.androidaps.plugins.general.automation
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.text.method.ScrollingMovementMethod
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
@ -16,12 +17,12 @@ import info.nightscout.androidaps.plugins.general.automation.dragHelpers.SimpleI
|
||||||
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationDataChanged
|
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationDataChanged
|
||||||
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateGui
|
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateGui
|
||||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||||
|
import info.nightscout.androidaps.utils.HtmlHelper
|
||||||
import info.nightscout.androidaps.utils.plusAssign
|
import info.nightscout.androidaps.utils.plusAssign
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
import io.reactivex.disposables.CompositeDisposable
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
import kotlinx.android.synthetic.main.automation_fragment.*
|
import kotlinx.android.synthetic.main.automation_fragment.*
|
||||||
|
|
||||||
|
|
||||||
class AutomationFragment : Fragment(), OnStartDragListener {
|
class AutomationFragment : Fragment(), OnStartDragListener {
|
||||||
|
|
||||||
private var disposable: CompositeDisposable = CompositeDisposable()
|
private var disposable: CompositeDisposable = CompositeDisposable()
|
||||||
|
@ -40,6 +41,8 @@ class AutomationFragment : Fragment(), OnStartDragListener {
|
||||||
automation_eventListView.layoutManager = LinearLayoutManager(context)
|
automation_eventListView.layoutManager = LinearLayoutManager(context)
|
||||||
automation_eventListView.adapter = eventListAdapter
|
automation_eventListView.adapter = eventListAdapter
|
||||||
|
|
||||||
|
automation_logView.setMovementMethod(ScrollingMovementMethod())
|
||||||
|
|
||||||
automation_fabAddEvent.setOnClickListener {
|
automation_fabAddEvent.setOnClickListener {
|
||||||
val dialog = EditEventDialog()
|
val dialog = EditEventDialog()
|
||||||
val args = Bundle()
|
val args = Bundle()
|
||||||
|
@ -88,8 +91,8 @@ class AutomationFragment : Fragment(), OnStartDragListener {
|
||||||
eventListAdapter?.notifyDataSetChanged()
|
eventListAdapter?.notifyDataSetChanged()
|
||||||
val sb = StringBuilder()
|
val sb = StringBuilder()
|
||||||
for (l in AutomationPlugin.executionLog.reversed())
|
for (l in AutomationPlugin.executionLog.reversed())
|
||||||
sb.append(l).append("\n")
|
sb.append(l).append("<br>")
|
||||||
automation_logView?.text = sb.toString()
|
automation_logView?.text = HtmlHelper.fromHtml(sb.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStartDrag(viewHolder: RecyclerView.ViewHolder) {
|
override fun onStartDrag(viewHolder: RecyclerView.ViewHolder) {
|
||||||
|
|
|
@ -178,10 +178,10 @@ object AutomationPlugin : PluginBase(PluginDescription()
|
||||||
val sb = StringBuilder()
|
val sb = StringBuilder()
|
||||||
sb.append(DateUtil.timeString(DateUtil.now()))
|
sb.append(DateUtil.timeString(DateUtil.now()))
|
||||||
sb.append(" ")
|
sb.append(" ")
|
||||||
sb.append(if (result.success) "☺" else "X")
|
sb.append(if (result.success) "☺" else "▼")
|
||||||
sb.append(" ")
|
sb.append(" <b>")
|
||||||
sb.append(event.title)
|
sb.append(event.title)
|
||||||
sb.append(": ")
|
sb.append(":</b> ")
|
||||||
sb.append(action.shortDescription())
|
sb.append(action.shortDescription())
|
||||||
sb.append(": ")
|
sb.append(": ")
|
||||||
sb.append(result.comment)
|
sb.append(result.comment)
|
||||||
|
|
|
@ -21,17 +21,29 @@ import info.nightscout.androidaps.plugins.general.automation.elements.InputProfi
|
||||||
import info.nightscout.androidaps.plugins.general.automation.elements.LabelWithElement;
|
import info.nightscout.androidaps.plugins.general.automation.elements.LabelWithElement;
|
||||||
import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder;
|
import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder;
|
||||||
import info.nightscout.androidaps.queue.Callback;
|
import info.nightscout.androidaps.queue.Callback;
|
||||||
|
import info.nightscout.androidaps.utils.DateUtil;
|
||||||
import info.nightscout.androidaps.utils.JsonHelper;
|
import info.nightscout.androidaps.utils.JsonHelper;
|
||||||
|
|
||||||
public class ActionProfileSwitch extends Action {
|
public class ActionProfileSwitch extends Action {
|
||||||
private static Logger log = LoggerFactory.getLogger(L.AUTOMATION);
|
private static Logger log = LoggerFactory.getLogger(L.AUTOMATION);
|
||||||
public InputProfileName inputProfileName = new InputProfileName(ProfileFunctions.getInstance().getProfileName());
|
InputProfileName inputProfileName;
|
||||||
String profileName = "";
|
String profileName = "";
|
||||||
|
|
||||||
public ActionProfileSwitch() {
|
public ActionProfileSwitch() {
|
||||||
// Prevent action if active profile is already active
|
// Prevent action if active profile is already active
|
||||||
// but we don't have a trigger IS_NOT_EQUAL
|
// but we don't have a trigger IS_NOT_EQUAL
|
||||||
// so check is in the doRun()
|
// so check is in the doRun()
|
||||||
|
ProfileInterface profileInterface = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface();
|
||||||
|
if (profileInterface != null) {
|
||||||
|
ProfileStore profileStore = profileInterface.getProfile();
|
||||||
|
if (profileStore != null) {
|
||||||
|
String name = profileStore.getDefaultProfileName();
|
||||||
|
if (name != null) {
|
||||||
|
profileName = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inputProfileName = new InputProfileName(profileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -50,23 +62,43 @@ public class ActionProfileSwitch extends Action {
|
||||||
|
|
||||||
String activeProfileName = ProfileFunctions.getInstance().getProfileName();
|
String activeProfileName = ProfileFunctions.getInstance().getProfileName();
|
||||||
//Check for uninitialized profileName
|
//Check for uninitialized profileName
|
||||||
if ( profileName.equals("")){ profileName = activeProfileName; }
|
if ( profileName.equals("")){
|
||||||
|
log.error("Selected profile not initialized");
|
||||||
|
if (callback != null)
|
||||||
|
callback.result(new PumpEnactResult().success(false).comment(R.string.error_field_must_not_be_empty)).run();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( ProfileFunctions.getInstance().getProfile() == null){
|
||||||
|
log.error("ProfileFunctions not initialized");
|
||||||
|
if (callback != null)
|
||||||
|
callback.result(new PumpEnactResult().success(false).comment(R.string.noprofile)).run();
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (profileName.equals(activeProfileName)) {
|
if (profileName.equals(activeProfileName)) {
|
||||||
// Profile is already switched
|
if (L.isEnabled(L.AUTOMATION))
|
||||||
|
log.debug("Profile is already switched");
|
||||||
|
if (callback != null)
|
||||||
|
callback.result(new PumpEnactResult().success(true).comment(R.string.alreadyset)).run();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ProfileInterface activeProfile = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface();
|
ProfileInterface activeProfile = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface();
|
||||||
if (activeProfile == null) return;
|
if (activeProfile == null) {
|
||||||
|
log.error("ProfileInterface not initialized");
|
||||||
|
if (callback != null)
|
||||||
|
callback.result(new PumpEnactResult().success(false).comment(R.string.noprofile)).run();
|
||||||
|
return;
|
||||||
|
}
|
||||||
ProfileStore profileStore = activeProfile.getProfile();
|
ProfileStore profileStore = activeProfile.getProfile();
|
||||||
if (profileStore == null) return;
|
if (profileStore == null) return;
|
||||||
if(profileStore.getSpecificProfile(profileName) == null) {
|
if(profileStore.getSpecificProfile(profileName) == null) {
|
||||||
if (L.isEnabled(L.AUTOMATION))
|
if (L.isEnabled(L.AUTOMATION))
|
||||||
log.error("Selected profile does not exist! - "+ profileName);
|
log.error("Selected profile does not exist! - "+ profileName);
|
||||||
|
if (callback != null)
|
||||||
|
callback.result(new PumpEnactResult().success(false).comment(R.string.notexists)).run();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProfileFunctions.doProfileSwitch(profileStore, profileName, 0, 100, 0);
|
ProfileFunctions.doProfileSwitch(profileStore, profileName, 0, 100, 0, DateUtil.now());
|
||||||
if (callback != null)
|
if (callback != null)
|
||||||
callback.result(new PumpEnactResult().success(true).comment(R.string.ok)).run();
|
callback.result(new PumpEnactResult().success(true).comment(R.string.ok)).run();
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,7 +75,7 @@ public class ActionStartTempTarget extends Action {
|
||||||
int unitResId = value.getUnits().equals(Constants.MGDL) ? R.string.mgdl : R.string.mmol;
|
int unitResId = value.getUnits().equals(Constants.MGDL) ? R.string.mgdl : R.string.mmol;
|
||||||
|
|
||||||
new LayoutBuilder()
|
new LayoutBuilder()
|
||||||
.add(new LabelWithElement(MainApp.gs(R.string.careportal_temporarytarget) + " [" + MainApp.gs(unitResId) + "]", "", value))
|
.add(new LabelWithElement(MainApp.gs(R.string.careportal_temporarytarget) + "\n[" + MainApp.gs(unitResId) + "]", "", value))
|
||||||
.add(new LabelWithElement(MainApp.gs(R.string.careportal_newnstreatment_duration_min_label), "", duration))
|
.add(new LabelWithElement(MainApp.gs(R.string.careportal_newnstreatment_duration_min_label), "", duration))
|
||||||
.build(root);
|
.build(root);
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ class ActionListAdapter(private val fragmentManager: FragmentManager, private va
|
||||||
|
|
||||||
class ViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
|
class ViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
|
||||||
|
|
||||||
fun bind(action: Action, fragmentManager: FragmentManager, recyclerView: RecyclerView.Adapter<ViewHolder>, position : Int, actionList: MutableList<Action>) {
|
fun bind(action: Action, fragmentManager: FragmentManager, recyclerView: RecyclerView.Adapter<ViewHolder>, position: Int, actionList: MutableList<Action>) {
|
||||||
view.findViewById<LinearLayout>(R.id.automation_layoutText).setOnClickListener {
|
view.findViewById<LinearLayout>(R.id.automation_layoutText).setOnClickListener {
|
||||||
if (action.hasDialog()) {
|
if (action.hasDialog()) {
|
||||||
val args = Bundle()
|
val args = Bundle()
|
||||||
|
@ -48,6 +48,7 @@ class ActionListAdapter(private val fragmentManager: FragmentManager, private va
|
||||||
recyclerView.notifyDataSetChanged()
|
recyclerView.notifyDataSetChanged()
|
||||||
RxBus.send(EventAutomationUpdateGui())
|
RxBus.send(EventAutomationUpdateGui())
|
||||||
}
|
}
|
||||||
|
if (action.icon().isPresent) view.findViewById<ImageView>(R.id.automation_action_image).setImageResource(action.icon().get())
|
||||||
view.findViewById<TextView>(R.id.automation_viewActionTitle).text = action.shortDescription()
|
view.findViewById<TextView>(R.id.automation_viewActionTitle).text = action.shortDescription()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,19 +5,18 @@ import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.RadioButton
|
import android.widget.RadioButton
|
||||||
import androidx.fragment.app.DialogFragment
|
|
||||||
import info.nightscout.androidaps.R
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.dialogs.DialogFragmentWithDate
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||||
import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin
|
import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin
|
||||||
import info.nightscout.androidaps.plugins.general.automation.actions.Action
|
import info.nightscout.androidaps.plugins.general.automation.actions.Action
|
||||||
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationAddAction
|
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationAddAction
|
||||||
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateGui
|
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateGui
|
||||||
import kotlinx.android.synthetic.main.automation_dialog_choose_action.*
|
import kotlinx.android.synthetic.main.automation_dialog_choose_action.*
|
||||||
import kotlinx.android.synthetic.main.okcancel.*
|
|
||||||
|
|
||||||
class ChooseActionDialog : DialogFragment() {
|
class ChooseActionDialog : DialogFragmentWithDate() {
|
||||||
|
|
||||||
var checkedIndex = -1
|
private var checkedIndex = -1
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?): View? {
|
savedInstanceState: Bundle?): View? {
|
||||||
|
@ -26,7 +25,7 @@ class ChooseActionDialog : DialogFragment() {
|
||||||
checkedIndex = bundle.getInt("checkedIndex")
|
checkedIndex = bundle.getInt("checkedIndex")
|
||||||
}
|
}
|
||||||
|
|
||||||
dialog?.setCanceledOnTouchOutside(false)
|
onCreateViewGeneral()
|
||||||
return inflater.inflate(R.layout.automation_dialog_choose_action, container, false)
|
return inflater.inflate(R.layout.automation_dialog_choose_action, container, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,27 +41,19 @@ class ChooseActionDialog : DialogFragment() {
|
||||||
|
|
||||||
if (checkedIndex != -1)
|
if (checkedIndex != -1)
|
||||||
(automation_radioGroup.getChildAt(checkedIndex) as RadioButton).isChecked = true
|
(automation_radioGroup.getChildAt(checkedIndex) as RadioButton).isChecked = true
|
||||||
|
}
|
||||||
|
|
||||||
// OK button
|
override fun submit(): Boolean {
|
||||||
ok.setOnClickListener {
|
instantiateAction()?.let {
|
||||||
dismiss()
|
RxBus.send(EventAutomationAddAction(it))
|
||||||
instantiateAction()?.let {
|
RxBus.send(EventAutomationUpdateGui())
|
||||||
RxBus.send(EventAutomationAddAction(it))
|
|
||||||
RxBus.send(EventAutomationUpdateGui())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return true
|
||||||
// Cancel button
|
|
||||||
cancel.setOnClickListener { dismiss() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStart() {
|
override fun onSaveInstanceState(savedInstanceState: Bundle) {
|
||||||
super.onStart()
|
super.onSaveInstanceState(savedInstanceState)
|
||||||
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
savedInstanceState.putInt("checkedIndex", determineCheckedIndex())
|
||||||
}
|
|
||||||
|
|
||||||
override fun onSaveInstanceState(bundle: Bundle) {
|
|
||||||
bundle.putInt("checkedIndex", determineCheckedIndex())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun instantiateAction(): Action? {
|
private fun instantiateAction(): Action? {
|
||||||
|
@ -86,5 +77,4 @@ class ChooseActionDialog : DialogFragment() {
|
||||||
}
|
}
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,17 +5,15 @@ import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.RadioButton
|
import android.widget.RadioButton
|
||||||
import androidx.fragment.app.DialogFragment
|
|
||||||
import info.nightscout.androidaps.R
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.dialogs.DialogFragmentWithDate
|
||||||
import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin
|
import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin
|
||||||
import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger
|
import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger
|
||||||
import kotlinx.android.synthetic.main.automation_dialog_choose_trigger.*
|
import kotlinx.android.synthetic.main.automation_dialog_choose_trigger.*
|
||||||
import kotlinx.android.synthetic.main.okcancel.*
|
|
||||||
|
|
||||||
class ChooseTriggerDialog : DialogFragment() {
|
class ChooseTriggerDialog : DialogFragmentWithDate() {
|
||||||
|
|
||||||
private var checkedIndex = -1
|
private var checkedIndex = -1
|
||||||
|
|
||||||
private var clickListener: OnClickListener? = null
|
private var clickListener: OnClickListener? = null
|
||||||
|
|
||||||
interface OnClickListener {
|
interface OnClickListener {
|
||||||
|
@ -29,7 +27,7 @@ class ChooseTriggerDialog : DialogFragment() {
|
||||||
checkedIndex = bundle.getInt("checkedIndex")
|
checkedIndex = bundle.getInt("checkedIndex")
|
||||||
}
|
}
|
||||||
|
|
||||||
dialog?.setCanceledOnTouchOutside(false)
|
onCreateViewGeneral()
|
||||||
return inflater.inflate(R.layout.automation_dialog_choose_trigger, container, false)
|
return inflater.inflate(R.layout.automation_dialog_choose_trigger, container, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,30 +43,22 @@ class ChooseTriggerDialog : DialogFragment() {
|
||||||
|
|
||||||
if (checkedIndex != -1)
|
if (checkedIndex != -1)
|
||||||
(automation_chooseTriggerRadioGroup.getChildAt(checkedIndex) as RadioButton).isChecked = true
|
(automation_chooseTriggerRadioGroup.getChildAt(checkedIndex) as RadioButton).isChecked = true
|
||||||
|
|
||||||
// OK button
|
|
||||||
ok.setOnClickListener {
|
|
||||||
dismiss()
|
|
||||||
instantiateTrigger()?.let {
|
|
||||||
clickListener?.onClick(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cancel button
|
|
||||||
cancel.setOnClickListener { dismiss() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStart() {
|
override fun submit(): Boolean {
|
||||||
super.onStart()
|
instantiateTrigger()?.let {
|
||||||
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
clickListener?.onClick(it)
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setOnClickListener(clickListener: OnClickListener) {
|
fun setOnClickListener(clickListener: OnClickListener) {
|
||||||
this.clickListener = clickListener
|
this.clickListener = clickListener
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSaveInstanceState(bundle: Bundle) {
|
override fun onSaveInstanceState(savedInstanceState: Bundle) {
|
||||||
bundle.putInt("checkedIndex", determineCheckedIndex())
|
super.onSaveInstanceState(savedInstanceState)
|
||||||
|
savedInstanceState.putInt("checkedIndex", determineCheckedIndex())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun instantiateTrigger(): Trigger? {
|
private fun instantiateTrigger(): Trigger? {
|
||||||
|
@ -92,5 +82,4 @@ class ChooseTriggerDialog : DialogFragment() {
|
||||||
}
|
}
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,16 +4,15 @@ import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.fragment.app.DialogFragment
|
|
||||||
import info.nightscout.androidaps.R
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.dialogs.DialogFragmentWithDate
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||||
import info.nightscout.androidaps.plugins.general.automation.actions.Action
|
import info.nightscout.androidaps.plugins.general.automation.actions.Action
|
||||||
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateAction
|
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateAction
|
||||||
import kotlinx.android.synthetic.main.automation_dialog_action.*
|
import kotlinx.android.synthetic.main.automation_dialog_action.*
|
||||||
import kotlinx.android.synthetic.main.okcancel.*
|
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
|
|
||||||
class EditActionDialog : DialogFragment() {
|
class EditActionDialog : DialogFragmentWithDate() {
|
||||||
private var action: Action? = null
|
private var action: Action? = null
|
||||||
private var actionPosition: Int = -1
|
private var actionPosition: Int = -1
|
||||||
|
|
||||||
|
@ -24,8 +23,7 @@ class EditActionDialog : DialogFragment() {
|
||||||
actionPosition = bundle.getInt("actionPosition", -1)
|
actionPosition = bundle.getInt("actionPosition", -1)
|
||||||
bundle.getString("action")?.let { action = Action.instantiate(JSONObject(it)) }
|
bundle.getString("action")?.let { action = Action.instantiate(JSONObject(it)) }
|
||||||
}
|
}
|
||||||
|
onCreateViewGeneral()
|
||||||
dialog?.setCanceledOnTouchOutside(false)
|
|
||||||
return inflater.inflate(R.layout.automation_dialog_action, container, false)
|
return inflater.inflate(R.layout.automation_dialog_action, container, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,22 +35,13 @@ class EditActionDialog : DialogFragment() {
|
||||||
automation_editActionLayout.removeAllViews()
|
automation_editActionLayout.removeAllViews()
|
||||||
it.generateDialog(automation_editActionLayout)
|
it.generateDialog(automation_editActionLayout)
|
||||||
}
|
}
|
||||||
|
|
||||||
// OK button
|
|
||||||
ok.setOnClickListener {
|
|
||||||
dismiss()
|
|
||||||
action?.let {
|
|
||||||
RxBus.send(EventAutomationUpdateAction(it, actionPosition))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cancel button
|
|
||||||
cancel.setOnClickListener { dismiss() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStart() {
|
override fun submit(): Boolean {
|
||||||
super.onStart()
|
action?.let {
|
||||||
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
RxBus.send(EventAutomationUpdateAction(it, actionPosition))
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSaveInstanceState(bundle: Bundle) {
|
override fun onSaveInstanceState(bundle: Bundle) {
|
||||||
|
|
|
@ -4,9 +4,9 @@ import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.fragment.app.DialogFragment
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import info.nightscout.androidaps.R
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.dialogs.DialogFragmentWithDate
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||||
import info.nightscout.androidaps.plugins.general.automation.AutomationEvent
|
import info.nightscout.androidaps.plugins.general.automation.AutomationEvent
|
||||||
import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin
|
import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin
|
||||||
|
@ -17,9 +17,8 @@ import info.nightscout.androidaps.utils.ToastUtils
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
import io.reactivex.disposables.CompositeDisposable
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
import kotlinx.android.synthetic.main.automation_dialog_event.*
|
import kotlinx.android.synthetic.main.automation_dialog_event.*
|
||||||
import kotlinx.android.synthetic.main.okcancel.*
|
|
||||||
|
|
||||||
class EditEventDialog : DialogFragment() {
|
class EditEventDialog : DialogFragmentWithDate() {
|
||||||
|
|
||||||
private var actionListAdapter: ActionListAdapter? = null
|
private var actionListAdapter: ActionListAdapter? = null
|
||||||
private var event: AutomationEvent = AutomationEvent()
|
private var event: AutomationEvent = AutomationEvent()
|
||||||
|
@ -35,7 +34,7 @@ class EditEventDialog : DialogFragment() {
|
||||||
bundle.getString("event")?.let { event = AutomationEvent().fromJSON(it) }
|
bundle.getString("event")?.let { event = AutomationEvent().fromJSON(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
dialog?.setCanceledOnTouchOutside(false)
|
onCreateViewGeneral()
|
||||||
return inflater.inflate(R.layout.automation_dialog_event, container, false)
|
return inflater.inflate(R.layout.automation_dialog_event, container, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,39 +59,6 @@ class EditEventDialog : DialogFragment() {
|
||||||
|
|
||||||
automation_addAction.setOnClickListener { fragmentManager?.let { ChooseActionDialog().show(it, "ChooseActionDialog") } }
|
automation_addAction.setOnClickListener { fragmentManager?.let { ChooseActionDialog().show(it, "ChooseActionDialog") } }
|
||||||
|
|
||||||
// OK button
|
|
||||||
ok.setOnClickListener {
|
|
||||||
// check for title
|
|
||||||
val title = automation_inputEventTitle.text.toString()
|
|
||||||
if (title.isEmpty()) {
|
|
||||||
ToastUtils.showToastInUiThread(context, R.string.automation_missing_task_name)
|
|
||||||
return@setOnClickListener
|
|
||||||
}
|
|
||||||
event.title = title
|
|
||||||
// check for at least one trigger
|
|
||||||
val con = event.trigger as TriggerConnector
|
|
||||||
if (con.size() == 0) {
|
|
||||||
ToastUtils.showToastInUiThread(context, R.string.automation_missing_trigger)
|
|
||||||
return@setOnClickListener
|
|
||||||
}
|
|
||||||
// check for at least one action
|
|
||||||
if (event.actions.isEmpty()) {
|
|
||||||
ToastUtils.showToastInUiThread(context, R.string.automation_missing_action)
|
|
||||||
return@setOnClickListener
|
|
||||||
}
|
|
||||||
// store
|
|
||||||
if (position == -1)
|
|
||||||
AutomationPlugin.automationEvents.add(event)
|
|
||||||
else
|
|
||||||
AutomationPlugin.automationEvents[position] = event
|
|
||||||
|
|
||||||
dismiss()
|
|
||||||
RxBus.send(EventAutomationDataChanged())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cancel button
|
|
||||||
cancel.setOnClickListener { dismiss() }
|
|
||||||
|
|
||||||
showPreconditions()
|
showPreconditions()
|
||||||
|
|
||||||
disposable.add(RxBus
|
disposable.add(RxBus
|
||||||
|
@ -137,9 +103,33 @@ class EditEventDialog : DialogFragment() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStart() {
|
override fun submit() : Boolean{
|
||||||
super.onStart()
|
// check for title
|
||||||
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
val title = automation_inputEventTitle.text.toString()
|
||||||
|
if (title.isEmpty()) {
|
||||||
|
ToastUtils.showToastInUiThread(context, R.string.automation_missing_task_name)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
event.title = title
|
||||||
|
// check for at least one trigger
|
||||||
|
val con = event.trigger as TriggerConnector
|
||||||
|
if (con.size() == 0) {
|
||||||
|
ToastUtils.showToastInUiThread(context, R.string.automation_missing_trigger)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
// check for at least one action
|
||||||
|
if (event.actions.isEmpty()) {
|
||||||
|
ToastUtils.showToastInUiThread(context, R.string.automation_missing_action)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
// store
|
||||||
|
if (position == -1)
|
||||||
|
AutomationPlugin.automationEvents.add(event)
|
||||||
|
else
|
||||||
|
AutomationPlugin.automationEvents[position] = event
|
||||||
|
|
||||||
|
RxBus.send(EventAutomationDataChanged())
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
|
@ -147,10 +137,10 @@ class EditEventDialog : DialogFragment() {
|
||||||
disposable.clear()
|
disposable.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSaveInstanceState(bundle: Bundle) {
|
override fun onSaveInstanceState(savedInstanceState: Bundle) {
|
||||||
super.onSaveInstanceState(bundle)
|
super.onSaveInstanceState(savedInstanceState)
|
||||||
bundle.putString("event", event.toJSON())
|
savedInstanceState.putString("event", event.toJSON())
|
||||||
bundle.putInt("position", position)
|
savedInstanceState.putInt("position", position)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showPreconditions() {
|
private fun showPreconditions() {
|
||||||
|
@ -164,5 +154,4 @@ class EditEventDialog : DialogFragment() {
|
||||||
automation_forcedTriggerDescriptionLabel.visibility = View.GONE
|
automation_forcedTriggerDescriptionLabel.visibility = View.GONE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,15 +4,14 @@ import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.fragment.app.DialogFragment
|
|
||||||
import info.nightscout.androidaps.R
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.dialogs.DialogFragmentWithDate
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||||
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateTrigger
|
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateTrigger
|
||||||
import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger
|
import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger
|
||||||
import kotlinx.android.synthetic.main.automation_dialog_edit_trigger.*
|
import kotlinx.android.synthetic.main.automation_dialog_edit_trigger.*
|
||||||
import kotlinx.android.synthetic.main.okcancel.*
|
|
||||||
|
|
||||||
class EditTriggerDialog : DialogFragment() {
|
class EditTriggerDialog : DialogFragmentWithDate() {
|
||||||
|
|
||||||
private var trigger: Trigger? = null
|
private var trigger: Trigger? = null
|
||||||
|
|
||||||
|
@ -23,7 +22,7 @@ class EditTriggerDialog : DialogFragment() {
|
||||||
bundle.getString("trigger")?.let { trigger = Trigger.instantiate(it) }
|
bundle.getString("trigger")?.let { trigger = Trigger.instantiate(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
dialog?.setCanceledOnTouchOutside(false)
|
onCreateViewGeneral()
|
||||||
return inflater.inflate(R.layout.automation_dialog_edit_trigger, container, false)
|
return inflater.inflate(R.layout.automation_dialog_edit_trigger, container, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,24 +31,15 @@ class EditTriggerDialog : DialogFragment() {
|
||||||
|
|
||||||
// display root trigger
|
// display root trigger
|
||||||
trigger?.generateDialog(automation_layoutTrigger, fragmentManager)
|
trigger?.generateDialog(automation_layoutTrigger, fragmentManager)
|
||||||
|
|
||||||
// OK button
|
|
||||||
ok.setOnClickListener {
|
|
||||||
dismiss()
|
|
||||||
trigger?.let { trigger -> RxBus.send(EventAutomationUpdateTrigger(trigger)) }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cancel button
|
|
||||||
cancel.setOnClickListener { dismiss() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStart() {
|
override fun submit():Boolean {
|
||||||
super.onStart()
|
trigger?.let { trigger -> RxBus.send(EventAutomationUpdateTrigger(trigger)) }
|
||||||
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSaveInstanceState(bundle: Bundle) {
|
override fun onSaveInstanceState(savedInstanceState: Bundle) {
|
||||||
super.onSaveInstanceState(bundle)
|
super.onSaveInstanceState(savedInstanceState)
|
||||||
trigger?.let { bundle.putString("trigger", it.toJSON()) }
|
trigger?.let { savedInstanceState.putString("trigger", it.toJSON()) }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -75,7 +75,7 @@ public class TriggerListAdapter {
|
||||||
|
|
||||||
private Spinner createSpinner() {
|
private Spinner createSpinner() {
|
||||||
Spinner spinner = new Spinner(mContext);
|
Spinner spinner = new Spinner(mContext);
|
||||||
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<>(mContext, android.R.layout.simple_spinner_item, TriggerConnector.Type.labels());
|
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<>(mContext, R.layout.spinner_centered, TriggerConnector.Type.labels());
|
||||||
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||||
spinner.setAdapter(spinnerArrayAdapter);
|
spinner.setAdapter(spinnerArrayAdapter);
|
||||||
return spinner;
|
return spinner;
|
||||||
|
|
|
@ -87,7 +87,7 @@ public class Comparator extends Element {
|
||||||
@Override
|
@Override
|
||||||
public void addToLayout(LinearLayout root) {
|
public void addToLayout(LinearLayout root) {
|
||||||
Spinner spinner = new Spinner(root.getContext());
|
Spinner spinner = new Spinner(root.getContext());
|
||||||
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<>(root.getContext(), android.R.layout.simple_spinner_item, Compare.labels());
|
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<>(root.getContext(), R.layout.spinner_centered, Compare.labels());
|
||||||
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||||
spinner.setAdapter(spinnerArrayAdapter);
|
spinner.setAdapter(spinnerArrayAdapter);
|
||||||
LinearLayout.LayoutParams spinnerParams = new LinearLayout.LayoutParams(
|
LinearLayout.LayoutParams spinnerParams = new LinearLayout.LayoutParams(
|
||||||
|
|
|
@ -54,7 +54,7 @@ public class ComparatorExists extends Element {
|
||||||
@Override
|
@Override
|
||||||
public void addToLayout(LinearLayout root) {
|
public void addToLayout(LinearLayout root) {
|
||||||
Spinner spinner = new Spinner(root.getContext());
|
Spinner spinner = new Spinner(root.getContext());
|
||||||
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<>(root.getContext(), android.R.layout.simple_spinner_item, Compare.labels());
|
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<>(root.getContext(), R.layout.spinner_centered, Compare.labels());
|
||||||
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||||
spinner.setAdapter(spinnerArrayAdapter);
|
spinner.setAdapter(spinnerArrayAdapter);
|
||||||
LinearLayout.LayoutParams spinnerParams = new LinearLayout.LayoutParams(
|
LinearLayout.LayoutParams spinnerParams = new LinearLayout.LayoutParams(
|
||||||
|
|
|
@ -87,7 +87,7 @@ public class InputDelta extends Element {
|
||||||
@Override
|
@Override
|
||||||
public void addToLayout(LinearLayout root) {
|
public void addToLayout(LinearLayout root) {
|
||||||
Spinner spinner = new Spinner(root.getContext());
|
Spinner spinner = new Spinner(root.getContext());
|
||||||
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<>(root.getContext(), android.R.layout.simple_spinner_item, DeltaType.labels());
|
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<>(root.getContext(), R.layout.spinner_centered, DeltaType.labels());
|
||||||
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||||
spinner.setAdapter(spinnerArrayAdapter);
|
spinner.setAdapter(spinnerArrayAdapter);
|
||||||
LinearLayout.LayoutParams spinnerParams = new LinearLayout.LayoutParams(
|
LinearLayout.LayoutParams spinnerParams = new LinearLayout.LayoutParams(
|
||||||
|
|
|
@ -0,0 +1,107 @@
|
||||||
|
package info.nightscout.androidaps.plugins.general.automation.elements;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.AdapterView;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.Spinner;
|
||||||
|
|
||||||
|
import androidx.annotation.StringRes;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.MainApp;
|
||||||
|
import info.nightscout.androidaps.R;
|
||||||
|
|
||||||
|
public class InputLocationMode extends Element {
|
||||||
|
|
||||||
|
public enum Mode {
|
||||||
|
INSIDE,
|
||||||
|
OUTSIDE,
|
||||||
|
GOING_IN,
|
||||||
|
GOING_OUT;
|
||||||
|
|
||||||
|
public @StringRes
|
||||||
|
int getStringRes() {
|
||||||
|
switch (this) {
|
||||||
|
case INSIDE:
|
||||||
|
return R.string.location_inside;
|
||||||
|
case OUTSIDE:
|
||||||
|
return R.string.location_outside;
|
||||||
|
case GOING_IN:
|
||||||
|
return R.string.location_going_in;
|
||||||
|
case GOING_OUT:
|
||||||
|
return R.string.location_going_out;
|
||||||
|
default:
|
||||||
|
return R.string.unknown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<String> labels() {
|
||||||
|
List<String> list = new ArrayList<>();
|
||||||
|
for (Mode c : Mode.values()) {
|
||||||
|
list.add(MainApp.gs(c.getStringRes()));
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mode fromString(String wanted){
|
||||||
|
for (Mode c : Mode.values()) {
|
||||||
|
if(c.toString() == wanted)
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Mode mode;
|
||||||
|
|
||||||
|
public InputLocationMode() {
|
||||||
|
super();
|
||||||
|
mode = Mode.INSIDE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InputLocationMode(InputLocationMode another) {
|
||||||
|
super();
|
||||||
|
this.mode = another.mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addToLayout(LinearLayout root) {
|
||||||
|
ArrayAdapter<String> adapter = new ArrayAdapter<>(root.getContext(),
|
||||||
|
R.layout.spinner_centered, Mode.labels());
|
||||||
|
Spinner spinner = new Spinner(root.getContext());
|
||||||
|
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||||
|
spinner.setAdapter(adapter);
|
||||||
|
LinearLayout.LayoutParams spinnerParams = new LinearLayout.LayoutParams(
|
||||||
|
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||||
|
LinearLayout.LayoutParams.WRAP_CONTENT
|
||||||
|
);
|
||||||
|
spinnerParams.setMargins(0, MainApp.dpToPx(4), 0, MainApp.dpToPx(4));
|
||||||
|
spinner.setLayoutParams(spinnerParams);
|
||||||
|
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||||
|
@Override
|
||||||
|
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||||
|
setValue(Mode.values()[position]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNothingSelected(AdapterView<?> parent) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
spinner.setSelection(this.getValue().ordinal());
|
||||||
|
root.addView(spinner);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mode getValue() {
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InputLocationMode setValue(Mode mode) {
|
||||||
|
this.mode = mode;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -19,6 +19,7 @@ import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.logging.L;
|
import info.nightscout.androidaps.logging.L;
|
||||||
import info.nightscout.androidaps.plugins.general.automation.elements.InputButton;
|
import info.nightscout.androidaps.plugins.general.automation.elements.InputButton;
|
||||||
import info.nightscout.androidaps.plugins.general.automation.elements.InputDouble;
|
import info.nightscout.androidaps.plugins.general.automation.elements.InputDouble;
|
||||||
|
import info.nightscout.androidaps.plugins.general.automation.elements.InputLocationMode;
|
||||||
import info.nightscout.androidaps.plugins.general.automation.elements.InputString;
|
import info.nightscout.androidaps.plugins.general.automation.elements.InputString;
|
||||||
import info.nightscout.androidaps.plugins.general.automation.elements.LabelWithElement;
|
import info.nightscout.androidaps.plugins.general.automation.elements.LabelWithElement;
|
||||||
import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder;
|
import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder;
|
||||||
|
@ -28,12 +29,17 @@ import info.nightscout.androidaps.utils.DateUtil;
|
||||||
import info.nightscout.androidaps.utils.JsonHelper;
|
import info.nightscout.androidaps.utils.JsonHelper;
|
||||||
import info.nightscout.androidaps.utils.T;
|
import info.nightscout.androidaps.utils.T;
|
||||||
|
|
||||||
|
import static info.nightscout.androidaps.plugins.general.automation.elements.InputLocationMode.Mode.*;
|
||||||
|
|
||||||
public class TriggerLocation extends Trigger {
|
public class TriggerLocation extends Trigger {
|
||||||
private static Logger log = LoggerFactory.getLogger(L.AUTOMATION);
|
private static Logger log = LoggerFactory.getLogger(L.AUTOMATION);
|
||||||
|
|
||||||
InputDouble latitude = new InputDouble(0d, -90d, +90d, 0.000001d, new DecimalFormat("0.000000"));
|
InputDouble latitude = new InputDouble(0d, -90d, +90d, 0.000001d, new DecimalFormat("0.000000"));
|
||||||
InputDouble longitude = new InputDouble(0d, -180d, +180d, 0.000001d, new DecimalFormat("0.000000"));
|
InputDouble longitude = new InputDouble(0d, -180d, +180d, 0.000001d, new DecimalFormat("0.000000"));
|
||||||
InputDouble distance = new InputDouble(200d, 0, 100000, 10d, new DecimalFormat("0"));
|
InputDouble distance = new InputDouble(200d, 0, 100000, 10d, new DecimalFormat("0"));
|
||||||
|
InputLocationMode modeSelected = new InputLocationMode();
|
||||||
|
InputLocationMode.Mode lastMode = INSIDE;
|
||||||
|
|
||||||
InputString name = new InputString();
|
InputString name = new InputString();
|
||||||
|
|
||||||
private Runnable buttonAction = () -> {
|
private Runnable buttonAction = () -> {
|
||||||
|
@ -54,13 +60,16 @@ public class TriggerLocation extends Trigger {
|
||||||
latitude = new InputDouble(triggerLocation.latitude);
|
latitude = new InputDouble(triggerLocation.latitude);
|
||||||
longitude = new InputDouble(triggerLocation.longitude);
|
longitude = new InputDouble(triggerLocation.longitude);
|
||||||
distance = new InputDouble(triggerLocation.distance);
|
distance = new InputDouble(triggerLocation.distance);
|
||||||
|
modeSelected = new InputLocationMode(triggerLocation.modeSelected);
|
||||||
|
if (modeSelected.getValue() == GOING_OUT)
|
||||||
|
lastMode = OUTSIDE;
|
||||||
lastRun = triggerLocation.lastRun;
|
lastRun = triggerLocation.lastRun;
|
||||||
name = triggerLocation.name;
|
name = triggerLocation.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized boolean shouldRun() {
|
public synchronized boolean shouldRun() {
|
||||||
Location location = LocationService.getLastLocation();
|
Location location = this.getCurrentLocation();
|
||||||
if (location == null)
|
if (location == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -72,11 +81,20 @@ public class TriggerLocation extends Trigger {
|
||||||
a.setLongitude(longitude.getValue());
|
a.setLongitude(longitude.getValue());
|
||||||
double calculatedDistance = location.distanceTo(a);
|
double calculatedDistance = location.distanceTo(a);
|
||||||
|
|
||||||
if (calculatedDistance < distance.getValue()) {
|
// log.debug("Moded(current/last/wanted): "+(currentMode(calculatedDistance))+"/"+lastMode+"/"+modeSelected.getValue());
|
||||||
|
// log.debug("Distance: "+calculatedDistance + "("+distance.getValue()+")");
|
||||||
|
|
||||||
|
if ((modeSelected.getValue() == INSIDE) && (calculatedDistance <= distance.getValue()) ||
|
||||||
|
((modeSelected.getValue() == OUTSIDE) && (calculatedDistance > distance.getValue())) ||
|
||||||
|
((modeSelected.getValue() == GOING_IN) && (calculatedDistance <= distance.getValue()) && (lastMode == OUTSIDE)) ||
|
||||||
|
((modeSelected.getValue() == GOING_OUT) && (calculatedDistance > distance.getValue()) && (lastMode == INSIDE))
|
||||||
|
) {
|
||||||
if (L.isEnabled(L.AUTOMATION))
|
if (L.isEnabled(L.AUTOMATION))
|
||||||
log.debug("Ready for execution: " + friendlyDescription());
|
log.debug("Ready for execution: " + friendlyDescription());
|
||||||
|
lastMode = currentMode(calculatedDistance);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
lastMode = currentMode(calculatedDistance); // current mode will be last mode for the next check
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,6 +108,7 @@ public class TriggerLocation extends Trigger {
|
||||||
data.put("longitude", longitude.getValue());
|
data.put("longitude", longitude.getValue());
|
||||||
data.put("distance", distance.getValue());
|
data.put("distance", distance.getValue());
|
||||||
data.put("name", name.getValue());
|
data.put("name", name.getValue());
|
||||||
|
data.put("mode", modeSelected.getValue());
|
||||||
data.put("lastRun", lastRun);
|
data.put("lastRun", lastRun);
|
||||||
o.put("data", data);
|
o.put("data", data);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
|
@ -106,7 +125,10 @@ public class TriggerLocation extends Trigger {
|
||||||
longitude.setValue(JsonHelper.safeGetDouble(d, "longitude"));
|
longitude.setValue(JsonHelper.safeGetDouble(d, "longitude"));
|
||||||
distance.setValue(JsonHelper.safeGetDouble(d, "distance"));
|
distance.setValue(JsonHelper.safeGetDouble(d, "distance"));
|
||||||
name.setValue(JsonHelper.safeGetString(d, "name"));
|
name.setValue(JsonHelper.safeGetString(d, "name"));
|
||||||
lastRun = JsonHelper.safeGetLong(d, "lastRun");
|
modeSelected.setValue(InputLocationMode.Mode.valueOf(JsonHelper.safeGetString(d, "mode")));
|
||||||
|
if (modeSelected.getValue() == GOING_OUT)
|
||||||
|
lastMode = OUTSIDE;
|
||||||
|
lastRun = DateUtil.now(); // set lastRun to now to give the service 5 mins to get the location properly
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
|
@ -120,7 +142,7 @@ public class TriggerLocation extends Trigger {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String friendlyDescription() {
|
public String friendlyDescription() {
|
||||||
return MainApp.gs(R.string.locationis, name.getValue());
|
return MainApp.gs(R.string.locationis, MainApp.gs(modeSelected.getValue().getStringRes()), " " + name.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -154,6 +176,11 @@ public class TriggerLocation extends Trigger {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TriggerLocation setMode(InputLocationMode.Mode value) {
|
||||||
|
modeSelected.setValue(value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generateDialog(LinearLayout root, FragmentManager fragmentManager) {
|
public void generateDialog(LinearLayout root, FragmentManager fragmentManager) {
|
||||||
new LayoutBuilder()
|
new LayoutBuilder()
|
||||||
|
@ -162,7 +189,21 @@ public class TriggerLocation extends Trigger {
|
||||||
.add(new LabelWithElement(MainApp.gs(R.string.latitude_short), "", latitude))
|
.add(new LabelWithElement(MainApp.gs(R.string.latitude_short), "", latitude))
|
||||||
.add(new LabelWithElement(MainApp.gs(R.string.longitude_short), "", longitude))
|
.add(new LabelWithElement(MainApp.gs(R.string.longitude_short), "", longitude))
|
||||||
.add(new LabelWithElement(MainApp.gs(R.string.distance_short), "", distance))
|
.add(new LabelWithElement(MainApp.gs(R.string.distance_short), "", distance))
|
||||||
|
.add(new LabelWithElement(MainApp.gs(R.string.location_mode), "", modeSelected))
|
||||||
.add(new InputButton(MainApp.gs(R.string.currentlocation), buttonAction), LocationService.getLastLocation() != null)
|
.add(new InputButton(MainApp.gs(R.string.currentlocation), buttonAction), LocationService.getLastLocation() != null)
|
||||||
.build(root);
|
.build(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Method to return the actual mode based on the current distance
|
||||||
|
InputLocationMode.Mode currentMode(double currentDistance){
|
||||||
|
if ( currentDistance <= this.distance.getValue() )
|
||||||
|
return INSIDE;
|
||||||
|
else
|
||||||
|
return OUTSIDE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Location getCurrentLocation(){
|
||||||
|
return LocationService.getLastLocation();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,7 +93,7 @@ public class TriggerTempTarget extends Trigger {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int friendlyName() {
|
public int friendlyName() {
|
||||||
return R.string.temptarget;
|
return R.string.careportal_temporarytarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -124,7 +124,7 @@ public class TriggerTempTarget extends Trigger {
|
||||||
@Override
|
@Override
|
||||||
public void generateDialog(LinearLayout root, FragmentManager fragmentManager) {
|
public void generateDialog(LinearLayout root, FragmentManager fragmentManager) {
|
||||||
new LayoutBuilder()
|
new LayoutBuilder()
|
||||||
.add(new StaticLabel(R.string.temptarget))
|
.add(new StaticLabel(R.string.careportal_temporarytarget))
|
||||||
.add(comparator)
|
.add(comparator)
|
||||||
.build(root);
|
.build(root);
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,7 +149,7 @@ public class TriggerTimeRange extends Trigger {
|
||||||
|
|
||||||
public int getMinSinceMidnight(long time) {
|
public int getMinSinceMidnight(long time) {
|
||||||
// if passed argument is smaller than 1440 ( 24 h * 60 min ) that value is already converted
|
// if passed argument is smaller than 1440 ( 24 h * 60 min ) that value is already converted
|
||||||
if (0 < time && time < 1441)
|
if (0 <= time && time < 1441)
|
||||||
return (int) time;
|
return (int) time;
|
||||||
Calendar calendar = DateUtil.gregorianCalendar();
|
Calendar calendar = DateUtil.gregorianCalendar();
|
||||||
calendar.setTimeInMillis(time);
|
calendar.setTimeInMillis(time);
|
||||||
|
|
|
@ -63,7 +63,6 @@ public class CareportalFragment extends Fragment implements View.OnClickListener
|
||||||
public static final OptionsToShow TEMPBASALSTART = new OptionsToShow(R.id.careportal_tempbasalstart, R.string.careportal_tempbasalstart).date().bg().duration().percent().absolute();
|
public static final OptionsToShow TEMPBASALSTART = new OptionsToShow(R.id.careportal_tempbasalstart, R.string.careportal_tempbasalstart).date().bg().duration().percent().absolute();
|
||||||
public static final OptionsToShow TEMPBASALEND = new OptionsToShow(R.id.careportal_tempbasalend, R.string.careportal_tempbasalend).date().bg();
|
public static final OptionsToShow TEMPBASALEND = new OptionsToShow(R.id.careportal_tempbasalend, R.string.careportal_tempbasalend).date().bg();
|
||||||
public static final OptionsToShow PROFILESWITCH = new OptionsToShow(R.id.careportal_profileswitch, R.string.careportal_profileswitch).date().duration().profile();
|
public static final OptionsToShow PROFILESWITCH = new OptionsToShow(R.id.careportal_profileswitch, R.string.careportal_profileswitch).date().duration().profile();
|
||||||
public static final OptionsToShow PROFILESWITCHDIRECT = new OptionsToShow(R.id.careportal_profileswitch, R.string.careportal_profileswitch).duration().profile();
|
|
||||||
public static final OptionsToShow OPENAPSOFFLINE = new OptionsToShow(R.id.careportal_openapsoffline, R.string.careportal_openapsoffline).date().duration();
|
public static final OptionsToShow OPENAPSOFFLINE = new OptionsToShow(R.id.careportal_openapsoffline, R.string.careportal_openapsoffline).date().duration();
|
||||||
public static final OptionsToShow TEMPTARGET = new OptionsToShow(R.id.careportal_temporarytarget, R.string.careportal_temporarytarget).date().duration().tempTarget();
|
public static final OptionsToShow TEMPTARGET = new OptionsToShow(R.id.careportal_temporarytarget, R.string.careportal_temporarytarget).date().duration().tempTarget();
|
||||||
|
|
||||||
|
@ -180,7 +179,6 @@ public class CareportalFragment extends Fragment implements View.OnClickListener
|
||||||
newDialog.setOptions(NOTE, R.string.careportal_note);
|
newDialog.setOptions(NOTE, R.string.careportal_note);
|
||||||
break;
|
break;
|
||||||
case R.id.careportal_profileswitch:
|
case R.id.careportal_profileswitch:
|
||||||
PROFILESWITCH.executeProfileSwitch = false;
|
|
||||||
newDialog.setOptions(PROFILESWITCH, R.string.careportal_profileswitch);
|
newDialog.setOptions(PROFILESWITCH, R.string.careportal_profileswitch);
|
||||||
break;
|
break;
|
||||||
case R.id.careportal_pumpsitechange:
|
case R.id.careportal_pumpsitechange:
|
||||||
|
@ -202,7 +200,6 @@ public class CareportalFragment extends Fragment implements View.OnClickListener
|
||||||
newDialog.setOptions(OPENAPSOFFLINE, R.string.careportal_openapsoffline);
|
newDialog.setOptions(OPENAPSOFFLINE, R.string.careportal_openapsoffline);
|
||||||
break;
|
break;
|
||||||
case R.id.careportal_temporarytarget:
|
case R.id.careportal_temporarytarget:
|
||||||
TEMPTARGET.executeTempTarget = false;
|
|
||||||
newDialog.setOptions(TEMPTARGET, R.string.careportal_temporarytarget);
|
newDialog.setOptions(TEMPTARGET, R.string.careportal_temporarytarget);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -222,7 +219,7 @@ public class CareportalFragment extends Fragment implements View.OnClickListener
|
||||||
activity.runOnUiThread(
|
activity.runOnUiThread(
|
||||||
() -> {
|
() -> {
|
||||||
CareportalEvent careportalEvent;
|
CareportalEvent careportalEvent;
|
||||||
NSSettingsStatus nsSettings = new NSSettingsStatus().getInstance();
|
NSSettingsStatus nsSettings = NSSettingsStatus.getInstance();
|
||||||
|
|
||||||
double iageUrgent = nsSettings.getExtendedWarnValue("iage", "urgent", 96);
|
double iageUrgent = nsSettings.getExtendedWarnValue("iage", "urgent", 96);
|
||||||
double iageWarn = nsSettings.getExtendedWarnValue("iage", "warn", 72);
|
double iageWarn = nsSettings.getExtendedWarnValue("iage", "warn", 72);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package info.nightscout.androidaps.plugins.general.careportal;
|
package info.nightscout.androidaps.plugins.general.careportal;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.Config;
|
||||||
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.PluginDescription;
|
||||||
|
@ -22,10 +23,14 @@ public class CareportalPlugin extends PluginBase {
|
||||||
.fragmentClass(CareportalFragment.class.getName())
|
.fragmentClass(CareportalFragment.class.getName())
|
||||||
.pluginName(R.string.careportal)
|
.pluginName(R.string.careportal)
|
||||||
.shortName(R.string.careportal_shortname)
|
.shortName(R.string.careportal_shortname)
|
||||||
.visibleByDefault(true)
|
.visibleByDefault(Config.NSCLIENT)
|
||||||
.enableByDefault(true)
|
.enableByDefault(Config.NSCLIENT)
|
||||||
.description(R.string.description_careportal)
|
.description(R.string.description_careportal)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean specialEnableCondition() {
|
||||||
|
return Config.NSCLIENT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package info.nightscout.androidaps.plugins.general.careportal.Dialogs;
|
package info.nightscout.androidaps.plugins.general.careportal.Dialogs;
|
||||||
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
|
@ -9,6 +8,8 @@ import android.text.format.DateFormat;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.view.Window;
|
||||||
|
import android.view.WindowManager;
|
||||||
import android.widget.AdapterView;
|
import android.widget.AdapterView;
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
|
@ -18,7 +19,6 @@ import android.widget.RadioButton;
|
||||||
import android.widget.Spinner;
|
import android.widget.Spinner;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.appcompat.app.AlertDialog;
|
|
||||||
import androidx.appcompat.app.AppCompatDialogFragment;
|
import androidx.appcompat.app.AppCompatDialogFragment;
|
||||||
import androidx.fragment.app.DialogFragment;
|
import androidx.fragment.app.DialogFragment;
|
||||||
|
|
||||||
|
@ -45,8 +45,6 @@ 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.db.ProfileSwitch;
|
import info.nightscout.androidaps.db.ProfileSwitch;
|
||||||
import info.nightscout.androidaps.db.Source;
|
|
||||||
import info.nightscout.androidaps.db.TempTarget;
|
|
||||||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
|
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
|
||||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
|
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
|
||||||
import info.nightscout.androidaps.plugins.general.careportal.OptionsToShow;
|
import info.nightscout.androidaps.plugins.general.careportal.OptionsToShow;
|
||||||
|
@ -58,6 +56,7 @@ import info.nightscout.androidaps.utils.DefaultValueHelper;
|
||||||
import info.nightscout.androidaps.utils.HardLimits;
|
import info.nightscout.androidaps.utils.HardLimits;
|
||||||
import info.nightscout.androidaps.utils.JsonHelper;
|
import info.nightscout.androidaps.utils.JsonHelper;
|
||||||
import info.nightscout.androidaps.utils.NumberPicker;
|
import info.nightscout.androidaps.utils.NumberPicker;
|
||||||
|
import info.nightscout.androidaps.utils.OKDialog;
|
||||||
import info.nightscout.androidaps.utils.SP;
|
import info.nightscout.androidaps.utils.SP;
|
||||||
import info.nightscout.androidaps.utils.SafeParse;
|
import info.nightscout.androidaps.utils.SafeParse;
|
||||||
import info.nightscout.androidaps.utils.Translator;
|
import info.nightscout.androidaps.utils.Translator;
|
||||||
|
@ -68,7 +67,7 @@ public class NewNSTreatmentDialog extends AppCompatDialogFragment implements Vie
|
||||||
private static OptionsToShow options;
|
private static OptionsToShow options;
|
||||||
private static String event;
|
private static String event;
|
||||||
|
|
||||||
Profile profile;
|
private Profile profile;
|
||||||
public ProfileStore profileStore;
|
public ProfileStore profileStore;
|
||||||
|
|
||||||
TextView eventTypeText;
|
TextView eventTypeText;
|
||||||
|
@ -105,9 +104,10 @@ public class NewNSTreatmentDialog extends AppCompatDialogFragment implements Vie
|
||||||
|
|
||||||
private static Integer seconds = null;
|
private static Integer seconds = null;
|
||||||
|
|
||||||
public void setOptions(OptionsToShow options, int event) {
|
public NewNSTreatmentDialog setOptions(OptionsToShow options, int event) {
|
||||||
this.options = options;
|
this.options = options;
|
||||||
this.event = MainApp.gs(event);
|
this.event = MainApp.gs(event);
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NewNSTreatmentDialog() {
|
public NewNSTreatmentDialog() {
|
||||||
|
@ -122,7 +122,10 @@ public class NewNSTreatmentDialog extends AppCompatDialogFragment implements Vie
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
if (options == null) return null;
|
if (options == null) return null;
|
||||||
getDialog().setTitle(MainApp.gs(options.eventName));
|
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
|
||||||
|
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
|
||||||
|
setCancelable(true);
|
||||||
|
getDialog().setCanceledOnTouchOutside(false);
|
||||||
setStyle(DialogFragment.STYLE_NORMAL, getTheme());
|
setStyle(DialogFragment.STYLE_NORMAL, getTheme());
|
||||||
View view = inflater.inflate(R.layout.careportal_newnstreatment_dialog, container, false);
|
View view = inflater.inflate(R.layout.careportal_newnstreatment_dialog, container, false);
|
||||||
|
|
||||||
|
@ -200,16 +203,15 @@ public class NewNSTreatmentDialog extends AppCompatDialogFragment implements Vie
|
||||||
boolean erase = false;
|
boolean erase = false;
|
||||||
|
|
||||||
String units = ProfileFunctions.getSystemUnits();
|
String units = ProfileFunctions.getSystemUnits();
|
||||||
DefaultValueHelper helper = new DefaultValueHelper();
|
|
||||||
if (MainApp.gs(R.string.eatingsoon).equals(reasonList.get(position))) {
|
if (MainApp.gs(R.string.eatingsoon).equals(reasonList.get(position))) {
|
||||||
defaultDuration = helper.determineEatingSoonTTDuration();
|
defaultDuration = DefaultValueHelper.determineEatingSoonTTDuration();
|
||||||
defaultTarget = helper.determineEatingSoonTT();
|
defaultTarget = DefaultValueHelper.determineEatingSoonTT();
|
||||||
} else if (MainApp.gs(R.string.activity).equals(reasonList.get(position))) {
|
} else if (MainApp.gs(R.string.activity).equals(reasonList.get(position))) {
|
||||||
defaultDuration = helper.determineActivityTTDuration();
|
defaultDuration = DefaultValueHelper.determineActivityTTDuration();
|
||||||
defaultTarget = helper.determineActivityTT();
|
defaultTarget = DefaultValueHelper.determineActivityTT();
|
||||||
} else if (MainApp.gs(R.string.hypo).equals(reasonList.get(position))) {
|
} else if (MainApp.gs(R.string.hypo).equals(reasonList.get(position))) {
|
||||||
defaultDuration = helper.determineHypoTTDuration();
|
defaultDuration = DefaultValueHelper.determineHypoTTDuration();
|
||||||
defaultTarget = helper.determineHypoTT();
|
defaultTarget = DefaultValueHelper.determineHypoTT();
|
||||||
} else if (editDuration.getValue() != 0) {
|
} else if (editDuration.getValue() != 0) {
|
||||||
defaultDuration = editDuration.getValue();
|
defaultDuration = editDuration.getValue();
|
||||||
} else {
|
} else {
|
||||||
|
@ -394,6 +396,13 @@ public class NewNSTreatmentDialog extends AppCompatDialogFragment implements Vie
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
getDialog().getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
Calendar calendar = Calendar.getInstance();
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
@ -585,12 +594,12 @@ public class NewNSTreatmentDialog extends AppCompatDialogFragment implements Vie
|
||||||
|
|
||||||
String buildConfirmText(JSONObject data) {
|
String buildConfirmText(JSONObject data) {
|
||||||
String ret = "";
|
String ret = "";
|
||||||
if (data.has("eventType")) {
|
// if (data.has("eventType")) {
|
||||||
ret += MainApp.gs(R.string.careportal_newnstreatment_eventtype);
|
// ret += MainApp.gs(R.string.careportal_newnstreatment_eventtype);
|
||||||
ret += ": ";
|
// ret += ": ";
|
||||||
ret += Translator.translate(JsonHelper.safeGetString(data, "eventType", ""));
|
// ret += Translator.translate(JsonHelper.safeGetString(data, "eventType", ""));
|
||||||
ret += "\n";
|
// ret += "\n";
|
||||||
}
|
// }
|
||||||
if (data.has("glucose")) {
|
if (data.has("glucose")) {
|
||||||
ret += MainApp.gs(R.string.treatments_wizard_bg_label);
|
ret += MainApp.gs(R.string.treatments_wizard_bg_label);
|
||||||
ret += ": ";
|
ret += ": ";
|
||||||
|
@ -672,7 +681,7 @@ public class NewNSTreatmentDialog extends AppCompatDialogFragment implements Vie
|
||||||
ret += "\n";
|
ret += "\n";
|
||||||
}
|
}
|
||||||
if (data.has("created_at")) {
|
if (data.has("created_at")) {
|
||||||
ret += MainApp.gs(R.string.careportal_newnstreatment_eventtime_label);
|
ret += MainApp.gs(R.string.event_time_label);
|
||||||
ret += ": ";
|
ret += ": ";
|
||||||
ret += eventTime.toLocaleString();
|
ret += eventTime.toLocaleString();
|
||||||
ret += "\n";
|
ret += "\n";
|
||||||
|
@ -687,61 +696,25 @@ public class NewNSTreatmentDialog extends AppCompatDialogFragment implements Vie
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void confirmNSTreatmentCreation() {
|
private void confirmNSTreatmentCreation() {
|
||||||
Context context = getContext();
|
final JSONObject data = gatherData();
|
||||||
if (context != null) {
|
OKDialog.showConfirmation(getContext(), Translator.translate(JsonHelper.safeGetString(data, "eventType", MainApp.gs(R.string.overview_treatment_label))), buildConfirmText(data), () -> createNSTreatment(data));
|
||||||
final JSONObject data = gatherData();
|
|
||||||
final String confirmText = buildConfirmText(data);
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
|
||||||
builder.setTitle(MainApp.gs(R.string.confirmation));
|
|
||||||
builder.setMessage(confirmText);
|
|
||||||
builder.setPositiveButton(MainApp.gs(R.string.ok), (dialog, id) -> createNSTreatment(data));
|
|
||||||
builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
|
|
||||||
builder.show();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void createNSTreatment(JSONObject data) {
|
void createNSTreatment(JSONObject data) {
|
||||||
if (options.executeProfileSwitch) {
|
if (JsonHelper.safeGetString(data, "eventType", "").equals(CareportalEvent.PROFILESWITCH)) {
|
||||||
if (data.has("profile")) {
|
ProfileSwitch profileSwitch = ProfileFunctions.prepareProfileSwitch(
|
||||||
ProfileFunctions.doProfileSwitch(profileStore, JsonHelper.safeGetString(data, "profile"), JsonHelper.safeGetInt(data, "duration"), JsonHelper.safeGetInt(data, "percentage"), JsonHelper.safeGetInt(data, "timeshift"));
|
profileStore,
|
||||||
}
|
JsonHelper.safeGetString(data, "profile"),
|
||||||
} else if (options.executeTempTarget) {
|
JsonHelper.safeGetInt(data, "duration"),
|
||||||
final int duration = JsonHelper.safeGetInt(data, "duration");
|
JsonHelper.safeGetInt(data, "percentage"),
|
||||||
final double targetBottom = JsonHelper.safeGetDouble(data, "targetBottom");
|
JsonHelper.safeGetInt(data, "timeshift"),
|
||||||
final double targetTop = JsonHelper.safeGetDouble(data, "targetTop");
|
eventTime.getTime()
|
||||||
final String reason = JsonHelper.safeGetString(data, "reason", "");
|
);
|
||||||
if ((targetBottom != 0d && targetTop != 0d) || duration == 0) {
|
NSUpload.uploadProfileSwitch(profileSwitch);
|
||||||
TempTarget tempTarget = new TempTarget()
|
|
||||||
.date(eventTime.getTime())
|
|
||||||
.duration(duration)
|
|
||||||
.reason(reason)
|
|
||||||
.source(Source.USER);
|
|
||||||
if (tempTarget.durationInMinutes != 0) {
|
|
||||||
tempTarget.low(Profile.toMgdl(targetBottom, ProfileFunctions.getSystemUnits()))
|
|
||||||
.high(Profile.toMgdl(targetTop, ProfileFunctions.getSystemUnits()));
|
|
||||||
} else {
|
|
||||||
tempTarget.low(0).high(0);
|
|
||||||
}
|
|
||||||
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget);
|
|
||||||
}
|
|
||||||
if (duration == 10)
|
|
||||||
SP.putBoolean(R.string.key_objectiveusetemptarget, true);
|
|
||||||
} else {
|
} else {
|
||||||
if (JsonHelper.safeGetString(data, "eventType").equals(CareportalEvent.PROFILESWITCH)) {
|
NSUpload.uploadCareportalEntryToNS(data);
|
||||||
ProfileSwitch profileSwitch = ProfileFunctions.prepareProfileSwitch(
|
|
||||||
profileStore,
|
|
||||||
JsonHelper.safeGetString(data, "profile"),
|
|
||||||
JsonHelper.safeGetInt(data, "duration"),
|
|
||||||
JsonHelper.safeGetInt(data, "percentage"),
|
|
||||||
JsonHelper.safeGetInt(data, "timeshift"),
|
|
||||||
eventTime.getTime()
|
|
||||||
);
|
|
||||||
NSUpload.uploadProfileSwitch(profileSwitch);
|
|
||||||
} else {
|
|
||||||
NSUpload.uploadCareportalEntryToNS(data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,10 +19,6 @@ public class OptionsToShow {
|
||||||
public boolean split;
|
public boolean split;
|
||||||
public boolean tempTarget;
|
public boolean tempTarget;
|
||||||
|
|
||||||
// perform direct actions
|
|
||||||
public boolean executeProfileSwitch = false;
|
|
||||||
public boolean executeTempTarget = false;
|
|
||||||
|
|
||||||
public OptionsToShow(int eventType, int eventName) {
|
public OptionsToShow(int eventType, int eventName) {
|
||||||
this.eventType = eventType;
|
this.eventType = eventType;
|
||||||
this.eventName = eventName;
|
this.eventName = eventName;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package info.nightscout.androidaps.plugins.general.food;
|
package info.nightscout.androidaps.plugins.general.food;
|
||||||
|
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
|
@ -14,14 +13,11 @@ import android.widget.EditText;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
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;
|
||||||
|
@ -33,6 +29,7 @@ import info.nightscout.androidaps.events.EventFoodDatabaseChanged;
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBus;
|
import info.nightscout.androidaps.plugins.bus.RxBus;
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
|
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
|
||||||
import info.nightscout.androidaps.utils.FabricPrivacy;
|
import info.nightscout.androidaps.utils.FabricPrivacy;
|
||||||
|
import info.nightscout.androidaps.utils.OKDialog;
|
||||||
import info.nightscout.androidaps.utils.SpinnerHelper;
|
import info.nightscout.androidaps.utils.SpinnerHelper;
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
import io.reactivex.disposables.CompositeDisposable;
|
import io.reactivex.disposables.CompositeDisposable;
|
||||||
|
@ -42,43 +39,36 @@ import io.reactivex.disposables.CompositeDisposable;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class FoodFragment extends Fragment {
|
public class FoodFragment extends Fragment {
|
||||||
private static Logger log = LoggerFactory.getLogger(FoodFragment.class);
|
|
||||||
private CompositeDisposable disposable = new CompositeDisposable();
|
private CompositeDisposable disposable = new CompositeDisposable();
|
||||||
|
|
||||||
EditText filter;
|
private EditText filter;
|
||||||
ImageView clearFilter;
|
private SpinnerHelper category;
|
||||||
SpinnerHelper category;
|
private SpinnerHelper subcategory;
|
||||||
SpinnerHelper subcategory;
|
private RecyclerView recyclerView;
|
||||||
RecyclerView recyclerView;
|
|
||||||
|
|
||||||
List<Food> unfiltered;
|
private List<Food> unfiltered;
|
||||||
List<Food> filtered;
|
private List<Food> filtered;
|
||||||
ArrayList<CharSequence> categories;
|
|
||||||
ArrayList<CharSequence> subcategories;
|
|
||||||
|
|
||||||
final String EMPTY = MainApp.gs(R.string.none);
|
private final String EMPTY = MainApp.gs(R.string.none);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
View view = inflater.inflate(R.layout.food_fragment, container, false);
|
View view = inflater.inflate(R.layout.food_fragment, container, false);
|
||||||
filter = (EditText) view.findViewById(R.id.food_filter);
|
filter = view.findViewById(R.id.food_filter);
|
||||||
clearFilter = (ImageView) view.findViewById(R.id.food_clearfilter);
|
ImageView clearFilter = view.findViewById(R.id.food_clearfilter);
|
||||||
category = new SpinnerHelper(view.findViewById(R.id.food_category));
|
category = new SpinnerHelper(view.findViewById(R.id.food_category));
|
||||||
subcategory = new SpinnerHelper(view.findViewById(R.id.food_subcategory));
|
subcategory = new SpinnerHelper(view.findViewById(R.id.food_subcategory));
|
||||||
recyclerView = (RecyclerView) view.findViewById(R.id.food_recyclerview);
|
recyclerView = view.findViewById(R.id.food_recyclerview);
|
||||||
recyclerView.setHasFixedSize(true);
|
recyclerView.setHasFixedSize(true);
|
||||||
LinearLayoutManager llm = new LinearLayoutManager(view.getContext());
|
LinearLayoutManager llm = new LinearLayoutManager(view.getContext());
|
||||||
recyclerView.setLayoutManager(llm);
|
recyclerView.setLayoutManager(llm);
|
||||||
|
|
||||||
clearFilter.setOnClickListener(new View.OnClickListener() {
|
clearFilter.setOnClickListener(v -> {
|
||||||
@Override
|
filter.setText("");
|
||||||
public void onClick(View v) {
|
category.setSelection(0);
|
||||||
filter.setText("");
|
subcategory.setSelection(0);
|
||||||
category.setSelection(0);
|
filterData();
|
||||||
subcategory.setSelection(0);
|
|
||||||
filterData();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
category.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
category.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||||
|
@ -149,11 +139,11 @@ public class FoodFragment extends Fragment {
|
||||||
disposable.clear();
|
disposable.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadData() {
|
private void loadData() {
|
||||||
unfiltered = FoodPlugin.getPlugin().getService().getFoodData();
|
unfiltered = FoodPlugin.getPlugin().getService().getFoodData();
|
||||||
}
|
}
|
||||||
|
|
||||||
void fillCategories() {
|
private void fillCategories() {
|
||||||
Set<CharSequence> catSet = new HashSet<>();
|
Set<CharSequence> catSet = new HashSet<>();
|
||||||
|
|
||||||
for (Food f : unfiltered) {
|
for (Food f : unfiltered) {
|
||||||
|
@ -162,7 +152,7 @@ public class FoodFragment extends Fragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
// make it unique
|
// make it unique
|
||||||
categories = new ArrayList<>(catSet);
|
ArrayList<CharSequence> categories = new ArrayList<>(catSet);
|
||||||
categories.add(0, MainApp.gs(R.string.none));
|
categories.add(0, MainApp.gs(R.string.none));
|
||||||
|
|
||||||
ArrayAdapter<CharSequence> adapterCategories = new ArrayAdapter<>(getContext(),
|
ArrayAdapter<CharSequence> adapterCategories = new ArrayAdapter<>(getContext(),
|
||||||
|
@ -170,7 +160,7 @@ public class FoodFragment extends Fragment {
|
||||||
category.setAdapter(adapterCategories);
|
category.setAdapter(adapterCategories);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fillSubcategories() {
|
private void fillSubcategories() {
|
||||||
String categoryFilter = category.getSelectedItem().toString();
|
String categoryFilter = category.getSelectedItem().toString();
|
||||||
|
|
||||||
Set<CharSequence> subCatSet = new HashSet<>();
|
Set<CharSequence> subCatSet = new HashSet<>();
|
||||||
|
@ -184,7 +174,7 @@ public class FoodFragment extends Fragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
// make it unique
|
// make it unique
|
||||||
subcategories = new ArrayList<>(subCatSet);
|
ArrayList<CharSequence> subcategories = new ArrayList<>(subCatSet);
|
||||||
subcategories.add(0, MainApp.gs(R.string.none));
|
subcategories.add(0, MainApp.gs(R.string.none));
|
||||||
|
|
||||||
ArrayAdapter<CharSequence> adapterSubcategories = new ArrayAdapter<>(getContext(),
|
ArrayAdapter<CharSequence> adapterSubcategories = new ArrayAdapter<>(getContext(),
|
||||||
|
@ -192,7 +182,7 @@ public class FoodFragment extends Fragment {
|
||||||
subcategory.setAdapter(adapterSubcategories);
|
subcategory.setAdapter(adapterSubcategories);
|
||||||
}
|
}
|
||||||
|
|
||||||
void filterData() {
|
private void filterData() {
|
||||||
String textFilter = filter.getText().toString();
|
String textFilter = filter.getText().toString();
|
||||||
String categoryFilter = category.getSelectedItem().toString();
|
String categoryFilter = category.getSelectedItem().toString();
|
||||||
String subcategoryFilter = subcategory.getSelectedItem().toString();
|
String subcategoryFilter = subcategory.getSelectedItem().toString();
|
||||||
|
@ -227,6 +217,7 @@ public class FoodFragment extends Fragment {
|
||||||
this.foodList = foodList;
|
this.foodList = foodList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public FoodsViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
|
public FoodsViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
|
||||||
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.food_item, viewGroup, false);
|
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.food_item, viewGroup, false);
|
||||||
|
@ -257,7 +248,7 @@ public class FoodFragment extends Fragment {
|
||||||
return foodList.size();
|
return foodList.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
class FoodsViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
|
class FoodsViewHolder extends RecyclerView.ViewHolder {
|
||||||
TextView name;
|
TextView name;
|
||||||
TextView portion;
|
TextView portion;
|
||||||
TextView carbs;
|
TextView carbs;
|
||||||
|
@ -269,43 +260,26 @@ public class FoodFragment extends Fragment {
|
||||||
|
|
||||||
FoodsViewHolder(View itemView) {
|
FoodsViewHolder(View itemView) {
|
||||||
super(itemView);
|
super(itemView);
|
||||||
name = (TextView) itemView.findViewById(R.id.food_name);
|
name = itemView.findViewById(R.id.food_name);
|
||||||
portion = (TextView) itemView.findViewById(R.id.food_portion);
|
portion = itemView.findViewById(R.id.food_portion);
|
||||||
carbs = (TextView) itemView.findViewById(R.id.food_carbs);
|
carbs = itemView.findViewById(R.id.food_carbs);
|
||||||
fat = (TextView) itemView.findViewById(R.id.food_fat);
|
fat = itemView.findViewById(R.id.food_fat);
|
||||||
protein = (TextView) itemView.findViewById(R.id.food_protein);
|
protein = itemView.findViewById(R.id.food_protein);
|
||||||
energy = (TextView) itemView.findViewById(R.id.food_energy);
|
energy = itemView.findViewById(R.id.food_energy);
|
||||||
ns = (TextView) itemView.findViewById(R.id.ns_sign);
|
ns = itemView.findViewById(R.id.ns_sign);
|
||||||
remove = (TextView) itemView.findViewById(R.id.food_remove);
|
remove = itemView.findViewById(R.id.food_remove);
|
||||||
remove.setOnClickListener(this);
|
remove.setOnClickListener(v -> {
|
||||||
|
final Food food = (Food) v.getTag();
|
||||||
|
OKDialog.showConfirmation(getContext(), MainApp.gs(R.string.confirmation), MainApp.gs(R.string.removerecord) + "\n" + food.name, (dialog, id) -> {
|
||||||
|
final String _id = food._id;
|
||||||
|
if (_id != null && !_id.equals("")) {
|
||||||
|
NSUpload.removeFoodFromNS(_id);
|
||||||
|
}
|
||||||
|
FoodPlugin.getPlugin().getService().delete(food);
|
||||||
|
}, null);
|
||||||
|
});
|
||||||
remove.setPaintFlags(remove.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
|
remove.setPaintFlags(remove.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
final Food food = (Food) v.getTag();
|
|
||||||
switch (v.getId()) {
|
|
||||||
|
|
||||||
case R.id.food_remove:
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
|
|
||||||
builder.setTitle(MainApp.gs(R.string.confirmation));
|
|
||||||
builder.setMessage(MainApp.gs(R.string.removerecord) + "\n" + food.name);
|
|
||||||
builder.setPositiveButton(MainApp.gs(R.string.ok), new DialogInterface.OnClickListener() {
|
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
|
||||||
final String _id = food._id;
|
|
||||||
if (_id != null && !_id.equals("")) {
|
|
||||||
NSUpload.removeFoodFromNS(_id);
|
|
||||||
}
|
|
||||||
FoodPlugin.getPlugin().getService().delete(food);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
|
|
||||||
builder.show();
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,15 +2,14 @@ package info.nightscout.androidaps.plugins.general.maintenance;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import androidx.core.app.ActivityCompat;
|
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -39,7 +38,7 @@ import info.nightscout.androidaps.utils.ToastUtils;
|
||||||
|
|
||||||
public class ImportExportPrefs {
|
public class ImportExportPrefs {
|
||||||
private static Logger log = LoggerFactory.getLogger(L.CORE);
|
private static Logger log = LoggerFactory.getLogger(L.CORE);
|
||||||
static File path = new File(Environment.getExternalStorageDirectory().toString());
|
private static File path = new File(Environment.getExternalStorageDirectory().toString());
|
||||||
static public final File file = new File(path, MainApp.gs(R.string.app_name) + "Preferences");
|
static public final File file = new File(path, MainApp.gs(R.string.app_name) + "Preferences");
|
||||||
|
|
||||||
private static final int REQUEST_EXTERNAL_STORAGE = 1;
|
private static final int REQUEST_EXTERNAL_STORAGE = 1;
|
||||||
|
@ -48,21 +47,7 @@ public class ImportExportPrefs {
|
||||||
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||||
};
|
};
|
||||||
|
|
||||||
public static void verifyStoragePermissions(Activity activity) {
|
static void verifyStoragePermissions(Fragment fragment) {
|
||||||
// Check if we have write permission
|
|
||||||
int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
|
|
||||||
|
|
||||||
if (permission != PackageManager.PERMISSION_GRANTED) {
|
|
||||||
// We don't have permission so prompt the user
|
|
||||||
ActivityCompat.requestPermissions(
|
|
||||||
activity,
|
|
||||||
PERMISSIONS_STORAGE,
|
|
||||||
REQUEST_EXTERNAL_STORAGE
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void verifyStoragePermissions(Fragment fragment) {
|
|
||||||
int permission = ContextCompat.checkSelfPermission(fragment.getContext(),
|
int permission = ContextCompat.checkSelfPermission(fragment.getContext(),
|
||||||
Manifest.permission.WRITE_EXTERNAL_STORAGE);
|
Manifest.permission.WRITE_EXTERNAL_STORAGE);
|
||||||
|
|
||||||
|
@ -73,85 +58,71 @@ public class ImportExportPrefs {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void exportSharedPreferences(final Fragment f) {
|
static void exportSharedPreferences(final Fragment f) {
|
||||||
exportSharedPreferences(f.getContext());
|
exportSharedPreferences(f.getContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void exportSharedPreferences(final Context c) {
|
private static void exportSharedPreferences(final Context context) {
|
||||||
|
OKDialog.showConfirmation(context, MainApp.gs(R.string.maintenance), MainApp.gs(R.string.export_to) + " " + file + " ?", () -> {
|
||||||
new AlertDialog.Builder(c)
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
.setMessage(MainApp.gs(R.string.export_to) + " " + file + " ?")
|
try {
|
||||||
.setPositiveButton(android.R.string.yes, (dialog, which) -> {
|
FileWriter fw = new FileWriter(file);
|
||||||
|
PrintWriter pw = new PrintWriter(fw);
|
||||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c);
|
Map<String, ?> prefsMap = prefs.getAll();
|
||||||
try {
|
for (Map.Entry<String, ?> entry : prefsMap.entrySet()) {
|
||||||
FileWriter fw = new FileWriter(file);
|
pw.println(entry.getKey() + "::" + entry.getValue().toString());
|
||||||
PrintWriter pw = new PrintWriter(fw);
|
}
|
||||||
Map<String, ?> prefsMap = prefs.getAll();
|
pw.close();
|
||||||
for (Map.Entry<String, ?> entry : prefsMap.entrySet()) {
|
fw.close();
|
||||||
pw.println(entry.getKey() + "::" + entry.getValue().toString());
|
ToastUtils.showToastInUiThread(context, MainApp.gs(R.string.exported));
|
||||||
}
|
} catch (FileNotFoundException e) {
|
||||||
pw.close();
|
ToastUtils.showToastInUiThread(context, MainApp.gs(R.string.filenotfound) + " " + file);
|
||||||
fw.close();
|
log.error("Unhandled exception", e);
|
||||||
ToastUtils.showToastInUiThread(c, MainApp.gs(R.string.exported));
|
} catch (IOException e) {
|
||||||
} catch (FileNotFoundException e) {
|
log.error("Unhandled exception", e);
|
||||||
ToastUtils.showToastInUiThread(c, MainApp.gs(R.string.filenotfound) + " " + file);
|
}
|
||||||
log.error("Unhandled exception", e);
|
});
|
||||||
} catch (IOException e) {
|
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.setNegativeButton(android.R.string.cancel, null)
|
|
||||||
.show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void importSharedPreferences(final Fragment fragment) {
|
static void importSharedPreferences(final Fragment fragment) {
|
||||||
importSharedPreferences(fragment.getContext());
|
importSharedPreferences(fragment.getContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void importSharedPreferences(final Context context) {
|
public static void importSharedPreferences(final Context context) {
|
||||||
new AlertDialog.Builder(context)
|
OKDialog.showConfirmation(context, MainApp.gs(R.string.maintenance), MainApp.gs(R.string.import_from) + " " + file + " ?", () -> {
|
||||||
.setMessage(MainApp.gs(R.string.import_from) + " " + file + " ?")
|
String line;
|
||||||
.setPositiveButton(android.R.string.yes, (dialog, which) -> {
|
String[] lineParts;
|
||||||
|
try {
|
||||||
|
SP.clear();
|
||||||
|
|
||||||
String line;
|
BufferedReader reader = new BufferedReader(new FileReader(file));
|
||||||
String[] lineParts;
|
while ((line = reader.readLine()) != null) {
|
||||||
try {
|
lineParts = line.split("::");
|
||||||
SP.clear();
|
if (lineParts.length == 2) {
|
||||||
|
if (lineParts[1].equals("true") || lineParts[1].equals("false")) {
|
||||||
BufferedReader reader = new BufferedReader(new FileReader(file));
|
SP.putBoolean(lineParts[0], Boolean.parseBoolean(lineParts[1]));
|
||||||
while ((line = reader.readLine()) != null) {
|
} else {
|
||||||
lineParts = line.split("::");
|
SP.putString(lineParts[0], lineParts[1]);
|
||||||
if (lineParts.length == 2) {
|
|
||||||
if (lineParts[1].equals("true") || lineParts[1].equals("false")) {
|
|
||||||
SP.putBoolean(lineParts[0], Boolean.parseBoolean(lineParts[1]));
|
|
||||||
} else {
|
|
||||||
SP.putString(lineParts[0], lineParts[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
reader.close();
|
|
||||||
SP.putBoolean(R.string.key_setupwizard_processed, true);
|
|
||||||
OKDialog.show(context, MainApp.gs(R.string.setting_imported), MainApp.gs(R.string.restartingapp), () -> {
|
|
||||||
log.debug("Exiting");
|
|
||||||
MainApp.instance().stopKeepAliveService();
|
|
||||||
RxBus.INSTANCE.send(new EventAppExit());
|
|
||||||
MainApp.closeDbHelper();
|
|
||||||
if (context instanceof Activity) {
|
|
||||||
((Activity)context).finish();
|
|
||||||
}
|
|
||||||
System.runFinalization();
|
|
||||||
System.exit(0);
|
|
||||||
});
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
ToastUtils.showToastInUiThread(context, MainApp.gs(R.string.filenotfound) + " " + file);
|
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
} catch (IOException e) {
|
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
.setNegativeButton(android.R.string.cancel, null)
|
reader.close();
|
||||||
.show();
|
SP.putBoolean(R.string.key_setupwizard_processed, true);
|
||||||
|
OKDialog.show(context, MainApp.gs(R.string.setting_imported), MainApp.gs(R.string.restartingapp), () -> {
|
||||||
|
log.debug("Exiting");
|
||||||
|
RxBus.INSTANCE.send(new EventAppExit());
|
||||||
|
if (context instanceof Activity) {
|
||||||
|
((Activity) context).finish();
|
||||||
|
}
|
||||||
|
System.runFinalization();
|
||||||
|
System.exit(0);
|
||||||
|
});
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
ToastUtils.showToastInUiThread(context, MainApp.gs(R.string.filenotfound) + " " + file);
|
||||||
|
log.error("Unhandled exception", e);
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("Unhandled exception", e);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,81 +2,58 @@ package info.nightscout.androidaps.plugins.general.maintenance;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
import androidx.appcompat.app.AlertDialog;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
|
||||||
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.general.food.FoodPlugin;
|
import info.nightscout.androidaps.plugins.general.food.FoodPlugin;
|
||||||
import info.nightscout.androidaps.plugins.general.maintenance.activities.LogSettingActivity;
|
import info.nightscout.androidaps.plugins.general.maintenance.activities.LogSettingActivity;
|
||||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
|
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
|
||||||
|
import info.nightscout.androidaps.utils.OKDialog;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class MaintenanceFragment extends Fragment {
|
public class MaintenanceFragment extends Fragment {
|
||||||
|
|
||||||
private Fragment f;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
|
|
||||||
this.f = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPause() {
|
|
||||||
super.onPause();
|
|
||||||
|
|
||||||
this.f = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
View view = inflater.inflate(R.layout.maintenance_fragment, container, false);
|
View view = inflater.inflate(R.layout.maintenance_fragment, container, false);
|
||||||
|
|
||||||
final Fragment f = this;
|
|
||||||
|
|
||||||
view.findViewById(R.id.log_send).setOnClickListener(view1 -> MaintenancePlugin.getPlugin().sendLogs());
|
view.findViewById(R.id.log_send).setOnClickListener(view1 -> MaintenancePlugin.getPlugin().sendLogs());
|
||||||
|
|
||||||
view.findViewById(R.id.log_delete).setOnClickListener(view1 -> MaintenancePlugin.getPlugin().deleteLogs());
|
view.findViewById(R.id.log_delete).setOnClickListener(view1 -> MaintenancePlugin.getPlugin().deleteLogs());
|
||||||
|
|
||||||
view.findViewById(R.id.nav_resetdb).setOnClickListener(view1 -> new AlertDialog.Builder(f.getContext())
|
view.findViewById(R.id.nav_resetdb).setOnClickListener(view1 ->
|
||||||
.setTitle(R.string.nav_resetdb)
|
OKDialog.showConfirmation(getContext(), MainApp.gs(R.string.maintenance), MainApp.gs(R.string.reset_db_confirm), () -> {
|
||||||
.setMessage(R.string.reset_db_confirm)
|
|
||||||
.setNegativeButton(android.R.string.cancel, null)
|
|
||||||
.setPositiveButton(android.R.string.ok, (dialog, which) -> {
|
|
||||||
MainApp.getDbHelper().resetDatabases();
|
MainApp.getDbHelper().resetDatabases();
|
||||||
// should be handled by Plugin-Interface and
|
// should be handled by Plugin-Interface and
|
||||||
// additional service interface and plugin registry
|
// additional service interface and plugin registry
|
||||||
FoodPlugin.getPlugin().getService().resetFood();
|
FoodPlugin.getPlugin().getService().resetFood();
|
||||||
TreatmentsPlugin.getPlugin().getService().resetTreatments();
|
TreatmentsPlugin.getPlugin().getService().resetTreatments();
|
||||||
})
|
})
|
||||||
.create()
|
);
|
||||||
.show());
|
|
||||||
|
|
||||||
view.findViewById(R.id.nav_export).setOnClickListener(view1 -> {
|
view.findViewById(R.id.nav_export).setOnClickListener(view1 -> {
|
||||||
// start activity for checking permissions...
|
// start activity for checking permissions...
|
||||||
ImportExportPrefs.verifyStoragePermissions(f);
|
ImportExportPrefs.verifyStoragePermissions(this);
|
||||||
ImportExportPrefs.exportSharedPreferences(f);
|
ImportExportPrefs.exportSharedPreferences(this);
|
||||||
});
|
});
|
||||||
|
|
||||||
view.findViewById(R.id.nav_import).setOnClickListener(view1 -> {
|
view.findViewById(R.id.nav_import).setOnClickListener(view1 -> {
|
||||||
// start activity for checking permissions...
|
// start activity for checking permissions...
|
||||||
ImportExportPrefs.verifyStoragePermissions(f);
|
ImportExportPrefs.verifyStoragePermissions(this);
|
||||||
ImportExportPrefs.importSharedPreferences(f);
|
ImportExportPrefs.importSharedPreferences(this);
|
||||||
});
|
});
|
||||||
|
|
||||||
view.findViewById(R.id.nav_logsettings).setOnClickListener(view1 -> {
|
view.findViewById(R.id.nav_logsettings).setOnClickListener(view1 -> {
|
||||||
startActivity(new Intent(getActivity(), LogSettingActivity.class));
|
startActivity(new Intent(getActivity(), LogSettingActivity.class));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
package info.nightscout.androidaps.plugins.general.nsclient;
|
package info.nightscout.androidaps.plugins.general.nsclient;
|
||||||
|
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.Html;
|
import android.text.Html;
|
||||||
|
@ -25,6 +22,7 @@ import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientN
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart;
|
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart;
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientUpdateGUI;
|
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientUpdateGUI;
|
||||||
import info.nightscout.androidaps.utils.FabricPrivacy;
|
import info.nightscout.androidaps.utils.FabricPrivacy;
|
||||||
|
import info.nightscout.androidaps.utils.OKDialog;
|
||||||
import info.nightscout.androidaps.utils.SP;
|
import info.nightscout.androidaps.utils.SP;
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
import io.reactivex.disposables.CompositeDisposable;
|
import io.reactivex.disposables.CompositeDisposable;
|
||||||
|
@ -113,20 +111,11 @@ public class NSClientFragment extends Fragment implements View.OnClickListener,
|
||||||
NSClientPlugin.getPlugin().clearLog();
|
NSClientPlugin.getPlugin().clearLog();
|
||||||
break;
|
break;
|
||||||
case R.id.nsclientinternal_clearqueue:
|
case R.id.nsclientinternal_clearqueue:
|
||||||
final Context context = getContext();
|
OKDialog.showConfirmation(getContext(),MainApp.gs(R.string.nsclientinternal), MainApp.gs(R.string.clearqueueconfirm), () -> {
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
UploadQueue.clearQueue();
|
||||||
|
updateGui();
|
||||||
builder.setTitle(MainApp.gs(R.string.confirmation));
|
FabricPrivacy.getInstance().logCustom("NSClientClearQueue");
|
||||||
builder.setMessage("Clear queue? All data in queue will be lost!");
|
|
||||||
builder.setPositiveButton(MainApp.gs(R.string.ok), new DialogInterface.OnClickListener() {
|
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
|
||||||
UploadQueue.clearQueue();
|
|
||||||
updateGui();
|
|
||||||
FabricPrivacy.getInstance().logCustom("NSClientClearQueue");
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
|
|
||||||
builder.show();
|
|
||||||
break;
|
break;
|
||||||
case R.id.nsclientinternal_showqueue:
|
case R.id.nsclientinternal_showqueue:
|
||||||
RxBus.INSTANCE.send(new EventNSClientNewLog("QUEUE", NSClientPlugin.getPlugin().queue().textList()));
|
RxBus.INSTANCE.send(new EventNSClientNewLog("QUEUE", NSClientPlugin.getPlugin().queue().textList()));
|
||||||
|
|
|
@ -32,6 +32,8 @@ import info.nightscout.androidaps.interfaces.PluginDescription;
|
||||||
import info.nightscout.androidaps.interfaces.PluginType;
|
import info.nightscout.androidaps.interfaces.PluginType;
|
||||||
import info.nightscout.androidaps.logging.L;
|
import info.nightscout.androidaps.logging.L;
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBus;
|
import info.nightscout.androidaps.plugins.bus.RxBus;
|
||||||
|
import info.nightscout.androidaps.plugins.general.nsclient.data.AlarmAck;
|
||||||
|
import info.nightscout.androidaps.plugins.general.nsclient.data.NSAlarm;
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientNewLog;
|
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientNewLog;
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientStatus;
|
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientStatus;
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientUpdateGUI;
|
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientUpdateGUI;
|
||||||
|
@ -250,4 +252,25 @@ public class NSClientPlugin extends PluginBase {
|
||||||
public boolean hasWritePermission() {
|
public boolean hasWritePermission() {
|
||||||
return nsClientService.hasWriteAuth;
|
return nsClientService.hasWriteAuth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void handleClearAlarm(NSAlarm originalAlarm, long silenceTimeInMsec) {
|
||||||
|
|
||||||
|
if (!isEnabled(PluginType.GENERAL)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (SP.getBoolean(R.string.key_ns_noupload, false)) {
|
||||||
|
if (L.isEnabled(L.NSCLIENT))
|
||||||
|
log.debug("Upload disabled. Message dropped");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AlarmAck ack = new AlarmAck();
|
||||||
|
ack.level = originalAlarm.getLevel();
|
||||||
|
ack.group = originalAlarm.getGroup();
|
||||||
|
ack.silenceTime = silenceTimeInMsec;
|
||||||
|
|
||||||
|
if (nsClientService != null)
|
||||||
|
nsClientService.sendAlarmAck(ack);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
package info.nightscout.androidaps.plugins.general.nsclient;
|
package info.nightscout.androidaps.plugins.general.nsclient;
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.pm.ResolveInfo;
|
import android.content.pm.ResolveInfo;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
|
@ -24,22 +23,23 @@ import java.util.Locale;
|
||||||
|
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.logging.L;
|
|
||||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
|
|
||||||
import info.nightscout.androidaps.services.Intents;
|
|
||||||
import info.nightscout.androidaps.data.DetailedBolusInfo;
|
import info.nightscout.androidaps.data.DetailedBolusInfo;
|
||||||
|
import info.nightscout.androidaps.data.IobTotal;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
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.db.DbRequest;
|
||||||
import info.nightscout.androidaps.db.ExtendedBolus;
|
import info.nightscout.androidaps.db.ExtendedBolus;
|
||||||
import info.nightscout.androidaps.db.ProfileSwitch;
|
import info.nightscout.androidaps.db.ProfileSwitch;
|
||||||
import info.nightscout.androidaps.db.TempTarget;
|
import info.nightscout.androidaps.db.TempTarget;
|
||||||
import info.nightscout.androidaps.db.TemporaryBasal;
|
import info.nightscout.androidaps.db.TemporaryBasal;
|
||||||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
|
import info.nightscout.androidaps.logging.L;
|
||||||
import info.nightscout.androidaps.plugins.aps.loop.APSResult;
|
import info.nightscout.androidaps.plugins.aps.loop.APSResult;
|
||||||
import info.nightscout.androidaps.plugins.aps.loop.DeviceStatus;
|
import info.nightscout.androidaps.plugins.aps.loop.DeviceStatus;
|
||||||
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin;
|
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin;
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.data.DbLogger;
|
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
|
||||||
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
|
||||||
import info.nightscout.androidaps.utils.BatteryLevel;
|
import info.nightscout.androidaps.utils.BatteryLevel;
|
||||||
import info.nightscout.androidaps.utils.DateUtil;
|
import info.nightscout.androidaps.utils.DateUtil;
|
||||||
import info.nightscout.androidaps.utils.SP;
|
import info.nightscout.androidaps.utils.SP;
|
||||||
|
@ -53,7 +53,6 @@ public class NSUpload {
|
||||||
|
|
||||||
public static void uploadTempBasalStartAbsolute(TemporaryBasal temporaryBasal, Double originalExtendedAmount) {
|
public static void uploadTempBasalStartAbsolute(TemporaryBasal temporaryBasal, Double originalExtendedAmount) {
|
||||||
try {
|
try {
|
||||||
Context context = MainApp.instance().getApplicationContext();
|
|
||||||
JSONObject data = new JSONObject();
|
JSONObject data = new JSONObject();
|
||||||
data.put("eventType", CareportalEvent.TEMPBASAL);
|
data.put("eventType", CareportalEvent.TEMPBASAL);
|
||||||
data.put("duration", temporaryBasal.durationInMinutes);
|
data.put("duration", temporaryBasal.durationInMinutes);
|
||||||
|
@ -65,15 +64,7 @@ public class NSUpload {
|
||||||
data.put("enteredBy", "openaps://" + MainApp.gs(R.string.app_name));
|
data.put("enteredBy", "openaps://" + MainApp.gs(R.string.app_name));
|
||||||
if (originalExtendedAmount != null)
|
if (originalExtendedAmount != null)
|
||||||
data.put("originalExtendedAmount", originalExtendedAmount); // for back synchronization
|
data.put("originalExtendedAmount", originalExtendedAmount); // for back synchronization
|
||||||
Bundle bundle = new Bundle();
|
UploadQueue.add(new DbRequest("dbAdd", "treatments", data));
|
||||||
bundle.putString("action", "dbAdd");
|
|
||||||
bundle.putString("collection", "treatments");
|
|
||||||
bundle.putString("data", data.toString());
|
|
||||||
Intent intent = new Intent(Intents.ACTION_DATABASE);
|
|
||||||
intent.putExtras(bundle);
|
|
||||||
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
|
|
||||||
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
|
|
||||||
DbLogger.dbAdd(intent, data.toString());
|
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
|
@ -96,7 +87,6 @@ public class NSUpload {
|
||||||
uploadTempBasalStartAbsolute(t, null);
|
uploadTempBasalStartAbsolute(t, null);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Context context = MainApp.instance().getApplicationContext();
|
|
||||||
JSONObject data = new JSONObject();
|
JSONObject data = new JSONObject();
|
||||||
data.put("eventType", CareportalEvent.TEMPBASAL);
|
data.put("eventType", CareportalEvent.TEMPBASAL);
|
||||||
data.put("duration", temporaryBasal.durationInMinutes);
|
data.put("duration", temporaryBasal.durationInMinutes);
|
||||||
|
@ -107,15 +97,7 @@ public class NSUpload {
|
||||||
data.put("pumpId", temporaryBasal.pumpId);
|
data.put("pumpId", temporaryBasal.pumpId);
|
||||||
data.put("created_at", DateUtil.toISOString(temporaryBasal.date));
|
data.put("created_at", DateUtil.toISOString(temporaryBasal.date));
|
||||||
data.put("enteredBy", "openaps://" + MainApp.gs(R.string.app_name));
|
data.put("enteredBy", "openaps://" + MainApp.gs(R.string.app_name));
|
||||||
Bundle bundle = new Bundle();
|
UploadQueue.add(new DbRequest("dbAdd", "treatments", data));
|
||||||
bundle.putString("action", "dbAdd");
|
|
||||||
bundle.putString("collection", "treatments");
|
|
||||||
bundle.putString("data", data.toString());
|
|
||||||
Intent intent = new Intent(Intents.ACTION_DATABASE);
|
|
||||||
intent.putExtras(bundle);
|
|
||||||
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
|
|
||||||
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
|
|
||||||
DbLogger.dbAdd(intent, data.toString());
|
|
||||||
}
|
}
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception", e);
|
||||||
|
@ -124,7 +106,6 @@ public class NSUpload {
|
||||||
|
|
||||||
public static void uploadTempBasalEnd(long time, boolean isFakedTempBasal, long pumpId) {
|
public static void uploadTempBasalEnd(long time, boolean isFakedTempBasal, long pumpId) {
|
||||||
try {
|
try {
|
||||||
Context context = MainApp.instance().getApplicationContext();
|
|
||||||
JSONObject data = new JSONObject();
|
JSONObject data = new JSONObject();
|
||||||
data.put("eventType", CareportalEvent.TEMPBASAL);
|
data.put("eventType", CareportalEvent.TEMPBASAL);
|
||||||
data.put("created_at", DateUtil.toISOString(time));
|
data.put("created_at", DateUtil.toISOString(time));
|
||||||
|
@ -133,15 +114,7 @@ public class NSUpload {
|
||||||
data.put("isFakedTempBasal", isFakedTempBasal);
|
data.put("isFakedTempBasal", isFakedTempBasal);
|
||||||
if (pumpId != 0)
|
if (pumpId != 0)
|
||||||
data.put("pumpId", pumpId);
|
data.put("pumpId", pumpId);
|
||||||
Bundle bundle = new Bundle();
|
UploadQueue.add(new DbRequest("dbAdd", "treatments", data));
|
||||||
bundle.putString("action", "dbAdd");
|
|
||||||
bundle.putString("collection", "treatments");
|
|
||||||
bundle.putString("data", data.toString());
|
|
||||||
Intent intent = new Intent(Intents.ACTION_DATABASE);
|
|
||||||
intent.putExtras(bundle);
|
|
||||||
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
|
|
||||||
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
|
|
||||||
DbLogger.dbAdd(intent, data.toString());
|
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
|
@ -149,7 +122,6 @@ public class NSUpload {
|
||||||
|
|
||||||
public static void uploadExtendedBolus(ExtendedBolus extendedBolus) {
|
public static void uploadExtendedBolus(ExtendedBolus extendedBolus) {
|
||||||
try {
|
try {
|
||||||
Context context = MainApp.instance().getApplicationContext();
|
|
||||||
JSONObject data = new JSONObject();
|
JSONObject data = new JSONObject();
|
||||||
data.put("eventType", CareportalEvent.COMBOBOLUS);
|
data.put("eventType", CareportalEvent.COMBOBOLUS);
|
||||||
data.put("duration", extendedBolus.durationInMinutes);
|
data.put("duration", extendedBolus.durationInMinutes);
|
||||||
|
@ -161,15 +133,7 @@ public class NSUpload {
|
||||||
data.put("pumpId", extendedBolus.pumpId);
|
data.put("pumpId", extendedBolus.pumpId);
|
||||||
data.put("created_at", DateUtil.toISOString(extendedBolus.date));
|
data.put("created_at", DateUtil.toISOString(extendedBolus.date));
|
||||||
data.put("enteredBy", "openaps://" + MainApp.gs(R.string.app_name));
|
data.put("enteredBy", "openaps://" + MainApp.gs(R.string.app_name));
|
||||||
Bundle bundle = new Bundle();
|
UploadQueue.add(new DbRequest("dbAdd", "treatments", data));
|
||||||
bundle.putString("action", "dbAdd");
|
|
||||||
bundle.putString("collection", "treatments");
|
|
||||||
bundle.putString("data", data.toString());
|
|
||||||
Intent intent = new Intent(Intents.ACTION_DATABASE);
|
|
||||||
intent.putExtras(bundle);
|
|
||||||
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
|
|
||||||
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
|
|
||||||
DbLogger.dbAdd(intent, data.toString());
|
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
|
@ -177,7 +141,6 @@ public class NSUpload {
|
||||||
|
|
||||||
public static void uploadExtendedBolusEnd(long time, long pumpId) {
|
public static void uploadExtendedBolusEnd(long time, long pumpId) {
|
||||||
try {
|
try {
|
||||||
Context context = MainApp.instance().getApplicationContext();
|
|
||||||
JSONObject data = new JSONObject();
|
JSONObject data = new JSONObject();
|
||||||
data.put("eventType", CareportalEvent.COMBOBOLUS);
|
data.put("eventType", CareportalEvent.COMBOBOLUS);
|
||||||
data.put("duration", 0);
|
data.put("duration", 0);
|
||||||
|
@ -189,15 +152,7 @@ public class NSUpload {
|
||||||
data.put("enteredBy", "openaps://" + MainApp.gs(R.string.app_name));
|
data.put("enteredBy", "openaps://" + MainApp.gs(R.string.app_name));
|
||||||
if (pumpId != 0)
|
if (pumpId != 0)
|
||||||
data.put("pumpId", pumpId);
|
data.put("pumpId", pumpId);
|
||||||
Bundle bundle = new Bundle();
|
UploadQueue.add(new DbRequest("dbAdd", "treatments", data));
|
||||||
bundle.putString("action", "dbAdd");
|
|
||||||
bundle.putString("collection", "treatments");
|
|
||||||
bundle.putString("data", data.toString());
|
|
||||||
Intent intent = new Intent(Intents.ACTION_DATABASE);
|
|
||||||
intent.putExtras(bundle);
|
|
||||||
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
|
|
||||||
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
|
|
||||||
DbLogger.dbAdd(intent, data.toString());
|
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
|
@ -246,7 +201,12 @@ public class NSUpload {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (L.isEnabled(L.NSCLIENT))
|
if (L.isEnabled(L.NSCLIENT))
|
||||||
log.debug("OpenAPS data too old to upload");
|
log.debug("OpenAPS data too old to upload, sending iob only");
|
||||||
|
IobTotal[] iob = IobCobCalculatorPlugin.getPlugin().calculateIobArrayInDia(profile);
|
||||||
|
if (iob.length > 0) {
|
||||||
|
deviceStatus.iob = iob[0].json();
|
||||||
|
deviceStatus.iob.put("time", DateUtil.toISOString(DateUtil.now()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
deviceStatus.device = "openaps://" + Build.MANUFACTURER + " " + Build.MODEL;
|
deviceStatus.device = "openaps://" + Build.MANUFACTURER + " " + Build.MODEL;
|
||||||
JSONObject pumpstatus = ConfigBuilderPlugin.getPlugin().getActivePump().getJSONStatus(profile, profileName);
|
JSONObject pumpstatus = ConfigBuilderPlugin.getPlugin().getActivePump().getJSONStatus(profile, profileName);
|
||||||
|
@ -258,16 +218,7 @@ public class NSUpload {
|
||||||
deviceStatus.uploaderBattery = batteryLevel;
|
deviceStatus.uploaderBattery = batteryLevel;
|
||||||
|
|
||||||
deviceStatus.created_at = DateUtil.toISOString(new Date());
|
deviceStatus.created_at = DateUtil.toISOString(new Date());
|
||||||
Context context = MainApp.instance().getApplicationContext();
|
UploadQueue.add(new DbRequest("dbAdd", "devicestatus", deviceStatus.mongoRecord()));
|
||||||
Bundle bundle = new Bundle();
|
|
||||||
bundle.putString("action", "dbAdd");
|
|
||||||
bundle.putString("collection", "devicestatus");
|
|
||||||
bundle.putString("data", deviceStatus.mongoRecord().toString());
|
|
||||||
Intent intent = new Intent(Intents.ACTION_DATABASE);
|
|
||||||
intent.putExtras(bundle);
|
|
||||||
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
|
|
||||||
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
|
|
||||||
DbLogger.dbAdd(intent, deviceStatus.mongoRecord().toString());
|
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
|
@ -315,11 +266,13 @@ public class NSUpload {
|
||||||
JSONObject data = new JSONObject();
|
JSONObject data = new JSONObject();
|
||||||
data.put("eventType", CareportalEvent.TEMPORARYTARGET);
|
data.put("eventType", CareportalEvent.TEMPORARYTARGET);
|
||||||
data.put("duration", tempTarget.durationInMinutes);
|
data.put("duration", tempTarget.durationInMinutes);
|
||||||
data.put("reason", tempTarget.reason);
|
if (tempTarget.low > 0) {
|
||||||
data.put("targetBottom", Profile.fromMgdlToUnits(tempTarget.low, ProfileFunctions.getSystemUnits()));
|
data.put("reason", tempTarget.reason);
|
||||||
data.put("targetTop", Profile.fromMgdlToUnits(tempTarget.high, ProfileFunctions.getSystemUnits()));
|
data.put("targetBottom", Profile.fromMgdlToUnits(tempTarget.low, ProfileFunctions.getSystemUnits()));
|
||||||
|
data.put("targetTop", Profile.fromMgdlToUnits(tempTarget.high, ProfileFunctions.getSystemUnits()));
|
||||||
|
data.put("units", ProfileFunctions.getSystemUnits());
|
||||||
|
}
|
||||||
data.put("created_at", DateUtil.toISOString(tempTarget.date));
|
data.put("created_at", DateUtil.toISOString(tempTarget.date));
|
||||||
data.put("units", ProfileFunctions.getSystemUnits());
|
|
||||||
data.put("enteredBy", MainApp.gs(R.string.app_name));
|
data.put("enteredBy", MainApp.gs(R.string.app_name));
|
||||||
uploadCareportalEntryToNS(data);
|
uploadCareportalEntryToNS(data);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
|
@ -331,17 +284,7 @@ public class NSUpload {
|
||||||
try {
|
try {
|
||||||
JSONObject data = getJson(profileSwitch);
|
JSONObject data = getJson(profileSwitch);
|
||||||
if (profileSwitch._id != null) {
|
if (profileSwitch._id != null) {
|
||||||
Context context = MainApp.instance().getApplicationContext();
|
UploadQueue.add(new DbRequest("dbUpdate", "treatments", profileSwitch._id, data));
|
||||||
Bundle bundle = new Bundle();
|
|
||||||
bundle.putString("action", "dbUpdate");
|
|
||||||
bundle.putString("collection", "treatments");
|
|
||||||
bundle.putString("data", data.toString());
|
|
||||||
bundle.putString("_id", profileSwitch._id);
|
|
||||||
Intent intent = new Intent(Intents.ACTION_DATABASE);
|
|
||||||
intent.putExtras(bundle);
|
|
||||||
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
|
|
||||||
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
|
|
||||||
DbLogger.dbAdd(intent, data.toString());
|
|
||||||
}
|
}
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception", e);
|
||||||
|
@ -380,16 +323,7 @@ public class NSUpload {
|
||||||
prebolus.put("created_at", DateUtil.toISOString(preBolusDate));
|
prebolus.put("created_at", DateUtil.toISOString(preBolusDate));
|
||||||
uploadCareportalEntryToNS(prebolus);
|
uploadCareportalEntryToNS(prebolus);
|
||||||
}
|
}
|
||||||
Context context = MainApp.instance().getApplicationContext();
|
UploadQueue.add(new DbRequest("dbAdd", "treatments", data));
|
||||||
Bundle bundle = new Bundle();
|
|
||||||
bundle.putString("action", "dbAdd");
|
|
||||||
bundle.putString("collection", "treatments");
|
|
||||||
bundle.putString("data", data.toString());
|
|
||||||
Intent intent = new Intent(Intents.ACTION_DATABASE);
|
|
||||||
intent.putExtras(bundle);
|
|
||||||
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
|
|
||||||
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
|
|
||||||
DbLogger.dbAdd(intent, data.toString());
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
|
@ -397,40 +331,17 @@ public class NSUpload {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void removeCareportalEntryFromNS(String _id) {
|
public static void removeCareportalEntryFromNS(String _id) {
|
||||||
try {
|
UploadQueue.add(new DbRequest("dbRemove", "treatments", _id));
|
||||||
Context context = MainApp.instance().getApplicationContext();
|
|
||||||
Bundle bundle = new Bundle();
|
|
||||||
bundle.putString("action", "dbRemove");
|
|
||||||
bundle.putString("collection", "treatments");
|
|
||||||
bundle.putString("_id", _id);
|
|
||||||
Intent intent = new Intent(Intents.ACTION_DATABASE);
|
|
||||||
intent.putExtras(bundle);
|
|
||||||
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
|
|
||||||
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
|
|
||||||
DbLogger.dbRemove(intent, _id);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void uploadOpenAPSOffline(double durationInMinutes) {
|
public static void uploadOpenAPSOffline(double durationInMinutes) {
|
||||||
try {
|
try {
|
||||||
Context context = MainApp.instance().getApplicationContext();
|
|
||||||
JSONObject data = new JSONObject();
|
JSONObject data = new JSONObject();
|
||||||
data.put("eventType", "OpenAPS Offline");
|
data.put("eventType", "OpenAPS Offline");
|
||||||
data.put("duration", durationInMinutes);
|
data.put("duration", durationInMinutes);
|
||||||
data.put("created_at", DateUtil.toISOString(new Date()));
|
data.put("created_at", DateUtil.toISOString(new Date()));
|
||||||
data.put("enteredBy", "openaps://" + MainApp.gs(R.string.app_name));
|
data.put("enteredBy", "openaps://" + MainApp.gs(R.string.app_name));
|
||||||
Bundle bundle = new Bundle();
|
UploadQueue.add(new DbRequest("dbAdd", "treatments", data));
|
||||||
bundle.putString("action", "dbAdd");
|
|
||||||
bundle.putString("collection", "treatments");
|
|
||||||
bundle.putString("data", data.toString());
|
|
||||||
Intent intent = new Intent(Intents.ACTION_DATABASE);
|
|
||||||
intent.putExtras(bundle);
|
|
||||||
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
|
|
||||||
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
|
|
||||||
DbLogger.dbAdd(intent, data.toString());
|
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
|
@ -441,10 +352,6 @@ public class NSUpload {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void uploadError(String error, Date date) {
|
public static void uploadError(String error, Date date) {
|
||||||
Context context = MainApp.instance().getApplicationContext();
|
|
||||||
Bundle bundle = new Bundle();
|
|
||||||
bundle.putString("action", "dbAdd");
|
|
||||||
bundle.putString("collection", "treatments");
|
|
||||||
JSONObject data = new JSONObject();
|
JSONObject data = new JSONObject();
|
||||||
try {
|
try {
|
||||||
data.put("eventType", "Announcement");
|
data.put("eventType", "Announcement");
|
||||||
|
@ -455,19 +362,10 @@ public class NSUpload {
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
bundle.putString("data", data.toString());
|
UploadQueue.add(new DbRequest("dbAdd", "treatments", data));
|
||||||
Intent intent = new Intent(Intents.ACTION_DATABASE);
|
|
||||||
intent.putExtras(bundle);
|
|
||||||
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
|
|
||||||
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
|
|
||||||
DbLogger.dbAdd(intent, data.toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void uploadBg(BgReading reading, String source) {
|
public static void uploadBg(BgReading reading, String source) {
|
||||||
Context context = MainApp.instance().getApplicationContext();
|
|
||||||
Bundle bundle = new Bundle();
|
|
||||||
bundle.putString("action", "dbAdd");
|
|
||||||
bundle.putString("collection", "entries");
|
|
||||||
JSONObject data = new JSONObject();
|
JSONObject data = new JSONObject();
|
||||||
try {
|
try {
|
||||||
data.put("device", source);
|
data.put("device", source);
|
||||||
|
@ -479,20 +377,11 @@ public class NSUpload {
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
bundle.putString("data", data.toString());
|
UploadQueue.add(new DbRequest("dbAdd", "entries", data));
|
||||||
Intent intent = new Intent(Intents.ACTION_DATABASE);
|
|
||||||
intent.putExtras(bundle);
|
|
||||||
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
|
|
||||||
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
|
|
||||||
DbLogger.dbAdd(intent, data.toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void uploadAppStart() {
|
public static void uploadAppStart() {
|
||||||
if (SP.getBoolean(R.string.key_ns_logappstartedevent, true)) {
|
if (SP.getBoolean(R.string.key_ns_logappstartedevent, true)) {
|
||||||
Context context = MainApp.instance().getApplicationContext();
|
|
||||||
Bundle bundle = new Bundle();
|
|
||||||
bundle.putString("action", "dbAdd");
|
|
||||||
bundle.putString("collection", "treatments");
|
|
||||||
JSONObject data = new JSONObject();
|
JSONObject data = new JSONObject();
|
||||||
try {
|
try {
|
||||||
data.put("eventType", "Note");
|
data.put("eventType", "Note");
|
||||||
|
@ -501,35 +390,17 @@ public class NSUpload {
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
bundle.putString("data", data.toString());
|
UploadQueue.add(new DbRequest("dbAdd", "treatments", data));
|
||||||
Intent intent = new Intent(Intents.ACTION_DATABASE);
|
|
||||||
intent.putExtras(bundle);
|
|
||||||
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
|
|
||||||
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
|
|
||||||
DbLogger.dbAdd(intent, data.toString());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void uploadProfileStore(JSONObject profileStore) {
|
public static void uploadProfileStore(JSONObject profileStore) {
|
||||||
if (SP.getBoolean(R.string.key_ns_uploadlocalprofile, false)) {
|
if (SP.getBoolean(R.string.key_ns_uploadlocalprofile, false)) {
|
||||||
Context context = MainApp.instance().getApplicationContext();
|
UploadQueue.add(new DbRequest("dbAdd", "profile", String.valueOf(profileStore)));
|
||||||
Bundle bundle = new Bundle();
|
|
||||||
bundle.putString("action", "dbAdd");
|
|
||||||
bundle.putString("collection", "profile");
|
|
||||||
bundle.putString("data", String.valueOf(profileStore));
|
|
||||||
Intent intent = new Intent(Intents.ACTION_DATABASE);
|
|
||||||
intent.putExtras(bundle);
|
|
||||||
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
|
|
||||||
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
|
|
||||||
DbLogger.dbAdd(intent, String.valueOf(profileStore));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void uploadEvent(String careportalEvent, long time, @Nullable String notes) {
|
public static void uploadEvent(String careportalEvent, long time, @Nullable String notes) {
|
||||||
Context context = MainApp.instance().getApplicationContext();
|
|
||||||
Bundle bundle = new Bundle();
|
|
||||||
bundle.putString("action", "dbAdd");
|
|
||||||
bundle.putString("collection", "treatments");
|
|
||||||
JSONObject data = new JSONObject();
|
JSONObject data = new JSONObject();
|
||||||
try {
|
try {
|
||||||
data.put("eventType", careportalEvent);
|
data.put("eventType", careportalEvent);
|
||||||
|
@ -541,26 +412,12 @@ public class NSUpload {
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
bundle.putString("data", data.toString());
|
UploadQueue.add(new DbRequest("dbAdd", "treatments", data));
|
||||||
Intent intent = new Intent(Intents.ACTION_DATABASE);
|
|
||||||
intent.putExtras(bundle);
|
|
||||||
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
|
|
||||||
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
|
|
||||||
DbLogger.dbAdd(intent, data.toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void removeFoodFromNS(String _id) {
|
public static void removeFoodFromNS(String _id) {
|
||||||
try {
|
try {
|
||||||
Context context = MainApp.instance().getApplicationContext();
|
UploadQueue.add(new DbRequest("dbRemove", "food", _id));
|
||||||
Bundle bundle = new Bundle();
|
|
||||||
bundle.putString("action", "dbRemove");
|
|
||||||
bundle.putString("collection", "food");
|
|
||||||
bundle.putString("_id", _id);
|
|
||||||
Intent intent = new Intent(Intents.ACTION_DATABASE);
|
|
||||||
intent.putExtras(bundle);
|
|
||||||
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
|
|
||||||
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
|
|
||||||
DbLogger.dbRemove(intent, _id);
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,17 @@ public class UploadQueue {
|
||||||
NSClientService.handler.post(() -> {
|
NSClientService.handler.post(() -> {
|
||||||
if (L.isEnabled(L.NSCLIENT))
|
if (L.isEnabled(L.NSCLIENT))
|
||||||
log.debug("Adding to queue: " + dbr.data);
|
log.debug("Adding to queue: " + dbr.data);
|
||||||
MainApp.getDbHelper().create(dbr);
|
try {
|
||||||
|
MainApp.getDbHelper().create(dbr);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Unhandled exception", e);
|
||||||
|
dbr.nsClientID += "1";
|
||||||
|
try {
|
||||||
|
MainApp.getDbHelper().create(dbr);
|
||||||
|
} catch (Exception e1) {
|
||||||
|
log.error("Unhandled exception", e1);
|
||||||
|
}
|
||||||
|
}
|
||||||
NSClientPlugin plugin = NSClientPlugin.getPlugin();
|
NSClientPlugin plugin = NSClientPlugin.getPlugin();
|
||||||
if (plugin != null) {
|
if (plugin != null) {
|
||||||
plugin.resend("newdata");
|
plugin.resend("newdata");
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
package info.nightscout.androidaps.plugins.general.nsclient.broadcasts;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.MainApp;
|
|
||||||
import info.nightscout.androidaps.R;
|
|
||||||
import info.nightscout.androidaps.services.Intents;
|
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.data.NSAlarm;
|
|
||||||
import info.nightscout.androidaps.utils.SP;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by mike on 11.06.2017.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class BroadcastAckAlarm {
|
|
||||||
|
|
||||||
public static void handleClearAlarm(NSAlarm originalAlarm, Context context, long silenceTimeInMsec) {
|
|
||||||
|
|
||||||
Bundle bundle = new Bundle();
|
|
||||||
bundle.putInt("level", originalAlarm.getLevel());
|
|
||||||
bundle.putString("group", originalAlarm.getGroup());
|
|
||||||
bundle.putLong("silenceTime", silenceTimeInMsec);
|
|
||||||
Intent intent = new Intent(Intents.ACTION_ACK_ALARM);
|
|
||||||
intent.putExtras(bundle);
|
|
||||||
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
|
|
||||||
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
|
|
||||||
|
|
||||||
if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
|
|
||||||
bundle = new Bundle();
|
|
||||||
bundle.putInt("level", originalAlarm.getLevel());
|
|
||||||
bundle.putString("group", originalAlarm.getGroup());
|
|
||||||
bundle.putLong("silenceTime", silenceTimeInMsec);
|
|
||||||
intent = new Intent(Intents.ACTION_ACK_ALARM);
|
|
||||||
intent.putExtras(bundle);
|
|
||||||
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
|
|
||||||
context.sendBroadcast(intent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -25,12 +25,11 @@ import info.nightscout.androidaps.utils.SP;
|
||||||
public class BroadcastTreatment {
|
public class BroadcastTreatment {
|
||||||
private static Logger log = LoggerFactory.getLogger(L.NSCLIENT);
|
private static Logger log = LoggerFactory.getLogger(L.NSCLIENT);
|
||||||
|
|
||||||
public static void handleNewTreatment(JSONObject treatment, boolean isDelta, boolean isLocalBypass) {
|
public static void handleNewTreatment(JSONObject treatment, boolean isDelta) {
|
||||||
|
|
||||||
Bundle bundle = new Bundle();
|
Bundle bundle = new Bundle();
|
||||||
bundle.putString("treatment", treatment.toString());
|
bundle.putString("treatment", treatment.toString());
|
||||||
bundle.putBoolean("delta", isDelta);
|
bundle.putBoolean("delta", isDelta);
|
||||||
bundle.putBoolean("islocal", isLocalBypass);
|
|
||||||
Intent intent = new Intent(Intents.ACTION_NEW_TREATMENT);
|
Intent intent = new Intent(Intents.ACTION_NEW_TREATMENT);
|
||||||
intent.putExtras(bundle);
|
intent.putExtras(bundle);
|
||||||
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
|
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
package info.nightscout.androidaps.plugins.general.nsclient.data;
|
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.pm.ResolveInfo;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.MainApp;
|
|
||||||
import info.nightscout.androidaps.R;
|
|
||||||
import info.nightscout.androidaps.logging.L;
|
|
||||||
import info.nightscout.androidaps.utils.ToastUtils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by mike on 02.07.2016.
|
|
||||||
*/
|
|
||||||
public class DbLogger {
|
|
||||||
private static Logger log = LoggerFactory.getLogger(L.NSCLIENT);
|
|
||||||
|
|
||||||
public static void dbAdd(Intent intent, String data) {
|
|
||||||
List<ResolveInfo> q = MainApp.instance().getApplicationContext().getPackageManager().queryBroadcastReceivers(intent, 0);
|
|
||||||
if (q.size() < 1) {
|
|
||||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.nsclientnotinstalled));
|
|
||||||
log.error("DBADD No receivers");
|
|
||||||
} else if (L.isEnabled(L.NSCLIENT)) {
|
|
||||||
if (L.isEnabled(L.NSCLIENT))
|
|
||||||
log.debug("DBADD dbAdd " + q.size() + " receivers " + data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void dbRemove(Intent intent, String data) {
|
|
||||||
List<ResolveInfo> q = MainApp.instance().getApplicationContext().getPackageManager().queryBroadcastReceivers(intent, 0);
|
|
||||||
if (q.size() < 1) {
|
|
||||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.nsclientnotinstalled));
|
|
||||||
log.error("DBREMOVE No receivers");
|
|
||||||
} else if (L.isEnabled(L.NSCLIENT)) {
|
|
||||||
if (L.isEnabled(L.NSCLIENT))
|
|
||||||
log.debug("DBREMOVE dbRemove " + q.size() + " receivers " + data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -407,7 +407,7 @@ public class NSDeviceStatus {
|
||||||
}
|
}
|
||||||
Uploader uploader = uploaders.get(device);
|
Uploader uploader = uploaders.get(device);
|
||||||
// check if this is new data
|
// check if this is new data
|
||||||
if (clock != 0 && (uploader != null && clock > uploader.clock || uploader == null)) {
|
if (clock != 0 && battery != null && (uploader != null && clock > uploader.clock || uploader == null)) {
|
||||||
if (uploader == null)
|
if (uploader == null)
|
||||||
uploader = new Uploader();
|
uploader = new Uploader();
|
||||||
uploader.battery = battery;
|
uploader.battery = battery;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue