Merge branch 'dev' into virtual_pump_Bug863
This commit is contained in:
commit
c6bc15e311
627 changed files with 95095 additions and 17409 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -11,3 +11,5 @@ app/src/main/jniLibs
|
|||
full/
|
||||
debug/
|
||||
release/
|
||||
app/com.crashlytics.settings.json
|
||||
app/session_analytics.tap
|
|
@ -44,12 +44,12 @@ def generateGitBuild = { ->
|
|||
stringBuilder.append('NoGitSystemAvailable')
|
||||
}
|
||||
stringBuilder.append('-')
|
||||
stringBuilder.append((new Date()).format('yyyy.MM.dd'))
|
||||
stringBuilder.append((new Date()).format('yyyy.MM.dd-HH:mm'))
|
||||
stringBuilder.append('"')
|
||||
return stringBuilder.toString()
|
||||
}
|
||||
|
||||
tasks.matching {it instanceof Test}.all {
|
||||
tasks.matching { it instanceof Test }.all {
|
||||
testLogging.events = ["failed", "skipped", "started"]
|
||||
testLogging.exceptionFormat = "full"
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ android {
|
|||
targetSdkVersion 25
|
||||
multiDexEnabled true
|
||||
versionCode 1500
|
||||
version "1.60e-dev"
|
||||
version "2.0c-dev"
|
||||
buildConfigField "String", "VERSION", '"' + version + '"'
|
||||
buildConfigField "String", "BUILDVERSION", generateGitBuild()
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
|
@ -89,7 +89,7 @@ android {
|
|||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
debug {
|
||||
testCoverageEnabled (project.hasProperty('coverage') ? true : false)
|
||||
testCoverageEnabled(project.hasProperty('coverage') ? true : false)
|
||||
}
|
||||
}
|
||||
productFlavors {
|
||||
|
@ -99,7 +99,8 @@ android {
|
|||
resValue "string", "app_name", "AndroidAPS"
|
||||
versionName version
|
||||
manifestPlaceholders = [
|
||||
appIcon: "@mipmap/blueowl"
|
||||
appIcon: "@mipmap/ic_launcher",
|
||||
appIconRound: "@mipmap/ic_launcher_round"
|
||||
]
|
||||
buildConfigField "boolean", "APS", "true"
|
||||
buildConfigField "boolean", "PUMPDRIVERS", "true"
|
||||
|
@ -112,7 +113,8 @@ android {
|
|||
resValue "string", "app_name", "AndroidAPS"
|
||||
versionName version
|
||||
manifestPlaceholders = [
|
||||
appIcon: "@mipmap/blueowl"
|
||||
appIcon: "@mipmap/blueowl",
|
||||
appIconRound: "@null"
|
||||
]
|
||||
buildConfigField "boolean", "APS", "false"
|
||||
buildConfigField "boolean", "PUMPDRIVERS", "true"
|
||||
|
@ -125,7 +127,8 @@ android {
|
|||
resValue "string", "app_name", "NSClient"
|
||||
versionName version + "-nsclient"
|
||||
manifestPlaceholders = [
|
||||
appIcon: "@mipmap/yellowowl"
|
||||
appIcon: "@mipmap/yellowowl",
|
||||
appIconRound: "@null"
|
||||
]
|
||||
buildConfigField "boolean", "APS", "false"
|
||||
buildConfigField "boolean", "PUMPDRIVERS", "false"
|
||||
|
@ -138,7 +141,8 @@ android {
|
|||
resValue "string", "app_name", "NSClient"
|
||||
versionName version + "-nsclient"
|
||||
manifestPlaceholders = [
|
||||
appIcon: "@mipmap/yellowowl"
|
||||
appIcon: "@mipmap/yellowowl",
|
||||
appIconRound: "@null"
|
||||
]
|
||||
buildConfigField "boolean", "APS", "false"
|
||||
buildConfigField "boolean", "PUMPDRIVERS", "false"
|
||||
|
@ -156,7 +160,7 @@ android {
|
|||
unitTests.returnDefaultValues = true
|
||||
unitTests.includeAndroidResources = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
|
@ -242,7 +246,7 @@ dependencies {
|
|||
}
|
||||
|
||||
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 outputDir = file("${buildDir}/unpacked/dist")
|
||||
|
||||
|
|
Binary file not shown.
|
@ -30,46 +30,50 @@
|
|||
android:name=".MainApp"
|
||||
android:allowBackup="true"
|
||||
android:icon="${appIcon}"
|
||||
android:roundIcon="${appIconRound}"
|
||||
android:label="@string/app_name"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
android:theme="@style/AppTheme.NoActionBar">
|
||||
<activity android:name=".MainActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name=".PreferencesActivity" />
|
||||
<activity android:name=".activities.PreferencesActivity" />
|
||||
<activity
|
||||
android:name=".plugins.Overview.Dialogs.BolusProgressHelperActivity"
|
||||
android:theme="@style/Theme.AppCompat.Translucent" />
|
||||
<activity
|
||||
android:name=".plugins.Overview.Dialogs.ErrorHelperActivity"
|
||||
android:theme="@style/Theme.AppCompat.Translucent" />
|
||||
<activity android:name=".AgreementActivity" />
|
||||
<activity android:name=".activities.AgreementActivity" />
|
||||
<activity android:name=".plugins.PumpDanaR.activities.DanaRHistoryActivity" />
|
||||
<activity android:name=".TDDStatsActivity" />
|
||||
<activity android:name=".plugins.PumpDanaR.activities.DanaRUserOptionsActivity" />
|
||||
<activity android:name=".activities.TDDStatsActivity" />
|
||||
<activity android:name=".plugins.Overview.activities.QuickWizardListActivity">
|
||||
<intent-filter>
|
||||
<action android:name="info.nightscout.androidaps.plugins.Overview.activities.QuickWizardListActivity" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name=".plugins.PumpDanaRS.activities.BLEScanActivity">
|
||||
<intent-filter>
|
||||
<action android:name="info.nightscout.androidaps.plugins.PumpDanaRS.activities.BLEScanActivity" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name=".plugins.PumpDanaRS.activities.PairingHelperActivity" />
|
||||
<activity android:name=".HistoryBrowseActivity" />
|
||||
<activity android:name=".activities.HistoryBrowseActivity" />
|
||||
|
||||
<receiver
|
||||
android:name=".receivers.DataReceiver"
|
||||
android:enabled="true"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
|
||||
<!-- Receive new SMS messages -->
|
||||
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
|
||||
<!-- Receiver from xDrip -->
|
||||
|
@ -80,6 +84,8 @@
|
|||
<action android:name="it.ct.glicemia.ACTION_GLUCOSE_MEASURED" />
|
||||
<!-- Receiver from DexcomG5 -->
|
||||
<action android:name="com.dexcom.cgm.DATA" />
|
||||
<!-- Receiver from Poctech -->
|
||||
<action android:name="com.china.poctech.data" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<!-- Receiver keepalive, scheduled every 30 min -->
|
||||
|
@ -123,7 +129,7 @@
|
|||
|
||||
<!-- Service processing incomming data -->
|
||||
<service
|
||||
android:name=".Services.DataService"
|
||||
android:name=".services.DataService"
|
||||
android:exported="false" />
|
||||
<service
|
||||
android:name=".plugins.PumpDanaR.services.DanaRExecutionService"
|
||||
|
@ -140,7 +146,7 @@
|
|||
<service
|
||||
android:name=".plugins.PumpDanaRS.services.DanaRSService"
|
||||
android:enabled="true"
|
||||
android:exported="true"></service>
|
||||
android:exported="true" />
|
||||
<service
|
||||
android:name=".plugins.Wear.wearintegration.WatchUpdaterService"
|
||||
android:exported="true">
|
||||
|
@ -153,17 +159,28 @@
|
|||
android:enabled="true"
|
||||
android:exported="true" />
|
||||
<service
|
||||
android:name=".Services.AlarmSoundService"
|
||||
android:name=".services.AlarmSoundService"
|
||||
android:enabled="true"
|
||||
android:exported="true" />
|
||||
<service
|
||||
android:name=".plugins.Overview.notifications.DismissNotificationService"
|
||||
android:exported="false"></service>
|
||||
android:exported="false" />
|
||||
|
||||
<service android:name=".plugins.Persistentnotification.DummyService" />
|
||||
|
||||
<meta-data
|
||||
android:name="io.fabric.ApiKey"
|
||||
android:value="59d462666c664c57b29e1d79ea123e01f8057cfa" />
|
||||
|
||||
<activity
|
||||
android:name=".setupwizard.SetupWizardActivity"
|
||||
android:configChanges="orientation|keyboardHidden|screenSize"
|
||||
android:theme="@style/AppTheme.NoActionBar"
|
||||
android:label="@string/title_activity_setup_wizard" />
|
||||
|
||||
<activity android:name=".activities.SingleFragmentActivity"
|
||||
android:theme="@style/AppTheme" />
|
||||
<activity android:name=".logging.LogSettingActivity"></activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
|
@ -406,8 +406,8 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_
|
|||
} else {
|
||||
console.error("SMB disabled (no enableSMB preferences active)");
|
||||
}
|
||||
// enable UAM (if enabled in preferences) if SMB is enabled
|
||||
var enableUAM=(profile.enableUAM && enableSMB);
|
||||
// enable UAM (if enabled in preferences)
|
||||
var enableUAM=(profile.enableUAM);
|
||||
|
||||
|
||||
//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);
|
||||
if (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 {
|
||||
durationReq = round(durationReq/30)*30;
|
||||
durationReq = Math.min(120,Math.max(0,durationReq));
|
||||
durationReq = Math.min(60,Math.max(0,durationReq));
|
||||
}
|
||||
//console.error(durationReq);
|
||||
//rT.reason += "insulinReq " + insulinReq + "; "
|
||||
|
|
|
@ -1,36 +1,39 @@
|
|||
<configuration>
|
||||
<!-- 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"/>
|
||||
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${EXT_FILES_DIR}/AndroidAPS.log</file>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- Create a file appender for a log in the application's data directory -->
|
||||
<property name="EXT_FILES_DIR" scope="context"
|
||||
value="${EXT_DIR:-/sdcard}/Android/data/${PACKAGE_NAME}/files" />
|
||||
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<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
|
||||
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>
|
||||
</timeBasedFileNamingAndTriggeringPolicy>
|
||||
<!-- keep 30 days' worth of history -->
|
||||
<maxHistory>120</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level [%class:%line]: %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level [%class{0}.%M\(\):%line]: %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<appender name="logcat" class="ch.qos.logback.classic.android.LogcatAppender">
|
||||
<tagEncoder>
|
||||
<pattern>%logger{0}</pattern>
|
||||
</tagEncoder>
|
||||
<encoder>
|
||||
<pattern>[%thread] %-5level [%class:%line]: %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
<tagEncoder>
|
||||
<pattern>%logger{0}</pattern>
|
||||
</tagEncoder>
|
||||
<encoder>
|
||||
<pattern>[%thread] [%class{0}.%M\(\):%line]: %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- Write INFO (and higher-level) messages to the log file -->
|
||||
<root level="DEBUG">
|
||||
<appender-ref ref="file" />
|
||||
<appender-ref ref="logcat" />
|
||||
</root>
|
||||
<!-- Write INFO (and higher-level) messages to the log file -->
|
||||
<root level="DEBUG">
|
||||
<appender-ref ref="file" />
|
||||
<appender-ref ref="logcat" />
|
||||
</root>
|
||||
</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 |
|
@ -11,6 +11,7 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
|
||||
import info.nightscout.androidaps.events.Event;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
|
||||
/** Logs events has they're being posted to and dispatched from the event bus.
|
||||
*
|
||||
|
@ -18,7 +19,7 @@ import info.nightscout.androidaps.events.Event;
|
|||
* after 10s (after startup) and then again every 60s.
|
||||
* */
|
||||
public class LoggingBus extends Bus {
|
||||
private static Logger log = LoggerFactory.getLogger(LoggingBus.class);
|
||||
private static Logger log = LoggerFactory.getLogger(L.EVENTS);
|
||||
|
||||
private static long everyMinute = System.currentTimeMillis() + 10 * 1000;
|
||||
private Map<String, Set<String>> event2Receiver = new HashMap<>();
|
||||
|
|
|
@ -23,22 +23,4 @@ public class Config {
|
|||
public static final boolean SMSCOMMUNICATORENABLED = !BuildConfig.NSCLIENTOLNY && !BuildConfig.G5UPLOADER;
|
||||
|
||||
|
||||
public static final boolean detailedLog = true;
|
||||
public static final boolean logFunctionCalls = true;
|
||||
public static final boolean logIncommingData = true;
|
||||
public static final boolean logAPSResult = true;
|
||||
public static final boolean logPumpComm = true;
|
||||
public static final boolean logPrefsChange = true;
|
||||
public static final boolean logConfigBuilder = true;
|
||||
public static final boolean logNSUpload = true;
|
||||
public static final boolean logPumpActions = true;
|
||||
public static final boolean logCongigBuilderActions = true;
|
||||
public static final boolean logAutosensData = false;
|
||||
public static final boolean logEvents = false;
|
||||
public static final boolean logProfile = false;
|
||||
|
||||
// DanaR specific
|
||||
public static final boolean logDanaBTComm = true;
|
||||
public static boolean logDanaMessageDetail = true;
|
||||
public static final boolean logDanaSerialEngine = true;
|
||||
}
|
||||
|
|
|
@ -67,4 +67,5 @@ public class Constants {
|
|||
|
||||
//SMS Communicator
|
||||
public static final long SMS_CONFIRM_TIMEOUT = T.mins(5).msecs();
|
||||
|
||||
}
|
||||
|
|
|
@ -1,404 +0,0 @@
|
|||
package info.nightscout.androidaps;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.content.res.ResourcesCompat;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.PopupMenu;
|
||||
import android.text.SpannableString;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.jjoe64.graphview.GraphView;
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Calendar;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import butterknife.OnLongClick;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.events.EventCustomCalculationFinished;
|
||||
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
|
||||
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished;
|
||||
import info.nightscout.androidaps.plugins.Overview.OverviewFragment;
|
||||
import info.nightscout.androidaps.plugins.Overview.OverviewPlugin;
|
||||
import info.nightscout.androidaps.plugins.Overview.graphData.GraphData;
|
||||
import info.nightscout.utils.DateUtil;
|
||||
import info.nightscout.utils.SP;
|
||||
|
||||
public class HistoryBrowseActivity extends AppCompatActivity {
|
||||
private static Logger log = LoggerFactory.getLogger(HistoryBrowseActivity.class);
|
||||
|
||||
|
||||
ImageButton chartButton;
|
||||
|
||||
boolean showBasal = true;
|
||||
boolean showIob, showCob, showDev, showRat, showDevslope;
|
||||
|
||||
|
||||
@BindView(R.id.historybrowse_date)
|
||||
Button buttonDate;
|
||||
@BindView(R.id.historybrowse_zoom)
|
||||
Button buttonZoom;
|
||||
@BindView(R.id.historyybrowse_bggraph)
|
||||
GraphView bgGraph;
|
||||
@BindView(R.id.historybrowse_iobgraph)
|
||||
GraphView iobGraph;
|
||||
@BindView(R.id.historybrowse_seekBar)
|
||||
SeekBar seekBar;
|
||||
@BindView(R.id.historybrowse_noprofile)
|
||||
TextView noProfile;
|
||||
|
||||
private int rangeToDisplay = 24; // for graph
|
||||
private long start;
|
||||
|
||||
IobCobCalculatorPlugin iobCobCalculatorPlugin;
|
||||
|
||||
EventCustomCalculationFinished eventCustomCalculationFinished = new EventCustomCalculationFinished();
|
||||
|
||||
public HistoryBrowseActivity() {
|
||||
iobCobCalculatorPlugin = new IobCobCalculatorPlugin();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_historybrowse);
|
||||
|
||||
ButterKnife.bind(this);
|
||||
|
||||
bgGraph.getGridLabelRenderer().setGridColor(MainApp.gc(R.color.graphgrid));
|
||||
bgGraph.getGridLabelRenderer().reloadStyles();
|
||||
iobGraph.getGridLabelRenderer().setGridColor(MainApp.gc(R.color.graphgrid));
|
||||
iobGraph.getGridLabelRenderer().reloadStyles();
|
||||
iobGraph.getGridLabelRenderer().setHorizontalLabelsVisible(false);
|
||||
bgGraph.getGridLabelRenderer().setLabelVerticalWidth(50);
|
||||
iobGraph.getGridLabelRenderer().setLabelVerticalWidth(50);
|
||||
iobGraph.getGridLabelRenderer().setNumVerticalLabels(5);
|
||||
|
||||
setupChartMenu();
|
||||
|
||||
// set start of current day
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTimeInMillis(System.currentTimeMillis());
|
||||
calendar.set(Calendar.MILLISECOND, 0);
|
||||
calendar.set(Calendar.SECOND, 0);
|
||||
calendar.set(Calendar.MINUTE, 0);
|
||||
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
||||
start = calendar.getTimeInMillis();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
updateGUI("onResume");
|
||||
}
|
||||
|
||||
|
||||
@OnClick(R.id.historybrowse_start)
|
||||
void onClickStart() {
|
||||
}
|
||||
|
||||
@OnClick(R.id.historybrowse_left)
|
||||
void onClickLeft() {
|
||||
start -= rangeToDisplay * 60 * 60 * 1000L;
|
||||
updateGUI("left");
|
||||
iobCobCalculatorPlugin.clearCache();
|
||||
iobCobCalculatorPlugin.runCalculation("onClickLeft", start, true, eventCustomCalculationFinished);
|
||||
}
|
||||
|
||||
@OnClick(R.id.historybrowse_right)
|
||||
void onClickRight() {
|
||||
start += rangeToDisplay * 60 * 60 * 1000L;
|
||||
updateGUI("right");
|
||||
iobCobCalculatorPlugin.clearCache();
|
||||
iobCobCalculatorPlugin.runCalculation("onClickRight", start, true, eventCustomCalculationFinished);
|
||||
}
|
||||
|
||||
@OnClick(R.id.historybrowse_end)
|
||||
void onClickEnd() {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTimeInMillis(System.currentTimeMillis());
|
||||
calendar.set(Calendar.MILLISECOND, 0);
|
||||
calendar.set(Calendar.SECOND, 0);
|
||||
calendar.set(Calendar.MINUTE, 0);
|
||||
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
||||
start = calendar.getTimeInMillis();
|
||||
updateGUI("resetToMidnight");
|
||||
iobCobCalculatorPlugin.clearCache();
|
||||
iobCobCalculatorPlugin.runCalculation("onClickEnd", start, true, eventCustomCalculationFinished);
|
||||
}
|
||||
|
||||
@OnClick(R.id.historybrowse_zoom)
|
||||
void onClickZoom() {
|
||||
rangeToDisplay += 6;
|
||||
rangeToDisplay = rangeToDisplay > 24 ? 6 : rangeToDisplay;
|
||||
updateGUI("rangeChange");
|
||||
}
|
||||
|
||||
@OnLongClick(R.id.historybrowse_zoom)
|
||||
boolean onLongClickZoom() {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTimeInMillis(start);
|
||||
calendar.set(Calendar.MILLISECOND, 0);
|
||||
calendar.set(Calendar.SECOND, 0);
|
||||
calendar.set(Calendar.MINUTE, 0);
|
||||
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
||||
start = calendar.getTimeInMillis();
|
||||
updateGUI("resetToMidnight");
|
||||
iobCobCalculatorPlugin.clearCache();
|
||||
iobCobCalculatorPlugin.runCalculation("onLongClickZoom", start, true, eventCustomCalculationFinished);
|
||||
return true;
|
||||
}
|
||||
|
||||
@OnClick(R.id.historybrowse_date)
|
||||
void onClickDate() {
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventAutosensCalculationFinished e) {
|
||||
Activity activity = this;
|
||||
if (activity != null && e.cause == eventCustomCalculationFinished) {
|
||||
log.debug("EventAutosensCalculationFinished");
|
||||
activity.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateGUI("EventAutosensCalculationFinished");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void updateGUI(String from) {
|
||||
final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
|
||||
final Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||
|
||||
if (profile == null) {
|
||||
noProfile.setVisibility(View.VISIBLE);
|
||||
return;
|
||||
} else {
|
||||
noProfile.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
final String units = profile.getUnits();
|
||||
|
||||
double lowLineSetting = SP.getDouble("low_mark", Profile.fromMgdlToUnits(OverviewPlugin.bgTargetLow, units));
|
||||
double highLineSetting = SP.getDouble("high_mark", Profile.fromMgdlToUnits(OverviewPlugin.bgTargetHigh, units));
|
||||
|
||||
if (lowLineSetting < 1)
|
||||
lowLineSetting = Profile.fromMgdlToUnits(76d, units);
|
||||
if (highLineSetting < 1)
|
||||
highLineSetting = Profile.fromMgdlToUnits(180d, units);
|
||||
|
||||
final double lowLine = lowLineSetting;
|
||||
final double highLine = highLineSetting;
|
||||
|
||||
final boolean showPrediction = false;
|
||||
|
||||
int hoursToFetch;
|
||||
final long toTime;
|
||||
final long fromTime;
|
||||
//if (showPrediction) {
|
||||
//int predHours = (int) (Math.ceil(((DetermineBasalResultAMA) finalLastRun.constraintsProcessed).getLatestPredictionsTime() - System.currentTimeMillis()) / (60 * 60 * 1000));
|
||||
//predHours = Math.min(2, predHours);
|
||||
//predHours = Math.max(0, predHours);
|
||||
//hoursToFetch = rangeToDisplay - predHours;
|
||||
//toTime = calendar.getTimeInMillis() + 100000; // little bit more to avoid wrong rounding - Graphview specific
|
||||
//fromTime = toTime - hoursToFetch * 60 * 60 * 1000L;
|
||||
//endTime = toTime + predHours * 60 * 60 * 1000L;
|
||||
//} else {
|
||||
fromTime = start + 100000;
|
||||
toTime = start + rangeToDisplay * 60 * 60 * 1000L;
|
||||
//}
|
||||
|
||||
buttonDate.setText(DateUtil.dateAndTimeString(start));
|
||||
buttonZoom.setText(String.valueOf(rangeToDisplay));
|
||||
|
||||
log.debug("Period: " + DateUtil.dateAndTimeString(fromTime) + " - " + DateUtil.dateAndTimeString(toTime));
|
||||
|
||||
final long pointer = System.currentTimeMillis();
|
||||
|
||||
// ------------------ 1st graph
|
||||
|
||||
final GraphData graphData = new GraphData(bgGraph, IobCobCalculatorPlugin.getPlugin());
|
||||
|
||||
// **** In range Area ****
|
||||
graphData.addInRangeArea(fromTime, toTime, lowLine, highLine);
|
||||
|
||||
// **** BG ****
|
||||
if (showPrediction)
|
||||
//graphData.addBgReadings(fromTime, toTime, lowLine, highLine, (DetermineBasalResultAMA) finalLastRun.constraintsProcessed);
|
||||
;
|
||||
else
|
||||
graphData.addBgReadings(fromTime, toTime, lowLine, highLine, null);
|
||||
|
||||
// set manual x bounds to have nice steps
|
||||
graphData.formatAxis(fromTime, toTime);
|
||||
|
||||
// Treatments
|
||||
graphData.addTreatments(fromTime, toTime);
|
||||
|
||||
// add basal data
|
||||
if (pump.getPumpDescription().isTempBasalCapable && showBasal) {
|
||||
graphData.addBasals(fromTime, toTime, lowLine / graphData.maxY / 1.2d);
|
||||
}
|
||||
|
||||
// **** NOW line ****
|
||||
graphData.addNowLine(pointer);
|
||||
|
||||
// ------------------ 2nd graph
|
||||
|
||||
final GraphData secondGraphData = new GraphData(iobGraph, iobCobCalculatorPlugin);
|
||||
|
||||
boolean useIobForScale = false;
|
||||
boolean useCobForScale = false;
|
||||
boolean useDevForScale = false;
|
||||
boolean useRatioForScale = false;
|
||||
boolean useDevSlopeForScale = false;
|
||||
|
||||
if (showIob) {
|
||||
useIobForScale = true;
|
||||
} else if (showCob) {
|
||||
useCobForScale = true;
|
||||
} else if (showDev) {
|
||||
useDevForScale = true;
|
||||
} else if (showRat) {
|
||||
useRatioForScale = true;
|
||||
} else if (showDevslope) {
|
||||
useDevSlopeForScale = true;
|
||||
}
|
||||
|
||||
if (showIob)
|
||||
secondGraphData.addIob(fromTime, toTime, useIobForScale, 1d);
|
||||
if (showCob)
|
||||
secondGraphData.addCob(fromTime, toTime, useCobForScale, useCobForScale ? 1d : 0.5d);
|
||||
if (showDev)
|
||||
secondGraphData.addDeviations(fromTime, toTime, useDevForScale, 1d);
|
||||
if (showRat)
|
||||
secondGraphData.addRatio(fromTime, toTime, useRatioForScale, 1d);
|
||||
if (showDevslope)
|
||||
secondGraphData.addDeviationSlope(fromTime, toTime, useDevSlopeForScale, 1d);
|
||||
|
||||
// **** NOW line ****
|
||||
// set manual x bounds to have nice steps
|
||||
secondGraphData.formatAxis(fromTime, toTime);
|
||||
secondGraphData.addNowLine(pointer);
|
||||
|
||||
// do GUI update
|
||||
if (showIob || showCob || showDev || showRat || showDevslope) {
|
||||
iobGraph.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
iobGraph.setVisibility(View.GONE);
|
||||
}
|
||||
// finally enforce drawing of graphs
|
||||
graphData.performUpdate();
|
||||
secondGraphData.performUpdate();
|
||||
}
|
||||
|
||||
private void setupChartMenu() {
|
||||
chartButton = (ImageButton) findViewById(R.id.overview_chartMenuButton);
|
||||
chartButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
MenuItem item;
|
||||
CharSequence title;
|
||||
SpannableString s;
|
||||
PopupMenu popup = new PopupMenu(v.getContext(), v);
|
||||
|
||||
|
||||
item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.BAS.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_basals));
|
||||
title = item.getTitle();
|
||||
s = new SpannableString(title);
|
||||
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.basal, null)), 0, s.length(), 0);
|
||||
item.setTitle(s);
|
||||
item.setCheckable(true);
|
||||
item.setChecked(showBasal);
|
||||
|
||||
item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.IOB.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_iob));
|
||||
title = item.getTitle();
|
||||
s = new SpannableString(title);
|
||||
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.iob, null)), 0, s.length(), 0);
|
||||
item.setTitle(s);
|
||||
item.setCheckable(true);
|
||||
item.setChecked(showIob);
|
||||
|
||||
item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.COB.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_cob));
|
||||
title = item.getTitle();
|
||||
s = new SpannableString(title);
|
||||
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.cob, null)), 0, s.length(), 0);
|
||||
item.setTitle(s);
|
||||
item.setCheckable(true);
|
||||
item.setChecked(showCob);
|
||||
|
||||
item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.DEV.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_deviations));
|
||||
title = item.getTitle();
|
||||
s = new SpannableString(title);
|
||||
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.deviations, null)), 0, s.length(), 0);
|
||||
item.setTitle(s);
|
||||
item.setCheckable(true);
|
||||
item.setChecked(showDev);
|
||||
|
||||
item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.SEN.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_sensitivity));
|
||||
title = item.getTitle();
|
||||
s = new SpannableString(title);
|
||||
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.ratio, null)), 0, s.length(), 0);
|
||||
item.setTitle(s);
|
||||
item.setCheckable(true);
|
||||
item.setChecked(showRat);
|
||||
|
||||
if (MainApp.devBranch) {
|
||||
item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.DEVSLOPE.ordinal(), Menu.NONE, "Deviation slope");
|
||||
title = item.getTitle();
|
||||
s = new SpannableString(title);
|
||||
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.devslopepos, null)), 0, s.length(), 0);
|
||||
item.setTitle(s);
|
||||
item.setCheckable(true);
|
||||
item.setChecked(showDevslope);
|
||||
}
|
||||
|
||||
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
if (item.getItemId() == OverviewFragment.CHARTTYPE.BAS.ordinal()) {
|
||||
showBasal = !item.isChecked();
|
||||
} else if (item.getItemId() == OverviewFragment.CHARTTYPE.IOB.ordinal()) {
|
||||
showIob = !item.isChecked();
|
||||
} else if (item.getItemId() == OverviewFragment.CHARTTYPE.COB.ordinal()) {
|
||||
showCob = !item.isChecked();
|
||||
} else if (item.getItemId() == OverviewFragment.CHARTTYPE.DEV.ordinal()) {
|
||||
showDev = !item.isChecked();
|
||||
} else if (item.getItemId() == OverviewFragment.CHARTTYPE.SEN.ordinal()) {
|
||||
showRat = !item.isChecked();
|
||||
} else if (item.getItemId() == OverviewFragment.CHARTTYPE.DEVSLOPE.ordinal()) {
|
||||
showDevslope = !item.isChecked();
|
||||
}
|
||||
updateGUI("onGraphCheckboxesCheckedChanged");
|
||||
return true;
|
||||
}
|
||||
});
|
||||
chartButton.setImageResource(R.drawable.ic_arrow_drop_up_white_24dp);
|
||||
popup.setOnDismissListener(new PopupMenu.OnDismissListener() {
|
||||
@Override
|
||||
public void onDismiss(PopupMenu menu) {
|
||||
chartButton.setImageResource(R.drawable.ic_arrow_drop_down_white_24dp);
|
||||
}
|
||||
});
|
||||
popup.show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -1,35 +1,34 @@
|
|||
package info.nightscout.androidaps;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Rect;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.PersistableBundle;
|
||||
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.content.ContextCompat;
|
||||
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.AppCompatActivity;
|
||||
import android.support.v7.widget.PopupMenu;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.text.SpannableString;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.text.util.Linkify;
|
||||
import android.view.MenuInflater;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.joanzapata.iconify.Iconify;
|
||||
|
@ -39,75 +38,148 @@ import com.squareup.otto.Subscribe;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.activities.AgreementActivity;
|
||||
import info.nightscout.androidaps.activities.HistoryBrowseActivity;
|
||||
import info.nightscout.androidaps.activities.PreferencesActivity;
|
||||
import info.nightscout.androidaps.activities.SingleFragmentActivity;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.events.EventAppExit;
|
||||
import info.nightscout.androidaps.events.EventFeatureRunning;
|
||||
import info.nightscout.androidaps.events.EventPreferenceChange;
|
||||
import info.nightscout.androidaps.events.EventRefreshGui;
|
||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.logging.LogSettingActivity;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions;
|
||||
import info.nightscout.androidaps.plugins.Food.FoodPlugin;
|
||||
import info.nightscout.androidaps.plugins.Overview.events.EventSetWakeLock;
|
||||
import info.nightscout.androidaps.plugins.NSClientInternal.data.NSSettingsStatus;
|
||||
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.utils.AndroidPermission;
|
||||
import info.nightscout.utils.ImportExportPrefs;
|
||||
import info.nightscout.utils.LocaleHelper;
|
||||
import info.nightscout.utils.LogDialog;
|
||||
import info.nightscout.utils.OKDialog;
|
||||
import info.nightscout.utils.PasswordProtection;
|
||||
import info.nightscout.utils.SP;
|
||||
import info.nightscout.utils.ToastUtils;
|
||||
|
||||
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
|
||||
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;
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
private static Logger log = LoggerFactory.getLogger(L.CORE);
|
||||
|
||||
protected PowerManager.WakeLock mWakeLock;
|
||||
|
||||
private ActionBarDrawerToggle actionBarDrawerToggle;
|
||||
|
||||
private MenuItem pluginPreferencesMenuItem;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle 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 (L.isEnabled(L.CORE))
|
||||
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();
|
||||
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 (L.isEnabled(L.CORE))
|
||||
log.debug("onResume");
|
||||
|
||||
if (!SP.getBoolean(R.string.key_setupwizard_processed, false)) {
|
||||
Intent intent = new Intent(this, SetupWizardActivity.class);
|
||||
startActivity(intent);
|
||||
} else {
|
||||
checkEula();
|
||||
}
|
||||
|
||||
AndroidPermission.notifyForStoragePermission(this);
|
||||
AndroidPermission.notifyForBatteryOptimizationPermission(this);
|
||||
if (BuildConfig.APS || BuildConfig.PUMPCONTROL) {
|
||||
AndroidPermission.notifyForLocationPermissions(this);
|
||||
AndroidPermission.notifyForSMSPermissions(this);
|
||||
}
|
||||
|
||||
MainApp.bus().post(new EventFeatureRunning(EventFeatureRunning.Feature.MAIN));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
if (L.isEnabled(L.CORE))
|
||||
log.debug("onDestroy");
|
||||
if (mWakeLock != null)
|
||||
if (mWakeLock.isHeld())
|
||||
mWakeLock.release();
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventSetWakeLock ev) {
|
||||
final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
|
||||
if (ev.lock) {
|
||||
mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "AAPS");
|
||||
if (!mWakeLock.isHeld())
|
||||
mWakeLock.acquire();
|
||||
} else {
|
||||
if (mWakeLock != null && mWakeLock.isHeld())
|
||||
mWakeLock.release();
|
||||
public void onEventPreferenceChange(final EventPreferenceChange ev) {
|
||||
if (ev.isChanged(R.string.key_keep_screen_on)) {
|
||||
boolean keepScreenOn = SP.getBoolean(R.string.key_keep_screen_on, false);
|
||||
final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
|
||||
if (keepScreenOn) {
|
||||
mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "AAPS");
|
||||
if (!mWakeLock.isHeld())
|
||||
mWakeLock.acquire();
|
||||
} else {
|
||||
if (mWakeLock != null && mWakeLock.isHeld())
|
||||
mWakeLock.release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -115,39 +187,75 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
public void onStatusEvent(final EventRefreshGui ev) {
|
||||
String lang = SP.getString("language", "en");
|
||||
LocaleHelper.setLocale(getApplicationContext(), lang);
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (ev.recreate) {
|
||||
recreate();
|
||||
} else {
|
||||
try { // activity may be destroyed
|
||||
setUpTabs(true);
|
||||
} catch (IllegalStateException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
runOnUiThread(() -> {
|
||||
if (ev.recreate) {
|
||||
recreate();
|
||||
} else {
|
||||
try { // activity may be destroyed
|
||||
setupTabs();
|
||||
setupViews(true);
|
||||
} catch (IllegalStateException 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);
|
||||
NavigationView navigationView = findViewById(R.id.navigation_view);
|
||||
navigationView.setNavigationItemSelectedListener(menuItem -> {
|
||||
return true;
|
||||
});
|
||||
Menu menu = navigationView.getMenu();
|
||||
menu.clear();
|
||||
for (PluginBase p : MainApp.getPluginsList()) {
|
||||
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);
|
||||
SlidingTabLayout mTabs = (SlidingTabLayout) findViewById(R.id.tabs);
|
||||
mTabs.setViewPager(mPager);
|
||||
if (switchToLast)
|
||||
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() {
|
||||
|
@ -185,7 +293,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
private void checkUpgradeToProfileTarget() { // TODO: can be removed in the future
|
||||
boolean oldKeyExists = SP.contains("openapsma_min_bg");
|
||||
if (oldKeyExists) {
|
||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||
String oldRange = SP.getDouble("openapsma_min_bg", 0d) + " - " + SP.getDouble("openapsma_max_bg", 0d);
|
||||
String newRange = "";
|
||||
if (profile != null) {
|
||||
|
@ -205,120 +313,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
|
||||
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
if (permissions.length != 0) {
|
||||
if (ActivityCompat.checkSelfPermission(this, permissions[0]) == PackageManager.PERMISSION_GRANTED) {
|
||||
switch (requestCode) {
|
||||
case CASE_STORAGE:
|
||||
case AndroidPermission.CASE_STORAGE:
|
||||
//show dialog after permission is granted
|
||||
AlertDialog.Builder alert = new AlertDialog.Builder(this);
|
||||
alert.setMessage(R.string.alert_dialog_storage_permission_text);
|
||||
alert.setPositiveButton(R.string.ok, null);
|
||||
alert.show();
|
||||
break;
|
||||
case CASE_LOCATION:
|
||||
case CASE_SMS:
|
||||
case AndroidPermission.CASE_LOCATION:
|
||||
case AndroidPermission.CASE_SMS:
|
||||
case AndroidPermission.CASE_BATTERY:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -343,96 +353,99 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onClick(final View v) {
|
||||
final Activity activity = this;
|
||||
switch (v.getId()) {
|
||||
case R.id.overview_menuButton:
|
||||
PopupMenu popup = new PopupMenu(v.getContext(), v);
|
||||
MenuInflater inflater = popup.getMenuInflater();
|
||||
inflater.inflate(R.menu.menu_main, popup.getMenu());
|
||||
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
int id = item.getItemId();
|
||||
switch (id) {
|
||||
case R.id.nav_preferences:
|
||||
PasswordProtection.QueryPassword(v.getContext(), R.string.settings_password, "settings_password", new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Intent i = new Intent(v.getContext(), PreferencesActivity.class);
|
||||
i.putExtra("id", -1);
|
||||
startActivity(i);
|
||||
}
|
||||
}, null);
|
||||
break;
|
||||
case R.id.nav_historybrowser:
|
||||
startActivity(new Intent(v.getContext(), HistoryBrowseActivity.class));
|
||||
break;
|
||||
case R.id.nav_resetdb:
|
||||
new AlertDialog.Builder(v.getContext())
|
||||
.setTitle(R.string.nav_resetdb)
|
||||
.setMessage(R.string.reset_db_confirm)
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
MainApp.getDbHelper().resetDatabases();
|
||||
// should be handled by Plugin-Interface and
|
||||
// additional service interface and plugin registry
|
||||
FoodPlugin.getPlugin().getService().resetFood();
|
||||
TreatmentsPlugin.getPlugin().getService().resetTreatments();
|
||||
}
|
||||
})
|
||||
.create()
|
||||
.show();
|
||||
break;
|
||||
case R.id.nav_export:
|
||||
ImportExportPrefs.verifyStoragePermissions(activity);
|
||||
ImportExportPrefs.exportSharedPreferences(activity);
|
||||
break;
|
||||
case R.id.nav_import:
|
||||
ImportExportPrefs.verifyStoragePermissions(activity);
|
||||
ImportExportPrefs.importSharedPreferences(activity);
|
||||
break;
|
||||
case R.id.nav_show_logcat:
|
||||
LogDialog.showLogcat(v.getContext());
|
||||
break;
|
||||
case R.id.nav_about:
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext());
|
||||
builder.setTitle(MainApp.gs(R.string.app_name) + " " + BuildConfig.VERSION);
|
||||
if (Config.NSCLIENT || Config.G5UPLOADER)
|
||||
builder.setIcon(R.mipmap.yellowowl);
|
||||
else
|
||||
builder.setIcon(R.mipmap.blueowl);
|
||||
String message = "Build: " + BuildConfig.BUILDVERSION + "\n";
|
||||
message += "Flavor: " + BuildConfig.FLAVOR + BuildConfig.BUILD_TYPE + "\n";
|
||||
message += MainApp.gs(R.string.configbuilder_nightscoutversion_label) + " " + ConfigBuilderPlugin.nightscoutVersionName;
|
||||
if (MainApp.engineeringMode)
|
||||
message += "\n" + MainApp.gs(R.string.engineering_mode_enabled);
|
||||
message += MainApp.gs(R.string.about_link_urls);
|
||||
final SpannableString messageSpanned = new SpannableString(message);
|
||||
Linkify.addLinks(messageSpanned, Linkify.WEB_URLS);
|
||||
builder.setMessage(messageSpanned);
|
||||
builder.setPositiveButton(MainApp.gs(R.string.ok), null);
|
||||
AlertDialog alertDialog = builder.create();
|
||||
alertDialog.show();
|
||||
((TextView)alertDialog.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance());
|
||||
break;
|
||||
case R.id.nav_exit:
|
||||
log.debug("Exiting");
|
||||
MainApp.instance().stopKeepAliveService();
|
||||
MainApp.bus().post(new EventAppExit());
|
||||
MainApp.closeDbHelper();
|
||||
finish();
|
||||
System.runFinalization();
|
||||
System.exit(0);
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
popup.show();
|
||||
break;
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_main, menu);
|
||||
pluginPreferencesMenuItem = menu.findItem(R.id.nav_plugin_preferences);
|
||||
checkPluginPreferences(findViewById(R.id.pager));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
int id = item.getItemId();
|
||||
switch (id) {
|
||||
case R.id.nav_preferences:
|
||||
PasswordProtection.QueryPassword(this, R.string.settings_password, "settings_password", () -> {
|
||||
Intent i = new Intent(this, PreferencesActivity.class);
|
||||
i.putExtra("id", -1);
|
||||
startActivity(i);
|
||||
}, null);
|
||||
return true;
|
||||
case R.id.nav_historybrowser:
|
||||
startActivity(new Intent(this, HistoryBrowseActivity.class));
|
||||
return true;
|
||||
case R.id.nav_setupwizard:
|
||||
startActivity(new Intent(this, SetupWizardActivity.class));
|
||||
return true;
|
||||
case R.id.nav_resetdb:
|
||||
new AlertDialog.Builder(this)
|
||||
.setTitle(R.string.nav_resetdb)
|
||||
.setMessage(R.string.reset_db_confirm)
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.setPositiveButton(android.R.string.ok, (dialog, which) -> {
|
||||
MainApp.getDbHelper().resetDatabases();
|
||||
// should be handled by Plugin-Interface and
|
||||
// additional service interface and plugin registry
|
||||
FoodPlugin.getPlugin().getService().resetFood();
|
||||
TreatmentsPlugin.getPlugin().getService().resetTreatments();
|
||||
})
|
||||
.create()
|
||||
.show();
|
||||
return true;
|
||||
case R.id.nav_export:
|
||||
ImportExportPrefs.verifyStoragePermissions(this);
|
||||
ImportExportPrefs.exportSharedPreferences(this);
|
||||
return true;
|
||||
case R.id.nav_import:
|
||||
ImportExportPrefs.verifyStoragePermissions(this);
|
||||
ImportExportPrefs.importSharedPreferences(this);
|
||||
return true;
|
||||
case R.id.nav_show_logcat:
|
||||
LogDialog.showLogcat(this);
|
||||
return true;
|
||||
case R.id.nav_logsettings:
|
||||
startActivity(new Intent(this, LogSettingActivity.class));
|
||||
return true;
|
||||
case R.id.nav_about:
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setTitle(MainApp.gs(R.string.app_name) + " " + BuildConfig.VERSION);
|
||||
if (Config.NSCLIENT || Config.G5UPLOADER)
|
||||
builder.setIcon(R.mipmap.yellowowl);
|
||||
else
|
||||
builder.setIcon(R.mipmap.blueowl);
|
||||
String message = "Build: " + BuildConfig.BUILDVERSION + "\n";
|
||||
message += "Flavor: " + BuildConfig.FLAVOR + BuildConfig.BUILD_TYPE + "\n";
|
||||
message += MainApp.gs(R.string.configbuilder_nightscoutversion_label) + " " + NSSettingsStatus.getInstance().nightscoutVersionName;
|
||||
if (MainApp.engineeringMode)
|
||||
message += "\n" + MainApp.gs(R.string.engineering_mode_enabled);
|
||||
message += MainApp.gs(R.string.about_link_urls);
|
||||
final SpannableString messageSpanned = new SpannableString(message);
|
||||
Linkify.addLinks(messageSpanned, Linkify.WEB_URLS);
|
||||
builder.setMessage(messageSpanned);
|
||||
builder.setPositiveButton(MainApp.gs(R.string.ok), null);
|
||||
AlertDialog alertDialog = builder.create();
|
||||
alertDialog.show();
|
||||
((TextView) alertDialog.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance());
|
||||
return true;
|
||||
case R.id.nav_exit:
|
||||
log.debug("Exiting");
|
||||
MainApp.instance().stopKeepAliveService();
|
||||
MainApp.bus().post(new EventAppExit());
|
||||
MainApp.closeDbHelper();
|
||||
finish();
|
||||
System.runFinalization();
|
||||
System.exit(0);
|
||||
return true;
|
||||
case R.id.nav_plugin_preferences:
|
||||
ViewPager viewPager = findViewById(R.id.pager);
|
||||
final PluginBase plugin = ((TabPageAdapter) viewPager.getAdapter()).getPluginAt(viewPager.getCurrentItem());
|
||||
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 actionBarDrawerToggle.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,11 +5,11 @@ import android.content.IntentFilter;
|
|||
import android.content.res.Resources;
|
||||
import android.os.SystemClock;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.PluralsRes;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
|
||||
import com.crashlytics.android.Crashlytics;
|
||||
import com.crashlytics.android.answers.Answers;
|
||||
import com.crashlytics.android.answers.CustomEvent;
|
||||
import com.j256.ormlite.android.apptools.OpenHelperManager;
|
||||
import com.squareup.otto.Bus;
|
||||
import com.squareup.otto.LoggingBus;
|
||||
|
@ -24,12 +24,12 @@ import java.io.File;
|
|||
import java.util.ArrayList;
|
||||
|
||||
import ch.qos.logback.classic.LoggerContext;
|
||||
import info.nightscout.androidaps.Services.Intents;
|
||||
import info.nightscout.androidaps.data.ConstraintChecker;
|
||||
import info.nightscout.androidaps.db.DatabaseHelper;
|
||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
import info.nightscout.androidaps.interfaces.PluginType;
|
||||
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.Actions.ActionsFragment;
|
||||
import info.nightscout.androidaps.plugins.Careportal.CareportalPlugin;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
|
@ -42,13 +42,12 @@ import info.nightscout.androidaps.plugins.Insulin.InsulinOrefUltraRapidActingPlu
|
|||
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
|
||||
import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
|
||||
import info.nightscout.androidaps.plugins.NSClientInternal.NSClientPlugin;
|
||||
import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload;
|
||||
import info.nightscout.androidaps.plugins.NSClientInternal.receivers.AckAlarmReceiver;
|
||||
import info.nightscout.androidaps.plugins.OpenAPSAMA.OpenAPSAMAPlugin;
|
||||
import info.nightscout.androidaps.plugins.OpenAPSMA.OpenAPSMAPlugin;
|
||||
import info.nightscout.androidaps.plugins.OpenAPSSMB.OpenAPSSMBPlugin;
|
||||
import info.nightscout.androidaps.plugins.Overview.OverviewPlugin;
|
||||
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
|
||||
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
|
||||
import info.nightscout.androidaps.plugins.Persistentnotification.PersistentNotificationPlugin;
|
||||
import info.nightscout.androidaps.plugins.ProfileLocal.LocalProfilePlugin;
|
||||
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.PumpMDI.MDIPlugin;
|
||||
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
|
||||
import info.nightscout.androidaps.plugins.SensitivityAAPS.SensitivityAAPSPlugin;
|
||||
import info.nightscout.androidaps.plugins.SensitivityOref0.SensitivityOref0Plugin;
|
||||
import info.nightscout.androidaps.plugins.SensitivityWeightedAverage.SensitivityWeightedAveragePlugin;
|
||||
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityAAPSPlugin;
|
||||
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityOref0Plugin;
|
||||
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityOref1Plugin;
|
||||
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityWeightedAveragePlugin;
|
||||
import info.nightscout.androidaps.plugins.SmsCommunicator.SmsCommunicatorPlugin;
|
||||
import info.nightscout.androidaps.plugins.Source.SourceDexcomG5Plugin;
|
||||
import info.nightscout.androidaps.plugins.Source.SourceGlimpPlugin;
|
||||
import info.nightscout.androidaps.plugins.Source.SourceMM640gPlugin;
|
||||
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.Treatments.TreatmentsPlugin;
|
||||
import info.nightscout.androidaps.plugins.Wear.WearPlugin;
|
||||
|
@ -76,13 +77,13 @@ import info.nightscout.androidaps.plugins.XDripStatusline.StatuslinePlugin;
|
|||
import info.nightscout.androidaps.receivers.DataReceiver;
|
||||
import info.nightscout.androidaps.receivers.KeepAliveReceiver;
|
||||
import info.nightscout.androidaps.receivers.NSAlarmReceiver;
|
||||
import info.nightscout.androidaps.services.Intents;
|
||||
import info.nightscout.utils.FabricPrivacy;
|
||||
import info.nightscout.utils.NSUpload;
|
||||
import io.fabric.sdk.android.Fabric;
|
||||
|
||||
|
||||
public class MainApp extends Application {
|
||||
private static Logger log = LoggerFactory.getLogger(MainApp.class);
|
||||
private static Logger log = LoggerFactory.getLogger(L.CORE);
|
||||
private static KeepAliveReceiver keepAliveReceiver;
|
||||
|
||||
private static Bus sBus;
|
||||
|
@ -106,6 +107,7 @@ public class MainApp extends Application {
|
|||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
log.debug("onCreate");
|
||||
sInstance = this;
|
||||
sResources = getResources();
|
||||
sConstraintsChecker = new ConstraintChecker(this);
|
||||
|
@ -118,7 +120,7 @@ public class MainApp extends Application {
|
|||
Crashlytics.setString("BUILDVERSION", BuildConfig.BUILDVERSION);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
android.util.Log.e("ANDROIDAPS", "Error with Fabric init! " + e);
|
||||
log.error("Error with Fabric init! " + e);
|
||||
}
|
||||
|
||||
JodaTimeAndroid.init(this);
|
||||
|
@ -132,7 +134,7 @@ public class MainApp extends Application {
|
|||
engineeringMode = engineeringModeSemaphore.exists() && engineeringModeSemaphore.isFile();
|
||||
devBranch = BuildConfig.VERSION.contains("dev");
|
||||
|
||||
sBus = Config.logEvents ? new LoggingBus(ThreadEnforcer.ANY) : new Bus(ThreadEnforcer.ANY);
|
||||
sBus = L.isEnabled(L.EVENTS) ? new LoggingBus(ThreadEnforcer.ANY) : new Bus(ThreadEnforcer.ANY);
|
||||
|
||||
registerLocalBroadcastReceiver();
|
||||
|
||||
|
@ -148,6 +150,7 @@ public class MainApp extends Application {
|
|||
pluginsList.add(SensitivityOref0Plugin.getPlugin());
|
||||
pluginsList.add(SensitivityAAPSPlugin.getPlugin());
|
||||
pluginsList.add(SensitivityWeightedAveragePlugin.getPlugin());
|
||||
pluginsList.add(SensitivityOref1Plugin.getPlugin());
|
||||
if (Config.HWPUMPS) pluginsList.add(DanaRPlugin.getPlugin());
|
||||
if (Config.HWPUMPS) pluginsList.add(DanaRKoreanPlugin.getPlugin());
|
||||
if (Config.HWPUMPS) pluginsList.add(DanaRv2Plugin.getPlugin());
|
||||
|
@ -178,30 +181,22 @@ public class MainApp extends Application {
|
|||
pluginsList.add(SourceGlimpPlugin.getPlugin());
|
||||
if (!Config.NSCLIENT)
|
||||
pluginsList.add(SourceDexcomG5Plugin.getPlugin());
|
||||
if (!Config.NSCLIENT)
|
||||
pluginsList.add(SourcePoctechPlugin.getPlugin());
|
||||
if (Config.SMSCOMMUNICATORENABLED) pluginsList.add(SmsCommunicatorPlugin.getPlugin());
|
||||
pluginsList.add(FoodPlugin.getPlugin());
|
||||
|
||||
pluginsList.add(WearPlugin.initPlugin(this));
|
||||
pluginsList.add(StatuslinePlugin.initPlugin(this));
|
||||
pluginsList.add(new PersistentNotificationPlugin(this));
|
||||
pluginsList.add(PersistentNotificationPlugin.getPlugin());
|
||||
pluginsList.add(NSClientPlugin.getPlugin());
|
||||
|
||||
pluginsList.add(sConfigBuilder = ConfigBuilderPlugin.getPlugin());
|
||||
|
||||
MainApp.getConfigBuilder().initialize();
|
||||
}
|
||||
NSUpload.uploadAppStart();
|
||||
|
||||
if (Config.NSCLIENT)
|
||||
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"));
|
||||
NSUpload.uploadAppStart();
|
||||
|
||||
final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
|
||||
if (pump != null) {
|
||||
|
@ -278,6 +273,10 @@ public class MainApp extends Application {
|
|||
return sResources.getString(id, args);
|
||||
}
|
||||
|
||||
public static String gq(@PluralsRes int id, int quantity, Object... args) {
|
||||
return sResources.getQuantityString(id, quantity, args);
|
||||
}
|
||||
|
||||
public static int gc(int id) {
|
||||
return sResources.getColor(id);
|
||||
}
|
||||
|
@ -397,6 +396,8 @@ public class MainApp extends Application {
|
|||
|
||||
@Override
|
||||
public void onTerminate() {
|
||||
if (L.isEnabled(L.CORE))
|
||||
log.debug("onTerminate");
|
||||
super.onTerminate();
|
||||
if (sDatabaseHelper != null) {
|
||||
sDatabaseHelper.close();
|
||||
|
|
|
@ -1,558 +0,0 @@
|
|||
package info.nightscout.androidaps.Services;
|
||||
|
||||
import android.app.IntentService;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Telephony;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.Config;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.ProfileStore;
|
||||
import info.nightscout.androidaps.db.BgReading;
|
||||
import info.nightscout.androidaps.db.CareportalEvent;
|
||||
import info.nightscout.androidaps.events.EventNsFood;
|
||||
import info.nightscout.androidaps.events.EventNsTreatment;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin;
|
||||
import info.nightscout.androidaps.plugins.NSClientInternal.data.NSDeviceStatus;
|
||||
import info.nightscout.androidaps.plugins.NSClientInternal.data.NSMbg;
|
||||
import info.nightscout.androidaps.plugins.NSClientInternal.data.NSSettingsStatus;
|
||||
import info.nightscout.androidaps.plugins.NSClientInternal.data.NSSgv;
|
||||
import info.nightscout.androidaps.plugins.Overview.OverviewPlugin;
|
||||
import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification;
|
||||
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
|
||||
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
|
||||
import info.nightscout.androidaps.plugins.ProfileNS.NSProfilePlugin;
|
||||
import info.nightscout.androidaps.plugins.ProfileNS.events.EventNSProfileUpdateGUI;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.activities.DanaRNSHistorySync;
|
||||
import info.nightscout.androidaps.plugins.SmsCommunicator.events.EventNewSMS;
|
||||
import info.nightscout.androidaps.plugins.Source.SourceDexcomG5Plugin;
|
||||
import info.nightscout.androidaps.plugins.Source.SourceGlimpPlugin;
|
||||
import info.nightscout.androidaps.plugins.Source.SourceMM640gPlugin;
|
||||
import info.nightscout.androidaps.plugins.Source.SourceNSClientPlugin;
|
||||
import info.nightscout.androidaps.plugins.Source.SourceXdripPlugin;
|
||||
import info.nightscout.androidaps.receivers.DataReceiver;
|
||||
import info.nightscout.utils.BundleLogger;
|
||||
import info.nightscout.utils.JsonHelper;
|
||||
import info.nightscout.utils.NSUpload;
|
||||
import info.nightscout.utils.SP;
|
||||
|
||||
|
||||
public class DataService extends IntentService {
|
||||
private static Logger log = LoggerFactory.getLogger(DataService.class);
|
||||
|
||||
boolean xDripEnabled = false;
|
||||
boolean nsClientEnabled = true;
|
||||
boolean mm640gEnabled = false;
|
||||
boolean glimpEnabled = false;
|
||||
boolean dexcomG5Enabled = false;
|
||||
|
||||
public DataService() {
|
||||
super("DataService");
|
||||
registerBus();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onHandleIntent(final Intent intent) {
|
||||
if (Config.logFunctionCalls)
|
||||
log.debug("onHandleIntent " + BundleLogger.log(intent.getExtras()));
|
||||
if (ConfigBuilderPlugin.getPlugin().getActiveBgSource() == null) {
|
||||
xDripEnabled = true;
|
||||
nsClientEnabled = false;
|
||||
mm640gEnabled = false;
|
||||
glimpEnabled = false;
|
||||
dexcomG5Enabled = false;
|
||||
} else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceXdripPlugin.class)) {
|
||||
xDripEnabled = true;
|
||||
nsClientEnabled = false;
|
||||
mm640gEnabled = false;
|
||||
glimpEnabled = false;
|
||||
dexcomG5Enabled = false;
|
||||
} else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceNSClientPlugin.class)) {
|
||||
xDripEnabled = false;
|
||||
nsClientEnabled = true;
|
||||
mm640gEnabled = false;
|
||||
glimpEnabled = false;
|
||||
dexcomG5Enabled = false;
|
||||
} else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceMM640gPlugin.class)) {
|
||||
xDripEnabled = false;
|
||||
nsClientEnabled = false;
|
||||
mm640gEnabled = true;
|
||||
glimpEnabled = false;
|
||||
dexcomG5Enabled = false;
|
||||
} else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceGlimpPlugin.class)) {
|
||||
xDripEnabled = false;
|
||||
nsClientEnabled = false;
|
||||
mm640gEnabled = false;
|
||||
glimpEnabled = true;
|
||||
dexcomG5Enabled = false;
|
||||
} else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceDexcomG5Plugin.class)) {
|
||||
xDripEnabled = false;
|
||||
nsClientEnabled = false;
|
||||
mm640gEnabled = false;
|
||||
glimpEnabled = false;
|
||||
dexcomG5Enabled = true;
|
||||
}
|
||||
|
||||
boolean isNSProfile = MainApp.getConfigBuilder().getActiveProfileInterface() != null && MainApp.getConfigBuilder().getActiveProfileInterface().getClass().equals(NSProfilePlugin.class);
|
||||
|
||||
boolean acceptNSData = !SP.getBoolean(R.string.key_ns_upload_only, false);
|
||||
Bundle bundles = intent.getExtras();
|
||||
if (bundles != null && bundles.containsKey("islocal")) {
|
||||
acceptNSData = acceptNSData || bundles.getBoolean("islocal");
|
||||
}
|
||||
|
||||
|
||||
if (intent != null) {
|
||||
final String action = intent.getAction();
|
||||
if (Intents.ACTION_NEW_BG_ESTIMATE.equals(action)) {
|
||||
if (xDripEnabled) {
|
||||
handleNewDataFromXDrip(intent);
|
||||
}
|
||||
} else if (Intents.NS_EMULATOR.equals(action)) {
|
||||
if (mm640gEnabled) {
|
||||
handleNewDataFromMM640g(intent);
|
||||
}
|
||||
} else if (Intents.GLIMP_BG.equals(action)) {
|
||||
if (glimpEnabled) {
|
||||
handleNewDataFromGlimp(intent);
|
||||
}
|
||||
} else if (Intents.DEXCOMG5_BG.equals(action)) {
|
||||
if (dexcomG5Enabled) {
|
||||
handleNewDataFromDexcomG5(intent);
|
||||
}
|
||||
} else if (Intents.ACTION_NEW_SGV.equals(action)) {
|
||||
if (nsClientEnabled || SP.getBoolean(R.string.key_ns_autobackfill, true))
|
||||
handleNewDataFromNSClient(intent);
|
||||
// Objectives 0
|
||||
ObjectivesPlugin.bgIsAvailableInNS = true;
|
||||
ObjectivesPlugin.saveProgress();
|
||||
} else if (isNSProfile && Intents.ACTION_NEW_PROFILE.equals(action) || Intents.ACTION_NEW_DEVICESTATUS.equals(action)) {
|
||||
// always handle Profile if NSProfile is enabled without looking at nsUploadOnly
|
||||
handleNewDataFromNSClient(intent);
|
||||
} else if (acceptNSData &&
|
||||
(Intents.ACTION_NEW_TREATMENT.equals(action) ||
|
||||
Intents.ACTION_CHANGED_TREATMENT.equals(action) ||
|
||||
Intents.ACTION_REMOVED_TREATMENT.equals(action) ||
|
||||
Intents.ACTION_NEW_STATUS.equals(action) ||
|
||||
Intents.ACTION_NEW_DEVICESTATUS.equals(action) ||
|
||||
Intents.ACTION_NEW_FOOD.equals(action) ||
|
||||
Intents.ACTION_CHANGED_FOOD.equals(action) ||
|
||||
Intents.ACTION_REMOVED_FOOD.equals(action) ||
|
||||
Intents.ACTION_NEW_CAL.equals(action) ||
|
||||
Intents.ACTION_NEW_MBG.equals(action))
|
||||
) {
|
||||
handleNewDataFromNSClient(intent);
|
||||
} else if (Telephony.Sms.Intents.SMS_RECEIVED_ACTION.equals(action)) {
|
||||
handleNewSMS(intent);
|
||||
}
|
||||
}
|
||||
if (Config.logFunctionCalls)
|
||||
log.debug("onHandleIntent exit " + intent);
|
||||
DataReceiver.completeWakefulIntent(intent);
|
||||
}
|
||||
|
||||
/*
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
super.onStartCommand(intent, flags, startId);
|
||||
|
||||
if (Config.logFunctionCalls)
|
||||
log.debug("onStartCommand");
|
||||
|
||||
return START_STICKY;
|
||||
}
|
||||
*/
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
MainApp.bus().unregister(this);
|
||||
}
|
||||
|
||||
private void registerBus() {
|
||||
try {
|
||||
MainApp.bus().unregister(this);
|
||||
} catch (RuntimeException x) {
|
||||
// Ignore
|
||||
}
|
||||
MainApp.bus().register(this);
|
||||
}
|
||||
|
||||
private void handleNewDataFromXDrip(Intent intent) {
|
||||
Bundle bundle = intent.getExtras();
|
||||
if (bundle == null) return;
|
||||
|
||||
BgReading bgReading = new BgReading();
|
||||
|
||||
bgReading.value = bundle.getDouble(Intents.EXTRA_BG_ESTIMATE);
|
||||
bgReading.direction = bundle.getString(Intents.EXTRA_BG_SLOPE_NAME);
|
||||
bgReading.date = bundle.getLong(Intents.EXTRA_TIMESTAMP);
|
||||
bgReading.raw = bundle.getDouble(Intents.EXTRA_RAW);
|
||||
String source = bundle.getString(Intents.XDRIP_DATA_SOURCE_DESCRIPTION, "no Source specified");
|
||||
SourceXdripPlugin.getPlugin().setSource(source);
|
||||
MainApp.getDbHelper().createIfNotExists(bgReading, "XDRIP");
|
||||
}
|
||||
|
||||
private void handleNewDataFromGlimp(Intent intent) {
|
||||
Bundle bundle = intent.getExtras();
|
||||
if (bundle == null) return;
|
||||
|
||||
BgReading bgReading = new BgReading();
|
||||
|
||||
bgReading.value = bundle.getDouble("mySGV");
|
||||
bgReading.direction = bundle.getString("myTrend");
|
||||
bgReading.date = bundle.getLong("myTimestamp");
|
||||
bgReading.raw = 0;
|
||||
|
||||
MainApp.getDbHelper().createIfNotExists(bgReading, "GLIMP");
|
||||
}
|
||||
|
||||
private void handleNewDataFromDexcomG5(Intent intent) {
|
||||
// onHandleIntent Bundle{ data => [{"m_time":1511939180,"m_trend":"NotComputable","m_value":335}]; android.support.content.wakelockid => 95; }Bundle
|
||||
|
||||
Bundle bundle = intent.getExtras();
|
||||
if (bundle == null) return;
|
||||
|
||||
BgReading bgReading = new BgReading();
|
||||
|
||||
String data = bundle.getString("data");
|
||||
log.debug("Received Dexcom Data", data);
|
||||
|
||||
try {
|
||||
JSONArray jsonArray = new JSONArray(data);
|
||||
log.debug("Received Dexcom Data size:" + jsonArray.length());
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
JSONObject json = jsonArray.getJSONObject(i);
|
||||
bgReading.value = json.getInt("m_value");
|
||||
bgReading.direction = json.getString("m_trend");
|
||||
bgReading.date = json.getLong("m_time") * 1000L;
|
||||
bgReading.raw = 0;
|
||||
boolean isNew = MainApp.getDbHelper().createIfNotExists(bgReading, "DexcomG5");
|
||||
if (isNew && SP.getBoolean(R.string.key_dexcomg5_nsupload, false)) {
|
||||
NSUpload.uploadBg(bgReading);
|
||||
}
|
||||
if (isNew && SP.getBoolean(R.string.key_dexcomg5_xdripupload, false)) {
|
||||
NSUpload.sendToXdrip(bgReading);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void handleNewDataFromMM640g(Intent intent) {
|
||||
Bundle bundle = intent.getExtras();
|
||||
if (bundle == null) return;
|
||||
|
||||
final String collection = bundle.getString("collection");
|
||||
if (collection == null) return;
|
||||
|
||||
if (collection.equals("entries")) {
|
||||
final String data = bundle.getString("data");
|
||||
|
||||
if ((data != null) && (data.length() > 0)) {
|
||||
try {
|
||||
final JSONArray json_array = new JSONArray(data);
|
||||
for (int i = 0; i < json_array.length(); i++) {
|
||||
final JSONObject json_object = json_array.getJSONObject(i);
|
||||
final String type = json_object.getString("type");
|
||||
switch (type) {
|
||||
case "sgv":
|
||||
BgReading bgReading = new BgReading();
|
||||
|
||||
bgReading.value = json_object.getDouble("sgv");
|
||||
bgReading.direction = json_object.getString("direction");
|
||||
bgReading.date = json_object.getLong("date");
|
||||
bgReading.raw = json_object.getDouble("sgv");
|
||||
|
||||
MainApp.getDbHelper().createIfNotExists(bgReading, "MM640g");
|
||||
break;
|
||||
default:
|
||||
log.debug("Unknown entries type: " + type);
|
||||
}
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
log.error("Got JSON exception: " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleNewDataFromNSClient(Intent intent) {
|
||||
Bundle bundles = intent.getExtras();
|
||||
if (bundles == null) return;
|
||||
if (Config.logIncommingData)
|
||||
log.debug("Got intent: " + intent.getAction());
|
||||
|
||||
|
||||
if (intent.getAction().equals(Intents.ACTION_NEW_STATUS)) {
|
||||
if (bundles.containsKey("nsclientversioncode")) {
|
||||
ConfigBuilderPlugin.nightscoutVersionCode = bundles.getInt("nightscoutversioncode"); // for ver 1.2.3 contains 10203
|
||||
ConfigBuilderPlugin.nightscoutVersionName = bundles.getString("nightscoutversionname");
|
||||
ConfigBuilderPlugin.nsClientVersionCode = bundles.getInt("nsclientversioncode"); // for ver 1.17 contains 117
|
||||
ConfigBuilderPlugin.nsClientVersionName = bundles.getString("nsclientversionname");
|
||||
log.debug("Got versions: NSClient: " + ConfigBuilderPlugin.nsClientVersionName + " Nightscout: " + ConfigBuilderPlugin.nightscoutVersionName);
|
||||
try {
|
||||
if (ConfigBuilderPlugin.nsClientVersionCode < MainApp.instance().getPackageManager().getPackageInfo(MainApp.instance().getPackageName(), 0).versionCode) {
|
||||
Notification notification = new Notification(Notification.OLD_NSCLIENT, MainApp.gs(R.string.unsupportedclientver), Notification.URGENT);
|
||||
MainApp.bus().post(new EventNewNotification(notification));
|
||||
} else {
|
||||
MainApp.bus().post(new EventDismissNotification(Notification.OLD_NSCLIENT));
|
||||
}
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
if (ConfigBuilderPlugin.nightscoutVersionCode < Config.SUPPORTEDNSVERSION) {
|
||||
Notification notification = new Notification(Notification.OLD_NS, MainApp.gs(R.string.unsupportednsversion), Notification.NORMAL);
|
||||
MainApp.bus().post(new EventNewNotification(notification));
|
||||
} else {
|
||||
MainApp.bus().post(new EventDismissNotification(Notification.OLD_NS));
|
||||
}
|
||||
} else {
|
||||
Notification notification = new Notification(Notification.OLD_NSCLIENT, MainApp.gs(R.string.unsupportedclientver), Notification.URGENT);
|
||||
MainApp.bus().post(new EventNewNotification(notification));
|
||||
}
|
||||
if (bundles.containsKey("status")) {
|
||||
try {
|
||||
JSONObject statusJson = new JSONObject(bundles.getString("status"));
|
||||
NSSettingsStatus.getInstance().setData(statusJson);
|
||||
if (Config.logIncommingData)
|
||||
log.debug("Received status: " + statusJson.toString());
|
||||
Double targetHigh = NSSettingsStatus.getInstance().getThreshold("bgTargetTop");
|
||||
Double targetlow = NSSettingsStatus.getInstance().getThreshold("bgTargetBottom");
|
||||
if (targetHigh != null)
|
||||
OverviewPlugin.bgTargetHigh = targetHigh;
|
||||
if (targetlow != null)
|
||||
OverviewPlugin.bgTargetLow = targetlow;
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (intent.getAction().equals(Intents.ACTION_NEW_DEVICESTATUS)) {
|
||||
try {
|
||||
if (bundles.containsKey("devicestatus")) {
|
||||
JSONObject devicestatusJson = new JSONObject(bundles.getString("devicestatus"));
|
||||
NSDeviceStatus.getInstance().setData(devicestatusJson);
|
||||
if (devicestatusJson.has("pump")) {
|
||||
// Objectives 0
|
||||
ObjectivesPlugin.pumpStatusIsAvailableInNS = true;
|
||||
ObjectivesPlugin.saveProgress();
|
||||
}
|
||||
}
|
||||
if (bundles.containsKey("devicestatuses")) {
|
||||
String devicestatusesstring = bundles.getString("devicestatuses");
|
||||
JSONArray jsonArray = new JSONArray(devicestatusesstring);
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
JSONObject devicestatusJson = jsonArray.getJSONObject(i);
|
||||
NSDeviceStatus.getInstance().setData(devicestatusJson);
|
||||
if (devicestatusJson.has("pump")) {
|
||||
// Objectives 0
|
||||
ObjectivesPlugin.pumpStatusIsAvailableInNS = true;
|
||||
ObjectivesPlugin.saveProgress();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
}
|
||||
// Handle profile
|
||||
if (intent.getAction().equals(Intents.ACTION_NEW_PROFILE)) {
|
||||
try {
|
||||
String activeProfile = bundles.getString("activeprofile");
|
||||
String profile = bundles.getString("profile");
|
||||
ProfileStore profileStore = new ProfileStore(new JSONObject(profile));
|
||||
NSProfilePlugin.getPlugin().storeNewProfile(profileStore);
|
||||
MainApp.bus().post(new EventNSProfileUpdateGUI());
|
||||
if (Config.logIncommingData)
|
||||
log.debug("Received profileStore: " + activeProfile + " " + profile);
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
if (intent.getAction().equals(Intents.ACTION_NEW_TREATMENT) || intent.getAction().equals(Intents.ACTION_CHANGED_TREATMENT)) {
|
||||
try {
|
||||
if (bundles.containsKey("treatment")) {
|
||||
JSONObject json = new JSONObject(bundles.getString("treatment"));
|
||||
handleTreatmentFromNS(json, intent);
|
||||
}
|
||||
if (bundles.containsKey("treatments")) {
|
||||
String trstring = bundles.getString("treatments");
|
||||
JSONArray jsonArray = new JSONArray(trstring);
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
JSONObject json = jsonArray.getJSONObject(i);
|
||||
handleTreatmentFromNS(json, intent);
|
||||
}
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
if (intent.getAction().equals(Intents.ACTION_REMOVED_TREATMENT)) {
|
||||
try {
|
||||
if (bundles.containsKey("treatment")) {
|
||||
String trstring = bundles.getString("treatment");
|
||||
JSONObject json = new JSONObject(trstring);
|
||||
handleTreatmentFromNS(json);
|
||||
}
|
||||
|
||||
if (bundles.containsKey("treatments")) {
|
||||
String trstring = bundles.getString("treatments");
|
||||
JSONArray jsonArray = new JSONArray(trstring);
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
JSONObject json = jsonArray.getJSONObject(i);
|
||||
handleTreatmentFromNS(json);
|
||||
}
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
if (intent.getAction().equals(Intents.ACTION_NEW_SGV)) {
|
||||
try {
|
||||
if (bundles.containsKey("sgv")) {
|
||||
String sgvstring = bundles.getString("sgv");
|
||||
JSONObject sgvJson = new JSONObject(sgvstring);
|
||||
NSSgv nsSgv = new NSSgv(sgvJson);
|
||||
BgReading bgReading = new BgReading(nsSgv);
|
||||
MainApp.getDbHelper().createIfNotExists(bgReading, "NS");
|
||||
}
|
||||
|
||||
if (bundles.containsKey("sgvs")) {
|
||||
String sgvstring = bundles.getString("sgvs");
|
||||
JSONArray jsonArray = new JSONArray(sgvstring);
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
JSONObject sgvJson = jsonArray.getJSONObject(i);
|
||||
NSSgv nsSgv = new NSSgv(sgvJson);
|
||||
BgReading bgReading = new BgReading(nsSgv);
|
||||
MainApp.getDbHelper().createIfNotExists(bgReading, "NS");
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
if (intent.getAction().equals(Intents.ACTION_NEW_MBG)) {
|
||||
try {
|
||||
if (bundles.containsKey("mbg")) {
|
||||
String mbgstring = bundles.getString("mbg");
|
||||
JSONObject mbgJson = new JSONObject(mbgstring);
|
||||
NSMbg nsMbg = new NSMbg(mbgJson);
|
||||
CareportalEvent careportalEvent = new CareportalEvent(nsMbg);
|
||||
MainApp.getDbHelper().createOrUpdate(careportalEvent);
|
||||
if (Config.logIncommingData)
|
||||
log.debug("Adding/Updating new MBG: " + careportalEvent.log());
|
||||
}
|
||||
|
||||
if (bundles.containsKey("mbgs")) {
|
||||
String sgvstring = bundles.getString("mbgs");
|
||||
JSONArray jsonArray = new JSONArray(sgvstring);
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
JSONObject mbgJson = jsonArray.getJSONObject(i);
|
||||
NSMbg nsMbg = new NSMbg(mbgJson);
|
||||
CareportalEvent careportalEvent = new CareportalEvent(nsMbg);
|
||||
MainApp.getDbHelper().createOrUpdate(careportalEvent);
|
||||
if (Config.logIncommingData)
|
||||
log.debug("Adding/Updating new MBG: " + careportalEvent.log());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
if (intent.getAction().equals(Intents.ACTION_NEW_FOOD)
|
||||
|| intent.getAction().equals(Intents.ACTION_CHANGED_FOOD)) {
|
||||
int mode = Intents.ACTION_NEW_FOOD.equals(intent.getAction()) ? EventNsFood.ADD : EventNsFood.UPDATE;
|
||||
EventNsFood evt = new EventNsFood(mode, bundles);
|
||||
MainApp.bus().post(evt);
|
||||
}
|
||||
|
||||
if (intent.getAction().equals(Intents.ACTION_REMOVED_FOOD)) {
|
||||
EventNsFood evt = new EventNsFood(EventNsFood.REMOVE, bundles);
|
||||
MainApp.bus().post(evt);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleTreatmentFromNS(JSONObject json) {
|
||||
// new DB model
|
||||
EventNsTreatment evtTreatment = new EventNsTreatment(EventNsTreatment.REMOVE, json);
|
||||
MainApp.bus().post(evtTreatment);
|
||||
// old DB model
|
||||
String _id = JsonHelper.safeGetString(json, "_id");
|
||||
MainApp.getDbHelper().deleteTempTargetById(_id);
|
||||
MainApp.getDbHelper().deleteTempBasalById(_id);
|
||||
MainApp.getDbHelper().deleteExtendedBolusById(_id);
|
||||
MainApp.getDbHelper().deleteCareportalEventById(_id);
|
||||
MainApp.getDbHelper().deleteProfileSwitchById(_id);
|
||||
}
|
||||
|
||||
private void handleTreatmentFromNS(JSONObject json, Intent intent) throws JSONException {
|
||||
// new DB model
|
||||
int mode = Intents.ACTION_NEW_TREATMENT.equals(intent.getAction()) ? EventNsTreatment.ADD : EventNsTreatment.UPDATE;
|
||||
double insulin = JsonHelper.safeGetDouble(json, "insulin");
|
||||
double carbs = JsonHelper.safeGetDouble(json, "carbs");
|
||||
String eventType = JsonHelper.safeGetString(json, "eventType");
|
||||
if (insulin > 0 || carbs > 0) {
|
||||
EventNsTreatment evtTreatment = new EventNsTreatment(mode, json);
|
||||
MainApp.bus().post(evtTreatment);
|
||||
} else if (json.has(DanaRNSHistorySync.DANARSIGNATURE)) {
|
||||
// old DB model
|
||||
MainApp.getDbHelper().updateDanaRHistoryRecordId(json);
|
||||
} else if (eventType.equals(CareportalEvent.TEMPORARYTARGET)) {
|
||||
MainApp.getDbHelper().createTemptargetFromJsonIfNotExists(json);
|
||||
} else if (eventType.equals(CareportalEvent.TEMPBASAL)) {
|
||||
MainApp.getDbHelper().createTempBasalFromJsonIfNotExists(json);
|
||||
} else if (eventType.equals(CareportalEvent.COMBOBOLUS)) {
|
||||
MainApp.getDbHelper().createExtendedBolusFromJsonIfNotExists(json);
|
||||
} else if (eventType.equals(CareportalEvent.PROFILESWITCH)) {
|
||||
MainApp.getDbHelper().createProfileSwitchFromJsonIfNotExists(json);
|
||||
} else if (eventType.equals(CareportalEvent.SITECHANGE) ||
|
||||
eventType.equals(CareportalEvent.INSULINCHANGE) ||
|
||||
eventType.equals(CareportalEvent.SENSORCHANGE) ||
|
||||
eventType.equals(CareportalEvent.BGCHECK) ||
|
||||
eventType.equals(CareportalEvent.NOTE) ||
|
||||
eventType.equals(CareportalEvent.NONE) ||
|
||||
eventType.equals(CareportalEvent.ANNOUNCEMENT) ||
|
||||
eventType.equals(CareportalEvent.QUESTION) ||
|
||||
eventType.equals(CareportalEvent.EXERCISE) ||
|
||||
eventType.equals(CareportalEvent.OPENAPSOFFLINE) ||
|
||||
eventType.equals(CareportalEvent.PUMPBATTERYCHANGE)) {
|
||||
MainApp.getDbHelper().createCareportalEventFromJsonIfNotExists(json);
|
||||
}
|
||||
|
||||
if (eventType.equals(CareportalEvent.ANNOUNCEMENT)) {
|
||||
long date = JsonHelper.safeGetLong(json,"mills");
|
||||
long now = System.currentTimeMillis();
|
||||
String enteredBy = JsonHelper.safeGetString(json, "enteredBy", "");
|
||||
String notes = JsonHelper.safeGetString(json, "notes", "");
|
||||
if (date > now - 15 * 60 * 1000L && !notes.isEmpty()
|
||||
&& !enteredBy.equals(SP.getString("careportal_enteredby", "AndroidAPS"))) {
|
||||
Notification announcement = new Notification(Notification.NSANNOUNCEMENT, notes, Notification.ANNOUNCEMENT, 60);
|
||||
MainApp.bus().post(new EventNewNotification(announcement));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleNewSMS(Intent intent) {
|
||||
Bundle bundle = intent.getExtras();
|
||||
if (bundle == null) return;
|
||||
MainApp.bus().post(new EventNewSMS(bundle));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package info.nightscout.androidaps;
|
||||
package info.nightscout.androidaps.activities;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
|
@ -9,6 +9,8 @@ import android.view.View;
|
|||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
|
||||
import info.nightscout.androidaps.MainActivity;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.utils.SP;
|
||||
|
||||
public class AgreementActivity extends Activity {
|
|
@ -0,0 +1,435 @@
|
|||
package info.nightscout.androidaps.activities;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.SystemClock;
|
||||
import android.support.v4.content.res.ResourcesCompat;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.PopupMenu;
|
||||
import android.text.SpannableString;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.jjoe64.graphview.GraphView;
|
||||
import com.squareup.otto.Subscribe;
|
||||
import com.wdullaer.materialdatetimepicker.date.DatePickerDialog;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import butterknife.OnLongClick;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.events.EventCustomCalculationFinished;
|
||||
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions;
|
||||
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
|
||||
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished;
|
||||
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventIobCalculationProgress;
|
||||
import info.nightscout.androidaps.plugins.Overview.OverviewFragment;
|
||||
import info.nightscout.androidaps.plugins.Overview.OverviewPlugin;
|
||||
import info.nightscout.androidaps.plugins.Overview.graphData.GraphData;
|
||||
import info.nightscout.utils.DateUtil;
|
||||
import info.nightscout.utils.T;
|
||||
|
||||
public class HistoryBrowseActivity extends AppCompatActivity {
|
||||
private static Logger log = LoggerFactory.getLogger(HistoryBrowseActivity.class);
|
||||
|
||||
|
||||
ImageButton chartButton;
|
||||
|
||||
boolean showBasal = true;
|
||||
boolean showIob, showCob, showDev, showRat, showDevslope;
|
||||
|
||||
|
||||
@BindView(R.id.historybrowse_date)
|
||||
Button buttonDate;
|
||||
@BindView(R.id.historybrowse_zoom)
|
||||
Button buttonZoom;
|
||||
@BindView(R.id.historyybrowse_bggraph)
|
||||
GraphView bgGraph;
|
||||
@BindView(R.id.historybrowse_iobgraph)
|
||||
GraphView iobGraph;
|
||||
@BindView(R.id.historybrowse_seekBar)
|
||||
SeekBar seekBar;
|
||||
@BindView(R.id.historybrowse_noprofile)
|
||||
TextView noProfile;
|
||||
@BindView(R.id.overview_iobcalculationprogess)
|
||||
TextView iobCalculationProgressView;
|
||||
|
||||
private int rangeToDisplay = 24; // for graph
|
||||
private long start = 0;
|
||||
|
||||
IobCobCalculatorPlugin iobCobCalculatorPlugin;
|
||||
|
||||
EventCustomCalculationFinished eventCustomCalculationFinished = new EventCustomCalculationFinished();
|
||||
|
||||
public HistoryBrowseActivity() {
|
||||
iobCobCalculatorPlugin = new IobCobCalculatorPlugin();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_historybrowse);
|
||||
|
||||
ButterKnife.bind(this);
|
||||
|
||||
bgGraph.getGridLabelRenderer().setGridColor(MainApp.gc(R.color.graphgrid));
|
||||
bgGraph.getGridLabelRenderer().reloadStyles();
|
||||
iobGraph.getGridLabelRenderer().setGridColor(MainApp.gc(R.color.graphgrid));
|
||||
iobGraph.getGridLabelRenderer().reloadStyles();
|
||||
iobGraph.getGridLabelRenderer().setHorizontalLabelsVisible(false);
|
||||
bgGraph.getGridLabelRenderer().setLabelVerticalWidth(50);
|
||||
iobGraph.getGridLabelRenderer().setLabelVerticalWidth(50);
|
||||
iobGraph.getGridLabelRenderer().setNumVerticalLabels(5);
|
||||
|
||||
setupChartMenu();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
MainApp.bus().unregister(this);
|
||||
iobCobCalculatorPlugin.stopCalculation("onPause");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
MainApp.bus().register(this);
|
||||
// set start of current day
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTimeInMillis(System.currentTimeMillis());
|
||||
calendar.set(Calendar.MILLISECOND, 0);
|
||||
calendar.set(Calendar.SECOND, 0);
|
||||
calendar.set(Calendar.MINUTE, 0);
|
||||
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
||||
start = calendar.getTimeInMillis();
|
||||
runCalculation("onResume");
|
||||
SystemClock.sleep(1000);
|
||||
updateGUI("onResume");
|
||||
}
|
||||
|
||||
@OnClick(R.id.historybrowse_left)
|
||||
void onClickLeft() {
|
||||
start -= T.hours(rangeToDisplay).msecs();
|
||||
updateGUI("onClickLeft");
|
||||
runCalculation("onClickLeft");
|
||||
}
|
||||
|
||||
@OnClick(R.id.historybrowse_right)
|
||||
void onClickRight() {
|
||||
start += T.hours(rangeToDisplay).msecs();
|
||||
updateGUI("onClickRight");
|
||||
runCalculation("onClickRight");
|
||||
}
|
||||
|
||||
@OnClick(R.id.historybrowse_end)
|
||||
void onClickEnd() {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTimeInMillis(System.currentTimeMillis());
|
||||
calendar.set(Calendar.MILLISECOND, 0);
|
||||
calendar.set(Calendar.SECOND, 0);
|
||||
calendar.set(Calendar.MINUTE, 0);
|
||||
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
||||
start = calendar.getTimeInMillis();
|
||||
updateGUI("onClickEnd");
|
||||
runCalculation("onClickEnd");
|
||||
}
|
||||
|
||||
@OnClick(R.id.historybrowse_zoom)
|
||||
void onClickZoom() {
|
||||
rangeToDisplay += 6;
|
||||
rangeToDisplay = rangeToDisplay > 24 ? 6 : rangeToDisplay;
|
||||
updateGUI("rangeChange");
|
||||
}
|
||||
|
||||
@OnLongClick(R.id.historybrowse_zoom)
|
||||
boolean onLongClickZoom() {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTimeInMillis(start);
|
||||
calendar.set(Calendar.MILLISECOND, 0);
|
||||
calendar.set(Calendar.SECOND, 0);
|
||||
calendar.set(Calendar.MINUTE, 0);
|
||||
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
||||
start = calendar.getTimeInMillis();
|
||||
updateGUI("resetToMidnight");
|
||||
runCalculation("onLongClickZoom");
|
||||
return true;
|
||||
}
|
||||
|
||||
@OnClick(R.id.historybrowse_date)
|
||||
void onClickDate() {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(new Date(start));
|
||||
DatePickerDialog dpd = DatePickerDialog.newInstance(
|
||||
(view, year, monthOfYear, dayOfMonth) -> {
|
||||
Date date = new Date(0);
|
||||
date.setYear(year - 1900);
|
||||
date.setMonth(monthOfYear);
|
||||
date.setDate(dayOfMonth);
|
||||
date.setHours(0);
|
||||
start = date.getTime();
|
||||
updateGUI("onClickDate");
|
||||
runCalculation("onClickDate");
|
||||
},
|
||||
calendar.get(Calendar.YEAR),
|
||||
calendar.get(Calendar.MONTH),
|
||||
calendar.get(Calendar.DAY_OF_MONTH)
|
||||
);
|
||||
dpd.setThemeDark(true);
|
||||
dpd.dismissOnPause(true);
|
||||
dpd.show(getFragmentManager(), "Datepickerdialog");
|
||||
}
|
||||
|
||||
private void runCalculation(String from) {
|
||||
long end = start + T.hours(rangeToDisplay).msecs();
|
||||
iobCobCalculatorPlugin.stopCalculation(from);
|
||||
iobCobCalculatorPlugin.clearCache();
|
||||
iobCobCalculatorPlugin.runCalculation(from, end, true, false, eventCustomCalculationFinished);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventAutosensCalculationFinished e) {
|
||||
if (e.cause == eventCustomCalculationFinished) {
|
||||
log.debug("EventAutosensCalculationFinished");
|
||||
runOnUiThread(() -> {
|
||||
synchronized (HistoryBrowseActivity.this) {
|
||||
updateGUI("EventAutosensCalculationFinished");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventIobCalculationProgress e) {
|
||||
runOnUiThread(() -> {
|
||||
if (iobCalculationProgressView != null)
|
||||
iobCalculationProgressView.setText(e.progress);
|
||||
});
|
||||
}
|
||||
|
||||
void updateGUI(String from) {
|
||||
log.debug("updateGUI from: " + from);
|
||||
|
||||
if (noProfile == null || buttonDate == null || buttonZoom == null || bgGraph == null || iobGraph == null || seekBar == null)
|
||||
return;
|
||||
|
||||
final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
|
||||
final Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||
|
||||
if (profile == null) {
|
||||
noProfile.setVisibility(View.VISIBLE);
|
||||
return;
|
||||
} else {
|
||||
noProfile.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
final String units = profile.getUnits();
|
||||
final double lowLine = OverviewPlugin.getPlugin().determineLowLine(units);
|
||||
final double highLine = OverviewPlugin.getPlugin().determineHighLine(units);
|
||||
|
||||
buttonDate.setText(DateUtil.dateAndTimeString(start));
|
||||
buttonZoom.setText(String.valueOf(rangeToDisplay));
|
||||
|
||||
final boolean showPrediction = false;
|
||||
|
||||
int hoursToFetch;
|
||||
final long toTime;
|
||||
final long fromTime;
|
||||
//if (showPrediction) {
|
||||
//int predHours = (int) (Math.ceil(((DetermineBasalResultAMA) finalLastRun.constraintsProcessed).getLatestPredictionsTime() - System.currentTimeMillis()) / (60 * 60 * 1000));
|
||||
//predHours = Math.min(2, predHours);
|
||||
//predHours = Math.max(0, predHours);
|
||||
//hoursToFetch = rangeToDisplay - predHours;
|
||||
//toTime = calendar.getTimeInMillis() + 100000; // little bit more to avoid wrong rounding - Graphview specific
|
||||
//fromTime = toTime - hoursToFetch * 60 * 60 * 1000L;
|
||||
//endTime = toTime + predHours * 60 * 60 * 1000L;
|
||||
//} else {
|
||||
fromTime = start + T.secs(100).msecs();
|
||||
toTime = start + T.hours(rangeToDisplay).msecs();
|
||||
//}
|
||||
|
||||
log.debug("Period: " + DateUtil.dateAndTimeString(fromTime) + " - " + DateUtil.dateAndTimeString(toTime));
|
||||
|
||||
final long pointer = System.currentTimeMillis();
|
||||
|
||||
// ------------------ 1st graph
|
||||
|
||||
final GraphData graphData = new GraphData(bgGraph, iobCobCalculatorPlugin);
|
||||
|
||||
// **** In range Area ****
|
||||
graphData.addInRangeArea(fromTime, toTime, lowLine, highLine);
|
||||
|
||||
// **** BG ****
|
||||
if (showPrediction)
|
||||
//graphData.addBgReadings(fromTime, toTime, lowLine, highLine, (DetermineBasalResultAMA) finalLastRun.constraintsProcessed);
|
||||
;
|
||||
else
|
||||
graphData.addBgReadings(fromTime, toTime, lowLine, highLine, null);
|
||||
|
||||
// set manual x bounds to have nice steps
|
||||
graphData.formatAxis(fromTime, toTime);
|
||||
|
||||
// Treatments
|
||||
graphData.addTreatments(fromTime, toTime);
|
||||
|
||||
// add basal data
|
||||
if (pump.getPumpDescription().isTempBasalCapable && showBasal) {
|
||||
graphData.addBasals(fromTime, toTime, lowLine / graphData.maxY / 1.2d);
|
||||
}
|
||||
|
||||
// **** NOW line ****
|
||||
graphData.addNowLine(pointer);
|
||||
|
||||
// ------------------ 2nd graph
|
||||
|
||||
new Thread(() -> {
|
||||
final GraphData secondGraphData = new GraphData(iobGraph, iobCobCalculatorPlugin);
|
||||
|
||||
boolean useIobForScale = false;
|
||||
boolean useCobForScale = false;
|
||||
boolean useDevForScale = false;
|
||||
boolean useRatioForScale = false;
|
||||
boolean useDSForScale = false;
|
||||
|
||||
if (showIob) {
|
||||
useIobForScale = true;
|
||||
} else if (showCob) {
|
||||
useCobForScale = true;
|
||||
} else if (showDev) {
|
||||
useDevForScale = true;
|
||||
} else if (showRat) {
|
||||
useRatioForScale = true;
|
||||
} else if (showDevslope) {
|
||||
useDSForScale = true;
|
||||
}
|
||||
|
||||
if (showIob)
|
||||
secondGraphData.addIob(fromTime, toTime, useIobForScale, 1d);
|
||||
if (showCob)
|
||||
secondGraphData.addCob(fromTime, toTime, useCobForScale, useCobForScale ? 1d : 0.5d);
|
||||
if (showDev)
|
||||
secondGraphData.addDeviations(fromTime, toTime, useDevForScale, 1d);
|
||||
if (showRat)
|
||||
secondGraphData.addRatio(fromTime, toTime, useRatioForScale, 1d);
|
||||
if (showDevslope)
|
||||
secondGraphData.addDeviationSlope(fromTime, toTime, useDSForScale, 1d);
|
||||
|
||||
// **** NOW line ****
|
||||
// set manual x bounds to have nice steps
|
||||
secondGraphData.formatAxis(fromTime, toTime);
|
||||
secondGraphData.addNowLine(pointer);
|
||||
|
||||
// do GUI update
|
||||
runOnUiThread(() -> {
|
||||
if (showIob || showCob || showDev || showRat || showDevslope) {
|
||||
iobGraph.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
iobGraph.setVisibility(View.GONE);
|
||||
}
|
||||
// finally enforce drawing of graphs
|
||||
graphData.performUpdate();
|
||||
if (showIob || showCob || showDev || showRat || showDevslope)
|
||||
secondGraphData.performUpdate();
|
||||
});
|
||||
}).start();
|
||||
}
|
||||
|
||||
private void setupChartMenu() {
|
||||
chartButton = (ImageButton) findViewById(R.id.overview_chartMenuButton);
|
||||
chartButton.setOnClickListener(v -> {
|
||||
MenuItem item;
|
||||
CharSequence title;
|
||||
SpannableString s;
|
||||
PopupMenu popup = new PopupMenu(v.getContext(), v);
|
||||
|
||||
|
||||
item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.BAS.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_basals));
|
||||
title = item.getTitle();
|
||||
s = new SpannableString(title);
|
||||
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.basal, null)), 0, s.length(), 0);
|
||||
item.setTitle(s);
|
||||
item.setCheckable(true);
|
||||
item.setChecked(showBasal);
|
||||
|
||||
item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.IOB.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_iob));
|
||||
title = item.getTitle();
|
||||
s = new SpannableString(title);
|
||||
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.iob, null)), 0, s.length(), 0);
|
||||
item.setTitle(s);
|
||||
item.setCheckable(true);
|
||||
item.setChecked(showIob);
|
||||
|
||||
item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.COB.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_cob));
|
||||
title = item.getTitle();
|
||||
s = new SpannableString(title);
|
||||
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.cob, null)), 0, s.length(), 0);
|
||||
item.setTitle(s);
|
||||
item.setCheckable(true);
|
||||
item.setChecked(showCob);
|
||||
|
||||
item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.DEV.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_deviations));
|
||||
title = item.getTitle();
|
||||
s = new SpannableString(title);
|
||||
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.deviations, null)), 0, s.length(), 0);
|
||||
item.setTitle(s);
|
||||
item.setCheckable(true);
|
||||
item.setChecked(showDev);
|
||||
|
||||
item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.SEN.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_sensitivity));
|
||||
title = item.getTitle();
|
||||
s = new SpannableString(title);
|
||||
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.ratio, null)), 0, s.length(), 0);
|
||||
item.setTitle(s);
|
||||
item.setCheckable(true);
|
||||
item.setChecked(showRat);
|
||||
|
||||
if (MainApp.devBranch) {
|
||||
item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.DEVSLOPE.ordinal(), Menu.NONE, "Deviation slope");
|
||||
title = item.getTitle();
|
||||
s = new SpannableString(title);
|
||||
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.devslopepos, null)), 0, s.length(), 0);
|
||||
item.setTitle(s);
|
||||
item.setCheckable(true);
|
||||
item.setChecked(showDevslope);
|
||||
}
|
||||
|
||||
popup.setOnMenuItemClickListener(item1 -> {
|
||||
if (item1.getItemId() == OverviewFragment.CHARTTYPE.BAS.ordinal()) {
|
||||
showBasal = !item1.isChecked();
|
||||
} else if (item1.getItemId() == OverviewFragment.CHARTTYPE.IOB.ordinal()) {
|
||||
showIob = !item1.isChecked();
|
||||
} else if (item1.getItemId() == OverviewFragment.CHARTTYPE.COB.ordinal()) {
|
||||
showCob = !item1.isChecked();
|
||||
} else if (item1.getItemId() == OverviewFragment.CHARTTYPE.DEV.ordinal()) {
|
||||
showDev = !item1.isChecked();
|
||||
} else if (item1.getItemId() == OverviewFragment.CHARTTYPE.SEN.ordinal()) {
|
||||
showRat = !item1.isChecked();
|
||||
} else if (item1.getItemId() == OverviewFragment.CHARTTYPE.DEVSLOPE.ordinal()) {
|
||||
showDevslope = !item1.isChecked();
|
||||
}
|
||||
updateGUI("onGraphCheckboxesCheckedChanged");
|
||||
return true;
|
||||
});
|
||||
chartButton.setImageResource(R.drawable.ic_arrow_drop_up_white_24dp);
|
||||
popup.setOnDismissListener(menu -> chartButton.setImageResource(R.drawable.ic_arrow_drop_down_white_24dp));
|
||||
popup.show();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package info.nightscout.androidaps;
|
||||
package info.nightscout.androidaps.activities;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
|
@ -11,6 +11,9 @@ import android.preference.PreferenceGroup;
|
|||
import android.preference.PreferenceManager;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import info.nightscout.androidaps.Config;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.events.EventPreferenceChange;
|
||||
import info.nightscout.androidaps.events.EventRefreshGui;
|
||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
|
@ -30,9 +33,10 @@ import info.nightscout.androidaps.plugins.PumpDanaRS.DanaRSPlugin;
|
|||
import info.nightscout.androidaps.plugins.PumpDanaRv2.DanaRv2Plugin;
|
||||
import info.nightscout.androidaps.plugins.PumpInsight.InsightPlugin;
|
||||
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
|
||||
import info.nightscout.androidaps.plugins.SensitivityAAPS.SensitivityAAPSPlugin;
|
||||
import info.nightscout.androidaps.plugins.SensitivityOref0.SensitivityOref0Plugin;
|
||||
import info.nightscout.androidaps.plugins.SensitivityWeightedAverage.SensitivityWeightedAveragePlugin;
|
||||
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityAAPSPlugin;
|
||||
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityOref0Plugin;
|
||||
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityOref1Plugin;
|
||||
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityWeightedAveragePlugin;
|
||||
import info.nightscout.androidaps.plugins.SmsCommunicator.SmsCommunicatorPlugin;
|
||||
import info.nightscout.androidaps.plugins.Source.SourceDexcomG5Plugin;
|
||||
import info.nightscout.androidaps.plugins.Wear.WearPlugin;
|
||||
|
@ -85,7 +89,7 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
|
|||
pref.setSummary("******");
|
||||
} else if (pref.getKey().equals(MainApp.gs(R.string.key_danars_name))) {
|
||||
pref.setSummary(SP.getString(R.string.key_danars_name, ""));
|
||||
} else if (editTextPref.getText() != null && !editTextPref.getText().equals("")) {
|
||||
} else if (editTextPref.getText() != null ) {
|
||||
((EditTextPreference) pref).setDialogMessage(editTextPref.getDialogMessage());
|
||||
pref.setSummary(editTextPref.getText());
|
||||
} else if (pref.getKey().contains("smscommunicator_allowednumbers") && TextUtils.isEmpty(editTextPref.getText().trim())) {
|
||||
|
@ -152,6 +156,7 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
|
|||
addPreferencesFromResourceIfEnabled(SensitivityAAPSPlugin.getPlugin(), PluginType.SENSITIVITY);
|
||||
addPreferencesFromResourceIfEnabled(SensitivityWeightedAveragePlugin.getPlugin(), PluginType.SENSITIVITY);
|
||||
addPreferencesFromResourceIfEnabled(SensitivityOref0Plugin.getPlugin(), PluginType.SENSITIVITY);
|
||||
addPreferencesFromResourceIfEnabled(SensitivityOref1Plugin.getPlugin(), PluginType.SENSITIVITY);
|
||||
|
||||
if (Config.HWPUMPS) {
|
||||
addPreferencesFromResourceIfEnabled(DanaRPlugin.getPlugin(), PluginType.PUMP);
|
|
@ -0,0 +1,60 @@
|
|||
package info.nightscout.androidaps.activities;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.activities.PreferencesActivity;
|
||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
import info.nightscout.utils.PasswordProtection;
|
||||
|
||||
public class SingleFragmentActivity extends AppCompatActivity {
|
||||
|
||||
private PluginBase plugin;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_single_fragment);
|
||||
|
||||
this.plugin = MainApp.getPluginsList().get(getIntent().getIntExtra("plugin", -1));
|
||||
setTitle(plugin.getName());
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
getSupportActionBar().setDisplayShowHomeEnabled(true);
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout,
|
||||
Fragment.instantiate(this, plugin.pluginDescription.getFragmentClass())).commit();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
else if (item.getItemId() == R.id.nav_plugin_preferences) {
|
||||
PasswordProtection.QueryPassword(this, R.string.settings_password, "settings_password", () -> {
|
||||
Intent i = new Intent(this, PreferencesActivity.class);
|
||||
i.putExtra("id", plugin.getPreferencesId());
|
||||
startActivity(i);
|
||||
}, null);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
if (plugin.getPreferencesId() != -1)
|
||||
getMenuInflater().inflate(R.menu.menu_single_fragment, menu);
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package info.nightscout.androidaps;
|
||||
package info.nightscout.androidaps.activities;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.graphics.Color;
|
||||
|
@ -33,14 +33,15 @@ import java.util.Date;
|
|||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.db.DanaRHistoryRecord;
|
||||
import info.nightscout.androidaps.db.TDD;
|
||||
import info.nightscout.androidaps.events.EventPumpStatusChanged;
|
||||
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPlugin;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.RecordTypes;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.events.EventDanaRSyncStatus;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaRKorean.DanaRKoreanPlugin;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaRS.DanaRSPlugin;
|
||||
|
@ -121,7 +122,7 @@ public class TDDStatsActivity extends Activity {
|
|||
|
||||
TBB = SP.getString("TBB", "10.00");
|
||||
|
||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||
if (profile != null) {
|
||||
double cppTBB = profile.baseBasalSum();
|
||||
TBB = decimalFormat.format(cppTBB);
|
|
@ -4,12 +4,10 @@ import java.util.ArrayList;
|
|||
|
||||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.interfaces.BgSourceInterface;
|
||||
import info.nightscout.androidaps.interfaces.Constraint;
|
||||
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
|
||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
import info.nightscout.androidaps.interfaces.PluginType;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
|
||||
/**
|
||||
* Created by mike on 19.03.2018.
|
||||
|
@ -25,7 +23,7 @@ public class ConstraintChecker implements ConstraintsInterface {
|
|||
|
||||
|
||||
public Constraint<Boolean> isLoopInvokationAllowed() {
|
||||
return isLoopInvokationAllowed(new Constraint<>(true));
|
||||
return isLoopInvocationAllowed(new Constraint<>(true));
|
||||
}
|
||||
|
||||
public Constraint<Boolean> isClosedLoopAllowed() {
|
||||
|
@ -69,13 +67,13 @@ public class ConstraintChecker implements ConstraintsInterface {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Constraint<Boolean> isLoopInvokationAllowed(Constraint<Boolean> value) {
|
||||
public Constraint<Boolean> isLoopInvocationAllowed(Constraint<Boolean> value) {
|
||||
|
||||
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||
for (PluginBase p : constraintsPlugins) {
|
||||
ConstraintsInterface constraint = (ConstraintsInterface) p;
|
||||
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
|
||||
constraint.isLoopInvokationAllowed(value);
|
||||
constraint.isLoopInvocationAllowed(value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import java.util.Date;
|
|||
|
||||
import info.nightscout.androidaps.db.CareportalEvent;
|
||||
import info.nightscout.androidaps.db.Source;
|
||||
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||
|
||||
/**
|
||||
* Created by mike on 29.05.2017.
|
||||
|
@ -17,6 +18,7 @@ import info.nightscout.androidaps.db.Source;
|
|||
|
||||
public class DetailedBolusInfo {
|
||||
public long date = System.currentTimeMillis();
|
||||
public long lastKnownBolusTime;
|
||||
public String eventType = CareportalEvent.MEALBOLUS;
|
||||
public double insulin = 0;
|
||||
public double carbs = 0;
|
||||
|
|
|
@ -52,6 +52,14 @@ public class Profile {
|
|||
protected Profile() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (json != null)
|
||||
return json.toString();
|
||||
else
|
||||
return "Profile has no JSON";
|
||||
}
|
||||
|
||||
// Constructor from profileStore JSON
|
||||
public Profile(JSONObject json, String units) {
|
||||
init(json, 100, 0);
|
||||
|
@ -202,6 +210,12 @@ public class Profile {
|
|||
if (targetHigh_v == null)
|
||||
targetHigh_v = convertToSparseArray(targetHigh);
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -226,6 +240,10 @@ public class Profile {
|
|||
basal_v.setValueAt(i, description.basalMinimumRate);
|
||||
if (notify)
|
||||
sendBelowMinimumNotification(from);
|
||||
} else if (basal_v.valueAt(i) > description.basalMaximumRate) {
|
||||
basal_v.setValueAt(i, description.basalMaximumRate);
|
||||
if (notify)
|
||||
sendAboveMaximumNotification(from);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -235,12 +253,16 @@ public class Profile {
|
|||
isValidated = false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return isValid;
|
||||
}
|
||||
|
||||
protected void sendBelowMinimumNotification(String from) {
|
||||
MainApp.bus().post(new EventNewNotification(new Notification(Notification.MINIMAL_BASAL_VALUE_REPLACED, String.format(MainApp.gs(R.string.minimalbasalvaluereplaced), from), Notification.NORMAL)));
|
||||
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) {
|
||||
|
@ -281,8 +303,6 @@ public class Profile {
|
|||
Integer getShitfTimeSecs(Integer originalTime) {
|
||||
Integer shiftedTime = originalTime + timeshift * 60 * 60;
|
||||
shiftedTime = (shiftedTime + 24 * 60 * 60) % (24 * 60 * 60);
|
||||
if (timeshift != 0 && Config.logProfile)
|
||||
log.debug("(Sec) Original time: " + originalTime + " ShiftedTime: " + shiftedTime);
|
||||
return shiftedTime;
|
||||
}
|
||||
|
||||
|
@ -444,12 +464,12 @@ public class Profile {
|
|||
return ret;
|
||||
}
|
||||
|
||||
public double getTarget(){
|
||||
return getTarget(secondsFromMidnight(System.currentTimeMillis()));
|
||||
public double getTarget() {
|
||||
return getTarget(secondsFromMidnight(System.currentTimeMillis()));
|
||||
}
|
||||
|
||||
protected double getTarget(int timeAsSeconds) {
|
||||
return (getTargetLowTimeFromMidnight(timeAsSeconds) + getTargetHighTimeFromMidnight(timeAsSeconds))/2;
|
||||
return (getTargetLowTimeFromMidnight(timeAsSeconds) + getTargetHighTimeFromMidnight(timeAsSeconds)) / 2;
|
||||
}
|
||||
|
||||
public double getTargetLow() {
|
||||
|
@ -544,6 +564,12 @@ public class Profile {
|
|||
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
|
||||
public static String toTargetRangeString(double low, double high, String sourceUnits, String units) {
|
||||
double lowMgdl = toMgdl(low, sourceUnits);
|
||||
|
|
|
@ -10,11 +10,12 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.utils.DecimalFormatter;
|
||||
import info.nightscout.utils.Round;
|
||||
|
||||
public class PumpEnactResult {
|
||||
private static Logger log = LoggerFactory.getLogger(PumpEnactResult.class);
|
||||
private static Logger log = LoggerFactory.getLogger(L.APS);
|
||||
|
||||
public boolean success = false; // request was processed successfully (but possible no change was needed)
|
||||
public boolean enacted = false; // request was processed successfully and change has been made
|
||||
|
|
|
@ -15,6 +15,8 @@ import info.nightscout.androidaps.Constants;
|
|||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions;
|
||||
import info.nightscout.androidaps.plugins.NSClientInternal.data.NSSgv;
|
||||
import info.nightscout.androidaps.plugins.Overview.OverviewPlugin;
|
||||
import info.nightscout.androidaps.plugins.Overview.graphExtensions.DataPointWithLabelInterface;
|
||||
|
@ -24,7 +26,7 @@ import info.nightscout.utils.SP;
|
|||
|
||||
@DatabaseTable(tableName = DatabaseHelper.DATABASE_BGREADINGS)
|
||||
public class BgReading implements DataPointWithLabelInterface {
|
||||
private static Logger log = LoggerFactory.getLogger(BgReading.class);
|
||||
private static Logger log = LoggerFactory.getLogger(L.DATABASE);
|
||||
|
||||
@DatabaseField(id = true)
|
||||
public long date;
|
||||
|
@ -142,7 +144,7 @@ public class BgReading implements DataPointWithLabelInterface {
|
|||
return false;
|
||||
if (raw != other.raw)
|
||||
return false;
|
||||
if (!direction.equals(other.direction))
|
||||
if (!Objects.equals(direction, other.direction))
|
||||
return false;
|
||||
if (!Objects.equals(_id, other._id))
|
||||
return false;
|
||||
|
@ -168,7 +170,7 @@ public class BgReading implements DataPointWithLabelInterface {
|
|||
|
||||
@Override
|
||||
public double getY() {
|
||||
String units = MainApp.getConfigBuilder().getProfileUnits();
|
||||
String units = ProfileFunctions.getInstance().getProfileUnits();
|
||||
return valueToUnits(units);
|
||||
}
|
||||
|
||||
|
@ -202,7 +204,7 @@ public class BgReading implements DataPointWithLabelInterface {
|
|||
|
||||
@Override
|
||||
public int getColor() {
|
||||
String units = MainApp.getConfigBuilder().getProfileUnits();
|
||||
String units = ProfileFunctions.getInstance().getProfileUnits();
|
||||
Double lowLine = SP.getDouble("low_mark", 0d);
|
||||
Double highLine = SP.getDouble("high_mark", 0d);
|
||||
if (lowLine < 1) {
|
||||
|
|
|
@ -24,16 +24,20 @@ import info.nightscout.androidaps.Constants;
|
|||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.interfaces.Interval;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions;
|
||||
import info.nightscout.androidaps.plugins.NSClientInternal.data.NSMbg;
|
||||
import info.nightscout.androidaps.plugins.Overview.OverviewFragment;
|
||||
import info.nightscout.androidaps.plugins.Overview.graphExtensions.DataPointWithLabelInterface;
|
||||
import info.nightscout.androidaps.plugins.Overview.graphExtensions.PointsWithLabelGraphSeries;
|
||||
import info.nightscout.utils.DateUtil;
|
||||
import info.nightscout.utils.T;
|
||||
import info.nightscout.utils.Translator;
|
||||
|
||||
@DatabaseTable(tableName = DatabaseHelper.DATABASE_CAREPORTALEVENTS)
|
||||
public class CareportalEvent implements DataPointWithLabelInterface {
|
||||
private static Logger log = LoggerFactory.getLogger(CareportalEvent.class);
|
||||
public class CareportalEvent implements DataPointWithLabelInterface, Interval {
|
||||
private static Logger log = LoggerFactory.getLogger(L.DATABASE);
|
||||
|
||||
@DatabaseField(id = true)
|
||||
public long date;
|
||||
|
@ -87,7 +91,7 @@ public class CareportalEvent implements DataPointWithLabelInterface {
|
|||
}
|
||||
|
||||
public long getHoursFromStart() {
|
||||
return (System.currentTimeMillis() - date) / (60 * 1000);
|
||||
return (System.currentTimeMillis() - date) / (60 * 60 * 1000);
|
||||
}
|
||||
|
||||
public String age() {
|
||||
|
@ -98,13 +102,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);
|
||||
}
|
||||
|
||||
public boolean isOlderThan(double 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 boolean isOlderThan(double hours) { return getHoursFromStart() > hours; }
|
||||
|
||||
public String log() {
|
||||
return "CareportalEvent{" +
|
||||
|
@ -133,6 +131,19 @@ public class CareportalEvent implements DataPointWithLabelInterface {
|
|||
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 -------
|
||||
|
||||
@Override
|
||||
|
@ -144,7 +155,7 @@ public class CareportalEvent implements DataPointWithLabelInterface {
|
|||
|
||||
@Override
|
||||
public double getY() {
|
||||
String units = MainApp.getConfigBuilder().getProfileUnits();
|
||||
String units = ProfileFunctions.getInstance().getProfileUnits();
|
||||
if (eventType.equals(MBG)) {
|
||||
double mbg = 0d;
|
||||
try {
|
||||
|
@ -213,14 +224,7 @@ public class CareportalEvent implements DataPointWithLabelInterface {
|
|||
|
||||
@Override
|
||||
public long getDuration() {
|
||||
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;
|
||||
return end() - start();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -259,8 +263,79 @@ public class CareportalEvent implements DataPointWithLabelInterface {
|
|||
if (eventType.equals(EXERCISE))
|
||||
return Color.BLUE;
|
||||
if (eventType.equals(OPENAPSOFFLINE))
|
||||
return Color.GRAY;
|
||||
return Color.GRAY & 0x80FFFFFF;
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,9 +27,8 @@ import java.util.concurrent.ScheduledExecutorService;
|
|||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import info.nightscout.androidaps.Config;
|
||||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.data.OverlappingIntervals;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.data.ProfileStore;
|
||||
import info.nightscout.androidaps.events.EventCareportalEventChange;
|
||||
|
@ -42,12 +41,14 @@ import info.nightscout.androidaps.events.EventReloadTempBasalData;
|
|||
import info.nightscout.androidaps.events.EventReloadTreatmentData;
|
||||
import info.nightscout.androidaps.events.EventTempBasalChange;
|
||||
import info.nightscout.androidaps.events.EventTempTargetChange;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions;
|
||||
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventNewHistoryData;
|
||||
import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.activities.DanaRNSHistorySync;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaR.comm.RecordTypes;
|
||||
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
|
||||
import info.nightscout.utils.JsonHelper;
|
||||
import info.nightscout.utils.NSUpload;
|
||||
import info.nightscout.utils.PercentageSplitter;
|
||||
import info.nightscout.utils.ToastUtils;
|
||||
|
||||
|
@ -60,7 +61,7 @@ import info.nightscout.utils.ToastUtils;
|
|||
* direct calls to the corresponding methods (eg. resetDatabases) should be done by a central service.
|
||||
*/
|
||||
public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||
private static Logger log = LoggerFactory.getLogger(DatabaseHelper.class);
|
||||
private static Logger log = LoggerFactory.getLogger(L.DATABASE);
|
||||
|
||||
public static final String DATABASE_NAME = "AndroidAPSDb";
|
||||
public static final String DATABASE_BGREADINGS = "BgReadings";
|
||||
|
@ -107,7 +108,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
@Override
|
||||
public void onCreate(SQLiteDatabase database, ConnectionSource connectionSource) {
|
||||
try {
|
||||
log.info("onCreate");
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.info("onCreate");
|
||||
TableUtils.createTableIfNotExists(connectionSource, TempTarget.class);
|
||||
TableUtils.createTableIfNotExists(connectionSource, BgReading.class);
|
||||
TableUtils.createTableIfNotExists(connectionSource, DanaRHistoryRecord.class);
|
||||
|
@ -325,15 +327,18 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
BgReading old = getDaoBgReadings().queryForId(bgReading.date);
|
||||
if (old == null) {
|
||||
getDaoBgReadings().create(bgReading);
|
||||
log.debug("BG: New record from: " + from + " " + bgReading.toString());
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("BG: New record from: " + from + " " + bgReading.toString());
|
||||
scheduleBgChange(bgReading);
|
||||
return true;
|
||||
}
|
||||
if (!old.isEqual(bgReading)) {
|
||||
log.debug("BG: Similiar found: " + old.toString());
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("BG: Similiar found: " + old.toString());
|
||||
old.copyFrom(bgReading);
|
||||
getDaoBgReadings().update(old);
|
||||
log.debug("BG: Updating record from: " + from + " New data: " + old.toString());
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("BG: Updating record from: " + from + " New data: " + old.toString());
|
||||
scheduleBgChange(bgReading);
|
||||
return false;
|
||||
}
|
||||
|
@ -355,7 +360,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
private static void scheduleBgChange(@Nullable final BgReading bgReading) {
|
||||
class PostRunnable implements Runnable {
|
||||
public void run() {
|
||||
log.debug("Firing EventNewBg");
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("Firing EventNewBg");
|
||||
MainApp.bus().post(new EventNewBG(bgReading));
|
||||
scheduledBgPost = null;
|
||||
}
|
||||
|
@ -387,7 +393,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
bgList = daoBgReadings.query(preparedQuery);
|
||||
|
||||
} catch (SQLException e) {
|
||||
log.debug(e.getMessage(), e);
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
if (bgList != null && bgList.size() > 0)
|
||||
return bgList.get(0);
|
||||
|
@ -430,6 +436,23 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
return new ArrayList<BgReading>();
|
||||
}
|
||||
|
||||
public List<BgReading> getBgreadingsDataFromTime(long start, long end, boolean ascending) {
|
||||
try {
|
||||
Dao<BgReading, Long> daoBgreadings = getDaoBgReadings();
|
||||
List<BgReading> bgReadings;
|
||||
QueryBuilder<BgReading, Long> queryBuilder = daoBgreadings.queryBuilder();
|
||||
queryBuilder.orderBy("date", ascending);
|
||||
Where where = queryBuilder.where();
|
||||
where.between("date", start, end).and().gt("value", 38).and().eq("isValid", true);
|
||||
PreparedQuery<BgReading> preparedQuery = queryBuilder.prepare();
|
||||
bgReadings = daoBgreadings.query(preparedQuery);
|
||||
return bgReadings;
|
||||
} catch (SQLException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return new ArrayList<BgReading>();
|
||||
}
|
||||
|
||||
public List<BgReading> getAllBgreadingsDataFromTime(long mills, boolean ascending) {
|
||||
try {
|
||||
Dao<BgReading, Long> daoBgreadings = getDaoBgReadings();
|
||||
|
@ -578,7 +601,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
getDaoTempTargets().delete(old); // need to delete/create because date may change too
|
||||
old.copyFrom(tempTarget);
|
||||
getDaoTempTargets().create(old);
|
||||
log.debug("TEMPTARGET: Updating record by date from: " + Source.getString(tempTarget.source) + " " + old.toString());
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("TEMPTARGET: Updating record by date from: " + Source.getString(tempTarget.source) + " " + old.toString());
|
||||
scheduleTemporaryTargetChange();
|
||||
return true;
|
||||
}
|
||||
|
@ -597,20 +621,23 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
getDaoTempTargets().delete(old); // need to delete/create because date may change too
|
||||
old.copyFrom(tempTarget);
|
||||
getDaoTempTargets().create(old);
|
||||
log.debug("TEMPTARGET: Updating record by _id from: " + Source.getString(tempTarget.source) + " " + old.toString());
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("TEMPTARGET: Updating record by _id from: " + Source.getString(tempTarget.source) + " " + old.toString());
|
||||
scheduleTemporaryTargetChange();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
getDaoTempTargets().create(tempTarget);
|
||||
log.debug("TEMPTARGET: New record from: " + Source.getString(tempTarget.source) + " " + tempTarget.toString());
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("TEMPTARGET: New record from: " + Source.getString(tempTarget.source) + " " + tempTarget.toString());
|
||||
scheduleTemporaryTargetChange();
|
||||
return true;
|
||||
}
|
||||
if (tempTarget.source == Source.USER) {
|
||||
getDaoTempTargets().create(tempTarget);
|
||||
log.debug("TEMPTARGET: New record from: " + Source.getString(tempTarget.source) + " " + tempTarget.toString());
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("TEMPTARGET: New record from: " + Source.getString(tempTarget.source) + " " + tempTarget.toString());
|
||||
scheduleTemporaryTargetChange();
|
||||
return true;
|
||||
}
|
||||
|
@ -632,7 +659,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
private static void scheduleTemporaryTargetChange() {
|
||||
class PostRunnable implements Runnable {
|
||||
public void run() {
|
||||
log.debug("Firing EventTempTargetChange");
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("Firing EventTempTargetChange");
|
||||
MainApp.bus().post(new EventTempTargetChange());
|
||||
scheduledTemTargetPost = null;
|
||||
}
|
||||
|
@ -664,7 +692,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
|
||||
public void createTemptargetFromJsonIfNotExists(JSONObject trJson) {
|
||||
try {
|
||||
String units = JsonHelper.safeGetString(trJson, "units", MainApp.getConfigBuilder().getProfileUnits());
|
||||
String units = JsonHelper.safeGetString(trJson, "units", ProfileFunctions.getInstance().getProfileUnits());
|
||||
TempTarget tempTarget = new TempTarget()
|
||||
.date(trJson.getLong("mills"))
|
||||
.duration(trJson.getInt("duration"))
|
||||
|
@ -675,7 +703,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
.source(Source.NIGHTSCOUT);
|
||||
createOrUpdate(tempTarget);
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
log.error("Unhandled exception: " + trJson.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -752,7 +780,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
} else if (list.size() == 1) {
|
||||
DanaRHistoryRecord record = list.get(0);
|
||||
if (record._id == null || !record._id.equals(trJson.getString("_id"))) {
|
||||
if (Config.logIncommingData)
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("Updating _id in DanaR history database: " + trJson.getString("_id"));
|
||||
record._id = trJson.getString("_id");
|
||||
getDaoDanaRHistory().update(record);
|
||||
|
@ -761,7 +789,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
}
|
||||
}
|
||||
} catch (SQLException | JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
log.error("Unhandled exception: " + trJson.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -782,11 +810,13 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
List<TemporaryBasal> trList = getDaoTemporaryBasal().query(preparedQuery);
|
||||
if (trList.size() > 0) {
|
||||
// do nothing, pump history record cannot be changed
|
||||
log.debug("TEMPBASAL: Already exists from: " + Source.getString(tempBasal.source) + " " + tempBasal.toString());
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("TEMPBASAL: Already exists from: " + Source.getString(tempBasal.source) + " " + tempBasal.toString());
|
||||
return false;
|
||||
}
|
||||
getDaoTemporaryBasal().create(tempBasal);
|
||||
log.debug("TEMPBASAL: New record from: " + Source.getString(tempBasal.source) + " " + tempBasal.toString());
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("TEMPBASAL: New record from: " + Source.getString(tempBasal.source) + " " + tempBasal.toString());
|
||||
updateEarliestDataChange(tempBasal.date);
|
||||
scheduleTemporaryBasalChange();
|
||||
return true;
|
||||
|
@ -803,7 +833,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
getDaoTemporaryBasal().delete(old); // need to delete/create because date may change too
|
||||
old.copyFrom(tempBasal);
|
||||
getDaoTemporaryBasal().create(old);
|
||||
log.debug("TEMPBASAL: Updating record by date from: " + Source.getString(tempBasal.source) + " " + old.toString());
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("TEMPBASAL: Updating record by date from: " + Source.getString(tempBasal.source) + " " + old.toString());
|
||||
updateEarliestDataChange(oldDate);
|
||||
updateEarliestDataChange(old.date);
|
||||
scheduleTemporaryBasalChange();
|
||||
|
@ -825,7 +856,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
getDaoTemporaryBasal().delete(old); // need to delete/create because date may change too
|
||||
old.copyFrom(tempBasal);
|
||||
getDaoTemporaryBasal().create(old);
|
||||
log.debug("TEMPBASAL: Updating record by _id from: " + Source.getString(tempBasal.source) + " " + old.toString());
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("TEMPBASAL: Updating record by _id from: " + Source.getString(tempBasal.source) + " " + old.toString());
|
||||
updateEarliestDataChange(oldDate);
|
||||
updateEarliestDataChange(old.date);
|
||||
scheduleTemporaryBasalChange();
|
||||
|
@ -834,14 +866,16 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
}
|
||||
}
|
||||
getDaoTemporaryBasal().create(tempBasal);
|
||||
log.debug("TEMPBASAL: New record from: " + Source.getString(tempBasal.source) + " " + tempBasal.toString());
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("TEMPBASAL: New record from: " + Source.getString(tempBasal.source) + " " + tempBasal.toString());
|
||||
updateEarliestDataChange(tempBasal.date);
|
||||
scheduleTemporaryBasalChange();
|
||||
return true;
|
||||
}
|
||||
if (tempBasal.source == Source.USER) {
|
||||
getDaoTemporaryBasal().create(tempBasal);
|
||||
log.debug("TEMPBASAL: New record from: " + Source.getString(tempBasal.source) + " " + tempBasal.toString());
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("TEMPBASAL: New record from: " + Source.getString(tempBasal.source) + " " + tempBasal.toString());
|
||||
updateEarliestDataChange(tempBasal.date);
|
||||
scheduleTemporaryBasalChange();
|
||||
return true;
|
||||
|
@ -881,7 +915,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
private static void scheduleTemporaryBasalChange() {
|
||||
class PostRunnable implements Runnable {
|
||||
public void run() {
|
||||
log.debug("Firing EventTempBasalChange");
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("Firing EventTempBasalChange");
|
||||
MainApp.bus().post(new EventReloadTempBasalData());
|
||||
MainApp.bus().post(new EventTempBasalChange());
|
||||
if (earliestDataChange != null)
|
||||
|
@ -966,14 +1001,15 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
createOrUpdate(tempBasal);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
log.error("Unhandled exception: " + trJson.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteTempBasalById(String _id) {
|
||||
TemporaryBasal stored = findTempBasalById(_id);
|
||||
if (stored != null) {
|
||||
log.debug("TEMPBASAL: Removing TempBasal record from database: " + stored.toString());
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("TEMPBASAL: Removing TempBasal record from database: " + stored.toString());
|
||||
delete(stored);
|
||||
updateEarliestDataChange(stored.date);
|
||||
scheduleTemporaryBasalChange();
|
||||
|
@ -1019,7 +1055,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
return false;
|
||||
}
|
||||
getDaoExtendedBolus().create(extendedBolus);
|
||||
log.debug("EXTENDEDBOLUS: New record from: " + Source.getString(extendedBolus.source) + " " + extendedBolus.toString());
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("EXTENDEDBOLUS: New record from: " + Source.getString(extendedBolus.source) + " " + extendedBolus.toString());
|
||||
updateEarliestDataChange(extendedBolus.date);
|
||||
scheduleExtendedBolusChange();
|
||||
return true;
|
||||
|
@ -1032,7 +1069,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
getDaoExtendedBolus().delete(old); // need to delete/create because date may change too
|
||||
old.copyFrom(extendedBolus);
|
||||
getDaoExtendedBolus().create(old);
|
||||
log.debug("EXTENDEDBOLUS: Updating record by date from: " + Source.getString(extendedBolus.source) + " " + old.toString());
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("EXTENDEDBOLUS: Updating record by date from: " + Source.getString(extendedBolus.source) + " " + old.toString());
|
||||
updateEarliestDataChange(oldDate);
|
||||
updateEarliestDataChange(old.date);
|
||||
scheduleExtendedBolusChange();
|
||||
|
@ -1054,7 +1092,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
getDaoExtendedBolus().delete(old); // need to delete/create because date may change too
|
||||
old.copyFrom(extendedBolus);
|
||||
getDaoExtendedBolus().create(old);
|
||||
log.debug("EXTENDEDBOLUS: Updating record by _id from: " + Source.getString(extendedBolus.source) + " " + old.toString());
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("EXTENDEDBOLUS: Updating record by _id from: " + Source.getString(extendedBolus.source) + " " + old.toString());
|
||||
updateEarliestDataChange(oldDate);
|
||||
updateEarliestDataChange(old.date);
|
||||
scheduleExtendedBolusChange();
|
||||
|
@ -1063,14 +1102,16 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
}
|
||||
}
|
||||
getDaoExtendedBolus().create(extendedBolus);
|
||||
log.debug("EXTENDEDBOLUS: New record from: " + Source.getString(extendedBolus.source) + " " + extendedBolus.toString());
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("EXTENDEDBOLUS: New record from: " + Source.getString(extendedBolus.source) + " " + extendedBolus.toString());
|
||||
updateEarliestDataChange(extendedBolus.date);
|
||||
scheduleExtendedBolusChange();
|
||||
return true;
|
||||
}
|
||||
if (extendedBolus.source == Source.USER) {
|
||||
getDaoExtendedBolus().create(extendedBolus);
|
||||
log.debug("EXTENDEDBOLUS: New record from: " + Source.getString(extendedBolus.source) + " " + extendedBolus.toString());
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("EXTENDEDBOLUS: New record from: " + Source.getString(extendedBolus.source) + " " + extendedBolus.toString());
|
||||
updateEarliestDataChange(extendedBolus.date);
|
||||
scheduleExtendedBolusChange();
|
||||
return true;
|
||||
|
@ -1110,7 +1151,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
public void deleteExtendedBolusById(String _id) {
|
||||
ExtendedBolus stored = findExtendedBolusById(_id);
|
||||
if (stored != null) {
|
||||
log.debug("EXTENDEDBOLUS: Removing ExtendedBolus record from database: " + stored.toString());
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("EXTENDEDBOLUS: Removing ExtendedBolus record from database: " + stored.toString());
|
||||
delete(stored);
|
||||
updateEarliestDataChange(stored.date);
|
||||
scheduleExtendedBolusChange();
|
||||
|
@ -1163,7 +1205,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
private static void scheduleExtendedBolusChange() {
|
||||
class PostRunnable implements Runnable {
|
||||
public void run() {
|
||||
log.debug("Firing EventExtendedBolusChange");
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("Firing EventExtendedBolusChange");
|
||||
MainApp.bus().post(new EventReloadTreatmentData(new EventExtendedBolusChange()));
|
||||
if (earliestDataChange != null)
|
||||
MainApp.bus().post(new EventNewHistoryData(earliestDataChange));
|
||||
|
@ -1242,6 +1285,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
where.ge("date", mills);
|
||||
PreparedQuery<CareportalEvent> preparedQuery = queryBuilder.prepare();
|
||||
careportalEvents = getDaoCareportalEvents().query(preparedQuery);
|
||||
preprocessOpenAPSOfflineEvents(careportalEvents);
|
||||
return careportalEvents;
|
||||
} catch (SQLException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
|
@ -1249,13 +1293,41 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
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 {
|
||||
List<CareportalEvent> careportalEvents;
|
||||
QueryBuilder<CareportalEvent, Long> queryBuilder = getDaoCareportalEvents().queryBuilder();
|
||||
queryBuilder.orderBy("date", ascending);
|
||||
PreparedQuery<CareportalEvent> preparedQuery = queryBuilder.prepare();
|
||||
careportalEvents = getDaoCareportalEvents().query(preparedQuery);
|
||||
preprocessOpenAPSOfflineEvents(careportalEvents);
|
||||
return careportalEvents;
|
||||
} catch (SQLException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
|
@ -1274,11 +1346,11 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
|
||||
if (list.size() == 1) {
|
||||
CareportalEvent record = list.get(0);
|
||||
if (Config.logIncommingData)
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("Removing CareportalEvent record from database: " + record.log());
|
||||
delete(record);
|
||||
} else {
|
||||
if (Config.logIncommingData)
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("CareportalEvent not found database: " + _id);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
|
@ -1298,12 +1370,12 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
if (list.size() == 0) {
|
||||
careportalEvent = new CareportalEvent();
|
||||
careportalEvent.source = Source.NIGHTSCOUT;
|
||||
if (Config.logIncommingData)
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("Adding CareportalEvent record to database: " + trJson.toString());
|
||||
// Record does not exists. add
|
||||
} else if (list.size() == 1) {
|
||||
careportalEvent = list.get(0);
|
||||
if (Config.logIncommingData)
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("Updating CareportalEvent record in database: " + trJson.toString());
|
||||
} else {
|
||||
log.error("Something went wrong");
|
||||
|
@ -1315,14 +1387,15 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
careportalEvent._id = trJson.getString("_id");
|
||||
createOrUpdate(careportalEvent);
|
||||
} catch (SQLException | JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
log.error("Unhandled exception: " + trJson.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void scheduleCareportalEventChange() {
|
||||
class PostRunnable implements Runnable {
|
||||
public void run() {
|
||||
log.debug("Firing scheduleCareportalEventChange");
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("Firing scheduleCareportalEventChange");
|
||||
MainApp.bus().post(new EventCareportalEventChange());
|
||||
scheduledCareportalEventPost = null;
|
||||
}
|
||||
|
@ -1368,7 +1441,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
profileSwitch.profileName = old.profileName; // preserver profileName to prevent multiple CPP extension
|
||||
getDaoProfileSwitch().delete(old); // need to delete/create because date may change too
|
||||
getDaoProfileSwitch().create(profileSwitch);
|
||||
log.debug("PROFILESWITCH: Updating record by date from: " + Source.getString(profileSwitch.source) + " " + old.toString());
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("PROFILESWITCH: Updating record by date from: " + Source.getString(profileSwitch.source) + " " + old.toString());
|
||||
scheduleProfileSwitchChange();
|
||||
return true;
|
||||
}
|
||||
|
@ -1387,7 +1461,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
getDaoProfileSwitch().delete(old); // need to delete/create because date may change too
|
||||
old.copyFrom(profileSwitch);
|
||||
getDaoProfileSwitch().create(old);
|
||||
log.debug("PROFILESWITCH: Updating record by _id from: " + Source.getString(profileSwitch.source) + " " + old.toString());
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("PROFILESWITCH: Updating record by _id from: " + Source.getString(profileSwitch.source) + " " + old.toString());
|
||||
scheduleProfileSwitchChange();
|
||||
return true;
|
||||
}
|
||||
|
@ -1396,13 +1471,15 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
// look for already added percentage from NS
|
||||
profileSwitch.profileName = PercentageSplitter.pureName(profileSwitch.profileName);
|
||||
getDaoProfileSwitch().create(profileSwitch);
|
||||
log.debug("PROFILESWITCH: New record from: " + Source.getString(profileSwitch.source) + " " + profileSwitch.toString());
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("PROFILESWITCH: New record from: " + Source.getString(profileSwitch.source) + " " + profileSwitch.toString());
|
||||
scheduleProfileSwitchChange();
|
||||
return true;
|
||||
}
|
||||
if (profileSwitch.source == Source.USER) {
|
||||
getDaoProfileSwitch().create(profileSwitch);
|
||||
log.debug("PROFILESWITCH: New record from: " + Source.getString(profileSwitch.source) + " " + profileSwitch.toString());
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("PROFILESWITCH: New record from: " + Source.getString(profileSwitch.source) + " " + profileSwitch.toString());
|
||||
scheduleProfileSwitchChange();
|
||||
return true;
|
||||
}
|
||||
|
@ -1424,7 +1501,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
private static void scheduleProfileSwitchChange() {
|
||||
class PostRunnable implements Runnable {
|
||||
public void run() {
|
||||
log.debug("Firing EventProfileSwitchChange");
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("Firing EventProfileSwitchChange");
|
||||
MainApp.bus().post(new EventReloadProfileSwitchData());
|
||||
MainApp.bus().post(new EventProfileSwitchChange());
|
||||
scheduledProfileSwitchEventPost = null;
|
||||
|
@ -1470,14 +1548,22 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
profileSwitch.profileJson = trJson.getString("profileJson");
|
||||
else {
|
||||
ProfileStore store = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile();
|
||||
Profile profile = store.getSpecificProfile(profileSwitch.profileName);
|
||||
if (profile != null) {
|
||||
profileSwitch.profileJson = profile.getData().toString();
|
||||
log.debug("Profile switch prefilled with JSON from local store");
|
||||
// Update data in NS
|
||||
NSUpload.updateProfileSwitch(profileSwitch);
|
||||
if (store != null) {
|
||||
Profile profile = store.getSpecificProfile(profileSwitch.profileName);
|
||||
if (profile != null) {
|
||||
profileSwitch.profileJson = profile.getData().toString();
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("Profile switch prefilled with JSON from local store");
|
||||
// Update data in NS
|
||||
NSUpload.updateProfileSwitch(profileSwitch);
|
||||
} else {
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("JSON for profile switch doesn't exist. Ignoring: " + trJson.toString());
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
log.debug("JSON for profile switch doesn't exist. Ignoring: " + trJson.toString());
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("Store for profile switch doesn't exist. Ignoring: " + trJson.toString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1485,14 +1571,15 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
profileSwitch.profilePlugin = trJson.getString("profilePlugin");
|
||||
createOrUpdate(profileSwitch);
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
log.error("Unhandled exception: " + trJson.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteProfileSwitchById(String _id) {
|
||||
ProfileSwitch stored = findProfileSwitchById(_id);
|
||||
if (stored != null) {
|
||||
log.debug("PROFILESWITCH: Removing ProfileSwitch record from database: " + stored.toString());
|
||||
if (L.isEnabled(L.DATABASE))
|
||||
log.debug("PROFILESWITCH: Removing ProfileSwitch record from database: " + stored.toString());
|
||||
delete(stored);
|
||||
scheduleTemporaryTargetChange();
|
||||
}
|
||||
|
|
|
@ -10,6 +10,8 @@ import org.json.JSONObject;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
|
||||
/**
|
||||
* Created by mike on 27.02.2016.
|
||||
* <p>
|
||||
|
@ -17,7 +19,7 @@ import org.slf4j.LoggerFactory;
|
|||
*/
|
||||
@DatabaseTable(tableName = DatabaseHelper.DATABASE_DBREQUESTS)
|
||||
public class DbRequest {
|
||||
private static Logger log = LoggerFactory.getLogger(DbRequest.class);
|
||||
private static Logger log = LoggerFactory.getLogger(L.DATABASE);
|
||||
|
||||
@DatabaseField(id = true)
|
||||
public String nsClientID = null;
|
||||
|
|
|
@ -21,6 +21,7 @@ import info.nightscout.androidaps.data.Iob;
|
|||
import info.nightscout.androidaps.data.IobTotal;
|
||||
import info.nightscout.androidaps.interfaces.InsulinInterface;
|
||||
import info.nightscout.androidaps.interfaces.Interval;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.Overview.graphExtensions.DataPointWithLabelInterface;
|
||||
import info.nightscout.androidaps.plugins.Overview.graphExtensions.PointsWithLabelGraphSeries;
|
||||
|
@ -36,7 +37,7 @@ import info.nightscout.utils.Round;
|
|||
|
||||
@DatabaseTable(tableName = DatabaseHelper.DATABASE_EXTENDEDBOLUSES)
|
||||
public class ExtendedBolus implements Interval, DataPointWithLabelInterface {
|
||||
private static Logger log = LoggerFactory.getLogger(ExtendedBolus.class);
|
||||
private static Logger log = LoggerFactory.getLogger(L.DATABASE);
|
||||
|
||||
@DatabaseField(id = true)
|
||||
public long date;
|
||||
|
|
|
@ -17,6 +17,7 @@ import info.nightscout.androidaps.MainApp;
|
|||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.interfaces.Interval;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
|
||||
import info.nightscout.androidaps.plugins.Overview.graphExtensions.DataPointWithLabelInterface;
|
||||
import info.nightscout.androidaps.plugins.Overview.graphExtensions.PointsWithLabelGraphSeries;
|
||||
|
@ -27,7 +28,7 @@ import info.nightscout.utils.DecimalFormatter;
|
|||
|
||||
@DatabaseTable(tableName = DatabaseHelper.DATABASE_PROFILESWITCHES)
|
||||
public class ProfileSwitch implements Interval, DataPointWithLabelInterface {
|
||||
private static Logger log = LoggerFactory.getLogger(ProfileSwitch.class);
|
||||
private static Logger log = LoggerFactory.getLogger(L.DATABASE);
|
||||
|
||||
@DatabaseField(id = true)
|
||||
public long date;
|
||||
|
|
|
@ -8,6 +8,8 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
import java.util.Objects;
|
||||
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
|
||||
/**
|
||||
* Created by mike on 20.09.2017.
|
||||
*/
|
||||
|
@ -15,7 +17,7 @@ import java.util.Objects;
|
|||
|
||||
@DatabaseTable(tableName = DatabaseHelper.DATABASE_TDDS)
|
||||
public class TDD {
|
||||
private static Logger log = LoggerFactory.getLogger(TDD.class);
|
||||
private static Logger log = LoggerFactory.getLogger(L.DATABASE);
|
||||
|
||||
@DatabaseField(id = true)
|
||||
public long date;
|
||||
|
|
|
@ -11,12 +11,13 @@ import java.util.Objects;
|
|||
|
||||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.interfaces.Interval;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.utils.DateUtil;
|
||||
import info.nightscout.utils.DecimalFormatter;
|
||||
|
||||
@DatabaseTable(tableName = DatabaseHelper.DATABASE_TEMPTARGETS)
|
||||
public class TempTarget implements Interval {
|
||||
private static Logger log = LoggerFactory.getLogger(TempTarget.class);
|
||||
private static Logger log = LoggerFactory.getLogger(L.DATABASE);
|
||||
|
||||
@DatabaseField(id = true)
|
||||
public long date;
|
||||
|
|
|
@ -15,7 +15,9 @@ import info.nightscout.androidaps.data.IobTotal;
|
|||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.interfaces.InsulinInterface;
|
||||
import info.nightscout.androidaps.interfaces.Interval;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions;
|
||||
import info.nightscout.androidaps.plugins.Treatments.Treatment;
|
||||
import info.nightscout.utils.DateUtil;
|
||||
import info.nightscout.utils.DecimalFormatter;
|
||||
|
@ -27,7 +29,7 @@ import info.nightscout.utils.SP;
|
|||
|
||||
@DatabaseTable(tableName = DatabaseHelper.DATABASE_TEMPORARYBASALS)
|
||||
public class TemporaryBasal implements Interval {
|
||||
private static Logger log = LoggerFactory.getLogger(TemporaryBasal.class);
|
||||
private static Logger log = LoggerFactory.getLogger(L.DATABASE);
|
||||
|
||||
@DatabaseField(id = true)
|
||||
public long date;
|
||||
|
@ -93,7 +95,7 @@ public class TemporaryBasal implements Interval {
|
|||
}
|
||||
|
||||
public TemporaryBasal(ExtendedBolus extendedBolus) {
|
||||
double basal = MainApp.getConfigBuilder().getProfile(extendedBolus.date).getBasal(extendedBolus.date);
|
||||
double basal = ProfileFunctions.getInstance().getProfile(extendedBolus.date).getBasal(extendedBolus.date);
|
||||
this.date = extendedBolus.date;
|
||||
this.isValid = extendedBolus.isValid;
|
||||
this.source = extendedBolus.source;
|
||||
|
@ -318,7 +320,7 @@ public class TemporaryBasal implements Interval {
|
|||
public String toStringFull() {
|
||||
if(isFakeExtended){
|
||||
|
||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||
Double currentBasalRate = profile.getBasal();
|
||||
double rate = (currentBasalRate == null)?0d:(currentBasalRate+netExtendedRate);
|
||||
return getCalcuatedPercentageIfNeeded() + DecimalFormatter.to2Decimal(rate) + "U/h ("+DecimalFormatter.to2Decimal(netExtendedRate)+"E) @" +
|
||||
|
@ -340,7 +342,7 @@ public class TemporaryBasal implements Interval {
|
|||
|
||||
double rate = 0d;
|
||||
if (isFakeExtended) {
|
||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||
Double currentBasalRate = profile.getBasal();
|
||||
rate = (currentBasalRate == null)?0d:(currentBasalRate+netExtendedRate);
|
||||
} else if (isAbsolute){
|
||||
|
@ -348,7 +350,7 @@ public class TemporaryBasal implements Interval {
|
|||
}
|
||||
|
||||
if(SP.getBoolean(R.string.key_danar_visualizeextendedaspercentage, false) && SP.getBoolean(R.string.key_danar_useextended, false)){
|
||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||
if(profile != null) {
|
||||
double basal = profile.getBasal();
|
||||
if(basal != 0){
|
||||
|
@ -367,7 +369,7 @@ public class TemporaryBasal implements Interval {
|
|||
|
||||
double rate = 0d;
|
||||
if (isFakeExtended) {
|
||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||
Double currentBasalRate = profile.getBasal();
|
||||
rate = (currentBasalRate == null)?0d:(currentBasalRate+netExtendedRate);
|
||||
} else if (isAbsolute){
|
||||
|
@ -375,7 +377,7 @@ public class TemporaryBasal implements Interval {
|
|||
}
|
||||
|
||||
if(SP.getBoolean(R.string.key_danar_visualizeextendedaspercentage, false) && SP.getBoolean(R.string.key_danar_useextended, false)){
|
||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||
if(profile != null) {
|
||||
double basal = profile.getBasal();
|
||||
if(basal != 0){
|
||||
|
@ -392,7 +394,7 @@ public class TemporaryBasal implements Interval {
|
|||
|
||||
double rate = 0d;
|
||||
if (isFakeExtended) {
|
||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||
Double currentBasalRate = profile.getBasal();
|
||||
rate = (currentBasalRate == null)?0d:(currentBasalRate+netExtendedRate);
|
||||
} else if (isAbsolute){
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
package info.nightscout.androidaps.events;
|
||||
|
||||
/** Base class for events to update the UI, mostly a specific tab. */
|
||||
public class EventAcceptOpenLoopChange extends Event {
|
||||
}
|
|
@ -1,5 +1,8 @@
|
|||
package info.nightscout.androidaps.events;
|
||||
|
||||
|
||||
import info.nightscout.utils.StringUtils;
|
||||
|
||||
public class EventNetworkChange extends Event {
|
||||
|
||||
public boolean mobileConnected = false;
|
||||
|
@ -9,6 +12,6 @@ public class EventNetworkChange extends Event {
|
|||
public boolean roaming = false;
|
||||
|
||||
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 {
|
||||
}
|
|
@ -1,8 +1,12 @@
|
|||
package info.nightscout.androidaps.interfaces;
|
||||
|
||||
import android.content.Intent;
|
||||
|
||||
/**
|
||||
* Created by mike on 20.06.2016.
|
||||
*/
|
||||
public interface BgSourceInterface {
|
||||
boolean advancedFilteringSupported();
|
||||
|
||||
void handleNewData(Intent intent);
|
||||
}
|
||||
|
|
|
@ -6,12 +6,14 @@ import org.slf4j.LoggerFactory;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
|
||||
/**
|
||||
* Created by mike on 19.03.2018.
|
||||
*/
|
||||
|
||||
public class Constraint<T extends Comparable> {
|
||||
private static Logger log = LoggerFactory.getLogger(Constraint.class);
|
||||
private static Logger log = LoggerFactory.getLogger(L.APS);
|
||||
|
||||
T value;
|
||||
T originalValue;
|
||||
|
@ -57,7 +59,7 @@ public class Constraint<T extends Comparable> {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Constraint<T> setIfGreater(T value, String reason, Object from) {
|
||||
public Constraint<T> setIfGreater(T value, String reason, Object from) {
|
||||
if (value.compareTo(this.value) > 0) {
|
||||
this.value = value;
|
||||
mostLimiting.clear();
|
||||
|
@ -74,7 +76,7 @@ public class Constraint<T extends Comparable> {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Constraint addMostLimingReason(String reason, Object from) {
|
||||
public Constraint addMostLimingReason(String reason, Object from) {
|
||||
mostLimiting.add(from.getClass().getSimpleName().replace("Plugin", "") + ": " + reason);
|
||||
return this;
|
||||
}
|
||||
|
@ -86,7 +88,8 @@ public class Constraint<T extends Comparable> {
|
|||
if (count++ != 0) sb.append("\n");
|
||||
sb.append(r);
|
||||
}
|
||||
log.debug("Limiting origial value: " + originalValue + " to " + value + ". Reason: " + sb.toString());
|
||||
if (L.isEnabled(L.APS))
|
||||
log.debug("Limiting origial value: " + originalValue + " to " + value + ". Reason: " + sb.toString());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
@ -110,7 +113,7 @@ public class Constraint<T extends Comparable> {
|
|||
}
|
||||
|
||||
public void copyReasons(Constraint<?> another) {
|
||||
for (String s: another.getReasonList()) {
|
||||
for (String s : another.getReasonList()) {
|
||||
reasons.add(s);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ import info.nightscout.androidaps.data.Profile;
|
|||
*/
|
||||
public interface ConstraintsInterface {
|
||||
|
||||
default Constraint<Boolean> isLoopInvokationAllowed(Constraint<Boolean> value) {
|
||||
default Constraint<Boolean> isLoopInvocationAllowed(Constraint<Boolean> value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,4 +9,5 @@ import info.nightscout.androidaps.data.PumpEnactResult;
|
|||
public interface DanaRInterface {
|
||||
PumpEnactResult loadHistory(byte type); // for history browser
|
||||
PumpEnactResult loadEvents(); // events history to build treatments from
|
||||
PumpEnactResult setUserOptions(); // like AnyDana does
|
||||
}
|
||||
|
|
|
@ -1,18 +1,21 @@
|
|||
package info.nightscout.androidaps.interfaces;
|
||||
|
||||
import android.os.SystemClock;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderFragment;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
|
||||
/**
|
||||
* Created by mike on 09.06.2016.
|
||||
*/
|
||||
public abstract class PluginBase {
|
||||
private static Logger log = LoggerFactory.getLogger(PluginBase.class);
|
||||
private static Logger log = LoggerFactory.getLogger(L.CORE);
|
||||
|
||||
public enum State {
|
||||
NOT_INITIALIZED,
|
||||
|
@ -32,6 +35,12 @@ public abstract class PluginBase {
|
|||
this.pluginDescription = pluginDescription;
|
||||
}
|
||||
|
||||
// Default always calls invoke
|
||||
// Plugins that have special constraints if they get switched to may override this method
|
||||
public void switchAllowed(ConfigBuilderFragment.PluginViewHolder.PluginSwitcher pluginSwitcher, FragmentActivity activity) {
|
||||
pluginSwitcher.invoke();
|
||||
}
|
||||
|
||||
// public PluginType getType() {
|
||||
// return mainType;
|
||||
// }
|
||||
|
@ -57,6 +66,11 @@ public abstract class PluginBase {
|
|||
return getName();
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
if (pluginDescription.description == -1) return null;
|
||||
else return MainApp.gs(pluginDescription.description);
|
||||
}
|
||||
|
||||
public PluginType getType() {
|
||||
return pluginDescription.mainType;
|
||||
}
|
||||
|
@ -100,7 +114,8 @@ public abstract class PluginBase {
|
|||
if (state != State.ENABLED) {
|
||||
onStateChange(type, state, State.ENABLED);
|
||||
state = State.ENABLED;
|
||||
log.debug("Starting: " + getName());
|
||||
if (L.isEnabled(L.CORE))
|
||||
log.debug("Starting: " + getName());
|
||||
onStart();
|
||||
}
|
||||
} else { // disabling plugin
|
||||
|
@ -108,7 +123,8 @@ public abstract class PluginBase {
|
|||
onStateChange(type, state, State.ENABLED);
|
||||
state = State.DISABLED;
|
||||
onStop();
|
||||
log.debug("Stopping: " + getName());
|
||||
if (L.isEnabled(L.CORE))
|
||||
log.debug("Stopping: " + getName());
|
||||
}
|
||||
}
|
||||
} else if (type == PluginType.PROFILE) {
|
||||
|
|
|
@ -9,6 +9,7 @@ public class PluginDescription {
|
|||
boolean showInList = true;
|
||||
int pluginName = -1;
|
||||
int shortName = -1;
|
||||
int description = -1;
|
||||
int preferencesId = -1;
|
||||
int advancedPreferencesId = -1;
|
||||
public boolean enableByDefault = false;
|
||||
|
@ -74,6 +75,11 @@ public class PluginDescription {
|
|||
return this;
|
||||
}
|
||||
|
||||
public PluginDescription description(int description) {
|
||||
this.description = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getFragmentClass() {
|
||||
return fragmentClass;
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ public class PumpDescription {
|
|||
public boolean isSetBasalProfileCapable = true;
|
||||
public double basalStep = 0.01d;
|
||||
public double basalMinimumRate = 0.04d;
|
||||
public double basalMaximumRate = 25d;
|
||||
|
||||
public boolean isRefillingCapable = false;
|
||||
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
package info.nightscout.androidaps.interfaces;
|
||||
|
||||
import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensResult;
|
||||
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
|
||||
|
||||
/**
|
||||
* Created by mike on 24.06.2017.
|
||||
*/
|
||||
|
||||
public interface SensitivityInterface {
|
||||
AutosensResult detectSensitivity(long fromTime, long toTime);
|
||||
|
||||
double MIN_HOURS = 1;
|
||||
double MIN_HOURS_FULL_AUTOSENS = 4;
|
||||
|
||||
AutosensResult detectSensitivity(IobCobCalculatorPlugin plugin, long fromTime, long toTime);
|
||||
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ public interface TreatmentsInterface {
|
|||
|
||||
boolean addToHistoryExtendedBolus(ExtendedBolus extendedBolus);
|
||||
|
||||
boolean addToHistoryTreatment(DetailedBolusInfo detailedBolusInfo);
|
||||
boolean addToHistoryTreatment(DetailedBolusInfo detailedBolusInfo, boolean allowUpdate);
|
||||
|
||||
TempTarget getTempTargetFromHistory();
|
||||
TempTarget getTempTargetFromHistory(long time);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package info.nightscout.utils;
|
||||
package info.nightscout.androidaps.logging;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
121
app/src/main/java/info/nightscout/androidaps/logging/L.java
Normal file
121
app/src/main/java/info/nightscout/androidaps/logging/L.java
Normal file
|
@ -0,0 +1,121 @@
|
|||
package info.nightscout.androidaps.logging;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import info.nightscout.utils.SP;
|
||||
|
||||
public class L {
|
||||
|
||||
public static class LogElement {
|
||||
String name;
|
||||
boolean defaultValue;
|
||||
boolean enabled;
|
||||
boolean requiresRestart = false;
|
||||
|
||||
LogElement(String name, boolean defaultValue) {
|
||||
this.name = name;
|
||||
this.defaultValue = defaultValue;
|
||||
enabled = SP.getBoolean(getSPName(), defaultValue);
|
||||
}
|
||||
|
||||
LogElement(String name, boolean defaultValue, boolean requiresRestart) {
|
||||
this.name = name;
|
||||
this.defaultValue = defaultValue;
|
||||
this.requiresRestart = requiresRestart;
|
||||
enabled = SP.getBoolean(getSPName(), defaultValue);
|
||||
}
|
||||
|
||||
LogElement(boolean defaultValue) {
|
||||
this.name = "NONEXISTING";
|
||||
this.defaultValue = defaultValue;
|
||||
enabled = defaultValue;
|
||||
}
|
||||
|
||||
private String getSPName() {
|
||||
return "log_" + name;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
SP.putBoolean(getSPName(), enabled);
|
||||
}
|
||||
|
||||
void resetToDefault() {
|
||||
setEnabled(defaultValue);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<LogElement> logElements;
|
||||
|
||||
static {
|
||||
initialize();
|
||||
}
|
||||
|
||||
private static LogElement findByName(String name) {
|
||||
for (LogElement element : logElements) {
|
||||
if (element.name.equals(name))
|
||||
return element;
|
||||
}
|
||||
return new LogElement(false);
|
||||
}
|
||||
|
||||
public static boolean isEnabled(String name) {
|
||||
return findByName(name).enabled;
|
||||
}
|
||||
|
||||
public static List<LogElement> getLogElements() {
|
||||
return logElements;
|
||||
}
|
||||
|
||||
public static void resetToDefaults() {
|
||||
for (LogElement element : logElements) {
|
||||
element.resetToDefault();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static final String CORE = "CORE";
|
||||
public static final String AUTOSENS = "AUTOSENS";
|
||||
public static final String EVENTS = "EVENTS";
|
||||
public static final String BGSOURCE = "BGSOURCE";
|
||||
public static final String OVERVIEW = "OVERVIEW";
|
||||
public static final String NOTIFICATION = "NOTIFICATION";
|
||||
public static final String DATASERVICE = "DATASERVICE";
|
||||
public static final String DATABASE = "DATABASE";
|
||||
public static final String DATAFOOD = "DATAFOOD";
|
||||
public static final String DATATREATMENTS = "DATATREATMENTS";
|
||||
public static final String NSCLIENT = "NSCLIENT";
|
||||
public static final String OBJECTIVES = "OBJECTIVES";
|
||||
public static final String PUMP = "PUMP";
|
||||
public static final String PUMPQUEUE = "PUMPQUEUE";
|
||||
public static final String PUMPCOMM = "PUMPCOMM";
|
||||
public static final String PUMPBTCOMM = "PUMPBTCOMM";
|
||||
public static final String APS = "APS";
|
||||
public static final String PROFILE = "PROFILE";
|
||||
public static final String CONFIGBUILDER = "CONFIGBUILDER";
|
||||
|
||||
private static void initialize() {
|
||||
logElements = new ArrayList<>();
|
||||
logElements.add(new LogElement(APS, true));
|
||||
logElements.add(new LogElement(AUTOSENS, false));
|
||||
logElements.add(new LogElement(BGSOURCE, true));
|
||||
logElements.add(new LogElement(CONFIGBUILDER, true));
|
||||
logElements.add(new LogElement(CORE, true));
|
||||
logElements.add(new LogElement(DATABASE, true));
|
||||
logElements.add(new LogElement(DATAFOOD, true));
|
||||
logElements.add(new LogElement(DATASERVICE, true));
|
||||
logElements.add(new LogElement(DATATREATMENTS, true));
|
||||
logElements.add(new LogElement(EVENTS, false, true));
|
||||
logElements.add(new LogElement(NOTIFICATION, true));
|
||||
logElements.add(new LogElement(NSCLIENT, true));
|
||||
logElements.add(new LogElement(OBJECTIVES, false));
|
||||
logElements.add(new LogElement(OVERVIEW, true));
|
||||
logElements.add(new LogElement(PROFILE, true));
|
||||
logElements.add(new LogElement(PUMP, true));
|
||||
logElements.add(new LogElement(PUMPBTCOMM, false));
|
||||
logElements.add(new LogElement(PUMPCOMM, true));
|
||||
logElements.add(new LogElement(PUMPQUEUE, true));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
package info.nightscout.androidaps.logging;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.view.View;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import butterknife.Unbinder;
|
||||
import info.nightscout.androidaps.R;
|
||||
|
||||
public class LogSettingActivity extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_logsetting);
|
||||
ButterKnife.bind(this);
|
||||
|
||||
createViewsForSettings(L.getLogElements());
|
||||
}
|
||||
|
||||
private void createViewsForSettings(List<L.LogElement> elements) {
|
||||
if (elements.size() == 0) return;
|
||||
LinearLayout container = (LinearLayout) findViewById(R.id.logsettings_placeholder);
|
||||
container.removeAllViews();
|
||||
for (L.LogElement element : elements) {
|
||||
PluginViewHolder pluginViewHolder = new PluginViewHolder(element);
|
||||
container.addView(pluginViewHolder.getBaseView());
|
||||
}
|
||||
}
|
||||
|
||||
@OnClick(R.id.logsettings_reset)
|
||||
public void onResetClick() {
|
||||
L.resetToDefaults();
|
||||
createViewsForSettings(L.getLogElements());
|
||||
}
|
||||
|
||||
public class PluginViewHolder {
|
||||
|
||||
private Unbinder unbinder;
|
||||
private L.LogElement element;
|
||||
|
||||
LinearLayout baseView;
|
||||
@BindView(R.id.logsettings_description)
|
||||
TextView description;
|
||||
@BindView(R.id.logsettings_visibility)
|
||||
CheckBox enabled;
|
||||
|
||||
public PluginViewHolder(L.LogElement element) {
|
||||
this.element = element;
|
||||
baseView = (LinearLayout) getLayoutInflater().inflate(R.layout.logsettings_item, null);
|
||||
unbinder = ButterKnife.bind(this, baseView);
|
||||
|
||||
description.setText(element.name);
|
||||
enabled.setChecked(element.enabled);
|
||||
}
|
||||
|
||||
public View getBaseView() {
|
||||
return baseView;
|
||||
}
|
||||
|
||||
@OnClick(R.id.logsettings_visibility)
|
||||
void onEnagledChanged() {
|
||||
element.setEnabled(enabled.isChecked());
|
||||
}
|
||||
|
||||
public void unbind() {
|
||||
unbinder.unbind();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -14,10 +14,10 @@ import com.crashlytics.android.answers.CustomEvent;
|
|||
import com.squareup.otto.Subscribe;
|
||||
|
||||
import info.nightscout.androidaps.Config;
|
||||
import info.nightscout.androidaps.HistoryBrowseActivity;
|
||||
import info.nightscout.androidaps.activities.HistoryBrowseActivity;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.TDDStatsActivity;
|
||||
import info.nightscout.androidaps.activities.TDDStatsActivity;
|
||||
import info.nightscout.androidaps.db.ExtendedBolus;
|
||||
import info.nightscout.androidaps.db.TemporaryBasal;
|
||||
import info.nightscout.androidaps.events.EventExtendedBolusChange;
|
||||
|
@ -33,6 +33,7 @@ import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialo
|
|||
import info.nightscout.androidaps.plugins.Careportal.OptionsToShow;
|
||||
import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions;
|
||||
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||
import info.nightscout.utils.FabricPrivacy;
|
||||
import info.nightscout.utils.SingleClickButton;
|
||||
|
@ -125,13 +126,13 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL
|
|||
activity.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (MainApp.getConfigBuilder().getActiveProfileInterface().getProfile() != null) {
|
||||
if (MainApp.getConfigBuilder().getActiveProfileInterface() != null && MainApp.getConfigBuilder().getActiveProfileInterface().getProfile() != null) {
|
||||
profileSwitch.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
profileSwitch.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (MainApp.getConfigBuilder().getProfile() == null) {
|
||||
if (ProfileFunctions.getInstance().getProfile() == null) {
|
||||
tempTarget.setVisibility(View.GONE);
|
||||
extendedBolus.setVisibility(View.GONE);
|
||||
extendedBolusCancel.setVisibility(View.GONE);
|
||||
|
|
|
@ -17,6 +17,7 @@ public class ActionsPlugin extends PluginBase {
|
|||
.fragmentClass(ActionsFragment.class.getName())
|
||||
.pluginName(R.string.actions)
|
||||
.shortName(R.string.actions_shortname)
|
||||
.description(R.string.description_actions)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity;
|
|||
import info.nightscout.androidaps.queue.Callback;
|
||||
import info.nightscout.utils.DecimalFormatter;
|
||||
import info.nightscout.utils.FabricPrivacy;
|
||||
import info.nightscout.utils.NSUpload;
|
||||
import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload;
|
||||
import info.nightscout.utils.NumberPicker;
|
||||
import info.nightscout.utils.SP;
|
||||
import info.nightscout.utils.SafeParse;
|
||||
|
@ -61,6 +61,10 @@ public class FillDialog extends DialogFragment implements OnClickListener {
|
|||
|
||||
private EditText notesEdit;
|
||||
|
||||
//one shot guards
|
||||
private boolean accepted;
|
||||
private boolean okClicked;
|
||||
|
||||
final private TextWatcher textWatcher = new TextWatcher() {
|
||||
@Override
|
||||
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 {
|
||||
Double insulin = SafeParse.stringToDouble(editInsulin.getText());
|
||||
|
||||
|
@ -179,10 +190,10 @@ public class FillDialog extends DialogFragment implements OnClickListener {
|
|||
}
|
||||
|
||||
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())
|
||||
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();
|
||||
if (!notes.isEmpty()) {
|
||||
|
@ -198,32 +209,40 @@ public class FillDialog extends DialogFragment implements OnClickListener {
|
|||
if (insulinAfterConstraints > 0 || pumpSiteChangeCheckbox.isChecked() || insulinCartridgeChangeCheckbox.isChecked()) {
|
||||
builder.setMessage(Html.fromHtml(Joiner.on("<br/>").join(confirmMessage)));
|
||||
builder.setPositiveButton(MainApp.gs(R.string.primefill), (dialog, id) -> {
|
||||
if (finalInsulinAfterConstraints > 0) {
|
||||
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
|
||||
detailedBolusInfo.insulin = finalInsulinAfterConstraints;
|
||||
detailedBolusInfo.context = context;
|
||||
detailedBolusInfo.source = Source.USER;
|
||||
detailedBolusInfo.isValid = false; // do not count it in IOB (for pump history)
|
||||
detailedBolusInfo.notes = notes;
|
||||
ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!result.success) {
|
||||
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
|
||||
i.putExtra("soundid", R.raw.boluserror);
|
||||
i.putExtra("status", result.comment);
|
||||
i.putExtra("title", MainApp.gs(R.string.treatmentdeliveryerror));
|
||||
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
MainApp.instance().startActivity(i);
|
||||
synchronized (builder) {
|
||||
if (accepted) {
|
||||
log.debug("guarding: already accepted");
|
||||
return;
|
||||
}
|
||||
accepted = true;
|
||||
|
||||
if (finalInsulinAfterConstraints > 0) {
|
||||
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
|
||||
detailedBolusInfo.insulin = finalInsulinAfterConstraints;
|
||||
detailedBolusInfo.context = context;
|
||||
detailedBolusInfo.source = Source.USER;
|
||||
detailedBolusInfo.isValid = false; // do not count it in IOB (for pump history)
|
||||
detailedBolusInfo.notes = notes;
|
||||
ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!result.success) {
|
||||
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
|
||||
i.putExtra("soundid", R.raw.boluserror);
|
||||
i.putExtra("status", result.comment);
|
||||
i.putExtra("title", MainApp.gs(R.string.treatmentdeliveryerror));
|
||||
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
MainApp.instance().startActivity(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
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 {
|
||||
builder.setMessage(MainApp.gs(R.string.no_action_selected));
|
||||
|
|
|
@ -25,6 +25,7 @@ import info.nightscout.androidaps.data.Profile;
|
|||
import info.nightscout.androidaps.interfaces.Constraint;
|
||||
import info.nightscout.androidaps.interfaces.PumpDescription;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions;
|
||||
import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity;
|
||||
import info.nightscout.androidaps.queue.Callback;
|
||||
import info.nightscout.utils.FabricPrivacy;
|
||||
|
@ -70,7 +71,7 @@ public class NewTempBasalDialog extends DialogFragment implements View.OnClickLi
|
|||
double tempPercentStep = pumpDescription.tempPercentStep;
|
||||
basalPercent.setParams(100d, 0d, maxTempPercent, tempPercentStep, new DecimalFormat("0"), true);
|
||||
|
||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||
Double currentBasal = profile != null ? profile.getBasal() : 0d;
|
||||
basalAbsolute = (NumberPicker) view.findViewById(R.id.overview_newtempbasal_basalabsoluteinput);
|
||||
basalAbsolute.setParams(currentBasal, 0d, pumpDescription.maxTempAbsolute, pumpDescription.tempAbsoluteStep, new DecimalFormat("0.00"), true);
|
||||
|
@ -118,7 +119,7 @@ public class NewTempBasalDialog extends DialogFragment implements View.OnClickLi
|
|||
final boolean setAsPercent = percentRadio.isChecked();
|
||||
int durationInMinutes = SafeParse.stringToInt(duration.getText());
|
||||
|
||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||
if (profile == null)
|
||||
return;
|
||||
|
||||
|
|
|
@ -218,50 +218,19 @@ public class CareportalFragment extends SubscriberFragment implements View.OnCli
|
|||
|
||||
double iageUrgent = nsSettings.getExtendedWarnValue("iage", "urgent", 96);
|
||||
double iageWarn = nsSettings.getExtendedWarnValue("iage", "warn", 72);
|
||||
handleAge(iage, CareportalEvent.INSULINCHANGE, iageWarn, iageUrgent);
|
||||
|
||||
double cageUrgent = nsSettings.getExtendedWarnValue("cage", "urgent", 72);
|
||||
double cageWarn = nsSettings.getExtendedWarnValue("cage", "warn", 48);
|
||||
handleAge(cage, CareportalEvent.SITECHANGE, cageWarn, cageUrgent);
|
||||
|
||||
double sageUrgent = nsSettings.getExtendedWarnValue("sage", "urgent", 166);
|
||||
double sageWarn = nsSettings.getExtendedWarnValue("sage", "warn", 164);
|
||||
handleAge(sage, CareportalEvent.SENSORCHANGE, sageWarn, sageUrgent);
|
||||
|
||||
double pbageUrgent = nsSettings.getExtendedWarnValue("pgage", "urgent", 360);
|
||||
double pbageWarn = nsSettings.getExtendedWarnValue("pgage", "warn", 240);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
handleAge(pbage, CareportalEvent.PUMPBATTERYCHANGE, pbageWarn, pbageUrgent);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -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())
|
||||
.pluginName(R.string.careportal)
|
||||
.shortName(R.string.careportal_shortname)
|
||||
.visibleByDefault(true)
|
||||
.enableByDefault(true)
|
||||
.description(R.string.description_careportal)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -49,13 +49,14 @@ import info.nightscout.androidaps.db.ProfileSwitch;
|
|||
import info.nightscout.androidaps.db.Source;
|
||||
import info.nightscout.androidaps.db.TempTarget;
|
||||
import info.nightscout.androidaps.plugins.Careportal.OptionsToShow;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions;
|
||||
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||
import info.nightscout.utils.DateUtil;
|
||||
import info.nightscout.utils.DefaultValueHelper;
|
||||
import info.nightscout.utils.FabricPrivacy;
|
||||
import info.nightscout.utils.HardLimits;
|
||||
import info.nightscout.utils.JsonHelper;
|
||||
import info.nightscout.utils.NSUpload;
|
||||
import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload;
|
||||
import info.nightscout.utils.NumberPicker;
|
||||
import info.nightscout.utils.SP;
|
||||
import info.nightscout.utils.SafeParse;
|
||||
|
@ -171,7 +172,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
|
|||
view.findViewById(R.id.cancel).setOnClickListener(this);
|
||||
|
||||
// profile
|
||||
profile = MainApp.getConfigBuilder().getProfile();
|
||||
profile = ProfileFunctions.getInstance().getProfile();
|
||||
profileStore = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile();
|
||||
if (profileStore == null) {
|
||||
if (options.eventType == R.id.careportal_profileswitch) {
|
||||
|
@ -186,7 +187,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
|
|||
profileSpinner.setAdapter(adapter);
|
||||
// set selected to actual profile
|
||||
for (int p = 0; p < profileList.size(); p++) {
|
||||
if (profileList.get(p).equals(MainApp.getConfigBuilder().getProfileName(false)))
|
||||
if (profileList.get(p).equals(ProfileFunctions.getInstance().getProfileName(false)))
|
||||
profileSpinner.setSelection(p);
|
||||
}
|
||||
}
|
||||
|
@ -206,12 +207,15 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
|
|||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
double defaultDuration;
|
||||
double defaultTarget = 0;
|
||||
if (profile != null) {
|
||||
if (profile != null && editTemptarget.getValue() == bg) {
|
||||
defaultTarget = bg;
|
||||
} else {
|
||||
//prevent changes on screen rotate
|
||||
defaultTarget = editTemptarget.getValue();
|
||||
}
|
||||
boolean erase = false;
|
||||
|
||||
String units = MainApp.getConfigBuilder().getProfileUnits();
|
||||
String units = ProfileFunctions.getInstance().getProfileUnits();
|
||||
DefaultValueHelper helper = new DefaultValueHelper();
|
||||
if (MainApp.gs(R.string.eatingsoon).equals(reasonList.get(position))) {
|
||||
defaultDuration = helper.determineEatingSoonTTDuration();
|
||||
|
@ -222,6 +226,8 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
|
|||
} else if (MainApp.gs(R.string.hypo).equals(reasonList.get(position))) {
|
||||
defaultDuration = helper.determineHypoTTDuration();
|
||||
defaultTarget = helper.determineHypoTT(units);
|
||||
} else if (editDuration.getValue() != 0) {
|
||||
defaultDuration = editDuration.getValue();
|
||||
} else {
|
||||
defaultDuration = 0;
|
||||
erase = true;
|
||||
|
@ -258,7 +264,6 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
|
|||
if (sensorRadioButton.isChecked()) meterRadioButton.setChecked(true);
|
||||
}
|
||||
};
|
||||
|
||||
editBg = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_bginput);
|
||||
editTemptarget = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_temptarget);
|
||||
if (profile == null) {
|
||||
|
@ -271,9 +276,14 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
|
|||
editBg.setParams(bg, 0d, 500d, 1d, new DecimalFormat("0"), false, bgTextWatcher);
|
||||
editTemptarget.setParams(bg, 0d, 500d, 1d, new DecimalFormat("0"), false);
|
||||
}
|
||||
|
||||
sensorRadioButton.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
Double bg1 = Profile.fromMgdlToUnits(GlucoseStatus.getGlucoseStatusData() != null ? GlucoseStatus.getGlucoseStatusData().glucose : 0d, profile.getUnits());
|
||||
editBg.setValue(bg1);
|
||||
if (savedInstanceState != null && savedInstanceState.getDouble("editBg") != bg1) {
|
||||
editBg.setValue(savedInstanceState.getDouble("editBg"));
|
||||
} else {
|
||||
editBg.setValue(bg1);
|
||||
}
|
||||
});
|
||||
|
||||
Integer maxCarbs = MainApp.getConstraintChecker().getMaxCarbsAllowed().value();
|
||||
|
@ -378,6 +388,25 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
|
|||
|
||||
setCancelable(true);
|
||||
getDialog().setCanceledOnTouchOutside(false);
|
||||
//recovering state if there is something
|
||||
// only numberPickers and editTexts
|
||||
if (savedInstanceState != null) {
|
||||
editBg.setValue(savedInstanceState.getDouble("editBg"));
|
||||
editTemptarget.setValue(savedInstanceState.getDouble("editTemptarget"));
|
||||
notesEdit.setText(savedInstanceState.getString("notesEdit"));
|
||||
editCarbs.setValue(savedInstanceState.getDouble("editCarbs"));
|
||||
editCarbs.setValue(savedInstanceState.getDouble("editCarbs"));
|
||||
editInsulin.setValue(savedInstanceState.getDouble("editInsulin"));
|
||||
editDuration.setValue(savedInstanceState.getDouble("editDuration"));
|
||||
editPercent.setValue(savedInstanceState.getDouble("editPercent"));
|
||||
editAbsolute.setValue(savedInstanceState.getDouble("editAbsolute"));
|
||||
editCarbTime.setValue(savedInstanceState.getDouble("editCarbTime"));
|
||||
editPercentage.setValue(savedInstanceState.getDouble("editPercentage"));
|
||||
editTimeshift.setValue(savedInstanceState.getDouble("editTimeshift"));
|
||||
// time and date
|
||||
dateButton.setText(savedInstanceState.getString("dateButton"));
|
||||
timeButton.setText(savedInstanceState.getString("timeButton"));
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
|
@ -758,8 +787,8 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
|
|||
profileSwitch = new ProfileSwitch();
|
||||
profileSwitch.date = System.currentTimeMillis();
|
||||
profileSwitch.source = Source.USER;
|
||||
profileSwitch.profileName = MainApp.getConfigBuilder().getProfileName(System.currentTimeMillis(), false);
|
||||
profileSwitch.profileJson = MainApp.getConfigBuilder().getProfile().getData().toString();
|
||||
profileSwitch.profileName = ProfileFunctions.getInstance().getProfileName(System.currentTimeMillis(), false);
|
||||
profileSwitch.profileJson = ProfileFunctions.getInstance().getProfile().getData().toString();
|
||||
profileSwitch.profilePlugin = MainApp.getConfigBuilder().getActiveProfileInterface().getClass().getName();
|
||||
profileSwitch.durationInMinutes = duration;
|
||||
profileSwitch.isCPP = percentage != 100 || timeshift != 0;
|
||||
|
@ -772,4 +801,22 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle savedInstanceState) {
|
||||
savedInstanceState.putString("notesEdit", notesEdit.getText().toString());
|
||||
savedInstanceState.putString("dateButton", dateButton.getText().toString());
|
||||
savedInstanceState.putString("timeButton", timeButton.getText().toString());
|
||||
savedInstanceState.putDouble("editBg", editBg.getValue());
|
||||
savedInstanceState.putDouble("editCarbs", editCarbs.getValue());
|
||||
savedInstanceState.putDouble("editInsulin", editInsulin.getValue());
|
||||
savedInstanceState.putDouble("editDuration", editDuration.getValue());
|
||||
savedInstanceState.putDouble("editPercent", editPercent.getValue());
|
||||
savedInstanceState.putDouble("editAbsolute", editAbsolute.getValue());
|
||||
savedInstanceState.putDouble("editCarbTime", editCarbTime.getValue());
|
||||
savedInstanceState.putDouble("editTemptarget", editTemptarget.getValue());
|
||||
savedInstanceState.putDouble("editPercentage", editPercentage.getValue());
|
||||
savedInstanceState.putDouble("editTimeshift", editTimeshift.getValue());
|
||||
super.onSaveInstanceState(savedInstanceState);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ abstract public class SubscriberFragment extends Fragment {
|
|||
updateGUI();
|
||||
}
|
||||
|
||||
@Override public void onDestroyView() {
|
||||
@Override public synchronized void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
if (unbinder != null)
|
||||
unbinder.unbind();
|
||||
|
|
|
@ -1,32 +1,32 @@
|
|||
package info.nightscout.androidaps.plugins.ConfigBuilder;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.StringRes;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ListAdapter;
|
||||
import android.widget.ListView;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.crashlytics.android.answers.CustomEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import info.nightscout.androidaps.Config;
|
||||
import butterknife.Unbinder;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.PreferencesActivity;
|
||||
import info.nightscout.androidaps.activities.PreferencesActivity;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.events.EventConfigBuilderChange;
|
||||
import info.nightscout.androidaps.events.EventRefreshGui;
|
||||
|
@ -43,76 +43,36 @@ import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
|
|||
import info.nightscout.androidaps.plugins.Insulin.InsulinOrefRapidActingPlugin;
|
||||
import info.nightscout.androidaps.plugins.ProfileNS.NSProfilePlugin;
|
||||
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
|
||||
import info.nightscout.androidaps.plugins.SensitivityOref0.SensitivityOref0Plugin;
|
||||
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityOref0Plugin;
|
||||
import info.nightscout.utils.FabricPrivacy;
|
||||
import info.nightscout.utils.PasswordProtection;
|
||||
|
||||
|
||||
public class ConfigBuilderFragment extends SubscriberFragment {
|
||||
|
||||
@BindView(R.id.configbuilder_insulinlistview)
|
||||
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;
|
||||
private List<PluginViewHolder> pluginViewHolders = new ArrayList<>();
|
||||
|
||||
@BindView(R.id.configbuilder_mainlayout)
|
||||
LinearLayout mainLayout;
|
||||
@BindView(R.id.configbuilder_unlock)
|
||||
@BindView(R.id.categories)
|
||||
LinearLayout categories;
|
||||
|
||||
@BindView(R.id.main_layout)
|
||||
ScrollView mainLayout;
|
||||
@BindView(R.id.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
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
try {
|
||||
View view = inflater.inflate(R.layout.configbuilder_fragment, container, false);
|
||||
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
|
||||
if (PasswordProtection.isLocked("settings_password"))
|
||||
mainLayout.setVisibility(View.GONE);
|
||||
else
|
||||
unlock.setVisibility(View.GONE);
|
||||
else unlock.setVisibility(View.GONE);
|
||||
|
||||
createViews();
|
||||
|
||||
return view;
|
||||
} catch (Exception e) {
|
||||
FabricPrivacy.logException(e);
|
||||
|
@ -121,225 +81,58 @@ public class ConfigBuilderFragment extends SubscriberFragment {
|
|||
return null;
|
||||
}
|
||||
|
||||
@OnClick(R.id.configbuilder_unlock)
|
||||
public void onClickUnlock() {
|
||||
@OnClick(R.id.unlock)
|
||||
void onClickUnlock() {
|
||||
PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", () -> {
|
||||
mainLayout.setVisibility(View.VISIBLE);
|
||||
unlock.setVisibility(View.GONE);
|
||||
}, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
for (PluginViewHolder pluginViewHolder : pluginViewHolders) pluginViewHolder.unbind();
|
||||
pluginViewHolders.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateGUI() {
|
||||
|
||||
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);
|
||||
for (PluginViewHolder pluginViewHolder : pluginViewHolders) pluginViewHolder.update();
|
||||
}
|
||||
|
||||
/*
|
||||
* ConfigBuilderFragment code
|
||||
*/
|
||||
|
||||
private class PluginCustomAdapter extends ArrayAdapter<PluginBase> {
|
||||
|
||||
private ArrayList<PluginBase> pluginList;
|
||||
final private PluginType type;
|
||||
|
||||
PluginCustomAdapter(Context context, int textViewResourceId,
|
||||
ArrayList<PluginBase> pluginList, PluginType type) {
|
||||
super(context, textViewResourceId, pluginList);
|
||||
this.pluginList = new ArrayList<>();
|
||||
this.pluginList.addAll(pluginList);
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
private class PluginViewHolder {
|
||||
TextView name;
|
||||
CheckBox checkboxEnabled;
|
||||
CheckBox checkboxVisible;
|
||||
ImageView settings;
|
||||
}
|
||||
|
||||
@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;
|
||||
|
||||
}
|
||||
|
||||
private void createViews() {
|
||||
createViewsForPlugins(R.string.configbuilder_profile, R.string.configbuilder_profile_description, PluginType.PROFILE, MainApp.getSpecificPluginsVisibleInListByInterface(ProfileInterface.class, PluginType.PROFILE));
|
||||
createViewsForPlugins(R.string.configbuilder_insulin, R.string.configbuilder_insulin_description, PluginType.INSULIN, MainApp.getSpecificPluginsVisibleInListByInterface(InsulinInterface.class, PluginType.INSULIN));
|
||||
createViewsForPlugins(R.string.configbuilder_bgsource, R.string.configbuilder_bgsource_description, PluginType.BGSOURCE, MainApp.getSpecificPluginsVisibleInListByInterface(BgSourceInterface.class, PluginType.BGSOURCE));
|
||||
createViewsForPlugins(R.string.configbuilder_pump, R.string.configbuilder_pump_description, PluginType.PUMP, MainApp.getSpecificPluginsVisibleInList(PluginType.PUMP));
|
||||
createViewsForPlugins(R.string.configbuilder_sensitivity, R.string.configbuilder_sensitivity_description, PluginType.SENSITIVITY, MainApp.getSpecificPluginsVisibleInListByInterface(SensitivityInterface.class, PluginType.SENSITIVITY));
|
||||
createViewsForPlugins(R.string.configbuilder_aps, R.string.configbuilder_aps_description, PluginType.APS, MainApp.getSpecificPluginsVisibleInList(PluginType.APS));
|
||||
createViewsForPlugins(R.string.configbuilder_loop, R.string.configbuilder_loop_description, PluginType.LOOP, MainApp.getSpecificPluginsVisibleInList(PluginType.LOOP));
|
||||
createViewsForPlugins(R.string.constraints, R.string.configbuilder_constraints_description, PluginType.CONSTRAINTS, MainApp.getSpecificPluginsVisibleInListByInterface(ConstraintsInterface.class, PluginType.CONSTRAINTS));
|
||||
createViewsForPlugins(R.string.configbuilder_treatments, R.string.configbuilder_treatments_description, PluginType.TREATMENT, MainApp.getSpecificPluginsVisibleInList(PluginType.TREATMENT));
|
||||
createViewsForPlugins(R.string.configbuilder_general, R.string.configbuilder_general_description, PluginType.GENERAL, MainApp.getSpecificPluginsVisibleInList(PluginType.GENERAL));
|
||||
}
|
||||
|
||||
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;
|
||||
switch (type) {
|
||||
// Multiple selection allowed
|
||||
|
@ -391,34 +184,103 @@ public class ConfigBuilderFragment extends SubscriberFragment {
|
|||
else
|
||||
pluginsInCategory.get(0).setPluginEnabled(type, true);
|
||||
}
|
||||
updateGUI();
|
||||
}
|
||||
}
|
||||
|
||||
/****
|
||||
* 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;
|
||||
public class PluginViewHolder {
|
||||
|
||||
int desiredWidth = View.MeasureSpec.makeMeasureSpec(listView.getWidth(), View.MeasureSpec.UNSPECIFIED);
|
||||
int totalHeight = 0;
|
||||
View view = null;
|
||||
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));
|
||||
private Unbinder unbinder;
|
||||
private PluginType pluginType;
|
||||
private PluginBase plugin;
|
||||
|
||||
view.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
|
||||
totalHeight += view.getMeasuredHeight();
|
||||
LinearLayout baseView;
|
||||
@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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,35 +1,17 @@
|
|||
package info.nightscout.androidaps.plugins.ConfigBuilder;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.crashlytics.android.answers.CustomEvent;
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
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.DetailedBolusInfo;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.data.ProfileStore;
|
||||
import info.nightscout.androidaps.data.PumpEnactResult;
|
||||
import info.nightscout.androidaps.db.CareportalEvent;
|
||||
import info.nightscout.androidaps.db.ProfileSwitch;
|
||||
import info.nightscout.androidaps.db.Source;
|
||||
import info.nightscout.androidaps.db.TemporaryBasal;
|
||||
import info.nightscout.androidaps.events.EventAppInitialized;
|
||||
import info.nightscout.androidaps.events.EventNewBasalProfile;
|
||||
import info.nightscout.androidaps.events.EventProfileSwitchChange;
|
||||
import info.nightscout.androidaps.interfaces.APSInterface;
|
||||
import info.nightscout.androidaps.interfaces.BgSourceInterface;
|
||||
import info.nightscout.androidaps.interfaces.Constraint;
|
||||
import info.nightscout.androidaps.interfaces.InsulinInterface;
|
||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
import info.nightscout.androidaps.interfaces.PluginDescription;
|
||||
|
@ -38,24 +20,18 @@ import info.nightscout.androidaps.interfaces.ProfileInterface;
|
|||
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||
import info.nightscout.androidaps.interfaces.SensitivityInterface;
|
||||
import info.nightscout.androidaps.interfaces.TreatmentsInterface;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.Insulin.InsulinOrefRapidActingPlugin;
|
||||
import info.nightscout.androidaps.plugins.Loop.APSResult;
|
||||
import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
|
||||
import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity;
|
||||
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
|
||||
import info.nightscout.androidaps.plugins.SensitivityOref0.SensitivityOref0Plugin;
|
||||
import info.nightscout.androidaps.queue.Callback;
|
||||
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityOref0Plugin;
|
||||
import info.nightscout.androidaps.queue.CommandQueue;
|
||||
import info.nightscout.utils.FabricPrivacy;
|
||||
import info.nightscout.utils.NSUpload;
|
||||
import info.nightscout.utils.SP;
|
||||
import info.nightscout.utils.ToastUtils;
|
||||
|
||||
/**
|
||||
* Created by mike on 05.08.2016.
|
||||
*/
|
||||
public class ConfigBuilderPlugin extends PluginBase {
|
||||
private static Logger log = LoggerFactory.getLogger(ConfigBuilderPlugin.class);
|
||||
private Logger log = LoggerFactory.getLogger(L.CONFIGBUILDER);
|
||||
|
||||
private static ConfigBuilderPlugin configBuilderPlugin;
|
||||
|
||||
|
@ -70,15 +46,9 @@ public class ConfigBuilderPlugin extends PluginBase {
|
|||
private static ProfileInterface activeProfile;
|
||||
private static TreatmentsInterface activeTreatments;
|
||||
private static APSInterface activeAPS;
|
||||
private static LoopPlugin activeLoop;
|
||||
private static InsulinInterface activeInsulin;
|
||||
private static SensitivityInterface activeSensitivity;
|
||||
|
||||
static public String nightscoutVersionName = "";
|
||||
static public Integer nightscoutVersionCode = 0;
|
||||
static public String nsClientVersionName = "";
|
||||
static public Integer nsClientVersionCode = 0;
|
||||
|
||||
private static ArrayList<PluginBase> pluginList;
|
||||
|
||||
private static CommandQueue commandQueue = new CommandQueue();
|
||||
|
@ -87,11 +57,12 @@ public class ConfigBuilderPlugin extends PluginBase {
|
|||
super(new PluginDescription()
|
||||
.mainType(PluginType.GENERAL)
|
||||
.fragmentClass(ConfigBuilderFragment.class.getName())
|
||||
.showInList(false)
|
||||
.showInList(true)
|
||||
.alwaysEnabled(true)
|
||||
.alwayVisible(true)
|
||||
.alwayVisible(false)
|
||||
.pluginName(R.string.configbuilder)
|
||||
.shortName(R.string.configbuilder_shortname)
|
||||
.description(R.string.description_config_builder)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -112,12 +83,21 @@ public class ConfigBuilderPlugin extends PluginBase {
|
|||
pluginList = MainApp.getPluginsList();
|
||||
upgradeSettings();
|
||||
loadSettings();
|
||||
setAlwaysEnabledPluginsEnabled();
|
||||
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) {
|
||||
if (pluginList != null) {
|
||||
if (Config.logPrefsChange)
|
||||
if (L.isEnabled(L.CONFIGBUILDER))
|
||||
log.debug("Storing settings from: " + from);
|
||||
|
||||
for (PluginBase p : pluginList) {
|
||||
|
@ -140,16 +120,18 @@ public class ConfigBuilderPlugin extends PluginBase {
|
|||
private void savePref(PluginBase p, PluginType type, boolean storeVisible) {
|
||||
String settingEnabled = "ConfigBuilder_" + type.name() + "_" + p.getClass().getSimpleName() + "_Enabled";
|
||||
SP.putBoolean(settingEnabled, p.isEnabled(type));
|
||||
log.debug("Storing: " + settingEnabled + ":" + p.isEnabled(type));
|
||||
if (L.isEnabled(L.CONFIGBUILDER))
|
||||
log.debug("Storing: " + settingEnabled + ":" + p.isEnabled(type));
|
||||
if (storeVisible) {
|
||||
String settingVisible = "ConfigBuilder_" + type.name() + "_" + p.getClass().getSimpleName() + "_Visible";
|
||||
SP.putBoolean(settingVisible, p.isFragmentVisible());
|
||||
log.debug("Storing: " + settingVisible + ":" + p.isFragmentVisible());
|
||||
if (L.isEnabled(L.CONFIGBUILDER))
|
||||
log.debug("Storing: " + settingVisible + ":" + p.isFragmentVisible());
|
||||
}
|
||||
}
|
||||
|
||||
private void loadSettings() {
|
||||
if (Config.logPrefsChange)
|
||||
if (L.isEnabled(L.CONFIGBUILDER))
|
||||
log.debug("Loading stored settings");
|
||||
for (PluginBase p : pluginList) {
|
||||
PluginType type = p.getType();
|
||||
|
@ -170,7 +152,8 @@ public class ConfigBuilderPlugin extends PluginBase {
|
|||
else if (p.getType() == type && (p.pluginDescription.enableByDefault || p.pluginDescription.alwaysEnabled)) {
|
||||
p.setPluginEnabled(type, true);
|
||||
}
|
||||
log.debug("Loaded: " + settingEnabled + ":" + p.isEnabled(type));
|
||||
if (L.isEnabled(L.CONFIGBUILDER))
|
||||
log.debug("Loaded: " + settingEnabled + ":" + p.isEnabled(type));
|
||||
if (loadVisible) {
|
||||
String settingVisible = "ConfigBuilder_" + type.name() + "_" + p.getClass().getSimpleName() + "_Visible";
|
||||
if (SP.contains(settingVisible))
|
||||
|
@ -178,7 +161,8 @@ public class ConfigBuilderPlugin extends PluginBase {
|
|||
else if (p.getType() == type && p.pluginDescription.visibleByDefault) {
|
||||
p.setFragmentVisible(type, true);
|
||||
}
|
||||
log.debug("Loaded: " + settingVisible + ":" + p.isFragmentVisible());
|
||||
if (L.isEnabled(L.CONFIGBUILDER))
|
||||
log.debug("Loaded: " + settingVisible + ":" + p.isFragmentVisible());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -186,10 +170,11 @@ public class ConfigBuilderPlugin extends PluginBase {
|
|||
private void upgradeSettings() {
|
||||
if (!SP.contains("ConfigBuilder_1_NSProfilePlugin_Enabled"))
|
||||
return;
|
||||
if (Config.logPrefsChange)
|
||||
if (L.isEnabled(L.CONFIGBUILDER))
|
||||
log.debug("Upgrading stored settings");
|
||||
for (PluginBase p : pluginList) {
|
||||
log.debug("Processing " + p.getName());
|
||||
if (L.isEnabled(L.CONFIGBUILDER))
|
||||
log.debug("Processing " + p.getName());
|
||||
for (int type = 1; type < 11; type++) {
|
||||
PluginType newType;
|
||||
switch (type) {
|
||||
|
@ -273,20 +258,21 @@ public class ConfigBuilderPlugin extends PluginBase {
|
|||
}
|
||||
|
||||
void logPluginStatus() {
|
||||
for (PluginBase p : pluginList) {
|
||||
log.debug(p.getName() + ":" +
|
||||
(p.isEnabled(PluginType.GENERAL) ? " GENERAL" : "") +
|
||||
(p.isEnabled(PluginType.TREATMENT) ? " TREATMENT" : "") +
|
||||
(p.isEnabled(PluginType.SENSITIVITY) ? " SENSITIVITY" : "") +
|
||||
(p.isEnabled(PluginType.PROFILE) ? " PROFILE" : "") +
|
||||
(p.isEnabled(PluginType.APS) ? " APS" : "") +
|
||||
(p.isEnabled(PluginType.PUMP) ? " PUMP" : "") +
|
||||
(p.isEnabled(PluginType.CONSTRAINTS) ? " CONSTRAINTS" : "") +
|
||||
(p.isEnabled(PluginType.LOOP) ? " LOOP" : "") +
|
||||
(p.isEnabled(PluginType.BGSOURCE) ? " BGSOURCE" : "") +
|
||||
(p.isEnabled(PluginType.INSULIN) ? " INSULIN" : "")
|
||||
);
|
||||
}
|
||||
if (L.isEnabled(L.CONFIGBUILDER))
|
||||
for (PluginBase p : pluginList) {
|
||||
log.debug(p.getName() + ":" +
|
||||
(p.isEnabled(PluginType.GENERAL) ? " GENERAL" : "") +
|
||||
(p.isEnabled(PluginType.TREATMENT) ? " TREATMENT" : "") +
|
||||
(p.isEnabled(PluginType.SENSITIVITY) ? " SENSITIVITY" : "") +
|
||||
(p.isEnabled(PluginType.PROFILE) ? " PROFILE" : "") +
|
||||
(p.isEnabled(PluginType.APS) ? " APS" : "") +
|
||||
(p.isEnabled(PluginType.PUMP) ? " PUMP" : "") +
|
||||
(p.isEnabled(PluginType.CONSTRAINTS) ? " CONSTRAINTS" : "") +
|
||||
(p.isEnabled(PluginType.LOOP) ? " LOOP" : "") +
|
||||
(p.isEnabled(PluginType.BGSOURCE) ? " BGSOURCE" : "") +
|
||||
(p.isEnabled(PluginType.INSULIN) ? " INSULIN" : "")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private void verifySelectionInCategories() {
|
||||
|
@ -328,9 +314,6 @@ public class ConfigBuilderPlugin extends PluginBase {
|
|||
}
|
||||
this.setFragmentVisiblities(((PluginBase) activePump).getName(), pluginsInCategory, PluginType.PUMP);
|
||||
|
||||
// PluginType.LOOP
|
||||
activeLoop = this.determineActivePlugin(PluginType.LOOP);
|
||||
|
||||
// PluginType.TREATMENT
|
||||
activeTreatments = this.determineActivePlugin(PluginType.TREATMENT);
|
||||
}
|
||||
|
@ -386,7 +369,7 @@ public class ConfigBuilderPlugin extends PluginBase {
|
|||
|
||||
private void setFragmentVisiblities(String activePluginName, ArrayList<PluginBase> pluginsInCategory,
|
||||
PluginType pluginType) {
|
||||
if (Config.logConfigBuilder)
|
||||
if (L.isEnabled(L.CONFIGBUILDER))
|
||||
log.debug("Selected interface: " + activePluginName);
|
||||
for (PluginBase p : pluginsInCategory) {
|
||||
if (!p.getName().equals(activePluginName)) {
|
||||
|
@ -412,246 +395,4 @@ public class ConfigBuilderPlugin extends PluginBase {
|
|||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* expect absolute request and allow both absolute and percent response based on pump capabilities
|
||||
*/
|
||||
public void applyTBRRequest(APSResult request, Profile profile, Callback callback) {
|
||||
if (!request.tempBasalRequested) {
|
||||
if (callback != null) {
|
||||
callback.result(new PumpEnactResult().enacted(false).success(true).comment(MainApp.gs(R.string.nochangerequested))).run();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
PumpInterface pump = getActivePump();
|
||||
|
||||
request.rateConstraint = new Constraint<>(request.rate);
|
||||
request.rate = MainApp.getConstraintChecker().applyBasalConstraints(request.rateConstraint, profile).value();
|
||||
|
||||
if (!pump.isInitialized()) {
|
||||
log.debug("applyAPSRequest: " + MainApp.gs(R.string.pumpNotInitialized));
|
||||
if (callback != null) {
|
||||
callback.result(new PumpEnactResult().comment(MainApp.gs(R.string.pumpNotInitialized)).enacted(false).success(false)).run();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (pump.isSuspended()) {
|
||||
log.debug("applyAPSRequest: " + MainApp.gs(R.string.pumpsuspended));
|
||||
if (callback != null) {
|
||||
callback.result(new PumpEnactResult().comment(MainApp.gs(R.string.pumpsuspended)).enacted(false).success(false)).run();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (Config.logCongigBuilderActions)
|
||||
log.debug("applyAPSRequest: " + request.toString());
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
TemporaryBasal activeTemp = activeTreatments.getTempBasalFromHistory(now);
|
||||
if ((request.rate == 0 && request.duration == 0) || Math.abs(request.rate - pump.getBaseBasalRate()) < pump.getPumpDescription().basalStep) {
|
||||
if (activeTemp != null) {
|
||||
if (Config.logCongigBuilderActions)
|
||||
log.debug("applyAPSRequest: cancelTempBasal()");
|
||||
getCommandQueue().cancelTempBasal(false, callback);
|
||||
} else {
|
||||
if (Config.logCongigBuilderActions)
|
||||
log.debug("applyAPSRequest: Basal set correctly");
|
||||
if (callback != null) {
|
||||
callback.result(new PumpEnactResult().absolute(request.rate).duration(0)
|
||||
.enacted(false).success(true).comment(MainApp.gs(R.string.basal_set_correctly))).run();
|
||||
}
|
||||
}
|
||||
} else if (activeTemp != null
|
||||
&& activeTemp.getPlannedRemainingMinutes() > 5
|
||||
&& request.duration - activeTemp.getPlannedRemainingMinutes() < 30
|
||||
&& Math.abs(request.rate - activeTemp.tempBasalConvertedToAbsolute(now, profile)) < pump.getPumpDescription().basalStep) {
|
||||
if (Config.logCongigBuilderActions)
|
||||
log.debug("applyAPSRequest: Temp basal set correctly");
|
||||
if (callback != null) {
|
||||
callback.result(new PumpEnactResult().absolute(activeTemp.tempBasalConvertedToAbsolute(now, profile))
|
||||
.enacted(false).success(true).duration(activeTemp.getPlannedRemainingMinutes())
|
||||
.comment(MainApp.gs(R.string.let_temp_basal_run))).run();
|
||||
}
|
||||
} else {
|
||||
if (Config.logCongigBuilderActions)
|
||||
log.debug("applyAPSRequest: setTempBasalAbsolute()");
|
||||
getCommandQueue().tempBasalAbsolute(request.rate, request.duration, false, profile, callback);
|
||||
}
|
||||
}
|
||||
|
||||
public void applySMBRequest(APSResult request, Callback callback) {
|
||||
if (!request.bolusRequested) {
|
||||
return;
|
||||
}
|
||||
|
||||
long lastBolusTime = activeTreatments.getLastBolusTime();
|
||||
if (lastBolusTime != 0 && lastBolusTime + 3 * 60 * 1000 > System.currentTimeMillis()) {
|
||||
log.debug("SMB requested but still in 3 min interval");
|
||||
if (callback != null) {
|
||||
callback.result(new PumpEnactResult()
|
||||
.comment(MainApp.gs(R.string.smb_frequency_exceeded))
|
||||
.enacted(false).success(false)).run();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
PumpInterface pump = getActivePump();
|
||||
|
||||
if (!pump.isInitialized()) {
|
||||
log.debug("applySMBRequest: " + MainApp.gs(R.string.pumpNotInitialized));
|
||||
if (callback != null) {
|
||||
callback.result(new PumpEnactResult().comment(MainApp.gs(R.string.pumpNotInitialized)).enacted(false).success(false)).run();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (pump.isSuspended()) {
|
||||
log.debug("applySMBRequest: " + MainApp.gs(R.string.pumpsuspended));
|
||||
if (callback != null) {
|
||||
callback.result(new PumpEnactResult().comment(MainApp.gs(R.string.pumpsuspended)).enacted(false).success(false)).run();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (Config.logCongigBuilderActions)
|
||||
log.debug("applySMBRequest: " + request.toString());
|
||||
|
||||
// deliver SMB
|
||||
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
|
||||
detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS;
|
||||
detailedBolusInfo.insulin = request.smb;
|
||||
detailedBolusInfo.isSMB = true;
|
||||
detailedBolusInfo.source = Source.USER;
|
||||
detailedBolusInfo.deliverAt = request.deliverAt;
|
||||
if (Config.logCongigBuilderActions)
|
||||
log.debug("applyAPSRequest: bolus()");
|
||||
getCommandQueue().bolus(detailedBolusInfo, callback);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onProfileSwitch(EventProfileSwitchChange ignored) {
|
||||
getCommandQueue().setProfile(getProfile(), new Callback() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!result.success) {
|
||||
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
|
||||
i.putExtra("soundid", R.raw.boluserror);
|
||||
i.putExtra("status", result.comment);
|
||||
i.putExtra("title", MainApp.gs(R.string.failedupdatebasalprofile));
|
||||
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
MainApp.instance().startActivity(i);
|
||||
}
|
||||
MainApp.bus().post(new EventNewBasalProfile());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public String getProfileName() {
|
||||
return getProfileName(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
public String getProfileName(boolean customized) {
|
||||
return getProfileName(System.currentTimeMillis(), customized);
|
||||
}
|
||||
|
||||
public String getProfileName(long time) {
|
||||
return getProfileName(time, true);
|
||||
}
|
||||
|
||||
public String getProfileName(long time, boolean customized) {
|
||||
ProfileSwitch profileSwitch = activeTreatments.getProfileSwitchFromHistory(time);
|
||||
if (profileSwitch != null) {
|
||||
if (profileSwitch.profileJson != null) {
|
||||
return customized ? profileSwitch.getCustomizedName() : profileSwitch.profileName;
|
||||
} else {
|
||||
ProfileStore profileStore = activeProfile.getProfile();
|
||||
if (profileStore != null) {
|
||||
Profile profile = profileStore.getSpecificProfile(profileSwitch.profileName);
|
||||
if (profile != null)
|
||||
return profileSwitch.profileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
return MainApp.gs(R.string.noprofileselected);
|
||||
}
|
||||
|
||||
public boolean isProfileValid(String from) {
|
||||
return getProfile() != null && getProfile().isValid(from);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Profile getProfile() {
|
||||
return getProfile(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
public String getProfileUnits() {
|
||||
Profile profile = getProfile();
|
||||
return profile != null ? profile.getUnits() : Constants.MGDL;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Profile getProfile(long time) {
|
||||
if (activeTreatments == null) {
|
||||
log.debug("getProfile activeTreatments == null: returning null");
|
||||
return null; //app not initialized
|
||||
}
|
||||
//log.debug("Profile for: " + new Date(time).toLocaleString() + " : " + getProfileName(time));
|
||||
ProfileSwitch profileSwitch = activeTreatments.getProfileSwitchFromHistory(time);
|
||||
if (profileSwitch != null) {
|
||||
if (profileSwitch.profileJson != null) {
|
||||
return profileSwitch.getProfileObject();
|
||||
} else if (activeProfile.getProfile() != null) {
|
||||
Profile profile = activeProfile.getProfile().getSpecificProfile(profileSwitch.profileName);
|
||||
if (profile != null)
|
||||
return profile;
|
||||
}
|
||||
}
|
||||
if (activeTreatments.getProfileSwitchesFromHistory().size() > 0) {
|
||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("CatchedError")
|
||||
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
|
||||
.putCustomAttribute("version", BuildConfig.VERSION)
|
||||
.putCustomAttribute("time", time)
|
||||
.putCustomAttribute("getProfileSwitchesFromHistory", activeTreatments.getProfileSwitchesFromHistory().toString())
|
||||
);
|
||||
}
|
||||
log.debug("getProfile at the end: returning null");
|
||||
return null;
|
||||
}
|
||||
|
||||
public void disconnectPump(int durationInMinutes, Profile profile) {
|
||||
LoopPlugin.getPlugin().disconnectTo(System.currentTimeMillis() + durationInMinutes * 60 * 1000L);
|
||||
getCommandQueue().tempBasalPercent(0, durationInMinutes, true, profile, new Callback() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!result.success) {
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.tempbasaldeliveryerror));
|
||||
}
|
||||
}
|
||||
});
|
||||
if (getActivePump().getPumpDescription().isExtendedBolusCapable && activeTreatments.isInHistoryExtendedBoluslInProgress()) {
|
||||
getCommandQueue().cancelExtended(new Callback() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!result.success) {
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.extendedbolusdeliveryerror));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
NSUpload.uploadOpenAPSOffline(durationInMinutes);
|
||||
}
|
||||
|
||||
public void suspendLoop(int durationInMinutes) {
|
||||
LoopPlugin.getPlugin().suspendTo(System.currentTimeMillis() + durationInMinutes * 60 * 1000);
|
||||
getCommandQueue().cancelTempBasal(true, new Callback() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!result.success) {
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.tempbasaldeliveryerror));
|
||||
}
|
||||
}
|
||||
});
|
||||
NSUpload.uploadOpenAPSOffline(durationInMinutes);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,17 +6,17 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import info.nightscout.androidaps.data.DetailedBolusInfo;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
|
||||
/**
|
||||
* Created by mike on 08.08.2017.
|
||||
*/
|
||||
|
||||
public class DetailedBolusInfoStorage {
|
||||
private static Logger log = LoggerFactory.getLogger(DetailedBolusInfoStorage.class);
|
||||
private static Logger log = LoggerFactory.getLogger(L.PUMP);
|
||||
private static List<DetailedBolusInfo> store = new ArrayList<>();
|
||||
|
||||
public static synchronized void add(DetailedBolusInfo detailedBolusInfo) {
|
||||
|
@ -29,7 +29,8 @@ public class DetailedBolusInfoStorage {
|
|||
DetailedBolusInfo found = null;
|
||||
for (int i = 0; i < store.size(); i++) {
|
||||
long infoTime = store.get(i).date;
|
||||
log.debug("Existing bolus info: " + store.get(i));
|
||||
if (L.isEnabled(L.PUMP))
|
||||
log.debug("Existing bolus info: " + store.get(i));
|
||||
if (bolustime > infoTime - 60 * 1000 && bolustime < infoTime + 60 * 1000) {
|
||||
found = store.get(i);
|
||||
break;
|
||||
|
@ -42,7 +43,8 @@ public class DetailedBolusInfoStorage {
|
|||
for (int i = 0; i < store.size(); i++) {
|
||||
long infoTime = store.get(i).date;
|
||||
if (bolustime > infoTime - 60 * 1000 && bolustime < infoTime + 60 * 1000) {
|
||||
log.debug("Removing bolus info: " + store.get(i));
|
||||
if (L.isEnabled(L.PUMP))
|
||||
log.debug("Removing bolus info: " + store.get(i));
|
||||
store.remove(i);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,142 @@
|
|||
package info.nightscout.androidaps.plugins.ConfigBuilder;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.crashlytics.android.answers.CustomEvent;
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.BuildConfig;
|
||||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.data.ProfileStore;
|
||||
import info.nightscout.androidaps.db.ProfileSwitch;
|
||||
import info.nightscout.androidaps.events.EventNewBasalProfile;
|
||||
import info.nightscout.androidaps.events.EventProfileSwitchChange;
|
||||
import info.nightscout.androidaps.interfaces.ProfileInterface;
|
||||
import info.nightscout.androidaps.interfaces.TreatmentsInterface;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity;
|
||||
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||
import info.nightscout.androidaps.queue.Callback;
|
||||
import info.nightscout.utils.FabricPrivacy;
|
||||
|
||||
public class ProfileFunctions {
|
||||
private static Logger log = LoggerFactory.getLogger(L.PROFILE);
|
||||
|
||||
private static ProfileFunctions profileFunctions = null;
|
||||
|
||||
public static ProfileFunctions getInstance() {
|
||||
if (profileFunctions == null)
|
||||
profileFunctions = new ProfileFunctions();
|
||||
return profileFunctions;
|
||||
}
|
||||
|
||||
static {
|
||||
ProfileFunctions.getInstance(); // register to bus at start
|
||||
}
|
||||
|
||||
ProfileFunctions() {
|
||||
MainApp.bus().register(this);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onProfileSwitch(EventProfileSwitchChange ignored) {
|
||||
if (L.isEnabled(L.PROFILE))
|
||||
log.debug("onProfileSwitch");
|
||||
MainApp.getConfigBuilder().getCommandQueue().setProfile(getProfile(), new Callback() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!result.success) {
|
||||
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
|
||||
i.putExtra("soundid", R.raw.boluserror);
|
||||
i.putExtra("status", result.comment);
|
||||
i.putExtra("title", MainApp.gs(R.string.failedupdatebasalprofile));
|
||||
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
MainApp.instance().startActivity(i);
|
||||
}
|
||||
MainApp.bus().post(new EventNewBasalProfile());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public String getProfileName() {
|
||||
return getProfileName(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
public String getProfileName(boolean customized) {
|
||||
return getProfileName(System.currentTimeMillis(), customized);
|
||||
}
|
||||
|
||||
public String getProfileName(long time) {
|
||||
return getProfileName(time, true);
|
||||
}
|
||||
|
||||
public String getProfileName(long time, boolean customized) {
|
||||
TreatmentsInterface activeTreatments = TreatmentsPlugin.getPlugin();
|
||||
ProfileInterface activeProfile = MainApp.getConfigBuilder().getActiveProfileInterface();
|
||||
|
||||
ProfileSwitch profileSwitch = activeTreatments.getProfileSwitchFromHistory(time);
|
||||
if (profileSwitch != null) {
|
||||
if (profileSwitch.profileJson != null) {
|
||||
return customized ? profileSwitch.getCustomizedName() : profileSwitch.profileName;
|
||||
} else {
|
||||
ProfileStore profileStore = activeProfile.getProfile();
|
||||
if (profileStore != null) {
|
||||
Profile profile = profileStore.getSpecificProfile(profileSwitch.profileName);
|
||||
if (profile != null)
|
||||
return profileSwitch.profileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
return MainApp.gs(R.string.noprofileselected);
|
||||
}
|
||||
|
||||
public boolean isProfileValid(String from) {
|
||||
return getProfile() != null && getProfile().isValid(from);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Profile getProfile() {
|
||||
return getProfile(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
public String getProfileUnits() {
|
||||
Profile profile = getProfile();
|
||||
return profile != null ? profile.getUnits() : Constants.MGDL;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Profile getProfile(long time) {
|
||||
TreatmentsInterface activeTreatments = TreatmentsPlugin.getPlugin();
|
||||
ProfileInterface activeProfile = MainApp.getConfigBuilder().getActiveProfileInterface();
|
||||
|
||||
//log.debug("Profile for: " + new Date(time).toLocaleString() + " : " + getProfileName(time));
|
||||
ProfileSwitch profileSwitch = activeTreatments.getProfileSwitchFromHistory(time);
|
||||
if (profileSwitch != null) {
|
||||
if (profileSwitch.profileJson != null) {
|
||||
return profileSwitch.getProfileObject();
|
||||
} else if (activeProfile.getProfile() != null) {
|
||||
Profile profile = activeProfile.getProfile().getSpecificProfile(profileSwitch.profileName);
|
||||
if (profile != null)
|
||||
return profile;
|
||||
}
|
||||
}
|
||||
if (activeTreatments.getProfileSwitchesFromHistory().size() > 0) {
|
||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("CatchedError")
|
||||
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
|
||||
.putCustomAttribute("version", BuildConfig.VERSION)
|
||||
.putCustomAttribute("time", time)
|
||||
.putCustomAttribute("getProfileSwitchesFromHistory", activeTreatments.getProfileSwitchesFromHistory().toString())
|
||||
);
|
||||
}
|
||||
log.error("getProfile at the end: returning null");
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,12 +1,15 @@
|
|||
package info.nightscout.androidaps.plugins.ConstraintsObjectives;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.widget.CardView;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.LinearSmoothScroller;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.text.Html;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
@ -15,204 +18,28 @@ import android.widget.CheckBox;
|
|||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
|
||||
import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective;
|
||||
import info.nightscout.utils.FabricPrivacy;
|
||||
import info.nightscout.utils.T;
|
||||
|
||||
public class ObjectivesFragment extends SubscriberFragment {
|
||||
private static Logger log = LoggerFactory.getLogger(ObjectivesFragment.class);
|
||||
|
||||
RecyclerView recyclerView;
|
||||
LinearLayoutManager llm;
|
||||
CheckBox enableFake;
|
||||
LinearLayout fake_layout;
|
||||
TextView reset;
|
||||
ObjectivesAdapter objectivesAdapter = new ObjectivesAdapter();
|
||||
Handler handler = new Handler(Looper.getMainLooper());
|
||||
|
||||
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ObjectiveViewHolder> {
|
||||
|
||||
List<ObjectivesPlugin.Objective> objectives;
|
||||
|
||||
RecyclerViewAdapter(List<ObjectivesPlugin.Objective> objectives) {
|
||||
this.objectives = objectives;
|
||||
}
|
||||
|
||||
private Runnable objectiveUpdater = new Runnable() {
|
||||
@Override
|
||||
public ObjectiveViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
|
||||
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.objectives_item, viewGroup, false);
|
||||
return new ObjectiveViewHolder(v);
|
||||
public void run() {
|
||||
handler.postDelayed(this, 60 * 1000);
|
||||
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
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
|
@ -220,44 +47,20 @@ public class ObjectivesFragment extends SubscriberFragment {
|
|||
try {
|
||||
View view = inflater.inflate(R.layout.objectives_fragment, container, false);
|
||||
|
||||
recyclerView = (RecyclerView) view.findViewById(R.id.objectives_recyclerview);
|
||||
recyclerView.setHasFixedSize(true);
|
||||
llm = new LinearLayoutManager(view.getContext());
|
||||
recyclerView.setLayoutManager(llm);
|
||||
enableFake = (CheckBox) view.findViewById(R.id.objectives_fake);
|
||||
fake_layout = (LinearLayout) view.findViewById(R.id.objectives_fake_layout);
|
||||
reset = (TextView) view.findViewById(R.id.objectives_reset);
|
||||
enableFake.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
updateGUI();
|
||||
}
|
||||
recyclerView = view.findViewById(R.id.objectives_recyclerview);
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(view.getContext()));
|
||||
recyclerView.setAdapter(objectivesAdapter);
|
||||
enableFake = view.findViewById(R.id.objectives_fake);
|
||||
reset = view.findViewById(R.id.objectives_reset);
|
||||
enableFake.setOnClickListener(v -> updateGUI());
|
||||
reset.setOnClickListener(v -> {
|
||||
ObjectivesPlugin.getPlugin().reset();
|
||||
ObjectivesPlugin.saveProgress();
|
||||
recyclerView.getAdapter().notifyDataSetChanged();
|
||||
scrollToCurrentObjective();
|
||||
});
|
||||
reset.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
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();
|
||||
|
||||
scrollToCurrentObjective();
|
||||
startUpdateTimer();
|
||||
return view;
|
||||
} catch (Exception e) {
|
||||
FabricPrivacy.logException(e);
|
||||
|
@ -266,13 +69,142 @@ public class ObjectivesFragment extends SubscriberFragment {
|
|||
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
|
||||
public void updateGUI() {
|
||||
Activity activity = getActivity();
|
||||
if (activity != null)
|
||||
activity.runOnUiThread(() -> {
|
||||
RecyclerViewAdapter adapter = new RecyclerViewAdapter(ObjectivesPlugin.objectives);
|
||||
recyclerView.setAdapter(adapter);
|
||||
objectivesAdapter.notifyDataSetChanged();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,43 +1,47 @@
|
|||
package info.nightscout.androidaps.plugins.ConstraintsObjectives;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import info.nightscout.androidaps.Config;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
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.ConstraintsInterface;
|
||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
import info.nightscout.androidaps.interfaces.PluginDescription;
|
||||
import info.nightscout.androidaps.interfaces.PluginType;
|
||||
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.ConstraintsSafety.SafetyPlugin;
|
||||
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.androidaps.plugins.ConstraintsObjectives.events.EventObjectivesSaved;
|
||||
import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective;
|
||||
import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective1;
|
||||
import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective2;
|
||||
import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective3;
|
||||
import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective4;
|
||||
import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective5;
|
||||
import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective6;
|
||||
import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective7;
|
||||
import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective8;
|
||||
import info.nightscout.utils.SP;
|
||||
|
||||
/**
|
||||
* Created by mike on 05.08.2016.
|
||||
*/
|
||||
public class ObjectivesPlugin extends PluginBase implements ConstraintsInterface {
|
||||
private static Logger log = LoggerFactory.getLogger(ObjectivesPlugin.class);
|
||||
private static Logger log = LoggerFactory.getLogger(L.OBJECTIVES);
|
||||
|
||||
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() {
|
||||
if (objectivesPlugin == null) {
|
||||
objectivesPlugin = new ObjectivesPlugin();
|
||||
|
@ -45,8 +49,6 @@ public class ObjectivesPlugin extends PluginBase implements ConstraintsInterface
|
|||
return objectivesPlugin;
|
||||
}
|
||||
|
||||
public static List<Objective> objectives;
|
||||
|
||||
private ObjectivesPlugin() {
|
||||
super(new PluginDescription()
|
||||
.mainType(PluginType.CONSTRAINTS)
|
||||
|
@ -55,8 +57,9 @@ public class ObjectivesPlugin extends PluginBase implements ConstraintsInterface
|
|||
.showInList(!Config.NSCLIENT && !Config.G5UPLOADER)
|
||||
.pluginName(R.string.objectives)
|
||||
.shortName(R.string.objectives_shortname)
|
||||
.description(R.string.description_objectives)
|
||||
);
|
||||
initializeData();
|
||||
setupObjectives();
|
||||
loadProgress();
|
||||
}
|
||||
|
||||
|
@ -66,186 +69,38 @@ public class ObjectivesPlugin extends PluginBase implements ConstraintsInterface
|
|||
return pump == null || pump.getPumpDescription().isTempBasalCapable;
|
||||
}
|
||||
|
||||
public class Objective {
|
||||
Integer num;
|
||||
String objective;
|
||||
String gate;
|
||||
Date started;
|
||||
Integer durationInDays;
|
||||
Date accomplished;
|
||||
|
||||
Objective(Integer num, String objective, String gate, Date started, Integer durationInDays, Date accomplished) {
|
||||
this.num = num;
|
||||
this.objective = objective;
|
||||
this.gate = gate;
|
||||
this.started = started;
|
||||
this.durationInDays = durationInDays;
|
||||
this.accomplished = accomplished;
|
||||
}
|
||||
|
||||
public void setStarted(Date started) {
|
||||
this.started = started;
|
||||
}
|
||||
|
||||
boolean isStarted() {
|
||||
return started.getTime() > 0;
|
||||
}
|
||||
|
||||
boolean isFinished() {
|
||||
return accomplished.getTime() != 0;
|
||||
}
|
||||
private void setupObjectives() {
|
||||
objectives.add(new Objective1());
|
||||
objectives.add(new Objective2());
|
||||
objectives.add(new Objective3());
|
||||
objectives.add(new Objective4());
|
||||
objectives.add(new Objective5());
|
||||
objectives.add(new Objective6());
|
||||
objectives.add(new Objective7());
|
||||
objectives.add(new Objective8());
|
||||
}
|
||||
|
||||
// Objective 0
|
||||
public static boolean bgIsAvailableInNS = false;
|
||||
public static boolean pumpStatusIsAvailableInNS = false;
|
||||
// Objective 1
|
||||
public static Integer manualEnacts = 0;
|
||||
private static final Integer manualEnactsNeeded = 20;
|
||||
|
||||
class RequirementResult {
|
||||
boolean done = false;
|
||||
String comment = "";
|
||||
|
||||
RequirementResult(boolean done, String comment) {
|
||||
this.done = done;
|
||||
this.comment = comment;
|
||||
public void reset() {
|
||||
for (Objective objective : objectives) {
|
||||
objective.setStartedOn(null);
|
||||
objective.setAccomplishedOn(null);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
pumpStatusIsAvailableInNS = false;
|
||||
manualEnacts = 0;
|
||||
|
||||
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)));
|
||||
saveProgress();
|
||||
}
|
||||
|
||||
public static void saveProgress() {
|
||||
if (objectives != null) {
|
||||
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext());
|
||||
SharedPreferences.Editor editor = settings.edit();
|
||||
for (int num = 0; num < objectives.size(); num++) {
|
||||
Objective o = objectives.get(num);
|
||||
editor.putString("Objectives" + num + "started", Long.toString(o.started.getTime()));
|
||||
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");
|
||||
}
|
||||
SP.putBoolean("Objectives" + "bgIsAvailableInNS", bgIsAvailableInNS);
|
||||
SP.putBoolean("Objectives" + "pumpStatusIsAvailableInNS", pumpStatusIsAvailableInNS);
|
||||
SP.putString("Objectives" + "manualEnacts", Integer.toString(manualEnacts));
|
||||
if (L.isEnabled(L.OBJECTIVES))
|
||||
log.debug("Objectives stored");
|
||||
MainApp.bus().post(new EventObjectivesSaved());
|
||||
}
|
||||
|
||||
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);
|
||||
pumpStatusIsAvailableInNS = SP.getBoolean("Objectives" + "pumpStatusIsAvailableInNS", false);
|
||||
try {
|
||||
|
@ -253,15 +108,19 @@ public class ObjectivesPlugin extends PluginBase implements ConstraintsInterface
|
|||
} catch (Exception e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
if (Config.logPrefsChange)
|
||||
if (L.isEnabled(L.OBJECTIVES))
|
||||
log.debug("Objectives loaded");
|
||||
}
|
||||
|
||||
public static List<Objective> getObjectives() {
|
||||
return objectives;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constraints interface
|
||||
**/
|
||||
@Override
|
||||
public Constraint<Boolean> isLoopInvokationAllowed(Constraint<Boolean> value) {
|
||||
public Constraint<Boolean> isLoopInvocationAllowed(Constraint<Boolean> value) {
|
||||
if (!objectives.get(0).isStarted())
|
||||
value.set(false, String.format(MainApp.gs(R.string.objectivenotstarted), 1), this);
|
||||
return value;
|
||||
|
@ -297,7 +156,7 @@ public class ObjectivesPlugin extends PluginBase implements ConstraintsInterface
|
|||
|
||||
@Override
|
||||
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);
|
||||
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
|
||||
**/
|
||||
@Override
|
||||
public Constraint<Boolean> isLoopInvokationAllowed(Constraint<Boolean> value) {
|
||||
public Constraint<Boolean> isLoopInvocationAllowed(Constraint<Boolean> value) {
|
||||
if (!ConfigBuilderPlugin.getActivePump().getPumpDescription().isTempBasalCapable)
|
||||
value.set(false, MainApp.gs(R.string.pumpisnottempbasalcapable), this);
|
||||
return value;
|
||||
|
|
|
@ -33,7 +33,7 @@ import info.nightscout.androidaps.R;
|
|||
import info.nightscout.androidaps.events.EventFoodDatabaseChanged;
|
||||
import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
|
||||
import info.nightscout.utils.FabricPrivacy;
|
||||
import info.nightscout.utils.NSUpload;
|
||||
import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload;
|
||||
import info.nightscout.utils.SpinnerHelper;
|
||||
|
||||
/**
|
||||
|
|
|
@ -26,6 +26,7 @@ public class FoodPlugin extends PluginBase {
|
|||
.fragmentClass(FoodFragment.class.getName())
|
||||
.pluginName(R.string.food)
|
||||
.shortName(R.string.food_short)
|
||||
.description(R.string.description_food)
|
||||
);
|
||||
this.service = new FoodService();
|
||||
}
|
||||
|
|
|
@ -33,13 +33,14 @@ import info.nightscout.androidaps.db.ICallback;
|
|||
import info.nightscout.androidaps.events.Event;
|
||||
import info.nightscout.androidaps.events.EventFoodDatabaseChanged;
|
||||
import info.nightscout.androidaps.events.EventNsFood;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
|
||||
/**
|
||||
* Created by mike on 24.09.2017.
|
||||
*/
|
||||
|
||||
public class FoodService extends OrmLiteBaseService<DatabaseHelper> {
|
||||
private static Logger log = LoggerFactory.getLogger(FoodService.class);
|
||||
private Logger log = LoggerFactory.getLogger(L.DATAFOOD);
|
||||
|
||||
private static final ScheduledExecutorService foodEventWorker = Executors.newSingleThreadScheduledExecutor();
|
||||
private static ScheduledFuture<?> scheduledFoodEventPost = null;
|
||||
|
@ -110,7 +111,8 @@ public class FoodService extends OrmLiteBaseService<DatabaseHelper> {
|
|||
public void onCreate() {
|
||||
super.onCreate();
|
||||
try {
|
||||
log.info("onCreate");
|
||||
if (L.isEnabled(L.DATAFOOD))
|
||||
log.info("onCreate");
|
||||
TableUtils.createTableIfNotExists(this.getConnectionSource(), Food.class);
|
||||
} catch (SQLException e) {
|
||||
log.error("Can't create database", e);
|
||||
|
@ -122,7 +124,8 @@ public class FoodService extends OrmLiteBaseService<DatabaseHelper> {
|
|||
if (oldVersion == 7 && newVersion == 8) {
|
||||
log.debug("Upgrading database from v7 to v8");
|
||||
} else {
|
||||
log.info("onUpgrade");
|
||||
if (L.isEnabled(L.DATAFOOD))
|
||||
log.info("onUpgrade");
|
||||
// this.resetFood();
|
||||
}
|
||||
}
|
||||
|
@ -161,7 +164,8 @@ public class FoodService extends OrmLiteBaseService<DatabaseHelper> {
|
|||
|
||||
class PostRunnable implements Runnable {
|
||||
public void run() {
|
||||
log.debug("Firing EventFoodChange");
|
||||
if (L.isEnabled(L.DATAFOOD))
|
||||
log.debug("Firing EventFoodChange");
|
||||
MainApp.bus().post(event);
|
||||
callback.setPost(null);
|
||||
}
|
||||
|
@ -271,7 +275,8 @@ public class FoodService extends OrmLiteBaseService<DatabaseHelper> {
|
|||
public void deleteByNSId(String _id) throws SQLException {
|
||||
Food stored = this.findByNSId(_id);
|
||||
if (stored != null) {
|
||||
log.debug("FOOD: Removing Food record from database: " + stored.toString());
|
||||
if (L.isEnabled(L.DATAFOOD))
|
||||
log.debug("Removing Food record from database: " + stored.toString());
|
||||
this.delete(stored);
|
||||
}
|
||||
}
|
||||
|
@ -324,7 +329,8 @@ public class FoodService extends OrmLiteBaseService<DatabaseHelper> {
|
|||
public void createOrUpdate(Food food) {
|
||||
try {
|
||||
this.getDao().createOrUpdate(food);
|
||||
log.debug("FOOD: Created or Updated: " + food.toString());
|
||||
if (L.isEnabled(L.DATAFOOD))
|
||||
log.debug("Created or Updated: " + food.toString());
|
||||
} catch (SQLException e) {
|
||||
log.error("Unable to createOrUpdate Food", e);
|
||||
}
|
||||
|
@ -334,7 +340,8 @@ public class FoodService extends OrmLiteBaseService<DatabaseHelper> {
|
|||
public void create(Food food) {
|
||||
try {
|
||||
this.getDao().create(food);
|
||||
log.debug("FOOD: New record: " + food.toString());
|
||||
if (L.isEnabled(L.DATAFOOD))
|
||||
log.debug("New record: " + food.toString());
|
||||
} catch (SQLException e) {
|
||||
log.error("Unable to create Food", e);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import com.squareup.otto.Bus;
|
|||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.Iob;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions;
|
||||
import info.nightscout.androidaps.plugins.Treatments.Treatment;
|
||||
import info.nightscout.androidaps.interfaces.InsulinInterface;
|
||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
|
@ -29,6 +30,7 @@ public abstract class InsulinOrefBasePlugin extends PluginBase implements Insuli
|
|||
.fragmentClass(InsulinFragment.class.getName())
|
||||
.pluginName(R.string.fastactinginsulin)
|
||||
.shortName(R.string.insulin_shortname)
|
||||
.visibleByDefault(false)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -60,7 +62,7 @@ public abstract class InsulinOrefBasePlugin extends PluginBase implements Insuli
|
|||
}
|
||||
|
||||
public double getUserDefinedDia() {
|
||||
return MainApp.getConfigBuilder().getProfile() != null ? MainApp.getConfigBuilder().getProfile().getDia() : MIN_DIA;
|
||||
return ProfileFunctions.getInstance().getProfile() != null ? ProfileFunctions.getInstance().getProfile().getDia() : MIN_DIA;
|
||||
}
|
||||
|
||||
public Iob iobCalcForTreatment(Treatment treatment, long time) {
|
||||
|
|
|
@ -24,7 +24,8 @@ public class InsulinOrefFreePeakPlugin extends InsulinOrefBasePlugin {
|
|||
super();
|
||||
pluginDescription
|
||||
.pluginName(R.string.free_peak_oref)
|
||||
.preferencesId(R.xml.pref_insulinoreffreepeak);
|
||||
.preferencesId(R.xml.pref_insulinoreffreepeak)
|
||||
.description(R.string.description_insulin_free_peak);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -22,7 +22,8 @@ public class InsulinOrefRapidActingPlugin extends InsulinOrefBasePlugin {
|
|||
private InsulinOrefRapidActingPlugin() {
|
||||
super();
|
||||
pluginDescription
|
||||
.pluginName(R.string.rapid_acting_oref);
|
||||
.pluginName(R.string.rapid_acting_oref)
|
||||
.description(R.string.description_insulin_rapid);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -22,7 +22,8 @@ public class InsulinOrefUltraRapidActingPlugin extends InsulinOrefBasePlugin {
|
|||
private InsulinOrefUltraRapidActingPlugin() {
|
||||
super();
|
||||
pluginDescription
|
||||
.pluginName(R.string.ultrarapid_oref);
|
||||
.pluginName(R.string.ultrarapid_oref)
|
||||
.description(R.string.description_insulin_ultra_rapid);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -12,12 +12,14 @@ import info.nightscout.androidaps.MainApp;
|
|||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.interfaces.PluginType;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions;
|
||||
import info.nightscout.androidaps.plugins.OpenAPSSMB.SMBDefaults;
|
||||
import info.nightscout.androidaps.plugins.Overview.graphExtensions.DataPointWithLabelInterface;
|
||||
import info.nightscout.androidaps.plugins.Overview.graphExtensions.PointsWithLabelGraphSeries;
|
||||
import info.nightscout.androidaps.plugins.Overview.graphExtensions.Scale;
|
||||
import info.nightscout.androidaps.plugins.SensitivityAAPS.SensitivityAAPSPlugin;
|
||||
import info.nightscout.androidaps.plugins.SensitivityWeightedAverage.SensitivityWeightedAveragePlugin;
|
||||
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityAAPSPlugin;
|
||||
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityWeightedAveragePlugin;
|
||||
import info.nightscout.androidaps.plugins.Treatments.Treatment;
|
||||
import info.nightscout.utils.SP;
|
||||
|
||||
|
@ -26,7 +28,7 @@ import info.nightscout.utils.SP;
|
|||
*/
|
||||
|
||||
public class AutosensData implements DataPointWithLabelInterface {
|
||||
private static Logger log = LoggerFactory.getLogger(AutosensData.class);
|
||||
private static Logger log = LoggerFactory.getLogger(L.AUTOSENS);
|
||||
|
||||
public void setChartTime(long chartTime) {
|
||||
this.chartTime = chartTime;
|
||||
|
@ -44,11 +46,12 @@ public class AutosensData implements DataPointWithLabelInterface {
|
|||
remaining = t.carbs;
|
||||
if (SensitivityAAPSPlugin.getPlugin().isEnabled(PluginType.SENSITIVITY) || SensitivityWeightedAveragePlugin.getPlugin().isEnabled(PluginType.SENSITIVITY)) {
|
||||
double maxAbsorptionHours = SP.getDouble(R.string.key_absorption_maxtime, Constants.DEFAULT_MAX_ABSORPTION_TIME);
|
||||
Profile profile = MainApp.getConfigBuilder().getProfile(t.date);
|
||||
Profile profile = ProfileFunctions.getInstance().getProfile(t.date);
|
||||
double sens = Profile.toMgdl(profile.getIsf(t.date), profile.getUnits());
|
||||
double ic = profile.getIc(t.date);
|
||||
min5minCarbImpact = t.carbs / (maxAbsorptionHours * 60 / 5) * sens / ic;
|
||||
log.debug("Min 5m carbs impact for " + carbs + "g @" + new Date(t.date).toLocaleString() + " for " + maxAbsorptionHours + "h calculated to " + min5minCarbImpact + " ISF: " + sens + " IC: " + ic);
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("Min 5m carbs impact for " + carbs + "g @" + new Date(t.date).toLocaleString() + " for " + maxAbsorptionHours + "h calculated to " + min5minCarbImpact + " ISF: " + sens + " IC: " + ic);
|
||||
} else {
|
||||
min5minCarbImpact = SP.getDouble(R.string.key_openapsama_min_5m_carbimpact, SMBDefaults.min_5m_carbimpact);
|
||||
}
|
||||
|
@ -56,11 +59,11 @@ public class AutosensData implements DataPointWithLabelInterface {
|
|||
}
|
||||
|
||||
public long time = 0L;
|
||||
long chartTime;
|
||||
public double bg = 0; // mgdl
|
||||
private long chartTime;
|
||||
public String pastSensitivity = "";
|
||||
public double deviation = 0d;
|
||||
boolean nonCarbsDeviation = false;
|
||||
public boolean nonEqualDeviation = false;
|
||||
public boolean validDeviation = false;
|
||||
List<CarbsInPast> activeCarbsList = new ArrayList<>();
|
||||
double absorbed = 0d;
|
||||
public double carbsFromBolus = 0d;
|
||||
|
@ -70,15 +73,23 @@ public class AutosensData implements DataPointWithLabelInterface {
|
|||
public double avgDelta = 0d;
|
||||
public double avgDeviation = 0d;
|
||||
|
||||
public double autosensRatio = 1d;
|
||||
public AutosensResult autosensResult = new AutosensResult();
|
||||
public double slopeFromMaxDeviation = 0;
|
||||
public double slopeFromMinDeviation = 999;
|
||||
public double usedMinCarbsImpact = 0d;
|
||||
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
|
||||
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() {
|
||||
|
@ -99,7 +110,8 @@ public class AutosensData implements DataPointWithLabelInterface {
|
|||
activeCarbsList.remove(i--);
|
||||
if (c.remaining > 0)
|
||||
cob -= c.remaining;
|
||||
log.debug("Removing carbs at " + new Date(toTime).toLocaleString() + " + after " + maxAbsorptionHours + "h :" + new Date(c.time).toLocaleString());
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("Removing carbs at " + new Date(toTime).toLocaleString() + " + after " + maxAbsorptionHours + "h :" + new Date(c.time).toLocaleString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,16 +5,18 @@ import org.json.JSONObject;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
|
||||
/**
|
||||
* Created by mike on 06.01.2017.
|
||||
*/
|
||||
public class AutosensResult {
|
||||
private static Logger log = LoggerFactory.getLogger(AutosensResult.class);
|
||||
private static Logger log = LoggerFactory.getLogger(L.AUTOSENS);
|
||||
|
||||
//default values to show when autosens algorithm is not called
|
||||
public double ratio = 1d;
|
||||
public double carbsAbsorbed = 0d;
|
||||
public String sensResult = "autosens deactivated";
|
||||
public String sensResult = "autosens not available";
|
||||
public String pastSensitivity = "";
|
||||
public String ratioLimit = "";
|
||||
|
||||
|
@ -32,4 +34,8 @@ public class AutosensResult {
|
|||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return json().toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ import java.util.ArrayList;
|
|||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import info.nightscout.androidaps.Config;
|
||||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
|
@ -32,12 +31,16 @@ import info.nightscout.androidaps.events.EventPreferenceChange;
|
|||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
import info.nightscout.androidaps.interfaces.PluginDescription;
|
||||
import info.nightscout.androidaps.interfaces.PluginType;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions;
|
||||
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventNewHistoryData;
|
||||
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.TreatmentsPlugin;
|
||||
import info.nightscout.utils.DateUtil;
|
||||
import info.nightscout.utils.T;
|
||||
|
||||
import static info.nightscout.utils.DateUtil.now;
|
||||
|
||||
|
@ -46,7 +49,7 @@ import static info.nightscout.utils.DateUtil.now;
|
|||
*/
|
||||
|
||||
public class IobCobCalculatorPlugin extends PluginBase {
|
||||
private Logger log = LoggerFactory.getLogger(IobCobCalculatorPlugin.class);
|
||||
private Logger log = LoggerFactory.getLogger(L.AUTOSENS);
|
||||
|
||||
private static IobCobCalculatorPlugin plugin = null;
|
||||
|
||||
|
@ -68,7 +71,7 @@ public class IobCobCalculatorPlugin extends PluginBase {
|
|||
final Object dataLock = new Object();
|
||||
|
||||
boolean stopCalculationTrigger = false;
|
||||
private IobCobThread thread = null;
|
||||
private Thread thread = null;
|
||||
|
||||
public IobCobCalculatorPlugin() {
|
||||
super(new PluginDescription()
|
||||
|
@ -96,6 +99,10 @@ public class IobCobCalculatorPlugin extends PluginBase {
|
|||
return autosensDataTable;
|
||||
}
|
||||
|
||||
public List<BgReading> getBgReadings() {
|
||||
return bgReadings;
|
||||
}
|
||||
|
||||
public List<BgReading> getBucketedData() {
|
||||
return bucketed_data;
|
||||
}
|
||||
|
@ -105,13 +112,15 @@ public class IobCobCalculatorPlugin extends PluginBase {
|
|||
//log.debug("Locking getBucketedData");
|
||||
synchronized (dataLock) {
|
||||
if (bucketed_data == null) {
|
||||
log.debug("No bucketed data available");
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("No bucketed data available");
|
||||
return null;
|
||||
}
|
||||
int index = indexNewerThan(fromTime);
|
||||
if (index > -1) {
|
||||
List<BgReading> part = bucketed_data.subList(0, index);
|
||||
log.debug("Bucketed data striped off: " + part.size() + "/" + bucketed_data.size());
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("Bucketed data striped off: " + part.size() + "/" + bucketed_data.size());
|
||||
return part;
|
||||
}
|
||||
}
|
||||
|
@ -130,13 +139,15 @@ public class IobCobCalculatorPlugin extends PluginBase {
|
|||
public static long roundUpTime(long time) {
|
||||
if (time % 60000 == 0)
|
||||
return time;
|
||||
long rouded = (time / 60000 + 1) * 60000;
|
||||
return rouded;
|
||||
long rounded = (time / 60000 + 1) * 60000;
|
||||
return rounded;
|
||||
}
|
||||
|
||||
void loadBgData(long start) {
|
||||
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));
|
||||
void loadBgData(long now) {
|
||||
long start = (long) (now - 60 * 60 * 1000L * (24 + dia));
|
||||
bgReadings = MainApp.getDbHelper().getBgreadingsDataFromTime(start, now, false);
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("BG data loaded. Size: " + bgReadings.size() + " Start date: " + DateUtil.dateAndTimeString(start) + " End date: " + DateUtil.dateAndTimeString(now));
|
||||
}
|
||||
|
||||
private boolean isAbout5minData() {
|
||||
|
@ -152,13 +163,15 @@ public class IobCobCalculatorPlugin extends PluginBase {
|
|||
totalDiff += diff;
|
||||
if (diff > 30 * 1000 && diff < 270 * 1000) { // 0:30 - 4:30
|
||||
log.debug("Interval detection: values: " + bgReadings.size() + " diff: " + (diff / 1000) + "sec is5minData: " + false);
|
||||
return false;
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
double intervals = totalDiff / (5 * 60 * 1000d);
|
||||
double variability = Math.abs(intervals - Math.round(intervals));
|
||||
boolean is5mindata = variability < 0.02;
|
||||
log.debug("Interval detection: values: " + bgReadings.size() + " variability: " + variability + " is5minData: " + is5mindata);
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("Interval detection: values: " + bgReadings.size() + " variability: " + variability + " is5minData: " + is5mindata);
|
||||
return is5mindata;
|
||||
}
|
||||
}
|
||||
|
@ -285,15 +298,24 @@ public class IobCobCalculatorPlugin extends PluginBase {
|
|||
//log.error("***** Average");
|
||||
}
|
||||
}
|
||||
log.debug("Bucketed data created. Size: " + bucketed_data.size());
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("Bucketed data created. Size: " + bucketed_data.size());
|
||||
}
|
||||
|
||||
public long oldestDataAvailable() {
|
||||
long now = System.currentTimeMillis();
|
||||
public long calculateDetectionStart(long from, boolean limitDataToOldestAvailable) {
|
||||
Profile profile = ProfileFunctions.getInstance().getProfile(from);
|
||||
double dia = Constants.defaultDIA;
|
||||
if (profile != null) dia = profile.getDia();
|
||||
|
||||
long oldestDataAvailable = TreatmentsPlugin.getPlugin().oldestDataAvailable();
|
||||
long getBGDataFrom = Math.max(oldestDataAvailable, (long) (now - 60 * 60 * 1000L * (24 + MainApp.getConfigBuilder().getProfile().getDia())));
|
||||
log.debug("Limiting data to oldest available temps: " + new Date(oldestDataAvailable).toString());
|
||||
long getBGDataFrom;
|
||||
if (limitDataToOldestAvailable) {
|
||||
getBGDataFrom = Math.max(oldestDataAvailable, (long) (from - T.hours(1).msecs() * (24 + dia)));
|
||||
if (getBGDataFrom == oldestDataAvailable)
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("Limiting data to oldest available temps: " + new Date(oldestDataAvailable).toString());
|
||||
} else
|
||||
getBGDataFrom = (long) (from - T.hours(1).msecs() * (24 + dia));
|
||||
return getBGDataFrom;
|
||||
}
|
||||
|
||||
|
@ -347,13 +369,12 @@ public class IobCobCalculatorPlugin extends PluginBase {
|
|||
return null;
|
||||
}
|
||||
|
||||
public BasalData getBasalData(long time) {
|
||||
public BasalData getBasalData(Profile profile, long time) {
|
||||
long now = System.currentTimeMillis();
|
||||
time = roundUpTime(time);
|
||||
BasalData retval = basalDataTable.get(time);
|
||||
if (retval == null) {
|
||||
retval = new BasalData();
|
||||
Profile profile = MainApp.getConfigBuilder().getProfile(time);
|
||||
TemporaryBasal tb = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(time);
|
||||
retval.basal = profile.getBasal(time);
|
||||
if (tb != null) {
|
||||
|
@ -377,22 +398,20 @@ public class IobCobCalculatorPlugin extends PluginBase {
|
|||
public AutosensData getAutosensData(long time) {
|
||||
synchronized (dataLock) {
|
||||
long now = System.currentTimeMillis();
|
||||
if (time > now)
|
||||
if (time > now) {
|
||||
return null;
|
||||
}
|
||||
Long previous = findPreviousTimeFromBucketedData(time);
|
||||
if (previous == null)
|
||||
if (previous == null) {
|
||||
return null;
|
||||
}
|
||||
time = roundUpTime(previous);
|
||||
AutosensData data = autosensDataTable.get(time);
|
||||
if (data != null) {
|
||||
//log.debug(">>> getAutosensData Cache hit " + data.log(time));
|
||||
//log.debug(">>> AUTOSENSDATA Cache hit " + data.toString());
|
||||
return data;
|
||||
} else {
|
||||
if (time > now) {
|
||||
// data may not be calculated yet, use last data
|
||||
return getLastAutosensData("getAutosensData");
|
||||
}
|
||||
//log.debug(">>> getAutosensData Cache miss " + new Date(time).toLocaleString());
|
||||
//log.debug(">>> AUTOSENSDATA Cache miss " + new Date(time).toLocaleString());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -400,6 +419,16 @@ public class IobCobCalculatorPlugin extends PluginBase {
|
|||
|
||||
@Nullable
|
||||
public AutosensData getLastAutosensDataSynchronized(String reason) {
|
||||
if (thread != null && thread.isAlive()) {
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("AUTOSENSDATA is waiting for calculation thread: " + reason);
|
||||
try {
|
||||
thread.join(5000);
|
||||
} catch (InterruptedException ignored) {
|
||||
}
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("AUTOSENSDATA finished waiting for calculation thread: " + reason);
|
||||
}
|
||||
synchronized (dataLock) {
|
||||
return getLastAutosensData(reason);
|
||||
}
|
||||
|
@ -436,7 +465,8 @@ public class IobCobCalculatorPlugin extends PluginBase {
|
|||
@Nullable
|
||||
public AutosensData getLastAutosensData(String reason) {
|
||||
if (autosensDataTable.size() < 1) {
|
||||
log.debug("AUTOSENSDATA null: autosensDataTable empty (" + reason + ")");
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("AUTOSENSDATA null: autosensDataTable empty (" + reason + ")");
|
||||
return null;
|
||||
}
|
||||
AutosensData data;
|
||||
|
@ -450,13 +480,23 @@ public class IobCobCalculatorPlugin extends PluginBase {
|
|||
return null;
|
||||
}
|
||||
if (data.time < System.currentTimeMillis() - 11 * 60 * 1000) {
|
||||
log.debug("AUTOSENSDATA null: data is old (" + reason + ") size()=" + autosensDataTable.size() + " lastdata=" + DateUtil.dateAndTimeString(data.time));
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("AUTOSENSDATA null: data is old (" + reason + ") size()=" + autosensDataTable.size() + " lastdata=" + DateUtil.dateAndTimeString(data.time));
|
||||
return null;
|
||||
} else {
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("AUTOSENSDATA (" + reason + ") " + data.toString());
|
||||
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) {
|
||||
// predict IOB out to DIA plus 30m
|
||||
long time = System.currentTimeMillis();
|
||||
|
@ -491,14 +531,10 @@ public class IobCobCalculatorPlugin extends PluginBase {
|
|||
|
||||
public AutosensResult detectSensitivityWithLock(long fromTime, long toTime) {
|
||||
synchronized (dataLock) {
|
||||
return detectSensitivity(fromTime, toTime);
|
||||
return ConfigBuilderPlugin.getActiveSensitivity().detectSensitivity(this, fromTime, toTime);
|
||||
}
|
||||
}
|
||||
|
||||
static AutosensResult detectSensitivity(long fromTime, long toTime) {
|
||||
return ConfigBuilderPlugin.getActiveSensitivity().detectSensitivity(fromTime, toTime);
|
||||
}
|
||||
|
||||
public static JSONArray convertToJSONArray(IobTotal[] iobArray) {
|
||||
JSONArray array = new JSONArray();
|
||||
for (int i = 0; i < iobArray.length; i++) {
|
||||
|
@ -511,38 +547,46 @@ public class IobCobCalculatorPlugin extends PluginBase {
|
|||
@SuppressWarnings("unused")
|
||||
public void onEventAppInitialized(EventAppInitialized ev) {
|
||||
if (this != getPlugin()) {
|
||||
log.debug("Ignoring event for non default instance");
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("Ignoring event for non default instance");
|
||||
return;
|
||||
}
|
||||
runCalculation("onEventAppInitialized", System.currentTimeMillis(), true, ev);
|
||||
runCalculation("onEventAppInitialized", System.currentTimeMillis(), true, true, ev);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@SuppressWarnings("unused")
|
||||
public void onEventNewBG(EventNewBG ev) {
|
||||
if (this != getPlugin()) {
|
||||
log.debug("Ignoring event for non default instance");
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("Ignoring event for non default instance");
|
||||
return;
|
||||
}
|
||||
stopCalculation("onEventNewBG");
|
||||
runCalculation("onEventNewBG", System.currentTimeMillis(), true, ev);
|
||||
runCalculation("onEventNewBG", System.currentTimeMillis(), true, true, ev);
|
||||
}
|
||||
|
||||
private void stopCalculation(String from) {
|
||||
public void stopCalculation(String from) {
|
||||
if (thread != null && thread.getState() != Thread.State.TERMINATED) {
|
||||
stopCalculationTrigger = true;
|
||||
log.debug("Stopping calculation thread: " + from);
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("Stopping calculation thread: " + from);
|
||||
while (thread.getState() != Thread.State.TERMINATED) {
|
||||
SystemClock.sleep(100);
|
||||
}
|
||||
log.debug("Calculation thread stopped: " + from);
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("Calculation thread stopped: " + from);
|
||||
}
|
||||
}
|
||||
|
||||
public void runCalculation(String from, long start, boolean bgDataReload, Event cause) {
|
||||
log.debug("Starting calculation thread: " + from);
|
||||
public void runCalculation(String from, long end, boolean bgDataReload, boolean limitDataToOldestAvailable, Event cause) {
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("Starting calculation thread: " + from + " to " + DateUtil.dateAndTimeString(end));
|
||||
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, end, bgDataReload, limitDataToOldestAvailable, cause);
|
||||
else
|
||||
thread = new IobCobThread(this, from, end, bgDataReload, limitDataToOldestAvailable, cause);
|
||||
thread.start();
|
||||
}
|
||||
}
|
||||
|
@ -550,12 +594,13 @@ public class IobCobCalculatorPlugin extends PluginBase {
|
|||
@Subscribe
|
||||
public void onNewProfile(EventNewBasalProfile ev) {
|
||||
if (this != getPlugin()) {
|
||||
log.debug("Ignoring event for non default instance");
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("Ignoring event for non default instance");
|
||||
return;
|
||||
}
|
||||
if (MainApp.getConfigBuilder() == null)
|
||||
return; // app still initializing
|
||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||
if (profile == null)
|
||||
return; // app still initializing
|
||||
dia = profile.getDia();
|
||||
|
@ -564,55 +609,63 @@ public class IobCobCalculatorPlugin extends PluginBase {
|
|||
}
|
||||
stopCalculation("onNewProfile");
|
||||
synchronized (dataLock) {
|
||||
log.debug("Invalidating cached data because of new profile. IOB: " + iobTable.size() + " Autosens: " + autosensDataTable.size() + " records");
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("Invalidating cached data because of new profile. IOB: " + iobTable.size() + " Autosens: " + autosensDataTable.size() + " records");
|
||||
iobTable = new LongSparseArray<>();
|
||||
autosensDataTable = new LongSparseArray<>();
|
||||
}
|
||||
runCalculation("onNewProfile", System.currentTimeMillis(), false, ev);
|
||||
runCalculation("onNewProfile", System.currentTimeMillis(), false, true, ev);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onEventPreferenceChange(EventPreferenceChange ev) {
|
||||
if (this != getPlugin()) {
|
||||
log.debug("Ignoring event for non default instance");
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("Ignoring event for non default instance");
|
||||
return;
|
||||
}
|
||||
if (ev.isChanged(R.string.key_openapsama_autosens_period) ||
|
||||
ev.isChanged(R.string.key_age) ||
|
||||
ev.isChanged(R.string.key_absorption_maxtime) ||
|
||||
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");
|
||||
synchronized (dataLock) {
|
||||
log.debug("Invalidating cached data because of preference change. IOB: " + iobTable.size() + " Autosens: " + autosensDataTable.size() + " records");
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("Invalidating cached data because of preference change. IOB: " + iobTable.size() + " Autosens: " + autosensDataTable.size() + " records");
|
||||
iobTable = new LongSparseArray<>();
|
||||
autosensDataTable = new LongSparseArray<>();
|
||||
}
|
||||
runCalculation("onEventPreferenceChange", System.currentTimeMillis(), false, ev);
|
||||
runCalculation("onEventPreferenceChange", System.currentTimeMillis(), false, true, ev);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onEventConfigBuilderChange(EventConfigBuilderChange ev) {
|
||||
if (this != getPlugin()) {
|
||||
log.debug("Ignoring event for non default instance");
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("Ignoring event for non default instance");
|
||||
return;
|
||||
}
|
||||
stopCalculation("onEventConfigBuilderChange");
|
||||
synchronized (dataLock) {
|
||||
log.debug("Invalidating cached data because of configuration change. IOB: " + iobTable.size() + " Autosens: " + autosensDataTable.size() + " records");
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("Invalidating cached data because of configuration change. IOB: " + iobTable.size() + " Autosens: " + autosensDataTable.size() + " records");
|
||||
iobTable = new LongSparseArray<>();
|
||||
autosensDataTable = new LongSparseArray<>();
|
||||
}
|
||||
runCalculation("onEventConfigBuilderChange", System.currentTimeMillis(), false, ev);
|
||||
runCalculation("onEventConfigBuilderChange", System.currentTimeMillis(), false, true, ev);
|
||||
}
|
||||
|
||||
// When historical data is changed (comming from NS etc) finished calculations after this date must be invalidated
|
||||
@Subscribe
|
||||
public void onEventNewHistoryData(EventNewHistoryData ev) {
|
||||
if (this != getPlugin()) {
|
||||
log.debug("Ignoring event for non default instance");
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("Ignoring event for non default instance");
|
||||
return;
|
||||
}
|
||||
//log.debug("Locking onNewHistoryData");
|
||||
|
@ -620,10 +673,11 @@ public class IobCobCalculatorPlugin extends PluginBase {
|
|||
synchronized (dataLock) {
|
||||
// clear up 5 min back for proper COB calculation
|
||||
long time = ev.time - 5 * 60 * 1000L;
|
||||
log.debug("Invalidating cached data to: " + new Date(time).toLocaleString());
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("Invalidating cached data to: " + new Date(time).toLocaleString());
|
||||
for (int index = iobTable.size() - 1; index >= 0; index--) {
|
||||
if (iobTable.keyAt(index) > time) {
|
||||
if (Config.logAutosensData)
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("Removing from iobTable: " + new Date(iobTable.keyAt(index)).toLocaleString());
|
||||
iobTable.removeAt(index);
|
||||
} else {
|
||||
|
@ -632,7 +686,7 @@ public class IobCobCalculatorPlugin extends PluginBase {
|
|||
}
|
||||
for (int index = autosensDataTable.size() - 1; index >= 0; index--) {
|
||||
if (autosensDataTable.keyAt(index) > time) {
|
||||
if (Config.logAutosensData)
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("Removing from autosensDataTable: " + new Date(autosensDataTable.keyAt(index)).toLocaleString());
|
||||
autosensDataTable.removeAt(index);
|
||||
} else {
|
||||
|
@ -641,7 +695,7 @@ public class IobCobCalculatorPlugin extends PluginBase {
|
|||
}
|
||||
for (int index = basalDataTable.size() - 1; index >= 0; index--) {
|
||||
if (basalDataTable.keyAt(index) > time) {
|
||||
if (Config.logAutosensData)
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("Removing from basalDataTable: " + new Date(basalDataTable.keyAt(index)).toLocaleString());
|
||||
basalDataTable.removeAt(index);
|
||||
} else {
|
||||
|
@ -649,13 +703,14 @@ public class IobCobCalculatorPlugin extends PluginBase {
|
|||
}
|
||||
}
|
||||
}
|
||||
runCalculation("onEventNewHistoryData", System.currentTimeMillis(), false, ev);
|
||||
runCalculation("onEventNewHistoryData", System.currentTimeMillis(), false, true, ev);
|
||||
//log.debug("Releasing onNewHistoryData");
|
||||
}
|
||||
|
||||
public void clearCache() {
|
||||
synchronized (dataLock) {
|
||||
log.debug("Clearing cached data.");
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("Clearing cached data.");
|
||||
iobTable = new LongSparseArray<>();
|
||||
autosensDataTable = new LongSparseArray<>();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,373 @@
|
|||
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.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.logging.L;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions;
|
||||
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(L.AUTOSENS);
|
||||
private final Event cause;
|
||||
|
||||
private IobCobCalculatorPlugin iobCobCalculatorPlugin;
|
||||
private boolean bgDataReload;
|
||||
private boolean limitDataToOldestAvailable;
|
||||
private String from;
|
||||
private long end;
|
||||
|
||||
private PowerManager.WakeLock mWakeLock;
|
||||
|
||||
public IobCobOref1Thread(IobCobCalculatorPlugin plugin, String from, long end, boolean bgDataReload, boolean limitDataToOldestAvailable, Event cause) {
|
||||
super();
|
||||
|
||||
this.iobCobCalculatorPlugin = plugin;
|
||||
this.bgDataReload = bgDataReload;
|
||||
this.limitDataToOldestAvailable = limitDataToOldestAvailable;
|
||||
this.from = from;
|
||||
this.cause = cause;
|
||||
this.end = end;
|
||||
|
||||
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 {
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("AUTOSENSDATA thread started: " + from);
|
||||
if (MainApp.getConfigBuilder() == null) {
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("Aborting calculation thread (ConfigBuilder not ready): " + from);
|
||||
return; // app still initializing
|
||||
}
|
||||
if (!ProfileFunctions.getInstance().isProfileValid("IobCobThread")) {
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("Aborting calculation thread (No profile): " + from);
|
||||
return; // app still initializing
|
||||
}
|
||||
//log.debug("Locking calculateSensitivityData");
|
||||
|
||||
long oldestTimeWithData = iobCobCalculatorPlugin.calculateDetectionStart(end, limitDataToOldestAvailable);
|
||||
|
||||
synchronized (iobCobCalculatorPlugin.dataLock) {
|
||||
if (bgDataReload) {
|
||||
iobCobCalculatorPlugin.loadBgData(end);
|
||||
iobCobCalculatorPlugin.createBucketedData();
|
||||
}
|
||||
List<BgReading> bucketed_data = iobCobCalculatorPlugin.getBucketedData();
|
||||
LongSparseArray<AutosensData> autosensDataTable = iobCobCalculatorPlugin.getAutosensDataTable();
|
||||
|
||||
if (bucketed_data == null || bucketed_data.size() < 3) {
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("Aborting calculation thread (No bucketed data available): " + from);
|
||||
return;
|
||||
}
|
||||
|
||||
long prevDataTime = IobCobCalculatorPlugin.roundUpTime(bucketed_data.get(bucketed_data.size() - 3).date);
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
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;
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
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 = ProfileFunctions.getInstance().getProfile(bgTime);
|
||||
if (profile == null) {
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("Aborting calculation thread (no profile): " + from);
|
||||
return; // profile not set yet
|
||||
}
|
||||
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
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.getAutosensData(hourago);
|
||||
if (hourAgoData != null) {
|
||||
int initialIndex = autosensDataTable.indexOfKey(hourAgoData.time);
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
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.isEnabled(L.AUTOSENS))
|
||||
// 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 (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("Running detectSensitivity from: " + DateUtil.dateAndTimeString(oldestTimeWithData) + " to: " + DateUtil.dateAndTimeString(bgTime) + " lastDataTime:" + iobCobCalculatorPlugin.lastDataTime());
|
||||
AutosensResult sensitivity = iobCobCalculatorPlugin.detectSensitivityWithLock(oldestTimeWithData, bgTime);
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("Sensitivity result: " + sensitivity.toString());
|
||||
autosensData.autosensResult = sensitivity;
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug(autosensData.toString());
|
||||
}
|
||||
}
|
||||
new Thread(() -> {
|
||||
SystemClock.sleep(1000);
|
||||
MainApp.bus().post(new EventAutosensCalculationFinished(cause));
|
||||
}).start();
|
||||
} finally {
|
||||
mWakeLock.release();
|
||||
MainApp.bus().post(new EventIobCalculationProgress(""));
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("AUTOSENSDATA thread ended: " + from);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -2,6 +2,7 @@ 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;
|
||||
|
@ -14,7 +15,6 @@ import java.util.Date;
|
|||
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;
|
||||
|
@ -23,11 +23,13 @@ import info.nightscout.androidaps.data.Profile;
|
|||
import info.nightscout.androidaps.db.BgReading;
|
||||
import info.nightscout.androidaps.events.Event;
|
||||
import info.nightscout.androidaps.interfaces.PluginType;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions;
|
||||
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.SensitivityAAPS.SensitivityAAPSPlugin;
|
||||
import info.nightscout.androidaps.plugins.SensitivityWeightedAverage.SensitivityWeightedAveragePlugin;
|
||||
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityAAPSPlugin;
|
||||
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityWeightedAveragePlugin;
|
||||
import info.nightscout.androidaps.plugins.Treatments.Treatment;
|
||||
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||
import info.nightscout.utils.DateUtil;
|
||||
|
@ -41,24 +43,26 @@ import static info.nightscout.utils.DateUtil.now;
|
|||
*/
|
||||
|
||||
public class IobCobThread extends Thread {
|
||||
private static Logger log = LoggerFactory.getLogger(IobCobThread.class);
|
||||
private static Logger log = LoggerFactory.getLogger(L.AUTOSENS);
|
||||
private final Event cause;
|
||||
|
||||
private IobCobCalculatorPlugin iobCobCalculatorPlugin;
|
||||
private boolean bgDataReload;
|
||||
private boolean limitDataToOldestAvailable;
|
||||
private String from;
|
||||
private long start;
|
||||
private long end;
|
||||
|
||||
private PowerManager.WakeLock mWakeLock;
|
||||
|
||||
public IobCobThread(IobCobCalculatorPlugin plugin, String from, long start, boolean bgDataReload, Event cause) {
|
||||
public IobCobThread(IobCobCalculatorPlugin plugin, String from, long end, boolean bgDataReload, boolean limitDataToOldestAvailable, Event cause) {
|
||||
super();
|
||||
|
||||
this.iobCobCalculatorPlugin = plugin;
|
||||
this.bgDataReload = bgDataReload;
|
||||
this.limitDataToOldestAvailable = limitDataToOldestAvailable;
|
||||
this.from = from;
|
||||
this.cause = cause;
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
|
||||
PowerManager powerManager = (PowerManager) MainApp.instance().getApplicationContext().getSystemService(Context.POWER_SERVICE);
|
||||
mWakeLock = powerManager.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "iobCobThread");
|
||||
|
@ -68,33 +72,39 @@ public class IobCobThread extends Thread {
|
|||
public final void run() {
|
||||
mWakeLock.acquire();
|
||||
try {
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("AUTOSENSDATA thread started: " + from);
|
||||
if (MainApp.getConfigBuilder() == null) {
|
||||
log.debug("Aborting calculation thread (ConfigBuilder not ready): " + from);
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
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);
|
||||
if (!ProfileFunctions.getInstance().isProfileValid("IobCobThread")) {
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("Aborting calculation thread (No profile): " + from);
|
||||
return; // app still initializing
|
||||
}
|
||||
//log.debug("Locking calculateSensitivityData");
|
||||
|
||||
long oldestTimeWithData = iobCobCalculatorPlugin.oldestDataAvailable();
|
||||
long oldestTimeWithData = iobCobCalculatorPlugin.calculateDetectionStart(end, limitDataToOldestAvailable);
|
||||
|
||||
synchronized (iobCobCalculatorPlugin.dataLock) {
|
||||
if (bgDataReload) {
|
||||
iobCobCalculatorPlugin.loadBgData(start);
|
||||
iobCobCalculatorPlugin.loadBgData(end);
|
||||
iobCobCalculatorPlugin.createBucketedData();
|
||||
}
|
||||
List<BgReading> bucketed_data = iobCobCalculatorPlugin.getBucketedData();
|
||||
LongSparseArray<AutosensData> autosensDataTable = IobCobCalculatorPlugin.getPlugin().getAutosensDataTable();
|
||||
LongSparseArray<AutosensData> autosensDataTable = iobCobCalculatorPlugin.getAutosensDataTable();
|
||||
|
||||
if (bucketed_data == null || bucketed_data.size() < 3) {
|
||||
log.debug("Aborting calculation thread (No bucketed data available): " + from);
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
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());
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
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--) {
|
||||
|
@ -103,7 +113,8 @@ public class IobCobThread extends Thread {
|
|||
|
||||
if (iobCobCalculatorPlugin.stopCalculationTrigger) {
|
||||
iobCobCalculatorPlugin.stopCalculationTrigger = false;
|
||||
log.debug("Aborting calculation thread (trigger): " + from);
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("Aborting calculation thread (trigger): " + from);
|
||||
return;
|
||||
}
|
||||
// check if data already exists
|
||||
|
@ -118,13 +129,14 @@ public class IobCobThread extends Thread {
|
|||
continue;
|
||||
}
|
||||
|
||||
Profile profile = MainApp.getConfigBuilder().getProfile(bgTime);
|
||||
Profile profile = ProfileFunctions.getInstance().getProfile(bgTime);
|
||||
if (profile == null) {
|
||||
log.debug("Aborting calculation thread (no profile): " + from);
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("Aborting calculation thread (no profile): " + from);
|
||||
return; // profile not set yet
|
||||
}
|
||||
|
||||
if (Config.logAutosensData)
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("Processing calculation thread: " + from + " (" + i + "/" + bucketed_data.size() + ")");
|
||||
|
||||
double sens = Profile.toMgdl(profile.getIsf(bgTime), profile.getUnits());
|
||||
|
@ -145,6 +157,7 @@ public class IobCobThread extends Thread {
|
|||
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;
|
||||
|
||||
|
@ -162,10 +175,10 @@ public class IobCobThread extends Thread {
|
|||
// 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);
|
||||
AutosensData hourAgoData = iobCobCalculatorPlugin.getAutosensData(hourago);
|
||||
if (hourAgoData != null) {
|
||||
int initialIndex = autosensDataTable.indexOfKey(hourAgoData.time);
|
||||
if (Config.logAutosensData)
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug(">>>>> bucketed_data.size()=" + bucketed_data.size() + " i=" + i + "hourAgoData=" + hourAgoData.toString());
|
||||
int past = 1;
|
||||
try {
|
||||
|
@ -181,7 +194,7 @@ public class IobCobThread extends Thread {
|
|||
minDeviation = ad.avgDeviation;
|
||||
}
|
||||
|
||||
//if (Config.logAutosensData)
|
||||
//if (Config.isEnabled(L.AUTOSENS))
|
||||
// log.debug("Deviations: " + new Date(bgTime) + new Date(ad.time) + " avgDeviation=" + avgDeviation + " deviationSlope=" + deviationSlope + " slopeFromMaxDeviation=" + slopeFromMaxDeviation + " slopeFromMinDeviation=" + slopeFromMinDeviation);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
@ -245,35 +258,42 @@ public class IobCobThread extends Thread {
|
|||
// calculate autosens only without COB
|
||||
if (autosensData.cob <= 0) {
|
||||
if (Math.abs(deviation) < Constants.DEVIATION_TO_BE_EQUAL) {
|
||||
autosensData.pastSensitivity += "=";
|
||||
autosensData.nonEqualDeviation = true;
|
||||
autosensData.pastSensitivity = "=";
|
||||
autosensData.validDeviation = true;
|
||||
} else if (deviation > 0) {
|
||||
autosensData.pastSensitivity += "+";
|
||||
autosensData.nonEqualDeviation = true;
|
||||
autosensData.pastSensitivity = "+";
|
||||
autosensData.validDeviation = true;
|
||||
} else {
|
||||
autosensData.pastSensitivity += "-";
|
||||
autosensData.nonEqualDeviation = true;
|
||||
autosensData.pastSensitivity = "-";
|
||||
autosensData.validDeviation = true;
|
||||
}
|
||||
autosensData.nonCarbsDeviation = true;
|
||||
} 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);
|
||||
|
||||
previous = autosensData;
|
||||
autosensDataTable.put(bgTime, autosensData);
|
||||
if (Config.logAutosensData)
|
||||
log.debug("Running detectSensitivity from: " + DateUtil.dateAndTimeString(oldestTimeWithData) + " to: " + DateUtil.dateAndTimeString(bgTime));
|
||||
autosensData.autosensRatio = iobCobCalculatorPlugin.detectSensitivity(oldestTimeWithData, bgTime).ratio;
|
||||
if (Config.logAutosensData)
|
||||
if (bgTime < now())
|
||||
autosensDataTable.put(bgTime, autosensData);
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("Running detectSensitivity from: " + DateUtil.dateAndTimeString(oldestTimeWithData) + " to: " + DateUtil.dateAndTimeString(bgTime) + " lastDataTime:" + iobCobCalculatorPlugin.lastDataTime());
|
||||
AutosensResult sensitivity = iobCobCalculatorPlugin.detectSensitivityWithLock(oldestTimeWithData, bgTime);
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("Sensitivity result: " + sensitivity.toString());
|
||||
autosensData.autosensResult = sensitivity;
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug(autosensData.toString());
|
||||
}
|
||||
}
|
||||
MainApp.bus().post(new EventAutosensCalculationFinished(cause));
|
||||
log.debug("Finishing calculation thread: " + from);
|
||||
new Thread(() -> {
|
||||
SystemClock.sleep(1000);
|
||||
MainApp.bus().post(new EventAutosensCalculationFinished(cause));
|
||||
}).start();
|
||||
} finally {
|
||||
mWakeLock.release();
|
||||
MainApp.bus().post(new EventIobCalculationProgress(""));
|
||||
if (L.isEnabled(L.AUTOSENS))
|
||||
log.debug("AUTOSENSDATA thread ended: " + from);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
|
@ -19,6 +18,7 @@ import info.nightscout.androidaps.data.IobTotal;
|
|||
import info.nightscout.androidaps.db.BgReading;
|
||||
import info.nightscout.androidaps.interfaces.Constraint;
|
||||
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.utils.DecimalFormatter;
|
||||
|
||||
|
@ -26,9 +26,9 @@ import info.nightscout.utils.DecimalFormatter;
|
|||
* Created by mike on 09.06.2016.
|
||||
*/
|
||||
public class APSResult {
|
||||
private static Logger log = LoggerFactory.getLogger(APSResult.class);
|
||||
private static Logger log = LoggerFactory.getLogger(L.APS);
|
||||
|
||||
public Date date;
|
||||
public long date = 0;
|
||||
public String reason;
|
||||
public double rate;
|
||||
public int duration;
|
||||
|
@ -133,8 +133,8 @@ public class APSResult {
|
|||
public List<BgReading> getPredictions() {
|
||||
List<BgReading> array = new ArrayList<>();
|
||||
try {
|
||||
long startTime = date.getTime();
|
||||
if (json.has("predBGs")) {
|
||||
long startTime = date;
|
||||
if (json != null && json.has("predBGs")) {
|
||||
JSONObject predBGs = json.getJSONObject("predBGs");
|
||||
if (predBGs.has("IOB")) {
|
||||
JSONArray iob = predBGs.getJSONArray("IOB");
|
||||
|
@ -196,8 +196,8 @@ public class APSResult {
|
|||
public long getLatestPredictionsTime() {
|
||||
long latest = 0;
|
||||
try {
|
||||
long startTime = date != null ? date.getTime() : 0;
|
||||
if (json.has("predBGs")) {
|
||||
long startTime = date;
|
||||
if (json != null && json.has("predBGs")) {
|
||||
JSONObject predBGs = json.getJSONObject("predBGs");
|
||||
if (predBGs.has("IOB")) {
|
||||
JSONArray iob = predBGs.getJSONArray("IOB");
|
||||
|
|
|
@ -1,17 +1,11 @@
|
|||
package info.nightscout.androidaps.plugins.Loop;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.Services.Intents;
|
||||
import info.nightscout.androidaps.plugins.NSClientInternal.data.DbLogger;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
|
||||
/*
|
||||
{
|
||||
|
@ -371,7 +365,7 @@ import info.nightscout.androidaps.plugins.NSClientInternal.data.DbLogger;
|
|||
*/
|
||||
|
||||
public class DeviceStatus {
|
||||
private static Logger log = LoggerFactory.getLogger(DeviceStatus.class);
|
||||
private static Logger log = LoggerFactory.getLogger(L.APS);
|
||||
|
||||
public String device = null;
|
||||
public JSONObject pump = null;
|
||||
|
@ -381,12 +375,12 @@ public class DeviceStatus {
|
|||
public int uploaderBattery = 0;
|
||||
public String created_at = null;
|
||||
|
||||
public JSONObject mongoRecord () {
|
||||
public JSONObject mongoRecord() {
|
||||
JSONObject record = new JSONObject();
|
||||
|
||||
try {
|
||||
if (device != null) record.put("device" , device);
|
||||
if (pump != null) record.put("pump" , pump);
|
||||
if (device != null) record.put("device", device);
|
||||
if (pump != null) record.put("pump", pump);
|
||||
if (suggested != null) {
|
||||
JSONObject openaps = new JSONObject();
|
||||
if (enacted != null) openaps.put("enacted", enacted);
|
||||
|
@ -395,7 +389,7 @@ public class DeviceStatus {
|
|||
record.put("openaps", openaps);
|
||||
}
|
||||
if (uploaderBattery != 0) record.put("uploaderBattery", uploaderBattery);
|
||||
if (created_at != null) record.put("created_at" , created_at);
|
||||
if (created_at != null) record.put("created_at", created_at);
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
|
|
|
@ -28,8 +28,6 @@ import info.nightscout.androidaps.plugins.Loop.events.EventLoopUpdateGui;
|
|||
import info.nightscout.utils.FabricPrivacy;
|
||||
|
||||
public class LoopFragment extends SubscriberFragment {
|
||||
private static Logger log = LoggerFactory.getLogger(LoopFragment.class);
|
||||
|
||||
@BindView(R.id.loop_run)
|
||||
Button runNowButton;
|
||||
@BindView(R.id.loop_lastrun)
|
||||
|
@ -80,7 +78,7 @@ public class LoopFragment extends SubscriberFragment {
|
|||
clearGUI();
|
||||
final Activity activity = getActivity();
|
||||
if (activity != null)
|
||||
activity.runOnUiThread(() -> lastRunView.setText(ev.text));
|
||||
activity.runOnUiThread(() -> { synchronized (LoopFragment.this) { if (lastRunView != null) lastRunView.setText(ev.text); } });
|
||||
}
|
||||
|
||||
|
||||
|
@ -89,26 +87,29 @@ public class LoopFragment extends SubscriberFragment {
|
|||
Activity activity = getActivity();
|
||||
if (activity != null)
|
||||
activity.runOnUiThread(() -> {
|
||||
LoopPlugin.LastRun lastRun = LoopPlugin.lastRun;
|
||||
if (lastRun != null) {
|
||||
requestView.setText(lastRun.request != null ? lastRun.request.toSpanned() : "");
|
||||
constraintsProcessedView.setText(lastRun.constraintsProcessed != null ? lastRun.constraintsProcessed.toSpanned() : "");
|
||||
sourceView.setText(lastRun.source != null ? lastRun.source : "");
|
||||
lastRunView.setText(lastRun.lastAPSRun != null && lastRun.lastAPSRun.getTime() != 0 ? lastRun.lastAPSRun.toLocaleString() : "");
|
||||
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()) : "");
|
||||
synchronized (LoopFragment.this) {
|
||||
if (!isBound()) return;
|
||||
LoopPlugin.LastRun lastRun = LoopPlugin.lastRun;
|
||||
if (lastRun != null) {
|
||||
requestView.setText(lastRun.request != null ? lastRun.request.toSpanned() : "");
|
||||
constraintsProcessedView.setText(lastRun.constraintsProcessed != null ? lastRun.constraintsProcessed.toSpanned() : "");
|
||||
sourceView.setText(lastRun.source != null ? lastRun.source : "");
|
||||
lastRunView.setText(lastRun.lastAPSRun != null && lastRun.lastAPSRun.getTime() != 0 ? lastRun.lastAPSRun.toLocaleString() : "");
|
||||
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 = "";
|
||||
if (lastRun.constraintsProcessed != null) {
|
||||
Constraint<Double> allConstraints = new Constraint<>(0d);
|
||||
if (lastRun.constraintsProcessed.rateConstraint != null)
|
||||
allConstraints.copyReasons(lastRun.constraintsProcessed.rateConstraint);
|
||||
if (lastRun.constraintsProcessed.smbConstraint != null)
|
||||
allConstraints.copyReasons(lastRun.constraintsProcessed.smbConstraint);
|
||||
constraints = allConstraints.getMostLimitedReasons();
|
||||
String constraints = "";
|
||||
if (lastRun.constraintsProcessed != null) {
|
||||
Constraint<Double> allConstraints = new Constraint<>(0d);
|
||||
if (lastRun.constraintsProcessed.rateConstraint != null)
|
||||
allConstraints.copyReasons(lastRun.constraintsProcessed.rateConstraint);
|
||||
if (lastRun.constraintsProcessed.smbConstraint != null)
|
||||
allConstraints.copyReasons(lastRun.constraintsProcessed.smbConstraint);
|
||||
constraints = allConstraints.getMostLimitedReasons();
|
||||
}
|
||||
constraintsView.setText(constraints);
|
||||
}
|
||||
constraintsView.setText(constraints);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -117,13 +118,29 @@ public class LoopFragment extends SubscriberFragment {
|
|||
Activity activity = getActivity();
|
||||
if (activity != null)
|
||||
activity.runOnUiThread(() -> {
|
||||
requestView.setText("");
|
||||
constraintsProcessedView.setText("");
|
||||
sourceView.setText("");
|
||||
lastRunView.setText("");
|
||||
lastEnactView.setText("");
|
||||
tbrSetByPumpView.setText("");
|
||||
smbSetByPumpView.setText("");
|
||||
synchronized (LoopFragment.this) {
|
||||
if (isBound()) {
|
||||
requestView.setText("");
|
||||
constraintsProcessedView.setText("");
|
||||
sourceView.setText("");
|
||||
lastRunView.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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,46 +21,56 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
import java.util.Date;
|
||||
|
||||
import info.nightscout.androidaps.Config;
|
||||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.MainActivity;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.DetailedBolusInfo;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.data.PumpEnactResult;
|
||||
import info.nightscout.androidaps.db.BgReading;
|
||||
import info.nightscout.androidaps.db.CareportalEvent;
|
||||
import info.nightscout.androidaps.db.DatabaseHelper;
|
||||
import info.nightscout.androidaps.db.Source;
|
||||
import info.nightscout.androidaps.db.TemporaryBasal;
|
||||
import info.nightscout.androidaps.events.Event;
|
||||
import info.nightscout.androidaps.events.EventNewBG;
|
||||
import info.nightscout.androidaps.events.EventTreatmentChange;
|
||||
import info.nightscout.androidaps.interfaces.APSInterface;
|
||||
import info.nightscout.androidaps.interfaces.Constraint;
|
||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
import info.nightscout.androidaps.interfaces.PluginDescription;
|
||||
import info.nightscout.androidaps.interfaces.PluginType;
|
||||
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||
import info.nightscout.androidaps.interfaces.TreatmentsInterface;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions;
|
||||
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished;
|
||||
import info.nightscout.androidaps.plugins.Loop.events.EventLoopSetLastRunGui;
|
||||
import info.nightscout.androidaps.plugins.Loop.events.EventLoopUpdateGui;
|
||||
import info.nightscout.androidaps.plugins.Loop.events.EventNewOpenLoopNotification;
|
||||
import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload;
|
||||
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||
import info.nightscout.androidaps.plugins.Wear.ActionStringHandler;
|
||||
import info.nightscout.androidaps.events.EventAcceptOpenLoopChange;
|
||||
import info.nightscout.androidaps.queue.Callback;
|
||||
import info.nightscout.androidaps.queue.commands.Command;
|
||||
import info.nightscout.utils.FabricPrivacy;
|
||||
import info.nightscout.utils.NSUpload;
|
||||
import info.nightscout.utils.SP;
|
||||
import info.nightscout.utils.ToastUtils;
|
||||
|
||||
/**
|
||||
* Created by mike on 05.08.2016.
|
||||
*/
|
||||
public class LoopPlugin extends PluginBase {
|
||||
private static Logger log = LoggerFactory.getLogger(LoopPlugin.class);
|
||||
private static Logger log = LoggerFactory.getLogger(L.APS);
|
||||
|
||||
public static final String CHANNEL_ID = "AndroidAPS-Openloop";
|
||||
private static final String CHANNEL_ID = "AndroidAPS-Openloop";
|
||||
|
||||
long lastBgTriggeredRun = 0;
|
||||
private long lastBgTriggeredRun = 0;
|
||||
|
||||
protected static LoopPlugin loopPlugin;
|
||||
private static LoopPlugin loopPlugin;
|
||||
|
||||
@NonNull
|
||||
public static LoopPlugin getPlugin() {
|
||||
|
@ -94,6 +104,7 @@ public class LoopPlugin extends PluginBase {
|
|||
.pluginName(R.string.loop)
|
||||
.shortName(R.string.loop_shortname)
|
||||
.preferencesId(R.xml.pref_closedmode)
|
||||
.description(R.string.description_loop)
|
||||
);
|
||||
loopSuspendedTill = SP.getLong("loopSuspendedTill", 0L);
|
||||
isSuperBolus = SP.getBoolean("isSuperBolus", false);
|
||||
|
@ -136,9 +147,9 @@ public class LoopPlugin extends PluginBase {
|
|||
* has current data to work with. However, autosens calculation can be triggered by multiple
|
||||
* sources and currently only a new BG should trigger a loop run. Hence we return early if
|
||||
* the event causing the calculation is not EventNewBg.
|
||||
*
|
||||
* Callers of {@link info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin#runCalculation(String, long, boolean, Event)}
|
||||
* are sources triggering a calculation which triggers this method upon completion.
|
||||
* <p>
|
||||
* Callers of {@link info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin#runCalculation(String, long, boolean, Event)}
|
||||
* are sources triggering a calculation which triggers this method upon completion.
|
||||
*/
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventAutosensCalculationFinished ev) {
|
||||
|
@ -247,19 +258,20 @@ public class LoopPlugin extends PluginBase {
|
|||
return isDisconnected;
|
||||
}
|
||||
|
||||
public synchronized void invoke(String initiator, boolean allowNotification){
|
||||
public synchronized void invoke(String initiator, boolean allowNotification) {
|
||||
invoke(initiator, allowNotification, false);
|
||||
}
|
||||
|
||||
public synchronized void invoke(String initiator, boolean allowNotification, boolean tempBasalFallback) {
|
||||
try {
|
||||
if (Config.logFunctionCalls)
|
||||
if (L.isEnabled(L.APS))
|
||||
log.debug("invoke from " + initiator);
|
||||
Constraint<Boolean> loopEnabled = MainApp.getConstraintChecker().isLoopInvokationAllowed();
|
||||
|
||||
if (!loopEnabled.value()) {
|
||||
String message = MainApp.gs(R.string.loopdisabled) + "\n" + loopEnabled.getReasons();
|
||||
log.debug(message);
|
||||
if (L.isEnabled(L.APS))
|
||||
log.debug(message);
|
||||
MainApp.bus().post(new EventLoopSetLastRunGui(message));
|
||||
return;
|
||||
}
|
||||
|
@ -269,10 +281,11 @@ public class LoopPlugin extends PluginBase {
|
|||
if (!isEnabled(PluginType.LOOP))
|
||||
return;
|
||||
|
||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||
|
||||
if (!MainApp.getConfigBuilder().isProfileValid("Loop")) {
|
||||
log.debug(MainApp.gs(R.string.noprofileselected));
|
||||
if (!ProfileFunctions.getInstance().isProfileValid("Loop")) {
|
||||
if (L.isEnabled(L.APS))
|
||||
log.debug(MainApp.gs(R.string.noprofileselected));
|
||||
MainApp.bus().post(new EventLoopSetLastRunGui(MainApp.gs(R.string.noprofileselected)));
|
||||
return;
|
||||
}
|
||||
|
@ -302,7 +315,8 @@ public class LoopPlugin extends PluginBase {
|
|||
// safety check for multiple SMBs
|
||||
long lastBolusTime = TreatmentsPlugin.getPlugin().getLastBolusTime();
|
||||
if (lastBolusTime != 0 && lastBolusTime + 3 * 60 * 1000 > System.currentTimeMillis()) {
|
||||
log.debug("SMB requsted but still in 3 min interval");
|
||||
if (L.isEnabled(L.APS))
|
||||
log.debug("SMB requsted but still in 3 min interval");
|
||||
resultAfterConstraints.smb = 0;
|
||||
}
|
||||
|
||||
|
@ -317,13 +331,15 @@ public class LoopPlugin extends PluginBase {
|
|||
NSUpload.uploadDeviceStatus();
|
||||
|
||||
if (isSuspended()) {
|
||||
log.debug(MainApp.gs(R.string.loopsuspended));
|
||||
if (L.isEnabled(L.APS))
|
||||
log.debug(MainApp.gs(R.string.loopsuspended));
|
||||
MainApp.bus().post(new EventLoopSetLastRunGui(MainApp.gs(R.string.loopsuspended)));
|
||||
return;
|
||||
}
|
||||
|
||||
if (pump.isSuspended()) {
|
||||
log.debug(MainApp.gs(R.string.pumpsuspended));
|
||||
if (L.isEnabled(L.APS))
|
||||
log.debug(MainApp.gs(R.string.pumpsuspended));
|
||||
MainApp.bus().post(new EventLoopSetLastRunGui(MainApp.gs(R.string.pumpsuspended)));
|
||||
return;
|
||||
}
|
||||
|
@ -331,7 +347,9 @@ public class LoopPlugin extends PluginBase {
|
|||
Constraint<Boolean> closedLoopEnabled = MainApp.getConstraintChecker().isClosedLoopAllowed();
|
||||
|
||||
if (closedLoopEnabled.value()) {
|
||||
if (result.isChangeRequested()) {
|
||||
if (result.isChangeRequested()
|
||||
&& !ConfigBuilderPlugin.getCommandQueue().bolusInQueue()
|
||||
&& !ConfigBuilderPlugin.getCommandQueue().isRunning(Command.CommandType.BOLUS)) {
|
||||
final PumpEnactResult waiting = new PumpEnactResult();
|
||||
waiting.queued = true;
|
||||
if (resultAfterConstraints.tempBasalRequested)
|
||||
|
@ -340,13 +358,13 @@ public class LoopPlugin extends PluginBase {
|
|||
lastRun.smbSetByPump = waiting;
|
||||
MainApp.bus().post(new EventLoopUpdateGui());
|
||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("APSRequest"));
|
||||
MainApp.getConfigBuilder().applyTBRRequest(resultAfterConstraints, profile, new Callback() {
|
||||
applyTBRRequest(resultAfterConstraints, profile, new Callback() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (result.enacted || result.success) {
|
||||
lastRun.tbrSetByPump = result;
|
||||
lastRun.lastEnact = lastRun.lastAPSRun;
|
||||
MainApp.getConfigBuilder().applySMBRequest(resultAfterConstraints, new Callback() {
|
||||
applySMBRequest(resultAfterConstraints, new Callback() {
|
||||
@Override
|
||||
public void run() {
|
||||
//Callback is only called if a bolus was acutally requested
|
||||
|
@ -381,7 +399,8 @@ public class LoopPlugin extends PluginBase {
|
|||
.setAutoCancel(true)
|
||||
.setPriority(Notification.PRIORITY_HIGH)
|
||||
.setCategory(Notification.CATEGORY_ALARM)
|
||||
.setVisibility(Notification.VISIBILITY_PUBLIC);
|
||||
.setVisibility(Notification.VISIBILITY_PUBLIC)
|
||||
.setLocalOnly(true);
|
||||
|
||||
// Creates an explicit intent for an Activity in your app
|
||||
Intent resultIntent = new Intent(MainApp.instance().getApplicationContext(), MainActivity.class);
|
||||
|
@ -403,14 +422,210 @@ public class LoopPlugin extends PluginBase {
|
|||
// mId allows you to update the notification later on.
|
||||
mNotificationManager.notify(Constants.notificationID, builder.build());
|
||||
MainApp.bus().post(new EventNewOpenLoopNotification());
|
||||
|
||||
// Send to Wear
|
||||
ActionStringHandler.handleInitiate("changeRequest");
|
||||
} else if (allowNotification) {
|
||||
// dismiss notifications
|
||||
NotificationManager notificationManager =
|
||||
(NotificationManager) MainApp.instance().getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
notificationManager.cancel(Constants.notificationID);
|
||||
ActionStringHandler.handleInitiate("cancelChangeRequest");
|
||||
}
|
||||
}
|
||||
|
||||
MainApp.bus().post(new EventLoopUpdateGui());
|
||||
} finally {
|
||||
if (Config.logFunctionCalls)
|
||||
if (L.isEnabled(L.APS))
|
||||
log.debug("invoke end");
|
||||
}
|
||||
}
|
||||
|
||||
public void acceptChangeRequest() {
|
||||
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||
|
||||
applyTBRRequest(lastRun.constraintsProcessed, profile, new Callback() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (result.enacted) {
|
||||
lastRun.tbrSetByPump = result;
|
||||
lastRun.lastEnact = new Date();
|
||||
lastRun.lastOpenModeAccept = new Date();
|
||||
NSUpload.uploadDeviceStatus();
|
||||
ObjectivesPlugin objectivesPlugin = MainApp.getSpecificPlugin(ObjectivesPlugin.class);
|
||||
if (objectivesPlugin != null) {
|
||||
ObjectivesPlugin.manualEnacts++;
|
||||
ObjectivesPlugin.saveProgress();
|
||||
}
|
||||
}
|
||||
MainApp.bus().post(new EventAcceptOpenLoopChange());
|
||||
}
|
||||
});
|
||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("AcceptTemp"));
|
||||
}
|
||||
|
||||
/**
|
||||
* expect absolute request and allow both absolute and percent response based on pump capabilities
|
||||
*/
|
||||
public void applyTBRRequest(APSResult request, Profile profile, Callback callback) {
|
||||
if (!request.tempBasalRequested) {
|
||||
if (callback != null) {
|
||||
callback.result(new PumpEnactResult().enacted(false).success(true).comment(MainApp.gs(R.string.nochangerequested))).run();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
PumpInterface pump = MainApp.getConfigBuilder().getActivePump();
|
||||
TreatmentsInterface activeTreatments = TreatmentsPlugin.getPlugin();
|
||||
|
||||
request.rateConstraint = new Constraint<>(request.rate);
|
||||
request.rate = MainApp.getConstraintChecker().applyBasalConstraints(request.rateConstraint, profile).value();
|
||||
|
||||
if (!pump.isInitialized()) {
|
||||
if (L.isEnabled(L.APS))
|
||||
log.debug("applyAPSRequest: " + MainApp.gs(R.string.pumpNotInitialized));
|
||||
if (callback != null) {
|
||||
callback.result(new PumpEnactResult().comment(MainApp.gs(R.string.pumpNotInitialized)).enacted(false).success(false)).run();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (pump.isSuspended()) {
|
||||
if (L.isEnabled(L.APS))
|
||||
log.debug("applyAPSRequest: " + MainApp.gs(R.string.pumpsuspended));
|
||||
if (callback != null) {
|
||||
callback.result(new PumpEnactResult().comment(MainApp.gs(R.string.pumpsuspended)).enacted(false).success(false)).run();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (L.isEnabled(L.APS))
|
||||
log.debug("applyAPSRequest: " + request.toString());
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
TemporaryBasal activeTemp = activeTreatments.getTempBasalFromHistory(now);
|
||||
if ((request.rate == 0 && request.duration == 0) || Math.abs(request.rate - pump.getBaseBasalRate()) < pump.getPumpDescription().basalStep) {
|
||||
if (activeTemp != null) {
|
||||
if (L.isEnabled(L.APS))
|
||||
log.debug("applyAPSRequest: cancelTempBasal()");
|
||||
MainApp.getConfigBuilder().getCommandQueue().cancelTempBasal(false, callback);
|
||||
} else {
|
||||
if (L.isEnabled(L.APS))
|
||||
log.debug("applyAPSRequest: Basal set correctly");
|
||||
if (callback != null) {
|
||||
callback.result(new PumpEnactResult().absolute(request.rate).duration(0)
|
||||
.enacted(false).success(true).comment(MainApp.gs(R.string.basal_set_correctly))).run();
|
||||
}
|
||||
}
|
||||
} else if (activeTemp != null
|
||||
&& activeTemp.getPlannedRemainingMinutes() > 5
|
||||
&& request.duration - activeTemp.getPlannedRemainingMinutes() < 30
|
||||
&& Math.abs(request.rate - activeTemp.tempBasalConvertedToAbsolute(now, profile)) < pump.getPumpDescription().basalStep) {
|
||||
if (L.isEnabled(L.APS))
|
||||
log.debug("applyAPSRequest: Temp basal set correctly");
|
||||
if (callback != null) {
|
||||
callback.result(new PumpEnactResult().absolute(activeTemp.tempBasalConvertedToAbsolute(now, profile))
|
||||
.enacted(false).success(true).duration(activeTemp.getPlannedRemainingMinutes())
|
||||
.comment(MainApp.gs(R.string.let_temp_basal_run))).run();
|
||||
}
|
||||
} else {
|
||||
if (L.isEnabled(L.APS))
|
||||
log.debug("applyAPSRequest: setTempBasalAbsolute()");
|
||||
MainApp.getConfigBuilder().getCommandQueue().tempBasalAbsolute(request.rate, request.duration, false, profile, callback);
|
||||
}
|
||||
}
|
||||
|
||||
public void applySMBRequest(APSResult request, Callback callback) {
|
||||
if (!request.bolusRequested) {
|
||||
return;
|
||||
}
|
||||
|
||||
PumpInterface pump = MainApp.getConfigBuilder().getActivePump();
|
||||
TreatmentsInterface activeTreatments = TreatmentsPlugin.getPlugin();
|
||||
|
||||
long lastBolusTime = activeTreatments.getLastBolusTime();
|
||||
if (lastBolusTime != 0 && lastBolusTime + 3 * 60 * 1000 > System.currentTimeMillis()) {
|
||||
if (L.isEnabled(L.APS))
|
||||
log.debug("SMB requested but still in 3 min interval");
|
||||
if (callback != null) {
|
||||
callback.result(new PumpEnactResult()
|
||||
.comment(MainApp.gs(R.string.smb_frequency_exceeded))
|
||||
.enacted(false).success(false)).run();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pump.isInitialized()) {
|
||||
if (L.isEnabled(L.APS))
|
||||
log.debug("applySMBRequest: " + MainApp.gs(R.string.pumpNotInitialized));
|
||||
if (callback != null) {
|
||||
callback.result(new PumpEnactResult().comment(MainApp.gs(R.string.pumpNotInitialized)).enacted(false).success(false)).run();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (pump.isSuspended()) {
|
||||
if (L.isEnabled(L.APS))
|
||||
log.debug("applySMBRequest: " + MainApp.gs(R.string.pumpsuspended));
|
||||
if (callback != null) {
|
||||
callback.result(new PumpEnactResult().comment(MainApp.gs(R.string.pumpsuspended)).enacted(false).success(false)).run();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (L.isEnabled(L.APS))
|
||||
log.debug("applySMBRequest: " + request.toString());
|
||||
|
||||
// deliver SMB
|
||||
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
|
||||
detailedBolusInfo.lastKnownBolusTime = activeTreatments.getLastBolusTime();
|
||||
detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS;
|
||||
detailedBolusInfo.insulin = request.smb;
|
||||
detailedBolusInfo.isSMB = true;
|
||||
detailedBolusInfo.source = Source.USER;
|
||||
detailedBolusInfo.deliverAt = request.deliverAt;
|
||||
if (L.isEnabled(L.APS))
|
||||
log.debug("applyAPSRequest: bolus()");
|
||||
MainApp.getConfigBuilder().getCommandQueue().bolus(detailedBolusInfo, callback);
|
||||
}
|
||||
|
||||
public void disconnectPump(int durationInMinutes, Profile profile) {
|
||||
PumpInterface pump = MainApp.getConfigBuilder().getActivePump();
|
||||
TreatmentsInterface activeTreatments = TreatmentsPlugin.getPlugin();
|
||||
|
||||
LoopPlugin.getPlugin().disconnectTo(System.currentTimeMillis() + durationInMinutes * 60 * 1000L);
|
||||
MainApp.getConfigBuilder().getCommandQueue().tempBasalPercent(0, durationInMinutes, true, profile, new Callback() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!result.success) {
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.tempbasaldeliveryerror));
|
||||
}
|
||||
}
|
||||
});
|
||||
if (pump.getPumpDescription().isExtendedBolusCapable && activeTreatments.isInHistoryExtendedBoluslInProgress()) {
|
||||
MainApp.getConfigBuilder().getCommandQueue().cancelExtended(new Callback() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!result.success) {
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.extendedbolusdeliveryerror));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
NSUpload.uploadOpenAPSOffline(durationInMinutes);
|
||||
}
|
||||
|
||||
public void suspendLoop(int durationInMinutes) {
|
||||
LoopPlugin.getPlugin().suspendTo(System.currentTimeMillis() + durationInMinutes * 60 * 1000);
|
||||
MainApp.getConfigBuilder().getCommandQueue().cancelTempBasal(true, new Callback() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!result.success) {
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.tempbasaldeliveryerror));
|
||||
}
|
||||
}
|
||||
});
|
||||
NSUpload.uploadOpenAPSOffline(durationInMinutes);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -34,8 +34,6 @@ import info.nightscout.utils.FabricPrivacy;
|
|||
import info.nightscout.utils.SP;
|
||||
|
||||
public class NSClientFragment extends SubscriberFragment implements View.OnClickListener, CompoundButton.OnCheckedChangeListener {
|
||||
private static Logger log = LoggerFactory.getLogger(NSClientFragment.class);
|
||||
|
||||
private TextView logTextView;
|
||||
private TextView queueTextView;
|
||||
private TextView urlTextView;
|
||||
|
|
|
@ -29,6 +29,7 @@ import info.nightscout.androidaps.events.EventPreferenceChange;
|
|||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
import info.nightscout.androidaps.interfaces.PluginDescription;
|
||||
import info.nightscout.androidaps.interfaces.PluginType;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.NSClientInternal.events.EventNSClientNewLog;
|
||||
import info.nightscout.androidaps.plugins.NSClientInternal.events.EventNSClientStatus;
|
||||
import info.nightscout.androidaps.plugins.NSClientInternal.events.EventNSClientUpdateGUI;
|
||||
|
@ -37,7 +38,7 @@ import info.nightscout.utils.SP;
|
|||
import info.nightscout.utils.ToastUtils;
|
||||
|
||||
public class NSClientPlugin extends PluginBase {
|
||||
private static Logger log = LoggerFactory.getLogger(NSClientPlugin.class);
|
||||
private Logger log = LoggerFactory.getLogger(L.NSCLIENT);
|
||||
|
||||
static NSClientPlugin nsClientPlugin;
|
||||
|
||||
|
@ -53,8 +54,8 @@ public class NSClientPlugin extends PluginBase {
|
|||
private final List<EventNSClientNewLog> listLog = new ArrayList<>();
|
||||
Spanned textLog = Html.fromHtml("");
|
||||
|
||||
public boolean paused = false;
|
||||
boolean autoscroll = true;
|
||||
public boolean paused;
|
||||
boolean autoscroll;
|
||||
|
||||
public String status = "";
|
||||
|
||||
|
@ -69,6 +70,7 @@ public class NSClientPlugin extends PluginBase {
|
|||
.pluginName(R.string.nsclientinternal)
|
||||
.shortName(R.string.nsclientinternal_shortname)
|
||||
.preferencesId(R.xml.pref_nsclientinternal)
|
||||
.description(R.string.description_ns_client)
|
||||
);
|
||||
|
||||
if (Config.NSCLIENT || Config.G5UPLOADER) {
|
||||
|
@ -131,12 +133,14 @@ public class NSClientPlugin extends PluginBase {
|
|||
private ServiceConnection mConnection = new ServiceConnection() {
|
||||
|
||||
public void onServiceDisconnected(ComponentName name) {
|
||||
log.debug("Service is disconnected");
|
||||
if (L.isEnabled(L.NSCLIENT))
|
||||
log.debug("Service is disconnected");
|
||||
nsClientService = null;
|
||||
}
|
||||
|
||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||
log.debug("Service is connected");
|
||||
if (L.isEnabled(L.NSCLIENT))
|
||||
log.debug("Service is connected");
|
||||
NSClientService.LocalBinder mLocalBinder = (NSClientService.LocalBinder) service;
|
||||
if (mLocalBinder != null) // is null when running in roboelectric
|
||||
nsClientService = mLocalBinder.getServiceInstance();
|
||||
|
@ -154,7 +158,8 @@ public class NSClientPlugin extends PluginBase {
|
|||
@Subscribe
|
||||
public void onStatusEvent(final EventNSClientNewLog ev) {
|
||||
addToLog(ev);
|
||||
log.debug(ev.action + " " + ev.logText);
|
||||
if (L.isEnabled(L.NSCLIENT))
|
||||
log.debug(ev.action + " " + ev.logText);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
|
@ -164,30 +169,24 @@ public class NSClientPlugin extends PluginBase {
|
|||
}
|
||||
|
||||
synchronized void clearLog() {
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
synchronized (listLog) {
|
||||
listLog.clear();
|
||||
}
|
||||
MainApp.bus().post(new EventNSClientUpdateGUI());
|
||||
handler.post(() -> {
|
||||
synchronized (listLog) {
|
||||
listLog.clear();
|
||||
}
|
||||
MainApp.bus().post(new EventNSClientUpdateGUI());
|
||||
});
|
||||
}
|
||||
|
||||
private synchronized void addToLog(final EventNSClientNewLog ev) {
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
synchronized (listLog) {
|
||||
listLog.add(ev);
|
||||
// remove the first line if log is too large
|
||||
if (listLog.size() >= Constants.MAX_LOG_LINES) {
|
||||
listLog.remove(0);
|
||||
}
|
||||
handler.post(() -> {
|
||||
synchronized (listLog) {
|
||||
listLog.add(ev);
|
||||
// remove the first line if log is too large
|
||||
if (listLog.size() >= Constants.MAX_LOG_LINES) {
|
||||
listLog.remove(0);
|
||||
}
|
||||
MainApp.bus().post(new EventNSClientUpdateGUI());
|
||||
}
|
||||
MainApp.bus().post(new EventNSClientUpdateGUI());
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package info.nightscout.utils;
|
||||
package info.nightscout.androidaps.plugins.NSClientInternal;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
@ -23,7 +23,9 @@ import java.util.Locale;
|
|||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.Services.Intents;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions;
|
||||
import info.nightscout.androidaps.services.Intents;
|
||||
import info.nightscout.androidaps.data.DetailedBolusInfo;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.db.BgReading;
|
||||
|
@ -37,13 +39,16 @@ import info.nightscout.androidaps.plugins.Loop.APSResult;
|
|||
import info.nightscout.androidaps.plugins.Loop.DeviceStatus;
|
||||
import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
|
||||
import info.nightscout.androidaps.plugins.NSClientInternal.data.DbLogger;
|
||||
import info.nightscout.utils.BatteryLevel;
|
||||
import info.nightscout.utils.DateUtil;
|
||||
import info.nightscout.utils.SP;
|
||||
|
||||
/**
|
||||
* Created by mike on 26.05.2017.
|
||||
*/
|
||||
|
||||
public class NSUpload {
|
||||
private static Logger log = LoggerFactory.getLogger(NSUpload.class);
|
||||
private static Logger log = LoggerFactory.getLogger(L.NSCLIENT);
|
||||
|
||||
public static void uploadTempBasalStartAbsolute(TemporaryBasal temporaryBasal, Double originalExtendedAmount) {
|
||||
try {
|
||||
|
@ -79,7 +84,7 @@ public class NSUpload {
|
|||
if (useAbsolute) {
|
||||
TemporaryBasal t = temporaryBasal.clone();
|
||||
t.isAbsolute = true;
|
||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||
if (profile != null) {
|
||||
t.absoluteRate = profile.getBasal(temporaryBasal.date) * temporaryBasal.percentRate / 100d;
|
||||
uploadTempBasalStartAbsolute(t, null);
|
||||
|
@ -191,8 +196,8 @@ public class NSUpload {
|
|||
}
|
||||
|
||||
public static void uploadDeviceStatus() {
|
||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||
String profileName = MainApp.getConfigBuilder().getProfileName();
|
||||
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||
String profileName = ProfileFunctions.getInstance().getProfileName();
|
||||
|
||||
if (profile == null || profileName == null) {
|
||||
log.error("Profile is null. Skipping upload");
|
||||
|
@ -232,7 +237,8 @@ public class NSUpload {
|
|||
deviceStatus.enacted.put("requested", requested);
|
||||
}
|
||||
} else {
|
||||
log.debug("OpenAPS data too old to upload");
|
||||
if (L.isEnabled(L.NSCLIENT))
|
||||
log.debug("OpenAPS data too old to upload");
|
||||
}
|
||||
deviceStatus.device = "openaps://" + Build.MANUFACTURER + " " + Build.MODEL;
|
||||
JSONObject pumpstatus = ConfigBuilderPlugin.getActivePump().getJSONStatus(profile, profileName);
|
||||
|
@ -289,19 +295,7 @@ public class NSUpload {
|
|||
|
||||
public static void uploadProfileSwitch(ProfileSwitch profileSwitch) {
|
||||
try {
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("eventType", CareportalEvent.PROFILESWITCH);
|
||||
data.put("duration", profileSwitch.durationInMinutes);
|
||||
data.put("profile", profileSwitch.getCustomizedName());
|
||||
data.put("profileJson", profileSwitch.profileJson);
|
||||
data.put("profilePlugin", profileSwitch.profilePlugin);
|
||||
if (profileSwitch.isCPP) {
|
||||
data.put("CircadianPercentageProfile", true);
|
||||
data.put("timeshift", profileSwitch.timeshift);
|
||||
data.put("percentage", profileSwitch.percentage);
|
||||
}
|
||||
data.put("created_at", DateUtil.toISOString(profileSwitch.date));
|
||||
data.put("enteredBy", MainApp.gs(R.string.app_name));
|
||||
JSONObject data = getJson(profileSwitch);
|
||||
uploadCareportalEntryToNS(data);
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
|
@ -310,7 +304,7 @@ public class NSUpload {
|
|||
|
||||
public static void uploadTempTarget(TempTarget tempTarget) {
|
||||
try {
|
||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||
|
||||
if (profile == null) {
|
||||
log.error("Profile is null. Skipping upload");
|
||||
|
@ -334,19 +328,7 @@ public class NSUpload {
|
|||
|
||||
public static void updateProfileSwitch(ProfileSwitch profileSwitch) {
|
||||
try {
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("eventType", CareportalEvent.PROFILESWITCH);
|
||||
data.put("duration", profileSwitch.durationInMinutes);
|
||||
data.put("profile", profileSwitch.getCustomizedName());
|
||||
data.put("profileJson", profileSwitch.profileJson);
|
||||
data.put("profilePlugin", profileSwitch.profilePlugin);
|
||||
if (profileSwitch.isCPP) {
|
||||
data.put("CircadianPercentageProfile", true);
|
||||
data.put("timeshift", profileSwitch.timeshift);
|
||||
data.put("percentage", profileSwitch.percentage);
|
||||
}
|
||||
data.put("created_at", DateUtil.toISOString(profileSwitch.date));
|
||||
data.put("enteredBy", MainApp.gs(R.string.app_name));
|
||||
JSONObject data = getJson(profileSwitch);
|
||||
if (profileSwitch._id != null) {
|
||||
Context context = MainApp.instance().getApplicationContext();
|
||||
Bundle bundle = new Bundle();
|
||||
|
@ -365,6 +347,24 @@ public class NSUpload {
|
|||
}
|
||||
}
|
||||
|
||||
private static JSONObject getJson(ProfileSwitch profileSwitch) throws JSONException {
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("eventType", CareportalEvent.PROFILESWITCH);
|
||||
data.put("duration", profileSwitch.durationInMinutes);
|
||||
data.put("profile", profileSwitch.getCustomizedName());
|
||||
data.put("profileJson", profileSwitch.profileJson);
|
||||
data.put("profilePlugin", profileSwitch.profilePlugin);
|
||||
if (profileSwitch.isCPP) {
|
||||
data.put("CircadianPercentageProfile", true);
|
||||
data.put("timeshift", profileSwitch.timeshift);
|
||||
data.put("percentage", profileSwitch.percentage);
|
||||
}
|
||||
data.put("created_at", DateUtil.toISOString(profileSwitch.date));
|
||||
data.put("enteredBy", MainApp.gs(R.string.app_name));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public static void uploadCareportalEntryToNS(JSONObject data) {
|
||||
try {
|
||||
if (data.has("preBolus") && data.has("carbs")) {
|
||||
|
@ -496,7 +496,7 @@ public class NSUpload {
|
|||
try {
|
||||
data.put("eventType", "Note");
|
||||
data.put("created_at", DateUtil.toISOString(new Date()));
|
||||
data.put("notes", MainApp.gs(R.string.androidaps_start)+" - "+ Build.MANUFACTURER + " "+ Build.MODEL);
|
||||
data.put("notes", MainApp.gs(R.string.androidaps_start) + " - " + Build.MANUFACTURER + " " + Build.MODEL);
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
|
@ -506,7 +506,7 @@ public class NSUpload {
|
|||
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
|
||||
context.sendBroadcast(intent);
|
||||
DbLogger.dbAdd(intent, data.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void uploadEvent(String careportalEvent, long time, @Nullable String notes) {
|
|
@ -122,7 +122,8 @@ class NsClientReceiverDelegate {
|
|||
boolean newAllowedState = true;
|
||||
|
||||
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;
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -16,13 +16,14 @@ import java.sql.SQLException;
|
|||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.db.DatabaseHelper;
|
||||
import info.nightscout.androidaps.db.DbRequest;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.NSClientInternal.services.NSClientService;
|
||||
|
||||
/**
|
||||
* Created by mike on 21.02.2016.
|
||||
*/
|
||||
public class UploadQueue {
|
||||
private static Logger log = LoggerFactory.getLogger(UploadQueue.class);
|
||||
private static Logger log = LoggerFactory.getLogger(L.NSCLIENT);
|
||||
|
||||
public static String status() {
|
||||
return "QUEUE: " + MainApp.getDbHelper().size(DatabaseHelper.DATABASE_DBREQUESTS);
|
||||
|
@ -43,15 +44,13 @@ public class UploadQueue {
|
|||
public static void add(final DbRequest dbr) {
|
||||
startService();
|
||||
if (NSClientService.handler != null) {
|
||||
NSClientService.handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
log.debug("QUEUE adding: " + dbr.data);
|
||||
MainApp.getDbHelper().create(dbr);
|
||||
NSClientPlugin plugin = NSClientPlugin.getPlugin();
|
||||
if (plugin != null) {
|
||||
plugin.resend("newdata");
|
||||
}
|
||||
NSClientService.handler.post(() -> {
|
||||
if (L.isEnabled(L.NSCLIENT))
|
||||
log.debug("Adding to queue: " + dbr.data);
|
||||
MainApp.getDbHelper().create(dbr);
|
||||
NSClientPlugin plugin = NSClientPlugin.getPlugin();
|
||||
if (plugin != null) {
|
||||
plugin.resend("newdata");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -60,13 +59,12 @@ public class UploadQueue {
|
|||
public static void clearQueue() {
|
||||
startService();
|
||||
if (NSClientService.handler != null) {
|
||||
NSClientService.handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
log.debug("QUEUE ClearQueue");
|
||||
MainApp.getDbHelper().deleteAllDbRequests();
|
||||
NSClientService.handler.post(() -> {
|
||||
if (L.isEnabled(L.NSCLIENT))
|
||||
log.debug("ClearQueue");
|
||||
MainApp.getDbHelper().deleteAllDbRequests();
|
||||
if (L.isEnabled(L.NSCLIENT))
|
||||
log.debug(status());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -74,22 +72,20 @@ public class UploadQueue {
|
|||
public static void removeID(final JSONObject record) {
|
||||
startService();
|
||||
if (NSClientService.handler != null) {
|
||||
NSClientService.handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
String id;
|
||||
if (record.has("NSCLIENT_ID")) {
|
||||
id = record.getString("NSCLIENT_ID");
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
if (MainApp.getDbHelper().deleteDbRequest(id) == 1) {
|
||||
log.debug("Removed item from UploadQueue. " + UploadQueue.status());
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
NSClientService.handler.post(() -> {
|
||||
try {
|
||||
String id;
|
||||
if (record.has("NSCLIENT_ID")) {
|
||||
id = record.getString("NSCLIENT_ID");
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
if (MainApp.getDbHelper().deleteDbRequest(id) == 1) {
|
||||
if (L.isEnabled(L.NSCLIENT))
|
||||
log.debug("Removed item from UploadQueue. " + UploadQueue.status());
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -100,18 +96,17 @@ public class UploadQueue {
|
|||
return;
|
||||
startService();
|
||||
if (NSClientService.handler != null) {
|
||||
NSClientService.handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
MainApp.getDbHelper().deleteDbRequestbyMongoId(action, _id);
|
||||
}
|
||||
NSClientService.handler.post(() -> {
|
||||
MainApp.getDbHelper().deleteDbRequestbyMongoId(action, _id);
|
||||
if (L.isEnabled(L.NSCLIENT))
|
||||
log.debug("Removing " + _id + " from UploadQueue. " + UploadQueue.status());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public String textList() {
|
||||
String result = "";
|
||||
CloseableIterator<DbRequest> iterator = null;
|
||||
CloseableIterator<DbRequest> iterator;
|
||||
try {
|
||||
iterator = MainApp.getDbHelper().getDbRequestInterator();
|
||||
try {
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
package info.nightscout.androidaps.plugins.NSClientInternal.acks;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.events.Event;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.NSClientInternal.events.EventNSClientRestart;
|
||||
import io.socket.client.Ack;
|
||||
|
||||
|
@ -15,17 +15,18 @@ import io.socket.client.Ack;
|
|||
* Created by mike on 29.12.2015.
|
||||
*/
|
||||
public class NSAddAck extends Event implements Ack {
|
||||
private static Logger log = LoggerFactory.getLogger(NSAddAck.class);
|
||||
private static Logger log = LoggerFactory.getLogger(L.NSCLIENT);
|
||||
public String _id = null;
|
||||
public String nsClientID = null;
|
||||
public JSONObject json = null;
|
||||
public void call(Object...args) {
|
||||
|
||||
public void call(Object... args) {
|
||||
// Regular response
|
||||
try {
|
||||
JSONArray responsearray = (JSONArray) (args[0]);
|
||||
JSONObject response = null;
|
||||
if (responsearray.length()>0) {
|
||||
response = responsearray.getJSONObject(0);
|
||||
if (responsearray.length() > 0) {
|
||||
response = responsearray.getJSONObject(0);
|
||||
_id = response.getString("_id");
|
||||
json = response;
|
||||
if (response.has("NSCLIENT_ID")) {
|
||||
|
@ -35,6 +36,7 @@ public class NSAddAck extends Event implements Ack {
|
|||
MainApp.bus().post(this);
|
||||
return;
|
||||
} catch (Exception e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
// Check for not authorized
|
||||
try {
|
||||
|
@ -45,7 +47,8 @@ public class NSAddAck extends Event implements Ack {
|
|||
MainApp.bus().post(new EventNSClientRestart());
|
||||
return;
|
||||
}
|
||||
log.debug("DBACCESS " + response.getString("result"));
|
||||
if (L.isEnabled(L.NSCLIENT))
|
||||
log.debug("DBACCESS " + response.getString("result"));
|
||||
}
|
||||
return;
|
||||
} catch (Exception e) {
|
||||
|
|
|
@ -7,15 +7,16 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.events.Event;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import io.socket.client.Ack;
|
||||
|
||||
/**
|
||||
* Created by mike on 21.02.2016.
|
||||
*/
|
||||
public class NSUpdateAck extends Event implements Ack {
|
||||
private static Logger log = LoggerFactory.getLogger(NSUpdateAck.class);
|
||||
private static Logger log = LoggerFactory.getLogger(L.NSCLIENT);
|
||||
public boolean result = false;
|
||||
public String _id = null;
|
||||
public String _id;
|
||||
public String action;
|
||||
public void call(Object...args) {
|
||||
JSONObject response = (JSONObject)args[0];
|
||||
|
@ -29,6 +30,7 @@ public class NSUpdateAck extends Event implements Ack {
|
|||
}
|
||||
MainApp.bus().post(this);
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,18 +2,12 @@ package info.nightscout.androidaps.plugins.NSClientInternal.broadcasts;
|
|||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.Services.Intents;
|
||||
import info.nightscout.androidaps.services.Intents;
|
||||
import info.nightscout.androidaps.plugins.NSClientInternal.data.NSAlarm;
|
||||
import info.nightscout.utils.SP;
|
||||
|
||||
|
@ -22,7 +16,6 @@ import info.nightscout.utils.SP;
|
|||
*/
|
||||
|
||||
public class BroadcastAckAlarm {
|
||||
private static Logger log = LoggerFactory.getLogger(BroadcastAckAlarm.class);
|
||||
|
||||
public static void handleClearAlarm(NSAlarm originalAlarm, Context context, long silenceTimeInMsec) {
|
||||
|
||||
|
|
|
@ -2,27 +2,20 @@ package info.nightscout.androidaps.plugins.NSClientInternal.broadcasts;
|
|||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.Services.Intents;
|
||||
import info.nightscout.androidaps.services.Intents;
|
||||
import info.nightscout.utils.SP;
|
||||
|
||||
/**
|
||||
* Created by mike on 26.06.2016.
|
||||
*/
|
||||
public class BroadcastAlarm {
|
||||
private static Logger log = LoggerFactory.getLogger(BroadcastAlarm.class);
|
||||
|
||||
public static void handleAlarm(JSONObject alarm, Context context) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString("data", alarm.toString());
|
||||
|
|
|
@ -2,28 +2,20 @@ package info.nightscout.androidaps.plugins.NSClientInternal.broadcasts;
|
|||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.Services.Intents;
|
||||
import info.nightscout.androidaps.services.Intents;
|
||||
import info.nightscout.utils.SP;
|
||||
|
||||
/**
|
||||
* Created by mike on 26.06.2016.
|
||||
*/
|
||||
public class BroadcastAnnouncement {
|
||||
private static Logger log = LoggerFactory.getLogger(BroadcastAnnouncement.class);
|
||||
|
||||
public static void handleAnnouncement(JSONObject announcement, Context context) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString("data", announcement.toString());
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue