Merge tag '2.6.0' into omnipod_eros_dev
This commit is contained in:
commit
3eea2598f2
438 changed files with 17378 additions and 11682 deletions
11
.gitignore
vendored
11
.gitignore
vendored
|
@ -6,10 +6,17 @@
|
|||
/captures
|
||||
*.apk
|
||||
build/
|
||||
.idea/
|
||||
.idea/*
|
||||
!.idea/codeStyles/
|
||||
app/src/main/jniLibs
|
||||
full/
|
||||
debug/
|
||||
release/
|
||||
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
|
||||
|
|
134
.idea/codeStyles/Project.xml
Normal file
134
.idea/codeStyles/Project.xml
Normal file
|
@ -0,0 +1,134 @@
|
|||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<option name="AUTODETECT_INDENTS" value="false" />
|
||||
<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>
|
|
@ -228,8 +228,10 @@ dependencies {
|
|||
|
||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||
implementation 'com.google.android.gms:play-services-wearable:17.0.0'
|
||||
implementation 'com.google.firebase:firebase-core:17.2.0'
|
||||
implementation("com.crashlytics.sdk.android:crashlytics:2.9.9@aar") {
|
||||
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') {
|
||||
transitive = true;
|
||||
}
|
||||
|
||||
|
@ -237,11 +239,11 @@ dependencies {
|
|||
implementation 'androidx.legacy:legacy-support-v13:1.0.0'
|
||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||
implementation 'androidx.cardview:cardview:1.0.0'
|
||||
implementation 'androidx.recyclerview:recyclerview:1.0.0'
|
||||
implementation 'androidx.recyclerview:recyclerview:1.1.0'
|
||||
implementation 'androidx.gridlayout:gridlayout:1.0.0'
|
||||
implementation 'com.google.android.material:material:1.0.0'
|
||||
implementation 'androidx.percentlayout:percentlayout:1.0.0'
|
||||
implementation "com.wdullaer:materialdatetimepicker:2.3.0"
|
||||
implementation 'com.wdullaer:materialdatetimepicker:4.2.3'
|
||||
|
||||
implementation "io.reactivex.rxjava2:rxandroid:2.1.1"
|
||||
|
||||
|
@ -250,11 +252,11 @@ dependencies {
|
|||
implementation("com.github.tony19:logback-android-classic:1.1.1-6") {
|
||||
exclude group: "com.google.android", module: "android"
|
||||
}
|
||||
implementation "org.apache.commons:commons-lang3:3.7"
|
||||
implementation "org.slf4j:slf4j-api:1.7.21"
|
||||
implementation "org.apache.commons:commons-lang3:3.9"
|
||||
implementation "org.slf4j:slf4j-api:1.7.29"
|
||||
// Graphview cannot be upgraded
|
||||
implementation "com.jjoe64:graphview:4.0.1"
|
||||
implementation "com.joanzapata.iconify:android-iconify-fontawesome:2.1.1"
|
||||
implementation "com.joanzapata.iconify:android-iconify-fontawesome:2.2.2"
|
||||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
||||
implementation(name: "android-edittext-validator-v1.3.4-mod", ext: "aar")
|
||||
implementation(name: "com.atech-software.android.library.wizardpager-1.1.1", ext: "aar")
|
||||
|
@ -268,26 +270,29 @@ dependencies {
|
|||
// excluding org.json which is provided by Android
|
||||
exclude group: "org.json", module: "json"
|
||||
}
|
||||
implementation "com.google.code.gson:gson:2.8.5"
|
||||
implementation "com.google.guava:guava:24.1-jre"
|
||||
implementation "com.google.code.gson:gson:2.8.6"
|
||||
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.9.9.1"
|
||||
implementation "uk.com.robust-it:cloning:1.9.9"
|
||||
implementation "net.danlew:android.joda:2.10.3"
|
||||
|
||||
implementation 'org.mozilla:rhino:1.7.7.2'
|
||||
implementation 'org.mozilla:rhino:1.7.11'
|
||||
|
||||
implementation 'com.github.DavidProdinger:weekdays-selector:1.1.0'
|
||||
|
||||
testImplementation "junit:junit:4.12"
|
||||
testImplementation "org.json:json:20140107"
|
||||
testImplementation "org.json:json:20190722"
|
||||
testImplementation "org.mockito:mockito-core:2.8.47"
|
||||
testImplementation "org.powermock:powermock-api-mockito2:${powermockVersion}"
|
||||
testImplementation "org.powermock:powermock-module-junit4-rule-agent:${powermockVersion}"
|
||||
testImplementation "org.powermock:powermock-module-junit4-rule:${powermockVersion}"
|
||||
testImplementation "org.powermock:powermock-module-junit4:${powermockVersion}"
|
||||
testImplementation "joda-time:joda-time:2.9.9"
|
||||
testImplementation "joda-time:joda-time:2.10.5"
|
||||
testImplementation("com.google.truth:truth:0.39") {
|
||||
exclude group: "com.google.guava", module: "guava"
|
||||
exclude group: "com.google.code.findbugs", module: "jsr305"
|
||||
}
|
||||
testImplementation "org.skyscreamer:jsonassert:1.5.0"
|
||||
testImplementation "org.hamcrest:hamcrest-all:1.3"
|
||||
|
@ -297,20 +302,25 @@ 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-reflect:$kotlin_version"
|
||||
|
||||
|
||||
// new for tidepool
|
||||
implementation 'com.squareup.okhttp3:okhttp:3.10.0'
|
||||
implementation 'com.squareup.okhttp3:logging-interceptor:3.10.0'
|
||||
implementation "com.squareup.retrofit2:retrofit:2.4.0"
|
||||
implementation "com.squareup.retrofit2:adapter-rxjava2:2.4.0"
|
||||
implementation "com.squareup.retrofit2:converter-gson:2.4.0"
|
||||
implementation 'com.squareup.okhttp3:okhttp:4.2.2'
|
||||
implementation 'com.squareup.okhttp3:logging-interceptor:4.2.2'
|
||||
implementation "com.squareup.retrofit2:retrofit:2.6.2"
|
||||
implementation "com.squareup.retrofit2:adapter-rxjava2: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'
|
||||
androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'
|
||||
}
|
||||
|
||||
|
||||
|
@ -337,7 +347,37 @@ task copyLibs(dependsOn: downloadAndUnzipFile, type: Copy) {
|
|||
task full_clean(type: Delete) {
|
||||
delete file("src/main/jniLibs")
|
||||
}
|
||||
|
||||
/*
|
||||
// Run 'adb' shell command to clear application data of main app for 'debug' variant
|
||||
task clearMainAppData(type: Exec) {
|
||||
// we have to iterate to find the 'debug' variant to obtain a variant reference
|
||||
android.applicationVariants.all { variant ->
|
||||
if (variant.name == "fullDebug") {
|
||||
def applicationId = [variant.mergedFlavor.applicationId, variant.buildType.applicationIdSuffix].findAll().join()
|
||||
def clearDataCommand = ['adb', 'shell', 'pm', 'clear', applicationId]
|
||||
println "Clearing application data of ${variant.name} variant: [${clearDataCommand}]"
|
||||
def stdout = new ByteArrayOutputStream()
|
||||
exec {
|
||||
commandLine clearDataCommand
|
||||
standardOutput = stdout
|
||||
}
|
||||
String result = stdout.toString().trim()
|
||||
if (!result.startsWith("Success")) {
|
||||
println result
|
||||
throw new GradleException(clearDataCommand.join(" "))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Clear Application Data (once) before running instrumentation test
|
||||
tasks.whenTaskAdded { task ->
|
||||
// Both of these targets are equivalent today, although in future connectedCheck
|
||||
// will also include connectedUiAutomatorTest (not implemented yet)
|
||||
if(task.name == "connectedAndroidTest" || task.name == "connectedCheck"){
|
||||
task.dependsOn(clearMainAppData)
|
||||
}
|
||||
}
|
||||
*/
|
||||
clean.dependsOn full_clean
|
||||
preBuild.dependsOn copyLibs
|
||||
|
||||
|
|
|
@ -13,7 +13,12 @@
|
|||
"package_name": "info.nightscout.aapspumpcontrol"
|
||||
}
|
||||
},
|
||||
"oauth_client": [],
|
||||
"oauth_client": [
|
||||
{
|
||||
"client_id": "477603612366-a925drvlvs7qn7gt73r585erbqto8c79.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyDcZpDRMaGjdhihXp531cVYM6LkEL8KbgM"
|
||||
|
@ -37,7 +42,12 @@
|
|||
"package_name": "info.nightscout.androidaps"
|
||||
}
|
||||
},
|
||||
"oauth_client": [],
|
||||
"oauth_client": [
|
||||
{
|
||||
"client_id": "477603612366-a925drvlvs7qn7gt73r585erbqto8c79.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyDcZpDRMaGjdhihXp531cVYM6LkEL8KbgM"
|
||||
|
@ -61,7 +71,12 @@
|
|||
"package_name": "info.nightscout.nsclient"
|
||||
}
|
||||
},
|
||||
"oauth_client": [],
|
||||
"oauth_client": [
|
||||
{
|
||||
"client_id": "477603612366-a925drvlvs7qn7gt73r585erbqto8c79.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyDcZpDRMaGjdhihXp531cVYM6LkEL8KbgM"
|
||||
|
@ -85,7 +100,12 @@
|
|||
"package_name": "info.nightscout.nsclient2"
|
||||
}
|
||||
},
|
||||
"oauth_client": [],
|
||||
"oauth_client": [
|
||||
{
|
||||
"client_id": "477603612366-a925drvlvs7qn7gt73r585erbqto8c79.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyDcZpDRMaGjdhihXp531cVYM6LkEL8KbgM"
|
||||
|
|
BIN
app/libs/ustwo-clockwise-debug.aar
Normal file
BIN
app/libs/ustwo-clockwise-debug.aar
Normal file
Binary file not shown.
|
@ -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,35 @@
|
|||
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
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
import androidx.test.uiautomator.UiSelector
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
fun clickOkInDialog() {
|
||||
val uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
|
||||
val button = uiDevice.findObject(UiSelector().clickable(true).checkable(false).index(1))
|
||||
if (button.exists() && button.isEnabled) button.click()
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
package info.nightscout.androidaps
|
||||
|
||||
import android.os.SystemClock
|
||||
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.PluginBase
|
||||
import info.nightscout.androidaps.interfaces.PluginType
|
||||
import info.nightscout.androidaps.interfaces.PumpInterface
|
||||
import info.nightscout.androidaps.logging.L
|
||||
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.general.actions.ActionsPlugin
|
||||
import info.nightscout.androidaps.plugins.insulin.InsulinOrefUltraRapidActingPlugin
|
||||
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin
|
||||
import info.nightscout.androidaps.plugins.pump.danaRv2.DanaRv2Plugin
|
||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin
|
||||
import info.nightscout.androidaps.plugins.source.RandomBgPlugin
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.SP
|
||||
import info.nightscout.androidaps.utils.isRunningTest
|
||||
import org.json.JSONObject
|
||||
import org.junit.Assert
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
@LargeTest
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class RealPumpTest {
|
||||
|
||||
private val log = LoggerFactory.getLogger(L.CORE)
|
||||
|
||||
companion object {
|
||||
val pump: PumpInterface = DanaRv2Plugin.getPlugin()
|
||||
const val R_PASSWORD = 1234
|
||||
const val R_SERIAL = "PBB00013LR_P"
|
||||
}
|
||||
|
||||
private val validProfile = "{\"dia\":\"6\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"10\"},{\"time\":\"2:00\",\"value\":\"11\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}"
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
var mActivityTestRule = ActivityTestRule(MainActivity::class.java)
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
var mGrantPermissionRule: GrantPermissionRule =
|
||||
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()
|
||||
SP.putBoolean(R.string.key_setupwizard_processed, true)
|
||||
SP.putString(R.string.key_aps_mode, "closed")
|
||||
MainApp.getDbHelper().resetDatabases()
|
||||
MainApp.devBranch = false
|
||||
}
|
||||
|
||||
private fun preparePlugins() {
|
||||
// Source
|
||||
RandomBgPlugin.performPluginSwitch(true, PluginType.BGSOURCE)
|
||||
// Profile
|
||||
LocalProfilePlugin.performPluginSwitch(true, PluginType.PROFILE)
|
||||
val profile = Profile(JSONObject(validProfile), Constants.MGDL)
|
||||
Assert.assertTrue(profile.isValid("Test"))
|
||||
LocalProfilePlugin.profiles.clear()
|
||||
LocalProfilePlugin.numOfProfiles = 0
|
||||
val singleProfile = LocalProfilePlugin.SingleProfile().copyFrom(profile, "TestProfile")
|
||||
LocalProfilePlugin.addProfile(singleProfile)
|
||||
ProfileFunctions.doProfileSwitch(LocalProfilePlugin.createProfileStore(), "TestProfile", 0, 100, 0, DateUtil.now())
|
||||
// Insulin
|
||||
InsulinOrefUltraRapidActingPlugin.getPlugin().performPluginSwitch(true, PluginType.INSULIN)
|
||||
// Pump
|
||||
SP.putInt(R.string.key_danar_password, R_PASSWORD)
|
||||
SP.putString(R.string.key_danar_bt_name, R_SERIAL)
|
||||
(pump as PluginBase).performPluginSwitch(true, PluginType.PUMP)
|
||||
// Sensitivity
|
||||
SensitivityOref1Plugin.getPlugin().performPluginSwitch(true, PluginType.SENSITIVITY)
|
||||
// APS
|
||||
OpenAPSSMBPlugin.getPlugin().performPluginSwitch(true, PluginType.APS)
|
||||
LoopPlugin.getPlugin().performPluginSwitch(true, PluginType.LOOP)
|
||||
|
||||
// Enable common
|
||||
ActionsPlugin.performPluginSwitch(true, PluginType.GENERAL)
|
||||
|
||||
// Disable unneeded
|
||||
MainApp.getPluginsList().remove(ObjectivesPlugin)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun doTest() {
|
||||
Assert.assertTrue(isRunningTest())
|
||||
preparePlugins()
|
||||
|
||||
while (!pump.isInitialized) {
|
||||
log.debug("Waiting for initialization")
|
||||
SystemClock.sleep(1000)
|
||||
}
|
||||
|
||||
while (true) {
|
||||
log.debug("Tick")
|
||||
SystemClock.sleep(1000)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,231 @@
|
|||
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.isDisplayed
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withClassName
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withId
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withTagValue
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withText
|
||||
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.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 =
|
||||
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() {
|
||||
SP.clear()
|
||||
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())
|
||||
// Location 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())
|
||||
}
|
||||
// Import settings : skip of found
|
||||
askButton = onView(withText("IMPORT SETTINGS"))
|
||||
if (askButton.isDisplayed()) {
|
||||
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())
|
||||
// confirm dialog
|
||||
//onView(Matchers.allOf(withText("OK"), isDisplayed())).perform(click()) not working on real phone
|
||||
clickOkInDialog()
|
||||
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()) not working on real phone
|
||||
clickOkInDialog()
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -52,12 +52,11 @@
|
|||
</activity>
|
||||
<activity android:name=".activities.PreferencesActivity" />
|
||||
<activity
|
||||
android:name=".plugins.general.overview.dialogs.BolusProgressHelperActivity"
|
||||
android:name=".activities.BolusProgressHelperActivity"
|
||||
android:theme="@style/Theme.AppCompat.Translucent" />
|
||||
<activity
|
||||
android:name=".plugins.general.overview.dialogs.ErrorHelperActivity"
|
||||
android:name=".activities.ErrorHelperActivity"
|
||||
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.DanaRUserOptionsActivity" />
|
||||
<activity android:name=".activities.TDDStatsActivity" />
|
||||
|
@ -77,6 +76,8 @@
|
|||
</activity>
|
||||
<activity android:name=".plugins.pump.danaRS.activities.PairingHelperActivity" />
|
||||
<activity android:name=".activities.HistoryBrowseActivity" />
|
||||
<activity android:name=".activities.SurveyActivity" />
|
||||
<activity android:name=".activities.StatsActivity" />
|
||||
|
||||
<!-- Receive new BG readings from other local apps -->
|
||||
<receiver
|
||||
|
@ -115,7 +116,7 @@
|
|||
|
||||
<!-- Auto start -->
|
||||
<receiver
|
||||
android:name=".plugins.general.nsclient.receivers.AutoStartReceiver"
|
||||
android:name=".receivers.AutoStartReceiver"
|
||||
android:enabled="true"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
|
@ -123,16 +124,6 @@
|
|||
</intent-filter>
|
||||
</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 -->
|
||||
<receiver android:name=".receivers.NetworkChangeReceiver">
|
||||
<intent-filter>
|
||||
|
|
|
@ -1,2 +1,4 @@
|
|||
#Demo certificate
|
||||
51:6D:12:67:4C:27:F4:9B:9F:E5:42:9B:01:B3:98:E4:66:2B:85:B7:A8:DD:70:32:B7:6A:D7:97:9A:0D:97:10
|
||||
51:6D:12:67:4C:27:F4:9B:9F:E5:42:9B:01:B3:98:E4:66:2B:85:B7:A8:DD:70:32:B7:6A:D7:97:9A:0D:97:10
|
||||
#Leaked
|
||||
55:5D:70:C9:BE:10:41:7E:4B:01:A9:C4:C6:44:4A:F8:69:71:35:25:ED:95:23:16:C7:15:E8:EB:C6:08:FC:B1
|
||||
|
|
|
@ -25,8 +25,6 @@ public class Constants {
|
|||
public static final int hoursToKeepInDatabase = 72;
|
||||
public static final int daysToKeepHistoryInDatabase = 30;
|
||||
|
||||
public static final long keepAliveMsecs = 5 * 60 * 1000L;
|
||||
|
||||
// SMS COMMUNICATOR
|
||||
public static final long remoteBolusMinDistance = 15 * 60 * 1000L;
|
||||
|
||||
|
@ -78,4 +76,15 @@ public class Constants {
|
|||
//Storage [MB]
|
||||
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;
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -37,12 +37,11 @@ import com.joanzapata.iconify.fonts.FontAwesomeModule;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.activities.AgreementActivity;
|
||||
import info.nightscout.androidaps.activities.HistoryBrowseActivity;
|
||||
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity;
|
||||
import info.nightscout.androidaps.activities.PreferencesActivity;
|
||||
import info.nightscout.androidaps.activities.SingleFragmentActivity;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.activities.StatsActivity;
|
||||
import info.nightscout.androidaps.events.EventAppExit;
|
||||
import info.nightscout.androidaps.events.EventPreferenceChange;
|
||||
import info.nightscout.androidaps.events.EventRebuildTabs;
|
||||
|
@ -51,7 +50,6 @@ import info.nightscout.androidaps.interfaces.PluginType;
|
|||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin;
|
||||
import info.nightscout.androidaps.plugins.bus.RxBus;
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
|
||||
import info.nightscout.androidaps.plugins.constraints.versionChecker.VersionCheckerUtilsKt;
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus;
|
||||
import info.nightscout.androidaps.setupwizard.SetupWizardActivity;
|
||||
|
@ -65,6 +63,8 @@ import info.nightscout.androidaps.utils.SP;
|
|||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.CompositeDisposable;
|
||||
|
||||
import static info.nightscout.androidaps.utils.EspressoTestHelperKt.isRunningRealPumpTest;
|
||||
|
||||
public class MainActivity extends NoSplashAppCompatActivity {
|
||||
private static Logger log = LoggerFactory.getLogger(L.CORE);
|
||||
private CompositeDisposable disposable = new CompositeDisposable();
|
||||
|
@ -94,8 +94,6 @@ public class MainActivity extends NoSplashAppCompatActivity {
|
|||
// initialize screen wake lock
|
||||
processPreferenceChange(new EventPreferenceChange(R.string.key_keep_screen_on));
|
||||
|
||||
doMigrations();
|
||||
|
||||
final ViewPager viewPager = findViewById(R.id.pager);
|
||||
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
|
||||
@Override
|
||||
|
@ -141,11 +139,9 @@ public class MainActivity extends NoSplashAppCompatActivity {
|
|||
.subscribe(this::processPreferenceChange, FabricPrivacy::logException)
|
||||
);
|
||||
|
||||
if (!SP.getBoolean(R.string.key_setupwizard_processed, false)) {
|
||||
if (!SP.getBoolean(R.string.key_setupwizard_processed, false) && !isRunningRealPumpTest()) {
|
||||
Intent intent = new Intent(this, SetupWizardActivity.class);
|
||||
startActivity(intent);
|
||||
} else {
|
||||
checkEula();
|
||||
}
|
||||
|
||||
AndroidPermission.notifyForStoragePermission(this);
|
||||
|
@ -153,6 +149,7 @@ public class MainActivity extends NoSplashAppCompatActivity {
|
|||
if (Config.PUMPDRIVERS) {
|
||||
AndroidPermission.notifyForLocationPermissions(this);
|
||||
AndroidPermission.notifyForSMSPermissions(this);
|
||||
AndroidPermission.notifyForSystemWindowPermissions(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -237,49 +234,6 @@ public class MainActivity extends NoSplashAppCompatActivity {
|
|||
}
|
||||
}
|
||||
|
||||
private void checkEula() {
|
||||
//SP.removeBoolean(R.string.key_i_understand);
|
||||
boolean IUnderstand = SP.getBoolean(R.string.key_i_understand, false);
|
||||
if (!IUnderstand) {
|
||||
Intent intent = new Intent(getApplicationContext(), AgreementActivity.class);
|
||||
startActivity(intent);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
private void doMigrations() {
|
||||
|
||||
checkUpgradeToProfileTarget();
|
||||
|
||||
// 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));
|
||||
}
|
||||
|
||||
|
||||
private void checkUpgradeToProfileTarget() { // TODO: can be removed in the future
|
||||
boolean oldKeyExists = SP.contains("openapsma_min_bg");
|
||||
if (oldKeyExists) {
|
||||
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||
String oldRange = SP.getDouble("openapsma_min_bg", 0d) + " - " + SP.getDouble("openapsma_max_bg", 0d);
|
||||
String newRange = "";
|
||||
if (profile != null) {
|
||||
newRange = profile.getTargetLow() + " - " + profile.getTargetHigh();
|
||||
}
|
||||
String message = "Target range is changed in current version.\n\nIt's not taken from preferences but from profile.\n\n!!! REVIEW YOUR SETTINGS !!!";
|
||||
message += "\n\nOld settings: " + oldRange;
|
||||
message += "\nProfile settings: " + newRange;
|
||||
OKDialog.show(this, "Target range change", message, () -> {
|
||||
SP.remove("openapsma_min_bg");
|
||||
SP.remove("openapsma_max_bg");
|
||||
SP.remove("openapsma_target_bg");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
|
@ -288,15 +242,13 @@ public class MainActivity extends NoSplashAppCompatActivity {
|
|||
switch (requestCode) {
|
||||
case AndroidPermission.CASE_STORAGE:
|
||||
//show dialog after permission is granted
|
||||
AlertDialog.Builder alert = new AlertDialog.Builder(this);
|
||||
alert.setMessage(R.string.alert_dialog_storage_permission_text);
|
||||
alert.setPositiveButton(R.string.ok, null);
|
||||
alert.show();
|
||||
OKDialog.show(this, "", MainApp.gs(R.string.alert_dialog_storage_permission_text));
|
||||
break;
|
||||
case AndroidPermission.CASE_LOCATION:
|
||||
case AndroidPermission.CASE_SMS:
|
||||
case AndroidPermission.CASE_BATTERY:
|
||||
case AndroidPermission.CASE_PHONE_STATE:
|
||||
case AndroidPermission.CASE_SYSTEM_WINDOW:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -365,9 +317,7 @@ public class MainActivity extends NoSplashAppCompatActivity {
|
|||
return true;
|
||||
case R.id.nav_exit:
|
||||
log.debug("Exiting");
|
||||
MainApp.instance().stopKeepAliveService();
|
||||
RxBus.INSTANCE.send(new EventAppExit());
|
||||
MainApp.closeDbHelper();
|
||||
finish();
|
||||
System.runFinalization();
|
||||
System.exit(0);
|
||||
|
@ -381,6 +331,14 @@ public class MainActivity extends NoSplashAppCompatActivity {
|
|||
startActivity(i);
|
||||
}, null);
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
package info.nightscout.androidaps;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.res.Resources;
|
||||
import android.os.SystemClock;
|
||||
|
||||
import androidx.annotation.ColorRes;
|
||||
import androidx.annotation.PluralsRes;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
|
||||
import com.crashlytics.android.Crashlytics;
|
||||
|
@ -15,6 +17,7 @@ import com.j256.ormlite.android.apptools.OpenHelperManager;
|
|||
|
||||
import net.danlew.android.joda.JodaTimeAndroid;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -22,6 +25,7 @@ import java.io.File;
|
|||
import java.util.ArrayList;
|
||||
|
||||
import info.nightscout.androidaps.data.ConstraintChecker;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.db.DatabaseHelper;
|
||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
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.openAPSSMB.OpenAPSSMBPlugin;
|
||||
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.objectives.ObjectivesPlugin;
|
||||
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.nsclient.NSClientPlugin;
|
||||
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.persistentNotification.PersistentNotificationPlugin;
|
||||
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin;
|
||||
|
@ -59,7 +62,6 @@ import info.nightscout.androidaps.plugins.insulin.InsulinOrefUltraRapidActingPlu
|
|||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
|
||||
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin;
|
||||
import info.nightscout.androidaps.plugins.profile.ns.NSProfilePlugin;
|
||||
import info.nightscout.androidaps.plugins.profile.simple.SimpleProfilePlugin;
|
||||
import info.nightscout.androidaps.plugins.pump.combo.ComboPlugin;
|
||||
import info.nightscout.androidaps.plugins.pump.danaR.DanaRPlugin;
|
||||
import info.nightscout.androidaps.plugins.pump.danaRKorean.DanaRKoreanPlugin;
|
||||
|
@ -74,6 +76,7 @@ import info.nightscout.androidaps.plugins.sensitivity.SensitivityAAPSPlugin;
|
|||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref0Plugin;
|
||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin;
|
||||
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.SourceEversensePlugin;
|
||||
import info.nightscout.androidaps.plugins.source.SourceGlimpPlugin;
|
||||
|
@ -88,8 +91,10 @@ import info.nightscout.androidaps.receivers.KeepAliveReceiver;
|
|||
import info.nightscout.androidaps.receivers.NSAlarmReceiver;
|
||||
import info.nightscout.androidaps.receivers.TimeDateOrTZChangeReceiver;
|
||||
import info.nightscout.androidaps.services.Intents;
|
||||
import info.nightscout.androidaps.utils.ActivityMonitor;
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy;
|
||||
import info.nightscout.androidaps.utils.LocaleHelper;
|
||||
import info.nightscout.androidaps.utils.SP;
|
||||
import io.fabric.sdk.android.Fabric;
|
||||
|
||||
import static info.nightscout.androidaps.plugins.constraints.versionChecker.VersionCheckerUtilsKt.triggerCheckVersion;
|
||||
|
@ -97,7 +102,6 @@ import static info.nightscout.androidaps.plugins.constraints.versionChecker.Vers
|
|||
|
||||
public class MainApp extends Application {
|
||||
private static Logger log = LoggerFactory.getLogger(L.CORE);
|
||||
private static KeepAliveReceiver keepAliveReceiver;
|
||||
|
||||
private static MainApp sInstance;
|
||||
public static Resources sResources;
|
||||
|
@ -110,11 +114,7 @@ public class MainApp extends Application {
|
|||
private static ArrayList<PluginBase> pluginsList = null;
|
||||
|
||||
private static DataReceiver dataReceiver = new DataReceiver();
|
||||
private static NSAlarmReceiver alarmReciever = new NSAlarmReceiver();
|
||||
private static AckAlarmReceiver ackAlarmReciever = new AckAlarmReceiver();
|
||||
private static DBAccessReceiver dbAccessReciever = new DBAccessReceiver();
|
||||
private LocalBroadcastManager lbm;
|
||||
BroadcastReceiver btReceiver;
|
||||
private static NSAlarmReceiver alarmReceiver = new NSAlarmReceiver();
|
||||
TimeDateOrTZChangeReceiver timeDateOrTZChangeReceiver;
|
||||
|
||||
public static boolean devBranch;
|
||||
|
@ -147,6 +147,8 @@ public class MainApp extends Application {
|
|||
log.error("Error with Fabric init! " + e);
|
||||
}
|
||||
|
||||
registerActivityLifecycleCallbacks(ActivityMonitor.INSTANCE);
|
||||
|
||||
mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
|
||||
mFirebaseAnalytics.setAnalyticsCollectionEnabled(!Boolean.getBoolean("disableFirebase"));
|
||||
|
||||
|
@ -166,7 +168,6 @@ public class MainApp extends Application {
|
|||
|
||||
//trigger here to see the new version on app start after an update
|
||||
triggerCheckVersion();
|
||||
//setBTReceiver();
|
||||
|
||||
if (pluginsList == null) {
|
||||
pluginsList = new ArrayList<>();
|
||||
|
@ -192,14 +193,13 @@ public class MainApp extends Application {
|
|||
pluginsList.add(OmnipodPumpPlugin.getPlugin());
|
||||
if (!Config.NSCLIENT) pluginsList.add(MDIPlugin.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(OpenAPSMAPlugin.getPlugin());
|
||||
if (Config.APS) pluginsList.add(OpenAPSAMAPlugin.getPlugin());
|
||||
if (Config.APS) pluginsList.add(OpenAPSSMBPlugin.getPlugin());
|
||||
pluginsList.add(NSProfilePlugin.getPlugin());
|
||||
if (!Config.NSCLIENT) pluginsList.add(SimpleProfilePlugin.getPlugin());
|
||||
if (!Config.NSCLIENT) pluginsList.add(LocalProfilePlugin.getPlugin());
|
||||
if (!Config.NSCLIENT) pluginsList.add(LocalProfilePlugin.INSTANCE);
|
||||
pluginsList.add(TreatmentsPlugin.getPlugin());
|
||||
if (!Config.NSCLIENT) pluginsList.add(SafetyPlugin.getPlugin());
|
||||
if (!Config.NSCLIENT) pluginsList.add(VersionCheckerPlugin.INSTANCE);
|
||||
|
@ -214,6 +214,7 @@ public class MainApp extends Application {
|
|||
pluginsList.add(SourcePoctechPlugin.getPlugin());
|
||||
pluginsList.add(SourceTomatoPlugin.getPlugin());
|
||||
pluginsList.add(SourceEversensePlugin.getPlugin());
|
||||
pluginsList.add(RandomBgPlugin.INSTANCE);
|
||||
if (!Config.NSCLIENT) pluginsList.add(SmsCommunicatorPlugin.INSTANCE);
|
||||
pluginsList.add(FoodPlugin.getPlugin());
|
||||
|
||||
|
@ -240,13 +241,40 @@ public class MainApp extends Application {
|
|||
new Thread(() -> {
|
||||
SystemClock.sleep(5000);
|
||||
ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("Initialization", null);
|
||||
startKeepAliveService();
|
||||
}).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() {
|
||||
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_CHANGED_TREATMENT));
|
||||
lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_REMOVED_TREATMENT));
|
||||
|
@ -261,39 +289,21 @@ public class MainApp extends Application {
|
|||
lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_NEW_CAL));
|
||||
|
||||
//register alarms
|
||||
lbm.registerReceiver(alarmReciever, new IntentFilter(Intents.ACTION_ALARM));
|
||||
lbm.registerReceiver(alarmReciever, new IntentFilter(Intents.ACTION_ANNOUNCEMENT));
|
||||
lbm.registerReceiver(alarmReciever, new IntentFilter(Intents.ACTION_CLEAR_ALARM));
|
||||
lbm.registerReceiver(alarmReciever, 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));
|
||||
lbm.registerReceiver(alarmReceiver, new IntentFilter(Intents.ACTION_ALARM));
|
||||
lbm.registerReceiver(alarmReceiver, new IntentFilter(Intents.ACTION_ANNOUNCEMENT));
|
||||
lbm.registerReceiver(alarmReceiver, new IntentFilter(Intents.ACTION_CLEAR_ALARM));
|
||||
lbm.registerReceiver(alarmReceiver, new IntentFilter(Intents.ACTION_URGENT_ALARM));
|
||||
|
||||
this.timeDateOrTZChangeReceiver = new TimeDateOrTZChangeReceiver();
|
||||
this.timeDateOrTZChangeReceiver.registerBroadcasts(this);
|
||||
|
||||
}
|
||||
|
||||
private void startKeepAliveService() {
|
||||
if (keepAliveReceiver == null) {
|
||||
keepAliveReceiver = new KeepAliveReceiver();
|
||||
keepAliveReceiver.setAlarm(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void stopKeepAliveService() {
|
||||
if (keepAliveReceiver != null)
|
||||
KeepAliveReceiver.cancelAlarm(this);
|
||||
}
|
||||
|
||||
public static String gs(int id) {
|
||||
public static String gs(@StringRes int 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);
|
||||
}
|
||||
|
||||
|
@ -301,8 +311,8 @@ public class MainApp extends Application {
|
|||
return sResources.getQuantityString(id, quantity, args);
|
||||
}
|
||||
|
||||
public static int gc(int id) {
|
||||
return sResources.getColor(id);
|
||||
public static int gc(@ColorRes int id) {
|
||||
return ContextCompat.getColor(instance(), id);
|
||||
}
|
||||
|
||||
public static MainApp instance() {
|
||||
|
@ -313,13 +323,6 @@ public class MainApp extends Application {
|
|||
return sDatabaseHelper;
|
||||
}
|
||||
|
||||
public static void closeDbHelper() {
|
||||
if (sDatabaseHelper != null) {
|
||||
sDatabaseHelper.close();
|
||||
sDatabaseHelper = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static FirebaseAnalytics getFirebaseAnalytics() {
|
||||
return mFirebaseAnalytics;
|
||||
}
|
||||
|
@ -422,20 +425,12 @@ public class MainApp extends Application {
|
|||
public void onTerminate() {
|
||||
if (L.isEnabled(L.CORE))
|
||||
log.debug("onTerminate");
|
||||
super.onTerminate();
|
||||
if (sDatabaseHelper != null) {
|
||||
sDatabaseHelper.close();
|
||||
sDatabaseHelper = null;
|
||||
}
|
||||
|
||||
if (btReceiver != null) {
|
||||
unregisterReceiver(btReceiver);
|
||||
}
|
||||
|
||||
if (timeDateOrTZChangeReceiver != null) {
|
||||
if (timeDateOrTZChangeReceiver != null)
|
||||
unregisterReceiver(timeDateOrTZChangeReceiver);
|
||||
}
|
||||
|
||||
unregisterActivityLifecycleCallbacks(ActivityMonitor.INSTANCE);
|
||||
KeepAliveReceiver.cancelAlarm(this);
|
||||
super.onTerminate();
|
||||
}
|
||||
|
||||
public static int dpToPx(int dp) {
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
package info.nightscout.androidaps.activities;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
|
||||
import info.nightscout.androidaps.MainActivity;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.utils.SP;
|
||||
|
||||
public class AgreementActivity extends NoSplashActivity {
|
||||
boolean IUnderstand;
|
||||
CheckBox agreeCheckBox;
|
||||
Button saveButton;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_agreement);
|
||||
IUnderstand = SP.getBoolean(R.string.key_i_understand, false);
|
||||
setContentView(R.layout.activity_agreement);
|
||||
agreeCheckBox = (CheckBox)findViewById(R.id.agreementCheckBox);
|
||||
agreeCheckBox.setChecked(IUnderstand);
|
||||
saveButton = (Button)findViewById(R.id.agreementSaveButton);
|
||||
addListenerOnButton();
|
||||
}
|
||||
|
||||
public void addListenerOnButton() {
|
||||
saveButton.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
|
||||
SP.putBoolean(R.string.key_i_understand, agreeCheckBox.isChecked());
|
||||
|
||||
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
|
||||
startActivity(intent);
|
||||
finish();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
}
|
|
@ -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 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.utils.SP
|
||||
|
||||
class ErrorHelperActivity : NoSplashAppCompatActivity() {
|
||||
class ErrorHelperActivity : DialogAppCompatActivity() {
|
||||
|
||||
@Override
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
|
@ -45,7 +45,7 @@ import info.nightscout.androidaps.utils.T;
|
|||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.CompositeDisposable;
|
||||
|
||||
public class HistoryBrowseActivity extends NoSplashActivity {
|
||||
public class HistoryBrowseActivity extends NoSplashAppCompatActivity {
|
||||
private static Logger log = LoggerFactory.getLogger(HistoryBrowseActivity.class);
|
||||
private CompositeDisposable disposable = new CompositeDisposable();
|
||||
|
||||
|
@ -150,7 +150,7 @@ public class HistoryBrowseActivity extends NoSplashActivity {
|
|||
);
|
||||
dpd.setThemeDark(true);
|
||||
dpd.dismissOnPause(true);
|
||||
dpd.show(getFragmentManager(), "Datepickerdialog");
|
||||
dpd.show(getSupportFragmentManager(), "Datepickerdialog");
|
||||
});
|
||||
|
||||
bgGraph.getGridLabelRenderer().setGridColor(MainApp.gc(R.color.graphgrid));
|
||||
|
@ -231,9 +231,8 @@ public class HistoryBrowseActivity extends NoSplashActivity {
|
|||
noProfile.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
final String units = profile.getUnits();
|
||||
final double lowLine = OverviewPlugin.INSTANCE.determineLowLine(units);
|
||||
final double highLine = OverviewPlugin.INSTANCE.determineHighLine(units);
|
||||
final double lowLine = OverviewPlugin.INSTANCE.determineLowLine();
|
||||
final double highLine = OverviewPlugin.INSTANCE.determineHighLine();
|
||||
|
||||
buttonDate.setText(DateUtil.dateAndTimeString(start));
|
||||
buttonZoom.setText(String.valueOf(rangeToDisplay));
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
package info.nightscout.androidaps.activities
|
||||
|
||||
import android.app.Activity
|
||||
import android.os.Bundle
|
||||
|
||||
import info.nightscout.androidaps.R
|
||||
|
||||
open class NoSplashActivity : Activity() {
|
||||
public override fun onCreate(savedInstanceState: Bundle?) {
|
||||
setTheme(R.style.AppTheme_NoActionBar)
|
||||
super.onCreate(savedInstanceState)
|
||||
}
|
||||
}
|
|
@ -1,12 +1,18 @@
|
|||
package info.nightscout.androidaps.activities
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.utils.LocaleHelper
|
||||
|
||||
open class NoSplashAppCompatActivity : AppCompatActivity() {
|
||||
public override fun onCreate(savedInstanceState: Bundle?) {
|
||||
setTheme(R.style.AppTheme_NoActionBar)
|
||||
super.onCreate(savedInstanceState)
|
||||
}
|
||||
|
||||
public override fun attachBaseContext(newBase: Context) {
|
||||
super.attachBaseContext(LocaleHelper.wrap(newBase))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package info.nightscout.androidaps.activities;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.preference.EditTextPreference;
|
||||
|
@ -12,9 +13,12 @@ import android.preference.PreferenceManager;
|
|||
import android.preference.PreferenceScreen;
|
||||
import android.preference.SwitchPreference;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import info.nightscout.androidaps.Config;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.events.EventPreferenceChange;
|
||||
import info.nightscout.androidaps.events.EventRebuildTabs;
|
||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
|
@ -48,8 +52,10 @@ import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref0Plugin;
|
|||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin;
|
||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityWeightedAveragePlugin;
|
||||
import info.nightscout.androidaps.plugins.source.SourceDexcomPlugin;
|
||||
import info.nightscout.androidaps.utils.LocaleHelper;
|
||||
import info.nightscout.androidaps.utils.OKDialog;
|
||||
import info.nightscout.androidaps.utils.SP;
|
||||
import info.nightscout.androidaps.utils.SafeParse;
|
||||
|
||||
public class PreferencesActivity extends PreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
MyPreferenceFragment myPreferenceFragment;
|
||||
|
@ -66,23 +72,49 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
|
|||
PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attachBaseContext(Context newBase) {
|
||||
super.attachBaseContext(LocaleHelper.INSTANCE.wrap(newBase));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||
RxBus.INSTANCE.send(new EventPreferenceChange(key));
|
||||
if (key.equals("language")) {
|
||||
if (key.equals(MainApp.gs(R.string.key_language))) {
|
||||
RxBus.INSTANCE.send(new EventRebuildTabs(true));
|
||||
//recreate() does not update language so better close settings
|
||||
finish();
|
||||
}
|
||||
if (key.equals("short_tabtitles")) {
|
||||
if (key.equals(MainApp.gs(R.string.key_short_tabtitles))) {
|
||||
RxBus.INSTANCE.send(new EventRebuildTabs());
|
||||
}
|
||||
if (key.equals(MainApp.gs(R.string.key_units))) {
|
||||
recreate();
|
||||
return;
|
||||
}
|
||||
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));
|
||||
}
|
||||
|
||||
private static void adjustUnitDependentPrefs(Preference pref) {
|
||||
// convert preferences values to current units
|
||||
String[] unitDependent = new String[]{
|
||||
MainApp.gs(R.string.key_hypo_target),
|
||||
MainApp.gs(R.string.key_activity_target),
|
||||
MainApp.gs(R.string.key_eatingsoon_target),
|
||||
MainApp.gs(R.string.key_high_mark),
|
||||
MainApp.gs(R.string.key_low_mark)
|
||||
};
|
||||
if (Arrays.asList(unitDependent).contains(pref.getKey())) {
|
||||
EditTextPreference editTextPref = (EditTextPreference) pref;
|
||||
String converted = Profile.toCurrentUnitsString(SafeParse.stringToDouble(editTextPref.getText()));
|
||||
editTextPref.setSummary(converted);
|
||||
editTextPref.setText(converted);
|
||||
}
|
||||
}
|
||||
|
||||
private static void updatePrefSummary(Preference pref) {
|
||||
if (pref instanceof ListPreference) {
|
||||
ListPreference listPref = (ListPreference) pref;
|
||||
|
@ -101,6 +133,8 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
|
|||
}
|
||||
}
|
||||
}
|
||||
if (pref != null)
|
||||
adjustUnitDependentPrefs(pref);
|
||||
}
|
||||
|
||||
public static void initSummary(Preference p) {
|
||||
|
@ -143,8 +177,8 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
|
|||
if (!Config.NSCLIENT) {
|
||||
addPreferencesFromResource(R.xml.pref_password);
|
||||
}
|
||||
addPreferencesFromResource(R.xml.pref_general);
|
||||
addPreferencesFromResource(R.xml.pref_age);
|
||||
addPreferencesFromResource(R.xml.pref_language);
|
||||
|
||||
addPreferencesFromResource(R.xml.pref_overview);
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ package info.nightscout.androidaps.activities
|
|||
import android.os.Bundle
|
||||
import info.nightscout.androidaps.plugins.source.SourceDexcomPlugin
|
||||
|
||||
class RequestDexcomPermissionActivity : NoSplashAppCompatActivity() {
|
||||
class RequestDexcomPermissionActivity : DialogAppCompatActivity() {
|
||||
|
||||
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"
|
||||
}
|
||||
|
||||
}
|
|
@ -54,7 +54,7 @@ import info.nightscout.androidaps.utils.SafeParse;
|
|||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.CompositeDisposable;
|
||||
|
||||
public class TDDStatsActivity extends NoSplashActivity {
|
||||
public class TDDStatsActivity extends NoSplashAppCompatActivity {
|
||||
private static Logger log = LoggerFactory.getLogger(TDDStatsActivity.class);
|
||||
private CompositeDisposable disposable = new CompositeDisposable();
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package info.nightscout.androidaps.data;
|
||||
|
||||
import com.rits.cloning.Cloner;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -37,8 +35,19 @@ public class IobTotal implements DataPointWithLabelInterface {
|
|||
|
||||
|
||||
public IobTotal copy() {
|
||||
Cloner cloner = new Cloner();
|
||||
return cloner.deepClone(this);
|
||||
IobTotal i = new IobTotal(time);
|
||||
i.iob = iob;
|
||||
i.activity = activity;
|
||||
i.bolussnooze = bolussnooze;
|
||||
i.basaliob = basaliob;
|
||||
i.netbasalinsulin = netbasalinsulin;
|
||||
i.hightempinsulin = hightempinsulin;
|
||||
i.lastBolusTime = lastBolusTime;
|
||||
if (iobWithZeroTemp != null) i.iobWithZeroTemp = iobWithZeroTemp.copy();
|
||||
i.netInsulin = netInsulin;
|
||||
i.netRatio = netRatio;
|
||||
i.extendedBolusInsulin = extendedBolusInsulin;
|
||||
return i;
|
||||
}
|
||||
|
||||
public IobTotal(long time) {
|
||||
|
@ -137,7 +146,7 @@ public class IobTotal implements DataPointWithLabelInterface {
|
|||
|
||||
// DataPoint interface
|
||||
|
||||
int color;
|
||||
private int color;
|
||||
|
||||
@Override
|
||||
public double getX() {
|
||||
|
|
|
@ -19,6 +19,7 @@ import info.nightscout.androidaps.interfaces.PumpDescription;
|
|||
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||
import info.nightscout.androidaps.plugins.bus.RxBus;
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
|
||||
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification;
|
||||
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
|
||||
import info.nightscout.androidaps.utils.DateUtil;
|
||||
|
@ -76,6 +77,11 @@ public class Profile {
|
|||
}
|
||||
}
|
||||
|
||||
// Constructor from profileStore JSON
|
||||
public Profile(JSONObject json) {
|
||||
init(json, 100, 0);
|
||||
}
|
||||
|
||||
public Profile(JSONObject json, int percentage, int timeshift) {
|
||||
init(json, percentage, timeshift);
|
||||
}
|
||||
|
@ -101,8 +107,6 @@ public class Profile {
|
|||
units = json.getString("units").toLowerCase();
|
||||
if (json.has("dia"))
|
||||
dia = json.getDouble("dia");
|
||||
if (json.has("dia"))
|
||||
dia = json.getDouble("dia");
|
||||
if (json.has("timezone"))
|
||||
timeZone = TimeZone.getTimeZone(json.getString("timezone"));
|
||||
isf = json.getJSONArray("sens");
|
||||
|
@ -150,7 +154,7 @@ public class Profile {
|
|||
return units;
|
||||
}
|
||||
|
||||
public TimeZone getTimeZone() {
|
||||
TimeZone getTimeZone() {
|
||||
return timeZone;
|
||||
}
|
||||
|
||||
|
@ -163,7 +167,7 @@ public class Profile {
|
|||
double multiplier = getMultiplier(array);
|
||||
|
||||
LongSparseArray<Double> sparse = new LongSparseArray<>();
|
||||
for (Integer index = 0; index < array.length(); index++) {
|
||||
for (int index = 0; index < array.length(); index++) {
|
||||
try {
|
||||
final JSONObject o = array.getJSONObject(index);
|
||||
long tas = 0;
|
||||
|
@ -386,15 +390,15 @@ public class Profile {
|
|||
return retValue;
|
||||
}
|
||||
|
||||
public double getIsf() {
|
||||
return getIsfTimeFromMidnight(secondsFromMidnight());
|
||||
public double getIsfMgdl() {
|
||||
return toMgdl(getIsfTimeFromMidnight(secondsFromMidnight()), units);
|
||||
}
|
||||
|
||||
public double getIsf(long time) {
|
||||
return getIsfTimeFromMidnight(secondsFromMidnight(time));
|
||||
public double getIsfMgdl(long time) {
|
||||
return toMgdl(getIsfTimeFromMidnight(secondsFromMidnight(time)), units);
|
||||
}
|
||||
|
||||
double getIsfTimeFromMidnight(int timeAsSeconds) {
|
||||
public double getIsfTimeFromMidnight(int timeAsSeconds) {
|
||||
if (isf_v == null)
|
||||
isf_v = convertToSparseArray(isf);
|
||||
return getValueToTime(isf_v, timeAsSeconds);
|
||||
|
@ -406,15 +410,15 @@ public class Profile {
|
|||
return getValuesList(isf_v, null, new DecimalFormat("0.0"), getUnits() + MainApp.gs(R.string.profile_per_unit));
|
||||
}
|
||||
|
||||
public ProfileValue[] getIsfs() {
|
||||
public ProfileValue[] getIsfsMgdl() {
|
||||
if (isf_v == null)
|
||||
isf_v = convertToSparseArray(ic);
|
||||
ProfileValue[] ret = new ProfileValue[isf_v.size()];
|
||||
|
||||
for (Integer index = 0; index < isf_v.size(); index++) {
|
||||
Integer tas = (int) isf_v.keyAt(index);
|
||||
for (int index = 0; index < isf_v.size(); index++) {
|
||||
int tas = (int) isf_v.keyAt(index);
|
||||
double value = isf_v.valueAt(index);
|
||||
ret[index] = new ProfileValue(tas, value);
|
||||
ret[index] = new ProfileValue(tas, toMgdl(value, units));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -507,44 +511,44 @@ public class Profile {
|
|||
return ret;
|
||||
}
|
||||
|
||||
public double getTarget() {
|
||||
return getTarget(secondsFromMidnight());
|
||||
public double getTargetMgdl() {
|
||||
return getTargetMgdl(secondsFromMidnight());
|
||||
}
|
||||
|
||||
protected double getTarget(int timeAsSeconds) {
|
||||
return (getTargetLowTimeFromMidnight(timeAsSeconds) + getTargetHighTimeFromMidnight(timeAsSeconds)) / 2;
|
||||
public double getTargetMgdl(int timeAsSeconds) {
|
||||
return toMgdl((getTargetLowTimeFromMidnight(timeAsSeconds) + getTargetHighTimeFromMidnight(timeAsSeconds)) / 2, units);
|
||||
}
|
||||
|
||||
public double getTargetLow() {
|
||||
return getTargetLowTimeFromMidnight(secondsFromMidnight());
|
||||
public double getTargetLowMgdl() {
|
||||
return toMgdl(getTargetLowTimeFromMidnight(secondsFromMidnight()), units);
|
||||
}
|
||||
|
||||
public double getTargetLow(long time) {
|
||||
return getTargetLowTimeFromMidnight(secondsFromMidnight(time));
|
||||
public double getTargetLowMgdl(long time) {
|
||||
return toMgdl(getTargetLowTimeFromMidnight(secondsFromMidnight(time)), units);
|
||||
}
|
||||
|
||||
public double getTargetLowTimeFromMidnight(int timeAsSeconds) {
|
||||
double getTargetLowTimeFromMidnight(int timeAsSeconds) {
|
||||
if (targetLow_v == null)
|
||||
targetLow_v = convertToSparseArray(targetLow);
|
||||
return getValueToTime(targetLow_v, timeAsSeconds);
|
||||
}
|
||||
|
||||
public double getTargetHigh() {
|
||||
return getTargetHighTimeFromMidnight(secondsFromMidnight());
|
||||
public double getTargetHighMgdl() {
|
||||
return toMgdl(getTargetHighTimeFromMidnight(secondsFromMidnight()), units);
|
||||
}
|
||||
|
||||
public double getTargetHigh(long time) {
|
||||
return getTargetHighTimeFromMidnight(secondsFromMidnight(time));
|
||||
public double getTargetHighMgdl(long time) {
|
||||
return toMgdl(getTargetHighTimeFromMidnight(secondsFromMidnight(time)), units);
|
||||
}
|
||||
|
||||
public double getTargetHighTimeFromMidnight(int timeAsSeconds) {
|
||||
double getTargetHighTimeFromMidnight(int timeAsSeconds) {
|
||||
if (targetHigh_v == null)
|
||||
targetHigh_v = convertToSparseArray(targetHigh);
|
||||
return getValueToTime(targetHigh_v, timeAsSeconds);
|
||||
}
|
||||
|
||||
public class TargetValue {
|
||||
public TargetValue(int timeAsSeconds, double low, double high) {
|
||||
TargetValue(int timeAsSeconds, double low, double high) {
|
||||
this.timeAsSeconds = timeAsSeconds;
|
||||
this.low = low;
|
||||
this.high = high;
|
||||
|
@ -571,17 +575,17 @@ public class Profile {
|
|||
return ret;
|
||||
}
|
||||
|
||||
public ProfileValue[] getSingleTargets() {
|
||||
public ProfileValue[] getSingleTargetsMgdl() {
|
||||
if (targetLow_v == null)
|
||||
targetLow_v = convertToSparseArray(targetLow);
|
||||
if (targetHigh_v == null)
|
||||
targetHigh_v = convertToSparseArray(targetHigh);
|
||||
ProfileValue[] ret = new ProfileValue[targetLow_v.size()];
|
||||
|
||||
for (Integer index = 0; index < targetLow_v.size(); index++) {
|
||||
Integer tas = (int) targetLow_v.keyAt(index);
|
||||
for (int index = 0; index < targetLow_v.size(); index++) {
|
||||
int tas = (int) targetLow_v.keyAt(index);
|
||||
double target = (targetLow_v.valueAt(index) + targetHigh_v.valueAt(index)) / 2;
|
||||
ret[index] = new ProfileValue(tas, target);
|
||||
ret[index] = new ProfileValue(tas, toMgdl(target, units));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -597,7 +601,7 @@ public class Profile {
|
|||
public double getMaxDailyBasal() {
|
||||
double max = 0d;
|
||||
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;
|
||||
}
|
||||
return max;
|
||||
|
@ -629,22 +633,39 @@ public class Profile {
|
|||
else return value * Constants.MGDL_TO_MMOLL;
|
||||
}
|
||||
|
||||
public static double toUnits(Double valueInMgdl, Double valueInMmol, String units) {
|
||||
public static double fromMmolToUnits(double value, String units) {
|
||||
if (units.equals(Constants.MMOL)) return value;
|
||||
else return value * Constants.MMOLL_TO_MGDL;
|
||||
}
|
||||
|
||||
public static double toUnits(double valueInMgdl, double valueInMmol, String units) {
|
||||
if (units.equals(Constants.MGDL)) return valueInMgdl;
|
||||
else return valueInMmol;
|
||||
}
|
||||
|
||||
public static String toUnitsString(Double valueInMgdl, Double valueInMmol, String units) {
|
||||
public static String toUnitsString(double valueInMgdl, double valueInMmol, String units) {
|
||||
if (units.equals(Constants.MGDL)) return DecimalFormatter.to0Decimal(valueInMgdl);
|
||||
else return DecimalFormatter.to1Decimal(valueInMmol);
|
||||
}
|
||||
|
||||
public static String toSignedUnitsString(Double valueInMgdl, Double valueInMmol, String units) {
|
||||
public static String toSignedUnitsString(double valueInMgdl, double valueInMmol, String units) {
|
||||
if (units.equals(Constants.MGDL))
|
||||
return (valueInMgdl > 0 ? "+" : "") + DecimalFormatter.to0Decimal(valueInMgdl);
|
||||
else return (valueInMmol > 0 ? "+" : "") + DecimalFormatter.to1Decimal(valueInMmol);
|
||||
}
|
||||
|
||||
public static double toCurrentUnits(double anyBg) {
|
||||
if (anyBg < 32) return fromMmolToUnits(anyBg, ProfileFunctions.getSystemUnits());
|
||||
else return fromMgdlToUnits(anyBg, ProfileFunctions.getSystemUnits());
|
||||
}
|
||||
|
||||
public static String toCurrentUnitsString(double anyBg) {
|
||||
if (anyBg < 32)
|
||||
return toUnitsString(anyBg * Constants.MMOLL_TO_MGDL, anyBg, ProfileFunctions.getSystemUnits());
|
||||
else
|
||||
return toUnitsString(anyBg, anyBg * Constants.MGDL_TO_MMOLL, ProfileFunctions.getSystemUnits());
|
||||
}
|
||||
|
||||
// targets are stored in mg/dl but profile vary
|
||||
public static String toTargetRangeString(double low, double high, String sourceUnits, String units) {
|
||||
double lowMgdl = toMgdl(low, sourceUnits);
|
||||
|
@ -683,6 +704,113 @@ public class Profile {
|
|||
return timeshift;
|
||||
}
|
||||
|
||||
public Profile convertToNonCustomizedProfile() {
|
||||
JSONObject o = new JSONObject();
|
||||
try {
|
||||
o.put("units", units);
|
||||
o.put("dia", dia);
|
||||
o.put("timezone", timeZone.getID());
|
||||
// SENS
|
||||
JSONArray sens = new JSONArray();
|
||||
double lastValue = -1d;
|
||||
for (int i = 0; i < 24; i++) {
|
||||
int timeAsSeconds = i * 60 * 60;
|
||||
double value = getIsfTimeFromMidnight(timeAsSeconds);
|
||||
if (value != lastValue) {
|
||||
JSONObject item = new JSONObject();
|
||||
String time;
|
||||
DecimalFormat df = new DecimalFormat("00");
|
||||
time = df.format(i) + ":00";
|
||||
item.put("time", time);
|
||||
item.put("timeAsSeconds", timeAsSeconds);
|
||||
item.put("value", value);
|
||||
lastValue = value;
|
||||
sens.put(item);
|
||||
}
|
||||
}
|
||||
o.put("sens", sens);
|
||||
// CARBRATIO
|
||||
JSONArray carbratio = new JSONArray();
|
||||
lastValue = -1d;
|
||||
for (int i = 0; i < 24; i++) {
|
||||
int timeAsSeconds = i * 60 * 60;
|
||||
double value = getIcTimeFromMidnight(timeAsSeconds);
|
||||
if (value != lastValue) {
|
||||
JSONObject item = new JSONObject();
|
||||
String time;
|
||||
DecimalFormat df = new DecimalFormat("00");
|
||||
time = df.format(i) + ":00";
|
||||
item.put("time", time);
|
||||
item.put("timeAsSeconds", timeAsSeconds);
|
||||
item.put("value", value);
|
||||
lastValue = value;
|
||||
carbratio.put(item);
|
||||
}
|
||||
}
|
||||
o.put("carbratio", carbratio);
|
||||
// BASAL
|
||||
JSONArray basal = new JSONArray();
|
||||
lastValue = -1d;
|
||||
for (int i = 0; i < 24; i++) {
|
||||
int timeAsSeconds = i * 60 * 60;
|
||||
double value = getBasalTimeFromMidnight(timeAsSeconds);
|
||||
if (value != lastValue) {
|
||||
JSONObject item = new JSONObject();
|
||||
String time;
|
||||
DecimalFormat df = new DecimalFormat("00");
|
||||
time = df.format(i) + ":00";
|
||||
item.put("time", time);
|
||||
item.put("timeAsSeconds", timeAsSeconds);
|
||||
item.put("value", value);
|
||||
lastValue = value;
|
||||
basal.put(item);
|
||||
}
|
||||
}
|
||||
o.put("basal", basal);
|
||||
// TARGET_LOW
|
||||
JSONArray target_low = new JSONArray();
|
||||
lastValue = -1d;
|
||||
for (int i = 0; i < 24; i++) {
|
||||
int timeAsSeconds = i * 60 * 60;
|
||||
double value = getTargetLowTimeFromMidnight(timeAsSeconds);
|
||||
if (value != lastValue) {
|
||||
JSONObject item = new JSONObject();
|
||||
String time;
|
||||
DecimalFormat df = new DecimalFormat("00");
|
||||
time = df.format(i) + ":00";
|
||||
item.put("time", time);
|
||||
item.put("timeAsSeconds", timeAsSeconds);
|
||||
item.put("value", value);
|
||||
lastValue = value;
|
||||
target_low.put(item);
|
||||
}
|
||||
}
|
||||
o.put("target_low", target_low);
|
||||
// TARGET_HIGH
|
||||
JSONArray target_high = new JSONArray();
|
||||
lastValue = -1d;
|
||||
for (int i = 0; i < 24; i++) {
|
||||
int timeAsSeconds = i * 60 * 60;
|
||||
double value = getTargetHighTimeFromMidnight(timeAsSeconds);
|
||||
if (value != lastValue) {
|
||||
JSONObject item = new JSONObject();
|
||||
String time;
|
||||
DecimalFormat df = new DecimalFormat("00");
|
||||
time = df.format(i) + ":00";
|
||||
item.put("time", time);
|
||||
item.put("timeAsSeconds", timeAsSeconds);
|
||||
item.put("value", value);
|
||||
lastValue = value;
|
||||
target_high.put(item);
|
||||
}
|
||||
}
|
||||
o.put("target_high", target_high);
|
||||
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception" + e);
|
||||
}
|
||||
return new Profile(o);
|
||||
}
|
||||
|
||||
public boolean isProfileTheSame(Profile otherProfile) {
|
||||
|
||||
|
@ -704,5 +832,4 @@ public class Profile {
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,118 +0,0 @@
|
|||
package info.nightscout.androidaps.data;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.collection.ArrayMap;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
|
||||
import info.nightscout.androidaps.Constants;
|
||||
|
||||
/**
|
||||
* Created by mike on 01.06.2017.
|
||||
*/
|
||||
|
||||
public class ProfileStore {
|
||||
private static Logger log = LoggerFactory.getLogger(ProfileStore.class);
|
||||
private JSONObject json = null;
|
||||
private String units = Constants.MGDL;
|
||||
|
||||
ArrayMap<String, Profile> cachedObjects = new ArrayMap<>();
|
||||
|
||||
public ProfileStore(JSONObject json) {
|
||||
this.json = json;
|
||||
getDefaultProfile(); // initialize units
|
||||
}
|
||||
|
||||
public JSONObject getData() {
|
||||
return json;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Profile getDefaultProfile() {
|
||||
Profile profile = null;
|
||||
try {
|
||||
String defaultProfileName = json.getString("defaultProfile");
|
||||
JSONObject store = json.getJSONObject("store");
|
||||
if (store.has(defaultProfileName)) {
|
||||
profile = cachedObjects.get(defaultProfileName);
|
||||
if (profile == null) {
|
||||
if (store.has("units"))
|
||||
units = store.getString("units");
|
||||
profile = new Profile(store.getJSONObject(defaultProfileName), units);
|
||||
units = profile.getUnits();
|
||||
cachedObjects.put(defaultProfileName, profile);
|
||||
}
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return profile;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getDefaultProfileName() {
|
||||
String defaultProfileName = null;
|
||||
try {
|
||||
defaultProfileName = json.getString("defaultProfile");
|
||||
JSONObject store = json.getJSONObject("store");
|
||||
if (store.has(defaultProfileName)) {
|
||||
return defaultProfileName;
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return defaultProfileName;
|
||||
}
|
||||
|
||||
public String getUnits() {
|
||||
return units;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Profile getSpecificProfile(String profileName) {
|
||||
Profile profile = null;
|
||||
try {
|
||||
JSONObject store = json.getJSONObject("store");
|
||||
if (store.has(profileName)) {
|
||||
profile = cachedObjects.get(profileName);
|
||||
if (profile == null) {
|
||||
if (store.has("units"))
|
||||
units = store.getString("units");
|
||||
profile = new Profile(store.getJSONObject(profileName), units);
|
||||
units = profile.getUnits();
|
||||
cachedObjects.put(profileName, profile);
|
||||
}
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return profile;
|
||||
}
|
||||
|
||||
public ArrayList<CharSequence> getProfileList() {
|
||||
ArrayList<CharSequence> ret = new ArrayList<CharSequence>();
|
||||
|
||||
JSONObject store;
|
||||
try {
|
||||
store = json.getJSONObject("store");
|
||||
Iterator<?> keys = store.keys();
|
||||
|
||||
while (keys.hasNext()) {
|
||||
String profileName = (String) keys.next();
|
||||
ret.add(profileName);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package info.nightscout.androidaps.data
|
||||
|
||||
import androidx.collection.ArrayMap
|
||||
import info.nightscout.androidaps.utils.JsonHelper
|
||||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.util.*
|
||||
|
||||
class ProfileStore(val data: JSONObject) {
|
||||
private val log = LoggerFactory.getLogger(ProfileStore::class.java)
|
||||
|
||||
private val cachedObjects = ArrayMap<String, Profile>()
|
||||
|
||||
private fun getStore(): JSONObject? {
|
||||
try {
|
||||
if (data.has("store")) return data.getJSONObject("store")
|
||||
} catch (e: JSONException) {
|
||||
log.error("Unhandled exception", e)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun getDefaultProfile(): Profile? = getDefaultProfileName()?.let { getSpecificProfile(it) }
|
||||
|
||||
fun getDefaultProfileName(): String? {
|
||||
val defaultProfileName = data.getString("defaultProfile")
|
||||
return getStore()?.has(defaultProfileName)?.let { defaultProfileName }
|
||||
}
|
||||
|
||||
fun getProfileList(): ArrayList<CharSequence> {
|
||||
val ret = ArrayList<CharSequence>()
|
||||
getStore()?.keys()?.let { keys ->
|
||||
while (keys.hasNext()) {
|
||||
val profileName = keys.next() as String
|
||||
ret.add(profileName)
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
fun getSpecificProfile(profileName: String): Profile? {
|
||||
var profile: Profile? = null
|
||||
getStore()?.let { store ->
|
||||
if (store.has(profileName)) {
|
||||
profile = cachedObjects[profileName]
|
||||
if (profile == null) {
|
||||
JsonHelper.safeGetJSONObject(store, profileName, null)?.let { profileObject ->
|
||||
// take units from profile and if N/A from store
|
||||
JsonHelper.safeGetStringAllowNull(profileObject, "units", JsonHelper.safeGetString(data, "units"))?.let { units ->
|
||||
profile = Profile(profileObject, units)
|
||||
cachedObjects[profileName] = profile
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return profile
|
||||
}
|
||||
}
|
|
@ -11,6 +11,7 @@ import info.nightscout.androidaps.R;
|
|||
import info.nightscout.androidaps.db.BgReading;
|
||||
import info.nightscout.androidaps.db.TempTarget;
|
||||
import info.nightscout.androidaps.interfaces.TreatmentsInterface;
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.CobInfo;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
|
||||
|
@ -74,7 +75,7 @@ public class QuickWizardEntry {
|
|||
//BG
|
||||
double bg = 0;
|
||||
if (lastBG != null && useBG() == YES) {
|
||||
bg = lastBG.valueToUnits(profile.getUnits());
|
||||
bg = lastBG.valueToUnits(ProfileFunctions.getSystemUnits());
|
||||
}
|
||||
|
||||
// COB
|
||||
|
@ -124,7 +125,8 @@ public class QuickWizardEntry {
|
|||
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() {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import info.nightscout.androidaps.Constants;
|
||||
|
@ -19,10 +20,11 @@ import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin;
|
|||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface;
|
||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries;
|
||||
import info.nightscout.androidaps.utils.DecimalFormatter;
|
||||
import info.nightscout.androidaps.utils.T;
|
||||
|
||||
@DatabaseTable(tableName = DatabaseHelper.DATABASE_BGREADINGS)
|
||||
public class BgReading implements DataPointWithLabelInterface {
|
||||
private static Logger log = LoggerFactory.getLogger(L.DATABASE);
|
||||
private static Logger log = LoggerFactory.getLogger(L.GLUCOSE);
|
||||
|
||||
@DatabaseField(id = true)
|
||||
public long date;
|
||||
|
@ -73,9 +75,10 @@ public class BgReading implements DataPointWithLabelInterface {
|
|||
|
||||
public String directionToSymbol() {
|
||||
String symbol = "";
|
||||
if (direction == null) {
|
||||
symbol = "??";
|
||||
} else if (direction.compareTo("DoubleDown") == 0) {
|
||||
if (direction == null)
|
||||
direction = calculateDirection();
|
||||
|
||||
if (direction.compareTo("DoubleDown") == 0) {
|
||||
symbol = "\u21ca";
|
||||
} else if (direction.compareTo("SingleDown") == 0) {
|
||||
symbol = "\u2193";
|
||||
|
@ -95,18 +98,13 @@ public class BgReading implements DataPointWithLabelInterface {
|
|||
return symbol;
|
||||
}
|
||||
|
||||
public static boolean isSlopeNameInvalid(String direction) {
|
||||
if (direction.compareTo("NOT_COMPUTABLE") == 0 ||
|
||||
private static boolean isSlopeNameInvalid(String direction) {
|
||||
return direction.compareTo("NOT_COMPUTABLE") == 0 ||
|
||||
direction.compareTo("NOT COMPUTABLE") == 0 ||
|
||||
direction.compareTo("OUT_OF_RANGE") == 0 ||
|
||||
direction.compareTo("OUT OF RANGE") == 0 ||
|
||||
direction.compareTo("NONE") == 0 ||
|
||||
direction.compareTo("NotComputable") == 0
|
||||
) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
direction.compareTo("NotComputable") == 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -123,7 +121,8 @@ public class BgReading implements DataPointWithLabelInterface {
|
|||
|
||||
public boolean isDataChanging(BgReading other) {
|
||||
if (date != other.date) {
|
||||
log.error("Comparing different");
|
||||
if (L.isEnabled(L.GLUCOSE))
|
||||
log.error("Comparing different");
|
||||
return false;
|
||||
}
|
||||
if (value != other.value)
|
||||
|
@ -133,7 +132,8 @@ public class BgReading implements DataPointWithLabelInterface {
|
|||
|
||||
public boolean isEqual(BgReading other) {
|
||||
if (date != other.date) {
|
||||
log.error("Comparing different");
|
||||
if (L.isEnabled(L.GLUCOSE))
|
||||
log.error("Comparing different");
|
||||
return false;
|
||||
}
|
||||
if (value != other.value)
|
||||
|
@ -149,7 +149,8 @@ public class BgReading implements DataPointWithLabelInterface {
|
|||
|
||||
public void copyFrom(BgReading other) {
|
||||
if (date != other.date) {
|
||||
log.error("Copying different");
|
||||
if (L.isEnabled(L.GLUCOSE))
|
||||
log.error("Copying different");
|
||||
return;
|
||||
}
|
||||
value = other.value;
|
||||
|
@ -181,8 +182,7 @@ public class BgReading implements DataPointWithLabelInterface {
|
|||
|
||||
@Override
|
||||
public double getY() {
|
||||
String units = ProfileFunctions.getInstance().getProfileUnits();
|
||||
return valueToUnits(units);
|
||||
return valueToUnits(ProfileFunctions.getSystemUnits());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -215,9 +215,9 @@ public class BgReading implements DataPointWithLabelInterface {
|
|||
|
||||
@Override
|
||||
public int getColor() {
|
||||
String units = ProfileFunctions.getInstance().getProfileUnits();
|
||||
Double lowLine = OverviewPlugin.INSTANCE.determineLowLine(units);
|
||||
Double highLine = OverviewPlugin.INSTANCE.determineHighLine(units);
|
||||
String units = ProfileFunctions.getSystemUnits();
|
||||
Double lowLine = OverviewPlugin.INSTANCE.determineLowLine();
|
||||
Double highLine = OverviewPlugin.INSTANCE.determineHighLine();
|
||||
int color = MainApp.gc(R.color.inrange);
|
||||
if (isPrediction())
|
||||
return getPredectionColor();
|
||||
|
@ -246,4 +246,53 @@ public class BgReading implements DataPointWithLabelInterface {
|
|||
return isaCOBPrediction || isCOBPrediction || isIOBPrediction || isUAMPrediction || isZTPrediction;
|
||||
}
|
||||
|
||||
|
||||
// Copied from xDrip+
|
||||
String calculateDirection() {
|
||||
// Rework to get bgreaings from internal DB and calculate on that base
|
||||
|
||||
List<BgReading> bgReadingsList = MainApp.getDbHelper().getAllBgreadingsDataFromTime(this.date - T.mins(10).msecs(), false);
|
||||
if (bgReadingsList == null || bgReadingsList.size() < 2)
|
||||
return "NONE";
|
||||
BgReading current = bgReadingsList.get(1);
|
||||
BgReading previous = bgReadingsList.get(0);
|
||||
|
||||
if (bgReadingsList.get(1).date < bgReadingsList.get(0).date) {
|
||||
current = bgReadingsList.get(0);
|
||||
previous = bgReadingsList.get(1);
|
||||
}
|
||||
|
||||
double slope;
|
||||
|
||||
// Avoid division by 0
|
||||
if (current.date == previous.date)
|
||||
slope = 0;
|
||||
else
|
||||
slope = (previous.value - current.value) / (previous.date - current.date);
|
||||
|
||||
if (L.isEnabled(L.GLUCOSE))
|
||||
log.debug("Slope is :" + slope + " delta " + (previous.value - current.value) + " date difference " + (current.date - previous.date));
|
||||
|
||||
double slope_by_minute = slope * 60000;
|
||||
String arrow = "NONE";
|
||||
|
||||
if (slope_by_minute <= (-3.5)) {
|
||||
arrow = "DoubleDown";
|
||||
} else if (slope_by_minute <= (-2)) {
|
||||
arrow = "SingleDown";
|
||||
} else if (slope_by_minute <= (-1)) {
|
||||
arrow = "FortyFiveDown";
|
||||
} else if (slope_by_minute <= (1)) {
|
||||
arrow = "Flat";
|
||||
} else if (slope_by_minute <= (2)) {
|
||||
arrow = "FortyFiveUp";
|
||||
} else if (slope_by_minute <= (3.5)) {
|
||||
arrow = "SingleUp";
|
||||
} else if (slope_by_minute <= (40)) {
|
||||
arrow = "DoubleUp";
|
||||
}
|
||||
if (L.isEnabled(L.GLUCOSE))
|
||||
log.debug("Direction set to: " + arrow);
|
||||
return arrow;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -167,7 +167,7 @@ public class CareportalEvent implements DataPointWithLabelInterface, Interval {
|
|||
|
||||
@Override
|
||||
public double getY() {
|
||||
String units = ProfileFunctions.getInstance().getProfileUnits();
|
||||
String units = ProfileFunctions.getSystemUnits();
|
||||
if (eventType.equals(MBG)) {
|
||||
double mbg = 0d;
|
||||
try {
|
||||
|
|
|
@ -3,6 +3,7 @@ package info.nightscout.androidaps.db;
|
|||
import android.content.Context;
|
||||
import android.database.DatabaseUtils;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
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.MainApp;
|
||||
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.ProfileStore;
|
||||
import info.nightscout.androidaps.events.EventCareportalEventChange;
|
||||
|
@ -198,15 +199,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
return newVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the database connections and clear any cached DAOs.
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
super.close();
|
||||
}
|
||||
|
||||
|
||||
public long size(String database) {
|
||||
return DatabaseUtils.queryNumEntries(getReadableDatabase(), database);
|
||||
}
|
||||
|
@ -569,12 +561,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
|
||||
// ------------- DbRequests handling -------------------
|
||||
|
||||
public void create(DbRequest dbr) {
|
||||
try {
|
||||
public void create(DbRequest dbr) throws SQLException {
|
||||
getDaoDbRequest().create(dbr);
|
||||
} catch (SQLException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
public int delete(DbRequest dbr) {
|
||||
|
@ -783,8 +771,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
TempTarget tempTarget = new TempTarget()
|
||||
.date(trJson.getLong("mills"))
|
||||
.duration(JsonHelper.safeGetInt(trJson, "duration"))
|
||||
.low(Profile.toMgdl(trJson.getDouble("targetBottom"), units))
|
||||
.high(Profile.toMgdl(trJson.getDouble("targetTop"), units))
|
||||
.low(Profile.toMgdl(JsonHelper.safeGetDouble(trJson, "targetBottom"), units))
|
||||
.high(Profile.toMgdl(JsonHelper.safeGetDouble(trJson, "targetTop"), units))
|
||||
.reason(JsonHelper.safeGetString(trJson, "reason", ""))
|
||||
._id(trJson.getString("_id"))
|
||||
.source(Source.NIGHTSCOUT);
|
||||
|
@ -1436,7 +1424,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
QueryBuilder<CareportalEvent, Long> queryBuilder = getDaoCareportalEvents().queryBuilder();
|
||||
queryBuilder.orderBy("date", false);
|
||||
Where where = queryBuilder.where();
|
||||
where.eq("eventType", event);
|
||||
where.eq("eventType", event).and().isNotNull("json");
|
||||
queryBuilder.limit(1L);
|
||||
PreparedQuery<CareportalEvent> preparedQuery = queryBuilder.prepare();
|
||||
careportalEvents = getDaoCareportalEvents().query(preparedQuery);
|
||||
|
@ -1456,10 +1444,10 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
QueryBuilder<CareportalEvent, Long> queryBuilder = getDaoCareportalEvents().queryBuilder();
|
||||
queryBuilder.orderBy("date", ascending);
|
||||
Where where = queryBuilder.where();
|
||||
where.ge("date", mills);
|
||||
where.ge("date", mills).and().isNotNull("json").and().isNotNull("eventType");
|
||||
PreparedQuery<CareportalEvent> preparedQuery = queryBuilder.prepare();
|
||||
careportalEvents = getDaoCareportalEvents().query(preparedQuery);
|
||||
preprocessOpenAPSOfflineEvents(careportalEvents);
|
||||
careportalEvents = preprocessOpenAPSOfflineEvents(careportalEvents);
|
||||
return careportalEvents;
|
||||
} catch (SQLException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
|
@ -1473,10 +1461,10 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
QueryBuilder<CareportalEvent, Long> queryBuilder = getDaoCareportalEvents().queryBuilder();
|
||||
queryBuilder.orderBy("date", ascending);
|
||||
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();
|
||||
careportalEvents = getDaoCareportalEvents().query(preparedQuery);
|
||||
preprocessOpenAPSOfflineEvents(careportalEvents);
|
||||
careportalEvents = preprocessOpenAPSOfflineEvents(careportalEvents);
|
||||
return careportalEvents;
|
||||
} catch (SQLException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
|
@ -1484,14 +1472,16 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
public void preprocessOpenAPSOfflineEvents(List<CareportalEvent> list) {
|
||||
OverlappingIntervals offlineEvents = new OverlappingIntervals();
|
||||
public List<CareportalEvent> preprocessOpenAPSOfflineEvents(List<CareportalEvent> list) {
|
||||
NonOverlappingIntervals offlineEvents = new NonOverlappingIntervals();
|
||||
List<CareportalEvent> other = new ArrayList<>();
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
CareportalEvent event = list.get(i);
|
||||
if (!event.eventType.equals(CareportalEvent.OPENAPSOFFLINE)) continue;
|
||||
offlineEvents.add(event);
|
||||
if (event.eventType.equals(CareportalEvent.OPENAPSOFFLINE)) offlineEvents.add(event);
|
||||
else other.add(event);
|
||||
}
|
||||
|
||||
other.addAll(offlineEvents.getList());
|
||||
return other;
|
||||
}
|
||||
|
||||
public List<CareportalEvent> getCareportalEventsFromTime(long mills, String type, boolean ascending) {
|
||||
|
@ -1500,10 +1490,10 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
QueryBuilder<CareportalEvent, Long> queryBuilder = getDaoCareportalEvents().queryBuilder();
|
||||
queryBuilder.orderBy("date", ascending);
|
||||
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();
|
||||
careportalEvents = getDaoCareportalEvents().query(preparedQuery);
|
||||
preprocessOpenAPSOfflineEvents(careportalEvents);
|
||||
careportalEvents = preprocessOpenAPSOfflineEvents(careportalEvents);
|
||||
return careportalEvents;
|
||||
} catch (SQLException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
|
@ -1516,9 +1506,11 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
List<CareportalEvent> careportalEvents;
|
||||
QueryBuilder<CareportalEvent, Long> queryBuilder = getDaoCareportalEvents().queryBuilder();
|
||||
queryBuilder.orderBy("date", ascending);
|
||||
Where where = queryBuilder.where();
|
||||
where.isNotNull("json").and().isNotNull("eventType");
|
||||
PreparedQuery<CareportalEvent> preparedQuery = queryBuilder.prepare();
|
||||
careportalEvents = getDaoCareportalEvents().query(preparedQuery);
|
||||
preprocessOpenAPSOfflineEvents(careportalEvents);
|
||||
careportalEvents = preprocessOpenAPSOfflineEvents(careportalEvents);
|
||||
return careportalEvents;
|
||||
} catch (SQLException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
|
@ -1603,15 +1595,23 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
|
||||
// ---------------- ProfileSwitch handling ---------------
|
||||
|
||||
public List<ProfileSwitch> getProfileSwitchData(boolean ascending) {
|
||||
public List<ProfileSwitch> getProfileSwitchData(long from, boolean ascending) {
|
||||
try {
|
||||
Dao<ProfileSwitch, Long> daoProfileSwitch = getDaoProfileSwitch();
|
||||
List<ProfileSwitch> profileSwitches;
|
||||
QueryBuilder<ProfileSwitch, Long> queryBuilder = daoProfileSwitch.queryBuilder();
|
||||
queryBuilder.orderBy("date", ascending);
|
||||
queryBuilder.limit(100L);
|
||||
Where where = queryBuilder.where();
|
||||
where.ge("date", from);
|
||||
PreparedQuery<ProfileSwitch> preparedQuery = queryBuilder.prepare();
|
||||
profileSwitches = daoProfileSwitch.query(preparedQuery);
|
||||
//add last one without duration
|
||||
ProfileSwitch last = getLastProfileSwitchWithoutDuration();
|
||||
if (last != null) {
|
||||
if (!profileSwitches.contains(last))
|
||||
profileSwitches.add(last);
|
||||
}
|
||||
return profileSwitches;
|
||||
} catch (SQLException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
|
@ -1619,6 +1619,28 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
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) {
|
||||
try {
|
||||
Dao<ProfileSwitch, Long> daoProfileSwitch = getDaoProfileSwitch();
|
||||
|
|
|
@ -11,6 +11,7 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.utils.DateUtil;
|
||||
|
||||
/**
|
||||
* Created by mike on 27.02.2016.
|
||||
|
@ -40,66 +41,55 @@ public class DbRequest {
|
|||
}
|
||||
|
||||
// dbAdd
|
||||
public DbRequest(String action, String collection, String nsClientID, JSONObject data) {
|
||||
public DbRequest(String action, String collection, JSONObject json) {
|
||||
this.action = action;
|
||||
this.collection = collection;
|
||||
this.data = data.toString();
|
||||
this.nsClientID = nsClientID;
|
||||
this.nsClientID = "" + DateUtil.now();
|
||||
try {
|
||||
json.put("NSCLIENT_ID", nsClientID);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
this.data = json.toString();
|
||||
this._id = "";
|
||||
}
|
||||
|
||||
// dbUpdate, dbUpdateUnset
|
||||
public DbRequest(String action, String collection, String nsClientID, String _id, JSONObject data) {
|
||||
public DbRequest(String action, String collection, String _id, JSONObject json) {
|
||||
this.action = action;
|
||||
this.collection = collection;
|
||||
this.data = data.toString();
|
||||
this.nsClientID = nsClientID;
|
||||
this.nsClientID = "" + DateUtil.now();
|
||||
try {
|
||||
json.put("NSCLIENT_ID", nsClientID);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
this.data = json.toString();
|
||||
this._id = _id;
|
||||
}
|
||||
|
||||
// dbRemove
|
||||
public DbRequest(String action, String collection, String nsClientID, String _id) {
|
||||
public DbRequest(String action, String collection,
|
||||
String _id) {
|
||||
JSONObject json = new JSONObject();
|
||||
this.action = action;
|
||||
this.collection = collection;
|
||||
this.data = new JSONObject().toString();
|
||||
this.nsClientID = nsClientID;
|
||||
this.nsClientID = "" + DateUtil.now();
|
||||
try {
|
||||
json.put("NSCLIENT_ID", nsClientID);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
this.data = json.toString();
|
||||
this._id = _id;
|
||||
}
|
||||
|
||||
public String hash() {
|
||||
return Hashing.sha1().hashString(action + collection + _id + data.toString(), Charsets.UTF_8).toString();
|
||||
}
|
||||
|
||||
public JSONObject toJSON() {
|
||||
JSONObject object = new JSONObject();
|
||||
try {
|
||||
object.put("action", action);
|
||||
object.put("collection", collection);
|
||||
object.put("data", new JSONObject(data));
|
||||
if (_id != null) object.put("_id", _id);
|
||||
if (nsClientID != null) object.put("nsClientID", nsClientID);
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
public static DbRequest fromJSON(JSONObject jsonObject) {
|
||||
DbRequest result = new DbRequest();
|
||||
try {
|
||||
if (jsonObject.has("action"))
|
||||
result.action = jsonObject.getString("action");
|
||||
if (jsonObject.has("collection"))
|
||||
result.collection = jsonObject.getString("collection");
|
||||
if (jsonObject.has("data"))
|
||||
result.data = jsonObject.getJSONObject("data").toString();
|
||||
if (jsonObject.has("_id"))
|
||||
result._id = jsonObject.getString("_id");
|
||||
if (jsonObject.has("nsClientID"))
|
||||
result.nsClientID = jsonObject.getString("nsClientID");
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return result;
|
||||
public String log() {
|
||||
return
|
||||
"\nnsClientID:" + nsClientID +
|
||||
"\naction:" + action +
|
||||
"\ncollection:" + collection +
|
||||
"\ndata:" + data +
|
||||
"\n_id:" + _id;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -259,11 +259,11 @@ public class ExtendedBolus implements Interval, DataPointWithLabelInterface {
|
|||
double sensitivityRatio = lastAutosensResult.ratio;
|
||||
double normalTarget = 100;
|
||||
|
||||
if (exercise_mode && isTempTarget && profile.getTarget() >= normalTarget + 5) {
|
||||
if (exercise_mode && isTempTarget && profile.getTargetMgdl() >= normalTarget + 5) {
|
||||
// w/ target 100, temp target 110 = .89, 120 = 0.8, 140 = 0.67, 160 = .57, and 200 = .44
|
||||
// e.g.: Sensitivity ratio set to 0.8 based on temp target of 120; Adjusting basal from 1.65 to 1.35; ISF from 58.9 to 73.6
|
||||
double c = half_basal_exercise_target - normalTarget;
|
||||
sensitivityRatio = c / (c + profile.getTarget() - normalTarget);
|
||||
sensitivityRatio = c / (c + profile.getTargetMgdl() - normalTarget);
|
||||
}
|
||||
|
||||
if (realDuration > 0) {
|
||||
|
@ -325,8 +325,8 @@ public class ExtendedBolus implements Interval, DataPointWithLabelInterface {
|
|||
}
|
||||
|
||||
public String toStringMedium() {
|
||||
return "E " + DecimalFormatter.to2Decimal(absoluteRate()) + "U/h ("
|
||||
+ getRealDuration() + "/" + durationInMinutes + ") ";
|
||||
return DecimalFormatter.to2Decimal(absoluteRate()) + "U/h "
|
||||
+ getRealDuration() + "/" + durationInMinutes + "'";
|
||||
}
|
||||
|
||||
public String toStringTotal() {
|
||||
|
|
|
@ -6,8 +6,11 @@ import com.j256.ormlite.table.DatabaseTable;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil;
|
||||
import info.nightscout.androidaps.utils.DateUtil;
|
||||
|
||||
/**
|
||||
* Created by mike on 20.09.2017.
|
||||
|
@ -56,4 +59,12 @@ public class TDD {
|
|||
", 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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -299,11 +299,11 @@ public class TemporaryBasal implements Interval, DbObjectBase {
|
|||
double sensitivityRatio = lastAutosensResult.ratio;
|
||||
double normalTarget = 100;
|
||||
|
||||
if (exercise_mode && isTempTarget && profile.getTarget() >= normalTarget + 5) {
|
||||
if (exercise_mode && isTempTarget && profile.getTargetMgdl() >= normalTarget + 5) {
|
||||
// w/ target 100, temp target 110 = .89, 120 = 0.8, 140 = 0.67, 160 = .57, and 200 = .44
|
||||
// e.g.: Sensitivity ratio set to 0.8 based on temp target of 120; Adjusting basal from 1.65 to 1.35; ISF from 58.9 to 73.6
|
||||
double c = half_basal_exercise_target - normalTarget;
|
||||
sensitivityRatio = c / (c + profile.getTarget() - normalTarget);
|
||||
sensitivityRatio = c / (c + profile.getTargetMgdl() - normalTarget);
|
||||
}
|
||||
|
||||
if (realDuration > 0) {
|
||||
|
|
|
@ -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,69 @@
|
|||
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 {
|
||||
log.debug("USER ENTRY: CALIBRATION $bg")
|
||||
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,228 @@
|
|||
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) {
|
||||
log.debug("USER ENTRY: TEMPTARGET ACTIVITY $activityTT duration: $activityTTDuration")
|
||||
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) {
|
||||
log.debug("USER ENTRY: TEMPTARGET EATING SOON $eatingSoonTT duration: $eatingSoonTTDuration")
|
||||
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) {
|
||||
log.debug("USER ENTRY: TEMPTARGET HYPO $hypoTT duration: $hypoTTDuration")
|
||||
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) {
|
||||
log.debug("USER ENTRY: CARBS $carbsAfterConstraints time: $time")
|
||||
CarbsGenerator.createCarb(carbsAfterConstraints, time, CareportalEvent.CARBCORRECTION, notes)
|
||||
} else {
|
||||
log.debug("USER ENTRY: CARBS $carbsAfterConstraints time: $time duration: $duration")
|
||||
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,190 @@
|
|||
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()
|
||||
log.debug("USER ENTRY: CAREPORTAL ${careportalEvent.eventType} json: ${careportalEvent.json}")
|
||||
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() {
|
||||
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.ClipData
|
||||
import android.content.ClipboardManager
|
||||
|
@ -10,11 +9,14 @@ import android.os.Bundle
|
|||
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.ErrorHelperActivity
|
||||
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 java.util.*
|
||||
|
||||
|
@ -29,26 +31,30 @@ class ErrorDialog : DialogFragment() {
|
|||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View? {
|
||||
dialog?.setTitle(title)
|
||||
isCancelable = false
|
||||
dialog?.window?.requestFeature(Window.FEATURE_NO_TITLE)
|
||||
dialog?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN)
|
||||
isCancelable = true
|
||||
dialog?.setCanceledOnTouchOutside(false)
|
||||
|
||||
savedInstanceState?.let { bundle ->
|
||||
bundle.getString("status")?.let { status = it }
|
||||
bundle.getString("title")?.let { title = it }
|
||||
sound = bundle.getInt("sound", R.raw.error)
|
||||
}
|
||||
return inflater.inflate(R.layout.overview_error_dialog, container, false)
|
||||
log.debug("Error dialog displayed")
|
||||
return inflater.inflate(R.layout.dialog_error, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
error_title.text = title
|
||||
overview_error_ok.setOnClickListener {
|
||||
log.debug("Error dialog ok button pressed")
|
||||
log.debug("USER ENTRY: Error dialog ok button pressed")
|
||||
dismiss()
|
||||
}
|
||||
overview_error_mute.setOnClickListener {
|
||||
log.debug("Error dialog mute button pressed")
|
||||
log.debug("USER ENTRY: Error dialog mute button pressed")
|
||||
stopAlarm()
|
||||
}
|
||||
copyToClipboard()
|
||||
|
@ -70,9 +76,13 @@ class ErrorDialog : DialogFragment() {
|
|||
bundle.putInt("sound", sound)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
overview_error_status.text = status
|
||||
}
|
||||
|
||||
|
@ -95,5 +105,5 @@ class ErrorDialog : DialogFragment() {
|
|||
}
|
||||
|
||||
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,83 @@
|
|||
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 {
|
||||
log.debug("USER ENTRY: EXTENDED BOLUS $insulinAfterConstraint duration: $durationInMinutes")
|
||||
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,172 @@
|
|||
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) {
|
||||
log.debug("USER ENTRY: PRIME BOLUS $insulinAfterConstraints")
|
||||
requestPrimeBolus(insulinAfterConstraints, notes)
|
||||
}
|
||||
if (siteChange) {
|
||||
log.debug("USER ENTRY: SITE CHANGE")
|
||||
generateCareportalEvent(CareportalEvent.SITECHANGE, eventTime, notes)
|
||||
}
|
||||
if (insulinChange) {
|
||||
// add a second for case of both checked
|
||||
log.debug("USER ENTRY: INSULIN CHANGE")
|
||||
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,196 @@
|
|||
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) {
|
||||
log.debug("USER ENTRY: TEMPTARGET EATING SOON $eatingSoonTT duration: $eatingSoonTTDuration")
|
||||
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) {
|
||||
log.debug("USER ENTRY: BOLUS RECORD ONLY $insulinAfterConstraints")
|
||||
detailedBolusInfo.date = time
|
||||
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false)
|
||||
} else {
|
||||
log.debug("USER ENTRY: BOLUS $insulinAfterConstraints")
|
||||
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,106 @@
|
|||
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 {
|
||||
log.debug("USER ENTRY: PROFILE SWITCH $profile percent: $percent timeshift: $timeShift duration: $duration")
|
||||
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.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.Constants
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
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.utils.DateUtil
|
||||
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() {
|
||||
private var time: Long = 0
|
||||
|
||||
enum class Mode(val i: Int) {
|
||||
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?,
|
||||
savedInstanceState: Bundle?): View? {
|
||||
|
@ -31,19 +36,23 @@ class ProfileViewerDialog : DialogFragment() {
|
|||
(savedInstanceState ?: arguments)?.let { bundle ->
|
||||
time = bundle.getLong("time", 0)
|
||||
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?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
close.setOnClickListener { dismiss() }
|
||||
profileview_reload.setOnClickListener {
|
||||
ConfigBuilderPlugin.getPlugin().commandQueue.readStatus("ProfileViewDialog", null)
|
||||
dismiss()
|
||||
}
|
||||
|
||||
val profile: Profile?
|
||||
val profileName: String?
|
||||
|
@ -53,15 +62,14 @@ class ProfileViewerDialog : DialogFragment() {
|
|||
profile = TreatmentsPlugin.getPlugin().getProfileSwitchFromHistory(time)?.profileObject
|
||||
profileName = TreatmentsPlugin.getPlugin().getProfileSwitchFromHistory(time)?.customizedName
|
||||
date = DateUtil.dateAndTimeString(TreatmentsPlugin.getPlugin().getProfileSwitchFromHistory(time)?.date
|
||||
?: 0)
|
||||
profileview_reload.visibility = View.GONE
|
||||
?: 0)
|
||||
profileview_datelayout.visibility = View.VISIBLE
|
||||
}
|
||||
Mode.PUMP_PROFILE -> {
|
||||
profile = (ConfigBuilderPlugin.getPlugin().activePump as ProfileInterface?)?.profile?.defaultProfile
|
||||
profileName = (ConfigBuilderPlugin.getPlugin().activePump as ProfileInterface?)?.profileName
|
||||
|
||||
Mode.CUSTOM_PROFILE -> {
|
||||
profile = Profile(JSONObject(customProfileJson), customProfileUnits)
|
||||
profileName = customProfileName
|
||||
date = ""
|
||||
profileview_reload.visibility = View.VISIBLE
|
||||
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)
|
||||
super.onResume()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(bundle: Bundle) {
|
||||
super.onSaveInstanceState(bundle)
|
||||
bundle.putLong("time", time)
|
||||
bundle.putInt("mode", mode.ordinal)
|
||||
bundle.putString("customProfile", customProfileJson)
|
||||
bundle.putString("customProfileName", customProfileName)
|
||||
bundle.putString("customProfileUnits", customProfileUnits)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
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) {
|
||||
log.debug("USER ENTRY: TEMP BASAL $percent% duration: $durationInMinutes")
|
||||
ConfigBuilderPlugin.getPlugin().commandQueue.tempBasalPercent(percent, durationInMinutes, true, profile, callback)
|
||||
} else {
|
||||
log.debug("USER ENTRY: TEMP BASAL $absolute duration: $durationInMinutes")
|
||||
ConfigBuilderPlugin.getPlugin().commandQueue.tempBasalAbsolute(absolute, durationInMinutes, true, profile, callback)
|
||||
}
|
||||
})
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
|
@ -0,0 +1,153 @@
|
|||
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.toInt()
|
||||
if (target != 0.0 && duration != 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_mins, 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 {
|
||||
log.debug("USER ENTRY: TEMP TARGET $target duration: $duration")
|
||||
if (target == 0.0 || duration == 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) SP.putBoolean(R.string.key_objectiveusetemptarget, true)
|
||||
})
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
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 {
|
||||
log.debug("USER ENTRY: BOLUS insulin $insulin carbs: $carbs")
|
||||
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.text.Editable
|
||||
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.OnItemSelectedListener
|
||||
import android.widget.ArrayAdapter
|
||||
|
@ -26,7 +29,7 @@ import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
|||
import info.nightscout.androidaps.utils.*
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
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 java.text.DecimalFormat
|
||||
import java.util.*
|
||||
|
@ -36,16 +39,13 @@ class WizardDialog : DialogFragment() {
|
|||
private val log = LoggerFactory.getLogger(WizardDialog::class.java)
|
||||
|
||||
private var wizard: BolusWizard? = null
|
||||
private var parentContext: Context? = null
|
||||
|
||||
//one shot guards
|
||||
private var okClicked: Boolean = false
|
||||
|
||||
private val 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) {
|
||||
calculateInsulin()
|
||||
}
|
||||
|
@ -53,21 +53,11 @@ class WizardDialog : DialogFragment() {
|
|||
|
||||
private var disposable: CompositeDisposable = CompositeDisposable()
|
||||
|
||||
override fun onAttach(context: Context) {
|
||||
super.onAttach(context)
|
||||
this.parentContext = context
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
}
|
||||
|
||||
override fun onDetach() {
|
||||
super.onDetach()
|
||||
this.parentContext = null
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(savedInstanceState: Bundle) {
|
||||
super.onSaveInstanceState(savedInstanceState)
|
||||
savedInstanceState.putDouble("treatments_wizard_bg_input", treatments_wizard_bg_input.value)
|
||||
|
@ -83,28 +73,28 @@ class WizardDialog : DialogFragment() {
|
|||
isCancelable = true
|
||||
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?) {
|
||||
loadCheckedStates()
|
||||
processCobCheckBox()
|
||||
treatments_wizard_sbcheckbox.visibility = if (SP.getBoolean(R.string.key_usesuperbolus, false)) View.VISIBLE else View.GONE
|
||||
treatments_wizard_notes_layout.visibility = if (SP.getBoolean(R.string.key_show_notes_entry_dialogs, false)) View.VISIBLE else View.GONE
|
||||
treatments_wizard_sbcheckbox.visibility = SP.getBoolean(R.string.key_usesuperbolus, false).toVisibility()
|
||||
treatments_wizard_notes_layout.visibility = SP.getBoolean(R.string.key_show_notes_entry_dialogs, false).toVisibility()
|
||||
|
||||
val maxCarbs = MainApp.getConstraintChecker().maxCarbsAllowed.value()
|
||||
val maxCorrection = MainApp.getConstraintChecker().maxBolusAllowed.value()
|
||||
|
||||
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")
|
||||
?: 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
|
||||
?: 0.1
|
||||
?: 0.1
|
||||
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")
|
||||
?: 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()
|
||||
|
||||
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 {
|
||||
okClicked = true
|
||||
calculateInsulin()
|
||||
parentContext?.let { context ->
|
||||
context?.let { context ->
|
||||
wizard?.confirmAndExecute(context)
|
||||
}
|
||||
}
|
||||
|
@ -124,23 +114,23 @@ class WizardDialog : DialogFragment() {
|
|||
// cancel button
|
||||
cancel.setOnClickListener { dismiss() }
|
||||
// checkboxes
|
||||
treatments_wizard_bgcheckbox.setOnCheckedChangeListener { buttonView, _ -> onCheckedChanged(buttonView) }
|
||||
treatments_wizard_ttcheckbox.setOnCheckedChangeListener { buttonView, _ -> onCheckedChanged(buttonView) }
|
||||
treatments_wizard_cobcheckbox.setOnCheckedChangeListener { buttonView, _ -> onCheckedChanged(buttonView) }
|
||||
treatments_wizard_basaliobcheckbox.setOnCheckedChangeListener { buttonView, _ -> onCheckedChanged(buttonView) }
|
||||
treatments_wizard_bolusiobcheckbox.setOnCheckedChangeListener { buttonView, _ -> onCheckedChanged(buttonView) }
|
||||
treatments_wizard_bgtrendcheckbox.setOnCheckedChangeListener { buttonView, _ -> onCheckedChanged(buttonView) }
|
||||
treatments_wizard_sbcheckbox.setOnCheckedChangeListener { buttonView, _ -> onCheckedChanged(buttonView) }
|
||||
treatments_wizard_bgcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||
treatments_wizard_ttcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||
treatments_wizard_cobcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||
treatments_wizard_basaliobcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||
treatments_wizard_bolusiobcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||
treatments_wizard_bgtrendcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||
treatments_wizard_sbcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||
|
||||
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_resulttable.visibility = if (showCalc) View.VISIBLE else View.GONE
|
||||
treatments_wizard_delimiter.visibility = showCalc.toVisibility()
|
||||
treatments_wizard_resulttable.visibility = showCalc.toVisibility()
|
||||
treatments_wizard_calculationcheckbox.isChecked = showCalc
|
||||
treatments_wizard_calculationcheckbox.setOnCheckedChangeListener { _, isChecked ->
|
||||
run {
|
||||
SP.putBoolean(MainApp.gs(R.string.key_wizard_calculation_visible), isChecked)
|
||||
treatments_wizard_delimiter.visibility = if (isChecked) View.VISIBLE else View.GONE
|
||||
treatments_wizard_resulttable.visibility = if (isChecked) View.VISIBLE else View.GONE
|
||||
treatments_wizard_delimiter.visibility = isChecked.toVisibility()
|
||||
treatments_wizard_resulttable.visibility = isChecked.toVisibility()
|
||||
}
|
||||
}
|
||||
// profile spinner
|
||||
|
@ -157,13 +147,13 @@ class WizardDialog : DialogFragment() {
|
|||
}
|
||||
// bus
|
||||
disposable.add(RxBus
|
||||
.toObservable(EventAutosensCalculationFinished::class.java)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({
|
||||
activity?.runOnUiThread { calculateInsulin() }
|
||||
}, {
|
||||
FabricPrivacy.logException(it)
|
||||
})
|
||||
.toObservable(EventAutosensCalculationFinished::class.java)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({
|
||||
activity?.runOnUiThread { calculateInsulin() }
|
||||
}, {
|
||||
FabricPrivacy.logException(it)
|
||||
})
|
||||
)
|
||||
|
||||
}
|
||||
|
@ -173,7 +163,7 @@ class WizardDialog : DialogFragment() {
|
|||
disposable.clear()
|
||||
}
|
||||
|
||||
private fun onCheckedChanged(buttonView: CompoundButton) {
|
||||
private fun onCheckedChanged(buttonView: CompoundButton, @Suppress("UNUSED_PARAMETER") state: Boolean) {
|
||||
saveCheckedStates()
|
||||
treatments_wizard_ttcheckbox.isEnabled = treatments_wizard_bgcheckbox.isChecked && TreatmentsPlugin.getPlugin().tempTargetFromHistory != null
|
||||
if (buttonView.id == treatments_wizard_cobcheckbox.id)
|
||||
|
@ -214,15 +204,14 @@ class WizardDialog : DialogFragment() {
|
|||
}
|
||||
|
||||
val profileList: ArrayList<CharSequence>
|
||||
profileList = profileStore.profileList
|
||||
profileList = profileStore.getProfileList()
|
||||
profileList.add(0, MainApp.gs(R.string.active))
|
||||
context?.let { context ->
|
||||
val adapter = ArrayAdapter(context, R.layout.spinner_centered, profileList)
|
||||
treatments_wizard_profile.adapter = adapter
|
||||
} ?: return
|
||||
|
||||
|
||||
val units = profile.units
|
||||
val units = ProfileFunctions.getSystemUnits()
|
||||
treatments_wizard_bgunits.text = units
|
||||
if (units == Constants.MGDL)
|
||||
treatments_wizard_bg_input.setStep(1.0)
|
||||
|
@ -250,7 +239,7 @@ class WizardDialog : DialogFragment() {
|
|||
|
||||
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() {
|
||||
|
@ -291,18 +280,18 @@ class WizardDialog : DialogFragment() {
|
|||
val carbTime = SafeParse.stringToInt(treatments_wizard_carb_time_input.text)
|
||||
|
||||
wizard = BolusWizard(specificProfile, profileName, tempTarget, carbsAfterConstraint, cob, bg, correction,
|
||||
SP.getInt(R.string.key_boluswizard_percentage, 100).toDouble(),
|
||||
treatments_wizard_bgcheckbox.isChecked,
|
||||
treatments_wizard_cobcheckbox.isChecked,
|
||||
treatments_wizard_bolusiobcheckbox.isChecked,
|
||||
treatments_wizard_basaliobcheckbox.isChecked,
|
||||
treatments_wizard_sbcheckbox.isChecked,
|
||||
treatments_wizard_ttcheckbox.isChecked,
|
||||
treatments_wizard_bgtrendcheckbox.isChecked,
|
||||
treatment_wizard_notes.text.toString(), carbTime)
|
||||
SP.getInt(R.string.key_boluswizard_percentage, 100).toDouble(),
|
||||
treatments_wizard_bgcheckbox.isChecked,
|
||||
treatments_wizard_cobcheckbox.isChecked,
|
||||
treatments_wizard_bolusiobcheckbox.isChecked,
|
||||
treatments_wizard_basaliobcheckbox.isChecked,
|
||||
treatments_wizard_sbcheckbox.isChecked,
|
||||
treatments_wizard_ttcheckbox.isChecked,
|
||||
treatments_wizard_bgtrendcheckbox.isChecked,
|
||||
treatment_wizard_notes.text.toString(), carbTime)
|
||||
|
||||
wizard?.let { wizard ->
|
||||
treatments_wizard_bg.text = String.format(MainApp.gs(R.string.format_bg_isf), BgReading().value(Profile.toMgdl(bg, specificProfile.units)).valueToUnitsToString(specificProfile.units), 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)
|
||||
treatments_wizard_bginsulin.text = StringUtils.formatInsulin(wizard.insulinFromBG)
|
||||
|
||||
treatments_wizard_carbs.text = String.format(MainApp.gs(R.string.format_carbs_ic), carbs.toDouble(), wizard.ic)
|
||||
|
@ -320,8 +309,8 @@ class WizardDialog : DialogFragment() {
|
|||
// Trend
|
||||
if (treatments_wizard_bgtrendcheckbox.isChecked && wizard.glucoseStatus != null) {
|
||||
treatments_wizard_bgtrend.text = ((if (wizard.trend > 0) "+" else "")
|
||||
+ Profile.toUnitsString(wizard.trend * 3, wizard.trend * 3 / Constants.MMOLL_TO_MGDL, specificProfile.units)
|
||||
+ " " + specificProfile.units)
|
||||
+ Profile.toUnitsString(wizard.trend * 3, wizard.trend * 3 / Constants.MMOLL_TO_MGDL, ProfileFunctions.getSystemUnits())
|
||||
+ " " + ProfileFunctions.getSystemUnits())
|
||||
} else {
|
||||
treatments_wizard_bgtrend.text = ""
|
||||
}
|
|
@ -4,7 +4,6 @@ import android.os.SystemClock;
|
|||
import android.preference.Preference;
|
||||
import android.preference.PreferenceFragment;
|
||||
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
|
||||
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.EventConfigBuilderUpdateGui;
|
||||
import info.nightscout.androidaps.queue.CommandQueue;
|
||||
import info.nightscout.androidaps.utils.OKDialog;
|
||||
import info.nightscout.androidaps.utils.SP;
|
||||
|
||||
/**
|
||||
|
@ -58,27 +58,23 @@ public abstract class PluginBase {
|
|||
if (allowHardwarePump || activity == null) {
|
||||
performPluginSwitch(newState, type);
|
||||
} else {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
||||
builder.setMessage(R.string.allow_hardware_pump_text)
|
||||
.setPositiveButton(R.string.yes, (dialog, id) -> {
|
||||
performPluginSwitch(newState, type);
|
||||
SP.putBoolean("allow_hardware_pump", true);
|
||||
if (L.isEnabled(L.PUMP))
|
||||
log.debug("First time HW pump allowed!");
|
||||
})
|
||||
.setNegativeButton(R.string.cancel, (dialog, id) -> {
|
||||
RxBus.INSTANCE.send(new EventConfigBuilderUpdateGui());
|
||||
if (L.isEnabled(L.PUMP))
|
||||
log.debug("User does not allow switching to HW pump!");
|
||||
});
|
||||
builder.create().show();
|
||||
OKDialog.showConfirmation(activity, MainApp.gs(R.string.allow_hardware_pump_text), () -> {
|
||||
performPluginSwitch(newState, type);
|
||||
SP.putBoolean("allow_hardware_pump", true);
|
||||
if (L.isEnabled(L.PUMP))
|
||||
log.debug("First time HW pump allowed!");
|
||||
}, () -> {
|
||||
RxBus.INSTANCE.send(new EventConfigBuilderUpdateGui());
|
||||
if (L.isEnabled(L.PUMP))
|
||||
log.debug("User does not allow switching to HW pump!");
|
||||
});
|
||||
}
|
||||
} else {
|
||||
performPluginSwitch(newState, type);
|
||||
}
|
||||
}
|
||||
|
||||
private void performPluginSwitch(boolean enabled, PluginType type) {
|
||||
public void performPluginSwitch(boolean enabled, PluginType type) {
|
||||
setPluginEnabled(type, enabled);
|
||||
setFragmentVisible(type, enabled);
|
||||
ConfigBuilderPlugin.getPlugin().processOnEnabledCategoryChanged(this, getType());
|
||||
|
|
|
@ -29,8 +29,8 @@ public class PluginDescription {
|
|||
return this;
|
||||
}
|
||||
|
||||
public PluginDescription alwaysVisible(boolean alwayVisible) {
|
||||
this.alwaysVisible = alwayVisible;
|
||||
public PluginDescription alwaysVisible(boolean alwaysVisible) {
|
||||
this.alwaysVisible = alwaysVisible;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,5 @@ import info.nightscout.androidaps.data.ProfileStore;
|
|||
public interface ProfileInterface {
|
||||
@Nullable
|
||||
ProfileStore getProfile();
|
||||
String getUnits();
|
||||
String getProfileName();
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ public interface TreatmentsInterface {
|
|||
MealData getMealData();
|
||||
|
||||
List<Treatment> getTreatmentsFromHistory();
|
||||
List<Treatment> getTreatments5MinBackFromHistory(long time);
|
||||
List<Treatment> getCarbTreatments5MinBackFromHistory(long time);
|
||||
List<Treatment> getTreatmentsFromHistoryAfterTimestamp(long timestamp);
|
||||
long getLastBolusTime();
|
||||
|
||||
|
|
|
@ -381,13 +381,11 @@ public class DeviceStatus {
|
|||
try {
|
||||
if (device != null) record.put("device", device);
|
||||
if (pump != null) record.put("pump", pump);
|
||||
if (suggested != null) {
|
||||
JSONObject openaps = new JSONObject();
|
||||
if (enacted != null) openaps.put("enacted", enacted);
|
||||
if (suggested != null) openaps.put("suggested", suggested);
|
||||
if (iob != null) openaps.put("iob", iob);
|
||||
record.put("openaps", openaps);
|
||||
}
|
||||
JSONObject openaps = new JSONObject();
|
||||
if (enacted != null) openaps.put("enacted", enacted);
|
||||
if (suggested != null) openaps.put("suggested", suggested);
|
||||
if (iob != null) openaps.put("iob", iob);
|
||||
record.put("openaps", openaps);
|
||||
if (uploaderBattery != 0) record.put("uploaderBattery", uploaderBattery);
|
||||
if (created_at != null) record.put("created_at", created_at);
|
||||
} catch (JSONException e) {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package info.nightscout.androidaps.plugins.aps.loop
|
||||
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
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.EventLoopUpdateGui
|
||||
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.disposables.CompositeDisposable
|
||||
import kotlinx.android.synthetic.main.loop_fragment.*
|
||||
|
@ -39,23 +42,21 @@ class LoopFragment : Fragment() {
|
|||
override fun onResume() {
|
||||
super.onResume()
|
||||
disposable += RxBus
|
||||
.toObservable(EventLoopUpdateGui::class.java)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({
|
||||
updateGUI()
|
||||
}, {
|
||||
FabricPrivacy.logException(it)
|
||||
})
|
||||
.toObservable(EventLoopUpdateGui::class.java)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({
|
||||
updateGUI()
|
||||
}, {
|
||||
FabricPrivacy.logException(it)
|
||||
})
|
||||
|
||||
disposable += RxBus
|
||||
.toObservable(EventLoopSetLastRunGui::class.java)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({
|
||||
clearGUI()
|
||||
loop_lastrun.text = it.text
|
||||
}, {
|
||||
FabricPrivacy.logException(it)
|
||||
})
|
||||
.toObservable(EventLoopSetLastRunGui::class.java)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({
|
||||
clearGUI()
|
||||
loop_lastrun?.text = it.text
|
||||
}, { FabricPrivacy.logException(it) })
|
||||
|
||||
updateGUI()
|
||||
SP.putBoolean(R.string.key_objectiveuseloop, true)
|
||||
|
@ -71,39 +72,44 @@ class LoopFragment : Fragment() {
|
|||
fun updateGUI() {
|
||||
if (loop_request == null) return
|
||||
LoopPlugin.lastRun?.let {
|
||||
loop_request.text = it.request?.toSpanned() ?: ""
|
||||
loop_constraintsprocessed.text = it.constraintsProcessed?.toSpanned() ?: ""
|
||||
loop_source.text = it.source ?: ""
|
||||
loop_lastrun.text = it.lastAPSRun?.let { lastRun -> DateUtil.dateAndTimeString(lastRun.time) }
|
||||
?: ""
|
||||
loop_lastenact.text = it.lastAPSRun?.let { lastEnact -> DateUtil.dateAndTimeString(lastEnact.time) }
|
||||
?: ""
|
||||
loop_tbrsetbypump.text = it.tbrSetByPump?.let { tbrSetByPump -> HtmlHelper.fromHtml(tbrSetByPump.toHtml()) }
|
||||
?: ""
|
||||
loop_smbsetbypump.text = it.smbSetByPump?.let { smbSetByPump -> HtmlHelper.fromHtml(smbSetByPump.toHtml()) }
|
||||
?: ""
|
||||
loop_request?.text = it.request?.toSpanned() ?: ""
|
||||
loop_constraintsprocessed?.text = it.constraintsProcessed?.toSpanned() ?: ""
|
||||
loop_source?.text = it.source ?: ""
|
||||
loop_lastrun?.text = it.lastAPSRun?.let { lastRun -> DateUtil.dateAndTimeString(lastRun.time) }
|
||||
?: ""
|
||||
loop_smbrequest_time?.text = DateUtil.dateAndTimeAndSecondsString(it.lastSMBRequest)
|
||||
loop_smbexecution_time?.text = DateUtil.dateAndTimeAndSecondsString(it.lastSMBEnact)
|
||||
loop_tbrrequest_time?.text = DateUtil.dateAndTimeAndSecondsString(it.lastTBRRequest)
|
||||
loop_tbrexecution_time?.text = DateUtil.dateAndTimeAndSecondsString(it.lastTBREnact)
|
||||
|
||||
loop_tbrsetbypump?.text = it.tbrSetByPump?.let { tbrSetByPump -> HtmlHelper.fromHtml(tbrSetByPump.toHtml()) }
|
||||
?: ""
|
||||
loop_smbsetbypump?.text = it.smbSetByPump?.let { smbSetByPump -> HtmlHelper.fromHtml(smbSetByPump.toHtml()) }
|
||||
?: ""
|
||||
|
||||
val constraints =
|
||||
it.constraintsProcessed?.let { constraintsProcessed ->
|
||||
val allConstraints = Constraint(0.0)
|
||||
constraintsProcessed.rateConstraint?.let { rateConstraint -> allConstraints.copyReasons(rateConstraint) }
|
||||
constraintsProcessed.smbConstraint?.let { smbConstraint -> allConstraints.copyReasons(smbConstraint) }
|
||||
allConstraints.mostLimitedReasons
|
||||
} ?: ""
|
||||
loop_constraints.text = constraints
|
||||
it.constraintsProcessed?.let { constraintsProcessed ->
|
||||
val allConstraints = Constraint(0.0)
|
||||
constraintsProcessed.rateConstraint?.let { rateConstraint -> allConstraints.copyReasons(rateConstraint) }
|
||||
constraintsProcessed.smbConstraint?.let { smbConstraint -> allConstraints.copyReasons(smbConstraint) }
|
||||
allConstraints.mostLimitedReasons
|
||||
} ?: ""
|
||||
loop_constraints?.text = constraints
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
private fun clearGUI() {
|
||||
if (loop_request == null) return
|
||||
loop_request.text = ""
|
||||
loop_constraints.text = ""
|
||||
loop_constraintsprocessed.text = ""
|
||||
loop_source.text = ""
|
||||
loop_lastrun.text = ""
|
||||
loop_lastenact.text = ""
|
||||
loop_tbrsetbypump.text = ""
|
||||
loop_smbsetbypump.text = ""
|
||||
loop_request?.text = ""
|
||||
loop_constraints?.text = ""
|
||||
loop_constraintsprocessed?.text = ""
|
||||
loop_source?.text = ""
|
||||
loop_lastrun?.text = ""
|
||||
loop_smbrequest_time?.text = ""
|
||||
loop_smbexecution_time?.text = ""
|
||||
loop_tbrrequest_time?.text = ""
|
||||
loop_tbrexecution_time?.text = ""
|
||||
loop_tbrsetbypump?.text = ""
|
||||
loop_smbsetbypump?.text = ""
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@ import android.os.SystemClock;
|
|||
import androidx.annotation.NonNull;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -50,17 +52,17 @@ import info.nightscout.androidaps.plugins.bus.RxBus;
|
|||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
|
||||
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.iob.iobCobCalculator.events.EventAutosensCalculationFinished;
|
||||
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin;
|
||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
|
||||
import info.nightscout.androidaps.queue.Callback;
|
||||
import info.nightscout.androidaps.queue.commands.Command;
|
||||
import info.nightscout.androidaps.utils.DateUtil;
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy;
|
||||
import info.nightscout.androidaps.utils.SP;
|
||||
import info.nightscout.androidaps.utils.T;
|
||||
import info.nightscout.androidaps.utils.ToastUtils;
|
||||
import io.reactivex.disposables.CompositeDisposable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
|
@ -85,9 +87,9 @@ public class LoopPlugin extends PluginBase {
|
|||
return loopPlugin;
|
||||
}
|
||||
|
||||
private long loopSuspendedTill = 0L; // end of manual loop suspend
|
||||
private boolean isSuperBolus = false;
|
||||
private boolean isDisconnected = false;
|
||||
private long loopSuspendedTill; // end of manual loop suspend
|
||||
private boolean isSuperBolus;
|
||||
private boolean isDisconnected;
|
||||
|
||||
public class LastRun {
|
||||
public APSResult request = null;
|
||||
|
@ -96,8 +98,11 @@ public class LoopPlugin extends PluginBase {
|
|||
public PumpEnactResult smbSetByPump = null;
|
||||
public String source = null;
|
||||
public Date lastAPSRun = null;
|
||||
public Date lastEnact = null;
|
||||
public Date lastOpenModeAccept;
|
||||
public long lastTBREnact = 0;
|
||||
public long lastSMBEnact = 0;
|
||||
public long lastTBRRequest = 0;
|
||||
public long lastSMBRequest = 0;
|
||||
public long lastOpenModeAccept;
|
||||
}
|
||||
|
||||
static public LastRun lastRun = null;
|
||||
|
@ -343,6 +348,10 @@ public class LoopPlugin extends PluginBase {
|
|||
lastRun.source = ((PluginBase) usedAPS).getName();
|
||||
lastRun.tbrSetByPump = null;
|
||||
lastRun.smbSetByPump = null;
|
||||
lastRun.lastTBREnact = 0;
|
||||
lastRun.lastTBRRequest = 0;
|
||||
lastRun.lastSMBEnact = 0;
|
||||
lastRun.lastSMBRequest = 0;
|
||||
|
||||
NSUpload.uploadDeviceStatus();
|
||||
|
||||
|
@ -379,14 +388,17 @@ public class LoopPlugin extends PluginBase {
|
|||
public void run() {
|
||||
if (result.enacted || result.success) {
|
||||
lastRun.tbrSetByPump = result;
|
||||
lastRun.lastEnact = lastRun.lastAPSRun;
|
||||
lastRun.lastTBRRequest = lastRun.lastAPSRun.getTime();
|
||||
lastRun.lastTBREnact = DateUtil.now();
|
||||
RxBus.INSTANCE.send(new EventLoopUpdateGui());
|
||||
applySMBRequest(resultAfterConstraints, new Callback() {
|
||||
@Override
|
||||
public void run() {
|
||||
//Callback is only called if a bolus was acutally requested
|
||||
if (result.enacted || result.success) {
|
||||
lastRun.smbSetByPump = result;
|
||||
lastRun.lastEnact = lastRun.lastAPSRun;
|
||||
lastRun.lastSMBRequest = lastRun.lastAPSRun.getTime();
|
||||
lastRun.lastSMBEnact = DateUtil.now();
|
||||
} else {
|
||||
new Thread(() -> {
|
||||
SystemClock.sleep(1000);
|
||||
|
@ -466,8 +478,9 @@ public class LoopPlugin extends PluginBase {
|
|||
public void run() {
|
||||
if (result.enacted) {
|
||||
lastRun.tbrSetByPump = result;
|
||||
lastRun.lastEnact = new Date();
|
||||
lastRun.lastOpenModeAccept = new Date();
|
||||
lastRun.lastTBRRequest = lastRun.lastAPSRun.getTime();
|
||||
lastRun.lastTBREnact = DateUtil.now();
|
||||
lastRun.lastOpenModeAccept = DateUtil.now();
|
||||
NSUpload.uploadDeviceStatus();
|
||||
SP.incInt(R.string.key_ObjectivesmanualEnacts);
|
||||
}
|
||||
|
@ -686,7 +699,7 @@ public class LoopPlugin extends PluginBase {
|
|||
}
|
||||
});
|
||||
}
|
||||
NSUpload.uploadOpenAPSOffline(durationInMinutes);
|
||||
createOfflineEvent(durationInMinutes);
|
||||
}
|
||||
|
||||
public void suspendLoop(int durationInMinutes) {
|
||||
|
@ -704,7 +717,23 @@ public class LoopPlugin extends PluginBase {
|
|||
}
|
||||
}
|
||||
});
|
||||
NSUpload.uploadOpenAPSOffline(durationInMinutes);
|
||||
createOfflineEvent(durationInMinutes);
|
||||
}
|
||||
|
||||
public void createOfflineEvent(int durationInMinutes) {
|
||||
JSONObject data = new JSONObject();
|
||||
try {
|
||||
data.put("eventType", CareportalEvent.OPENAPSOFFLINE);
|
||||
data.put("duration", durationInMinutes);
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
CareportalEvent event = new CareportalEvent();
|
||||
event.date = DateUtil.now();
|
||||
event.source = Source.USER;
|
||||
event.eventType = CareportalEvent.OPENAPSOFFLINE;
|
||||
event.json = data.toString();
|
||||
MainApp.getDbHelper().createOrUpdate(event);
|
||||
NSUpload.uploadOpenAPSOffline(event);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import javax.annotation.Nullable;
|
|||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||
import info.nightscout.androidaps.data.IobTotal;
|
||||
import info.nightscout.androidaps.data.MealData;
|
||||
|
@ -194,8 +195,6 @@ public class DetermineBasalAdapterAMAJS {
|
|||
double autosensDataRatio,
|
||||
boolean tempTargetSet) throws JSONException {
|
||||
|
||||
String units = profile.getUnits();
|
||||
|
||||
mProfile = new JSONObject();
|
||||
mProfile.put("max_iob", maxIob);
|
||||
mProfile.put("dia", Math.min(profile.getDia(), 3d));
|
||||
|
@ -206,7 +205,7 @@ public class DetermineBasalAdapterAMAJS {
|
|||
mProfile.put("max_bg", maxBg);
|
||||
mProfile.put("target_bg", targetBg);
|
||||
mProfile.put("carb_ratio", profile.getIc());
|
||||
mProfile.put("sens", Profile.toMgdl(profile.getIsf(), units));
|
||||
mProfile.put("sens", profile.getIsfMgdl());
|
||||
mProfile.put("max_daily_safety_multiplier", SP.getInt(R.string.key_openapsama_max_daily_safety_multiplier, 3));
|
||||
mProfile.put("current_basal_safety_multiplier", SP.getDouble(R.string.key_openapsama_current_basal_safety_multiplier, 4d));
|
||||
mProfile.put("skip_neutral_temps", true);
|
||||
|
@ -220,7 +219,7 @@ public class DetermineBasalAdapterAMAJS {
|
|||
mProfile.put("min_5m_carbimpact", SP.getDouble(R.string.key_openapsama_min_5m_carbimpact, SMBDefaults.min_5m_carbimpact));
|
||||
}
|
||||
|
||||
if (units.equals(Constants.MMOL)) {
|
||||
if (ProfileFunctions.getSystemUnits().equals(Constants.MMOL)) {
|
||||
mProfile.put("out_units", "mmol/L");
|
||||
}
|
||||
|
||||
|
|
|
@ -107,6 +107,13 @@ public class OpenAPSAMAPlugin extends PluginBase implements APSInterface {
|
|||
return;
|
||||
}
|
||||
|
||||
if (pump == null) {
|
||||
RxBus.INSTANCE.send(new EventOpenAPSUpdateResultGui(MainApp.gs(R.string.nopumpselected)));
|
||||
if (L.isEnabled(L.APS))
|
||||
log.debug(MainApp.gs(R.string.nopumpselected));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isEnabled(PluginType.APS)) {
|
||||
RxBus.INSTANCE.send(new EventOpenAPSUpdateResultGui(MainApp.gs(R.string.openapsma_disabled)));
|
||||
if (L.isEnabled(L.APS))
|
||||
|
@ -121,12 +128,10 @@ public class OpenAPSAMAPlugin extends PluginBase implements APSInterface {
|
|||
return;
|
||||
}
|
||||
|
||||
String units = profile.getUnits();
|
||||
|
||||
double maxBasal = MainApp.getConstraintChecker().getMaxBasalAllowed(profile).value();
|
||||
double minBg = Profile.toMgdl(profile.getTargetLow(), units);
|
||||
double maxBg = Profile.toMgdl(profile.getTargetHigh(), units);
|
||||
double targetBg = Profile.toMgdl(profile.getTarget(), units);
|
||||
double minBg = profile.getTargetLowMgdl();
|
||||
double maxBg = profile.getTargetHighMgdl();
|
||||
double targetBg = profile.getTargetMgdl();
|
||||
|
||||
minBg = Round.roundTo(minBg, 0.1d);
|
||||
maxBg = Round.roundTo(maxBg, 0.1d);
|
||||
|
@ -162,7 +167,7 @@ public class OpenAPSAMAPlugin extends PluginBase implements APSInterface {
|
|||
return;
|
||||
if (!HardLimits.checkOnlyHardLimits(profile.getIcTimeFromMidnight(Profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC))
|
||||
return;
|
||||
if (!HardLimits.checkOnlyHardLimits(Profile.toMgdl(profile.getIsf(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF))
|
||||
if (!HardLimits.checkOnlyHardLimits(profile.getIsfMgdl(), "sens", HardLimits.MINISF, HardLimits.MAXISF))
|
||||
return;
|
||||
if (!HardLimits.checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.02, HardLimits.maxBasal()))
|
||||
return;
|
||||
|
|
|
@ -20,6 +20,7 @@ import javax.annotation.Nullable;
|
|||
|
||||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||
import info.nightscout.androidaps.data.IobTotal;
|
||||
import info.nightscout.androidaps.data.MealData;
|
||||
|
@ -160,8 +161,6 @@ public class DetermineBasalAdapterMAJS {
|
|||
GlucoseStatus glucoseStatus,
|
||||
MealData mealData) throws JSONException {
|
||||
|
||||
String units = profile.getUnits();
|
||||
|
||||
mProfile = new JSONObject();
|
||||
mProfile.put("max_iob", maxIob);
|
||||
mProfile.put("dia", Math.min(profile.getDia(), 3d));
|
||||
|
@ -172,11 +171,11 @@ public class DetermineBasalAdapterMAJS {
|
|||
mProfile.put("max_bg", maxBg);
|
||||
mProfile.put("target_bg", targetBg);
|
||||
mProfile.put("carb_ratio", profile.getIc());
|
||||
mProfile.put("sens", Profile.toMgdl(profile.getIsf(), units));
|
||||
mProfile.put("sens", profile.getIsfMgdl());
|
||||
|
||||
mProfile.put("current_basal", basalRate);
|
||||
|
||||
if (units.equals(Constants.MMOL)) {
|
||||
if (ProfileFunctions.getSystemUnits().equals(Constants.MMOL)) {
|
||||
mProfile.put("out_units", "mmol/L");
|
||||
}
|
||||
|
||||
|
|
|
@ -106,6 +106,13 @@ public class OpenAPSMAPlugin extends PluginBase implements APSInterface {
|
|||
return;
|
||||
}
|
||||
|
||||
if (pump == null) {
|
||||
RxBus.INSTANCE.send(new EventOpenAPSUpdateResultGui(MainApp.gs(R.string.nopumpselected)));
|
||||
if (L.isEnabled(L.APS))
|
||||
log.debug(MainApp.gs(R.string.nopumpselected));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isEnabled(PluginType.APS)) {
|
||||
RxBus.INSTANCE.send(new EventOpenAPSUpdateResultGui(MainApp.gs(R.string.openapsma_disabled)));
|
||||
if (L.isEnabled(L.APS))
|
||||
|
@ -120,13 +127,11 @@ public class OpenAPSMAPlugin extends PluginBase implements APSInterface {
|
|||
return;
|
||||
}
|
||||
|
||||
String units = profile.getUnits();
|
||||
|
||||
double maxBasal = MainApp.getConstraintChecker().getMaxBasalAllowed(profile).value();
|
||||
|
||||
double minBg = Profile.toMgdl(profile.getTargetLow(), units);
|
||||
double maxBg = Profile.toMgdl(profile.getTargetHigh(), units);
|
||||
double targetBg = Profile.toMgdl(profile.getTarget(), units);
|
||||
double minBg = profile.getTargetLowMgdl();
|
||||
double maxBg = profile.getTargetHighMgdl();
|
||||
double targetBg = profile.getTargetMgdl();
|
||||
|
||||
minBg = Round.roundTo(minBg, 0.1d);
|
||||
maxBg = Round.roundTo(maxBg, 0.1d);
|
||||
|
@ -160,7 +165,7 @@ public class OpenAPSMAPlugin extends PluginBase implements APSInterface {
|
|||
return;
|
||||
if (!checkOnlyHardLimits(profile.getIcTimeFromMidnight(Profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC))
|
||||
return;
|
||||
if (!checkOnlyHardLimits(Profile.toMgdl(profile.getIsf(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF))
|
||||
if (!checkOnlyHardLimits(profile.getIsfMgdl(), "sens", HardLimits.MINISF, HardLimits.MAXISF))
|
||||
return;
|
||||
if (!checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.02, HardLimits.maxBasal()))
|
||||
return;
|
||||
|
|
|
@ -23,6 +23,7 @@ import javax.annotation.Nullable;
|
|||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||
import info.nightscout.androidaps.data.IobTotal;
|
||||
import info.nightscout.androidaps.data.MealData;
|
||||
|
@ -219,8 +220,6 @@ public class DetermineBasalAdapterSMBJS {
|
|||
boolean advancedFiltering
|
||||
) throws JSONException {
|
||||
|
||||
String units = profile.getUnits();
|
||||
|
||||
mProfile = new JSONObject();
|
||||
|
||||
mProfile.put("max_iob", maxIob);
|
||||
|
@ -232,7 +231,7 @@ public class DetermineBasalAdapterSMBJS {
|
|||
mProfile.put("max_bg", maxBg);
|
||||
mProfile.put("target_bg", targetBg);
|
||||
mProfile.put("carb_ratio", profile.getIc());
|
||||
mProfile.put("sens", Profile.toMgdl(profile.getIsf(), units));
|
||||
mProfile.put("sens", profile.getIsfMgdl());
|
||||
mProfile.put("max_daily_safety_multiplier", SP.getInt(R.string.key_openapsama_max_daily_safety_multiplier, 3));
|
||||
mProfile.put("current_basal_safety_multiplier", SP.getDouble(R.string.key_openapsama_current_basal_safety_multiplier, 4d));
|
||||
|
||||
|
@ -273,7 +272,7 @@ public class DetermineBasalAdapterSMBJS {
|
|||
mProfile.put("temptargetSet", tempTargetSet);
|
||||
mProfile.put("autosens_max", SafeParse.stringToDouble(SP.getString(R.string.key_openapsama_autosens_max, "1.2")));
|
||||
|
||||
if (units.equals(Constants.MMOL)) {
|
||||
if (ProfileFunctions.getSystemUnits().equals(Constants.MMOL)) {
|
||||
mProfile.put("out_units", "mmol/L");
|
||||
}
|
||||
|
||||
|
|
|
@ -111,6 +111,13 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface, Constr
|
|||
return;
|
||||
}
|
||||
|
||||
if (pump == null) {
|
||||
RxBus.INSTANCE.send(new EventOpenAPSUpdateResultGui(MainApp.gs(R.string.nopumpselected)));
|
||||
if (L.isEnabled(L.APS))
|
||||
log.debug(MainApp.gs(R.string.nopumpselected));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isEnabled(PluginType.APS)) {
|
||||
RxBus.INSTANCE.send(new EventOpenAPSUpdateResultGui(MainApp.gs(R.string.openapsma_disabled)));
|
||||
if (L.isEnabled(L.APS))
|
||||
|
@ -125,16 +132,14 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface, Constr
|
|||
return;
|
||||
}
|
||||
|
||||
String units = profile.getUnits();
|
||||
|
||||
Constraint<Double> inputConstraints = new Constraint<>(0d); // fake. only for collecting all results
|
||||
|
||||
Constraint<Double> maxBasalConstraint = MainApp.getConstraintChecker().getMaxBasalAllowed(profile);
|
||||
inputConstraints.copyReasons(maxBasalConstraint);
|
||||
double maxBasal = maxBasalConstraint.value();
|
||||
double minBg = Profile.toMgdl(profile.getTargetLow(), units);
|
||||
double maxBg = Profile.toMgdl(profile.getTargetHigh(), units);
|
||||
double targetBg = Profile.toMgdl(profile.getTarget(), units);
|
||||
double minBg = profile.getTargetLowMgdl();
|
||||
double maxBg = profile.getTargetHighMgdl();
|
||||
double targetBg = profile.getTargetMgdl();
|
||||
|
||||
minBg = Round.roundTo(minBg, 0.1d);
|
||||
maxBg = Round.roundTo(maxBg, 0.1d);
|
||||
|
@ -168,7 +173,7 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface, Constr
|
|||
return;
|
||||
if (!checkOnlyHardLimits(profile.getIcTimeFromMidnight(Profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC))
|
||||
return;
|
||||
if (!checkOnlyHardLimits(Profile.toMgdl(profile.getIsf(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF))
|
||||
if (!checkOnlyHardLimits(profile.getIsfMgdl(), "sens", HardLimits.MINISF, HardLimits.MAXISF))
|
||||
return;
|
||||
if (!checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.02, HardLimits.maxBasal()))
|
||||
return;
|
||||
|
|
|
@ -2,7 +2,11 @@ package info.nightscout.androidaps.plugins.configBuilder
|
|||
|
||||
import android.content.Intent
|
||||
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.activities.PreferencesActivity
|
||||
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.plugins.bus.RxBus
|
||||
import info.nightscout.androidaps.utils.PasswordProtection
|
||||
import info.nightscout.androidaps.utils.toVisibility
|
||||
|
||||
class PluginViewHolder internal constructor(private val fragment: ConfigBuilderFragment,
|
||||
private val pluginType: PluginType,
|
||||
|
@ -56,8 +61,8 @@ class PluginViewHolder internal constructor(private val fragment: ConfigBuilderF
|
|||
}
|
||||
|
||||
fun update() {
|
||||
enabledExclusive.visibility = if (areMultipleSelectionsAllowed(pluginType)) View.GONE else View.VISIBLE
|
||||
enabledInclusive.visibility = if (areMultipleSelectionsAllowed(pluginType)) View.VISIBLE else View.GONE
|
||||
enabledExclusive.visibility = areMultipleSelectionsAllowed(pluginType).not().toVisibility()
|
||||
enabledInclusive.visibility = areMultipleSelectionsAllowed(pluginType).toVisibility()
|
||||
enabledExclusive.isChecked = plugin.isEnabled(pluginType)
|
||||
enabledInclusive.isChecked = plugin.isEnabled(pluginType)
|
||||
enabledInclusive.isEnabled = !plugin.pluginDescription.alwaysEnabled
|
||||
|
@ -70,7 +75,7 @@ class PluginViewHolder internal constructor(private val fragment: ConfigBuilderF
|
|||
pluginDescription.text = plugin.description
|
||||
}
|
||||
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.isChecked = plugin.isFragmentVisible
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ import info.nightscout.androidaps.interfaces.ProfileInterface;
|
|||
import info.nightscout.androidaps.interfaces.TreatmentsInterface;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
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.queue.Callback;
|
||||
import info.nightscout.androidaps.utils.DateUtil;
|
||||
|
@ -124,9 +124,8 @@ public class ProfileFunctions {
|
|||
return getProfile(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
public String getProfileUnits() {
|
||||
Profile profile = getProfile();
|
||||
return profile != null ? profile.getUnits() : Constants.MGDL;
|
||||
public static String getSystemUnits() {
|
||||
return SP.getString(R.string.key_units, Constants.MGDL);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
@ -171,8 +170,8 @@ public class ProfileFunctions {
|
|||
return profileSwitch;
|
||||
}
|
||||
|
||||
public static void doProfileSwitch(final ProfileStore profileStore, final String profileName, final int duration, final int percentage, final int timeshift) {
|
||||
ProfileSwitch profileSwitch = prepareProfileSwitch(profileStore, profileName, duration, percentage, timeshift, System.currentTimeMillis());
|
||||
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, date);
|
||||
TreatmentsPlugin.getPlugin().addToHistoryProfileSwitch(profileSwitch);
|
||||
if (percentage == 90 && duration == 10)
|
||||
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.objectives.Objective.ExamTask
|
||||
import info.nightscout.androidaps.receivers.NetworkChangeReceiver
|
||||
import info.nightscout.androidaps.setupwizard.events.EventSWUpdate
|
||||
import info.nightscout.androidaps.utils.*
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
|
@ -71,13 +72,13 @@ class ObjectivesFragment : Fragment() {
|
|||
override fun onResume() {
|
||||
super.onResume()
|
||||
disposable.add(RxBus
|
||||
.toObservable(EventObjectivesUpdateGui::class.java)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({
|
||||
objectives_recyclerview.adapter?.notifyDataSetChanged()
|
||||
}, {
|
||||
FabricPrivacy.logException(it)
|
||||
})
|
||||
.toObservable(EventObjectivesUpdateGui::class.java)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({
|
||||
objectives_recyclerview.adapter?.notifyDataSetChanged()
|
||||
}, {
|
||||
FabricPrivacy.logException(it)
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -217,6 +218,7 @@ class ObjectivesFragment : Fragment() {
|
|||
scrollToCurrentObjective()
|
||||
startUpdateTimer()
|
||||
RxBus.send(EventObjectivesUpdateGui())
|
||||
RxBus.send(EventSWUpdate(false))
|
||||
} else {
|
||||
// move out of UI thread
|
||||
Thread {
|
||||
|
@ -234,6 +236,7 @@ class ObjectivesFragment : Fragment() {
|
|||
RxBus.send(EventNtpStatus(MainApp.gs(R.string.success), 100))
|
||||
SystemClock.sleep(1000)
|
||||
RxBus.send(EventObjectivesUpdateGui())
|
||||
RxBus.send(EventSWUpdate(false))
|
||||
SystemClock.sleep(100)
|
||||
scrollToCurrentObjective()
|
||||
} else {
|
||||
|
@ -254,6 +257,7 @@ class ObjectivesFragment : Fragment() {
|
|||
scrollToCurrentObjective()
|
||||
startUpdateTimer()
|
||||
RxBus.send(EventObjectivesUpdateGui())
|
||||
RxBus.send(EventSWUpdate(false))
|
||||
} else
|
||||
// move out of UI thread
|
||||
Thread {
|
||||
|
@ -270,6 +274,7 @@ class ObjectivesFragment : Fragment() {
|
|||
RxBus.send(EventNtpStatus(MainApp.gs(R.string.success), 100))
|
||||
SystemClock.sleep(1000)
|
||||
RxBus.send(EventObjectivesUpdateGui())
|
||||
RxBus.send(EventSWUpdate(false))
|
||||
SystemClock.sleep(100)
|
||||
scrollToCurrentObjective()
|
||||
} else {
|
||||
|
@ -280,16 +285,20 @@ class ObjectivesFragment : Fragment() {
|
|||
}.start()
|
||||
}
|
||||
holder.unStart.setOnClickListener {
|
||||
OKDialog.showConfirmation(activity, MainApp.gs(R.string.doyouwantresetstart)) {
|
||||
objective.startedOn = 0
|
||||
scrollToCurrentObjective()
|
||||
RxBus.send(EventObjectivesUpdateGui())
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, MainApp.gs(R.string.objectives), MainApp.gs(R.string.doyouwantresetstart), Runnable {
|
||||
objective.startedOn = 0
|
||||
scrollToCurrentObjective()
|
||||
RxBus.send(EventObjectivesUpdateGui())
|
||||
RxBus.send(EventSWUpdate(false))
|
||||
})
|
||||
}
|
||||
}
|
||||
holder.unFinish.setOnClickListener {
|
||||
objective.accomplishedOn = 0
|
||||
scrollToCurrentObjective()
|
||||
RxBus.send(EventObjectivesUpdateGui())
|
||||
RxBus.send(EventSWUpdate(false))
|
||||
}
|
||||
if (objective.hasSpecialInput && !objective.isAccomplished && objective.isStarted && objective.specialActionEnabled()) {
|
||||
// generate random request code if none exists
|
||||
|
@ -313,7 +322,6 @@ class ObjectivesFragment : Fragment() {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return ObjectivesPlugin.objectives.size
|
||||
}
|
||||
|
|
|
@ -122,9 +122,9 @@ object ObjectivesPlugin : PluginBase(PluginDescription()
|
|||
SP.putLong("Objectives_" + "smb" + "_started", DateUtil.now())
|
||||
SP.putLong("Objectives_" + "smb" + "_accomplished", DateUtil.now())
|
||||
setupObjectives()
|
||||
OKDialog.show(activity, "", MainApp.gs(R.string.codeaccepted), null)
|
||||
OKDialog.show(activity, MainApp.gs(R.string.objectives), MainApp.gs(R.string.codeaccepted))
|
||||
} 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 io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import kotlinx.android.synthetic.main.overview_bolusprogress_dialog.*
|
||||
import kotlinx.android.synthetic.main.dialog_bolusprogress.*
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
class NtpProgressDialog : DialogFragment() {
|
||||
|
@ -33,16 +33,17 @@ class NtpProgressDialog : DialogFragment() {
|
|||
state = savedInstanceState?.getString("state", DEFAULT_STATE) ?: DEFAULT_STATE
|
||||
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?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
overview_bolusprogress_stop.setOnClickListener { dismiss() }
|
||||
overview_bolusprogress_status.setText(state)
|
||||
overview_bolusprogress_progressbar.setMax(100)
|
||||
overview_bolusprogress_progressbar.setProgress(percent)
|
||||
overview_bolusprogress_status.text = state
|
||||
overview_bolusprogress_progressbar.max = 100
|
||||
overview_bolusprogress_progressbar.progress = percent
|
||||
overview_bolusprogress_stop.text = MainApp.gs(R.string.close)
|
||||
overview_bolusprogress_title.text = MainApp.gs(R.string.please_wait)
|
||||
}
|
||||
|
||||
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.notifications.Notification;
|
||||
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.HardLimits;
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,19 @@
|
|||
package info.nightscout.androidaps.plugins.constraints.versionChecker
|
||||
|
||||
import info.nightscout.androidaps.BuildConfig
|
||||
import info.nightscout.androidaps.MainApp
|
||||
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.general.overview.events.EventNewNotification
|
||||
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
|
||||
import info.nightscout.androidaps.utils.SP
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
/**
|
||||
* Usually we would have a class here.
|
||||
|
@ -16,16 +22,23 @@ import java.util.concurrent.TimeUnit
|
|||
* */
|
||||
|
||||
object VersionCheckerPlugin : PluginBase(PluginDescription()
|
||||
.mainType(PluginType.CONSTRAINTS)
|
||||
.neverVisible(true)
|
||||
.alwaysEnabled(true)
|
||||
.showInList(false)
|
||||
.pluginName(R.string.versionChecker)), ConstraintsInterface {
|
||||
.mainType(PluginType.CONSTRAINTS)
|
||||
.neverVisible(true)
|
||||
.alwaysEnabled(true)
|
||||
.showInList(false)
|
||||
.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> {
|
||||
checkWarning()
|
||||
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)
|
||||
else
|
||||
value
|
||||
|
@ -33,41 +46,49 @@ object VersionCheckerPlugin : PluginBase(PluginDescription()
|
|||
|
||||
private fun checkWarning() {
|
||||
val now = System.currentTimeMillis()
|
||||
|
||||
|
||||
if (!SP.contains(R.string.key_last_versionchecker_plugin_warning)) {
|
||||
SP.putLong(R.string.key_last_versionchecker_plugin_warning, now)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
if (isOldVersion(GRACE_PERIOD_WARNING) && shouldWarnAgain(now)) {
|
||||
if (isOldVersion(gracePeriod.warning.daysToMillis()) && shouldWarnAgain(now)) {
|
||||
// store last notification time
|
||||
SP.putLong(R.string.key_last_versionchecker_plugin_warning, now)
|
||||
|
||||
//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)
|
||||
RxBus.send(EventNewNotification(notification))
|
||||
}
|
||||
}
|
||||
|
||||
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> =
|
||||
if (isOldVersion(GRACE_PERIOD_OLD))
|
||||
maxIob.set(0.toDouble(), MainApp.gs(R.string.old_version), this)
|
||||
else
|
||||
maxIob
|
||||
if (isOldVersion(gracePeriod.old.daysToMillis()))
|
||||
maxIob.set(0.toDouble(), MainApp.gs(R.string.old_version), this)
|
||||
else
|
||||
maxIob
|
||||
|
||||
private fun isOldVersion(gracePeriod: Long): Boolean {
|
||||
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)
|
||||
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)
|
||||
private val WARN_EVERY = TimeUnit.DAYS.toMillis(1)
|
||||
|
||||
}
|
||||
|
||||
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.ViewGroup
|
||||
import android.widget.LinearLayout
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import info.nightscout.androidaps.Config
|
||||
import info.nightscout.androidaps.MainApp
|
||||
|
@ -18,20 +19,27 @@ import info.nightscout.androidaps.plugins.bus.RxBus
|
|||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
|
||||
import info.nightscout.androidaps.plugins.general.actions.defs.CustomAction
|
||||
import info.nightscout.androidaps.plugins.general.actions.dialogs.FillDialog
|
||||
import info.nightscout.androidaps.plugins.general.actions.dialogs.NewExtendedBolusDialog
|
||||
import info.nightscout.androidaps.plugins.general.actions.dialogs.NewTempBasalDialog
|
||||
import info.nightscout.androidaps.dialogs.CareDialog
|
||||
import info.nightscout.androidaps.dialogs.ExtendedBolusDialog
|
||||
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.Dialogs.NewNSTreatmentDialog
|
||||
import info.nightscout.androidaps.activities.ErrorHelperActivity
|
||||
import info.nightscout.androidaps.dialogs.ProfileSwitchDialog
|
||||
import info.nightscout.androidaps.dialogs.TempTargetDialog
|
||||
import info.nightscout.androidaps.logging.L
|
||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
||||
import info.nightscout.androidaps.queue.Callback
|
||||
import info.nightscout.androidaps.utils.*
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import kotlinx.android.synthetic.main.actions_fragment.*
|
||||
import kotlinx.android.synthetic.main.careportal_stats_fragment.*
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.util.*
|
||||
|
||||
class ActionsFragment : Fragment() {
|
||||
private val log = LoggerFactory.getLogger(L.CORE)
|
||||
|
||||
private var disposable: CompositeDisposable = CompositeDisposable()
|
||||
|
||||
|
@ -47,39 +55,52 @@ class ActionsFragment : Fragment() {
|
|||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
actions_profileswitch.setOnClickListener {
|
||||
val newDialog = NewNSTreatmentDialog()
|
||||
val profileSwitch = CareportalFragment.PROFILESWITCH
|
||||
profileSwitch.executeProfileSwitch = true
|
||||
newDialog.setOptions(profileSwitch, R.string.careportal_profileswitch)
|
||||
fragmentManager?.let { newDialog.show(it, "NewNSTreatmentDialog") }
|
||||
fragmentManager?.let { ProfileSwitchDialog().show(it, "Actions") }
|
||||
}
|
||||
actions_temptarget.setOnClickListener {
|
||||
val newTTDialog = NewNSTreatmentDialog()
|
||||
val temptarget = CareportalFragment.TEMPTARGET
|
||||
temptarget.executeTempTarget = true
|
||||
newTTDialog.setOptions(temptarget, R.string.careportal_temporarytarget)
|
||||
fragmentManager?.let { newTTDialog.show(it, "NewNSTreatmentDialog") }
|
||||
fragmentManager?.let { TempTargetDialog().show(it, "Actions") }
|
||||
}
|
||||
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 {
|
||||
if (TreatmentsPlugin.getPlugin().isInHistoryExtendedBoluslInProgress) {
|
||||
log.debug("USER ENTRY: CANCEL EXTENDED BOLUS")
|
||||
ConfigBuilderPlugin.getPlugin().commandQueue.cancelExtended(object : Callback() {
|
||||
override fun run() {
|
||||
if (!result.success)
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().applicationContext, MainApp.gs(R.string.extendedbolusdeliveryerror))
|
||||
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.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 {
|
||||
if (TreatmentsPlugin.getPlugin().isTempBasalInProgress) {
|
||||
log.debug("USER ENTRY: CANCEL TEMP BASAL")
|
||||
ConfigBuilderPlugin.getPlugin().commandQueue.cancelTempBasal(true, object : Callback() {
|
||||
override fun run() {
|
||||
if (!result.success)
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().applicationContext, MainApp.gs(R.string.tempbasaldeliveryerror))
|
||||
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)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -87,6 +108,21 @@ class ActionsFragment : Fragment() {
|
|||
actions_fill.setOnClickListener { fragmentManager?.let { FillDialog().show(it, "FillDialog") } }
|
||||
actions_historybrowser.setOnClickListener { startActivity(Intent(context, HistoryBrowseActivity::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)
|
||||
}
|
||||
|
@ -97,43 +133,27 @@ class ActionsFragment : Fragment() {
|
|||
disposable += RxBus
|
||||
.toObservable(EventInitializationChanged::class.java)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({
|
||||
updateGui()
|
||||
}, {
|
||||
FabricPrivacy.logException(it)
|
||||
})
|
||||
.subscribe({ updateGui() }, { FabricPrivacy.logException(it) })
|
||||
disposable += RxBus
|
||||
.toObservable(EventRefreshOverview::class.java)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({
|
||||
updateGui()
|
||||
}, {
|
||||
FabricPrivacy.logException(it)
|
||||
})
|
||||
.subscribe({ updateGui() }, { FabricPrivacy.logException(it) })
|
||||
disposable += RxBus
|
||||
.toObservable(EventExtendedBolusChange::class.java)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({
|
||||
updateGui()
|
||||
}, {
|
||||
FabricPrivacy.logException(it)
|
||||
})
|
||||
.subscribe({ updateGui() }, { FabricPrivacy.logException(it) })
|
||||
disposable += RxBus
|
||||
.toObservable(EventTempBasalChange::class.java)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({
|
||||
updateGui()
|
||||
}, {
|
||||
FabricPrivacy.logException(it)
|
||||
})
|
||||
.subscribe({ updateGui() }, { FabricPrivacy.logException(it) })
|
||||
disposable += RxBus
|
||||
.toObservable(EventCustomActionsChanged::class.java)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({
|
||||
updateGui()
|
||||
}, {
|
||||
FabricPrivacy.logException(it)
|
||||
})
|
||||
.subscribe({ updateGui() }, { FabricPrivacy.logException(it) })
|
||||
disposable += RxBus
|
||||
.toObservable(EventCareportalEventChange::class.java)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({ updateGui() }, { FabricPrivacy.logException(it) })
|
||||
updateGui()
|
||||
}
|
||||
|
||||
|
@ -164,7 +184,7 @@ class ActionsFragment : Fragment() {
|
|||
|
||||
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_cancel?.visibility = View.GONE
|
||||
} else {
|
||||
|
@ -172,7 +192,7 @@ class ActionsFragment : Fragment() {
|
|||
if (activeExtendedBolus != null) {
|
||||
actions_extendedbolus?.visibility = View.GONE
|
||||
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 {
|
||||
actions_extendedbolus?.visibility = View.VISIBLE
|
||||
actions_extendedbolus_cancel?.visibility = View.GONE
|
||||
|
@ -198,8 +218,11 @@ class ActionsFragment : Fragment() {
|
|||
if (!pump.pumpDescription.isRefillingCapable || !pump.isInitialized || pump.isSuspended) View.GONE
|
||||
else View.VISIBLE
|
||||
|
||||
actions_temptarget?.visibility = if (!Config.APS) View.GONE else View.VISIBLE
|
||||
actions_tddstats?.visibility = if (!pump.pumpDescription.supportsTDDs) View.GONE else View.VISIBLE
|
||||
actions_temptarget?.visibility = Config.APS.toVisibility()
|
||||
actions_tddstats?.visibility = pump.pumpDescription.supportsTDDs.toVisibility()
|
||||
activity?.let { activity ->
|
||||
CareportalFragment.updateAge(activity, careportal_sensorage, careportal_insulinage, careportal_canulaage, careportal_pbage)
|
||||
}
|
||||
checkPumpCustomActions()
|
||||
}
|
||||
|
||||
|
@ -224,8 +247,7 @@ class ActionsFragment : Fragment() {
|
|||
val action = this.pumpCustomActions[b.text.toString()]
|
||||
ConfigBuilderPlugin.getPlugin().activePump!!.executeCustomAction(action!!.customActionType)
|
||||
}
|
||||
|
||||
val top = resources.getDrawable(customAction.iconResourceId)
|
||||
val top = activity?.let { ContextCompat.getDrawable(it, customAction.iconResourceId) }
|
||||
btn.setCompoundDrawablesWithIntrinsicBounds(null, top, null, null)
|
||||
|
||||
action_buttons_layout?.addView(btn)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package info.nightscout.androidaps.plugins.general.actions
|
||||
|
||||
import info.nightscout.androidaps.Config
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.interfaces.PluginBase
|
||||
import info.nightscout.androidaps.interfaces.PluginDescription
|
||||
|
@ -8,6 +9,8 @@ import info.nightscout.androidaps.interfaces.PluginType
|
|||
object ActionsPlugin : PluginBase(PluginDescription()
|
||||
.mainType(PluginType.GENERAL)
|
||||
.fragmentClass(ActionsFragment::class.qualifiedName)
|
||||
.enableByDefault(Config.APS || Config.PUMPCONTROL)
|
||||
.visibleByDefault(Config.APS || Config.PUMPCONTROL)
|
||||
.pluginName(R.string.actions)
|
||||
.shortName(R.string.actions_shortname)
|
||||
.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,27 +1,35 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation
|
||||
|
||||
import android.os.Bundle
|
||||
import android.text.method.ScrollingMovementMethod
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||
import info.nightscout.androidaps.plugins.general.automation.dialogs.EditEventDialog
|
||||
import info.nightscout.androidaps.plugins.general.automation.dragHelpers.OnStartDragListener
|
||||
import info.nightscout.androidaps.plugins.general.automation.dragHelpers.SimpleItemTouchHelperCallback
|
||||
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationDataChanged
|
||||
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateGui
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||
import info.nightscout.androidaps.utils.HtmlHelper
|
||||
import info.nightscout.androidaps.utils.plusAssign
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import kotlinx.android.synthetic.main.automation_fragment.*
|
||||
|
||||
class AutomationFragment : Fragment() {
|
||||
class AutomationFragment : Fragment(), OnStartDragListener {
|
||||
|
||||
private var disposable: CompositeDisposable = CompositeDisposable()
|
||||
private var eventListAdapter: EventListAdapter? = null
|
||||
|
||||
private var itemTouchHelper: ItemTouchHelper? = null
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return inflater.inflate(R.layout.automation_fragment, container, false)
|
||||
}
|
||||
|
@ -29,10 +37,12 @@ class AutomationFragment : Fragment() {
|
|||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
eventListAdapter = EventListAdapter(AutomationPlugin.automationEvents, fragmentManager, activity)
|
||||
eventListAdapter = EventListAdapter(AutomationPlugin.automationEvents, fragmentManager, activity, this)
|
||||
automation_eventListView.layoutManager = LinearLayoutManager(context)
|
||||
automation_eventListView.adapter = eventListAdapter
|
||||
|
||||
automation_logView.setMovementMethod(ScrollingMovementMethod())
|
||||
|
||||
automation_fabAddEvent.setOnClickListener {
|
||||
val dialog = EditEventDialog()
|
||||
val args = Bundle()
|
||||
|
@ -42,6 +52,10 @@ class AutomationFragment : Fragment() {
|
|||
fragmentManager?.let { dialog.show(it, "EditEventDialog") }
|
||||
}
|
||||
|
||||
val callback: ItemTouchHelper.Callback = SimpleItemTouchHelperCallback(eventListAdapter!!)
|
||||
itemTouchHelper = ItemTouchHelper(callback)
|
||||
itemTouchHelper?.attachToRecyclerView(automation_eventListView)
|
||||
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
|
@ -77,8 +91,12 @@ class AutomationFragment : Fragment() {
|
|||
eventListAdapter?.notifyDataSetChanged()
|
||||
val sb = StringBuilder()
|
||||
for (l in AutomationPlugin.executionLog.reversed())
|
||||
sb.append(l).append("\n")
|
||||
automation_logView?.text = sb.toString()
|
||||
sb.append(l).append("<br>")
|
||||
automation_logView?.text = HtmlHelper.fromHtml(sb.toString())
|
||||
}
|
||||
|
||||
override fun onStartDrag(viewHolder: RecyclerView.ViewHolder) {
|
||||
itemTouchHelper?.startDrag(viewHolder);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -161,7 +161,7 @@ object AutomationPlugin : PluginBase(PluginDescription()
|
|||
private fun processActions() {
|
||||
if (!isEnabled(PluginType.GENERAL))
|
||||
return
|
||||
if (LoopPlugin.getPlugin().isSuspended) {
|
||||
if (LoopPlugin.getPlugin().isSuspended || !LoopPlugin.getPlugin().isEnabled(PluginType.LOOP)) {
|
||||
if (L.isEnabled(L.AUTOMATION))
|
||||
log.debug("Loop deactivated")
|
||||
return
|
||||
|
@ -178,10 +178,10 @@ object AutomationPlugin : PluginBase(PluginDescription()
|
|||
val sb = StringBuilder()
|
||||
sb.append(DateUtil.timeString(DateUtil.now()))
|
||||
sb.append(" ")
|
||||
sb.append(if (result.success) "☺" else "X")
|
||||
sb.append(" ")
|
||||
sb.append(if (result.success) "☺" else "▼")
|
||||
sb.append(" <b>")
|
||||
sb.append(event.title)
|
||||
sb.append(": ")
|
||||
sb.append(":</b> ")
|
||||
sb.append(action.shortDescription())
|
||||
sb.append(": ")
|
||||
sb.append(result.comment)
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CheckBox;
|
||||
|
@ -17,6 +20,7 @@ import androidx.annotation.NonNull;
|
|||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -25,19 +29,26 @@ import info.nightscout.androidaps.R;
|
|||
import info.nightscout.androidaps.plugins.bus.RxBus;
|
||||
import info.nightscout.androidaps.plugins.general.automation.actions.Action;
|
||||
import info.nightscout.androidaps.plugins.general.automation.dialogs.EditEventDialog;
|
||||
import info.nightscout.androidaps.plugins.general.automation.dragHelpers.ItemTouchHelperAdapter;
|
||||
import info.nightscout.androidaps.plugins.general.automation.dragHelpers.ItemTouchHelperViewHolder;
|
||||
import info.nightscout.androidaps.plugins.general.automation.dragHelpers.OnStartDragListener;
|
||||
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.triggers.TriggerConnector;
|
||||
import info.nightscout.androidaps.utils.OKDialog;
|
||||
|
||||
class EventListAdapter extends RecyclerView.Adapter<EventListAdapter.ViewHolder> {
|
||||
class EventListAdapter extends RecyclerView.Adapter<EventListAdapter.ViewHolder> implements ItemTouchHelperAdapter {
|
||||
private final List<AutomationEvent> eventList;
|
||||
private final FragmentManager fragmentManager;
|
||||
private final Activity activity;
|
||||
|
||||
EventListAdapter(List<AutomationEvent> events, FragmentManager fragmentManager, Activity activity) {
|
||||
private final OnStartDragListener mDragStartListener;
|
||||
|
||||
EventListAdapter(List<AutomationEvent> events, FragmentManager fragmentManager, Activity activity, OnStartDragListener dragStartListener) {
|
||||
this.eventList = events;
|
||||
this.fragmentManager = fragmentManager;
|
||||
this.activity = activity;
|
||||
mDragStartListener = dragStartListener;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
@ -54,6 +65,7 @@ class EventListAdapter extends RecyclerView.Adapter<EventListAdapter.ViewHolder>
|
|||
layout.addView(iv);
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||
final AutomationEvent event = eventList.get(position);
|
||||
|
@ -91,16 +103,10 @@ class EventListAdapter extends RecyclerView.Adapter<EventListAdapter.ViewHolder>
|
|||
RxBus.INSTANCE.send(new EventAutomationDataChanged());
|
||||
});
|
||||
|
||||
// remove event
|
||||
holder.iconTrash.setOnClickListener(v ->
|
||||
OKDialog.showConfirmation(activity, MainApp.gs(R.string.removerecord) + " " + event.getTitle(), () -> {
|
||||
eventList.remove(event);
|
||||
RxBus.INSTANCE.send(new EventAutomationDataChanged());
|
||||
})
|
||||
);
|
||||
|
||||
// edit event
|
||||
holder.rootLayout.setOnClickListener(v -> {
|
||||
holder.rootLayout.setOnClickListener(v ->
|
||||
|
||||
{
|
||||
//EditEventDialog dialog = EditEventDialog.Companion.newInstance(event, false);
|
||||
EditEventDialog dialog = new EditEventDialog();
|
||||
Bundle args = new Bundle();
|
||||
|
@ -110,6 +116,17 @@ class EventListAdapter extends RecyclerView.Adapter<EventListAdapter.ViewHolder>
|
|||
if (fragmentManager != null)
|
||||
dialog.show(fragmentManager, "EditEventDialog");
|
||||
});
|
||||
|
||||
// Start a drag whenever the handle view it touched
|
||||
holder.iconSort.setOnTouchListener((v, motionEvent) ->
|
||||
|
||||
{
|
||||
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
mDragStartListener.onStartDrag(holder);
|
||||
return true;
|
||||
}
|
||||
return v.onTouchEvent(motionEvent);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -117,12 +134,33 @@ class EventListAdapter extends RecyclerView.Adapter<EventListAdapter.ViewHolder>
|
|||
return eventList.size();
|
||||
}
|
||||
|
||||
static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
@Override
|
||||
public boolean onItemMove(int fromPosition, int toPosition) {
|
||||
Collections.swap(eventList, fromPosition, toPosition);
|
||||
notifyItemMoved(fromPosition, toPosition);
|
||||
RxBus.INSTANCE.send(new EventAutomationDataChanged());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemDismiss(int position) {
|
||||
OKDialog.showConfirmation(activity, MainApp.gs(R.string.removerecord) + " " + eventList.get(position).getTitle(),
|
||||
() -> {
|
||||
eventList.remove(position);
|
||||
notifyItemRemoved(position);
|
||||
RxBus.INSTANCE.send(new EventAutomationDataChanged());
|
||||
RxBus.INSTANCE.send(new EventAutomationUpdateGui());
|
||||
}, () -> {
|
||||
RxBus.INSTANCE.send(new EventAutomationUpdateGui());
|
||||
});
|
||||
}
|
||||
|
||||
static class ViewHolder extends RecyclerView.ViewHolder implements ItemTouchHelperViewHolder {
|
||||
final RelativeLayout rootLayout;
|
||||
final LinearLayout iconLayout;
|
||||
final TextView eventTitle;
|
||||
final Context context;
|
||||
final ImageView iconTrash;
|
||||
final ImageView iconSort;
|
||||
final CheckBox enabled;
|
||||
|
||||
ViewHolder(View view, Context context) {
|
||||
|
@ -131,8 +169,18 @@ class EventListAdapter extends RecyclerView.Adapter<EventListAdapter.ViewHolder>
|
|||
eventTitle = view.findViewById(R.id.viewEventTitle);
|
||||
rootLayout = view.findViewById(R.id.rootLayout);
|
||||
iconLayout = view.findViewById(R.id.iconLayout);
|
||||
iconTrash = view.findViewById(R.id.iconTrash);
|
||||
iconSort = view.findViewById(R.id.iconSort);
|
||||
enabled = view.findViewById(R.id.automation_enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemSelected() {
|
||||
itemView.setBackgroundColor(Color.LTGRAY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClear() {
|
||||
itemView.setBackgroundColor(MainApp.gc(R.color.ribbonDefault));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ public class ActionLoopResume extends Action {
|
|||
if (LoopPlugin.getPlugin().isSuspended()) {
|
||||
LoopPlugin.getPlugin().suspendTo(0);
|
||||
ConfigBuilderPlugin.getPlugin().storeSettings("ActionLoopResume");
|
||||
NSUpload.uploadOpenAPSOffline(0);
|
||||
LoopPlugin.getPlugin().createOfflineEvent(0);
|
||||
RxBus.INSTANCE.send(new EventRefreshOverview("ActionLoopResume"));
|
||||
if (callback != null)
|
||||
callback.result(new PumpEnactResult().success(true).comment(R.string.ok)).run();
|
||||
|
|
|
@ -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.LayoutBuilder;
|
||||
import info.nightscout.androidaps.queue.Callback;
|
||||
import info.nightscout.androidaps.utils.DateUtil;
|
||||
import info.nightscout.androidaps.utils.JsonHelper;
|
||||
|
||||
public class ActionProfileSwitch extends Action {
|
||||
private static Logger log = LoggerFactory.getLogger(L.AUTOMATION);
|
||||
public InputProfileName inputProfileName = new InputProfileName(ProfileFunctions.getInstance().getProfileName());
|
||||
InputProfileName inputProfileName;
|
||||
String profileName = "";
|
||||
|
||||
public ActionProfileSwitch() {
|
||||
// Prevent action if active profile is already active
|
||||
// but we don't have a trigger IS_NOT_EQUAL
|
||||
// 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
|
||||
|
@ -50,23 +62,43 @@ public class ActionProfileSwitch extends Action {
|
|||
|
||||
String activeProfileName = ProfileFunctions.getInstance().getProfileName();
|
||||
//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)) {
|
||||
// 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;
|
||||
}
|
||||
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();
|
||||
if (profileStore == null) return;
|
||||
if(profileStore.getSpecificProfile(profileName) == null) {
|
||||
if (L.isEnabled(L.AUTOMATION))
|
||||
log.error("Selected profile does not exist! - "+ profileName);
|
||||
if (callback != null)
|
||||
callback.result(new PumpEnactResult().success(false).comment(R.string.notexists)).run();
|
||||
return;
|
||||
}
|
||||
|
||||
ProfileFunctions.doProfileSwitch(profileStore, profileName, 0, 100, 0);
|
||||
ProfileFunctions.doProfileSwitch(profileStore, profileName, 0, 100, 0, DateUtil.now());
|
||||
if (callback != null)
|
||||
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;
|
||||
|
||||
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))
|
||||
.build(root);
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ class ActionListAdapter(private val fragmentManager: FragmentManager, private va
|
|||
|
||||
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 {
|
||||
if (action.hasDialog()) {
|
||||
val args = Bundle()
|
||||
|
@ -48,6 +48,7 @@ class ActionListAdapter(private val fragmentManager: FragmentManager, private va
|
|||
recyclerView.notifyDataSetChanged()
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,19 +5,18 @@ import android.view.LayoutInflater
|
|||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.RadioButton
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.dialogs.DialogFragmentWithDate
|
||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||
import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin
|
||||
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.EventAutomationUpdateGui
|
||||
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?,
|
||||
savedInstanceState: Bundle?): View? {
|
||||
|
@ -26,7 +25,7 @@ class ChooseActionDialog : DialogFragment() {
|
|||
checkedIndex = bundle.getInt("checkedIndex")
|
||||
}
|
||||
|
||||
dialog?.setCanceledOnTouchOutside(false)
|
||||
onCreateViewGeneral()
|
||||
return inflater.inflate(R.layout.automation_dialog_choose_action, container, false)
|
||||
}
|
||||
|
||||
|
@ -42,27 +41,19 @@ class ChooseActionDialog : DialogFragment() {
|
|||
|
||||
if (checkedIndex != -1)
|
||||
(automation_radioGroup.getChildAt(checkedIndex) as RadioButton).isChecked = true
|
||||
}
|
||||
|
||||
// OK button
|
||||
ok.setOnClickListener {
|
||||
dismiss()
|
||||
instantiateAction()?.let {
|
||||
RxBus.send(EventAutomationAddAction(it))
|
||||
RxBus.send(EventAutomationUpdateGui())
|
||||
}
|
||||
override fun submit(): Boolean {
|
||||
instantiateAction()?.let {
|
||||
RxBus.send(EventAutomationAddAction(it))
|
||||
RxBus.send(EventAutomationUpdateGui())
|
||||
}
|
||||
|
||||
// Cancel button
|
||||
cancel.setOnClickListener { dismiss() }
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(bundle: Bundle) {
|
||||
bundle.putInt("checkedIndex", determineCheckedIndex())
|
||||
override fun onSaveInstanceState(savedInstanceState: Bundle) {
|
||||
super.onSaveInstanceState(savedInstanceState)
|
||||
savedInstanceState.putInt("checkedIndex", determineCheckedIndex())
|
||||
}
|
||||
|
||||
private fun instantiateAction(): Action? {
|
||||
|
@ -86,5 +77,4 @@ class ChooseActionDialog : DialogFragment() {
|
|||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,17 +5,15 @@ import android.view.LayoutInflater
|
|||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.RadioButton
|
||||
import androidx.fragment.app.DialogFragment
|
||||
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.triggers.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 clickListener: OnClickListener? = null
|
||||
|
||||
interface OnClickListener {
|
||||
|
@ -29,7 +27,7 @@ class ChooseTriggerDialog : DialogFragment() {
|
|||
checkedIndex = bundle.getInt("checkedIndex")
|
||||
}
|
||||
|
||||
dialog?.setCanceledOnTouchOutside(false)
|
||||
onCreateViewGeneral()
|
||||
return inflater.inflate(R.layout.automation_dialog_choose_trigger, container, false)
|
||||
}
|
||||
|
||||
|
@ -45,30 +43,22 @@ class ChooseTriggerDialog : DialogFragment() {
|
|||
|
||||
if (checkedIndex != -1)
|
||||
(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() {
|
||||
super.onStart()
|
||||
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
override fun submit(): Boolean {
|
||||
instantiateTrigger()?.let {
|
||||
clickListener?.onClick(it)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
fun setOnClickListener(clickListener: OnClickListener) {
|
||||
this.clickListener = clickListener
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(bundle: Bundle) {
|
||||
bundle.putInt("checkedIndex", determineCheckedIndex())
|
||||
override fun onSaveInstanceState(savedInstanceState: Bundle) {
|
||||
super.onSaveInstanceState(savedInstanceState)
|
||||
savedInstanceState.putInt("checkedIndex", determineCheckedIndex())
|
||||
}
|
||||
|
||||
private fun instantiateTrigger(): Trigger? {
|
||||
|
@ -92,5 +82,4 @@ class ChooseTriggerDialog : DialogFragment() {
|
|||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,16 +4,15 @@ import android.os.Bundle
|
|||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.dialogs.DialogFragmentWithDate
|
||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||
import info.nightscout.androidaps.plugins.general.automation.actions.Action
|
||||
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateAction
|
||||
import kotlinx.android.synthetic.main.automation_dialog_action.*
|
||||
import kotlinx.android.synthetic.main.okcancel.*
|
||||
import org.json.JSONObject
|
||||
|
||||
class EditActionDialog : DialogFragment() {
|
||||
class EditActionDialog : DialogFragmentWithDate() {
|
||||
private var action: Action? = null
|
||||
private var actionPosition: Int = -1
|
||||
|
||||
|
@ -24,8 +23,7 @@ class EditActionDialog : DialogFragment() {
|
|||
actionPosition = bundle.getInt("actionPosition", -1)
|
||||
bundle.getString("action")?.let { action = Action.instantiate(JSONObject(it)) }
|
||||
}
|
||||
|
||||
dialog?.setCanceledOnTouchOutside(false)
|
||||
onCreateViewGeneral()
|
||||
return inflater.inflate(R.layout.automation_dialog_action, container, false)
|
||||
}
|
||||
|
||||
|
@ -37,22 +35,13 @@ class EditActionDialog : DialogFragment() {
|
|||
automation_editActionLayout.removeAllViews()
|
||||
it.generateDialog(automation_editActionLayout)
|
||||
}
|
||||
|
||||
// OK button
|
||||
ok.setOnClickListener {
|
||||
dismiss()
|
||||
action?.let {
|
||||
RxBus.send(EventAutomationUpdateAction(it, actionPosition))
|
||||
}
|
||||
}
|
||||
|
||||
// Cancel button
|
||||
cancel.setOnClickListener { dismiss() }
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
override fun submit(): Boolean {
|
||||
action?.let {
|
||||
RxBus.send(EventAutomationUpdateAction(it, actionPosition))
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(bundle: Bundle) {
|
||||
|
|
|
@ -4,9 +4,9 @@ import android.os.Bundle
|
|||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.dialogs.DialogFragmentWithDate
|
||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||
import info.nightscout.androidaps.plugins.general.automation.AutomationEvent
|
||||
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.disposables.CompositeDisposable
|
||||
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 event: AutomationEvent = AutomationEvent()
|
||||
|
@ -35,7 +34,7 @@ class EditEventDialog : DialogFragment() {
|
|||
bundle.getString("event")?.let { event = AutomationEvent().fromJSON(it) }
|
||||
}
|
||||
|
||||
dialog?.setCanceledOnTouchOutside(false)
|
||||
onCreateViewGeneral()
|
||||
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") } }
|
||||
|
||||
// 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()
|
||||
|
||||
disposable.add(RxBus
|
||||
|
@ -137,9 +103,33 @@ class EditEventDialog : DialogFragment() {
|
|||
)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
override fun submit() : Boolean{
|
||||
// check for title
|
||||
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() {
|
||||
|
@ -147,10 +137,10 @@ class EditEventDialog : DialogFragment() {
|
|||
disposable.clear()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(bundle: Bundle) {
|
||||
super.onSaveInstanceState(bundle)
|
||||
bundle.putString("event", event.toJSON())
|
||||
bundle.putInt("position", position)
|
||||
override fun onSaveInstanceState(savedInstanceState: Bundle) {
|
||||
super.onSaveInstanceState(savedInstanceState)
|
||||
savedInstanceState.putString("event", event.toJSON())
|
||||
savedInstanceState.putInt("position", position)
|
||||
}
|
||||
|
||||
private fun showPreconditions() {
|
||||
|
@ -164,5 +154,4 @@ class EditEventDialog : DialogFragment() {
|
|||
automation_forcedTriggerDescriptionLabel.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,15 +4,14 @@ import android.os.Bundle
|
|||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.dialogs.DialogFragmentWithDate
|
||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateTrigger
|
||||
import info.nightscout.androidaps.plugins.general.automation.triggers.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
|
||||
|
||||
|
@ -23,7 +22,7 @@ class EditTriggerDialog : DialogFragment() {
|
|||
bundle.getString("trigger")?.let { trigger = Trigger.instantiate(it) }
|
||||
}
|
||||
|
||||
dialog?.setCanceledOnTouchOutside(false)
|
||||
onCreateViewGeneral()
|
||||
return inflater.inflate(R.layout.automation_dialog_edit_trigger, container, false)
|
||||
}
|
||||
|
||||
|
@ -32,24 +31,15 @@ class EditTriggerDialog : DialogFragment() {
|
|||
|
||||
// display root trigger
|
||||
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() {
|
||||
super.onStart()
|
||||
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
override fun submit():Boolean {
|
||||
trigger?.let { trigger -> RxBus.send(EventAutomationUpdateTrigger(trigger)) }
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(bundle: Bundle) {
|
||||
super.onSaveInstanceState(bundle)
|
||||
trigger?.let { bundle.putString("trigger", it.toJSON()) }
|
||||
override fun onSaveInstanceState(savedInstanceState: Bundle) {
|
||||
super.onSaveInstanceState(savedInstanceState)
|
||||
trigger?.let { savedInstanceState.putString("trigger", it.toJSON()) }
|
||||
}
|
||||
}
|
|
@ -75,7 +75,7 @@ public class TriggerListAdapter {
|
|||
|
||||
private Spinner createSpinner() {
|
||||
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);
|
||||
spinner.setAdapter(spinnerArrayAdapter);
|
||||
return spinner;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue