Merge branch 'dev' of https://github.com/MilosKozak/AndroidAPS into dev
This commit is contained in:
commit
5fa8f9e3f5
381 changed files with 81326 additions and 4472 deletions
|
@ -44,12 +44,12 @@ def generateGitBuild = { ->
|
||||||
stringBuilder.append('NoGitSystemAvailable')
|
stringBuilder.append('NoGitSystemAvailable')
|
||||||
}
|
}
|
||||||
stringBuilder.append('-')
|
stringBuilder.append('-')
|
||||||
stringBuilder.append((new Date()).format('yyyy.MM.dd'))
|
stringBuilder.append((new Date()).format('yyyy.MM.dd-HH:mm'))
|
||||||
stringBuilder.append('"')
|
stringBuilder.append('"')
|
||||||
return stringBuilder.toString()
|
return stringBuilder.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.matching {it instanceof Test}.all {
|
tasks.matching { it instanceof Test }.all {
|
||||||
testLogging.events = ["failed", "skipped", "started"]
|
testLogging.events = ["failed", "skipped", "started"]
|
||||||
testLogging.exceptionFormat = "full"
|
testLogging.exceptionFormat = "full"
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ android {
|
||||||
targetSdkVersion 25
|
targetSdkVersion 25
|
||||||
multiDexEnabled true
|
multiDexEnabled true
|
||||||
versionCode 1500
|
versionCode 1500
|
||||||
version "1.60e-dev"
|
version "2.0a-dev"
|
||||||
buildConfigField "String", "VERSION", '"' + version + '"'
|
buildConfigField "String", "VERSION", '"' + version + '"'
|
||||||
buildConfigField "String", "BUILDVERSION", generateGitBuild()
|
buildConfigField "String", "BUILDVERSION", generateGitBuild()
|
||||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
|
@ -89,7 +89,7 @@ android {
|
||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
}
|
}
|
||||||
debug {
|
debug {
|
||||||
testCoverageEnabled (project.hasProperty('coverage') ? true : false)
|
testCoverageEnabled(project.hasProperty('coverage') ? true : false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
productFlavors {
|
productFlavors {
|
||||||
|
@ -99,7 +99,8 @@ android {
|
||||||
resValue "string", "app_name", "AndroidAPS"
|
resValue "string", "app_name", "AndroidAPS"
|
||||||
versionName version
|
versionName version
|
||||||
manifestPlaceholders = [
|
manifestPlaceholders = [
|
||||||
appIcon: "@mipmap/blueowl"
|
appIcon: "@mipmap/ic_launcher",
|
||||||
|
appIconRound: "@mipmap/ic_launcher_round"
|
||||||
]
|
]
|
||||||
buildConfigField "boolean", "APS", "true"
|
buildConfigField "boolean", "APS", "true"
|
||||||
buildConfigField "boolean", "PUMPDRIVERS", "true"
|
buildConfigField "boolean", "PUMPDRIVERS", "true"
|
||||||
|
@ -112,7 +113,8 @@ android {
|
||||||
resValue "string", "app_name", "AndroidAPS"
|
resValue "string", "app_name", "AndroidAPS"
|
||||||
versionName version
|
versionName version
|
||||||
manifestPlaceholders = [
|
manifestPlaceholders = [
|
||||||
appIcon: "@mipmap/blueowl"
|
appIcon: "@mipmap/blueowl",
|
||||||
|
appIconRound: "@null"
|
||||||
]
|
]
|
||||||
buildConfigField "boolean", "APS", "false"
|
buildConfigField "boolean", "APS", "false"
|
||||||
buildConfigField "boolean", "PUMPDRIVERS", "true"
|
buildConfigField "boolean", "PUMPDRIVERS", "true"
|
||||||
|
@ -125,7 +127,8 @@ android {
|
||||||
resValue "string", "app_name", "NSClient"
|
resValue "string", "app_name", "NSClient"
|
||||||
versionName version + "-nsclient"
|
versionName version + "-nsclient"
|
||||||
manifestPlaceholders = [
|
manifestPlaceholders = [
|
||||||
appIcon: "@mipmap/yellowowl"
|
appIcon: "@mipmap/yellowowl",
|
||||||
|
appIconRound: "@null"
|
||||||
]
|
]
|
||||||
buildConfigField "boolean", "APS", "false"
|
buildConfigField "boolean", "APS", "false"
|
||||||
buildConfigField "boolean", "PUMPDRIVERS", "false"
|
buildConfigField "boolean", "PUMPDRIVERS", "false"
|
||||||
|
@ -138,7 +141,8 @@ android {
|
||||||
resValue "string", "app_name", "NSClient"
|
resValue "string", "app_name", "NSClient"
|
||||||
versionName version + "-nsclient"
|
versionName version + "-nsclient"
|
||||||
manifestPlaceholders = [
|
manifestPlaceholders = [
|
||||||
appIcon: "@mipmap/yellowowl"
|
appIcon: "@mipmap/yellowowl",
|
||||||
|
appIconRound: "@null"
|
||||||
]
|
]
|
||||||
buildConfigField "boolean", "APS", "false"
|
buildConfigField "boolean", "APS", "false"
|
||||||
buildConfigField "boolean", "PUMPDRIVERS", "false"
|
buildConfigField "boolean", "PUMPDRIVERS", "false"
|
||||||
|
@ -156,7 +160,7 @@ android {
|
||||||
unitTests.returnDefaultValues = true
|
unitTests.returnDefaultValues = true
|
||||||
unitTests.includeAndroidResources = true
|
unitTests.includeAndroidResources = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
|
@ -242,7 +246,7 @@ dependencies {
|
||||||
}
|
}
|
||||||
|
|
||||||
task unzip(type: Copy) {
|
task unzip(type: Copy) {
|
||||||
def zipPath = configurations.libs.find {it.name.startsWith("danars") }
|
def zipPath = configurations.libs.find { it.name.startsWith("danars") }
|
||||||
def zipFile = file(zipPath)
|
def zipFile = file(zipPath)
|
||||||
def outputDir = file("${buildDir}/unpacked/dist")
|
def outputDir = file("${buildDir}/unpacked/dist")
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -30,13 +30,13 @@
|
||||||
android:name=".MainApp"
|
android:name=".MainApp"
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:icon="${appIcon}"
|
android:icon="${appIcon}"
|
||||||
|
android:roundIcon="${appIconRound}"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme">
|
android:theme="@style/AppTheme.NoActionBar">
|
||||||
<activity android:name=".MainActivity">
|
<activity android:name=".MainActivity">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
@ -49,16 +49,19 @@
|
||||||
android:theme="@style/Theme.AppCompat.Translucent" />
|
android:theme="@style/Theme.AppCompat.Translucent" />
|
||||||
<activity android:name=".AgreementActivity" />
|
<activity android:name=".AgreementActivity" />
|
||||||
<activity android:name=".plugins.PumpDanaR.activities.DanaRHistoryActivity" />
|
<activity android:name=".plugins.PumpDanaR.activities.DanaRHistoryActivity" />
|
||||||
|
<activity android:name=".plugins.PumpDanaR.activities.DanaRUserOptionsActivity" />
|
||||||
<activity android:name=".TDDStatsActivity" />
|
<activity android:name=".TDDStatsActivity" />
|
||||||
<activity android:name=".plugins.Overview.activities.QuickWizardListActivity">
|
<activity android:name=".plugins.Overview.activities.QuickWizardListActivity">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="info.nightscout.androidaps.plugins.Overview.activities.QuickWizardListActivity" />
|
<action android:name="info.nightscout.androidaps.plugins.Overview.activities.QuickWizardListActivity" />
|
||||||
|
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity android:name=".plugins.PumpDanaRS.activities.BLEScanActivity">
|
<activity android:name=".plugins.PumpDanaRS.activities.BLEScanActivity">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="info.nightscout.androidaps.plugins.PumpDanaRS.activities.BLEScanActivity" />
|
<action android:name="info.nightscout.androidaps.plugins.PumpDanaRS.activities.BLEScanActivity" />
|
||||||
|
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
@ -70,6 +73,7 @@
|
||||||
android:enabled="true"
|
android:enabled="true"
|
||||||
android:exported="true">
|
android:exported="true">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
|
|
||||||
<!-- Receive new SMS messages -->
|
<!-- Receive new SMS messages -->
|
||||||
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
|
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
|
||||||
<!-- Receiver from xDrip -->
|
<!-- Receiver from xDrip -->
|
||||||
|
@ -80,6 +84,8 @@
|
||||||
<action android:name="it.ct.glicemia.ACTION_GLUCOSE_MEASURED" />
|
<action android:name="it.ct.glicemia.ACTION_GLUCOSE_MEASURED" />
|
||||||
<!-- Receiver from DexcomG5 -->
|
<!-- Receiver from DexcomG5 -->
|
||||||
<action android:name="com.dexcom.cgm.DATA" />
|
<action android:name="com.dexcom.cgm.DATA" />
|
||||||
|
<!-- Receiver from Poctech -->
|
||||||
|
<action android:name="com.china.poctech.data" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
<!-- Receiver keepalive, scheduled every 30 min -->
|
<!-- Receiver keepalive, scheduled every 30 min -->
|
||||||
|
@ -140,7 +146,7 @@
|
||||||
<service
|
<service
|
||||||
android:name=".plugins.PumpDanaRS.services.DanaRSService"
|
android:name=".plugins.PumpDanaRS.services.DanaRSService"
|
||||||
android:enabled="true"
|
android:enabled="true"
|
||||||
android:exported="true"></service>
|
android:exported="true" />
|
||||||
<service
|
<service
|
||||||
android:name=".plugins.Wear.wearintegration.WatchUpdaterService"
|
android:name=".plugins.Wear.wearintegration.WatchUpdaterService"
|
||||||
android:exported="true">
|
android:exported="true">
|
||||||
|
@ -158,12 +164,22 @@
|
||||||
android:exported="true" />
|
android:exported="true" />
|
||||||
<service
|
<service
|
||||||
android:name=".plugins.Overview.notifications.DismissNotificationService"
|
android:name=".plugins.Overview.notifications.DismissNotificationService"
|
||||||
android:exported="false"></service>
|
android:exported="false" />
|
||||||
|
|
||||||
|
<service android:name=".plugins.Persistentnotification.DummyService" />
|
||||||
|
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="io.fabric.ApiKey"
|
android:name="io.fabric.ApiKey"
|
||||||
android:value="59d462666c664c57b29e1d79ea123e01f8057cfa" />
|
android:value="59d462666c664c57b29e1d79ea123e01f8057cfa" />
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".setupwizard.SetupWizardActivity"
|
||||||
|
android:configChanges="orientation|keyboardHidden|screenSize"
|
||||||
|
android:theme="@style/AppTheme.NoActionBar"
|
||||||
|
android:label="@string/title_activity_setup_wizard" />
|
||||||
|
|
||||||
|
<activity android:name=".SingleFragmentActivity"
|
||||||
|
android:theme="@style/AppTheme" />
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
|
@ -406,8 +406,8 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_
|
||||||
} else {
|
} else {
|
||||||
console.error("SMB disabled (no enableSMB preferences active)");
|
console.error("SMB disabled (no enableSMB preferences active)");
|
||||||
}
|
}
|
||||||
// enable UAM (if enabled in preferences) if SMB is enabled
|
// enable UAM (if enabled in preferences)
|
||||||
var enableUAM=(profile.enableUAM && enableSMB);
|
var enableUAM=(profile.enableUAM);
|
||||||
|
|
||||||
|
|
||||||
//console.error(meal_data);
|
//console.error(meal_data);
|
||||||
|
@ -942,10 +942,10 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_
|
||||||
var durationReq = round(60*worstCaseInsulinReq / profile.current_basal);
|
var durationReq = round(60*worstCaseInsulinReq / profile.current_basal);
|
||||||
if (durationReq < 0) {
|
if (durationReq < 0) {
|
||||||
durationReq = 0;
|
durationReq = 0;
|
||||||
// don't set a temp longer than 120 minutes
|
// don't set an SMB zero temp longer than 60 minutess
|
||||||
} else {
|
} else {
|
||||||
durationReq = round(durationReq/30)*30;
|
durationReq = round(durationReq/30)*30;
|
||||||
durationReq = Math.min(120,Math.max(0,durationReq));
|
durationReq = Math.min(60,Math.max(0,durationReq));
|
||||||
}
|
}
|
||||||
//console.error(durationReq);
|
//console.error(durationReq);
|
||||||
//rT.reason += "insulinReq " + insulinReq + "; "
|
//rT.reason += "insulinReq " + insulinReq + "; "
|
||||||
|
|
|
@ -1,36 +1,39 @@
|
||||||
<configuration>
|
<configuration>
|
||||||
<!-- Create a file appender for a log in the application's data directory -->
|
<!-- Create a file appender for a log in the application's data directory -->
|
||||||
<property scope="context" name="EXT_FILES_DIR" value="${EXT_DIR:-/sdcard}/Android/data/${PACKAGE_NAME}/files"/>
|
<property name="EXT_FILES_DIR" scope="context"
|
||||||
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
value="${EXT_DIR:-/sdcard}/Android/data/${PACKAGE_NAME}/files" />
|
||||||
<file>${EXT_FILES_DIR}/AndroidAPS.log</file>
|
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
<file>${EXT_FILES_DIR}/AndroidAPS.log</file>
|
||||||
|
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||||
<!-- daily rollover. Make sure the path matches the one in the file element or else
|
<!-- daily rollover. Make sure the path matches the one in the file element or else
|
||||||
the rollover logs are placed in the working directory. -->
|
the rollover logs are placed in the working directory. -->
|
||||||
<fileNamePattern>${EXT_FILES_DIR}/AndroidAPS._%d{yyyy-MM-dd}_%d{HH-mm-ss, aux}_.%i.zip</fileNamePattern>
|
<fileNamePattern>${EXT_FILES_DIR}/AndroidAPS._%d{yyyy-MM-dd}_%d{HH-mm-ss, aux}_.%i.zip
|
||||||
|
</fileNamePattern>
|
||||||
|
|
||||||
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
|
<timeBasedFileNamingAndTriggeringPolicy
|
||||||
|
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
|
||||||
<maxFileSize>5MB</maxFileSize>
|
<maxFileSize>5MB</maxFileSize>
|
||||||
</timeBasedFileNamingAndTriggeringPolicy>
|
</timeBasedFileNamingAndTriggeringPolicy>
|
||||||
<!-- keep 30 days' worth of history -->
|
<!-- keep 30 days' worth of history -->
|
||||||
<maxHistory>120</maxHistory>
|
<maxHistory>120</maxHistory>
|
||||||
</rollingPolicy>
|
</rollingPolicy>
|
||||||
<encoder>
|
<encoder>
|
||||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level [%class:%line]: %msg%n</pattern>
|
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level [%class{0}.%M\(\):%line]: %msg%n</pattern>
|
||||||
</encoder>
|
</encoder>
|
||||||
</appender>
|
</appender>
|
||||||
|
|
||||||
<appender name="logcat" class="ch.qos.logback.classic.android.LogcatAppender">
|
<appender name="logcat" class="ch.qos.logback.classic.android.LogcatAppender">
|
||||||
<tagEncoder>
|
<tagEncoder>
|
||||||
<pattern>%logger{0}</pattern>
|
<pattern>%logger{0}</pattern>
|
||||||
</tagEncoder>
|
</tagEncoder>
|
||||||
<encoder>
|
<encoder>
|
||||||
<pattern>[%thread] %-5level [%class:%line]: %msg%n</pattern>
|
<pattern>[%thread] [%class{0}.%M\(\):%line]: %msg%n</pattern>
|
||||||
</encoder>
|
</encoder>
|
||||||
</appender>
|
</appender>
|
||||||
|
|
||||||
<!-- Write INFO (and higher-level) messages to the log file -->
|
<!-- Write INFO (and higher-level) messages to the log file -->
|
||||||
<root level="DEBUG">
|
<root level="DEBUG">
|
||||||
<appender-ref ref="file" />
|
<appender-ref ref="file" />
|
||||||
<appender-ref ref="logcat" />
|
<appender-ref ref="logcat" />
|
||||||
</root>
|
</root>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|
BIN
app/src/main/blueowl-web.png
Normal file
BIN
app/src/main/blueowl-web.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 60 KiB |
BIN
app/src/main/ic_launcher-web.png
Normal file
BIN
app/src/main/ic_launcher-web.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 60 KiB |
BIN
app/src/main/ic_launcher_round-web.png
Normal file
BIN
app/src/main/ic_launcher_round-web.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 60 KiB |
|
@ -12,7 +12,7 @@ public class Constants {
|
||||||
public static final double MMOLL_TO_MGDL = 18; // 18.0182;
|
public static final double MMOLL_TO_MGDL = 18; // 18.0182;
|
||||||
public static final double MGDL_TO_MMOLL = 1 / MMOLL_TO_MGDL;
|
public static final double MGDL_TO_MMOLL = 1 / MMOLL_TO_MGDL;
|
||||||
|
|
||||||
public static final double defaultDIA = 3d;
|
public static final double defaultDIA = 5d;
|
||||||
|
|
||||||
public static final Double REALLYHIGHBASALRATE = 1111111d;
|
public static final Double REALLYHIGHBASALRATE = 1111111d;
|
||||||
public static final Integer REALLYHIGHPERCENTBASALRATE = 1111111;
|
public static final Integer REALLYHIGHPERCENTBASALRATE = 1111111;
|
||||||
|
|
|
@ -176,13 +176,19 @@ public class HistoryBrowseActivity extends AppCompatActivity {
|
||||||
activity.runOnUiThread(new Runnable() {
|
activity.runOnUiThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
updateGUI("EventAutosensCalculationFinished");
|
synchronized (HistoryBrowseActivity.this) {
|
||||||
|
updateGUI("EventAutosensCalculationFinished");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateGUI(String from) {
|
void updateGUI(String from) {
|
||||||
|
|
||||||
|
if (noProfile == null || buttonDate == null || buttonZoom == null || bgGraph == null || iobGraph == null || seekBar == null)
|
||||||
|
return;
|
||||||
|
|
||||||
final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
|
final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
|
||||||
final Profile profile = MainApp.getConfigBuilder().getProfile();
|
final Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||||
|
|
||||||
|
|
|
@ -1,35 +1,34 @@
|
||||||
package info.nightscout.androidaps;
|
package info.nightscout.androidaps;
|
||||||
|
|
||||||
import android.Manifest;
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.ActivityNotFoundException;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.PersistableBundle;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.provider.Settings;
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.design.widget.NavigationView;
|
||||||
|
import android.support.design.widget.TabLayout;
|
||||||
import android.support.v4.app.ActivityCompat;
|
import android.support.v4.app.ActivityCompat;
|
||||||
import android.support.v4.content.ContextCompat;
|
|
||||||
import android.support.v4.view.ViewPager;
|
import android.support.v4.view.ViewPager;
|
||||||
|
import android.support.v4.widget.DrawerLayout;
|
||||||
|
import android.support.v7.app.ActionBarDrawerToggle;
|
||||||
import android.support.v7.app.AlertDialog;
|
import android.support.v7.app.AlertDialog;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.support.v7.widget.PopupMenu;
|
import android.support.v7.widget.Toolbar;
|
||||||
import android.text.SpannableString;
|
import android.text.SpannableString;
|
||||||
import android.text.method.LinkMovementMethod;
|
import android.text.method.LinkMovementMethod;
|
||||||
import android.text.util.Linkify;
|
import android.text.util.Linkify;
|
||||||
import android.view.MenuInflater;
|
import android.util.TypedValue;
|
||||||
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.ImageButton;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.joanzapata.iconify.Iconify;
|
import com.joanzapata.iconify.Iconify;
|
||||||
|
@ -47,67 +46,128 @@ import info.nightscout.androidaps.events.EventRefreshGui;
|
||||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Food.FoodPlugin;
|
import info.nightscout.androidaps.plugins.Food.FoodPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Overview.events.EventSetWakeLock;
|
|
||||||
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.androidaps.tabs.SlidingTabLayout;
|
import info.nightscout.androidaps.setupwizard.SetupWizardActivity;
|
||||||
import info.nightscout.androidaps.tabs.TabPageAdapter;
|
import info.nightscout.androidaps.tabs.TabPageAdapter;
|
||||||
|
import info.nightscout.utils.AndroidPermission;
|
||||||
import info.nightscout.utils.ImportExportPrefs;
|
import info.nightscout.utils.ImportExportPrefs;
|
||||||
import info.nightscout.utils.LocaleHelper;
|
import info.nightscout.utils.LocaleHelper;
|
||||||
import info.nightscout.utils.LogDialog;
|
import info.nightscout.utils.LogDialog;
|
||||||
import info.nightscout.utils.OKDialog;
|
import info.nightscout.utils.OKDialog;
|
||||||
import info.nightscout.utils.PasswordProtection;
|
import info.nightscout.utils.PasswordProtection;
|
||||||
import info.nightscout.utils.SP;
|
import info.nightscout.utils.SP;
|
||||||
import info.nightscout.utils.ToastUtils;
|
|
||||||
|
|
||||||
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
|
public class MainActivity extends AppCompatActivity {
|
||||||
private static Logger log = LoggerFactory.getLogger(MainActivity.class);
|
private static Logger log = LoggerFactory.getLogger(MainActivity.class);
|
||||||
|
|
||||||
static final int CASE_STORAGE = 0x1;
|
|
||||||
static final int CASE_SMS = 0x2;
|
|
||||||
static final int CASE_LOCATION = 0x3;
|
|
||||||
|
|
||||||
private boolean askForSMS = false;
|
|
||||||
private boolean askForLocation = true;
|
|
||||||
|
|
||||||
ImageButton menuButton;
|
|
||||||
|
|
||||||
protected PowerManager.WakeLock mWakeLock;
|
protected PowerManager.WakeLock mWakeLock;
|
||||||
|
|
||||||
|
private ActionBarDrawerToggle actionBarDrawerToggle;
|
||||||
|
|
||||||
|
private MenuItem pluginPreferencesMenuItem;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
Iconify.with(new FontAwesomeModule());
|
|
||||||
LocaleHelper.onCreate(this, "en");
|
|
||||||
setContentView(R.layout.activity_main);
|
|
||||||
menuButton = (ImageButton) findViewById(R.id.overview_menuButton);
|
|
||||||
menuButton.setOnClickListener(this);
|
|
||||||
|
|
||||||
checkEula();
|
|
||||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) {
|
|
||||||
askForPermission(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,
|
|
||||||
Manifest.permission.WRITE_EXTERNAL_STORAGE}, CASE_STORAGE);
|
|
||||||
}
|
|
||||||
askForBatteryOptimizationPermission();
|
|
||||||
doMigrations();
|
|
||||||
if (Config.logFunctionCalls)
|
if (Config.logFunctionCalls)
|
||||||
log.debug("onCreate");
|
log.debug("onCreate");
|
||||||
|
|
||||||
onStatusEvent(new EventSetWakeLock(SP.getBoolean("lockscreen", false)));
|
Iconify.with(new FontAwesomeModule());
|
||||||
|
LocaleHelper.onCreate(this, "en");
|
||||||
|
|
||||||
|
setContentView(R.layout.activity_main);
|
||||||
|
setSupportActionBar(findViewById(R.id.toolbar));
|
||||||
|
getSupportActionBar().setDisplayShowTitleEnabled(false);
|
||||||
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
|
getSupportActionBar().setHomeButtonEnabled(true);
|
||||||
|
|
||||||
|
DrawerLayout drawerLayout = findViewById(R.id.drawer_layout);
|
||||||
|
actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.string.open_navigation, R.string.close_navigation);
|
||||||
|
drawerLayout.addDrawerListener(actionBarDrawerToggle);
|
||||||
|
actionBarDrawerToggle.syncState();
|
||||||
|
|
||||||
|
// initialize screen wake lock
|
||||||
|
onEventPreferenceChange(new EventPreferenceChange(R.string.key_keep_screen_on));
|
||||||
|
|
||||||
|
doMigrations();
|
||||||
|
|
||||||
registerBus();
|
registerBus();
|
||||||
setUpTabs(false);
|
setupTabs();
|
||||||
|
setupViews(false);
|
||||||
|
|
||||||
|
final ViewPager viewPager = findViewById(R.id.pager);
|
||||||
|
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageSelected(int position) {
|
||||||
|
checkPluginPreferences(viewPager);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageScrollStateChanged(int state) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkPluginPreferences(ViewPager viewPager) {
|
||||||
|
if (pluginPreferencesMenuItem == null) return;
|
||||||
|
if (((TabPageAdapter) viewPager.getAdapter()).getPluginAt(viewPager.getCurrentItem()).getPreferencesId() != -1)
|
||||||
|
pluginPreferencesMenuItem.setEnabled(true);
|
||||||
|
else pluginPreferencesMenuItem.setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPostCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {
|
||||||
|
super.onPostCreate(savedInstanceState, persistentState);
|
||||||
|
actionBarDrawerToggle.syncState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
if (!SP.getBoolean(R.string.key_setupwizard_processed, false)) {
|
||||||
|
Intent intent = new Intent(this, SetupWizardActivity.class);
|
||||||
|
startActivity(intent);
|
||||||
|
} else {
|
||||||
|
checkEula();
|
||||||
|
}
|
||||||
|
|
||||||
|
AndroidPermission.notifyForStoragePermission(this);
|
||||||
|
AndroidPermission.notifyForBatteryOptimizationPermission(this);
|
||||||
|
if (BuildConfig.APS || BuildConfig.PUMPCONTROL) {
|
||||||
|
AndroidPermission.notifyForLocationPermissions(this);
|
||||||
|
AndroidPermission.notifyForSMSPermissions(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
MainApp.bus().post(new EventFeatureRunning(EventFeatureRunning.Feature.MAIN));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
if (mWakeLock != null)
|
||||||
|
if (mWakeLock.isHeld())
|
||||||
|
mWakeLock.release();
|
||||||
|
super.onDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onStatusEvent(final EventSetWakeLock ev) {
|
public void onEventPreferenceChange(final EventPreferenceChange ev) {
|
||||||
final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
|
if (ev.isChanged(R.string.key_keep_screen_on)) {
|
||||||
if (ev.lock) {
|
boolean keepScreenOn = SP.getBoolean(R.string.key_keep_screen_on, false);
|
||||||
mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "AAPS");
|
final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
|
||||||
if (!mWakeLock.isHeld())
|
if (keepScreenOn) {
|
||||||
mWakeLock.acquire();
|
mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "AAPS");
|
||||||
} else {
|
if (!mWakeLock.isHeld())
|
||||||
if (mWakeLock != null && mWakeLock.isHeld())
|
mWakeLock.acquire();
|
||||||
mWakeLock.release();
|
} else {
|
||||||
|
if (mWakeLock != null && mWakeLock.isHeld())
|
||||||
|
mWakeLock.release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,39 +175,75 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
||||||
public void onStatusEvent(final EventRefreshGui ev) {
|
public void onStatusEvent(final EventRefreshGui ev) {
|
||||||
String lang = SP.getString("language", "en");
|
String lang = SP.getString("language", "en");
|
||||||
LocaleHelper.setLocale(getApplicationContext(), lang);
|
LocaleHelper.setLocale(getApplicationContext(), lang);
|
||||||
runOnUiThread(new Runnable() {
|
runOnUiThread(() -> {
|
||||||
@Override
|
if (ev.recreate) {
|
||||||
public void run() {
|
recreate();
|
||||||
if (ev.recreate) {
|
} else {
|
||||||
recreate();
|
try { // activity may be destroyed
|
||||||
} else {
|
setupTabs();
|
||||||
try { // activity may be destroyed
|
setupViews(true);
|
||||||
setUpTabs(true);
|
} catch (IllegalStateException e) {
|
||||||
} catch (IllegalStateException e) {
|
log.error("Unhandled exception", e);
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean lockScreen = BuildConfig.NSCLIENTOLNY && SP.getBoolean("lockscreen", false);
|
|
||||||
if (lockScreen)
|
|
||||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
|
||||||
else
|
|
||||||
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean keepScreenOn = BuildConfig.NSCLIENTOLNY && SP.getBoolean(R.string.key_keep_screen_on, false);
|
||||||
|
if (keepScreenOn)
|
||||||
|
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||||
|
else
|
||||||
|
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUpTabs(boolean switchToLast) {
|
private void setupViews(boolean switchToLast) {
|
||||||
TabPageAdapter pageAdapter = new TabPageAdapter(getSupportFragmentManager(), this);
|
TabPageAdapter pageAdapter = new TabPageAdapter(getSupportFragmentManager(), this);
|
||||||
|
NavigationView navigationView = findViewById(R.id.navigation_view);
|
||||||
|
navigationView.setNavigationItemSelectedListener(menuItem -> {
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
Menu menu = navigationView.getMenu();
|
||||||
|
menu.clear();
|
||||||
for (PluginBase p : MainApp.getPluginsList()) {
|
for (PluginBase p : MainApp.getPluginsList()) {
|
||||||
pageAdapter.registerNewFragment(p);
|
pageAdapter.registerNewFragment(p);
|
||||||
|
if (p.hasFragment() && !p.isFragmentVisible() && p.isEnabled(p.pluginDescription.getType()) && !p.pluginDescription.neverVisible) {
|
||||||
|
MenuItem menuItem = menu.add(p.getName());
|
||||||
|
menuItem.setCheckable(true);
|
||||||
|
menuItem.setOnMenuItemClickListener(item -> {
|
||||||
|
Intent intent = new Intent(this, SingleFragmentActivity.class);
|
||||||
|
intent.putExtra("plugin", MainApp.getPluginsList().indexOf(p));
|
||||||
|
startActivity(intent);
|
||||||
|
((DrawerLayout) findViewById(R.id.drawer_layout)).closeDrawers();
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ViewPager mPager = (ViewPager) findViewById(R.id.pager);
|
ViewPager mPager = findViewById(R.id.pager);
|
||||||
mPager.setAdapter(pageAdapter);
|
mPager.setAdapter(pageAdapter);
|
||||||
SlidingTabLayout mTabs = (SlidingTabLayout) findViewById(R.id.tabs);
|
|
||||||
mTabs.setViewPager(mPager);
|
|
||||||
if (switchToLast)
|
if (switchToLast)
|
||||||
mPager.setCurrentItem(pageAdapter.getCount() - 1, false);
|
mPager.setCurrentItem(pageAdapter.getCount() - 1, false);
|
||||||
|
checkPluginPreferences(mPager);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupTabs() {
|
||||||
|
ViewPager viewPager = findViewById(R.id.pager);
|
||||||
|
TabLayout normalTabs = findViewById(R.id.tabs_normal);
|
||||||
|
normalTabs.setupWithViewPager(viewPager, true);
|
||||||
|
TabLayout compactTabs = findViewById(R.id.tabs_compact);
|
||||||
|
compactTabs.setupWithViewPager(viewPager, true);
|
||||||
|
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||||
|
if (SP.getBoolean("short_tabtitles", false)) {
|
||||||
|
normalTabs.setVisibility(View.GONE);
|
||||||
|
compactTabs.setVisibility(View.VISIBLE);
|
||||||
|
toolbar.setLayoutParams(new LinearLayout.LayoutParams(Toolbar.LayoutParams.MATCH_PARENT, (int) getResources().getDimension(R.dimen.compact_height)));
|
||||||
|
} else {
|
||||||
|
normalTabs.setVisibility(View.VISIBLE);
|
||||||
|
compactTabs.setVisibility(View.GONE);
|
||||||
|
TypedValue typedValue = new TypedValue();
|
||||||
|
if (getTheme().resolveAttribute(R.attr.actionBarSize, typedValue, true)) {
|
||||||
|
toolbar.setLayoutParams(new LinearLayout.LayoutParams(Toolbar.LayoutParams.MATCH_PARENT,
|
||||||
|
TypedValue.complexToDimensionPixelSize(typedValue.data, getResources().getDisplayMetrics())));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerBus() {
|
private void registerBus() {
|
||||||
|
@ -205,120 +301,22 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//check for sms permission if enable in prefernces
|
|
||||||
@Subscribe
|
|
||||||
public void onStatusEvent(final EventPreferenceChange ev) {
|
|
||||||
if (ev.isChanged(R.string.key_smscommunicator_remotecommandsallowed)) {
|
|
||||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) {
|
|
||||||
synchronized (this) {
|
|
||||||
if (SP.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)) {
|
|
||||||
setAskForSMS();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private synchronized void setAskForSMS() {
|
|
||||||
askForSMS = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
askForSMSPermissions();
|
|
||||||
askForLocationPermissions();
|
|
||||||
MainApp.bus().post(new EventFeatureRunning(EventFeatureRunning.Feature.MAIN));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDestroy() {
|
|
||||||
if (mWakeLock != null)
|
|
||||||
if (mWakeLock.isHeld())
|
|
||||||
mWakeLock.release();
|
|
||||||
super.onDestroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void askForBatteryOptimizationPermission() {
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
||||||
final String packageName = getPackageName();
|
|
||||||
|
|
||||||
final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
|
|
||||||
if (!pm.isIgnoringBatteryOptimizations(packageName)) {
|
|
||||||
log.debug("Requesting ignore battery optimization");
|
|
||||||
|
|
||||||
OKDialog.show(this, MainApp.gs(R.string.pleaseallowpermission), String.format(MainApp.gs(R.string.needwhitelisting), MainApp.gs(R.string.app_name)), new Runnable() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
final Intent intent = new Intent();
|
|
||||||
|
|
||||||
// ignoring battery optimizations required for constant connection
|
|
||||||
intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
|
|
||||||
intent.setData(Uri.parse("package:" + packageName));
|
|
||||||
startActivity(intent);
|
|
||||||
|
|
||||||
} catch (ActivityNotFoundException e) {
|
|
||||||
final String msg = MainApp.gs(R.string.batteryoptimalizationerror);
|
|
||||||
ToastUtils.showToastInUiThread(getApplicationContext(), msg);
|
|
||||||
log.error(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private synchronized void askForSMSPermissions() {
|
|
||||||
if (askForSMS) { //only when settings were changed an MainActivity resumes.
|
|
||||||
askForSMS = false;
|
|
||||||
if (SP.getBoolean(R.string.smscommunicator_remotecommandsallowed, false)) {
|
|
||||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) {
|
|
||||||
askForPermission(new String[]{Manifest.permission.RECEIVE_SMS,
|
|
||||||
Manifest.permission.SEND_SMS,
|
|
||||||
Manifest.permission.RECEIVE_MMS}, CASE_SMS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private synchronized void askForLocationPermissions() {
|
|
||||||
if (askForLocation) { //only when settings were changed an MainActivity resumes.
|
|
||||||
askForLocation = false;
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
||||||
askForPermission(new String[]{Manifest.permission.ACCESS_FINE_LOCATION,
|
|
||||||
Manifest.permission.ACCESS_FINE_LOCATION,
|
|
||||||
Manifest.permission.ACCESS_FINE_LOCATION}, CASE_LOCATION);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void askForPermission(String[] permission, Integer requestCode) {
|
|
||||||
boolean test = false;
|
|
||||||
for (int i = 0; i < permission.length; i++) {
|
|
||||||
test = test || (ContextCompat.checkSelfPermission(this, permission[i]) != PackageManager.PERMISSION_GRANTED);
|
|
||||||
}
|
|
||||||
if (test) {
|
|
||||||
ActivityCompat.requestPermissions(this, permission, requestCode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
|
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
|
||||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||||
if (permissions.length != 0) {
|
if (permissions.length != 0) {
|
||||||
if (ActivityCompat.checkSelfPermission(this, permissions[0]) == PackageManager.PERMISSION_GRANTED) {
|
if (ActivityCompat.checkSelfPermission(this, permissions[0]) == PackageManager.PERMISSION_GRANTED) {
|
||||||
switch (requestCode) {
|
switch (requestCode) {
|
||||||
case CASE_STORAGE:
|
case AndroidPermission.CASE_STORAGE:
|
||||||
//show dialog after permission is granted
|
//show dialog after permission is granted
|
||||||
AlertDialog.Builder alert = new AlertDialog.Builder(this);
|
AlertDialog.Builder alert = new AlertDialog.Builder(this);
|
||||||
alert.setMessage(R.string.alert_dialog_storage_permission_text);
|
alert.setMessage(R.string.alert_dialog_storage_permission_text);
|
||||||
alert.setPositiveButton(R.string.ok, null);
|
alert.setPositiveButton(R.string.ok, null);
|
||||||
alert.show();
|
alert.show();
|
||||||
break;
|
break;
|
||||||
case CASE_LOCATION:
|
case AndroidPermission.CASE_LOCATION:
|
||||||
case CASE_SMS:
|
case AndroidPermission.CASE_SMS:
|
||||||
|
case AndroidPermission.CASE_BATTERY:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -343,96 +341,97 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(final View v) {
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
final Activity activity = this;
|
getMenuInflater().inflate(R.menu.menu_main, menu);
|
||||||
switch (v.getId()) {
|
pluginPreferencesMenuItem = menu.findItem(R.id.nav_plugin_preferences);
|
||||||
case R.id.overview_menuButton:
|
menu.findItem(R.id.nav_historybrowser).setVisible(MainApp.devBranch);
|
||||||
PopupMenu popup = new PopupMenu(v.getContext(), v);
|
checkPluginPreferences(findViewById(R.id.pager));
|
||||||
MenuInflater inflater = popup.getMenuInflater();
|
return true;
|
||||||
inflater.inflate(R.menu.menu_main, popup.getMenu());
|
}
|
||||||
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onMenuItemClick(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
int id = item.getItemId();
|
int id = item.getItemId();
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case R.id.nav_preferences:
|
case R.id.nav_preferences:
|
||||||
PasswordProtection.QueryPassword(v.getContext(), R.string.settings_password, "settings_password", new Runnable() {
|
PasswordProtection.QueryPassword(this, R.string.settings_password, "settings_password", () -> {
|
||||||
@Override
|
Intent i = new Intent(this, PreferencesActivity.class);
|
||||||
public void run() {
|
i.putExtra("id", -1);
|
||||||
Intent i = new Intent(v.getContext(), PreferencesActivity.class);
|
startActivity(i);
|
||||||
i.putExtra("id", -1);
|
}, null);
|
||||||
startActivity(i);
|
return true;
|
||||||
}
|
case R.id.nav_historybrowser:
|
||||||
}, null);
|
startActivity(new Intent(this, HistoryBrowseActivity.class));
|
||||||
break;
|
return true;
|
||||||
case R.id.nav_historybrowser:
|
case R.id.nav_setupwizard:
|
||||||
startActivity(new Intent(v.getContext(), HistoryBrowseActivity.class));
|
startActivity(new Intent(this, SetupWizardActivity.class));
|
||||||
break;
|
return true;
|
||||||
case R.id.nav_resetdb:
|
case R.id.nav_resetdb:
|
||||||
new AlertDialog.Builder(v.getContext())
|
new AlertDialog.Builder(this)
|
||||||
.setTitle(R.string.nav_resetdb)
|
.setTitle(R.string.nav_resetdb)
|
||||||
.setMessage(R.string.reset_db_confirm)
|
.setMessage(R.string.reset_db_confirm)
|
||||||
.setNegativeButton(android.R.string.cancel, null)
|
.setNegativeButton(android.R.string.cancel, null)
|
||||||
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
.setPositiveButton(android.R.string.ok, (dialog, which) -> {
|
||||||
@Override
|
MainApp.getDbHelper().resetDatabases();
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
// should be handled by Plugin-Interface and
|
||||||
MainApp.getDbHelper().resetDatabases();
|
// additional service interface and plugin registry
|
||||||
// should be handled by Plugin-Interface and
|
FoodPlugin.getPlugin().getService().resetFood();
|
||||||
// additional service interface and plugin registry
|
TreatmentsPlugin.getPlugin().getService().resetTreatments();
|
||||||
FoodPlugin.getPlugin().getService().resetFood();
|
})
|
||||||
TreatmentsPlugin.getPlugin().getService().resetTreatments();
|
.create()
|
||||||
}
|
.show();
|
||||||
})
|
return true;
|
||||||
.create()
|
case R.id.nav_export:
|
||||||
.show();
|
ImportExportPrefs.verifyStoragePermissions(this);
|
||||||
break;
|
ImportExportPrefs.exportSharedPreferences(this);
|
||||||
case R.id.nav_export:
|
return true;
|
||||||
ImportExportPrefs.verifyStoragePermissions(activity);
|
case R.id.nav_import:
|
||||||
ImportExportPrefs.exportSharedPreferences(activity);
|
ImportExportPrefs.verifyStoragePermissions(this);
|
||||||
break;
|
ImportExportPrefs.importSharedPreferences(this);
|
||||||
case R.id.nav_import:
|
return true;
|
||||||
ImportExportPrefs.verifyStoragePermissions(activity);
|
case R.id.nav_show_logcat:
|
||||||
ImportExportPrefs.importSharedPreferences(activity);
|
LogDialog.showLogcat(this);
|
||||||
break;
|
return true;
|
||||||
case R.id.nav_show_logcat:
|
case R.id.nav_about:
|
||||||
LogDialog.showLogcat(v.getContext());
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||||
break;
|
builder.setTitle(MainApp.gs(R.string.app_name) + " " + BuildConfig.VERSION);
|
||||||
case R.id.nav_about:
|
if (Config.NSCLIENT || Config.G5UPLOADER)
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext());
|
builder.setIcon(R.mipmap.yellowowl);
|
||||||
builder.setTitle(MainApp.gs(R.string.app_name) + " " + BuildConfig.VERSION);
|
else
|
||||||
if (Config.NSCLIENT || Config.G5UPLOADER)
|
builder.setIcon(R.mipmap.blueowl);
|
||||||
builder.setIcon(R.mipmap.yellowowl);
|
String message = "Build: " + BuildConfig.BUILDVERSION + "\n";
|
||||||
else
|
message += "Flavor: " + BuildConfig.FLAVOR + BuildConfig.BUILD_TYPE + "\n";
|
||||||
builder.setIcon(R.mipmap.blueowl);
|
message += MainApp.gs(R.string.configbuilder_nightscoutversion_label) + " " + ConfigBuilderPlugin.nightscoutVersionName;
|
||||||
String message = "Build: " + BuildConfig.BUILDVERSION + "\n";
|
if (MainApp.engineeringMode)
|
||||||
message += "Flavor: " + BuildConfig.FLAVOR + BuildConfig.BUILD_TYPE + "\n";
|
message += "\n" + MainApp.gs(R.string.engineering_mode_enabled);
|
||||||
message += MainApp.gs(R.string.configbuilder_nightscoutversion_label) + " " + ConfigBuilderPlugin.nightscoutVersionName;
|
message += MainApp.gs(R.string.about_link_urls);
|
||||||
if (MainApp.engineeringMode)
|
final SpannableString messageSpanned = new SpannableString(message);
|
||||||
message += "\n" + MainApp.gs(R.string.engineering_mode_enabled);
|
Linkify.addLinks(messageSpanned, Linkify.WEB_URLS);
|
||||||
message += MainApp.gs(R.string.about_link_urls);
|
builder.setMessage(messageSpanned);
|
||||||
final SpannableString messageSpanned = new SpannableString(message);
|
builder.setPositiveButton(MainApp.gs(R.string.ok), null);
|
||||||
Linkify.addLinks(messageSpanned, Linkify.WEB_URLS);
|
AlertDialog alertDialog = builder.create();
|
||||||
builder.setMessage(messageSpanned);
|
alertDialog.show();
|
||||||
builder.setPositiveButton(MainApp.gs(R.string.ok), null);
|
((TextView) alertDialog.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance());
|
||||||
AlertDialog alertDialog = builder.create();
|
return true;
|
||||||
alertDialog.show();
|
case R.id.nav_exit:
|
||||||
((TextView)alertDialog.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance());
|
log.debug("Exiting");
|
||||||
break;
|
MainApp.instance().stopKeepAliveService();
|
||||||
case R.id.nav_exit:
|
MainApp.bus().post(new EventAppExit());
|
||||||
log.debug("Exiting");
|
MainApp.closeDbHelper();
|
||||||
MainApp.instance().stopKeepAliveService();
|
finish();
|
||||||
MainApp.bus().post(new EventAppExit());
|
System.runFinalization();
|
||||||
MainApp.closeDbHelper();
|
System.exit(0);
|
||||||
finish();
|
return true;
|
||||||
System.runFinalization();
|
case R.id.nav_plugin_preferences:
|
||||||
System.exit(0);
|
ViewPager viewPager = findViewById(R.id.pager);
|
||||||
break;
|
final PluginBase plugin = ((TabPageAdapter) viewPager.getAdapter()).getPluginAt(viewPager.getCurrentItem());
|
||||||
}
|
PasswordProtection.QueryPassword(this, R.string.settings_password, "settings_password", () -> {
|
||||||
return false;
|
Intent i = new Intent(this, PreferencesActivity.class);
|
||||||
}
|
i.putExtra("id", plugin.getPreferencesId());
|
||||||
});
|
startActivity(i);
|
||||||
popup.show();
|
}, null);
|
||||||
break;
|
return true;
|
||||||
}
|
}
|
||||||
|
return actionBarDrawerToggle.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import android.content.IntentFilter;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.annotation.PluralsRes;
|
||||||
import android.support.v4.content.LocalBroadcastManager;
|
import android.support.v4.content.LocalBroadcastManager;
|
||||||
|
|
||||||
import com.crashlytics.android.Crashlytics;
|
import com.crashlytics.android.Crashlytics;
|
||||||
|
@ -47,8 +48,6 @@ import info.nightscout.androidaps.plugins.OpenAPSAMA.OpenAPSAMAPlugin;
|
||||||
import info.nightscout.androidaps.plugins.OpenAPSMA.OpenAPSMAPlugin;
|
import info.nightscout.androidaps.plugins.OpenAPSMA.OpenAPSMAPlugin;
|
||||||
import info.nightscout.androidaps.plugins.OpenAPSSMB.OpenAPSSMBPlugin;
|
import info.nightscout.androidaps.plugins.OpenAPSSMB.OpenAPSSMBPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Overview.OverviewPlugin;
|
import info.nightscout.androidaps.plugins.Overview.OverviewPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
|
|
||||||
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
|
|
||||||
import info.nightscout.androidaps.plugins.Persistentnotification.PersistentNotificationPlugin;
|
import info.nightscout.androidaps.plugins.Persistentnotification.PersistentNotificationPlugin;
|
||||||
import info.nightscout.androidaps.plugins.ProfileLocal.LocalProfilePlugin;
|
import info.nightscout.androidaps.plugins.ProfileLocal.LocalProfilePlugin;
|
||||||
import info.nightscout.androidaps.plugins.ProfileNS.NSProfilePlugin;
|
import info.nightscout.androidaps.plugins.ProfileNS.NSProfilePlugin;
|
||||||
|
@ -61,14 +60,16 @@ import info.nightscout.androidaps.plugins.PumpDanaRv2.DanaRv2Plugin;
|
||||||
import info.nightscout.androidaps.plugins.PumpInsight.InsightPlugin;
|
import info.nightscout.androidaps.plugins.PumpInsight.InsightPlugin;
|
||||||
import info.nightscout.androidaps.plugins.PumpMDI.MDIPlugin;
|
import info.nightscout.androidaps.plugins.PumpMDI.MDIPlugin;
|
||||||
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
|
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
|
||||||
import info.nightscout.androidaps.plugins.SensitivityAAPS.SensitivityAAPSPlugin;
|
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityAAPSPlugin;
|
||||||
import info.nightscout.androidaps.plugins.SensitivityOref0.SensitivityOref0Plugin;
|
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityOref0Plugin;
|
||||||
import info.nightscout.androidaps.plugins.SensitivityWeightedAverage.SensitivityWeightedAveragePlugin;
|
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityOref1Plugin;
|
||||||
|
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityWeightedAveragePlugin;
|
||||||
import info.nightscout.androidaps.plugins.SmsCommunicator.SmsCommunicatorPlugin;
|
import info.nightscout.androidaps.plugins.SmsCommunicator.SmsCommunicatorPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Source.SourceDexcomG5Plugin;
|
import info.nightscout.androidaps.plugins.Source.SourceDexcomG5Plugin;
|
||||||
import info.nightscout.androidaps.plugins.Source.SourceGlimpPlugin;
|
import info.nightscout.androidaps.plugins.Source.SourceGlimpPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Source.SourceMM640gPlugin;
|
import info.nightscout.androidaps.plugins.Source.SourceMM640gPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Source.SourceNSClientPlugin;
|
import info.nightscout.androidaps.plugins.Source.SourceNSClientPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.Source.SourcePoctechPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Source.SourceXdripPlugin;
|
import info.nightscout.androidaps.plugins.Source.SourceXdripPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Wear.WearPlugin;
|
import info.nightscout.androidaps.plugins.Wear.WearPlugin;
|
||||||
|
@ -148,6 +149,7 @@ public class MainApp extends Application {
|
||||||
pluginsList.add(SensitivityOref0Plugin.getPlugin());
|
pluginsList.add(SensitivityOref0Plugin.getPlugin());
|
||||||
pluginsList.add(SensitivityAAPSPlugin.getPlugin());
|
pluginsList.add(SensitivityAAPSPlugin.getPlugin());
|
||||||
pluginsList.add(SensitivityWeightedAveragePlugin.getPlugin());
|
pluginsList.add(SensitivityWeightedAveragePlugin.getPlugin());
|
||||||
|
pluginsList.add(SensitivityOref1Plugin.getPlugin());
|
||||||
if (Config.HWPUMPS) pluginsList.add(DanaRPlugin.getPlugin());
|
if (Config.HWPUMPS) pluginsList.add(DanaRPlugin.getPlugin());
|
||||||
if (Config.HWPUMPS) pluginsList.add(DanaRKoreanPlugin.getPlugin());
|
if (Config.HWPUMPS) pluginsList.add(DanaRKoreanPlugin.getPlugin());
|
||||||
if (Config.HWPUMPS) pluginsList.add(DanaRv2Plugin.getPlugin());
|
if (Config.HWPUMPS) pluginsList.add(DanaRv2Plugin.getPlugin());
|
||||||
|
@ -178,30 +180,22 @@ public class MainApp extends Application {
|
||||||
pluginsList.add(SourceGlimpPlugin.getPlugin());
|
pluginsList.add(SourceGlimpPlugin.getPlugin());
|
||||||
if (!Config.NSCLIENT)
|
if (!Config.NSCLIENT)
|
||||||
pluginsList.add(SourceDexcomG5Plugin.getPlugin());
|
pluginsList.add(SourceDexcomG5Plugin.getPlugin());
|
||||||
|
if (!Config.NSCLIENT)
|
||||||
|
pluginsList.add(SourcePoctechPlugin.getPlugin());
|
||||||
if (Config.SMSCOMMUNICATORENABLED) pluginsList.add(SmsCommunicatorPlugin.getPlugin());
|
if (Config.SMSCOMMUNICATORENABLED) pluginsList.add(SmsCommunicatorPlugin.getPlugin());
|
||||||
pluginsList.add(FoodPlugin.getPlugin());
|
pluginsList.add(FoodPlugin.getPlugin());
|
||||||
|
|
||||||
pluginsList.add(WearPlugin.initPlugin(this));
|
pluginsList.add(WearPlugin.initPlugin(this));
|
||||||
pluginsList.add(StatuslinePlugin.initPlugin(this));
|
pluginsList.add(StatuslinePlugin.initPlugin(this));
|
||||||
pluginsList.add(new PersistentNotificationPlugin(this));
|
pluginsList.add(PersistentNotificationPlugin.getPlugin());
|
||||||
pluginsList.add(NSClientPlugin.getPlugin());
|
pluginsList.add(NSClientPlugin.getPlugin());
|
||||||
|
|
||||||
pluginsList.add(sConfigBuilder = ConfigBuilderPlugin.getPlugin());
|
pluginsList.add(sConfigBuilder = ConfigBuilderPlugin.getPlugin());
|
||||||
|
|
||||||
MainApp.getConfigBuilder().initialize();
|
MainApp.getConfigBuilder().initialize();
|
||||||
}
|
}
|
||||||
NSUpload.uploadAppStart();
|
|
||||||
|
|
||||||
if (Config.NSCLIENT)
|
NSUpload.uploadAppStart();
|
||||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("AppStart-NSClient"));
|
|
||||||
else if (Config.G5UPLOADER)
|
|
||||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("AppStart-G5Uploader"));
|
|
||||||
else if (Config.PUMPCONTROL)
|
|
||||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("AppStart-PumpControl"));
|
|
||||||
else if (MainApp.getConstraintChecker().isClosedLoopAllowed().value())
|
|
||||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("AppStart-ClosedLoop"));
|
|
||||||
else
|
|
||||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("AppStart-OpenLoop"));
|
|
||||||
|
|
||||||
final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
|
final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
|
||||||
if (pump != null) {
|
if (pump != null) {
|
||||||
|
@ -278,6 +272,10 @@ public class MainApp extends Application {
|
||||||
return sResources.getString(id, args);
|
return sResources.getString(id, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String gq(@PluralsRes int id, int quantity, Object... args) {
|
||||||
|
return sResources.getQuantityString(id, quantity, args);
|
||||||
|
}
|
||||||
|
|
||||||
public static int gc(int id) {
|
public static int gc(int id) {
|
||||||
return sResources.getColor(id);
|
return sResources.getColor(id);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,9 +30,10 @@ import info.nightscout.androidaps.plugins.PumpDanaRS.DanaRSPlugin;
|
||||||
import info.nightscout.androidaps.plugins.PumpDanaRv2.DanaRv2Plugin;
|
import info.nightscout.androidaps.plugins.PumpDanaRv2.DanaRv2Plugin;
|
||||||
import info.nightscout.androidaps.plugins.PumpInsight.InsightPlugin;
|
import info.nightscout.androidaps.plugins.PumpInsight.InsightPlugin;
|
||||||
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
|
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
|
||||||
import info.nightscout.androidaps.plugins.SensitivityAAPS.SensitivityAAPSPlugin;
|
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityAAPSPlugin;
|
||||||
import info.nightscout.androidaps.plugins.SensitivityOref0.SensitivityOref0Plugin;
|
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityOref0Plugin;
|
||||||
import info.nightscout.androidaps.plugins.SensitivityWeightedAverage.SensitivityWeightedAveragePlugin;
|
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityOref1Plugin;
|
||||||
|
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityWeightedAveragePlugin;
|
||||||
import info.nightscout.androidaps.plugins.SmsCommunicator.SmsCommunicatorPlugin;
|
import info.nightscout.androidaps.plugins.SmsCommunicator.SmsCommunicatorPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Source.SourceDexcomG5Plugin;
|
import info.nightscout.androidaps.plugins.Source.SourceDexcomG5Plugin;
|
||||||
import info.nightscout.androidaps.plugins.Wear.WearPlugin;
|
import info.nightscout.androidaps.plugins.Wear.WearPlugin;
|
||||||
|
@ -152,6 +153,7 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
|
||||||
addPreferencesFromResourceIfEnabled(SensitivityAAPSPlugin.getPlugin(), PluginType.SENSITIVITY);
|
addPreferencesFromResourceIfEnabled(SensitivityAAPSPlugin.getPlugin(), PluginType.SENSITIVITY);
|
||||||
addPreferencesFromResourceIfEnabled(SensitivityWeightedAveragePlugin.getPlugin(), PluginType.SENSITIVITY);
|
addPreferencesFromResourceIfEnabled(SensitivityWeightedAveragePlugin.getPlugin(), PluginType.SENSITIVITY);
|
||||||
addPreferencesFromResourceIfEnabled(SensitivityOref0Plugin.getPlugin(), PluginType.SENSITIVITY);
|
addPreferencesFromResourceIfEnabled(SensitivityOref0Plugin.getPlugin(), PluginType.SENSITIVITY);
|
||||||
|
addPreferencesFromResourceIfEnabled(SensitivityOref1Plugin.getPlugin(), PluginType.SENSITIVITY);
|
||||||
|
|
||||||
if (Config.HWPUMPS) {
|
if (Config.HWPUMPS) {
|
||||||
addPreferencesFromResourceIfEnabled(DanaRPlugin.getPlugin(), PluginType.PUMP);
|
addPreferencesFromResourceIfEnabled(DanaRPlugin.getPlugin(), PluginType.PUMP);
|
||||||
|
|
|
@ -13,6 +13,7 @@ import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import info.nightscout.androidaps.Config;
|
import info.nightscout.androidaps.Config;
|
||||||
|
import info.nightscout.androidaps.Constants;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.data.ProfileStore;
|
import info.nightscout.androidaps.data.ProfileStore;
|
||||||
|
@ -38,6 +39,7 @@ import info.nightscout.androidaps.plugins.Source.SourceDexcomG5Plugin;
|
||||||
import info.nightscout.androidaps.plugins.Source.SourceGlimpPlugin;
|
import info.nightscout.androidaps.plugins.Source.SourceGlimpPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Source.SourceMM640gPlugin;
|
import info.nightscout.androidaps.plugins.Source.SourceMM640gPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Source.SourceNSClientPlugin;
|
import info.nightscout.androidaps.plugins.Source.SourceNSClientPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.Source.SourcePoctechPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Source.SourceXdripPlugin;
|
import info.nightscout.androidaps.plugins.Source.SourceXdripPlugin;
|
||||||
import info.nightscout.androidaps.receivers.DataReceiver;
|
import info.nightscout.androidaps.receivers.DataReceiver;
|
||||||
import info.nightscout.utils.BundleLogger;
|
import info.nightscout.utils.BundleLogger;
|
||||||
|
@ -54,6 +56,7 @@ public class DataService extends IntentService {
|
||||||
boolean mm640gEnabled = false;
|
boolean mm640gEnabled = false;
|
||||||
boolean glimpEnabled = false;
|
boolean glimpEnabled = false;
|
||||||
boolean dexcomG5Enabled = false;
|
boolean dexcomG5Enabled = false;
|
||||||
|
boolean poctechEnabled = false;
|
||||||
|
|
||||||
public DataService() {
|
public DataService() {
|
||||||
super("DataService");
|
super("DataService");
|
||||||
|
@ -70,36 +73,49 @@ public class DataService extends IntentService {
|
||||||
mm640gEnabled = false;
|
mm640gEnabled = false;
|
||||||
glimpEnabled = false;
|
glimpEnabled = false;
|
||||||
dexcomG5Enabled = false;
|
dexcomG5Enabled = false;
|
||||||
|
poctechEnabled = false;
|
||||||
} else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceXdripPlugin.class)) {
|
} else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceXdripPlugin.class)) {
|
||||||
xDripEnabled = true;
|
xDripEnabled = true;
|
||||||
nsClientEnabled = false;
|
nsClientEnabled = false;
|
||||||
mm640gEnabled = false;
|
mm640gEnabled = false;
|
||||||
glimpEnabled = false;
|
glimpEnabled = false;
|
||||||
dexcomG5Enabled = false;
|
dexcomG5Enabled = false;
|
||||||
|
poctechEnabled = false;
|
||||||
} else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceNSClientPlugin.class)) {
|
} else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceNSClientPlugin.class)) {
|
||||||
xDripEnabled = false;
|
xDripEnabled = false;
|
||||||
nsClientEnabled = true;
|
nsClientEnabled = true;
|
||||||
mm640gEnabled = false;
|
mm640gEnabled = false;
|
||||||
glimpEnabled = false;
|
glimpEnabled = false;
|
||||||
dexcomG5Enabled = false;
|
dexcomG5Enabled = false;
|
||||||
|
poctechEnabled = false;
|
||||||
} else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceMM640gPlugin.class)) {
|
} else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceMM640gPlugin.class)) {
|
||||||
xDripEnabled = false;
|
xDripEnabled = false;
|
||||||
nsClientEnabled = false;
|
nsClientEnabled = false;
|
||||||
mm640gEnabled = true;
|
mm640gEnabled = true;
|
||||||
glimpEnabled = false;
|
glimpEnabled = false;
|
||||||
dexcomG5Enabled = false;
|
dexcomG5Enabled = false;
|
||||||
|
poctechEnabled = false;
|
||||||
} else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceGlimpPlugin.class)) {
|
} else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceGlimpPlugin.class)) {
|
||||||
xDripEnabled = false;
|
xDripEnabled = false;
|
||||||
nsClientEnabled = false;
|
nsClientEnabled = false;
|
||||||
mm640gEnabled = false;
|
mm640gEnabled = false;
|
||||||
glimpEnabled = true;
|
glimpEnabled = true;
|
||||||
dexcomG5Enabled = false;
|
dexcomG5Enabled = false;
|
||||||
|
poctechEnabled = false;
|
||||||
} else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceDexcomG5Plugin.class)) {
|
} else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceDexcomG5Plugin.class)) {
|
||||||
xDripEnabled = false;
|
xDripEnabled = false;
|
||||||
nsClientEnabled = false;
|
nsClientEnabled = false;
|
||||||
mm640gEnabled = false;
|
mm640gEnabled = false;
|
||||||
glimpEnabled = false;
|
glimpEnabled = false;
|
||||||
dexcomG5Enabled = true;
|
dexcomG5Enabled = true;
|
||||||
|
poctechEnabled = false;
|
||||||
|
} else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourcePoctechPlugin.class)) {
|
||||||
|
xDripEnabled = false;
|
||||||
|
nsClientEnabled = false;
|
||||||
|
mm640gEnabled = false;
|
||||||
|
glimpEnabled = false;
|
||||||
|
dexcomG5Enabled = false;
|
||||||
|
poctechEnabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isNSProfile = MainApp.getConfigBuilder().getActiveProfileInterface() != null && MainApp.getConfigBuilder().getActiveProfileInterface().getClass().equals(NSProfilePlugin.class);
|
boolean isNSProfile = MainApp.getConfigBuilder().getActiveProfileInterface() != null && MainApp.getConfigBuilder().getActiveProfileInterface().getClass().equals(NSProfilePlugin.class);
|
||||||
|
@ -129,6 +145,10 @@ public class DataService extends IntentService {
|
||||||
if (dexcomG5Enabled) {
|
if (dexcomG5Enabled) {
|
||||||
handleNewDataFromDexcomG5(intent);
|
handleNewDataFromDexcomG5(intent);
|
||||||
}
|
}
|
||||||
|
} else if (Intents.POCTECH_BG.equals(action)) {
|
||||||
|
if (poctechEnabled) {
|
||||||
|
handleNewDataFromPoctech(intent);
|
||||||
|
}
|
||||||
} else if (Intents.ACTION_NEW_SGV.equals(action)) {
|
} else if (Intents.ACTION_NEW_SGV.equals(action)) {
|
||||||
if (nsClientEnabled || SP.getBoolean(R.string.key_ns_autobackfill, true))
|
if (nsClientEnabled || SP.getBoolean(R.string.key_ns_autobackfill, true))
|
||||||
handleNewDataFromNSClient(intent);
|
handleNewDataFromNSClient(intent);
|
||||||
|
@ -250,6 +270,41 @@ public class DataService extends IntentService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void handleNewDataFromPoctech(Intent intent) {
|
||||||
|
|
||||||
|
Bundle bundle = intent.getExtras();
|
||||||
|
if (bundle == null) return;
|
||||||
|
|
||||||
|
BgReading bgReading = new BgReading();
|
||||||
|
|
||||||
|
String data = bundle.getString("data");
|
||||||
|
log.debug("Received Poctech Data", data);
|
||||||
|
|
||||||
|
try {
|
||||||
|
JSONArray jsonArray = new JSONArray(data);
|
||||||
|
log.debug("Received Poctech Data size:" + jsonArray.length());
|
||||||
|
for (int i = 0; i < jsonArray.length(); i++) {
|
||||||
|
JSONObject json = jsonArray.getJSONObject(i);
|
||||||
|
bgReading.value = json.getDouble("current");
|
||||||
|
bgReading.direction = json.getString("direction");
|
||||||
|
bgReading.date = json.getLong("date");
|
||||||
|
bgReading.raw = json.getDouble("raw");
|
||||||
|
if (JsonHelper.safeGetString(json, "units", Constants.MGDL).equals("mmol/L"))
|
||||||
|
bgReading.value = bgReading.value * Constants.MMOLL_TO_MGDL;
|
||||||
|
boolean isNew = MainApp.getDbHelper().createIfNotExists(bgReading, "Poctech");
|
||||||
|
if (isNew && SP.getBoolean(R.string.key_dexcomg5_nsupload, false)) {
|
||||||
|
NSUpload.uploadBg(bgReading);
|
||||||
|
}
|
||||||
|
if (isNew && SP.getBoolean(R.string.key_dexcomg5_xdripupload, false)) {
|
||||||
|
NSUpload.sendToXdrip(bgReading);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void handleNewDataFromMM640g(Intent intent) {
|
private void handleNewDataFromMM640g(Intent intent) {
|
||||||
Bundle bundle = intent.getExtras();
|
Bundle bundle = intent.getExtras();
|
||||||
if (bundle == null) return;
|
if (bundle == null) return;
|
||||||
|
@ -427,9 +482,7 @@ public class DataService extends IntentService {
|
||||||
if (bundles.containsKey("sgv")) {
|
if (bundles.containsKey("sgv")) {
|
||||||
String sgvstring = bundles.getString("sgv");
|
String sgvstring = bundles.getString("sgv");
|
||||||
JSONObject sgvJson = new JSONObject(sgvstring);
|
JSONObject sgvJson = new JSONObject(sgvstring);
|
||||||
NSSgv nsSgv = new NSSgv(sgvJson);
|
storeSgv(sgvJson);
|
||||||
BgReading bgReading = new BgReading(nsSgv);
|
|
||||||
MainApp.getDbHelper().createIfNotExists(bgReading, "NS");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bundles.containsKey("sgvs")) {
|
if (bundles.containsKey("sgvs")) {
|
||||||
|
@ -437,9 +490,7 @@ public class DataService extends IntentService {
|
||||||
JSONArray jsonArray = new JSONArray(sgvstring);
|
JSONArray jsonArray = new JSONArray(sgvstring);
|
||||||
for (int i = 0; i < jsonArray.length(); i++) {
|
for (int i = 0; i < jsonArray.length(); i++) {
|
||||||
JSONObject sgvJson = jsonArray.getJSONObject(i);
|
JSONObject sgvJson = jsonArray.getJSONObject(i);
|
||||||
NSSgv nsSgv = new NSSgv(sgvJson);
|
storeSgv(sgvJson);
|
||||||
BgReading bgReading = new BgReading(nsSgv);
|
|
||||||
MainApp.getDbHelper().createIfNotExists(bgReading, "NS");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -452,11 +503,7 @@ public class DataService extends IntentService {
|
||||||
if (bundles.containsKey("mbg")) {
|
if (bundles.containsKey("mbg")) {
|
||||||
String mbgstring = bundles.getString("mbg");
|
String mbgstring = bundles.getString("mbg");
|
||||||
JSONObject mbgJson = new JSONObject(mbgstring);
|
JSONObject mbgJson = new JSONObject(mbgstring);
|
||||||
NSMbg nsMbg = new NSMbg(mbgJson);
|
storeMbg(mbgJson);
|
||||||
CareportalEvent careportalEvent = new CareportalEvent(nsMbg);
|
|
||||||
MainApp.getDbHelper().createOrUpdate(careportalEvent);
|
|
||||||
if (Config.logIncommingData)
|
|
||||||
log.debug("Adding/Updating new MBG: " + careportalEvent.log());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bundles.containsKey("mbgs")) {
|
if (bundles.containsKey("mbgs")) {
|
||||||
|
@ -464,11 +511,7 @@ public class DataService extends IntentService {
|
||||||
JSONArray jsonArray = new JSONArray(sgvstring);
|
JSONArray jsonArray = new JSONArray(sgvstring);
|
||||||
for (int i = 0; i < jsonArray.length(); i++) {
|
for (int i = 0; i < jsonArray.length(); i++) {
|
||||||
JSONObject mbgJson = jsonArray.getJSONObject(i);
|
JSONObject mbgJson = jsonArray.getJSONObject(i);
|
||||||
NSMbg nsMbg = new NSMbg(mbgJson);
|
storeMbg(mbgJson);
|
||||||
CareportalEvent careportalEvent = new CareportalEvent(nsMbg);
|
|
||||||
MainApp.getDbHelper().createOrUpdate(careportalEvent);
|
|
||||||
if (Config.logIncommingData)
|
|
||||||
log.debug("Adding/Updating new MBG: " + careportalEvent.log());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -549,6 +592,21 @@ public class DataService extends IntentService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void storeMbg(JSONObject mbgJson) {
|
||||||
|
NSMbg nsMbg = new NSMbg(mbgJson);
|
||||||
|
CareportalEvent careportalEvent = new CareportalEvent(nsMbg);
|
||||||
|
MainApp.getDbHelper().createOrUpdate(careportalEvent);
|
||||||
|
if (Config.logIncommingData)
|
||||||
|
log.debug("Adding/Updating new MBG: " + careportalEvent.log());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void storeSgv(JSONObject sgvJson) {
|
||||||
|
NSSgv nsSgv = new NSSgv(sgvJson);
|
||||||
|
BgReading bgReading = new BgReading(nsSgv);
|
||||||
|
MainApp.getDbHelper().createIfNotExists(bgReading, "NS");
|
||||||
|
SourceNSClientPlugin.getPlugin().detectSource(JsonHelper.safeGetString(sgvJson, "device"), JsonHelper.safeGetLong(sgvJson, "mills"));
|
||||||
|
}
|
||||||
|
|
||||||
private void handleNewSMS(Intent intent) {
|
private void handleNewSMS(Intent intent) {
|
||||||
Bundle bundle = intent.getExtras();
|
Bundle bundle = intent.getExtras();
|
||||||
if (bundle == null) return;
|
if (bundle == null) return;
|
||||||
|
|
|
@ -49,4 +49,6 @@ public interface Intents {
|
||||||
String GLIMP_BG = "it.ct.glicemia.ACTION_GLUCOSE_MEASURED";
|
String GLIMP_BG = "it.ct.glicemia.ACTION_GLUCOSE_MEASURED";
|
||||||
|
|
||||||
String DEXCOMG5_BG = "com.dexcom.cgm.DATA";
|
String DEXCOMG5_BG = "com.dexcom.cgm.DATA";
|
||||||
|
|
||||||
|
String POCTECH_BG = "com.china.poctech.data";
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
package info.nightscout.androidaps;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.v4.app.Fragment;
|
||||||
|
import android.support.v4.view.ViewPager;
|
||||||
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||||
|
import info.nightscout.androidaps.tabs.TabPageAdapter;
|
||||||
|
import info.nightscout.utils.PasswordProtection;
|
||||||
|
|
||||||
|
public class SingleFragmentActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
private PluginBase plugin;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_single_fragment);
|
||||||
|
|
||||||
|
this.plugin = MainApp.getPluginsList().get(getIntent().getIntExtra("plugin", -1));
|
||||||
|
setTitle(plugin.getName());
|
||||||
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
|
getSupportActionBar().setDisplayShowHomeEnabled(true);
|
||||||
|
|
||||||
|
if (savedInstanceState == null) {
|
||||||
|
getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout,
|
||||||
|
Fragment.instantiate(this, plugin.pluginDescription.getFragmentClass())).commit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
if (item.getItemId() == android.R.id.home) {
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (item.getItemId() == R.id.nav_plugin_preferences) {
|
||||||
|
PasswordProtection.QueryPassword(this, R.string.settings_password, "settings_password", () -> {
|
||||||
|
Intent i = new Intent(this, PreferencesActivity.class);
|
||||||
|
i.putExtra("id", plugin.getPreferencesId());
|
||||||
|
startActivity(i);
|
||||||
|
}, null);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
|
if (plugin.getPreferencesId() != -1)
|
||||||
|
getMenuInflater().inflate(R.menu.menu_single_fragment, menu);
|
||||||
|
return super.onCreateOptionsMenu(menu);
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,12 +4,10 @@ import java.util.ArrayList;
|
||||||
|
|
||||||
import info.nightscout.androidaps.Constants;
|
import info.nightscout.androidaps.Constants;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.interfaces.BgSourceInterface;
|
|
||||||
import info.nightscout.androidaps.interfaces.Constraint;
|
import info.nightscout.androidaps.interfaces.Constraint;
|
||||||
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
|
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
|
||||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||||
import info.nightscout.androidaps.interfaces.PluginType;
|
import info.nightscout.androidaps.interfaces.PluginType;
|
||||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by mike on 19.03.2018.
|
* Created by mike on 19.03.2018.
|
||||||
|
@ -25,7 +23,7 @@ public class ConstraintChecker implements ConstraintsInterface {
|
||||||
|
|
||||||
|
|
||||||
public Constraint<Boolean> isLoopInvokationAllowed() {
|
public Constraint<Boolean> isLoopInvokationAllowed() {
|
||||||
return isLoopInvokationAllowed(new Constraint<>(true));
|
return isLoopInvocationAllowed(new Constraint<>(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Constraint<Boolean> isClosedLoopAllowed() {
|
public Constraint<Boolean> isClosedLoopAllowed() {
|
||||||
|
@ -69,13 +67,13 @@ public class ConstraintChecker implements ConstraintsInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Constraint<Boolean> isLoopInvokationAllowed(Constraint<Boolean> value) {
|
public Constraint<Boolean> isLoopInvocationAllowed(Constraint<Boolean> value) {
|
||||||
|
|
||||||
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||||
for (PluginBase p : constraintsPlugins) {
|
for (PluginBase p : constraintsPlugins) {
|
||||||
ConstraintsInterface constraint = (ConstraintsInterface) p;
|
ConstraintsInterface constraint = (ConstraintsInterface) p;
|
||||||
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
|
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
|
||||||
constraint.isLoopInvokationAllowed(value);
|
constraint.isLoopInvocationAllowed(value);
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import java.util.Date;
|
||||||
|
|
||||||
import info.nightscout.androidaps.db.CareportalEvent;
|
import info.nightscout.androidaps.db.CareportalEvent;
|
||||||
import info.nightscout.androidaps.db.Source;
|
import info.nightscout.androidaps.db.Source;
|
||||||
|
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by mike on 29.05.2017.
|
* Created by mike on 29.05.2017.
|
||||||
|
@ -17,6 +18,7 @@ import info.nightscout.androidaps.db.Source;
|
||||||
|
|
||||||
public class DetailedBolusInfo {
|
public class DetailedBolusInfo {
|
||||||
public long date = System.currentTimeMillis();
|
public long date = System.currentTimeMillis();
|
||||||
|
public long lastKnownBolusTime;
|
||||||
public String eventType = CareportalEvent.MEALBOLUS;
|
public String eventType = CareportalEvent.MEALBOLUS;
|
||||||
public double insulin = 0;
|
public double insulin = 0;
|
||||||
public double carbs = 0;
|
public double carbs = 0;
|
||||||
|
|
|
@ -202,6 +202,12 @@ public class Profile {
|
||||||
if (targetHigh_v == null)
|
if (targetHigh_v == null)
|
||||||
targetHigh_v = convertToSparseArray(targetHigh);
|
targetHigh_v = convertToSparseArray(targetHigh);
|
||||||
validate(targetHigh_v);
|
validate(targetHigh_v);
|
||||||
|
|
||||||
|
if (targetHigh_v.size() != targetLow_v.size()) isValid = false;
|
||||||
|
else for (int i = 0; i < targetHigh_v.size(); i++)
|
||||||
|
if (targetHigh_v.valueAt(i) < targetLow_v.valueAt(i))
|
||||||
|
isValid = false;
|
||||||
|
|
||||||
isValidated = true;
|
isValidated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,6 +232,10 @@ public class Profile {
|
||||||
basal_v.setValueAt(i, description.basalMinimumRate);
|
basal_v.setValueAt(i, description.basalMinimumRate);
|
||||||
if (notify)
|
if (notify)
|
||||||
sendBelowMinimumNotification(from);
|
sendBelowMinimumNotification(from);
|
||||||
|
} else if (basal_v.valueAt(i) > description.basalMaximumRate) {
|
||||||
|
basal_v.setValueAt(i, description.basalMaximumRate);
|
||||||
|
if (notify)
|
||||||
|
sendAboveMaximumNotification(from);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -235,12 +245,16 @@ public class Profile {
|
||||||
isValidated = false;
|
isValidated = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return isValid;
|
return isValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void sendBelowMinimumNotification(String from) {
|
protected void sendBelowMinimumNotification(String from) {
|
||||||
MainApp.bus().post(new EventNewNotification(new Notification(Notification.MINIMAL_BASAL_VALUE_REPLACED, String.format(MainApp.gs(R.string.minimalbasalvaluereplaced), from), Notification.NORMAL)));
|
MainApp.bus().post(new EventNewNotification(new Notification(Notification.MINIMAL_BASAL_VALUE_REPLACED, String.format(MainApp.gs(R.string.minimalbasalvaluereplaced), from), Notification.NORMAL)));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void sendAboveMaximumNotification(String from) {
|
||||||
|
MainApp.bus().post(new EventNewNotification(new Notification(Notification.MAXIMUM_BASAL_VALUE_REPLACED, String.format(MainApp.gs(R.string.maximumbasalvaluereplaced), from), Notification.NORMAL)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validate(LongSparseArray array) {
|
private void validate(LongSparseArray array) {
|
||||||
|
@ -444,12 +458,12 @@ public class Profile {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getTarget(){
|
public double getTarget() {
|
||||||
return getTarget(secondsFromMidnight(System.currentTimeMillis()));
|
return getTarget(secondsFromMidnight(System.currentTimeMillis()));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected double getTarget(int timeAsSeconds) {
|
protected double getTarget(int timeAsSeconds) {
|
||||||
return (getTargetLowTimeFromMidnight(timeAsSeconds) + getTargetHighTimeFromMidnight(timeAsSeconds))/2;
|
return (getTargetLowTimeFromMidnight(timeAsSeconds) + getTargetHighTimeFromMidnight(timeAsSeconds)) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getTargetLow() {
|
public double getTargetLow() {
|
||||||
|
@ -544,6 +558,12 @@ public class Profile {
|
||||||
else return DecimalFormatter.to1Decimal(valueInMmol);
|
else return DecimalFormatter.to1Decimal(valueInMmol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String toSignedUnitsString(Double valueInMgdl, Double valueInMmol, String units) {
|
||||||
|
if (units.equals(Constants.MGDL))
|
||||||
|
return (valueInMgdl > 0 ? "+" : "") + DecimalFormatter.to0Decimal(valueInMgdl);
|
||||||
|
else return (valueInMmol > 0 ? "+" : "") + DecimalFormatter.to1Decimal(valueInMmol);
|
||||||
|
}
|
||||||
|
|
||||||
// targets are stored in mg/dl but profile vary
|
// targets are stored in mg/dl but profile vary
|
||||||
public static String toTargetRangeString(double low, double high, String sourceUnits, String units) {
|
public static String toTargetRangeString(double low, double high, String sourceUnits, String units) {
|
||||||
double lowMgdl = toMgdl(low, sourceUnits);
|
double lowMgdl = toMgdl(low, sourceUnits);
|
||||||
|
|
|
@ -24,15 +24,17 @@ import info.nightscout.androidaps.Constants;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
|
import info.nightscout.androidaps.interfaces.Interval;
|
||||||
import info.nightscout.androidaps.plugins.NSClientInternal.data.NSMbg;
|
import info.nightscout.androidaps.plugins.NSClientInternal.data.NSMbg;
|
||||||
import info.nightscout.androidaps.plugins.Overview.OverviewFragment;
|
import info.nightscout.androidaps.plugins.Overview.OverviewFragment;
|
||||||
import info.nightscout.androidaps.plugins.Overview.graphExtensions.DataPointWithLabelInterface;
|
import info.nightscout.androidaps.plugins.Overview.graphExtensions.DataPointWithLabelInterface;
|
||||||
import info.nightscout.androidaps.plugins.Overview.graphExtensions.PointsWithLabelGraphSeries;
|
import info.nightscout.androidaps.plugins.Overview.graphExtensions.PointsWithLabelGraphSeries;
|
||||||
import info.nightscout.utils.DateUtil;
|
import info.nightscout.utils.DateUtil;
|
||||||
|
import info.nightscout.utils.T;
|
||||||
import info.nightscout.utils.Translator;
|
import info.nightscout.utils.Translator;
|
||||||
|
|
||||||
@DatabaseTable(tableName = DatabaseHelper.DATABASE_CAREPORTALEVENTS)
|
@DatabaseTable(tableName = DatabaseHelper.DATABASE_CAREPORTALEVENTS)
|
||||||
public class CareportalEvent implements DataPointWithLabelInterface {
|
public class CareportalEvent implements DataPointWithLabelInterface, Interval {
|
||||||
private static Logger log = LoggerFactory.getLogger(CareportalEvent.class);
|
private static Logger log = LoggerFactory.getLogger(CareportalEvent.class);
|
||||||
|
|
||||||
@DatabaseField(id = true)
|
@DatabaseField(id = true)
|
||||||
|
@ -87,7 +89,7 @@ public class CareportalEvent implements DataPointWithLabelInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getHoursFromStart() {
|
public long getHoursFromStart() {
|
||||||
return (System.currentTimeMillis() - date) / (60 * 1000);
|
return (System.currentTimeMillis() - date) / (60 * 60 * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String age() {
|
public String age() {
|
||||||
|
@ -98,13 +100,7 @@ public class CareportalEvent implements DataPointWithLabelInterface {
|
||||||
return diff.get(TimeUnit.DAYS) + " " + MainApp.gs(R.string.days) + " " + diff.get(TimeUnit.HOURS) + " " + MainApp.gs(R.string.hours);
|
return diff.get(TimeUnit.DAYS) + " " + MainApp.gs(R.string.days) + " " + diff.get(TimeUnit.HOURS) + " " + MainApp.gs(R.string.hours);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isOlderThan(double hours) {
|
public boolean isOlderThan(double hours) { return getHoursFromStart() > hours; }
|
||||||
Map<TimeUnit, Long> diff = computeDiff(date, System.currentTimeMillis());
|
|
||||||
if(diff.get(TimeUnit.DAYS)*24 + diff.get(TimeUnit.HOURS) > hours)
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String log() {
|
public String log() {
|
||||||
return "CareportalEvent{" +
|
return "CareportalEvent{" +
|
||||||
|
@ -133,6 +129,19 @@ public class CareportalEvent implements DataPointWithLabelInterface {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static boolean isEvent5minBack(List<CareportalEvent> list, long time) {
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
CareportalEvent event = list.get(i);
|
||||||
|
if (event.date <= time && event.date > (time - T.mins(5).msecs())) {
|
||||||
|
//log.debug("Found event for time: " + DateUtil.dateAndTimeString(time) + " " + event.toString());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//log.debug("WWWWWW No found event for time: " + DateUtil.dateAndTimeString(time));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// -------- DataPointWithLabelInterface -------
|
// -------- DataPointWithLabelInterface -------
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -213,14 +222,7 @@ public class CareportalEvent implements DataPointWithLabelInterface {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getDuration() {
|
public long getDuration() {
|
||||||
try {
|
return end() - start();
|
||||||
JSONObject object = new JSONObject(json);
|
|
||||||
if (object.has("duration"))
|
|
||||||
return object.getInt("duration") * 60 * 1000L;
|
|
||||||
} catch (JSONException e) {
|
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -259,8 +261,79 @@ public class CareportalEvent implements DataPointWithLabelInterface {
|
||||||
if (eventType.equals(EXERCISE))
|
if (eventType.equals(EXERCISE))
|
||||||
return Color.BLUE;
|
return Color.BLUE;
|
||||||
if (eventType.equals(OPENAPSOFFLINE))
|
if (eventType.equals(OPENAPSOFFLINE))
|
||||||
return Color.GRAY;
|
return Color.GRAY & 0x80FFFFFF;
|
||||||
return Color.GRAY;
|
return Color.GRAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Interval interface
|
||||||
|
Long cuttedEnd = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long durationInMsec() {
|
||||||
|
try {
|
||||||
|
JSONObject object = new JSONObject(json);
|
||||||
|
if (object.has("duration"))
|
||||||
|
return object.getInt("duration") * 60 * 1000L;
|
||||||
|
} catch (JSONException e) {
|
||||||
|
log.error("Unhandled exception", e);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long start() {
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long originalEnd() {
|
||||||
|
return date + durationInMsec();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long end() {
|
||||||
|
if (cuttedEnd != null)
|
||||||
|
return cuttedEnd;
|
||||||
|
return originalEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cutEndTo(long end) {
|
||||||
|
cuttedEnd = end;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean match(long time) {
|
||||||
|
if (start() <= time && end() >= time)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean before(long time) {
|
||||||
|
if (end() < time)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean after(long time) {
|
||||||
|
if (start() > time)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInProgress() {
|
||||||
|
return match(System.currentTimeMillis());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEndingEvent() {
|
||||||
|
return durationInMsec() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValid() {
|
||||||
|
return eventType.equals(OPENAPSOFFLINE);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ import java.util.concurrent.TimeUnit;
|
||||||
import info.nightscout.androidaps.Config;
|
import info.nightscout.androidaps.Config;
|
||||||
import info.nightscout.androidaps.Constants;
|
import info.nightscout.androidaps.Constants;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
|
import info.nightscout.androidaps.data.OverlappingIntervals;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
import info.nightscout.androidaps.data.ProfileStore;
|
import info.nightscout.androidaps.data.ProfileStore;
|
||||||
import info.nightscout.androidaps.events.EventCareportalEventChange;
|
import info.nightscout.androidaps.events.EventCareportalEventChange;
|
||||||
|
@ -675,7 +676,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
.source(Source.NIGHTSCOUT);
|
.source(Source.NIGHTSCOUT);
|
||||||
createOrUpdate(tempTarget);
|
createOrUpdate(tempTarget);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception: " + trJson.toString(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -761,7 +762,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (SQLException | JSONException e) {
|
} catch (SQLException | JSONException e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception: " + trJson.toString(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -966,7 +967,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
createOrUpdate(tempBasal);
|
createOrUpdate(tempBasal);
|
||||||
}
|
}
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception: " + trJson.toString(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1242,6 +1243,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
where.ge("date", mills);
|
where.ge("date", mills);
|
||||||
PreparedQuery<CareportalEvent> preparedQuery = queryBuilder.prepare();
|
PreparedQuery<CareportalEvent> preparedQuery = queryBuilder.prepare();
|
||||||
careportalEvents = getDaoCareportalEvents().query(preparedQuery);
|
careportalEvents = getDaoCareportalEvents().query(preparedQuery);
|
||||||
|
preprocessOpenAPSOfflineEvents(careportalEvents);
|
||||||
return careportalEvents;
|
return careportalEvents;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception", e);
|
||||||
|
@ -1249,13 +1251,41 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<CareportalEvent> getCareportalEventsFromTime(boolean ascending) {
|
public void preprocessOpenAPSOfflineEvents(List<CareportalEvent> list) {
|
||||||
|
OverlappingIntervals offlineEvents = new OverlappingIntervals();
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
CareportalEvent event = list.get(i);
|
||||||
|
if (!event.eventType.equals(CareportalEvent.OPENAPSOFFLINE)) continue;
|
||||||
|
offlineEvents.add(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<CareportalEvent> getCareportalEventsFromTime(long mills, String type, boolean ascending) {
|
||||||
|
try {
|
||||||
|
List<CareportalEvent> careportalEvents;
|
||||||
|
QueryBuilder<CareportalEvent, Long> queryBuilder = getDaoCareportalEvents().queryBuilder();
|
||||||
|
queryBuilder.orderBy("date", ascending);
|
||||||
|
Where where = queryBuilder.where();
|
||||||
|
where.ge("date", mills).and().eq("eventType", type);
|
||||||
|
PreparedQuery<CareportalEvent> preparedQuery = queryBuilder.prepare();
|
||||||
|
careportalEvents = getDaoCareportalEvents().query(preparedQuery);
|
||||||
|
preprocessOpenAPSOfflineEvents(careportalEvents);
|
||||||
|
return careportalEvents;
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error("Unhandled exception", e);
|
||||||
|
}
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<CareportalEvent> getCareportalEvents(boolean ascending) {
|
||||||
try {
|
try {
|
||||||
List<CareportalEvent> careportalEvents;
|
List<CareportalEvent> careportalEvents;
|
||||||
QueryBuilder<CareportalEvent, Long> queryBuilder = getDaoCareportalEvents().queryBuilder();
|
QueryBuilder<CareportalEvent, Long> queryBuilder = getDaoCareportalEvents().queryBuilder();
|
||||||
queryBuilder.orderBy("date", ascending);
|
queryBuilder.orderBy("date", ascending);
|
||||||
PreparedQuery<CareportalEvent> preparedQuery = queryBuilder.prepare();
|
PreparedQuery<CareportalEvent> preparedQuery = queryBuilder.prepare();
|
||||||
careportalEvents = getDaoCareportalEvents().query(preparedQuery);
|
careportalEvents = getDaoCareportalEvents().query(preparedQuery);
|
||||||
|
preprocessOpenAPSOfflineEvents(careportalEvents);
|
||||||
return careportalEvents;
|
return careportalEvents;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception", e);
|
||||||
|
@ -1315,7 +1345,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
careportalEvent._id = trJson.getString("_id");
|
careportalEvent._id = trJson.getString("_id");
|
||||||
createOrUpdate(careportalEvent);
|
createOrUpdate(careportalEvent);
|
||||||
} catch (SQLException | JSONException e) {
|
} catch (SQLException | JSONException e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception: " + trJson.toString(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1470,14 +1500,19 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
profileSwitch.profileJson = trJson.getString("profileJson");
|
profileSwitch.profileJson = trJson.getString("profileJson");
|
||||||
else {
|
else {
|
||||||
ProfileStore store = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile();
|
ProfileStore store = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile();
|
||||||
Profile profile = store.getSpecificProfile(profileSwitch.profileName);
|
if (store != null) {
|
||||||
if (profile != null) {
|
Profile profile = store.getSpecificProfile(profileSwitch.profileName);
|
||||||
profileSwitch.profileJson = profile.getData().toString();
|
if (profile != null) {
|
||||||
log.debug("Profile switch prefilled with JSON from local store");
|
profileSwitch.profileJson = profile.getData().toString();
|
||||||
// Update data in NS
|
log.debug("Profile switch prefilled with JSON from local store");
|
||||||
NSUpload.updateProfileSwitch(profileSwitch);
|
// Update data in NS
|
||||||
|
NSUpload.updateProfileSwitch(profileSwitch);
|
||||||
|
} else {
|
||||||
|
log.debug("JSON for profile switch doesn't exist. Ignoring: " + trJson.toString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
log.debug("JSON for profile switch doesn't exist. Ignoring: " + trJson.toString());
|
log.debug("Store for profile switch doesn't exist. Ignoring: " + trJson.toString());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1485,7 +1520,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
profileSwitch.profilePlugin = trJson.getString("profilePlugin");
|
profileSwitch.profilePlugin = trJson.getString("profilePlugin");
|
||||||
createOrUpdate(profileSwitch);
|
createOrUpdate(profileSwitch);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception: " + trJson.toString(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ public class ExtendedBolus implements Interval, DataPointWithLabelInterface {
|
||||||
public int durationInMinutes = 0; // duration == 0 means end of extended bolus
|
public int durationInMinutes = 0; // duration == 0 means end of extended bolus
|
||||||
|
|
||||||
@DatabaseField
|
@DatabaseField
|
||||||
public int insulinInterfaceID = InsulinInterface.FASTACTINGINSULIN;
|
public int insulinInterfaceID = InsulinInterface.OREF_RAPID_ACTING;
|
||||||
@DatabaseField
|
@DatabaseField
|
||||||
public double dia = Constants.defaultDIA;
|
public double dia = Constants.defaultDIA;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
package info.nightscout.androidaps.events;
|
package info.nightscout.androidaps.events;
|
||||||
|
|
||||||
|
|
||||||
|
import info.nightscout.utils.StringUtils;
|
||||||
|
|
||||||
public class EventNetworkChange extends Event {
|
public class EventNetworkChange extends Event {
|
||||||
|
|
||||||
public boolean mobileConnected = false;
|
public boolean mobileConnected = false;
|
||||||
|
@ -9,6 +12,6 @@ public class EventNetworkChange extends Event {
|
||||||
public boolean roaming = false;
|
public boolean roaming = false;
|
||||||
|
|
||||||
public String getSsid() {
|
public String getSsid() {
|
||||||
return ssid.replace("SSID: ","").replaceAll("\"","");
|
return StringUtils.removeSurroundingQuotes(ssid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
package info.nightscout.androidaps.events;
|
||||||
|
|
||||||
|
public class EventProfileStoreChanged extends Event {
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ import info.nightscout.androidaps.data.Profile;
|
||||||
*/
|
*/
|
||||||
public interface ConstraintsInterface {
|
public interface ConstraintsInterface {
|
||||||
|
|
||||||
default Constraint<Boolean> isLoopInvokationAllowed(Constraint<Boolean> value) {
|
default Constraint<Boolean> isLoopInvocationAllowed(Constraint<Boolean> value) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,4 +9,5 @@ import info.nightscout.androidaps.data.PumpEnactResult;
|
||||||
public interface DanaRInterface {
|
public interface DanaRInterface {
|
||||||
PumpEnactResult loadHistory(byte type); // for history browser
|
PumpEnactResult loadHistory(byte type); // for history browser
|
||||||
PumpEnactResult loadEvents(); // events history to build treatments from
|
PumpEnactResult loadEvents(); // events history to build treatments from
|
||||||
|
PumpEnactResult setUserOptions(); // like AnyDana does
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,8 @@ import info.nightscout.androidaps.plugins.Treatments.Treatment;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public interface InsulinInterface {
|
public interface InsulinInterface {
|
||||||
int FASTACTINGINSULIN = 0;
|
// int FASTACTINGINSULIN = 0; // old model no longer available
|
||||||
int FASTACTINGINSULINPROLONGED = 1;
|
// int FASTACTINGINSULINPROLONGED = 1; // old model no longer available
|
||||||
int OREF_RAPID_ACTING = 2;
|
int OREF_RAPID_ACTING = 2;
|
||||||
int OREF_ULTRA_RAPID_ACTING = 3;
|
int OREF_ULTRA_RAPID_ACTING = 3;
|
||||||
int OREF_FREE_PEAK = 4;
|
int OREF_FREE_PEAK = 4;
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
package info.nightscout.androidaps.interfaces;
|
package info.nightscout.androidaps.interfaces;
|
||||||
|
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
|
import android.support.v4.app.FragmentActivity;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderFragment;
|
||||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -32,6 +34,12 @@ public abstract class PluginBase {
|
||||||
this.pluginDescription = pluginDescription;
|
this.pluginDescription = pluginDescription;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Default always calls invoke
|
||||||
|
// Plugins that have special constraints if they get switched to may override this method
|
||||||
|
public void switchAllowed(ConfigBuilderFragment.PluginViewHolder.PluginSwitcher pluginSwitcher, FragmentActivity activity) {
|
||||||
|
pluginSwitcher.invoke();
|
||||||
|
}
|
||||||
|
|
||||||
// public PluginType getType() {
|
// public PluginType getType() {
|
||||||
// return mainType;
|
// return mainType;
|
||||||
// }
|
// }
|
||||||
|
@ -57,6 +65,11 @@ public abstract class PluginBase {
|
||||||
return getName();
|
return getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
if (pluginDescription.description == -1) return null;
|
||||||
|
else return MainApp.gs(pluginDescription.description);
|
||||||
|
}
|
||||||
|
|
||||||
public PluginType getType() {
|
public PluginType getType() {
|
||||||
return pluginDescription.mainType;
|
return pluginDescription.mainType;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ public class PluginDescription {
|
||||||
boolean showInList = true;
|
boolean showInList = true;
|
||||||
int pluginName = -1;
|
int pluginName = -1;
|
||||||
int shortName = -1;
|
int shortName = -1;
|
||||||
|
int description = -1;
|
||||||
int preferencesId = -1;
|
int preferencesId = -1;
|
||||||
int advancedPreferencesId = -1;
|
int advancedPreferencesId = -1;
|
||||||
public boolean enableByDefault = false;
|
public boolean enableByDefault = false;
|
||||||
|
@ -74,6 +75,11 @@ public class PluginDescription {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PluginDescription description(int description) {
|
||||||
|
this.description = description;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public String getFragmentClass() {
|
public String getFragmentClass() {
|
||||||
return fragmentClass;
|
return fragmentClass;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ public class PumpDescription {
|
||||||
public boolean isSetBasalProfileCapable = true;
|
public boolean isSetBasalProfileCapable = true;
|
||||||
public double basalStep = 0.01d;
|
public double basalStep = 0.01d;
|
||||||
public double basalMinimumRate = 0.04d;
|
public double basalMinimumRate = 0.04d;
|
||||||
|
public double basalMaximumRate = 25d;
|
||||||
|
|
||||||
public boolean isRefillingCapable = false;
|
public boolean isRefillingCapable = false;
|
||||||
|
|
||||||
|
|
|
@ -7,5 +7,10 @@ import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensResult;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public interface SensitivityInterface {
|
public interface SensitivityInterface {
|
||||||
|
|
||||||
|
double MIN_HOURS = 1;
|
||||||
|
double MIN_HOURS_FULL_AUTOSENS = 4;
|
||||||
|
|
||||||
AutosensResult detectSensitivity(long fromTime, long toTime);
|
AutosensResult detectSensitivity(long fromTime, long toTime);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ public interface TreatmentsInterface {
|
||||||
|
|
||||||
boolean addToHistoryExtendedBolus(ExtendedBolus extendedBolus);
|
boolean addToHistoryExtendedBolus(ExtendedBolus extendedBolus);
|
||||||
|
|
||||||
boolean addToHistoryTreatment(DetailedBolusInfo detailedBolusInfo);
|
boolean addToHistoryTreatment(DetailedBolusInfo detailedBolusInfo, boolean allowUpdate);
|
||||||
|
|
||||||
TempTarget getTempTargetFromHistory();
|
TempTarget getTempTargetFromHistory();
|
||||||
TempTarget getTempTargetFromHistory(long time);
|
TempTarget getTempTargetFromHistory(long time);
|
||||||
|
|
|
@ -87,6 +87,7 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL
|
||||||
tempBasalCancel.setOnClickListener(this);
|
tempBasalCancel.setOnClickListener(this);
|
||||||
fill.setOnClickListener(this);
|
fill.setOnClickListener(this);
|
||||||
history.setOnClickListener(this);
|
history.setOnClickListener(this);
|
||||||
|
history.setVisibility(MainApp.devBranch ? View.VISIBLE : View.GONE);
|
||||||
tddStats.setOnClickListener(this);
|
tddStats.setOnClickListener(this);
|
||||||
|
|
||||||
updateGUI();
|
updateGUI();
|
||||||
|
@ -125,7 +126,7 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL
|
||||||
activity.runOnUiThread(new Runnable() {
|
activity.runOnUiThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (MainApp.getConfigBuilder().getActiveProfileInterface().getProfile() != null) {
|
if (MainApp.getConfigBuilder().getActiveProfileInterface() != null && MainApp.getConfigBuilder().getActiveProfileInterface().getProfile() != null) {
|
||||||
profileSwitch.setVisibility(View.VISIBLE);
|
profileSwitch.setVisibility(View.VISIBLE);
|
||||||
} else {
|
} else {
|
||||||
profileSwitch.setVisibility(View.GONE);
|
profileSwitch.setVisibility(View.GONE);
|
||||||
|
|
|
@ -17,6 +17,7 @@ public class ActionsPlugin extends PluginBase {
|
||||||
.fragmentClass(ActionsFragment.class.getName())
|
.fragmentClass(ActionsFragment.class.getName())
|
||||||
.pluginName(R.string.actions)
|
.pluginName(R.string.actions)
|
||||||
.shortName(R.string.actions_shortname)
|
.shortName(R.string.actions_shortname)
|
||||||
|
.description(R.string.description_actions)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,10 @@ public class FillDialog extends DialogFragment implements OnClickListener {
|
||||||
|
|
||||||
private EditText notesEdit;
|
private EditText notesEdit;
|
||||||
|
|
||||||
|
//one shot guards
|
||||||
|
private boolean accepted;
|
||||||
|
private boolean okClicked;
|
||||||
|
|
||||||
final private TextWatcher textWatcher = new TextWatcher() {
|
final private TextWatcher textWatcher = new TextWatcher() {
|
||||||
@Override
|
@Override
|
||||||
public void afterTextChanged(Editable s) {
|
public void afterTextChanged(Editable s) {
|
||||||
|
@ -163,7 +167,14 @@ public class FillDialog extends DialogFragment implements OnClickListener {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void confirmAndDeliver() {
|
private synchronized void confirmAndDeliver() {
|
||||||
|
if (okClicked) {
|
||||||
|
log.debug("guarding: ok already clicked");
|
||||||
|
dismiss();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
okClicked = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Double insulin = SafeParse.stringToDouble(editInsulin.getText());
|
Double insulin = SafeParse.stringToDouble(editInsulin.getText());
|
||||||
|
|
||||||
|
@ -179,10 +190,10 @@ public class FillDialog extends DialogFragment implements OnClickListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pumpSiteChangeCheckbox.isChecked())
|
if (pumpSiteChangeCheckbox.isChecked())
|
||||||
confirmMessage.add("" + "<font color='" + MainApp.gc(R.color.high) + "'>" + MainApp.gs(R.string.record_pump_site_change) + "</font>");
|
confirmMessage.add("" + "<font color='" + MainApp.gc(R.color.actionsConfirm) + "'>" + MainApp.gs(R.string.record_pump_site_change) + "</font>");
|
||||||
|
|
||||||
if (insulinCartridgeChangeCheckbox.isChecked())
|
if (insulinCartridgeChangeCheckbox.isChecked())
|
||||||
confirmMessage.add("" + "<font color='" + MainApp.gc(R.color.high) + "'>" + MainApp.gs(R.string.record_insulin_cartridge_change) + "</font>");
|
confirmMessage.add("" + "<font color='" + MainApp.gc(R.color.actionsConfirm) + "'>" + MainApp.gs(R.string.record_insulin_cartridge_change) + "</font>");
|
||||||
|
|
||||||
final String notes = notesEdit.getText().toString();
|
final String notes = notesEdit.getText().toString();
|
||||||
if (!notes.isEmpty()) {
|
if (!notes.isEmpty()) {
|
||||||
|
@ -198,32 +209,40 @@ public class FillDialog extends DialogFragment implements OnClickListener {
|
||||||
if (insulinAfterConstraints > 0 || pumpSiteChangeCheckbox.isChecked() || insulinCartridgeChangeCheckbox.isChecked()) {
|
if (insulinAfterConstraints > 0 || pumpSiteChangeCheckbox.isChecked() || insulinCartridgeChangeCheckbox.isChecked()) {
|
||||||
builder.setMessage(Html.fromHtml(Joiner.on("<br/>").join(confirmMessage)));
|
builder.setMessage(Html.fromHtml(Joiner.on("<br/>").join(confirmMessage)));
|
||||||
builder.setPositiveButton(MainApp.gs(R.string.primefill), (dialog, id) -> {
|
builder.setPositiveButton(MainApp.gs(R.string.primefill), (dialog, id) -> {
|
||||||
if (finalInsulinAfterConstraints > 0) {
|
synchronized (builder) {
|
||||||
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
|
if (accepted) {
|
||||||
detailedBolusInfo.insulin = finalInsulinAfterConstraints;
|
log.debug("guarding: already accepted");
|
||||||
detailedBolusInfo.context = context;
|
return;
|
||||||
detailedBolusInfo.source = Source.USER;
|
}
|
||||||
detailedBolusInfo.isValid = false; // do not count it in IOB (for pump history)
|
accepted = true;
|
||||||
detailedBolusInfo.notes = notes;
|
|
||||||
ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() {
|
if (finalInsulinAfterConstraints > 0) {
|
||||||
@Override
|
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
|
||||||
public void run() {
|
detailedBolusInfo.insulin = finalInsulinAfterConstraints;
|
||||||
if (!result.success) {
|
detailedBolusInfo.context = context;
|
||||||
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
|
detailedBolusInfo.source = Source.USER;
|
||||||
i.putExtra("soundid", R.raw.boluserror);
|
detailedBolusInfo.isValid = false; // do not count it in IOB (for pump history)
|
||||||
i.putExtra("status", result.comment);
|
detailedBolusInfo.notes = notes;
|
||||||
i.putExtra("title", MainApp.gs(R.string.treatmentdeliveryerror));
|
ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() {
|
||||||
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
@Override
|
||||||
MainApp.instance().startActivity(i);
|
public void run() {
|
||||||
|
if (!result.success) {
|
||||||
|
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
|
||||||
|
i.putExtra("soundid", R.raw.boluserror);
|
||||||
|
i.putExtra("status", result.comment);
|
||||||
|
i.putExtra("title", MainApp.gs(R.string.treatmentdeliveryerror));
|
||||||
|
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
|
MainApp.instance().startActivity(i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
FabricPrivacy.getInstance().logCustom(new CustomEvent("Fill"));
|
||||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("Fill"));
|
}
|
||||||
|
if (pumpSiteChangeCheckbox.isChecked())
|
||||||
|
NSUpload.uploadEvent(CareportalEvent.SITECHANGE, now(), notes);
|
||||||
|
if (insulinCartridgeChangeCheckbox.isChecked())
|
||||||
|
NSUpload.uploadEvent(CareportalEvent.INSULINCHANGE, now() + 1000, notes);
|
||||||
}
|
}
|
||||||
if (pumpSiteChangeCheckbox.isChecked())
|
|
||||||
NSUpload.uploadEvent(CareportalEvent.SITECHANGE, now(), notes);
|
|
||||||
if (insulinCartridgeChangeCheckbox.isChecked())
|
|
||||||
NSUpload.uploadEvent(CareportalEvent.INSULINCHANGE, now() + 1000, notes);
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
builder.setMessage(MainApp.gs(R.string.no_action_selected));
|
builder.setMessage(MainApp.gs(R.string.no_action_selected));
|
||||||
|
|
|
@ -218,50 +218,19 @@ public class CareportalFragment extends SubscriberFragment implements View.OnCli
|
||||||
|
|
||||||
double iageUrgent = nsSettings.getExtendedWarnValue("iage", "urgent", 96);
|
double iageUrgent = nsSettings.getExtendedWarnValue("iage", "urgent", 96);
|
||||||
double iageWarn = nsSettings.getExtendedWarnValue("iage", "warn", 72);
|
double iageWarn = nsSettings.getExtendedWarnValue("iage", "warn", 72);
|
||||||
|
handleAge(iage, CareportalEvent.INSULINCHANGE, iageWarn, iageUrgent);
|
||||||
|
|
||||||
double cageUrgent = nsSettings.getExtendedWarnValue("cage", "urgent", 72);
|
double cageUrgent = nsSettings.getExtendedWarnValue("cage", "urgent", 72);
|
||||||
double cageWarn = nsSettings.getExtendedWarnValue("cage", "warn", 48);
|
double cageWarn = nsSettings.getExtendedWarnValue("cage", "warn", 48);
|
||||||
|
handleAge(cage, CareportalEvent.SITECHANGE, cageWarn, cageUrgent);
|
||||||
|
|
||||||
double sageUrgent = nsSettings.getExtendedWarnValue("sage", "urgent", 166);
|
double sageUrgent = nsSettings.getExtendedWarnValue("sage", "urgent", 166);
|
||||||
double sageWarn = nsSettings.getExtendedWarnValue("sage", "warn", 164);
|
double sageWarn = nsSettings.getExtendedWarnValue("sage", "warn", 164);
|
||||||
|
handleAge(sage, CareportalEvent.SENSORCHANGE, sageWarn, sageUrgent);
|
||||||
|
|
||||||
double pbageUrgent = nsSettings.getExtendedWarnValue("pgage", "urgent", 360);
|
double pbageUrgent = nsSettings.getExtendedWarnValue("pgage", "urgent", 360);
|
||||||
double pbageWarn = nsSettings.getExtendedWarnValue("pgage", "warn", 240);
|
double pbageWarn = nsSettings.getExtendedWarnValue("pgage", "warn", 240);
|
||||||
|
handleAge(pbage, CareportalEvent.PUMPBATTERYCHANGE, pbageWarn, pbageUrgent);
|
||||||
String notavailable = OverviewFragment.shorttextmode ? "-" : MainApp.gs(R.string.notavailable);
|
|
||||||
if (sage != null) {
|
|
||||||
careportalEvent = MainApp.getDbHelper().getLastCareportalEvent(CareportalEvent.SENSORCHANGE);
|
|
||||||
if (careportalEvent != null) {
|
|
||||||
sage.setTextColor(CareportalFragment.determineTextColor(careportalEvent, sageWarn, sageUrgent));
|
|
||||||
sage.setText(careportalEvent.age());
|
|
||||||
} else {
|
|
||||||
sage.setText(notavailable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (iage != null) {
|
|
||||||
careportalEvent = MainApp.getDbHelper().getLastCareportalEvent(CareportalEvent.INSULINCHANGE);
|
|
||||||
if (careportalEvent != null) {
|
|
||||||
iage.setTextColor(CareportalFragment.determineTextColor(careportalEvent, iageWarn, iageUrgent));
|
|
||||||
iage.setText(careportalEvent.age());
|
|
||||||
} else {
|
|
||||||
iage.setText(notavailable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (cage != null) {
|
|
||||||
careportalEvent = MainApp.getDbHelper().getLastCareportalEvent(CareportalEvent.SITECHANGE);
|
|
||||||
if (careportalEvent != null) {
|
|
||||||
cage.setTextColor(CareportalFragment.determineTextColor(careportalEvent, cageWarn, cageUrgent));
|
|
||||||
cage.setText(careportalEvent.age());
|
|
||||||
} else {
|
|
||||||
cage.setText(notavailable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (pbage != null) {
|
|
||||||
careportalEvent = MainApp.getDbHelper().getLastCareportalEvent(CareportalEvent.PUMPBATTERYCHANGE);
|
|
||||||
if (careportalEvent != null) {
|
|
||||||
pbage.setTextColor(CareportalFragment.determineTextColor(careportalEvent, pbageWarn, pbageUrgent));
|
|
||||||
pbage.setText(careportalEvent.age());
|
|
||||||
} else {
|
|
||||||
pbage.setText(notavailable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -277,5 +246,21 @@ public class CareportalFragment extends SubscriberFragment implements View.OnCli
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static TextView handleAge(final TextView age, String eventType, double warnThreshold, double urgentThreshold) {
|
||||||
|
String notavailable = OverviewFragment.shorttextmode ? "-" : MainApp.gs(R.string.notavailable);
|
||||||
|
|
||||||
|
if (age != null) {
|
||||||
|
CareportalEvent careportalEvent = MainApp.getDbHelper().getLastCareportalEvent(eventType);
|
||||||
|
if (careportalEvent != null) {
|
||||||
|
age.setTextColor(CareportalFragment.determineTextColor(careportalEvent, warnThreshold, urgentThreshold));
|
||||||
|
age.setText(careportalEvent.age());
|
||||||
|
} else {
|
||||||
|
age.setText(notavailable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return age;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,9 @@ public class CareportalPlugin extends PluginBase {
|
||||||
.fragmentClass(CareportalFragment.class.getName())
|
.fragmentClass(CareportalFragment.class.getName())
|
||||||
.pluginName(R.string.careportal)
|
.pluginName(R.string.careportal)
|
||||||
.shortName(R.string.careportal_shortname)
|
.shortName(R.string.careportal_shortname)
|
||||||
|
.visibleByDefault(true)
|
||||||
|
.enableByDefault(true)
|
||||||
|
.description(R.string.description_careportal)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ abstract public class SubscriberFragment extends Fragment {
|
||||||
updateGUI();
|
updateGUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void onDestroyView() {
|
@Override public synchronized void onDestroyView() {
|
||||||
super.onDestroyView();
|
super.onDestroyView();
|
||||||
if (unbinder != null)
|
if (unbinder != null)
|
||||||
unbinder.unbind();
|
unbinder.unbind();
|
||||||
|
|
|
@ -1,30 +1,30 @@
|
||||||
package info.nightscout.androidaps.plugins.ConfigBuilder;
|
package info.nightscout.androidaps.plugins.ConfigBuilder;
|
||||||
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.StringRes;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ArrayAdapter;
|
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.CheckBox;
|
import android.widget.CheckBox;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageButton;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.ListAdapter;
|
import android.widget.RadioButton;
|
||||||
import android.widget.ListView;
|
import android.widget.ScrollView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.crashlytics.android.answers.CustomEvent;
|
import com.crashlytics.android.answers.CustomEvent;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
import butterknife.OnClick;
|
import butterknife.OnClick;
|
||||||
import info.nightscout.androidaps.Config;
|
import butterknife.Unbinder;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.PreferencesActivity;
|
import info.nightscout.androidaps.PreferencesActivity;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
|
@ -43,76 +43,36 @@ import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
|
||||||
import info.nightscout.androidaps.plugins.Insulin.InsulinOrefRapidActingPlugin;
|
import info.nightscout.androidaps.plugins.Insulin.InsulinOrefRapidActingPlugin;
|
||||||
import info.nightscout.androidaps.plugins.ProfileNS.NSProfilePlugin;
|
import info.nightscout.androidaps.plugins.ProfileNS.NSProfilePlugin;
|
||||||
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
|
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
|
||||||
import info.nightscout.androidaps.plugins.SensitivityOref0.SensitivityOref0Plugin;
|
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityOref0Plugin;
|
||||||
import info.nightscout.utils.FabricPrivacy;
|
import info.nightscout.utils.FabricPrivacy;
|
||||||
import info.nightscout.utils.PasswordProtection;
|
import info.nightscout.utils.PasswordProtection;
|
||||||
|
|
||||||
|
|
||||||
public class ConfigBuilderFragment extends SubscriberFragment {
|
public class ConfigBuilderFragment extends SubscriberFragment {
|
||||||
|
|
||||||
@BindView(R.id.configbuilder_insulinlistview)
|
private List<PluginViewHolder> pluginViewHolders = new ArrayList<>();
|
||||||
ListView insulinListView;
|
|
||||||
@BindView(R.id.configbuilder_sensitivitylistview)
|
|
||||||
ListView sensitivityListView;
|
|
||||||
@BindView(R.id.configbuilder_bgsourcelistview)
|
|
||||||
ListView bgsourceListView;
|
|
||||||
@BindView(R.id.configbuilder_bgsourcelabel)
|
|
||||||
TextView bgsourceLabel;
|
|
||||||
@BindView(R.id.configbuilder_pumplistview)
|
|
||||||
ListView pumpListView;
|
|
||||||
@BindView(R.id.configbuilder_pumplabel)
|
|
||||||
TextView pumpLabel;
|
|
||||||
@BindView(R.id.configbuilder_looplistview)
|
|
||||||
ListView loopListView;
|
|
||||||
@BindView(R.id.configbuilder_looplabel)
|
|
||||||
TextView loopLabel;
|
|
||||||
@BindView(R.id.configbuilder_treatmentslistview)
|
|
||||||
ListView treatmentsListView;
|
|
||||||
@BindView(R.id.configbuilder_treatmentslabel)
|
|
||||||
TextView treatmentsLabel;
|
|
||||||
@BindView(R.id.configbuilder_profilelistview)
|
|
||||||
ListView profileListView;
|
|
||||||
@BindView(R.id.configbuilder_profilelabel)
|
|
||||||
TextView profileLabel;
|
|
||||||
@BindView(R.id.configbuilder_apslistview)
|
|
||||||
ListView apsListView;
|
|
||||||
@BindView(R.id.configbuilder_apslabel)
|
|
||||||
TextView apsLabel;
|
|
||||||
@BindView(R.id.configbuilder_constraintslistview)
|
|
||||||
ListView constraintsListView;
|
|
||||||
@BindView(R.id.configbuilder_constraintslabel)
|
|
||||||
TextView constraintsLabel;
|
|
||||||
@BindView(R.id.configbuilder_generallistview)
|
|
||||||
ListView generalListView;
|
|
||||||
|
|
||||||
@BindView(R.id.configbuilder_mainlayout)
|
@BindView(R.id.categories)
|
||||||
LinearLayout mainLayout;
|
LinearLayout categories;
|
||||||
@BindView(R.id.configbuilder_unlock)
|
|
||||||
|
@BindView(R.id.main_layout)
|
||||||
|
ScrollView mainLayout;
|
||||||
|
@BindView(R.id.unlock)
|
||||||
Button unlock;
|
Button unlock;
|
||||||
|
|
||||||
PluginCustomAdapter insulinDataAdapter = null;
|
|
||||||
PluginCustomAdapter sensivityDataAdapter = null;
|
|
||||||
PluginCustomAdapter bgsourceDataAdapter = null;
|
|
||||||
PluginCustomAdapter pumpDataAdapter = null;
|
|
||||||
PluginCustomAdapter loopDataAdapter = null;
|
|
||||||
PluginCustomAdapter treatmentDataAdapter = null;
|
|
||||||
PluginCustomAdapter profileDataAdapter = null;
|
|
||||||
PluginCustomAdapter apsDataAdapter = null;
|
|
||||||
PluginCustomAdapter constraintsDataAdapter = null;
|
|
||||||
PluginCustomAdapter generalDataAdapter = null;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
try {
|
try {
|
||||||
View view = inflater.inflate(R.layout.configbuilder_fragment, container, false);
|
View view = inflater.inflate(R.layout.configbuilder_fragment, container, false);
|
||||||
|
|
||||||
unbinder = ButterKnife.bind(this, view);
|
unbinder = ButterKnife.bind(this, view);
|
||||||
|
|
||||||
if (PasswordProtection.isLocked("settings_password"))
|
if (PasswordProtection.isLocked("settings_password"))
|
||||||
mainLayout.setVisibility(View.GONE);
|
mainLayout.setVisibility(View.GONE);
|
||||||
else
|
else unlock.setVisibility(View.GONE);
|
||||||
unlock.setVisibility(View.GONE);
|
|
||||||
|
createViews();
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
FabricPrivacy.logException(e);
|
FabricPrivacy.logException(e);
|
||||||
|
@ -121,225 +81,58 @@ public class ConfigBuilderFragment extends SubscriberFragment {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClick(R.id.configbuilder_unlock)
|
@OnClick(R.id.unlock)
|
||||||
public void onClickUnlock() {
|
void onClickUnlock() {
|
||||||
PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", () -> {
|
PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", () -> {
|
||||||
mainLayout.setVisibility(View.VISIBLE);
|
mainLayout.setVisibility(View.VISIBLE);
|
||||||
unlock.setVisibility(View.GONE);
|
unlock.setVisibility(View.GONE);
|
||||||
}, null);
|
}, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroyView() {
|
||||||
|
super.onDestroyView();
|
||||||
|
for (PluginViewHolder pluginViewHolder : pluginViewHolders) pluginViewHolder.unbind();
|
||||||
|
pluginViewHolders.clear();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void updateGUI() {
|
protected void updateGUI() {
|
||||||
|
for (PluginViewHolder pluginViewHolder : pluginViewHolders) pluginViewHolder.update();
|
||||||
insulinDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInListByInterface(InsulinInterface.class, PluginType.INSULIN), PluginType.INSULIN);
|
|
||||||
insulinListView.setAdapter(insulinDataAdapter);
|
|
||||||
setListViewHeightBasedOnChildren(insulinListView);
|
|
||||||
bgsourceDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInListByInterface(BgSourceInterface.class, PluginType.BGSOURCE), PluginType.BGSOURCE);
|
|
||||||
bgsourceListView.setAdapter(bgsourceDataAdapter);
|
|
||||||
if (MainApp.getSpecificPluginsVisibleInList(PluginType.BGSOURCE).size() == 0)
|
|
||||||
bgsourceLabel.setVisibility(View.GONE);
|
|
||||||
setListViewHeightBasedOnChildren(bgsourceListView);
|
|
||||||
pumpDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInList(PluginType.PUMP), PluginType.PUMP);
|
|
||||||
pumpListView.setAdapter(pumpDataAdapter);
|
|
||||||
if (MainApp.getSpecificPluginsVisibleInList(PluginType.PUMP).size() == 0 || Config.NSCLIENT || Config.G5UPLOADER) {
|
|
||||||
pumpLabel.setVisibility(View.GONE);
|
|
||||||
pumpListView.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
setListViewHeightBasedOnChildren(pumpListView);
|
|
||||||
loopDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInList(PluginType.LOOP), PluginType.LOOP);
|
|
||||||
loopListView.setAdapter(loopDataAdapter);
|
|
||||||
setListViewHeightBasedOnChildren(loopListView);
|
|
||||||
if (MainApp.getSpecificPluginsVisibleInList(PluginType.LOOP).size() == 0)
|
|
||||||
loopLabel.setVisibility(View.GONE);
|
|
||||||
treatmentDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInList(PluginType.TREATMENT), PluginType.TREATMENT);
|
|
||||||
treatmentsListView.setAdapter(treatmentDataAdapter);
|
|
||||||
setListViewHeightBasedOnChildren(treatmentsListView);
|
|
||||||
if (MainApp.getSpecificPluginsVisibleInList(PluginType.TREATMENT).size() == 0)
|
|
||||||
treatmentsLabel.setVisibility(View.GONE);
|
|
||||||
profileDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInListByInterface(ProfileInterface.class, PluginType.PROFILE), PluginType.PROFILE);
|
|
||||||
profileListView.setAdapter(profileDataAdapter);
|
|
||||||
if (MainApp.getSpecificPluginsVisibleInList(PluginType.PROFILE).size() == 0)
|
|
||||||
profileLabel.setVisibility(View.GONE);
|
|
||||||
setListViewHeightBasedOnChildren(profileListView);
|
|
||||||
apsDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInList(PluginType.APS), PluginType.APS);
|
|
||||||
apsListView.setAdapter(apsDataAdapter);
|
|
||||||
setListViewHeightBasedOnChildren(apsListView);
|
|
||||||
if (MainApp.getSpecificPluginsVisibleInList(PluginType.APS).size() == 0)
|
|
||||||
apsLabel.setVisibility(View.GONE);
|
|
||||||
sensivityDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInListByInterface(SensitivityInterface.class, PluginType.SENSITIVITY), PluginType.SENSITIVITY);
|
|
||||||
sensitivityListView.setAdapter(sensivityDataAdapter);
|
|
||||||
setListViewHeightBasedOnChildren(sensitivityListView);
|
|
||||||
constraintsDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInListByInterface(ConstraintsInterface.class, PluginType.CONSTRAINTS), PluginType.CONSTRAINTS);
|
|
||||||
constraintsListView.setAdapter(constraintsDataAdapter);
|
|
||||||
setListViewHeightBasedOnChildren(constraintsListView);
|
|
||||||
if (MainApp.getSpecificPluginsVisibleInList(PluginType.CONSTRAINTS).size() == 0)
|
|
||||||
constraintsLabel.setVisibility(View.GONE);
|
|
||||||
generalDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInList(PluginType.GENERAL), PluginType.GENERAL);
|
|
||||||
generalListView.setAdapter(generalDataAdapter);
|
|
||||||
setListViewHeightBasedOnChildren(generalListView);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
private void createViews() {
|
||||||
* ConfigBuilderFragment code
|
createViewsForPlugins(R.string.configbuilder_profile, R.string.configbuilder_profile_description, PluginType.PROFILE, MainApp.getSpecificPluginsVisibleInListByInterface(ProfileInterface.class, PluginType.PROFILE));
|
||||||
*/
|
createViewsForPlugins(R.string.configbuilder_insulin, R.string.configbuilder_insulin_description, PluginType.INSULIN, MainApp.getSpecificPluginsVisibleInListByInterface(InsulinInterface.class, PluginType.INSULIN));
|
||||||
|
createViewsForPlugins(R.string.configbuilder_bgsource, R.string.configbuilder_bgsource_description, PluginType.BGSOURCE, MainApp.getSpecificPluginsVisibleInListByInterface(BgSourceInterface.class, PluginType.BGSOURCE));
|
||||||
private class PluginCustomAdapter extends ArrayAdapter<PluginBase> {
|
createViewsForPlugins(R.string.configbuilder_pump, R.string.configbuilder_pump_description, PluginType.PUMP, MainApp.getSpecificPluginsVisibleInList(PluginType.PUMP));
|
||||||
|
createViewsForPlugins(R.string.configbuilder_sensitivity, R.string.configbuilder_sensitivity_description, PluginType.SENSITIVITY, MainApp.getSpecificPluginsVisibleInListByInterface(SensitivityInterface.class, PluginType.SENSITIVITY));
|
||||||
private ArrayList<PluginBase> pluginList;
|
createViewsForPlugins(R.string.configbuilder_aps, R.string.configbuilder_aps_description, PluginType.APS, MainApp.getSpecificPluginsVisibleInList(PluginType.APS));
|
||||||
final private PluginType type;
|
createViewsForPlugins(R.string.configbuilder_loop, R.string.configbuilder_loop_description, PluginType.LOOP, MainApp.getSpecificPluginsVisibleInList(PluginType.LOOP));
|
||||||
|
createViewsForPlugins(R.string.constraints, R.string.configbuilder_constraints_description, PluginType.CONSTRAINTS, MainApp.getSpecificPluginsVisibleInListByInterface(ConstraintsInterface.class, PluginType.CONSTRAINTS));
|
||||||
PluginCustomAdapter(Context context, int textViewResourceId,
|
createViewsForPlugins(R.string.configbuilder_treatments, R.string.configbuilder_treatments_description, PluginType.TREATMENT, MainApp.getSpecificPluginsVisibleInList(PluginType.TREATMENT));
|
||||||
ArrayList<PluginBase> pluginList, PluginType type) {
|
createViewsForPlugins(R.string.configbuilder_general, R.string.configbuilder_general_description, PluginType.GENERAL, MainApp.getSpecificPluginsVisibleInList(PluginType.GENERAL));
|
||||||
super(context, textViewResourceId, pluginList);
|
|
||||||
this.pluginList = new ArrayList<>();
|
|
||||||
this.pluginList.addAll(pluginList);
|
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class PluginViewHolder {
|
|
||||||
TextView name;
|
|
||||||
CheckBox checkboxEnabled;
|
|
||||||
CheckBox checkboxVisible;
|
|
||||||
ImageView settings;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public View getView(int position, View view, @NonNull ViewGroup parent) {
|
|
||||||
|
|
||||||
PluginViewHolder holder;
|
|
||||||
PluginBase plugin = pluginList.get(position);
|
|
||||||
|
|
||||||
if (view == null) {
|
|
||||||
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.configbuilder_simpleitem, null);
|
|
||||||
|
|
||||||
holder = new PluginViewHolder();
|
|
||||||
holder.name = (TextView) view.findViewById(R.id.configbuilder_simpleitem_name);
|
|
||||||
holder.checkboxEnabled = (CheckBox) view.findViewById(R.id.configbuilder_simpleitem_checkboxenabled);
|
|
||||||
holder.checkboxVisible = (CheckBox) view.findViewById(R.id.configbuilder_simpleitem_checkboxvisible);
|
|
||||||
holder.settings = (ImageView) view.findViewById(R.id.configbuilder_simpleitem_settings);
|
|
||||||
|
|
||||||
if (plugin.isEnabled(type) && plugin.getPreferencesId() != -1)
|
|
||||||
holder.settings.setVisibility(View.VISIBLE);
|
|
||||||
else
|
|
||||||
holder.settings.setVisibility(View.INVISIBLE);
|
|
||||||
|
|
||||||
view.setTag(holder);
|
|
||||||
|
|
||||||
holder.checkboxEnabled.setOnClickListener(v -> {
|
|
||||||
CheckBox cb = (CheckBox) v;
|
|
||||||
PluginBase plugin1 = (PluginBase) cb.getTag();
|
|
||||||
plugin1.setPluginEnabled(type, cb.isChecked());
|
|
||||||
plugin1.setFragmentVisible(type, cb.isChecked());
|
|
||||||
onEnabledCategoryChanged(plugin1, type);
|
|
||||||
ConfigBuilderPlugin.getPlugin().storeSettings("CheckedCheckboxEnabled");
|
|
||||||
MainApp.bus().post(new EventRefreshGui());
|
|
||||||
MainApp.bus().post(new EventConfigBuilderChange());
|
|
||||||
ConfigBuilderPlugin.getPlugin().logPluginStatus();
|
|
||||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("ConfigurationChange"));
|
|
||||||
});
|
|
||||||
|
|
||||||
holder.checkboxVisible.setOnClickListener(v -> {
|
|
||||||
CheckBox cb = (CheckBox) v;
|
|
||||||
PluginBase plugin12 = (PluginBase) cb.getTag();
|
|
||||||
plugin12.setFragmentVisible(type, cb.isChecked());
|
|
||||||
ConfigBuilderPlugin.getPlugin().storeSettings("CheckedCheckboxVisible");
|
|
||||||
MainApp.bus().post(new EventRefreshGui());
|
|
||||||
ConfigBuilderPlugin.getPlugin().logPluginStatus();
|
|
||||||
});
|
|
||||||
|
|
||||||
holder.settings.setOnClickListener(v -> {
|
|
||||||
final PluginBase plugin13 = (PluginBase) v.getTag();
|
|
||||||
PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", () -> {
|
|
||||||
Intent i = new Intent(getContext(), PreferencesActivity.class);
|
|
||||||
i.putExtra("id", plugin13.getPreferencesId());
|
|
||||||
startActivity(i);
|
|
||||||
}, null);
|
|
||||||
});
|
|
||||||
|
|
||||||
holder.name.setOnLongClickListener(v -> {
|
|
||||||
final PluginBase plugin14 = (PluginBase) v.getTag();
|
|
||||||
PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", () -> {
|
|
||||||
Intent i = new Intent(getContext(), PreferencesActivity.class);
|
|
||||||
i.putExtra("id", plugin14.getPreferencesId());
|
|
||||||
startActivity(i);
|
|
||||||
}, null);
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
} else {
|
|
||||||
holder = (PluginViewHolder) view.getTag();
|
|
||||||
}
|
|
||||||
|
|
||||||
holder.name.setText(plugin.getName());
|
|
||||||
holder.checkboxEnabled.setChecked(plugin.isEnabled(type));
|
|
||||||
holder.checkboxVisible.setChecked(plugin.isFragmentVisible());
|
|
||||||
holder.name.setTag(plugin);
|
|
||||||
holder.checkboxEnabled.setTag(plugin);
|
|
||||||
holder.checkboxVisible.setTag(plugin);
|
|
||||||
holder.settings.setTag(plugin);
|
|
||||||
|
|
||||||
if (plugin.pluginDescription.alwaysEnabled) {
|
|
||||||
holder.checkboxEnabled.setEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (plugin.pluginDescription.alwayVisible) {
|
|
||||||
holder.checkboxEnabled.setEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!plugin.isEnabled(type)) {
|
|
||||||
holder.checkboxVisible.setEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!plugin.hasFragment()) {
|
|
||||||
holder.checkboxVisible.setVisibility(View.INVISIBLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hide enabled control and force enabled plugin if there is only one plugin available
|
|
||||||
if (type == PluginType.INSULIN || type == PluginType.PUMP || type == PluginType.SENSITIVITY)
|
|
||||||
if (pluginList.size() < 2) {
|
|
||||||
holder.checkboxEnabled.setEnabled(false);
|
|
||||||
plugin.setPluginEnabled(type, true);
|
|
||||||
ConfigBuilderPlugin.getPlugin().storeSettings("ForceEnable");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Constraints cannot be disabled
|
|
||||||
if (type == PluginType.CONSTRAINTS)
|
|
||||||
holder.checkboxEnabled.setEnabled(false);
|
|
||||||
|
|
||||||
// Hide disabled profiles by default
|
|
||||||
if (type == PluginType.PROFILE) {
|
|
||||||
if (!plugin.isEnabled(type)) {
|
|
||||||
holder.checkboxVisible.setEnabled(false);
|
|
||||||
holder.checkboxVisible.setChecked(false);
|
|
||||||
} else {
|
|
||||||
holder.checkboxVisible.setEnabled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disable profile control for pump profiles if pump is not enabled
|
|
||||||
if (type == PluginType.PROFILE) {
|
|
||||||
if (PumpInterface.class.isAssignableFrom(plugin.getClass())) {
|
|
||||||
if (!plugin.isEnabled(PluginType.PUMP)) {
|
|
||||||
holder.checkboxEnabled.setEnabled(false);
|
|
||||||
holder.checkboxEnabled.setChecked(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (plugin.isEnabled(type)) {
|
|
||||||
view.setBackgroundColor(MainApp.gc(R.color.configBuilderSelectedBackground));
|
|
||||||
}
|
|
||||||
|
|
||||||
return view;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void onEnabledCategoryChanged(PluginBase changedPlugin, PluginType type) {
|
private void createViewsForPlugins(@StringRes int title, @StringRes int description, PluginType pluginType, List<PluginBase> plugins) {
|
||||||
|
if (plugins.size() == 0) return;
|
||||||
|
LinearLayout parent = (LinearLayout) getLayoutInflater().inflate(R.layout.configbuilder_single_category, null);
|
||||||
|
((TextView) parent.findViewById(R.id.category_title)).setText(MainApp.gs(title));
|
||||||
|
((TextView) parent.findViewById(R.id.category_description)).setText(MainApp.gs(description));
|
||||||
|
LinearLayout pluginContainer = parent.findViewById(R.id.category_plugins);
|
||||||
|
for (PluginBase plugin: plugins) {
|
||||||
|
PluginViewHolder pluginViewHolder = new PluginViewHolder(pluginType, plugin);
|
||||||
|
pluginContainer.addView(pluginViewHolder.getBaseView());
|
||||||
|
pluginViewHolders.add(pluginViewHolder);
|
||||||
|
}
|
||||||
|
categories.addView(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean areMultipleSelectionsAllowed(PluginType type) {
|
||||||
|
return type == PluginType.GENERAL || type == PluginType.CONSTRAINTS ||type == PluginType.LOOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void processOnEnabledCategoryChanged(PluginBase changedPlugin, PluginType type) {
|
||||||
ArrayList<PluginBase> pluginsInCategory = null;
|
ArrayList<PluginBase> pluginsInCategory = null;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
// Multiple selection allowed
|
// Multiple selection allowed
|
||||||
|
@ -391,34 +184,103 @@ public class ConfigBuilderFragment extends SubscriberFragment {
|
||||||
else
|
else
|
||||||
pluginsInCategory.get(0).setPluginEnabled(type, true);
|
pluginsInCategory.get(0).setPluginEnabled(type, true);
|
||||||
}
|
}
|
||||||
updateGUI();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/****
|
public class PluginViewHolder {
|
||||||
* Method for Setting the Height of the ListView dynamically.
|
|
||||||
* *** Hack to fix the issue of not showing all the items of the ListView
|
|
||||||
* *** when placed inside a ScrollView
|
|
||||||
****/
|
|
||||||
public static void setListViewHeightBasedOnChildren(ListView listView) {
|
|
||||||
ListAdapter listAdapter = listView.getAdapter();
|
|
||||||
if (listAdapter == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
int desiredWidth = View.MeasureSpec.makeMeasureSpec(listView.getWidth(), View.MeasureSpec.UNSPECIFIED);
|
private Unbinder unbinder;
|
||||||
int totalHeight = 0;
|
private PluginType pluginType;
|
||||||
View view = null;
|
private PluginBase plugin;
|
||||||
for (int i = 0; i < listAdapter.getCount(); i++) {
|
|
||||||
view = listAdapter.getView(i, view, listView);
|
|
||||||
if (i == 0)
|
|
||||||
view.setLayoutParams(new ViewGroup.LayoutParams(desiredWidth, ViewGroup.LayoutParams.WRAP_CONTENT));
|
|
||||||
|
|
||||||
view.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
|
LinearLayout baseView;
|
||||||
totalHeight += view.getMeasuredHeight();
|
@BindView(R.id.plugin_enabled_exclusive)
|
||||||
|
RadioButton enabledExclusive;
|
||||||
|
@BindView(R.id.plugin_enabled_inclusive)
|
||||||
|
CheckBox enabledInclusive;
|
||||||
|
@BindView(R.id.plugin_name)
|
||||||
|
TextView pluginName;
|
||||||
|
@BindView(R.id.plugin_description)
|
||||||
|
TextView pluginDescription;
|
||||||
|
@BindView(R.id.plugin_preferences)
|
||||||
|
ImageButton pluginPreferences;
|
||||||
|
@BindView(R.id.plugin_visibility)
|
||||||
|
CheckBox pluginVisibility;
|
||||||
|
|
||||||
|
public PluginViewHolder(PluginType pluginType, PluginBase plugin) {
|
||||||
|
this.pluginType = pluginType;
|
||||||
|
this.plugin = plugin;
|
||||||
|
baseView = (LinearLayout) getLayoutInflater().inflate(R.layout.configbuilder_single_plugin, null);
|
||||||
|
unbinder = ButterKnife.bind(this, baseView);
|
||||||
|
update();
|
||||||
}
|
}
|
||||||
ViewGroup.LayoutParams params = listView.getLayoutParams();
|
|
||||||
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
|
|
||||||
listView.setLayoutParams(params);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public LinearLayout getBaseView() {
|
||||||
|
return baseView;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update() {
|
||||||
|
enabledExclusive.setVisibility(areMultipleSelectionsAllowed(pluginType) ? View.GONE : View.VISIBLE);
|
||||||
|
enabledInclusive.setVisibility(areMultipleSelectionsAllowed(pluginType) ? View.VISIBLE : View.GONE);
|
||||||
|
enabledExclusive.setChecked(plugin.isEnabled(pluginType));
|
||||||
|
enabledInclusive.setChecked(plugin.isEnabled(pluginType));
|
||||||
|
enabledInclusive.setEnabled(!plugin.pluginDescription.alwaysEnabled);
|
||||||
|
enabledExclusive.setEnabled(!plugin.pluginDescription.alwaysEnabled);
|
||||||
|
pluginName.setText(plugin.getName());
|
||||||
|
if (plugin.getDescription() == null) pluginDescription.setVisibility(View.GONE);
|
||||||
|
else {
|
||||||
|
pluginDescription.setVisibility(View.VISIBLE);
|
||||||
|
pluginDescription.setText(plugin.getDescription());
|
||||||
|
}
|
||||||
|
pluginPreferences.setVisibility(plugin.getPreferencesId() == -1 || !plugin.isEnabled(pluginType) ? View.INVISIBLE : View.VISIBLE);
|
||||||
|
pluginVisibility.setVisibility(plugin.hasFragment() ? View.VISIBLE : View.INVISIBLE);
|
||||||
|
pluginVisibility.setEnabled(!(plugin.pluginDescription.neverVisible || plugin.pluginDescription.alwayVisible) && plugin.isEnabled(pluginType));
|
||||||
|
pluginVisibility.setChecked(plugin.isFragmentVisible());
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnClick(R.id.plugin_visibility)
|
||||||
|
void onVisibilityChanged() {
|
||||||
|
plugin.setFragmentVisible(pluginType, pluginVisibility.isChecked());
|
||||||
|
ConfigBuilderPlugin.getPlugin().storeSettings("CheckedCheckboxVisible");
|
||||||
|
MainApp.bus().post(new EventRefreshGui());
|
||||||
|
ConfigBuilderPlugin.getPlugin().logPluginStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnClick({R.id.plugin_enabled_exclusive, R.id.plugin_enabled_inclusive})
|
||||||
|
void onEnabledChanged() {
|
||||||
|
plugin.switchAllowed(new PluginSwitcher(), getActivity());
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnClick(R.id.plugin_preferences)
|
||||||
|
void onPluginPreferencesClicked() {
|
||||||
|
PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", () -> {
|
||||||
|
Intent i = new Intent(getContext(), PreferencesActivity.class);
|
||||||
|
i.putExtra("id", plugin.getPreferencesId());
|
||||||
|
startActivity(i);
|
||||||
|
}, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unbind() {
|
||||||
|
unbinder.unbind();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PluginSwitcher {
|
||||||
|
public void invoke() {
|
||||||
|
boolean enabled = enabledExclusive.getVisibility() == View.VISIBLE ? enabledExclusive.isChecked() : enabledInclusive.isChecked();
|
||||||
|
plugin.setPluginEnabled(pluginType, enabled);
|
||||||
|
plugin.setFragmentVisible(pluginType, enabled);
|
||||||
|
processOnEnabledCategoryChanged(plugin, pluginType);
|
||||||
|
updateGUI();
|
||||||
|
ConfigBuilderPlugin.getPlugin().storeSettings("CheckedCheckboxEnabled");
|
||||||
|
MainApp.bus().post(new EventRefreshGui());
|
||||||
|
MainApp.bus().post(new EventConfigBuilderChange());
|
||||||
|
ConfigBuilderPlugin.getPlugin().logPluginStatus();
|
||||||
|
FabricPrivacy.getInstance().logCustom(new CustomEvent("ConfigurationChange"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cancel(){
|
||||||
|
updateGUI();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ import info.nightscout.androidaps.plugins.Loop.APSResult;
|
||||||
import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
|
import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity;
|
import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity;
|
||||||
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
|
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
|
||||||
import info.nightscout.androidaps.plugins.SensitivityOref0.SensitivityOref0Plugin;
|
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityOref0Plugin;
|
||||||
import info.nightscout.androidaps.queue.Callback;
|
import info.nightscout.androidaps.queue.Callback;
|
||||||
import info.nightscout.androidaps.queue.CommandQueue;
|
import info.nightscout.androidaps.queue.CommandQueue;
|
||||||
import info.nightscout.utils.FabricPrivacy;
|
import info.nightscout.utils.FabricPrivacy;
|
||||||
|
@ -87,11 +87,12 @@ public class ConfigBuilderPlugin extends PluginBase {
|
||||||
super(new PluginDescription()
|
super(new PluginDescription()
|
||||||
.mainType(PluginType.GENERAL)
|
.mainType(PluginType.GENERAL)
|
||||||
.fragmentClass(ConfigBuilderFragment.class.getName())
|
.fragmentClass(ConfigBuilderFragment.class.getName())
|
||||||
.showInList(false)
|
.showInList(true)
|
||||||
.alwaysEnabled(true)
|
.alwaysEnabled(true)
|
||||||
.alwayVisible(true)
|
.alwayVisible(false)
|
||||||
.pluginName(R.string.configbuilder)
|
.pluginName(R.string.configbuilder)
|
||||||
.shortName(R.string.configbuilder_shortname)
|
.shortName(R.string.configbuilder_shortname)
|
||||||
|
.description(R.string.description_config_builder)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,9 +113,17 @@ public class ConfigBuilderPlugin extends PluginBase {
|
||||||
pluginList = MainApp.getPluginsList();
|
pluginList = MainApp.getPluginsList();
|
||||||
upgradeSettings();
|
upgradeSettings();
|
||||||
loadSettings();
|
loadSettings();
|
||||||
|
setAlwaysEnabledPluginsEnabled();
|
||||||
MainApp.bus().post(new EventAppInitialized());
|
MainApp.bus().post(new EventAppInitialized());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setAlwaysEnabledPluginsEnabled() {
|
||||||
|
for (PluginBase plugin : pluginList) {
|
||||||
|
if (plugin.pluginDescription.alwaysEnabled) plugin.setPluginEnabled(plugin.getType(), true);
|
||||||
|
}
|
||||||
|
storeSettings("setAlwaysEnabledPluginsEnabled");
|
||||||
|
}
|
||||||
|
|
||||||
public void storeSettings(String from) {
|
public void storeSettings(String from) {
|
||||||
if (pluginList != null) {
|
if (pluginList != null) {
|
||||||
if (Config.logPrefsChange)
|
if (Config.logPrefsChange)
|
||||||
|
@ -519,6 +528,7 @@ public class ConfigBuilderPlugin extends PluginBase {
|
||||||
|
|
||||||
// deliver SMB
|
// deliver SMB
|
||||||
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
|
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
|
||||||
|
detailedBolusInfo.lastKnownBolusTime = activeTreatments.getLastBolusTime();
|
||||||
detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS;
|
detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS;
|
||||||
detailedBolusInfo.insulin = request.smb;
|
detailedBolusInfo.insulin = request.smb;
|
||||||
detailedBolusInfo.isSMB = true;
|
detailedBolusInfo.isSMB = true;
|
||||||
|
|
|
@ -1,12 +1,18 @@
|
||||||
package info.nightscout.androidaps.plugins.ConstraintsObjectives;
|
package info.nightscout.androidaps.plugins.ConstraintsObjectives;
|
||||||
|
|
||||||
|
import android.animation.LayoutTransition;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.app.Fragment;
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.v4.content.ContextCompat;
|
||||||
import android.support.v7.widget.CardView;
|
import android.support.v7.widget.CardView;
|
||||||
import android.support.v7.widget.LinearLayoutManager;
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
|
import android.support.v7.widget.LinearSmoothScroller;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
|
import android.text.Html;
|
||||||
|
import android.util.DisplayMetrics;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
@ -16,203 +22,40 @@ import android.widget.LinearLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
|
||||||
|
import com.squareup.otto.Subscribe;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
|
import info.nightscout.androidaps.events.EventConfigBuilderChange;
|
||||||
|
import info.nightscout.androidaps.events.EventNewBG;
|
||||||
|
import info.nightscout.androidaps.events.EventProfileSwitchChange;
|
||||||
|
import info.nightscout.androidaps.events.EventTreatmentChange;
|
||||||
import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
|
import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
|
||||||
|
import info.nightscout.androidaps.plugins.ConstraintsObjectives.events.EventObjectivesSaved;
|
||||||
|
import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective;
|
||||||
import info.nightscout.utils.FabricPrivacy;
|
import info.nightscout.utils.FabricPrivacy;
|
||||||
import info.nightscout.utils.T;
|
|
||||||
|
|
||||||
public class ObjectivesFragment extends SubscriberFragment {
|
public class ObjectivesFragment extends SubscriberFragment {
|
||||||
private static Logger log = LoggerFactory.getLogger(ObjectivesFragment.class);
|
private static Logger log = LoggerFactory.getLogger(ObjectivesFragment.class);
|
||||||
|
|
||||||
RecyclerView recyclerView;
|
RecyclerView recyclerView;
|
||||||
LinearLayoutManager llm;
|
|
||||||
CheckBox enableFake;
|
CheckBox enableFake;
|
||||||
LinearLayout fake_layout;
|
|
||||||
TextView reset;
|
TextView reset;
|
||||||
|
ObjectivesAdapter objectivesAdapter = new ObjectivesAdapter();
|
||||||
|
Handler handler = new Handler(Looper.getMainLooper());
|
||||||
|
|
||||||
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ObjectiveViewHolder> {
|
private Runnable objectiveUpdater = new Runnable() {
|
||||||
|
|
||||||
List<ObjectivesPlugin.Objective> objectives;
|
|
||||||
|
|
||||||
RecyclerViewAdapter(List<ObjectivesPlugin.Objective> objectives) {
|
|
||||||
this.objectives = objectives;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ObjectiveViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
|
public void run() {
|
||||||
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.objectives_item, viewGroup, false);
|
handler.postDelayed(this, 60 * 1000);
|
||||||
return new ObjectiveViewHolder(v);
|
updateGUI();
|
||||||
}
|
}
|
||||||
|
};
|
||||||
@Override
|
|
||||||
public void onBindViewHolder(ObjectiveViewHolder holder, int position) {
|
|
||||||
ObjectivesPlugin.Objective o = objectives.get(position);
|
|
||||||
ObjectivesPlugin.RequirementResult requirementsMet = ObjectivesPlugin.getPlugin().requirementsMet(position);
|
|
||||||
Context context = MainApp.instance().getApplicationContext();
|
|
||||||
holder.position.setText(String.valueOf(position + 1));
|
|
||||||
holder.objective.setText(o.objective);
|
|
||||||
holder.gate.setText(o.gate);
|
|
||||||
holder.duration.setText(MainApp.gs(R.string.objectives_minimalduration) + " " + o.durationInDays + " " + MainApp.gs(R.string.days));
|
|
||||||
holder.progress.setText(requirementsMet.comment);
|
|
||||||
holder.started.setText(o.started.toLocaleString());
|
|
||||||
holder.accomplished.setText(o.accomplished.toLocaleString());
|
|
||||||
|
|
||||||
holder.startButton.setTag(o);
|
|
||||||
holder.verifyButton.setTag(o);
|
|
||||||
|
|
||||||
holder.startButton.setOnClickListener(new View.OnClickListener() {
|
|
||||||
public void onClick(View v) {
|
|
||||||
ObjectivesPlugin.Objective o = (ObjectivesPlugin.Objective) v.getTag();
|
|
||||||
o.started = new Date();
|
|
||||||
updateGUI();
|
|
||||||
ObjectivesPlugin.saveProgress();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
holder.verifyButton.setOnClickListener(new View.OnClickListener() {
|
|
||||||
public void onClick(View v) {
|
|
||||||
ObjectivesPlugin.Objective o = (ObjectivesPlugin.Objective) v.getTag();
|
|
||||||
if (ObjectivesPlugin.getPlugin().requirementsMet(o.num).done || enableFake.isChecked()) {
|
|
||||||
o.accomplished = new Date();
|
|
||||||
updateGUI();
|
|
||||||
ObjectivesPlugin.saveProgress();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
long prevObjectiveAccomplishedTime = position > 0 ?
|
|
||||||
objectives.get(position - 1).accomplished.getTime() : -1;
|
|
||||||
|
|
||||||
int phase = modifyVisibility(position, prevObjectiveAccomplishedTime,
|
|
||||||
o.started.getTime(), o.durationInDays,
|
|
||||||
o.accomplished.getTime(), requirementsMet.done, enableFake.isChecked());
|
|
||||||
|
|
||||||
switch (phase) {
|
|
||||||
case 0:
|
|
||||||
// Phase 0: previous not completed
|
|
||||||
holder.startedLayout.setVisibility(View.GONE);
|
|
||||||
holder.durationLayout.setVisibility(View.GONE);
|
|
||||||
holder.progressLayout.setVisibility(View.GONE);
|
|
||||||
holder.verifyLayout.setVisibility(View.GONE);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
// Phase 1: not started
|
|
||||||
holder.durationLayout.setVisibility(View.GONE);
|
|
||||||
holder.progressLayout.setVisibility(View.GONE);
|
|
||||||
holder.verifyLayout.setVisibility(View.GONE);
|
|
||||||
holder.started.setVisibility(View.GONE);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
// Phase 2: started, waiting for duration and met requirements
|
|
||||||
holder.startButton.setEnabled(false);
|
|
||||||
holder.verifyLayout.setVisibility(View.GONE);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
// Phase 3: started, after duration, requirements met
|
|
||||||
holder.startButton.setEnabled(false);
|
|
||||||
holder.accomplished.setVisibility(View.INVISIBLE);
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
// Phase 4: verified
|
|
||||||
holder.gateLayout.setVisibility(View.GONE);
|
|
||||||
holder.startedLayout.setVisibility(View.GONE);
|
|
||||||
holder.durationLayout.setVisibility(View.GONE);
|
|
||||||
holder.progressLayout.setVisibility(View.GONE);
|
|
||||||
holder.verifyButton.setVisibility(View.INVISIBLE);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// should not happen
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getItemCount() {
|
|
||||||
return objectives.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
|
|
||||||
super.onAttachedToRecyclerView(recyclerView);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ObjectiveViewHolder extends RecyclerView.ViewHolder {
|
|
||||||
CardView cv;
|
|
||||||
TextView position;
|
|
||||||
TextView objective;
|
|
||||||
LinearLayout gateLayout;
|
|
||||||
TextView gate;
|
|
||||||
TextView duration;
|
|
||||||
LinearLayout durationLayout;
|
|
||||||
TextView progress;
|
|
||||||
LinearLayout progressLayout;
|
|
||||||
TextView started;
|
|
||||||
Button startButton;
|
|
||||||
LinearLayout startedLayout;
|
|
||||||
TextView accomplished;
|
|
||||||
Button verifyButton;
|
|
||||||
LinearLayout verifyLayout;
|
|
||||||
|
|
||||||
ObjectiveViewHolder(View itemView) {
|
|
||||||
super(itemView);
|
|
||||||
cv = (CardView) itemView.findViewById(R.id.objectives_cardview);
|
|
||||||
position = (TextView) itemView.findViewById(R.id.objectives_position);
|
|
||||||
objective = (TextView) itemView.findViewById(R.id.objectives_objective);
|
|
||||||
durationLayout = (LinearLayout) itemView.findViewById(R.id.objectives_duration_linearlayout);
|
|
||||||
duration = (TextView) itemView.findViewById(R.id.objectives_duration);
|
|
||||||
progressLayout = (LinearLayout) itemView.findViewById(R.id.objectives_progresslayout);
|
|
||||||
progress = (TextView) itemView.findViewById(R.id.objectives_progress);
|
|
||||||
gateLayout = (LinearLayout) itemView.findViewById(R.id.objectives_gate_linearlayout);
|
|
||||||
gate = (TextView) itemView.findViewById(R.id.objectives_gate);
|
|
||||||
startedLayout = (LinearLayout) itemView.findViewById(R.id.objectives_start_linearlayout);
|
|
||||||
started = (TextView) itemView.findViewById(R.id.objectives_started);
|
|
||||||
startButton = (Button) itemView.findViewById(R.id.objectives_start);
|
|
||||||
verifyLayout = (LinearLayout) itemView.findViewById(R.id.objectives_verify_linearlayout);
|
|
||||||
accomplished = (TextView) itemView.findViewById(R.id.objectives_accomplished);
|
|
||||||
verifyButton = (Button) itemView.findViewById(R.id.objectives_verify);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns an int, which represents the phase the current objective is at.
|
|
||||||
*
|
|
||||||
* this is mainly used for unit-testing the conditions
|
|
||||||
*
|
|
||||||
* @param currentPosition
|
|
||||||
* @param prevObjectiveAccomplishedTime
|
|
||||||
* @param objectiveStartedTime
|
|
||||||
* @param durationInDays
|
|
||||||
* @param objectiveAccomplishedTime
|
|
||||||
* @param requirementsMet
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public int modifyVisibility(int currentPosition,
|
|
||||||
long prevObjectiveAccomplishedTime,
|
|
||||||
long objectiveStartedTime, int durationInDays,
|
|
||||||
long objectiveAccomplishedTime, boolean requirementsMet,
|
|
||||||
boolean enableFakeValue) {
|
|
||||||
Long now = System.currentTimeMillis();
|
|
||||||
if (currentPosition > 0 && prevObjectiveAccomplishedTime == 0) {
|
|
||||||
return 0;
|
|
||||||
} else if (objectiveStartedTime == 0) {
|
|
||||||
return 1;
|
|
||||||
} else if (objectiveStartedTime > 0 && !enableFakeValue
|
|
||||||
&& objectiveAccomplishedTime == 0
|
|
||||||
&& !(objectiveStartedTime + T.days(durationInDays).msecs() < now && requirementsMet)) {
|
|
||||||
return 2;
|
|
||||||
} else if (objectiveAccomplishedTime == 0) {
|
|
||||||
return 3;
|
|
||||||
} else {
|
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
|
@ -220,44 +63,20 @@ public class ObjectivesFragment extends SubscriberFragment {
|
||||||
try {
|
try {
|
||||||
View view = inflater.inflate(R.layout.objectives_fragment, container, false);
|
View view = inflater.inflate(R.layout.objectives_fragment, container, false);
|
||||||
|
|
||||||
recyclerView = (RecyclerView) view.findViewById(R.id.objectives_recyclerview);
|
recyclerView = view.findViewById(R.id.objectives_recyclerview);
|
||||||
recyclerView.setHasFixedSize(true);
|
recyclerView.setLayoutManager(new LinearLayoutManager(view.getContext()));
|
||||||
llm = new LinearLayoutManager(view.getContext());
|
recyclerView.setAdapter(objectivesAdapter);
|
||||||
recyclerView.setLayoutManager(llm);
|
enableFake = view.findViewById(R.id.objectives_fake);
|
||||||
enableFake = (CheckBox) view.findViewById(R.id.objectives_fake);
|
reset = view.findViewById(R.id.objectives_reset);
|
||||||
fake_layout = (LinearLayout) view.findViewById(R.id.objectives_fake_layout);
|
enableFake.setOnClickListener(v -> updateGUI());
|
||||||
reset = (TextView) view.findViewById(R.id.objectives_reset);
|
reset.setOnClickListener(v -> {
|
||||||
enableFake.setOnClickListener(new View.OnClickListener() {
|
ObjectivesPlugin.getPlugin().reset();
|
||||||
public void onClick(View v) {
|
ObjectivesPlugin.saveProgress();
|
||||||
updateGUI();
|
recyclerView.getAdapter().notifyDataSetChanged();
|
||||||
}
|
scrollToCurrentObjective();
|
||||||
});
|
});
|
||||||
reset.setOnClickListener(new View.OnClickListener() {
|
scrollToCurrentObjective();
|
||||||
public void onClick(View v) {
|
startUpdateTimer();
|
||||||
ObjectivesPlugin.getPlugin().initializeData();
|
|
||||||
ObjectivesPlugin.saveProgress();
|
|
||||||
updateGUI();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add correct translations to array after app is initialized
|
|
||||||
ObjectivesPlugin.objectives.get(0).objective = MainApp.gs(R.string.objectives_0_objective);
|
|
||||||
ObjectivesPlugin.objectives.get(1).objective = MainApp.gs(R.string.objectives_1_objective);
|
|
||||||
ObjectivesPlugin.objectives.get(2).objective = MainApp.gs(R.string.objectives_2_objective);
|
|
||||||
ObjectivesPlugin.objectives.get(3).objective = MainApp.gs(R.string.objectives_3_objective);
|
|
||||||
ObjectivesPlugin.objectives.get(4).objective = MainApp.gs(R.string.objectives_4_objective);
|
|
||||||
ObjectivesPlugin.objectives.get(5).objective = MainApp.gs(R.string.objectives_5_objective);
|
|
||||||
ObjectivesPlugin.objectives.get(6).objective = MainApp.gs(R.string.objectives_6_objective);
|
|
||||||
ObjectivesPlugin.objectives.get(7).objective = MainApp.gs(R.string.objectives_7_objective);
|
|
||||||
ObjectivesPlugin.objectives.get(0).gate = MainApp.gs(R.string.objectives_0_gate);
|
|
||||||
ObjectivesPlugin.objectives.get(1).gate = MainApp.gs(R.string.objectives_1_gate);
|
|
||||||
ObjectivesPlugin.objectives.get(2).gate = MainApp.gs(R.string.objectives_2_gate);
|
|
||||||
ObjectivesPlugin.objectives.get(3).gate = MainApp.gs(R.string.objectives_3_gate);
|
|
||||||
ObjectivesPlugin.objectives.get(4).gate = MainApp.gs(R.string.objectives_4_gate);
|
|
||||||
ObjectivesPlugin.objectives.get(5).gate = MainApp.gs(R.string.objectives_5_gate);
|
|
||||||
|
|
||||||
updateGUI();
|
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
FabricPrivacy.logException(e);
|
FabricPrivacy.logException(e);
|
||||||
|
@ -266,14 +85,143 @@ public class ObjectivesFragment extends SubscriberFragment {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void onDestroyView() {
|
||||||
|
super.onDestroyView();
|
||||||
|
handler.removeCallbacks(objectiveUpdater);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startUpdateTimer() {
|
||||||
|
handler.removeCallbacks(objectiveUpdater);
|
||||||
|
for (Objective objective : ObjectivesPlugin.getObjectives()) {
|
||||||
|
if (objective.isStarted() && !objective.isAccomplished()) {
|
||||||
|
long timeTillNextMinute = (System.currentTimeMillis() - objective.getStartedOn().getTime()) % (60 * 1000);
|
||||||
|
handler.postDelayed(objectiveUpdater, timeTillNextMinute);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void scrollToCurrentObjective() {
|
||||||
|
for (int i = 0; i < ObjectivesPlugin.getObjectives().size(); i++) {
|
||||||
|
Objective objective = ObjectivesPlugin.getObjectives().get(i);
|
||||||
|
if (!objective.isStarted() || !objective.isAccomplished()) {
|
||||||
|
RecyclerView.SmoothScroller smoothScroller = new LinearSmoothScroller(getContext()) {
|
||||||
|
@Override
|
||||||
|
protected int getVerticalSnapPreference() {
|
||||||
|
return LinearSmoothScroller.SNAP_TO_START;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int calculateTimeForScrolling(int dx) {
|
||||||
|
return super.calculateTimeForScrolling(dx) * 4;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
smoothScroller.setTargetPosition(i);
|
||||||
|
recyclerView.getLayoutManager().startSmoothScroll(smoothScroller);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ObjectivesAdapter extends RecyclerView.Adapter<ObjectivesAdapter.ViewHolder> {
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
|
return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.objectives_item, parent, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||||
|
Objective objective = ObjectivesPlugin.getObjectives().get(position);
|
||||||
|
holder.title.setText(MainApp.gs(R.string.nth_objective, position + 1));
|
||||||
|
if (objective.getObjective() != 0) {
|
||||||
|
holder.objective.setVisibility(View.VISIBLE);
|
||||||
|
holder.objective.setText(MainApp.gs(objective.getObjective()));
|
||||||
|
} else holder.objective.setVisibility(View.GONE);
|
||||||
|
if (objective.getGate() != 0) {
|
||||||
|
holder.gate.setVisibility(View.VISIBLE);
|
||||||
|
holder.gate.setText(MainApp.gs(objective.getGate()));
|
||||||
|
} else holder.gate.setVisibility(View.GONE);
|
||||||
|
if (!objective.isStarted()) {
|
||||||
|
holder.gate.setTextColor(0xFFFFFFFF);
|
||||||
|
holder.verify.setVisibility(View.GONE);
|
||||||
|
holder.progress.setVisibility(View.GONE);
|
||||||
|
if (position == 0 || ObjectivesPlugin.getObjectives().get(position - 1).isAccomplished())
|
||||||
|
holder.start.setVisibility(View.VISIBLE);
|
||||||
|
else holder.start.setVisibility(View.GONE);
|
||||||
|
} else if (objective.isAccomplished()) {
|
||||||
|
holder.gate.setTextColor(0xFF4CAF50);
|
||||||
|
holder.verify.setVisibility(View.GONE);
|
||||||
|
holder.progress.setVisibility(View.GONE);
|
||||||
|
holder.start.setVisibility(View.GONE);
|
||||||
|
} else if (objective.isStarted()) {
|
||||||
|
holder.gate.setTextColor(0xFFFFFFFF);
|
||||||
|
holder.verify.setVisibility(View.VISIBLE);
|
||||||
|
holder.verify.setEnabled(objective.isCompleted() || enableFake.isChecked());
|
||||||
|
holder.start.setVisibility(View.GONE);
|
||||||
|
holder.progress.setVisibility(View.VISIBLE);
|
||||||
|
holder.progress.removeAllViews();
|
||||||
|
for (Objective.Task task : objective.getTasks()) {
|
||||||
|
if (task.shouldBeIgnored()) continue;
|
||||||
|
TextView textView = new TextView(holder.progress.getContext());
|
||||||
|
textView.setTextColor(0xFFFFFFFF);
|
||||||
|
String basicHTML = "%2$s: <font color=\"%1$s\"><b>%3$s</b></font>";
|
||||||
|
String formattedHTML = String.format(basicHTML, task.isCompleted() ? "#4CAF50" : "#FF9800", MainApp.gs(task.getTask()), task.getProgress());
|
||||||
|
textView.setText(Html.fromHtml(formattedHTML));
|
||||||
|
holder.progress.addView(textView, LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
holder.verify.setOnClickListener((view) -> {
|
||||||
|
objective.setAccomplishedOn(new Date());
|
||||||
|
notifyDataSetChanged();
|
||||||
|
scrollToCurrentObjective();
|
||||||
|
startUpdateTimer();
|
||||||
|
});
|
||||||
|
holder.start.setOnClickListener((view) -> {
|
||||||
|
objective.setStartedOn(new Date());
|
||||||
|
notifyDataSetChanged();
|
||||||
|
scrollToCurrentObjective();
|
||||||
|
startUpdateTimer();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return ObjectivesPlugin.getObjectives().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
|
||||||
|
public CardView cardView;
|
||||||
|
public TextView title;
|
||||||
|
public TextView objective;
|
||||||
|
public TextView gate;
|
||||||
|
public LinearLayout progress;
|
||||||
|
public Button verify;
|
||||||
|
public Button start;
|
||||||
|
|
||||||
|
public ViewHolder(View itemView) {
|
||||||
|
super(itemView);
|
||||||
|
cardView = (CardView) itemView;
|
||||||
|
title = itemView.findViewById(R.id.objective_title);
|
||||||
|
objective = itemView.findViewById(R.id.objective_objective);
|
||||||
|
gate = itemView.findViewById(R.id.objective_gate);
|
||||||
|
progress = itemView.findViewById(R.id.objective_progress);
|
||||||
|
verify = itemView.findViewById(R.id.objective_verify);
|
||||||
|
start = itemView.findViewById(R.id.objective_start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateGUI() {
|
public void updateGUI() {
|
||||||
Activity activity = getActivity();
|
Activity activity = getActivity();
|
||||||
if (activity != null)
|
if (activity != null)
|
||||||
activity.runOnUiThread(() -> {
|
activity.runOnUiThread(() -> {
|
||||||
RecyclerViewAdapter adapter = new RecyclerViewAdapter(ObjectivesPlugin.objectives);
|
objectivesAdapter.notifyDataSetChanged();
|
||||||
recyclerView.setAdapter(adapter);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,14 @@
|
||||||
package info.nightscout.androidaps.plugins.ConstraintsObjectives;
|
package info.nightscout.androidaps.plugins.ConstraintsObjectives;
|
||||||
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.preference.PreferenceManager;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import info.nightscout.androidaps.Config;
|
import info.nightscout.androidaps.Config;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.db.DatabaseHelper;
|
|
||||||
import info.nightscout.androidaps.interfaces.APSInterface;
|
|
||||||
import info.nightscout.androidaps.interfaces.Constraint;
|
import info.nightscout.androidaps.interfaces.Constraint;
|
||||||
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
|
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
|
||||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||||
|
@ -22,12 +16,16 @@ import info.nightscout.androidaps.interfaces.PluginDescription;
|
||||||
import info.nightscout.androidaps.interfaces.PluginType;
|
import info.nightscout.androidaps.interfaces.PluginType;
|
||||||
import info.nightscout.androidaps.interfaces.PumpInterface;
|
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||||
import info.nightscout.androidaps.plugins.ConstraintsSafety.SafetyPlugin;
|
import info.nightscout.androidaps.plugins.ConstraintsObjectives.events.EventObjectivesSaved;
|
||||||
import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
|
import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective;
|
||||||
import info.nightscout.androidaps.plugins.NSClientInternal.NSClientPlugin;
|
import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective1;
|
||||||
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
|
import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective2;
|
||||||
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective3;
|
||||||
import info.nightscout.utils.DateUtil;
|
import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective4;
|
||||||
|
import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective5;
|
||||||
|
import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective6;
|
||||||
|
import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective7;
|
||||||
|
import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective8;
|
||||||
import info.nightscout.utils.SP;
|
import info.nightscout.utils.SP;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,6 +36,11 @@ public class ObjectivesPlugin extends PluginBase implements ConstraintsInterface
|
||||||
|
|
||||||
private static ObjectivesPlugin objectivesPlugin;
|
private static ObjectivesPlugin objectivesPlugin;
|
||||||
|
|
||||||
|
public static List<Objective> objectives = new ArrayList<>();
|
||||||
|
public static boolean bgIsAvailableInNS = false;
|
||||||
|
public static boolean pumpStatusIsAvailableInNS = false;
|
||||||
|
public static Integer manualEnacts = 0;
|
||||||
|
|
||||||
public static ObjectivesPlugin getPlugin() {
|
public static ObjectivesPlugin getPlugin() {
|
||||||
if (objectivesPlugin == null) {
|
if (objectivesPlugin == null) {
|
||||||
objectivesPlugin = new ObjectivesPlugin();
|
objectivesPlugin = new ObjectivesPlugin();
|
||||||
|
@ -45,8 +48,6 @@ public class ObjectivesPlugin extends PluginBase implements ConstraintsInterface
|
||||||
return objectivesPlugin;
|
return objectivesPlugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<Objective> objectives;
|
|
||||||
|
|
||||||
private ObjectivesPlugin() {
|
private ObjectivesPlugin() {
|
||||||
super(new PluginDescription()
|
super(new PluginDescription()
|
||||||
.mainType(PluginType.CONSTRAINTS)
|
.mainType(PluginType.CONSTRAINTS)
|
||||||
|
@ -55,8 +56,9 @@ public class ObjectivesPlugin extends PluginBase implements ConstraintsInterface
|
||||||
.showInList(!Config.NSCLIENT && !Config.G5UPLOADER)
|
.showInList(!Config.NSCLIENT && !Config.G5UPLOADER)
|
||||||
.pluginName(R.string.objectives)
|
.pluginName(R.string.objectives)
|
||||||
.shortName(R.string.objectives_shortname)
|
.shortName(R.string.objectives_shortname)
|
||||||
|
.description(R.string.description_objectives)
|
||||||
);
|
);
|
||||||
initializeData();
|
setupObjectives();
|
||||||
loadProgress();
|
loadProgress();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,186 +68,38 @@ public class ObjectivesPlugin extends PluginBase implements ConstraintsInterface
|
||||||
return pump == null || pump.getPumpDescription().isTempBasalCapable;
|
return pump == null || pump.getPumpDescription().isTempBasalCapable;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Objective {
|
private void setupObjectives() {
|
||||||
Integer num;
|
objectives.add(new Objective1());
|
||||||
String objective;
|
objectives.add(new Objective2());
|
||||||
String gate;
|
objectives.add(new Objective3());
|
||||||
Date started;
|
objectives.add(new Objective4());
|
||||||
Integer durationInDays;
|
objectives.add(new Objective5());
|
||||||
Date accomplished;
|
objectives.add(new Objective6());
|
||||||
|
objectives.add(new Objective7());
|
||||||
Objective(Integer num, String objective, String gate, Date started, Integer durationInDays, Date accomplished) {
|
objectives.add(new Objective8());
|
||||||
this.num = num;
|
|
||||||
this.objective = objective;
|
|
||||||
this.gate = gate;
|
|
||||||
this.started = started;
|
|
||||||
this.durationInDays = durationInDays;
|
|
||||||
this.accomplished = accomplished;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStarted(Date started) {
|
|
||||||
this.started = started;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean isStarted() {
|
|
||||||
return started.getTime() > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean isFinished() {
|
|
||||||
return accomplished.getTime() != 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Objective 0
|
public void reset() {
|
||||||
public static boolean bgIsAvailableInNS = false;
|
for (Objective objective : objectives) {
|
||||||
public static boolean pumpStatusIsAvailableInNS = false;
|
objective.setStartedOn(null);
|
||||||
// Objective 1
|
objective.setAccomplishedOn(null);
|
||||||
public static Integer manualEnacts = 0;
|
|
||||||
private static final Integer manualEnactsNeeded = 20;
|
|
||||||
|
|
||||||
class RequirementResult {
|
|
||||||
boolean done = false;
|
|
||||||
String comment = "";
|
|
||||||
|
|
||||||
RequirementResult(boolean done, String comment) {
|
|
||||||
this.done = done;
|
|
||||||
this.comment = comment;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private String yesOrNo(boolean yes) {
|
|
||||||
if (yes) return "☺";
|
|
||||||
else return "---";
|
|
||||||
}
|
|
||||||
|
|
||||||
RequirementResult requirementsMet(Integer objNum) {
|
|
||||||
switch (objNum) {
|
|
||||||
case 0:
|
|
||||||
boolean isVirtualPump = VirtualPumpPlugin.getPlugin().isEnabled(PluginType.PUMP);
|
|
||||||
boolean vpUploadEnabled = SP.getBoolean("virtualpump_uploadstatus", false);
|
|
||||||
boolean vpUploadNeeded = !isVirtualPump || vpUploadEnabled;
|
|
||||||
boolean hasBGData = DatabaseHelper.lastBg() != null;
|
|
||||||
|
|
||||||
boolean apsEnabled = false;
|
|
||||||
APSInterface usedAPS = ConfigBuilderPlugin.getActiveAPS();
|
|
||||||
if (usedAPS != null && ((PluginBase) usedAPS).isEnabled(PluginType.APS))
|
|
||||||
apsEnabled = true;
|
|
||||||
|
|
||||||
boolean profileSwitchExists = TreatmentsPlugin.getPlugin().getProfileSwitchFromHistory(DateUtil.now()) != null;
|
|
||||||
|
|
||||||
return new RequirementResult(hasBGData && bgIsAvailableInNS && pumpStatusIsAvailableInNS && NSClientPlugin.getPlugin().hasWritePermission() && LoopPlugin.getPlugin().isEnabled(PluginType.LOOP) && apsEnabled && vpUploadNeeded && profileSwitchExists,
|
|
||||||
MainApp.gs(R.string.objectives_bgavailableinns) + ": " + yesOrNo(bgIsAvailableInNS)
|
|
||||||
+ "\n" + MainApp.gs(R.string.nsclienthaswritepermission) + ": " + yesOrNo(NSClientPlugin.getPlugin().hasWritePermission())
|
|
||||||
+ (isVirtualPump ? "\n" + MainApp.gs(R.string.virtualpump_uploadstatus_title) + ": " + yesOrNo(vpUploadEnabled) : "")
|
|
||||||
+ "\n" + MainApp.gs(R.string.objectives_pumpstatusavailableinns) + ": " + yesOrNo(pumpStatusIsAvailableInNS)
|
|
||||||
+ "\n" + MainApp.gs(R.string.hasbgdata) + ": " + yesOrNo(hasBGData)
|
|
||||||
+ "\n" + MainApp.gs(R.string.loopenabled) + ": " + yesOrNo(LoopPlugin.getPlugin().isEnabled(PluginType.LOOP))
|
|
||||||
+ "\n" + MainApp.gs(R.string.apsselected) + ": " + yesOrNo(apsEnabled)
|
|
||||||
+ "\n" + MainApp.gs(R.string.activate_profile) + ": " + yesOrNo(profileSwitchExists)
|
|
||||||
);
|
|
||||||
case 1:
|
|
||||||
return new RequirementResult(manualEnacts >= manualEnactsNeeded,
|
|
||||||
MainApp.gs(R.string.objectives_manualenacts) + ": " + manualEnacts + "/" + manualEnactsNeeded);
|
|
||||||
case 2:
|
|
||||||
return new RequirementResult(true, "");
|
|
||||||
case 3:
|
|
||||||
Constraint<Boolean> closedLoopEnabled = new Constraint<>(true);
|
|
||||||
SafetyPlugin.getPlugin().isClosedLoopAllowed(closedLoopEnabled);
|
|
||||||
return new RequirementResult(closedLoopEnabled.value(), MainApp.gs(R.string.closedmodeenabled) + ": " + yesOrNo(closedLoopEnabled.value()));
|
|
||||||
case 4:
|
|
||||||
double maxIOB = MainApp.getConstraintChecker().getMaxIOBAllowed().value();
|
|
||||||
boolean maxIobSet = maxIOB > 0;
|
|
||||||
return new RequirementResult(maxIobSet, MainApp.gs(R.string.maxiobset) + ": " + yesOrNo(maxIobSet));
|
|
||||||
default:
|
|
||||||
return new RequirementResult(true, "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void initializeData() {
|
|
||||||
bgIsAvailableInNS = false;
|
bgIsAvailableInNS = false;
|
||||||
pumpStatusIsAvailableInNS = false;
|
pumpStatusIsAvailableInNS = false;
|
||||||
manualEnacts = 0;
|
manualEnacts = 0;
|
||||||
|
saveProgress();
|
||||||
objectives = new ArrayList<>();
|
|
||||||
objectives.add(new Objective(0,
|
|
||||||
MainApp.gs(R.string.objectives_0_objective),
|
|
||||||
MainApp.gs(R.string.objectives_0_gate),
|
|
||||||
new Date(0),
|
|
||||||
0, // 0 day
|
|
||||||
new Date(0)));
|
|
||||||
objectives.add(new Objective(1,
|
|
||||||
MainApp.gs(R.string.objectives_1_objective),
|
|
||||||
MainApp.gs(R.string.objectives_1_gate),
|
|
||||||
new Date(0),
|
|
||||||
7, // 7 days
|
|
||||||
new Date(0)));
|
|
||||||
objectives.add(new Objective(2,
|
|
||||||
MainApp.gs(R.string.objectives_2_objective),
|
|
||||||
MainApp.gs(R.string.objectives_2_gate),
|
|
||||||
new Date(0),
|
|
||||||
0, // 0 days
|
|
||||||
new Date(0)));
|
|
||||||
objectives.add(new Objective(3,
|
|
||||||
MainApp.gs(R.string.objectives_3_objective),
|
|
||||||
MainApp.gs(R.string.objectives_3_gate),
|
|
||||||
new Date(0),
|
|
||||||
5, // 5 days
|
|
||||||
new Date(0)));
|
|
||||||
objectives.add(new Objective(4,
|
|
||||||
MainApp.gs(R.string.objectives_4_objective),
|
|
||||||
MainApp.gs(R.string.objectives_4_gate),
|
|
||||||
new Date(0),
|
|
||||||
1,
|
|
||||||
new Date(0)));
|
|
||||||
objectives.add(new Objective(5,
|
|
||||||
MainApp.gs(R.string.objectives_5_objective),
|
|
||||||
MainApp.gs(R.string.objectives_5_gate),
|
|
||||||
new Date(0),
|
|
||||||
7,
|
|
||||||
new Date(0)));
|
|
||||||
objectives.add(new Objective(6,
|
|
||||||
MainApp.gs(R.string.objectives_6_objective),
|
|
||||||
"",
|
|
||||||
new Date(0),
|
|
||||||
28,
|
|
||||||
new Date(0)));
|
|
||||||
objectives.add(new Objective(7,
|
|
||||||
MainApp.gs(R.string.objectives_7_objective),
|
|
||||||
"",
|
|
||||||
new Date(0),
|
|
||||||
28,
|
|
||||||
new Date(0)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void saveProgress() {
|
public static void saveProgress() {
|
||||||
if (objectives != null) {
|
SP.putBoolean("Objectives" + "bgIsAvailableInNS", bgIsAvailableInNS);
|
||||||
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext());
|
SP.putBoolean("Objectives" + "pumpStatusIsAvailableInNS", pumpStatusIsAvailableInNS);
|
||||||
SharedPreferences.Editor editor = settings.edit();
|
SP.putString("Objectives" + "manualEnacts", Integer.toString(manualEnacts));
|
||||||
for (int num = 0; num < objectives.size(); num++) {
|
if (Config.logPrefsChange)
|
||||||
Objective o = objectives.get(num);
|
log.debug("Objectives stored");
|
||||||
editor.putString("Objectives" + num + "started", Long.toString(o.started.getTime()));
|
MainApp.bus().post(new EventObjectivesSaved());
|
||||||
editor.putString("Objectives" + num + "accomplished", Long.toString(o.accomplished.getTime()));
|
|
||||||
}
|
|
||||||
editor.putBoolean("Objectives" + "bgIsAvailableInNS", bgIsAvailableInNS);
|
|
||||||
editor.putBoolean("Objectives" + "pumpStatusIsAvailableInNS", pumpStatusIsAvailableInNS);
|
|
||||||
editor.putString("Objectives" + "manualEnacts", Integer.toString(manualEnacts));
|
|
||||||
editor.apply();
|
|
||||||
if (Config.logPrefsChange)
|
|
||||||
log.debug("Objectives stored");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadProgress() {
|
private void loadProgress() {
|
||||||
for (int num = 0; num < objectives.size(); num++) {
|
|
||||||
Objective o = objectives.get(num);
|
|
||||||
try {
|
|
||||||
o.started = new Date(SP.getLong("Objectives" + num + "started", 0L));
|
|
||||||
o.accomplished = new Date(SP.getLong("Objectives" + num + "accomplished", 0L));
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bgIsAvailableInNS = SP.getBoolean("Objectives" + "bgIsAvailableInNS", false);
|
bgIsAvailableInNS = SP.getBoolean("Objectives" + "bgIsAvailableInNS", false);
|
||||||
pumpStatusIsAvailableInNS = SP.getBoolean("Objectives" + "pumpStatusIsAvailableInNS", false);
|
pumpStatusIsAvailableInNS = SP.getBoolean("Objectives" + "pumpStatusIsAvailableInNS", false);
|
||||||
try {
|
try {
|
||||||
|
@ -257,11 +111,15 @@ public class ObjectivesPlugin extends PluginBase implements ConstraintsInterface
|
||||||
log.debug("Objectives loaded");
|
log.debug("Objectives loaded");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<Objective> getObjectives() {
|
||||||
|
return objectives;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constraints interface
|
* Constraints interface
|
||||||
**/
|
**/
|
||||||
@Override
|
@Override
|
||||||
public Constraint<Boolean> isLoopInvokationAllowed(Constraint<Boolean> value) {
|
public Constraint<Boolean> isLoopInvocationAllowed(Constraint<Boolean> value) {
|
||||||
if (!objectives.get(0).isStarted())
|
if (!objectives.get(0).isStarted())
|
||||||
value.set(false, String.format(MainApp.gs(R.string.objectivenotstarted), 1), this);
|
value.set(false, String.format(MainApp.gs(R.string.objectivenotstarted), 1), this);
|
||||||
return value;
|
return value;
|
||||||
|
@ -297,7 +155,7 @@ public class ObjectivesPlugin extends PluginBase implements ConstraintsInterface
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Constraint<Double> applyMaxIOBConstraints(Constraint<Double> maxIob) {
|
public Constraint<Double> applyMaxIOBConstraints(Constraint<Double> maxIob) {
|
||||||
if (objectives.get(3).isStarted() && !objectives.get(3).isFinished())
|
if (objectives.get(3).isStarted() && !objectives.get(3).isAccomplished())
|
||||||
maxIob.set(0d, String.format(MainApp.gs(R.string.objectivenotfinished), 4), this);
|
maxIob.set(0d, String.format(MainApp.gs(R.string.objectivenotfinished), 4), this);
|
||||||
return maxIob;
|
return maxIob;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
package info.nightscout.androidaps.plugins.ConstraintsObjectives.events;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.events.Event;
|
||||||
|
|
||||||
|
public class EventObjectivesSaved extends Event {
|
||||||
|
}
|
|
@ -0,0 +1,140 @@
|
||||||
|
package info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives;
|
||||||
|
|
||||||
|
import android.support.annotation.StringRes;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.MainApp;
|
||||||
|
import info.nightscout.androidaps.R;
|
||||||
|
import info.nightscout.utils.SP;
|
||||||
|
|
||||||
|
public abstract class Objective {
|
||||||
|
|
||||||
|
private int number;
|
||||||
|
@StringRes
|
||||||
|
private int objective;
|
||||||
|
@StringRes
|
||||||
|
private int gate;
|
||||||
|
private Date startedOn;
|
||||||
|
private Date accomplishedOn;
|
||||||
|
private List<Task> tasks = new ArrayList<>();
|
||||||
|
|
||||||
|
public Objective(int number, @StringRes int objective, @StringRes int gate) {
|
||||||
|
this.number = number;
|
||||||
|
this.objective = objective;
|
||||||
|
this.gate = gate;
|
||||||
|
startedOn = new Date(SP.getLong("Objectives" + number + "started", 0L));
|
||||||
|
if (startedOn.getTime() == 0L) startedOn = null;
|
||||||
|
accomplishedOn = new Date(SP.getLong("Objectives" + number + "accomplished", 0L));
|
||||||
|
if (accomplishedOn.getTime() == 0L) accomplishedOn = null;
|
||||||
|
setupTasks(tasks);
|
||||||
|
for (Task task : tasks) task.objective = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCompleted() {
|
||||||
|
for (Task task : tasks) {
|
||||||
|
if (!task.shouldBeIgnored() && !task.isCompleted())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAccomplished() {
|
||||||
|
return accomplishedOn != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isStarted() {
|
||||||
|
return startedOn != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getStartedOn() {
|
||||||
|
return startedOn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getObjective() {
|
||||||
|
return objective;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getGate() {
|
||||||
|
return gate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStartedOn(Date startedOn) {
|
||||||
|
this.startedOn = startedOn;
|
||||||
|
SP.putLong("Objectives" + number + "started", startedOn == null ? 0 : startedOn.getTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAccomplishedOn(Date accomplishedOn) {
|
||||||
|
this.accomplishedOn = accomplishedOn;
|
||||||
|
SP.putLong("Objectives" + number + "accomplished", accomplishedOn == null ? 0 : accomplishedOn.getTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setupTasks(List<Task> tasks) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Task> getTasks() {
|
||||||
|
return tasks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class Task {
|
||||||
|
@StringRes
|
||||||
|
private int task;
|
||||||
|
private Objective objective;
|
||||||
|
|
||||||
|
public Task(@StringRes int task) {
|
||||||
|
this.task = task;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTask() {
|
||||||
|
return task;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Objective getObjective() {
|
||||||
|
return objective;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract boolean isCompleted();
|
||||||
|
|
||||||
|
public String getProgress() {
|
||||||
|
return MainApp.gs(isCompleted() ? R.string.completed_well_done : R.string.not_completed_yet);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean shouldBeIgnored() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MinimumDurationTask extends Task {
|
||||||
|
|
||||||
|
private long minimumDuration;
|
||||||
|
|
||||||
|
public MinimumDurationTask(long minimumDuration) {
|
||||||
|
super(R.string.time_elapsed);
|
||||||
|
this.minimumDuration = minimumDuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCompleted() {
|
||||||
|
return getObjective().isStarted() && System.currentTimeMillis() - getObjective().getStartedOn().getTime() >= minimumDuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getProgress() {
|
||||||
|
return getDurationText(System.currentTimeMillis() - getObjective().getStartedOn().getTime())
|
||||||
|
+ " / " + getDurationText(minimumDuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getDurationText(long duration) {
|
||||||
|
int days = (int) Math.floor((double) duration / (24D * 60D * 60D * 1000D));
|
||||||
|
int hours = (int) Math.floor((double) duration / (60D * 60D * 1000D));
|
||||||
|
int minutes = (int) Math.floor((double) duration / (60D * 1000D));
|
||||||
|
if (days > 0) return MainApp.gq(R.plurals.objective_days, days, days);
|
||||||
|
else if (hours > 0) return MainApp.gq(R.plurals.objective_hours, hours, hours);
|
||||||
|
else return MainApp.gq(R.plurals.objective_minutes, minutes, minutes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
package info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.R;
|
||||||
|
import info.nightscout.androidaps.db.DatabaseHelper;
|
||||||
|
import info.nightscout.androidaps.interfaces.APSInterface;
|
||||||
|
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||||
|
import info.nightscout.androidaps.interfaces.PluginType;
|
||||||
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.NSClientInternal.NSClientPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||||
|
import info.nightscout.utils.DateUtil;
|
||||||
|
import info.nightscout.utils.SP;
|
||||||
|
|
||||||
|
public class Objective1 extends Objective {
|
||||||
|
|
||||||
|
public Objective1() {
|
||||||
|
super(0, R.string.objectives_0_objective, R.string.objectives_0_gate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setupTasks(List<Task> tasks) {
|
||||||
|
tasks.add(new Task(R.string.objectives_bgavailableinns) {
|
||||||
|
@Override
|
||||||
|
public boolean isCompleted() {
|
||||||
|
return ObjectivesPlugin.bgIsAvailableInNS;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
tasks.add(new Task(R.string.nsclienthaswritepermission) {
|
||||||
|
@Override
|
||||||
|
public boolean isCompleted() {
|
||||||
|
return NSClientPlugin.getPlugin().hasWritePermission();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
tasks.add(new Task(R.string.virtualpump_uploadstatus_title) {
|
||||||
|
@Override
|
||||||
|
public boolean isCompleted() {
|
||||||
|
return SP.getBoolean("virtualpump_uploadstatus", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldBeIgnored() {
|
||||||
|
return !VirtualPumpPlugin.getPlugin().isEnabled(PluginType.PUMP);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
tasks.add(new Task(R.string.objectives_pumpstatusavailableinns) {
|
||||||
|
@Override
|
||||||
|
public boolean isCompleted() {
|
||||||
|
return ObjectivesPlugin.pumpStatusIsAvailableInNS;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
tasks.add(new Task(R.string.hasbgdata) {
|
||||||
|
@Override
|
||||||
|
public boolean isCompleted() {
|
||||||
|
return DatabaseHelper.lastBg() != null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
tasks.add(new Task(R.string.loopenabled) {
|
||||||
|
@Override
|
||||||
|
public boolean isCompleted() {
|
||||||
|
return LoopPlugin.getPlugin().isEnabled(PluginType.LOOP);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
tasks.add(new Task(R.string.apsselected) {
|
||||||
|
@Override
|
||||||
|
public boolean isCompleted() {
|
||||||
|
APSInterface usedAPS = ConfigBuilderPlugin.getActiveAPS();
|
||||||
|
if (usedAPS != null && ((PluginBase) usedAPS).isEnabled(PluginType.APS))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
tasks.add(new Task(R.string.activate_profile) {
|
||||||
|
@Override
|
||||||
|
public boolean isCompleted() {
|
||||||
|
return TreatmentsPlugin.getPlugin().getProfileSwitchFromHistory(DateUtil.now()) != null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.MainApp;
|
||||||
|
import info.nightscout.androidaps.R;
|
||||||
|
import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin;
|
||||||
|
|
||||||
|
public class Objective2 extends Objective {
|
||||||
|
|
||||||
|
public static final int MANUAL_ENACTS_NEEDED = 20;
|
||||||
|
|
||||||
|
public Objective2() {
|
||||||
|
super(1, R.string.objectives_1_objective, R.string.objectives_1_gate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setupTasks(List<Task> tasks) {
|
||||||
|
tasks.add(new MinimumDurationTask(7L * 24L * 60L * 60L * 1000L));
|
||||||
|
tasks.add(new Task(R.string.objectives_manualenacts) {
|
||||||
|
@Override
|
||||||
|
public boolean isCompleted() {
|
||||||
|
return ObjectivesPlugin.manualEnacts >= MANUAL_ENACTS_NEEDED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getProgress() {
|
||||||
|
if (ObjectivesPlugin.manualEnacts >= MANUAL_ENACTS_NEEDED) return MainApp.gs(R.string.completed_well_done);
|
||||||
|
else return ObjectivesPlugin.manualEnacts + " / " + MANUAL_ENACTS_NEEDED;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.R;
|
||||||
|
|
||||||
|
public class Objective3 extends Objective {
|
||||||
|
|
||||||
|
public Objective3() {
|
||||||
|
super(2, R.string.objectives_2_objective, R.string.objectives_2_gate);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.R;
|
||||||
|
import info.nightscout.androidaps.interfaces.Constraint;
|
||||||
|
import info.nightscout.androidaps.plugins.ConstraintsSafety.SafetyPlugin;
|
||||||
|
|
||||||
|
public class Objective4 extends Objective {
|
||||||
|
|
||||||
|
public Objective4() {
|
||||||
|
super(3, R.string.objectives_3_objective, R.string.objectives_3_gate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setupTasks(List<Task> tasks) {
|
||||||
|
tasks.add(new MinimumDurationTask(5L * 24L * 60L * 60L * 1000L));
|
||||||
|
tasks.add(new Task(R.string.closedmodeenabled) {
|
||||||
|
@Override
|
||||||
|
public boolean isCompleted() {
|
||||||
|
Constraint<Boolean> closedLoopEnabled = new Constraint<>(true);
|
||||||
|
SafetyPlugin.getPlugin().isClosedLoopAllowed(closedLoopEnabled);
|
||||||
|
return closedLoopEnabled.value();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.MainApp;
|
||||||
|
import info.nightscout.androidaps.R;
|
||||||
|
|
||||||
|
public class Objective5 extends Objective {
|
||||||
|
|
||||||
|
public Objective5() {
|
||||||
|
super(4, R.string.objectives_4_objective, R.string.objectives_4_gate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setupTasks(List<Task> tasks) {
|
||||||
|
tasks.add(new MinimumDurationTask(24L * 60L * 60L * 1000L));
|
||||||
|
tasks.add(new Task(R.string.maxiobset) {
|
||||||
|
@Override
|
||||||
|
public boolean isCompleted() {
|
||||||
|
double maxIOB = MainApp.getConstraintChecker().getMaxIOBAllowed().value();
|
||||||
|
return maxIOB > 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.R;
|
||||||
|
|
||||||
|
public class Objective6 extends Objective {
|
||||||
|
|
||||||
|
public Objective6() {
|
||||||
|
super(5, R.string.objectives_5_objective, R.string.objectives_5_gate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setupTasks(List<Task> tasks) {
|
||||||
|
tasks.add(new MinimumDurationTask(7L * 24L * 60L * 60L * 1000L));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.R;
|
||||||
|
|
||||||
|
public class Objective7 extends Objective {
|
||||||
|
|
||||||
|
public Objective7() {
|
||||||
|
super(6, R.string.objectives_6_objective, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setupTasks(List<Task> tasks) {
|
||||||
|
tasks.add(new MinimumDurationTask(28L * 24L * 60L * 60L * 1000L));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.R;
|
||||||
|
|
||||||
|
public class Objective8 extends Objective {
|
||||||
|
|
||||||
|
public Objective8() {
|
||||||
|
super(7, R.string.objectives_7_objective, R.string.objectives_7_gate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setupTasks(List<Task> tasks) {
|
||||||
|
tasks.add(new MinimumDurationTask(28L * 24L * 60L * 60L * 1000L));
|
||||||
|
}
|
||||||
|
}
|
|
@ -49,7 +49,7 @@ public class SafetyPlugin extends PluginBase implements ConstraintsInterface {
|
||||||
* Constraints interface
|
* Constraints interface
|
||||||
**/
|
**/
|
||||||
@Override
|
@Override
|
||||||
public Constraint<Boolean> isLoopInvokationAllowed(Constraint<Boolean> value) {
|
public Constraint<Boolean> isLoopInvocationAllowed(Constraint<Boolean> value) {
|
||||||
if (!ConfigBuilderPlugin.getActivePump().getPumpDescription().isTempBasalCapable)
|
if (!ConfigBuilderPlugin.getActivePump().getPumpDescription().isTempBasalCapable)
|
||||||
value.set(false, MainApp.gs(R.string.pumpisnottempbasalcapable), this);
|
value.set(false, MainApp.gs(R.string.pumpisnottempbasalcapable), this);
|
||||||
return value;
|
return value;
|
||||||
|
|
|
@ -26,6 +26,7 @@ public class FoodPlugin extends PluginBase {
|
||||||
.fragmentClass(FoodFragment.class.getName())
|
.fragmentClass(FoodFragment.class.getName())
|
||||||
.pluginName(R.string.food)
|
.pluginName(R.string.food)
|
||||||
.shortName(R.string.food_short)
|
.shortName(R.string.food_short)
|
||||||
|
.description(R.string.description_food)
|
||||||
);
|
);
|
||||||
this.service = new FoodService();
|
this.service = new FoodService();
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ public abstract class InsulinOrefBasePlugin extends PluginBase implements Insuli
|
||||||
.fragmentClass(InsulinFragment.class.getName())
|
.fragmentClass(InsulinFragment.class.getName())
|
||||||
.pluginName(R.string.fastactinginsulin)
|
.pluginName(R.string.fastactinginsulin)
|
||||||
.shortName(R.string.insulin_shortname)
|
.shortName(R.string.insulin_shortname)
|
||||||
|
.visibleByDefault(false)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,8 @@ public class InsulinOrefFreePeakPlugin extends InsulinOrefBasePlugin {
|
||||||
super();
|
super();
|
||||||
pluginDescription
|
pluginDescription
|
||||||
.pluginName(R.string.free_peak_oref)
|
.pluginName(R.string.free_peak_oref)
|
||||||
.preferencesId(R.xml.pref_insulinoreffreepeak);
|
.preferencesId(R.xml.pref_insulinoreffreepeak)
|
||||||
|
.description(R.string.description_insulin_free_peak);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -22,7 +22,8 @@ public class InsulinOrefRapidActingPlugin extends InsulinOrefBasePlugin {
|
||||||
private InsulinOrefRapidActingPlugin() {
|
private InsulinOrefRapidActingPlugin() {
|
||||||
super();
|
super();
|
||||||
pluginDescription
|
pluginDescription
|
||||||
.pluginName(R.string.rapid_acting_oref);
|
.pluginName(R.string.rapid_acting_oref)
|
||||||
|
.description(R.string.description_insulin_rapid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -22,7 +22,8 @@ public class InsulinOrefUltraRapidActingPlugin extends InsulinOrefBasePlugin {
|
||||||
private InsulinOrefUltraRapidActingPlugin() {
|
private InsulinOrefUltraRapidActingPlugin() {
|
||||||
super();
|
super();
|
||||||
pluginDescription
|
pluginDescription
|
||||||
.pluginName(R.string.ultrarapid_oref);
|
.pluginName(R.string.ultrarapid_oref)
|
||||||
|
.description(R.string.description_insulin_ultra_rapid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -16,8 +16,8 @@ import info.nightscout.androidaps.plugins.OpenAPSSMB.SMBDefaults;
|
||||||
import info.nightscout.androidaps.plugins.Overview.graphExtensions.DataPointWithLabelInterface;
|
import info.nightscout.androidaps.plugins.Overview.graphExtensions.DataPointWithLabelInterface;
|
||||||
import info.nightscout.androidaps.plugins.Overview.graphExtensions.PointsWithLabelGraphSeries;
|
import info.nightscout.androidaps.plugins.Overview.graphExtensions.PointsWithLabelGraphSeries;
|
||||||
import info.nightscout.androidaps.plugins.Overview.graphExtensions.Scale;
|
import info.nightscout.androidaps.plugins.Overview.graphExtensions.Scale;
|
||||||
import info.nightscout.androidaps.plugins.SensitivityAAPS.SensitivityAAPSPlugin;
|
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityAAPSPlugin;
|
||||||
import info.nightscout.androidaps.plugins.SensitivityWeightedAverage.SensitivityWeightedAveragePlugin;
|
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityWeightedAveragePlugin;
|
||||||
import info.nightscout.androidaps.plugins.Treatments.Treatment;
|
import info.nightscout.androidaps.plugins.Treatments.Treatment;
|
||||||
import info.nightscout.utils.SP;
|
import info.nightscout.utils.SP;
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ import info.nightscout.utils.SP;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class AutosensData implements DataPointWithLabelInterface {
|
public class AutosensData implements DataPointWithLabelInterface {
|
||||||
private static Logger log = LoggerFactory.getLogger(AutosensData.class);
|
private static Logger log = LoggerFactory.getLogger("AUTOSENS");
|
||||||
|
|
||||||
public void setChartTime(long chartTime) {
|
public void setChartTime(long chartTime) {
|
||||||
this.chartTime = chartTime;
|
this.chartTime = chartTime;
|
||||||
|
@ -56,11 +56,11 @@ public class AutosensData implements DataPointWithLabelInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
public long time = 0L;
|
public long time = 0L;
|
||||||
long chartTime;
|
public double bg = 0; // mgdl
|
||||||
|
private long chartTime;
|
||||||
public String pastSensitivity = "";
|
public String pastSensitivity = "";
|
||||||
public double deviation = 0d;
|
public double deviation = 0d;
|
||||||
boolean nonCarbsDeviation = false;
|
public boolean validDeviation = false;
|
||||||
public boolean nonEqualDeviation = false;
|
|
||||||
List<CarbsInPast> activeCarbsList = new ArrayList<>();
|
List<CarbsInPast> activeCarbsList = new ArrayList<>();
|
||||||
double absorbed = 0d;
|
double absorbed = 0d;
|
||||||
public double carbsFromBolus = 0d;
|
public double carbsFromBolus = 0d;
|
||||||
|
@ -70,15 +70,23 @@ public class AutosensData implements DataPointWithLabelInterface {
|
||||||
public double avgDelta = 0d;
|
public double avgDelta = 0d;
|
||||||
public double avgDeviation = 0d;
|
public double avgDeviation = 0d;
|
||||||
|
|
||||||
public double autosensRatio = 1d;
|
public AutosensResult autosensResult = new AutosensResult();
|
||||||
public double slopeFromMaxDeviation = 0;
|
public double slopeFromMaxDeviation = 0;
|
||||||
public double slopeFromMinDeviation = 999;
|
public double slopeFromMinDeviation = 999;
|
||||||
public double usedMinCarbsImpact = 0d;
|
public double usedMinCarbsImpact = 0d;
|
||||||
public boolean failoverToMinAbsorbtionRate = false;
|
public boolean failoverToMinAbsorbtionRate = false;
|
||||||
|
|
||||||
|
// Oref1
|
||||||
|
public boolean absorbing = false;
|
||||||
|
public double mealCarbs = 0;
|
||||||
|
public int mealStartCounter = 999;
|
||||||
|
public String type = "";
|
||||||
|
public boolean uam = false;
|
||||||
|
public List<Double> extraDeviation = new ArrayList<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "AutosensData: " + new Date(time).toLocaleString() + " " + pastSensitivity + " Delta=" + delta + " avgDelta=" + avgDelta + " Bgi=" + bgi + " Deviation=" + deviation + " avgDeviation=" + avgDeviation + " Absorbed=" + absorbed + " CarbsFromBolus=" + carbsFromBolus + " COB=" + cob + " autosensRatio=" + autosensRatio + " slopeFromMaxDeviation=" + slopeFromMaxDeviation + " slopeFromMinDeviation =" + slopeFromMinDeviation;
|
return "AutosensData: " + new Date(time).toLocaleString() + " " + pastSensitivity + " Delta=" + delta + " avgDelta=" + avgDelta + " Bgi=" + bgi + " Deviation=" + deviation + " avgDeviation=" + avgDeviation + " Absorbed=" + absorbed + " CarbsFromBolus=" + carbsFromBolus + " COB=" + cob + " autosensRatio=" + autosensResult.ratio + " slopeFromMaxDeviation=" + slopeFromMaxDeviation + " slopeFromMinDeviation=" + slopeFromMinDeviation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int minOld() {
|
public int minOld() {
|
||||||
|
|
|
@ -9,12 +9,12 @@ import org.slf4j.LoggerFactory;
|
||||||
* Created by mike on 06.01.2017.
|
* Created by mike on 06.01.2017.
|
||||||
*/
|
*/
|
||||||
public class AutosensResult {
|
public class AutosensResult {
|
||||||
private static Logger log = LoggerFactory.getLogger(AutosensResult.class);
|
private static Logger log = LoggerFactory.getLogger("AUTOSENS");
|
||||||
|
|
||||||
//default values to show when autosens algorithm is not called
|
//default values to show when autosens algorithm is not called
|
||||||
public double ratio = 1d;
|
public double ratio = 1d;
|
||||||
public double carbsAbsorbed = 0d;
|
public double carbsAbsorbed = 0d;
|
||||||
public String sensResult = "autosens deactivated";
|
public String sensResult = "autosens not available";
|
||||||
public String pastSensitivity = "";
|
public String pastSensitivity = "";
|
||||||
public String ratioLimit = "";
|
public String ratioLimit = "";
|
||||||
|
|
||||||
|
@ -32,4 +32,8 @@ public class AutosensResult {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return json().toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,9 +35,11 @@ import info.nightscout.androidaps.interfaces.PluginType;
|
||||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||||
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventNewHistoryData;
|
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventNewHistoryData;
|
||||||
import info.nightscout.androidaps.plugins.OpenAPSSMB.OpenAPSSMBPlugin;
|
import info.nightscout.androidaps.plugins.OpenAPSSMB.OpenAPSSMBPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityOref1Plugin;
|
||||||
import info.nightscout.androidaps.plugins.Treatments.Treatment;
|
import info.nightscout.androidaps.plugins.Treatments.Treatment;
|
||||||
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.utils.DateUtil;
|
import info.nightscout.utils.DateUtil;
|
||||||
|
import info.nightscout.utils.T;
|
||||||
|
|
||||||
import static info.nightscout.utils.DateUtil.now;
|
import static info.nightscout.utils.DateUtil.now;
|
||||||
|
|
||||||
|
@ -46,7 +48,7 @@ import static info.nightscout.utils.DateUtil.now;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class IobCobCalculatorPlugin extends PluginBase {
|
public class IobCobCalculatorPlugin extends PluginBase {
|
||||||
private Logger log = LoggerFactory.getLogger(IobCobCalculatorPlugin.class);
|
private Logger log = LoggerFactory.getLogger("AUTOSENS");
|
||||||
|
|
||||||
private static IobCobCalculatorPlugin plugin = null;
|
private static IobCobCalculatorPlugin plugin = null;
|
||||||
|
|
||||||
|
@ -68,7 +70,7 @@ public class IobCobCalculatorPlugin extends PluginBase {
|
||||||
final Object dataLock = new Object();
|
final Object dataLock = new Object();
|
||||||
|
|
||||||
boolean stopCalculationTrigger = false;
|
boolean stopCalculationTrigger = false;
|
||||||
private IobCobThread thread = null;
|
private Thread thread = null;
|
||||||
|
|
||||||
public IobCobCalculatorPlugin() {
|
public IobCobCalculatorPlugin() {
|
||||||
super(new PluginDescription()
|
super(new PluginDescription()
|
||||||
|
@ -130,11 +132,15 @@ public class IobCobCalculatorPlugin extends PluginBase {
|
||||||
public static long roundUpTime(long time) {
|
public static long roundUpTime(long time) {
|
||||||
if (time % 60000 == 0)
|
if (time % 60000 == 0)
|
||||||
return time;
|
return time;
|
||||||
long rouded = (time / 60000 + 1) * 60000;
|
long rounded = (time / 60000 + 1) * 60000;
|
||||||
return rouded;
|
return rounded;
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadBgData(long start) {
|
void loadBgData(long start) {
|
||||||
|
if (start < oldestDataAvailable()) {
|
||||||
|
start = oldestDataAvailable();
|
||||||
|
log.debug("Limiting BG data to oldest data available: " + DateUtil.dateAndTimeString(start));
|
||||||
|
}
|
||||||
bgReadings = MainApp.getDbHelper().getBgreadingsDataFromTime((long) (start - 60 * 60 * 1000L * (24 + dia)), false);
|
bgReadings = MainApp.getDbHelper().getBgreadingsDataFromTime((long) (start - 60 * 60 * 1000L * (24 + dia)), false);
|
||||||
log.debug("BG data loaded. Size: " + bgReadings.size() + " Start date: " + DateUtil.dateAndTimeString(start));
|
log.debug("BG data loaded. Size: " + bgReadings.size() + " Start date: " + DateUtil.dateAndTimeString(start));
|
||||||
}
|
}
|
||||||
|
@ -292,7 +298,7 @@ public class IobCobCalculatorPlugin extends PluginBase {
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
|
|
||||||
long oldestDataAvailable = TreatmentsPlugin.getPlugin().oldestDataAvailable();
|
long oldestDataAvailable = TreatmentsPlugin.getPlugin().oldestDataAvailable();
|
||||||
long getBGDataFrom = Math.max(oldestDataAvailable, (long) (now - 60 * 60 * 1000L * (24 + MainApp.getConfigBuilder().getProfile().getDia())));
|
long getBGDataFrom = Math.max(oldestDataAvailable, (long) (now - T.hours(1).msecs() * (24 + MainApp.getConfigBuilder().getProfile().getDia())));
|
||||||
log.debug("Limiting data to oldest available temps: " + new Date(oldestDataAvailable).toString());
|
log.debug("Limiting data to oldest available temps: " + new Date(oldestDataAvailable).toString());
|
||||||
return getBGDataFrom;
|
return getBGDataFrom;
|
||||||
}
|
}
|
||||||
|
@ -347,13 +353,12 @@ public class IobCobCalculatorPlugin extends PluginBase {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BasalData getBasalData(long time) {
|
public BasalData getBasalData(Profile profile, long time) {
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
time = roundUpTime(time);
|
time = roundUpTime(time);
|
||||||
BasalData retval = basalDataTable.get(time);
|
BasalData retval = basalDataTable.get(time);
|
||||||
if (retval == null) {
|
if (retval == null) {
|
||||||
retval = new BasalData();
|
retval = new BasalData();
|
||||||
Profile profile = MainApp.getConfigBuilder().getProfile(time);
|
|
||||||
TemporaryBasal tb = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(time);
|
TemporaryBasal tb = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(time);
|
||||||
retval.basal = profile.getBasal(time);
|
retval.basal = profile.getBasal(time);
|
||||||
if (tb != null) {
|
if (tb != null) {
|
||||||
|
@ -377,22 +382,20 @@ public class IobCobCalculatorPlugin extends PluginBase {
|
||||||
public AutosensData getAutosensData(long time) {
|
public AutosensData getAutosensData(long time) {
|
||||||
synchronized (dataLock) {
|
synchronized (dataLock) {
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
if (time > now)
|
if (time > now) {
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
Long previous = findPreviousTimeFromBucketedData(time);
|
Long previous = findPreviousTimeFromBucketedData(time);
|
||||||
if (previous == null)
|
if (previous == null) {
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
time = roundUpTime(previous);
|
time = roundUpTime(previous);
|
||||||
AutosensData data = autosensDataTable.get(time);
|
AutosensData data = autosensDataTable.get(time);
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
//log.debug(">>> getAutosensData Cache hit " + data.log(time));
|
//log.debug(">>> AUTOSENSDATA Cache hit " + data.toString());
|
||||||
return data;
|
return data;
|
||||||
} else {
|
} else {
|
||||||
if (time > now) {
|
//log.debug(">>> AUTOSENSDATA Cache miss " + new Date(time).toLocaleString());
|
||||||
// data may not be calculated yet, use last data
|
|
||||||
return getLastAutosensData("getAutosensData");
|
|
||||||
}
|
|
||||||
//log.debug(">>> getAutosensData Cache miss " + new Date(time).toLocaleString());
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -400,6 +403,14 @@ public class IobCobCalculatorPlugin extends PluginBase {
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public AutosensData getLastAutosensDataSynchronized(String reason) {
|
public AutosensData getLastAutosensDataSynchronized(String reason) {
|
||||||
|
if (thread != null && thread.isAlive()) {
|
||||||
|
log.debug("AUTOSENSDATA is waiting for calculation thread: " + reason);
|
||||||
|
try {
|
||||||
|
thread.join(5000);
|
||||||
|
} catch (InterruptedException ignored) {
|
||||||
|
}
|
||||||
|
log.debug("AUTOSENSDATA finished waiting for calculation thread: " + reason);
|
||||||
|
}
|
||||||
synchronized (dataLock) {
|
synchronized (dataLock) {
|
||||||
return getLastAutosensData(reason);
|
return getLastAutosensData(reason);
|
||||||
}
|
}
|
||||||
|
@ -453,10 +464,18 @@ public class IobCobCalculatorPlugin extends PluginBase {
|
||||||
log.debug("AUTOSENSDATA null: data is old (" + reason + ") size()=" + autosensDataTable.size() + " lastdata=" + DateUtil.dateAndTimeString(data.time));
|
log.debug("AUTOSENSDATA null: data is old (" + reason + ") size()=" + autosensDataTable.size() + " lastdata=" + DateUtil.dateAndTimeString(data.time));
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
|
log.debug("AUTOSENSDATA (" + reason + ") " + data.toString());
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String lastDataTime() {
|
||||||
|
if (autosensDataTable.size() > 0)
|
||||||
|
return DateUtil.dateAndTimeString(autosensDataTable.valueAt(autosensDataTable.size() - 1).time);
|
||||||
|
else
|
||||||
|
return "autosensDataTable empty";
|
||||||
|
}
|
||||||
|
|
||||||
public IobTotal[] calculateIobArrayInDia(Profile profile) {
|
public IobTotal[] calculateIobArrayInDia(Profile profile) {
|
||||||
// predict IOB out to DIA plus 30m
|
// predict IOB out to DIA plus 30m
|
||||||
long time = System.currentTimeMillis();
|
long time = System.currentTimeMillis();
|
||||||
|
@ -491,14 +510,10 @@ public class IobCobCalculatorPlugin extends PluginBase {
|
||||||
|
|
||||||
public AutosensResult detectSensitivityWithLock(long fromTime, long toTime) {
|
public AutosensResult detectSensitivityWithLock(long fromTime, long toTime) {
|
||||||
synchronized (dataLock) {
|
synchronized (dataLock) {
|
||||||
return detectSensitivity(fromTime, toTime);
|
return ConfigBuilderPlugin.getActiveSensitivity().detectSensitivity(fromTime, toTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static AutosensResult detectSensitivity(long fromTime, long toTime) {
|
|
||||||
return ConfigBuilderPlugin.getActiveSensitivity().detectSensitivity(fromTime, toTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static JSONArray convertToJSONArray(IobTotal[] iobArray) {
|
public static JSONArray convertToJSONArray(IobTotal[] iobArray) {
|
||||||
JSONArray array = new JSONArray();
|
JSONArray array = new JSONArray();
|
||||||
for (int i = 0; i < iobArray.length; i++) {
|
for (int i = 0; i < iobArray.length; i++) {
|
||||||
|
@ -542,7 +557,10 @@ public class IobCobCalculatorPlugin extends PluginBase {
|
||||||
public void runCalculation(String from, long start, boolean bgDataReload, Event cause) {
|
public void runCalculation(String from, long start, boolean bgDataReload, Event cause) {
|
||||||
log.debug("Starting calculation thread: " + from);
|
log.debug("Starting calculation thread: " + from);
|
||||||
if (thread == null || thread.getState() == Thread.State.TERMINATED) {
|
if (thread == null || thread.getState() == Thread.State.TERMINATED) {
|
||||||
thread = new IobCobThread(this, from, start, bgDataReload, cause);
|
if (SensitivityOref1Plugin.getPlugin().isEnabled(PluginType.SENSITIVITY))
|
||||||
|
thread = new IobCobOref1Thread(this, from, start, bgDataReload, cause);
|
||||||
|
else
|
||||||
|
thread = new IobCobThread(this, from, start, bgDataReload, cause);
|
||||||
thread.start();
|
thread.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -581,7 +599,9 @@ public class IobCobCalculatorPlugin extends PluginBase {
|
||||||
ev.isChanged(R.string.key_age) ||
|
ev.isChanged(R.string.key_age) ||
|
||||||
ev.isChanged(R.string.key_absorption_maxtime) ||
|
ev.isChanged(R.string.key_absorption_maxtime) ||
|
||||||
ev.isChanged(R.string.key_openapsama_min_5m_carbimpact) ||
|
ev.isChanged(R.string.key_openapsama_min_5m_carbimpact) ||
|
||||||
ev.isChanged(R.string.key_absorption_cutoff)
|
ev.isChanged(R.string.key_absorption_cutoff) ||
|
||||||
|
ev.isChanged(R.string.key_openapsama_autosens_max) ||
|
||||||
|
ev.isChanged(R.string.key_openapsama_autosens_min)
|
||||||
) {
|
) {
|
||||||
stopCalculation("onEventPreferenceChange");
|
stopCalculation("onEventPreferenceChange");
|
||||||
synchronized (dataLock) {
|
synchronized (dataLock) {
|
||||||
|
|
|
@ -0,0 +1,362 @@
|
||||||
|
package info.nightscout.androidaps.plugins.IobCobCalculator;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.PowerManager;
|
||||||
|
import android.os.SystemClock;
|
||||||
|
import android.support.v4.util.LongSparseArray;
|
||||||
|
|
||||||
|
import com.crashlytics.android.answers.CustomEvent;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.GregorianCalendar;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.BuildConfig;
|
||||||
|
import info.nightscout.androidaps.Config;
|
||||||
|
import info.nightscout.androidaps.Constants;
|
||||||
|
import info.nightscout.androidaps.MainApp;
|
||||||
|
import info.nightscout.androidaps.R;
|
||||||
|
import info.nightscout.androidaps.data.IobTotal;
|
||||||
|
import info.nightscout.androidaps.data.Profile;
|
||||||
|
import info.nightscout.androidaps.db.BgReading;
|
||||||
|
import info.nightscout.androidaps.db.TempTarget;
|
||||||
|
import info.nightscout.androidaps.events.Event;
|
||||||
|
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished;
|
||||||
|
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventIobCalculationProgress;
|
||||||
|
import info.nightscout.androidaps.plugins.OpenAPSSMB.SMBDefaults;
|
||||||
|
import info.nightscout.androidaps.plugins.Treatments.Treatment;
|
||||||
|
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||||
|
import info.nightscout.utils.DateUtil;
|
||||||
|
import info.nightscout.utils.FabricPrivacy;
|
||||||
|
import info.nightscout.utils.SP;
|
||||||
|
|
||||||
|
import static info.nightscout.utils.DateUtil.now;
|
||||||
|
import static java.util.Calendar.MINUTE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mike on 23.01.2018.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class IobCobOref1Thread extends Thread {
|
||||||
|
private static Logger log = LoggerFactory.getLogger("AUTOSENS");
|
||||||
|
private final Event cause;
|
||||||
|
|
||||||
|
private IobCobCalculatorPlugin iobCobCalculatorPlugin;
|
||||||
|
private boolean bgDataReload;
|
||||||
|
private String from;
|
||||||
|
private long start;
|
||||||
|
|
||||||
|
private PowerManager.WakeLock mWakeLock;
|
||||||
|
|
||||||
|
public IobCobOref1Thread(IobCobCalculatorPlugin plugin, String from, long start, boolean bgDataReload, Event cause) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.iobCobCalculatorPlugin = plugin;
|
||||||
|
this.bgDataReload = bgDataReload;
|
||||||
|
this.from = from;
|
||||||
|
this.cause = cause;
|
||||||
|
this.start = start;
|
||||||
|
|
||||||
|
PowerManager powerManager = (PowerManager) MainApp.instance().getApplicationContext().getSystemService(Context.POWER_SERVICE);
|
||||||
|
mWakeLock = powerManager.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "iobCobThread");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void run() {
|
||||||
|
mWakeLock.acquire();
|
||||||
|
try {
|
||||||
|
log.debug("AUTOSENSDATA thread started: " + from);
|
||||||
|
if (MainApp.getConfigBuilder() == null) {
|
||||||
|
log.debug("Aborting calculation thread (ConfigBuilder not ready): " + from);
|
||||||
|
return; // app still initializing
|
||||||
|
}
|
||||||
|
if (!MainApp.getConfigBuilder().isProfileValid("IobCobThread")) {
|
||||||
|
log.debug("Aborting calculation thread (No profile): " + from);
|
||||||
|
return; // app still initializing
|
||||||
|
}
|
||||||
|
//log.debug("Locking calculateSensitivityData");
|
||||||
|
|
||||||
|
long oldestTimeWithData = iobCobCalculatorPlugin.oldestDataAvailable();
|
||||||
|
|
||||||
|
synchronized (iobCobCalculatorPlugin.dataLock) {
|
||||||
|
if (bgDataReload) {
|
||||||
|
iobCobCalculatorPlugin.loadBgData(start);
|
||||||
|
iobCobCalculatorPlugin.createBucketedData();
|
||||||
|
}
|
||||||
|
List<BgReading> bucketed_data = iobCobCalculatorPlugin.getBucketedData();
|
||||||
|
LongSparseArray<AutosensData> autosensDataTable = IobCobCalculatorPlugin.getPlugin().getAutosensDataTable();
|
||||||
|
|
||||||
|
if (bucketed_data == null || bucketed_data.size() < 3) {
|
||||||
|
log.debug("Aborting calculation thread (No bucketed data available): " + from);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
long prevDataTime = IobCobCalculatorPlugin.roundUpTime(bucketed_data.get(bucketed_data.size() - 3).date);
|
||||||
|
log.debug("Prev data time: " + new Date(prevDataTime).toLocaleString());
|
||||||
|
AutosensData previous = autosensDataTable.get(prevDataTime);
|
||||||
|
// start from oldest to be able sub cob
|
||||||
|
for (int i = bucketed_data.size() - 4; i >= 0; i--) {
|
||||||
|
String progress = i + (MainApp.isDev() ? " (" + from + ")" : "");
|
||||||
|
MainApp.bus().post(new EventIobCalculationProgress(progress));
|
||||||
|
|
||||||
|
if (iobCobCalculatorPlugin.stopCalculationTrigger) {
|
||||||
|
iobCobCalculatorPlugin.stopCalculationTrigger = false;
|
||||||
|
log.debug("Aborting calculation thread (trigger): " + from);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// check if data already exists
|
||||||
|
long bgTime = bucketed_data.get(i).date;
|
||||||
|
bgTime = IobCobCalculatorPlugin.roundUpTime(bgTime);
|
||||||
|
if (bgTime > IobCobCalculatorPlugin.roundUpTime(now()))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
AutosensData existing;
|
||||||
|
if ((existing = autosensDataTable.get(bgTime)) != null) {
|
||||||
|
previous = existing;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Profile profile = MainApp.getConfigBuilder().getProfile(bgTime);
|
||||||
|
if (profile == null) {
|
||||||
|
log.debug("Aborting calculation thread (no profile): " + from);
|
||||||
|
return; // profile not set yet
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Config.logAutosensData)
|
||||||
|
log.debug("Processing calculation thread: " + from + " (" + i + "/" + bucketed_data.size() + ")");
|
||||||
|
|
||||||
|
double sens = Profile.toMgdl(profile.getIsf(bgTime), profile.getUnits());
|
||||||
|
|
||||||
|
AutosensData autosensData = new AutosensData();
|
||||||
|
autosensData.time = bgTime;
|
||||||
|
if (previous != null)
|
||||||
|
autosensData.activeCarbsList = new ArrayList<>(previous.activeCarbsList);
|
||||||
|
else
|
||||||
|
autosensData.activeCarbsList = new ArrayList<>();
|
||||||
|
|
||||||
|
//console.error(bgTime , bucketed_data[i].glucose);
|
||||||
|
double bg;
|
||||||
|
double avgDelta;
|
||||||
|
double delta;
|
||||||
|
bg = bucketed_data.get(i).value;
|
||||||
|
if (bg < 39 || bucketed_data.get(i + 3).value < 39) {
|
||||||
|
log.error("! value < 39");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
autosensData.bg = bg;
|
||||||
|
delta = (bg - bucketed_data.get(i + 1).value);
|
||||||
|
avgDelta = (bg - bucketed_data.get(i + 3).value) / 3;
|
||||||
|
|
||||||
|
IobTotal iob = iobCobCalculatorPlugin.calculateFromTreatmentsAndTemps(bgTime, profile);
|
||||||
|
|
||||||
|
double bgi = -iob.activity * sens * 5;
|
||||||
|
double deviation = delta - bgi;
|
||||||
|
double avgDeviation = Math.round((avgDelta - bgi) * 1000) / 1000;
|
||||||
|
|
||||||
|
double slopeFromMaxDeviation = 0;
|
||||||
|
double slopeFromMinDeviation = 999;
|
||||||
|
double maxDeviation = 0;
|
||||||
|
double minDeviation = 999;
|
||||||
|
|
||||||
|
// https://github.com/openaps/oref0/blob/master/lib/determine-basal/cob-autosens.js#L169
|
||||||
|
if (i < bucketed_data.size() - 16) { // we need 1h of data to calculate minDeviationSlope
|
||||||
|
long hourago = bgTime + 10 * 1000 - 60 * 60 * 1000L;
|
||||||
|
AutosensData hourAgoData = IobCobCalculatorPlugin.getPlugin().getAutosensData(hourago);
|
||||||
|
if (hourAgoData != null) {
|
||||||
|
int initialIndex = autosensDataTable.indexOfKey(hourAgoData.time);
|
||||||
|
if (Config.logAutosensData)
|
||||||
|
log.debug(">>>>> bucketed_data.size()=" + bucketed_data.size() + " i=" + i + "hourAgoData=" + hourAgoData.toString());
|
||||||
|
int past = 1;
|
||||||
|
try {
|
||||||
|
for (; past < 12; past++) {
|
||||||
|
AutosensData ad = autosensDataTable.valueAt(initialIndex + past);
|
||||||
|
double deviationSlope = (ad.avgDeviation - avgDeviation) / (ad.time - bgTime) * 1000 * 60 * 5;
|
||||||
|
if (ad.avgDeviation > maxDeviation) {
|
||||||
|
slopeFromMaxDeviation = Math.min(0, deviationSlope);
|
||||||
|
maxDeviation = ad.avgDeviation;
|
||||||
|
}
|
||||||
|
if (ad.avgDeviation < minDeviation) {
|
||||||
|
slopeFromMinDeviation = Math.max(0, deviationSlope);
|
||||||
|
minDeviation = ad.avgDeviation;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (Config.logAutosensData)
|
||||||
|
// log.debug("Deviations: " + new Date(bgTime) + new Date(ad.time) + " avgDeviation=" + avgDeviation + " deviationSlope=" + deviationSlope + " slopeFromMaxDeviation=" + slopeFromMaxDeviation + " slopeFromMinDeviation=" + slopeFromMinDeviation);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Unhandled exception", e);
|
||||||
|
FabricPrivacy.logException(e);
|
||||||
|
FabricPrivacy.getInstance().logCustom(new CustomEvent("CatchedError")
|
||||||
|
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
|
||||||
|
.putCustomAttribute("version", BuildConfig.VERSION)
|
||||||
|
.putCustomAttribute("autosensDataTable", iobCobCalculatorPlugin.getAutosensDataTable().toString())
|
||||||
|
.putCustomAttribute("for_data", ">>>>> bucketed_data.size()=" + bucketed_data.size() + " i=" + i + "hourAgoData=" + hourAgoData.toString())
|
||||||
|
.putCustomAttribute("past", past)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Treatment> recentTreatments = TreatmentsPlugin.getPlugin().getTreatments5MinBackFromHistory(bgTime);
|
||||||
|
for (int ir = 0; ir < recentTreatments.size(); ir++) {
|
||||||
|
autosensData.carbsFromBolus += recentTreatments.get(ir).carbs;
|
||||||
|
autosensData.activeCarbsList.add(new AutosensData.CarbsInPast(recentTreatments.get(ir)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// if we are absorbing carbs
|
||||||
|
if (previous != null && previous.cob > 0) {
|
||||||
|
// calculate sum of min carb impact from all active treatments
|
||||||
|
double totalMinCarbsImpact = 0d;
|
||||||
|
// if (SensitivityAAPSPlugin.getPlugin().isEnabled(PluginType.SENSITIVITY) || SensitivityWeightedAveragePlugin.getPlugin().isEnabled(PluginType.SENSITIVITY)) {
|
||||||
|
//when the impact depends on a max time, sum them up as smaller carb sizes make them smaller
|
||||||
|
// for (int ii = 0; ii < autosensData.activeCarbsList.size(); ++ii) {
|
||||||
|
// AutosensData.CarbsInPast c = autosensData.activeCarbsList.get(ii);
|
||||||
|
// totalMinCarbsImpact += c.min5minCarbImpact;
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
//Oref sensitivity
|
||||||
|
totalMinCarbsImpact = SP.getDouble(R.string.key_openapsama_min_5m_carbimpact, SMBDefaults.min_5m_carbimpact);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// figure out how many carbs that represents
|
||||||
|
// but always assume at least 3mg/dL/5m (default) absorption per active treatment
|
||||||
|
double ci = Math.max(deviation, totalMinCarbsImpact);
|
||||||
|
if (ci != deviation)
|
||||||
|
autosensData.failoverToMinAbsorbtionRate = true;
|
||||||
|
autosensData.absorbed = ci * profile.getIc(bgTime) / sens;
|
||||||
|
// and add that to the running total carbsAbsorbed
|
||||||
|
autosensData.cob = Math.max(previous.cob - autosensData.absorbed, 0d);
|
||||||
|
autosensData.mealCarbs = previous.mealCarbs;
|
||||||
|
autosensData.substractAbosorbedCarbs();
|
||||||
|
autosensData.usedMinCarbsImpact = totalMinCarbsImpact;
|
||||||
|
autosensData.absorbing = previous.absorbing;
|
||||||
|
autosensData.mealStartCounter = previous.mealStartCounter;
|
||||||
|
autosensData.type = previous.type;
|
||||||
|
autosensData.uam = previous.uam;
|
||||||
|
}
|
||||||
|
|
||||||
|
autosensData.removeOldCarbs(bgTime);
|
||||||
|
autosensData.cob += autosensData.carbsFromBolus;
|
||||||
|
autosensData.mealCarbs += autosensData.carbsFromBolus;
|
||||||
|
autosensData.deviation = deviation;
|
||||||
|
autosensData.bgi = bgi;
|
||||||
|
autosensData.delta = delta;
|
||||||
|
autosensData.avgDelta = avgDelta;
|
||||||
|
autosensData.avgDeviation = avgDeviation;
|
||||||
|
autosensData.slopeFromMaxDeviation = slopeFromMaxDeviation;
|
||||||
|
autosensData.slopeFromMinDeviation = slopeFromMinDeviation;
|
||||||
|
|
||||||
|
|
||||||
|
// If mealCOB is zero but all deviations since hitting COB=0 are positive, exclude from autosens
|
||||||
|
if (autosensData.cob > 0 || autosensData.absorbing || autosensData.mealCarbs > 0) {
|
||||||
|
if (deviation > 0)
|
||||||
|
autosensData.absorbing = true;
|
||||||
|
else
|
||||||
|
autosensData.absorbing = false;
|
||||||
|
// stop excluding positive deviations as soon as mealCOB=0 if meal has been absorbing for >5h
|
||||||
|
if (autosensData.mealStartCounter > 60 && autosensData.cob < 0.5) {
|
||||||
|
autosensData.absorbing = false;
|
||||||
|
}
|
||||||
|
if (!autosensData.absorbing && autosensData.cob < 0.5) {
|
||||||
|
autosensData.mealCarbs = 0;
|
||||||
|
}
|
||||||
|
// check previous "type" value, and if it wasn't csf, set a mealAbsorption start flag
|
||||||
|
if (!autosensData.type.equals("csf")) {
|
||||||
|
// process.stderr.write("(");
|
||||||
|
autosensData.mealStartCounter = 0;
|
||||||
|
}
|
||||||
|
autosensData.mealStartCounter++;
|
||||||
|
autosensData.type = "csf";
|
||||||
|
} else {
|
||||||
|
// check previous "type" value, and if it was csf, set a mealAbsorption end flag
|
||||||
|
if (autosensData.type.equals("csf")) {
|
||||||
|
// process.stderr.write(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
double currentBasal = profile.getBasal(bgTime);
|
||||||
|
// always exclude the first 45m after each carb entry
|
||||||
|
//if (iob.iob > currentBasal || uam ) {
|
||||||
|
if (iob.iob > 2 * currentBasal || autosensData.uam || autosensData.mealStartCounter < 9) {
|
||||||
|
autosensData.mealStartCounter++;
|
||||||
|
if (deviation > 0)
|
||||||
|
autosensData.uam = true;
|
||||||
|
else
|
||||||
|
autosensData.uam = false;
|
||||||
|
if (!autosensData.type.equals("uam")) {
|
||||||
|
// process.stderr.write("u(");
|
||||||
|
}
|
||||||
|
autosensData.type = "uam";
|
||||||
|
} else {
|
||||||
|
if (autosensData.type.equals("uam")) {
|
||||||
|
// process.stderr.write(")");
|
||||||
|
}
|
||||||
|
autosensData.type = "non-meal";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exclude meal-related deviations (carb absorption) from autosens
|
||||||
|
if (autosensData.type.equals("non-meal")) {
|
||||||
|
if (Math.abs(deviation) < Constants.DEVIATION_TO_BE_EQUAL) {
|
||||||
|
autosensData.pastSensitivity = "=";
|
||||||
|
autosensData.validDeviation = true;
|
||||||
|
} else if (deviation > 0) {
|
||||||
|
autosensData.pastSensitivity = "+";
|
||||||
|
autosensData.validDeviation = true;
|
||||||
|
} else {
|
||||||
|
autosensData.pastSensitivity = "-";
|
||||||
|
autosensData.validDeviation = true;
|
||||||
|
}
|
||||||
|
} else if (autosensData.type.equals("uam")) {
|
||||||
|
autosensData.pastSensitivity = "u";
|
||||||
|
} else {
|
||||||
|
autosensData.pastSensitivity = "x";
|
||||||
|
}
|
||||||
|
//log.debug("TIME: " + new Date(bgTime).toString() + " BG: " + bg + " SENS: " + sens + " DELTA: " + delta + " AVGDELTA: " + avgDelta + " IOB: " + iob.iob + " ACTIVITY: " + iob.activity + " BGI: " + bgi + " DEVIATION: " + deviation);
|
||||||
|
|
||||||
|
// add an extra negative deviation if a high temptarget is running and exercise mode is set
|
||||||
|
if (SP.getBoolean(R.string.key_high_temptarget_raises_sensitivity, SMBDefaults.high_temptarget_raises_sensitivity)) {
|
||||||
|
TempTarget tempTarget = TreatmentsPlugin.getPlugin().getTempTargetFromHistory(bgTime);
|
||||||
|
if (tempTarget != null && tempTarget.target() >= 100) {
|
||||||
|
autosensData.extraDeviation.add(-(tempTarget.target() - 100) / 20);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add one neutral deviation every 2 hours to help decay over long exclusion periods
|
||||||
|
GregorianCalendar calendar = new GregorianCalendar();
|
||||||
|
calendar.setTimeInMillis(bgTime);
|
||||||
|
int min = calendar.get(MINUTE);
|
||||||
|
int hours = calendar.get(Calendar.HOUR_OF_DAY);
|
||||||
|
if (min >= 0 && min < 5 && hours % 2 == 0)
|
||||||
|
autosensData.extraDeviation.add(0d);
|
||||||
|
|
||||||
|
previous = autosensData;
|
||||||
|
if (bgTime < now())
|
||||||
|
autosensDataTable.put(bgTime, autosensData);
|
||||||
|
if (Config.logAutosensData)
|
||||||
|
log.debug("Running detectSensitivity from: " + DateUtil.dateAndTimeString(oldestTimeWithData) + " to: " + DateUtil.dateAndTimeString(bgTime) + " lastDataTime:" + IobCobCalculatorPlugin.getPlugin().lastDataTime());
|
||||||
|
AutosensResult sensitivity = iobCobCalculatorPlugin.detectSensitivityWithLock(oldestTimeWithData, bgTime);
|
||||||
|
if (Config.logAutosensData)
|
||||||
|
log.debug("Sensitivity result: " + sensitivity.toString());
|
||||||
|
autosensData.autosensResult = sensitivity;
|
||||||
|
if (Config.logAutosensData)
|
||||||
|
log.debug(autosensData.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
new Thread(() -> {
|
||||||
|
SystemClock.sleep(1000);
|
||||||
|
MainApp.bus().post(new EventAutosensCalculationFinished(cause));
|
||||||
|
}).start();
|
||||||
|
} finally {
|
||||||
|
mWakeLock.release();
|
||||||
|
MainApp.bus().post(new EventIobCalculationProgress(""));
|
||||||
|
log.debug("AUTOSENSDATA thread ended: " + from);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2,6 +2,7 @@ package info.nightscout.androidaps.plugins.IobCobCalculator;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
|
import android.os.SystemClock;
|
||||||
import android.support.v4.util.LongSparseArray;
|
import android.support.v4.util.LongSparseArray;
|
||||||
|
|
||||||
import com.crashlytics.android.answers.CustomEvent;
|
import com.crashlytics.android.answers.CustomEvent;
|
||||||
|
@ -26,8 +27,8 @@ import info.nightscout.androidaps.interfaces.PluginType;
|
||||||
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished;
|
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished;
|
||||||
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventIobCalculationProgress;
|
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventIobCalculationProgress;
|
||||||
import info.nightscout.androidaps.plugins.OpenAPSSMB.SMBDefaults;
|
import info.nightscout.androidaps.plugins.OpenAPSSMB.SMBDefaults;
|
||||||
import info.nightscout.androidaps.plugins.SensitivityAAPS.SensitivityAAPSPlugin;
|
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityAAPSPlugin;
|
||||||
import info.nightscout.androidaps.plugins.SensitivityWeightedAverage.SensitivityWeightedAveragePlugin;
|
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityWeightedAveragePlugin;
|
||||||
import info.nightscout.androidaps.plugins.Treatments.Treatment;
|
import info.nightscout.androidaps.plugins.Treatments.Treatment;
|
||||||
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.utils.DateUtil;
|
import info.nightscout.utils.DateUtil;
|
||||||
|
@ -41,7 +42,7 @@ import static info.nightscout.utils.DateUtil.now;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class IobCobThread extends Thread {
|
public class IobCobThread extends Thread {
|
||||||
private static Logger log = LoggerFactory.getLogger(IobCobThread.class);
|
private static Logger log = LoggerFactory.getLogger("AUTOSENS");
|
||||||
private final Event cause;
|
private final Event cause;
|
||||||
|
|
||||||
private IobCobCalculatorPlugin iobCobCalculatorPlugin;
|
private IobCobCalculatorPlugin iobCobCalculatorPlugin;
|
||||||
|
@ -68,6 +69,7 @@ public class IobCobThread extends Thread {
|
||||||
public final void run() {
|
public final void run() {
|
||||||
mWakeLock.acquire();
|
mWakeLock.acquire();
|
||||||
try {
|
try {
|
||||||
|
log.debug("AUTOSENSDATA thread started: " + from);
|
||||||
if (MainApp.getConfigBuilder() == null) {
|
if (MainApp.getConfigBuilder() == null) {
|
||||||
log.debug("Aborting calculation thread (ConfigBuilder not ready): " + from);
|
log.debug("Aborting calculation thread (ConfigBuilder not ready): " + from);
|
||||||
return; // app still initializing
|
return; // app still initializing
|
||||||
|
@ -145,6 +147,7 @@ public class IobCobThread extends Thread {
|
||||||
log.error("! value < 39");
|
log.error("! value < 39");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
autosensData.bg = bg;
|
||||||
delta = (bg - bucketed_data.get(i + 1).value);
|
delta = (bg - bucketed_data.get(i + 1).value);
|
||||||
avgDelta = (bg - bucketed_data.get(i + 3).value) / 3;
|
avgDelta = (bg - bucketed_data.get(i + 3).value) / 3;
|
||||||
|
|
||||||
|
@ -245,35 +248,41 @@ public class IobCobThread extends Thread {
|
||||||
// calculate autosens only without COB
|
// calculate autosens only without COB
|
||||||
if (autosensData.cob <= 0) {
|
if (autosensData.cob <= 0) {
|
||||||
if (Math.abs(deviation) < Constants.DEVIATION_TO_BE_EQUAL) {
|
if (Math.abs(deviation) < Constants.DEVIATION_TO_BE_EQUAL) {
|
||||||
autosensData.pastSensitivity += "=";
|
autosensData.pastSensitivity = "=";
|
||||||
autosensData.nonEqualDeviation = true;
|
autosensData.validDeviation = true;
|
||||||
} else if (deviation > 0) {
|
} else if (deviation > 0) {
|
||||||
autosensData.pastSensitivity += "+";
|
autosensData.pastSensitivity = "+";
|
||||||
autosensData.nonEqualDeviation = true;
|
autosensData.validDeviation = true;
|
||||||
} else {
|
} else {
|
||||||
autosensData.pastSensitivity += "-";
|
autosensData.pastSensitivity = "-";
|
||||||
autosensData.nonEqualDeviation = true;
|
autosensData.validDeviation = true;
|
||||||
}
|
}
|
||||||
autosensData.nonCarbsDeviation = true;
|
|
||||||
} else {
|
} else {
|
||||||
autosensData.pastSensitivity += "C";
|
autosensData.pastSensitivity = "C";
|
||||||
}
|
}
|
||||||
//log.debug("TIME: " + new Date(bgTime).toString() + " BG: " + bg + " SENS: " + sens + " DELTA: " + delta + " AVGDELTA: " + avgDelta + " IOB: " + iob.iob + " ACTIVITY: " + iob.activity + " BGI: " + bgi + " DEVIATION: " + deviation);
|
//log.debug("TIME: " + new Date(bgTime).toString() + " BG: " + bg + " SENS: " + sens + " DELTA: " + delta + " AVGDELTA: " + avgDelta + " IOB: " + iob.iob + " ACTIVITY: " + iob.activity + " BGI: " + bgi + " DEVIATION: " + deviation);
|
||||||
|
|
||||||
previous = autosensData;
|
previous = autosensData;
|
||||||
autosensDataTable.put(bgTime, autosensData);
|
if (bgTime < now())
|
||||||
|
autosensDataTable.put(bgTime, autosensData);
|
||||||
if (Config.logAutosensData)
|
if (Config.logAutosensData)
|
||||||
log.debug("Running detectSensitivity from: " + DateUtil.dateAndTimeString(oldestTimeWithData) + " to: " + DateUtil.dateAndTimeString(bgTime));
|
log.debug("Running detectSensitivity from: " + DateUtil.dateAndTimeString(oldestTimeWithData) + " to: " + DateUtil.dateAndTimeString(bgTime) + " lastDataTime:" + IobCobCalculatorPlugin.getPlugin().lastDataTime());
|
||||||
autosensData.autosensRatio = iobCobCalculatorPlugin.detectSensitivity(oldestTimeWithData, bgTime).ratio;
|
AutosensResult sensitivity = iobCobCalculatorPlugin.detectSensitivityWithLock(oldestTimeWithData, bgTime);
|
||||||
|
if (Config.logAutosensData)
|
||||||
|
log.debug("Sensitivity result: " + sensitivity.toString());
|
||||||
|
autosensData.autosensResult = sensitivity;
|
||||||
if (Config.logAutosensData)
|
if (Config.logAutosensData)
|
||||||
log.debug(autosensData.toString());
|
log.debug(autosensData.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MainApp.bus().post(new EventAutosensCalculationFinished(cause));
|
new Thread(() -> {
|
||||||
log.debug("Finishing calculation thread: " + from);
|
SystemClock.sleep(1000);
|
||||||
|
MainApp.bus().post(new EventAutosensCalculationFinished(cause));
|
||||||
|
}).start();
|
||||||
} finally {
|
} finally {
|
||||||
mWakeLock.release();
|
mWakeLock.release();
|
||||||
MainApp.bus().post(new EventIobCalculationProgress(""));
|
MainApp.bus().post(new EventIobCalculationProgress(""));
|
||||||
|
log.debug("AUTOSENSDATA thread ended: " + from);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,6 @@ import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
|
@ -28,7 +27,7 @@ import info.nightscout.utils.DecimalFormatter;
|
||||||
public class APSResult {
|
public class APSResult {
|
||||||
private static Logger log = LoggerFactory.getLogger(APSResult.class);
|
private static Logger log = LoggerFactory.getLogger(APSResult.class);
|
||||||
|
|
||||||
public Date date;
|
public long date = 0;
|
||||||
public String reason;
|
public String reason;
|
||||||
public double rate;
|
public double rate;
|
||||||
public int duration;
|
public int duration;
|
||||||
|
@ -133,8 +132,8 @@ public class APSResult {
|
||||||
public List<BgReading> getPredictions() {
|
public List<BgReading> getPredictions() {
|
||||||
List<BgReading> array = new ArrayList<>();
|
List<BgReading> array = new ArrayList<>();
|
||||||
try {
|
try {
|
||||||
long startTime = date.getTime();
|
long startTime = date;
|
||||||
if (json.has("predBGs")) {
|
if (json != null && json.has("predBGs")) {
|
||||||
JSONObject predBGs = json.getJSONObject("predBGs");
|
JSONObject predBGs = json.getJSONObject("predBGs");
|
||||||
if (predBGs.has("IOB")) {
|
if (predBGs.has("IOB")) {
|
||||||
JSONArray iob = predBGs.getJSONArray("IOB");
|
JSONArray iob = predBGs.getJSONArray("IOB");
|
||||||
|
@ -196,8 +195,8 @@ public class APSResult {
|
||||||
public long getLatestPredictionsTime() {
|
public long getLatestPredictionsTime() {
|
||||||
long latest = 0;
|
long latest = 0;
|
||||||
try {
|
try {
|
||||||
long startTime = date != null ? date.getTime() : 0;
|
long startTime = date;
|
||||||
if (json.has("predBGs")) {
|
if (json != null && json.has("predBGs")) {
|
||||||
JSONObject predBGs = json.getJSONObject("predBGs");
|
JSONObject predBGs = json.getJSONObject("predBGs");
|
||||||
if (predBGs.has("IOB")) {
|
if (predBGs.has("IOB")) {
|
||||||
JSONArray iob = predBGs.getJSONArray("IOB");
|
JSONArray iob = predBGs.getJSONArray("IOB");
|
||||||
|
|
|
@ -80,7 +80,7 @@ public class LoopFragment extends SubscriberFragment {
|
||||||
clearGUI();
|
clearGUI();
|
||||||
final Activity activity = getActivity();
|
final Activity activity = getActivity();
|
||||||
if (activity != null)
|
if (activity != null)
|
||||||
activity.runOnUiThread(() -> lastRunView.setText(ev.text));
|
activity.runOnUiThread(() -> { synchronized (LoopFragment.this) { if (lastRunView != null) lastRunView.setText(ev.text); } });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -89,26 +89,29 @@ public class LoopFragment extends SubscriberFragment {
|
||||||
Activity activity = getActivity();
|
Activity activity = getActivity();
|
||||||
if (activity != null)
|
if (activity != null)
|
||||||
activity.runOnUiThread(() -> {
|
activity.runOnUiThread(() -> {
|
||||||
LoopPlugin.LastRun lastRun = LoopPlugin.lastRun;
|
synchronized (LoopFragment.this) {
|
||||||
if (lastRun != null) {
|
if (!isBound()) return;
|
||||||
requestView.setText(lastRun.request != null ? lastRun.request.toSpanned() : "");
|
LoopPlugin.LastRun lastRun = LoopPlugin.lastRun;
|
||||||
constraintsProcessedView.setText(lastRun.constraintsProcessed != null ? lastRun.constraintsProcessed.toSpanned() : "");
|
if (lastRun != null) {
|
||||||
sourceView.setText(lastRun.source != null ? lastRun.source : "");
|
requestView.setText(lastRun.request != null ? lastRun.request.toSpanned() : "");
|
||||||
lastRunView.setText(lastRun.lastAPSRun != null && lastRun.lastAPSRun.getTime() != 0 ? lastRun.lastAPSRun.toLocaleString() : "");
|
constraintsProcessedView.setText(lastRun.constraintsProcessed != null ? lastRun.constraintsProcessed.toSpanned() : "");
|
||||||
lastEnactView.setText(lastRun.lastEnact != null && lastRun.lastEnact.getTime() != 0 ? lastRun.lastEnact.toLocaleString() : "");
|
sourceView.setText(lastRun.source != null ? lastRun.source : "");
|
||||||
tbrSetByPumpView.setText(lastRun.tbrSetByPump != null ? Html.fromHtml(lastRun.tbrSetByPump.toHtml()) : "");
|
lastRunView.setText(lastRun.lastAPSRun != null && lastRun.lastAPSRun.getTime() != 0 ? lastRun.lastAPSRun.toLocaleString() : "");
|
||||||
smbSetByPumpView.setText(lastRun.smbSetByPump != null ? Html.fromHtml(lastRun.smbSetByPump.toHtml()) : "");
|
lastEnactView.setText(lastRun.lastEnact != null && lastRun.lastEnact.getTime() != 0 ? lastRun.lastEnact.toLocaleString() : "");
|
||||||
|
tbrSetByPumpView.setText(lastRun.tbrSetByPump != null ? Html.fromHtml(lastRun.tbrSetByPump.toHtml()) : "");
|
||||||
|
smbSetByPumpView.setText(lastRun.smbSetByPump != null ? Html.fromHtml(lastRun.smbSetByPump.toHtml()) : "");
|
||||||
|
|
||||||
String constraints = "";
|
String constraints = "";
|
||||||
if (lastRun.constraintsProcessed != null) {
|
if (lastRun.constraintsProcessed != null) {
|
||||||
Constraint<Double> allConstraints = new Constraint<>(0d);
|
Constraint<Double> allConstraints = new Constraint<>(0d);
|
||||||
if (lastRun.constraintsProcessed.rateConstraint != null)
|
if (lastRun.constraintsProcessed.rateConstraint != null)
|
||||||
allConstraints.copyReasons(lastRun.constraintsProcessed.rateConstraint);
|
allConstraints.copyReasons(lastRun.constraintsProcessed.rateConstraint);
|
||||||
if (lastRun.constraintsProcessed.smbConstraint != null)
|
if (lastRun.constraintsProcessed.smbConstraint != null)
|
||||||
allConstraints.copyReasons(lastRun.constraintsProcessed.smbConstraint);
|
allConstraints.copyReasons(lastRun.constraintsProcessed.smbConstraint);
|
||||||
constraints = allConstraints.getMostLimitedReasons();
|
constraints = allConstraints.getMostLimitedReasons();
|
||||||
|
}
|
||||||
|
constraintsView.setText(constraints);
|
||||||
}
|
}
|
||||||
constraintsView.setText(constraints);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -117,13 +120,29 @@ public class LoopFragment extends SubscriberFragment {
|
||||||
Activity activity = getActivity();
|
Activity activity = getActivity();
|
||||||
if (activity != null)
|
if (activity != null)
|
||||||
activity.runOnUiThread(() -> {
|
activity.runOnUiThread(() -> {
|
||||||
requestView.setText("");
|
synchronized (LoopFragment.this) {
|
||||||
constraintsProcessedView.setText("");
|
if (isBound()) {
|
||||||
sourceView.setText("");
|
requestView.setText("");
|
||||||
lastRunView.setText("");
|
constraintsProcessedView.setText("");
|
||||||
lastEnactView.setText("");
|
sourceView.setText("");
|
||||||
tbrSetByPumpView.setText("");
|
lastRunView.setText("");
|
||||||
smbSetByPumpView.setText("");
|
lastEnactView.setText("");
|
||||||
|
tbrSetByPumpView.setText("");
|
||||||
|
smbSetByPumpView.setText("");
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean isBound() {
|
||||||
|
return requestView != null
|
||||||
|
&& constraintsProcessedView != null
|
||||||
|
&& sourceView != null
|
||||||
|
&& lastRunView != null
|
||||||
|
&& lastEnactView != null
|
||||||
|
&& tbrSetByPumpView != null
|
||||||
|
&& smbSetByPumpView != null
|
||||||
|
&& constraintsView != null
|
||||||
|
&& runNowButton != null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,7 @@ import info.nightscout.androidaps.plugins.Loop.events.EventLoopUpdateGui;
|
||||||
import info.nightscout.androidaps.plugins.Loop.events.EventNewOpenLoopNotification;
|
import info.nightscout.androidaps.plugins.Loop.events.EventNewOpenLoopNotification;
|
||||||
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.androidaps.queue.Callback;
|
import info.nightscout.androidaps.queue.Callback;
|
||||||
|
import info.nightscout.androidaps.queue.commands.Command;
|
||||||
import info.nightscout.utils.FabricPrivacy;
|
import info.nightscout.utils.FabricPrivacy;
|
||||||
import info.nightscout.utils.NSUpload;
|
import info.nightscout.utils.NSUpload;
|
||||||
import info.nightscout.utils.SP;
|
import info.nightscout.utils.SP;
|
||||||
|
@ -94,6 +95,7 @@ public class LoopPlugin extends PluginBase {
|
||||||
.pluginName(R.string.loop)
|
.pluginName(R.string.loop)
|
||||||
.shortName(R.string.loop_shortname)
|
.shortName(R.string.loop_shortname)
|
||||||
.preferencesId(R.xml.pref_closedmode)
|
.preferencesId(R.xml.pref_closedmode)
|
||||||
|
.description(R.string.description_loop)
|
||||||
);
|
);
|
||||||
loopSuspendedTill = SP.getLong("loopSuspendedTill", 0L);
|
loopSuspendedTill = SP.getLong("loopSuspendedTill", 0L);
|
||||||
isSuperBolus = SP.getBoolean("isSuperBolus", false);
|
isSuperBolus = SP.getBoolean("isSuperBolus", false);
|
||||||
|
@ -331,7 +333,9 @@ public class LoopPlugin extends PluginBase {
|
||||||
Constraint<Boolean> closedLoopEnabled = MainApp.getConstraintChecker().isClosedLoopAllowed();
|
Constraint<Boolean> closedLoopEnabled = MainApp.getConstraintChecker().isClosedLoopAllowed();
|
||||||
|
|
||||||
if (closedLoopEnabled.value()) {
|
if (closedLoopEnabled.value()) {
|
||||||
if (result.isChangeRequested()) {
|
if (result.isChangeRequested()
|
||||||
|
&& !ConfigBuilderPlugin.getCommandQueue().bolusInQueue()
|
||||||
|
&& !ConfigBuilderPlugin.getCommandQueue().isRunning(Command.CommandType.BOLUS)) {
|
||||||
final PumpEnactResult waiting = new PumpEnactResult();
|
final PumpEnactResult waiting = new PumpEnactResult();
|
||||||
waiting.queued = true;
|
waiting.queued = true;
|
||||||
if (resultAfterConstraints.tempBasalRequested)
|
if (resultAfterConstraints.tempBasalRequested)
|
||||||
|
|
|
@ -69,6 +69,7 @@ public class NSClientPlugin extends PluginBase {
|
||||||
.pluginName(R.string.nsclientinternal)
|
.pluginName(R.string.nsclientinternal)
|
||||||
.shortName(R.string.nsclientinternal_shortname)
|
.shortName(R.string.nsclientinternal_shortname)
|
||||||
.preferencesId(R.xml.pref_nsclientinternal)
|
.preferencesId(R.xml.pref_nsclientinternal)
|
||||||
|
.description(R.string.description_ns_client)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (Config.NSCLIENT || Config.G5UPLOADER) {
|
if (Config.NSCLIENT || Config.G5UPLOADER) {
|
||||||
|
|
|
@ -122,7 +122,8 @@ class NsClientReceiverDelegate {
|
||||||
boolean newAllowedState = true;
|
boolean newAllowedState = true;
|
||||||
|
|
||||||
if (ev.wifiConnected) {
|
if (ev.wifiConnected) {
|
||||||
if (!allowedSSIDs.trim().isEmpty() && !allowedSSIDs.contains(ev.ssid)) {
|
if (!allowedSSIDs.trim().isEmpty() &&
|
||||||
|
(!allowedSSIDs.contains(ev.getSsid()) && !allowedSSIDs.contains(ev.ssid))) {
|
||||||
newAllowedState = false;
|
newAllowedState = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -26,14 +26,24 @@ public class BroadcastStatus {
|
||||||
private static Logger log = LoggerFactory.getLogger(BroadcastStatus.class);
|
private static Logger log = LoggerFactory.getLogger(BroadcastStatus.class);
|
||||||
|
|
||||||
public static void handleNewStatus(NSSettingsStatus status, Context context, boolean isDelta) {
|
public static void handleNewStatus(NSSettingsStatus status, Context context, boolean isDelta) {
|
||||||
|
LocalBroadcastManager.getInstance(MainApp.instance())
|
||||||
|
.sendBroadcast(createIntent(status, isDelta));
|
||||||
|
|
||||||
|
if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) {
|
||||||
|
context.sendBroadcast(createIntent(status, isDelta));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Intent createIntent(NSSettingsStatus status, boolean isDelta) {
|
||||||
Bundle bundle = new Bundle();
|
Bundle bundle = new Bundle();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
bundle.putString("nsclientversionname", MainApp.instance().getPackageManager().getPackageInfo(MainApp.instance().getPackageName(), 0).versionName);
|
bundle.putString("nsclientversionname", MainApp.instance().getPackageManager().getPackageInfo(MainApp.instance().getPackageName(), 0).versionName);
|
||||||
bundle.putInt("nsclientversioncode", MainApp.instance().getPackageManager().getPackageInfo(MainApp.instance().getPackageName(), 0).versionCode);
|
bundle.putInt("nsclientversioncode", MainApp.instance().getPackageManager().getPackageInfo(MainApp.instance().getPackageName(), 0).versionCode);
|
||||||
} catch (PackageManager.NameNotFoundException e) {
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
bundle.putString("nightscoutversionname", NSClientService.nightscoutVersionName);
|
bundle.putString("nightscoutversionname", NSClientService.nightscoutVersionName);
|
||||||
bundle.putInt("nightscoutversioncode", NSClientService.nightscoutVersionCode);
|
bundle.putInt("nightscoutversioncode", NSClientService.nightscoutVersionCode);
|
||||||
bundle.putString("status", status.getData().toString());
|
bundle.putString("status", status.getData().toString());
|
||||||
|
@ -41,24 +51,7 @@ public class BroadcastStatus {
|
||||||
Intent intent = new Intent(Intents.ACTION_NEW_STATUS);
|
Intent intent = new Intent(Intents.ACTION_NEW_STATUS);
|
||||||
intent.putExtras(bundle);
|
intent.putExtras(bundle);
|
||||||
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
|
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
|
||||||
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
|
|
||||||
|
|
||||||
if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) {
|
return intent;
|
||||||
bundle = new Bundle();
|
|
||||||
try {
|
|
||||||
bundle.putString("nsclientversionname", MainApp.instance().getPackageManager().getPackageInfo(MainApp.instance().getPackageName(), 0).versionName);
|
|
||||||
bundle.putInt("nsclientversioncode", MainApp.instance().getPackageManager().getPackageInfo(MainApp.instance().getPackageName(), 0).versionCode);
|
|
||||||
} catch (PackageManager.NameNotFoundException e) {
|
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
bundle.putString("nightscoutversionname", NSClientService.nightscoutVersionName);
|
|
||||||
bundle.putInt("nightscoutversioncode", NSClientService.nightscoutVersionCode);
|
|
||||||
bundle.putString("status", status.getData().toString());
|
|
||||||
bundle.putBoolean("delta", isDelta);
|
|
||||||
intent = new Intent(Intents.ACTION_NEW_STATUS);
|
|
||||||
intent.putExtras(bundle);
|
|
||||||
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
|
|
||||||
context.sendBroadcast(intent);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
|
import info.nightscout.androidaps.plugins.Loop.APSResult;
|
||||||
import info.nightscout.utils.DateUtil;
|
import info.nightscout.utils.DateUtil;
|
||||||
import info.nightscout.utils.Round;
|
import info.nightscout.utils.Round;
|
||||||
import info.nightscout.utils.SP;
|
import info.nightscout.utils.SP;
|
||||||
|
@ -374,7 +375,7 @@ public class NSDeviceStatus {
|
||||||
public String getUploaderStatus() {
|
public String getUploaderStatus() {
|
||||||
Iterator iter = uploaders.entrySet().iterator();
|
Iterator iter = uploaders.entrySet().iterator();
|
||||||
int minBattery = 100;
|
int minBattery = 100;
|
||||||
while(iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
Map.Entry pair = (Map.Entry) iter.next();
|
Map.Entry pair = (Map.Entry) iter.next();
|
||||||
Uploader uploader = (Uploader) pair.getValue();
|
Uploader uploader = (Uploader) pair.getValue();
|
||||||
if (minBattery > uploader.battery)
|
if (minBattery > uploader.battery)
|
||||||
|
@ -388,7 +389,7 @@ public class NSDeviceStatus {
|
||||||
StringBuilder string = new StringBuilder();
|
StringBuilder string = new StringBuilder();
|
||||||
|
|
||||||
Iterator iter = uploaders.entrySet().iterator();
|
Iterator iter = uploaders.entrySet().iterator();
|
||||||
while(iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
Map.Entry pair = (Map.Entry) iter.next();
|
Map.Entry pair = (Map.Entry) iter.next();
|
||||||
Uploader uploader = (Uploader) pair.getValue();
|
Uploader uploader = (Uploader) pair.getValue();
|
||||||
String device = (String) pair.getKey();
|
String device = (String) pair.getKey();
|
||||||
|
@ -398,4 +399,11 @@ public class NSDeviceStatus {
|
||||||
return Html.fromHtml(string.toString());
|
return Html.fromHtml(string.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static APSResult getAPSResult() {
|
||||||
|
APSResult result = new APSResult();
|
||||||
|
result.json = deviceStatusOpenAPSData.suggested;
|
||||||
|
result.date = deviceStatusOpenAPSData.clockSuggested;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,19 +6,18 @@ import org.mozilla.javascript.NativeObject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.plugins.Loop.APSResult;
|
import info.nightscout.androidaps.plugins.Loop.APSResult;
|
||||||
|
import info.nightscout.utils.DateUtil;
|
||||||
|
|
||||||
public class DetermineBasalResultAMA extends APSResult {
|
public class DetermineBasalResultAMA extends APSResult {
|
||||||
private static Logger log = LoggerFactory.getLogger(DetermineBasalResultAMA.class);
|
private static Logger log = LoggerFactory.getLogger(DetermineBasalResultAMA.class);
|
||||||
|
|
||||||
public double eventualBG;
|
private double eventualBG;
|
||||||
public double snoozeBG;
|
private double snoozeBG;
|
||||||
|
|
||||||
public DetermineBasalResultAMA(NativeObject result, JSONObject j) {
|
DetermineBasalResultAMA(NativeObject result, JSONObject j) {
|
||||||
this();
|
this();
|
||||||
date = new Date();
|
date = DateUtil.now();
|
||||||
json = j;
|
json = j;
|
||||||
if (result.containsKey("error")) {
|
if (result.containsKey("error")) {
|
||||||
reason = result.get("error").toString();
|
reason = result.get("error").toString();
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package info.nightscout.androidaps.plugins.OpenAPSAMA;
|
package info.nightscout.androidaps.plugins.OpenAPSAMA;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensData;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -62,6 +63,7 @@ public class OpenAPSAMAPlugin extends PluginBase implements APSInterface {
|
||||||
.pluginName(R.string.openapsama)
|
.pluginName(R.string.openapsama)
|
||||||
.shortName(R.string.oaps_shortname)
|
.shortName(R.string.oaps_shortname)
|
||||||
.preferencesId(R.xml.pref_openapsama)
|
.preferencesId(R.xml.pref_openapsama)
|
||||||
|
.description(R.string.description_ama)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,9 +174,14 @@ public class OpenAPSAMAPlugin extends PluginBase implements APSInterface {
|
||||||
|
|
||||||
startPart = new Date();
|
startPart = new Date();
|
||||||
if (MainApp.getConstraintChecker().isAutosensModeEnabled().value()) {
|
if (MainApp.getConstraintChecker().isAutosensModeEnabled().value()) {
|
||||||
lastAutosensResult = IobCobCalculatorPlugin.getPlugin().detectSensitivityWithLock(IobCobCalculatorPlugin.getPlugin().oldestDataAvailable(), System.currentTimeMillis());
|
AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getLastAutosensDataSynchronized("OpenAPSPlugin");
|
||||||
|
if (autosensData == null) {
|
||||||
|
MainApp.bus().post(new EventOpenAPSUpdateResultGui(MainApp.gs(R.string.openaps_noasdata)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
lastAutosensResult = new AutosensResult();
|
lastAutosensResult = new AutosensResult();
|
||||||
|
lastAutosensResult.sensResult = "autosens disabled";
|
||||||
}
|
}
|
||||||
Profiler.log(log, "detectSensitivityandCarbAbsorption()", startPart);
|
Profiler.log(log, "detectSensitivityandCarbAbsorption()", startPart);
|
||||||
Profiler.log(log, "AMA data gathering", start);
|
Profiler.log(log, "AMA data gathering", start);
|
||||||
|
|
|
@ -62,6 +62,7 @@ public class OpenAPSMAPlugin extends PluginBase implements APSInterface {
|
||||||
.pluginName(R.string.openapsma)
|
.pluginName(R.string.openapsma)
|
||||||
.shortName(R.string.oaps_shortname)
|
.shortName(R.string.oaps_shortname)
|
||||||
.preferencesId(R.xml.pref_openapsma)
|
.preferencesId(R.xml.pref_openapsma)
|
||||||
|
.description(R.string.description_ma)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -234,8 +234,8 @@ public class DetermineBasalAdapterSMBJS {
|
||||||
mProfile.put("max_daily_safety_multiplier", SP.getInt(R.string.key_openapsama_max_daily_safety_multiplier, 3));
|
mProfile.put("max_daily_safety_multiplier", SP.getInt(R.string.key_openapsama_max_daily_safety_multiplier, 3));
|
||||||
mProfile.put("current_basal_safety_multiplier", SP.getDouble(R.string.key_openapsama_current_basal_safety_multiplier, 4d));
|
mProfile.put("current_basal_safety_multiplier", SP.getDouble(R.string.key_openapsama_current_basal_safety_multiplier, 4d));
|
||||||
|
|
||||||
mProfile.put("high_temptarget_raises_sensitivity", SMBDefaults.high_temptarget_raises_sensitivity);
|
mProfile.put("high_temptarget_raises_sensitivity", SP.getBoolean(R.string.key_high_temptarget_raises_sensitivity, SMBDefaults.high_temptarget_raises_sensitivity));
|
||||||
mProfile.put("low_temptarget_lowers_sensitivity", SMBDefaults.low_temptarget_lowers_sensitivity);
|
mProfile.put("low_temptarget_lowers_sensitivity", SP.getBoolean(R.string.key_low_temptarget_lowers_sensitivity, SMBDefaults.low_temptarget_lowers_sensitivity));
|
||||||
mProfile.put("sensitivity_raises_target", SMBDefaults.sensitivity_raises_target);
|
mProfile.put("sensitivity_raises_target", SMBDefaults.sensitivity_raises_target);
|
||||||
mProfile.put("resistance_lowers_target", SMBDefaults.resistance_lowers_target);
|
mProfile.put("resistance_lowers_target", SMBDefaults.resistance_lowers_target);
|
||||||
mProfile.put("adv_target_adjustments", SMBDefaults.adv_target_adjustments);
|
mProfile.put("adv_target_adjustments", SMBDefaults.adv_target_adjustments);
|
||||||
|
@ -250,7 +250,7 @@ public class DetermineBasalAdapterSMBJS {
|
||||||
mProfile.put("min_5m_carbimpact", SP.getDouble(R.string.key_openapsama_min_5m_carbimpact, SMBDefaults.min_5m_carbimpact));
|
mProfile.put("min_5m_carbimpact", SP.getDouble(R.string.key_openapsama_min_5m_carbimpact, SMBDefaults.min_5m_carbimpact));
|
||||||
}
|
}
|
||||||
mProfile.put("remainingCarbsCap", SMBDefaults.remainingCarbsCap);
|
mProfile.put("remainingCarbsCap", SMBDefaults.remainingCarbsCap);
|
||||||
mProfile.put("enableUAM", SP.getBoolean(R.string.key_use_uam, false)&& advancedFiltering);
|
mProfile.put("enableUAM", SP.getBoolean(R.string.key_use_uam, false));
|
||||||
mProfile.put("A52_risk_enable", SMBDefaults.A52_risk_enable);
|
mProfile.put("A52_risk_enable", SMBDefaults.A52_risk_enable);
|
||||||
mProfile.put("enableSMB_with_COB", SP.getBoolean(R.string.key_enableSMB_with_COB, false));
|
mProfile.put("enableSMB_with_COB", SP.getBoolean(R.string.key_enableSMB_with_COB, false));
|
||||||
mProfile.put("enableSMB_with_temptarget", SP.getBoolean(R.string.key_enableSMB_with_temptarget, false));
|
mProfile.put("enableSMB_with_temptarget", SP.getBoolean(R.string.key_enableSMB_with_temptarget, false));
|
||||||
|
|
|
@ -5,22 +5,20 @@ import org.json.JSONObject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.plugins.Loop.APSResult;
|
import info.nightscout.androidaps.plugins.Loop.APSResult;
|
||||||
import info.nightscout.utils.DateUtil;
|
import info.nightscout.utils.DateUtil;
|
||||||
|
|
||||||
public class DetermineBasalResultSMB extends APSResult {
|
public class DetermineBasalResultSMB extends APSResult {
|
||||||
private static final Logger log = LoggerFactory.getLogger(DetermineBasalResultSMB.class);
|
private static final Logger log = LoggerFactory.getLogger(DetermineBasalResultSMB.class);
|
||||||
|
|
||||||
public double eventualBG;
|
private double eventualBG;
|
||||||
public double snoozeBG;
|
private double snoozeBG;
|
||||||
public double insulinReq;
|
//public double insulinReq;
|
||||||
public double carbsReq;
|
//public double carbsReq;
|
||||||
|
|
||||||
public DetermineBasalResultSMB(JSONObject result) {
|
DetermineBasalResultSMB(JSONObject result) {
|
||||||
this();
|
this();
|
||||||
date = new Date();
|
date = DateUtil.now();
|
||||||
json = result;
|
json = result;
|
||||||
try {
|
try {
|
||||||
if (result.has("error")) {
|
if (result.has("error")) {
|
||||||
|
@ -31,8 +29,8 @@ public class DetermineBasalResultSMB extends APSResult {
|
||||||
reason = result.getString("reason");
|
reason = result.getString("reason");
|
||||||
if (result.has("eventualBG")) eventualBG = result.getDouble("eventualBG");
|
if (result.has("eventualBG")) eventualBG = result.getDouble("eventualBG");
|
||||||
if (result.has("snoozeBG")) snoozeBG = result.getDouble("snoozeBG");
|
if (result.has("snoozeBG")) snoozeBG = result.getDouble("snoozeBG");
|
||||||
if (result.has("insulinReq")) insulinReq = result.getDouble("insulinReq");
|
//if (result.has("insulinReq")) insulinReq = result.getDouble("insulinReq");
|
||||||
if (result.has("carbsReq")) carbsReq = result.getDouble("carbsReq");
|
//if (result.has("carbsReq")) carbsReq = result.getDouble("carbsReq");
|
||||||
|
|
||||||
if (result.has("rate") && result.has("duration")) {
|
if (result.has("rate") && result.has("duration")) {
|
||||||
tempBasalRequested = true;
|
tempBasalRequested = true;
|
||||||
|
@ -64,7 +62,7 @@ public class DetermineBasalResultSMB extends APSResult {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public DetermineBasalResultSMB() {
|
private DetermineBasalResultSMB() {
|
||||||
hasPredictions = true;
|
hasPredictions = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -87,34 +87,37 @@ public class OpenAPSSMBFragment extends SubscriberFragment {
|
||||||
activity.runOnUiThread(new Runnable() {
|
activity.runOnUiThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
OpenAPSSMBPlugin plugin = OpenAPSSMBPlugin.getPlugin();
|
synchronized (OpenAPSSMBFragment.this) {
|
||||||
DetermineBasalResultSMB lastAPSResult = plugin.lastAPSResult;
|
if (!isBound()) return;
|
||||||
if (lastAPSResult != null) {
|
OpenAPSSMBPlugin plugin = OpenAPSSMBPlugin.getPlugin();
|
||||||
resultView.setText(JSONFormatter.format(lastAPSResult.json));
|
DetermineBasalResultSMB lastAPSResult = plugin.lastAPSResult;
|
||||||
requestView.setText(lastAPSResult.toSpanned());
|
if (lastAPSResult != null) {
|
||||||
}
|
resultView.setText(JSONFormatter.format(lastAPSResult.json));
|
||||||
DetermineBasalAdapterSMBJS determineBasalAdapterSMBJS = plugin.lastDetermineBasalAdapterSMBJS;
|
requestView.setText(lastAPSResult.toSpanned());
|
||||||
if (determineBasalAdapterSMBJS != null) {
|
}
|
||||||
glucoseStatusView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getGlucoseStatusParam()).toString().trim());
|
DetermineBasalAdapterSMBJS determineBasalAdapterSMBJS = plugin.lastDetermineBasalAdapterSMBJS;
|
||||||
currentTempView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getCurrentTempParam()).toString().trim());
|
if (determineBasalAdapterSMBJS != null) {
|
||||||
try {
|
glucoseStatusView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getGlucoseStatusParam()).toString().trim());
|
||||||
JSONArray iobArray = new JSONArray(determineBasalAdapterSMBJS.getIobDataParam());
|
currentTempView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getCurrentTempParam()).toString().trim());
|
||||||
iobDataView.setText((String.format(MainApp.gs(R.string.array_of_elements), iobArray.length()) + "\n" + JSONFormatter.format(iobArray.getString(0))).trim());
|
try {
|
||||||
} catch (JSONException e) {
|
JSONArray iobArray = new JSONArray(determineBasalAdapterSMBJS.getIobDataParam());
|
||||||
log.error("Unhandled exception", e);
|
iobDataView.setText((String.format(MainApp.gs(R.string.array_of_elements), iobArray.length()) + "\n" + JSONFormatter.format(iobArray.getString(0))).trim());
|
||||||
iobDataView.setText("JSONException see log for details");
|
} catch (JSONException e) {
|
||||||
|
log.error("Unhandled exception", e);
|
||||||
|
iobDataView.setText("JSONException see log for details");
|
||||||
|
}
|
||||||
|
profileView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getProfileParam()).toString().trim());
|
||||||
|
mealDataView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getMealDataParam()).toString().trim());
|
||||||
|
scriptdebugView.setText(determineBasalAdapterSMBJS.getScriptDebug().trim());
|
||||||
|
if (lastAPSResult != null && lastAPSResult.inputConstraints != null)
|
||||||
|
constraintsView.setText(lastAPSResult.inputConstraints.getReasons().trim());
|
||||||
|
}
|
||||||
|
if (plugin.lastAPSRun != null) {
|
||||||
|
lastRunView.setText(plugin.lastAPSRun.toLocaleString().trim());
|
||||||
|
}
|
||||||
|
if (plugin.lastAutosensResult != null) {
|
||||||
|
autosensDataView.setText(JSONFormatter.format(plugin.lastAutosensResult.json()).toString().trim());
|
||||||
}
|
}
|
||||||
profileView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getProfileParam()).toString().trim());
|
|
||||||
mealDataView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getMealDataParam()).toString().trim());
|
|
||||||
scriptdebugView.setText(determineBasalAdapterSMBJS.getScriptDebug().trim());
|
|
||||||
if (lastAPSResult != null && lastAPSResult.inputConstraints != null)
|
|
||||||
constraintsView.setText(lastAPSResult.inputConstraints.getReasons().trim());
|
|
||||||
}
|
|
||||||
if (plugin.lastAPSRun != null) {
|
|
||||||
lastRunView.setText(plugin.lastAPSRun.toLocaleString().trim());
|
|
||||||
}
|
|
||||||
if (plugin.lastAutosensResult != null) {
|
|
||||||
autosensDataView.setText(JSONFormatter.format(plugin.lastAutosensResult.json()).toString().trim());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -126,17 +129,36 @@ public class OpenAPSSMBFragment extends SubscriberFragment {
|
||||||
activity.runOnUiThread(new Runnable() {
|
activity.runOnUiThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
resultView.setText(text);
|
synchronized (OpenAPSSMBFragment.this) {
|
||||||
glucoseStatusView.setText("");
|
if (isBound()) {
|
||||||
currentTempView.setText("");
|
resultView.setText(text);
|
||||||
iobDataView.setText("");
|
glucoseStatusView.setText("");
|
||||||
profileView.setText("");
|
currentTempView.setText("");
|
||||||
mealDataView.setText("");
|
iobDataView.setText("");
|
||||||
autosensDataView.setText("");
|
profileView.setText("");
|
||||||
scriptdebugView.setText("");
|
mealDataView.setText("");
|
||||||
requestView.setText("");
|
autosensDataView.setText("");
|
||||||
lastRunView.setText("");
|
scriptdebugView.setText("");
|
||||||
|
requestView.setText("");
|
||||||
|
lastRunView.setText("");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isBound() {
|
||||||
|
return run != null
|
||||||
|
&& lastRunView != null
|
||||||
|
&& constraintsView != null
|
||||||
|
&& glucoseStatusView != null
|
||||||
|
&& currentTempView != null
|
||||||
|
&& iobDataView != null
|
||||||
|
&& profileView != null
|
||||||
|
&& mealDataView != null
|
||||||
|
&& autosensDataView != null
|
||||||
|
&& resultView != null
|
||||||
|
&& scriptdebugView != null
|
||||||
|
&& requestView != null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package info.nightscout.androidaps.plugins.OpenAPSSMB;
|
package info.nightscout.androidaps.plugins.OpenAPSSMB;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensData;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -65,6 +66,7 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface {
|
||||||
.pluginName(R.string.openapssmb)
|
.pluginName(R.string.openapssmb)
|
||||||
.shortName(R.string.smb_shortname)
|
.shortName(R.string.smb_shortname)
|
||||||
.preferencesId(R.xml.pref_openapssmb)
|
.preferencesId(R.xml.pref_openapssmb)
|
||||||
|
.description(R.string.description_smb)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,9 +181,15 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface {
|
||||||
|
|
||||||
startPart = new Date();
|
startPart = new Date();
|
||||||
if (MainApp.getConstraintChecker().isAutosensModeEnabled().value()) {
|
if (MainApp.getConstraintChecker().isAutosensModeEnabled().value()) {
|
||||||
lastAutosensResult = IobCobCalculatorPlugin.getPlugin().detectSensitivityWithLock(IobCobCalculatorPlugin.getPlugin().oldestDataAvailable(), System.currentTimeMillis());
|
AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getLastAutosensDataSynchronized("OpenAPSPlugin");
|
||||||
|
if (autosensData == null) {
|
||||||
|
MainApp.bus().post(new EventOpenAPSUpdateResultGui(MainApp.gs(R.string.openaps_noasdata)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lastAutosensResult = autosensData.autosensResult;
|
||||||
} else {
|
} else {
|
||||||
lastAutosensResult = new AutosensResult();
|
lastAutosensResult = new AutosensResult();
|
||||||
|
lastAutosensResult.sensResult = "autosens disabled";
|
||||||
}
|
}
|
||||||
|
|
||||||
Constraint<Boolean> smbAllowed = new Constraint<>(!tempBasalFallback);
|
Constraint<Boolean> smbAllowed = new Constraint<>(!tempBasalFallback);
|
||||||
|
|
|
@ -112,7 +112,7 @@ public class BolusProgressDialog extends DialogFragment implements View.OnClickL
|
||||||
stopPressed = true;
|
stopPressed = true;
|
||||||
stopPressedView.setVisibility(View.VISIBLE);
|
stopPressedView.setVisibility(View.VISIBLE);
|
||||||
stopButton.setVisibility(View.INVISIBLE);
|
stopButton.setVisibility(View.INVISIBLE);
|
||||||
ConfigBuilderPlugin.getActivePump().stopBolusDelivering();
|
ConfigBuilderPlugin.getCommandQueue().cancelAllBoluses();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import android.widget.RadioButton;
|
||||||
|
|
||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
|
|
||||||
|
import info.nightscout.utils.NSUpload;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -32,7 +33,9 @@ import info.nightscout.androidaps.Constants;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
|
import info.nightscout.androidaps.db.BgReading;
|
||||||
import info.nightscout.androidaps.db.CareportalEvent;
|
import info.nightscout.androidaps.db.CareportalEvent;
|
||||||
|
import info.nightscout.androidaps.db.DatabaseHelper;
|
||||||
import info.nightscout.androidaps.db.Source;
|
import info.nightscout.androidaps.db.Source;
|
||||||
import info.nightscout.androidaps.db.TempTarget;
|
import info.nightscout.androidaps.db.TempTarget;
|
||||||
import info.nightscout.androidaps.interfaces.Constraint;
|
import info.nightscout.androidaps.interfaces.Constraint;
|
||||||
|
@ -124,7 +127,6 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, C
|
||||||
startEatingSoonTTCheckbox = view.findViewById(R.id.newcarbs_eating_soon_tt);
|
startEatingSoonTTCheckbox = view.findViewById(R.id.newcarbs_eating_soon_tt);
|
||||||
startEatingSoonTTCheckbox.setOnCheckedChangeListener(this);
|
startEatingSoonTTCheckbox.setOnCheckedChangeListener(this);
|
||||||
startHypoTTCheckbox = view.findViewById(R.id.newcarbs_hypo_tt);
|
startHypoTTCheckbox = view.findViewById(R.id.newcarbs_hypo_tt);
|
||||||
startHypoTTCheckbox.setOnCheckedChangeListener(this);
|
|
||||||
|
|
||||||
editTime = view.findViewById(R.id.newcarbs_time);
|
editTime = view.findViewById(R.id.newcarbs_time);
|
||||||
editTime.setParams(0d, -12 * 60d, 12 * 60d, 5d, new DecimalFormat("0"), false, textWatcher);
|
editTime.setParams(0d, -12 * 60d, 12 * 60d, 5d, new DecimalFormat("0"), false, textWatcher);
|
||||||
|
@ -153,6 +155,13 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, C
|
||||||
notesLayout.setVisibility(SP.getBoolean(R.string.key_show_notes_entry_dialogs, false) ? View.VISIBLE : View.GONE);
|
notesLayout.setVisibility(SP.getBoolean(R.string.key_show_notes_entry_dialogs, false) ? View.VISIBLE : View.GONE);
|
||||||
notesEdit = view.findViewById(R.id.newcarbs_notes);
|
notesEdit = view.findViewById(R.id.newcarbs_notes);
|
||||||
|
|
||||||
|
BgReading bgReading = DatabaseHelper.actualBg();
|
||||||
|
if (bgReading != null && bgReading.value < 72) {
|
||||||
|
startHypoTTCheckbox.setOnCheckedChangeListener(null);
|
||||||
|
startHypoTTCheckbox.setChecked(true);
|
||||||
|
}
|
||||||
|
startHypoTTCheckbox.setOnClickListener(this);
|
||||||
|
|
||||||
setCancelable(true);
|
setCancelable(true);
|
||||||
getDialog().setCanceledOnTouchOutside(false);
|
getDialog().setCanceledOnTouchOutside(false);
|
||||||
return view;
|
return view;
|
||||||
|
@ -221,13 +230,13 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, C
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||||
// Logic to disable a selected radio when pressed. When a checked radio
|
// Logic to disable a selected radio when pressed: when a checked radio
|
||||||
// is pressed, no CheckChanged event is trigger, so register a Click event
|
// is pressed, no CheckChanged event is triggered, so register a Click event
|
||||||
// when checking a radio. Since Click events come after CheckChanged events,
|
// when checking a radio. Since Click events come after CheckChanged events,
|
||||||
// the Click event is triggered immediately after this. Thus, set toggingTT
|
// the Click event is triggered immediately after this. Thus, set togglingTT
|
||||||
// var to true, so that the first Click event fired after this is ignored.
|
// var to true, so that the first Click event fired after this is ignored.
|
||||||
// Radios remove themselves from Click events once unchecked.
|
// Radios remove themselves from Click events once unchecked.
|
||||||
// Since radios are not in a group, manually update their state.
|
// Since radios are not in a group, their state is manually updated here.
|
||||||
switch (buttonView.getId()) {
|
switch (buttonView.getId()) {
|
||||||
case R.id.newcarbs_activity_tt:
|
case R.id.newcarbs_activity_tt:
|
||||||
togglingTT = true;
|
togglingTT = true;
|
||||||
|
@ -303,21 +312,21 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, C
|
||||||
if (currentProfile.getUnits().equals(Constants.MMOL)) {
|
if (currentProfile.getUnits().equals(Constants.MMOL)) {
|
||||||
unitLabel = "mmol/l";
|
unitLabel = "mmol/l";
|
||||||
}
|
}
|
||||||
|
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.tempTargetConfirmation) + "'>" + DecimalFormatter.to1Decimal(activityTT) + " " + unitLabel + " (" + activityTTDuration + " min)</font>");
|
||||||
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.high) + "'>" + DecimalFormatter.to1Decimal(activityTT) + " " + unitLabel + " (" + activityTTDuration + " min)</font>");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
if (startEatingSoonTTCheckbox.isChecked()) {
|
if (startEatingSoonTTCheckbox.isChecked()) {
|
||||||
if (currentProfile.getUnits().equals(Constants.MMOL)) {
|
if (currentProfile.getUnits().equals(Constants.MMOL)) {
|
||||||
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.high) + "'>" + DecimalFormatter.to1Decimal(eatingSoonTT) + " mmol/l (" + eatingSoonTTDuration + " min)</font>");
|
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.tempTargetConfirmation) + "'>" + DecimalFormatter.to1Decimal(eatingSoonTT) + " mmol/l (" + eatingSoonTTDuration + " min)</font>");
|
||||||
} else
|
} else {
|
||||||
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.high) + "'>" + DecimalFormatter.to0Decimal(eatingSoonTT) + " mg/dl (" + eatingSoonTTDuration + " min)</font>");
|
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.tempTargetConfirmation) + "'>" + DecimalFormatter.to0Decimal(eatingSoonTT) + " mg/dl (" + eatingSoonTTDuration + " min)</font>");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (startHypoTTCheckbox.isChecked()) {
|
if (startHypoTTCheckbox.isChecked()) {
|
||||||
if (currentProfile.getUnits().equals(Constants.MMOL)) {
|
if (currentProfile.getUnits().equals(Constants.MMOL)) {
|
||||||
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.high) + "'>" + DecimalFormatter.to1Decimal(hypoTT) + " mmol/l (" + hypoTTDuration + " min)</font>");
|
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.tempTargetConfirmation) + "'>" + DecimalFormatter.to1Decimal(hypoTT) + " mmol/l (" + hypoTTDuration + " min)</font>");
|
||||||
} else
|
} else {
|
||||||
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.high) + "'>" + DecimalFormatter.to0Decimal(hypoTT) + " mg/dl (" + hypoTTDuration + " min)</font>");
|
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.tempTargetConfirmation) + "'>" + DecimalFormatter.to0Decimal(hypoTT) + " mg/dl (" + hypoTTDuration + " min)</font>");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int timeOffset = editTime.getValue().intValue();
|
int timeOffset = editTime.getValue().intValue();
|
||||||
|
@ -394,6 +403,7 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, C
|
||||||
CarbsGenerator.createCarb(carbsAfterConstraints, time, CareportalEvent.CARBCORRECTION, notes);
|
CarbsGenerator.createCarb(carbsAfterConstraints, time, CareportalEvent.CARBCORRECTION, notes);
|
||||||
} else {
|
} else {
|
||||||
CarbsGenerator.generateCarbs(carbsAfterConstraints, time, duration, notes);
|
CarbsGenerator.generateCarbs(carbsAfterConstraints, time, duration, notes);
|
||||||
|
NSUpload.uploadEvent(CareportalEvent.NOTE, now() - 2000, MainApp.gs(R.string.generated_ecarbs_note, carbsAfterConstraints, duration, timeOffset));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,6 +148,11 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener
|
||||||
|
|
||||||
setCancelable(true);
|
setCancelable(true);
|
||||||
getDialog().setCanceledOnTouchOutside(false);
|
getDialog().setCanceledOnTouchOutside(false);
|
||||||
|
if (savedInstanceState != null) {
|
||||||
|
// log.debug("savedInstanceState in onCreate is:" + savedInstanceState.toString());
|
||||||
|
editInsulin.setValue(savedInstanceState.getDouble("editInsulin"));
|
||||||
|
editTime.setValue(savedInstanceState.getDouble("editTime"));
|
||||||
|
}
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,6 +161,17 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener
|
||||||
return value > 0 ? "+" + formatted : formatted;
|
return value > 0 ? "+" + formatted : formatted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSaveInstanceState(Bundle insulinDialogState) {
|
||||||
|
insulinDialogState.putBoolean("startEatingSoonTTCheckbox", startEatingSoonTTCheckbox.isChecked());
|
||||||
|
insulinDialogState.putBoolean("recordOnlyCheckbox", recordOnlyCheckbox.isChecked());
|
||||||
|
insulinDialogState.putDouble("editTime", editTime.getValue());
|
||||||
|
insulinDialogState.putDouble("editInsulin", editInsulin.getValue());
|
||||||
|
insulinDialogState.putString("notesEdit",notesEdit.getText().toString());
|
||||||
|
log.debug("Instance state saved:"+insulinDialogState.toString());
|
||||||
|
super.onSaveInstanceState(insulinDialogState);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void onClick(View view) {
|
public synchronized void onClick(View view) {
|
||||||
switch (view.getId()) {
|
switch (view.getId()) {
|
||||||
|
@ -217,9 +233,9 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener
|
||||||
|
|
||||||
if (startEatingSoonTTCheckbox.isChecked()) {
|
if (startEatingSoonTTCheckbox.isChecked()) {
|
||||||
if (currentProfile.getUnits().equals(Constants.MMOL)) {
|
if (currentProfile.getUnits().equals(Constants.MMOL)) {
|
||||||
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.high) + "'>" + DecimalFormatter.to1Decimal(eatingSoonTT) + " mmol/l (" + eatingSoonTTDuration + " min)</font>");
|
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.tempTargetConfirmation) + "'>" + DecimalFormatter.to1Decimal(eatingSoonTT) + " mmol/l (" + eatingSoonTTDuration + " min)</font>");
|
||||||
} else
|
} else
|
||||||
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.high) + "'>" + DecimalFormatter.to0Decimal(eatingSoonTT) + " mg/dl (" + eatingSoonTTDuration + " min)</font>");
|
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.tempTargetConfirmation) + "'>" + DecimalFormatter.to0Decimal(eatingSoonTT) + " mg/dl (" + eatingSoonTTDuration + " min)</font>");
|
||||||
}
|
}
|
||||||
|
|
||||||
int timeOffset = editTime.getValue().intValue();
|
int timeOffset = editTime.getValue().intValue();
|
||||||
|
@ -270,7 +286,7 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener
|
||||||
detailedBolusInfo.notes = notes;
|
detailedBolusInfo.notes = notes;
|
||||||
if (recordOnlyCheckbox.isChecked()) {
|
if (recordOnlyCheckbox.isChecked()) {
|
||||||
detailedBolusInfo.date = time;
|
detailedBolusInfo.date = time;
|
||||||
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo);
|
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false);
|
||||||
} else {
|
} else {
|
||||||
detailedBolusInfo.date = now();
|
detailedBolusInfo.date = now();
|
||||||
ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() {
|
ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() {
|
||||||
|
|
|
@ -25,7 +25,6 @@ import org.slf4j.LoggerFactory;
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import info.nightscout.androidaps.Constants;
|
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.data.DetailedBolusInfo;
|
import info.nightscout.androidaps.data.DetailedBolusInfo;
|
||||||
|
@ -187,7 +186,7 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo);
|
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false);
|
||||||
}
|
}
|
||||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("Bolus"));
|
FabricPrivacy.getInstance().logCustom(new CustomEvent("Bolus"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -315,6 +315,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
|
||||||
confirmMessage += "<br/>" + MainApp.gs(R.string.carbs) + ": " + "<font color='" + MainApp.gc(R.color.carbs) + "'>" + carbsAfterConstraints + "g" + "</font>";
|
confirmMessage += "<br/>" + MainApp.gs(R.string.carbs) + ": " + "<font color='" + MainApp.gc(R.color.carbs) + "'>" + carbsAfterConstraints + "g" + "</font>";
|
||||||
|
|
||||||
if (insulinAfterConstraints - calculatedTotalInsulin != 0 || !carbsAfterConstraints.equals(calculatedCarbs)) {
|
if (insulinAfterConstraints - calculatedTotalInsulin != 0 || !carbsAfterConstraints.equals(calculatedCarbs)) {
|
||||||
|
okClicked = false;
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||||
builder.setTitle(MainApp.gs(R.string.treatmentdeliveryerror));
|
builder.setTitle(MainApp.gs(R.string.treatmentdeliveryerror));
|
||||||
builder.setMessage(MainApp.gs(R.string.constraints_violation) + "\n" + MainApp.gs(R.string.changeyourinput));
|
builder.setMessage(MainApp.gs(R.string.constraints_violation) + "\n" + MainApp.gs(R.string.changeyourinput));
|
||||||
|
@ -388,7 +389,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo);
|
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false);
|
||||||
}
|
}
|
||||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("Wizard"));
|
FabricPrivacy.getInstance().logCustom(new CustomEvent("Wizard"));
|
||||||
}
|
}
|
||||||
|
@ -408,9 +409,9 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
|
||||||
|
|
||||||
private void initDialog() {
|
private void initDialog() {
|
||||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||||
ProfileStore profileStore = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile();
|
ProfileStore profileStore = MainApp.getConfigBuilder().getActiveProfileInterface() != null ? MainApp.getConfigBuilder().getActiveProfileInterface().getProfile() : null;
|
||||||
|
|
||||||
if (profile == null) {
|
if (profile == null || profileStore == null) {
|
||||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.noprofile));
|
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.noprofile));
|
||||||
dismiss();
|
dismiss();
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -24,14 +24,11 @@ import android.text.style.ForegroundColorSpan;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
import android.view.ContextMenu;
|
import android.view.ContextMenu;
|
||||||
import android.view.HapticFeedbackConstants;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.CheckBox;
|
|
||||||
import android.widget.CompoundButton;
|
|
||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
@ -88,10 +85,12 @@ import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialo
|
||||||
import info.nightscout.androidaps.plugins.Careportal.OptionsToShow;
|
import info.nightscout.androidaps.plugins.Careportal.OptionsToShow;
|
||||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||||
import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin;
|
import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensResult;
|
||||||
import info.nightscout.androidaps.plugins.IobCobCalculator.CobInfo;
|
import info.nightscout.androidaps.plugins.IobCobCalculator.CobInfo;
|
||||||
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
|
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
|
||||||
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished;
|
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished;
|
||||||
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventIobCalculationProgress;
|
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventIobCalculationProgress;
|
||||||
|
import info.nightscout.androidaps.plugins.Loop.APSResult;
|
||||||
import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
|
import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Loop.events.EventNewOpenLoopNotification;
|
import info.nightscout.androidaps.plugins.Loop.events.EventNewOpenLoopNotification;
|
||||||
import info.nightscout.androidaps.plugins.NSClientInternal.data.NSDeviceStatus;
|
import info.nightscout.androidaps.plugins.NSClientInternal.data.NSDeviceStatus;
|
||||||
|
@ -102,7 +101,6 @@ import info.nightscout.androidaps.plugins.Overview.Dialogs.NewInsulinDialog;
|
||||||
import info.nightscout.androidaps.plugins.Overview.Dialogs.NewTreatmentDialog;
|
import info.nightscout.androidaps.plugins.Overview.Dialogs.NewTreatmentDialog;
|
||||||
import info.nightscout.androidaps.plugins.Overview.Dialogs.WizardDialog;
|
import info.nightscout.androidaps.plugins.Overview.Dialogs.WizardDialog;
|
||||||
import info.nightscout.androidaps.plugins.Overview.activities.QuickWizardListActivity;
|
import info.nightscout.androidaps.plugins.Overview.activities.QuickWizardListActivity;
|
||||||
import info.nightscout.androidaps.plugins.Overview.events.EventSetWakeLock;
|
|
||||||
import info.nightscout.androidaps.plugins.Overview.graphData.GraphData;
|
import info.nightscout.androidaps.plugins.Overview.graphData.GraphData;
|
||||||
import info.nightscout.androidaps.plugins.Overview.notifications.NotificationRecyclerViewAdapter;
|
import info.nightscout.androidaps.plugins.Overview.notifications.NotificationRecyclerViewAdapter;
|
||||||
import info.nightscout.androidaps.plugins.Overview.notifications.NotificationStore;
|
import info.nightscout.androidaps.plugins.Overview.notifications.NotificationStore;
|
||||||
|
@ -114,22 +112,29 @@ import info.nightscout.androidaps.queue.Callback;
|
||||||
import info.nightscout.utils.BolusWizard;
|
import info.nightscout.utils.BolusWizard;
|
||||||
import info.nightscout.utils.DateUtil;
|
import info.nightscout.utils.DateUtil;
|
||||||
import info.nightscout.utils.DecimalFormatter;
|
import info.nightscout.utils.DecimalFormatter;
|
||||||
|
import info.nightscout.utils.DefaultValueHelper;
|
||||||
import info.nightscout.utils.FabricPrivacy;
|
import info.nightscout.utils.FabricPrivacy;
|
||||||
import info.nightscout.utils.NSUpload;
|
import info.nightscout.utils.NSUpload;
|
||||||
import info.nightscout.utils.OKDialog;
|
import info.nightscout.utils.OKDialog;
|
||||||
import info.nightscout.utils.Profiler;
|
import info.nightscout.utils.Profiler;
|
||||||
import info.nightscout.utils.SP;
|
import info.nightscout.utils.SP;
|
||||||
import info.nightscout.utils.SingleClickButton;
|
import info.nightscout.utils.SingleClickButton;
|
||||||
|
import info.nightscout.utils.T;
|
||||||
import info.nightscout.utils.ToastUtils;
|
import info.nightscout.utils.ToastUtils;
|
||||||
|
|
||||||
|
import static info.nightscout.utils.DateUtil.now;
|
||||||
|
|
||||||
public class OverviewFragment extends Fragment implements View.OnClickListener, View.OnLongClickListener {
|
public class OverviewFragment extends Fragment implements View.OnClickListener, View.OnLongClickListener {
|
||||||
private static Logger log = LoggerFactory.getLogger(OverviewFragment.class);
|
private static Logger log = LoggerFactory.getLogger(OverviewFragment.class);
|
||||||
|
|
||||||
TextView timeView;
|
TextView timeView;
|
||||||
TextView bgView;
|
TextView bgView;
|
||||||
TextView arrowView;
|
TextView arrowView;
|
||||||
|
TextView sensitivityView;
|
||||||
TextView timeAgoView;
|
TextView timeAgoView;
|
||||||
|
TextView timeAgoShortView;
|
||||||
TextView deltaView;
|
TextView deltaView;
|
||||||
|
TextView deltaShortView;
|
||||||
TextView avgdeltaView;
|
TextView avgdeltaView;
|
||||||
TextView baseBasalView;
|
TextView baseBasalView;
|
||||||
TextView extendedBolusView;
|
TextView extendedBolusView;
|
||||||
|
@ -168,8 +173,6 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
SingleClickButton cgmButton;
|
SingleClickButton cgmButton;
|
||||||
SingleClickButton quickWizardButton;
|
SingleClickButton quickWizardButton;
|
||||||
|
|
||||||
CheckBox lockScreen;
|
|
||||||
|
|
||||||
boolean smallWidth;
|
boolean smallWidth;
|
||||||
boolean smallHeight;
|
boolean smallHeight;
|
||||||
|
|
||||||
|
@ -226,8 +229,11 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
if (smallWidth) {
|
if (smallWidth) {
|
||||||
arrowView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 35);
|
arrowView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 35);
|
||||||
}
|
}
|
||||||
|
sensitivityView = (TextView) view.findViewById(R.id.overview_sensitivity);
|
||||||
timeAgoView = (TextView) view.findViewById(R.id.overview_timeago);
|
timeAgoView = (TextView) view.findViewById(R.id.overview_timeago);
|
||||||
|
timeAgoShortView = (TextView) view.findViewById(R.id.overview_timeagoshort);
|
||||||
deltaView = (TextView) view.findViewById(R.id.overview_delta);
|
deltaView = (TextView) view.findViewById(R.id.overview_delta);
|
||||||
|
deltaShortView = (TextView) view.findViewById(R.id.overview_deltashort);
|
||||||
avgdeltaView = (TextView) view.findViewById(R.id.overview_avgdelta);
|
avgdeltaView = (TextView) view.findViewById(R.id.overview_avgdelta);
|
||||||
baseBasalView = (TextView) view.findViewById(R.id.overview_basebasal);
|
baseBasalView = (TextView) view.findViewById(R.id.overview_basebasal);
|
||||||
extendedBolusView = (TextView) view.findViewById(R.id.overview_extendedbolus);
|
extendedBolusView = (TextView) view.findViewById(R.id.overview_extendedbolus);
|
||||||
|
@ -281,7 +287,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
acceptTempLayout = (LinearLayout) view.findViewById(R.id.overview_accepttemplayout);
|
acceptTempLayout = (LinearLayout) view.findViewById(R.id.overview_accepttemplayout);
|
||||||
|
|
||||||
notificationsView = (RecyclerView) view.findViewById(R.id.overview_notifications);
|
notificationsView = (RecyclerView) view.findViewById(R.id.overview_notifications);
|
||||||
notificationsView.setHasFixedSize(true);
|
notificationsView.setHasFixedSize(false);
|
||||||
llm = new LinearLayoutManager(view.getContext());
|
llm = new LinearLayoutManager(view.getContext());
|
||||||
notificationsView.setLayoutManager(llm);
|
notificationsView.setLayoutManager(llm);
|
||||||
|
|
||||||
|
@ -307,7 +313,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
iobGraph.getGridLabelRenderer().setHorizontalLabelsVisible(false);
|
iobGraph.getGridLabelRenderer().setHorizontalLabelsVisible(false);
|
||||||
bgGraph.getGridLabelRenderer().setLabelVerticalWidth(axisWidth);
|
bgGraph.getGridLabelRenderer().setLabelVerticalWidth(axisWidth);
|
||||||
iobGraph.getGridLabelRenderer().setLabelVerticalWidth(axisWidth);
|
iobGraph.getGridLabelRenderer().setLabelVerticalWidth(axisWidth);
|
||||||
iobGraph.getGridLabelRenderer().setNumVerticalLabels(5);
|
iobGraph.getGridLabelRenderer().setNumVerticalLabels(3);
|
||||||
|
|
||||||
rangeToDisplay = SP.getInt(R.string.key_rangetodisplay, 6);
|
rangeToDisplay = SP.getInt(R.string.key_rangetodisplay, 6);
|
||||||
|
|
||||||
|
@ -324,18 +330,6 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
|
|
||||||
setupChartMenu(view);
|
setupChartMenu(view);
|
||||||
|
|
||||||
lockScreen = (CheckBox) view.findViewById(R.id.overview_lockscreen);
|
|
||||||
if (lockScreen != null) {
|
|
||||||
lockScreen.setChecked(SP.getBoolean("lockscreen", false));
|
|
||||||
lockScreen.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
|
||||||
@Override
|
|
||||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
|
||||||
SP.putBoolean("lockscreen", isChecked);
|
|
||||||
MainApp.bus().post(new EventSetWakeLock(isChecked));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
FabricPrivacy.logException(e);
|
FabricPrivacy.logException(e);
|
||||||
|
@ -351,7 +345,13 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
final LoopPlugin.LastRun finalLastRun = LoopPlugin.lastRun;
|
final LoopPlugin.LastRun finalLastRun = LoopPlugin.lastRun;
|
||||||
final boolean predictionsAvailable = finalLastRun != null && finalLastRun.request.hasPredictions;
|
boolean predictionsAvailable;
|
||||||
|
if (Config.APS)
|
||||||
|
predictionsAvailable = finalLastRun != null && finalLastRun.request.hasPredictions;
|
||||||
|
else if (Config.NSCLIENT)
|
||||||
|
predictionsAvailable = true;
|
||||||
|
else
|
||||||
|
predictionsAvailable = false;
|
||||||
|
|
||||||
MenuItem item;
|
MenuItem item;
|
||||||
CharSequence title;
|
CharSequence title;
|
||||||
|
@ -485,9 +485,18 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
} else if (v == activeProfileView) {
|
} else if (v == activeProfileView) {
|
||||||
menu.setHeaderTitle(MainApp.gs(R.string.profile));
|
menu.setHeaderTitle(MainApp.gs(R.string.profile));
|
||||||
menu.add(MainApp.gs(R.string.danar_viewprofile));
|
menu.add(MainApp.gs(R.string.danar_viewprofile));
|
||||||
if (MainApp.getConfigBuilder().getActiveProfileInterface().getProfile() != null) {
|
if (MainApp.getConfigBuilder().getActiveProfileInterface() != null && MainApp.getConfigBuilder().getActiveProfileInterface().getProfile() != null) {
|
||||||
menu.add(MainApp.gs(R.string.careportal_profileswitch));
|
menu.add(MainApp.gs(R.string.careportal_profileswitch));
|
||||||
}
|
}
|
||||||
|
} else if (v == tempTargetView) {
|
||||||
|
menu.setHeaderTitle(MainApp.gs(R.string.careportal_temporarytarget));
|
||||||
|
menu.add(MainApp.gs(R.string.custom));
|
||||||
|
menu.add(MainApp.gs(R.string.eatingsoon));
|
||||||
|
menu.add(MainApp.gs(R.string.activity));
|
||||||
|
menu.add(MainApp.gs(R.string.hypo));
|
||||||
|
if (TreatmentsPlugin.getPlugin().getTempTargetFromHistory() != null) {
|
||||||
|
menu.add(MainApp.gs(R.string.cancel));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -578,6 +587,53 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
ProfileViewerDialog pvd = ProfileViewerDialog.newInstance(System.currentTimeMillis());
|
ProfileViewerDialog pvd = ProfileViewerDialog.newInstance(System.currentTimeMillis());
|
||||||
FragmentManager manager = getFragmentManager();
|
FragmentManager manager = getFragmentManager();
|
||||||
pvd.show(manager, "ProfileViewDialog");
|
pvd.show(manager, "ProfileViewDialog");
|
||||||
|
} else if (item.getTitle().equals(MainApp.gs(R.string.eatingsoon))) {
|
||||||
|
DefaultValueHelper defHelper = new DefaultValueHelper();
|
||||||
|
double target = defHelper.determineEatingSoonTT(profile.getUnits());
|
||||||
|
TempTarget tempTarget = new TempTarget()
|
||||||
|
.date(System.currentTimeMillis())
|
||||||
|
.duration(defHelper.determineEatingSoonTTDuration())
|
||||||
|
.reason(MainApp.gs(R.string.eatingsoon))
|
||||||
|
.source(Source.USER)
|
||||||
|
.low(target)
|
||||||
|
.high(target);
|
||||||
|
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget);
|
||||||
|
} else if (item.getTitle().equals(MainApp.gs(R.string.activity))) {
|
||||||
|
DefaultValueHelper defHelper = new DefaultValueHelper();
|
||||||
|
double target = defHelper.determineActivityTT(profile.getUnits());
|
||||||
|
TempTarget tempTarget = new TempTarget()
|
||||||
|
.date(now())
|
||||||
|
.duration(defHelper.determineActivityTTDuration())
|
||||||
|
.reason(MainApp.gs(R.string.activity))
|
||||||
|
.source(Source.USER)
|
||||||
|
.low(target)
|
||||||
|
.high(target);
|
||||||
|
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget);
|
||||||
|
} else if (item.getTitle().equals(MainApp.gs(R.string.hypo))) {
|
||||||
|
DefaultValueHelper defHelper = new DefaultValueHelper();
|
||||||
|
double target = defHelper.determineHypoTT(profile.getUnits());
|
||||||
|
TempTarget tempTarget = new TempTarget()
|
||||||
|
.date(now())
|
||||||
|
.duration(defHelper.determineHypoTTDuration())
|
||||||
|
.reason(MainApp.gs(R.string.activity))
|
||||||
|
.source(Source.USER)
|
||||||
|
.low(target)
|
||||||
|
.high(target);
|
||||||
|
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget);
|
||||||
|
} else if (item.getTitle().equals(MainApp.gs(R.string.custom))) {
|
||||||
|
NewNSTreatmentDialog newTTDialog = new NewNSTreatmentDialog();
|
||||||
|
final OptionsToShow temptarget = CareportalFragment.TEMPTARGET;
|
||||||
|
temptarget.executeTempTarget = true;
|
||||||
|
newTTDialog.setOptions(temptarget, R.string.careportal_temporarytarget);
|
||||||
|
newTTDialog.show(getFragmentManager(), "NewNSTreatmentDialog");
|
||||||
|
} else if (item.getTitle().equals(MainApp.gs(R.string.cancel))) {
|
||||||
|
TempTarget tempTarget = new TempTarget()
|
||||||
|
.source(Source.USER)
|
||||||
|
.date(now())
|
||||||
|
.duration(0)
|
||||||
|
.low(0)
|
||||||
|
.high(0);
|
||||||
|
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.onContextItemSelected(item);
|
return super.onContextItemSelected(item);
|
||||||
|
@ -590,6 +646,10 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
String units = MainApp.getConfigBuilder().getProfileUnits();
|
String units = MainApp.getConfigBuilder().getProfileUnits();
|
||||||
|
|
||||||
FragmentManager manager = getFragmentManager();
|
FragmentManager manager = getFragmentManager();
|
||||||
|
// try to fix https://fabric.io/nightscout3/android/apps/info.nightscout.androidaps/issues/5aca7a1536c7b23527eb4be7?time=last-seven-days
|
||||||
|
// https://stackoverflow.com/questions/14860239/checking-if-state-is-saved-before-committing-a-fragmenttransaction
|
||||||
|
if (manager.isStateSaved())
|
||||||
|
return;
|
||||||
switch (v.getId()) {
|
switch (v.getId()) {
|
||||||
case R.id.overview_accepttempbutton:
|
case R.id.overview_accepttempbutton:
|
||||||
onClickAcceptTemp();
|
onClickAcceptTemp();
|
||||||
|
@ -672,12 +732,15 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
|
|
||||||
private void onClickAcceptTemp() {
|
private void onClickAcceptTemp() {
|
||||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||||
|
Context context = getContext();
|
||||||
|
|
||||||
|
if (context == null) return;
|
||||||
|
|
||||||
if (LoopPlugin.getPlugin().isEnabled(PluginType.LOOP) && profile != null) {
|
if (LoopPlugin.getPlugin().isEnabled(PluginType.LOOP) && profile != null) {
|
||||||
LoopPlugin.getPlugin().invoke("Accept temp button", false);
|
LoopPlugin.getPlugin().invoke("Accept temp button", false);
|
||||||
final LoopPlugin.LastRun finalLastRun = LoopPlugin.lastRun;
|
final LoopPlugin.LastRun finalLastRun = LoopPlugin.lastRun;
|
||||||
if (finalLastRun != null && finalLastRun.lastAPSRun != null && finalLastRun.constraintsProcessed.isChangeRequested()) {
|
if (finalLastRun != null && finalLastRun.lastAPSRun != null && finalLastRun.constraintsProcessed.isChangeRequested()) {
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
|
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||||
builder.setTitle(MainApp.gs(R.string.confirmation));
|
builder.setTitle(MainApp.gs(R.string.confirmation));
|
||||||
builder.setMessage(MainApp.gs(R.string.setbasalquestion) + "\n" + finalLastRun.constraintsProcessed);
|
builder.setMessage(MainApp.gs(R.string.setbasalquestion) + "\n" + finalLastRun.constraintsProcessed);
|
||||||
builder.setPositiveButton(MainApp.gs(R.string.ok), (dialog, id) -> {
|
builder.setPositiveButton(MainApp.gs(R.string.ok), (dialog, id) -> {
|
||||||
|
@ -777,7 +840,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
if (wizard.superBolus) {
|
if (wizard.superBolus) {
|
||||||
final LoopPlugin loopPlugin = LoopPlugin.getPlugin();
|
final LoopPlugin loopPlugin = LoopPlugin.getPlugin();
|
||||||
if (loopPlugin.isEnabled(PluginType.LOOP)) {
|
if (loopPlugin.isEnabled(PluginType.LOOP)) {
|
||||||
loopPlugin.superBolusTo(System.currentTimeMillis() + 2 * 60L * 60 * 1000);
|
loopPlugin.superBolusTo(System.currentTimeMillis() + T.hours(2).msecs());
|
||||||
MainApp.bus().post(new EventRefreshOverview("WizardDialog"));
|
MainApp.bus().post(new EventRefreshOverview("WizardDialog"));
|
||||||
}
|
}
|
||||||
ConfigBuilderPlugin.getCommandQueue().tempBasalPercent(0, 120, true, profile, new Callback() {
|
ConfigBuilderPlugin.getCommandQueue().tempBasalPercent(0, 120, true, profile, new Callback() {
|
||||||
|
@ -816,7 +879,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo);
|
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false);
|
||||||
}
|
}
|
||||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("QuickWizard"));
|
FabricPrivacy.getInstance().logCustom(new CustomEvent("QuickWizard"));
|
||||||
}
|
}
|
||||||
|
@ -836,6 +899,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
sLoopHandler.removeCallbacksAndMessages(null);
|
sLoopHandler.removeCallbacksAndMessages(null);
|
||||||
unregisterForContextMenu(apsModeView);
|
unregisterForContextMenu(apsModeView);
|
||||||
unregisterForContextMenu(activeProfileView);
|
unregisterForContextMenu(activeProfileView);
|
||||||
|
unregisterForContextMenu(tempTargetView);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -849,6 +913,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
sLoopHandler.postDelayed(sRefreshLoop, 60 * 1000L);
|
sLoopHandler.postDelayed(sRefreshLoop, 60 * 1000L);
|
||||||
registerForContextMenu(apsModeView);
|
registerForContextMenu(apsModeView);
|
||||||
registerForContextMenu(activeProfileView);
|
registerForContextMenu(activeProfileView);
|
||||||
|
registerForContextMenu(tempTargetView);
|
||||||
updateGUI("onResume");
|
updateGUI("onResume");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -981,16 +1046,19 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
if (timeView != null) { //must not exists
|
if (timeView != null) { //must not exists
|
||||||
timeView.setText(DateUtil.timeString(new Date()));
|
timeView.setText(DateUtil.timeString(new Date()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateNotifications();
|
||||||
|
|
||||||
|
pumpStatusLayout.setVisibility(View.GONE);
|
||||||
|
loopStatusLayout.setVisibility(View.GONE);
|
||||||
|
|
||||||
if (!MainApp.getConfigBuilder().isProfileValid("Overview")) {
|
if (!MainApp.getConfigBuilder().isProfileValid("Overview")) {
|
||||||
pumpStatusView.setText(R.string.noprofileset);
|
pumpStatusView.setText(R.string.noprofileset);
|
||||||
pumpStatusLayout.setVisibility(View.VISIBLE);
|
pumpStatusLayout.setVisibility(View.VISIBLE);
|
||||||
loopStatusLayout.setVisibility(View.GONE);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pumpStatusLayout.setVisibility(View.GONE);
|
|
||||||
loopStatusLayout.setVisibility(View.VISIBLE);
|
loopStatusLayout.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
updateNotifications();
|
|
||||||
CareportalFragment.updateAge(getActivity(), sage, iage, cage, pbage);
|
CareportalFragment.updateAge(getActivity(), sage, iage, cage, pbage);
|
||||||
BgReading actualBG = DatabaseHelper.actualBg();
|
BgReading actualBG = DatabaseHelper.actualBg();
|
||||||
BgReading lastBG = DatabaseHelper.lastBg();
|
BgReading lastBG = DatabaseHelper.lastBg();
|
||||||
|
@ -1017,12 +1085,18 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
arrowView.setTextColor(color);
|
arrowView.setTextColor(color);
|
||||||
GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData();
|
GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData();
|
||||||
if (glucoseStatus != null) {
|
if (glucoseStatus != null) {
|
||||||
deltaView.setText("Δ " + Profile.toUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units) + " " + units);
|
if (deltaView != null)
|
||||||
|
deltaView.setText("Δ " + Profile.toUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units) + " " + units);
|
||||||
|
if (deltaShortView != null)
|
||||||
|
deltaShortView.setText(Profile.toSignedUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units));
|
||||||
if (avgdeltaView != null)
|
if (avgdeltaView != null)
|
||||||
avgdeltaView.setText("øΔ15m: " + Profile.toUnitsString(glucoseStatus.short_avgdelta, glucoseStatus.short_avgdelta * Constants.MGDL_TO_MMOLL, units) +
|
avgdeltaView.setText("øΔ15m: " + Profile.toUnitsString(glucoseStatus.short_avgdelta, glucoseStatus.short_avgdelta * Constants.MGDL_TO_MMOLL, units) +
|
||||||
" øΔ40m: " + Profile.toUnitsString(glucoseStatus.long_avgdelta, glucoseStatus.long_avgdelta * Constants.MGDL_TO_MMOLL, units));
|
" øΔ40m: " + Profile.toUnitsString(glucoseStatus.long_avgdelta, glucoseStatus.long_avgdelta * Constants.MGDL_TO_MMOLL, units));
|
||||||
} else {
|
} else {
|
||||||
deltaView.setText("Δ " + MainApp.gs(R.string.notavailable));
|
if (deltaView != null)
|
||||||
|
deltaView.setText("Δ " + MainApp.gs(R.string.notavailable));
|
||||||
|
if (deltaShortView != null)
|
||||||
|
deltaShortView.setText("---");
|
||||||
if (avgdeltaView != null)
|
if (avgdeltaView != null)
|
||||||
avgdeltaView.setText("");
|
avgdeltaView.setText("");
|
||||||
}
|
}
|
||||||
|
@ -1126,15 +1200,12 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
} else {
|
} else {
|
||||||
basalText = DecimalFormatter.to2Decimal(profile.getBasal()) + "U/h";
|
basalText = DecimalFormatter.to2Decimal(profile.getBasal()) + "U/h";
|
||||||
}
|
}
|
||||||
baseBasalView.setOnClickListener(new View.OnClickListener() {
|
baseBasalView.setOnClickListener(v -> {
|
||||||
@Override
|
String fullText = MainApp.gs(R.string.pump_basebasalrate_label) + ": " + DecimalFormatter.to2Decimal(profile.getBasal()) + "U/h\n";
|
||||||
public void onClick(View v) {
|
if (activeTemp != null) {
|
||||||
String fullText = MainApp.gs(R.string.pump_basebasalrate_label) + ": " + DecimalFormatter.to2Decimal(profile.getBasal()) + "U/h\n";
|
fullText += MainApp.gs(R.string.pump_tempbasal_label) + ": " + activeTemp.toStringFull();
|
||||||
if (activeTemp != null) {
|
|
||||||
fullText += MainApp.gs(R.string.pump_tempbasal_label) + ": " + activeTemp.toStringFull();
|
|
||||||
}
|
|
||||||
OKDialog.show(getActivity(), MainApp.gs(R.string.basal), fullText, null);
|
|
||||||
}
|
}
|
||||||
|
OKDialog.show(getActivity(), MainApp.gs(R.string.basal), fullText, null);
|
||||||
});
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -1163,22 +1234,17 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
if (extendedBolus != null && !pump.isFakingTempsByExtendedBoluses()) {
|
if (extendedBolus != null && !pump.isFakingTempsByExtendedBoluses()) {
|
||||||
extendedBolusText = DecimalFormatter.to2Decimal(extendedBolus.absoluteRate()) + "U/h";
|
extendedBolusText = DecimalFormatter.to2Decimal(extendedBolus.absoluteRate()) + "U/h";
|
||||||
}
|
}
|
||||||
extendedBolusView.setText(extendedBolusText);
|
|
||||||
extendedBolusView.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
OKDialog.show(getActivity(), MainApp.gs(R.string.extendedbolus), extendedBolus.toString(), null);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (extendedBolus != null && !pump.isFakingTempsByExtendedBoluses()) {
|
if (extendedBolus != null && !pump.isFakingTempsByExtendedBoluses()) {
|
||||||
extendedBolusText = extendedBolus.toString();
|
extendedBolusText = extendedBolus.toString();
|
||||||
}
|
}
|
||||||
extendedBolusView.setText(extendedBolusText);
|
}
|
||||||
|
extendedBolusView.setText(extendedBolusText);
|
||||||
|
if (Config.NSCLIENT || Config.G5UPLOADER) {
|
||||||
|
extendedBolusView.setOnClickListener(v -> OKDialog.show(getActivity(), MainApp.gs(R.string.extendedbolus), extendedBolus.toString(), null));
|
||||||
}
|
}
|
||||||
if (extendedBolusText.equals(""))
|
if (extendedBolusText.equals(""))
|
||||||
extendedBolusView.setVisibility(View.GONE);
|
extendedBolusView.setVisibility(Config.NSCLIENT || Config.G5UPLOADER ? View.INVISIBLE : View.GONE);
|
||||||
else
|
else
|
||||||
extendedBolusView.setVisibility(View.VISIBLE);
|
extendedBolusView.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
@ -1186,17 +1252,6 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
activeProfileView.setText(MainApp.getConfigBuilder().getProfileName());
|
activeProfileView.setText(MainApp.getConfigBuilder().getProfileName());
|
||||||
activeProfileView.setBackgroundColor(Color.GRAY);
|
activeProfileView.setBackgroundColor(Color.GRAY);
|
||||||
|
|
||||||
tempTargetView.setOnLongClickListener(view -> {
|
|
||||||
view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
|
|
||||||
NewNSTreatmentDialog newTTDialog = new NewNSTreatmentDialog();
|
|
||||||
final OptionsToShow temptarget = CareportalFragment.TEMPTARGET;
|
|
||||||
temptarget.executeTempTarget = true;
|
|
||||||
newTTDialog.setOptions(temptarget, R.string.careportal_temporarytarget);
|
|
||||||
newTTDialog.show(getFragmentManager(), "NewNSTreatmentDialog");
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
tempTargetView.setLongClickable(true);
|
|
||||||
|
|
||||||
// QuickWizard button
|
// QuickWizard button
|
||||||
QuickWizardEntry quickWizardEntry = OverviewPlugin.getPlugin().quickWizard.getActive();
|
QuickWizardEntry quickWizardEntry = OverviewPlugin.getPlugin().quickWizard.getActive();
|
||||||
if (quickWizardEntry != null && lastBG != null && pump.isInitialized() && !pump.isSuspended()) {
|
if (quickWizardEntry != null && lastBG != null && pump.isInitialized() && !pump.isSuspended()) {
|
||||||
|
@ -1256,7 +1311,10 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
flag &= ~Paint.STRIKE_THRU_TEXT_FLAG;
|
flag &= ~Paint.STRIKE_THRU_TEXT_FLAG;
|
||||||
bgView.setPaintFlags(flag);
|
bgView.setPaintFlags(flag);
|
||||||
|
|
||||||
timeAgoView.setText(DateUtil.minAgo(lastBG.date));
|
if (timeAgoView != null)
|
||||||
|
timeAgoView.setText(DateUtil.minAgo(lastBG.date));
|
||||||
|
if (timeAgoShortView != null)
|
||||||
|
timeAgoShortView.setText("(" + DateUtil.minAgoShort(lastBG.date) + ")");
|
||||||
|
|
||||||
// iob
|
// iob
|
||||||
TreatmentsPlugin.getPlugin().updateTotalIOBTreatments();
|
TreatmentsPlugin.getPlugin().updateTotalIOBTreatments();
|
||||||
|
@ -1297,7 +1355,15 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
cobView.setText(cobText);
|
cobView.setText(cobText);
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean predictionsAvailable = finalLastRun != null && finalLastRun.request.hasPredictions;
|
boolean predictionsAvailable;
|
||||||
|
if (Config.APS)
|
||||||
|
predictionsAvailable = finalLastRun != null && finalLastRun.request.hasPredictions;
|
||||||
|
else if (Config.NSCLIENT)
|
||||||
|
predictionsAvailable = true;
|
||||||
|
else
|
||||||
|
predictionsAvailable = false;
|
||||||
|
final boolean finalPredictionsAvailable = predictionsAvailable;
|
||||||
|
|
||||||
// pump status from ns
|
// pump status from ns
|
||||||
if (pumpDeviceStatusView != null) {
|
if (pumpDeviceStatusView != null) {
|
||||||
pumpDeviceStatusView.setText(NSDeviceStatus.getInstance().getPumpStatus());
|
pumpDeviceStatusView.setText(NSDeviceStatus.getInstance().getPumpStatus());
|
||||||
|
@ -1316,6 +1382,15 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
uploaderDeviceStatusView.setOnClickListener(v -> OKDialog.show(getActivity(), MainApp.gs(R.string.uploader), NSDeviceStatus.getInstance().getExtendedUploaderStatus(), null));
|
uploaderDeviceStatusView.setOnClickListener(v -> OKDialog.show(getActivity(), MainApp.gs(R.string.uploader), NSDeviceStatus.getInstance().getExtendedUploaderStatus(), null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sensitivity
|
||||||
|
if (sensitivityView != null) {
|
||||||
|
AutosensResult lastAutosensResult = IobCobCalculatorPlugin.getPlugin().detectSensitivityWithLock(IobCobCalculatorPlugin.getPlugin().oldestDataAvailable(), System.currentTimeMillis());
|
||||||
|
if (lastAutosensResult != null)
|
||||||
|
sensitivityView.setText(String.format("%.0f%%", lastAutosensResult.ratio * 100));
|
||||||
|
else
|
||||||
|
sensitivityView.setText("");
|
||||||
|
}
|
||||||
|
|
||||||
// ****** GRAPH *******
|
// ****** GRAPH *******
|
||||||
|
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
|
@ -1331,18 +1406,25 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
final long toTime;
|
final long toTime;
|
||||||
final long fromTime;
|
final long fromTime;
|
||||||
final long endTime;
|
final long endTime;
|
||||||
if (predictionsAvailable && SP.getBoolean("showprediction", false)) {
|
|
||||||
int predHours = (int) (Math.ceil(finalLastRun.constraintsProcessed.getLatestPredictionsTime() - System.currentTimeMillis()) / (60 * 60 * 1000));
|
APSResult apsResult = null;
|
||||||
|
|
||||||
|
if (finalPredictionsAvailable && SP.getBoolean("showprediction", false)) {
|
||||||
|
if (Config.APS)
|
||||||
|
apsResult = finalLastRun.constraintsProcessed;
|
||||||
|
else
|
||||||
|
apsResult = NSDeviceStatus.getAPSResult();
|
||||||
|
int predHours = (int) (Math.ceil(apsResult.getLatestPredictionsTime() - System.currentTimeMillis()) / (60 * 60 * 1000));
|
||||||
predHours = Math.min(2, predHours);
|
predHours = Math.min(2, predHours);
|
||||||
predHours = Math.max(0, predHours);
|
predHours = Math.max(0, predHours);
|
||||||
hoursToFetch = rangeToDisplay - predHours;
|
hoursToFetch = rangeToDisplay - predHours;
|
||||||
toTime = calendar.getTimeInMillis() + 100000; // little bit more to avoid wrong rounding - Graphview specific
|
toTime = calendar.getTimeInMillis() + 100000; // little bit more to avoid wrong rounding - Graphview specific
|
||||||
fromTime = toTime - hoursToFetch * 60 * 60 * 1000L;
|
fromTime = toTime - T.hours(hoursToFetch).msecs();
|
||||||
endTime = toTime + predHours * 60 * 60 * 1000L;
|
endTime = toTime + T.hours(predHours).msecs();
|
||||||
} else {
|
} else {
|
||||||
hoursToFetch = rangeToDisplay;
|
hoursToFetch = rangeToDisplay;
|
||||||
toTime = calendar.getTimeInMillis() + 100000; // little bit more to avoid wrong rounding - Graphview specific
|
toTime = calendar.getTimeInMillis() + 100000; // little bit more to avoid wrong rounding - Graphview specific
|
||||||
fromTime = toTime - hoursToFetch * 60 * 60 * 1000L;
|
fromTime = toTime - T.hours(hoursToFetch).msecs();
|
||||||
endTime = toTime;
|
endTime = toTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1358,9 +1440,9 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
graphData.addInRangeArea(fromTime, endTime, lowLine, highLine);
|
graphData.addInRangeArea(fromTime, endTime, lowLine, highLine);
|
||||||
|
|
||||||
// **** BG ****
|
// **** BG ****
|
||||||
if (predictionsAvailable && SP.getBoolean("showprediction", false))
|
if (finalPredictionsAvailable && SP.getBoolean("showprediction", false))
|
||||||
graphData.addBgReadings(fromTime, toTime, lowLine, highLine,
|
graphData.addBgReadings(fromTime, toTime, lowLine, highLine,
|
||||||
finalLastRun.constraintsProcessed.getPredictions());
|
apsResult.getPredictions());
|
||||||
else
|
else
|
||||||
graphData.addBgReadings(fromTime, toTime, lowLine, highLine, null);
|
graphData.addBgReadings(fromTime, toTime, lowLine, highLine, null);
|
||||||
|
|
||||||
|
@ -1412,7 +1494,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
secondGraphData.addDeviations(fromTime, now, useDevForScale, 1d);
|
secondGraphData.addDeviations(fromTime, now, useDevForScale, 1d);
|
||||||
if (SP.getBoolean("showratios", false))
|
if (SP.getBoolean("showratios", false))
|
||||||
secondGraphData.addRatio(fromTime, now, useRatioForScale, 1d);
|
secondGraphData.addRatio(fromTime, now, useRatioForScale, 1d);
|
||||||
if (SP.getBoolean("showdevslope", false))
|
if (SP.getBoolean("showdevslope", false) && MainApp.devBranch)
|
||||||
secondGraphData.addDeviationSlope(fromTime, now, useDSForScale, 1d);
|
secondGraphData.addDeviationSlope(fromTime, now, useDSForScale, 1d);
|
||||||
|
|
||||||
// **** NOW line ****
|
// **** NOW line ****
|
||||||
|
|
|
@ -50,6 +50,7 @@ public class OverviewPlugin extends PluginBase {
|
||||||
.pluginName(R.string.overview)
|
.pluginName(R.string.overview)
|
||||||
.shortName(R.string.overview_shortname)
|
.shortName(R.string.overview_shortname)
|
||||||
.preferencesId(R.xml.pref_overview)
|
.preferencesId(R.xml.pref_overview)
|
||||||
|
.description(R.string.description_overview)
|
||||||
);
|
);
|
||||||
String storedData = SP.getString("QuickWizard", "[]");
|
String storedData = SP.getString("QuickWizard", "[]");
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
package info.nightscout.androidaps.plugins.Overview.events;
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.events.Event;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by mike on 02.07.2017.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class EventSetWakeLock extends Event {
|
|
||||||
public boolean lock = false;
|
|
||||||
|
|
||||||
public EventSetWakeLock(boolean val) {
|
|
||||||
lock = val;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -49,7 +49,8 @@ import info.nightscout.utils.Round;
|
||||||
public class GraphData {
|
public class GraphData {
|
||||||
|
|
||||||
private GraphView graph;
|
private GraphView graph;
|
||||||
public double maxY = 0;
|
public double maxY = Double.MIN_VALUE;
|
||||||
|
public double minY = Double.MAX_VALUE;
|
||||||
private List<BgReading> bgReadingsArray;
|
private List<BgReading> bgReadingsArray;
|
||||||
private String units;
|
private String units;
|
||||||
private List<Series> series = new ArrayList<>();
|
private List<Series> series = new ArrayList<>();
|
||||||
|
@ -63,7 +64,7 @@ public class GraphData {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addBgReadings(long fromTime, long toTime, double lowLine, double highLine, List<BgReading> predictions) {
|
public void addBgReadings(long fromTime, long toTime, double lowLine, double highLine, List<BgReading> predictions) {
|
||||||
double maxBgValue = 0d;
|
double maxBgValue = Double.MIN_VALUE;
|
||||||
bgReadingsArray = MainApp.getDbHelper().getBgreadingsDataFromTime(fromTime, true);
|
bgReadingsArray = MainApp.getDbHelper().getBgreadingsDataFromTime(fromTime, true);
|
||||||
List<DataPointWithLabelInterface> bgListArray = new ArrayList<>();
|
List<DataPointWithLabelInterface> bgListArray = new ArrayList<>();
|
||||||
|
|
||||||
|
@ -93,10 +94,8 @@ public class GraphData {
|
||||||
|
|
||||||
|
|
||||||
maxY = maxBgValue;
|
maxY = maxBgValue;
|
||||||
|
minY = 0;
|
||||||
// set manual y bounds to have nice steps
|
// set manual y bounds to have nice steps
|
||||||
graph.getViewport().setMaxY(maxY);
|
|
||||||
graph.getViewport().setMinY(0);
|
|
||||||
graph.getViewport().setYAxisBoundsManual(true);
|
|
||||||
graph.getGridLabelRenderer().setNumVerticalLabels(numOfVertLines);
|
graph.getGridLabelRenderer().setNumVerticalLabels(numOfVertLines);
|
||||||
|
|
||||||
addSeries(new PointsWithLabelGraphSeries<>(bg));
|
addSeries(new PointsWithLabelGraphSeries<>(bg));
|
||||||
|
@ -136,7 +135,9 @@ public class GraphData {
|
||||||
double lastBaseBasal = 0;
|
double lastBaseBasal = 0;
|
||||||
double lastTempBasal = 0;
|
double lastTempBasal = 0;
|
||||||
for (long time = fromTime; time < toTime; time += 60 * 1000L) {
|
for (long time = fromTime; time < toTime; time += 60 * 1000L) {
|
||||||
BasalData basalData = IobCobCalculatorPlugin.getPlugin().getBasalData(time);
|
Profile profile = MainApp.getConfigBuilder().getProfile(time);
|
||||||
|
if (profile == null) continue;
|
||||||
|
BasalData basalData = IobCobCalculatorPlugin.getPlugin().getBasalData(profile, time);
|
||||||
double baseBasalValue = basalData.basal;
|
double baseBasalValue = basalData.basal;
|
||||||
double absoluteLineValue = baseBasalValue;
|
double absoluteLineValue = baseBasalValue;
|
||||||
double tempBasalValue = 0;
|
double tempBasalValue = 0;
|
||||||
|
@ -333,7 +334,7 @@ public class GraphData {
|
||||||
public void addIob(long fromTime, long toTime, boolean useForScale, double scale) {
|
public void addIob(long fromTime, long toTime, boolean useForScale, double scale) {
|
||||||
FixedLineGraphSeries<ScaledDataPoint> iobSeries;
|
FixedLineGraphSeries<ScaledDataPoint> iobSeries;
|
||||||
List<ScaledDataPoint> iobArray = new ArrayList<>();
|
List<ScaledDataPoint> iobArray = new ArrayList<>();
|
||||||
Double maxIobValueFound = 0d;
|
Double maxIobValueFound = Double.MIN_VALUE;
|
||||||
double lastIob = 0;
|
double lastIob = 0;
|
||||||
Scale iobScale = new Scale();
|
Scale iobScale = new Scale();
|
||||||
|
|
||||||
|
@ -359,8 +360,10 @@ public class GraphData {
|
||||||
iobSeries.setColor(MainApp.gc(R.color.iob));
|
iobSeries.setColor(MainApp.gc(R.color.iob));
|
||||||
iobSeries.setThickness(3);
|
iobSeries.setThickness(3);
|
||||||
|
|
||||||
if (useForScale)
|
if (useForScale) {
|
||||||
maxY = maxIobValueFound;
|
maxY = maxIobValueFound;
|
||||||
|
minY = -maxIobValueFound;
|
||||||
|
}
|
||||||
|
|
||||||
iobScale.setMultiplier(maxY * scale / maxIobValueFound);
|
iobScale.setMultiplier(maxY * scale / maxIobValueFound);
|
||||||
|
|
||||||
|
@ -404,8 +407,10 @@ public class GraphData {
|
||||||
cobSeries.setColor(MainApp.gc(R.color.cob));
|
cobSeries.setColor(MainApp.gc(R.color.cob));
|
||||||
cobSeries.setThickness(3);
|
cobSeries.setThickness(3);
|
||||||
|
|
||||||
if (useForScale)
|
if (useForScale) {
|
||||||
maxY = maxCobValueFound;
|
maxY = maxCobValueFound;
|
||||||
|
minY = 0;
|
||||||
|
}
|
||||||
|
|
||||||
cobScale.setMultiplier(maxY * scale / maxCobValueFound);
|
cobScale.setMultiplier(maxY * scale / maxCobValueFound);
|
||||||
|
|
||||||
|
@ -436,9 +441,18 @@ public class GraphData {
|
||||||
AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getAutosensData(time);
|
AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getAutosensData(time);
|
||||||
if (autosensData != null) {
|
if (autosensData != null) {
|
||||||
int color = MainApp.gc(R.color.deviationblack); // "="
|
int color = MainApp.gc(R.color.deviationblack); // "="
|
||||||
if (autosensData.pastSensitivity.equals("C")) color = MainApp.gc(R.color.deviationgrey);
|
if (autosensData.type.equals("") || autosensData.type.equals("non-meal")) {
|
||||||
if (autosensData.pastSensitivity.equals("+")) color = MainApp.gc(R.color.deviationgreen);
|
if (autosensData.pastSensitivity.equals("C"))
|
||||||
if (autosensData.pastSensitivity.equals("-")) color = MainApp.gc(R.color.deviationred);
|
color = MainApp.gc(R.color.deviationgrey);
|
||||||
|
if (autosensData.pastSensitivity.equals("+"))
|
||||||
|
color = MainApp.gc(R.color.deviationgreen);
|
||||||
|
if (autosensData.pastSensitivity.equals("-"))
|
||||||
|
color = MainApp.gc(R.color.deviationred);
|
||||||
|
} else if (autosensData.type.equals("uam")) {
|
||||||
|
color = MainApp.gc(R.color.uam);
|
||||||
|
} else if (autosensData.type.equals("csf")) {
|
||||||
|
color = MainApp.gc(R.color.deviationgrey);
|
||||||
|
}
|
||||||
devArray.add(new DeviationDataPoint(time, autosensData.deviation, color, devScale));
|
devArray.add(new DeviationDataPoint(time, autosensData.deviation, color, devScale));
|
||||||
maxDevValueFound = Math.max(maxDevValueFound, Math.abs(autosensData.deviation));
|
maxDevValueFound = Math.max(maxDevValueFound, Math.abs(autosensData.deviation));
|
||||||
}
|
}
|
||||||
|
@ -455,8 +469,10 @@ public class GraphData {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (useForScale)
|
if (useForScale) {
|
||||||
maxY = maxDevValueFound;
|
maxY = maxDevValueFound;
|
||||||
|
minY = -maxY;
|
||||||
|
}
|
||||||
|
|
||||||
devScale.setMultiplier(maxY * scale / maxDevValueFound);
|
devScale.setMultiplier(maxY * scale / maxDevValueFound);
|
||||||
|
|
||||||
|
@ -467,14 +483,16 @@ public class GraphData {
|
||||||
public void addRatio(long fromTime, long toTime, boolean useForScale, double scale) {
|
public void addRatio(long fromTime, long toTime, boolean useForScale, double scale) {
|
||||||
LineGraphSeries<ScaledDataPoint> ratioSeries;
|
LineGraphSeries<ScaledDataPoint> ratioSeries;
|
||||||
List<ScaledDataPoint> ratioArray = new ArrayList<>();
|
List<ScaledDataPoint> ratioArray = new ArrayList<>();
|
||||||
Double maxRatioValueFound = 0d;
|
Double maxRatioValueFound = Double.MIN_VALUE;
|
||||||
Scale ratioScale = new Scale(-1d);
|
Double minRatioValueFound = Double.MAX_VALUE;
|
||||||
|
Scale ratioScale = new Scale();
|
||||||
|
|
||||||
for (long time = fromTime; time <= toTime; time += 5 * 60 * 1000L) {
|
for (long time = fromTime; time <= toTime; time += 5 * 60 * 1000L) {
|
||||||
AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getAutosensData(time);
|
AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getAutosensData(time);
|
||||||
if (autosensData != null) {
|
if (autosensData != null) {
|
||||||
ratioArray.add(new ScaledDataPoint(time, autosensData.autosensRatio, ratioScale));
|
ratioArray.add(new ScaledDataPoint(time, autosensData.autosensResult.ratio - 1, ratioScale));
|
||||||
maxRatioValueFound = Math.max(maxRatioValueFound, Math.abs(autosensData.autosensRatio));
|
maxRatioValueFound = Math.max(maxRatioValueFound, autosensData.autosensResult.ratio - 1);
|
||||||
|
minRatioValueFound = Math.min(minRatioValueFound, autosensData.autosensResult.ratio - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -485,8 +503,10 @@ public class GraphData {
|
||||||
ratioSeries.setColor(MainApp.gc(R.color.ratio));
|
ratioSeries.setColor(MainApp.gc(R.color.ratio));
|
||||||
ratioSeries.setThickness(3);
|
ratioSeries.setThickness(3);
|
||||||
|
|
||||||
if (useForScale)
|
if (useForScale) {
|
||||||
maxY = maxRatioValueFound;
|
maxY = maxRatioValueFound;
|
||||||
|
minY = minRatioValueFound;
|
||||||
|
}
|
||||||
|
|
||||||
ratioScale.setMultiplier(maxY * scale / maxRatioValueFound);
|
ratioScale.setMultiplier(maxY * scale / maxRatioValueFound);
|
||||||
|
|
||||||
|
@ -527,8 +547,10 @@ public class GraphData {
|
||||||
dsMinSeries.setColor(MainApp.gc(R.color.devslopeneg));
|
dsMinSeries.setColor(MainApp.gc(R.color.devslopeneg));
|
||||||
dsMinSeries.setThickness(3);
|
dsMinSeries.setThickness(3);
|
||||||
|
|
||||||
if (useForScale)
|
if (useForScale) {
|
||||||
maxY = Math.max(maxFromMaxValueFound, maxFromMinValueFound);
|
maxY = Math.max(maxFromMaxValueFound, maxFromMinValueFound);
|
||||||
|
minY = -maxY;
|
||||||
|
}
|
||||||
|
|
||||||
dsMaxScale.setMultiplier(maxY * scale / maxFromMaxValueFound);
|
dsMaxScale.setMultiplier(maxY * scale / maxFromMaxValueFound);
|
||||||
dsMinScale.setMultiplier(maxY * scale / maxFromMinValueFound);
|
dsMinScale.setMultiplier(maxY * scale / maxFromMinValueFound);
|
||||||
|
@ -582,6 +604,10 @@ public class GraphData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
graph.getViewport().setMaxY(Round.ceilTo(maxY, 1d));
|
||||||
|
graph.getViewport().setMinY(Round.floorTo(minY, 1d));
|
||||||
|
graph.getViewport().setYAxisBoundsManual(true);
|
||||||
|
|
||||||
// draw it
|
// draw it
|
||||||
graph.onDataChanged(false, false);
|
graph.onDataChanged(false, false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -312,20 +312,20 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
|
||||||
mPaint.setStrokeWidth(5);
|
mPaint.setStrokeWidth(5);
|
||||||
canvas.drawRect(px - 3, bounds.top + py - 3, xpluslength + 3, bounds.bottom + py + 3, mPaint);
|
canvas.drawRect(px - 3, bounds.top + py - 3, xpluslength + 3, bounds.bottom + py + 3, mPaint);
|
||||||
}
|
}
|
||||||
} else if (value.getShape() == Shape.OPENAPSOFFLINE) {
|
} else if (value.getShape() == Shape.OPENAPSOFFLINE && value.getDuration() != 0) {
|
||||||
mPaint.setStrokeWidth(0);
|
mPaint.setStrokeWidth(0);
|
||||||
if (value.getLabel() != null) {
|
if (value.getLabel() != null) {
|
||||||
mPaint.setStrokeWidth(0);
|
//mPaint.setStrokeWidth(0);
|
||||||
mPaint.setTextSize(scaledTextSize);
|
//mPaint.setTextSize(scaledTextSize);
|
||||||
mPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
|
//mPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
|
||||||
Rect bounds = new Rect();
|
Rect bounds = new Rect();
|
||||||
mPaint.getTextBounds(value.getLabel(), 0, value.getLabel().length(), bounds);
|
//mPaint.getTextBounds(value.getLabel(), 0, value.getLabel().length(), bounds);
|
||||||
mPaint.setStyle(Paint.Style.STROKE);
|
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
|
||||||
float px = endX;
|
float px = endX;
|
||||||
float py = graphTop + 50;
|
float py = graphTop + 50;
|
||||||
canvas.drawText(value.getLabel(), px, py, mPaint);
|
//canvas.drawText(value.getLabel(), px, py, mPaint);
|
||||||
mPaint.setStrokeWidth(5);
|
mPaint.setStrokeWidth(5);
|
||||||
canvas.drawRect(px - 3, bounds.top + py - 3, xpluslength + 3, bounds.bottom + py + 3, mPaint);
|
canvas.drawRect(px - 3, graphTop, xpluslength + 3, graphTop + graphHeight, mPaint);
|
||||||
}
|
}
|
||||||
} else if (value.getShape() == Shape.GENERALWITHDURATION) {
|
} else if (value.getShape() == Shape.GENERALWITHDURATION) {
|
||||||
mPaint.setStrokeWidth(0);
|
mPaint.setStrokeWidth(0);
|
||||||
|
|
|
@ -42,6 +42,8 @@ public class Notification {
|
||||||
public static final int APPROACHING_DAILY_LIMIT = 11;
|
public static final int APPROACHING_DAILY_LIMIT = 11;
|
||||||
public static final int NSCLIENT_NO_WRITE_PERMISSION = 12;
|
public static final int NSCLIENT_NO_WRITE_PERMISSION = 12;
|
||||||
public static final int MISSING_SMS_PERMISSION = 13;
|
public static final int MISSING_SMS_PERMISSION = 13;
|
||||||
|
public static final int PUMPERROR = 14;
|
||||||
|
public static final int WRONGSERIALNUMBER = 15;
|
||||||
|
|
||||||
public static final int NSANNOUNCEMENT = 18;
|
public static final int NSANNOUNCEMENT = 18;
|
||||||
public static final int NSALARM = 19;
|
public static final int NSALARM = 19;
|
||||||
|
@ -59,6 +61,13 @@ public class Notification {
|
||||||
public static final int ZERO_VALUE_IN_PROFILE = 31;
|
public static final int ZERO_VALUE_IN_PROFILE = 31;
|
||||||
public static final int PROFILE_SWITCH_MISSING = 32;
|
public static final int PROFILE_SWITCH_MISSING = 32;
|
||||||
public static final int NOT_ENG_MODE_OR_RELEASE = 33;
|
public static final int NOT_ENG_MODE_OR_RELEASE = 33;
|
||||||
|
public static final int WRONG_PUMP_PASSWORD = 34;
|
||||||
|
public static final int PERMISSION_STORAGE = 35;
|
||||||
|
public static final int PERMISSION_LOCATION = 36;
|
||||||
|
public static final int PERMISSION_BATTERY = 37;
|
||||||
|
public static final int PERMISSION_SMS = 38;
|
||||||
|
public static final int MAXIMUM_BASAL_VALUE_REPLACED = 39;
|
||||||
|
|
||||||
|
|
||||||
public int id;
|
public int id;
|
||||||
public Date date;
|
public Date date;
|
||||||
|
|
|
@ -42,9 +42,12 @@ public class NotificationRecyclerViewAdapter extends RecyclerView.Adapter<Notifi
|
||||||
public void onBindViewHolder(NotificationsViewHolder holder, int position) {
|
public void onBindViewHolder(NotificationsViewHolder holder, int position) {
|
||||||
Notification notification = notificationsList.get(position);
|
Notification notification = notificationsList.get(position);
|
||||||
holder.dismiss.setTag(notification);
|
holder.dismiss.setTag(notification);
|
||||||
if (Objects.equals(notification.text, MainApp.gs(R.string.nsalarm_staledata)))
|
if (notification instanceof NotificationWithAction)
|
||||||
|
holder.dismiss.setText(((NotificationWithAction) notification).buttonText);
|
||||||
|
else if (Objects.equals(notification.text, MainApp.gs(R.string.nsalarm_staledata)))
|
||||||
holder.dismiss.setText("snooze");
|
holder.dismiss.setText("snooze");
|
||||||
holder.text.setText(notification.text);
|
|
||||||
|
holder.text.setText(notification.text + '\n');
|
||||||
holder.time.setText(DateUtil.timeString(notification.date));
|
holder.time.setText(DateUtil.timeString(notification.date));
|
||||||
if (notification.level == Notification.URGENT)
|
if (notification.level == Notification.URGENT)
|
||||||
holder.cv.setBackgroundColor(ContextCompat.getColor(MainApp.instance(), R.color.notificationUrgent));
|
holder.cv.setBackgroundColor(ContextCompat.getColor(MainApp.instance(), R.color.notificationUrgent));
|
||||||
|
@ -100,6 +103,9 @@ public class NotificationRecyclerViewAdapter extends RecyclerView.Adapter<Notifi
|
||||||
log.debug("snooze nsalarm_staledatavalue in minutes is " + SP.getInt("nsalarm_staledatavalue", 15) + "\n in ms is: " + msToSnooze + " currentTimeMillis is: " + System.currentTimeMillis());
|
log.debug("snooze nsalarm_staledatavalue in minutes is " + SP.getInt("nsalarm_staledatavalue", 15) + "\n in ms is: " + msToSnooze + " currentTimeMillis is: " + System.currentTimeMillis());
|
||||||
nstore.snoozeTo(System.currentTimeMillis() + (SP.getInt("nsalarm_staledatavalue", 15) * 60 * 1000L));
|
nstore.snoozeTo(System.currentTimeMillis() + (SP.getInt("nsalarm_staledatavalue", 15) * 60 * 1000L));
|
||||||
}
|
}
|
||||||
|
if (notification instanceof NotificationWithAction) {
|
||||||
|
((NotificationWithAction) notification).action.run();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.Config;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.Services.AlarmSoundService;
|
import info.nightscout.androidaps.Services.AlarmSoundService;
|
||||||
|
@ -61,7 +62,7 @@ public class NotificationStore {
|
||||||
}
|
}
|
||||||
store.add(n);
|
store.add(n);
|
||||||
|
|
||||||
if (SP.getBoolean(MainApp.gs(R.string.key_raise_notifications_as_android_notifications), false)) {
|
if (SP.getBoolean(MainApp.gs(R.string.key_raise_notifications_as_android_notifications), false) && !(n instanceof NotificationWithAction)) {
|
||||||
raiseSystemNotification(n);
|
raiseSystemNotification(n);
|
||||||
if (usesChannels && n.soundId != null) {
|
if (usesChannels && n.soundId != null) {
|
||||||
Intent alarm = new Intent(MainApp.instance().getApplicationContext(), AlarmSoundService.class);
|
Intent alarm = new Intent(MainApp.instance().getApplicationContext(), AlarmSoundService.class);
|
||||||
|
@ -123,10 +124,15 @@ public class NotificationStore {
|
||||||
Context context = MainApp.instance().getApplicationContext();
|
Context context = MainApp.instance().getApplicationContext();
|
||||||
NotificationManager mgr = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
NotificationManager mgr = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
Bitmap largeIcon = BitmapFactory.decodeResource(context.getResources(), R.mipmap.blueowl);
|
Bitmap largeIcon = BitmapFactory.decodeResource(context.getResources(), R.mipmap.blueowl);
|
||||||
|
int smallIcon = R.drawable.ic_notification;
|
||||||
|
if (Config.NSCLIENT || Config.G5UPLOADER){
|
||||||
|
largeIcon = BitmapFactory.decodeResource(MainApp.instance().getResources(), R.mipmap.yellowowl);
|
||||||
|
smallIcon = R.drawable.nsclient_smallicon;
|
||||||
|
}
|
||||||
Uri sound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
|
Uri sound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
|
||||||
NotificationCompat.Builder notificationBuilder =
|
NotificationCompat.Builder notificationBuilder =
|
||||||
new NotificationCompat.Builder(context, CHANNEL_ID)
|
new NotificationCompat.Builder(context, CHANNEL_ID)
|
||||||
.setSmallIcon(R.drawable.ic_notification)
|
.setSmallIcon(smallIcon)
|
||||||
.setLargeIcon(largeIcon)
|
.setLargeIcon(largeIcon)
|
||||||
.setContentText(n.text)
|
.setContentText(n.text)
|
||||||
.setPriority(NotificationCompat.PRIORITY_MAX)
|
.setPriority(NotificationCompat.PRIORITY_MAX)
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
package info.nightscout.androidaps.plugins.Overview.notifications;
|
||||||
|
|
||||||
|
public class NotificationWithAction extends Notification {
|
||||||
|
|
||||||
|
Runnable action;
|
||||||
|
String buttonText;
|
||||||
|
|
||||||
|
public NotificationWithAction(int id, String text, int level) {
|
||||||
|
super(id, text, level);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void action(String buttonText, Runnable action) {
|
||||||
|
this.buttonText = buttonText;
|
||||||
|
this.action = action;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package info.nightscout.androidaps.plugins.Persistentnotification;
|
||||||
|
|
||||||
|
import android.app.Notification;
|
||||||
|
import android.app.Service;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keeps AndroidAPS in foreground state, so it won't be terminated by Android nor get restricted by the background execution limits
|
||||||
|
*/
|
||||||
|
public class DummyService extends Service {
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public IBinder onBind(Intent intent) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||||
|
Notification notification = PersistentNotificationPlugin.getPlugin().updateNotification();
|
||||||
|
if (notification != null)
|
||||||
|
startForeground(PersistentNotificationPlugin.ONGOING_NOTIFICATION_ID, notification);
|
||||||
|
return START_STICKY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
stopForeground(true);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
package info.nightscout.androidaps.plugins.Persistentnotification;
|
package info.nightscout.androidaps.plugins.Persistentnotification;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
|
import android.app.Notification;
|
||||||
import android.app.NotificationChannel;
|
import android.app.NotificationChannel;
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
|
@ -14,6 +15,7 @@ import android.support.v4.app.TaskStackBuilder;
|
||||||
|
|
||||||
import com.squareup.otto.Subscribe;
|
import com.squareup.otto.Subscribe;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.Config;
|
||||||
import info.nightscout.androidaps.Constants;
|
import info.nightscout.androidaps.Constants;
|
||||||
import info.nightscout.androidaps.MainActivity;
|
import info.nightscout.androidaps.MainActivity;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
|
@ -35,7 +37,6 @@ import info.nightscout.androidaps.interfaces.PluginBase;
|
||||||
import info.nightscout.androidaps.interfaces.PluginDescription;
|
import info.nightscout.androidaps.interfaces.PluginDescription;
|
||||||
import info.nightscout.androidaps.interfaces.PluginType;
|
import info.nightscout.androidaps.interfaces.PluginType;
|
||||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||||
import info.nightscout.androidaps.plugins.IobCobCalculator.CobInfo;
|
|
||||||
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
|
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.utils.DecimalFormatter;
|
import info.nightscout.utils.DecimalFormatter;
|
||||||
|
@ -46,9 +47,16 @@ import info.nightscout.utils.DecimalFormatter;
|
||||||
|
|
||||||
public class PersistentNotificationPlugin extends PluginBase {
|
public class PersistentNotificationPlugin extends PluginBase {
|
||||||
|
|
||||||
|
private static PersistentNotificationPlugin plugin;
|
||||||
|
|
||||||
|
public static PersistentNotificationPlugin getPlugin() {
|
||||||
|
if (plugin == null) plugin = new PersistentNotificationPlugin(MainApp.instance());
|
||||||
|
return plugin;
|
||||||
|
}
|
||||||
|
|
||||||
public static final String CHANNEL_ID = "AndroidAPS-Ongoing";
|
public static final String CHANNEL_ID = "AndroidAPS-Ongoing";
|
||||||
|
|
||||||
private static final int ONGOING_NOTIFICATION_ID = 4711;
|
public static final int ONGOING_NOTIFICATION_ID = 4711;
|
||||||
private final Context ctx;
|
private final Context ctx;
|
||||||
|
|
||||||
public PersistentNotificationPlugin(Context ctx) {
|
public PersistentNotificationPlugin(Context ctx) {
|
||||||
|
@ -57,6 +65,8 @@ public class PersistentNotificationPlugin extends PluginBase {
|
||||||
.neverVisible(true)
|
.neverVisible(true)
|
||||||
.pluginName(R.string.ongoingnotificaction)
|
.pluginName(R.string.ongoingnotificaction)
|
||||||
.enableByDefault(true)
|
.enableByDefault(true)
|
||||||
|
.alwaysEnabled(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
||||||
|
.description(R.string.description_persistent_notification)
|
||||||
);
|
);
|
||||||
this.ctx = ctx;
|
this.ctx = ctx;
|
||||||
}
|
}
|
||||||
|
@ -65,7 +75,7 @@ public class PersistentNotificationPlugin extends PluginBase {
|
||||||
protected void onStart() {
|
protected void onStart() {
|
||||||
MainApp.bus().register(this);
|
MainApp.bus().register(this);
|
||||||
createNotificationChannel();
|
createNotificationChannel();
|
||||||
updateNotification();
|
triggerNotificationUpdate();
|
||||||
super.onStart();
|
super.onStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,20 +94,22 @@ public class PersistentNotificationPlugin extends PluginBase {
|
||||||
@Override
|
@Override
|
||||||
protected void onStop() {
|
protected void onStop() {
|
||||||
MainApp.bus().unregister(this);
|
MainApp.bus().unregister(this);
|
||||||
NotificationManager mNotificationManager =
|
MainApp.instance().stopService(new Intent(MainApp.instance(), DummyService.class));
|
||||||
(NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
|
|
||||||
mNotificationManager.cancel(ONGOING_NOTIFICATION_ID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateNotification() {
|
private void triggerNotificationUpdate() {
|
||||||
|
MainApp.instance().startService(new Intent(MainApp.instance(), DummyService.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
Notification updateNotification() {
|
||||||
if (!isEnabled(PluginType.GENERAL)) {
|
if (!isEnabled(PluginType.GENERAL)) {
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
String line1 = "";
|
String line1 = "";
|
||||||
|
|
||||||
if (MainApp.getConfigBuilder().getActiveProfileInterface() == null || !MainApp.getConfigBuilder().isProfileValid("Notificiation"))
|
if (MainApp.getConfigBuilder().getActiveProfileInterface() == null || !MainApp.getConfigBuilder().isProfileValid("Notificiation"))
|
||||||
return;
|
return null;
|
||||||
String units = MainApp.getConfigBuilder().getProfileUnits();
|
String units = MainApp.getConfigBuilder().getProfileUnits();
|
||||||
|
|
||||||
|
|
||||||
|
@ -142,9 +154,15 @@ public class PersistentNotificationPlugin extends PluginBase {
|
||||||
builder.setOngoing(true);
|
builder.setOngoing(true);
|
||||||
builder.setOnlyAlertOnce(true);
|
builder.setOnlyAlertOnce(true);
|
||||||
builder.setCategory(NotificationCompat.CATEGORY_STATUS);
|
builder.setCategory(NotificationCompat.CATEGORY_STATUS);
|
||||||
builder.setSmallIcon(R.drawable.ic_notification);
|
if (Config.NSCLIENT || Config.G5UPLOADER){
|
||||||
Bitmap largeIcon = BitmapFactory.decodeResource(ctx.getResources(), R.mipmap.blueowl);
|
builder.setSmallIcon(R.drawable.nsclient_smallicon);
|
||||||
builder.setLargeIcon(largeIcon);
|
Bitmap largeIcon = BitmapFactory.decodeResource(ctx.getResources(), R.mipmap.yellowowl);
|
||||||
|
builder.setLargeIcon(largeIcon);
|
||||||
|
} else {
|
||||||
|
builder.setSmallIcon(R.drawable.ic_notification);
|
||||||
|
Bitmap largeIcon = BitmapFactory.decodeResource(ctx.getResources(), R.mipmap.blueowl);
|
||||||
|
builder.setLargeIcon(largeIcon);
|
||||||
|
}
|
||||||
builder.setContentTitle(line1);
|
builder.setContentTitle(line1);
|
||||||
builder.setContentText(line2);
|
builder.setContentText(line2);
|
||||||
builder.setSubText(line3);
|
builder.setSubText(line3);
|
||||||
|
@ -165,7 +183,7 @@ public class PersistentNotificationPlugin extends PluginBase {
|
||||||
|
|
||||||
android.app.Notification notification = builder.build();
|
android.app.Notification notification = builder.build();
|
||||||
mNotificationManager.notify(ONGOING_NOTIFICATION_ID, notification);
|
mNotificationManager.notify(ONGOING_NOTIFICATION_ID, notification);
|
||||||
|
return notification;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String deltastring(double deltaMGDL, double deltaMMOL, String units) {
|
private String deltastring(double deltaMGDL, double deltaMMOL, String units) {
|
||||||
|
@ -187,42 +205,42 @@ public class PersistentNotificationPlugin extends PluginBase {
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onStatusEvent(final EventPreferenceChange ev) {
|
public void onStatusEvent(final EventPreferenceChange ev) {
|
||||||
updateNotification();
|
triggerNotificationUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onStatusEvent(final EventTreatmentChange ev) {
|
public void onStatusEvent(final EventTreatmentChange ev) {
|
||||||
updateNotification();
|
triggerNotificationUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onStatusEvent(final EventTempBasalChange ev) {
|
public void onStatusEvent(final EventTempBasalChange ev) {
|
||||||
updateNotification();
|
triggerNotificationUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onStatusEvent(final EventExtendedBolusChange ev) {
|
public void onStatusEvent(final EventExtendedBolusChange ev) {
|
||||||
updateNotification();
|
triggerNotificationUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onStatusEvent(final EventNewBG ev) {
|
public void onStatusEvent(final EventNewBG ev) {
|
||||||
updateNotification();
|
triggerNotificationUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onStatusEvent(final EventNewBasalProfile ev) {
|
public void onStatusEvent(final EventNewBasalProfile ev) {
|
||||||
updateNotification();
|
triggerNotificationUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onStatusEvent(final EventInitializationChanged ev) {
|
public void onStatusEvent(final EventInitializationChanged ev) {
|
||||||
updateNotification();
|
triggerNotificationUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onStatusEvent(final EventRefreshOverview ev) {
|
public void onStatusEvent(final EventRefreshOverview ev) {
|
||||||
updateNotification();
|
triggerNotificationUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ package info.nightscout.androidaps.plugins.ProfileLocal;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.v4.app.FragmentTransaction;
|
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
@ -23,7 +22,6 @@ import java.text.DecimalFormat;
|
||||||
|
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
|
||||||
import info.nightscout.androidaps.data.ProfileStore;
|
import info.nightscout.androidaps.data.ProfileStore;
|
||||||
import info.nightscout.androidaps.events.EventInitializationChanged;
|
import info.nightscout.androidaps.events.EventInitializationChanged;
|
||||||
import info.nightscout.androidaps.interfaces.PumpDescription;
|
import info.nightscout.androidaps.interfaces.PumpDescription;
|
||||||
|
@ -109,41 +107,32 @@ public class LocalProfileFragment extends SubscriberFragment {
|
||||||
mgdlView.setChecked(LocalProfilePlugin.getPlugin().mgdl);
|
mgdlView.setChecked(LocalProfilePlugin.getPlugin().mgdl);
|
||||||
mmolView.setChecked(LocalProfilePlugin.getPlugin().mmol);
|
mmolView.setChecked(LocalProfilePlugin.getPlugin().mmol);
|
||||||
|
|
||||||
mgdlView.setOnClickListener(new View.OnClickListener() {
|
mgdlView.setOnClickListener(v -> {
|
||||||
@Override
|
LocalProfilePlugin.getPlugin().mgdl = mgdlView.isChecked();
|
||||||
public void onClick(View v) {
|
LocalProfilePlugin.getPlugin().mmol = !LocalProfilePlugin.getPlugin().mgdl;
|
||||||
LocalProfilePlugin.getPlugin().mgdl = mgdlView.isChecked();
|
mmolView.setChecked(LocalProfilePlugin.getPlugin().mmol);
|
||||||
LocalProfilePlugin.getPlugin().mmol = !LocalProfilePlugin.getPlugin().mgdl;
|
doEdit();
|
||||||
mmolView.setChecked(LocalProfilePlugin.getPlugin().mmol);
|
|
||||||
doEdit();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
mmolView.setOnClickListener(new View.OnClickListener() {
|
mmolView.setOnClickListener(v -> {
|
||||||
@Override
|
LocalProfilePlugin.getPlugin().mmol = mmolView.isChecked();
|
||||||
public void onClick(View v) {
|
LocalProfilePlugin.getPlugin().mgdl = !LocalProfilePlugin.getPlugin().mmol;
|
||||||
LocalProfilePlugin.getPlugin().mmol = mmolView.isChecked();
|
mgdlView.setChecked(LocalProfilePlugin.getPlugin().mgdl);
|
||||||
LocalProfilePlugin.getPlugin().mgdl = !LocalProfilePlugin.getPlugin().mmol;
|
doEdit();
|
||||||
mgdlView.setChecked(LocalProfilePlugin.getPlugin().mgdl);
|
|
||||||
doEdit();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
profileswitchButton.setOnClickListener(new View.OnClickListener() {
|
profileswitchButton.setOnClickListener(view -> {
|
||||||
@Override
|
NewNSTreatmentDialog newDialog = new NewNSTreatmentDialog();
|
||||||
public void onClick(View view) {
|
final OptionsToShow profileswitch = CareportalFragment.PROFILESWITCHDIRECT;
|
||||||
NewNSTreatmentDialog newDialog = new NewNSTreatmentDialog();
|
profileswitch.executeProfileSwitch = true;
|
||||||
final OptionsToShow profileswitch = CareportalFragment.PROFILESWITCHDIRECT;
|
newDialog.setOptions(profileswitch, R.string.careportal_profileswitch);
|
||||||
profileswitch.executeProfileSwitch = true;
|
newDialog.show(getFragmentManager(), "NewNSTreatmentDialog");
|
||||||
newDialog.setOptions(profileswitch, R.string.careportal_profileswitch);
|
|
||||||
newDialog.show(getFragmentManager(), "NewNSTreatmentDialog");
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
resetButton.setOnClickListener(view -> {
|
resetButton.setOnClickListener(view -> {
|
||||||
LocalProfilePlugin.getPlugin().loadSettings();
|
LocalProfilePlugin.getPlugin().loadSettings();
|
||||||
mgdlView.setChecked(LocalProfilePlugin.getPlugin().mgdl);
|
mgdlView.setChecked(LocalProfilePlugin.getPlugin().mgdl);
|
||||||
mmolView.setChecked(LocalProfilePlugin.getPlugin().mmol);
|
mmolView.setChecked(LocalProfilePlugin.getPlugin().mmol);
|
||||||
diaView.setParams(LocalProfilePlugin.getPlugin().dia, 2d, 48d, 0.1d, new DecimalFormat("0.0"), false, textWatch);
|
diaView.setParams(LocalProfilePlugin.getPlugin().dia, 5d, 12d, 0.1d, new DecimalFormat("0.0"), false, textWatch);
|
||||||
icView = new TimeListEdit(getContext(), layout, R.id.localprofile_ic, MainApp.gs(R.string.nsprofileview_ic_label) + ":", LocalProfilePlugin.getPlugin().ic, null, 0.5, 50d, 0.1d, new DecimalFormat("0.0"), save);
|
icView = new TimeListEdit(getContext(), layout, R.id.localprofile_ic, MainApp.gs(R.string.nsprofileview_ic_label) + ":", LocalProfilePlugin.getPlugin().ic, null, 0.5, 50d, 0.1d, new DecimalFormat("0.0"), save);
|
||||||
isfView = new TimeListEdit(getContext(), layout, R.id.localprofile_isf, MainApp.gs(R.string.nsprofileview_isf_label) + ":", LocalProfilePlugin.getPlugin().isf, null, 0.5, 500d, 0.1d, new DecimalFormat("0.0"), save);
|
isfView = new TimeListEdit(getContext(), layout, R.id.localprofile_isf, MainApp.gs(R.string.nsprofileview_isf_label) + ":", LocalProfilePlugin.getPlugin().isf, null, 0.5, 500d, 0.1d, new DecimalFormat("0.0"), save);
|
||||||
basalView = new TimeListEdit(getContext(), layout, R.id.localprofile_basal, MainApp.gs(R.string.nsprofileview_basal_label) + ": " + getSumLabel(), LocalProfilePlugin.getPlugin().basal, null, pumpDescription.basalMinimumRate, 10, 0.01d, new DecimalFormat("0.00"), save);
|
basalView = new TimeListEdit(getContext(), layout, R.id.localprofile_basal, MainApp.gs(R.string.nsprofileview_basal_label) + ": " + getSumLabel(), LocalProfilePlugin.getPlugin().basal, null, pumpDescription.basalMinimumRate, 10, 0.01d, new DecimalFormat("0.00"), save);
|
||||||
|
|
|
@ -13,6 +13,7 @@ import info.nightscout.androidaps.Constants;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.data.ProfileStore;
|
import info.nightscout.androidaps.data.ProfileStore;
|
||||||
|
import info.nightscout.androidaps.events.EventProfileStoreChanged;
|
||||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||||
import info.nightscout.androidaps.interfaces.PluginDescription;
|
import info.nightscout.androidaps.interfaces.PluginDescription;
|
||||||
import info.nightscout.androidaps.interfaces.PluginType;
|
import info.nightscout.androidaps.interfaces.PluginType;
|
||||||
|
@ -63,6 +64,7 @@ public class LocalProfilePlugin extends PluginBase implements ProfileInterface {
|
||||||
.fragmentClass(LocalProfileFragment.class.getName())
|
.fragmentClass(LocalProfileFragment.class.getName())
|
||||||
.pluginName(R.string.localprofile)
|
.pluginName(R.string.localprofile)
|
||||||
.shortName(R.string.localprofile_shortname)
|
.shortName(R.string.localprofile_shortname)
|
||||||
|
.description(R.string.description_profile_local)
|
||||||
);
|
);
|
||||||
loadSettings();
|
loadSettings();
|
||||||
}
|
}
|
||||||
|
@ -81,6 +83,7 @@ public class LocalProfilePlugin extends PluginBase implements ProfileInterface {
|
||||||
edited = false;
|
edited = false;
|
||||||
if (Config.logPrefsChange)
|
if (Config.logPrefsChange)
|
||||||
log.debug("Storing settings: " + getRawProfile().getData().toString());
|
log.debug("Storing settings: " + getRawProfile().getData().toString());
|
||||||
|
MainApp.bus().post(new EventProfileStoreChanged());
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void loadSettings() {
|
public synchronized void loadSettings() {
|
||||||
|
|
|
@ -79,11 +79,14 @@ public class NSProfileFragment extends SubscriberFragment {
|
||||||
public void onStatusEvent(final EventNSProfileUpdateGUI ev) {
|
public void onStatusEvent(final EventNSProfileUpdateGUI ev) {
|
||||||
Activity activity = getActivity();
|
Activity activity = getActivity();
|
||||||
if (activity != null)
|
if (activity != null)
|
||||||
activity.runOnUiThread(() -> updateGUI());
|
activity.runOnUiThread(() -> { synchronized (NSProfileFragment.this) { updateGUI(); } });
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void updateGUI() {
|
protected void updateGUI() {
|
||||||
|
if (noProfile == null || profileSpinner == null)
|
||||||
|
return;
|
||||||
|
|
||||||
ProfileStore profileStore = NSProfilePlugin.getPlugin().getProfile();
|
ProfileStore profileStore = NSProfilePlugin.getPlugin().getProfile();
|
||||||
if (profileStore != null) {
|
if (profileStore != null) {
|
||||||
ArrayList<CharSequence> profileList = profileStore.getProfileList();
|
ArrayList<CharSequence> profileList = profileStore.getProfileList();
|
||||||
|
|
|
@ -16,6 +16,7 @@ import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.Services.Intents;
|
import info.nightscout.androidaps.Services.Intents;
|
||||||
import info.nightscout.androidaps.data.ProfileStore;
|
import info.nightscout.androidaps.data.ProfileStore;
|
||||||
|
import info.nightscout.androidaps.events.EventProfileStoreChanged;
|
||||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||||
import info.nightscout.androidaps.interfaces.PluginDescription;
|
import info.nightscout.androidaps.interfaces.PluginDescription;
|
||||||
import info.nightscout.androidaps.interfaces.PluginType;
|
import info.nightscout.androidaps.interfaces.PluginType;
|
||||||
|
@ -43,11 +44,12 @@ public class NSProfilePlugin extends PluginBase implements ProfileInterface {
|
||||||
super(new PluginDescription()
|
super(new PluginDescription()
|
||||||
.mainType(PluginType.PROFILE)
|
.mainType(PluginType.PROFILE)
|
||||||
.fragmentClass(NSProfileFragment.class.getName())
|
.fragmentClass(NSProfileFragment.class.getName())
|
||||||
.pluginName(R.string.profileviewer)
|
.pluginName(R.string.nsprofile)
|
||||||
.shortName(R.string.profileviewer_shortname)
|
.shortName(R.string.profileviewer_shortname)
|
||||||
.alwaysEnabled(Config.NSCLIENT)
|
.alwaysEnabled(Config.NSCLIENT)
|
||||||
.alwayVisible(Config.NSCLIENT)
|
.alwayVisible(Config.NSCLIENT)
|
||||||
.showInList(!Config.NSCLIENT)
|
.showInList(!Config.NSCLIENT)
|
||||||
|
.description(R.string.description_profile_nightscout)
|
||||||
);
|
);
|
||||||
loadNSProfile();
|
loadNSProfile();
|
||||||
}
|
}
|
||||||
|
@ -68,6 +70,7 @@ public class NSProfilePlugin extends PluginBase implements ProfileInterface {
|
||||||
profile = new ProfileStore(newProfile.getData());
|
profile = new ProfileStore(newProfile.getData());
|
||||||
storeNSProfile();
|
storeNSProfile();
|
||||||
MainApp.bus().post(new EventNSProfileUpdateGUI());
|
MainApp.bus().post(new EventNSProfileUpdateGUI());
|
||||||
|
MainApp.bus().post(new EventProfileStoreChanged());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void storeNSProfile() {
|
private void storeNSProfile() {
|
||||||
|
|
|
@ -73,34 +73,25 @@ public class SimpleProfileFragment extends SubscriberFragment {
|
||||||
targetlowView.setText(SimpleProfilePlugin.getPlugin().targetLow.toString());
|
targetlowView.setText(SimpleProfilePlugin.getPlugin().targetLow.toString());
|
||||||
targethighView.setText(SimpleProfilePlugin.getPlugin().targetHigh.toString());
|
targethighView.setText(SimpleProfilePlugin.getPlugin().targetHigh.toString());
|
||||||
|
|
||||||
mgdlView.setOnClickListener(new View.OnClickListener() {
|
mgdlView.setOnClickListener(v -> {
|
||||||
@Override
|
SimpleProfilePlugin.getPlugin().mgdl = mgdlView.isChecked();
|
||||||
public void onClick(View v) {
|
SimpleProfilePlugin.getPlugin().mmol = !SimpleProfilePlugin.getPlugin().mgdl;
|
||||||
SimpleProfilePlugin.getPlugin().mgdl = mgdlView.isChecked();
|
mmolView.setChecked(SimpleProfilePlugin.getPlugin().mmol);
|
||||||
SimpleProfilePlugin.getPlugin().mmol = !SimpleProfilePlugin.getPlugin().mgdl;
|
SimpleProfilePlugin.getPlugin().storeSettings();
|
||||||
mmolView.setChecked(SimpleProfilePlugin.getPlugin().mmol);
|
|
||||||
SimpleProfilePlugin.getPlugin().storeSettings();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
mmolView.setOnClickListener(new View.OnClickListener() {
|
mmolView.setOnClickListener(v -> {
|
||||||
@Override
|
SimpleProfilePlugin.getPlugin().mmol = mmolView.isChecked();
|
||||||
public void onClick(View v) {
|
SimpleProfilePlugin.getPlugin().mgdl = !SimpleProfilePlugin.getPlugin().mmol;
|
||||||
SimpleProfilePlugin.getPlugin().mmol = mmolView.isChecked();
|
mgdlView.setChecked(SimpleProfilePlugin.getPlugin().mgdl);
|
||||||
SimpleProfilePlugin.getPlugin().mgdl = !SimpleProfilePlugin.getPlugin().mmol;
|
SimpleProfilePlugin.getPlugin().storeSettings();
|
||||||
mgdlView.setChecked(SimpleProfilePlugin.getPlugin().mgdl);
|
|
||||||
SimpleProfilePlugin.getPlugin().storeSettings();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
profileswitchButton.setOnClickListener(new View.OnClickListener() {
|
profileswitchButton.setOnClickListener(view -> {
|
||||||
@Override
|
NewNSTreatmentDialog newDialog = new NewNSTreatmentDialog();
|
||||||
public void onClick(View view) {
|
final OptionsToShow profileswitch = CareportalFragment.PROFILESWITCH;
|
||||||
NewNSTreatmentDialog newDialog = new NewNSTreatmentDialog();
|
profileswitch.executeProfileSwitch = true;
|
||||||
final OptionsToShow profileswitch = CareportalFragment.PROFILESWITCH;
|
newDialog.setOptions(profileswitch, R.string.careportal_profileswitch);
|
||||||
profileswitch.executeProfileSwitch = true;
|
newDialog.show(getFragmentManager(), "NewNSTreatmentDialog");
|
||||||
newDialog.setOptions(profileswitch, R.string.careportal_profileswitch);
|
|
||||||
newDialog.show(getFragmentManager(), "NewNSTreatmentDialog");
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
TextWatcher textWatch = new TextWatcher() {
|
TextWatcher textWatch = new TextWatcher() {
|
||||||
|
@ -152,20 +143,17 @@ public class SimpleProfileFragment extends SubscriberFragment {
|
||||||
protected void updateGUI() {
|
protected void updateGUI() {
|
||||||
Activity activity = getActivity();
|
Activity activity = getActivity();
|
||||||
if (activity != null)
|
if (activity != null)
|
||||||
activity.runOnUiThread(new Runnable() {
|
activity.runOnUiThread(() -> {
|
||||||
@Override
|
boolean isValid = SimpleProfilePlugin.getPlugin().getProfile() != null && SimpleProfilePlugin.getPlugin().getProfile().getDefaultProfile().isValid(MainApp.gs(R.string.simpleprofile));
|
||||||
public void run() {
|
if (!ConfigBuilderPlugin.getActivePump().isInitialized() || ConfigBuilderPlugin.getActivePump().isSuspended() || !isValid) {
|
||||||
boolean isValid = SimpleProfilePlugin.getPlugin().getProfile() != null && SimpleProfilePlugin.getPlugin().getProfile().getDefaultProfile().isValid(MainApp.gs(R.string.simpleprofile));
|
profileswitchButton.setVisibility(View.GONE);
|
||||||
if (!ConfigBuilderPlugin.getActivePump().isInitialized() || ConfigBuilderPlugin.getActivePump().isSuspended() || !isValid) {
|
} else {
|
||||||
profileswitchButton.setVisibility(View.GONE);
|
profileswitchButton.setVisibility(View.VISIBLE);
|
||||||
} else {
|
|
||||||
profileswitchButton.setVisibility(View.VISIBLE);
|
|
||||||
}
|
|
||||||
if (isValid)
|
|
||||||
invalidProfile.setVisibility(View.GONE);
|
|
||||||
else
|
|
||||||
invalidProfile.setVisibility(View.VISIBLE);
|
|
||||||
}
|
}
|
||||||
|
if (isValid)
|
||||||
|
invalidProfile.setVisibility(View.GONE);
|
||||||
|
else
|
||||||
|
invalidProfile.setVisibility(View.VISIBLE);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ import info.nightscout.androidaps.Constants;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.data.ProfileStore;
|
import info.nightscout.androidaps.data.ProfileStore;
|
||||||
|
import info.nightscout.androidaps.events.EventProfileStoreChanged;
|
||||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||||
import info.nightscout.androidaps.interfaces.PluginDescription;
|
import info.nightscout.androidaps.interfaces.PluginDescription;
|
||||||
import info.nightscout.androidaps.interfaces.PluginType;
|
import info.nightscout.androidaps.interfaces.PluginType;
|
||||||
|
@ -51,6 +52,7 @@ public class SimpleProfilePlugin extends PluginBase implements ProfileInterface
|
||||||
.fragmentClass(SimpleProfileFragment.class.getName())
|
.fragmentClass(SimpleProfileFragment.class.getName())
|
||||||
.pluginName(R.string.simpleprofile)
|
.pluginName(R.string.simpleprofile)
|
||||||
.shortName(R.string.simpleprofile_shortname)
|
.shortName(R.string.simpleprofile_shortname)
|
||||||
|
.description(R.string.description_profile_simple)
|
||||||
);
|
);
|
||||||
loadSettings();
|
loadSettings();
|
||||||
}
|
}
|
||||||
|
@ -73,6 +75,7 @@ public class SimpleProfilePlugin extends PluginBase implements ProfileInterface
|
||||||
createConvertedProfile();
|
createConvertedProfile();
|
||||||
if (Config.logPrefsChange)
|
if (Config.logPrefsChange)
|
||||||
log.debug("Storing settings: " + getRawProfile().getData().toString());
|
log.debug("Storing settings: " + getRawProfile().getData().toString());
|
||||||
|
MainApp.bus().post(new EventProfileStoreChanged());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadSettings() {
|
private void loadSettings() {
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
package info.nightscout.androidaps.plugins.PumpCombo;
|
package info.nightscout.androidaps.plugins.PumpCombo;
|
||||||
|
|
||||||
|
import android.content.DialogInterface;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.v4.app.FragmentActivity;
|
||||||
|
import android.support.v7.app.AlertDialog;
|
||||||
|
|
||||||
import com.crashlytics.android.answers.CustomEvent;
|
import com.crashlytics.android.answers.CustomEvent;
|
||||||
|
|
||||||
|
@ -28,6 +31,7 @@ import info.nightscout.androidaps.db.CareportalEvent;
|
||||||
import info.nightscout.androidaps.db.Source;
|
import info.nightscout.androidaps.db.Source;
|
||||||
import info.nightscout.androidaps.db.TDD;
|
import info.nightscout.androidaps.db.TDD;
|
||||||
import info.nightscout.androidaps.db.TemporaryBasal;
|
import info.nightscout.androidaps.db.TemporaryBasal;
|
||||||
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderFragment;
|
||||||
import info.nightscout.androidaps.plugins.Treatments.Treatment;
|
import info.nightscout.androidaps.plugins.Treatments.Treatment;
|
||||||
import info.nightscout.androidaps.events.EventInitializationChanged;
|
import info.nightscout.androidaps.events.EventInitializationChanged;
|
||||||
import info.nightscout.androidaps.events.EventRefreshOverview;
|
import info.nightscout.androidaps.events.EventRefreshOverview;
|
||||||
|
@ -57,8 +61,6 @@ import info.nightscout.androidaps.plugins.PumpCombo.ruffyscripter.history.PumpHi
|
||||||
import info.nightscout.androidaps.plugins.PumpCombo.ruffyscripter.history.PumpHistoryRequest;
|
import info.nightscout.androidaps.plugins.PumpCombo.ruffyscripter.history.PumpHistoryRequest;
|
||||||
import info.nightscout.androidaps.plugins.PumpCombo.ruffyscripter.history.Tdd;
|
import info.nightscout.androidaps.plugins.PumpCombo.ruffyscripter.history.Tdd;
|
||||||
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.androidaps.queue.Callback;
|
|
||||||
import info.nightscout.androidaps.queue.CommandQueue;
|
|
||||||
import info.nightscout.utils.DateUtil;
|
import info.nightscout.utils.DateUtil;
|
||||||
import info.nightscout.utils.FabricPrivacy;
|
import info.nightscout.utils.FabricPrivacy;
|
||||||
import info.nightscout.utils.SP;
|
import info.nightscout.utils.SP;
|
||||||
|
@ -166,6 +168,7 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
|
||||||
.fragmentClass(ComboFragment.class.getName())
|
.fragmentClass(ComboFragment.class.getName())
|
||||||
.pluginName(R.string.combopump)
|
.pluginName(R.string.combopump)
|
||||||
.shortName(R.string.combopump_shortname)
|
.shortName(R.string.combopump_shortname)
|
||||||
|
.description(R.string.description_pump_combo)
|
||||||
);
|
);
|
||||||
ruffyScripter = new RuffyScripter(MainApp.instance().getApplicationContext());
|
ruffyScripter = new RuffyScripter(MainApp.instance().getApplicationContext());
|
||||||
}
|
}
|
||||||
|
@ -192,6 +195,32 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
|
||||||
return MainApp.gs(R.string.combo_pump_state_running);
|
return MainApp.gs(R.string.combo_pump_state_running);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void switchAllowed(ConfigBuilderFragment.PluginViewHolder.PluginSwitcher pluginSwitcher, FragmentActivity context) {
|
||||||
|
boolean allowHardwarePump = SP.getBoolean("allow_hardware_pump", false);
|
||||||
|
if (allowHardwarePump || context == null){
|
||||||
|
pluginSwitcher.invoke();
|
||||||
|
} else {
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||||
|
builder.setMessage(R.string.allow_hardware_pump_text)
|
||||||
|
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
|
pluginSwitcher.invoke();
|
||||||
|
SP.putBoolean("allow_hardware_pump", true);
|
||||||
|
log.debug("First time HW pump allowed!");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
|
pluginSwitcher.cancel();
|
||||||
|
log.debug("User does not allow switching to HW pump!");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
builder.create().show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInitialized() {
|
public boolean isInitialized() {
|
||||||
return pump.initialized;
|
return pump.initialized;
|
||||||
|
@ -352,6 +381,11 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
|
||||||
|
|
||||||
// trigger a connect, which will update state and check history
|
// trigger a connect, which will update state and check history
|
||||||
CommandResult stateResult = runCommand(null, 1, ruffyScripter::readPumpState);
|
CommandResult stateResult = runCommand(null, 1, ruffyScripter::readPumpState);
|
||||||
|
if (stateResult.invalidSetup) {
|
||||||
|
MainApp.bus().post(new EventNewNotification(
|
||||||
|
new Notification(Notification.COMBO_PUMP_ALARM, MainApp.gs(R.string.combo_invalid_setup), Notification.URGENT)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!stateResult.success) {
|
if (!stateResult.success) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -421,9 +455,6 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
|
||||||
return pump.basalProfile.hourlyRates[currentHour];
|
return pump.basalProfile.hourlyRates[currentHour];
|
||||||
}
|
}
|
||||||
|
|
||||||
private static BolusProgressReporter nullBolusProgressReporter = (state, percent, delivered) -> {
|
|
||||||
};
|
|
||||||
|
|
||||||
private static BolusProgressReporter bolusProgressReporter = (state, percent, delivered) -> {
|
private static BolusProgressReporter bolusProgressReporter = (state, percent, delivered) -> {
|
||||||
EventOverviewBolusProgress event = EventOverviewBolusProgress.getInstance();
|
EventOverviewBolusProgress event = EventOverviewBolusProgress.getInstance();
|
||||||
switch (state) {
|
switch (state) {
|
||||||
|
@ -464,7 +495,7 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
|
||||||
return deliverBolus(detailedBolusInfo);
|
return deliverBolus(detailedBolusInfo);
|
||||||
} else {
|
} else {
|
||||||
// no bolus required, carb only treatment
|
// no bolus required, carb only treatment
|
||||||
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo);
|
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false);
|
||||||
|
|
||||||
EventOverviewBolusProgress bolusingEvent = EventOverviewBolusProgress.getInstance();
|
EventOverviewBolusProgress bolusingEvent = EventOverviewBolusProgress.getInstance();
|
||||||
bolusingEvent.t = new Treatment();
|
bolusingEvent.t = new Treatment();
|
||||||
|
@ -549,12 +580,14 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
|
||||||
return new PumpEnactResult().success(true).enacted(false);
|
return new PumpEnactResult().success(true).enacted(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
BolusProgressReporter progressReporter = detailedBolusInfo.isSMB ? nullBolusProgressReporter : bolusProgressReporter;
|
Treatment treatment = new Treatment();
|
||||||
|
treatment.isSMB = detailedBolusInfo.isSMB;
|
||||||
|
EventOverviewBolusProgress.getInstance().t = treatment;
|
||||||
|
|
||||||
// start bolus delivery
|
// start bolus delivery
|
||||||
scripterIsBolusing = true;
|
scripterIsBolusing = true;
|
||||||
runCommand(null, 0,
|
runCommand(null, 0,
|
||||||
() -> ruffyScripter.deliverBolus(detailedBolusInfo.insulin, progressReporter));
|
() -> ruffyScripter.deliverBolus(detailedBolusInfo.insulin, bolusProgressReporter));
|
||||||
scripterIsBolusing = false;
|
scripterIsBolusing = false;
|
||||||
|
|
||||||
// Note that the result of the issued bolus command is not checked. If there was
|
// Note that the result of the issued bolus command is not checked. If there was
|
||||||
|
@ -653,7 +686,7 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
|
||||||
dbi.source = Source.PUMP;
|
dbi.source = Source.PUMP;
|
||||||
dbi.insulin = lastPumpBolus.amount;
|
dbi.insulin = lastPumpBolus.amount;
|
||||||
try {
|
try {
|
||||||
boolean treatmentCreated = TreatmentsPlugin.getPlugin().addToHistoryTreatment(dbi);
|
boolean treatmentCreated = TreatmentsPlugin.getPlugin().addToHistoryTreatment(dbi, false);
|
||||||
if (!treatmentCreated) {
|
if (!treatmentCreated) {
|
||||||
log.error("Adding treatment record overrode an existing record: " + dbi);
|
log.error("Adding treatment record overrode an existing record: " + dbi);
|
||||||
if (dbi.isSMB) {
|
if (dbi.isSMB) {
|
||||||
|
@ -1152,7 +1185,8 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
|
||||||
dbi.source = Source.PUMP;
|
dbi.source = Source.PUMP;
|
||||||
dbi.insulin = pumpBolus.amount;
|
dbi.insulin = pumpBolus.amount;
|
||||||
dbi.eventType = CareportalEvent.CORRECTIONBOLUS;
|
dbi.eventType = CareportalEvent.CORRECTIONBOLUS;
|
||||||
if (TreatmentsPlugin.getPlugin().addToHistoryTreatment(dbi)) {
|
if (TreatmentsPlugin.getPlugin().getService().getPumpRecordById(dbi.pumpId) == null) {
|
||||||
|
TreatmentsPlugin.getPlugin().addToHistoryTreatment(dbi, false);
|
||||||
updated = true;
|
updated = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1356,7 +1390,7 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
|
||||||
private boolean validBasalRateProfileSelectedOnPump = true;
|
private boolean validBasalRateProfileSelectedOnPump = true;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Constraint<Boolean> isLoopInvokationAllowed(Constraint<Boolean> value) {
|
public Constraint<Boolean> isLoopInvocationAllowed(Constraint<Boolean> value) {
|
||||||
if (!validBasalRateProfileSelectedOnPump)
|
if (!validBasalRateProfileSelectedOnPump)
|
||||||
value.set(false, MainApp.gs(R.string.novalidbasalrate), this);
|
value.set(false, MainApp.gs(R.string.novalidbasalrate), this);
|
||||||
return value;
|
return value;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue