Merge commit 'origin/dev^' into combo-dev-merge
* commit 'origin/dev^': (313 commits) cleanup draw profile in dana profile viewer optimize imports draw basal in profile viewer BG autobackfill configurable travis 2nd try Save new profile when updating it Add environment variable to handle testCoverage do not pass DIA to SMB determine_basal show Dana model properly after communication error fix deviation slope calculations Read maximum basal and bolus amount from pump update maxIOB hard limits Allow bolus record only in new treatment dialog use safeGetString JsonHelper test food code cleanup Show bolus progress Missing import statement Insight: add treatment to progress event ...
This commit is contained in:
commit
db00404e43
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -7,3 +7,4 @@
|
|||
*.apk
|
||||
build/
|
||||
.idea/
|
||||
app/src/main/jniLibs
|
||||
|
|
|
@ -18,7 +18,7 @@ before_install:
|
|||
|
||||
script:
|
||||
# Unit Test
|
||||
- ./gradlew test jacocoTestReport
|
||||
- ./gradlew -Pcoverage test jacocoTestReport
|
||||
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
|
@ -57,7 +57,7 @@ android {
|
|||
targetSdkVersion 23
|
||||
multiDexEnabled true
|
||||
versionCode 1500
|
||||
version "1.58-combo-phantom-fusion"
|
||||
version "1.59-dev"
|
||||
buildConfigField "String", "VERSION", '"' + version + '"'
|
||||
buildConfigField "String", "BUILDVERSION", generateGitBuild()
|
||||
|
||||
|
@ -82,7 +82,7 @@ android {
|
|||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
debug {
|
||||
testCoverageEnabled true
|
||||
testCoverageEnabled (project.hasProperty('coverage') ? true : false)
|
||||
}
|
||||
}
|
||||
productFlavors {
|
||||
|
@ -187,6 +187,7 @@ dependencies {
|
|||
compile("com.crashlytics.sdk.android:answers:1.3.12@aar") {
|
||||
transitive = true;
|
||||
}
|
||||
compile 'MilosKozak:danars-support-lib:master@zip'
|
||||
|
||||
compile "com.android.support:appcompat-v7:${supportLibraryVersion}"
|
||||
compile "com.android.support:support-v4:${supportLibraryVersion}"
|
||||
|
@ -196,6 +197,7 @@ dependencies {
|
|||
compile "com.android.support:design:${supportLibraryVersion}"
|
||||
compile "com.android.support:percent:${supportLibraryVersion}"
|
||||
compile "com.wdullaer:materialdatetimepicker:2.3.0"
|
||||
compile 'com.android.support.constraint:constraint-layout:1.0.2'
|
||||
compile "com.squareup:otto:1.3.7"
|
||||
compile "com.j256.ormlite:ormlite-core:${ormLiteVersion}"
|
||||
compile "com.j256.ormlite:ormlite-android:${ormLiteVersion}"
|
||||
|
@ -208,6 +210,8 @@ dependencies {
|
|||
compile "com.joanzapata.iconify:android-iconify-fontawesome:2.1.1"
|
||||
compile "com.google.android.gms:play-services-wearable:7.5.0"
|
||||
compile(name: "android-edittext-validator-v1.3.4-mod", ext: "aar")
|
||||
compile(name: "sightparser-release", ext: "aar")
|
||||
|
||||
compile("com.google.android:flexbox:0.3.0") {
|
||||
exclude group: "com.android.support"
|
||||
}
|
||||
|
@ -220,6 +224,8 @@ dependencies {
|
|||
|
||||
compile "net.danlew:android.joda:2.9.9.1"
|
||||
|
||||
compile 'org.mozilla:rhino:1.7.7.2'
|
||||
|
||||
api "com.jakewharton:butterknife:8.8.1"
|
||||
annotationProcessor "com.jakewharton:butterknife-compiler:8.8.1"
|
||||
|
||||
|
@ -231,8 +237,33 @@ dependencies {
|
|||
testCompile "org.powermock:powermock-module-junit4-rule:${powermockVersion}"
|
||||
testCompile "org.powermock:powermock-module-junit4:${powermockVersion}"
|
||||
testCompile "joda-time:joda-time:2.9.4.2"
|
||||
testCompile "com.google.truth:truth:0.39"
|
||||
|
||||
androidTestCompile "org.mockito:mockito-core:2.7.22"
|
||||
androidTestCompile "com.google.dexmaker:dexmaker:${dexmakerVersion}"
|
||||
androidTestCompile "com.google.dexmaker:dexmaker-mockito:${dexmakerVersion}"
|
||||
}
|
||||
|
||||
task unzip(type: Copy) {
|
||||
def zipPath = configurations.compile.find {it.name.startsWith("danars") }
|
||||
def zipFile = file(zipPath)
|
||||
def outputDir = file("${buildDir}/unpacked/dist")
|
||||
|
||||
from zipTree(zipFile)
|
||||
into outputDir
|
||||
}
|
||||
|
||||
task copyLibs(dependsOn: unzip, type: Copy) {
|
||||
def src = file("${buildDir}/unpacked/dist/danars-support-lib-master")
|
||||
def target = file("src/main/jniLibs/")
|
||||
|
||||
from src
|
||||
into target
|
||||
}
|
||||
|
||||
task full_clean(type: Delete) {
|
||||
delete file("src/main/jniLibs")
|
||||
}
|
||||
|
||||
clean.dependsOn full_clean
|
||||
preBuild.dependsOn copyLibs
|
Binary file not shown.
BIN
app/libs/sightparser-release.aar
Normal file
BIN
app/libs/sightparser-release.aar
Normal file
Binary file not shown.
|
@ -61,6 +61,7 @@
|
|||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name=".plugins.PumpDanaRS.activities.PairingHelperActivity" />
|
||||
<activity android:name=".HistoryBrowseActivity" />
|
||||
|
||||
<receiver
|
||||
android:name=".receivers.DataReceiver"
|
||||
|
|
61
app/src/main/assets/OpenAPSSMB/basal-set-temp.js
Normal file
61
app/src/main/assets/OpenAPSSMB/basal-set-temp.js
Normal file
|
@ -0,0 +1,61 @@
|
|||
'use strict';
|
||||
|
||||
function reason(rT, msg) {
|
||||
rT.reason = (rT.reason ? rT.reason + '. ' : '') + msg;
|
||||
console.error(msg);
|
||||
}
|
||||
|
||||
var tempBasalFunctions = {};
|
||||
|
||||
tempBasalFunctions.getMaxSafeBasal = function getMaxSafeBasal(profile) {
|
||||
|
||||
var max_daily_safety_multiplier = (isNaN(profile.max_daily_safety_multiplier) || profile.max_daily_safety_multiplier == null) ? 3 : profile.max_daily_safety_multiplier;
|
||||
var current_basal_safety_multiplier = (isNaN(profile.current_basal_safety_multiplier) || profile.current_basal_safety_multiplier == null) ? 4 : profile.current_basal_safety_multiplier;
|
||||
|
||||
return Math.min(profile.max_basal, max_daily_safety_multiplier * profile.max_daily_basal, current_basal_safety_multiplier * profile.current_basal);
|
||||
};
|
||||
|
||||
tempBasalFunctions.setTempBasal = function setTempBasal(rate, duration, profile, rT, currenttemp) {
|
||||
//var maxSafeBasal = Math.min(profile.max_basal, 3 * profile.max_daily_basal, 4 * profile.current_basal);
|
||||
|
||||
var maxSafeBasal = tempBasalFunctions.getMaxSafeBasal(profile);
|
||||
var round_basal = require('./round-basal');
|
||||
|
||||
if (rate < 0) {
|
||||
rate = 0;
|
||||
} // if >30m @ 0 required, zero temp will be extended to 30m instead
|
||||
else if (rate > maxSafeBasal) {
|
||||
rate = maxSafeBasal;
|
||||
}
|
||||
|
||||
var suggestedRate = round_basal(rate, profile);
|
||||
if (typeof(currenttemp) !== 'undefined' && typeof(currenttemp.duration) !== 'undefined' && typeof(currenttemp.rate) !== 'undefined' && currenttemp.duration > (duration-10) && currenttemp.duration <= 120 && suggestedRate <= currenttemp.rate * 1.2 && suggestedRate >= currenttemp.rate * 0.8) {
|
||||
rT.reason += " "+currenttemp.duration+"m left and " + currenttemp.rate + " ~ req " + suggestedRate + "U/hr: no temp required";
|
||||
return rT;
|
||||
}
|
||||
|
||||
if (suggestedRate === profile.current_basal) {
|
||||
if (profile.skip_neutral_temps) {
|
||||
if (typeof(currenttemp) !== 'undefined' && typeof(currenttemp.duration) !== 'undefined' && currenttemp.duration > 0) {
|
||||
reason(rT, 'Suggested rate is same as profile rate, a temp basal is active, canceling current temp');
|
||||
rT.duration = 0;
|
||||
rT.rate = 0;
|
||||
return rT;
|
||||
} else {
|
||||
reason(rT, 'Suggested rate is same as profile rate, no temp basal is active, doing nothing');
|
||||
return rT;
|
||||
}
|
||||
} else {
|
||||
reason(rT, 'Setting neutral temp basal of ' + profile.current_basal + 'U/hr');
|
||||
rT.duration = duration;
|
||||
rT.rate = suggestedRate;
|
||||
return rT;
|
||||
}
|
||||
} else {
|
||||
rT.duration = duration;
|
||||
rT.rate = suggestedRate;
|
||||
return rT;
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = tempBasalFunctions;
|
1146
app/src/main/assets/OpenAPSSMB/determine-basal.js
Normal file
1146
app/src/main/assets/OpenAPSSMB/determine-basal.js
Normal file
File diff suppressed because it is too large
Load diff
|
@ -25,6 +25,8 @@ public class Config {
|
|||
public static final boolean SMSCOMMUNICATORENABLED = !BuildConfig.NSCLIENTOLNY && !BuildConfig.G5UPLOADER;
|
||||
|
||||
|
||||
public static final boolean displayDeviationSlope = true;
|
||||
|
||||
public static final boolean detailedLog = true;
|
||||
public static final boolean logFunctionCalls = true;
|
||||
public static final boolean logIncommingData = true;
|
||||
|
|
|
@ -33,20 +33,17 @@ public class Constants {
|
|||
public static final int CPP_MIN_TIMESHIFT = -6;
|
||||
public static final int CPP_MAX_TIMESHIFT = 23;
|
||||
|
||||
// Very Hard Limits Ranges
|
||||
// First value is the Lowest and second value is the Highest a Limit can define
|
||||
public static final int[] VERY_HARD_LIMIT_MIN_BG = {72,180};
|
||||
public static final int[] VERY_HARD_LIMIT_MAX_BG = {90,270};
|
||||
public static final int[] VERY_HARD_LIMIT_TARGET_BG = {80,200};
|
||||
|
||||
// Very Hard Limits Ranges for Temp Targets
|
||||
public static final int[] VERY_HARD_LIMIT_TEMP_MIN_BG = {72,180};
|
||||
public static final int[] VERY_HARD_LIMIT_TEMP_MAX_BG = {72,270};
|
||||
public static final int[] VERY_HARD_LIMIT_TEMP_TARGET_BG = {72,200};
|
||||
|
||||
//DanaR
|
||||
public static final double dailyLimitWarning = 0.95d;
|
||||
|
||||
// Temp targets
|
||||
public static final int defaultActivityTTDuration = 90; // min
|
||||
public static final double defaultActivityTTmgdl = 90d;
|
||||
public static final double defaultActivityTTmmol = 5d;
|
||||
public static final int defaultEatingSoonTTDuration = 45; // min
|
||||
public static final double defaultEatingSoonTTmgdl = 140d;
|
||||
public static final double defaultEatingSoonTTmmol = 8d;
|
||||
|
||||
//NSClientInternal
|
||||
public static final int MAX_LOG_LINES = 100;
|
||||
|
||||
|
|
|
@ -0,0 +1,300 @@
|
|||
package info.nightscout.androidaps;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.SeekBar;
|
||||
|
||||
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.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);
|
||||
|
||||
@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.overview_showprediction)
|
||||
CheckBox showPredictionCheckbox;
|
||||
@BindView(R.id.overview_showbasals)
|
||||
CheckBox showBasalsCheckbox;
|
||||
@BindView(R.id.overview_showiob)
|
||||
CheckBox showIobCheckbox;
|
||||
@BindView(R.id.overview_showcob)
|
||||
CheckBox showCobCheckbox;
|
||||
@BindView(R.id.overview_showdeviations)
|
||||
CheckBox showDeviationsCheckbox;
|
||||
@BindView(R.id.overview_showratios)
|
||||
CheckBox showRatiosCheckbox;
|
||||
|
||||
private int rangeToDisplay = 24; // for graph
|
||||
private 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.sResources.getColor(R.color.graphgrid));
|
||||
bgGraph.getGridLabelRenderer().reloadStyles();
|
||||
iobGraph.getGridLabelRenderer().setGridColor(MainApp.sResources.getColor(R.color.graphgrid));
|
||||
iobGraph.getGridLabelRenderer().reloadStyles();
|
||||
iobGraph.getGridLabelRenderer().setHorizontalLabelsVisible(false);
|
||||
bgGraph.getGridLabelRenderer().setLabelVerticalWidth(50);
|
||||
iobGraph.getGridLabelRenderer().setLabelVerticalWidth(50);
|
||||
iobGraph.getGridLabelRenderer().setNumVerticalLabels(5);
|
||||
|
||||
// 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() {
|
||||
}
|
||||
|
||||
@OnClick({R.id.overview_showbasals, R.id.overview_showprediction, R.id.overview_showiob, R.id.overview_showcob, R.id.overview_showdeviations, R.id.overview_showratios})
|
||||
void onClickDate(View view) {
|
||||
//((CheckBox) view).toggle();
|
||||
updateGUI("checkboxToggle");
|
||||
iobCobCalculatorPlugin.clearCache();
|
||||
iobCobCalculatorPlugin.runCalculation("onClickDate", start, true, eventCustomCalculationFinished);
|
||||
}
|
||||
|
||||
|
||||
@Subscribe
|
||||
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();
|
||||
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 && showBasalsCheckbox.isChecked()) {
|
||||
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;
|
||||
|
||||
if (showIobCheckbox.isChecked()) {
|
||||
useIobForScale = true;
|
||||
} else if (showCobCheckbox.isChecked()) {
|
||||
useCobForScale = true;
|
||||
} else if (showDeviationsCheckbox.isChecked()) {
|
||||
useDevForScale = true;
|
||||
} else if (showRatiosCheckbox.isChecked()) {
|
||||
useRatioForScale = true;
|
||||
}
|
||||
|
||||
if (showIobCheckbox.isChecked())
|
||||
secondGraphData.addIob(fromTime, toTime, useIobForScale, 1d);
|
||||
if (showCobCheckbox.isChecked())
|
||||
secondGraphData.addCob(fromTime, toTime, useCobForScale, useCobForScale ? 1d : 0.5d);
|
||||
if (showDeviationsCheckbox.isChecked())
|
||||
secondGraphData.addDeviations(fromTime, toTime, useDevForScale, 1d);
|
||||
if (showRatiosCheckbox.isChecked())
|
||||
secondGraphData.addRatio(fromTime, toTime, useRatioForScale, 1d);
|
||||
|
||||
// **** NOW line ****
|
||||
// set manual x bounds to have nice steps
|
||||
secondGraphData.formatAxis(fromTime, toTime);
|
||||
secondGraphData.addNowLine(pointer);
|
||||
|
||||
// do GUI update
|
||||
if (showIobCheckbox.isChecked() || showCobCheckbox.isChecked() || showDeviationsCheckbox.isChecked() || showRatiosCheckbox.isChecked()) {
|
||||
iobGraph.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
iobGraph.setVisibility(View.GONE);
|
||||
}
|
||||
// finally enforce drawing of graphs
|
||||
graphData.performUpdate();
|
||||
secondGraphData.performUpdate();
|
||||
}
|
||||
}
|
|
@ -39,13 +39,14 @@ import com.squareup.otto.Subscribe;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.Services.AlarmSoundService;
|
||||
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.plugins.Food.FoodPlugin;
|
||||
import info.nightscout.androidaps.plugins.Overview.events.EventSetWakeLock;
|
||||
import info.nightscout.androidaps.tabs.SlidingTabLayout;
|
||||
import info.nightscout.androidaps.tabs.TabPageAdapter;
|
||||
|
@ -116,9 +117,9 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if(ev.recreate) {
|
||||
if (ev.recreate) {
|
||||
recreate();
|
||||
}else {
|
||||
} else {
|
||||
try { // activity may be destroyed
|
||||
setUpTabs(true);
|
||||
} catch (IllegalStateException e) {
|
||||
|
@ -175,7 +176,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
// Added in 1.57 at 21.01.2018
|
||||
Integer unreachable_threshold = SP.getInt(R.string.key_pump_unreachable_threshold, 30);
|
||||
SP.remove(R.string.key_pump_unreachable_threshold);
|
||||
if(unreachable_threshold < 30) unreachable_threshold = 30;
|
||||
if (unreachable_threshold < 30) unreachable_threshold = 30;
|
||||
SP.putString(R.string.key_pump_unreachable_threshold, unreachable_threshold.toString());
|
||||
}
|
||||
|
||||
|
@ -226,6 +227,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
super.onResume();
|
||||
askForSMSPermissions();
|
||||
askForLocationPermissions();
|
||||
MainApp.bus().post(new EventFeatureRunning(EventFeatureRunning.Feature.MAIN));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -362,6 +364,9 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
}
|
||||
}, 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)
|
||||
|
@ -371,6 +376,9 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
MainApp.getDbHelper().resetDatabases();
|
||||
// should be handled by Plugin-Interface and
|
||||
// additional service interface and plugin registry
|
||||
MainApp.getSpecificPlugin(FoodPlugin.class).getService().resetFood();
|
||||
}
|
||||
})
|
||||
.create()
|
||||
|
@ -390,7 +398,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
case R.id.nav_about:
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext());
|
||||
builder.setTitle(getString(R.string.app_name) + " " + BuildConfig.VERSION);
|
||||
if (Config.NSCLIENT|| Config.G5UPLOADER)
|
||||
if (Config.NSCLIENT || Config.G5UPLOADER)
|
||||
builder.setIcon(R.mipmap.yellowowl);
|
||||
else
|
||||
builder.setIcon(R.mipmap.blueowl);
|
||||
|
|
|
@ -44,9 +44,9 @@ import info.nightscout.androidaps.plugins.NSClientInternal.NSClientInternalPlugi
|
|||
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.Persistentnotification.PersistentNotificationPlugin;
|
||||
import info.nightscout.androidaps.plugins.ProfileCircadianPercentage.CircadianPercentageProfileFragment;
|
||||
import info.nightscout.androidaps.plugins.ProfileLocal.LocalProfilePlugin;
|
||||
import info.nightscout.androidaps.plugins.ProfileNS.NSProfilePlugin;
|
||||
import info.nightscout.androidaps.plugins.ProfileSimple.SimpleProfilePlugin;
|
||||
|
@ -55,6 +55,7 @@ import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPlugin;
|
|||
import info.nightscout.androidaps.plugins.PumpDanaRKorean.DanaRKoreanPlugin;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaRS.DanaRSPlugin;
|
||||
import info.nightscout.androidaps.plugins.PumpDanaRv2.DanaRv2Plugin;
|
||||
import info.nightscout.androidaps.plugins.PumpInsight.InsightPumpPlugin;
|
||||
import info.nightscout.androidaps.plugins.PumpMDI.MDIPlugin;
|
||||
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
|
||||
import info.nightscout.androidaps.plugins.SensitivityAAPS.SensitivityAAPSPlugin;
|
||||
|
@ -72,6 +73,7 @@ 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.utils.FabricPrivacy;
|
||||
import info.nightscout.utils.NSUpload;
|
||||
import io.fabric.sdk.android.Fabric;
|
||||
|
||||
|
@ -97,18 +99,26 @@ public class MainApp extends Application {
|
|||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
Fabric.with(this, new Crashlytics());
|
||||
Fabric.with(this, new Answers());
|
||||
sInstance = this;
|
||||
sResources = getResources();
|
||||
|
||||
try {
|
||||
if (FabricPrivacy.fabricEnabled()) {
|
||||
Fabric.with(this, new Crashlytics());
|
||||
Fabric.with(this, new Answers());
|
||||
Crashlytics.setString("BUILDVERSION", BuildConfig.BUILDVERSION);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
android.util.Log.e("ANDROIDAPS", "Error with Fabric init! " + e);
|
||||
}
|
||||
|
||||
JodaTimeAndroid.init(this);
|
||||
Crashlytics.setString("BUILDVERSION", BuildConfig.BUILDVERSION);
|
||||
|
||||
log.info("Version: " + BuildConfig.VERSION_NAME);
|
||||
log.info("BuildVersion: " + BuildConfig.BUILDVERSION);
|
||||
|
||||
sBus = Config.logEvents ? new LoggingBus(ThreadEnforcer.ANY) : new Bus(ThreadEnforcer.ANY);
|
||||
|
||||
sInstance = this;
|
||||
sResources = getResources();
|
||||
|
||||
registerLocalBroadcastReceiver();
|
||||
|
||||
if (pluginsList == null) {
|
||||
|
@ -131,16 +141,16 @@ public class MainApp extends Application {
|
|||
if (Config.DANAR) pluginsList.add(DanaRSPlugin.getPlugin());
|
||||
if (Config.COMBO) pluginsList.add(ComboPlugin.getPlugin());
|
||||
pluginsList.add(CareportalPlugin.getPlugin());
|
||||
// if (Config.DANAR) pluginsList.add(InsightPumpPlugin.getPlugin()); // <-- Enable Insight plugin here
|
||||
if (Config.MDI) pluginsList.add(MDIPlugin.getPlugin());
|
||||
if (Config.VIRTUALPUMP) pluginsList.add(VirtualPumpPlugin.getPlugin());
|
||||
if (Config.APS) pluginsList.add(LoopPlugin.getPlugin());
|
||||
if (Config.APS) pluginsList.add(OpenAPSMAPlugin.getPlugin());
|
||||
if (Config.APS) pluginsList.add(OpenAPSAMAPlugin.getPlugin());
|
||||
if (Config.APS) pluginsList.add(OpenAPSSMBPlugin.getPlugin());
|
||||
pluginsList.add(NSProfilePlugin.getPlugin());
|
||||
if (Config.OTHERPROFILES) pluginsList.add(SimpleProfilePlugin.getPlugin());
|
||||
if (Config.OTHERPROFILES) pluginsList.add(LocalProfilePlugin.getPlugin());
|
||||
if (Config.OTHERPROFILES)
|
||||
pluginsList.add(CircadianPercentageProfileFragment.getPlugin());
|
||||
pluginsList.add(TreatmentsPlugin.getPlugin());
|
||||
if (Config.SAFETY) pluginsList.add(SafetyPlugin.getPlugin());
|
||||
if (Config.APS) pluginsList.add(ObjectivesPlugin.getPlugin());
|
||||
|
@ -168,15 +178,15 @@ public class MainApp extends Application {
|
|||
}
|
||||
NSUpload.uploadAppStart();
|
||||
if (Config.NSCLIENT)
|
||||
Answers.getInstance().logCustom(new CustomEvent("AppStart-NSClient"));
|
||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("AppStart-NSClient"));
|
||||
else if (Config.G5UPLOADER)
|
||||
Answers.getInstance().logCustom(new CustomEvent("AppStart-G5Uploader"));
|
||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("AppStart-G5Uploader"));
|
||||
else if (Config.PUMPCONTROL)
|
||||
Answers.getInstance().logCustom(new CustomEvent("AppStart-PumpControl"));
|
||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("AppStart-PumpControl"));
|
||||
else if (MainApp.getConfigBuilder().isClosedModeEnabled())
|
||||
Answers.getInstance().logCustom(new CustomEvent("AppStart-ClosedLoop"));
|
||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("AppStart-ClosedLoop"));
|
||||
else
|
||||
Answers.getInstance().logCustom(new CustomEvent("AppStart-OpenLoop"));
|
||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("AppStart-OpenLoop"));
|
||||
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
|
@ -239,6 +249,10 @@ public class MainApp extends Application {
|
|||
return sResources.getString(id, args);
|
||||
}
|
||||
|
||||
public static int gc(int id) {
|
||||
return sResources.getColor(id);
|
||||
}
|
||||
|
||||
public static MainApp instance() {
|
||||
return sInstance;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import android.text.TextUtils;
|
|||
import info.nightscout.androidaps.events.EventPreferenceChange;
|
||||
import info.nightscout.androidaps.events.EventRefreshGui;
|
||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
import info.nightscout.androidaps.plugins.OpenAPSSMB.OpenAPSSMBPlugin;
|
||||
import info.nightscout.androidaps.plugins.Careportal.CareportalPlugin;
|
||||
import info.nightscout.androidaps.plugins.ConstraintsSafety.SafetyPlugin;
|
||||
import info.nightscout.androidaps.plugins.Insulin.InsulinOrefFreePeakPlugin;
|
||||
|
@ -129,6 +130,8 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
|
|||
addPreferencesFromResource(id);
|
||||
addPreferencesFromResource(R.xml.pref_advanced);
|
||||
} else {
|
||||
addPreferencesFromResource(R.xml.pref_overview);
|
||||
|
||||
if (!Config.NSCLIENT && !Config.G5UPLOADER) {
|
||||
addPreferencesFromResource(R.xml.pref_password);
|
||||
}
|
||||
|
@ -145,6 +148,7 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
|
|||
addPreferencesFromResourceIfEnabled(LoopPlugin.getPlugin(), PluginBase.LOOP);
|
||||
addPreferencesFromResourceIfEnabled(OpenAPSMAPlugin.getPlugin(), PluginBase.APS);
|
||||
addPreferencesFromResourceIfEnabled(OpenAPSAMAPlugin.getPlugin(), PluginBase.APS);
|
||||
addPreferencesFromResourceIfEnabled(OpenAPSSMBPlugin.getPlugin(), PluginBase.APS);
|
||||
}
|
||||
|
||||
addPreferencesFromResourceIfEnabled(SensitivityAAPSPlugin.getPlugin(), PluginBase.SENSITIVITY);
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
package info.nightscout.androidaps.Services;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.AssetFileDescriptor;
|
||||
import android.media.AudioManager;
|
||||
import android.media.MediaPlayer;
|
||||
import android.os.IBinder;
|
||||
|
||||
|
@ -53,7 +55,10 @@ public class AlarmSoundService extends Service {
|
|||
log.error("Unhandled exception", e);
|
||||
}
|
||||
player.setLooping(true); // Set looping
|
||||
player.setVolume(100, 100);
|
||||
AudioManager manager = (AudioManager)this.getSystemService(Context.AUDIO_SERVICE);
|
||||
if (manager == null || !manager.isMusicActive()) {
|
||||
player.setVolume(100, 100);
|
||||
}
|
||||
|
||||
try {
|
||||
player.prepare();
|
||||
|
|
|
@ -19,6 +19,7 @@ import info.nightscout.androidaps.data.ProfileStore;
|
|||
import info.nightscout.androidaps.db.BgReading;
|
||||
import info.nightscout.androidaps.db.CareportalEvent;
|
||||
import info.nightscout.androidaps.events.EventNewBasalProfile;
|
||||
import info.nightscout.androidaps.events.EventNsFood;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin;
|
||||
import info.nightscout.androidaps.plugins.NSClientInternal.data.NSDeviceStatus;
|
||||
|
@ -123,8 +124,8 @@ public class DataService extends IntentService {
|
|||
handleNewDataFromDexcomG5(intent);
|
||||
}
|
||||
} else if (Intents.ACTION_NEW_SGV.equals(action)) {
|
||||
// always backfill SGV from NS
|
||||
handleNewDataFromNSClient(intent);
|
||||
if (nsClientEnabled || SP.getBoolean(R.string.ns_autobackfill, true))
|
||||
handleNewDataFromNSClient(intent);
|
||||
// Objectives 0
|
||||
ObjectivesPlugin.bgIsAvailableInNS = true;
|
||||
ObjectivesPlugin.saveProgress();
|
||||
|
@ -474,57 +475,19 @@ public class DataService extends IntentService {
|
|||
}
|
||||
}
|
||||
|
||||
if (intent.getAction().equals(Intents.ACTION_NEW_FOOD) || intent.getAction().equals(Intents.ACTION_CHANGED_FOOD)) {
|
||||
try {
|
||||
if (bundles.containsKey("food")) {
|
||||
String trstring = bundles.getString("food");
|
||||
handleAddChangeFoodRecord(new JSONObject(trstring));
|
||||
}
|
||||
if (bundles.containsKey("foods")) {
|
||||
String trstring = bundles.getString("foods");
|
||||
JSONArray jsonArray = new JSONArray(trstring);
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
JSONObject trJson = jsonArray.getJSONObject(i);
|
||||
handleAddChangeFoodRecord(trJson);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
if (intent.getAction().equals(Intents.ACTION_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)) {
|
||||
try {
|
||||
if (bundles.containsKey("food")) {
|
||||
String trstring = bundles.getString("food");
|
||||
JSONObject trJson = new JSONObject(trstring);
|
||||
String _id = trJson.getString("_id");
|
||||
handleRemovedFoodRecord(_id);
|
||||
}
|
||||
|
||||
if (bundles.containsKey("foods")) {
|
||||
String trstring = bundles.getString("foods");
|
||||
JSONArray jsonArray = new JSONArray(trstring);
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
JSONObject trJson = jsonArray.getJSONObject(i);
|
||||
String _id = trJson.getString("_id");
|
||||
handleRemovedFoodRecord(_id);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
EventNsFood evt = new EventNsFood(EventNsFood.REMOVE, bundles);
|
||||
MainApp.bus().post(evt);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleRemovedFoodRecord(String _id) {
|
||||
MainApp.getDbHelper().foodHelper.deleteFoodById(_id);
|
||||
}
|
||||
|
||||
public void handleAddChangeFoodRecord(JSONObject trJson) throws JSONException {
|
||||
MainApp.getDbHelper().foodHelper.createFoodFromJsonIfNotExists(trJson);
|
||||
}
|
||||
|
||||
private void handleRemovedRecordFromNS(String _id) {
|
||||
MainApp.getDbHelper().deleteTreatmentById(_id);
|
||||
MainApp.getDbHelper().deleteTempTargetById(_id);
|
||||
|
|
|
@ -27,6 +27,7 @@ public class DetailedBolusInfo {
|
|||
public Context context = null; // context for progress dialog
|
||||
public long pumpId = 0; // id of record if comming from pump history (not a newly created treatment)
|
||||
public boolean isSMB = false; // is a Super-MicroBolus
|
||||
public long deliverAt = 0; // SMB should be delivered within 1 min from this time
|
||||
|
||||
public DetailedBolusInfo copy() {
|
||||
DetailedBolusInfo copy = new DetailedBolusInfo();
|
||||
|
@ -53,6 +54,7 @@ public class DetailedBolusInfo {
|
|||
" carbs: " + carbs +
|
||||
" isValid: " + isValid +
|
||||
" carbTime: " + carbTime +
|
||||
" isSMB: " + isSMB;
|
||||
" isSMB: " + isSMB +
|
||||
" deliverAt: " + new Date(deliverAt).toLocaleString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ public class GlucoseStatus {
|
|||
public double avgdelta = 0d;
|
||||
public double short_avgdelta = 0d;
|
||||
public double long_avgdelta = 0d;
|
||||
public long date = 0L;
|
||||
|
||||
|
||||
@Override
|
||||
|
@ -133,6 +134,7 @@ public class GlucoseStatus {
|
|||
|
||||
GlucoseStatus status = new GlucoseStatus();
|
||||
status.glucose = now.value;
|
||||
status.date = now_date;
|
||||
|
||||
status.short_avgdelta = average(short_deltas);
|
||||
|
||||
|
|
|
@ -21,8 +21,11 @@ public class IobTotal {
|
|||
public double hightempinsulin;
|
||||
|
||||
// oref1
|
||||
public double microBolusInsulin;
|
||||
public double microBolusIOB;
|
||||
public long lastBolusTime;
|
||||
public long lastTempDate;
|
||||
public int lastTempDuration;
|
||||
public double lastTempRate;
|
||||
public IobTotal iobWithZeroTemp;
|
||||
|
||||
public double netInsulin = 0d; // for calculations from temp basals only
|
||||
public double netRatio = 0d; // net ratio at start of temp basal
|
||||
|
@ -31,6 +34,23 @@ public class IobTotal {
|
|||
|
||||
long time;
|
||||
|
||||
|
||||
public IobTotal clone() {
|
||||
IobTotal copy = new IobTotal(time);
|
||||
copy.iob = iob;
|
||||
copy.activity = activity;
|
||||
copy.bolussnooze = bolussnooze;
|
||||
copy.basaliob = basaliob;
|
||||
copy.netbasalinsulin = netbasalinsulin;
|
||||
copy.hightempinsulin = hightempinsulin;
|
||||
copy.lastBolusTime = lastBolusTime;
|
||||
copy.lastTempDate = lastTempDate;
|
||||
copy.lastTempDuration = lastTempDuration;
|
||||
copy.lastTempRate = lastTempRate;
|
||||
copy.iobWithZeroTemp = iobWithZeroTemp;
|
||||
return copy;
|
||||
}
|
||||
|
||||
public IobTotal(long time) {
|
||||
this.iob = 0d;
|
||||
this.activity = 0d;
|
||||
|
@ -38,8 +58,7 @@ public class IobTotal {
|
|||
this.basaliob = 0d;
|
||||
this.netbasalinsulin = 0d;
|
||||
this.hightempinsulin = 0d;
|
||||
this.microBolusInsulin = 0d;
|
||||
this.microBolusIOB = 0d;
|
||||
this.lastBolusTime = 0;
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
|
@ -52,8 +71,6 @@ public class IobTotal {
|
|||
hightempinsulin += other.hightempinsulin;
|
||||
netInsulin += other.netInsulin;
|
||||
extendedBolusInsulin += other.extendedBolusInsulin;
|
||||
microBolusInsulin += other.microBolusInsulin;
|
||||
microBolusIOB += other.microBolusIOB;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -62,11 +79,14 @@ public class IobTotal {
|
|||
result.iob = bolusIOB.iob + basalIob.basaliob;
|
||||
result.activity = bolusIOB.activity + basalIob.activity;
|
||||
result.bolussnooze = bolusIOB.bolussnooze;
|
||||
result.basaliob = basalIob.basaliob;
|
||||
result.netbasalinsulin = basalIob.netbasalinsulin;
|
||||
result.hightempinsulin = basalIob.hightempinsulin;
|
||||
result.microBolusInsulin = bolusIOB.microBolusInsulin + basalIob.microBolusInsulin;
|
||||
result.microBolusIOB = bolusIOB.microBolusIOB + basalIob.microBolusIOB;
|
||||
result.basaliob = bolusIOB.basaliob + basalIob.basaliob;
|
||||
result.netbasalinsulin = bolusIOB.netbasalinsulin + basalIob.netbasalinsulin;
|
||||
result.hightempinsulin = basalIob.hightempinsulin + bolusIOB.hightempinsulin;
|
||||
result.lastBolusTime = bolusIOB.lastBolusTime;
|
||||
result.lastTempDate = basalIob.lastTempDate;
|
||||
result.lastTempRate = basalIob.lastTempRate;
|
||||
result.lastTempDuration = basalIob.lastTempDuration;
|
||||
result.iobWithZeroTemp = basalIob.iobWithZeroTemp;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -77,8 +97,6 @@ public class IobTotal {
|
|||
this.basaliob = Round.roundTo(this.basaliob, 0.001);
|
||||
this.netbasalinsulin = Round.roundTo(this.netbasalinsulin, 0.001);
|
||||
this.hightempinsulin = Round.roundTo(this.hightempinsulin, 0.001);
|
||||
this.microBolusInsulin = Round.roundTo(this.microBolusInsulin, 0.001);
|
||||
this.microBolusIOB = Round.roundTo(this.microBolusIOB, 0.001);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -102,7 +120,24 @@ public class IobTotal {
|
|||
json.put("basaliob", basaliob);
|
||||
json.put("bolussnooze", bolussnooze);
|
||||
json.put("activity", activity);
|
||||
json.put("lastBolusTime", lastBolusTime);
|
||||
json.put("time", DateUtil.toISOString(new Date(time)));
|
||||
/*
|
||||
|
||||
This is requested by SMB determine_basal but by based on Scott's info
|
||||
it's MDT specific safety check only
|
||||
It's causing rounding issues in determine_basal
|
||||
|
||||
JSONObject lastTemp = new JSONObject();
|
||||
lastTemp.put("date", lastTempDate);
|
||||
lastTemp.put("rate", lastTempRate);
|
||||
lastTemp.put("duration", lastTempDuration);
|
||||
json.put("lastTemp", lastTemp);
|
||||
*/
|
||||
if (iobWithZeroTemp != null) {
|
||||
JSONObject iwzt = iobWithZeroTemp.determineBasalJson();
|
||||
json.put("iobWithZeroTemp", iwzt);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
|
|
|
@ -7,4 +7,8 @@ public class MealData {
|
|||
public double boluses = 0d;
|
||||
public double carbs = 0d;
|
||||
public double mealCOB = 0.0d;
|
||||
public double slopeFromMaxDeviation = 0;
|
||||
public double slopeFromMinDeviation = 999;
|
||||
public long lastBolusTime;
|
||||
public long lastCarbTime = 0L;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ package info.nightscout.androidaps.data;
|
|||
|
||||
import android.support.v4.util.LongSparseArray;
|
||||
|
||||
import com.crashlytics.android.Crashlytics;
|
||||
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
|
@ -25,6 +25,7 @@ import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
|
|||
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
|
||||
import info.nightscout.utils.DateUtil;
|
||||
import info.nightscout.utils.DecimalFormatter;
|
||||
import info.nightscout.utils.FabricPrivacy;
|
||||
import info.nightscout.utils.ToastUtils;
|
||||
|
||||
public class Profile {
|
||||
|
@ -57,7 +58,7 @@ public class Profile {
|
|||
if (units != null)
|
||||
this.units = units;
|
||||
else {
|
||||
Crashlytics.log("Profile failover failed too");
|
||||
FabricPrivacy.log("Profile failover failed too");
|
||||
this.units = Constants.MGDL;
|
||||
}
|
||||
}
|
||||
|
@ -217,16 +218,18 @@ public class Profile {
|
|||
|
||||
if (isValid) {
|
||||
// Check for hours alignment
|
||||
for (int index = 0; index < basal_v.size(); index++) {
|
||||
long secondsFromMidnight = basal_v.keyAt(index);
|
||||
if (secondsFromMidnight % 3600 != 0) {
|
||||
Notification notification = new Notification(Notification.BASAL_PROFILE_NOT_ALIGNED_TO_HOURS, String.format(MainApp.gs(R.string.basalprofilenotaligned), from), Notification.NORMAL);
|
||||
MainApp.bus().post(new EventNewNotification(notification));
|
||||
PumpInterface pump = MainApp.getConfigBuilder().getActivePump();
|
||||
if (pump != null && !pump.getPumpDescription().is30minBasalRatesCapable) {
|
||||
for (int index = 0; index < basal_v.size(); index++) {
|
||||
long secondsFromMidnight = basal_v.keyAt(index);
|
||||
if (secondsFromMidnight % 3600 != 0) {
|
||||
Notification notification = new Notification(Notification.BASAL_PROFILE_NOT_ALIGNED_TO_HOURS, String.format(MainApp.gs(R.string.basalprofilenotaligned), from), Notification.NORMAL);
|
||||
MainApp.bus().post(new EventNewNotification(notification));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check for minimal basal value
|
||||
PumpInterface pump = ConfigBuilderPlugin.getActivePump();
|
||||
if (pump != null) {
|
||||
PumpDescription description = pump.getPumpDescription();
|
||||
for (int i = 0; i < basal_v.size(); i++) {
|
||||
|
@ -413,6 +416,8 @@ public class Profile {
|
|||
}
|
||||
|
||||
public String getBasalList() {
|
||||
if (basal_v == null)
|
||||
basal_v = convertToSparseArray(basal);
|
||||
return getValuesList(basal_v, null, new DecimalFormat("0.00"), "U");
|
||||
}
|
||||
|
||||
|
@ -439,6 +444,14 @@ public class Profile {
|
|||
return ret;
|
||||
}
|
||||
|
||||
public double getTarget(){
|
||||
return getTarget(secondsFromMidnight(System.currentTimeMillis()));
|
||||
}
|
||||
|
||||
private double getTarget(Integer time) {
|
||||
return (getTargetLow(time) + getTargetHigh(time))/2;
|
||||
}
|
||||
|
||||
public Double getTargetLow() {
|
||||
return getTargetLow(secondsFromMidnight(System.currentTimeMillis()));
|
||||
}
|
||||
|
|
|
@ -116,7 +116,7 @@ public class PumpEnactResult {
|
|||
}
|
||||
|
||||
public Spanned toSpanned() {
|
||||
String ret = MainApp.sResources.getString(R.string.success) + ": " + success;
|
||||
String ret = "<b>" + MainApp.sResources.getString(R.string.success) + "</b>: " + success;
|
||||
if (queued) {
|
||||
ret = MainApp.sResources.getString(R.string.waitingforpumpresult);
|
||||
} else if (enacted) {
|
||||
|
@ -124,17 +124,20 @@ public class PumpEnactResult {
|
|||
ret += "<br><b>" + MainApp.sResources.getString(R.string.enacted) + "</b>: " + enacted;
|
||||
ret += "<br><b>" + MainApp.sResources.getString(R.string.comment) + "</b>: " + comment +
|
||||
"<br>" + MainApp.sResources.getString(R.string.canceltemp);
|
||||
} else if (isPercent) {
|
||||
} else if (isPercent && percent != -1) {
|
||||
ret += "<br><b>" + MainApp.sResources.getString(R.string.enacted) + "</b>: " + enacted;
|
||||
ret += "<br><b>" + MainApp.sResources.getString(R.string.comment) + "</b>: " + comment;
|
||||
ret += "<br><b>" + MainApp.sResources.getString(R.string.duration) + "</b>: " + duration + " min";
|
||||
ret += "<br><b>" + MainApp.sResources.getString(R.string.percent) + "</b>: " + percent + "%";
|
||||
} else {
|
||||
} else if (absolute != -1) {
|
||||
ret += "<br><b>" + MainApp.sResources.getString(R.string.enacted) + "</b>: " + enacted;
|
||||
ret += "<br><b>" + MainApp.sResources.getString(R.string.comment) + "</b>: " + comment;
|
||||
ret += "<br><b>" + MainApp.sResources.getString(R.string.duration) + "</b>: " + duration + " min";
|
||||
ret += "<br><b>" + MainApp.sResources.getString(R.string.absolute) + "</b>: " + DecimalFormatter.to2Decimal(absolute) + " U/h";
|
||||
}
|
||||
if (bolusDelivered > 0) {
|
||||
ret += "<br><b>" + MainApp.sResources.getString(R.string.bolus) + "</b>: " + DecimalFormatter.to2Decimal(bolusDelivered) + " U";
|
||||
}
|
||||
} else {
|
||||
ret += "<br><b>" + MainApp.sResources.getString(R.string.comment) + "</b>: " + comment;
|
||||
}
|
||||
|
|
|
@ -82,9 +82,9 @@ public class QuickWizardEntry {
|
|||
double cob = 0d;
|
||||
AutosensData autosensData;
|
||||
if (_synchronized)
|
||||
autosensData = IobCobCalculatorPlugin.getLastAutosensDataSynchronized("QuickWizard COB");
|
||||
autosensData = IobCobCalculatorPlugin.getPlugin().getLastAutosensDataSynchronized("QuickWizard COB");
|
||||
else
|
||||
autosensData = IobCobCalculatorPlugin.getLastAutosensData("QuickWizard COB");
|
||||
autosensData = IobCobCalculatorPlugin.getPlugin().getLastAutosensData("QuickWizard COB");
|
||||
|
||||
if (autosensData != null && useCOB() == YES) {
|
||||
cob = autosensData.cob;
|
||||
|
|
|
@ -17,7 +17,6 @@ import info.nightscout.androidaps.plugins.NSClientInternal.data.NSSgv;
|
|||
import info.nightscout.androidaps.plugins.Overview.OverviewPlugin;
|
||||
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.DecimalFormatter;
|
||||
import info.nightscout.utils.SP;
|
||||
|
||||
|
@ -43,7 +42,11 @@ public class BgReading implements DataPointWithLabelInterface {
|
|||
@DatabaseField
|
||||
public String _id = null; // NS _id
|
||||
|
||||
public boolean isPrediction = false; // true when drawing predictions as bg points
|
||||
public boolean isCOBPrediction = false; // true when drawing predictions as bg points (COB)
|
||||
public boolean isaCOBPrediction = false; // true when drawing predictions as bg points (aCOB)
|
||||
public boolean isIOBPrediction = false; // true when drawing predictions as bg points (IOB)
|
||||
public boolean isUAMPrediction = false; // true when drawing predictions as bg points (UAM)
|
||||
public boolean isZTPrediction = false; // true when drawing predictions as bg points (ZT)
|
||||
|
||||
public BgReading() {
|
||||
}
|
||||
|
@ -184,7 +187,10 @@ public class BgReading implements DataPointWithLabelInterface {
|
|||
|
||||
@Override
|
||||
public PointsWithLabelGraphSeries.Shape getShape() {
|
||||
return PointsWithLabelGraphSeries.Shape.POINT;
|
||||
if (isPrediction())
|
||||
return PointsWithLabelGraphSeries.Shape.PREDICTION;
|
||||
else
|
||||
return PointsWithLabelGraphSeries.Shape.BG;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -205,7 +211,7 @@ public class BgReading implements DataPointWithLabelInterface {
|
|||
highLine = Profile.fromMgdlToUnits(OverviewPlugin.bgTargetHigh, units);
|
||||
}
|
||||
int color = MainApp.sResources.getColor(R.color.inrange);
|
||||
if (isPrediction)
|
||||
if (isPrediction())
|
||||
color = MainApp.sResources.getColor(R.color.prediction);
|
||||
else if (valueToUnits(units) < lowLine)
|
||||
color = MainApp.sResources.getColor(R.color.low);
|
||||
|
@ -214,4 +220,23 @@ public class BgReading implements DataPointWithLabelInterface {
|
|||
return color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSecondColor() {
|
||||
if (isIOBPrediction)
|
||||
return MainApp.sResources.getColor(R.color.iob);
|
||||
if (isCOBPrediction)
|
||||
return MainApp.sResources.getColor(R.color.cob);
|
||||
if (isaCOBPrediction)
|
||||
return 0x80FFFFFF & MainApp.sResources.getColor(R.color.cob);
|
||||
if (isUAMPrediction)
|
||||
return MainApp.sResources.getColor(R.color.uam);
|
||||
if (isZTPrediction)
|
||||
return MainApp.sResources.getColor(R.color.zt);
|
||||
return R.color.mdtp_white;
|
||||
}
|
||||
|
||||
private boolean isPrediction() {
|
||||
return isaCOBPrediction || isCOBPrediction || isIOBPrediction || isUAMPrediction || isZTPrediction;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -254,4 +254,9 @@ public class CareportalEvent implements DataPointWithLabelInterface {
|
|||
return Color.GRAY;
|
||||
return Color.GRAY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSecondColor() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import android.support.annotation.Nullable;
|
|||
import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper;
|
||||
import com.j256.ormlite.dao.CloseableIterator;
|
||||
import com.j256.ormlite.dao.Dao;
|
||||
import com.j256.ormlite.dao.DaoManager;
|
||||
import com.j256.ormlite.stmt.PreparedQuery;
|
||||
import com.j256.ormlite.stmt.QueryBuilder;
|
||||
import com.j256.ormlite.stmt.Where;
|
||||
|
@ -35,7 +36,6 @@ import info.nightscout.androidaps.data.Profile;
|
|||
import info.nightscout.androidaps.data.ProfileStore;
|
||||
import info.nightscout.androidaps.events.EventCareportalEventChange;
|
||||
import info.nightscout.androidaps.events.EventExtendedBolusChange;
|
||||
import info.nightscout.androidaps.events.EventFoodDatabaseChanged;
|
||||
import info.nightscout.androidaps.events.EventNewBG;
|
||||
import info.nightscout.androidaps.events.EventProfileSwitchChange;
|
||||
import info.nightscout.androidaps.events.EventRefreshOverview;
|
||||
|
@ -55,6 +55,14 @@ import info.nightscout.utils.DateUtil;
|
|||
import info.nightscout.utils.NSUpload;
|
||||
import info.nightscout.utils.PercentageSplitter;
|
||||
|
||||
/**
|
||||
* This Helper contains all resource to provide a central DB management functionality. Only methods handling
|
||||
* data-structure (and not the DB content) should be contained in here (meaning DDL and not SQL).
|
||||
*
|
||||
* This class can safely be called from Services, but should not call Services to avoid circular dependencies.
|
||||
* One major issue with this (right now) are the scheduled events, which are put into the service. Therefor all
|
||||
* direct calls to the corresponding methods (eg. resetDatabases) should be done by a central service.
|
||||
*/
|
||||
public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||
private static Logger log = LoggerFactory.getLogger(DatabaseHelper.class);
|
||||
|
||||
|
@ -68,7 +76,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
public static final String DATABASE_DBREQUESTS = "DBRequests";
|
||||
public static final String DATABASE_CAREPORTALEVENTS = "CareportalEvents";
|
||||
public static final String DATABASE_PROFILESWITCHES = "ProfileSwitches";
|
||||
public static final String DATABASE_FOODS = "Foods";
|
||||
|
||||
private static final int DATABASE_VERSION = 8;
|
||||
|
||||
|
@ -95,7 +102,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
private static final ScheduledExecutorService profileSwitchEventWorker = Executors.newSingleThreadScheduledExecutor();
|
||||
private static ScheduledFuture<?> scheduledProfileSwitchEventPost = null;
|
||||
|
||||
public FoodHelper foodHelper = new FoodHelper(this);
|
||||
private int oldVersion = 0;
|
||||
private int newVersion = 0;
|
||||
|
||||
public DatabaseHelper(Context context) {
|
||||
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||
|
@ -116,7 +124,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
TableUtils.createTableIfNotExists(connectionSource, ExtendedBolus.class);
|
||||
TableUtils.createTableIfNotExists(connectionSource, CareportalEvent.class);
|
||||
TableUtils.createTableIfNotExists(connectionSource, ProfileSwitch.class);
|
||||
TableUtils.createTableIfNotExists(connectionSource, Food.class);
|
||||
} catch (SQLException e) {
|
||||
log.error("Can't create database", e);
|
||||
throw new RuntimeException(e);
|
||||
|
@ -126,6 +133,9 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
@Override
|
||||
public void onUpgrade(SQLiteDatabase database, ConnectionSource connectionSource, int oldVersion, int newVersion) {
|
||||
try {
|
||||
this.oldVersion = oldVersion;
|
||||
this.newVersion = newVersion;
|
||||
|
||||
if (oldVersion == 7 && newVersion == 8) {
|
||||
log.debug("Upgrading database from v7 to v8");
|
||||
TableUtils.dropTable(connectionSource, Treatment.class, true);
|
||||
|
@ -141,7 +151,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
TableUtils.dropTable(connectionSource, ExtendedBolus.class, true);
|
||||
TableUtils.dropTable(connectionSource, CareportalEvent.class, true);
|
||||
TableUtils.dropTable(connectionSource, ProfileSwitch.class, true);
|
||||
TableUtils.dropTable(connectionSource, Food.class, true);
|
||||
onCreate(database, connectionSource);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
|
@ -150,6 +159,14 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
}
|
||||
}
|
||||
|
||||
public int getOldVersion() {
|
||||
return oldVersion;
|
||||
}
|
||||
|
||||
public int getNewVersion() {
|
||||
return newVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the database connections and clear any cached DAOs.
|
||||
*/
|
||||
|
@ -219,20 +236,18 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
TableUtils.createTableIfNotExists(connectionSource, ExtendedBolus.class);
|
||||
TableUtils.createTableIfNotExists(connectionSource, CareportalEvent.class);
|
||||
TableUtils.createTableIfNotExists(connectionSource, ProfileSwitch.class);
|
||||
foodHelper.resetFood();
|
||||
updateEarliestDataChange(0);
|
||||
} catch (SQLException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
VirtualPumpPlugin.setFakingStatus(true);
|
||||
scheduleBgChange(); // trigger refresh
|
||||
scheduleBgChange(null); // trigger refresh
|
||||
scheduleTemporaryBasalChange();
|
||||
scheduleTreatmentChange();
|
||||
scheduleTreatmentChange(null);
|
||||
scheduleExtendedBolusChange();
|
||||
scheduleTemporaryTargetChange();
|
||||
scheduleCareportalEventChange();
|
||||
scheduleProfileSwitchChange();
|
||||
foodHelper.scheduleFoodChange();
|
||||
new java.util.Timer().schedule(
|
||||
new java.util.TimerTask() {
|
||||
@Override
|
||||
|
@ -252,7 +267,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
} catch (SQLException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
scheduleTreatmentChange();
|
||||
scheduleTreatmentChange(null);
|
||||
}
|
||||
|
||||
public void resetTempTargets() {
|
||||
|
@ -308,6 +323,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
scheduleProfileSwitchChange();
|
||||
}
|
||||
|
||||
|
||||
// ------------------ getDao -------------------------------------------
|
||||
|
||||
private Dao<TempTarget, Long> getDaoTempTargets() throws SQLException {
|
||||
|
@ -358,7 +374,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
if (old == null) {
|
||||
getDaoBgReadings().create(bgReading);
|
||||
log.debug("BG: New record from: " + from + " " + bgReading.toString());
|
||||
scheduleBgChange();
|
||||
scheduleBgChange(bgReading);
|
||||
return true;
|
||||
}
|
||||
if (!old.isEqual(bgReading)) {
|
||||
|
@ -366,7 +382,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
old.copyFrom(bgReading);
|
||||
getDaoBgReadings().update(old);
|
||||
log.debug("BG: Updating record from: " + from + " New data: " + old.toString());
|
||||
scheduleBgChange();
|
||||
scheduleBgChange(bgReading);
|
||||
return false;
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
|
@ -384,11 +400,11 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
}
|
||||
}
|
||||
|
||||
private static void scheduleBgChange() {
|
||||
private static void scheduleBgChange(@Nullable final BgReading bgReading) {
|
||||
class PostRunnable implements Runnable {
|
||||
public void run() {
|
||||
log.debug("Firing EventNewBg");
|
||||
MainApp.bus().post(new EventNewBG());
|
||||
MainApp.bus().post(new EventNewBG(bgReading));
|
||||
scheduledBgPost = null;
|
||||
}
|
||||
}
|
||||
|
@ -563,7 +579,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
getDaoTreatments().create(treatment);
|
||||
log.debug("TREATMENT: New record from: " + Source.getString(treatment.source) + " " + treatment.toString());
|
||||
updateEarliestDataChange(treatment.date);
|
||||
scheduleTreatmentChange();
|
||||
scheduleTreatmentChange(treatment);
|
||||
return true;
|
||||
}
|
||||
if (treatment.source == Source.NIGHTSCOUT) {
|
||||
|
@ -580,7 +596,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
updateEarliestDataChange(oldDate);
|
||||
updateEarliestDataChange(old.date);
|
||||
}
|
||||
scheduleTreatmentChange();
|
||||
scheduleTreatmentChange(treatment);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -605,7 +621,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
updateEarliestDataChange(oldDate);
|
||||
updateEarliestDataChange(old.date);
|
||||
}
|
||||
scheduleTreatmentChange();
|
||||
scheduleTreatmentChange(treatment);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -613,14 +629,14 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
getDaoTreatments().create(treatment);
|
||||
log.debug("TREATMENT: New record from: " + Source.getString(treatment.source) + " " + treatment.toString());
|
||||
updateEarliestDataChange(treatment.date);
|
||||
scheduleTreatmentChange();
|
||||
scheduleTreatmentChange(treatment);
|
||||
return true;
|
||||
}
|
||||
if (treatment.source == Source.USER) {
|
||||
getDaoTreatments().create(treatment);
|
||||
log.debug("TREATMENT: New record from: " + Source.getString(treatment.source) + " " + treatment.toString());
|
||||
updateEarliestDataChange(treatment.date);
|
||||
scheduleTreatmentChange();
|
||||
scheduleTreatmentChange(treatment);
|
||||
return true;
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
|
@ -636,7 +652,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
} catch (SQLException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
scheduleTreatmentChange();
|
||||
scheduleTreatmentChange(treatment);
|
||||
}
|
||||
|
||||
public void update(Treatment treatment) {
|
||||
|
@ -646,7 +662,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
} catch (SQLException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
scheduleTreatmentChange();
|
||||
scheduleTreatmentChange(treatment);
|
||||
}
|
||||
|
||||
public void deleteTreatmentById(String _id) {
|
||||
|
@ -655,12 +671,12 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
log.debug("TREATMENT: Removing Treatment record from database: " + stored.toString());
|
||||
delete(stored);
|
||||
updateEarliestDataChange(stored.date);
|
||||
scheduleTreatmentChange();
|
||||
scheduleTreatmentChange(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Treatment findTreatmentById(String _id) {
|
||||
private Treatment findTreatmentById(String _id) {
|
||||
try {
|
||||
Dao<Treatment, Long> daoTreatments = getDaoTreatments();
|
||||
QueryBuilder<Treatment, Long> queryBuilder = daoTreatments.queryBuilder();
|
||||
|
@ -692,11 +708,11 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
}
|
||||
}
|
||||
|
||||
private static void scheduleTreatmentChange() {
|
||||
private static void scheduleTreatmentChange(@Nullable final Treatment treatment) {
|
||||
class PostRunnable implements Runnable {
|
||||
public void run() {
|
||||
log.debug("Firing EventTreatmentChange");
|
||||
MainApp.bus().post(new EventReloadTreatmentData(new EventTreatmentChange()));
|
||||
MainApp.bus().post(new EventReloadTreatmentData(new EventTreatmentChange(treatment)));
|
||||
if (earliestDataChange != null)
|
||||
MainApp.bus().post(new EventNewHistoryData(earliestDataChange));
|
||||
earliestDataChange = null;
|
||||
|
@ -1742,4 +1758,4 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
}
|
||||
|
||||
// ---------------- Food handling ---------------
|
||||
}
|
||||
}
|
||||
|
|
|
@ -285,4 +285,9 @@ public class ExtendedBolus implements Interval, DataPointWithLabelInterface {
|
|||
public int getColor() {
|
||||
return Color.CYAN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSecondColor() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,208 +0,0 @@
|
|||
package info.nightscout.androidaps.db;
|
||||
|
||||
import com.j256.ormlite.android.AndroidConnectionSource;
|
||||
import com.j256.ormlite.dao.Dao;
|
||||
import com.j256.ormlite.stmt.PreparedQuery;
|
||||
import com.j256.ormlite.stmt.QueryBuilder;
|
||||
import com.j256.ormlite.stmt.Where;
|
||||
import com.j256.ormlite.table.TableUtils;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.events.EventFoodDatabaseChanged;
|
||||
|
||||
/**
|
||||
* Created by mike on 24.09.2017.
|
||||
*/
|
||||
|
||||
public class FoodHelper {
|
||||
private static Logger log = LoggerFactory.getLogger(FoodHelper.class);
|
||||
|
||||
DatabaseHelper databaseHelper;
|
||||
|
||||
private static final ScheduledExecutorService foodEventWorker = Executors.newSingleThreadScheduledExecutor();
|
||||
private static ScheduledFuture<?> scheduledFoodEventPost = null;
|
||||
|
||||
public FoodHelper(DatabaseHelper databaseHelper) {
|
||||
this.databaseHelper = databaseHelper;
|
||||
}
|
||||
|
||||
private Dao<Food, Long> getDaoFood() throws SQLException {
|
||||
return databaseHelper.getDao(Food.class);
|
||||
}
|
||||
|
||||
public void resetFood() {
|
||||
try {
|
||||
TableUtils.dropTable(databaseHelper.getConnectionSource(), Food.class, true);
|
||||
TableUtils.createTableIfNotExists(databaseHelper.getConnectionSource(), Food.class);
|
||||
} catch (SQLException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
scheduleFoodChange();
|
||||
}
|
||||
|
||||
public List<Food> getFoodData() {
|
||||
try {
|
||||
Dao<Food, Long> daoFood = getDaoFood();
|
||||
List<Food> foods;
|
||||
QueryBuilder<Food, Long> queryBuilder = daoFood.queryBuilder();
|
||||
PreparedQuery<Food> preparedQuery = queryBuilder.prepare();
|
||||
foods = daoFood.query(preparedQuery);
|
||||
return foods;
|
||||
} catch (SQLException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
public boolean createOrUpdate(Food food) {
|
||||
try {
|
||||
// find by NS _id
|
||||
if (food._id != null && !food._id.equals("")) {
|
||||
Food old;
|
||||
|
||||
QueryBuilder<Food, Long> queryBuilder = getDaoFood().queryBuilder();
|
||||
Where where = queryBuilder.where();
|
||||
where.eq("_id", food._id);
|
||||
PreparedQuery<Food> preparedQuery = queryBuilder.prepare();
|
||||
List<Food> found = getDaoFood().query(preparedQuery);
|
||||
if (found.size() > 0) {
|
||||
old = found.get(0);
|
||||
if (!old.isEqual(food)) {
|
||||
getDaoFood().delete(old); // need to delete/create because date may change too
|
||||
old.copyFrom(food);
|
||||
getDaoFood().create(old);
|
||||
log.debug("FOOD: Updating record by _id: " + old.toString());
|
||||
scheduleFoodChange();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
getDaoFood().createOrUpdate(food);
|
||||
log.debug("FOOD: New record: " + food.toString());
|
||||
scheduleFoodChange();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void delete(Food food) {
|
||||
try {
|
||||
getDaoFood().delete(food);
|
||||
scheduleFoodChange();
|
||||
} catch (SQLException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void scheduleFoodChange() {
|
||||
class PostRunnable implements Runnable {
|
||||
public void run() {
|
||||
log.debug("Firing EventFoodChange");
|
||||
MainApp.bus().post(new EventFoodDatabaseChanged());
|
||||
scheduledFoodEventPost = null;
|
||||
}
|
||||
}
|
||||
// prepare task for execution in 1 sec
|
||||
// cancel waiting task to prevent sending multiple posts
|
||||
if (scheduledFoodEventPost != null)
|
||||
scheduledFoodEventPost.cancel(false);
|
||||
Runnable task = new PostRunnable();
|
||||
final int sec = 1;
|
||||
scheduledFoodEventPost = foodEventWorker.schedule(task, sec, TimeUnit.SECONDS);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
{
|
||||
"_id": "551ee3ad368e06e80856e6a9",
|
||||
"type": "food",
|
||||
"category": "Zakladni",
|
||||
"subcategory": "Napoje",
|
||||
"name": "Mleko",
|
||||
"portion": 250,
|
||||
"carbs": 12,
|
||||
"gi": 1,
|
||||
"created_at": "2015-04-14T06:59:16.500Z",
|
||||
"unit": "ml"
|
||||
}
|
||||
*/
|
||||
public void createFoodFromJsonIfNotExists(JSONObject trJson) {
|
||||
try {
|
||||
Food food = new Food();
|
||||
if (trJson.has("type") && trJson.getString("type").equals("food")) {
|
||||
if (trJson.has("_id"))
|
||||
food._id = trJson.getString("_id");
|
||||
if (trJson.has("category"))
|
||||
food.category = trJson.getString("category");
|
||||
if (trJson.has("subcategory"))
|
||||
food.subcategory = trJson.getString("subcategory");
|
||||
if (trJson.has("name"))
|
||||
food.name = trJson.getString("name");
|
||||
if (trJson.has("unit"))
|
||||
food.units = trJson.getString("unit");
|
||||
if (trJson.has("portion"))
|
||||
food.portion = trJson.getDouble("portion");
|
||||
if (trJson.has("carbs"))
|
||||
food.carbs = trJson.getInt("carbs");
|
||||
if (trJson.has("gi"))
|
||||
food.gi = trJson.getInt("gi");
|
||||
if (trJson.has("energy"))
|
||||
food.energy = trJson.getInt("energy");
|
||||
if (trJson.has("protein"))
|
||||
food.protein = trJson.getInt("protein");
|
||||
if (trJson.has("fat"))
|
||||
food.fat = trJson.getInt("fat");
|
||||
}
|
||||
createOrUpdate(food);
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteFoodById(String _id) {
|
||||
Food stored = findFoodById(_id);
|
||||
if (stored != null) {
|
||||
log.debug("FOOD: Removing Food record from database: " + stored.toString());
|
||||
delete(stored);
|
||||
scheduleFoodChange();
|
||||
}
|
||||
}
|
||||
|
||||
public Food findFoodById(String _id) {
|
||||
try {
|
||||
QueryBuilder<Food, Long> queryBuilder = getDaoFood().queryBuilder();
|
||||
Where where = queryBuilder.where();
|
||||
where.eq("_id", _id);
|
||||
PreparedQuery<Food> preparedQuery = queryBuilder.prepare();
|
||||
List<Food> list = getDaoFood().query(preparedQuery);
|
||||
|
||||
if (list.size() == 1) {
|
||||
return list.get(0);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package info.nightscout.androidaps.db;
|
||||
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
|
||||
/**
|
||||
* Created by triplem on 05.01.18.
|
||||
*/
|
||||
|
||||
public interface ICallback {
|
||||
|
||||
void setPost(ScheduledFuture<?> post);
|
||||
|
||||
ScheduledFuture<?> getPost();
|
||||
|
||||
}
|
|
@ -238,6 +238,11 @@ public class ProfileSwitch implements Interval, DataPointWithLabelInterface {
|
|||
return Color.CYAN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSecondColor() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "ProfileSwitch{" +
|
||||
"date=" + date +
|
||||
|
|
|
@ -41,6 +41,10 @@ public class TempTarget implements Interval {
|
|||
@DatabaseField
|
||||
public int durationInMinutes;
|
||||
|
||||
public double target() {
|
||||
return (low + high) / 2;
|
||||
}
|
||||
|
||||
public boolean isEqual(TempTarget other) {
|
||||
if (date != other.date) {
|
||||
return false;
|
||||
|
|
|
@ -325,13 +325,13 @@ public class TemporaryBasal implements Interval {
|
|||
if(profile != null) {
|
||||
double basal = profile.getBasal();
|
||||
if(basal != 0){
|
||||
return Math.round(rate*100d/basal) + "% ";
|
||||
return Math.round(rate*100d/basal) + "%";
|
||||
}
|
||||
}
|
||||
}
|
||||
return DecimalFormatter.to2Decimal(rate) + "U/h ";
|
||||
return DecimalFormatter.to2Decimal(rate) + "U/h";
|
||||
} else { // percent
|
||||
return percentRate + "% ";
|
||||
return percentRate + "%";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,9 +12,11 @@ import java.util.Objects;
|
|||
|
||||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.Iob;
|
||||
import info.nightscout.androidaps.interfaces.InsulinInterface;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.Overview.OverviewPlugin;
|
||||
import info.nightscout.androidaps.plugins.Overview.graphExtensions.DataPointWithLabelInterface;
|
||||
import info.nightscout.androidaps.plugins.Overview.graphExtensions.PointsWithLabelGraphSeries;
|
||||
import info.nightscout.utils.DateUtil;
|
||||
|
@ -120,7 +122,7 @@ public class Treatment implements DataPointWithLabelInterface {
|
|||
|
||||
@Override
|
||||
public double getY() {
|
||||
return yValue;
|
||||
return isSMB ? OverviewPlugin.getPlugin().determineLowLine() : yValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -139,7 +141,10 @@ public class Treatment implements DataPointWithLabelInterface {
|
|||
|
||||
@Override
|
||||
public PointsWithLabelGraphSeries.Shape getShape() {
|
||||
return PointsWithLabelGraphSeries.Shape.BOLUS;
|
||||
if (isSMB)
|
||||
return PointsWithLabelGraphSeries.Shape.SMB;
|
||||
else
|
||||
return PointsWithLabelGraphSeries.Shape.BOLUS;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -149,12 +154,19 @@ public class Treatment implements DataPointWithLabelInterface {
|
|||
|
||||
@Override
|
||||
public int getColor() {
|
||||
if (isValid)
|
||||
if (isSMB)
|
||||
return MainApp.sResources.getColor(R.color.tempbasal);
|
||||
else if (isValid)
|
||||
return Color.CYAN;
|
||||
else
|
||||
return MainApp.instance().getResources().getColor(android.R.color.holo_red_light);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSecondColor() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setY(double y) {
|
||||
yValue = y;
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
package info.nightscout.androidaps.events;
|
||||
|
||||
/**
|
||||
* Created by mike on 13.02.2018.
|
||||
*/
|
||||
|
||||
public class EventCustomCalculationFinished extends Event {
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package info.nightscout.androidaps.events;
|
||||
|
||||
/**
|
||||
* Created by jamorham on 07/02/2018.
|
||||
*
|
||||
* Event to indicate that an app feature is being used, for example bolus wizard being opened
|
||||
*
|
||||
* The purpose this has been created for is to enable opportunistic connection to the pump
|
||||
* so that it is already connected before the user wishes to enact a pump function
|
||||
*
|
||||
*/
|
||||
|
||||
public class EventFeatureRunning extends Event {
|
||||
|
||||
private Feature feature = Feature.UNKNOWN;
|
||||
|
||||
public EventFeatureRunning() {
|
||||
}
|
||||
|
||||
public EventFeatureRunning(Feature feature) {
|
||||
this.feature = feature;
|
||||
}
|
||||
|
||||
public Feature getFeature() {
|
||||
return feature;
|
||||
}
|
||||
|
||||
public enum Feature {
|
||||
UNKNOWN,
|
||||
MAIN,
|
||||
WIZARD,
|
||||
|
||||
JUST_ADD_MORE_HERE
|
||||
}
|
||||
|
||||
}
|
|
@ -1,7 +1,17 @@
|
|||
package info.nightscout.androidaps.events;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import info.nightscout.androidaps.db.BgReading;
|
||||
|
||||
/**
|
||||
* Created by mike on 05.06.2016.
|
||||
*/
|
||||
public class EventNewBG extends EventLoop {
|
||||
@Nullable
|
||||
public final BgReading bgReading;
|
||||
|
||||
public EventNewBG(BgReading bgReading) {
|
||||
this.bgReading = bgReading;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
package info.nightscout.androidaps.events;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
/**
|
||||
* Event which is published with data fetched from NightScout specific for the
|
||||
* Food-class.
|
||||
*
|
||||
* Payload is the from NS retrieved JSON-String which should be handled by all
|
||||
* subscriber.
|
||||
*/
|
||||
|
||||
public class EventNsFood extends Event {
|
||||
|
||||
public static final int ADD = 0;
|
||||
public static final int UPDATE = 1;
|
||||
public static final int REMOVE = 2;
|
||||
|
||||
private final int mode;
|
||||
|
||||
private final Bundle payload;
|
||||
|
||||
public EventNsFood(int mode, Bundle payload) {
|
||||
this.mode = mode;
|
||||
this.payload = payload;
|
||||
}
|
||||
|
||||
public int getMode() {
|
||||
return mode;
|
||||
}
|
||||
|
||||
public Bundle getPayload() {
|
||||
return payload;
|
||||
}
|
||||
}
|
|
@ -1,7 +1,17 @@
|
|||
package info.nightscout.androidaps.events;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import info.nightscout.androidaps.db.Treatment;
|
||||
|
||||
/**
|
||||
* Created by mike on 04.06.2016.
|
||||
*/
|
||||
public class EventTreatmentChange extends EventLoop {
|
||||
@Nullable
|
||||
public final Treatment treatment;
|
||||
|
||||
public EventTreatmentChange(Treatment treatment) {
|
||||
this.treatment = treatment;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,4 +4,5 @@ package info.nightscout.androidaps.interfaces;
|
|||
* Created by mike on 20.06.2016.
|
||||
*/
|
||||
public interface BgSourceInterface {
|
||||
boolean advancedFilteringSupported();
|
||||
}
|
||||
|
|
|
@ -10,16 +10,16 @@ import info.nightscout.androidaps.db.Treatment;
|
|||
*/
|
||||
|
||||
public interface InsulinInterface {
|
||||
final int FASTACTINGINSULIN = 0;
|
||||
final int FASTACTINGINSULINPROLONGED = 1;
|
||||
final int OREF_RAPID_ACTING = 2;
|
||||
final int OREF_ULTRA_RAPID_ACTING = 3;
|
||||
final int OREF_FREE_PEAK = 4;
|
||||
int FASTACTINGINSULIN = 0;
|
||||
int FASTACTINGINSULINPROLONGED = 1;
|
||||
int OREF_RAPID_ACTING = 2;
|
||||
int OREF_ULTRA_RAPID_ACTING = 3;
|
||||
int OREF_FREE_PEAK = 4;
|
||||
|
||||
|
||||
int getId();
|
||||
String getFriendlyName();
|
||||
String getComment();
|
||||
double getDia();
|
||||
public Iob iobCalcForTreatment(Treatment treatment, long time, double dia);
|
||||
Iob iobCalcForTreatment(Treatment treatment, long time, double dia);
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@ public class PumpDescription {
|
|||
public double tempAbsoluteStep = 0.05d;
|
||||
|
||||
public int tempDurationStep = 60;
|
||||
public boolean tempDurationStep15mAllowed = false;
|
||||
public boolean tempDurationStep30mAllowed = false;
|
||||
public int tempMaxDuration = 12 * 60;
|
||||
|
||||
|
||||
|
@ -37,4 +39,6 @@ public class PumpDescription {
|
|||
public boolean isRefillingCapable = false;
|
||||
|
||||
public boolean storesCarbInfo = true;
|
||||
|
||||
public boolean is30minBasalRatesCapable = false;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ public interface TreatmentsInterface {
|
|||
|
||||
List<Treatment> getTreatmentsFromHistory();
|
||||
List<Treatment> getTreatments5MinBackFromHistory(long time);
|
||||
long getLastBolusTime();
|
||||
|
||||
// real basals (not faked by extended bolus)
|
||||
boolean isInHistoryRealTempBasalInProgress();
|
||||
|
|
|
@ -9,8 +9,7 @@ import android.view.LayoutInflater;
|
|||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.crashlytics.android.Crashlytics;
|
||||
import com.crashlytics.android.answers.Answers;
|
||||
|
||||
import com.crashlytics.android.answers.CustomEvent;
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
|
@ -32,6 +31,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.utils.FabricPrivacy;
|
||||
import info.nightscout.utils.SingleClickButton;
|
||||
|
||||
/**
|
||||
|
@ -83,7 +83,7 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL
|
|||
updateGUI();
|
||||
return view;
|
||||
} catch (Exception e) {
|
||||
Crashlytics.logException(e);
|
||||
FabricPrivacy.logException(e);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -137,11 +137,11 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL
|
|||
extendedBolus.setVisibility(View.GONE);
|
||||
extendedBolusCancel.setVisibility(View.GONE);
|
||||
} else {
|
||||
if (MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) {
|
||||
ExtendedBolus activeExtendedBolus = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis());
|
||||
if (activeExtendedBolus != null) {
|
||||
extendedBolus.setVisibility(View.GONE);
|
||||
extendedBolusCancel.setVisibility(View.VISIBLE);
|
||||
ExtendedBolus running = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis());
|
||||
extendedBolusCancel.setText(MainApp.instance().getString(R.string.cancel) + " " + running.toString());
|
||||
extendedBolusCancel.setText(MainApp.instance().getString(R.string.cancel) + " " + activeExtendedBolus.toString());
|
||||
} else {
|
||||
extendedBolus.setVisibility(View.VISIBLE);
|
||||
extendedBolusCancel.setVisibility(View.GONE);
|
||||
|
@ -153,10 +153,10 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL
|
|||
tempBasal.setVisibility(View.GONE);
|
||||
tempBasalCancel.setVisibility(View.GONE);
|
||||
} else {
|
||||
if (MainApp.getConfigBuilder().isTempBasalInProgress()) {
|
||||
final TemporaryBasal activeTemp = MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis());
|
||||
if (activeTemp != null) {
|
||||
tempBasal.setVisibility(View.GONE);
|
||||
tempBasalCancel.setVisibility(View.VISIBLE);
|
||||
final TemporaryBasal activeTemp = MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis());
|
||||
tempBasalCancel.setText(MainApp.instance().getString(R.string.cancel) + " " + activeTemp.toStringShort());
|
||||
} else {
|
||||
tempBasal.setVisibility(View.VISIBLE);
|
||||
|
@ -203,13 +203,13 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL
|
|||
case R.id.actions_extendedbolus_cancel:
|
||||
if (MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) {
|
||||
ConfigBuilderPlugin.getCommandQueue().cancelExtended(null);
|
||||
Answers.getInstance().logCustom(new CustomEvent("CancelExtended"));
|
||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("CancelExtended"));
|
||||
}
|
||||
break;
|
||||
case R.id.actions_canceltempbasal:
|
||||
if (MainApp.getConfigBuilder().isTempBasalInProgress()) {
|
||||
ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, null);
|
||||
Answers.getInstance().logCustom(new CustomEvent("CancelTemp"));
|
||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("CancelTemp"));
|
||||
}
|
||||
break;
|
||||
case R.id.actions_settempbasal:
|
||||
|
|
|
@ -14,7 +14,6 @@ import android.view.Window;
|
|||
import android.view.WindowManager;
|
||||
import android.widget.Button;
|
||||
|
||||
import com.crashlytics.android.answers.Answers;
|
||||
import com.crashlytics.android.answers.CustomEvent;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
@ -31,6 +30,7 @@ import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
|||
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.NumberPicker;
|
||||
import info.nightscout.utils.SP;
|
||||
import info.nightscout.utils.SafeParse;
|
||||
|
@ -171,7 +171,7 @@ public class FillDialog extends DialogFragment implements OnClickListener {
|
|||
}
|
||||
}
|
||||
});
|
||||
Answers.getInstance().logCustom(new CustomEvent("Fill"));
|
||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("Fill"));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -10,7 +10,6 @@ import android.view.LayoutInflater;
|
|||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.crashlytics.android.answers.Answers;
|
||||
import com.crashlytics.android.answers.CustomEvent;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
@ -24,6 +23,7 @@ import info.nightscout.androidaps.R;
|
|||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity;
|
||||
import info.nightscout.androidaps.queue.Callback;
|
||||
import info.nightscout.utils.FabricPrivacy;
|
||||
import info.nightscout.utils.NumberPicker;
|
||||
import info.nightscout.utils.SafeParse;
|
||||
|
||||
|
@ -99,7 +99,7 @@ public class NewExtendedBolusDialog extends DialogFragment implements View.OnCli
|
|||
}
|
||||
}
|
||||
});
|
||||
Answers.getInstance().logCustom(new CustomEvent("ExtendedBolus"));
|
||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("ExtendedBolus"));
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton(getString(R.string.cancel), null);
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package info.nightscout.androidaps.plugins.Actions.dialogs;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
|
@ -13,7 +12,6 @@ import android.widget.LinearLayout;
|
|||
import android.widget.RadioButton;
|
||||
import android.widget.RadioGroup;
|
||||
|
||||
import com.crashlytics.android.answers.Answers;
|
||||
import com.crashlytics.android.answers.CustomEvent;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
@ -28,6 +26,7 @@ import info.nightscout.androidaps.interfaces.PumpDescription;
|
|||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity;
|
||||
import info.nightscout.androidaps.queue.Callback;
|
||||
import info.nightscout.utils.FabricPrivacy;
|
||||
import info.nightscout.utils.NumberPicker;
|
||||
import info.nightscout.utils.SafeParse;
|
||||
|
||||
|
@ -162,7 +161,7 @@ public class NewTempBasalDialog extends DialogFragment implements View.OnClickLi
|
|||
} else {
|
||||
ConfigBuilderPlugin.getCommandQueue().tempBasalAbsolute(finalBasal, finalDurationInMinutes, true, callback);
|
||||
}
|
||||
Answers.getInstance().logCustom(new CustomEvent("TempBasal"));
|
||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("TempBasal"));
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton(getString(R.string.cancel), null);
|
||||
|
|
|
@ -10,7 +10,6 @@ import android.view.ViewGroup;
|
|||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.crashlytics.android.Crashlytics;
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
import info.nightscout.androidaps.BuildConfig;
|
||||
|
@ -24,6 +23,7 @@ import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialo
|
|||
import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.Overview.OverviewFragment;
|
||||
import info.nightscout.utils.FabricPrivacy;
|
||||
|
||||
public class CareportalFragment extends SubscriberFragment implements View.OnClickListener {
|
||||
|
||||
|
@ -111,7 +111,7 @@ public class CareportalFragment extends SubscriberFragment implements View.OnCli
|
|||
updateGUI();
|
||||
return view;
|
||||
} catch (Exception e) {
|
||||
Crashlytics.logException(e);
|
||||
FabricPrivacy.logException(e);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
@ -23,7 +23,6 @@ import android.widget.RadioButton;
|
|||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.crashlytics.android.answers.Answers;
|
||||
import com.crashlytics.android.answers.CustomEvent;
|
||||
import com.wdullaer.materialdatetimepicker.date.DatePickerDialog;
|
||||
import com.wdullaer.materialdatetimepicker.time.RadialPickerLayout;
|
||||
|
@ -38,6 +37,7 @@ import java.text.DecimalFormat;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
|
@ -45,6 +45,7 @@ import info.nightscout.androidaps.R;
|
|||
import info.nightscout.androidaps.data.GlucoseStatus;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.data.ProfileStore;
|
||||
import info.nightscout.androidaps.db.BgReading;
|
||||
import info.nightscout.androidaps.db.CareportalEvent;
|
||||
import info.nightscout.androidaps.db.ProfileSwitch;
|
||||
import info.nightscout.androidaps.db.Source;
|
||||
|
@ -54,6 +55,7 @@ import info.nightscout.androidaps.plugins.Careportal.OptionsToShow;
|
|||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity;
|
||||
import info.nightscout.androidaps.queue.Callback;
|
||||
import info.nightscout.utils.FabricPrivacy;
|
||||
import info.nightscout.utils.DateUtil;
|
||||
import info.nightscout.utils.NSUpload;
|
||||
import info.nightscout.utils.NumberPicker;
|
||||
|
@ -407,12 +409,23 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
|
|||
else layout.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
private void updateBGforDateTime() {
|
||||
long millis = eventTime.getTime() - (150 * 1000L); // 2,5 * 60 * 1000
|
||||
List<BgReading> data = MainApp.getDbHelper().getBgreadingsDataFromTime(millis, true);
|
||||
if ((data.size() > 0) &&
|
||||
(data.get(0).date > millis - 7 * 60 * 1000L) &&
|
||||
(data.get(0).date < millis + 7 * 60 * 1000L)) {
|
||||
editBg.setValue(Profile.fromMgdlToUnits(data.get(0).value, profile != null ? profile.getUnits() : Constants.MGDL));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDateSet(DatePickerDialog view, int year, int monthOfYear, int dayOfMonth) {
|
||||
eventTime.setYear(year - 1900);
|
||||
eventTime.setMonth(monthOfYear);
|
||||
eventTime.setDate(dayOfMonth);
|
||||
dateButton.setText(DateUtil.dateString(eventTime));
|
||||
updateBGforDateTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -421,6 +434,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
|
|||
eventTime.setMinutes(minute);
|
||||
eventTime.setSeconds(second);
|
||||
timeButton.setText(DateUtil.timeString(eventTime));
|
||||
updateBGforDateTime();
|
||||
}
|
||||
|
||||
|
||||
|
@ -685,14 +699,14 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
|
|||
log.debug("Creating new TempTarget db record: " + tempTarget.toString());
|
||||
MainApp.getDbHelper().createOrUpdate(tempTarget);
|
||||
NSUpload.uploadCareportalEntryToNS(data);
|
||||
Answers.getInstance().logCustom(new CustomEvent("TempTarget"));
|
||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("TempTarget"));
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
} else {
|
||||
NSUpload.uploadCareportalEntryToNS(data);
|
||||
Answers.getInstance().logCustom(new CustomEvent("NSTreatment"));
|
||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("NSTreatment"));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -727,7 +741,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
|
|||
MainApp.bus().post(new EventNewBasalProfile());
|
||||
}
|
||||
});
|
||||
Answers.getInstance().logCustom(new CustomEvent("ProfileSwitch"));
|
||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("ProfileSwitch"));
|
||||
}
|
||||
|
||||
public static void doProfileSwitch(final int duration, final int percentage, final int timeshift) {
|
||||
|
@ -759,7 +773,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
|
|||
MainApp.bus().post(new EventNewBasalProfile());
|
||||
}
|
||||
});
|
||||
Answers.getInstance().logCustom(new CustomEvent("ProfileSwitch"));
|
||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("ProfileSwitch"));
|
||||
} else {
|
||||
log.error("No profile switch existing");
|
||||
}
|
||||
|
|
|
@ -17,8 +17,7 @@ import android.widget.ListAdapter;
|
|||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.crashlytics.android.Crashlytics;
|
||||
import com.crashlytics.android.answers.Answers;
|
||||
|
||||
import com.crashlytics.android.answers.CustomEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -40,6 +39,7 @@ import info.nightscout.androidaps.plugins.Insulin.InsulinFastactingPlugin;
|
|||
import info.nightscout.androidaps.plugins.ProfileNS.NSProfilePlugin;
|
||||
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
|
||||
import info.nightscout.androidaps.plugins.SensitivityOref0.SensitivityOref0Plugin;
|
||||
import info.nightscout.utils.FabricPrivacy;
|
||||
import info.nightscout.utils.PasswordProtection;
|
||||
|
||||
|
||||
|
@ -131,7 +131,7 @@ public class ConfigBuilderFragment extends Fragment {
|
|||
}
|
||||
return view;
|
||||
} catch (Exception e) {
|
||||
Crashlytics.logException(e);
|
||||
FabricPrivacy.logException(e);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -242,7 +242,7 @@ public class ConfigBuilderFragment extends Fragment {
|
|||
MainApp.bus().post(new EventRefreshGui());
|
||||
MainApp.bus().post(new EventConfigBuilderChange());
|
||||
getPlugin().logPluginStatus();
|
||||
Answers.getInstance().logCustom(new CustomEvent("ConfigurationChange"));
|
||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("ConfigurationChange"));
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -23,8 +23,10 @@ import info.nightscout.androidaps.data.MealData;
|
|||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.data.ProfileIntervals;
|
||||
import info.nightscout.androidaps.data.PumpEnactResult;
|
||||
import info.nightscout.androidaps.db.CareportalEvent;
|
||||
import info.nightscout.androidaps.db.ExtendedBolus;
|
||||
import info.nightscout.androidaps.db.ProfileSwitch;
|
||||
import info.nightscout.androidaps.db.Source;
|
||||
import info.nightscout.androidaps.db.TempTarget;
|
||||
import info.nightscout.androidaps.db.TemporaryBasal;
|
||||
import info.nightscout.androidaps.db.Treatment;
|
||||
|
@ -48,6 +50,7 @@ import info.nightscout.androidaps.queue.Callback;
|
|||
import info.nightscout.androidaps.queue.CommandQueue;
|
||||
import info.nightscout.utils.NSUpload;
|
||||
import info.nightscout.utils.SP;
|
||||
import info.nightscout.utils.ToastUtils;
|
||||
|
||||
/**
|
||||
* Created by mike on 05.08.2016.
|
||||
|
@ -243,96 +246,90 @@ public class ConfigBuilderPlugin implements PluginBase, ConstraintsInterface, Tr
|
|||
ArrayList<PluginBase> pluginsInCategory;
|
||||
|
||||
// PluginBase.APS
|
||||
pluginsInCategory = MainApp.getSpecificPluginsListByInterface(APSInterface.class);
|
||||
activeAPS = (APSInterface) getTheOneEnabledInArray(pluginsInCategory, PluginBase.APS);
|
||||
if (activeAPS != null) {
|
||||
if (Config.logConfigBuilder)
|
||||
log.debug("Selected APS interface: " + ((PluginBase) activeAPS).getName());
|
||||
for (PluginBase p : pluginsInCategory) {
|
||||
if (!p.getName().equals(((PluginBase) activeAPS).getName())) {
|
||||
p.setFragmentVisible(PluginBase.APS, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
activeAPS = this.determineActivePlugin(APSInterface.class, PluginBase.APS);
|
||||
|
||||
// PluginBase.INSULIN
|
||||
pluginsInCategory = MainApp.getSpecificPluginsListByInterface(InsulinInterface.class);
|
||||
activeInsulin = (InsulinInterface) getTheOneEnabledInArray(pluginsInCategory, PluginBase.INSULIN);
|
||||
if (Config.logConfigBuilder)
|
||||
log.debug("Selected insulin interface: " + ((PluginBase) activeInsulin).getName());
|
||||
for (PluginBase p : pluginsInCategory) {
|
||||
if (!p.getName().equals(((PluginBase) activeInsulin).getName())) {
|
||||
p.setFragmentVisible(PluginBase.INSULIN, false);
|
||||
}
|
||||
}
|
||||
activeInsulin = this.determineActivePlugin(InsulinInterface.class, PluginBase.INSULIN);
|
||||
|
||||
// PluginBase.SENSITIVITY
|
||||
pluginsInCategory = MainApp.getSpecificPluginsListByInterface(SensitivityInterface.class);
|
||||
activeSensitivity = (SensitivityInterface) getTheOneEnabledInArray(pluginsInCategory, PluginBase.SENSITIVITY);
|
||||
if (Config.logConfigBuilder)
|
||||
log.debug("Selected sensitivity interface: " + ((PluginBase) activeSensitivity).getName());
|
||||
for (PluginBase p : pluginsInCategory) {
|
||||
if (!p.getName().equals(((PluginBase) activeSensitivity).getName())) {
|
||||
p.setFragmentVisible(PluginBase.SENSITIVITY, false);
|
||||
}
|
||||
}
|
||||
activeSensitivity = this.determineActivePlugin(SensitivityInterface.class, PluginBase.SENSITIVITY);
|
||||
|
||||
// PluginBase.PROFILE
|
||||
pluginsInCategory = MainApp.getSpecificPluginsListByInterface(ProfileInterface.class);
|
||||
activeProfile = (ProfileInterface) getTheOneEnabledInArray(pluginsInCategory, PluginBase.PROFILE);
|
||||
if (Config.logConfigBuilder)
|
||||
log.debug("Selected profile interface: " + ((PluginBase) activeProfile).getName());
|
||||
for (PluginBase p : pluginsInCategory) {
|
||||
if (!p.getName().equals(((PluginBase) activeProfile).getName())) {
|
||||
p.setFragmentVisible(PluginBase.PROFILE, false);
|
||||
}
|
||||
}
|
||||
activeProfile = this.determineActivePlugin(ProfileInterface.class, PluginBase.PROFILE);
|
||||
|
||||
// PluginBase.BGSOURCE
|
||||
pluginsInCategory = MainApp.getSpecificPluginsListByInterface(BgSourceInterface.class);
|
||||
activeBgSource = (BgSourceInterface) getTheOneEnabledInArray(pluginsInCategory, PluginBase.BGSOURCE);
|
||||
if (Config.logConfigBuilder)
|
||||
log.debug("Selected bgSource interface: " + ((PluginBase) activeBgSource).getName());
|
||||
for (PluginBase p : pluginsInCategory) {
|
||||
if (!p.getName().equals(((PluginBase) activeBgSource).getName())) {
|
||||
p.setFragmentVisible(PluginBase.BGSOURCE, false);
|
||||
}
|
||||
}
|
||||
activeBgSource = this.determineActivePlugin(BgSourceInterface.class, PluginBase.BGSOURCE);
|
||||
|
||||
// PluginBase.PUMP
|
||||
pluginsInCategory = MainApp.getSpecificPluginsList(PluginBase.PUMP);
|
||||
activePump = (PumpInterface) getTheOneEnabledInArray(pluginsInCategory, PluginBase.PUMP);
|
||||
if (activePump == null)
|
||||
activePump = VirtualPumpPlugin.getPlugin(); // for NSClient build
|
||||
if (Config.logConfigBuilder)
|
||||
log.debug("Selected pump interface: " + ((PluginBase) activePump).getName());
|
||||
for (PluginBase p : pluginsInCategory) {
|
||||
if (!p.getName().equals(((PluginBase) activePump).getName())) {
|
||||
p.setFragmentVisible(PluginBase.PUMP, false);
|
||||
}
|
||||
}
|
||||
this.setFragmentVisiblities(((PluginBase) activePump).getName(), pluginsInCategory, PluginBase.PUMP);
|
||||
|
||||
// PluginBase.LOOP
|
||||
pluginsInCategory = MainApp.getSpecificPluginsList(PluginBase.LOOP);
|
||||
activeLoop = (LoopPlugin) getTheOneEnabledInArray(pluginsInCategory, PluginBase.LOOP);
|
||||
if (activeLoop != null) {
|
||||
if (Config.logConfigBuilder)
|
||||
log.debug("Selected loop interface: " + activeLoop.getName());
|
||||
for (PluginBase p : pluginsInCategory) {
|
||||
if (!p.getName().equals(activeLoop.getName())) {
|
||||
p.setFragmentVisible(PluginBase.LOOP, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
activeLoop = this.determineActivePlugin(PluginBase.LOOP);
|
||||
|
||||
// PluginBase.TREATMENT
|
||||
pluginsInCategory = MainApp.getSpecificPluginsList(PluginBase.TREATMENT);
|
||||
activeTreatments = (TreatmentsInterface) getTheOneEnabledInArray(pluginsInCategory, PluginBase.TREATMENT);
|
||||
activeTreatments = this.determineActivePlugin(PluginBase.TREATMENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* disables the visibility for all fragments of Plugins with the given PluginType
|
||||
* which are not equally named to the Plugin implementing the given Plugin Interface.
|
||||
*
|
||||
* @param pluginInterface
|
||||
* @param pluginType
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
private <T> T determineActivePlugin(Class<T> pluginInterface, int pluginType) {
|
||||
ArrayList<PluginBase> pluginsInCategory;
|
||||
pluginsInCategory = MainApp.getSpecificPluginsListByInterface(pluginInterface);
|
||||
|
||||
return this.determineActivePlugin(pluginsInCategory, pluginType);
|
||||
}
|
||||
|
||||
private <T> T determineActivePlugin(int pluginType) {
|
||||
ArrayList<PluginBase> pluginsInCategory;
|
||||
pluginsInCategory = MainApp.getSpecificPluginsList(pluginType);
|
||||
|
||||
return this.determineActivePlugin(pluginsInCategory, pluginType);
|
||||
}
|
||||
|
||||
/**
|
||||
* disables the visibility for all fragments of Plugins in the given pluginsInCategory
|
||||
* with the given PluginType which are not equally named to the Plugin implementing the
|
||||
* given Plugin Interface.
|
||||
* <p>
|
||||
* TODO we are casting an interface to PluginBase, which seems to be rather odd, since
|
||||
* TODO the interface is not implementing PluginBase (this is just avoiding errors through
|
||||
* TODO conventions.
|
||||
*
|
||||
* @param pluginsInCategory
|
||||
* @param pluginType
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
private <T> T determineActivePlugin(ArrayList<PluginBase> pluginsInCategory,
|
||||
int pluginType) {
|
||||
T activePlugin = (T) getTheOneEnabledInArray(pluginsInCategory, pluginType);
|
||||
|
||||
if (activePlugin != null) {
|
||||
this.setFragmentVisiblities(((PluginBase) activePlugin).getName(),
|
||||
pluginsInCategory, pluginType);
|
||||
}
|
||||
|
||||
return activePlugin;
|
||||
}
|
||||
|
||||
private void setFragmentVisiblities(String activePluginName, ArrayList<PluginBase> pluginsInCategory,
|
||||
int pluginType) {
|
||||
if (Config.logConfigBuilder)
|
||||
log.debug("Selected treatment interface: " + ((PluginBase) activeTreatments).getName());
|
||||
log.debug("Selected interface: " + activePluginName);
|
||||
for (PluginBase p : pluginsInCategory) {
|
||||
if (!p.getName().equals(((PluginBase) activeTreatments).getName())) {
|
||||
p.setFragmentVisible(PluginBase.TREATMENT, false);
|
||||
if (!p.getName().equals(activePluginName)) {
|
||||
p.setFragmentVisible(pluginType, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -354,33 +351,19 @@ public class ConfigBuilderPlugin implements PluginBase, ConstraintsInterface, Tr
|
|||
return found;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ex Pump interface
|
||||
*
|
||||
* Config builder return itself as a pump and check constraints before it passes command to pump driver
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* expect absolute request and allow both absolute and percent response based on pump capabilities
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
* true if command is going to be executed
|
||||
* false if error
|
||||
*/
|
||||
|
||||
public boolean applyAPSRequest(APSResult request, Callback callback) {
|
||||
public void applyAPSRequest(APSResult request, Callback callback) {
|
||||
PumpInterface pump = getActivePump();
|
||||
request.rate = applyBasalConstraints(request.rate);
|
||||
PumpEnactResult result;
|
||||
|
||||
if (!pump.isInitialized()) {
|
||||
log.debug("applyAPSRequest: " + MainApp.sResources.getString(R.string.pumpNotInitialized));
|
||||
if (callback != null) {
|
||||
callback.result(new PumpEnactResult().comment(MainApp.sResources.getString(R.string.pumpNotInitialized)).enacted(false).success(false)).run();
|
||||
}
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (pump.isSuspended()) {
|
||||
|
@ -388,43 +371,56 @@ public class ConfigBuilderPlugin implements PluginBase, ConstraintsInterface, Tr
|
|||
if (callback != null) {
|
||||
callback.result(new PumpEnactResult().comment(MainApp.sResources.getString(R.string.pumpsuspended)).enacted(false).success(false)).run();
|
||||
}
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (Config.logCongigBuilderActions)
|
||||
log.debug("applyAPSRequest: " + request.toString());
|
||||
if ((request.rate == 0 && request.duration == 0) || Math.abs(request.rate - pump.getBaseBasalRate()) < pump.getPumpDescription().basalStep) {
|
||||
if (isTempBasalInProgress()) {
|
||||
|
||||
if (request.tempBasalReqested) {
|
||||
if ((request.rate == 0 && request.duration == 0) || Math.abs(request.rate - pump.getBaseBasalRate()) < pump.getPumpDescription().basalStep) {
|
||||
if (isTempBasalInProgress()) {
|
||||
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("Basal set correctly")).run();
|
||||
}
|
||||
}
|
||||
} else if (isTempBasalInProgress()
|
||||
&& getTempBasalRemainingMinutesFromHistory() > 5
|
||||
&& Math.abs(request.rate - getTempBasalAbsoluteRateHistory()) < pump.getPumpDescription().basalStep) {
|
||||
if (Config.logCongigBuilderActions)
|
||||
log.debug("applyAPSRequest: cancelTempBasal()");
|
||||
getCommandQueue().cancelTempBasal(false, callback);
|
||||
return true;
|
||||
log.debug("applyAPSRequest: Temp basal set correctly");
|
||||
if (callback != null) {
|
||||
callback.result(new PumpEnactResult().absolute(getTempBasalAbsoluteRateHistory()).duration(getTempBasalFromHistory(System.currentTimeMillis()).getPlannedRemainingMinutes()).enacted(false).success(true).comment("Temp basal set correctly")).run();
|
||||
}
|
||||
} 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("Basal set correctly")).run();
|
||||
}
|
||||
return false;
|
||||
log.debug("applyAPSRequest: setTempBasalAbsolute()");
|
||||
getCommandQueue().tempBasalAbsolute(request.rate, request.duration, false, callback);
|
||||
}
|
||||
} else if (isTempBasalInProgress()
|
||||
&& getTempBasalRemainingMinutesFromHistory() > 5
|
||||
&& Math.abs(request.rate - getTempBasalAbsoluteRateHistory()) < pump.getPumpDescription().basalStep) {
|
||||
if (Config.logCongigBuilderActions)
|
||||
log.debug("applyAPSRequest: Temp basal set correctly");
|
||||
if (callback != null) {
|
||||
callback.result(new PumpEnactResult().absolute(getTempBasalAbsoluteRateHistory()).duration(getTempBasalFromHistory(System.currentTimeMillis()).getPlannedRemainingMinutes()).enacted(false).success(true).comment("Temp basal set correctly")).run();
|
||||
}
|
||||
|
||||
if (request.bolusRequested) {
|
||||
long lastBolusTime = getLastBolusTime();
|
||||
if (lastBolusTime != 0 && lastBolusTime + 3 * 60 * 1000 > System.currentTimeMillis()) {
|
||||
log.debug("SMB requsted but still in 3 min interval");
|
||||
} else {
|
||||
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
|
||||
detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS;
|
||||
detailedBolusInfo.insulin = request.smb;
|
||||
detailedBolusInfo.isSMB = true;
|
||||
detailedBolusInfo.source = Source.USER;
|
||||
detailedBolusInfo.deliverAt = request.deliverAt;
|
||||
getCommandQueue().bolus(detailedBolusInfo, callback);
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
if (Config.logCongigBuilderActions)
|
||||
log.debug("applyAPSRequest: setTempBasalAbsolute()");
|
||||
getCommandQueue().tempBasalAbsolute(request.rate, request.duration, false, callback);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constraints interface
|
||||
**/
|
||||
|
@ -599,6 +595,11 @@ public class ConfigBuilderPlugin implements PluginBase, ConstraintsInterface, Tr
|
|||
return activeTreatments.getTreatments5MinBackFromHistory(time);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLastBolusTime() {
|
||||
return activeTreatments.getLastBolusTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInHistoryRealTempBasalInProgress() {
|
||||
return activeTreatments.isInHistoryRealTempBasalInProgress();
|
||||
|
@ -745,14 +746,17 @@ public class ConfigBuilderPlugin implements PluginBase, ConstraintsInterface, Tr
|
|||
}
|
||||
|
||||
public String getProfileName(long time, boolean customized) {
|
||||
ProfileSwitch profileSwitch = getProfileSwitchFromHistory(time);
|
||||
if (profileSwitch != null) {
|
||||
if (profileSwitch.profileJson != null) {
|
||||
return customized ? profileSwitch.getCustomizedName() : profileSwitch.profileName;
|
||||
} else {
|
||||
Profile profile = activeProfile.getProfile().getSpecificProfile(profileSwitch.profileName);
|
||||
if (profile != null)
|
||||
return profileSwitch.profileName;
|
||||
boolean ignoreProfileSwitchEvents = SP.getBoolean(R.string.key_do_not_track_profile_switch, false);
|
||||
if (!ignoreProfileSwitchEvents) {
|
||||
ProfileSwitch profileSwitch = getProfileSwitchFromHistory(time);
|
||||
if (profileSwitch != null) {
|
||||
if (profileSwitch.profileJson != null) {
|
||||
return customized ? profileSwitch.getCustomizedName() : profileSwitch.profileName;
|
||||
} else {
|
||||
Profile profile = activeProfile.getProfile().getSpecificProfile(profileSwitch.profileName);
|
||||
if (profile != null)
|
||||
return profileSwitch.profileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Unable to determine profile, failover to default
|
||||
|
@ -790,10 +794,10 @@ public class ConfigBuilderPlugin implements PluginBase, ConstraintsInterface, Tr
|
|||
return profile;
|
||||
}
|
||||
}
|
||||
// Unable to determine profile, failover to default
|
||||
if (activeProfile.getProfile() == null)
|
||||
return null; //app not initialized
|
||||
}
|
||||
// Unable to determine profile, failover to default
|
||||
if (activeProfile.getProfile() == null)
|
||||
return null; //app not initialized
|
||||
Profile defaultProfile = activeProfile.getProfile().getDefaultProfile();
|
||||
if (defaultProfile != null)
|
||||
return defaultProfile;
|
||||
|
@ -813,4 +817,40 @@ public class ConfigBuilderPlugin implements PluginBase, ConstraintsInterface, Tr
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void disconnectPump(int durationInMinutes) {
|
||||
getActiveLoop().disconnectTo(System.currentTimeMillis() + durationInMinutes * 60 * 1000L);
|
||||
getCommandQueue().tempBasalPercent(0, durationInMinutes, true, new Callback() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!result.success) {
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.tempbasaldeliveryerror));
|
||||
}
|
||||
}
|
||||
});
|
||||
if (getActivePump().getPumpDescription().isExtendedBolusCapable && 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) {
|
||||
getActiveLoop().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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ import android.widget.CheckBox;
|
|||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.crashlytics.android.Crashlytics;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -25,6 +24,7 @@ import java.util.List;
|
|||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.utils.FabricPrivacy;
|
||||
|
||||
public class ObjectivesFragment extends Fragment {
|
||||
private static Logger log = LoggerFactory.getLogger(ObjectivesFragment.class);
|
||||
|
@ -208,7 +208,7 @@ public class ObjectivesFragment extends Fragment {
|
|||
|
||||
return view;
|
||||
} catch (Exception e) {
|
||||
Crashlytics.logException(e);
|
||||
FabricPrivacy.logException(e);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
@ -130,7 +130,7 @@ public class SafetyPlugin implements PluginBase, ConstraintsInterface {
|
|||
if (profile == null) return absoluteRate;
|
||||
if (absoluteRate < 0) absoluteRate = 0d;
|
||||
|
||||
Integer maxBasalMult = SP.getInt("openapsama_current_basal_safety_multiplier", 4);
|
||||
Double maxBasalMult = SP.getDouble("openapsama_current_basal_safety_multiplier", 4d);
|
||||
Integer maxBasalFromDaily = SP.getInt("openapsama_max_daily_safety_multiplier", 3);
|
||||
// Check percentRate but absolute rate too, because we know real current basal in pump
|
||||
Double origRate = absoluteRate;
|
||||
|
@ -168,7 +168,7 @@ public class SafetyPlugin implements PluginBase, ConstraintsInterface {
|
|||
|
||||
if (absoluteRate < 0) absoluteRate = 0d;
|
||||
|
||||
Integer maxBasalMult = SP.getInt("openapsama_current_basal_safety_multiplier", 4);
|
||||
Double maxBasalMult = SP.getDouble("openapsama_current_basal_safety_multiplier", 4d);
|
||||
Integer maxBasalFromDaily = SP.getInt("openapsama_max_daily_safety_multiplier", 3);
|
||||
// Check percentRate but absolute rate too, because we know real current basal in pump
|
||||
Double origRate = absoluteRate;
|
||||
|
|
|
@ -1,22 +1,27 @@
|
|||
package info.nightscout.androidaps.db;
|
||||
package info.nightscout.androidaps.plugins.Food;
|
||||
|
||||
import com.j256.ormlite.field.DatabaseField;
|
||||
import com.j256.ormlite.table.DatabaseTable;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import info.nightscout.utils.JsonHelper;
|
||||
|
||||
/**
|
||||
* Created by mike on 20.09.2017.
|
||||
*/
|
||||
|
||||
|
||||
@DatabaseTable(tableName = DatabaseHelper.DATABASE_FOODS)
|
||||
@DatabaseTable(tableName = Food.TABLE_FOODS)
|
||||
public class Food {
|
||||
private static Logger log = LoggerFactory.getLogger(Food.class);
|
||||
|
||||
public static final String TABLE_FOODS = "Foods";
|
||||
|
||||
@DatabaseField(id = true)
|
||||
public long key;
|
||||
|
||||
|
@ -64,6 +69,25 @@ public class Food {
|
|||
key = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public static Food createFromJson(JSONObject json) throws JSONException {
|
||||
Food food = new Food();
|
||||
if ("food".equals(JsonHelper.safeGetString(json, "type"))) {
|
||||
food._id = JsonHelper.safeGetString(json, "_id");
|
||||
food.category = JsonHelper.safeGetString(json, "category");
|
||||
food.subcategory = JsonHelper.safeGetString(json, "subcategory");
|
||||
food.name = JsonHelper.safeGetString(json, "name");
|
||||
food.units = JsonHelper.safeGetString(json, "unit");
|
||||
food.portion = JsonHelper.safeGetDouble(json, "portion");
|
||||
food.carbs = JsonHelper.safeGetInt(json, "carbs");
|
||||
food.gi = JsonHelper.safeGetInt(json, "gi");
|
||||
food.energy = JsonHelper.safeGetInt(json, "energy");
|
||||
food.protein = JsonHelper.safeGetInt(json, "protein");
|
||||
food.fat = JsonHelper.safeGetInt(json, "fat");
|
||||
}
|
||||
|
||||
return food;
|
||||
}
|
||||
|
||||
public boolean isEqual(Food other) {
|
||||
if (portion != other.portion)
|
||||
return false;
|
||||
|
@ -104,4 +128,22 @@ public class Food {
|
|||
units = other.units;
|
||||
gi = other.gi;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("_id=" + _id + ";");
|
||||
sb.append("isValid=" + isValid + ";");
|
||||
sb.append("name=" + name + ";");
|
||||
sb.append("category=" + category + ";");
|
||||
sb.append("subcategory=" + subcategory + ";");
|
||||
sb.append("portion=" + portion + ";");
|
||||
sb.append("carbs=" + carbs + ";");
|
||||
sb.append("protein=" + protein + ";");
|
||||
sb.append("energy=" + energy + ";");
|
||||
sb.append("units=" + units + ";");
|
||||
sb.append("gi=" + gi + ";");
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
|
@ -18,7 +18,6 @@ import android.widget.EditText;
|
|||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.crashlytics.android.Crashlytics;
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
@ -27,12 +26,13 @@ import org.slf4j.LoggerFactory;
|
|||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.db.Food;
|
||||
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.utils.SpinnerHelper;
|
||||
|
||||
|
@ -121,7 +121,8 @@ public class FoodFragment extends SubscriberFragment {
|
|||
}
|
||||
});
|
||||
|
||||
RecyclerViewAdapter adapter = new RecyclerViewAdapter(MainApp.getDbHelper().foodHelper.getFoodData());
|
||||
RecyclerViewAdapter adapter = new RecyclerViewAdapter(MainApp
|
||||
.getSpecificPlugin(FoodPlugin.class).getService().getFoodData());
|
||||
recyclerView.setAdapter(adapter);
|
||||
|
||||
loadData();
|
||||
|
@ -130,7 +131,7 @@ public class FoodFragment extends SubscriberFragment {
|
|||
filterData();
|
||||
return view;
|
||||
} catch (Exception e) {
|
||||
Crashlytics.logException(e);
|
||||
FabricPrivacy.logException(e);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -144,20 +145,19 @@ public class FoodFragment extends SubscriberFragment {
|
|||
}
|
||||
|
||||
void loadData() {
|
||||
unfiltered = MainApp.getDbHelper().foodHelper.getFoodData();
|
||||
unfiltered = MainApp.getSpecificPlugin(FoodPlugin.class).getService().getFoodData();
|
||||
}
|
||||
|
||||
void fillCategories() {
|
||||
categories = new ArrayList<>();
|
||||
Set<CharSequence> catSet = new HashSet<>();
|
||||
|
||||
for (Food f : unfiltered) {
|
||||
if (f.category != null && !f.category.equals(""))
|
||||
categories.add(f.category);
|
||||
catSet.add(f.category);
|
||||
}
|
||||
|
||||
// make it unique
|
||||
categories = new ArrayList<>(new HashSet<>(categories));
|
||||
|
||||
categories = new ArrayList<>(catSet);
|
||||
categories.add(0, MainApp.sResources.getString(R.string.none));
|
||||
|
||||
ArrayAdapter<CharSequence> adapterCategories = new ArrayAdapter<>(getContext(),
|
||||
|
@ -167,19 +167,19 @@ public class FoodFragment extends SubscriberFragment {
|
|||
|
||||
void fillSubcategories() {
|
||||
String categoryFilter = category.getSelectedItem().toString();
|
||||
subcategories = new ArrayList<>();
|
||||
|
||||
Set<CharSequence> subCatSet = new HashSet<>();
|
||||
|
||||
if (!categoryFilter.equals(EMPTY)) {
|
||||
for (Food f : unfiltered) {
|
||||
if (f.category != null && f.category.equals(categoryFilter))
|
||||
if (f.subcategory != null && !f.subcategory.equals(""))
|
||||
subcategories.add(f.subcategory);
|
||||
subCatSet.add(f.subcategory);
|
||||
}
|
||||
}
|
||||
|
||||
// make it unique
|
||||
subcategories = new ArrayList<>(new HashSet<>(subcategories));
|
||||
|
||||
subcategories = new ArrayList<>(subCatSet);
|
||||
subcategories.add(0, MainApp.sResources.getString(R.string.none));
|
||||
|
||||
ArrayAdapter<CharSequence> adapterSubcategories = new ArrayAdapter<>(getContext(),
|
||||
|
@ -299,7 +299,7 @@ public class FoodFragment extends SubscriberFragment {
|
|||
if (_id != null && !_id.equals("")) {
|
||||
NSUpload.removeFoodFromNS(_id);
|
||||
}
|
||||
MainApp.getDbHelper().foodHelper.delete(food);
|
||||
MainApp.getSpecificPlugin(FoodPlugin.class).getService().delete(food);
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton(MainApp.sResources.getString(R.string.cancel), null);
|
||||
|
|
|
@ -13,6 +13,12 @@ public class FoodPlugin implements PluginBase {
|
|||
|
||||
private static FoodPlugin plugin = null;
|
||||
|
||||
private FoodService service;
|
||||
|
||||
private FoodPlugin() {
|
||||
this.service = new FoodService();
|
||||
}
|
||||
|
||||
public static FoodPlugin getPlugin() {
|
||||
if (plugin == null)
|
||||
plugin = new FoodPlugin();
|
||||
|
@ -81,5 +87,8 @@ public class FoodPlugin implements PluginBase {
|
|||
return -1;
|
||||
}
|
||||
|
||||
public FoodService getService() {
|
||||
return this.service;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,368 @@
|
|||
package info.nightscout.androidaps.plugins.Food;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.j256.ormlite.android.apptools.OpenHelperManager;
|
||||
import com.j256.ormlite.android.apptools.OrmLiteBaseService;
|
||||
import com.j256.ormlite.dao.Dao;
|
||||
import com.j256.ormlite.dao.DaoManager;
|
||||
import com.j256.ormlite.support.ConnectionSource;
|
||||
import com.j256.ormlite.table.TableUtils;
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.db.DatabaseHelper;
|
||||
import info.nightscout.androidaps.db.ICallback;
|
||||
import info.nightscout.androidaps.events.Event;
|
||||
import info.nightscout.androidaps.events.EventFoodDatabaseChanged;
|
||||
import info.nightscout.androidaps.events.EventNsFood;
|
||||
|
||||
/**
|
||||
* Created by mike on 24.09.2017.
|
||||
*/
|
||||
|
||||
public class FoodService extends OrmLiteBaseService<DatabaseHelper> {
|
||||
private static Logger log = LoggerFactory.getLogger(FoodService.class);
|
||||
|
||||
private static final ScheduledExecutorService foodEventWorker = Executors.newSingleThreadScheduledExecutor();
|
||||
private static ScheduledFuture<?> scheduledFoodEventPost = null;
|
||||
|
||||
public FoodService() {
|
||||
onCreate();
|
||||
dbInitialize();
|
||||
MainApp.bus().register(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is a simple re-implementation of the database create and up/downgrade functionality
|
||||
* in SQLiteOpenHelper#getDatabaseLocked method.
|
||||
* <p>
|
||||
* It is implemented to be able to late initialize separate plugins of the application.
|
||||
*/
|
||||
protected void dbInitialize() {
|
||||
DatabaseHelper helper = OpenHelperManager.getHelper(this, DatabaseHelper.class);
|
||||
int newVersion = helper.getNewVersion();
|
||||
int oldVersion = helper.getOldVersion();
|
||||
|
||||
if (oldVersion > newVersion) {
|
||||
onDowngrade(this.getConnectionSource(), oldVersion, newVersion);
|
||||
} else {
|
||||
onUpgrade(this.getConnectionSource(), oldVersion, newVersion);
|
||||
}
|
||||
}
|
||||
|
||||
public Dao<Food, Long> getDao() {
|
||||
try {
|
||||
return DaoManager.createDao(this.getConnectionSource(), Food.class);
|
||||
} catch (SQLException e) {
|
||||
log.error("Cannot create Dao for Food.class");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void handleNsEvent(EventNsFood event) {
|
||||
int mode = event.getMode();
|
||||
Bundle payload = event.getPayload();
|
||||
|
||||
try {
|
||||
if (payload.containsKey("food")) {
|
||||
JSONObject json = new JSONObject(payload.getString("food"));
|
||||
if (mode == EventNsFood.ADD || mode == EventNsFood.UPDATE) {
|
||||
this.createFoodFromJsonIfNotExists(json);
|
||||
} else {
|
||||
this.deleteNS(json);
|
||||
}
|
||||
}
|
||||
|
||||
if (payload.containsKey("foods")) {
|
||||
JSONArray array = new JSONArray(payload.getString("foods"));
|
||||
if (mode == EventNsFood.ADD || mode == EventNsFood.UPDATE) {
|
||||
this.createFoodFromJsonIfNotExists(array);
|
||||
} else {
|
||||
this.deleteNS(array);
|
||||
}
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled Exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
try {
|
||||
log.info("onCreate");
|
||||
TableUtils.createTableIfNotExists(this.getConnectionSource(), Food.class);
|
||||
} catch (SQLException e) {
|
||||
log.error("Can't create database", e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void onUpgrade(ConnectionSource connectionSource, int oldVersion, int newVersion) {
|
||||
if (oldVersion == 7 && newVersion == 8) {
|
||||
log.debug("Upgrading database from v7 to v8");
|
||||
} else {
|
||||
log.info("onUpgrade");
|
||||
// this.resetFood();
|
||||
}
|
||||
}
|
||||
|
||||
public void onDowngrade(ConnectionSource connectionSource, int oldVersion, int newVersion) {
|
||||
// this method is not supported right now
|
||||
}
|
||||
|
||||
public void resetFood() {
|
||||
try {
|
||||
TableUtils.dropTable(this.getConnectionSource(), Food.class, true);
|
||||
TableUtils.createTableIfNotExists(this.getConnectionSource(), Food.class);
|
||||
} catch (SQLException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
scheduleFoodChange();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A place to centrally register events to be posted, if any data changed.
|
||||
* This should be implemented in an abstract service-class.
|
||||
* <p>
|
||||
* We do need to make sure, that ICallback is extended to be able to handle multiple
|
||||
* events, or handle a list of events.
|
||||
* <p>
|
||||
* on some methods the earliestDataChange event is handled separatly, in that it is checked if it is
|
||||
* set to null by another event already (eg. scheduleExtendedBolusChange).
|
||||
*
|
||||
* @param event
|
||||
* @param eventWorker
|
||||
* @param callback
|
||||
*/
|
||||
private void scheduleEvent(final Event event, ScheduledExecutorService eventWorker,
|
||||
final ICallback callback) {
|
||||
|
||||
class PostRunnable implements Runnable {
|
||||
public void run() {
|
||||
log.debug("Firing EventFoodChange");
|
||||
MainApp.bus().post(event);
|
||||
callback.setPost(null);
|
||||
}
|
||||
}
|
||||
// prepare task for execution in 1 sec
|
||||
// cancel waiting task to prevent sending multiple posts
|
||||
if (callback.getPost() != null)
|
||||
callback.getPost().cancel(false);
|
||||
Runnable task = new PostRunnable();
|
||||
final int sec = 1;
|
||||
callback.setPost(eventWorker.schedule(task, sec, TimeUnit.SECONDS));
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule a foodChange Event.
|
||||
*/
|
||||
public void scheduleFoodChange() {
|
||||
this.scheduleEvent(new EventFoodDatabaseChanged(), foodEventWorker, new ICallback() {
|
||||
@Override
|
||||
public void setPost(ScheduledFuture<?> post) {
|
||||
scheduledFoodEventPost = post;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScheduledFuture<?> getPost() {
|
||||
return scheduledFoodEventPost;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public List<Food> getFoodData() {
|
||||
try {
|
||||
return this.getDao().queryForAll();
|
||||
} catch (SQLException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
/*
|
||||
{
|
||||
"_id": "551ee3ad368e06e80856e6a9",
|
||||
"type": "food",
|
||||
"category": "Zakladni",
|
||||
"subcategory": "Napoje",
|
||||
"name": "Mleko",
|
||||
"portion": 250,
|
||||
"carbs": 12,
|
||||
"gi": 1,
|
||||
"created_at": "2015-04-14T06:59:16.500Z",
|
||||
"unit": "ml"
|
||||
}
|
||||
*/
|
||||
public void createFoodFromJsonIfNotExists(JSONObject json) {
|
||||
try {
|
||||
Food food = Food.createFromJson(json);
|
||||
this.createFoodFromJsonIfNotExists(food);
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void createFoodFromJsonIfNotExists(JSONArray array) {
|
||||
try {
|
||||
for (int n = 0; n < array.length(); n++) {
|
||||
JSONObject json = array.getJSONObject(n);
|
||||
Food food = Food.createFromJson(json);
|
||||
this.createFoodFromJsonIfNotExists(food);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void createFoodFromJsonIfNotExists(Food food) {
|
||||
this.createOrUpdateByNS(food);
|
||||
}
|
||||
|
||||
public void deleteNS(JSONObject json) {
|
||||
try {
|
||||
String _id = json.getString("_id");
|
||||
this.deleteByNSId(_id);
|
||||
} catch (JSONException | SQLException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteNS(JSONArray array) {
|
||||
try {
|
||||
for (int n = 0; n < array.length(); n++) {
|
||||
JSONObject json = array.getJSONObject(n);
|
||||
this.deleteNS(json);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* deletes an entry by its NS Id.
|
||||
* <p>
|
||||
* Basically a convenience method for findByNSId and delete.
|
||||
*
|
||||
* @param _id
|
||||
*/
|
||||
public void deleteByNSId(String _id) throws SQLException {
|
||||
Food stored = this.findByNSId(_id);
|
||||
if (stored != null) {
|
||||
log.debug("FOOD: Removing Food record from database: " + stored.toString());
|
||||
this.delete(stored);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* deletes the food and sends the foodChange Event
|
||||
* <p>
|
||||
* should be moved ot a Service
|
||||
*
|
||||
* @param food
|
||||
*/
|
||||
public void delete(Food food) {
|
||||
try {
|
||||
this.getDao().delete(food);
|
||||
this.scheduleFoodChange();
|
||||
} catch (SQLException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create of update a food record by the NS (Nightscout) Id.
|
||||
*
|
||||
* @param food
|
||||
* @return
|
||||
*/
|
||||
public boolean createOrUpdateByNS(Food food) {
|
||||
// find by NS _id
|
||||
if (food._id != null && !food._id.equals("")) {
|
||||
Food old = this.findByNSId(food._id);
|
||||
|
||||
if (old != null) {
|
||||
if (!old.isEqual(food)) {
|
||||
this.delete(old); // need to delete/create because date may change too
|
||||
old.copyFrom(food);
|
||||
this.create(old);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
this.createOrUpdate(food);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void createOrUpdate(Food food) {
|
||||
try {
|
||||
this.getDao().createOrUpdate(food);
|
||||
log.debug("FOOD: Created or Updated: " + food.toString());
|
||||
} catch (SQLException e) {
|
||||
log.error("Unable to createOrUpdate Food", e);
|
||||
}
|
||||
this.scheduleFoodChange();
|
||||
}
|
||||
|
||||
public void create(Food food) {
|
||||
try {
|
||||
this.getDao().create(food);
|
||||
log.debug("FOOD: New record: " + food.toString());
|
||||
} catch (SQLException e) {
|
||||
log.error("Unable to create Food", e);
|
||||
}
|
||||
this.scheduleFoodChange();
|
||||
}
|
||||
|
||||
/**
|
||||
* finds food by its NS Id.
|
||||
*
|
||||
* @param _id
|
||||
* @return
|
||||
*/
|
||||
public Food findByNSId(String _id) {
|
||||
try {
|
||||
List<Food> list = this.getDao().queryForEq("_id", _id);
|
||||
|
||||
if (list.size() == 1) { // really? if there are more then one result, then we do not return anything...
|
||||
return list.get(0);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -7,11 +7,11 @@ import android.view.View;
|
|||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.crashlytics.android.Crashlytics;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.utils.FabricPrivacy;
|
||||
|
||||
/**
|
||||
* Created by mike on 17.04.2017.
|
||||
|
@ -37,7 +37,7 @@ public class InsulinFragment extends Fragment {
|
|||
|
||||
return view;
|
||||
} catch (Exception e) {
|
||||
Crashlytics.logException(e);
|
||||
FabricPrivacy.logException(e);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
@ -57,11 +57,15 @@ public class AutosensData {
|
|||
public double cob = 0;
|
||||
public double bgi = 0d;
|
||||
public double delta = 0d;
|
||||
public double avgDelta = 0d;
|
||||
public double avgDeviation = 0d;
|
||||
|
||||
public double autosensRatio = 1d;
|
||||
public double slopeFromMaxDeviation = 0;
|
||||
public double slopeFromMinDeviation = 999;
|
||||
|
||||
public String log(long time) {
|
||||
return "AutosensData: " + new Date(time).toLocaleString() + " " + pastSensitivity + " Delta=" + delta + " Bgi=" + bgi + " Deviation=" + deviation + " Absorbed=" + absorbed + " CarbsFromBolus=" + carbsFromBolus + " COB=" + cob + " autosensRatio=" + autosensRatio;
|
||||
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 ;
|
||||
}
|
||||
|
||||
public int minOld() {
|
||||
|
|
|
@ -22,6 +22,7 @@ import info.nightscout.androidaps.data.IobTotal;
|
|||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.db.BgReading;
|
||||
import info.nightscout.androidaps.db.TemporaryBasal;
|
||||
import info.nightscout.androidaps.events.Event;
|
||||
import info.nightscout.androidaps.events.EventAppInitialized;
|
||||
import info.nightscout.androidaps.events.EventConfigBuilderChange;
|
||||
import info.nightscout.androidaps.events.EventNewBG;
|
||||
|
@ -30,6 +31,7 @@ import info.nightscout.androidaps.events.EventPreferenceChange;
|
|||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventNewHistoryData;
|
||||
import info.nightscout.androidaps.plugins.OpenAPSSMB.OpenAPSSMBPlugin;
|
||||
import info.nightscout.utils.DateUtil;
|
||||
|
||||
/**
|
||||
|
@ -39,19 +41,19 @@ import info.nightscout.utils.DateUtil;
|
|||
public class IobCobCalculatorPlugin implements PluginBase {
|
||||
private static Logger log = LoggerFactory.getLogger(IobCobCalculatorPlugin.class);
|
||||
|
||||
private static LongSparseArray<IobTotal> iobTable = new LongSparseArray<>(); // oldest at index 0
|
||||
private static LongSparseArray<AutosensData> autosensDataTable = new LongSparseArray<>(); // oldest at index 0
|
||||
private static LongSparseArray<BasalData> basalDataTable = new LongSparseArray<>(); // oldest at index 0
|
||||
private LongSparseArray<IobTotal> iobTable = new LongSparseArray<>(); // oldest at index 0
|
||||
private LongSparseArray<AutosensData> autosensDataTable = new LongSparseArray<>(); // oldest at index 0
|
||||
private LongSparseArray<BasalData> basalDataTable = new LongSparseArray<>(); // oldest at index 0
|
||||
|
||||
private static volatile List<BgReading> bgReadings = null; // newest at index 0
|
||||
private static volatile List<BgReading> bucketed_data = null;
|
||||
private volatile List<BgReading> bgReadings = null; // newest at index 0
|
||||
private volatile List<BgReading> bucketed_data = null;
|
||||
|
||||
private static double dia = Constants.defaultDIA;
|
||||
private double dia = Constants.defaultDIA;
|
||||
|
||||
static final Object dataLock = new Object();
|
||||
final Object dataLock = new Object();
|
||||
|
||||
boolean stopCalculationTrigger = false;
|
||||
IobCobThread thread = null;
|
||||
private IobCobThread thread = null;
|
||||
|
||||
private static IobCobCalculatorPlugin plugin = null;
|
||||
|
||||
|
@ -61,11 +63,11 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
|||
return plugin;
|
||||
}
|
||||
|
||||
public static LongSparseArray<AutosensData> getAutosensDataTable() {
|
||||
public LongSparseArray<AutosensData> getAutosensDataTable() {
|
||||
return autosensDataTable;
|
||||
}
|
||||
|
||||
public static List<BgReading> getBucketedData() {
|
||||
public List<BgReading> getBucketedData() {
|
||||
return bucketed_data;
|
||||
}
|
||||
|
||||
|
@ -129,12 +131,12 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
|||
return -1;
|
||||
}
|
||||
|
||||
IobCobCalculatorPlugin() {
|
||||
public IobCobCalculatorPlugin() {
|
||||
MainApp.bus().register(this);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static List<BgReading> getBucketedData(long fromTime) {
|
||||
public List<BgReading> getBucketedData(long fromTime) {
|
||||
//log.debug("Locking getBucketedData");
|
||||
synchronized (dataLock) {
|
||||
if (bucketed_data == null) {
|
||||
|
@ -152,7 +154,7 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
|||
return null;
|
||||
}
|
||||
|
||||
private static int indexNewerThan(long time) {
|
||||
private int indexNewerThan(long time) {
|
||||
for (int index = 0; index < bucketed_data.size(); index++) {
|
||||
if (bucketed_data.get(index).date < time)
|
||||
return index - 1;
|
||||
|
@ -167,9 +169,9 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
|||
return rouded;
|
||||
}
|
||||
|
||||
void loadBgData() {
|
||||
bgReadings = MainApp.getDbHelper().getBgreadingsDataFromTime((long) (System.currentTimeMillis() - 60 * 60 * 1000L * (24 + dia)), false);
|
||||
log.debug("BG data loaded. Size: " + bgReadings.size());
|
||||
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));
|
||||
}
|
||||
|
||||
private boolean isAbout5minData() {
|
||||
|
@ -259,7 +261,7 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
|||
}
|
||||
|
||||
|
||||
public void createBucketedData5min() {
|
||||
private void createBucketedData5min() {
|
||||
if (bgReadings == null || bgReadings.size() < 3) {
|
||||
bucketed_data = null;
|
||||
return;
|
||||
|
@ -330,13 +332,13 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
|||
return getBGDataFrom;
|
||||
}
|
||||
|
||||
public static IobTotal calculateFromTreatmentsAndTempsSynchronized(long time) {
|
||||
public IobTotal calculateFromTreatmentsAndTempsSynchronized(long time) {
|
||||
synchronized (dataLock) {
|
||||
return calculateFromTreatmentsAndTemps(time);
|
||||
}
|
||||
}
|
||||
|
||||
public static IobTotal calculateFromTreatmentsAndTemps(long time) {
|
||||
public IobTotal calculateFromTreatmentsAndTemps(long time) {
|
||||
long now = System.currentTimeMillis();
|
||||
time = roundUpTime(time);
|
||||
if (time < now && iobTable.get(time) != null) {
|
||||
|
@ -347,6 +349,21 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
|||
}
|
||||
IobTotal bolusIob = MainApp.getConfigBuilder().getCalculationToTimeTreatments(time).round();
|
||||
IobTotal basalIob = MainApp.getConfigBuilder().getCalculationToTimeTempBasals(time).round();
|
||||
if (OpenAPSSMBPlugin.getPlugin().isEnabled(PluginBase.APS)) {
|
||||
// Add expected zere temp basal for next 240 mins
|
||||
IobTotal basalIobWithZeroTemp = basalIob.clone();
|
||||
TemporaryBasal t = new TemporaryBasal();
|
||||
t.date = now + 60 * 1000L;
|
||||
t.durationInMinutes = 240;
|
||||
t.isAbsolute = true;
|
||||
t.absoluteRate = 0;
|
||||
if (t.date < time) {
|
||||
IobTotal calc = t.iobCalc(time);
|
||||
basalIobWithZeroTemp.plus(calc);
|
||||
}
|
||||
|
||||
basalIob.iobWithZeroTemp = basalIobWithZeroTemp;
|
||||
}
|
||||
|
||||
IobTotal iobTotal = IobTotal.combine(bolusIob, basalIob).round();
|
||||
if (time < System.currentTimeMillis()) {
|
||||
|
@ -356,7 +373,7 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
|||
}
|
||||
|
||||
@Nullable
|
||||
private static Long findPreviousTimeFromBucketedData(long time) {
|
||||
private Long findPreviousTimeFromBucketedData(long time) {
|
||||
if (bucketed_data == null)
|
||||
return null;
|
||||
for (int index = 0; index < bucketed_data.size(); index++) {
|
||||
|
@ -366,7 +383,7 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
|||
return null;
|
||||
}
|
||||
|
||||
public static BasalData getBasalData(long time) {
|
||||
public BasalData getBasalData(long time) {
|
||||
long now = System.currentTimeMillis();
|
||||
time = roundUpTime(time);
|
||||
BasalData retval = basalDataTable.get(time);
|
||||
|
@ -392,7 +409,7 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
|||
}
|
||||
|
||||
@Nullable
|
||||
public static AutosensData getAutosensData(long time) {
|
||||
public AutosensData getAutosensData(long time) {
|
||||
synchronized (dataLock) {
|
||||
long now = System.currentTimeMillis();
|
||||
if (time > now)
|
||||
|
@ -417,7 +434,7 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
|||
}
|
||||
|
||||
@Nullable
|
||||
public static AutosensData getLastAutosensDataSynchronized(String reason) {
|
||||
public AutosensData getLastAutosensDataSynchronized(String reason) {
|
||||
synchronized (dataLock) {
|
||||
return getLastAutosensData(reason);
|
||||
}
|
||||
|
@ -425,7 +442,7 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
|||
|
||||
|
||||
@Nullable
|
||||
public static AutosensData getLastAutosensData(String reason) {
|
||||
public AutosensData getLastAutosensData(String reason) {
|
||||
if (autosensDataTable.size() < 1) {
|
||||
log.debug("AUTOSENSDATA null: autosensDataTable empty (" + reason + ")");
|
||||
return null;
|
||||
|
@ -450,7 +467,7 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
|||
}
|
||||
}
|
||||
|
||||
public static IobTotal[] calculateIobArrayInDia() {
|
||||
public IobTotal[] calculateIobArrayInDia() {
|
||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||
// predict IOB out to DIA plus 30m
|
||||
long time = System.currentTimeMillis();
|
||||
|
@ -467,7 +484,24 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
|||
return array;
|
||||
}
|
||||
|
||||
public static AutosensResult detectSensitivityWithLock(long fromTime, long toTime) {
|
||||
public IobTotal[] calculateIobArrayForSMB() {
|
||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||
// predict IOB out to DIA plus 30m
|
||||
long time = System.currentTimeMillis();
|
||||
time = roundUpTime(time);
|
||||
int len = (4 * 60) / 5;
|
||||
IobTotal[] array = new IobTotal[len];
|
||||
int pos = 0;
|
||||
for (int i = 0; i < len; i++) {
|
||||
long t = time + i * 5 * 60000;
|
||||
IobTotal iob = calculateFromTreatmentsAndTempsSynchronized(t);
|
||||
array[pos] = iob;
|
||||
pos++;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public AutosensResult detectSensitivityWithLock(long fromTime, long toTime) {
|
||||
synchronized (dataLock) {
|
||||
return detectSensitivity(fromTime, toTime);
|
||||
}
|
||||
|
@ -487,13 +521,21 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
|||
|
||||
@Subscribe
|
||||
public void onEventAppInitialized(EventAppInitialized ev) {
|
||||
runCalculation("onEventAppInitialized", true);
|
||||
if (this != getPlugin()) {
|
||||
log.debug("Ignoring event for non default instance");
|
||||
return;
|
||||
}
|
||||
runCalculation("onEventAppInitialized", System.currentTimeMillis(), true, ev);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onEventNewBG(EventNewBG ev) {
|
||||
if (this != getPlugin()) {
|
||||
log.debug("Ignoring event for non default instance");
|
||||
return;
|
||||
}
|
||||
stopCalculation("onEventNewBG");
|
||||
runCalculation("onEventNewBG", true);
|
||||
runCalculation("onEventNewBG", System.currentTimeMillis(), true, ev);
|
||||
}
|
||||
|
||||
private void stopCalculation(String from) {
|
||||
|
@ -507,16 +549,20 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
|||
}
|
||||
}
|
||||
|
||||
private void runCalculation(String from, boolean bgDataReload) {
|
||||
public void runCalculation(String from, long start, boolean bgDataReload, Event cause) {
|
||||
log.debug("Starting calculation thread: " + from);
|
||||
if (thread == null || thread.getState() == Thread.State.TERMINATED) {
|
||||
thread = new IobCobThread(this, from, bgDataReload);
|
||||
thread = new IobCobThread(this, from, start, bgDataReload, cause);
|
||||
thread.start();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onNewProfile(EventNewBasalProfile ev) {
|
||||
if (this != getPlugin()) {
|
||||
log.debug("Ignoring event for non default instance");
|
||||
return;
|
||||
}
|
||||
if (MainApp.getConfigBuilder() == null)
|
||||
return; // app still initializing
|
||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||
|
@ -532,11 +578,15 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
|||
iobTable = new LongSparseArray<>();
|
||||
autosensDataTable = new LongSparseArray<>();
|
||||
}
|
||||
runCalculation("onNewProfile", false);
|
||||
runCalculation("onNewProfile", System.currentTimeMillis(), false, ev);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onEventPreferenceChange(EventPreferenceChange ev) {
|
||||
if (this != getPlugin()) {
|
||||
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)
|
||||
|
@ -547,24 +597,32 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
|||
iobTable = new LongSparseArray<>();
|
||||
autosensDataTable = new LongSparseArray<>();
|
||||
}
|
||||
runCalculation("onEventPreferenceChange", false);
|
||||
runCalculation("onEventPreferenceChange", System.currentTimeMillis(), false, ev);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onEventConfigBuilderChange(EventConfigBuilderChange ev) {
|
||||
if (this != getPlugin()) {
|
||||
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");
|
||||
iobTable = new LongSparseArray<>();
|
||||
autosensDataTable = new LongSparseArray<>();
|
||||
}
|
||||
runCalculation("onEventConfigBuilderChange", false);
|
||||
runCalculation("onEventConfigBuilderChange", System.currentTimeMillis(), false, 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");
|
||||
return;
|
||||
}
|
||||
//log.debug("Locking onNewHistoryData");
|
||||
stopCalculation("onEventNewHistoryData");
|
||||
synchronized (dataLock) {
|
||||
|
@ -599,10 +657,18 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
|||
}
|
||||
}
|
||||
}
|
||||
runCalculation("onEventNewHistoryData", false);
|
||||
runCalculation("onEventNewHistoryData", System.currentTimeMillis(), false, ev);
|
||||
//log.debug("Releasing onNewHistoryData");
|
||||
}
|
||||
|
||||
public void clearCache() {
|
||||
synchronized (dataLock) {
|
||||
log.debug("Clearing cached data.");
|
||||
iobTable = new LongSparseArray<>();
|
||||
autosensDataTable = new LongSparseArray<>();
|
||||
}
|
||||
}
|
||||
|
||||
// From https://gist.github.com/IceCreamYou/6ffa1b18c4c8f6aeaad2
|
||||
// Returns the value at a given percentile in a sorted numeric array.
|
||||
// "Linear interpolation between closest ranks" method
|
||||
|
|
|
@ -18,12 +18,10 @@ import info.nightscout.androidaps.data.IobTotal;
|
|||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.db.BgReading;
|
||||
import info.nightscout.androidaps.db.Treatment;
|
||||
import info.nightscout.androidaps.events.Event;
|
||||
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished;
|
||||
import info.nightscout.androidaps.queue.QueueThread;
|
||||
|
||||
import static info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin.getBucketedData;
|
||||
import static info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin.oldestDataAvailable;
|
||||
import static info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin.roundUpTime;
|
||||
import info.nightscout.utils.DateUtil;
|
||||
|
||||
/**
|
||||
* Created by mike on 23.01.2018.
|
||||
|
@ -31,19 +29,23 @@ import static info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculat
|
|||
|
||||
public class IobCobThread extends Thread {
|
||||
private static Logger log = LoggerFactory.getLogger(QueueThread.class);
|
||||
private final Event cause;
|
||||
|
||||
private IobCobCalculatorPlugin iobCobCalculatorPlugin;
|
||||
private boolean bgDataReload;
|
||||
private String from;
|
||||
private long start;
|
||||
|
||||
private PowerManager.WakeLock mWakeLock;
|
||||
|
||||
public IobCobThread(IobCobCalculatorPlugin plugin, String from, boolean bgDataReload) {
|
||||
public IobCobThread(IobCobCalculatorPlugin plugin, String from, long start, boolean bgDataReload, Event cause) {
|
||||
super();
|
||||
|
||||
this.iobCobCalculatorPlugin = plugin;
|
||||
this.bgDataReload = bgDataReload;
|
||||
this.from = from;
|
||||
this.cause = cause;
|
||||
this.start = start;
|
||||
|
||||
PowerManager powerManager = (PowerManager) MainApp.instance().getApplicationContext().getSystemService(Context.POWER_SERVICE);
|
||||
mWakeLock = powerManager.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "iobCobThread");
|
||||
|
@ -65,14 +67,14 @@ public class IobCobThread extends Thread {
|
|||
|
||||
Object dataLock = iobCobCalculatorPlugin.dataLock;
|
||||
|
||||
long oldestTimeWithData = oldestDataAvailable();
|
||||
long oldestTimeWithData = iobCobCalculatorPlugin.oldestDataAvailable();
|
||||
|
||||
synchronized (dataLock) {
|
||||
if (bgDataReload) {
|
||||
iobCobCalculatorPlugin.loadBgData();
|
||||
iobCobCalculatorPlugin.loadBgData(start);
|
||||
iobCobCalculatorPlugin.createBucketedData();
|
||||
}
|
||||
List<BgReading> bucketed_data = getBucketedData();
|
||||
List<BgReading> bucketed_data = iobCobCalculatorPlugin.getBucketedData();
|
||||
LongSparseArray<AutosensData> autosensDataTable = iobCobCalculatorPlugin.getAutosensDataTable();
|
||||
|
||||
if (bucketed_data == null || bucketed_data.size() < 3) {
|
||||
|
@ -80,7 +82,7 @@ public class IobCobThread extends Thread {
|
|||
return;
|
||||
}
|
||||
|
||||
long prevDataTime = roundUpTime(bucketed_data.get(bucketed_data.size() - 3).date);
|
||||
long prevDataTime = iobCobCalculatorPlugin.roundUpTime(bucketed_data.get(bucketed_data.size() - 3).date);
|
||||
log.debug("Prev data time: " + new Date(prevDataTime).toLocaleString());
|
||||
AutosensData previous = autosensDataTable.get(prevDataTime);
|
||||
// start from oldest to be able sub cob
|
||||
|
@ -92,7 +94,7 @@ public class IobCobThread extends Thread {
|
|||
}
|
||||
// check if data already exists
|
||||
long bgTime = bucketed_data.get(i).date;
|
||||
bgTime = roundUpTime(bgTime);
|
||||
bgTime = iobCobCalculatorPlugin.roundUpTime(bgTime);
|
||||
if (bgTime > System.currentTimeMillis())
|
||||
continue;
|
||||
Profile profile = MainApp.getConfigBuilder().getProfile(bgTime);
|
||||
|
@ -135,11 +137,43 @@ public class IobCobThread extends Thread {
|
|||
continue;
|
||||
}
|
||||
delta = (bg - bucketed_data.get(i + 1).value);
|
||||
avgDelta = (bg - bucketed_data.get(i + 3).value) / 3;
|
||||
|
||||
IobTotal iob = iobCobCalculatorPlugin.calculateFromTreatmentsAndTemps(bgTime);
|
||||
|
||||
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);
|
||||
|
||||
for (int past = 1; past < 12; past++) {
|
||||
AutosensData ad = autosensDataTable.valueAt(initialIndex + past);
|
||||
double deviationSlope = (ad.avgDeviation - avgDeviation) / (ad.time - bgTime) * 1000 * 60 * 5;
|
||||
if (ad.avgDeviation > maxDeviation) {
|
||||
slopeFromMaxDeviation = Math.min(0, deviationSlope);
|
||||
maxDeviation = ad.avgDeviation;
|
||||
}
|
||||
if (ad.avgDeviation < minDeviation) {
|
||||
slopeFromMinDeviation = Math.max(0, deviationSlope);
|
||||
minDeviation = ad.avgDeviation;
|
||||
}
|
||||
|
||||
//if (Config.logAutosensData)
|
||||
// log.debug("Deviations: " + new Date(bgTime) + new Date(ad.time) + " avgDeviation=" + avgDeviation + " deviationSlope=" + deviationSlope + " slopeFromMaxDeviation=" + slopeFromMaxDeviation + " slopeFromMinDeviation=" + slopeFromMinDeviation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<Treatment> recentTreatments = MainApp.getConfigBuilder().getTreatments5MinBackFromHistory(bgTime);
|
||||
for (int ir = 0; ir < recentTreatments.size(); ir++) {
|
||||
|
@ -170,6 +204,11 @@ public class IobCobThread extends Thread {
|
|||
autosensData.deviation = deviation;
|
||||
autosensData.bgi = bgi;
|
||||
autosensData.delta = delta;
|
||||
autosensData.avgDelta = avgDelta;
|
||||
autosensData.avgDeviation = avgDeviation;
|
||||
autosensData.slopeFromMaxDeviation = slopeFromMaxDeviation;
|
||||
autosensData.slopeFromMinDeviation = slopeFromMinDeviation;
|
||||
|
||||
|
||||
// calculate autosens only without COB
|
||||
if (autosensData.cob <= 0) {
|
||||
|
@ -191,12 +230,13 @@ public class IobCobThread extends Thread {
|
|||
|
||||
previous = autosensData;
|
||||
autosensDataTable.put(bgTime, autosensData);
|
||||
log.debug("Running detectSensitivity from: " + DateUtil.dateAndTimeString(oldestTimeWithData) + " to: " + DateUtil.dateAndTimeString(bgTime));
|
||||
autosensData.autosensRatio = iobCobCalculatorPlugin.detectSensitivity(oldestTimeWithData, bgTime).ratio;
|
||||
if (Config.logAutosensData)
|
||||
log.debug(autosensData.log(bgTime));
|
||||
}
|
||||
}
|
||||
MainApp.bus().post(new EventAutosensCalculationFinished());
|
||||
MainApp.bus().post(new EventAutosensCalculationFinished(cause));
|
||||
log.debug("Finishing calculation thread: " + from);
|
||||
} finally {
|
||||
mWakeLock.release();
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package info.nightscout.androidaps.plugins.IobCobCalculator.events;
|
||||
|
||||
import info.nightscout.androidaps.events.Event;
|
||||
import info.nightscout.androidaps.events.EventLoop;
|
||||
|
||||
/**
|
||||
|
@ -7,4 +8,9 @@ import info.nightscout.androidaps.events.EventLoop;
|
|||
*/
|
||||
|
||||
public class EventAutosensCalculationFinished extends EventLoop {
|
||||
public Event cause;
|
||||
|
||||
public EventAutosensCalculationFinished(Event cause) {
|
||||
this.cause = cause;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,22 @@
|
|||
package info.nightscout.androidaps.plugins.Loop;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.text.Html;
|
||||
import android.text.Spanned;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
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;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.IobTotal;
|
||||
import info.nightscout.androidaps.db.BgReading;
|
||||
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.utils.DecimalFormatter;
|
||||
|
@ -22,36 +27,64 @@ import info.nightscout.utils.DecimalFormatter;
|
|||
public class APSResult {
|
||||
private static Logger log = LoggerFactory.getLogger(APSResult.class);
|
||||
|
||||
public Date date;
|
||||
public String reason;
|
||||
public double rate;
|
||||
public int duration;
|
||||
public boolean changeRequested = false;
|
||||
public boolean tempBasalReqested = false;
|
||||
public boolean bolusRequested = false;
|
||||
public IobTotal iob;
|
||||
public JSONObject json = new JSONObject();
|
||||
public boolean hasPredictions = false;
|
||||
public double smb = 0d; // super micro bolus in units
|
||||
public long deliverAt = 0;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
|
||||
if (changeRequested) {
|
||||
if (isChangeRequested()) {
|
||||
String ret;
|
||||
// rate
|
||||
if (rate == 0 && duration == 0)
|
||||
return MainApp.sResources.getString(R.string.canceltemp);
|
||||
ret = MainApp.sResources.getString(R.string.canceltemp) + "\n";
|
||||
else if (rate == -1)
|
||||
ret = MainApp.sResources.getString(R.string.let_temp_basal_run) + "\n";
|
||||
else
|
||||
return MainApp.sResources.getString(R.string.rate) + ": " + DecimalFormatter.to2Decimal(rate) + " U/h " +
|
||||
"(" + DecimalFormatter.to2Decimal(rate / pump.getBaseBasalRate() * 100) + "%)\n" +
|
||||
MainApp.sResources.getString(R.string.duration) + ": " + DecimalFormatter.to0Decimal(duration) + " min\n" +
|
||||
MainApp.sResources.getString(R.string.reason) + ": " + reason;
|
||||
ret = MainApp.sResources.getString(R.string.rate) + ": " + DecimalFormatter.to2Decimal(rate) + " U/h " +
|
||||
"(" + DecimalFormatter.to2Decimal(rate / pump.getBaseBasalRate() * 100) + "%) \n" +
|
||||
MainApp.sResources.getString(R.string.duration) + ": " + DecimalFormatter.to2Decimal(duration) + " min\n";
|
||||
|
||||
// smb
|
||||
if (smb != 0)
|
||||
ret += ("SMB: " + DecimalFormatter.to2Decimal(smb) + " U\n");
|
||||
|
||||
// reason
|
||||
ret += MainApp.sResources.getString(R.string.reason) + ": " + reason;
|
||||
return ret;
|
||||
} else
|
||||
return MainApp.sResources.getString(R.string.nochangerequested);
|
||||
}
|
||||
|
||||
public Spanned toSpanned() {
|
||||
final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
|
||||
if (changeRequested) {
|
||||
String ret = "";
|
||||
if (rate == 0 && duration == 0) ret = MainApp.sResources.getString(R.string.canceltemp);
|
||||
if (isChangeRequested()) {
|
||||
String ret;
|
||||
// rate
|
||||
if (rate == 0 && duration == 0)
|
||||
ret = MainApp.sResources.getString(R.string.canceltemp) + "<br>";
|
||||
else if (rate == -1)
|
||||
ret = MainApp.sResources.getString(R.string.let_temp_basal_run) + "<br>";
|
||||
else
|
||||
ret = "<b>" + MainApp.sResources.getString(R.string.rate) + "</b>: " + DecimalFormatter.to2Decimal(rate) + " U/h " +
|
||||
"(" + DecimalFormatter.to2Decimal(rate / pump.getBaseBasalRate() * 100) + "%) <br>" +
|
||||
"<b>" + MainApp.sResources.getString(R.string.duration) + "</b>: " + DecimalFormatter.to2Decimal(duration) + " min<br>" +
|
||||
"<b>" + MainApp.sResources.getString(R.string.reason) + "</b>: " + reason.replace("<", "<").replace(">", ">");
|
||||
"(" + DecimalFormatter.to2Decimal(rate / pump.getBaseBasalRate() * 100) + "%) <br>" +
|
||||
"<b>" + MainApp.sResources.getString(R.string.duration) + "</b>: " + DecimalFormatter.to2Decimal(duration) + " min<br>";
|
||||
|
||||
// smb
|
||||
if (smb != 0)
|
||||
ret += ("<b>" + "SMB" + "</b>: " + DecimalFormatter.to2Decimal(smb) + " U<br>");
|
||||
|
||||
// reason
|
||||
ret += "<b>" + MainApp.sResources.getString(R.string.reason) + "</b>: " + reason.replace("<", "<").replace(">", ">");
|
||||
return Html.fromHtml(ret);
|
||||
} else
|
||||
return Html.fromHtml(MainApp.sResources.getString(R.string.nochangerequested));
|
||||
|
@ -62,17 +95,19 @@ public class APSResult {
|
|||
|
||||
public APSResult clone() {
|
||||
APSResult newResult = new APSResult();
|
||||
newResult.reason = new String(reason);
|
||||
newResult.reason = reason;
|
||||
newResult.rate = rate;
|
||||
newResult.duration = duration;
|
||||
newResult.changeRequested = changeRequested;
|
||||
newResult.tempBasalReqested = tempBasalReqested;
|
||||
newResult.bolusRequested = bolusRequested;
|
||||
newResult.iob = iob;
|
||||
return newResult;
|
||||
}
|
||||
|
||||
public JSONObject json() {
|
||||
JSONObject json = new JSONObject();
|
||||
try {
|
||||
if (changeRequested) {
|
||||
if (isChangeRequested()) {
|
||||
json.put("rate", rate);
|
||||
json.put("duration", duration);
|
||||
json.put("reason", reason);
|
||||
|
@ -82,4 +117,105 @@ public class APSResult {
|
|||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
public List<BgReading> getPredictions() {
|
||||
List<BgReading> array = new ArrayList<>();
|
||||
try {
|
||||
long startTime = date.getTime();
|
||||
if (json.has("predBGs")) {
|
||||
JSONObject predBGs = json.getJSONObject("predBGs");
|
||||
if (predBGs.has("IOB")) {
|
||||
JSONArray iob = predBGs.getJSONArray("IOB");
|
||||
for (int i = 1; i < iob.length(); i++) {
|
||||
BgReading bg = new BgReading();
|
||||
bg.value = iob.getInt(i);
|
||||
bg.date = startTime + i * 5 * 60 * 1000L;
|
||||
bg.isIOBPrediction = true;
|
||||
array.add(bg);
|
||||
}
|
||||
}
|
||||
if (predBGs.has("aCOB")) {
|
||||
JSONArray iob = predBGs.getJSONArray("aCOB");
|
||||
for (int i = 1; i < iob.length(); i++) {
|
||||
BgReading bg = new BgReading();
|
||||
bg.value = iob.getInt(i);
|
||||
bg.date = startTime + i * 5 * 60 * 1000L;
|
||||
bg.isaCOBPrediction = true;
|
||||
array.add(bg);
|
||||
}
|
||||
}
|
||||
if (predBGs.has("COB")) {
|
||||
JSONArray iob = predBGs.getJSONArray("COB");
|
||||
for (int i = 1; i < iob.length(); i++) {
|
||||
BgReading bg = new BgReading();
|
||||
bg.value = iob.getInt(i);
|
||||
bg.date = startTime + i * 5 * 60 * 1000L;
|
||||
bg.isCOBPrediction = true;
|
||||
array.add(bg);
|
||||
}
|
||||
}
|
||||
if (predBGs.has("UAM")) {
|
||||
JSONArray iob = predBGs.getJSONArray("UAM");
|
||||
for (int i = 1; i < iob.length(); i++) {
|
||||
BgReading bg = new BgReading();
|
||||
bg.value = iob.getInt(i);
|
||||
bg.date = startTime + i * 5 * 60 * 1000L;
|
||||
bg.isUAMPrediction = true;
|
||||
array.add(bg);
|
||||
}
|
||||
}
|
||||
if (predBGs.has("ZT")) {
|
||||
JSONArray iob = predBGs.getJSONArray("ZT");
|
||||
for (int i = 1; i < iob.length(); i++) {
|
||||
BgReading bg = new BgReading();
|
||||
bg.value = iob.getInt(i);
|
||||
bg.date = startTime + i * 5 * 60 * 1000L;
|
||||
bg.isZTPrediction = true;
|
||||
array.add(bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public long getLatestPredictionsTime() {
|
||||
long latest = 0;
|
||||
try {
|
||||
long startTime = date != null ? date.getTime() : 0;
|
||||
if (json.has("predBGs")) {
|
||||
JSONObject predBGs = json.getJSONObject("predBGs");
|
||||
if (predBGs.has("IOB")) {
|
||||
JSONArray iob = predBGs.getJSONArray("IOB");
|
||||
latest = Math.max(latest, startTime + (iob.length() - 1) * 5 * 60 * 1000L);
|
||||
}
|
||||
if (predBGs.has("aCOB")) {
|
||||
JSONArray iob = predBGs.getJSONArray("aCOB");
|
||||
latest = Math.max(latest, startTime + (iob.length() - 1) * 5 * 60 * 1000L);
|
||||
}
|
||||
if (predBGs.has("COB")) {
|
||||
JSONArray iob = predBGs.getJSONArray("COB");
|
||||
latest = Math.max(latest, startTime + (iob.length() - 1) * 5 * 60 * 1000L);
|
||||
}
|
||||
if (predBGs.has("UAM")) {
|
||||
JSONArray iob = predBGs.getJSONArray("UAM");
|
||||
latest = Math.max(latest, startTime + (iob.length() - 1) * 5 * 60 * 1000L);
|
||||
}
|
||||
if (predBGs.has("ZT")) {
|
||||
JSONArray iob = predBGs.getJSONArray("ZT");
|
||||
latest = Math.max(latest, startTime + (iob.length() - 1) * 5 * 60 * 1000L);
|
||||
}
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return latest;
|
||||
}
|
||||
|
||||
public boolean isChangeRequested() {
|
||||
return tempBasalReqested || bolusRequested;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,8 +9,6 @@ import android.view.ViewGroup;
|
|||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.crashlytics.android.Crashlytics;
|
||||
import com.crashlytics.android.answers.Answers;
|
||||
import com.crashlytics.android.answers.CustomEvent;
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
|
@ -22,6 +20,7 @@ import info.nightscout.androidaps.R;
|
|||
import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
|
||||
import info.nightscout.androidaps.plugins.Loop.events.EventLoopSetLastRunGui;
|
||||
import info.nightscout.androidaps.plugins.Loop.events.EventLoopUpdateGui;
|
||||
import info.nightscout.utils.FabricPrivacy;
|
||||
|
||||
public class LoopFragment extends SubscriberFragment implements View.OnClickListener {
|
||||
private static Logger log = LoggerFactory.getLogger(LoopFragment.class);
|
||||
|
@ -53,7 +52,7 @@ public class LoopFragment extends SubscriberFragment implements View.OnClickList
|
|||
updateGUI();
|
||||
return view;
|
||||
} catch (Exception e) {
|
||||
Crashlytics.logException(e);
|
||||
FabricPrivacy.logException(e);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -71,7 +70,7 @@ public class LoopFragment extends SubscriberFragment implements View.OnClickList
|
|||
}
|
||||
});
|
||||
thread.start();
|
||||
Answers.getInstance().logCustom(new CustomEvent("Loop_Run"));
|
||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("Loop_Run"));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ import android.content.Context;
|
|||
import android.content.Intent;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
|
||||
import com.crashlytics.android.answers.Answers;
|
||||
import com.crashlytics.android.answers.CustomEvent;
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
|
@ -30,10 +29,14 @@ import info.nightscout.androidaps.interfaces.ConstraintsInterface;
|
|||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished;
|
||||
import info.nightscout.androidaps.plugins.Loop.events.EventLoopResult;
|
||||
import info.nightscout.androidaps.plugins.Loop.events.EventLoopSetLastRunGui;
|
||||
import info.nightscout.androidaps.plugins.Loop.events.EventLoopUpdateGui;
|
||||
import info.nightscout.androidaps.plugins.Loop.events.EventNewOpenLoopNotification;
|
||||
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||
import info.nightscout.androidaps.queue.Callback;
|
||||
import info.nightscout.utils.FabricPrivacy;
|
||||
import info.nightscout.utils.NSUpload;
|
||||
import info.nightscout.utils.SP;
|
||||
|
||||
|
@ -148,12 +151,16 @@ public class LoopPlugin implements PluginBase {
|
|||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventTreatmentChange ev) {
|
||||
invoke("EventTreatmentChange", true);
|
||||
if (ev.treatment == null || !ev.treatment.isSMB){
|
||||
invoke("EventTreatmentChange", true);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventNewBG ev) {
|
||||
invoke("EventNewBG", true);
|
||||
public void onStatusEvent(final EventAutosensCalculationFinished ev) {
|
||||
if (ev.cause instanceof EventNewBG) {
|
||||
invoke(ev.getClass().getSimpleName() + "(" + ev.cause.getClass().getSimpleName() + ")", true);
|
||||
}
|
||||
}
|
||||
|
||||
public long suspendedTo() {
|
||||
|
@ -283,6 +290,14 @@ public class LoopPlugin implements PluginBase {
|
|||
// check rate for constrais
|
||||
final APSResult resultAfterConstraints = result.clone();
|
||||
resultAfterConstraints.rate = constraintsInterface.applyBasalConstraints(resultAfterConstraints.rate);
|
||||
resultAfterConstraints.smb = constraintsInterface.applyBolusConstraints(resultAfterConstraints.smb);
|
||||
|
||||
// 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");
|
||||
resultAfterConstraints.smb = 0;
|
||||
}
|
||||
|
||||
if (lastRun == null) lastRun = new LastRun();
|
||||
lastRun.request = result;
|
||||
|
@ -305,8 +320,10 @@ public class LoopPlugin implements PluginBase {
|
|||
return;
|
||||
}
|
||||
|
||||
MainApp.bus().post(new EventLoopResult(resultAfterConstraints));
|
||||
|
||||
if (constraintsInterface.isClosedModeEnabled()) {
|
||||
if (result.changeRequested) {
|
||||
if (result.isChangeRequested()) {
|
||||
final PumpEnactResult waiting = new PumpEnactResult();
|
||||
final PumpEnactResult previousResult = lastRun.setByPump;
|
||||
waiting.queued = true;
|
||||
|
@ -315,7 +332,7 @@ public class LoopPlugin implements PluginBase {
|
|||
MainApp.getConfigBuilder().applyAPSRequest(resultAfterConstraints, new Callback() {
|
||||
@Override
|
||||
public void run() {
|
||||
Answers.getInstance().logCustom(new CustomEvent("APSRequest"));
|
||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("APSRequest"));
|
||||
if (result.enacted || result.success) {
|
||||
lastRun.setByPump = result;
|
||||
lastRun.lastEnact = lastRun.lastAPSRun;
|
||||
|
@ -330,7 +347,7 @@ public class LoopPlugin implements PluginBase {
|
|||
lastRun.source = null;
|
||||
}
|
||||
} else {
|
||||
if (result.changeRequested && allowNotification) {
|
||||
if (result.isChangeRequested() && allowNotification) {
|
||||
NotificationCompat.Builder builder =
|
||||
new NotificationCompat.Builder(MainApp.instance().getApplicationContext());
|
||||
builder.setSmallIcon(R.drawable.notif_icon)
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
package info.nightscout.androidaps.plugins.Loop.events;
|
||||
|
||||
import info.nightscout.androidaps.plugins.Loop.APSResult;
|
||||
|
||||
public class EventLoopResult {
|
||||
public final APSResult apsResult;
|
||||
|
||||
public EventLoopResult(APSResult apsResult) {
|
||||
this.apsResult = apsResult;
|
||||
}
|
||||
}
|
||||
|
|
@ -18,8 +18,6 @@ import android.widget.CompoundButton;
|
|||
import android.widget.ScrollView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.crashlytics.android.Crashlytics;
|
||||
import com.crashlytics.android.answers.Answers;
|
||||
import com.crashlytics.android.answers.CustomEvent;
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
|
@ -33,6 +31,7 @@ import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
|
|||
import info.nightscout.androidaps.plugins.NSClientInternal.events.EventNSClientNewLog;
|
||||
import info.nightscout.androidaps.plugins.NSClientInternal.events.EventNSClientRestart;
|
||||
import info.nightscout.androidaps.plugins.NSClientInternal.events.EventNSClientUpdateGUI;
|
||||
import info.nightscout.utils.FabricPrivacy;
|
||||
import info.nightscout.utils.SP;
|
||||
|
||||
public class NSClientInternalFragment extends SubscriberFragment implements View.OnClickListener, CompoundButton.OnCheckedChangeListener {
|
||||
|
@ -88,7 +87,7 @@ public class NSClientInternalFragment extends SubscriberFragment implements View
|
|||
updateGUI();
|
||||
return view;
|
||||
} catch (Exception e) {
|
||||
Crashlytics.logException(e);
|
||||
FabricPrivacy.logException(e);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -99,11 +98,11 @@ public class NSClientInternalFragment extends SubscriberFragment implements View
|
|||
switch (view.getId()) {
|
||||
case R.id.nsclientinternal_restart:
|
||||
MainApp.bus().post(new EventNSClientRestart());
|
||||
Answers.getInstance().logCustom(new CustomEvent("NSClientRestart"));
|
||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("NSClientRestart"));
|
||||
break;
|
||||
case R.id.nsclientinternal_delivernow:
|
||||
NSClientInternalPlugin.getPlugin().resend("GUI");
|
||||
Answers.getInstance().logCustom(new CustomEvent("NSClientDeliverNow"));
|
||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("NSClientDeliverNow"));
|
||||
break;
|
||||
case R.id.nsclientinternal_clearlog:
|
||||
NSClientInternalPlugin.getPlugin().clearLog();
|
||||
|
@ -118,7 +117,7 @@ public class NSClientInternalFragment extends SubscriberFragment implements View
|
|||
public void onClick(DialogInterface dialog, int id) {
|
||||
UploadQueue.clearQueue();
|
||||
updateGUI();
|
||||
Answers.getInstance().logCustom(new CustomEvent("NSClientClearQueue"));
|
||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("NSClientClearQueue"));
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton(getString(R.string.cancel), null);
|
||||
|
@ -126,7 +125,7 @@ public class NSClientInternalFragment extends SubscriberFragment implements View
|
|||
break;
|
||||
case R.id.nsclientinternal_showqueue:
|
||||
MainApp.bus().post(new EventNSClientNewLog("QUEUE", NSClientInternalPlugin.getPlugin().queue().textList()));
|
||||
Answers.getInstance().logCustom(new CustomEvent("NSClientShowQueue"));
|
||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("NSClientShowQueue"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -139,7 +138,7 @@ public class NSClientInternalFragment extends SubscriberFragment implements View
|
|||
NSClientInternalPlugin.getPlugin().paused = isChecked;
|
||||
MainApp.bus().post(new EventPreferenceChange(R.string.key_nsclientinternal_paused));
|
||||
updateGUI();
|
||||
Answers.getInstance().logCustom(new CustomEvent("NSClientPause"));
|
||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("NSClientPause"));
|
||||
break;
|
||||
case R.id.nsclientinternal_autoscroll:
|
||||
SP.putBoolean(R.string.key_nsclientinternal_autoscroll, isChecked);
|
||||
|
|
|
@ -124,7 +124,7 @@ public class NSDeviceStatus {
|
|||
static DeviceStatusPumpData deviceStatusPumpData = null;
|
||||
|
||||
public Spanned getExtendedPumpStatus() {
|
||||
if (deviceStatusPumpData.extended != null)
|
||||
if (deviceStatusPumpData != null && deviceStatusPumpData.extended != null)
|
||||
return deviceStatusPumpData.extended;
|
||||
return Html.fromHtml("");
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import android.os.HandlerThread;
|
|||
import android.os.IBinder;
|
||||
import android.os.PowerManager;
|
||||
|
||||
import com.crashlytics.android.Crashlytics;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.hash.Hashing;
|
||||
import com.j256.ormlite.dao.CloseableIterator;
|
||||
|
@ -62,6 +62,8 @@ import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotificati
|
|||
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
|
||||
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
|
||||
import info.nightscout.utils.DateUtil;
|
||||
import info.nightscout.utils.FabricPrivacy;
|
||||
import info.nightscout.utils.JsonHelper;
|
||||
import info.nightscout.utils.SP;
|
||||
import io.socket.client.IO;
|
||||
import io.socket.client.Socket;
|
||||
|
@ -123,7 +125,7 @@ public class NSClientService extends Service {
|
|||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
mWakeLock.release();
|
||||
if (mWakeLock.isHeld()) mWakeLock.release();
|
||||
}
|
||||
|
||||
public class LocalBinder extends Binder {
|
||||
|
@ -345,14 +347,14 @@ public class NSClientService extends Service {
|
|||
try {
|
||||
data = (JSONObject) args[0];
|
||||
} catch (Exception e) {
|
||||
Crashlytics.log("Wrong Announcement from NS: " + args[0]);
|
||||
FabricPrivacy.log("Wrong Announcement from NS: " + args[0]);
|
||||
return;
|
||||
}
|
||||
if (Config.detailedLog)
|
||||
try {
|
||||
MainApp.bus().post(new EventNSClientNewLog("ANNOUNCEMENT", data.has("message") ? data.getString("message") : "received"));
|
||||
MainApp.bus().post(new EventNSClientNewLog("ANNOUNCEMENT", JsonHelper.safeGetString(data, "message", "received")));
|
||||
} catch (Exception e) {
|
||||
Crashlytics.logException(e);
|
||||
FabricPrivacy.logException(e);
|
||||
}
|
||||
BroadcastAnnouncement.handleAnnouncement(data, getApplicationContext());
|
||||
log.debug(data.toString());
|
||||
|
@ -381,7 +383,7 @@ public class NSClientService extends Service {
|
|||
try {
|
||||
data = (JSONObject) args[0];
|
||||
} catch (Exception e) {
|
||||
Crashlytics.log("Wrong alarm from NS: " + args[0]);
|
||||
FabricPrivacy.log("Wrong alarm from NS: " + args[0]);
|
||||
return;
|
||||
}
|
||||
BroadcastAlarm.handleAlarm(data, getApplicationContext());
|
||||
|
@ -409,7 +411,7 @@ public class NSClientService extends Service {
|
|||
try {
|
||||
data = (JSONObject) args[0];
|
||||
} catch (Exception e) {
|
||||
Crashlytics.log("Wrong Urgent alarm from NS: " + args[0]);
|
||||
FabricPrivacy.log("Wrong Urgent alarm from NS: " + args[0]);
|
||||
return;
|
||||
}
|
||||
if (Config.detailedLog)
|
||||
|
@ -434,7 +436,7 @@ public class NSClientService extends Service {
|
|||
try {
|
||||
data = (JSONObject) args[0];
|
||||
} catch (Exception e) {
|
||||
Crashlytics.log("Wrong Urgent alarm from NS: " + args[0]);
|
||||
FabricPrivacy.log("Wrong Urgent alarm from NS: " + args[0]);
|
||||
return;
|
||||
}
|
||||
if (Config.detailedLog)
|
||||
|
@ -572,22 +574,18 @@ public class NSClientService extends Service {
|
|||
MainApp.bus().post(new EventNSClientNewLog("DATA", "received " + foods.length() + " foods"));
|
||||
for (Integer index = 0; index < foods.length(); index++) {
|
||||
JSONObject jsonFood = foods.getJSONObject(index);
|
||||
NSTreatment treatment = new NSTreatment(jsonFood);
|
||||
|
||||
// remove from upload queue if Ack is failing
|
||||
UploadQueue.removeID(jsonFood);
|
||||
//Find latest date in treatment
|
||||
if (treatment.getMills() != null && treatment.getMills() < System.currentTimeMillis())
|
||||
if (treatment.getMills() > latestDateInReceivedData)
|
||||
latestDateInReceivedData = treatment.getMills();
|
||||
|
||||
if (treatment.getAction() == null) {
|
||||
String action = JsonHelper.safeGetString(jsonFood, "action");
|
||||
|
||||
if (action == null) {
|
||||
addedFoods.put(jsonFood);
|
||||
} else if (treatment.getAction().equals("update")) {
|
||||
} else if (action.equals("update")) {
|
||||
updatedFoods.put(jsonFood);
|
||||
} else if (treatment.getAction().equals("remove")) {
|
||||
if (treatment.getMills() != null && treatment.getMills() > System.currentTimeMillis() - 24 * 60 * 60 * 1000L) // handle 1 day old deletions only
|
||||
removedFoods.put(jsonFood);
|
||||
} else if (action.equals("remove")) {
|
||||
removedFoods.put(jsonFood);
|
||||
}
|
||||
}
|
||||
if (removedFoods.length() > 0) {
|
||||
|
@ -600,18 +598,6 @@ public class NSClientService extends Service {
|
|||
BroadcastFood.handleNewFood(addedFoods, MainApp.instance().getApplicationContext(), isDelta);
|
||||
}
|
||||
}
|
||||
if (data.has("")) {
|
||||
JSONArray foods = data.getJSONArray("food");
|
||||
if (foods.length() > 0) {
|
||||
MainApp.bus().post(new EventNSClientNewLog("DATA", "received " + foods.length() + " foods"));
|
||||
for (Integer index = 0; index < foods.length(); index++) {
|
||||
JSONObject jsonFood = foods.getJSONObject(index);
|
||||
// remove from upload queue if Ack is failing
|
||||
UploadQueue.removeID(jsonFood);
|
||||
}
|
||||
BroadcastDeviceStatus.handleNewFoods(foods, MainApp.instance().getApplicationContext(), isDelta);
|
||||
}
|
||||
}
|
||||
if (data.has("mbgs")) {
|
||||
JSONArray mbgs = data.getJSONArray("mbgs");
|
||||
if (mbgs.length() > 0)
|
||||
|
@ -665,7 +651,7 @@ public class NSClientService extends Service {
|
|||
}
|
||||
//MainApp.bus().post(new EventNSClientNewLog("NSCLIENT", "onDataUpdate end");
|
||||
} finally {
|
||||
wakeLock.release();
|
||||
if (wakeLock.isHeld()) wakeLock.release();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ import info.nightscout.androidaps.db.TemporaryBasal;
|
|||
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
|
||||
import info.nightscout.androidaps.plugins.Loop.ScriptReader;
|
||||
import info.nightscout.androidaps.plugins.OpenAPSMA.LoggerCallback;
|
||||
import info.nightscout.androidaps.plugins.OpenAPSSMB.SMBDefaults;
|
||||
import info.nightscout.utils.SP;
|
||||
|
||||
public class DetermineBasalAdapterAMAJS {
|
||||
|
@ -189,8 +190,7 @@ public class DetermineBasalAdapterAMAJS {
|
|||
GlucoseStatus glucoseStatus,
|
||||
MealData mealData,
|
||||
double autosensDataRatio,
|
||||
boolean tempTargetSet,
|
||||
double min_5m_carbimpact) throws JSONException {
|
||||
boolean tempTargetSet) throws JSONException {
|
||||
|
||||
String units = profile.getUnits();
|
||||
|
||||
|
@ -206,12 +206,13 @@ public class DetermineBasalAdapterAMAJS {
|
|||
mProfile.put("carb_ratio", profile.getIc());
|
||||
mProfile.put("sens", Profile.toMgdl(profile.getIsf().doubleValue(), units));
|
||||
mProfile.put("max_daily_safety_multiplier", SP.getInt("openapsama_max_daily_safety_multiplier", 3));
|
||||
mProfile.put("current_basal_safety_multiplier", SP.getInt("openapsama_current_basal_safety_multiplier", 4));
|
||||
mProfile.put("current_basal_safety_multiplier", SP.getDouble("openapsama_current_basal_safety_multiplier", 4d));
|
||||
mProfile.put("skip_neutral_temps", true);
|
||||
mProfile.put("current_basal", basalrate);
|
||||
mProfile.put("temptargetSet", tempTargetSet);
|
||||
mProfile.put("autosens_adjust_targets", SP.getBoolean("openapsama_autosens_adjusttargets", true));
|
||||
mProfile.put("min_5m_carbimpact", SP.getDouble("openapsama_min_5m_carbimpact", 3d));
|
||||
//TODO: align with max-absorption model in AMA sensitivity
|
||||
mProfile.put("min_5m_carbimpact", SP.getDouble("openapsama_min_5m_carbimpact", SMBDefaults.min_5m_carbimpact));
|
||||
|
||||
if (units.equals(Constants.MMOL)) {
|
||||
mProfile.put("out_units", "mmol/L");
|
||||
|
|
|
@ -1,35 +1,28 @@
|
|||
package info.nightscout.androidaps.plugins.OpenAPSAMA;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.mozilla.javascript.NativeObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import info.nightscout.androidaps.db.BgReading;
|
||||
import info.nightscout.androidaps.plugins.Loop.APSResult;
|
||||
import info.nightscout.androidaps.data.IobTotal;
|
||||
|
||||
public class DetermineBasalResultAMA extends APSResult {
|
||||
private static Logger log = LoggerFactory.getLogger(DetermineBasalResultAMA.class);
|
||||
|
||||
public Date date;
|
||||
public JSONObject json = new JSONObject();
|
||||
public double eventualBG;
|
||||
public double snoozeBG;
|
||||
public IobTotal iob;
|
||||
|
||||
public DetermineBasalResultAMA(NativeObject result, JSONObject j) {
|
||||
this();
|
||||
date = new Date();
|
||||
json = j;
|
||||
if (result.containsKey("error")) {
|
||||
reason = result.get("error").toString();
|
||||
changeRequested = false;
|
||||
tempBasalReqested = false;
|
||||
rate = -1;
|
||||
duration = -1;
|
||||
} else {
|
||||
|
@ -37,36 +30,37 @@ public class DetermineBasalResultAMA extends APSResult {
|
|||
if (result.containsKey("eventualBG")) eventualBG = (Double) result.get("eventualBG");
|
||||
if (result.containsKey("snoozeBG")) snoozeBG = (Double) result.get("snoozeBG");
|
||||
if (result.containsKey("rate")) {
|
||||
rate = (Double) result.get("rate");
|
||||
rate = (Double) result.get("rate");
|
||||
if (rate < 0d) rate = 0d;
|
||||
changeRequested = true;
|
||||
tempBasalReqested = true;
|
||||
} else {
|
||||
rate = -1;
|
||||
changeRequested = false;
|
||||
tempBasalReqested = false;
|
||||
}
|
||||
if (result.containsKey("duration")) {
|
||||
duration = ((Double)result.get("duration")).intValue();
|
||||
duration = ((Double) result.get("duration")).intValue();
|
||||
//changeRequested as above
|
||||
} else {
|
||||
duration = -1;
|
||||
changeRequested = false;
|
||||
tempBasalReqested = false;
|
||||
}
|
||||
}
|
||||
bolusRequested = false;
|
||||
}
|
||||
|
||||
public DetermineBasalResultAMA() {
|
||||
hasPredictions = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DetermineBasalResultAMA clone() {
|
||||
DetermineBasalResultAMA newResult = new DetermineBasalResultAMA();
|
||||
newResult.reason = new String(reason);
|
||||
newResult.reason = reason;
|
||||
newResult.rate = rate;
|
||||
newResult.duration = duration;
|
||||
newResult.changeRequested = changeRequested;
|
||||
newResult.tempBasalReqested = tempBasalReqested;
|
||||
newResult.rate = rate;
|
||||
newResult.duration = duration;
|
||||
newResult.changeRequested = changeRequested;
|
||||
|
||||
try {
|
||||
newResult.json = new JSONObject(json.toString());
|
||||
|
@ -90,72 +84,4 @@ public class DetermineBasalResultAMA extends APSResult {
|
|||
return null;
|
||||
}
|
||||
|
||||
public List<BgReading> getPredictions() {
|
||||
List<BgReading> array = new ArrayList<>();
|
||||
try {
|
||||
long startTime = date.getTime();
|
||||
if (json.has("predBGs")) {
|
||||
JSONObject predBGs = json.getJSONObject("predBGs");
|
||||
if (predBGs.has("IOB")) {
|
||||
JSONArray iob = predBGs.getJSONArray("IOB");
|
||||
for (int i = 1; i < iob.length(); i ++) {
|
||||
BgReading bg = new BgReading();
|
||||
bg.value = iob.getInt(i);
|
||||
bg.date = startTime + i * 5 * 60 * 1000L;
|
||||
bg.isPrediction = true;
|
||||
array.add(bg);
|
||||
}
|
||||
}
|
||||
if (predBGs.has("aCOB")) {
|
||||
JSONArray iob = predBGs.getJSONArray("aCOB");
|
||||
for (int i = 1; i < iob.length(); i ++) {
|
||||
BgReading bg = new BgReading();
|
||||
bg.value = iob.getInt(i);
|
||||
bg.date = startTime + i * 5 * 60 * 1000L;
|
||||
bg.isPrediction = true;
|
||||
array.add(bg);
|
||||
}
|
||||
}
|
||||
if (predBGs.has("COB")) {
|
||||
JSONArray iob = predBGs.getJSONArray("COB");
|
||||
for (int i = 1; i < iob.length(); i ++) {
|
||||
BgReading bg = new BgReading();
|
||||
bg.value = iob.getInt(i);
|
||||
bg.date = startTime + i * 5 * 60 * 1000L;
|
||||
bg.isPrediction = true;
|
||||
array.add(bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public long getLatestPredictionsTime() {
|
||||
long latest = 0;
|
||||
try {
|
||||
long startTime = date.getTime();
|
||||
if (json.has("predBGs")) {
|
||||
JSONObject predBGs = json.getJSONObject("predBGs");
|
||||
if (predBGs.has("IOB")) {
|
||||
JSONArray iob = predBGs.getJSONArray("IOB");
|
||||
latest = Math.max(latest, startTime + (iob.length() - 1) * 5 * 60 * 1000L);
|
||||
}
|
||||
if (predBGs.has("aCOB")) {
|
||||
JSONArray iob = predBGs.getJSONArray("aCOB");
|
||||
latest = Math.max(latest, startTime + (iob.length() - 1) * 5 * 60 * 1000L);
|
||||
}
|
||||
if (predBGs.has("COB")) {
|
||||
JSONArray iob = predBGs.getJSONArray("COB");
|
||||
latest = Math.max(latest, startTime + (iob.length() - 1) * 5 * 60 * 1000L);
|
||||
}
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
|
||||
return latest;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,8 +9,6 @@ import android.view.ViewGroup;
|
|||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.crashlytics.android.Crashlytics;
|
||||
import com.crashlytics.android.answers.Answers;
|
||||
import com.crashlytics.android.answers.CustomEvent;
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
|
@ -24,6 +22,7 @@ import info.nightscout.androidaps.R;
|
|||
import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
|
||||
import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateGui;
|
||||
import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateResultGui;
|
||||
import info.nightscout.utils.FabricPrivacy;
|
||||
import info.nightscout.utils.JSONFormatter;
|
||||
|
||||
public class OpenAPSAMAFragment extends SubscriberFragment implements View.OnClickListener {
|
||||
|
@ -63,7 +62,7 @@ public class OpenAPSAMAFragment extends SubscriberFragment implements View.OnCli
|
|||
updateGUI();
|
||||
return view;
|
||||
} catch (Exception e) {
|
||||
Crashlytics.logException(e);
|
||||
FabricPrivacy.logException(e);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -74,7 +73,7 @@ public class OpenAPSAMAFragment extends SubscriberFragment implements View.OnCli
|
|||
switch (view.getId()) {
|
||||
case R.id.openapsma_run:
|
||||
OpenAPSAMAPlugin.getPlugin().invoke("OpenAPSAMA button");
|
||||
Answers.getInstance().logCustom(new CustomEvent("OpenAPS_AMA_Run"));
|
||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("OpenAPS_AMA_Run"));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ import java.io.IOException;
|
|||
import java.util.Date;
|
||||
|
||||
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.GlucoseStatus;
|
||||
|
@ -18,6 +17,7 @@ import info.nightscout.androidaps.data.Profile;
|
|||
import info.nightscout.androidaps.db.TempTarget;
|
||||
import info.nightscout.androidaps.interfaces.APSInterface;
|
||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensResult;
|
||||
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
|
||||
|
@ -26,12 +26,10 @@ import info.nightscout.androidaps.plugins.Loop.ScriptReader;
|
|||
import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateGui;
|
||||
import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateResultGui;
|
||||
import info.nightscout.utils.DateUtil;
|
||||
import info.nightscout.utils.NSUpload;
|
||||
import info.nightscout.utils.HardLimits;
|
||||
import info.nightscout.utils.Profiler;
|
||||
import info.nightscout.utils.Round;
|
||||
import info.nightscout.utils.SP;
|
||||
import info.nightscout.utils.SafeParse;
|
||||
import info.nightscout.utils.ToastUtils;
|
||||
|
||||
/**
|
||||
* Created by mike on 05.08.2016.
|
||||
|
@ -149,6 +147,7 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface {
|
|||
|
||||
GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData();
|
||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||
PumpInterface pump = ConfigBuilderPlugin.getActivePump();
|
||||
|
||||
if (profile == null) {
|
||||
MainApp.bus().post(new EventOpenAPSUpdateResultGui(MainApp.instance().getString(R.string.noprofileselected)));
|
||||
|
@ -177,14 +176,14 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface {
|
|||
double maxBasal = SP.getDouble("openapsma_max_basal", 1d);
|
||||
double minBg = Profile.toMgdl(profile.getTargetLow(), units);
|
||||
double maxBg = Profile.toMgdl(profile.getTargetHigh(), units);
|
||||
double targetBg = (minBg + maxBg) / 2;
|
||||
double targetBg = Profile.toMgdl(profile.getTarget(), units);
|
||||
|
||||
minBg = Round.roundTo(minBg, 0.1d);
|
||||
maxBg = Round.roundTo(maxBg, 0.1d);
|
||||
|
||||
Date start = new Date();
|
||||
Date startPart = new Date();
|
||||
IobTotal[] iobArray = IobCobCalculatorPlugin.calculateIobArrayInDia();
|
||||
IobTotal[] iobArray = IobCobCalculatorPlugin.getPlugin().calculateIobArrayInDia();
|
||||
Profiler.log(log, "calculateIobArrayInDia()", startPart);
|
||||
|
||||
startPart = new Date();
|
||||
|
@ -193,35 +192,37 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface {
|
|||
|
||||
maxIob = MainApp.getConfigBuilder().applyMaxIOBConstraints(maxIob);
|
||||
|
||||
minBg = verifyHardLimits(minBg, "minBg", Constants.VERY_HARD_LIMIT_MIN_BG[0], Constants.VERY_HARD_LIMIT_MIN_BG[1]);
|
||||
maxBg = verifyHardLimits(maxBg, "maxBg", Constants.VERY_HARD_LIMIT_MAX_BG[0], Constants.VERY_HARD_LIMIT_MAX_BG[1]);
|
||||
targetBg = verifyHardLimits(targetBg, "targetBg", Constants.VERY_HARD_LIMIT_TARGET_BG[0], Constants.VERY_HARD_LIMIT_TARGET_BG[1]);
|
||||
minBg = HardLimits.verifyHardLimits(minBg, "minBg", HardLimits.VERY_HARD_LIMIT_MIN_BG[0], HardLimits.VERY_HARD_LIMIT_MIN_BG[1]);
|
||||
maxBg = HardLimits.verifyHardLimits(maxBg, "maxBg", HardLimits.VERY_HARD_LIMIT_MAX_BG[0], HardLimits.VERY_HARD_LIMIT_MAX_BG[1]);
|
||||
targetBg = HardLimits.verifyHardLimits(targetBg, "targetBg", HardLimits.VERY_HARD_LIMIT_TARGET_BG[0], HardLimits.VERY_HARD_LIMIT_TARGET_BG[1]);
|
||||
|
||||
boolean isTempTarget = false;
|
||||
TempTarget tempTarget = MainApp.getConfigBuilder().getTempTargetFromHistory(System.currentTimeMillis());
|
||||
if (tempTarget != null) {
|
||||
isTempTarget = true;
|
||||
minBg = verifyHardLimits(tempTarget.low, "minBg", Constants.VERY_HARD_LIMIT_TEMP_MIN_BG[0], Constants.VERY_HARD_LIMIT_TEMP_MIN_BG[1]);
|
||||
maxBg = verifyHardLimits(tempTarget.high, "maxBg", Constants.VERY_HARD_LIMIT_TEMP_MAX_BG[0], Constants.VERY_HARD_LIMIT_TEMP_MAX_BG[1]);
|
||||
targetBg = verifyHardLimits((tempTarget.low + tempTarget.high) / 2, "targetBg", Constants.VERY_HARD_LIMIT_TEMP_TARGET_BG[0], Constants.VERY_HARD_LIMIT_TEMP_TARGET_BG[1]);
|
||||
minBg = HardLimits.verifyHardLimits(tempTarget.low, "minBg", HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[1]);
|
||||
maxBg = HardLimits.verifyHardLimits(tempTarget.high, "maxBg", HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[1]);
|
||||
targetBg = HardLimits.verifyHardLimits(tempTarget.target(), "targetBg", HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[1]);
|
||||
}
|
||||
|
||||
|
||||
maxIob = verifyHardLimits(maxIob, "maxIob", 0, 7);
|
||||
maxBasal = verifyHardLimits(maxBasal, "max_basal", 0.1, 10);
|
||||
maxIob = HardLimits.verifyHardLimits(maxIob, "maxIob", 0, HardLimits.maxIobAMA());
|
||||
maxBasal = HardLimits.verifyHardLimits(maxBasal, "max_basal", 0.1, HardLimits.maxBasal());
|
||||
|
||||
if (!checkOnlyHardLimits(profile.getDia(), "dia", 2, 7)) return;
|
||||
if (!checkOnlyHardLimits(profile.getIc(Profile.secondsFromMidnight()), "carbratio", 2, 100))
|
||||
if (!HardLimits.checkOnlyHardLimits(profile.getDia(), "dia", HardLimits.MINDIA, HardLimits.MAXDIA))
|
||||
return;
|
||||
if (!checkOnlyHardLimits(Profile.toMgdl(profile.getIsf(), units), "sens", 2, 900))
|
||||
if (!HardLimits.checkOnlyHardLimits(profile.getIc(profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC))
|
||||
return;
|
||||
if (!checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.1, 10)) return;
|
||||
if (!checkOnlyHardLimits(ConfigBuilderPlugin.getActivePump().getBaseBasalRate(), "current_basal", 0.01, 5))
|
||||
if (!HardLimits.checkOnlyHardLimits(Profile.toMgdl(profile.getIsf().doubleValue(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF))
|
||||
return;
|
||||
if (!HardLimits.checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.05, HardLimits.maxBasal()))
|
||||
return;
|
||||
if (!HardLimits.checkOnlyHardLimits(pump.getBaseBasalRate(), "current_basal", 0.01, HardLimits.maxBasal()))
|
||||
return;
|
||||
|
||||
startPart = new Date();
|
||||
if (MainApp.getConfigBuilder().isAMAModeEnabled()) {
|
||||
lastAutosensResult = IobCobCalculatorPlugin.detectSensitivityWithLock(IobCobCalculatorPlugin.oldestDataAvailable(), System.currentTimeMillis());
|
||||
lastAutosensResult = IobCobCalculatorPlugin.getPlugin().detectSensitivityWithLock(IobCobCalculatorPlugin.oldestDataAvailable(), System.currentTimeMillis());
|
||||
} else {
|
||||
lastAutosensResult = new AutosensResult();
|
||||
}
|
||||
|
@ -233,8 +234,7 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface {
|
|||
try {
|
||||
determineBasalAdapterAMAJS.setData(profile, maxIob, maxBasal, minBg, maxBg, targetBg, ConfigBuilderPlugin.getActivePump().getBaseBasalRate(), iobArray, glucoseStatus, mealData,
|
||||
lastAutosensResult.ratio, //autosensDataRatio
|
||||
isTempTarget,
|
||||
SafeParse.stringToDouble(SP.getString("openapsama_min_5m_carbimpact", "3.0"))//min_5m_carbimpact
|
||||
isTempTarget
|
||||
);
|
||||
} catch (JSONException e) {
|
||||
log.error("Unable to set data: " + e.toString());
|
||||
|
@ -245,15 +245,15 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface {
|
|||
Profiler.log(log, "AMA calculation", start);
|
||||
// Fix bug determine basal
|
||||
if (determineBasalResultAMA.rate == 0d && determineBasalResultAMA.duration == 0 && !MainApp.getConfigBuilder().isTempBasalInProgress())
|
||||
determineBasalResultAMA.changeRequested = false;
|
||||
determineBasalResultAMA.tempBasalReqested = false;
|
||||
// limit requests on openloop mode
|
||||
if (!MainApp.getConfigBuilder().isClosedModeEnabled()) {
|
||||
if (MainApp.getConfigBuilder().isTempBasalInProgress() && determineBasalResultAMA.rate == 0 && determineBasalResultAMA.duration == 0) {
|
||||
// going to cancel
|
||||
} else if (MainApp.getConfigBuilder().isTempBasalInProgress() && Math.abs(determineBasalResultAMA.rate - MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory()) < 0.1) {
|
||||
determineBasalResultAMA.changeRequested = false;
|
||||
determineBasalResultAMA.tempBasalReqested = false;
|
||||
} else if (!MainApp.getConfigBuilder().isTempBasalInProgress() && Math.abs(determineBasalResultAMA.rate - ConfigBuilderPlugin.getActivePump().getBaseBasalRate()) < 0.1)
|
||||
determineBasalResultAMA.changeRequested = false;
|
||||
determineBasalResultAMA.tempBasalReqested = false;
|
||||
}
|
||||
|
||||
determineBasalResultAMA.iob = iobArray[0];
|
||||
|
@ -274,24 +274,4 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface {
|
|||
//deviceStatus.suggested = determineBasalResultAMA.json;
|
||||
}
|
||||
|
||||
// safety checks
|
||||
public static boolean checkOnlyHardLimits(Double value, String valueName, double lowLimit, double highLimit) {
|
||||
return value.equals(verifyHardLimits(value, valueName, lowLimit, highLimit));
|
||||
}
|
||||
|
||||
public static Double verifyHardLimits(Double value, String valueName, double lowLimit, double highLimit) {
|
||||
Double newvalue = value;
|
||||
if (newvalue < lowLimit || newvalue > highLimit) {
|
||||
newvalue = Math.max(newvalue, lowLimit);
|
||||
newvalue = Math.min(newvalue, highLimit);
|
||||
String msg = String.format(MainApp.sResources.getString(R.string.openapsma_valueoutofrange), valueName);
|
||||
msg += ".\n";
|
||||
msg += String.format(MainApp.sResources.getString(R.string.openapsma_valuelimitedto), value, newvalue);
|
||||
log.error(msg);
|
||||
NSUpload.uploadError(msg);
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), msg, R.raw.error);
|
||||
}
|
||||
return newvalue;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ import org.mozilla.javascript.NativeObject;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.data.IobTotal;
|
||||
import info.nightscout.androidaps.plugins.Loop.APSResult;
|
||||
|
||||
public class DetermineBasalResultMA extends APSResult {
|
||||
|
@ -16,13 +15,12 @@ public class DetermineBasalResultMA extends APSResult {
|
|||
public double eventualBG;
|
||||
public double snoozeBG;
|
||||
public String mealAssist;
|
||||
public IobTotal iob;
|
||||
|
||||
public DetermineBasalResultMA(NativeObject result, JSONObject j) {
|
||||
json = j;
|
||||
if (result.containsKey("error")) {
|
||||
reason = (String) result.get("error");
|
||||
changeRequested = false;
|
||||
tempBasalReqested = false;
|
||||
rate = -1;
|
||||
duration = -1;
|
||||
mealAssist = "";
|
||||
|
@ -33,17 +31,17 @@ public class DetermineBasalResultMA extends APSResult {
|
|||
if (result.containsKey("rate")) {
|
||||
rate = (Double) result.get("rate");
|
||||
if (rate < 0d) rate = 0d;
|
||||
changeRequested = true;
|
||||
tempBasalReqested = true;
|
||||
} else {
|
||||
rate = -1;
|
||||
changeRequested = false;
|
||||
tempBasalReqested = false;
|
||||
}
|
||||
if (result.containsKey("duration")) {
|
||||
duration = ((Double) result.get("duration")).intValue();
|
||||
//changeRequested as above
|
||||
} else {
|
||||
duration = -1;
|
||||
changeRequested = false;
|
||||
tempBasalReqested = false;
|
||||
}
|
||||
if (result.containsKey("mealAssist")) {
|
||||
mealAssist = result.get("mealAssist").toString();
|
||||
|
@ -60,10 +58,10 @@ public class DetermineBasalResultMA extends APSResult {
|
|||
newResult.reason = new String(reason);
|
||||
newResult.rate = rate;
|
||||
newResult.duration = duration;
|
||||
newResult.changeRequested = changeRequested;
|
||||
newResult.tempBasalReqested = isChangeRequested();
|
||||
newResult.rate = rate;
|
||||
newResult.duration = duration;
|
||||
newResult.changeRequested = changeRequested;
|
||||
newResult.tempBasalReqested = isChangeRequested();
|
||||
|
||||
try {
|
||||
newResult.json = new JSONObject(json.toString());
|
||||
|
@ -72,7 +70,7 @@ public class DetermineBasalResultMA extends APSResult {
|
|||
}
|
||||
newResult.eventualBG = eventualBG;
|
||||
newResult.snoozeBG = snoozeBG;
|
||||
newResult.mealAssist = new String(mealAssist);
|
||||
newResult.mealAssist = mealAssist;
|
||||
return newResult;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,8 +9,6 @@ import android.view.ViewGroup;
|
|||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.crashlytics.android.Crashlytics;
|
||||
import com.crashlytics.android.answers.Answers;
|
||||
import com.crashlytics.android.answers.CustomEvent;
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
|
@ -22,6 +20,7 @@ import info.nightscout.androidaps.R;
|
|||
import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
|
||||
import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateGui;
|
||||
import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateResultGui;
|
||||
import info.nightscout.utils.FabricPrivacy;
|
||||
import info.nightscout.utils.JSONFormatter;
|
||||
|
||||
public class OpenAPSMAFragment extends SubscriberFragment implements View.OnClickListener {
|
||||
|
@ -57,7 +56,7 @@ public class OpenAPSMAFragment extends SubscriberFragment implements View.OnClic
|
|||
updateGUI();
|
||||
return view;
|
||||
} catch (Exception e) {
|
||||
Crashlytics.logException(e);
|
||||
FabricPrivacy.logException(e);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -68,7 +67,7 @@ public class OpenAPSMAFragment extends SubscriberFragment implements View.OnClic
|
|||
switch (view.getId()) {
|
||||
case R.id.openapsma_run:
|
||||
OpenAPSMAPlugin.getPlugin().invoke("OpenAPSMA button");
|
||||
Answers.getInstance().logCustom(new CustomEvent("OpenAPS_MA_Run"));
|
||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("OpenAPS_MA_Run"));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ import java.io.IOException;
|
|||
import java.util.Date;
|
||||
|
||||
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.GlucoseStatus;
|
||||
|
@ -18,19 +17,21 @@ import info.nightscout.androidaps.data.Profile;
|
|||
import info.nightscout.androidaps.db.TempTarget;
|
||||
import info.nightscout.androidaps.interfaces.APSInterface;
|
||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.Loop.APSResult;
|
||||
import info.nightscout.androidaps.plugins.Loop.ScriptReader;
|
||||
import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateGui;
|
||||
import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateResultGui;
|
||||
import info.nightscout.utils.DateUtil;
|
||||
import info.nightscout.utils.HardLimits;
|
||||
import info.nightscout.utils.Profiler;
|
||||
import info.nightscout.utils.Round;
|
||||
import info.nightscout.utils.SP;
|
||||
import info.nightscout.utils.SafeParse;
|
||||
|
||||
import static info.nightscout.androidaps.plugins.OpenAPSAMA.OpenAPSAMAPlugin.checkOnlyHardLimits;
|
||||
import static info.nightscout.androidaps.plugins.OpenAPSAMA.OpenAPSAMAPlugin.verifyHardLimits;
|
||||
import static info.nightscout.utils.HardLimits.checkOnlyHardLimits;
|
||||
import static info.nightscout.utils.HardLimits.verifyHardLimits;
|
||||
|
||||
/**
|
||||
* Created by mike on 05.08.2016.
|
||||
|
@ -147,6 +148,7 @@ public class OpenAPSMAPlugin implements PluginBase, APSInterface {
|
|||
|
||||
GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData();
|
||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||
PumpInterface pump = ConfigBuilderPlugin.getActivePump();
|
||||
|
||||
if (profile == null) {
|
||||
MainApp.bus().post(new EventOpenAPSUpdateResultGui(MainApp.instance().getString(R.string.noprofileselected)));
|
||||
|
@ -177,7 +179,7 @@ public class OpenAPSMAPlugin implements PluginBase, APSInterface {
|
|||
double maxBasal = SafeParse.stringToDouble(SP.getString("openapsma_max_basal", "1"));
|
||||
double minBg = Profile.toMgdl(profile.getTargetLow(), units);
|
||||
double maxBg = Profile.toMgdl(profile.getTargetHigh(), units);
|
||||
double targetBg = (minBg + maxBg) / 2;
|
||||
double targetBg = Profile.toMgdl(profile.getTarget(), units);
|
||||
|
||||
minBg = Round.roundTo(minBg, 0.1d);
|
||||
maxBg = Round.roundTo(maxBg, 0.1d);
|
||||
|
@ -195,26 +197,29 @@ public class OpenAPSMAPlugin implements PluginBase, APSInterface {
|
|||
maxIob = MainApp.getConfigBuilder().applyMaxIOBConstraints(maxIob);
|
||||
Profiler.log(log, "MA data gathering", start);
|
||||
|
||||
minBg = verifyHardLimits(minBg, "minBg", Constants.VERY_HARD_LIMIT_MIN_BG[0], Constants.VERY_HARD_LIMIT_MIN_BG[1]);
|
||||
maxBg = verifyHardLimits(maxBg, "maxBg", Constants.VERY_HARD_LIMIT_MAX_BG[0], Constants.VERY_HARD_LIMIT_MAX_BG[1]);
|
||||
targetBg = verifyHardLimits(targetBg, "targetBg", Constants.VERY_HARD_LIMIT_TARGET_BG[0], Constants.VERY_HARD_LIMIT_TARGET_BG[1]);
|
||||
minBg = verifyHardLimits(minBg, "minBg", HardLimits.VERY_HARD_LIMIT_MIN_BG[0], HardLimits.VERY_HARD_LIMIT_MIN_BG[1]);
|
||||
maxBg = verifyHardLimits(maxBg, "maxBg", HardLimits.VERY_HARD_LIMIT_MAX_BG[0], HardLimits.VERY_HARD_LIMIT_MAX_BG[1]);
|
||||
targetBg = verifyHardLimits(targetBg, "targetBg", HardLimits.VERY_HARD_LIMIT_TARGET_BG[0], HardLimits.VERY_HARD_LIMIT_TARGET_BG[1]);
|
||||
|
||||
TempTarget tempTarget = MainApp.getConfigBuilder().getTempTargetFromHistory(System.currentTimeMillis());
|
||||
if (tempTarget != null) {
|
||||
minBg = verifyHardLimits(tempTarget.low, "minBg", Constants.VERY_HARD_LIMIT_TEMP_MIN_BG[0], Constants.VERY_HARD_LIMIT_TEMP_MIN_BG[1]);
|
||||
maxBg = verifyHardLimits(tempTarget.high, "maxBg", Constants.VERY_HARD_LIMIT_TEMP_MAX_BG[0], Constants.VERY_HARD_LIMIT_TEMP_MAX_BG[1]);
|
||||
targetBg = verifyHardLimits((tempTarget.low + tempTarget.high) / 2, "targetBg", Constants.VERY_HARD_LIMIT_TEMP_TARGET_BG[0], Constants.VERY_HARD_LIMIT_TEMP_TARGET_BG[1]);
|
||||
minBg = verifyHardLimits(tempTarget.low, "minBg", HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[1]);
|
||||
maxBg = verifyHardLimits(tempTarget.high, "maxBg", HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[1]);
|
||||
targetBg = verifyHardLimits(tempTarget.target(), "targetBg", HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[1]);
|
||||
}
|
||||
|
||||
maxIob = verifyHardLimits(maxIob, "maxIob", 0, 7);
|
||||
maxBasal = verifyHardLimits(maxBasal, "max_basal", 0.1, 10);
|
||||
maxIob = verifyHardLimits(maxIob, "maxIob", 0, HardLimits.maxIobAMA());
|
||||
maxBasal = verifyHardLimits(maxBasal, "max_basal", 0.1, HardLimits.maxBasal());
|
||||
|
||||
if (!checkOnlyHardLimits(profile.getDia(), "dia", 2, 7)) return;
|
||||
if (!checkOnlyHardLimits(profile.getIc(), "carbratio", 2, 100)) return;
|
||||
if (!checkOnlyHardLimits(Profile.toMgdl(profile.getIsf(), units), "sens", 2, 900))
|
||||
if (!checkOnlyHardLimits(profile.getDia(), "dia", HardLimits.MINDIA, HardLimits.MAXDIA))
|
||||
return;
|
||||
if (!checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.1, 10)) return;
|
||||
if (!checkOnlyHardLimits(ConfigBuilderPlugin.getActivePump().getBaseBasalRate(), "current_basal", 0.01, 5))
|
||||
if (!checkOnlyHardLimits(profile.getIc(profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC))
|
||||
return;
|
||||
if (!checkOnlyHardLimits(Profile.toMgdl(profile.getIsf().doubleValue(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF))
|
||||
return;
|
||||
if (!checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.05, HardLimits.maxBasal()))
|
||||
return;
|
||||
if (!checkOnlyHardLimits(pump.getBaseBasalRate(), "current_basal", 0.01, HardLimits.maxBasal()))
|
||||
return;
|
||||
|
||||
start = new Date();
|
||||
|
@ -229,15 +234,15 @@ public class OpenAPSMAPlugin implements PluginBase, APSInterface {
|
|||
DetermineBasalResultMA determineBasalResultMA = determineBasalAdapterMAJS.invoke();
|
||||
// Fix bug determinef basal
|
||||
if (determineBasalResultMA.rate == 0d && determineBasalResultMA.duration == 0 && !MainApp.getConfigBuilder().isTempBasalInProgress())
|
||||
determineBasalResultMA.changeRequested = false;
|
||||
determineBasalResultMA.tempBasalReqested = false;
|
||||
// limit requests on openloop mode
|
||||
if (!MainApp.getConfigBuilder().isClosedModeEnabled()) {
|
||||
if (MainApp.getConfigBuilder().isTempBasalInProgress() && determineBasalResultMA.rate == 0 && determineBasalResultMA.duration == 0) {
|
||||
// going to cancel
|
||||
} else if (MainApp.getConfigBuilder().isTempBasalInProgress() && Math.abs(determineBasalResultMA.rate - MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory()) < 0.1) {
|
||||
determineBasalResultMA.changeRequested = false;
|
||||
determineBasalResultMA.tempBasalReqested = false;
|
||||
} else if (!MainApp.getConfigBuilder().isTempBasalInProgress() && Math.abs(determineBasalResultMA.rate - ConfigBuilderPlugin.getActivePump().getBaseBasalRate()) < 0.1)
|
||||
determineBasalResultMA.changeRequested = false;
|
||||
determineBasalResultMA.tempBasalReqested = false;
|
||||
}
|
||||
|
||||
determineBasalResultMA.iob = iobTotal;
|
||||
|
|
|
@ -0,0 +1,345 @@
|
|||
package info.nightscout.androidaps.plugins.OpenAPSSMB;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.mozilla.javascript.Callable;
|
||||
import org.mozilla.javascript.Context;
|
||||
import org.mozilla.javascript.Function;
|
||||
import org.mozilla.javascript.NativeJSON;
|
||||
import org.mozilla.javascript.NativeObject;
|
||||
import org.mozilla.javascript.RhinoException;
|
||||
import org.mozilla.javascript.Scriptable;
|
||||
import org.mozilla.javascript.ScriptableObject;
|
||||
import org.mozilla.javascript.Undefined;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
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.GlucoseStatus;
|
||||
import info.nightscout.androidaps.data.IobTotal;
|
||||
import info.nightscout.androidaps.data.MealData;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.db.TemporaryBasal;
|
||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
|
||||
import info.nightscout.androidaps.plugins.Loop.ScriptReader;
|
||||
import info.nightscout.androidaps.plugins.OpenAPSMA.LoggerCallback;
|
||||
import info.nightscout.androidaps.plugins.SourceDexcomG5.SourceDexcomG5Plugin;
|
||||
import info.nightscout.utils.SP;
|
||||
import info.nightscout.utils.SafeParse;
|
||||
|
||||
public class DetermineBasalAdapterSMBJS {
|
||||
private static Logger log = LoggerFactory.getLogger(DetermineBasalAdapterSMBJS.class);
|
||||
|
||||
|
||||
private ScriptReader mScriptReader = null;
|
||||
private JSONObject mProfile;
|
||||
private JSONObject mGlucoseStatus;
|
||||
private JSONArray mIobData;
|
||||
private JSONObject mMealData;
|
||||
private JSONObject mCurrentTemp;
|
||||
private JSONObject mAutosensData = null;
|
||||
private boolean mMicrobolusAllowed;
|
||||
|
||||
private String storedCurrentTemp = null;
|
||||
private String storedIobData = null;
|
||||
|
||||
private String storedGlucoseStatus = null;
|
||||
private String storedProfile = null;
|
||||
private String storedMeal_data = null;
|
||||
private String storedAutosens_data = null;
|
||||
private String storedMicroBolusAllowed = null;
|
||||
|
||||
private String scriptDebug = "";
|
||||
|
||||
/**
|
||||
* Main code
|
||||
*/
|
||||
|
||||
public DetermineBasalAdapterSMBJS(ScriptReader scriptReader) throws IOException {
|
||||
mScriptReader = scriptReader;
|
||||
}
|
||||
|
||||
|
||||
public DetermineBasalResultSMB invoke() {
|
||||
|
||||
|
||||
log.debug(">>> Invoking detemine_basal <<<");
|
||||
log.debug("Glucose status: " + (storedGlucoseStatus = mGlucoseStatus.toString()));
|
||||
log.debug("IOB data: " + (storedIobData = mIobData.toString()));
|
||||
log.debug("Current temp: " + (storedCurrentTemp = mCurrentTemp.toString()));
|
||||
log.debug("Profile: " + (storedProfile = mProfile.toString()));
|
||||
log.debug("Meal data: " + (storedMeal_data = mMealData.toString()));
|
||||
if (mAutosensData != null)
|
||||
log.debug("Autosens data: " + (storedAutosens_data = mAutosensData.toString()));
|
||||
else
|
||||
log.debug("Autosens data: " + (storedAutosens_data = "undefined"));
|
||||
log.debug("Reservoir data: " + "undefined");
|
||||
log.debug("MicroBolusAllowed: " + (storedMicroBolusAllowed = "" + mMicrobolusAllowed));
|
||||
|
||||
DetermineBasalResultSMB determineBasalResultSMB = null;
|
||||
|
||||
Context rhino = Context.enter();
|
||||
Scriptable scope = rhino.initStandardObjects();
|
||||
// Turn off optimization to make Rhino Android compatible
|
||||
rhino.setOptimizationLevel(-1);
|
||||
|
||||
try {
|
||||
|
||||
//register logger callback for console.log and console.error
|
||||
ScriptableObject.defineClass(scope, LoggerCallback.class);
|
||||
Scriptable myLogger = rhino.newObject(scope, "LoggerCallback", null);
|
||||
scope.put("console2", scope, myLogger);
|
||||
rhino.evaluateString(scope, readFile("OpenAPSAMA/loggerhelper.js"), "JavaScript", 0, null);
|
||||
|
||||
//set module parent
|
||||
rhino.evaluateString(scope, "var module = {\"parent\":Boolean(1)};", "JavaScript", 0, null);
|
||||
rhino.evaluateString(scope, "var round_basal = function round_basal(basal, profile) { return basal; };", "JavaScript", 0, null);
|
||||
rhino.evaluateString(scope, "require = function() {return round_basal;};", "JavaScript", 0, null);
|
||||
|
||||
//generate functions "determine_basal" and "setTempBasal"
|
||||
rhino.evaluateString(scope, readFile("OpenAPSSMB/determine-basal.js"), "JavaScript", 0, null);
|
||||
rhino.evaluateString(scope, readFile("OpenAPSSMB/basal-set-temp.js"), "setTempBasal.js", 0, null);
|
||||
Object determineBasalObj = scope.get("determine_basal", scope);
|
||||
Object setTempBasalFunctionsObj = scope.get("tempBasalFunctions", scope);
|
||||
|
||||
//call determine-basal
|
||||
if (determineBasalObj instanceof Function && setTempBasalFunctionsObj instanceof NativeObject) {
|
||||
Function determineBasalJS = (Function) determineBasalObj;
|
||||
|
||||
//prepare parameters
|
||||
Object[] params = new Object[]{
|
||||
makeParam(mGlucoseStatus, rhino, scope),
|
||||
makeParam(mCurrentTemp, rhino, scope),
|
||||
makeParamArray(mIobData, rhino, scope),
|
||||
makeParam(mProfile, rhino, scope),
|
||||
makeParam(mAutosensData, rhino, scope),
|
||||
makeParam(mMealData, rhino, scope),
|
||||
setTempBasalFunctionsObj,
|
||||
new Boolean(mMicrobolusAllowed),
|
||||
makeParam(null, rhino, scope) // reservoir data as undefined
|
||||
};
|
||||
|
||||
|
||||
NativeObject jsResult = (NativeObject) determineBasalJS.call(rhino, scope, scope, params);
|
||||
scriptDebug = LoggerCallback.getScriptDebug();
|
||||
|
||||
// Parse the jsResult object to a JSON-String
|
||||
String result = NativeJSON.stringify(rhino, scope, jsResult, null, null).toString();
|
||||
if (Config.logAPSResult)
|
||||
log.debug("Result: " + result);
|
||||
try {
|
||||
determineBasalResultSMB = new DetermineBasalResultSMB(new JSONObject(result));
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
} else {
|
||||
log.debug("Problem loading JS Functions");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.debug("IOException");
|
||||
} catch (RhinoException e) {
|
||||
log.error("RhinoException: (" + e.lineNumber() + "," + e.columnNumber() + ") " + e.toString());
|
||||
} catch (IllegalAccessException e) {
|
||||
log.error(e.toString());
|
||||
} catch (InstantiationException e) {
|
||||
log.error(e.toString());
|
||||
} catch (InvocationTargetException e) {
|
||||
log.error(e.toString());
|
||||
} finally {
|
||||
Context.exit();
|
||||
}
|
||||
|
||||
storedGlucoseStatus = mGlucoseStatus.toString();
|
||||
storedIobData = mIobData.toString();
|
||||
storedCurrentTemp = mCurrentTemp.toString();
|
||||
storedProfile = mProfile.toString();
|
||||
storedMeal_data = mMealData.toString();
|
||||
|
||||
return determineBasalResultSMB;
|
||||
|
||||
}
|
||||
|
||||
String getGlucoseStatusParam() {
|
||||
return storedGlucoseStatus;
|
||||
}
|
||||
|
||||
String getCurrentTempParam() {
|
||||
return storedCurrentTemp;
|
||||
}
|
||||
|
||||
String getIobDataParam() {
|
||||
return storedIobData;
|
||||
}
|
||||
|
||||
String getProfileParam() {
|
||||
return storedProfile;
|
||||
}
|
||||
|
||||
String getMealDataParam() {
|
||||
return storedMeal_data;
|
||||
}
|
||||
|
||||
String getAutosensDataParam() {
|
||||
return storedAutosens_data;
|
||||
}
|
||||
|
||||
String getMicroBolusAllowedParam() {
|
||||
return storedMicroBolusAllowed;
|
||||
}
|
||||
|
||||
String getScriptDebug() {
|
||||
return scriptDebug;
|
||||
}
|
||||
|
||||
public void setData(Profile profile,
|
||||
double maxIob,
|
||||
double maxBasal,
|
||||
double minBg,
|
||||
double maxBg,
|
||||
double targetBg,
|
||||
double basalrate,
|
||||
IobTotal[] iobArray,
|
||||
GlucoseStatus glucoseStatus,
|
||||
MealData mealData,
|
||||
double autosensDataRatio,
|
||||
boolean tempTargetSet,
|
||||
boolean microBolusAllowed
|
||||
) throws JSONException {
|
||||
|
||||
String units = profile.getUnits();
|
||||
|
||||
mProfile = new JSONObject();
|
||||
|
||||
mProfile.put("max_iob", maxIob);
|
||||
//mProfile.put("dia", profile.getDia());
|
||||
mProfile.put("type", "current");
|
||||
mProfile.put("max_daily_basal", profile.getMaxDailyBasal());
|
||||
mProfile.put("max_basal", maxBasal);
|
||||
mProfile.put("min_bg", minBg);
|
||||
mProfile.put("max_bg", maxBg);
|
||||
mProfile.put("target_bg", targetBg);
|
||||
mProfile.put("carb_ratio", profile.getIc());
|
||||
mProfile.put("sens", Profile.toMgdl(profile.getIsf().doubleValue(), units));
|
||||
mProfile.put("max_daily_safety_multiplier", SP.getInt("openapsama_max_daily_safety_multiplier", 3));
|
||||
mProfile.put("current_basal_safety_multiplier", SP.getDouble("openapsama_current_basal_safety_multiplier", 4d));
|
||||
|
||||
mProfile.put("high_temptarget_raises_sensitivity", SMBDefaults.high_temptarget_raises_sensitivity);
|
||||
mProfile.put("low_temptarget_lowers_sensitivity", SMBDefaults.low_temptarget_lowers_sensitivity);
|
||||
mProfile.put("sensitivity_raises_target", SMBDefaults.sensitivity_raises_target);
|
||||
mProfile.put("resistance_lowers_target", SMBDefaults.resistance_lowers_target);
|
||||
mProfile.put("adv_target_adjustments", SMBDefaults.adv_target_adjustments);
|
||||
mProfile.put("exercise_mode", SMBDefaults.exercise_mode);
|
||||
mProfile.put("half_basal_exercise_target", SMBDefaults.half_basal_exercise_target);
|
||||
mProfile.put("maxCOB", SMBDefaults.maxCOB);
|
||||
mProfile.put("skip_neutral_temps", SMBDefaults.skip_neutral_temps);
|
||||
//TODO: align with max-absorption model in AMA sensitivity
|
||||
mProfile.put("min_5m_carbimpact", SP.getDouble("openapsama_min_5m_carbimpact", SMBDefaults.min_5m_carbimpact));;
|
||||
mProfile.put("remainingCarbsCap", SMBDefaults.remainingCarbsCap);
|
||||
mProfile.put("enableUAM", SP.getBoolean(R.string.key_use_uam, false));
|
||||
mProfile.put("A52_risk_enable", SMBDefaults.A52_risk_enable);
|
||||
mProfile.put("enableSMB_with_COB", SP.getBoolean(R.string.key_use_smb, false) && SP.getBoolean(R.string.key_enableSMB_with_COB, false));
|
||||
mProfile.put("enableSMB_with_temptarget", SP.getBoolean(R.string.key_use_smb, false) && SP.getBoolean(R.string.key_enableSMB_with_temptarget, false));
|
||||
mProfile.put("allowSMB_with_high_temptarget", SP.getBoolean(R.string.key_use_smb, false) && SP.getBoolean(R.string.key_allowSMB_with_high_temptarget, false));
|
||||
mProfile.put("enableSMB_always", SP.getBoolean(R.string.key_use_smb, false) && SP.getBoolean(R.string.key_enableSMB_always, false) && ConfigBuilderPlugin.getActiveBgSource().advancedFilteringSupported());
|
||||
mProfile.put("enableSMB_after_carbs", SP.getBoolean(R.string.key_use_smb, false) && SP.getBoolean(R.string.key_enableSMB_after_carbs, false) && ConfigBuilderPlugin.getActiveBgSource().advancedFilteringSupported());
|
||||
mProfile.put("maxSMBBasalMinutes", SP.getInt("key_smbmaxminutes", SMBDefaults.maxSMBBasalMinutes));
|
||||
mProfile.put("carbsReqThreshold", SMBDefaults.carbsReqThreshold);
|
||||
|
||||
mProfile.put("current_basal", basalrate);
|
||||
mProfile.put("temptargetSet", tempTargetSet);
|
||||
mProfile.put("autosens_max", SafeParse.stringToDouble(SP.getString("openapsama_autosens_max", "1.2")));
|
||||
|
||||
if (units.equals(Constants.MMOL)) {
|
||||
mProfile.put("out_units", "mmol/L");
|
||||
}
|
||||
|
||||
|
||||
mCurrentTemp = new JSONObject();
|
||||
mCurrentTemp.put("temp", "absolute");
|
||||
mCurrentTemp.put("duration", MainApp.getConfigBuilder().getTempBasalRemainingMinutesFromHistory());
|
||||
mCurrentTemp.put("rate", MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory());
|
||||
|
||||
// as we have non default temps longer than 30 mintues
|
||||
TemporaryBasal tempBasal = MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis());
|
||||
if (tempBasal != null) {
|
||||
mCurrentTemp.put("minutesrunning", tempBasal.getRealDuration());
|
||||
}
|
||||
|
||||
mIobData = IobCobCalculatorPlugin.convertToJSONArray(iobArray);
|
||||
|
||||
mGlucoseStatus = new JSONObject();
|
||||
mGlucoseStatus.put("glucose", glucoseStatus.glucose);
|
||||
|
||||
if (SP.getBoolean("always_use_shortavg", false)) {
|
||||
mGlucoseStatus.put("delta", glucoseStatus.short_avgdelta);
|
||||
} else {
|
||||
mGlucoseStatus.put("delta", glucoseStatus.delta);
|
||||
}
|
||||
mGlucoseStatus.put("short_avgdelta", glucoseStatus.short_avgdelta);
|
||||
mGlucoseStatus.put("long_avgdelta", glucoseStatus.long_avgdelta);
|
||||
mGlucoseStatus.put("date", glucoseStatus.date);
|
||||
|
||||
mMealData = new JSONObject();
|
||||
mMealData.put("carbs", mealData.carbs);
|
||||
mMealData.put("boluses", mealData.boluses);
|
||||
mMealData.put("mealCOB", mealData.mealCOB);
|
||||
mMealData.put("slopeFromMaxDeviation", mealData.slopeFromMaxDeviation);
|
||||
mMealData.put("slopeFromMinDeviation", mealData.slopeFromMinDeviation);
|
||||
mMealData.put("lastBolusTime", mealData.lastBolusTime);
|
||||
mMealData.put("lastCarbTime", mealData.lastCarbTime);
|
||||
|
||||
|
||||
if (MainApp.getConfigBuilder().isAMAModeEnabled()) {
|
||||
mAutosensData = new JSONObject();
|
||||
mAutosensData.put("ratio", autosensDataRatio);
|
||||
} else {
|
||||
mAutosensData = new JSONObject();
|
||||
mAutosensData.put("ratio", 1.0);
|
||||
}
|
||||
mMicrobolusAllowed = microBolusAllowed;
|
||||
|
||||
}
|
||||
|
||||
public Object makeParam(JSONObject jsonObject, Context rhino, Scriptable scope) {
|
||||
|
||||
if (jsonObject == null) return Undefined.instance;
|
||||
|
||||
Object param = NativeJSON.parse(rhino, scope, jsonObject.toString(), new Callable() {
|
||||
@Override
|
||||
public Object call(Context context, Scriptable scriptable, Scriptable scriptable1, Object[] objects) {
|
||||
return objects[1];
|
||||
}
|
||||
});
|
||||
return param;
|
||||
}
|
||||
|
||||
public Object makeParamArray(JSONArray jsonArray, Context rhino, Scriptable scope) {
|
||||
//Object param = NativeJSON.parse(rhino, scope, "{myarray: " + jsonArray.toString() + " }", new Callable() {
|
||||
Object param = NativeJSON.parse(rhino, scope, jsonArray.toString(), new Callable() {
|
||||
@Override
|
||||
public Object call(Context context, Scriptable scriptable, Scriptable scriptable1, Object[] objects) {
|
||||
return objects[1];
|
||||
}
|
||||
});
|
||||
return param;
|
||||
}
|
||||
|
||||
public String readFile(String filename) throws IOException {
|
||||
byte[] bytes = mScriptReader.readFile(filename);
|
||||
String string = new String(bytes, "UTF-8");
|
||||
if (string.startsWith("#!/usr/bin/env node")) {
|
||||
string = string.substring(20);
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
package info.nightscout.androidaps.plugins.OpenAPSSMB;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import info.nightscout.androidaps.plugins.Loop.APSResult;
|
||||
import info.nightscout.utils.DateUtil;
|
||||
|
||||
public class DetermineBasalResultSMB extends APSResult {
|
||||
private static final Logger log = LoggerFactory.getLogger(DetermineBasalResultSMB.class);
|
||||
|
||||
public double eventualBG;
|
||||
public double snoozeBG;
|
||||
public double insulinReq;
|
||||
public double carbsReq;
|
||||
|
||||
public DetermineBasalResultSMB(JSONObject result) {
|
||||
this();
|
||||
date = new Date();
|
||||
json = result;
|
||||
try {
|
||||
if (result.has("error")) {
|
||||
reason = result.getString("error");
|
||||
return;
|
||||
}
|
||||
|
||||
reason = result.getString("reason");
|
||||
if (result.has("eventualBG")) eventualBG = result.getDouble("eventualBG");
|
||||
if (result.has("snoozeBG")) snoozeBG = result.getDouble("snoozeBG");
|
||||
if (result.has("insulinReq")) insulinReq = result.getDouble("insulinReq");
|
||||
if (result.has("carbsReq")) carbsReq = result.getDouble("carbsReq");
|
||||
|
||||
if (result.has("rate") && result.has("duration")) {
|
||||
tempBasalReqested = true;
|
||||
rate = result.getDouble("rate");
|
||||
if (rate < 0d) rate = 0d;
|
||||
duration = result.getInt("duration");
|
||||
} else {
|
||||
rate = -1;
|
||||
duration = -1;
|
||||
}
|
||||
|
||||
if (result.has("units")) {
|
||||
bolusRequested = true;
|
||||
smb = result.getDouble("units");
|
||||
} else {
|
||||
smb = 0d;
|
||||
}
|
||||
|
||||
if (result.has("deliverAt")) {
|
||||
String date = result.getString("deliverAt");
|
||||
try {
|
||||
deliverAt = DateUtil.fromISODateString(date).getTime();
|
||||
} catch (Exception e) {
|
||||
log.warn("Error parsing 'deliverAt' date: " + date, e);
|
||||
}
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
log.error("Error parsing determine-basal result JSON", e);
|
||||
}
|
||||
}
|
||||
|
||||
public DetermineBasalResultSMB() {
|
||||
hasPredictions = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DetermineBasalResultSMB clone() {
|
||||
DetermineBasalResultSMB newResult = new DetermineBasalResultSMB();
|
||||
newResult.reason = reason;
|
||||
newResult.rate = rate;
|
||||
newResult.duration = duration;
|
||||
newResult.tempBasalReqested = tempBasalReqested;
|
||||
newResult.bolusRequested = bolusRequested;
|
||||
newResult.rate = rate;
|
||||
newResult.duration = duration;
|
||||
newResult.smb = smb;
|
||||
newResult.deliverAt = deliverAt;
|
||||
|
||||
try {
|
||||
newResult.json = new JSONObject(json.toString());
|
||||
} catch (JSONException e) {
|
||||
log.error("Error clone parsing determine-basal result", e);
|
||||
}
|
||||
newResult.eventualBG = eventualBG;
|
||||
newResult.snoozeBG = snoozeBG;
|
||||
newResult.date = date;
|
||||
return newResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONObject json() {
|
||||
try {
|
||||
return new JSONObject(this.json.toString());
|
||||
} catch (JSONException e) {
|
||||
log.error("Error converting determine-basal result to JSON", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,142 @@
|
|||
package info.nightscout.androidaps.plugins.OpenAPSSMB;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.crashlytics.android.answers.CustomEvent;
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
|
||||
import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateGui;
|
||||
import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateResultGui;
|
||||
import info.nightscout.utils.FabricPrivacy;
|
||||
import info.nightscout.utils.JSONFormatter;
|
||||
|
||||
public class OpenAPSSMBFragment extends SubscriberFragment implements View.OnClickListener {
|
||||
private static Logger log = LoggerFactory.getLogger(OpenAPSSMBFragment.class);
|
||||
|
||||
Button run;
|
||||
TextView lastRunView;
|
||||
TextView glucoseStatusView;
|
||||
TextView currentTempView;
|
||||
TextView iobDataView;
|
||||
TextView profileView;
|
||||
TextView mealDataView;
|
||||
TextView autosensDataView;
|
||||
TextView resultView;
|
||||
TextView scriptdebugView;
|
||||
TextView requestView;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.openapsama_fragment, container, false);
|
||||
|
||||
run = (Button) view.findViewById(R.id.openapsma_run);
|
||||
run.setOnClickListener(this);
|
||||
lastRunView = (TextView) view.findViewById(R.id.openapsma_lastrun);
|
||||
glucoseStatusView = (TextView) view.findViewById(R.id.openapsma_glucosestatus);
|
||||
currentTempView = (TextView) view.findViewById(R.id.openapsma_currenttemp);
|
||||
iobDataView = (TextView) view.findViewById(R.id.openapsma_iobdata);
|
||||
profileView = (TextView) view.findViewById(R.id.openapsma_profile);
|
||||
mealDataView = (TextView) view.findViewById(R.id.openapsma_mealdata);
|
||||
autosensDataView = (TextView) view.findViewById(R.id.openapsma_autosensdata);
|
||||
scriptdebugView = (TextView) view.findViewById(R.id.openapsma_scriptdebugdata);
|
||||
resultView = (TextView) view.findViewById(R.id.openapsma_result);
|
||||
requestView = (TextView) view.findViewById(R.id.openapsma_request);
|
||||
|
||||
updateGUI();
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.openapsma_run:
|
||||
OpenAPSSMBPlugin.getPlugin().invoke("OpenAPSSMB button");
|
||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("OpenAPS_SMB_Run"));
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventOpenAPSUpdateGui ev) {
|
||||
updateGUI();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventOpenAPSUpdateResultGui ev) {
|
||||
updateResultGUI(ev.text);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateGUI() {
|
||||
Activity activity = getActivity();
|
||||
if (activity != null)
|
||||
activity.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
OpenAPSSMBPlugin plugin = OpenAPSSMBPlugin.getPlugin();
|
||||
DetermineBasalResultSMB lastAPSResult = plugin.lastAPSResult;
|
||||
if (lastAPSResult != null) {
|
||||
resultView.setText(JSONFormatter.format(lastAPSResult.json));
|
||||
requestView.setText(lastAPSResult.toSpanned());
|
||||
}
|
||||
DetermineBasalAdapterSMBJS determineBasalAdapterSMBJS = plugin.lastDetermineBasalAdapterSMBJS;
|
||||
if (determineBasalAdapterSMBJS != null) {
|
||||
glucoseStatusView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getGlucoseStatusParam()));
|
||||
currentTempView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getCurrentTempParam()));
|
||||
try {
|
||||
JSONArray iobArray = new JSONArray(determineBasalAdapterSMBJS.getIobDataParam());
|
||||
iobDataView.setText(String.format(MainApp.sResources.getString(R.string.array_of_elements), iobArray.length()) + "\n" + JSONFormatter.format(iobArray.getString(0)));
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
iobDataView.setText("JSONException");
|
||||
}
|
||||
profileView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getProfileParam()));
|
||||
mealDataView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getMealDataParam()));
|
||||
scriptdebugView.setText(determineBasalAdapterSMBJS.getScriptDebug());
|
||||
}
|
||||
if (plugin.lastAPSRun != null) {
|
||||
lastRunView.setText(plugin.lastAPSRun.toLocaleString());
|
||||
}
|
||||
if (plugin.lastAutosensResult != null) {
|
||||
autosensDataView.setText(JSONFormatter.format(plugin.lastAutosensResult.json()));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void updateResultGUI(final String text) {
|
||||
Activity activity = getActivity();
|
||||
if (activity != null)
|
||||
activity.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
resultView.setText(text);
|
||||
glucoseStatusView.setText("");
|
||||
currentTempView.setText("");
|
||||
iobDataView.setText("");
|
||||
profileView.setText("");
|
||||
mealDataView.setText("");
|
||||
autosensDataView.setText("");
|
||||
scriptdebugView.setText("");
|
||||
requestView.setText("");
|
||||
lastRunView.setText("");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,301 @@
|
|||
package info.nightscout.androidaps.plugins.OpenAPSSMB;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
|
||||
import info.nightscout.androidaps.Config;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.GlucoseStatus;
|
||||
import info.nightscout.androidaps.data.IobTotal;
|
||||
import info.nightscout.androidaps.data.MealData;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.db.TempTarget;
|
||||
import info.nightscout.androidaps.interfaces.APSInterface;
|
||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensResult;
|
||||
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
|
||||
import info.nightscout.androidaps.plugins.Loop.APSResult;
|
||||
import info.nightscout.androidaps.plugins.Loop.ScriptReader;
|
||||
import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateGui;
|
||||
import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateResultGui;
|
||||
import info.nightscout.utils.DateUtil;
|
||||
import info.nightscout.utils.HardLimits;
|
||||
import info.nightscout.utils.NSUpload;
|
||||
import info.nightscout.utils.Profiler;
|
||||
import info.nightscout.utils.Round;
|
||||
import info.nightscout.utils.SP;
|
||||
import info.nightscout.utils.ToastUtils;
|
||||
|
||||
/**
|
||||
* Created by mike on 05.08.2016.
|
||||
*/
|
||||
public class OpenAPSSMBPlugin implements PluginBase, APSInterface {
|
||||
private static Logger log = LoggerFactory.getLogger(OpenAPSSMBPlugin.class);
|
||||
|
||||
// last values
|
||||
DetermineBasalAdapterSMBJS lastDetermineBasalAdapterSMBJS = null;
|
||||
Date lastAPSRun = null;
|
||||
DetermineBasalResultSMB lastAPSResult = null;
|
||||
AutosensResult lastAutosensResult = null;
|
||||
|
||||
boolean fragmentEnabled = false;
|
||||
boolean fragmentVisible = true;
|
||||
|
||||
private static OpenAPSSMBPlugin openAPSSMBPlugin;
|
||||
|
||||
private OpenAPSSMBPlugin() {
|
||||
}
|
||||
|
||||
public static OpenAPSSMBPlugin getPlugin() {
|
||||
if (openAPSSMBPlugin == null) {
|
||||
openAPSSMBPlugin = new OpenAPSSMBPlugin();
|
||||
}
|
||||
return openAPSSMBPlugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return MainApp.instance().getString(R.string.openapssmb);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNameShort() {
|
||||
String name = MainApp.sResources.getString(R.string.smb_shortname);
|
||||
if (!name.trim().isEmpty()) {
|
||||
//only if translation exists
|
||||
return name;
|
||||
}
|
||||
// use long name as fallback
|
||||
return getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled(int type) {
|
||||
boolean pumpCapable = ConfigBuilderPlugin.getActivePump() == null || ConfigBuilderPlugin.getActivePump().getPumpDescription().isTempBasalCapable;
|
||||
return type == APS && fragmentEnabled && pumpCapable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVisibleInTabs(int type) {
|
||||
boolean pumpCapable = ConfigBuilderPlugin.getActivePump() == null || ConfigBuilderPlugin.getActivePump().getPumpDescription().isTempBasalCapable;
|
||||
return type == APS && fragmentVisible && pumpCapable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeHidden(int type) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasFragment() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean showInList(int type) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFragmentVisible(int type, boolean fragmentVisible) {
|
||||
if (type == APS) this.fragmentVisible = fragmentVisible;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPreferencesId() {
|
||||
return R.xml.pref_openapssmb;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFragmentEnabled(int type, boolean fragmentEnabled) {
|
||||
if (type == APS) this.fragmentEnabled = fragmentEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getType() {
|
||||
return PluginBase.APS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFragmentClass() {
|
||||
return OpenAPSSMBFragment.class.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public APSResult getLastAPSResult() {
|
||||
return lastAPSResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getLastAPSRun() {
|
||||
return lastAPSRun;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(String initiator) {
|
||||
log.debug("invoke from " + initiator);
|
||||
lastAPSResult = null;
|
||||
DetermineBasalAdapterSMBJS determineBasalAdapterSMBJS = null;
|
||||
try {
|
||||
determineBasalAdapterSMBJS = new DetermineBasalAdapterSMBJS(new ScriptReader(MainApp.instance().getBaseContext()));
|
||||
} catch (IOException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return;
|
||||
}
|
||||
|
||||
GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData();
|
||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||
PumpInterface pump = ConfigBuilderPlugin.getActivePump();
|
||||
|
||||
if (profile == null) {
|
||||
MainApp.bus().post(new EventOpenAPSUpdateResultGui(MainApp.instance().getString(R.string.noprofileselected)));
|
||||
if (Config.logAPSResult)
|
||||
log.debug(MainApp.instance().getString(R.string.noprofileselected));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isEnabled(PluginBase.APS)) {
|
||||
MainApp.bus().post(new EventOpenAPSUpdateResultGui(MainApp.instance().getString(R.string.openapsma_disabled)));
|
||||
if (Config.logAPSResult)
|
||||
log.debug(MainApp.instance().getString(R.string.openapsma_disabled));
|
||||
return;
|
||||
}
|
||||
|
||||
if (glucoseStatus == null) {
|
||||
MainApp.bus().post(new EventOpenAPSUpdateResultGui(MainApp.instance().getString(R.string.openapsma_noglucosedata)));
|
||||
if (Config.logAPSResult)
|
||||
log.debug(MainApp.instance().getString(R.string.openapsma_noglucosedata));
|
||||
return;
|
||||
}
|
||||
|
||||
String units = profile.getUnits();
|
||||
|
||||
double maxIob = SP.getDouble("openapsma_max_iob", 1.5d);
|
||||
double maxBasal = SP.getDouble("openapsma_max_basal", 1d);
|
||||
double minBg = Profile.toMgdl(profile.getTargetLow(), units);
|
||||
double maxBg = Profile.toMgdl(profile.getTargetHigh(), units);
|
||||
double targetBg = Profile.toMgdl(profile.getTarget(), units);
|
||||
|
||||
minBg = Round.roundTo(minBg, 0.1d);
|
||||
maxBg = Round.roundTo(maxBg, 0.1d);
|
||||
|
||||
Date start = new Date();
|
||||
Date startPart = new Date();
|
||||
IobTotal[] iobArray = IobCobCalculatorPlugin.getPlugin().calculateIobArrayForSMB();
|
||||
Profiler.log(log, "calculateIobArrayInDia()", startPart);
|
||||
|
||||
startPart = new Date();
|
||||
MealData mealData = MainApp.getConfigBuilder().getMealData();
|
||||
Profiler.log(log, "getMealData()", startPart);
|
||||
|
||||
maxIob = MainApp.getConfigBuilder().applyMaxIOBConstraints(maxIob);
|
||||
|
||||
minBg = verifyHardLimits(minBg, "minBg", HardLimits.VERY_HARD_LIMIT_MIN_BG[0], HardLimits.VERY_HARD_LIMIT_MIN_BG[1]);
|
||||
maxBg = verifyHardLimits(maxBg, "maxBg", HardLimits.VERY_HARD_LIMIT_MAX_BG[0], HardLimits.VERY_HARD_LIMIT_MAX_BG[1]);
|
||||
targetBg = verifyHardLimits(targetBg, "targetBg", HardLimits.VERY_HARD_LIMIT_TARGET_BG[0], HardLimits.VERY_HARD_LIMIT_TARGET_BG[1]);
|
||||
|
||||
boolean isTempTarget = false;
|
||||
TempTarget tempTarget = MainApp.getConfigBuilder().getTempTargetFromHistory(System.currentTimeMillis());
|
||||
if (tempTarget != null) {
|
||||
isTempTarget = true;
|
||||
minBg = verifyHardLimits(tempTarget.low, "minBg", HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[1]);
|
||||
maxBg = verifyHardLimits(tempTarget.high, "maxBg", HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[1]);
|
||||
targetBg = verifyHardLimits(tempTarget.target(), "targetBg", HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[1]);
|
||||
}
|
||||
|
||||
|
||||
maxIob = verifyHardLimits(maxIob, "maxIob", 0, HardLimits.maxIobSMB());
|
||||
maxBasal = verifyHardLimits(maxBasal, "max_basal", 0.1, HardLimits.maxBasal());
|
||||
|
||||
if (!checkOnlyHardLimits(profile.getDia(), "dia", HardLimits.MINDIA, HardLimits.MAXDIA)) return;
|
||||
if (!checkOnlyHardLimits(profile.getIc(profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC))
|
||||
return;
|
||||
if (!checkOnlyHardLimits(Profile.toMgdl(profile.getIsf().doubleValue(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF))
|
||||
return;
|
||||
if (!checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.05, HardLimits.maxBasal())) return;
|
||||
if (!checkOnlyHardLimits(pump.getBaseBasalRate(), "current_basal", 0.01, HardLimits.maxBasal())) return;
|
||||
|
||||
startPart = new Date();
|
||||
if (MainApp.getConfigBuilder().isAMAModeEnabled()) {
|
||||
lastAutosensResult = IobCobCalculatorPlugin.getPlugin().detectSensitivityWithLock(IobCobCalculatorPlugin.oldestDataAvailable(), System.currentTimeMillis());
|
||||
} else {
|
||||
lastAutosensResult = new AutosensResult();
|
||||
}
|
||||
Profiler.log(log, "detectSensitivityandCarbAbsorption()", startPart);
|
||||
Profiler.log(log, "SMB data gathering", start);
|
||||
|
||||
start = new Date();
|
||||
try {
|
||||
determineBasalAdapterSMBJS.setData(profile, maxIob, maxBasal, minBg, maxBg, targetBg, ConfigBuilderPlugin.getActivePump().getBaseBasalRate(), iobArray, glucoseStatus, mealData,
|
||||
lastAutosensResult.ratio, //autosensDataRatio
|
||||
isTempTarget,
|
||||
true //microBolusAllowed
|
||||
);
|
||||
} catch (JSONException e) {
|
||||
log.error(e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
DetermineBasalResultSMB determineBasalResultSMB = determineBasalAdapterSMBJS.invoke();
|
||||
Profiler.log(log, "SMB calculation", start);
|
||||
// TODO still needed with oref1?
|
||||
// Fix bug determine basal
|
||||
if (determineBasalResultSMB.rate == 0d && determineBasalResultSMB.duration == 0 && !MainApp.getConfigBuilder().isTempBasalInProgress())
|
||||
determineBasalResultSMB.tempBasalReqested = false;
|
||||
// limit requests on openloop mode
|
||||
if (!MainApp.getConfigBuilder().isClosedModeEnabled()) {
|
||||
if (MainApp.getConfigBuilder().isTempBasalInProgress() && determineBasalResultSMB.rate == 0 && determineBasalResultSMB.duration == 0) {
|
||||
// going to cancel
|
||||
} else if (MainApp.getConfigBuilder().isTempBasalInProgress() && Math.abs(determineBasalResultSMB.rate - MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory()) < 0.1) {
|
||||
determineBasalResultSMB.tempBasalReqested = false;
|
||||
} else if (!MainApp.getConfigBuilder().isTempBasalInProgress() && Math.abs(determineBasalResultSMB.rate - pump.getBaseBasalRate()) < 0.1) {
|
||||
determineBasalResultSMB.tempBasalReqested = false;
|
||||
}
|
||||
}
|
||||
|
||||
determineBasalResultSMB.iob = iobArray[0];
|
||||
Date now = new Date();
|
||||
|
||||
try {
|
||||
determineBasalResultSMB.json.put("timestamp", DateUtil.toISOString(now));
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
|
||||
lastDetermineBasalAdapterSMBJS = determineBasalAdapterSMBJS;
|
||||
lastAPSResult = determineBasalResultSMB;
|
||||
lastAPSRun = now;
|
||||
MainApp.bus().post(new EventOpenAPSUpdateGui());
|
||||
|
||||
//deviceStatus.suggested = determineBasalResultAMA.json;
|
||||
}
|
||||
|
||||
// safety checks
|
||||
private static boolean checkOnlyHardLimits(Double value, String valueName, double lowLimit, double highLimit) {
|
||||
return value.equals(verifyHardLimits(value, valueName, lowLimit, highLimit));
|
||||
}
|
||||
|
||||
private static Double verifyHardLimits(Double value, String valueName, double lowLimit, double highLimit) {
|
||||
Double newvalue = value;
|
||||
if (newvalue < lowLimit || newvalue > highLimit) {
|
||||
newvalue = Math.max(newvalue, lowLimit);
|
||||
newvalue = Math.min(newvalue, highLimit);
|
||||
String msg = String.format(MainApp.sResources.getString(R.string.valueoutofrange), valueName);
|
||||
msg += ".\n";
|
||||
msg += String.format(MainApp.sResources.getString(R.string.valuelimitedto), value, newvalue);
|
||||
log.error(msg);
|
||||
NSUpload.uploadError(msg);
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), msg, R.raw.error);
|
||||
}
|
||||
return newvalue;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
package info.nightscout.androidaps.plugins.OpenAPSSMB;
|
||||
|
||||
/**
|
||||
* Created by mike on 10.12.2017.
|
||||
*/
|
||||
|
||||
public class SMBDefaults {
|
||||
// CALCULATED OR FROM PREFS
|
||||
|
||||
// max_iob: 0 // if max_iob is not provided, will default to zero
|
||||
// max_daily_safety_multiplier:3
|
||||
// current_basal_safety_multiplier:4
|
||||
// autosens_max:1.2
|
||||
// autosens_min:0.7
|
||||
|
||||
// USED IN AUTOSENS
|
||||
public final static boolean rewind_resets_autosens = true; // reset autosensitivity to neutral for awhile after each pump rewind
|
||||
|
||||
// USED IN TARGETS
|
||||
// by default the higher end of the target range is used only for avoiding bolus wizard overcorrections
|
||||
// use wide_bg_target_range: true to force neutral temps over a wider range of eventualBGs
|
||||
public final static boolean wide_bg_target_range = false; // by default use only the low end of the pump's BG target range as OpenAPS target
|
||||
|
||||
// USED IN AUTOTUNE
|
||||
public final static double autotune_isf_adjustmentFraction = 1.0; // keep autotune ISF closer to pump ISF via a weighted average of fullNewISF and pumpISF. 1.0 allows full adjustment, 0 is no adjustment from pump ISF.
|
||||
public final static double remainingCarbsFraction = 1.0; // fraction of carbs we'll assume will absorb over 4h if we don't yet see carb absorption
|
||||
|
||||
// USED IN DETERMINE_BASAL
|
||||
public final static boolean low_temptarget_lowers_sensitivity = false; // lower sensitivity for temptargets <= 99.
|
||||
public final static boolean high_temptarget_raises_sensitivity = false; // raise sensitivity for temptargets >= 111. synonym for exercise_mode
|
||||
public final static boolean sensitivity_raises_target = true; // raise BG target when autosens detects sensitivity
|
||||
public final static boolean resistance_lowers_target = false; // lower BG target when autosens detects resistance
|
||||
public final static boolean adv_target_adjustments = false; // lower target automatically when BG and eventualBG are high
|
||||
public final static boolean exercise_mode = false; // when true, > 105 mg/dL high temp target adjusts sensitivityRatio for exercise_mode. This majorly changes the behavior of high temp targets from before. synonmym for high_temptarget_raises_sensitivity
|
||||
public final static int half_basal_exercise_target = 160; // when temptarget is 160 mg/dL *and* exercise_mode=true, run 50% basal at this level (120 = 75%; 140 = 60%)
|
||||
// create maxCOB and default it to 120 because that's the most a typical body can absorb over 4 hours.
|
||||
// (If someone enters more carbs or stacks more; OpenAPS will just truncate dosing based on 120.
|
||||
// Essentially, this just limits AMA/SMB as a safety cap against excessive COB entry)
|
||||
public final static int maxCOB = 120;
|
||||
public final static boolean skip_neutral_temps = true; // ***** default false in oref1 ***** if true, don't set neutral temps
|
||||
// unsuspend_if_no_temp:false // if true, pump will un-suspend after a zero temp finishes
|
||||
// bolussnooze_dia_divisor:2 // bolus snooze decays after 1/2 of DIA
|
||||
public final static double min_5m_carbimpact = 8d; // mg/dL per 5m (8 mg/dL/5m corresponds to 24g/hr at a CSF of 4 mg/dL/g (x/5*60/4))
|
||||
public final static int remainingCarbsCap = 90; // max carbs we'll assume will absorb over 4h if we don't yet see carb absorption
|
||||
// WARNING: use SMB with caution: it can and will automatically bolus up to max_iob worth of extra insulin
|
||||
// enableUAM:true // enable detection of unannounced meal carb absorption
|
||||
public final static boolean A52_risk_enable = false;
|
||||
//public final static boolean enableSMB_with_COB = true; // ***** default false in oref1 ***** enable supermicrobolus while COB is positive
|
||||
//public final static boolean enableSMB_with_temptarget = true; // ***** default false in oref1 ***** enable supermicrobolus for eating soon temp targets
|
||||
// *** WARNING *** DO NOT USE enableSMB_always or enableSMB_after_carbs with xDrip+, Libre, or similar
|
||||
// xDrip+, LimiTTer, etc. do not properly filter out high-noise SGVs
|
||||
// Using SMB overnight with such data sources risks causing a dangerous overdose of insulin
|
||||
// if the CGM sensor reads falsely high and doesn't come down as actual BG does
|
||||
// public final static boolean enableSMB_always = false; // always enable supermicrobolus (unless disabled by high temptarget)
|
||||
// *** WARNING *** DO NOT USE enableSMB_always or enableSMB_after_carbs with xDrip+, Libre, or similar
|
||||
//public final static boolean enableSMB_after_carbs = false; // enable supermicrobolus for 6h after carbs, even with 0 COB
|
||||
//public final static boolean allowSMB_with_high_temptarget = false; // allow supermicrobolus (if otherwise enabled) even with high temp targets
|
||||
public final static int maxSMBBasalMinutes = 30; // maximum minutes of basal that can be delivered as a single SMB with uncovered COB
|
||||
// curve:"rapid-acting" // Supported curves: "bilinear", "rapid-acting" (Novolog, Novorapid, Humalog, Apidra) and "ultra-rapid" (Fiasp)
|
||||
// useCustomPeakTime:false // allows changing insulinPeakTime
|
||||
// insulinPeakTime:75 // number of minutes after a bolus activity peaks. defaults to 55m for Fiasp if useCustomPeakTime: false
|
||||
public final static int carbsReqThreshold = 1; // grams of carbsReq to trigger a pushover
|
||||
// offline_hotspot:false // enabled an offline-only local wifi hotspot if no Internet available
|
||||
}
|
|
@ -11,7 +11,6 @@ import android.view.Window;
|
|||
import android.view.WindowManager;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.crashlytics.android.answers.Answers;
|
||||
import com.crashlytics.android.answers.CustomEvent;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
@ -24,6 +23,7 @@ import info.nightscout.androidaps.MainApp;
|
|||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.GlucoseStatus;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.utils.FabricPrivacy;
|
||||
import info.nightscout.utils.NumberPicker;
|
||||
import info.nightscout.utils.SafeParse;
|
||||
import info.nightscout.utils.XdripCalibrations;
|
||||
|
@ -88,7 +88,7 @@ public class CalibrationDialog extends DialogFragment implements View.OnClickLis
|
|||
final Double bg = SafeParse.stringToDouble(bgNumber.getText());
|
||||
XdripCalibrations.confirmAndSendCalibration(bg, context);
|
||||
dismiss();
|
||||
Answers.getInstance().logCustom(new CustomEvent("Calibration"));
|
||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("Calibration"));
|
||||
break;
|
||||
case R.id.cancel:
|
||||
dismiss();
|
||||
|
|
|
@ -0,0 +1,380 @@
|
|||
package info.nightscout.androidaps.plugins.Overview.Dialogs;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.os.HandlerThread;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.text.Editable;
|
||||
import android.text.Html;
|
||||
import android.text.TextWatcher;
|
||||
import android.text.format.DateFormat;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.wdullaer.materialdatetimepicker.date.DatePickerDialog;
|
||||
import com.wdullaer.materialdatetimepicker.time.RadialPickerLayout;
|
||||
import com.wdullaer.materialdatetimepicker.time.TimePickerDialog;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
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.db.CareportalEvent;
|
||||
import info.nightscout.androidaps.db.Source;
|
||||
import info.nightscout.androidaps.db.TempTarget;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
|
||||
import info.nightscout.androidaps.queue.Callback;
|
||||
import info.nightscout.utils.DateUtil;
|
||||
import info.nightscout.utils.DecimalFormatter;
|
||||
import info.nightscout.utils.NumberPicker;
|
||||
import info.nightscout.utils.SP;
|
||||
import info.nightscout.utils.SafeParse;
|
||||
import info.nightscout.utils.ToastUtils;
|
||||
|
||||
public class NewCarbsDialog extends DialogFragment implements OnClickListener, DatePickerDialog.OnDateSetListener, TimePickerDialog.OnTimeSetListener {
|
||||
private static Logger log = LoggerFactory.getLogger(NewCarbsDialog.class);
|
||||
|
||||
private EditText foodText;
|
||||
private NumberPicker editCarbs;
|
||||
|
||||
private TextView dateButton;
|
||||
private TextView timeButton;
|
||||
|
||||
private Date initialEventTime;
|
||||
private Date eventTime;
|
||||
|
||||
private Button fav1Button;
|
||||
private Button fav2Button;
|
||||
private Button fav3Button;
|
||||
|
||||
private static final double FAV1_DEFAULT = 5;
|
||||
private static final double FAV2_DEFAULT = 10;
|
||||
private static final double FAV3_DEFAULT = 20;
|
||||
private CheckBox suspendLoopCheckbox;
|
||||
private CheckBox startActivityTTCheckbox;
|
||||
private CheckBox startEatingSoonTTCheckbox;
|
||||
|
||||
private Integer maxCarbs;
|
||||
|
||||
//one shot guards
|
||||
private boolean accepted;
|
||||
private boolean okClicked;
|
||||
|
||||
public NewCarbsDialog() {
|
||||
HandlerThread mHandlerThread = new HandlerThread(NewCarbsDialog.class.getSimpleName());
|
||||
mHandlerThread.start();
|
||||
}
|
||||
|
||||
final private TextWatcher textWatcher = new TextWatcher() {
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
validateInputs();
|
||||
}
|
||||
};
|
||||
|
||||
private void validateInputs() {
|
||||
Integer carbs = SafeParse.stringToInt(editCarbs.getText());
|
||||
if (carbs > maxCarbs) {
|
||||
editCarbs.setValue(0d);
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.carbsconstraintapplied));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.overview_newcarbs_dialog, container, false);
|
||||
|
||||
view.findViewById(R.id.ok).setOnClickListener(this);
|
||||
view.findViewById(R.id.cancel).setOnClickListener(this);
|
||||
|
||||
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
|
||||
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
|
||||
|
||||
maxCarbs = MainApp.getConfigBuilder().applyCarbsConstraints(Constants.carbsOnlyForCheckLimit);
|
||||
|
||||
foodText = view.findViewById(R.id.newcarb_food);
|
||||
|
||||
editCarbs = view.findViewById(R.id.newcarb_carbsamount);
|
||||
|
||||
editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false, textWatcher);
|
||||
|
||||
startActivityTTCheckbox = view.findViewById(R.id.newcarbs_activity_tt);
|
||||
startEatingSoonTTCheckbox = view.findViewById(R.id.carbs_eating_soon_tt);
|
||||
|
||||
dateButton = view.findViewById(R.id.newcarbs_eventdate);
|
||||
timeButton = view.findViewById(R.id.newcarb_eventtime);
|
||||
|
||||
initialEventTime = new Date();
|
||||
eventTime = new Date(initialEventTime.getTime());
|
||||
dateButton.setText(DateUtil.dateString(eventTime));
|
||||
timeButton.setText(DateUtil.timeString(eventTime));
|
||||
dateButton.setOnClickListener(this);
|
||||
timeButton.setOnClickListener(this);
|
||||
|
||||
//To be able to select only one TT at a time
|
||||
startEatingSoonTTCheckbox.setOnClickListener(this);
|
||||
startActivityTTCheckbox.setOnClickListener(this);
|
||||
|
||||
// TODO prefilling carbs, maybe
|
||||
// TODO maybe update suggested carbs to target TT when checked
|
||||
// APSResult lastAPSResult = ConfigBuilderPlugin.getActiveAPS().getLastAPSResult();
|
||||
// if (lastAPSResult != null && lastAPSResult instanceof DetermineBasalResultSMB && ((DetermineBasalResultSMB) lastAPSResult).carbsReq > 0) {
|
||||
// editCarbs.setValue(((DetermineBasalResultSMB) lastAPSResult).carbsReq);
|
||||
// }
|
||||
|
||||
fav1Button = view.findViewById(R.id.newcarbs_plus1);
|
||||
fav1Button.setOnClickListener(this);
|
||||
fav1Button.setText("+" + SP.getString(R.string.key_carbs_button_increment_1, String.valueOf(FAV1_DEFAULT)));
|
||||
fav2Button = view.findViewById(R.id.newcarbs_plus2);
|
||||
fav2Button.setOnClickListener(this);
|
||||
fav2Button.setText("+" + SP.getString(R.string.key_carbs_button_increment_2, String.valueOf(FAV2_DEFAULT)));
|
||||
fav3Button = view.findViewById(R.id.newcarbs_plus3);
|
||||
fav3Button.setOnClickListener(this);
|
||||
fav3Button.setText("+" + SP.getString(R.string.key_carbs_button_increment_3, String.valueOf(FAV3_DEFAULT)));
|
||||
|
||||
suspendLoopCheckbox = view.findViewById(R.id.newcarbs_suspend_loop);
|
||||
|
||||
setCancelable(true);
|
||||
getDialog().setCanceledOnTouchOutside(false);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void onClick(View view) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(eventTime);
|
||||
switch (view.getId()) {
|
||||
case R.id.ok:
|
||||
submit();
|
||||
break;
|
||||
case R.id.cancel:
|
||||
dismiss();
|
||||
break;
|
||||
case R.id.newcarbs_eventdate:
|
||||
DatePickerDialog dpd = DatePickerDialog.newInstance(
|
||||
this,
|
||||
calendar.get(Calendar.YEAR),
|
||||
calendar.get(Calendar.MONTH),
|
||||
calendar.get(Calendar.DAY_OF_MONTH)
|
||||
);
|
||||
dpd.setThemeDark(true);
|
||||
dpd.dismissOnPause(true);
|
||||
dpd.show(getActivity().getFragmentManager(), "Datepickerdialog");
|
||||
break;
|
||||
case R.id.newcarb_eventtime:
|
||||
TimePickerDialog tpd = TimePickerDialog.newInstance(
|
||||
this,
|
||||
calendar.get(Calendar.HOUR_OF_DAY),
|
||||
calendar.get(Calendar.MINUTE),
|
||||
DateFormat.is24HourFormat(getActivity())
|
||||
);
|
||||
tpd.setThemeDark(true);
|
||||
tpd.dismissOnPause(true);
|
||||
tpd.show(getActivity().getFragmentManager(), "Timepickerdialog");
|
||||
break;
|
||||
case R.id.newcarbs_plus1:
|
||||
editCarbs.setValue(editCarbs.getValue()
|
||||
+ SP.getDouble(R.string.key_carbs_button_increment_1, FAV1_DEFAULT));
|
||||
validateInputs();
|
||||
break;
|
||||
case R.id.newcarbs_plus2:
|
||||
editCarbs.setValue(editCarbs.getValue()
|
||||
+ SP.getDouble(R.string.key_carbs_button_increment_2, FAV2_DEFAULT));
|
||||
validateInputs();
|
||||
break;
|
||||
case R.id.newcarbs_plus3:
|
||||
editCarbs.setValue(editCarbs.getValue()
|
||||
+ SP.getDouble(R.string.key_carbs_button_increment_3, FAV3_DEFAULT));
|
||||
validateInputs();
|
||||
break;
|
||||
case R.id.newcarbs_activity_tt:
|
||||
startEatingSoonTTCheckbox.setChecked(false);
|
||||
break;
|
||||
case R.id.carbs_eating_soon_tt:
|
||||
startActivityTTCheckbox.setChecked(false);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void submit() {
|
||||
if (okClicked) {
|
||||
log.debug("guarding: ok already clicked");
|
||||
dismiss();
|
||||
return;
|
||||
}
|
||||
okClicked = true;
|
||||
try {
|
||||
final String food = StringUtils.trimToNull(foodText.getText().toString());
|
||||
final Integer carbs = SafeParse.stringToInt(editCarbs.getText());
|
||||
Integer carbsAfterConstraints = MainApp.getConfigBuilder().applyCarbsConstraints(carbs);
|
||||
|
||||
String confirmMessage = "";
|
||||
if (carbs > 0)
|
||||
confirmMessage += MainApp.gs(R.string.carbs) + ": " + "<font color='" + MainApp.gc(R.color.colorCarbsButton) + "'>" + carbsAfterConstraints + "g" + "</font>";
|
||||
if (!carbsAfterConstraints.equals(carbs))
|
||||
confirmMessage += "<br/><font color='" + MainApp.gc(R.color.low) + "'>" + MainApp.gs(R.string.carbsconstraintapplied) + "</font>";
|
||||
if (suspendLoopCheckbox.isChecked()) {
|
||||
confirmMessage += "<br/>" + MainApp.gs(R.string.loop) + ": " + "<font color='" + MainApp.gc(R.color.low) + "'>" + MainApp.gs(R.string.suspendloopfor30min) + "</font>";
|
||||
}
|
||||
|
||||
final Profile currentProfile = MainApp.getConfigBuilder().getProfile();
|
||||
if (currentProfile == null)
|
||||
return;
|
||||
|
||||
int activityTTDuration = SP.getInt(R.string.key_activity_duration, Constants.defaultActivityTTDuration);
|
||||
activityTTDuration = activityTTDuration > 0 ? activityTTDuration : Constants.defaultActivityTTDuration;
|
||||
double activityTT = SP.getDouble(R.string.key_activity_target, currentProfile.getUnits().equals(Constants.MMOL) ? Constants.defaultActivityTTmmol : Constants.defaultActivityTTmgdl);
|
||||
activityTT = activityTT > 0 ? activityTT : currentProfile.getUnits().equals(Constants.MMOL) ? Constants.defaultActivityTTmmol : Constants.defaultActivityTTmgdl;
|
||||
|
||||
int eatingSoonTTDuration = SP.getInt(R.string.key_eatingsoon_duration, Constants.defaultEatingSoonTTDuration);
|
||||
eatingSoonTTDuration = eatingSoonTTDuration > 0 ? eatingSoonTTDuration : Constants.defaultEatingSoonTTDuration;
|
||||
double eatingSoonTT = SP.getDouble(R.string.key_eatingsoon_target, currentProfile.getUnits().equals(Constants.MMOL) ? Constants.defaultEatingSoonTTmmol : Constants.defaultEatingSoonTTmgdl);
|
||||
eatingSoonTT = eatingSoonTT > 0 ? eatingSoonTT : currentProfile.getUnits().equals(Constants.MMOL) ? Constants.defaultEatingSoonTTmmol : Constants.defaultEatingSoonTTmgdl;
|
||||
|
||||
if (startActivityTTCheckbox.isChecked()) {
|
||||
if (currentProfile.getUnits().equals(Constants.MMOL)) {
|
||||
confirmMessage += "<br/>" + MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.high) + "'>" + DecimalFormatter.to1Decimal(activityTT) + " mmol/l (" + ((int) activityTTDuration) + " min)</font>";
|
||||
} else
|
||||
confirmMessage += "<br/>" + MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.high) + "'>" + DecimalFormatter.to0Decimal(activityTT) + " mg/dl (" + ((int) activityTTDuration) + " min)</font>";
|
||||
|
||||
}
|
||||
if (startEatingSoonTTCheckbox.isChecked() && !startActivityTTCheckbox.isChecked()) {
|
||||
if (currentProfile.getUnits().equals(Constants.MMOL)) {
|
||||
confirmMessage += "<br/>" + MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.high) + "'>" + DecimalFormatter.to1Decimal(eatingSoonTT) + " mmol/l (" + eatingSoonTTDuration + " min)</font>";
|
||||
} else
|
||||
confirmMessage += "<br/>" + MainApp.gs(R.string.temptargetshort) + ": " + "<font color='" + MainApp.gc(R.color.high) + "'>" + DecimalFormatter.to0Decimal(eatingSoonTT) + " mg/dl (" + eatingSoonTTDuration + " min)</font>";
|
||||
|
||||
}
|
||||
final double finalActivityTT = activityTT;
|
||||
final double finalEatigSoonTT = eatingSoonTT;
|
||||
final int finalActivityTTDuration = activityTTDuration;
|
||||
final int finalEatingSoonTTDuration = eatingSoonTTDuration;
|
||||
|
||||
if (StringUtils.isNoneEmpty(food)) {
|
||||
confirmMessage += "<br/>" + "Food: " + food;
|
||||
}
|
||||
|
||||
if (!initialEventTime.equals(eventTime)) {
|
||||
confirmMessage += "<br/> Time: " + DateUtil.dateAndTimeString(eventTime);
|
||||
}
|
||||
if (confirmMessage.length() > 0) {
|
||||
|
||||
final int finalCarbsAfterConstraints = carbsAfterConstraints;
|
||||
|
||||
final Context context = getContext();
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
|
||||
builder.setTitle(MainApp.gs(R.string.confirmation));
|
||||
if (confirmMessage.startsWith("<br/>"))
|
||||
confirmMessage = confirmMessage.substring("<br/>".length());
|
||||
|
||||
builder.setMessage(Html.fromHtml(confirmMessage));
|
||||
builder.setPositiveButton(MainApp.gs(R.string.ok), (dialog, id) -> {
|
||||
synchronized (builder) {
|
||||
if (accepted) {
|
||||
log.debug("guarding: already accepted");
|
||||
return;
|
||||
}
|
||||
accepted = true;
|
||||
|
||||
if (suspendLoopCheckbox.isChecked()) {
|
||||
final LoopPlugin activeloop = ConfigBuilderPlugin.getActiveLoop();
|
||||
activeloop.suspendTo(System.currentTimeMillis() + 30L * 60 * 1000);
|
||||
ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, new Callback() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!result.success) {
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.tempbasaldeliveryerror));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (startActivityTTCheckbox.isChecked()) {
|
||||
TempTarget tempTarget = new TempTarget();
|
||||
tempTarget.date = System.currentTimeMillis();
|
||||
tempTarget.durationInMinutes = finalActivityTTDuration;
|
||||
tempTarget.reason = MainApp.gs(R.string.activity);
|
||||
tempTarget.source = Source.USER;
|
||||
tempTarget.low = Profile.toMgdl(finalActivityTT, currentProfile.getUnits());
|
||||
tempTarget.high = Profile.toMgdl(finalActivityTT, currentProfile.getUnits());
|
||||
MainApp.getDbHelper().createOrUpdate(tempTarget);
|
||||
} else if (startEatingSoonTTCheckbox.isChecked()) {
|
||||
TempTarget tempTarget = new TempTarget();
|
||||
tempTarget.date = System.currentTimeMillis();
|
||||
tempTarget.durationInMinutes = finalEatingSoonTTDuration;
|
||||
tempTarget.reason = MainApp.gs(R.string.eatingsoon);
|
||||
tempTarget.source = Source.USER;
|
||||
tempTarget.low = Profile.toMgdl(finalEatigSoonTT, currentProfile.getUnits());
|
||||
tempTarget.high = Profile.toMgdl(finalEatigSoonTT, currentProfile.getUnits());
|
||||
MainApp.getDbHelper().createOrUpdate(tempTarget);
|
||||
}
|
||||
|
||||
if (finalCarbsAfterConstraints > 0 || food != null) {
|
||||
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
|
||||
detailedBolusInfo.date = eventTime.getTime();
|
||||
detailedBolusInfo.eventType = CareportalEvent.CARBCORRECTION;
|
||||
detailedBolusInfo.carbs = finalCarbsAfterConstraints;
|
||||
// detailedBolusInfo.food = food;
|
||||
detailedBolusInfo.context = context;
|
||||
detailedBolusInfo.source = Source.USER;
|
||||
MainApp.getConfigBuilder().addToHistoryTreatment(detailedBolusInfo);
|
||||
}
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
|
||||
builder.show();
|
||||
dismiss();
|
||||
} else
|
||||
dismiss();
|
||||
} catch (Exception e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDateSet(DatePickerDialog view, int year, int monthOfYear, int dayOfMonth) {
|
||||
eventTime.setYear(year - 1900);
|
||||
eventTime.setMonth(monthOfYear);
|
||||
eventTime.setDate(dayOfMonth);
|
||||
dateButton.setText(DateUtil.dateString(eventTime));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimeSet(RadialPickerLayout view, int hourOfDay, int minute, int second) {
|
||||
eventTime.setHours(hourOfDay);
|
||||
eventTime.setMinutes(minute);
|
||||
eventTime.setSeconds(second);
|
||||
timeButton.setText(DateUtil.timeString(eventTime));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,353 @@
|
|||
package info.nightscout.androidaps.plugins.Overview.Dialogs;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.HandlerThread;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.text.Editable;
|
||||
import android.text.Html;
|
||||
import android.text.TextWatcher;
|
||||
import android.text.format.DateFormat;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.crashlytics.android.answers.Answers;
|
||||
import com.crashlytics.android.answers.CustomEvent;
|
||||
import com.wdullaer.materialdatetimepicker.date.DatePickerDialog;
|
||||
import com.wdullaer.materialdatetimepicker.time.RadialPickerLayout;
|
||||
import com.wdullaer.materialdatetimepicker.time.TimePickerDialog;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
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.db.CareportalEvent;
|
||||
import info.nightscout.androidaps.db.Source;
|
||||
import info.nightscout.androidaps.db.TempTarget;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.Loop.APSResult;
|
||||
import info.nightscout.androidaps.plugins.OpenAPSSMB.DetermineBasalResultSMB;
|
||||
import info.nightscout.androidaps.queue.Callback;
|
||||
import info.nightscout.utils.DateUtil;
|
||||
import info.nightscout.utils.NumberPicker;
|
||||
import info.nightscout.utils.SP;
|
||||
import info.nightscout.utils.SafeParse;
|
||||
import info.nightscout.utils.ToastUtils;
|
||||
|
||||
public class NewInsulinDialog extends DialogFragment implements OnClickListener, DatePickerDialog.OnDateSetListener, TimePickerDialog.OnTimeSetListener {
|
||||
private static Logger log = LoggerFactory.getLogger(NewInsulinDialog.class);
|
||||
|
||||
private NumberPicker editInsulin;
|
||||
|
||||
private TextView dateButton;
|
||||
private TextView timeButton;
|
||||
|
||||
private Date initialEventTime;
|
||||
private Date eventTime;
|
||||
|
||||
private Button plus1Button;
|
||||
private Button plus2Button;
|
||||
private Button plus3Button;
|
||||
|
||||
public static final double PLUS1_DEFAULT = 0.5d;
|
||||
public static final double PLUS2_DEFAULT = 1d;
|
||||
public static final double PLUS3_DEFAULT = 2d;
|
||||
|
||||
private CheckBox startESMCheckbox;
|
||||
private CheckBox recordOnlyCheckbox;
|
||||
|
||||
private Double maxInsulin;
|
||||
|
||||
//one shot guards
|
||||
private boolean accepted;
|
||||
private boolean okClicked;
|
||||
|
||||
public NewInsulinDialog() {
|
||||
HandlerThread mHandlerThread = new HandlerThread(NewInsulinDialog.class.getSimpleName());
|
||||
mHandlerThread.start();
|
||||
}
|
||||
|
||||
final private TextWatcher textWatcher = new TextWatcher() {
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
validateInputs();
|
||||
}
|
||||
};
|
||||
|
||||
private void validateInputs() {
|
||||
Double insulin = SafeParse.stringToDouble(editInsulin.getText());
|
||||
if (insulin > maxInsulin) {
|
||||
editInsulin.setValue(0d);
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.bolusconstraintapplied));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.overview_newinsulin_dialog, container, false);
|
||||
|
||||
view.findViewById(R.id.ok).setOnClickListener(this);
|
||||
view.findViewById(R.id.cancel).setOnClickListener(this);
|
||||
|
||||
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
|
||||
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
|
||||
|
||||
maxInsulin = MainApp.getConfigBuilder().applyBolusConstraints(Constants.bolusOnlyForCheckLimit);
|
||||
|
||||
editInsulin = (NumberPicker) view.findViewById(R.id.treatments_newinsulin_amount);
|
||||
|
||||
editInsulin.setParams(0d, 0d, maxInsulin, ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep, new DecimalFormat("0.00"), false, textWatcher);
|
||||
|
||||
dateButton = (TextView) view.findViewById(R.id.newinsulin_eventdate);
|
||||
timeButton = (TextView) view.findViewById(R.id.newinsulin_eventtime);
|
||||
|
||||
initialEventTime = new Date();
|
||||
eventTime = new Date(initialEventTime.getTime());
|
||||
dateButton.setText(DateUtil.dateString(eventTime));
|
||||
timeButton.setText(DateUtil.timeString(eventTime));
|
||||
dateButton.setOnClickListener(this);
|
||||
timeButton.setOnClickListener(this);
|
||||
|
||||
/*
|
||||
// This makes it to easy to just bolus insulinReq, which is almost always too much
|
||||
APSResult lastAPSResult = ConfigBuilderPlugin.getActiveAPS().getLastAPSResult();
|
||||
if (lastAPSResult != null && lastAPSResult instanceof DetermineBasalResultSMB && ((DetermineBasalResultSMB) lastAPSResult).insulinReq > 0) {
|
||||
editInsulin.setValue(((DetermineBasalResultSMB )lastAPSResult).insulinReq);
|
||||
}
|
||||
*/
|
||||
|
||||
plus1Button = (Button) view.findViewById(R.id.newinsulin_plus05);
|
||||
plus1Button.setOnClickListener(this);
|
||||
plus1Button.setText("+" + SP.getString(MainApp.gs(R.string.key_insulin_button_increment_1), String.valueOf(PLUS1_DEFAULT)));
|
||||
plus2Button = (Button) view.findViewById(R.id.newinsulin_plus10);
|
||||
plus2Button.setOnClickListener(this);
|
||||
plus2Button.setText("+" + SP.getString(MainApp.gs(R.string.key_insulin_button_increment_2), String.valueOf(PLUS2_DEFAULT)));
|
||||
plus3Button = (Button) view.findViewById(R.id.newinsulin_plus20);
|
||||
plus3Button.setOnClickListener(this);
|
||||
plus3Button.setText("+" + SP.getString(MainApp.gs(R.string.key_insulin_button_increment_3), String.valueOf(PLUS3_DEFAULT)));
|
||||
|
||||
startESMCheckbox = (CheckBox) view.findViewById(R.id.newinsulin_start_eating_soon_tt);
|
||||
recordOnlyCheckbox = (CheckBox) view.findViewById(R.id.newinsulin_record_only);
|
||||
recordOnlyCheckbox.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
if (dateButton != null) dateButton.setEnabled(isChecked);
|
||||
if (timeButton != null) timeButton.setEnabled(isChecked);
|
||||
});
|
||||
|
||||
setCancelable(true);
|
||||
getDialog().setCanceledOnTouchOutside(false);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void onClick(View view) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(eventTime);
|
||||
switch (view.getId()) {
|
||||
case R.id.ok:
|
||||
submit();
|
||||
break;
|
||||
case R.id.cancel:
|
||||
dismiss();
|
||||
break;
|
||||
case R.id.newinsulin_eventdate:
|
||||
DatePickerDialog dpd = DatePickerDialog.newInstance(
|
||||
this,
|
||||
calendar.get(Calendar.YEAR),
|
||||
calendar.get(Calendar.MONTH),
|
||||
calendar.get(Calendar.DAY_OF_MONTH)
|
||||
);
|
||||
dpd.setThemeDark(true);
|
||||
dpd.dismissOnPause(true);
|
||||
dpd.show(getActivity().getFragmentManager(), "Datepickerdialog");
|
||||
break;
|
||||
case R.id.newinsulin_eventtime:
|
||||
TimePickerDialog tpd = TimePickerDialog.newInstance(
|
||||
this,
|
||||
calendar.get(Calendar.HOUR_OF_DAY),
|
||||
calendar.get(Calendar.MINUTE),
|
||||
DateFormat.is24HourFormat(getActivity())
|
||||
);
|
||||
tpd.setThemeDark(true);
|
||||
tpd.dismissOnPause(true);
|
||||
tpd.show(getActivity().getFragmentManager(), "Timepickerdialog");
|
||||
break;
|
||||
case R.id.newinsulin_start_eating_soon_tt:
|
||||
final Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||
double tt = SP.getDouble(R.string.key_eatingsoon_target, 0d);
|
||||
double ttBgAdd = (tt - profile.getTargetLow()) / profile.getIsf();
|
||||
editInsulin.setValue(editInsulin.getValue() + (startESMCheckbox.isChecked() ? ttBgAdd : -ttBgAdd));
|
||||
break;
|
||||
case R.id.newinsulin_plus05:
|
||||
editInsulin.setValue(editInsulin.getValue()
|
||||
+ SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_1), PLUS1_DEFAULT));
|
||||
validateInputs();
|
||||
break;
|
||||
case R.id.newinsulin_plus10:
|
||||
editInsulin.setValue(editInsulin.getValue()
|
||||
+ SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_2), PLUS2_DEFAULT));
|
||||
validateInputs();
|
||||
break;
|
||||
case R.id.newinsulin_plus20:
|
||||
editInsulin.setValue(editInsulin.getValue()
|
||||
+ SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_3), PLUS3_DEFAULT));
|
||||
validateInputs();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void submit() {
|
||||
if (okClicked){
|
||||
log.debug("guarding: ok already clicked");
|
||||
dismiss();
|
||||
return;
|
||||
}
|
||||
okClicked = true;
|
||||
try {
|
||||
Double insulin = SafeParse.stringToDouble(editInsulin.getText());
|
||||
Double insulinAfterConstraints = MainApp.getConfigBuilder().applyBolusConstraints(insulin);
|
||||
|
||||
String confirmMessage = "";
|
||||
if (insulin > 0) {
|
||||
confirmMessage += MainApp.gs(R.string.bolus) + ": " + "<font color='" + MainApp.gc(R.color.colorCarbsButton) + "'>" + insulinAfterConstraints + "U" + "</font>";
|
||||
if (recordOnlyCheckbox.isChecked()) {
|
||||
confirmMessage += "<br/><font color='" + MainApp.gc(R.color.low) + "'>" + MainApp.gs(R.string.bolusrecordedonly) + "</font>";
|
||||
}
|
||||
}
|
||||
|
||||
if (!insulinAfterConstraints.equals(insulin))
|
||||
confirmMessage += "<br/><font color='" + MainApp.sResources.getColor(R.color.low) + "'>" + MainApp.gs(R.string.bolusconstraintapplied) + "</font>";
|
||||
double prefTTDuration = SP.getDouble(R.string.key_eatingsoon_duration, 45d);
|
||||
double ttDuration = prefTTDuration > 0 ? prefTTDuration : 45d;
|
||||
double prefTT = SP.getDouble(R.string.key_eatingsoon_target, 80d);
|
||||
double tt = prefTT > 0 ? prefTT : 80d;
|
||||
Profile currentProfile = MainApp.getConfigBuilder().getProfile();
|
||||
if(currentProfile == null)
|
||||
return;
|
||||
if(currentProfile.getUnits().equals(Constants.MMOL))
|
||||
tt = prefTT > 0 ? Profile.toMgdl(prefTT, Constants.MMOL) : 80d;
|
||||
else
|
||||
tt = prefTT > 0 ? prefTT : 80d;
|
||||
final double finalTT = tt;
|
||||
if (startESMCheckbox.isChecked()) {
|
||||
if(currentProfile.getUnits().equals("mmol")){
|
||||
confirmMessage += "<br/>" + "TT: " + "<font color='" + MainApp.sResources.getColor(R.color.high) + "'>" + Profile.toMmol(tt, Constants.MGDL) + " mmol for " + ((int) ttDuration) + " min </font>";
|
||||
} else
|
||||
confirmMessage += "<br/>" + "TT: " + "<font color='" + MainApp.sResources.getColor(R.color.high) + "'>" + ((int) tt) + "mg/dl for " + ((int) ttDuration) + " min </font>";
|
||||
}
|
||||
|
||||
if (!initialEventTime.equals(eventTime)) {
|
||||
confirmMessage += "<br/>Time: " + DateUtil.dateAndTimeString(eventTime);
|
||||
}
|
||||
|
||||
final double finalInsulinAfterConstraints = insulinAfterConstraints;
|
||||
|
||||
final Context context = getContext();
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
|
||||
builder.setTitle(MainApp.gs(R.string.confirmation));
|
||||
if (confirmMessage.startsWith("<br/>"))
|
||||
confirmMessage = confirmMessage.substring("<br/>".length());
|
||||
builder.setMessage(Html.fromHtml(confirmMessage));
|
||||
builder.setPositiveButton(MainApp.gs(R.string.ok), (dialog, id) -> {
|
||||
synchronized (builder) {
|
||||
if (accepted) {
|
||||
log.debug("guarding: already accepted");
|
||||
return;
|
||||
}
|
||||
accepted = true;
|
||||
|
||||
if (startESMCheckbox.isChecked()) {
|
||||
TempTarget tempTarget = new TempTarget();
|
||||
tempTarget.date = System.currentTimeMillis();
|
||||
tempTarget.durationInMinutes = (int) ttDuration;
|
||||
tempTarget.reason = "Eating soon";
|
||||
tempTarget.source = Source.USER;
|
||||
tempTarget.low = (int) finalTT;
|
||||
tempTarget.high = (int) finalTT;
|
||||
MainApp.getDbHelper().createOrUpdate(tempTarget);
|
||||
}
|
||||
|
||||
if (finalInsulinAfterConstraints <= 0.01) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (recordOnlyCheckbox.isChecked()) {
|
||||
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
|
||||
detailedBolusInfo.source = Source.USER;
|
||||
detailedBolusInfo.date = eventTime.getTime();
|
||||
detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS;
|
||||
detailedBolusInfo.insulin = finalInsulinAfterConstraints;
|
||||
MainApp.getConfigBuilder().addToHistoryTreatment(detailedBolusInfo);
|
||||
} else {
|
||||
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
|
||||
detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS;
|
||||
detailedBolusInfo.insulin = finalInsulinAfterConstraints;
|
||||
detailedBolusInfo.context = context;
|
||||
detailedBolusInfo.source = Source.USER;
|
||||
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);
|
||||
}
|
||||
}
|
||||
});
|
||||
Answers.getInstance().logCustom(new CustomEvent("Bolus"));
|
||||
}
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
|
||||
builder.show();
|
||||
dismiss();
|
||||
} catch (Exception e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDateSet(DatePickerDialog view, int year, int monthOfYear, int dayOfMonth) {
|
||||
eventTime.setYear(year - 1900);
|
||||
eventTime.setMonth(monthOfYear);
|
||||
eventTime.setDate(dayOfMonth);
|
||||
dateButton.setText(DateUtil.dateString(eventTime));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimeSet(RadialPickerLayout view, int hourOfDay, int minute, int second) {
|
||||
eventTime.setHours(hourOfDay);
|
||||
eventTime.setMinutes(minute);
|
||||
eventTime.setSeconds(second);
|
||||
timeButton.setText(DateUtil.timeString(eventTime));
|
||||
}
|
||||
}
|
|
@ -15,8 +15,8 @@ import android.view.View.OnClickListener;
|
|||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.CheckBox;
|
||||
|
||||
import com.crashlytics.android.answers.Answers;
|
||||
import com.crashlytics.android.answers.CustomEvent;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
@ -33,6 +33,7 @@ import info.nightscout.androidaps.db.CareportalEvent;
|
|||
import info.nightscout.androidaps.db.Source;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.queue.Callback;
|
||||
import info.nightscout.utils.FabricPrivacy;
|
||||
import info.nightscout.utils.NumberPicker;
|
||||
import info.nightscout.utils.SafeParse;
|
||||
import info.nightscout.utils.ToastUtils;
|
||||
|
@ -50,6 +51,8 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene
|
|||
private boolean accepted;
|
||||
private boolean okClicked;
|
||||
|
||||
private CheckBox recordOnlyCheckbox;
|
||||
|
||||
public NewTreatmentDialog() {
|
||||
}
|
||||
|
||||
|
@ -72,12 +75,12 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene
|
|||
Integer carbs = SafeParse.stringToInt(editCarbs.getText());
|
||||
if (carbs > maxCarbs) {
|
||||
editCarbs.setValue(0d);
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), getString(R.string.carbsconstraintapplied));
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.carbsconstraintapplied));
|
||||
}
|
||||
Double insulin = SafeParse.stringToDouble(editInsulin.getText());
|
||||
if (insulin > maxInsulin) {
|
||||
editInsulin.setValue(0d);
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), getString(R.string.bolusconstraintapplied));
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.bolusconstraintapplied));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,6 +104,8 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene
|
|||
editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false, textWatcher);
|
||||
editInsulin.setParams(0d, 0d, maxInsulin, ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep, new DecimalFormat("0.00"), false, textWatcher);
|
||||
|
||||
recordOnlyCheckbox = (CheckBox) view.findViewById(R.id.newtreatment_record_only);
|
||||
|
||||
setCancelable(true);
|
||||
getDialog().setCanceledOnTouchOutside(false);
|
||||
return view;
|
||||
|
@ -121,15 +126,21 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene
|
|||
Double insulin = SafeParse.stringToDouble(editInsulin.getText());
|
||||
final Integer carbs = SafeParse.stringToInt(editCarbs.getText());
|
||||
|
||||
String confirmMessage = getString(R.string.entertreatmentquestion) + "<br/>";
|
||||
String confirmMessage = MainApp.gs(R.string.entertreatmentquestion) + "<br/>";
|
||||
|
||||
Double insulinAfterConstraints = MainApp.getConfigBuilder().applyBolusConstraints(insulin);
|
||||
Integer carbsAfterConstraints = MainApp.getConfigBuilder().applyCarbsConstraints(carbs);
|
||||
|
||||
confirmMessage += getString(R.string.bolus) + ": " + "<font color='" + MainApp.sResources.getColor(R.color.bolus) + "'>" + insulinAfterConstraints + "U" + "</font>";
|
||||
confirmMessage += "<br/>" + getString(R.string.carbs) + ": " + carbsAfterConstraints + "g";
|
||||
if (insulin > 0) {
|
||||
confirmMessage += MainApp.gs(R.string.bolus) + ": " + "<font color='" + MainApp.gc(R.color.colorCarbsButton) + "'>" + insulinAfterConstraints + "U" + "</font>";
|
||||
if (recordOnlyCheckbox.isChecked()) {
|
||||
confirmMessage += "<br/><font color='" + MainApp.gc(R.color.low) + "'>" + MainApp.gs(R.string.bolusrecordedonly) + "</font>";
|
||||
}
|
||||
}
|
||||
if (carbsAfterConstraints > 0)
|
||||
confirmMessage += "<br/>" + MainApp.gs(R.string.carbs) + ": " + carbsAfterConstraints + "g";
|
||||
if (insulinAfterConstraints - insulin != 0 || !Objects.equals(carbsAfterConstraints, carbs))
|
||||
confirmMessage += "<br/>" + getString(R.string.constraintapllied);
|
||||
confirmMessage += "<br/>" + MainApp.gs(R.string.constraintapllied);
|
||||
|
||||
|
||||
final double finalInsulinAfterConstraints = insulinAfterConstraints;
|
||||
|
@ -138,9 +149,9 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene
|
|||
final Context context = getContext();
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
|
||||
builder.setTitle(this.getContext().getString(R.string.confirmation));
|
||||
builder.setTitle(MainApp.gs(R.string.confirmation));
|
||||
builder.setMessage(Html.fromHtml(confirmMessage));
|
||||
builder.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
|
||||
builder.setPositiveButton(MainApp.gs(R.string.ok), new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
synchronized (builder) {
|
||||
if (accepted) {
|
||||
|
@ -158,7 +169,7 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene
|
|||
detailedBolusInfo.carbs = finalCarbsAfterConstraints;
|
||||
detailedBolusInfo.context = context;
|
||||
detailedBolusInfo.source = Source.USER;
|
||||
if (detailedBolusInfo.insulin > 0 || ConfigBuilderPlugin.getActivePump().getPumpDescription().storesCarbInfo) {
|
||||
if (!(recordOnlyCheckbox.isChecked() && (detailedBolusInfo.insulin > 0 || ConfigBuilderPlugin.getActivePump().getPumpDescription().storesCarbInfo))) {
|
||||
ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
@ -166,7 +177,7 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene
|
|||
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
|
||||
i.putExtra("soundid", R.raw.boluserror);
|
||||
i.putExtra("status", result.comment);
|
||||
i.putExtra("title", MainApp.sResources.getString(R.string.treatmentdeliveryerror));
|
||||
i.putExtra("title", MainApp.gs(R.string.treatmentdeliveryerror));
|
||||
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
MainApp.instance().startActivity(i);
|
||||
}
|
||||
|
@ -175,14 +186,12 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene
|
|||
} else {
|
||||
MainApp.getConfigBuilder().addToHistoryTreatment(detailedBolusInfo);
|
||||
}
|
||||
Answers.getInstance().logCustom(new CustomEvent("Bolus"));
|
||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("Bolus"));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton(
|
||||
|
||||
getString(R.string.cancel), null);
|
||||
builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
|
||||
builder.show();
|
||||
|
||||
dismiss();
|
||||
|
|
|
@ -25,7 +25,6 @@ import android.widget.LinearLayout;
|
|||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.crashlytics.android.answers.Answers;
|
||||
import com.crashlytics.android.answers.CustomEvent;
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
|
@ -50,6 +49,7 @@ import info.nightscout.androidaps.db.CareportalEvent;
|
|||
import info.nightscout.androidaps.db.DatabaseHelper;
|
||||
import info.nightscout.androidaps.db.Source;
|
||||
import info.nightscout.androidaps.db.TempTarget;
|
||||
import info.nightscout.androidaps.events.EventFeatureRunning;
|
||||
import info.nightscout.androidaps.events.EventNewBG;
|
||||
import info.nightscout.androidaps.events.EventRefreshOverview;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
|
@ -57,9 +57,8 @@ import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensData;
|
|||
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
|
||||
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished;
|
||||
import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
|
||||
import info.nightscout.androidaps.plugins.OpenAPSAMA.OpenAPSAMAPlugin;
|
||||
import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateGui;
|
||||
import info.nightscout.androidaps.queue.Callback;
|
||||
import info.nightscout.utils.FabricPrivacy;
|
||||
import info.nightscout.utils.BolusWizard;
|
||||
import info.nightscout.utils.DateUtil;
|
||||
import info.nightscout.utils.DecimalFormatter;
|
||||
|
@ -132,6 +131,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
|
|||
public void onResume() {
|
||||
super.onResume();
|
||||
MainApp.bus().register(this);
|
||||
MainApp.bus().post(new EventFeatureRunning(EventFeatureRunning.Feature.WIZARD));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -382,7 +382,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
|
|||
} else {
|
||||
MainApp.getConfigBuilder().addToHistoryTreatment(detailedBolusInfo);
|
||||
}
|
||||
Answers.getInstance().logCustom(new CustomEvent("Wizard"));
|
||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("Wizard"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -476,7 +476,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
|
|||
// COB
|
||||
Double c_cob = 0d;
|
||||
if (cobCheckbox.isChecked()) {
|
||||
AutosensData autosensData = IobCobCalculatorPlugin.getLastAutosensData("Wizard COB");
|
||||
AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getLastAutosensData("Wizard COB");
|
||||
|
||||
if(autosensData != null) {
|
||||
c_cob = autosensData.cob;
|
||||
|
|
|
@ -3,9 +3,11 @@ package info.nightscout.androidaps.plugins.Overview;
|
|||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.os.Bundle;
|
||||
|
@ -32,8 +34,6 @@ import android.widget.CompoundButton;
|
|||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.crashlytics.android.Crashlytics;
|
||||
import com.crashlytics.android.answers.Answers;
|
||||
import com.crashlytics.android.answers.CustomEvent;
|
||||
import com.jjoe64.graphview.GraphView;
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
@ -93,10 +93,10 @@ import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
|
|||
import info.nightscout.androidaps.plugins.Loop.events.EventNewOpenLoopNotification;
|
||||
import info.nightscout.androidaps.plugins.NSClientInternal.broadcasts.BroadcastAckAlarm;
|
||||
import info.nightscout.androidaps.plugins.NSClientInternal.data.NSDeviceStatus;
|
||||
import info.nightscout.androidaps.plugins.OpenAPSAMA.DetermineBasalResultAMA;
|
||||
import info.nightscout.androidaps.plugins.OpenAPSAMA.OpenAPSAMAPlugin;
|
||||
import info.nightscout.androidaps.plugins.Overview.Dialogs.CalibrationDialog;
|
||||
import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity;
|
||||
import info.nightscout.androidaps.plugins.Overview.Dialogs.NewCarbsDialog;
|
||||
import info.nightscout.androidaps.plugins.Overview.Dialogs.NewInsulinDialog;
|
||||
import info.nightscout.androidaps.plugins.Overview.Dialogs.NewTreatmentDialog;
|
||||
import info.nightscout.androidaps.plugins.Overview.Dialogs.WizardDialog;
|
||||
import info.nightscout.androidaps.plugins.Overview.activities.QuickWizardListActivity;
|
||||
|
@ -105,12 +105,14 @@ import info.nightscout.androidaps.plugins.Overview.events.EventSetWakeLock;
|
|||
import info.nightscout.androidaps.plugins.Overview.graphData.GraphData;
|
||||
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
|
||||
import info.nightscout.androidaps.plugins.Overview.notifications.NotificationStore;
|
||||
import info.nightscout.androidaps.plugins.SourceDexcomG5.SourceDexcomG5Plugin;
|
||||
import info.nightscout.androidaps.plugins.SourceXdrip.SourceXdripPlugin;
|
||||
import info.nightscout.androidaps.plugins.Treatments.fragments.ProfileViewerDialog;
|
||||
import info.nightscout.androidaps.queue.Callback;
|
||||
import info.nightscout.utils.BolusWizard;
|
||||
import info.nightscout.utils.DateUtil;
|
||||
import info.nightscout.utils.DecimalFormatter;
|
||||
import info.nightscout.utils.FabricPrivacy;
|
||||
import info.nightscout.utils.NSUpload;
|
||||
import info.nightscout.utils.OKDialog;
|
||||
import info.nightscout.utils.Profiler;
|
||||
|
@ -165,10 +167,14 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
LinearLayoutManager llm;
|
||||
|
||||
LinearLayout acceptTempLayout;
|
||||
SingleClickButton acceptTempButton;
|
||||
|
||||
SingleClickButton treatmentButton;
|
||||
SingleClickButton wizardButton;
|
||||
SingleClickButton calibrationButton;
|
||||
SingleClickButton acceptTempButton;
|
||||
SingleClickButton insulinButton;
|
||||
SingleClickButton carbsButton;
|
||||
SingleClickButton cgmButton;
|
||||
SingleClickButton quickWizardButton;
|
||||
|
||||
CheckBox lockScreen;
|
||||
|
@ -259,6 +265,12 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
treatmentButton.setOnClickListener(this);
|
||||
wizardButton = (SingleClickButton) view.findViewById(R.id.overview_wizardbutton);
|
||||
wizardButton.setOnClickListener(this);
|
||||
insulinButton = (SingleClickButton) view.findViewById(R.id.overview_insulinbutton);
|
||||
if (insulinButton != null)
|
||||
insulinButton.setOnClickListener(this);
|
||||
carbsButton = (SingleClickButton) view.findViewById(R.id.overview_carbsbutton);
|
||||
if (carbsButton != null)
|
||||
carbsButton.setOnClickListener(this);
|
||||
acceptTempButton = (SingleClickButton) view.findViewById(R.id.overview_accepttempbutton);
|
||||
if (acceptTempButton != null)
|
||||
acceptTempButton.setOnClickListener(this);
|
||||
|
@ -268,6 +280,9 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
calibrationButton = (SingleClickButton) view.findViewById(R.id.overview_calibrationbutton);
|
||||
if (calibrationButton != null)
|
||||
calibrationButton.setOnClickListener(this);
|
||||
cgmButton = (SingleClickButton) view.findViewById(R.id.overview_cgmbutton);
|
||||
if (cgmButton != null)
|
||||
cgmButton.setOnClickListener(this);
|
||||
|
||||
acceptTempLayout = (LinearLayout) view.findViewById(R.id.overview_accepttemplayout);
|
||||
|
||||
|
@ -344,7 +359,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
|
||||
return view;
|
||||
} catch (Exception e) {
|
||||
Crashlytics.logException(e);
|
||||
FabricPrivacy.logException(e);
|
||||
log.debug("Runtime Exception", e);
|
||||
}
|
||||
|
||||
|
@ -368,7 +383,9 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
menu.add(MainApp.sResources.getString(R.string.suspendloopfor2h));
|
||||
menu.add(MainApp.sResources.getString(R.string.suspendloopfor3h));
|
||||
menu.add(MainApp.sResources.getString(R.string.suspendloopfor10h));
|
||||
if (pumpDescription.tempDurationStep <= 30)
|
||||
if (pumpDescription.tempDurationStep15mAllowed)
|
||||
menu.add(MainApp.sResources.getString(R.string.disconnectpumpfor15m));
|
||||
if (pumpDescription.tempDurationStep30mAllowed)
|
||||
menu.add(MainApp.sResources.getString(R.string.disconnectpumpfor30m));
|
||||
menu.add(MainApp.sResources.getString(R.string.disconnectpumpfor1h));
|
||||
menu.add(MainApp.sResources.getString(R.string.disconnectpumpfor2h));
|
||||
|
@ -423,7 +440,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
activeloop.setFragmentVisible(PluginBase.LOOP, false);
|
||||
MainApp.getConfigBuilder().storeSettings();
|
||||
updateGUI("suspendmenu");
|
||||
ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, new Callback() {
|
||||
MainApp.getConfigBuilder().getCommandQueue().cancelTempBasal(true, new Callback() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!result.success) {
|
||||
|
@ -431,7 +448,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
}
|
||||
}
|
||||
});
|
||||
NSUpload.uploadOpenAPSOffline(60); // upload 60 min, we don;t know real duration
|
||||
NSUpload.uploadOpenAPSOffline(24 * 60); // upload 24h, we don't know real duration
|
||||
return true;
|
||||
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.enableloop))) {
|
||||
activeloop.setFragmentEnabled(PluginBase.LOOP, true);
|
||||
|
@ -443,7 +460,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.resume))) {
|
||||
activeloop.suspendTo(0L);
|
||||
updateGUI("suspendmenu");
|
||||
ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, new Callback() {
|
||||
MainApp.getConfigBuilder().getCommandQueue().cancelTempBasal(true, new Callback() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!result.success) {
|
||||
|
@ -454,148 +471,40 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
NSUpload.uploadOpenAPSOffline(0);
|
||||
return true;
|
||||
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.suspendloopfor1h))) {
|
||||
activeloop.suspendTo(System.currentTimeMillis() + 60L * 60 * 1000);
|
||||
MainApp.getConfigBuilder().suspendLoop(60);
|
||||
updateGUI("suspendmenu");
|
||||
ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, new Callback() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!result.success) {
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror));
|
||||
}
|
||||
}
|
||||
});
|
||||
NSUpload.uploadOpenAPSOffline(60);
|
||||
return true;
|
||||
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.suspendloopfor2h))) {
|
||||
activeloop.suspendTo(System.currentTimeMillis() + 2 * 60L * 60 * 1000);
|
||||
MainApp.getConfigBuilder().suspendLoop(120);
|
||||
updateGUI("suspendmenu");
|
||||
ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, new Callback() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!result.success) {
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror));
|
||||
}
|
||||
}
|
||||
});
|
||||
NSUpload.uploadOpenAPSOffline(120);
|
||||
return true;
|
||||
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.suspendloopfor3h))) {
|
||||
activeloop.suspendTo(System.currentTimeMillis() + 3 * 60L * 60 * 1000);
|
||||
MainApp.getConfigBuilder().suspendLoop(180);
|
||||
updateGUI("suspendmenu");
|
||||
ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, new Callback() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!result.success) {
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror));
|
||||
}
|
||||
}
|
||||
});
|
||||
NSUpload.uploadOpenAPSOffline(180);
|
||||
return true;
|
||||
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.suspendloopfor10h))) {
|
||||
activeloop.suspendTo(System.currentTimeMillis() + 10 * 60L * 60 * 1000);
|
||||
MainApp.getConfigBuilder().suspendLoop(600);
|
||||
updateGUI("suspendmenu");
|
||||
return true;
|
||||
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor15m))) {
|
||||
MainApp.getConfigBuilder().disconnectPump(15);
|
||||
updateGUI("suspendmenu");
|
||||
ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, new Callback() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!result.success) {
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror));
|
||||
}
|
||||
}
|
||||
});
|
||||
NSUpload.uploadOpenAPSOffline(600);
|
||||
return true;
|
||||
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor30m))) {
|
||||
activeloop.disconnectTo(System.currentTimeMillis() + 30L * 60 * 1000);
|
||||
MainApp.getConfigBuilder().disconnectPump(30);
|
||||
updateGUI("suspendmenu");
|
||||
ConfigBuilderPlugin.getCommandQueue().tempBasalPercent(0, 30, true, new Callback() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!result.success) {
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror));
|
||||
}
|
||||
}
|
||||
});
|
||||
if (MainApp.getConfigBuilder().getActivePump().getPumpDescription().isExtendedBolusCapable && MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) {
|
||||
ConfigBuilderPlugin.getCommandQueue().cancelExtended( new Callback() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!result.success) {
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.extendedbolusdeliveryerror));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
NSUpload.uploadOpenAPSOffline(30);
|
||||
return true;
|
||||
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor1h))) {
|
||||
activeloop.disconnectTo(System.currentTimeMillis() + 1 * 60L * 60 * 1000);
|
||||
MainApp.getConfigBuilder().disconnectPump(60);
|
||||
updateGUI("suspendmenu");
|
||||
ConfigBuilderPlugin.getCommandQueue().tempBasalPercent(0, 60, true, new Callback() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!result.success) {
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror));
|
||||
}
|
||||
}
|
||||
});
|
||||
if (MainApp.getConfigBuilder().getActivePump().getPumpDescription().isExtendedBolusCapable && MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) {
|
||||
ConfigBuilderPlugin.getCommandQueue().cancelExtended( new Callback() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!result.success) {
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.extendedbolusdeliveryerror));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
NSUpload.uploadOpenAPSOffline(60);
|
||||
return true;
|
||||
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor2h))) {
|
||||
activeloop.disconnectTo(System.currentTimeMillis() + 2 * 60L * 60 * 1000);
|
||||
MainApp.getConfigBuilder().disconnectPump(120);
|
||||
updateGUI("suspendmenu");
|
||||
ConfigBuilderPlugin.getCommandQueue().tempBasalPercent(0, 2 * 60, true, new Callback() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!result.success) {
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror));
|
||||
}
|
||||
}
|
||||
});
|
||||
if (MainApp.getConfigBuilder().getActivePump().getPumpDescription().isExtendedBolusCapable && MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) {
|
||||
ConfigBuilderPlugin.getCommandQueue().cancelExtended( new Callback() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!result.success) {
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.extendedbolusdeliveryerror));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
NSUpload.uploadOpenAPSOffline(120);
|
||||
return true;
|
||||
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor3h))) {
|
||||
activeloop.disconnectTo(System.currentTimeMillis() + 3 * 60L * 60 * 1000);
|
||||
MainApp.getConfigBuilder().disconnectPump(180);
|
||||
updateGUI("suspendmenu");
|
||||
ConfigBuilderPlugin.getCommandQueue().tempBasalPercent(0, 3 * 60, true, new Callback() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!result.success) {
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror));
|
||||
}
|
||||
}
|
||||
});
|
||||
if (MainApp.getConfigBuilder().getActivePump().getPumpDescription().isExtendedBolusCapable && MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) {
|
||||
ConfigBuilderPlugin.getCommandQueue().cancelExtended( new Callback() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!result.success) {
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.extendedbolusdeliveryerror));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
NSUpload.uploadOpenAPSOffline(180);
|
||||
return true;
|
||||
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.careportal_profileswitch))) {
|
||||
NewNSTreatmentDialog newDialog = new NewNSTreatmentDialog();
|
||||
|
@ -614,6 +523,10 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
boolean xdrip = MainApp.getSpecificPlugin(SourceXdripPlugin.class) != null && MainApp.getSpecificPlugin(SourceXdripPlugin.class).isEnabled(PluginBase.BGSOURCE);
|
||||
boolean g5 = MainApp.getSpecificPlugin(SourceDexcomG5Plugin.class) != null && MainApp.getSpecificPlugin(SourceDexcomG5Plugin.class).isEnabled(PluginBase.BGSOURCE);
|
||||
String units = MainApp.getConfigBuilder().getProfileUnits();
|
||||
|
||||
FragmentManager manager = getFragmentManager();
|
||||
switch (v.getId()) {
|
||||
case R.id.overview_accepttempbutton:
|
||||
|
@ -627,13 +540,36 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
wizardDialog.show(manager, "WizardDialog");
|
||||
break;
|
||||
case R.id.overview_calibrationbutton:
|
||||
CalibrationDialog calibrationDialog = new CalibrationDialog();
|
||||
calibrationDialog.show(manager, "CalibrationDialog");
|
||||
if (xdrip) {
|
||||
CalibrationDialog calibrationDialog = new CalibrationDialog();
|
||||
calibrationDialog.show(manager, "CalibrationDialog");
|
||||
} else if (g5) {
|
||||
try {
|
||||
Intent i = new Intent("com.dexcom.cgm.activities.MeterEntryActivity");
|
||||
startActivity(i);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
ToastUtils.showToastInUiThread(getActivity(), MainApp.gs(R.string.g5appnotdetected));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case R.id.overview_cgmbutton:
|
||||
if (xdrip)
|
||||
openCgmApp("com.eveningoutpost.dexdrip");
|
||||
else if (g5 && units.equals(Constants.MGDL))
|
||||
openCgmApp("com.dexcom.cgm.region5.mgdl");
|
||||
else if (g5 && units.equals(Constants.MMOL))
|
||||
openCgmApp("com.dexcom.cgm.region5.mmol");
|
||||
break;
|
||||
case R.id.overview_treatmentbutton:
|
||||
NewTreatmentDialog treatmentDialogFragment = new NewTreatmentDialog();
|
||||
treatmentDialogFragment.show(manager, "TreatmentDialog");
|
||||
break;
|
||||
case R.id.overview_insulinbutton:
|
||||
new NewInsulinDialog().show(manager, "InsulinDialog");
|
||||
break;
|
||||
case R.id.overview_carbsbutton:
|
||||
new NewCarbsDialog().show(manager, "CarbsDialog");
|
||||
break;
|
||||
case R.id.overview_pumpstatus:
|
||||
if (ConfigBuilderPlugin.getActivePump().isSuspended() || !ConfigBuilderPlugin.getActivePump().isInitialized())
|
||||
ConfigBuilderPlugin.getCommandQueue().readStatus("RefreshClicked", null);
|
||||
|
@ -660,6 +596,25 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
|
||||
}
|
||||
|
||||
public boolean openCgmApp(String packageName) {
|
||||
PackageManager packageManager = getContext().getPackageManager();
|
||||
try {
|
||||
Intent intent = packageManager.getLaunchIntentForPackage(packageName);
|
||||
if (intent == null) {
|
||||
throw new ActivityNotFoundException();
|
||||
}
|
||||
intent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||
getContext().startActivity(intent);
|
||||
return true;
|
||||
} catch (ActivityNotFoundException e) {
|
||||
new AlertDialog.Builder(getContext())
|
||||
.setMessage(R.string.error_starting_cgm)
|
||||
.setPositiveButton("OK", null)
|
||||
.show();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLongClick(View v) {
|
||||
switch (v.getId()) {
|
||||
|
@ -675,7 +630,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
if (ConfigBuilderPlugin.getActiveLoop() != null) {
|
||||
ConfigBuilderPlugin.getActiveLoop().invoke("Accept temp button", false);
|
||||
final LoopPlugin.LastRun finalLastRun = LoopPlugin.lastRun;
|
||||
if (finalLastRun != null && finalLastRun.lastAPSRun != null && finalLastRun.constraintsProcessed.changeRequested) {
|
||||
if (finalLastRun != null && finalLastRun.lastAPSRun != null && finalLastRun.constraintsProcessed.isChangeRequested()) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
|
||||
builder.setTitle(getContext().getString(R.string.confirmation));
|
||||
builder.setMessage(getContext().getString(R.string.setbasalquestion) + "\n" + finalLastRun.constraintsProcessed);
|
||||
|
@ -700,7 +655,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
scheduleUpdateGUI("onClickAcceptTemp");
|
||||
}
|
||||
});
|
||||
Answers.getInstance().logCustom(new CustomEvent("AcceptTemp"));
|
||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("AcceptTemp"));
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton(getContext().getString(R.string.cancel), null);
|
||||
|
@ -816,7 +771,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
}
|
||||
}
|
||||
});
|
||||
Answers.getInstance().logCustom(new CustomEvent("QuickWizard"));
|
||||
FabricPrivacy.getInstance().logCustom(new CustomEvent("QuickWizard"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1017,16 +972,8 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
return;
|
||||
}
|
||||
|
||||
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 double lowLine = OverviewPlugin.getPlugin().determineLowLine(units);
|
||||
final double highLine = OverviewPlugin.getPlugin().determineHighLine(units);
|
||||
|
||||
//Start with updating the BG as it is unaffected by loop.
|
||||
// **** BG value ****
|
||||
|
@ -1106,7 +1053,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
boolean showAcceptButton = !MainApp.getConfigBuilder().isClosedModeEnabled(); // Open mode needed
|
||||
showAcceptButton = showAcceptButton && finalLastRun != null && finalLastRun.lastAPSRun != null; // aps result must exist
|
||||
showAcceptButton = showAcceptButton && (finalLastRun.lastOpenModeAccept == null || finalLastRun.lastOpenModeAccept.getTime() < finalLastRun.lastAPSRun.getTime()); // never accepted or before last result
|
||||
showAcceptButton = showAcceptButton && finalLastRun.constraintsProcessed.changeRequested; // change is requested
|
||||
showAcceptButton = showAcceptButton && finalLastRun.constraintsProcessed.isChangeRequested(); // change is requested
|
||||
|
||||
if (showAcceptButton && pump.isInitialized() && !pump.isSuspended() && ConfigBuilderPlugin.getActiveLoop() != null) {
|
||||
acceptTempLayout.setVisibility(View.VISIBLE);
|
||||
|
@ -1116,14 +1063,26 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
}
|
||||
}
|
||||
|
||||
// **** Calibration button ****
|
||||
// **** Calibration & CGM buttons ****
|
||||
boolean xDripIsBgSource = MainApp.getSpecificPlugin(SourceXdripPlugin.class) != null && MainApp.getSpecificPlugin(SourceXdripPlugin.class).isEnabled(PluginBase.BGSOURCE);
|
||||
boolean g5IsBgSource = MainApp.getSpecificPlugin(SourceDexcomG5Plugin.class) != null && MainApp.getSpecificPlugin(SourceDexcomG5Plugin.class).isEnabled(PluginBase.BGSOURCE);
|
||||
boolean bgAvailable = DatabaseHelper.actualBg() != null;
|
||||
if (calibrationButton != null) {
|
||||
if (MainApp.getSpecificPlugin(SourceXdripPlugin.class) != null && MainApp.getSpecificPlugin(SourceXdripPlugin.class).isEnabled(PluginBase.BGSOURCE) && profile != null && DatabaseHelper.actualBg() != null) {
|
||||
if ((xDripIsBgSource || g5IsBgSource) && bgAvailable && SP.getBoolean(R.string.key_show_calibration_button, true)) {
|
||||
calibrationButton.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
calibrationButton.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
if (cgmButton != null) {
|
||||
if (xDripIsBgSource && SP.getBoolean(R.string.key_show_cgm_button, false)) {
|
||||
cgmButton.setVisibility(View.VISIBLE);
|
||||
} else if (g5IsBgSource && SP.getBoolean(R.string.key_show_cgm_button, false)) {
|
||||
cgmButton.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
cgmButton.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
final TemporaryBasal activeTemp = MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis());
|
||||
String basalText = "";
|
||||
|
@ -1220,15 +1179,40 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
} else
|
||||
quickWizardButton.setVisibility(View.GONE);
|
||||
|
||||
// Bolus and calc button
|
||||
if (pump.isInitialized() && !pump.isSuspended()) {
|
||||
wizardButton.setVisibility(View.VISIBLE);
|
||||
treatmentButton.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
wizardButton.setVisibility(View.GONE);
|
||||
treatmentButton.setVisibility(View.GONE);
|
||||
// **** Various treatment buttons ****
|
||||
if (carbsButton != null) {
|
||||
if (SP.getBoolean(R.string.key_show_carbs_button, true)
|
||||
&& !ConfigBuilderPlugin.getActivePump().getPumpDescription().storesCarbInfo ||
|
||||
(pump.isInitialized() && !pump.isSuspended())) {
|
||||
carbsButton.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
carbsButton.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
if (pump.isInitialized() && !pump.isSuspended()) {
|
||||
if (treatmentButton != null) {
|
||||
if (SP.getBoolean(R.string.key_show_treatment_button, false)) {
|
||||
treatmentButton.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
treatmentButton.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
if (wizardButton != null) {
|
||||
if (SP.getBoolean(R.string.key_show_wizard_button, true)) {
|
||||
wizardButton.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
wizardButton.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
if (insulinButton != null) {
|
||||
if (SP.getBoolean(R.string.key_show_insulin_button, true)) {
|
||||
insulinButton.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
insulinButton.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// **** BG value ****
|
||||
if (lastBG == null) { //left this here as it seems you want to exit at this point if it is null...
|
||||
|
@ -1276,14 +1260,14 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
// cob
|
||||
if (cobView != null) { // view must not exists
|
||||
String cobText = "";
|
||||
AutosensData autosensData = IobCobCalculatorPlugin.getLastAutosensData("Overview COB");
|
||||
AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getLastAutosensData("Overview COB");
|
||||
if (autosensData != null)
|
||||
cobText = (int) autosensData.cob + " g";
|
||||
cobView.setText(cobText);
|
||||
}
|
||||
|
||||
final boolean showPrediction = showPredictionCheckbox.isChecked() && finalLastRun != null && finalLastRun.constraintsProcessed.getClass().equals(DetermineBasalResultAMA.class);
|
||||
if (MainApp.getSpecificPlugin(OpenAPSAMAPlugin.class) != null && MainApp.getSpecificPlugin(OpenAPSAMAPlugin.class).isEnabled(PluginBase.APS)) {
|
||||
final boolean predictionsAvailable = finalLastRun != null && finalLastRun.request.hasPredictions;
|
||||
if (predictionsAvailable) {
|
||||
showPredictionCheckbox.setVisibility(View.VISIBLE);
|
||||
showPredictionLabel.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
|
@ -1341,8 +1325,8 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
final long toTime;
|
||||
final long fromTime;
|
||||
final long endTime;
|
||||
if (showPrediction) {
|
||||
int predHours = (int) (Math.ceil(((DetermineBasalResultAMA) finalLastRun.constraintsProcessed).getLatestPredictionsTime() - System.currentTimeMillis()) / (60 * 60 * 1000));
|
||||
if (predictionsAvailable && showPredictionCheckbox.isChecked()) {
|
||||
int predHours = (int) (Math.ceil(finalLastRun.constraintsProcessed.getLatestPredictionsTime() - System.currentTimeMillis()) / (60 * 60 * 1000));
|
||||
predHours = Math.min(2, predHours);
|
||||
predHours = Math.max(0, predHours);
|
||||
hoursToFetch = rangeToDisplay - predHours;
|
||||
|
@ -1362,14 +1346,14 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
// ------------------ 1st graph
|
||||
Profiler.log(log, from + " - 1st graph - START", updateGUIStart);
|
||||
|
||||
final GraphData graphData = new GraphData(bgGraph);
|
||||
final GraphData graphData = new GraphData(bgGraph, IobCobCalculatorPlugin.getPlugin());
|
||||
|
||||
// **** In range Area ****
|
||||
graphData.addInRangeArea(fromTime, endTime, lowLine, highLine);
|
||||
|
||||
// **** BG ****
|
||||
if (showPrediction)
|
||||
graphData.addBgReadings(fromTime, toTime, lowLine, highLine, (DetermineBasalResultAMA) finalLastRun.constraintsProcessed);
|
||||
if (predictionsAvailable && showPredictionCheckbox.isChecked())
|
||||
graphData.addBgReadings(fromTime, toTime, lowLine, highLine, finalLastRun.constraintsProcessed);
|
||||
else
|
||||
graphData.addBgReadings(fromTime, toTime, lowLine, highLine, null);
|
||||
|
||||
|
@ -1384,18 +1368,22 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
graphData.addBasals(fromTime, now, lowLine / graphData.maxY / 1.2d);
|
||||
}
|
||||
|
||||
// add target line
|
||||
graphData.addTargetLine(fromTime, toTime);
|
||||
|
||||
// **** NOW line ****
|
||||
graphData.addNowLine(now);
|
||||
|
||||
// ------------------ 2nd graph
|
||||
Profiler.log(log, from + " - 2nd graph - START", updateGUIStart);
|
||||
|
||||
final GraphData secondGraphData = new GraphData(iobGraph);
|
||||
final GraphData secondGraphData = new GraphData(iobGraph, IobCobCalculatorPlugin.getPlugin());
|
||||
|
||||
boolean useIobForScale = false;
|
||||
boolean useCobForScale = false;
|
||||
boolean useDevForScale = false;
|
||||
boolean useRatioForScale = false;
|
||||
boolean useDSForScale = false;
|
||||
|
||||
if (showIobCheckbox.isChecked()) {
|
||||
useIobForScale = true;
|
||||
|
@ -1405,6 +1393,8 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
useDevForScale = true;
|
||||
} else if (showRatiosCheckbox.isChecked()) {
|
||||
useRatioForScale = true;
|
||||
} else if (Config.displayDeviationSlope) {
|
||||
useDSForScale = true;
|
||||
}
|
||||
|
||||
if (showIobCheckbox.isChecked())
|
||||
|
@ -1415,6 +1405,8 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
secondGraphData.addDeviations(fromTime, now, useDevForScale, 1d);
|
||||
if (showRatiosCheckbox.isChecked())
|
||||
secondGraphData.addRatio(fromTime, now, useRatioForScale, 1d);
|
||||
if (Config.displayDeviationSlope)
|
||||
secondGraphData.addDeviationSlope(fromTime, now, useDSForScale, 1d);
|
||||
|
||||
// **** NOW line ****
|
||||
// set manual x bounds to have nice steps
|
||||
|
@ -1427,7 +1419,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
activity.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (showIobCheckbox.isChecked() || showCobCheckbox.isChecked() || showDeviationsCheckbox.isChecked() || showRatiosCheckbox.isChecked()) {
|
||||
if (showIobCheckbox.isChecked() || showCobCheckbox.isChecked() || showDeviationsCheckbox.isChecked() || showRatiosCheckbox.isChecked() || Config.displayDeviationSlope) {
|
||||
iobGraph.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
iobGraph.setVisibility(View.GONE);
|
||||
|
|
|
@ -9,6 +9,7 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.data.QuickWizard;
|
||||
import info.nightscout.androidaps.events.EventRefreshOverview;
|
||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
|
@ -26,7 +27,6 @@ public class OverviewPlugin implements PluginBase {
|
|||
private static OverviewPlugin overviewPlugin = new OverviewPlugin();
|
||||
|
||||
public static OverviewPlugin getPlugin() {
|
||||
|
||||
if (overviewPlugin == null)
|
||||
overviewPlugin = new OverviewPlugin();
|
||||
return overviewPlugin;
|
||||
|
@ -92,7 +92,7 @@ public class OverviewPlugin implements PluginBase {
|
|||
|
||||
@Override
|
||||
public boolean showInList(int type) {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -107,7 +107,7 @@ public class OverviewPlugin implements PluginBase {
|
|||
|
||||
@Override
|
||||
public int getPreferencesId() {
|
||||
return -1;
|
||||
return R.xml.pref_overview;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -128,4 +128,34 @@ public class OverviewPlugin implements PluginBase {
|
|||
MainApp.bus().post(new EventRefreshOverview("EventDismissNotification"));
|
||||
}
|
||||
|
||||
public double determineHighLine() {
|
||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||
if (profile == null) {
|
||||
return bgTargetHigh;
|
||||
}
|
||||
return determineHighLine(profile.getUnits());
|
||||
}
|
||||
|
||||
public double determineHighLine(String units) {
|
||||
double highLineSetting = SP.getDouble("high_mark", Profile.fromMgdlToUnits(OverviewPlugin.bgTargetHigh, units));
|
||||
if (highLineSetting < 1)
|
||||
highLineSetting = Profile.fromMgdlToUnits(180d, units);
|
||||
return highLineSetting;
|
||||
}
|
||||
|
||||
public double determineLowLine() {
|
||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||
if (profile == null) {
|
||||
return bgTargetLow;
|
||||
}
|
||||
return determineLowLine(profile.getUnits());
|
||||
}
|
||||
|
||||
public double determineLowLine(String units) {
|
||||
double lowLineSetting = SP.getDouble("low_mark", Profile.fromMgdlToUnits(OverviewPlugin.bgTargetLow, units));
|
||||
if (lowLineSetting < 1)
|
||||
lowLineSetting = Profile.fromMgdlToUnits(76d, units);
|
||||
return lowLineSetting;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package info.nightscout.androidaps.plugins.Overview.events;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.data.PumpEnactResult;
|
||||
import info.nightscout.androidaps.db.Treatment;
|
||||
import info.nightscout.androidaps.events.Event;
|
||||
|
||||
|
@ -11,11 +12,16 @@ public class EventOverviewBolusProgress extends Event {
|
|||
public String status = "";
|
||||
public Treatment t = null;
|
||||
public int percent = 0;
|
||||
public int bolusId;
|
||||
private static EventOverviewBolusProgress eventOverviewBolusProgress = null;
|
||||
|
||||
public EventOverviewBolusProgress() {
|
||||
}
|
||||
|
||||
public boolean isSMB(){
|
||||
return (t != null) && t.isSMB;
|
||||
}
|
||||
|
||||
public static EventOverviewBolusProgress getInstance() {
|
||||
if(eventOverviewBolusProgress == null) {
|
||||
eventOverviewBolusProgress = new EventOverviewBolusProgress();
|
||||
|
|
|
@ -12,7 +12,6 @@ import com.jjoe64.graphview.series.LineGraphSeries;
|
|||
import com.jjoe64.graphview.series.Series;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import info.nightscout.androidaps.Constants;
|
||||
|
@ -23,12 +22,14 @@ import info.nightscout.androidaps.db.BgReading;
|
|||
import info.nightscout.androidaps.db.CareportalEvent;
|
||||
import info.nightscout.androidaps.db.ExtendedBolus;
|
||||
import info.nightscout.androidaps.db.ProfileSwitch;
|
||||
import info.nightscout.androidaps.db.TempTarget;
|
||||
import info.nightscout.androidaps.db.Treatment;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensData;
|
||||
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
|
||||
import info.nightscout.androidaps.plugins.IobCobCalculator.BasalData;
|
||||
import info.nightscout.androidaps.plugins.OpenAPSAMA.DetermineBasalResultAMA;
|
||||
import info.nightscout.androidaps.plugins.Loop.APSResult;
|
||||
import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
|
||||
import info.nightscout.androidaps.plugins.Overview.graphExtensions.AreaGraphSeries;
|
||||
import info.nightscout.androidaps.plugins.Overview.graphExtensions.DataPointWithLabelInterface;
|
||||
import info.nightscout.androidaps.plugins.Overview.graphExtensions.DoubleDataPoint;
|
||||
|
@ -37,6 +38,7 @@ import info.nightscout.androidaps.plugins.Overview.graphExtensions.PointsWithLab
|
|||
import info.nightscout.androidaps.plugins.Overview.graphExtensions.Scale;
|
||||
import info.nightscout.androidaps.plugins.Overview.graphExtensions.ScaledDataPoint;
|
||||
import info.nightscout.androidaps.plugins.Overview.graphExtensions.TimeAsXAxisLabelFormatter;
|
||||
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||
import info.nightscout.utils.Round;
|
||||
|
||||
/**
|
||||
|
@ -51,12 +53,15 @@ public class GraphData {
|
|||
private String units;
|
||||
private List<Series> series = new ArrayList<>();
|
||||
|
||||
public GraphData(GraphView graph) {
|
||||
private IobCobCalculatorPlugin iobCobCalculatorPlugin;
|
||||
|
||||
public GraphData(GraphView graph, IobCobCalculatorPlugin iobCobCalculatorPlugin) {
|
||||
units = MainApp.getConfigBuilder().getProfileUnits();
|
||||
this.graph = graph;
|
||||
this.iobCobCalculatorPlugin = iobCobCalculatorPlugin;
|
||||
}
|
||||
|
||||
public void addBgReadings(long fromTime, long toTime, double lowLine, double highLine, DetermineBasalResultAMA amaResult) {
|
||||
public void addBgReadings(long fromTime, long toTime, double lowLine, double highLine, APSResult apsResult) {
|
||||
double maxBgValue = 0d;
|
||||
bgReadingsArray = MainApp.getDbHelper().getBgreadingsDataFromTime(fromTime, true);
|
||||
List<DataPointWithLabelInterface> bgListArray = new ArrayList<>();
|
||||
|
@ -65,14 +70,12 @@ public class GraphData {
|
|||
return;
|
||||
}
|
||||
|
||||
Iterator<BgReading> it = bgReadingsArray.iterator();
|
||||
while (it.hasNext()) {
|
||||
BgReading bg = it.next();
|
||||
for (BgReading bg : bgReadingsArray) {
|
||||
if (bg.value > maxBgValue) maxBgValue = bg.value;
|
||||
bgListArray.add(bg);
|
||||
}
|
||||
if (amaResult != null) {
|
||||
List<BgReading> predArray = amaResult.getPredictions();
|
||||
if (apsResult != null) {
|
||||
List<BgReading> predArray = apsResult.getPredictions();
|
||||
bgListArray.addAll(predArray);
|
||||
}
|
||||
|
||||
|
@ -125,11 +128,11 @@ public class GraphData {
|
|||
List<ScaledDataPoint> basalLineArray = new ArrayList<>();
|
||||
List<ScaledDataPoint> absoluteBasalLineArray = new ArrayList<>();
|
||||
double lastLineBasal = 0;
|
||||
double lastAbsoluteLineBasal = 0;
|
||||
double lastAbsoluteLineBasal = -1;
|
||||
double lastBaseBasal = 0;
|
||||
double lastTempBasal = 0;
|
||||
for (long time = fromTime; time < toTime; time += 60 * 1000L) {
|
||||
BasalData basalData = IobCobCalculatorPlugin.getBasalData(time);
|
||||
BasalData basalData = IobCobCalculatorPlugin.getPlugin().getBasalData(time);
|
||||
double baseBasalValue = basalData.basal;
|
||||
double absoluteLineValue = baseBasalValue;
|
||||
double tempBasalValue = 0;
|
||||
|
@ -218,6 +221,54 @@ public class GraphData {
|
|||
addSeries(absoluteBasalsLineSeries);
|
||||
}
|
||||
|
||||
public void addTargetLine(long fromTime, long toTime) {
|
||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||
if (profile == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
LineGraphSeries<DataPoint> targetsSeries;
|
||||
|
||||
Scale targetsScale = new Scale();
|
||||
targetsScale.setMultiplier(1);
|
||||
|
||||
List<DataPoint> targetsSeriesArray = new ArrayList<>();
|
||||
double lastTarget = 0;
|
||||
|
||||
if (LoopPlugin.lastRun != null && LoopPlugin.lastRun.constraintsProcessed != null) {
|
||||
APSResult apsResult = LoopPlugin.lastRun.constraintsProcessed;
|
||||
long latestPredictionsTime = apsResult.getLatestPredictionsTime();
|
||||
if (latestPredictionsTime > toTime) {
|
||||
toTime = latestPredictionsTime;
|
||||
}
|
||||
}
|
||||
|
||||
for (long time = fromTime; time < toTime; time += 60 * 1000L) {
|
||||
TempTarget tt = TreatmentsPlugin.getPlugin().getTempTargetFromHistory(time);
|
||||
double value;
|
||||
if (tt == null) {
|
||||
value = (profile.getTargetLow(time) + profile.getTargetHigh(time)) / 2;
|
||||
} else {
|
||||
value = tt.target();
|
||||
}
|
||||
if (lastTarget > 0 && lastTarget != value) {
|
||||
targetsSeriesArray.add(new DataPoint(time, lastTarget));
|
||||
}
|
||||
lastTarget = value;
|
||||
|
||||
targetsSeriesArray.add(new DataPoint(time, value));
|
||||
}
|
||||
|
||||
DataPoint[] targets = new DataPoint[targetsSeriesArray.size()];
|
||||
targets = targetsSeriesArray.toArray(targets);
|
||||
targetsSeries = new LineGraphSeries<>(targets);
|
||||
targetsSeries.setDrawBackground(false);
|
||||
targetsSeries.setColor(MainApp.sResources.getColor(R.color.tempTargetBackground));
|
||||
targetsSeries.setThickness(2);
|
||||
|
||||
addSeries(targetsSeries);
|
||||
}
|
||||
|
||||
public void addTreatments(long fromTime, long endTime) {
|
||||
List<DataPointWithLabelInterface> filteredTreatments = new ArrayList<>();
|
||||
|
||||
|
@ -267,7 +318,7 @@ public class GraphData {
|
|||
addSeries(new PointsWithLabelGraphSeries<>(treatmentsArray));
|
||||
}
|
||||
|
||||
double getNearestBg(long date) {
|
||||
private double getNearestBg(long date) {
|
||||
double bg = 0;
|
||||
for (int r = bgReadingsArray.size() - 1; r >= 0; r--) {
|
||||
BgReading reading = bgReadingsArray.get(r);
|
||||
|
@ -287,7 +338,7 @@ public class GraphData {
|
|||
Scale iobScale = new Scale();
|
||||
|
||||
for (long time = fromTime; time <= toTime; time += 5 * 60 * 1000L) {
|
||||
double iob = IobCobCalculatorPlugin.calculateFromTreatmentsAndTempsSynchronized(time).iob;
|
||||
double iob = IobCobCalculatorPlugin.getPlugin().calculateFromTreatmentsAndTempsSynchronized(time).iob;
|
||||
if (Math.abs(lastIob - iob) > 0.02) {
|
||||
if (Math.abs(lastIob - iob) > 0.2)
|
||||
iobArray.add(new ScaledDataPoint(time, lastIob, iobScale));
|
||||
|
@ -322,7 +373,7 @@ public class GraphData {
|
|||
Scale cobScale = new Scale();
|
||||
|
||||
for (long time = fromTime; time <= toTime; time += 5 * 60 * 1000L) {
|
||||
AutosensData autosensData = IobCobCalculatorPlugin.getAutosensData(time);
|
||||
AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getAutosensData(time);
|
||||
if (autosensData != null) {
|
||||
int cob = (int) autosensData.cob;
|
||||
if (cob != lastCob) {
|
||||
|
@ -369,7 +420,7 @@ public class GraphData {
|
|||
Scale devScale = new Scale();
|
||||
|
||||
for (long time = fromTime; time <= toTime; time += 5 * 60 * 1000L) {
|
||||
AutosensData autosensData = IobCobCalculatorPlugin.getAutosensData(time);
|
||||
AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getAutosensData(time);
|
||||
if (autosensData != null) {
|
||||
int color = Color.BLACK; // "="
|
||||
if (autosensData.pastSensitivity.equals("C")) color = Color.GRAY;
|
||||
|
@ -401,21 +452,21 @@ public class GraphData {
|
|||
|
||||
// scale in % of vertical size (like 0.3)
|
||||
public void addRatio(long fromTime, long toTime, boolean useForScale, double scale) {
|
||||
LineGraphSeries<DataPoint> ratioSeries;
|
||||
List<DataPoint> ratioArray = new ArrayList<>();
|
||||
LineGraphSeries<ScaledDataPoint> ratioSeries;
|
||||
List<ScaledDataPoint> ratioArray = new ArrayList<>();
|
||||
Double maxRatioValueFound = 0d;
|
||||
Scale ratioScale = new Scale(-1d);
|
||||
|
||||
for (long time = fromTime; time <= toTime; time += 5 * 60 * 1000L) {
|
||||
AutosensData autosensData = IobCobCalculatorPlugin.getAutosensData(time);
|
||||
AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getAutosensData(time);
|
||||
if (autosensData != null) {
|
||||
ratioArray.add(new DataPoint(time, autosensData.autosensRatio));
|
||||
ratioArray.add(new ScaledDataPoint(time, autosensData.autosensRatio, ratioScale));
|
||||
maxRatioValueFound = Math.max(maxRatioValueFound, Math.abs(autosensData.autosensRatio));
|
||||
}
|
||||
}
|
||||
|
||||
// RATIOS
|
||||
DataPoint[] ratioData = new DataPoint[ratioArray.size()];
|
||||
ScaledDataPoint[] ratioData = new ScaledDataPoint[ratioArray.size()];
|
||||
ratioData = ratioArray.toArray(ratioData);
|
||||
ratioSeries = new LineGraphSeries<>(ratioData);
|
||||
ratioSeries.setColor(MainApp.sResources.getColor(R.color.ratio));
|
||||
|
@ -429,6 +480,50 @@ public class GraphData {
|
|||
addSeries(ratioSeries);
|
||||
}
|
||||
|
||||
// scale in % of vertical size (like 0.3)
|
||||
public void addDeviationSlope(long fromTime, long toTime, boolean useForScale, double scale) {
|
||||
LineGraphSeries<ScaledDataPoint> dsMaxSeries;
|
||||
LineGraphSeries<ScaledDataPoint> dsMinSeries;
|
||||
List<ScaledDataPoint> dsMaxArray = new ArrayList<>();
|
||||
List<ScaledDataPoint> dsMinArray = new ArrayList<>();
|
||||
Double maxFromMaxValueFound = 0d;
|
||||
Double maxFromMinValueFound = 0d;
|
||||
Scale dsMaxScale = new Scale();
|
||||
Scale dsMinScale = new Scale();
|
||||
|
||||
for (long time = fromTime; time <= toTime; time += 5 * 60 * 1000L) {
|
||||
AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getAutosensData(time);
|
||||
if (autosensData != null) {
|
||||
dsMaxArray.add(new ScaledDataPoint(time, autosensData.slopeFromMaxDeviation, dsMaxScale));
|
||||
dsMinArray.add(new ScaledDataPoint(time, autosensData.slopeFromMinDeviation, dsMinScale));
|
||||
maxFromMaxValueFound = Math.max(maxFromMaxValueFound, Math.abs(autosensData.slopeFromMaxDeviation));
|
||||
maxFromMinValueFound = Math.max(maxFromMinValueFound, Math.abs(autosensData.slopeFromMinDeviation));
|
||||
}
|
||||
}
|
||||
|
||||
// Slopes
|
||||
ScaledDataPoint[] ratioMaxData = new ScaledDataPoint[dsMaxArray.size()];
|
||||
ratioMaxData = dsMaxArray.toArray(ratioMaxData);
|
||||
dsMaxSeries = new LineGraphSeries<>(ratioMaxData);
|
||||
dsMaxSeries.setColor(Color.MAGENTA);
|
||||
dsMaxSeries.setThickness(3);
|
||||
|
||||
ScaledDataPoint[] ratioMinData = new ScaledDataPoint[dsMinArray.size()];
|
||||
ratioMinData = dsMinArray.toArray(ratioMinData);
|
||||
dsMinSeries = new LineGraphSeries<>(ratioMinData);
|
||||
dsMinSeries.setColor(Color.YELLOW);
|
||||
dsMinSeries.setThickness(3);
|
||||
|
||||
if (useForScale)
|
||||
maxY = Math.max(maxFromMaxValueFound, maxFromMinValueFound);
|
||||
|
||||
dsMaxScale.setMultiplier(maxY * scale / maxFromMaxValueFound);
|
||||
dsMinScale.setMultiplier(maxY * scale / maxFromMinValueFound);
|
||||
|
||||
addSeries(dsMaxSeries);
|
||||
addSeries(dsMinSeries);
|
||||
}
|
||||
|
||||
// scale in % of vertical size (like 0.3)
|
||||
public void addNowLine(long now) {
|
||||
LineGraphSeries<DataPoint> seriesNow;
|
||||
|
|
|
@ -55,4 +55,5 @@ public interface DataPointWithLabelInterface extends DataPointInterface{
|
|||
PointsWithLabelGraphSeries.Shape getShape();
|
||||
float getSize();
|
||||
int getColor();
|
||||
int getSecondColor();
|
||||
}
|
||||
|
|
|
@ -60,17 +60,12 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
|
|||
* You can also render a custom drawing via {@link com.jjoe64.graphview.series.PointsGraphSeries.CustomShape}
|
||||
*/
|
||||
public enum Shape {
|
||||
/**
|
||||
* draws a point / circle
|
||||
*/
|
||||
POINT,
|
||||
|
||||
/**
|
||||
* draws a triangle
|
||||
*/
|
||||
BG,
|
||||
PREDICTION,
|
||||
TRIANGLE,
|
||||
RECTANGLE,
|
||||
BOLUS,
|
||||
SMB,
|
||||
EXTENDEDBOLUS,
|
||||
PROFILE,
|
||||
MBG,
|
||||
|
@ -202,9 +197,19 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
|
|||
|
||||
// draw data point
|
||||
if (!overdraw) {
|
||||
if (value.getShape() == Shape.POINT) {
|
||||
if (value.getShape() == Shape.BG) {
|
||||
mPaint.setStyle(Paint.Style.FILL);
|
||||
mPaint.setStrokeWidth(0);
|
||||
canvas.drawCircle(endX, endY, scaledPxSize, mPaint);
|
||||
} else if (value.getShape() == Shape.PREDICTION) {
|
||||
mPaint.setColor(value.getColor());
|
||||
mPaint.setStyle(Paint.Style.FILL);
|
||||
mPaint.setStrokeWidth(0);
|
||||
canvas.drawCircle(endX, endY, scaledPxSize, mPaint);
|
||||
mPaint.setColor(value.getSecondColor());
|
||||
mPaint.setStyle(Paint.Style.FILL);
|
||||
mPaint.setStrokeWidth(0);
|
||||
canvas.drawCircle(endX, endY, scaledPxSize / 3, mPaint);
|
||||
} else if (value.getShape() == Shape.RECTANGLE) {
|
||||
canvas.drawRect(endX-scaledPxSize, endY-scaledPxSize, endX+scaledPxSize, endY+scaledPxSize, mPaint);
|
||||
} else if (value.getShape() == Shape.TRIANGLE) {
|
||||
|
@ -225,6 +230,14 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
|
|||
if (value.getLabel() != null) {
|
||||
drawLabel45(endX, endY, value, canvas);
|
||||
}
|
||||
} else if (value.getShape() == Shape.SMB) {
|
||||
mPaint.setStrokeWidth(2);
|
||||
Point[] points = new Point[3];
|
||||
points[0] = new Point((int)endX, (int)(endY-value.getSize()));
|
||||
points[1] = new Point((int)(endX+value.getSize()), (int)(endY+value.getSize()*0.67));
|
||||
points[2] = new Point((int)(endX-value.getSize()), (int)(endY+value.getSize()*0.67));
|
||||
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
|
||||
drawArrows(points, canvas, mPaint);
|
||||
} else if (value.getShape() == Shape.EXTENDEDBOLUS) {
|
||||
mPaint.setStrokeWidth(0);
|
||||
if (value.getLabel() != null) {
|
||||
|
|
|
@ -21,8 +21,6 @@ import java.util.List;
|
|||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.Services.AlarmSoundService;
|
||||
import info.nightscout.androidaps.plugins.Wear.WearPlugin;
|
||||
//Added by Rumen for snooze time
|
||||
import info.nightscout.utils.SP;
|
||||
|
||||
/**
|
||||
|
@ -44,16 +42,12 @@ public class NotificationStore {
|
|||
}
|
||||
}
|
||||
|
||||
public Notification get(int index) {
|
||||
return store.get(index);
|
||||
}
|
||||
|
||||
public void add(Notification n) {
|
||||
public synchronized void add(Notification n) {
|
||||
log.info("Notification received: " + n.text);
|
||||
for (int i = 0; i < store.size(); i++) {
|
||||
if (get(i).id == n.id) {
|
||||
get(i).date = n.date;
|
||||
get(i).validTo = n.validTo;
|
||||
for (Notification storeNotification : store) {
|
||||
if (storeNotification.id == n.id) {
|
||||
storeNotification.date = n.date;
|
||||
storeNotification.validTo = n.validTo;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -72,6 +66,44 @@ public class NotificationStore {
|
|||
Collections.sort(store, new NotificationComparator());
|
||||
}
|
||||
|
||||
public synchronized boolean remove(int id) {
|
||||
for (int i = 0; i < store.size(); i++) {
|
||||
if (store.get(i).id == id) {
|
||||
if (store.get(i).soundId != null) {
|
||||
Intent alarm = new Intent(MainApp.instance().getApplicationContext(), AlarmSoundService.class);
|
||||
MainApp.instance().stopService(alarm);
|
||||
}
|
||||
store.remove(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public synchronized void removeExpired() {
|
||||
for (int i = 0; i < store.size(); i++) {
|
||||
Notification n = store.get(i);
|
||||
if (n.validTo.getTime() != 0 && n.validTo.getTime() < System.currentTimeMillis()) {
|
||||
store.remove(i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void snoozeTo(long timeToSnooze) {
|
||||
log.debug("Snoozing alarm until: " + timeToSnooze);
|
||||
SP.putLong("snoozedTo", timeToSnooze);
|
||||
}
|
||||
|
||||
public void unSnooze() {
|
||||
if (Notification.isAlarmForStaleData()) {
|
||||
Notification notification = new Notification(Notification.NSALARM, MainApp.sResources.getString(R.string.nsalarm_staledata), Notification.URGENT);
|
||||
SP.putLong("snoozedTo", System.currentTimeMillis());
|
||||
add(notification);
|
||||
log.debug("Snoozed to current time and added back notification!");
|
||||
}
|
||||
}
|
||||
|
||||
private void raiseSystemNotification(Notification n) {
|
||||
Context context = MainApp.instance().getApplicationContext();
|
||||
NotificationManager mgr = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
|
@ -95,42 +127,4 @@ public class NotificationStore {
|
|||
}
|
||||
mgr.notify(n.id, notificationBuilder.build());
|
||||
}
|
||||
|
||||
public boolean remove(int id) {
|
||||
for (int i = 0; i < store.size(); i++) {
|
||||
if (get(i).id == id) {
|
||||
if (get(i).soundId != null) {
|
||||
Intent alarm = new Intent(MainApp.instance().getApplicationContext(), AlarmSoundService.class);
|
||||
MainApp.instance().stopService(alarm);
|
||||
}
|
||||
store.remove(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void removeExpired() {
|
||||
for (int i = 0; i < store.size(); i++) {
|
||||
Notification n = get(i);
|
||||
if (n.validTo.getTime() != 0 && n.validTo.getTime() < System.currentTimeMillis()) {
|
||||
store.remove(i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void snoozeTo(long timeToSnooze) {
|
||||
log.debug("Snoozing alarm until: " + timeToSnooze);
|
||||
SP.putLong("snoozedTo", timeToSnooze);
|
||||
}
|
||||
|
||||
public void unSnooze() {
|
||||
if (Notification.isAlarmForStaleData()) {
|
||||
Notification notification = new Notification(Notification.NSALARM, MainApp.sResources.getString(R.string.nsalarm_staledata), Notification.URGENT);
|
||||
SP.putLong("snoozedTo", System.currentTimeMillis());
|
||||
add(notification);
|
||||
log.debug("Snoozed to current time and added back notification!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,546 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.ProfileCircadianPercentage;
|
||||
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.text.Editable;
|
||||
import android.text.Html;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.andreabaccega.widget.FormEditText;
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.events.EventInitializationChanged;
|
||||
import info.nightscout.androidaps.events.EventProfileSwitchChange;
|
||||
import info.nightscout.androidaps.plugins.Careportal.CareportalFragment;
|
||||
import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialog;
|
||||
import info.nightscout.androidaps.plugins.Careportal.OptionsToShow;
|
||||
import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.utils.DecimalFormatter;
|
||||
import info.nightscout.utils.SafeParse;
|
||||
|
||||
public class CircadianPercentageProfileFragment extends SubscriberFragment {
|
||||
private static Logger log = LoggerFactory.getLogger(CircadianPercentageProfileFragment.class);
|
||||
|
||||
private static CircadianPercentageProfilePlugin circadianPercentageProfilePlugin = new CircadianPercentageProfilePlugin();
|
||||
private Object snackbarCaller;
|
||||
|
||||
public static CircadianPercentageProfilePlugin getPlugin() {
|
||||
return circadianPercentageProfilePlugin;
|
||||
}
|
||||
|
||||
FormEditText diaView;
|
||||
RadioButton mgdlView;
|
||||
RadioButton mmolView;
|
||||
FormEditText targetlowView;
|
||||
FormEditText targethighView;
|
||||
FormEditText percentageView;
|
||||
FormEditText timeshiftView;
|
||||
TextView profileView;
|
||||
TextView baseprofileIC;
|
||||
TextView baseprofileBasal;
|
||||
LinearLayout baseprofileBasalLayout;
|
||||
TextView baseprofileISF;
|
||||
Button profileswitchButton;
|
||||
ImageView percentageIcon;
|
||||
ImageView timeIcon;
|
||||
ImageView basaleditIcon;
|
||||
ImageView iceditIcon;
|
||||
ImageView isfeditIcon;
|
||||
BasalEditDialog basalEditDialog;
|
||||
FrameLayout fl;
|
||||
Snackbar mSnackBar;
|
||||
|
||||
static Boolean percentageViewHint = true;
|
||||
static Boolean timeshiftViewHint = true;
|
||||
|
||||
TextWatcher textWatch = new TextWatcher() {
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start,
|
||||
int count, int after) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start,
|
||||
int before, int count) {
|
||||
|
||||
if (percentageView.testValidity()) {
|
||||
if (SafeParse.stringToInt(percentageView.getText().toString()) == 0) {
|
||||
circadianPercentageProfilePlugin.percentage = 100;
|
||||
} else {
|
||||
circadianPercentageProfilePlugin.percentage = SafeParse.stringToInt(percentageView.getText().toString());
|
||||
}
|
||||
updateProfileInfo();
|
||||
}
|
||||
if (timeshiftView.testValidity()) {
|
||||
circadianPercentageProfilePlugin.timeshift = SafeParse.stringToInt(timeshiftView.getText().toString());
|
||||
updateProfileInfo();
|
||||
}
|
||||
if (diaView.testValidity()) {
|
||||
circadianPercentageProfilePlugin.dia = SafeParse.stringToDouble(diaView.getText().toString());
|
||||
updateProfileInfo();
|
||||
}
|
||||
if (targethighView.testValidity()) {
|
||||
circadianPercentageProfilePlugin.targetLow = SafeParse.stringToDouble(targetlowView.getText().toString());
|
||||
updateProfileInfo();
|
||||
}
|
||||
if (targetlowView.testValidity()) {
|
||||
circadianPercentageProfilePlugin.targetHigh = SafeParse.stringToDouble(targethighView.getText().toString());
|
||||
updateProfileInfo();
|
||||
}
|
||||
circadianPercentageProfilePlugin.storeSettings();
|
||||
updateProfileInfo();
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
|
||||
showDeprecatedDialog();
|
||||
|
||||
View layout = inflater.inflate(R.layout.circadianpercentageprofile_fragment, container, false);
|
||||
fl = (FrameLayout) layout.findViewById(R.id.circadianpercentageprofile_framelayout);
|
||||
fl.requestFocusFromTouch();
|
||||
diaView = (FormEditText) layout.findViewById(R.id.circadianpercentageprofile_dia);
|
||||
mgdlView = (RadioButton) layout.findViewById(R.id.circadianpercentageprofile_mgdl);
|
||||
mmolView = (RadioButton) layout.findViewById(R.id.circadianpercentageprofile_mmol);
|
||||
targetlowView = (FormEditText) layout.findViewById(R.id.circadianpercentageprofile_targetlow);
|
||||
targethighView = (FormEditText) layout.findViewById(R.id.circadianpercentageprofile_targethigh);
|
||||
percentageView = (FormEditText) layout.findViewById(R.id.circadianpercentageprofile_percentage);
|
||||
timeshiftView = (FormEditText) layout.findViewById(R.id.circadianpercentageprofile_timeshift);
|
||||
profileView = (TextView) layout.findViewById(R.id.circadianpercentageprofile_profileview);
|
||||
baseprofileBasal = (TextView) layout.findViewById(R.id.circadianpercentageprofile_baseprofilebasal);
|
||||
baseprofileBasalLayout = (LinearLayout) layout.findViewById(R.id.circadianpercentageprofile_baseprofilebasal_layout);
|
||||
baseprofileIC = (TextView) layout.findViewById(R.id.circadianpercentageprofile_baseprofileic);
|
||||
baseprofileISF = (TextView) layout.findViewById(R.id.circadianpercentageprofile_baseprofileisf);
|
||||
percentageIcon = (ImageView) layout.findViewById(R.id.circadianpercentageprofile_percentageicon);
|
||||
timeIcon = (ImageView) layout.findViewById(R.id.circadianpercentageprofile_timeicon);
|
||||
profileswitchButton = (Button) layout.findViewById(R.id.circadianpercentageprofile_profileswitch);
|
||||
|
||||
basaleditIcon = (ImageView) layout.findViewById(R.id.circadianpercentageprofile_basaledit);
|
||||
iceditIcon = (ImageView) layout.findViewById(R.id.circadianpercentageprofile_icedit);
|
||||
isfeditIcon = (ImageView) layout.findViewById(R.id.circadianpercentageprofile_isfedit);
|
||||
|
||||
if (!ConfigBuilderPlugin.getActivePump().getPumpDescription().isTempBasalCapable) {
|
||||
layout.findViewById(R.id.circadianpercentageprofile_baseprofilebasal_layout).setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
mgdlView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
circadianPercentageProfilePlugin.mgdl = mgdlView.isChecked();
|
||||
circadianPercentageProfilePlugin.mmol = !circadianPercentageProfilePlugin.mgdl;
|
||||
mmolView.setChecked(circadianPercentageProfilePlugin.mmol);
|
||||
circadianPercentageProfilePlugin.storeSettings();
|
||||
updateProfileInfo();
|
||||
}
|
||||
});
|
||||
mmolView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
circadianPercentageProfilePlugin.mmol = mmolView.isChecked();
|
||||
circadianPercentageProfilePlugin.mgdl = !circadianPercentageProfilePlugin.mmol;
|
||||
mgdlView.setChecked(circadianPercentageProfilePlugin.mgdl);
|
||||
circadianPercentageProfilePlugin.storeSettings();
|
||||
updateProfileInfo();
|
||||
}
|
||||
});
|
||||
|
||||
profileswitchButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
NewNSTreatmentDialog newDialog = new NewNSTreatmentDialog();
|
||||
final OptionsToShow profileswitch = CareportalFragment.PROFILESWITCHDIRECT;
|
||||
profileswitch.executeProfileSwitch = true;
|
||||
newDialog.setOptions(profileswitch, R.string.careportal_profileswitch);
|
||||
newDialog.show(getFragmentManager(), "NewNSTreatmentDialog");
|
||||
}
|
||||
});
|
||||
|
||||
timeIcon.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
timeshiftView.requestFocusFromTouch();
|
||||
timeshiftView.setSelection(timeshiftView.getText().length());
|
||||
((InputMethodManager) getContext()
|
||||
.getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(timeshiftView, InputMethodManager.SHOW_IMPLICIT);
|
||||
}
|
||||
});
|
||||
|
||||
percentageIcon.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
percentageView.requestFocusFromTouch();
|
||||
percentageView.setSelection(percentageView.getText().length());
|
||||
((InputMethodManager) getContext()
|
||||
.getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(percentageView, InputMethodManager.SHOW_IMPLICIT);
|
||||
}
|
||||
});
|
||||
|
||||
basaleditIcon.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
basalEditDialog = new BasalEditDialog();
|
||||
basalEditDialog.setup(getPlugin().basebasal, getString(R.string.edit_base_basal), CircadianPercentageProfileFragment.this);
|
||||
basalEditDialog.show(getFragmentManager(), getString(R.string.edit_base_basal));
|
||||
}
|
||||
});
|
||||
|
||||
isfeditIcon.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
basalEditDialog = new BasalEditDialog();
|
||||
basalEditDialog.setup(getPlugin().baseisf, getString(R.string.edit_base_isf), CircadianPercentageProfileFragment.this);
|
||||
basalEditDialog.show(getFragmentManager(), getString(R.string.edit_base_isf));
|
||||
}
|
||||
});
|
||||
|
||||
iceditIcon.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
basalEditDialog = new BasalEditDialog();
|
||||
basalEditDialog.setup(getPlugin().baseic, getString(R.string.edit_base_ic), CircadianPercentageProfileFragment.this);
|
||||
basalEditDialog.show(getFragmentManager(), getString(R.string.edit_base_ic));
|
||||
}
|
||||
});
|
||||
|
||||
/*timeshiftView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
|
||||
|
||||
@Override
|
||||
public void onFocusChange(View view, boolean hasFocus) {
|
||||
if (!hasFocus) {
|
||||
if(mSnackBar!=null && snackbarCaller == timeshiftView){
|
||||
mSnackBar.dismiss();
|
||||
}
|
||||
timeshiftView.clearFocus();
|
||||
fl.requestFocusFromTouch();
|
||||
}
|
||||
else {
|
||||
if (timeshiftViewHint) {
|
||||
customSnackbar(view, getString(R.string.timeshift_hint), timeshiftView);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
percentageView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
|
||||
|
||||
@Override
|
||||
public void onFocusChange(View view, boolean hasFocus) {
|
||||
if (!hasFocus) {
|
||||
if(mSnackBar!=null && snackbarCaller == percentageView){
|
||||
mSnackBar.dismiss();
|
||||
}
|
||||
percentageView.clearFocus();
|
||||
fl.requestFocusFromTouch();
|
||||
}
|
||||
else {
|
||||
if (percentageViewHint) {
|
||||
customSnackbar(view, getString(R.string.percentagefactor_hint), percentageView);
|
||||
}
|
||||
}
|
||||
}
|
||||
});*/
|
||||
|
||||
diaView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
|
||||
|
||||
@Override
|
||||
public void onFocusChange(View view, boolean hasFocus) {
|
||||
if (!hasFocus) {
|
||||
diaView.clearFocus();
|
||||
fl.requestFocusFromTouch();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
targethighView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
|
||||
|
||||
@Override
|
||||
public void onFocusChange(View view, boolean hasFocus) {
|
||||
if (!hasFocus) {
|
||||
targethighView.clearFocus();
|
||||
fl.requestFocusFromTouch();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
targetlowView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
|
||||
|
||||
@Override
|
||||
public void onFocusChange(View view, boolean hasFocus) {
|
||||
if (!hasFocus) {
|
||||
targetlowView.clearFocus();
|
||||
fl.requestFocusFromTouch();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
diaView.addTextChangedListener(textWatch);
|
||||
targetlowView.addTextChangedListener(textWatch);
|
||||
targethighView.addTextChangedListener(textWatch);
|
||||
percentageView.addTextChangedListener(textWatch);
|
||||
timeshiftView.addTextChangedListener(textWatch);
|
||||
|
||||
updateGUI();
|
||||
|
||||
onStatusEvent(new EventInitializationChanged());
|
||||
|
||||
return layout;
|
||||
}
|
||||
|
||||
private void showDeprecatedDialog() {
|
||||
AlertDialog.Builder adb = new AlertDialog.Builder(getContext());
|
||||
adb.setTitle("DEPRECATED! Please migrate!");
|
||||
adb.setMessage("CircadianPercentageProfile has been deprecated. " +
|
||||
"It is recommended to migrate to LocalProfile.\n\n" +
|
||||
"Good news: You won't lose any functionality! Percentage and Timeshift have been ported to the ProfileSwitch :) \n\n " +
|
||||
"How to migrate:\n" +
|
||||
"1) Press MIGRATE, the system will automatically fill the LocalProfile for you.\n" +
|
||||
"2) Switch to LocalProfile in the ConfigBuilder\n" +
|
||||
"3) CHECK that all settings are correct in the LocalProfile!!!");
|
||||
adb.setIcon(android.R.drawable.ic_dialog_alert);
|
||||
adb.setPositiveButton("MIGRATE", new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
CircadianPercentageProfilePlugin.migrateToLP();
|
||||
}
|
||||
});
|
||||
adb.setNegativeButton("Cancel", null);
|
||||
adb.show();
|
||||
}
|
||||
|
||||
public void updateGUI() {
|
||||
updateProfileInfo();
|
||||
|
||||
diaView.removeTextChangedListener(textWatch);
|
||||
targetlowView.removeTextChangedListener(textWatch);
|
||||
targethighView.removeTextChangedListener(textWatch);
|
||||
percentageView.removeTextChangedListener(textWatch);
|
||||
timeshiftView.removeTextChangedListener(textWatch);
|
||||
|
||||
mgdlView.setChecked(circadianPercentageProfilePlugin.mgdl);
|
||||
mmolView.setChecked(circadianPercentageProfilePlugin.mmol);
|
||||
diaView.setText(circadianPercentageProfilePlugin.dia.toString());
|
||||
targetlowView.setText(circadianPercentageProfilePlugin.targetLow.toString());
|
||||
targethighView.setText(circadianPercentageProfilePlugin.targetHigh.toString());
|
||||
percentageView.setText("" + circadianPercentageProfilePlugin.percentage);
|
||||
timeshiftView.setText("" + circadianPercentageProfilePlugin.timeshift);
|
||||
|
||||
|
||||
diaView.addTextChangedListener(textWatch);
|
||||
targetlowView.addTextChangedListener(textWatch);
|
||||
targethighView.addTextChangedListener(textWatch);
|
||||
percentageView.addTextChangedListener(textWatch);
|
||||
timeshiftView.addTextChangedListener(textWatch);
|
||||
|
||||
}
|
||||
|
||||
private void customSnackbar(View view, final String Msg, Object snackbarCaller) {
|
||||
if (mSnackBar != null) mSnackBar.dismiss();
|
||||
|
||||
this.snackbarCaller = snackbarCaller;
|
||||
if (timeshiftViewHint || percentageViewHint) {
|
||||
//noinspection WrongConstant
|
||||
mSnackBar = Snackbar.make(view, Msg, 7000)
|
||||
.setActionTextColor(ContextCompat.getColor(MainApp.instance(), R.color.notificationInfo))
|
||||
.setAction(getString(R.string.dont_show_again), new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (Msg.equals(getString(R.string.percentagefactor_hint))) {
|
||||
percentageViewHint = false;
|
||||
} else if (Msg.equals(getString(R.string.timeshift_hint))) {
|
||||
timeshiftViewHint = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
view = mSnackBar.getView();
|
||||
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) view.getLayoutParams();
|
||||
params.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
|
||||
view.setLayoutParams(params);
|
||||
view.setBackgroundColor(ContextCompat.getColor(MainApp.instance(), R.color.cardview_dark_background));
|
||||
TextView mainTextView = (TextView) (view).findViewById(android.support.design.R.id.snackbar_text);
|
||||
mainTextView.setTextColor(ContextCompat.getColor(MainApp.instance(), R.color.mdtp_white));
|
||||
mSnackBar.show();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateProfileInfo() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("<h3>");
|
||||
sb.append(getString(R.string.nsprofileview_activeprofile_label));
|
||||
sb.append("</h3>");
|
||||
sb.append("<h4>");
|
||||
sb.append(getString(R.string.nsprofileview_basal_label));
|
||||
sb.append(" ( ∑");
|
||||
sb.append(DecimalFormatter.to2Decimal(circadianPercentageProfilePlugin.percentageBasalSum()));
|
||||
sb.append("U )");
|
||||
sb.append("</h4> " + circadianPercentageProfilePlugin.basalString());
|
||||
sb.append("<h4>");
|
||||
sb.append(getString(R.string.nsprofileview_ic_label));
|
||||
sb.append("</h4> " + circadianPercentageProfilePlugin.icString());
|
||||
sb.append("<h4>");
|
||||
sb.append(getString(R.string.nsprofileview_isf_label));
|
||||
sb.append("</h4> " + circadianPercentageProfilePlugin.isfString());
|
||||
profileView.setText(Html.fromHtml(sb.toString()));
|
||||
|
||||
baseprofileBasal.setText(Html.fromHtml("<h3>" + getString(R.string.base_profile_label) + " ( ∑" + DecimalFormatter.to2Decimal(circadianPercentageProfilePlugin.baseBasalSum()) + "U )</h3>" +
|
||||
"<h4>" + getString(R.string.nsprofileview_basal_label) + "</h4>" + circadianPercentageProfilePlugin.baseBasalString()));
|
||||
baseprofileIC.setText(Html.fromHtml("<h4>" + getString(R.string.nsprofileview_ic_label) + "</h4>" + circadianPercentageProfilePlugin.baseIcString()));
|
||||
baseprofileISF.setText(Html.fromHtml("<h4>" + getString(R.string.nsprofileview_isf_label) + "</h4>" + circadianPercentageProfilePlugin.baseIsfString()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
if (basalEditDialog != null && basalEditDialog.isVisible()) {
|
||||
basalEditDialog.dismiss();
|
||||
}
|
||||
basalEditDialog = null;
|
||||
fl.requestFocusFromTouch();
|
||||
}
|
||||
|
||||
public static class BasalEditDialog extends DialogFragment {
|
||||
|
||||
private double[] values;
|
||||
private String title;
|
||||
private CircadianPercentageProfileFragment fragment;
|
||||
|
||||
public void setup(double[] values, String title, CircadianPercentageProfileFragment fragment) {
|
||||
this.values = values;
|
||||
this.title = title;
|
||||
this.fragment = fragment;
|
||||
}
|
||||
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
getDialog().setTitle(title);
|
||||
View view = inflater.inflate(R.layout.circadianpercentageprofile_editbasal_dialog, container, false);
|
||||
LinearLayout list = (LinearLayout) view.findViewById(R.id.circadianpp_editbasal_listlayout);
|
||||
final EditText[] editTexts = new EditText[24];
|
||||
for (int i = 0; i < 24; i++) {
|
||||
View childview = inflater.inflate(R.layout.circadianpercentageprofile_listelement, container, false);
|
||||
((TextView) childview.findViewById(R.id.basal_time_elem)).setText((i < 10 ? "0" : "") + i + ":00: ");
|
||||
|
||||
ImageView copyprevbutton = (ImageView) childview.findViewById(R.id.basal_copyprev_elem);
|
||||
|
||||
if (i == 0) {
|
||||
copyprevbutton.setVisibility(View.INVISIBLE);
|
||||
} else {
|
||||
final int j = i; //needs to be final to be passed to inner class.
|
||||
copyprevbutton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
editTexts[j].setText(editTexts[j - 1].getText());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
editTexts[i] = ((EditText) childview.findViewById(R.id.basal_edittext_elem));
|
||||
editTexts[i].setText(DecimalFormatter.to2Decimal(values[i]));
|
||||
list.addView(childview);
|
||||
}
|
||||
getDialog().setCancelable(true);
|
||||
|
||||
view.findViewById(R.id.ok_button).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
for (int i = 0; i < 24; i++) {
|
||||
if (editTexts[i].getText().length() != 0) {
|
||||
values[i] = SafeParse.stringToDouble(editTexts[i].getText().toString());
|
||||
}
|
||||
}
|
||||
fragment.updateProfileInfo();
|
||||
getPlugin().storeSettings();
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
|
||||
view.findViewById(R.id.cancel_action).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
|
||||
return view;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
|
||||
if (basalEditDialog != null && basalEditDialog.isVisible()) {
|
||||
basalEditDialog.dismiss();
|
||||
}
|
||||
basalEditDialog = null;
|
||||
|
||||
fl.requestFocusFromTouch();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
onStatusEvent(new EventInitializationChanged());
|
||||
fl.requestFocusFromTouch();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventInitializationChanged e) {
|
||||
Activity activity = getActivity();
|
||||
if (activity != null)
|
||||
activity.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!ConfigBuilderPlugin.getActivePump().isInitialized() || ConfigBuilderPlugin.getActivePump().isSuspended()) {
|
||||
profileswitchButton.setVisibility(View.GONE);
|
||||
} else {
|
||||
profileswitchButton.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventProfileSwitchChange e) {
|
||||
Activity activity = getActivity();
|
||||
if (activity != null)
|
||||
activity.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateGUI();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -1,455 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.ProfileCircadianPercentage;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
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.Profile;
|
||||
import info.nightscout.androidaps.data.ProfileStore;
|
||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
import info.nightscout.androidaps.interfaces.ProfileInterface;
|
||||
import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialog;
|
||||
import info.nightscout.androidaps.plugins.ProfileLocal.LocalProfilePlugin;
|
||||
import info.nightscout.utils.DecimalFormatter;
|
||||
import info.nightscout.utils.NSUpload;
|
||||
import info.nightscout.utils.SP;
|
||||
import info.nightscout.utils.SafeParse;
|
||||
import info.nightscout.utils.ToastUtils;
|
||||
|
||||
/**
|
||||
* Created by Adrian on 12.11.2016.
|
||||
* Based on SimpleProfile created by mike on 05.08.2016.
|
||||
*/
|
||||
public class CircadianPercentageProfilePlugin implements PluginBase, ProfileInterface {
|
||||
public static final String SETTINGS_PREFIX = "CircadianPercentageProfile";
|
||||
private static Logger log = LoggerFactory.getLogger(CircadianPercentageProfilePlugin.class);
|
||||
|
||||
private boolean fragmentEnabled = false;
|
||||
private boolean fragmentVisible = false;
|
||||
|
||||
private static ProfileStore convertedProfile = null;
|
||||
private static String convertedProfileName = null;
|
||||
|
||||
boolean mgdl;
|
||||
boolean mmol;
|
||||
Double dia;
|
||||
Double targetLow;
|
||||
Double targetHigh;
|
||||
public int percentage;
|
||||
public int timeshift;
|
||||
double[] basebasal = new double[]{1d, 1d, 1d, 1d, 1d, 1d, 1d, 1d, 1d, 1d, 1d, 1d, 1d, 1d, 1d, 1d, 1d, 1d, 1d, 1d, 1d, 1d, 1d, 1d};
|
||||
double[] baseisf = new double[]{35d, 35d, 35d, 35d, 35d, 35d, 35d, 35d, 35d, 35d, 35d, 35d, 35d, 35d, 35d, 35d, 35d, 35d, 35d, 35d, 35d, 35d, 35d, 35d};
|
||||
double[] baseic = new double[]{4d, 4d, 4d, 4d, 4d, 4d, 4d, 4d, 4d, 4d, 4d, 4d, 4d, 4d, 4d, 4d, 4d, 4d, 4d, 4d, 4d, 4d, 4d, 4d};
|
||||
|
||||
public CircadianPercentageProfilePlugin() {
|
||||
loadSettings();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFragmentClass() {
|
||||
return CircadianPercentageProfileFragment.class.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getType() {
|
||||
return PluginBase.PROFILE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return MainApp.instance().getString(R.string.circadian_percentage_profile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNameShort() {
|
||||
String name = MainApp.sResources.getString(R.string.circadian_percentage_profile_shortname);
|
||||
if (!name.trim().isEmpty()) {
|
||||
//only if translation exists
|
||||
return name;
|
||||
}
|
||||
// use long name as fallback
|
||||
return getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled(int type) {
|
||||
return type == PROFILE && fragmentEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVisibleInTabs(int type) {
|
||||
return type == PROFILE && fragmentVisible;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeHidden(int type) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasFragment() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean showInList(int type) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFragmentEnabled(int type, boolean fragmentEnabled) {
|
||||
if (type == PROFILE) this.fragmentEnabled = fragmentEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFragmentVisible(int type, boolean fragmentVisible) {
|
||||
if (type == PROFILE) this.fragmentVisible = fragmentVisible;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPreferencesId() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
void storeSettings() {
|
||||
if (Config.logPrefsChange)
|
||||
log.debug("Storing settings");
|
||||
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext());
|
||||
SharedPreferences.Editor editor = settings.edit();
|
||||
editor.putBoolean(SETTINGS_PREFIX + "mmol", mmol);
|
||||
editor.putBoolean(SETTINGS_PREFIX + "mgdl", mgdl);
|
||||
editor.putString(SETTINGS_PREFIX + "dia", dia.toString());
|
||||
editor.putString(SETTINGS_PREFIX + "targetlow", targetLow.toString());
|
||||
editor.putString(SETTINGS_PREFIX + "targethigh", targetHigh.toString());
|
||||
editor.putString(SETTINGS_PREFIX + "timeshift", timeshift + "");
|
||||
editor.putString(SETTINGS_PREFIX + "percentage", percentage + "");
|
||||
|
||||
|
||||
for (int i = 0; i < 24; i++) {
|
||||
editor.putString(SETTINGS_PREFIX + "basebasal" + i, DecimalFormatter.to2Decimal(basebasal[i]));
|
||||
editor.putString(SETTINGS_PREFIX + "baseisf" + i, DecimalFormatter.to2Decimal(baseisf[i]));
|
||||
editor.putString(SETTINGS_PREFIX + "baseic" + i, DecimalFormatter.to2Decimal(baseic[i]));
|
||||
}
|
||||
editor.commit();
|
||||
createConvertedProfile();
|
||||
}
|
||||
|
||||
void loadSettings() {
|
||||
if (Config.logPrefsChange)
|
||||
log.debug("Loading stored settings");
|
||||
|
||||
mgdl = SP.getBoolean(SETTINGS_PREFIX + "mgdl", true);
|
||||
mmol = SP.getBoolean(SETTINGS_PREFIX + "mmol", false);
|
||||
dia = SP.getDouble(SETTINGS_PREFIX + "dia", Constants.defaultDIA);
|
||||
targetLow = SP.getDouble(SETTINGS_PREFIX + "targetlow", 80d);
|
||||
targetHigh = SP.getDouble(SETTINGS_PREFIX + "targethigh", 120d);
|
||||
percentage = SP.getInt(SETTINGS_PREFIX + "percentage", 100);
|
||||
timeshift = SP.getInt(SETTINGS_PREFIX + "timeshift", 0);
|
||||
|
||||
for (int i = 0; i < 24; i++) {
|
||||
basebasal[i] = SP.getDouble(SETTINGS_PREFIX + "basebasal" + i, basebasal[i]);
|
||||
baseic[i] = SP.getDouble(SETTINGS_PREFIX + "baseic" + i, baseic[i]);
|
||||
baseisf[i] = SP.getDouble(SETTINGS_PREFIX + "baseisf" + i, baseisf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public String externallySetParameters(int timeshift, int percentage) {
|
||||
|
||||
String msg = "";
|
||||
|
||||
if (!fragmentEnabled) {
|
||||
msg += "NO CPP!" + "\n";
|
||||
}
|
||||
|
||||
//check for validity
|
||||
if (percentage < Constants.CPP_MIN_PERCENTAGE || percentage > Constants.CPP_MAX_PERCENTAGE) {
|
||||
msg += String.format(MainApp.sResources.getString(R.string.openapsma_valueoutofrange), "Profile-Percentage") + "\n";
|
||||
}
|
||||
if (timeshift < 0 || timeshift > 23) {
|
||||
msg += String.format(MainApp.sResources.getString(R.string.openapsma_valueoutofrange), "Profile-Timeshift") + "\n";
|
||||
}
|
||||
final Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||
|
||||
if (profile == null || profile.getBasal() == null) {
|
||||
msg += MainApp.sResources.getString(R.string.cpp_notloadedplugins) + "\n";
|
||||
}
|
||||
if (!"".equals(msg)) {
|
||||
msg += MainApp.sResources.getString(R.string.cpp_valuesnotstored);
|
||||
return msg;
|
||||
}
|
||||
|
||||
//store profile
|
||||
this.timeshift = timeshift;
|
||||
this.percentage = percentage;
|
||||
storeSettings();
|
||||
|
||||
|
||||
//send profile to pumpe
|
||||
new NewNSTreatmentDialog(); //init
|
||||
NewNSTreatmentDialog.doProfileSwitch(this.getProfile(), this.getProfileName(), 0, percentage, timeshift);
|
||||
|
||||
//return formatted string
|
||||
/*msg += "%: " + this.percentage + " h: +" + this.timeshift;
|
||||
msg += "\n";
|
||||
msg += "\nBasal:\n" + basalString() + "\n";
|
||||
msg += "\nISF:\n" + isfString() + "\n";
|
||||
msg += "\nIC:\n" + isfString() + "\n";*/
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
public static void migrateToLP() {
|
||||
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext());
|
||||
SharedPreferences.Editor editor = settings.edit();
|
||||
editor.putBoolean("LocalProfile" + "mmol", SP.getBoolean(SETTINGS_PREFIX + "mmol", false));
|
||||
editor.putBoolean("LocalProfile" + "mgdl", SP.getBoolean(SETTINGS_PREFIX + "mgdl", true));
|
||||
editor.putString("LocalProfile" + "dia", "" + SP.getDouble(SETTINGS_PREFIX + "dia", Constants.defaultDIA));
|
||||
editor.putString("LocalProfile" + "ic", getLPic());
|
||||
editor.putString("LocalProfile" + "isf", getLPisf());
|
||||
editor.putString("LocalProfile" + "basal", getLPbasal());
|
||||
try {
|
||||
JSONArray targetLow = new JSONArray().put(new JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", SP.getDouble(SETTINGS_PREFIX + "targetlow", 120d)));
|
||||
JSONArray targetHigh = new JSONArray().put(new JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", SP.getDouble(SETTINGS_PREFIX + "targethigh", 120d)));
|
||||
editor.putString("LocalProfile" + "targetlow", targetLow.toString());
|
||||
editor.putString("LocalProfile" + "targethigh", targetHigh.toString());
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
editor.commit();
|
||||
LocalProfilePlugin lp = MainApp.getSpecificPlugin(LocalProfilePlugin.class);
|
||||
lp.loadSettings();
|
||||
|
||||
/* TODO: remove Settings and switch to LP later on
|
||||
* For now only nag the user every time (s)he opens the CPP fragment and offer to migrate.
|
||||
* Keep settings for now in order to allow the user to check that the migration went well.
|
||||
*/
|
||||
//removeSettings();
|
||||
|
||||
}
|
||||
|
||||
public static String getLPisf() {
|
||||
return getLPConversion("baseisf", 35d);
|
||||
}
|
||||
|
||||
public static String getLPic() {
|
||||
return getLPConversion("baseic", 4);
|
||||
}
|
||||
|
||||
public static String getLPbasal() {
|
||||
return getLPConversion("basebasal", 1);
|
||||
}
|
||||
|
||||
public static String getLPConversion(String type, double defaultValue) {
|
||||
try {
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
double last = -1d;
|
||||
|
||||
for (int i = 0; i < 24; i++) {
|
||||
double value = SP.getDouble(SETTINGS_PREFIX + type + i, defaultValue);
|
||||
String time;
|
||||
DecimalFormat df = new DecimalFormat("00");
|
||||
time = df.format(i) + ":00";
|
||||
if (last != value) {
|
||||
jsonArray.put(new JSONObject().put("time", time).put("timeAsSeconds", i * 60 * 60).put("value", value));
|
||||
}
|
||||
last = value;
|
||||
}
|
||||
return jsonArray.toString();
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return LocalProfilePlugin.DEFAULTARRAY;
|
||||
}
|
||||
|
||||
static void removeSettings() {
|
||||
if (Config.logPrefsChange)
|
||||
log.debug("Removing settings");
|
||||
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext());
|
||||
SharedPreferences.Editor editor = settings.edit();
|
||||
editor.remove(SETTINGS_PREFIX + "mmol");
|
||||
editor.remove(SETTINGS_PREFIX + "mgdl");
|
||||
editor.remove(SETTINGS_PREFIX + "dia");
|
||||
editor.remove(SETTINGS_PREFIX + "targetlow");
|
||||
editor.remove(SETTINGS_PREFIX + "targethigh");
|
||||
editor.remove(SETTINGS_PREFIX + "timeshift");
|
||||
editor.remove(SETTINGS_PREFIX + "percentage");
|
||||
|
||||
|
||||
for (int i = 0; i < 24; i++) {
|
||||
editor.remove(SETTINGS_PREFIX + "basebasal");
|
||||
editor.remove(SETTINGS_PREFIX + "baseisf" + i);
|
||||
editor.remove(SETTINGS_PREFIX + "baseic" + i);
|
||||
}
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
private void createConvertedProfile() {
|
||||
JSONObject json = new JSONObject();
|
||||
JSONObject store = new JSONObject();
|
||||
JSONObject profile = new JSONObject();
|
||||
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.append(DecimalFormatter.to2Decimal(sum(basebasal)));
|
||||
stringBuilder.append("U@");
|
||||
stringBuilder.append(percentage);
|
||||
stringBuilder.append("%>");
|
||||
stringBuilder.append(timeshift);
|
||||
stringBuilder.append("h");
|
||||
String profileName = stringBuilder.toString();
|
||||
|
||||
try {
|
||||
json.put("defaultProfile", profileName);
|
||||
json.put("store", store);
|
||||
profile.put("dia", dia);
|
||||
|
||||
int offset = -(timeshift % 24) + 24;
|
||||
|
||||
JSONArray icArray = new JSONArray();
|
||||
JSONArray isfArray = new JSONArray();
|
||||
JSONArray basalArray = new JSONArray();
|
||||
for (int i = 0; i < 24; i++) {
|
||||
String time;
|
||||
DecimalFormat df = new DecimalFormat("00");
|
||||
time = df.format(i) + ":00";
|
||||
icArray.put(new JSONObject().put("time", time).put("timeAsSeconds", i * 60 * 60).put("value", baseic[(offset + i) % 24] * 100d / percentage));
|
||||
isfArray.put(new JSONObject().put("time", time).put("timeAsSeconds", i * 60 * 60).put("value", baseisf[(offset + i) % 24] * 100d / percentage));
|
||||
basalArray.put(new JSONObject().put("time", time).put("timeAsSeconds", i * 60 * 60).put("value", basebasal[(offset + i) % 24] * percentage / 100d));
|
||||
}
|
||||
profile.put("carbratio", icArray);
|
||||
profile.put("sens", isfArray);
|
||||
profile.put("basal", basalArray);
|
||||
|
||||
|
||||
profile.put("target_low", new JSONArray().put(new JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", targetLow)));
|
||||
profile.put("target_high", new JSONArray().put(new JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", targetHigh)));
|
||||
profile.put("units", mgdl ? Constants.MGDL : Constants.MMOL);
|
||||
store.put(profileName, profile);
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
convertedProfile = new ProfileStore(json);
|
||||
convertedProfileName = profileName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProfileStore getProfile() {
|
||||
if (convertedProfile == null)
|
||||
createConvertedProfile();
|
||||
|
||||
performLimitCheck();
|
||||
return convertedProfile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUnits() {
|
||||
return mgdl ? Constants.MGDL : Constants.MMOL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProfileName() {
|
||||
if (convertedProfile == null)
|
||||
createConvertedProfile();
|
||||
|
||||
performLimitCheck();
|
||||
return convertedProfileName;
|
||||
}
|
||||
|
||||
private void performLimitCheck() {
|
||||
if (percentage < Constants.CPP_MIN_PERCENTAGE || percentage > Constants.CPP_MAX_PERCENTAGE) {
|
||||
String msg = String.format(MainApp.sResources.getString(R.string.openapsma_valueoutofrange), "Profile-Percentage");
|
||||
log.error(msg);
|
||||
NSUpload.uploadError(msg);
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), msg, R.raw.error);
|
||||
percentage = Math.max(percentage, Constants.CPP_MIN_PERCENTAGE);
|
||||
percentage = Math.min(percentage, Constants.CPP_MAX_PERCENTAGE);
|
||||
}
|
||||
}
|
||||
|
||||
String basalString() {
|
||||
return profileString(basebasal, timeshift, percentage, true);
|
||||
}
|
||||
|
||||
String icString() {
|
||||
return profileString(baseic, timeshift, percentage, false);
|
||||
}
|
||||
|
||||
String isfString() {
|
||||
return profileString(baseisf, timeshift, percentage, false);
|
||||
}
|
||||
|
||||
String baseIcString() {
|
||||
return profileString(baseic, 0, 100, false);
|
||||
}
|
||||
|
||||
String baseIsfString() {
|
||||
return profileString(baseisf, 0, 100, false);
|
||||
}
|
||||
|
||||
String baseBasalString() {
|
||||
return profileString(basebasal, 0, 100, true);
|
||||
}
|
||||
|
||||
public double baseBasalSum() {
|
||||
return sum(basebasal);
|
||||
}
|
||||
|
||||
public double percentageBasalSum() {
|
||||
double result = 0;
|
||||
for (int i = 0; i < basebasal.length; i++) {
|
||||
result += SafeParse.stringToDouble(DecimalFormatter.to2Decimal(basebasal[i] * percentage / 100d));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public static double sum(double values[]) {
|
||||
double result = 0;
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
result += values[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private static String profileString(double[] values, int timeshift, int percentage, boolean inc) {
|
||||
timeshift = -(timeshift % 24) + 24;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("<b>");
|
||||
sb.append(0);
|
||||
sb.append("h: ");
|
||||
sb.append("</b>");
|
||||
sb.append(DecimalFormatter.to2Decimal(values[(timeshift + 0) % 24] * (inc ? percentage / 100d : 100d / percentage)));
|
||||
double prevVal = values[(timeshift + 0) % 24];
|
||||
for (int i = 1; i < 24; i++) {
|
||||
if (prevVal != values[(timeshift + i) % 24]) {
|
||||
sb.append(", ");
|
||||
sb.append("<b>");
|
||||
sb.append(i);
|
||||
sb.append("h: ");
|
||||
sb.append("</b>");
|
||||
sb.append(DecimalFormatter.to2Decimal(values[(timeshift + i) % 24] * (inc ? percentage / 100d : 100d / percentage)));
|
||||
prevVal = values[(timeshift + i) % 24];
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public int getPercentage() {
|
||||
return percentage;
|
||||
}
|
||||
|
||||
public int getTimeshift() {
|
||||
return timeshift;
|
||||
}
|
||||
}
|
|
@ -13,7 +13,6 @@ import android.widget.Button;
|
|||
import android.widget.RadioButton;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.crashlytics.android.Crashlytics;
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
@ -33,6 +32,7 @@ import info.nightscout.androidaps.plugins.Careportal.OptionsToShow;
|
|||
import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.utils.DecimalFormatter;
|
||||
import info.nightscout.utils.FabricPrivacy;
|
||||
import info.nightscout.utils.NumberPicker;
|
||||
import info.nightscout.utils.SafeParse;
|
||||
import info.nightscout.utils.TimeListEdit;
|
||||
|
@ -140,7 +140,7 @@ public class LocalProfileFragment extends SubscriberFragment {
|
|||
return layout;
|
||||
} catch (Exception e) {
|
||||
log.error("Unhandled exception: ", e);
|
||||
Crashlytics.logException(e);
|
||||
FabricPrivacy.logException(e);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
@ -10,7 +10,6 @@ import android.widget.ArrayAdapter;
|
|||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.crashlytics.android.Crashlytics;
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -22,6 +21,7 @@ import info.nightscout.androidaps.data.ProfileStore;
|
|||
import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
|
||||
import info.nightscout.androidaps.plugins.ProfileNS.events.EventNSProfileUpdateGUI;
|
||||
import info.nightscout.utils.DecimalFormatter;
|
||||
import info.nightscout.utils.FabricPrivacy;
|
||||
|
||||
|
||||
public class NSProfileFragment extends SubscriberFragment implements AdapterView.OnItemSelectedListener {
|
||||
|
@ -56,7 +56,7 @@ public class NSProfileFragment extends SubscriberFragment implements AdapterView
|
|||
updateGUI();
|
||||
return layout;
|
||||
} catch (Exception e) {
|
||||
Crashlytics.logException(e);
|
||||
FabricPrivacy.logException(e);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
@ -13,7 +13,6 @@ import android.widget.EditText;
|
|||
import android.widget.RadioButton;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.crashlytics.android.Crashlytics;
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
@ -27,6 +26,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.utils.FabricPrivacy;
|
||||
import info.nightscout.utils.SafeParse;
|
||||
|
||||
public class SimpleProfileFragment extends SubscriberFragment {
|
||||
|
@ -137,7 +137,7 @@ public class SimpleProfileFragment extends SubscriberFragment {
|
|||
|
||||
return layout;
|
||||
} catch (Exception e) {
|
||||
Crashlytics.logException(e);
|
||||
FabricPrivacy.logException(e);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
@ -34,6 +34,7 @@ import info.nightscout.androidaps.plugins.PumpDanaR.services.AbstractDanaRExecut
|
|||
import info.nightscout.utils.DateUtil;
|
||||
import info.nightscout.utils.DecimalFormatter;
|
||||
import info.nightscout.utils.Round;
|
||||
import info.nightscout.utils.SP;
|
||||
|
||||
/**
|
||||
* Created by mike on 28.01.2018.
|
||||
|
@ -293,7 +294,7 @@ public abstract class AbstractDanaRPlugin implements PluginBase, PumpInterface,
|
|||
result.isTempCancel = false;
|
||||
result.duration = pump.extendedBolusRemainingMinutes;
|
||||
result.absolute = pump.extendedBolusAbsoluteRate;
|
||||
result.bolusDelivered = pump.extendedBolusAmount;
|
||||
if (! SP.getBoolean("danar_useextended", false)) result.bolusDelivered = pump.extendedBolusAmount;
|
||||
result.isPercent = false;
|
||||
if (Config.logPumpActions)
|
||||
log.debug("setExtendedBolus: OK");
|
||||
|
@ -538,11 +539,13 @@ public abstract class AbstractDanaRPlugin implements PluginBase, PumpInterface,
|
|||
if (pump.lastBolusTime.getTime() != 0) {
|
||||
ret += "LastBolus: " + DecimalFormatter.to2Decimal(pump.lastBolusAmount) + "U @" + android.text.format.DateFormat.format("HH:mm", pump.lastBolusTime) + "\n";
|
||||
}
|
||||
if (MainApp.getConfigBuilder().isInHistoryRealTempBasalInProgress()) {
|
||||
ret += "Temp: " + MainApp.getConfigBuilder().getRealTempBasalFromHistory(System.currentTimeMillis()).toStringFull() + "\n";
|
||||
TemporaryBasal activeTemp = MainApp.getConfigBuilder().getRealTempBasalFromHistory(System.currentTimeMillis());
|
||||
if (activeTemp != null) {
|
||||
ret += "Temp: " + activeTemp.toStringFull() + "\n";
|
||||
}
|
||||
if (MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) {
|
||||
ret += "Extended: " + MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()).toString() + "\n";
|
||||
ExtendedBolus activeExtendedBolus = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis());
|
||||
if (activeExtendedBolus != null) {
|
||||
ret += "Extended: " + activeExtendedBolus.toString() + "\n";
|
||||
}
|
||||
if (!veryShort) {
|
||||
ret += "TDD: " + DecimalFormatter.to0Decimal(pump.dailyTotalUnits) + " / " + pump.maxDailyTotalUnits + " U\n";
|
||||
|
|
|
@ -15,7 +15,7 @@ import android.widget.Button;
|
|||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.crashlytics.android.Crashlytics;
|
||||
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
@ -29,6 +29,7 @@ import butterknife.OnClick;
|
|||
import butterknife.Unbinder;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.db.ExtendedBolus;
|
||||
import info.nightscout.androidaps.events.EventExtendedBolusChange;
|
||||
import info.nightscout.androidaps.events.EventPumpStatusChanged;
|
||||
import info.nightscout.androidaps.events.EventTempBasalChange;
|
||||
|
@ -41,6 +42,7 @@ import info.nightscout.androidaps.plugins.PumpDanaR.events.EventDanaRNewStatus;
|
|||
import info.nightscout.androidaps.queue.events.EventQueueChanged;
|
||||
import info.nightscout.utils.DateUtil;
|
||||
import info.nightscout.utils.DecimalFormatter;
|
||||
import info.nightscout.utils.FabricPrivacy;
|
||||
import info.nightscout.utils.SetWarnColor;
|
||||
|
||||
public class DanaRFragment extends SubscriberFragment {
|
||||
|
@ -100,7 +102,7 @@ public class DanaRFragment extends SubscriberFragment {
|
|||
|
||||
return view;
|
||||
} catch (Exception e) {
|
||||
Crashlytics.logException(e);
|
||||
FabricPrivacy.logException(e);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -216,8 +218,9 @@ public class DanaRFragment extends SubscriberFragment {
|
|||
tempBasalView.setText("");
|
||||
}
|
||||
}
|
||||
if (MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) {
|
||||
extendedBolusView.setText(MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()).toString());
|
||||
ExtendedBolus activeExtendedBolus = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis());
|
||||
if (activeExtendedBolus != null) {
|
||||
extendedBolusView.setText(activeExtendedBolus.toString());
|
||||
} else {
|
||||
extendedBolusView.setText("");
|
||||
}
|
||||
|
@ -226,7 +229,7 @@ public class DanaRFragment extends SubscriberFragment {
|
|||
batteryView.setText("{fa-battery-" + (pump.batteryRemaining / 25) + "}");
|
||||
SetWarnColor.setColorInverse(batteryView, pump.batteryRemaining, 51d, 26d);
|
||||
iobView.setText(pump.iob + " U");
|
||||
if (pump.isNewPump) {
|
||||
if (pump.model != 0 || pump.protocol != 0 || pump.productCode != 0) {
|
||||
firmwareView.setText(String.format(MainApp.sResources.getString(R.string.danar_model), pump.model, pump.protocol, pump.productCode));
|
||||
} else {
|
||||
firmwareView.setText("OLD");
|
||||
|
|
|
@ -134,6 +134,7 @@ public class DanaRPlugin extends AbstractDanaRPlugin {
|
|||
detailedBolusInfo.insulin = configBuilderPlugin.applyBolusConstraints(detailedBolusInfo.insulin);
|
||||
if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) {
|
||||
Treatment t = new Treatment();
|
||||
t.isSMB = detailedBolusInfo.isSMB;
|
||||
boolean connectionOK = false;
|
||||
if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) connectionOK = sExecutionService.bolus(detailedBolusInfo.insulin, (int) detailedBolusInfo.carbs, detailedBolusInfo.carbTime, t);
|
||||
PumpEnactResult result = new PumpEnactResult();
|
||||
|
@ -315,8 +316,7 @@ public class DanaRPlugin extends AbstractDanaRPlugin {
|
|||
if (MainApp.getConfigBuilder().isInHistoryRealTempBasalInProgress())
|
||||
return cancelRealTempBasal();
|
||||
if (MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress() && useExtendedBoluses) {
|
||||
PumpEnactResult cancelEx = cancelExtendedBolus();
|
||||
return cancelEx;
|
||||
return cancelExtendedBolus();
|
||||
}
|
||||
PumpEnactResult result = new PumpEnactResult();
|
||||
result.success = true;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue