Update to current dev branch

This commit is contained in:
Nico Schmitz 2018-12-11 14:51:26 +01:00
commit 9e03f0f8ca
337 changed files with 26904 additions and 12488 deletions
ISSUE_TEMPLATE.mdREADME.md
app
build.gradle
src/main
AndroidManifest.xml
assets
java
com/squareup/otto
info/nightscout/androidaps
MainActivity.javaMainApp.java
activities
data
db
events
interfaces
logging
plugins
Actions
Careportal
ConfigBuilder
ConstraintsObjectives
ConstraintsSafety
Food
Insulin
IobCobCalculator
Loop
Maintenance
NSClientInternal
OpenAPSAMA
OpenAPSMA
OpenAPSSMB
Overview
Persistentnotification
ProfileLocal
ProfileNS
ProfileSimple
PumpCombo
PumpCommon

View file

@ -1,10 +1,10 @@
Reporting bugs
--------------
- Note the precise time the problem occurred and describe the circumstances and steps that caused
- **Note the precise time the problem occurred** and describe the circumstances and steps that caused
the problem
- Note the Build version (found in the About dialog in the app, when pressing the three dots in the
upper-right corner).
- Obtain the app's log files, which can be found on the phone in
_/storage/emulated/0/Android/data/info.nightscout.androidaps/_
See https://github.com/MilosKozak/AndroidAPS/wiki/Accessing-logfiles
- Open an issue at https://github.com/MilosKozak/AndroidAPS/issues/new
- Open an issue at https://github.com/MilosKozak/AndroidAPS/issues/new

View file

@ -1,6 +1,6 @@
# AndroidAPS
* Check the wiki: https://github.com/MilosKozak/AndroidAPS/wiki
* Check the wiki: http://wiki.androidaps.org
* Everyone whos been looping with AndroidAPS needs to fill out the form after 3 days of looping https://docs.google.com/forms/d/14KcMjlINPMJHVt28MDRupa4sz4DDIooI4SrW0P3HSN8/viewform?c=0&w=1
[![Gitter](https://badges.gitter.im/MilosKozak/AndroidAPS.svg)](https://gitter.im/MilosKozak/AndroidAPS?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

View file

@ -29,9 +29,7 @@ repositories {
}
def generateGitBuild = { ->
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append('"')
try {
def stdout = new ByteArrayOutputStream()
exec {
@ -43,9 +41,12 @@ def generateGitBuild = { ->
} catch (ignored) {
stringBuilder.append('NoGitSystemAvailable')
}
stringBuilder.append('-')
return stringBuilder.toString()
}
def generateDate = { ->
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append((new Date()).format('yyyy.MM.dd-HH:mm'))
stringBuilder.append('"')
return stringBuilder.toString()
}
@ -62,9 +63,10 @@ android {
targetSdkVersion 25
multiDexEnabled true
versionCode 1500
version "2.0d-dev"
version "2.0"
buildConfigField "String", "VERSION", '"' + version + '"'
buildConfigField "String", "BUILDVERSION", generateGitBuild()
buildConfigField "String", "BUILDVERSION", '"' + generateGitBuild() + '-' + generateDate() + '"'
buildConfigField "String", "HEAD", '"' + generateGitBuild() + '"'
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
ndk {

View file

@ -12,6 +12,7 @@
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.RECEIVE_MMS" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.SEND_MMS" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.INTERNET" />
@ -34,6 +35,9 @@
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme.NoActionBar">
<meta-data
android:name="com.google.android.gms.car.application"
android:resource="@xml/automotive_app_desc" />
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

View file

@ -9,33 +9,32 @@ 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);
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 round_basal = require('./round-basal');
if (rate < 0) {
rate = 0;
} 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) {
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 && duration > 0 ) {
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 (profile.skip_neutral_temps === true) {
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;
@ -58,4 +57,4 @@ var round_basal = require('./round-basal');
}
};
module.exports = tempBasalFunctions;
module.exports = tempBasalFunctions;

View file

@ -18,7 +18,7 @@
<maxHistory>120</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level [%class{0}.%M\(\):%line]: %msg%n</pattern>
<pattern>%d{HH:mm:ss.SSS} [%thread] %.-1level/%logger: [%class{0}.%M\(\):%line]: %msg%n</pattern>
</encoder>
</appender>

View file

@ -5,6 +5,7 @@ import org.slf4j.LoggerFactory;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ConcurrentModificationException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@ -13,11 +14,12 @@ import java.util.Set;
import info.nightscout.androidaps.events.Event;
import info.nightscout.androidaps.logging.L;
/** Logs events has they're being posted to and dispatched from the event bus.
*
/**
* Logs events has they're being posted to and dispatched from the event bus.
* <p>
* A summary of event-receiver calls that occurred so far is logged
* after 10s (after startup) and then again every 60s.
* */
*/
public class LoggingBus extends Bus {
private static Logger log = LoggerFactory.getLogger(L.EVENTS);
@ -49,7 +51,10 @@ public class LoggingBus extends Bus {
log.debug(" source: <unknown>");
}
super.post(event);
try {
super.post(event);
} catch (IllegalStateException ignored) {
}
}
@Override
@ -71,16 +76,19 @@ public class LoggingBus extends Bus {
log.debug(" receiver: <unknown>");
}
if (everyMinute < System.currentTimeMillis()) {
log.debug("***************** Event -> receiver pairings seen so far ****************");
for (Map.Entry<String, Set<String>> stringSetEntry : event2Receiver.entrySet()) {
log.debug(" " + stringSetEntry.getKey());
for (String s : stringSetEntry.getValue()) {
log.debug(" -> " + s);
try {
if (everyMinute < System.currentTimeMillis()) {
log.debug("***************** Event -> receiver pairings seen so far ****************");
for (Map.Entry<String, Set<String>> stringSetEntry : event2Receiver.entrySet()) {
log.debug(" " + stringSetEntry.getKey());
for (String s : stringSetEntry.getValue()) {
log.debug(" -> " + s);
}
}
log.debug("*************************************************************************");
everyMinute = System.currentTimeMillis() + 60 * 1000;
}
log.debug("*************************************************************************");
everyMinute = System.currentTimeMillis() + 60 * 1000;
} catch (ConcurrentModificationException ignored) {
}
super.dispatch(event, wrapper);

View file

@ -182,7 +182,7 @@ public class MainActivity extends AppCompatActivity {
@Subscribe
public void onStatusEvent(final EventRefreshGui ev) {
String lang = SP.getString("language", "en");
String lang = SP.getString(R.string.key_language, "en");
LocaleHelper.setLocale(getApplicationContext(), lang);
runOnUiThread(() -> {
if (ev.recreate) {
@ -326,6 +326,7 @@ public class MainActivity extends AppCompatActivity {
case AndroidPermission.CASE_LOCATION:
case AndroidPermission.CASE_SMS:
case AndroidPermission.CASE_BATTERY:
case AndroidPermission.CASE_PHONESTATE:
break;
}
}

View file

@ -93,7 +93,6 @@ public class MainApp extends Application {
public static Resources sResources;
private static DatabaseHelper sDatabaseHelper = null;
private static ConfigBuilderPlugin sConfigBuilder = null;
private static ConstraintChecker sConstraintsChecker = null;
private static ArrayList<PluginBase> pluginsList = null;
@ -137,7 +136,7 @@ public class MainApp extends Application {
engineeringMode = engineeringModeSemaphore.exists() && engineeringModeSemaphore.isFile();
devBranch = BuildConfig.VERSION.contains("dev");
sBus = L.isEnabled(L.EVENTS) ? new LoggingBus(ThreadEnforcer.ANY) : new Bus(ThreadEnforcer.ANY);
sBus = L.isEnabled(L.EVENTS) && devBranch ? new LoggingBus(ThreadEnforcer.ANY) : new Bus(ThreadEnforcer.ANY);
registerLocalBroadcastReceiver();
@ -189,18 +188,18 @@ public class MainApp extends Application {
pluginsList.add(NSClientPlugin.getPlugin());
pluginsList.add(MaintenancePlugin.initPlugin(this));
pluginsList.add(sConfigBuilder = ConfigBuilderPlugin.getPlugin());
pluginsList.add(ConfigBuilderPlugin.getPlugin());
MainApp.getConfigBuilder().initialize();
ConfigBuilderPlugin.getPlugin().initialize();
}
NSUpload.uploadAppStart();
final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
if (pump != null) {
new Thread(() -> {
SystemClock.sleep(5000);
ConfigBuilderPlugin.getCommandQueue().readStatus("Initialization", null);
ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("Initialization", null);
startKeepAliveService();
}).start();
}
@ -297,10 +296,6 @@ public class MainApp extends Application {
}
}
public static ConfigBuilderPlugin getConfigBuilder() {
return sConfigBuilder;
}
public static ConstraintChecker getConstraintChecker() {
return sConstraintsChecker;
}

View file

@ -229,7 +229,7 @@ public class HistoryBrowseActivity extends AppCompatActivity {
if (noProfile == null || buttonDate == null || buttonZoom == null || bgGraph == null || iobGraph == null || seekBar == null)
return;
final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
final Profile profile = ProfileFunctions.getInstance().getProfile();
if (profile == null) {

View file

@ -90,7 +90,7 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
pref.setSummary("******");
} else if (pref.getKey().equals(MainApp.gs(R.string.key_danars_name))) {
pref.setSummary(SP.getString(R.string.key_danars_name, ""));
} else if (editTextPref.getText() != null ) {
} else if (editTextPref.getText() != null) {
((EditTextPreference) pref).setDialogMessage(editTextPref.getDialogMessage());
pref.setSummary(editTextPref.getText());
} else if (pref.getKey().contains("smscommunicator_allowednumbers") && TextUtils.isEmpty(editTextPref.getText().trim())) {
@ -184,9 +184,7 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
addPreferencesFromResourceIfEnabled(NSClientPlugin.getPlugin(), PluginType.GENERAL);
addPreferencesFromResourceIfEnabled(SmsCommunicatorPlugin.getPlugin(), PluginType.GENERAL);
if (!Config.NSCLIENT) {
addPreferencesFromResource(R.xml.pref_others);
}
addPreferencesFromResource(R.xml.pref_others);
addPreferencesFromResource(R.xml.pref_datachoices);
addPreferencesFromResourceIfEnabled(WearPlugin.getPlugin(), PluginType.GENERAL);

View file

@ -130,7 +130,7 @@ public class TDDStatsActivity extends Activity {
}
totalBaseBasal.setText(TBB);
if (!ConfigBuilderPlugin.getActivePump().getPumpDescription().needsManualTDDLoad)
if (!ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().needsManualTDDLoad)
reloadButton.setVisibility(View.GONE);
// stats table
@ -239,7 +239,7 @@ public class TDDStatsActivity extends Activity {
statsMessage.setText(MainApp.gs(R.string.danar_stats_warning_Message));
}
});
ConfigBuilderPlugin.getCommandQueue().loadTDDs( new Callback() {
ConfigBuilderPlugin.getPlugin().getCommandQueue().loadTDDs( new Callback() {
@Override
public void run() {
loadDataFromDB();
@ -440,7 +440,7 @@ public class TDDStatsActivity extends Activity {
TableLayout.LayoutParams.WRAP_CONTENT));
}
if (isOldData(historyList) && ConfigBuilderPlugin.getActivePump().getPumpDescription().needsManualTDDLoad) {
if (isOldData(historyList) && ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().needsManualTDDLoad) {
statsMessage.setVisibility(View.VISIBLE);
statsMessage.setText(MainApp.gs(R.string.danar_stats_olddata_Message));
@ -545,7 +545,7 @@ public class TDDStatsActivity extends Activity {
public static boolean isOldData(List<TDD> historyList) {
Object activePump = MainApp.getConfigBuilder().getActivePump();
Object activePump = ConfigBuilderPlugin.getPlugin().getActivePump();
PumpInterface dana = MainApp.getSpecificPlugin(DanaRPlugin.class);
PumpInterface danaRS = MainApp.getSpecificPlugin(DanaRSPlugin.class);
PumpInterface danaV2 = MainApp.getSpecificPlugin(DanaRv2Plugin.class);

View file

@ -42,6 +42,10 @@ public class ConstraintChecker implements ConstraintsInterface {
return isSMBModeEnabled(new Constraint<>(true));
}
public Constraint<Boolean> isUAMEnabled() {
return isUAMEnabled(new Constraint<>(true));
}
public Constraint<Boolean> isAdvancedFilteringEnabled() {
return isAdvancedFilteringEnabled(new Constraint<>(true));
}
@ -58,6 +62,10 @@ public class ConstraintChecker implements ConstraintsInterface {
return applyBolusConstraints(new Constraint<>(Constants.REALLYHIGHBOLUS));
}
public Constraint<Double> getMaxExtendedBolusAllowed() {
return applyExtendedBolusConstraints(new Constraint<>(Constants.REALLYHIGHBOLUS));
}
public Constraint<Integer> getMaxCarbsAllowed() {
return applyCarbsConstraints(new Constraint<>(Constants.REALLYHIGHCARBS));
}
@ -126,6 +134,18 @@ public class ConstraintChecker implements ConstraintsInterface {
return value;
}
@Override
public Constraint<Boolean> isUAMEnabled(Constraint<Boolean> value) {
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
for (PluginBase p : constraintsPlugins) {
ConstraintsInterface constraint = (ConstraintsInterface) p;
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
constraint.isUAMEnabled(value);
}
return value;
}
@Override
public Constraint<Boolean> isAdvancedFilteringEnabled(Constraint<Boolean> value) {
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
@ -170,6 +190,17 @@ public class ConstraintChecker implements ConstraintsInterface {
return insulin;
}
@Override
public Constraint<Double> applyExtendedBolusConstraints(Constraint<Double> insulin) {
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
for (PluginBase p : constraintsPlugins) {
ConstraintsInterface constrain = (ConstraintsInterface) p;
if (!p.isEnabled(PluginType.CONSTRAINTS)) continue;
constrain.applyExtendedBolusConstraints(insulin);
}
return insulin;
}
@Override
public Constraint<Integer> applyCarbsConstraints(Constraint<Integer> carbs) {
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);

View file

@ -12,17 +12,18 @@ import java.text.DecimalFormat;
import java.util.Calendar;
import java.util.TimeZone;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.interfaces.PumpDescription;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
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.MidnightTime;
public class Profile {
private static Logger log = LoggerFactory.getLogger(Profile.class);
@ -221,7 +222,7 @@ public class Profile {
if (isValid) {
// Check for hours alignment
PumpInterface pump = MainApp.getConfigBuilder().getActivePump();
PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
if (pump != null && !pump.getPumpDescription().is30minBasalRatesCapable) {
for (int index = 0; index < basal_v.size(); index++) {
long secondsFromMidnight = basal_v.keyAt(index);
@ -381,7 +382,7 @@ public class Profile {
}
public double getIsf() {
return getIsfTimeFromMidnight(secondsFromMidnight(System.currentTimeMillis()));
return getIsfTimeFromMidnight(secondsFromMidnight());
}
public double getIsf(long time) {
@ -397,11 +398,11 @@ public class Profile {
public String getIsfList() {
if (isf_v == null)
isf_v = convertToSparseArray(isf);
return getValuesList(isf_v, null, new DecimalFormat("0.0"), getUnits() + "/U");
return getValuesList(isf_v, null, new DecimalFormat("0.0"), getUnits() + MainApp.gs(R.string.profile_per_unit));
}
public double getIc() {
return getIcTimeFromMidnight(secondsFromMidnight(System.currentTimeMillis()));
return getIcTimeFromMidnight(secondsFromMidnight());
}
public double getIc(long time) {
@ -417,11 +418,11 @@ public class Profile {
public String getIcList() {
if (ic_v == null)
ic_v = convertToSparseArray(ic);
return getValuesList(ic_v, null, new DecimalFormat("0.0"), "g/U");
return getValuesList(ic_v, null, new DecimalFormat("0.0"), MainApp.gs(R.string.profile_carbs_per_unit));
}
public double getBasal() {
return getBasalTimeFromMidnight(secondsFromMidnight(System.currentTimeMillis()));
return getBasalTimeFromMidnight(secondsFromMidnight());
}
public double getBasal(long time) {
@ -438,7 +439,7 @@ public class Profile {
public String getBasalList() {
if (basal_v == null)
basal_v = convertToSparseArray(basal);
return getValuesList(basal_v, null, new DecimalFormat("0.00"), "U/h");
return getValuesList(basal_v, null, new DecimalFormat("0.00"), MainApp.gs(R.string.profile_ins_units_per_hout));
}
public class BasalValue {
@ -465,7 +466,7 @@ public class Profile {
}
public double getTarget() {
return getTarget(secondsFromMidnight(System.currentTimeMillis()));
return getTarget(secondsFromMidnight());
}
protected double getTarget(int timeAsSeconds) {
@ -473,7 +474,7 @@ public class Profile {
}
public double getTargetLow() {
return getTargetLowTimeFromMidnight(secondsFromMidnight(System.currentTimeMillis()));
return getTargetLowTimeFromMidnight(secondsFromMidnight());
}
public double getTargetLow(long time) {
@ -487,7 +488,7 @@ public class Profile {
}
public double getTargetHigh() {
return getTargetHighTimeFromMidnight(secondsFromMidnight(System.currentTimeMillis()));
return getTargetHighTimeFromMidnight(secondsFromMidnight());
}
public double getTargetHigh(long time) {
@ -518,24 +519,13 @@ public class Profile {
}
public static int secondsFromMidnight() {
Calendar c = Calendar.getInstance();
long now = c.getTimeInMillis();
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
long passed = now - c.getTimeInMillis();
long passed = DateUtil.now() - MidnightTime.calc();
return (int) (passed / 1000);
}
public static int secondsFromMidnight(long date) {
Calendar c = Calendar.getInstance();
c.setTimeInMillis(date);
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
long passed = date - c.getTimeInMillis();
long midnight = MidnightTime.calc(date);
long passed = date - midnight;
return (int) (passed / 1000);
}

View file

@ -167,6 +167,11 @@ public class BgReading implements DataPointWithLabelInterface {
return this;
}
public BgReading date(Date date) {
this.date = date.getTime();
return this;
}
public BgReading value(double value) {
this.value = value;
return this;
@ -215,14 +220,8 @@ public class BgReading implements DataPointWithLabelInterface {
@Override
public int getColor() {
String units = ProfileFunctions.getInstance().getProfileUnits();
Double lowLine = SP.getDouble("low_mark", 0d);
Double highLine = SP.getDouble("high_mark", 0d);
if (lowLine < 1) {
lowLine = Profile.fromMgdlToUnits(OverviewPlugin.bgTargetLow, units);
}
if (highLine < 1) {
highLine = Profile.fromMgdlToUnits(OverviewPlugin.bgTargetHigh, units);
}
Double lowLine = OverviewPlugin.getPlugin().determineLowLine(units);
Double highLine = OverviewPlugin.getPlugin().determineHighLine(units);
int color = MainApp.gc(R.color.inrange);
if (isPrediction())
return getPredectionColor();

View file

@ -97,14 +97,17 @@ public class CareportalEvent implements DataPointWithLabelInterface, Interval {
public String age() {
Map<TimeUnit, Long> diff = computeDiff(date, System.currentTimeMillis());
if (OverviewFragment.shorttextmode)
return diff.get(TimeUnit.DAYS) +"d" + diff.get(TimeUnit.HOURS) + "h";
return diff.get(TimeUnit.DAYS) + "d" + diff.get(TimeUnit.HOURS) + "h";
else
return diff.get(TimeUnit.DAYS) + " " + MainApp.gs(R.string.days) + " " + diff.get(TimeUnit.HOURS) + " " + MainApp.gs(R.string.hours);
}
public boolean isOlderThan(double hours) { return getHoursFromStart() > hours; }
public boolean isOlderThan(double hours) {
return getHoursFromStart() > hours;
}
public String log() {
@Override
public String toString() {
return "CareportalEvent{" +
"date= " + date +
", date= " + DateUtil.dateAndTimeString(date) +
@ -136,11 +139,11 @@ public class CareportalEvent implements DataPointWithLabelInterface, Interval {
for (int i = 0; i < list.size(); i++) {
CareportalEvent event = list.get(i);
if (event.date <= time && event.date > (time - T.mins(5).msecs())) {
//log.debug("Found event for time: " + DateUtil.dateAndTimeString(time) + " " + event.toString());
if (L.isEnabled(L.DATABASE))
log.debug("Found event for time: " + DateUtil.dateAndTimeFullString(time) + " " + event.toString());
return true;
}
}
//log.debug("WWWWWW No found event for time: " + DateUtil.dateAndTimeString(time));
return false;
}

View file

@ -27,6 +27,7 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.data.OverlappingIntervals;
import info.nightscout.androidaps.data.Profile;
@ -41,7 +42,9 @@ import info.nightscout.androidaps.events.EventReloadTempBasalData;
import info.nightscout.androidaps.events.EventReloadTreatmentData;
import info.nightscout.androidaps.events.EventTempBasalChange;
import info.nightscout.androidaps.events.EventTempTargetChange;
import info.nightscout.androidaps.interfaces.ProfileInterface;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventNewHistoryData;
import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload;
@ -74,7 +77,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
public static final String DATABASE_PROFILESWITCHES = "ProfileSwitches";
public static final String DATABASE_TDDS = "TDDs";
private static final int DATABASE_VERSION = 8;
private static final int DATABASE_VERSION = 9;
public static Long earliestDataChange = null;
@ -133,6 +136,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
if (oldVersion == 7 && newVersion == 8) {
log.debug("Upgrading database from v7 to v8");
} else if (oldVersion == 8 && newVersion == 9) {
log.debug("Upgrading database from v8 to v9");
} else {
log.info(DatabaseHelper.class.getName(), "onUpgrade");
TableUtils.dropTable(connectionSource, TempTarget.class, true);
@ -151,6 +156,12 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
}
}
@Override
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
log.info("Do nothing for downgrading...");
log.debug("oldVersion: {}, newVersion: {}", oldVersion, newVersion);
}
public int getOldVersion() {
return oldVersion;
}
@ -198,7 +209,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
} catch (SQLException e) {
log.error("Unhandled exception", e);
}
VirtualPumpPlugin.setFakingStatus(true);
VirtualPumpPlugin.getPlugin().setFakingStatus(true);
scheduleBgChange(null); // trigger refresh
scheduleTemporaryBasalChange();
scheduleExtendedBolusChange();
@ -234,7 +245,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
} catch (SQLException e) {
log.error("Unhandled exception", e);
}
VirtualPumpPlugin.setFakingStatus(false);
VirtualPumpPlugin.getPlugin().setFakingStatus(false);
scheduleTemporaryBasalChange();
}
@ -392,7 +403,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
QueryBuilder<BgReading, Long> queryBuilder = daoBgReadings.queryBuilder();
queryBuilder.orderBy("date", false);
queryBuilder.limit(1L);
queryBuilder.where().gt("value", 38).and().eq("isValid", true);
queryBuilder.where().ge("value", 39).and().eq("isValid", true);
PreparedQuery<BgReading> preparedQuery = queryBuilder.prepare();
bgList = daoBgReadings.query(preparedQuery);
@ -430,7 +441,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
QueryBuilder<BgReading, Long> queryBuilder = daoBgreadings.queryBuilder();
queryBuilder.orderBy("date", ascending);
Where where = queryBuilder.where();
where.ge("date", mills).and().gt("value", 38).and().eq("isValid", true);
where.ge("date", mills).and().ge("value", 39).and().eq("isValid", true);
PreparedQuery<BgReading> preparedQuery = queryBuilder.prepare();
bgReadings = daoBgreadings.query(preparedQuery);
return bgReadings;
@ -447,7 +458,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
QueryBuilder<BgReading, Long> queryBuilder = daoBgreadings.queryBuilder();
queryBuilder.orderBy("date", ascending);
Where where = queryBuilder.where();
where.between("date", start, end).and().gt("value", 38).and().eq("isValid", true);
where.between("date", start, end).and().ge("value", 39).and().eq("isValid", true);
PreparedQuery<BgReading> preparedQuery = queryBuilder.prepare();
bgReadings = daoBgreadings.query(preparedQuery);
return bgReadings;
@ -696,7 +707,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
public void createTemptargetFromJsonIfNotExists(JSONObject trJson) {
try {
String units = JsonHelper.safeGetString(trJson, "units", ProfileFunctions.getInstance().getProfileUnits());
String units = JsonHelper.safeGetString(trJson, "units", Constants.MGDL);
TempTarget tempTarget = new TempTarget()
.date(trJson.getLong("mills"))
.duration(trJson.getInt("duration"))
@ -958,15 +969,16 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
public void createTempBasalFromJsonIfNotExists(JSONObject trJson) {
try {
if (trJson.has("originalExtendedAmount")) { // extended bolus uploaded as temp basal
ExtendedBolus extendedBolus = new ExtendedBolus();
extendedBolus.source = Source.NIGHTSCOUT;
extendedBolus.date = trJson.getLong("mills");
extendedBolus.pumpId = trJson.has("pumpId") ? trJson.getLong("pumpId") : 0;
extendedBolus.durationInMinutes = trJson.getInt("duration");
extendedBolus.insulin = trJson.getDouble("originalExtendedAmount");
extendedBolus._id = trJson.getString("_id");
if (!VirtualPumpPlugin.getFakingStatus()) {
VirtualPumpPlugin.setFakingStatus(true);
ExtendedBolus extendedBolus = new ExtendedBolus()
.source(Source.NIGHTSCOUT)
.date(trJson.getLong("mills"))
.pumpId(trJson.has("pumpId") ? trJson.getLong("pumpId") : 0)
.durationInMinutes(trJson.getInt("duration"))
.insulin(trJson.getDouble("originalExtendedAmount"))
._id(trJson.getString("_id"));
// if faking found in NS, adapt AAPS to use it too
if (!VirtualPumpPlugin.getPlugin().getFakingStatus()) {
VirtualPumpPlugin.getPlugin().setFakingStatus(true);
updateEarliestDataChange(0);
scheduleTemporaryBasalChange();
}
@ -979,8 +991,9 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
extendedBolus.durationInMinutes = 0;
extendedBolus.insulin = 0;
extendedBolus._id = trJson.getString("_id");
if (!VirtualPumpPlugin.getFakingStatus()) {
VirtualPumpPlugin.setFakingStatus(true);
// if faking found in NS, adapt AAPS to use it too
if (!VirtualPumpPlugin.getPlugin().getFakingStatus()) {
VirtualPumpPlugin.getPlugin().setFakingStatus(true);
updateEarliestDataChange(0);
scheduleTemporaryBasalChange();
}
@ -1044,23 +1057,33 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
public boolean createOrUpdate(ExtendedBolus extendedBolus) {
try {
if (L.isEnabled(L.DATABASE))
log.debug("EXTENDEDBOLUS: createOrUpdate: " + Source.getString(extendedBolus.source) + " " + extendedBolus.log());
ExtendedBolus old;
extendedBolus.date = roundDateToSec(extendedBolus.date);
if (extendedBolus.source == Source.PUMP) {
// check for changed from pump change in NS
QueryBuilder<ExtendedBolus, Long> queryBuilder = getDaoExtendedBolus().queryBuilder();
Where where = queryBuilder.where();
where.eq("pumpId", extendedBolus.pumpId);
PreparedQuery<ExtendedBolus> preparedQuery = queryBuilder.prepare();
List<ExtendedBolus> trList = getDaoExtendedBolus().query(preparedQuery);
if (trList.size() > 0) {
// do nothing, pump history record cannot be changed
return false;
// if pumpId == 0 do not check for existing pumpId
// used with pumps without history
// and insight where record as added first without pumpId
// and then is record updated with pumpId
if (extendedBolus.pumpId == 0) {
getDaoExtendedBolus().createOrUpdate(extendedBolus);
} else {
QueryBuilder<ExtendedBolus, Long> queryBuilder = getDaoExtendedBolus().queryBuilder();
Where where = queryBuilder.where();
where.eq("pumpId", extendedBolus.pumpId);
PreparedQuery<ExtendedBolus> preparedQuery = queryBuilder.prepare();
List<ExtendedBolus> trList = getDaoExtendedBolus().query(preparedQuery);
if (trList.size() > 1) {
log.error("EXTENDEDBOLUS: Multiple records found for pumpId: " + extendedBolus.pumpId);
return false;
}
getDaoExtendedBolus().createOrUpdate(extendedBolus);
}
getDaoExtendedBolus().create(extendedBolus);
if (L.isEnabled(L.DATABASE))
log.debug("EXTENDEDBOLUS: New record from: " + Source.getString(extendedBolus.source) + " " + extendedBolus.toString());
log.debug("EXTENDEDBOLUS: New record from: " + Source.getString(extendedBolus.source) + " " + extendedBolus.log());
updateEarliestDataChange(extendedBolus.date);
scheduleExtendedBolusChange();
return true;
@ -1074,7 +1097,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
old.copyFrom(extendedBolus);
getDaoExtendedBolus().create(old);
if (L.isEnabled(L.DATABASE))
log.debug("EXTENDEDBOLUS: Updating record by date from: " + Source.getString(extendedBolus.source) + " " + old.toString());
log.debug("EXTENDEDBOLUS: Updating record by date from: " + Source.getString(extendedBolus.source) + " " + old.log());
updateEarliestDataChange(oldDate);
updateEarliestDataChange(old.date);
scheduleExtendedBolusChange();
@ -1097,7 +1120,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
old.copyFrom(extendedBolus);
getDaoExtendedBolus().create(old);
if (L.isEnabled(L.DATABASE))
log.debug("EXTENDEDBOLUS: Updating record by _id from: " + Source.getString(extendedBolus.source) + " " + old.toString());
log.debug("EXTENDEDBOLUS: Updating record by _id from: " + Source.getString(extendedBolus.source) + " " + old.log());
updateEarliestDataChange(oldDate);
updateEarliestDataChange(old.date);
scheduleExtendedBolusChange();
@ -1107,7 +1130,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
}
getDaoExtendedBolus().create(extendedBolus);
if (L.isEnabled(L.DATABASE))
log.debug("EXTENDEDBOLUS: New record from: " + Source.getString(extendedBolus.source) + " " + extendedBolus.toString());
log.debug("EXTENDEDBOLUS: New record from: " + Source.getString(extendedBolus.source) + " " + extendedBolus.log());
updateEarliestDataChange(extendedBolus.date);
scheduleExtendedBolusChange();
return true;
@ -1115,7 +1138,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
if (extendedBolus.source == Source.USER) {
getDaoExtendedBolus().create(extendedBolus);
if (L.isEnabled(L.DATABASE))
log.debug("EXTENDEDBOLUS: New record from: " + Source.getString(extendedBolus.source) + " " + extendedBolus.toString());
log.debug("EXTENDEDBOLUS: New record from: " + Source.getString(extendedBolus.source) + " " + extendedBolus.log());
updateEarliestDataChange(extendedBolus.date);
scheduleExtendedBolusChange();
return true;
@ -1351,7 +1374,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
if (list.size() == 1) {
CareportalEvent record = list.get(0);
if (L.isEnabled(L.DATABASE))
log.debug("Removing CareportalEvent record from database: " + record.log());
log.debug("Removing CareportalEvent record from database: " + record.toString());
delete(record);
} else {
if (L.isEnabled(L.DATABASE))
@ -1432,6 +1455,24 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
return new ArrayList<>();
}
public List<ProfileSwitch> getProfileSwitchEventsFromTime(long mills, boolean ascending) {
try {
Dao<ProfileSwitch, Long> daoProfileSwitch = getDaoProfileSwitch();
List<ProfileSwitch> profileSwitches;
QueryBuilder<ProfileSwitch, Long> queryBuilder = daoProfileSwitch.queryBuilder();
queryBuilder.orderBy("date", ascending);
queryBuilder.limit(100L);
Where where = queryBuilder.where();
where.ge("date", mills);
PreparedQuery<ProfileSwitch> preparedQuery = queryBuilder.prepare();
profileSwitches = daoProfileSwitch.query(preparedQuery);
return profileSwitches;
} catch (SQLException e) {
log.error("Unhandled exception", e);
}
return new ArrayList<>();
}
public boolean createOrUpdate(ProfileSwitch profileSwitch) {
try {
ProfileSwitch old;
@ -1551,23 +1592,30 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
if (trJson.has("profileJson"))
profileSwitch.profileJson = trJson.getString("profileJson");
else {
ProfileStore store = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile();
if (store != null) {
Profile profile = store.getSpecificProfile(profileSwitch.profileName);
if (profile != null) {
profileSwitch.profileJson = profile.getData().toString();
if (L.isEnabled(L.DATABASE))
log.debug("Profile switch prefilled with JSON from local store");
// Update data in NS
NSUpload.updateProfileSwitch(profileSwitch);
ProfileInterface profileInterface = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface();
if (profileInterface != null) {
ProfileStore store = profileInterface.getProfile();
if (store != null) {
Profile profile = store.getSpecificProfile(profileSwitch.profileName);
if (profile != null) {
profileSwitch.profileJson = profile.getData().toString();
if (L.isEnabled(L.DATABASE))
log.debug("Profile switch prefilled with JSON from local store");
// Update data in NS
NSUpload.updateProfileSwitch(profileSwitch);
} else {
if (L.isEnabled(L.DATABASE))
log.debug("JSON for profile switch doesn't exist. Ignoring: " + trJson.toString());
return;
}
} else {
if (L.isEnabled(L.DATABASE))
log.debug("JSON for profile switch doesn't exist. Ignoring: " + trJson.toString());
log.debug("Store for profile switch doesn't exist. Ignoring: " + trJson.toString());
return;
}
} else {
if (L.isEnabled(L.DATABASE))
log.debug("Store for profile switch doesn't exist. Ignoring: " + trJson.toString());
log.debug("No active profile interface. Ignoring: " + trJson.toString());
return;
}
}

View file

@ -70,6 +70,36 @@ public class ExtendedBolus implements Interval, DataPointWithLabelInterface {
this.date = date;
}
public ExtendedBolus date(long date) {
this.date = date;
return this;
}
public ExtendedBolus insulin(double insulin) {
this.insulin = insulin;
return this;
}
public ExtendedBolus pumpId(long pumpId) {
this.pumpId = pumpId;
return this;
}
public ExtendedBolus source(int source) {
this.source = source;
return this;
}
public ExtendedBolus durationInMinutes(int durationInMinutes) {
this.durationInMinutes = durationInMinutes;
return this;
}
public ExtendedBolus _id(String _id) {
this._id = _id;
return this;
}
public boolean isEqual(ExtendedBolus other) {
if (date != other.date) {
return false;
@ -94,13 +124,13 @@ public class ExtendedBolus implements Interval, DataPointWithLabelInterface {
}
public static ExtendedBolus createFromJson(JSONObject json) {
ExtendedBolus extendedBolus = new ExtendedBolus();
extendedBolus.source = Source.NIGHTSCOUT;
extendedBolus.date = JsonHelper.safeGetLong(json, "mills");
extendedBolus.durationInMinutes = JsonHelper.safeGetInt(json, "duration");
extendedBolus.insulin = JsonHelper.safeGetDouble(json, "relative") / 60 * extendedBolus.durationInMinutes;
extendedBolus._id = JsonHelper.safeGetString(json, "_id");
extendedBolus.pumpId = JsonHelper.safeGetLong(json, "pumpId");
ExtendedBolus extendedBolus = new ExtendedBolus()
.source(Source.NIGHTSCOUT)
.date(JsonHelper.safeGetLong(json, "mills"))
.durationInMinutes(JsonHelper.safeGetInt(json, "duration"))
.insulin(JsonHelper.safeGetDouble(json, "relative") / 60 * JsonHelper.safeGetInt(json, "duration"))
._id(JsonHelper.safeGetString(json, "_id"))
.pumpId(JsonHelper.safeGetLong(json, "pumpId"));
return extendedBolus;
}
// -------- Interval interface ---------
@ -167,7 +197,7 @@ public class ExtendedBolus implements Interval, DataPointWithLabelInterface {
// -------- Interval interface end ---------
public String log() {
return "Bolus{" +
return "ExtendedBolus{" +
"date= " + date +
", date= " + DateUtil.dateAndTimeString(date) +
", isValid=" + isValid +
@ -188,7 +218,7 @@ public class ExtendedBolus implements Interval, DataPointWithLabelInterface {
public IobTotal iobCalc(long time) {
IobTotal result = new IobTotal(time);
InsulinInterface insulinInterface = ConfigBuilderPlugin.getActiveInsulin();
InsulinInterface insulinInterface = ConfigBuilderPlugin.getPlugin().getActiveInsulin();
int realDuration = getDurationToTime(time);

View file

@ -11,6 +11,7 @@ import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.Objects;
import info.nightscout.androidaps.MainApp;
@ -25,6 +26,7 @@ import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
import info.nightscout.androidaps.plugins.ProfileLocal.LocalProfilePlugin;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.T;
@DatabaseTable(tableName = DatabaseHelper.DATABASE_PROFILESWITCHES)
public class ProfileSwitch implements Interval, DataPointWithLabelInterface {
@ -99,6 +101,11 @@ public class ProfileSwitch implements Interval, DataPointWithLabelInterface {
return profile;
}
/**
* Note: the name returned here is used as the PS name when uploading to NS. When such a PS is retrieved
* again from NS, the added parts must be removed again, see
* {@link info.nightscout.utils.PercentageSplitter#pureName}
*/
public String getCustomizedName() {
String name = profileName;
if(LocalProfilePlugin.LOCAL_PROFILE.equals(name)){
@ -218,6 +225,26 @@ public class ProfileSwitch implements Interval, DataPointWithLabelInterface {
MainApp.bus().post(new EventNewNotification(notification));
}
public static boolean isEvent5minBack(List<ProfileSwitch> list, long time, boolean zeroDurationOnly) {
for (int i = 0; i < list.size(); i++) {
ProfileSwitch event = list.get(i);
if (event.date <= time && event.date > (time - T.mins(5).msecs())) {
if (zeroDurationOnly) {
if (event.durationInMinutes == 0) {
if (L.isEnabled(L.DATABASE))
log.debug("Found ProfileSwitch event for time: " + DateUtil.dateAndTimeFullString(time) + " " + event.toString());
return true;
}
} else {
if (L.isEnabled(L.DATABASE))
log.debug("Found ProfileSwitch event for time: " + DateUtil.dateAndTimeFullString(time) + " " + event.toString());
return true;
}
}
}
return false;
}
// -------- Interval interface end ---------
// ----------------- DataPointInterface --------------------

View file

@ -105,6 +105,7 @@ public class TemporaryBasal implements Interval {
this.isFakeExtended = true;
this.netExtendedRate = extendedBolus.absoluteRate();
this.absoluteRate = basal + extendedBolus.absoluteRate();
this.pumpId = extendedBolus.pumpId;
}
public TemporaryBasal clone() {
@ -221,15 +222,15 @@ public class TemporaryBasal implements Interval {
public IobTotal iobCalc(long time, Profile profile) {
if(isFakeExtended){
if (isFakeExtended) {
log.error("iobCalc should only be called on Extended boluses separately");
return new IobTotal(time);
}
IobTotal result = new IobTotal(time);
InsulinInterface insulinInterface = ConfigBuilderPlugin.getActiveInsulin();
InsulinInterface insulinInterface = ConfigBuilderPlugin.getPlugin().getActiveInsulin();
int realDuration = getDurationToTime(time);
int realDuration = getDurationToTime(time);
double netBasalAmount = 0d;
if (realDuration > 0) {
@ -292,12 +293,22 @@ public class TemporaryBasal implements Interval {
}
public double tempBasalConvertedToAbsolute(long time, Profile profile) {
if(isFakeExtended){
if (isFakeExtended) {
return profile.getBasal(time) + netExtendedRate;
} else if (isAbsolute) {
return absoluteRate;
} else {
return profile.getBasal(time) * percentRate / 100;
return profile.getBasal(time) * percentRate / 100;
}
}
public int tempBasalConvertedToPercent(long time, Profile profile) {
if (isFakeExtended) {
return (int) ((profile.getBasal(time) + netExtendedRate) / profile.getBasal(time)) * 100;
} else if (isAbsolute) {
return (int) (absoluteRate / profile.getBasal(time)) * 100;
} else {
return percentRate;
}
}
@ -318,12 +329,12 @@ public class TemporaryBasal implements Interval {
}
public String toStringFull() {
if(isFakeExtended){
if (isFakeExtended) {
Profile profile = ProfileFunctions.getInstance().getProfile();
Double currentBasalRate = profile.getBasal();
double rate = (currentBasalRate == null)?0d:(currentBasalRate+netExtendedRate);
return getCalcuatedPercentageIfNeeded() + DecimalFormatter.to2Decimal(rate) + "U/h ("+DecimalFormatter.to2Decimal(netExtendedRate)+"E) @" +
double rate = (currentBasalRate == null) ? 0d : (currentBasalRate + netExtendedRate);
return getCalcuatedPercentageIfNeeded() + DecimalFormatter.to2Decimal(rate) + "U/h (" + DecimalFormatter.to2Decimal(netExtendedRate) + "E) @" +
DateUtil.timeString(date) +
" " + getRealDuration() + "/" + durationInMinutes + "'";
} else if (isAbsolute) {
@ -340,21 +351,21 @@ public class TemporaryBasal implements Interval {
public String toStringShort() {
if (isAbsolute || isFakeExtended) {
double rate = 0d;
double rate = 0d;
if (isFakeExtended) {
Profile profile = ProfileFunctions.getInstance().getProfile();
Double currentBasalRate = profile.getBasal();
rate = (currentBasalRate == null)?0d:(currentBasalRate+netExtendedRate);
} else if (isAbsolute){
rate = (currentBasalRate == null) ? 0d : (currentBasalRate + netExtendedRate);
} else if (isAbsolute) {
rate = absoluteRate;
}
if(SP.getBoolean(R.string.key_danar_visualizeextendedaspercentage, false) && SP.getBoolean(R.string.key_danar_useextended, false)){
if (SP.getBoolean(R.string.key_danar_visualizeextendedaspercentage, false) && SP.getBoolean(R.string.key_danar_useextended, false)) {
Profile profile = ProfileFunctions.getInstance().getProfile();
if(profile != null) {
if (profile != null) {
double basal = profile.getBasal();
if(basal != 0){
return Math.round(rate*100d/basal) + "%";
if (basal != 0) {
return Math.round(rate * 100d / basal) + "%";
}
}
}
@ -364,24 +375,24 @@ public class TemporaryBasal implements Interval {
}
}
private String getCalcuatedPercentageIfNeeded(){
private String getCalcuatedPercentageIfNeeded() {
if (isAbsolute || isFakeExtended) {
double rate = 0d;
double rate = 0d;
if (isFakeExtended) {
Profile profile = ProfileFunctions.getInstance().getProfile();
Double currentBasalRate = profile.getBasal();
rate = (currentBasalRate == null)?0d:(currentBasalRate+netExtendedRate);
} else if (isAbsolute){
rate = (currentBasalRate == null) ? 0d : (currentBasalRate + netExtendedRate);
} else if (isAbsolute) {
rate = absoluteRate;
}
if(SP.getBoolean(R.string.key_danar_visualizeextendedaspercentage, false) && SP.getBoolean(R.string.key_danar_useextended, false)){
if (SP.getBoolean(R.string.key_danar_visualizeextendedaspercentage, false) && SP.getBoolean(R.string.key_danar_useextended, false)) {
Profile profile = ProfileFunctions.getInstance().getProfile();
if(profile != null) {
if (profile != null) {
double basal = profile.getBasal();
if(basal != 0){
return Math.round(rate*100d/basal) + "% ";
if (basal != 0) {
return Math.round(rate * 100d / basal) + "% ";
}
}
}
@ -392,12 +403,12 @@ public class TemporaryBasal implements Interval {
public String toStringVeryShort() {
if (isAbsolute || isFakeExtended) {
double rate = 0d;
double rate = 0d;
if (isFakeExtended) {
Profile profile = ProfileFunctions.getInstance().getProfile();
Double currentBasalRate = profile.getBasal();
rate = (currentBasalRate == null)?0d:(currentBasalRate+netExtendedRate);
} else if (isAbsolute){
rate = (currentBasalRate == null) ? 0d : (currentBasalRate + netExtendedRate);
} else if (isAbsolute) {
rate = absoluteRate;
}
return DecimalFormatter.to2Decimal(rate) + "U/h ";

View file

@ -10,9 +10,10 @@ import info.nightscout.androidaps.R;
public class EventPumpStatusChanged extends Event {
public static final int CONNECTING = 0;
public static final int CONNECTED = 1;
public static final int PERFORMING = 2;
public static final int DISCONNECTING = 3;
public static final int DISCONNECTED = 4;
public static final int HANDSHAKING = 2;
public static final int PERFORMING = 3;
public static final int DISCONNECTING = 4;
public static final int DISCONNECTED = 5;
public int sStatus = DISCONNECTED;
public int sSecondsElapsed = 0;
@ -47,6 +48,8 @@ public class EventPumpStatusChanged extends Event {
public String textStatus() {
if (sStatus == CONNECTING)
return String.format(MainApp.gs(R.string.danar_history_connectingfor), sSecondsElapsed);
else if (sStatus == HANDSHAKING)
return MainApp.gs(R.string.handshaking);
else if (sStatus == CONNECTED)
return MainApp.gs(R.string.connected);
else if (sStatus == PERFORMING)

View file

@ -13,7 +13,7 @@ import info.nightscout.androidaps.logging.L;
*/
public class Constraint<T extends Comparable> {
private static Logger log = LoggerFactory.getLogger(L.APS);
private static Logger log = LoggerFactory.getLogger(L.CONSTRAINTS);
T value;
T originalValue;
@ -37,18 +37,35 @@ public class Constraint<T extends Comparable> {
public Constraint<T> set(T value) {
this.value = value;
this.originalValue = value;
if (L.isEnabled(L.CONSTRAINTS))
log.debug("Setting value " + value);
return this;
}
public Constraint<T> set(T value, String reason, Object from) {
if (L.isEnabled(L.CONSTRAINTS))
log.debug("Setting value " + this.value + " -> " + value + " (" + reason + ")[" + translateFrom(from) + "]");
this.value = value;
addReason(reason, from);
addMostLimingReason(reason, from);
return this;
}
public Constraint<T> setIfDifferent(T value, String reason, Object from) {
if (!this.value.equals(value)) {
if (L.isEnabled(L.CONSTRAINTS))
log.debug("Setting because of different value " + this.value + " -> " + value + " (" + reason + ")[" + translateFrom(from) + "]");
this.value = value;
addReason(reason, from);
addMostLimingReason(reason, from);
}
return this;
}
public Constraint<T> setIfSmaller(T value, String reason, Object from) {
if (value.compareTo(this.value) < 0) {
if (L.isEnabled(L.CONSTRAINTS))
log.debug("Setting because of smaller value " + this.value + " -> " + value + " (" + reason + ")[" + translateFrom(from) + "]");
this.value = value;
mostLimiting.clear();
addMostLimingReason(reason, from);
@ -61,6 +78,8 @@ public class Constraint<T extends Comparable> {
public Constraint<T> setIfGreater(T value, String reason, Object from) {
if (value.compareTo(this.value) > 0) {
if (L.isEnabled(L.CONSTRAINTS))
log.debug("Setting because of greater value " + this.value + " -> " + value + " (" + reason + ")[" + translateFrom(from) + "]");
this.value = value;
mostLimiting.clear();
addMostLimingReason(reason, from);
@ -71,13 +90,17 @@ public class Constraint<T extends Comparable> {
return this;
}
private String translateFrom(Object from) {
return from.getClass().getSimpleName().replace("Plugin", "");
}
public Constraint addReason(String reason, Object from) {
reasons.add(from.getClass().getSimpleName().replace("Plugin", "") + ": " + reason);
reasons.add(translateFrom(from) + ": " + reason);
return this;
}
public Constraint addMostLimingReason(String reason, Object from) {
mostLimiting.add(from.getClass().getSimpleName().replace("Plugin", "") + ": " + reason);
mostLimiting.add(translateFrom(from) + ": " + reason);
return this;
}
@ -88,7 +111,7 @@ public class Constraint<T extends Comparable> {
if (count++ != 0) sb.append("\n");
sb.append(r);
}
if (L.isEnabled(L.APS))
if (L.isEnabled(L.CONSTRAINTS))
log.debug("Limiting origial value: " + originalValue + " to " + value + ". Reason: " + sb.toString());
return sb.toString();
}
@ -104,7 +127,8 @@ public class Constraint<T extends Comparable> {
if (count++ != 0) sb.append("\n");
sb.append(r);
}
log.debug("Limiting origial value: " + originalValue + " to " + value + ". Reason: " + sb.toString());
if (L.isEnabled(L.CONSTRAINTS))
log.debug("Limiting origial value: " + originalValue + " to " + value + ". Reason: " + sb.toString());
return sb.toString();
}

View file

@ -27,6 +27,10 @@ public interface ConstraintsInterface {
return value;
}
default Constraint<Boolean> isUAMEnabled(Constraint<Boolean> value) {
return value;
}
default Constraint<Boolean> isAdvancedFilteringEnabled(Constraint<Boolean> value) {
return value;
}
@ -43,6 +47,10 @@ public interface ConstraintsInterface {
return insulin;
}
default Constraint<Double> applyExtendedBolusConstraints(Constraint<Double> insulin) {
return insulin;
}
default Constraint<Integer> applyCarbsConstraints(Constraint<Integer> carbs) {
return carbs;
}

View file

@ -10,6 +10,7 @@ import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderFragment;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.queue.CommandQueue;
/**
* Created by mike on 09.06.2016.
@ -168,7 +169,9 @@ public abstract class PluginBase {
if (getType() == PluginType.PUMP) {
new Thread(() -> {
SystemClock.sleep(3000);
ConfigBuilderPlugin.getCommandQueue().readStatus("Pump driver changed.", null);
CommandQueue commandQueue = ConfigBuilderPlugin.getPlugin().getCommandQueue();
if (commandQueue != null)
commandQueue.readStatus("Pump driver changed.", null);
}).start();
}
}

View file

@ -1,48 +1,139 @@
package info.nightscout.androidaps.interfaces;
import info.nightscout.androidaps.plugins.PumpCommon.defs.PumpCapability;
import info.nightscout.androidaps.plugins.PumpCommon.defs.PumpTempBasalType;
import info.nightscout.androidaps.plugins.PumpCommon.defs.PumpType;
/**
* Created by mike on 08.12.2016.
*/
public class PumpDescription {
public PumpType pumpType = PumpType.GenericAAPS;
public PumpDescription () {
resetSettings();
}
public static final int NONE = 0;
public static final int PERCENT = 0x01;
public static final int ABSOLUTE = 0x02;
public boolean isBolusCapable = true;
public double bolusStep = 0.1d;
public boolean isBolusCapable;
public double bolusStep;
public boolean isExtendedBolusCapable = true;
public double extendedBolusStep = 0.1d;
public double extendedBolusDurationStep = 30;
public double extendedBolusMaxDuration = 12 * 60;
public boolean isExtendedBolusCapable;
public double extendedBolusStep;
public double extendedBolusDurationStep;
public double extendedBolusMaxDuration;
public boolean isTempBasalCapable = true;
public int tempBasalStyle = PERCENT;
public boolean isTempBasalCapable;
public int tempBasalStyle;
public int maxTempPercent = 200;
public int tempPercentStep = 10;
public int maxTempPercent;
public int tempPercentStep;
public double maxTempAbsolute = 10;
public double tempAbsoluteStep = 0.05d;
public double maxTempAbsolute;
public double tempAbsoluteStep;
public int tempDurationStep = 60;
public boolean tempDurationStep15mAllowed = false;
public boolean tempDurationStep30mAllowed = false;
public int tempMaxDuration = 12 * 60;
public int tempDurationStep;
public boolean tempDurationStep15mAllowed;
public boolean tempDurationStep30mAllowed;
public int tempMaxDuration;
public boolean isSetBasalProfileCapable;
public double basalStep;
public double basalMinimumRate;
public double basalMaximumRate;
public boolean isRefillingCapable;
public boolean storesCarbInfo;
public boolean is30minBasalRatesCapable;
public boolean supportsTDDs;
public boolean needsManualTDDLoad;
public boolean isSetBasalProfileCapable = true;
public double basalStep = 0.01d;
public double basalMinimumRate = 0.04d;
public double basalMaximumRate = 25d;
public void resetSettings() {
isBolusCapable = true;
bolusStep = 0.1d;
public boolean isRefillingCapable = false;
isExtendedBolusCapable = true;
extendedBolusStep = 0.1d;
extendedBolusDurationStep = 30;
extendedBolusMaxDuration = 12 * 60;
public boolean storesCarbInfo = true;
isTempBasalCapable = true;
tempBasalStyle = PERCENT;
maxTempPercent = 200;
tempPercentStep = 10;
maxTempAbsolute = 10;
tempAbsoluteStep = 0.05d;
tempDurationStep = 60;
tempMaxDuration = 12 * 60;
tempDurationStep15mAllowed = false;
tempDurationStep30mAllowed = false;
public boolean is30minBasalRatesCapable = false;
isSetBasalProfileCapable = true;
basalStep = 0.01d;
basalMinimumRate = 0.04d;
basalMaximumRate = 25d;
is30minBasalRatesCapable = false;
isRefillingCapable = false;
storesCarbInfo = true;
supportsTDDs = false;
needsManualTDDLoad = true;
}
public void setPumpDescription(PumpType pumpType) {
resetSettings();
this.pumpType = pumpType;
PumpCapability pumpCapability = pumpType.getPumpCapability();
isBolusCapable = pumpCapability.hasCapability(PumpCapability.Bolus);
bolusStep = pumpType.getBolusSize();
isExtendedBolusCapable = pumpCapability.hasCapability(PumpCapability.ExtendedBolus);
extendedBolusStep = pumpType.getExtendedBolusSettings().getStep();
extendedBolusDurationStep = pumpType.getExtendedBolusSettings().getDurationStep();
extendedBolusMaxDuration = pumpType.getExtendedBolusSettings().getMaxDuration();
isTempBasalCapable = pumpCapability.hasCapability(PumpCapability.TempBasal);
if (pumpType.getPumpTempBasalType() == PumpTempBasalType.Percent) {
tempBasalStyle = PERCENT;
maxTempPercent = pumpType.getTbrSettings().getMaxDose().intValue();
tempPercentStep = (int) pumpType.getTbrSettings().getStep();
} else {
tempBasalStyle = ABSOLUTE;
maxTempAbsolute = pumpType.getTbrSettings().getMaxDose();
tempAbsoluteStep = pumpType.getTbrSettings().getStep();
}
tempDurationStep = pumpType.getTbrSettings().getDurationStep();
tempMaxDuration = pumpType.getTbrSettings().getMaxDuration();
tempDurationStep15mAllowed = pumpType.getSpecialBasalDurations()
.hasCapability(PumpCapability.BasalRate_Duration15minAllowed);
tempDurationStep30mAllowed = pumpType.getSpecialBasalDurations()
.hasCapability(PumpCapability.BasalRate_Duration30minAllowed);
isSetBasalProfileCapable = pumpCapability.hasCapability(PumpCapability.BasalProfileSet);
basalStep = pumpType.getBaseBasalStep();
basalMinimumRate = pumpType.getBaseBasalMinValue();
isRefillingCapable = pumpCapability.hasCapability(PumpCapability.Refill);
storesCarbInfo = pumpCapability.hasCapability(PumpCapability.StoreCarbInfo);
supportsTDDs = pumpCapability.hasCapability(PumpCapability.TDD);
needsManualTDDLoad = pumpCapability.hasCapability(PumpCapability.ManualTDDLoad);
is30minBasalRatesCapable = pumpCapability.hasCapability(PumpCapability.BasalRate30min);
}
public boolean supportsTDDs = false;
public boolean needsManualTDDLoad = true;
}

View file

@ -11,11 +11,13 @@ import info.nightscout.androidaps.data.PumpEnactResult;
*/
public interface PumpInterface {
boolean isInitialized();
boolean isSuspended();
boolean isBusy();
boolean isConnected();
boolean isConnecting();
boolean isInitialized(); // true if pump status has been read and is ready to accept commands
boolean isSuspended(); // true if suspended (not delivering insulin)
boolean isBusy(); // if true pump is not ready to accept commands right now
boolean isConnected(); // true if BT connection is established
boolean isConnecting(); // true if BT connection is in progress
boolean isHandshakeInProgress(); // true if BT is connected but initial handshake is still in progress
void finishHandshaking(); // set initial handshake completed
void connect(String reason);
void disconnect(String reason);

View file

@ -86,7 +86,7 @@ public class L {
public static final String DATAFOOD = "DATAFOOD";
public static final String DATATREATMENTS = "DATATREATMENTS";
public static final String NSCLIENT = "NSCLIENT";
public static final String OBJECTIVES = "OBJECTIVES";
public static final String CONSTRAINTS = "CONSTRAINTS";
public static final String PUMP = "PUMP";
public static final String PUMPQUEUE = "PUMPQUEUE";
public static final String PUMPCOMM = "PUMPCOMM";
@ -101,16 +101,16 @@ public class L {
logElements.add(new LogElement(APS, true));
logElements.add(new LogElement(AUTOSENS, false));
logElements.add(new LogElement(BGSOURCE, true));
logElements.add(new LogElement(CONFIGBUILDER, true));
logElements.add(new LogElement(CONFIGBUILDER, false));
logElements.add(new LogElement(CONSTRAINTS, true));
logElements.add(new LogElement(CORE, true));
logElements.add(new LogElement(DATABASE, true));
logElements.add(new LogElement(DATAFOOD, true));
logElements.add(new LogElement(DATAFOOD, false));
logElements.add(new LogElement(DATASERVICE, true));
logElements.add(new LogElement(DATATREATMENTS, true));
logElements.add(new LogElement(EVENTS, false, true));
logElements.add(new LogElement(NOTIFICATION, true));
logElements.add(new LogElement(NSCLIENT, true));
logElements.add(new LogElement(OBJECTIVES, false));
logElements.add(new LogElement(OVERVIEW, true));
logElements.add(new LogElement(PROFILE, true));
logElements.add(new LogElement(PUMP, true));

View file

@ -126,7 +126,7 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
if (MainApp.getConfigBuilder().getActiveProfileInterface() != null && MainApp.getConfigBuilder().getActiveProfileInterface().getProfile() != null) {
if (ConfigBuilderPlugin.getPlugin().getActiveProfileInterface() != null && ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getProfile() != null) {
profileSwitch.setVisibility(View.VISIBLE);
} else {
profileSwitch.setVisibility(View.GONE);
@ -142,7 +142,7 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL
return;
}
final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
final boolean basalprofileEnabled = MainApp.isEngineeringModeOrRelease()
&& pump.getPumpDescription().isSetBasalProfileCapable;
@ -192,7 +192,7 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL
else
tempTarget.setVisibility(View.VISIBLE);
if (!ConfigBuilderPlugin.getActivePump().getPumpDescription().supportsTDDs) tddStats.setVisibility(View.GONE);
if (!ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().supportsTDDs) tddStats.setVisibility(View.GONE);
else tddStats.setVisibility(View.VISIBLE);
}
});
@ -223,13 +223,13 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL
break;
case R.id.actions_extendedbolus_cancel:
if (TreatmentsPlugin.getPlugin().isInHistoryExtendedBoluslInProgress()) {
ConfigBuilderPlugin.getCommandQueue().cancelExtended(null);
ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelExtended(null);
FabricPrivacy.getInstance().logCustom(new CustomEvent("CancelExtended"));
}
break;
case R.id.actions_canceltempbasal:
if (TreatmentsPlugin.getPlugin().isTempBasalInProgress()) {
ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, null);
ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(true, null);
FabricPrivacy.getInstance().logCustom(new CustomEvent("CancelTemp"));
}
break;

View file

@ -91,7 +91,7 @@ public class FillDialog extends DialogFragment implements OnClickListener {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.actions_fill_dialog, null, false);
View view = inflater.inflate(R.layout.actions_fill_dialog, container, false);
view.findViewById(R.id.ok).setOnClickListener(this);
view.findViewById(R.id.cancel).setOnClickListener(this);
@ -103,7 +103,7 @@ public class FillDialog extends DialogFragment implements OnClickListener {
insulinCartridgeChangeCheckbox = view.findViewById(R.id.fill_cartridge_change);
Double maxInsulin = MainApp.getConstraintChecker().getMaxBolusAllowed().value();
double bolusstep = ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep;
double bolusstep = ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().bolusStep;
editInsulin = view.findViewById(R.id.fill_insulinamount);
editInsulin.setParams(0d, 0d, maxInsulin, bolusstep, DecimalFormatter.pumpSupportedBolusFormat(), false, textWatcher);
@ -184,8 +184,8 @@ public class FillDialog extends DialogFragment implements OnClickListener {
if (insulinAfterConstraints > 0) {
confirmMessage.add(MainApp.gs(R.string.fillwarning));
confirmMessage.add("");
confirmMessage.add(MainApp.gs(R.string.bolus) + ": " + "<font color='" + MainApp.gc(R.color.colorCarbsButton) + "'>" + insulinAfterConstraints + "U" + "</font>");
if (!insulinAfterConstraints.equals(insulin))
confirmMessage.add(MainApp.gs(R.string.bolus) + ": " + "<font color='" + MainApp.gc(R.color.colorCarbsButton) + "'>" + DecimalFormatter.toPumpSupportedBolus(insulinAfterConstraints) + "U" + "</font>");
if (Math.abs(insulinAfterConstraints - insulin) > 0.01d)
confirmMessage.add("<font color='" + MainApp.gc(R.color.low) + "'>" + MainApp.gs(R.string.bolusconstraintapplied) + "</font>");
}
@ -223,7 +223,7 @@ public class FillDialog extends DialogFragment implements OnClickListener {
detailedBolusInfo.source = Source.USER;
detailedBolusInfo.isValid = false; // do not count it in IOB (for pump history)
detailedBolusInfo.notes = notes;
ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() {
ConfigBuilderPlugin.getPlugin().getCommandQueue().bolus(detailedBolusInfo, new Callback() {
@Override
public void run() {
if (!result.success) {

View file

@ -44,12 +44,12 @@ public class NewExtendedBolusDialog extends DialogFragment implements View.OnCli
View view = inflater.inflate(R.layout.overview_newextendedbolus_dialog, container, false);
Double maxInsulin = MainApp.getConstraintChecker().getMaxBolusAllowed().value();
Double maxInsulin = MainApp.getConstraintChecker().getMaxExtendedBolusAllowed().value();
editInsulin = (NumberPicker) view.findViewById(R.id.overview_newextendedbolus_insulin);
editInsulin.setParams(0d, 0d, maxInsulin, 0.1d, new DecimalFormat("0.00"), false);
double extendedDurationStep = ConfigBuilderPlugin.getActivePump().getPumpDescription().extendedBolusDurationStep;
double extendedMaxDuration = ConfigBuilderPlugin.getActivePump().getPumpDescription().extendedBolusMaxDuration;
double extendedDurationStep = ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().extendedBolusDurationStep;
double extendedMaxDuration = ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().extendedBolusMaxDuration;
editDuration = (NumberPicker) view.findViewById(R.id.overview_newextendedbolus_duration);
editDuration.setParams(extendedDurationStep, extendedDurationStep, extendedMaxDuration, extendedDurationStep, new DecimalFormat("0"), false);
@ -71,10 +71,10 @@ public class NewExtendedBolusDialog extends DialogFragment implements View.OnCli
String confirmMessage = MainApp.gs(R.string.setextendedbolusquestion);
Double insulinAfterConstraint = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(insulin)).value();
Double insulinAfterConstraint = MainApp.getConstraintChecker().applyExtendedBolusConstraints(new Constraint<>(insulin)).value();
confirmMessage += " " + insulinAfterConstraint + " U ";
confirmMessage += MainApp.gs(R.string.duration) + " " + durationInMinutes + "min ?";
if (insulinAfterConstraint - insulin != 0d)
if (Math.abs(insulinAfterConstraint - insulin) > 0.01d)
confirmMessage += "\n" + MainApp.gs(R.string.constraintapllied);
insulin = insulinAfterConstraint;
@ -87,7 +87,7 @@ public class NewExtendedBolusDialog extends DialogFragment implements View.OnCli
builder.setMessage(confirmMessage);
builder.setPositiveButton(MainApp.gs(R.string.ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
ConfigBuilderPlugin.getCommandQueue().extendedBolus(finalInsulin, finalDurationInMinutes, new Callback() {
ConfigBuilderPlugin.getPlugin().getCommandQueue().extendedBolus(finalInsulin, finalDurationInMinutes, new Callback() {
@Override
public void run() {
if (!result.success) {

View file

@ -64,7 +64,7 @@ public class NewTempBasalDialog extends DialogFragment implements View.OnClickLi
absoluteRadio = (RadioButton) view.findViewById(R.id.overview_newtempbasal_absolute_radio);
typeSelectorLayout = (LinearLayout) view.findViewById(R.id.overview_newtempbasal_typeselector_layout);
PumpDescription pumpDescription = ConfigBuilderPlugin.getActivePump().getPumpDescription();
PumpDescription pumpDescription = ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription();
basalPercent = (NumberPicker) view.findViewById(R.id.overview_newtempbasal_basalpercentinput);
double maxTempPercent = pumpDescription.maxTempPercent;
@ -136,7 +136,7 @@ public class NewTempBasalDialog extends DialogFragment implements View.OnClickLi
absolute = MainApp.getConstraintChecker().applyBasalConstraints(new Constraint<>(basalAbsoluteInput), profile).value();
confirmMessage += "\n" + absolute + " U/h ";
confirmMessage += "\n" + MainApp.gs(R.string.duration) + " " + durationInMinutes + "min ?";
if (absolute - basalAbsoluteInput != 0d)
if (Math.abs(absolute - basalAbsoluteInput) > 0.01d)
confirmMessage += "\n" + MainApp.gs(R.string.constraintapllied);
}
@ -163,9 +163,9 @@ public class NewTempBasalDialog extends DialogFragment implements View.OnClickLi
}
};
if (setAsPercent) {
ConfigBuilderPlugin.getCommandQueue().tempBasalPercent(finalBasalPercent, finalDurationInMinutes, true, profile, callback);
ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalPercent(finalBasalPercent, finalDurationInMinutes, true, profile, callback);
} else {
ConfigBuilderPlugin.getCommandQueue().tempBasalAbsolute(finalBasal, finalDurationInMinutes, true, profile, callback);
ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalAbsolute(finalBasal, finalDurationInMinutes, true, profile, callback);
}
FabricPrivacy.getInstance().logCustom(new CustomEvent("TempBasal"));
}

View file

@ -24,6 +24,7 @@ import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.events.EventCareportalEventChange;
import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialog;
import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.NSClientInternal.data.NSSettingsStatus;
import info.nightscout.androidaps.plugins.Overview.OverviewFragment;
import info.nightscout.utils.FabricPrivacy;
@ -100,7 +101,7 @@ public class CareportalFragment extends SubscriberFragment implements View.OnCli
noProfileView = view.findViewById(R.id.profileview_noprofile);
butonsLayout = (LinearLayout) view.findViewById(R.id.careportal_buttons);
ProfileStore profileStore = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile();
ProfileStore profileStore = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface() != null ? ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getProfile() : null;
if (profileStore == null) {
noProfileView.setVisibility(View.VISIBLE);
butonsLayout.setVisibility(View.GONE);

View file

@ -49,14 +49,15 @@ import info.nightscout.androidaps.db.ProfileSwitch;
import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.androidaps.plugins.Careportal.OptionsToShow;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload;
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.DefaultValueHelper;
import info.nightscout.utils.FabricPrivacy;
import info.nightscout.utils.HardLimits;
import info.nightscout.utils.JsonHelper;
import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload;
import info.nightscout.utils.NumberPicker;
import info.nightscout.utils.SP;
import info.nightscout.utils.SafeParse;
@ -173,7 +174,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
// profile
profile = ProfileFunctions.getInstance().getProfile();
profileStore = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile();
profileStore = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getProfile();
if (profileStore == null) {
if (options.eventType == R.id.careportal_profileswitch) {
log.error("Profile switch called but plugin doesn't contain valid profile");
@ -269,7 +270,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
if (profile == null) {
editBg.setParams(bg, 0d, 500d, 0.1d, new DecimalFormat("0.0"), false, bgTextWatcher);
editTemptarget.setParams(bg, 0d, 500d, 0.1d, new DecimalFormat("0.0"), false);
} else if (profile.getUnits().equals(Constants.MMOL)) {
} else if (units.equals(Constants.MMOL)) {
editBg.setParams(bg, 0d, 30d, 0.1d, new DecimalFormat("0.0"), false, bgTextWatcher);
editTemptarget.setParams(bg, 0d, 30d, 0.1d, new DecimalFormat("0.0"), false);
} else {
@ -278,7 +279,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
}
sensorRadioButton.setOnCheckedChangeListener((buttonView, isChecked) -> {
Double bg1 = Profile.fromMgdlToUnits(GlucoseStatus.getGlucoseStatusData() != null ? GlucoseStatus.getGlucoseStatusData().glucose : 0d, profile.getUnits());
Double bg1 = Profile.fromMgdlToUnits(GlucoseStatus.getGlucoseStatusData() != null ? GlucoseStatus.getGlucoseStatusData().glucose : 0d, units);
if (savedInstanceState != null && savedInstanceState.getDouble("editBg") != bg1) {
editBg.setValue(savedInstanceState.getDouble("editBg"));
} else {
@ -321,7 +322,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
if (profile != null)
maxPercent = MainApp.getConstraintChecker().getMaxBasalPercentAllowed(profile).value();
editPercent = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_percentinput);
editPercent.setParams(0d, 0d, (double) maxPercent, 5d, new DecimalFormat("0"), true, percentTextWatcher);
editPercent.setParams(0d, -100d, (double) maxPercent, 5d, new DecimalFormat("0"), true, percentTextWatcher);
TextWatcher absoluteTextWatcher = new TextWatcher() {
@Override
@ -458,7 +459,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
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));
editBg.setValue(Profile.fromMgdlToUnits(data.get(0).value, units));
}
}
@ -735,8 +736,8 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
.reason(reason)
.source(Source.USER);
if (tempTarget.durationInMinutes != 0) {
tempTarget.low(Profile.toMgdl(targetBottom, profile.getUnits()))
.high(Profile.toMgdl(targetTop, profile.getUnits()));
tempTarget.low(Profile.toMgdl(targetBottom, units))
.high(Profile.toMgdl(targetTop, units));
} else {
tempTarget.low(0).high(0);
}
@ -767,7 +768,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
profileSwitch.source = Source.USER;
profileSwitch.profileName = profileName;
profileSwitch.profileJson = profileStore.getSpecificProfile(profileName).getData().toString();
profileSwitch.profilePlugin = MainApp.getConfigBuilder().getActiveProfileInterface().getClass().getName();
profileSwitch.profilePlugin = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getClass().getName();
profileSwitch.durationInMinutes = duration;
profileSwitch.isCPP = percentage != 100 || timeshift != 0;
profileSwitch.timeshift = timeshift;
@ -789,7 +790,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
profileSwitch.source = Source.USER;
profileSwitch.profileName = ProfileFunctions.getInstance().getProfileName(System.currentTimeMillis(), false);
profileSwitch.profileJson = ProfileFunctions.getInstance().getProfile().getData().toString();
profileSwitch.profilePlugin = MainApp.getConfigBuilder().getActiveProfileInterface().getClass().getName();
profileSwitch.profilePlugin = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getClass().getName();
profileSwitch.durationInMinutes = duration;
profileSwitch.isCPP = percentage != 100 || timeshift != 0;
profileSwitch.timeshift = timeshift;

View file

@ -19,7 +19,6 @@ import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.interfaces.ProfileInterface;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.interfaces.SensitivityInterface;
import info.nightscout.androidaps.interfaces.TreatmentsInterface;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.Insulin.InsulinOrefRapidActingPlugin;
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
@ -42,16 +41,15 @@ public class ConfigBuilderPlugin extends PluginBase {
}
private BgSourceInterface activeBgSource;
private static PumpInterface activePump;
private static ProfileInterface activeProfile;
private static TreatmentsInterface activeTreatments;
private static APSInterface activeAPS;
private static InsulinInterface activeInsulin;
private static SensitivityInterface activeSensitivity;
private PumpInterface activePump;
private ProfileInterface activeProfile;
private APSInterface activeAPS;
private InsulinInterface activeInsulin;
private SensitivityInterface activeSensitivity;
private static ArrayList<PluginBase> pluginList;
private ArrayList<PluginBase> pluginList;
private static CommandQueue commandQueue = new CommandQueue();
private CommandQueue commandQueue = new CommandQueue();
public ConfigBuilderPlugin() {
super(new PluginDescription()
@ -230,7 +228,7 @@ public class ConfigBuilderPlugin extends PluginBase {
}
}
public static CommandQueue getCommandQueue() {
public CommandQueue getCommandQueue() {
return commandQueue;
}
@ -242,19 +240,19 @@ public class ConfigBuilderPlugin extends PluginBase {
return activeProfile;
}
public static InsulinInterface getActiveInsulin() {
public InsulinInterface getActiveInsulin() {
return activeInsulin;
}
public static APSInterface getActiveAPS() {
public APSInterface getActiveAPS() {
return activeAPS;
}
public static PumpInterface getActivePump() {
public PumpInterface getActivePump() {
return activePump;
}
public static SensitivityInterface getActiveSensitivity() {
public SensitivityInterface getActiveSensitivity() {
return activeSensitivity;
}
@ -322,7 +320,6 @@ public class ConfigBuilderPlugin extends PluginBase {
this.setFragmentVisiblities(((PluginBase) activePump).getName(), pluginsInCategory, PluginType.PUMP);
// PluginType.TREATMENT
activeTreatments = this.determineActivePlugin(PluginType.TREATMENT);
}
/**

View file

@ -49,7 +49,7 @@ public class ProfileFunctions {
public void onProfileSwitch(EventProfileSwitchChange ignored) {
if (L.isEnabled(L.PROFILE))
log.debug("onProfileSwitch");
MainApp.getConfigBuilder().getCommandQueue().setProfile(getProfile(), new Callback() {
ConfigBuilderPlugin.getPlugin().getCommandQueue().setProfile(getProfile(), new Callback() {
@Override
public void run() {
if (!result.success) {
@ -79,7 +79,7 @@ public class ProfileFunctions {
public String getProfileName(long time, boolean customized) {
TreatmentsInterface activeTreatments = TreatmentsPlugin.getPlugin();
ProfileInterface activeProfile = MainApp.getConfigBuilder().getActiveProfileInterface();
ProfileInterface activeProfile = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface();
ProfileSwitch profileSwitch = activeTreatments.getProfileSwitchFromHistory(time);
if (profileSwitch != null) {
@ -114,7 +114,7 @@ public class ProfileFunctions {
@Nullable
public Profile getProfile(long time) {
TreatmentsInterface activeTreatments = TreatmentsPlugin.getPlugin();
ProfileInterface activeProfile = MainApp.getConfigBuilder().getActiveProfileInterface();
ProfileInterface activeProfile = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface();
//log.debug("Profile for: " + new Date(time).toLocaleString() + " : " + getProfileName(time));
ProfileSwitch profileSwitch = activeTreatments.getProfileSwitchFromHistory(time);

View file

@ -55,7 +55,7 @@ public class ObjectivesFragment extends SubscriberFragment {
enableFake.setOnClickListener(v -> updateGUI());
reset.setOnClickListener(v -> {
ObjectivesPlugin.getPlugin().reset();
ObjectivesPlugin.saveProgress();
ObjectivesPlugin.getPlugin().saveProgress();
recyclerView.getAdapter().notifyDataSetChanged();
scrollToCurrentObjective();
});
@ -77,7 +77,7 @@ public class ObjectivesFragment extends SubscriberFragment {
private void startUpdateTimer() {
handler.removeCallbacks(objectiveUpdater);
for (Objective objective : ObjectivesPlugin.getObjectives()) {
for (Objective objective : ObjectivesPlugin.getPlugin().getObjectives()) {
if (objective.isStarted() && !objective.isAccomplished()) {
long timeTillNextMinute = (System.currentTimeMillis() - objective.getStartedOn().getTime()) % (60 * 1000);
handler.postDelayed(objectiveUpdater, timeTillNextMinute);
@ -87,8 +87,8 @@ public class ObjectivesFragment extends SubscriberFragment {
}
private void scrollToCurrentObjective() {
for (int i = 0; i < ObjectivesPlugin.getObjectives().size(); i++) {
Objective objective = ObjectivesPlugin.getObjectives().get(i);
for (int i = 0; i < ObjectivesPlugin.getPlugin().getObjectives().size(); i++) {
Objective objective = ObjectivesPlugin.getPlugin().getObjectives().get(i);
if (!objective.isStarted() || !objective.isAccomplished()) {
RecyclerView.SmoothScroller smoothScroller = new LinearSmoothScroller(getContext()) {
@Override
@ -118,7 +118,7 @@ public class ObjectivesFragment extends SubscriberFragment {
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Objective objective = ObjectivesPlugin.getObjectives().get(position);
Objective objective = ObjectivesPlugin.getPlugin().getObjectives().get(position);
holder.title.setText(MainApp.gs(R.string.nth_objective, position + 1));
if (objective.getObjective() != 0) {
holder.objective.setVisibility(View.VISIBLE);
@ -132,7 +132,7 @@ public class ObjectivesFragment extends SubscriberFragment {
holder.gate.setTextColor(0xFFFFFFFF);
holder.verify.setVisibility(View.GONE);
holder.progress.setVisibility(View.GONE);
if (position == 0 || ObjectivesPlugin.getObjectives().get(position - 1).isAccomplished())
if (position == 0 || ObjectivesPlugin.getPlugin().getObjectives().get(position - 1).isAccomplished())
holder.start.setVisibility(View.VISIBLE);
else holder.start.setVisibility(View.GONE);
} else if (objective.isAccomplished()) {
@ -173,7 +173,7 @@ public class ObjectivesFragment extends SubscriberFragment {
@Override
public int getItemCount() {
return ObjectivesPlugin.getObjectives().size();
return ObjectivesPlugin.getPlugin().getObjectives().size();
}
public class ViewHolder extends RecyclerView.ViewHolder {

View file

@ -33,14 +33,14 @@ import info.nightscout.utils.SP;
* Created by mike on 05.08.2016.
*/
public class ObjectivesPlugin extends PluginBase implements ConstraintsInterface {
private static Logger log = LoggerFactory.getLogger(L.OBJECTIVES);
private static Logger log = LoggerFactory.getLogger(L.CONSTRAINTS);
private static ObjectivesPlugin objectivesPlugin;
public static List<Objective> objectives = new ArrayList<>();
public static boolean bgIsAvailableInNS = false;
public static boolean pumpStatusIsAvailableInNS = false;
public static Integer manualEnacts = 0;
public List<Objective> objectives = new ArrayList<>();
public boolean bgIsAvailableInNS = false;
public boolean pumpStatusIsAvailableInNS = false;
public Integer manualEnacts = 0;
public static ObjectivesPlugin getPlugin() {
if (objectivesPlugin == null) {
@ -65,7 +65,7 @@ public class ObjectivesPlugin extends PluginBase implements ConstraintsInterface
@Override
public boolean specialEnableCondition() {
PumpInterface pump = ConfigBuilderPlugin.getActivePump();
PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
return pump == null || pump.getPumpDescription().isTempBasalCapable;
}
@ -91,11 +91,11 @@ public class ObjectivesPlugin extends PluginBase implements ConstraintsInterface
saveProgress();
}
public static void saveProgress() {
public void saveProgress() {
SP.putBoolean("Objectives" + "bgIsAvailableInNS", bgIsAvailableInNS);
SP.putBoolean("Objectives" + "pumpStatusIsAvailableInNS", pumpStatusIsAvailableInNS);
SP.putString("Objectives" + "manualEnacts", Integer.toString(manualEnacts));
if (L.isEnabled(L.OBJECTIVES))
if (L.isEnabled(L.CONSTRAINTS))
log.debug("Objectives stored");
MainApp.bus().post(new EventObjectivesSaved());
}
@ -108,11 +108,11 @@ public class ObjectivesPlugin extends PluginBase implements ConstraintsInterface
} catch (Exception e) {
log.error("Unhandled exception", e);
}
if (L.isEnabled(L.OBJECTIVES))
if (L.isEnabled(L.CONSTRAINTS))
log.debug("Objectives loaded");
}
public static List<Objective> getObjectives() {
public List<Objective> getObjectives() {
return objectives;
}

View file

@ -9,6 +9,7 @@ import java.util.List;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.utils.SP;
import info.nightscout.utils.T;
public abstract class Objective {
@ -128,9 +129,9 @@ public abstract class Objective {
}
private String getDurationText(long duration) {
int days = (int) Math.floor((double) duration / (24D * 60D * 60D * 1000D));
int hours = (int) Math.floor((double) duration / (60D * 60D * 1000D));
int minutes = (int) Math.floor((double) duration / (60D * 1000D));
int days = (int) Math.floor((double) duration / T.days(1).msecs());
int hours = (int) Math.floor((double) duration / T.hours(1).msecs());
int minutes = (int) Math.floor((double) duration / T.mins(1).msecs());
if (days > 0) return MainApp.gq(R.plurals.objective_days, days, days);
else if (hours > 0) return MainApp.gq(R.plurals.objective_hours, hours, hours);
else return MainApp.gq(R.plurals.objective_minutes, minutes, minutes);

View file

@ -27,7 +27,7 @@ public class Objective1 extends Objective {
tasks.add(new Task(R.string.objectives_bgavailableinns) {
@Override
public boolean isCompleted() {
return ObjectivesPlugin.bgIsAvailableInNS;
return ObjectivesPlugin.getPlugin().bgIsAvailableInNS;
}
});
tasks.add(new Task(R.string.nsclienthaswritepermission) {
@ -50,7 +50,7 @@ public class Objective1 extends Objective {
tasks.add(new Task(R.string.objectives_pumpstatusavailableinns) {
@Override
public boolean isCompleted() {
return ObjectivesPlugin.pumpStatusIsAvailableInNS;
return ObjectivesPlugin.getPlugin().pumpStatusIsAvailableInNS;
}
});
tasks.add(new Task(R.string.hasbgdata) {
@ -68,7 +68,7 @@ public class Objective1 extends Objective {
tasks.add(new Task(R.string.apsselected) {
@Override
public boolean isCompleted() {
APSInterface usedAPS = ConfigBuilderPlugin.getActiveAPS();
APSInterface usedAPS = ConfigBuilderPlugin.getPlugin().getActiveAPS();
if (usedAPS != null && ((PluginBase) usedAPS).isEnabled(PluginType.APS))
return true;
return false;

View file

@ -5,10 +5,11 @@ import java.util.List;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin;
import info.nightscout.utils.T;
public class Objective2 extends Objective {
public static final int MANUAL_ENACTS_NEEDED = 20;
public final int MANUAL_ENACTS_NEEDED = 20;
public Objective2() {
super(1, R.string.objectives_1_objective, R.string.objectives_1_gate);
@ -16,17 +17,19 @@ public class Objective2 extends Objective {
@Override
protected void setupTasks(List<Task> tasks) {
tasks.add(new MinimumDurationTask(7L * 24L * 60L * 60L * 1000L));
tasks.add(new MinimumDurationTask(T.days(7).msecs()));
tasks.add(new Task(R.string.objectives_manualenacts) {
@Override
public boolean isCompleted() {
return ObjectivesPlugin.manualEnacts >= MANUAL_ENACTS_NEEDED;
return ObjectivesPlugin.getPlugin().manualEnacts >= MANUAL_ENACTS_NEEDED;
}
@Override
public String getProgress() {
if (ObjectivesPlugin.manualEnacts >= MANUAL_ENACTS_NEEDED) return MainApp.gs(R.string.completed_well_done);
else return ObjectivesPlugin.manualEnacts + " / " + MANUAL_ENACTS_NEEDED;
if (ObjectivesPlugin.getPlugin().manualEnacts >= MANUAL_ENACTS_NEEDED)
return MainApp.gs(R.string.completed_well_done);
else
return ObjectivesPlugin.getPlugin().manualEnacts + " / " + MANUAL_ENACTS_NEEDED;
}
});
}

View file

@ -5,6 +5,7 @@ import java.util.List;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.plugins.ConstraintsSafety.SafetyPlugin;
import info.nightscout.utils.T;
public class Objective4 extends Objective {
@ -14,7 +15,7 @@ public class Objective4 extends Objective {
@Override
protected void setupTasks(List<Task> tasks) {
tasks.add(new MinimumDurationTask(5L * 24L * 60L * 60L * 1000L));
tasks.add(new MinimumDurationTask(T.days(5).msecs()));
tasks.add(new Task(R.string.closedmodeenabled) {
@Override
public boolean isCompleted() {

View file

@ -4,6 +4,7 @@ import java.util.List;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.utils.T;
public class Objective5 extends Objective {
@ -13,7 +14,7 @@ public class Objective5 extends Objective {
@Override
protected void setupTasks(List<Task> tasks) {
tasks.add(new MinimumDurationTask(24L * 60L * 60L * 1000L));
tasks.add(new MinimumDurationTask(T.days(1).msecs()));
tasks.add(new Task(R.string.maxiobset) {
@Override
public boolean isCompleted() {

View file

@ -3,6 +3,7 @@ package info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives;
import java.util.List;
import info.nightscout.androidaps.R;
import info.nightscout.utils.T;
public class Objective6 extends Objective {
@ -12,6 +13,6 @@ public class Objective6 extends Objective {
@Override
protected void setupTasks(List<Task> tasks) {
tasks.add(new MinimumDurationTask(7L * 24L * 60L * 60L * 1000L));
tasks.add(new MinimumDurationTask(T.days(7).msecs()));
}
}

View file

@ -3,6 +3,7 @@ package info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives;
import java.util.List;
import info.nightscout.androidaps.R;
import info.nightscout.utils.T;
public class Objective7 extends Objective {
@ -12,6 +13,6 @@ public class Objective7 extends Objective {
@Override
protected void setupTasks(List<Task> tasks) {
tasks.add(new MinimumDurationTask(28L * 24L * 60L * 60L * 1000L));
tasks.add(new MinimumDurationTask(T.days(28).msecs()));
}
}

View file

@ -3,6 +3,7 @@ package info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives;
import java.util.List;
import info.nightscout.androidaps.R;
import info.nightscout.utils.T;
public class Objective8 extends Objective {
@ -12,6 +13,6 @@ public class Objective8 extends Objective {
@Override
protected void setupTasks(List<Task> tasks) {
tasks.add(new MinimumDurationTask(28L * 24L * 60L * 60L * 1000L));
tasks.add(new MinimumDurationTask(T.days(28).msecs()));
}
}

View file

@ -10,12 +10,15 @@ import info.nightscout.androidaps.interfaces.ConstraintsInterface;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.PluginDescription;
import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.interfaces.PumpDescription;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
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.events.EventNewNotification;
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityOref1Plugin;
import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.HardLimits;
import info.nightscout.utils.Round;
@ -50,7 +53,7 @@ public class SafetyPlugin extends PluginBase implements ConstraintsInterface {
**/
@Override
public Constraint<Boolean> isLoopInvocationAllowed(Constraint<Boolean> value) {
if (!ConfigBuilderPlugin.getActivePump().getPumpDescription().isTempBasalCapable)
if (!ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().isTempBasalCapable)
value.set(false, MainApp.gs(R.string.pumpisnottempbasalcapable), this);
return value;
}
@ -92,9 +95,20 @@ public class SafetyPlugin extends PluginBase implements ConstraintsInterface {
return value;
}
@Override
public Constraint<Boolean> isUAMEnabled(Constraint<Boolean> value) {
boolean enabled = SP.getBoolean(R.string.key_use_uam, false);
if (!enabled)
value.set(false, MainApp.gs(R.string.uamdisabledinpreferences), this);
boolean oref1Enabled = SensitivityOref1Plugin.getPlugin().isEnabled(PluginType.SENSITIVITY);
if (!oref1Enabled)
value.set(false, MainApp.gs(R.string.uamdisabledoref1notselected), this);
return value;
}
@Override
public Constraint<Boolean> isAdvancedFilteringEnabled(Constraint<Boolean> value) {
BgSourceInterface bgSource = MainApp.getConfigBuilder().getActiveBgSource();
BgSourceInterface bgSource = ConfigBuilderPlugin.getPlugin().getActiveBgSource();
if (bgSource != null) {
if (!bgSource.advancedFilteringSupported())
@ -121,6 +135,18 @@ public class SafetyPlugin extends PluginBase implements ConstraintsInterface {
absoluteRate.setIfSmaller(maxFromDaily, String.format(MainApp.gs(R.string.limitingbasalratio), maxFromDaily, MainApp.gs(R.string.maxdailybasalmultiplier)), this);
absoluteRate.setIfSmaller(HardLimits.maxBasal(), String.format(MainApp.gs(R.string.limitingbasalratio), HardLimits.maxBasal(), MainApp.gs(R.string.hardlimit)), this);
PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
// check for pump max
if (pump != null && pump.getPumpDescription().tempBasalStyle == PumpDescription.ABSOLUTE) {
double pumpLimit = pump.getPumpDescription().pumpType.getTbrSettings().getMaxDose();
absoluteRate.setIfSmaller(pumpLimit, String.format(MainApp.gs(R.string.limitingbasalratio), pumpLimit, MainApp.gs(R.string.pumplimit)), this);
}
// do rounding
if (pump != null && pump.getPumpDescription().tempBasalStyle == PumpDescription.ABSOLUTE) {
absoluteRate.set(Round.roundTo(absoluteRate.value(), pump.getPumpDescription().tempAbsoluteStep));
}
return absoluteRate;
}
@ -136,13 +162,23 @@ public class SafetyPlugin extends PluginBase implements ConstraintsInterface {
applyBasalConstraints(absoluteConstraint, profile);
percentRate.copyReasons(absoluteConstraint);
PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
Integer percentRateAfterConst = Double.valueOf(absoluteConstraint.value() / currentBasal * 100).intValue();
if (percentRateAfterConst < 100)
percentRateAfterConst = Round.ceilTo((double) percentRateAfterConst, 10d).intValue();
else percentRateAfterConst = Round.floorTo((double) percentRateAfterConst, 10d).intValue();
if (pump != null) {
if (percentRateAfterConst < 100)
percentRateAfterConst = Round.ceilTo((double) percentRateAfterConst, (double) pump.getPumpDescription().tempPercentStep).intValue();
else
percentRateAfterConst = Round.floorTo((double) percentRateAfterConst, (double) pump.getPumpDescription().tempPercentStep).intValue();
}
percentRate.set(percentRateAfterConst, String.format(MainApp.gs(R.string.limitingpercentrate), percentRateAfterConst, MainApp.gs(R.string.pumplimit)), this);
if (pump != null && pump.getPumpDescription().tempBasalStyle == PumpDescription.PERCENT) {
double pumpLimit = pump.getPumpDescription().pumpType.getTbrSettings().getMaxDose();
percentRate.setIfSmaller((int) pumpLimit, String.format(MainApp.gs(R.string.limitingbasalratio), pumpLimit, MainApp.gs(R.string.pumplimit)), this);
}
return percentRate;
}
@ -154,6 +190,29 @@ public class SafetyPlugin extends PluginBase implements ConstraintsInterface {
insulin.setIfSmaller(maxBolus, String.format(MainApp.gs(R.string.limitingbolus), maxBolus, MainApp.gs(R.string.maxvalueinpreferences)), this);
insulin.setIfSmaller(HardLimits.maxBolus(), String.format(MainApp.gs(R.string.limitingbolus), HardLimits.maxBolus(), MainApp.gs(R.string.hardlimit)), this);
PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
if (pump != null) {
double rounded = Round.roundTo(insulin.value(), pump.getPumpDescription().pumpType.determineCorrectBolusSize(insulin.value()));
insulin.setIfDifferent(rounded, MainApp.gs(R.string.pumplimit), this);
}
return insulin;
}
@Override
public Constraint<Double> applyExtendedBolusConstraints(Constraint<Double> insulin) {
insulin.setIfGreater(0d, String.format(MainApp.gs(R.string.limitingextendedbolus), 0d, MainApp.gs(R.string.itmustbepositivevalue)), this);
Double maxBolus = SP.getDouble(R.string.key_treatmentssafety_maxbolus, 3d);
insulin.setIfSmaller(maxBolus, String.format(MainApp.gs(R.string.limitingextendedbolus), maxBolus, MainApp.gs(R.string.maxvalueinpreferences)), this);
insulin.setIfSmaller(HardLimits.maxBolus(), String.format(MainApp.gs(R.string.limitingextendedbolus), HardLimits.maxBolus(), MainApp.gs(R.string.hardlimit)), this);
PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
if (pump != null) {
double rounded = Round.roundTo(insulin.value(), pump.getPumpDescription().pumpType.determineCorrectExtendedBolusSize(insulin.value()));
insulin.setIfDifferent(rounded, MainApp.gs(R.string.pumplimit), this);
}
return insulin;
}

View file

@ -121,13 +121,9 @@ public class FoodService extends OrmLiteBaseService<DatabaseHelper> {
}
public void onUpgrade(ConnectionSource connectionSource, int oldVersion, int newVersion) {
if (oldVersion == 7 && newVersion == 8) {
log.debug("Upgrading database from v7 to v8");
} else {
if (L.isEnabled(L.DATAFOOD))
log.info("onUpgrade");
if (L.isEnabled(L.DATAFOOD))
log.info("onUpgrade");
// this.resetFood();
}
}
public void onDowngrade(ConnectionSource connectionSource, int oldVersion, int newVersion) {

View file

@ -50,10 +50,10 @@ public class InsulinFragment extends Fragment {
}
private void updateGUI() {
insulinName.setText(ConfigBuilderPlugin.getActiveInsulin().getFriendlyName());
insulinComment.setText(ConfigBuilderPlugin.getActiveInsulin().getComment());
insulinDia.setText(MainApp.gs(R.string.dia) + " " + Double.toString(ConfigBuilderPlugin.getActiveInsulin().getDia()) + "h");
insulinGraph.show(ConfigBuilderPlugin.getActiveInsulin());
insulinName.setText(ConfigBuilderPlugin.getPlugin().getActiveInsulin().getFriendlyName());
insulinComment.setText(ConfigBuilderPlugin.getPlugin().getActiveInsulin().getComment());
insulinDia.setText(MainApp.gs(R.string.dia) + " " + Double.toString(ConfigBuilderPlugin.getPlugin().getActiveInsulin().getDia()) + "h");
insulinGraph.show(ConfigBuilderPlugin.getPlugin().getActiveInsulin());
}
}

View file

@ -21,6 +21,7 @@ import info.nightscout.androidaps.plugins.Overview.graphExtensions.Scale;
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityAAPSPlugin;
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityWeightedAveragePlugin;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.SP;
/**
@ -40,7 +41,7 @@ public class AutosensData implements DataPointWithLabelInterface {
double min5minCarbImpact = 0d;
double remaining = 0d;
public CarbsInPast(Treatment t) {
CarbsInPast(Treatment t) {
time = t.date;
carbs = t.carbs;
remaining = t.carbs;
@ -56,6 +57,18 @@ public class AutosensData implements DataPointWithLabelInterface {
min5minCarbImpact = SP.getDouble(R.string.key_openapsama_min_5m_carbimpact, SMBDefaults.min_5m_carbimpact);
}
}
CarbsInPast (CarbsInPast other) {
this.time = other.time;
this.carbs = other.carbs;
this.min5minCarbImpact = other.min5minCarbImpact;
this.remaining = other.remaining;
}
@Override
public String toString() {
return String.format("CarbsInPast: time: %s carbs: %.02f min5minCI: %.02f remaining: %.2f", new Date(time).toLocaleString(), carbs, min5minCarbImpact, remaining);
}
}
public long time = 0L;
@ -89,11 +102,18 @@ public class AutosensData implements DataPointWithLabelInterface {
@Override
public String toString() {
return "AutosensData: " + new Date(time).toLocaleString() + " " + pastSensitivity + " Delta=" + delta + " avgDelta=" + avgDelta + " Bgi=" + bgi + " Deviation=" + deviation + " avgDeviation=" + avgDeviation + " Absorbed=" + absorbed + " CarbsFromBolus=" + carbsFromBolus + " COB=" + cob + " autosensRatio=" + autosensResult.ratio + " slopeFromMaxDeviation=" + slopeFromMaxDeviation + " slopeFromMinDeviation=" + slopeFromMinDeviation;
return String.format("AutosensData: %s pastSensitivity=%s delta=%.02f avgDelta=%.02f bgi=%.02f deviation=%.02f avgDeviation=%.02f absorbed=%.02f carbsFromBolus=%.02f cob=%.02f autosensRatio=%.02f slopeFromMaxDeviation=%.02f slopeFromMinDeviation=%.02f activeCarbsList=%s",
new Date(time).toLocaleString(), pastSensitivity, delta, avgDelta, bgi, deviation, avgDeviation, absorbed, carbsFromBolus, cob, autosensResult.ratio, slopeFromMaxDeviation, slopeFromMinDeviation, activeCarbsList.toString());
}
public int minOld() {
return (int) ((System.currentTimeMillis() - time) / 1000 / 60);
public List<CarbsInPast> cloneCarbsList() {
List<CarbsInPast> newActiveCarbsList = new ArrayList<>();
for(CarbsInPast c: activeCarbsList) {
newActiveCarbsList.add(new CarbsInPast(c));
}
return newActiveCarbsList;
}
// remove carbs older than timeframe
@ -111,7 +131,7 @@ public class AutosensData implements DataPointWithLabelInterface {
if (c.remaining > 0)
cob -= c.remaining;
if (L.isEnabled(L.AUTOSENS))
log.debug("Removing carbs at " + new Date(toTime).toLocaleString() + " + after " + maxAbsorptionHours + "h :" + new Date(c.time).toLocaleString());
log.debug("Removing carbs at " + new Date(toTime).toLocaleString() + " after " + maxAbsorptionHours + "h > " + c.toString());
}
}
}

View file

@ -135,18 +135,21 @@ public class IobCobCalculatorPlugin extends PluginBase {
long bgTime = bgReadings.get(i).date;
long lastbgTime = bgReadings.get(i - 1).date;
long diff = lastbgTime - bgTime;
diff %= T.mins(5).msecs();
if (diff > T.mins(2).plus(T.secs(30)).msecs())
diff = diff - T.mins(5).msecs();
totalDiff += diff;
if (diff > T.secs(30).msecs() && diff < T.secs(270).msecs()) { // 0:30 - 4:30
diff = Math.abs(diff);
if (diff > T.secs(30).msecs()) {
if (L.isEnabled(L.AUTOSENS))
log.debug("Interval detection: values: " + bgReadings.size() + " diff: " + (diff / 1000) + "sec is5minData: " + false);
log.debug("Interval detection: values: " + bgReadings.size() + " diff: " + (diff / 1000) + "[s] is5minData: " + false);
return false;
}
}
double intervals = totalDiff / (5 * 60 * 1000d);
double variability = Math.abs(intervals - Math.round(intervals));
boolean is5mindata = variability < 0.02;
long averageDiff = totalDiff / bgReadings.size() / 1000;
boolean is5mindata = averageDiff < 1;
if (L.isEnabled(L.AUTOSENS))
log.debug("Interval detection: values: " + bgReadings.size() + " variability: " + variability + " is5minData: " + is5mindata);
log.debug("Interval detection: values: " + bgReadings.size() + " averageDiff: " + averageDiff + "[s] is5minData: " + is5mindata);
return is5mindata;
}
}
@ -165,7 +168,7 @@ public class IobCobCalculatorPlugin extends PluginBase {
for (int i = 1; i < bgReadings.size(); ++i) {
if (bgReadings.get(i).date == time) return bgReadings.get(i);
if (bgReadings.get(i).date > time) continue;
lastFound = bgReadings.get(i-1);
lastFound = bgReadings.get(i - 1);
if (bgReadings.get(i).date < time) break;
}
return lastFound;
@ -228,13 +231,15 @@ public class IobCobCalculatorPlugin extends PluginBase {
bucketed_data = new ArrayList<>();
bucketed_data.add(bgReadings.get(0));
if (L.isEnabled(L.AUTOSENS))
log.debug("Adding. bgTime: " + DateUtil.toISOString(bgReadings.get(0).date) + " lastbgTime: " + "none-first-value" + " " + bgReadings.get(0).toString());
int j = 0;
for (int i = 1; i < bgReadings.size(); ++i) {
long bgTime = bgReadings.get(i).date;
long lastbgTime = bgReadings.get(i - 1).date;
//log.error("Processing " + i + ": " + new Date(bgTime).toString() + " " + bgReadings.get(i).value + " Previous: " + new Date(lastbgTime).toString() + " " + bgReadings.get(i - 1).value);
if (bgReadings.get(i).value < 39 || bgReadings.get(i - 1).value < 39) {
continue;
throw new IllegalStateException("<39");
}
long elapsed_minutes = (bgTime - lastbgTime) / (60 * 1000);
@ -255,7 +260,8 @@ public class IobCobCalculatorPlugin extends PluginBase {
newBgreading.value = Math.round(nextbg);
//console.error("Interpolated", bucketed_data[j]);
bucketed_data.add(newBgreading);
//log.error("******************************************************************************************************* Adding:" + new Date(newBgreading.date).toString() + " " + newBgreading.value);
if (L.isEnabled(L.AUTOSENS))
log.debug("Adding. bgTime: " + DateUtil.toISOString(bgTime) + " lastbgTime: " + DateUtil.toISOString(lastbgTime) + " " + newBgreading.toString());
elapsed_minutes = elapsed_minutes - 5;
lastbg = nextbg;
@ -266,14 +272,16 @@ public class IobCobCalculatorPlugin extends PluginBase {
newBgreading.value = bgReadings.get(i).value;
newBgreading.date = bgTime;
bucketed_data.add(newBgreading);
//log.error("******************************************************************************************************* Copying:" + new Date(newBgreading.date).toString() + " " + newBgreading.value);
if (L.isEnabled(L.AUTOSENS))
log.debug("Adding. bgTime: " + DateUtil.toISOString(bgTime) + " lastbgTime: " + DateUtil.toISOString(lastbgTime) + " " + newBgreading.toString());
} else if (Math.abs(elapsed_minutes) > 2) {
j++;
BgReading newBgreading = new BgReading();
newBgreading.value = bgReadings.get(i).value;
newBgreading.date = bgTime;
bucketed_data.add(newBgreading);
//log.error("******************************************************************************************************* Copying:" + new Date(newBgreading.date).toString() + " " + newBgreading.value);
if (L.isEnabled(L.AUTOSENS))
log.debug("Adding. bgTime: " + DateUtil.toISOString(bgTime) + " lastbgTime: " + DateUtil.toISOString(lastbgTime) + " " + newBgreading.toString());
} else {
bucketed_data.get(j).value = (bucketed_data.get(j).value + bgReadings.get(i).value) / 2;
//log.error("***** Average");
@ -281,12 +289,20 @@ public class IobCobCalculatorPlugin extends PluginBase {
}
// Normalize bucketed data
for (int i = bucketed_data.size() - 2; i > 0; i--) {
for (int i = bucketed_data.size() - 2; i >= 0; i--) {
BgReading current = bucketed_data.get(i);
BgReading previous = bucketed_data.get(i + 1);
long msecDiff = current.date - previous.date;
long adjusted = (msecDiff - T.mins(5).msecs()) / 1000;
log.debug("Adjusting bucketed data time. Current: " + DateUtil.toISOString(current.date) + " to: " + DateUtil.toISOString(previous.date + T.mins(5).msecs()) + " by " + adjusted + " sec");
if (L.isEnabled(L.AUTOSENS))
log.debug("Adjusting bucketed data time. Current: " + DateUtil.toISOString(current.date) + " to: " + DateUtil.toISOString(previous.date + T.mins(5).msecs()) + " by " + adjusted + " sec");
if (Math.abs(adjusted) > 90) {
// too big adjustment, fallback to non 5 min data
if (L.isEnabled(L.AUTOSENS))
log.debug("Fallback to non 5 min data");
createBucketedDataRecalculated();
return;
}
current.date = previous.date + T.mins(5).msecs();
}
@ -523,7 +539,7 @@ public class IobCobCalculatorPlugin extends PluginBase {
public AutosensResult detectSensitivityWithLock(long fromTime, long toTime) {
synchronized (dataLock) {
return ConfigBuilderPlugin.getActiveSensitivity().detectSensitivity(this, fromTime, toTime);
return ConfigBuilderPlugin.getPlugin().getActiveSensitivity().detectSensitivity(this, fromTime, toTime);
}
}
@ -590,7 +606,7 @@ public class IobCobCalculatorPlugin extends PluginBase {
log.debug("Ignoring event for non default instance");
return;
}
if (MainApp.getConfigBuilder() == null)
if (ConfigBuilderPlugin.getPlugin() == null)
return; // app still initializing
Profile profile = ProfileFunctions.getInstance().getProfile();
if (profile == null)

View file

@ -26,14 +26,20 @@ import info.nightscout.androidaps.db.BgReading;
import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.androidaps.events.Event;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished;
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventIobCalculationProgress;
import info.nightscout.androidaps.plugins.OpenAPSSMB.SMBDefaults;
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.FabricPrivacy;
import info.nightscout.utils.MidnightTime;
import info.nightscout.utils.Profiler;
import info.nightscout.utils.SP;
import static info.nightscout.utils.DateUtil.now;
@ -71,11 +77,12 @@ public class IobCobOref1Thread extends Thread {
@Override
public final void run() {
long start = DateUtil.now();
mWakeLock.acquire();
try {
if (L.isEnabled(L.AUTOSENS))
log.debug("AUTOSENSDATA thread started: " + from);
if (MainApp.getConfigBuilder() == null) {
if (ConfigBuilderPlugin.getPlugin() == null) {
if (L.isEnabled(L.AUTOSENS))
log.debug("Aborting calculation thread (ConfigBuilder not ready): " + from);
return; // app still initializing
@ -145,7 +152,7 @@ public class IobCobOref1Thread extends Thread {
AutosensData autosensData = new AutosensData();
autosensData.time = bgTime;
if (previous != null)
autosensData.activeCarbsList = new ArrayList<>(previous.activeCarbsList);
autosensData.activeCarbsList = previous.cloneCarbsList();
else
autosensData.activeCarbsList = new ArrayList<>();
@ -180,11 +187,24 @@ public class IobCobOref1Thread extends Thread {
if (hourAgoData != null) {
int initialIndex = autosensDataTable.indexOfKey(hourAgoData.time);
if (L.isEnabled(L.AUTOSENS))
log.debug(">>>>> bucketed_data.size()=" + bucketed_data.size() + " i=" + i + "hourAgoData=" + hourAgoData.toString());
log.debug(">>>>> bucketed_data.size()=" + bucketed_data.size() + " i=" + i + " hourAgoData=" + hourAgoData.toString());
int past = 1;
try {
for (; past < 12; past++) {
AutosensData ad = autosensDataTable.valueAt(initialIndex + past);
if (L.isEnabled(L.AUTOSENS)) {
log.debug(">>>>> past=" + past + " ad=" + (ad != null ? ad.toString() : null));
if (ad == null) {
log.debug(autosensDataTable.toString());
log.debug(bucketed_data.toString());
log.debug(IobCobCalculatorPlugin.getPlugin().getBgReadings().toString());
Notification notification = new Notification(Notification.SENDLOGFILES, MainApp.gs(R.string.sendlogfiles), Notification.LOW);
MainApp.bus().post(new EventNewNotification(notification));
SP.putBoolean("log_AUTOSENS", true);
break;
}
}
// let it here crash on NPE to get more data as i cannot reproduce this bug
double deviationSlope = (ad.avgDeviation - avgDeviation) / (ad.time - bgTime) * 1000 * 60 * 5;
if (ad.avgDeviation > maxDeviation) {
slopeFromMaxDeviation = Math.min(0, deviationSlope);
@ -208,7 +228,17 @@ public class IobCobOref1Thread extends Thread {
.putCustomAttribute("for_data", ">>>>> bucketed_data.size()=" + bucketed_data.size() + " i=" + i + "hourAgoData=" + hourAgoData.toString())
.putCustomAttribute("past", past)
);
log.debug(autosensDataTable.toString());
log.debug(bucketed_data.toString());
log.debug(IobCobCalculatorPlugin.getPlugin().getBgReadings().toString());
Notification notification = new Notification(Notification.SENDLOGFILES, MainApp.gs(R.string.sendlogfiles), Notification.LOW);
MainApp.bus().post(new EventNewNotification(notification));
SP.putBoolean("log_AUTOSENS", true);
break;
}
} else {
if (L.isEnabled(L.AUTOSENS))
log.debug(">>>>> bucketed_data.size()=" + bucketed_data.size() + " i=" + i + " hourAgoData=" + "null");
}
}
@ -216,6 +246,7 @@ public class IobCobOref1Thread extends Thread {
for (int ir = 0; ir < recentTreatments.size(); ir++) {
autosensData.carbsFromBolus += recentTreatments.get(ir).carbs;
autosensData.activeCarbsList.add(new AutosensData.CarbsInPast(recentTreatments.get(ir)));
autosensData.pastSensitivity += "[" + DecimalFormatter.to0Decimal(recentTreatments.get(ir).carbs) + "g]";
}
@ -313,19 +344,19 @@ public class IobCobOref1Thread extends Thread {
// Exclude meal-related deviations (carb absorption) from autosens
if (autosensData.type.equals("non-meal")) {
if (Math.abs(deviation) < Constants.DEVIATION_TO_BE_EQUAL) {
autosensData.pastSensitivity = "=";
autosensData.pastSensitivity += "=";
autosensData.validDeviation = true;
} else if (deviation > 0) {
autosensData.pastSensitivity = "+";
autosensData.pastSensitivity += "+";
autosensData.validDeviation = true;
} else {
autosensData.pastSensitivity = "-";
autosensData.pastSensitivity += "-";
autosensData.validDeviation = true;
}
} else if (autosensData.type.equals("uam")) {
autosensData.pastSensitivity = "u";
autosensData.pastSensitivity += "u";
} else {
autosensData.pastSensitivity = "x";
autosensData.pastSensitivity += "x";
}
//log.debug("TIME: " + new Date(bgTime).toString() + " BG: " + bg + " SENS: " + sens + " DELTA: " + delta + " AVGDELTA: " + avgDelta + " IOB: " + iob.iob + " ACTIVITY: " + iob.activity + " BGI: " + bgi + " DEVIATION: " + deviation);
@ -365,8 +396,11 @@ public class IobCobOref1Thread extends Thread {
} finally {
mWakeLock.release();
MainApp.bus().post(new EventIobCalculationProgress(""));
if (L.isEnabled(L.AUTOSENS))
if (L.isEnabled(L.AUTOSENS)) {
log.debug("AUTOSENSDATA thread ended: " + from);
log.debug("Midnights: " + MidnightTime.log());
}
Profiler.log(log, "IobCobOref1Thread", start);
}
}

View file

@ -24,16 +24,22 @@ import info.nightscout.androidaps.db.BgReading;
import info.nightscout.androidaps.events.Event;
import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished;
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventIobCalculationProgress;
import info.nightscout.androidaps.plugins.OpenAPSSMB.SMBDefaults;
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityAAPSPlugin;
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityWeightedAveragePlugin;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.FabricPrivacy;
import info.nightscout.utils.MidnightTime;
import info.nightscout.utils.Profiler;
import info.nightscout.utils.SP;
import static info.nightscout.utils.DateUtil.now;
@ -70,11 +76,12 @@ public class IobCobThread extends Thread {
@Override
public final void run() {
long start = DateUtil.now();
mWakeLock.acquire();
try {
if (L.isEnabled(L.AUTOSENS))
log.debug("AUTOSENSDATA thread started: " + from);
if (MainApp.getConfigBuilder() == null) {
if (ConfigBuilderPlugin.getPlugin() == null) {
if (L.isEnabled(L.AUTOSENS))
log.debug("Aborting calculation thread (ConfigBuilder not ready): " + from);
return; // app still initializing
@ -144,7 +151,7 @@ public class IobCobThread extends Thread {
AutosensData autosensData = new AutosensData();
autosensData.time = bgTime;
if (previous != null)
autosensData.activeCarbsList = new ArrayList<>(previous.activeCarbsList);
autosensData.activeCarbsList = previous.cloneCarbsList();
else
autosensData.activeCarbsList = new ArrayList<>();
@ -179,11 +186,24 @@ public class IobCobThread extends Thread {
if (hourAgoData != null) {
int initialIndex = autosensDataTable.indexOfKey(hourAgoData.time);
if (L.isEnabled(L.AUTOSENS))
log.debug(">>>>> bucketed_data.size()=" + bucketed_data.size() + " i=" + i + "hourAgoData=" + hourAgoData.toString());
log.debug(">>>>> bucketed_data.size()=" + bucketed_data.size() + " i=" + i + " hourAgoData=" + hourAgoData.toString());
int past = 1;
try {
for (; past < 12; past++) {
AutosensData ad = autosensDataTable.valueAt(initialIndex + past);
if (L.isEnabled(L.AUTOSENS)) {
log.debug(">>>>> past=" + past + " ad=" + (ad != null ? ad.toString() : null));
if (ad == null) {
log.debug(autosensDataTable.toString());
log.debug(bucketed_data.toString());
log.debug(IobCobCalculatorPlugin.getPlugin().getBgReadings().toString());
Notification notification = new Notification(Notification.SENDLOGFILES, MainApp.gs(R.string.sendlogfiles), Notification.LOW);
MainApp.bus().post(new EventNewNotification(notification));
SP.putBoolean("log_AUTOSENS", true);
break;
}
}
// let it here crash on NPE to get more data as i cannot reproduce this bug
double deviationSlope = (ad.avgDeviation - avgDeviation) / (ad.time - bgTime) * 1000 * 60 * 5;
if (ad.avgDeviation > maxDeviation) {
slopeFromMaxDeviation = Math.min(0, deviationSlope);
@ -207,7 +227,17 @@ public class IobCobThread extends Thread {
.putCustomAttribute("for_data", ">>>>> bucketed_data.size()=" + bucketed_data.size() + " i=" + i + "hourAgoData=" + hourAgoData.toString())
.putCustomAttribute("past", past)
);
log.debug(autosensDataTable.toString());
log.debug(bucketed_data.toString());
log.debug(IobCobCalculatorPlugin.getPlugin().getBgReadings().toString());
Notification notification = new Notification(Notification.SENDLOGFILES, MainApp.gs(R.string.sendlogfiles), Notification.LOW);
MainApp.bus().post(new EventNewNotification(notification));
SP.putBoolean("log_AUTOSENS", true);
break;
}
} else {
if (L.isEnabled(L.AUTOSENS))
log.debug(">>>>> bucketed_data.size()=" + bucketed_data.size() + " i=" + i + " hourAgoData=" + "null");
}
}
@ -215,6 +245,7 @@ public class IobCobThread extends Thread {
for (int ir = 0; ir < recentTreatments.size(); ir++) {
autosensData.carbsFromBolus += recentTreatments.get(ir).carbs;
autosensData.activeCarbsList.add(new AutosensData.CarbsInPast(recentTreatments.get(ir)));
autosensData.pastSensitivity += "[" + DecimalFormatter.to0Decimal(recentTreatments.get(ir).carbs) + "g]";
}
@ -258,17 +289,17 @@ public class IobCobThread extends Thread {
// calculate autosens only without COB
if (autosensData.cob <= 0) {
if (Math.abs(deviation) < Constants.DEVIATION_TO_BE_EQUAL) {
autosensData.pastSensitivity = "=";
autosensData.pastSensitivity += "=";
autosensData.validDeviation = true;
} else if (deviation > 0) {
autosensData.pastSensitivity = "+";
autosensData.pastSensitivity += "+";
autosensData.validDeviation = true;
} else {
autosensData.pastSensitivity = "-";
autosensData.pastSensitivity += "-";
autosensData.validDeviation = true;
}
} else {
autosensData.pastSensitivity = "C";
autosensData.pastSensitivity += "C";
}
//log.debug("TIME: " + new Date(bgTime).toString() + " BG: " + bg + " SENS: " + sens + " DELTA: " + delta + " AVGDELTA: " + avgDelta + " IOB: " + iob.iob + " ACTIVITY: " + iob.activity + " BGI: " + bgi + " DEVIATION: " + deviation);
@ -292,8 +323,11 @@ public class IobCobThread extends Thread {
} finally {
mWakeLock.release();
MainApp.bus().post(new EventIobCalculationProgress(""));
if (L.isEnabled(L.AUTOSENS))
if (L.isEnabled(L.AUTOSENS)) {
log.debug("AUTOSENSDATA thread ended: " + from);
log.debug("Midnights: " + MidnightTime.log());
}
Profiler.log(log, "IobCobThread", start);
}
}

View file

@ -15,12 +15,18 @@ import java.util.List;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.IobTotal;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.db.BgReading;
import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.interfaces.PumpDescription;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.SP;
/**
* Created by mike on 09.06.2016.
@ -31,6 +37,8 @@ public class APSResult {
public long date = 0;
public String reason;
public double rate;
public int percent;
public boolean usePercent = false;
public int duration;
public boolean tempBasalRequested = false;
public boolean bolusRequested = false;
@ -43,11 +51,42 @@ public class APSResult {
public Constraint<Double> inputConstraints;
public Constraint<Double> rateConstraint;
public Constraint<Integer> percentConstraint;
public Constraint<Double> smbConstraint;
public APSResult rate(double rate) {
this.rate = rate;
return this;
}
public APSResult duration(int duration) {
this.duration = duration;
return this;
}
public APSResult percent(int percent) {
this.percent = percent;
return this;
}
public APSResult tempBasalRequested(boolean tempBasalRequested) {
this.tempBasalRequested = tempBasalRequested;
return this;
}
public APSResult usePercent(boolean usePercent) {
this.usePercent = usePercent;
return this;
}
public APSResult json(JSONObject json) {
this.json = json;
return this;
}
@Override
public String toString() {
final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
if (isChangeRequested()) {
String ret;
// rate
@ -55,6 +94,10 @@ public class APSResult {
ret = MainApp.gs(R.string.canceltemp) + "\n";
else if (rate == -1)
ret = MainApp.gs(R.string.let_temp_basal_run) + "\n";
else if (usePercent)
ret = MainApp.gs(R.string.rate) + ": " + DecimalFormatter.to2Decimal(percent) + "% " +
"(" + DecimalFormatter.to2Decimal(percent * pump.getBaseBasalRate() / 100d) + " U/h)\n" +
MainApp.gs(R.string.duration) + ": " + DecimalFormatter.to2Decimal(duration) + " min\n";
else
ret = MainApp.gs(R.string.rate) + ": " + DecimalFormatter.to2Decimal(rate) + " U/h " +
"(" + DecimalFormatter.to2Decimal(rate / pump.getBaseBasalRate() * 100) + "%) \n" +
@ -72,7 +115,7 @@ public class APSResult {
}
public Spanned toSpanned() {
final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
if (isChangeRequested()) {
String ret;
// rate
@ -80,9 +123,13 @@ public class APSResult {
ret = MainApp.gs(R.string.canceltemp) + "<br>";
else if (rate == -1)
ret = MainApp.gs(R.string.let_temp_basal_run) + "<br>";
else if (usePercent)
ret = "<b>" + MainApp.gs(R.string.rate) + "</b>: " + DecimalFormatter.to2Decimal(percent) + "% " +
"(" + DecimalFormatter.to2Decimal(percent * pump.getBaseBasalRate() / 100d) + " U/h)<br>" +
"<b>" + MainApp.gs(R.string.duration) + "</b>: " + DecimalFormatter.to2Decimal(duration) + " min<br>";
else
ret = "<b>" + MainApp.gs(R.string.rate) + "</b>: " + DecimalFormatter.to2Decimal(rate) + " U/h " +
"(" + DecimalFormatter.to2Decimal(rate / pump.getBaseBasalRate() * 100) + "%) <br>" +
"(" + DecimalFormatter.to2Decimal(rate / pump.getBaseBasalRate() * 100d) + "%) <br>" +
"<b>" + MainApp.gs(R.string.duration) + "</b>: " + DecimalFormatter.to2Decimal(duration) + " min<br>";
// smb
@ -101,21 +148,33 @@ public class APSResult {
public APSResult clone() {
APSResult newResult = new APSResult();
newResult.reason = reason;
doClone(newResult);
return newResult;
}
protected void doClone(APSResult newResult) {
newResult.date = date;
newResult.reason = reason != null ? new String(reason) : null;
newResult.rate = rate;
newResult.duration = duration;
newResult.tempBasalRequested = tempBasalRequested;
newResult.bolusRequested = bolusRequested;
newResult.iob = iob;
newResult.json = json;
try {
newResult.json = new JSONObject(json.toString());
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
newResult.hasPredictions = hasPredictions;
newResult.smb = smb;
newResult.deliverAt = deliverAt;
newResult.rateConstraint = rateConstraint;
newResult.smbConstraint = smbConstraint;
return newResult;
newResult.percent = percent;
newResult.usePercent = usePercent;
}
public JSONObject json() {
JSONObject json = new JSONObject();
try {
@ -228,6 +287,119 @@ public class APSResult {
}
public boolean isChangeRequested() {
return tempBasalRequested || bolusRequested;
Constraint<Boolean> closedLoopEnabled = MainApp.getConstraintChecker().isClosedLoopAllowed();
// closed loop mode: handle change at driver level
if (closedLoopEnabled.value()) {
if (L.isEnabled(L.APS))
log.debug("DEFAULT: Closed mode");
return tempBasalRequested || bolusRequested;
}
// open loop mode: try to limit request
if (!tempBasalRequested && !bolusRequested) {
if (L.isEnabled(L.APS))
log.debug("FALSE: No request");
return false;
}
long now = System.currentTimeMillis();
TemporaryBasal activeTemp = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(now);
PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
Profile profile = ProfileFunctions.getInstance().getProfile();
if (profile == null) {
log.error("FALSE: No Profile");
return false;
}
if (usePercent) {
if (activeTemp == null && percent == 100) {
if (L.isEnabled(L.APS))
log.debug("FALSE: No temp running, asking cancel temp");
return false;
}
if (activeTemp != null && Math.abs(percent - activeTemp.tempBasalConvertedToPercent(now, profile)) < pump.getPumpDescription().basalStep) {
if (L.isEnabled(L.APS))
log.debug("FALSE: Temp equal");
return false;
}
// always report zerotemp
if (percent == 0) {
if (L.isEnabled(L.APS))
log.debug("TRUE: Zero temp");
return true;
}
// always report hightemp
if (pump != null && pump.getPumpDescription().tempBasalStyle == PumpDescription.PERCENT) {
double pumpLimit = pump.getPumpDescription().pumpType.getTbrSettings().getMaxDose();
if (percent == pumpLimit) {
if (L.isEnabled(L.APS))
log.debug("TRUE: Pump limit");
return true;
}
}
// report change bigger than 30%
double percentMinChangeChange = SP.getDouble(R.string.key_loop_openmode_min_change, 30d);
percentMinChangeChange /= 100d;
double lowThreshold = 1 - percentMinChangeChange;
double highThreshold = 1 + percentMinChangeChange;
double change = percent / 100d;
if (activeTemp != null)
change = percent / (double) activeTemp.tempBasalConvertedToPercent(now, profile);
if (change < lowThreshold || change > highThreshold) {
if (L.isEnabled(L.APS))
log.debug("TRUE: Outside allowed range " + (change * 100d) + "%");
return true;
} else {
if (L.isEnabled(L.APS))
log.debug("TRUE: Inside allowed range " + (change * 100d) + "%");
return false;
}
} else {
if (activeTemp == null && rate == pump.getBaseBasalRate()) {
if (L.isEnabled(L.APS))
log.debug("FALSE: No temp running, asking cancel temp");
return false;
}
if (activeTemp != null && Math.abs(rate - activeTemp.tempBasalConvertedToAbsolute(now, profile)) < pump.getPumpDescription().basalStep) {
if (L.isEnabled(L.APS))
log.debug("FALSE: Temp equal");
return false;
}
// always report zerotemp
if (rate == 0) {
if (L.isEnabled(L.APS))
log.debug("TRUE: Zero temp");
return true;
}
// always report hightemp
if (pump != null && pump.getPumpDescription().tempBasalStyle == PumpDescription.ABSOLUTE) {
double pumpLimit = pump.getPumpDescription().pumpType.getTbrSettings().getMaxDose();
if (rate == pumpLimit) {
if (L.isEnabled(L.APS))
log.debug("TRUE: Pump limit");
return true;
}
}
// report change bigger than 30%
double percentMinChangeChange = SP.getDouble(R.string.key_loop_openmode_min_change, 30d);
percentMinChangeChange /= 100d;
double lowThreshold = 1 - percentMinChangeChange;
double highThreshold = 1 + percentMinChangeChange;
double change = rate / profile.getBasal();
if (activeTemp != null)
change = rate / activeTemp.tempBasalConvertedToAbsolute(now, profile);
if (change < lowThreshold || change > highThreshold) {
if (L.isEnabled(L.APS))
log.debug("TRUE: Outside allowed range " + (change * 100d) + "%");
return true;
} else {
if (L.isEnabled(L.APS))
log.debug("TRUE: Inside allowed range " + (change * 100d) + "%");
return false;
}
}
}
}

View file

@ -33,13 +33,13 @@ import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.db.DatabaseHelper;
import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.events.Event;
import info.nightscout.androidaps.events.EventNewBG;
import info.nightscout.androidaps.interfaces.APSInterface;
import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.PluginDescription;
import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.interfaces.PumpDescription;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.interfaces.TreatmentsInterface;
import info.nightscout.androidaps.logging.L;
@ -51,6 +51,7 @@ import info.nightscout.androidaps.plugins.Loop.events.EventLoopSetLastRunGui;
import info.nightscout.androidaps.plugins.Loop.events.EventLoopUpdateGui;
import info.nightscout.androidaps.plugins.Loop.events.EventNewOpenLoopNotification;
import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload;
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
import info.nightscout.androidaps.plugins.Wear.ActionStringHandler;
import info.nightscout.androidaps.events.EventAcceptOpenLoopChange;
@ -58,6 +59,7 @@ import info.nightscout.androidaps.queue.Callback;
import info.nightscout.androidaps.queue.commands.Command;
import info.nightscout.utils.FabricPrivacy;
import info.nightscout.utils.SP;
import info.nightscout.utils.T;
import info.nightscout.utils.ToastUtils;
/**
@ -103,7 +105,7 @@ public class LoopPlugin extends PluginBase {
.fragmentClass(LoopFragment.class.getName())
.pluginName(R.string.loop)
.shortName(R.string.loop_shortname)
.preferencesId(R.xml.pref_closedmode)
.preferencesId(R.xml.pref_loop)
.description(R.string.description_loop)
);
loopSuspendedTill = SP.getLong("loopSuspendedTill", 0L);
@ -138,7 +140,7 @@ public class LoopPlugin extends PluginBase {
@Override
public boolean specialEnableCondition() {
PumpInterface pump = ConfigBuilderPlugin.getActivePump();
PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
return pump == null || pump.getPumpDescription().isTempBasalCapable;
}
@ -148,8 +150,6 @@ public class LoopPlugin extends PluginBase {
* sources and currently only a new BG should trigger a loop run. Hence we return early if
* the event causing the calculation is not EventNewBg.
* <p>
* Callers of {@link info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin#runCalculation(String, long, boolean, Event)}
* are sources triggering a calculation which triggers this method upon completion.
*/
@Subscribe
public void onStatusEvent(final EventAutosensCalculationFinished ev) {
@ -275,7 +275,7 @@ public class LoopPlugin extends PluginBase {
MainApp.bus().post(new EventLoopSetLastRunGui(message));
return;
}
final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
APSResult result = null;
if (!isEnabled(PluginType.LOOP))
@ -293,7 +293,7 @@ public class LoopPlugin extends PluginBase {
// Check if pump info is loaded
if (pump.getBaseBasalRate() < 0.01d) return;
APSInterface usedAPS = ConfigBuilderPlugin.getActiveAPS();
APSInterface usedAPS = ConfigBuilderPlugin.getPlugin().getActiveAPS();
if (usedAPS != null && ((PluginBase) usedAPS).isEnabled(PluginType.APS)) {
usedAPS.invoke(initiator, tempBasalFallback);
result = usedAPS.getLastAPSResult();
@ -305,16 +305,26 @@ public class LoopPlugin extends PluginBase {
return;
}
// Prepare for pumps using % basals
if (pump.getPumpDescription().tempBasalStyle == PumpDescription.PERCENT) {
result.usePercent = true;
}
result.percent = (int) (result.rate / profile.getBasal() * 100);
// check rate for constrais
final APSResult resultAfterConstraints = result.clone();
resultAfterConstraints.rateConstraint = new Constraint<>(resultAfterConstraints.rate);
resultAfterConstraints.rate = MainApp.getConstraintChecker().applyBasalConstraints(resultAfterConstraints.rateConstraint, profile).value();
resultAfterConstraints.percentConstraint = new Constraint<>(resultAfterConstraints.percent);
resultAfterConstraints.percent = MainApp.getConstraintChecker().applyBasalPercentConstraints(resultAfterConstraints.percentConstraint, profile).value();
resultAfterConstraints.smbConstraint = new Constraint<>(resultAfterConstraints.smb);
resultAfterConstraints.smb = MainApp.getConstraintChecker().applyBolusConstraints(resultAfterConstraints.smbConstraint).value();
// safety check for multiple SMBs
long lastBolusTime = TreatmentsPlugin.getPlugin().getLastBolusTime();
if (lastBolusTime != 0 && lastBolusTime + 3 * 60 * 1000 > System.currentTimeMillis()) {
if (lastBolusTime != 0 && lastBolusTime + T.mins(3).msecs() > System.currentTimeMillis()) {
if (L.isEnabled(L.APS))
log.debug("SMB requsted but still in 3 min interval");
resultAfterConstraints.smb = 0;
@ -347,9 +357,9 @@ public class LoopPlugin extends PluginBase {
Constraint<Boolean> closedLoopEnabled = MainApp.getConstraintChecker().isClosedLoopAllowed();
if (closedLoopEnabled.value()) {
if (result.isChangeRequested()
&& !ConfigBuilderPlugin.getCommandQueue().bolusInQueue()
&& !ConfigBuilderPlugin.getCommandQueue().isRunning(Command.CommandType.BOLUS)) {
if (resultAfterConstraints.isChangeRequested()
&& !ConfigBuilderPlugin.getPlugin().getCommandQueue().bolusInQueue()
&& !ConfigBuilderPlugin.getPlugin().getCommandQueue().isRunning(Command.CommandType.BOLUS)) {
final PumpEnactResult waiting = new PumpEnactResult();
waiting.queued = true;
if (resultAfterConstraints.tempBasalRequested)
@ -390,7 +400,7 @@ public class LoopPlugin extends PluginBase {
lastRun.smbSetByPump = null;
}
} else {
if (result.isChangeRequested() && allowNotification) {
if (resultAfterConstraints.isChangeRequested() && allowNotification) {
NotificationCompat.Builder builder =
new NotificationCompat.Builder(MainApp.instance().getApplicationContext(), CHANNEL_ID);
builder.setSmallIcon(R.drawable.notif_icon)
@ -399,8 +409,10 @@ public class LoopPlugin extends PluginBase {
.setAutoCancel(true)
.setPriority(Notification.PRIORITY_HIGH)
.setCategory(Notification.CATEGORY_ALARM)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setLocalOnly(true);
.setVisibility(Notification.VISIBILITY_PUBLIC);
if (SP.getBoolean("wearcontrol", false)) {
builder.setLocalOnly(true);
}
// Creates an explicit intent for an Activity in your app
Intent resultIntent = new Intent(MainApp.instance().getApplicationContext(), MainActivity.class);
@ -454,8 +466,8 @@ public class LoopPlugin extends PluginBase {
NSUpload.uploadDeviceStatus();
ObjectivesPlugin objectivesPlugin = MainApp.getSpecificPlugin(ObjectivesPlugin.class);
if (objectivesPlugin != null) {
ObjectivesPlugin.manualEnacts++;
ObjectivesPlugin.saveProgress();
ObjectivesPlugin.getPlugin().manualEnacts++;
ObjectivesPlugin.getPlugin().saveProgress();
}
}
MainApp.bus().post(new EventAcceptOpenLoopChange());
@ -466,8 +478,12 @@ public class LoopPlugin extends PluginBase {
/**
* expect absolute request and allow both absolute and percent response based on pump capabilities
* TODO: update pump drivers to support APS request in %
*/
public void applyTBRRequest(APSResult request, Profile profile, Callback callback) {
boolean allowPercentage = VirtualPumpPlugin.getPlugin().isEnabled(PluginType.PUMP);
if (!request.tempBasalRequested) {
if (callback != null) {
callback.result(new PumpEnactResult().enacted(false).success(true).comment(MainApp.gs(R.string.nochangerequested))).run();
@ -475,12 +491,9 @@ public class LoopPlugin extends PluginBase {
return;
}
PumpInterface pump = MainApp.getConfigBuilder().getActivePump();
PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
TreatmentsInterface activeTreatments = TreatmentsPlugin.getPlugin();
request.rateConstraint = new Constraint<>(request.rate);
request.rate = MainApp.getConstraintChecker().applyBasalConstraints(request.rateConstraint, profile).value();
if (!pump.isInitialized()) {
if (L.isEnabled(L.APS))
log.debug("applyAPSRequest: " + MainApp.gs(R.string.pumpNotInitialized));
@ -504,34 +517,66 @@ public class LoopPlugin extends PluginBase {
long now = System.currentTimeMillis();
TemporaryBasal activeTemp = activeTreatments.getTempBasalFromHistory(now);
if ((request.rate == 0 && request.duration == 0) || Math.abs(request.rate - pump.getBaseBasalRate()) < pump.getPumpDescription().basalStep) {
if (activeTemp != null) {
if (request.usePercent && allowPercentage) {
if (request.percent == 100 && request.duration == 0) {
if (activeTemp != null) {
if (L.isEnabled(L.APS))
log.debug("applyAPSRequest: cancelTempBasal()");
ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(false, callback);
} else {
if (L.isEnabled(L.APS))
log.debug("applyAPSRequest: Basal set correctly");
if (callback != null) {
callback.result(new PumpEnactResult().percent(request.percent).duration(0)
.enacted(false).success(true).comment(MainApp.gs(R.string.basal_set_correctly))).run();
}
}
} else if (activeTemp != null
&& activeTemp.getPlannedRemainingMinutes() > 5
&& request.duration - activeTemp.getPlannedRemainingMinutes() < 30
&& request.percent == activeTemp.percentRate) {
if (L.isEnabled(L.APS))
log.debug("applyAPSRequest: cancelTempBasal()");
MainApp.getConfigBuilder().getCommandQueue().cancelTempBasal(false, callback);
log.debug("applyAPSRequest: Temp basal set correctly");
if (callback != null) {
callback.result(new PumpEnactResult().percent(request.percent)
.enacted(false).success(true).duration(activeTemp.getPlannedRemainingMinutes())
.comment(MainApp.gs(R.string.let_temp_basal_run))).run();
}
} else {
if (L.isEnabled(L.APS))
log.debug("applyAPSRequest: Basal set correctly");
if (callback != null) {
callback.result(new PumpEnactResult().absolute(request.rate).duration(0)
.enacted(false).success(true).comment(MainApp.gs(R.string.basal_set_correctly))).run();
}
}
} else if (activeTemp != null
&& activeTemp.getPlannedRemainingMinutes() > 5
&& request.duration - activeTemp.getPlannedRemainingMinutes() < 30
&& Math.abs(request.rate - activeTemp.tempBasalConvertedToAbsolute(now, profile)) < pump.getPumpDescription().basalStep) {
if (L.isEnabled(L.APS))
log.debug("applyAPSRequest: Temp basal set correctly");
if (callback != null) {
callback.result(new PumpEnactResult().absolute(activeTemp.tempBasalConvertedToAbsolute(now, profile))
.enacted(false).success(true).duration(activeTemp.getPlannedRemainingMinutes())
.comment(MainApp.gs(R.string.let_temp_basal_run))).run();
log.debug("applyAPSRequest: tempBasalPercent()");
ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalPercent(request.percent, request.duration, false, profile, callback);
}
} else {
if (L.isEnabled(L.APS))
log.debug("applyAPSRequest: setTempBasalAbsolute()");
MainApp.getConfigBuilder().getCommandQueue().tempBasalAbsolute(request.rate, request.duration, false, profile, callback);
if ((request.rate == 0 && request.duration == 0) || Math.abs(request.rate - pump.getBaseBasalRate()) < pump.getPumpDescription().basalStep) {
if (activeTemp != null) {
if (L.isEnabled(L.APS))
log.debug("applyAPSRequest: cancelTempBasal()");
ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(false, callback);
} else {
if (L.isEnabled(L.APS))
log.debug("applyAPSRequest: Basal set correctly");
if (callback != null) {
callback.result(new PumpEnactResult().absolute(request.rate).duration(0)
.enacted(false).success(true).comment(MainApp.gs(R.string.basal_set_correctly))).run();
}
}
} else if (activeTemp != null
&& activeTemp.getPlannedRemainingMinutes() > 5
&& request.duration - activeTemp.getPlannedRemainingMinutes() < 30
&& Math.abs(request.rate - activeTemp.tempBasalConvertedToAbsolute(now, profile)) < pump.getPumpDescription().basalStep) {
if (L.isEnabled(L.APS))
log.debug("applyAPSRequest: Temp basal set correctly");
if (callback != null) {
callback.result(new PumpEnactResult().absolute(activeTemp.tempBasalConvertedToAbsolute(now, profile))
.enacted(false).success(true).duration(activeTemp.getPlannedRemainingMinutes())
.comment(MainApp.gs(R.string.let_temp_basal_run))).run();
}
} else {
if (L.isEnabled(L.APS))
log.debug("applyAPSRequest: setTempBasalAbsolute()");
ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalAbsolute(request.rate, request.duration, false, profile, callback);
}
}
}
@ -540,7 +585,7 @@ public class LoopPlugin extends PluginBase {
return;
}
PumpInterface pump = MainApp.getConfigBuilder().getActivePump();
PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
TreatmentsInterface activeTreatments = TreatmentsPlugin.getPlugin();
long lastBolusTime = activeTreatments.getLastBolusTime();
@ -586,15 +631,15 @@ public class LoopPlugin extends PluginBase {
detailedBolusInfo.deliverAt = request.deliverAt;
if (L.isEnabled(L.APS))
log.debug("applyAPSRequest: bolus()");
MainApp.getConfigBuilder().getCommandQueue().bolus(detailedBolusInfo, callback);
ConfigBuilderPlugin.getPlugin().getCommandQueue().bolus(detailedBolusInfo, callback);
}
public void disconnectPump(int durationInMinutes, Profile profile) {
PumpInterface pump = MainApp.getConfigBuilder().getActivePump();
PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
TreatmentsInterface activeTreatments = TreatmentsPlugin.getPlugin();
LoopPlugin.getPlugin().disconnectTo(System.currentTimeMillis() + durationInMinutes * 60 * 1000L);
MainApp.getConfigBuilder().getCommandQueue().tempBasalPercent(0, durationInMinutes, true, profile, new Callback() {
ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalPercent(0, durationInMinutes, true, profile, new Callback() {
@Override
public void run() {
if (!result.success) {
@ -603,7 +648,7 @@ public class LoopPlugin extends PluginBase {
}
});
if (pump.getPumpDescription().isExtendedBolusCapable && activeTreatments.isInHistoryExtendedBoluslInProgress()) {
MainApp.getConfigBuilder().getCommandQueue().cancelExtended(new Callback() {
ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelExtended(new Callback() {
@Override
public void run() {
if (!result.success) {
@ -617,7 +662,7 @@ public class LoopPlugin extends PluginBase {
public void suspendLoop(int durationInMinutes) {
LoopPlugin.getPlugin().suspendTo(System.currentTimeMillis() + durationInMinutes * 60 * 1000);
MainApp.getConfigBuilder().getCommandQueue().cancelTempBasal(true, new Callback() {
ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(true, new Callback() {
@Override
public void run() {
if (!result.success) {

View file

@ -28,6 +28,7 @@ import java.util.Map;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.events.EventAppExit;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.utils.OKDialog;
import info.nightscout.utils.ToastUtils;
@ -37,7 +38,7 @@ import info.nightscout.utils.ToastUtils;
*/
public class ImportExportPrefs {
private static Logger log = LoggerFactory.getLogger(ImportExportPrefs.class);
private static Logger log = LoggerFactory.getLogger(L.CORE);
static File path = new File(Environment.getExternalStorageDirectory().toString());
static public final File file = new File(path, MainApp.gs(R.string.app_name) + "Preferences");
@ -134,7 +135,6 @@ public class ImportExportPrefs {
}
reader.close();
editor.commit();
ConfigBuilderPlugin.getPlugin().storeSettings("importSharedPreferences"); // process potentially missing plugins
OKDialog.show(context, MainApp.gs(R.string.setting_imported), MainApp.gs(R.string.restartingapp), () -> {
log.debug("Exiting");
MainApp.instance().stopKeepAliveService();

View file

@ -4,13 +4,14 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.LoggerContext;
import info.nightscout.androidaps.logging.L;
/**
* This class provides serveral methods for log-handling (eg. sending logs as emails).
*/
public class LoggerUtils {
private static final Logger LOGGER = LoggerFactory.getLogger(LoggerUtils.class);
private static final Logger LOGGER = LoggerFactory.getLogger(L.CORE);
public static String SUFFIX = ".log.zip";

View file

@ -21,15 +21,19 @@ import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import info.nightscout.androidaps.BuildConfig;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.PluginDescription;
import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.NSClientInternal.data.NSSettingsStatus;
import info.nightscout.utils.SP;
public class MaintenancePlugin extends PluginBase {
private static final Logger LOG = LoggerFactory.getLogger(MaintenancePlugin.class);
private static final Logger LOG = LoggerFactory.getLogger(L.CORE);
private final Context ctx;
@ -69,8 +73,8 @@ public class MaintenancePlugin extends PluginBase {
}
public void sendLogs() {
String recipient = SP.getString("key_maintenance_logs_email", "logs@androidaps.org");
int amount = SP.getInt("key_maintenance_logs_amount", 2);
String recipient = SP.getString(R.string.key_maintenance_logs_email, "logs@androidaps.org");
int amount = SP.getInt(R.string.key_maintenance_logs_amount, 2);
String logDirectory = LoggerUtils.getLogDirectory();
List<File> logs = this.getLogfiles(logDirectory, amount);
@ -99,7 +103,7 @@ public class MaintenancePlugin extends PluginBase {
Arrays.sort(files, (f1, f2) -> f1.getName().compareTo(f2.getName()));
List<File> delFiles = Arrays.asList(files);
int amount = SP.getInt("key_logshipper_amount", 2);
int amount = SP.getInt(R.string.key_logshipper_amount, 2);
int keepIndex = amount - 1;
if (keepIndex < delFiles.size()) {
@ -203,6 +207,30 @@ public class MaintenancePlugin extends PluginBase {
out.close();
}
public static Intent sendMail(Uri attachementUri, String recipient, String subject) {
StringBuilder builder =new StringBuilder();
builder.append("ADD TIME OF EVENT HERE: " + System.lineSeparator());
builder.append("ADD ISSUE DESCRIPTION OR GITHUB ISSUE REFERENCE NUMBER: " + System.lineSeparator());
builder.append("-------------------------------------------------------" + System.lineSeparator());
builder.append("(Please remember this will send only very recent logs." + System.lineSeparator());
builder.append("If you want to provide logs for event older than a few hours," + System.lineSeparator());
builder.append("you have to do it manually)" + System.lineSeparator());
builder.append("-------------------------------------------------------" + System.lineSeparator());
builder.append(MainApp.gs(R.string.app_name) + " " + BuildConfig.VERSION + System.lineSeparator());
if (Config.NSCLIENT)
builder.append("NSCLIENT" + System.lineSeparator());
builder.append("Build: " + BuildConfig.BUILDVERSION + System.lineSeparator());
builder.append("Flavor: " + BuildConfig.FLAVOR + BuildConfig.BUILD_TYPE + System.lineSeparator());
builder.append(MainApp.gs(R.string.configbuilder_nightscoutversion_label) + " " + NSSettingsStatus.getInstance().nightscoutVersionName + System.lineSeparator());
if (MainApp.engineeringMode)
builder.append(MainApp.gs(R.string.engineering_mode_enabled));
return sendMail(attachementUri, recipient, subject, builder.toString());
}
/**
* send a mail with the given file to the recipients with the given subject.
*
@ -213,16 +241,18 @@ public class MaintenancePlugin extends PluginBase {
* @param attachementUri
* @param recipient
* @param subject
* @param body
*
* @return
*/
public static Intent sendMail(Uri attachementUri, String recipient, String subject) {
public static Intent sendMail(Uri attachementUri, String recipient, String subject, String body) {
LOG.debug("sending email to {} with subject {}", recipient, subject);
Intent emailIntent = new Intent(Intent.ACTION_SEND);
emailIntent.setType("text/plain");
emailIntent.putExtra(Intent.EXTRA_EMAIL , new String[]{recipient});
emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
emailIntent.putExtra(Intent.EXTRA_TEXT, "");
emailIntent.putExtra(Intent.EXTRA_TEXT, body);
LOG.debug("put path {}", attachementUri.toString());
emailIntent.putExtra(Intent.EXTRA_STREAM, attachementUri);

View file

@ -249,7 +249,7 @@ public class NSUpload {
log.debug("OpenAPS data too old to upload");
}
deviceStatus.device = "openaps://" + Build.MANUFACTURER + " " + Build.MODEL;
JSONObject pumpstatus = ConfigBuilderPlugin.getActivePump().getJSONStatus(profile, profileName);
JSONObject pumpstatus = ConfigBuilderPlugin.getPlugin().getActivePump().getJSONStatus(profile, profileName);
if (pumpstatus != null) {
deviceStatus.pump = pumpstatus;
}

View file

@ -28,7 +28,7 @@ public class BroadcastAckAlarm {
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) {
if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
bundle = new Bundle();
bundle.putInt("level", originalAlarm.getLevel());
bundle.putString("group", originalAlarm.getGroup());

View file

@ -24,7 +24,7 @@ public class BroadcastAlarm {
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) {
if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
bundle = new Bundle();
bundle.putString("data", alarm.toString());
intent = new Intent(Intents.ACTION_ALARM);

View file

@ -24,7 +24,7 @@ public class BroadcastAnnouncement {
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) {
if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
bundle = new Bundle();
bundle.putString("data", announcement.toString());
intent = new Intent(Intents.ACTION_ANNOUNCEMENT);

View file

@ -26,7 +26,7 @@ public class BroadcastCals {
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) {
if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
bundle = new Bundle();
bundle.putString("cals", cals.toString());
bundle.putBoolean("delta", isDelta);

View file

@ -24,7 +24,7 @@ public class BroadcastClearAlarm {
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) {
if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
bundle = new Bundle();
bundle.putString("data", clearalarm.toString());
intent = new Intent(Intents.ACTION_CLEAR_ALARM);

View file

@ -29,7 +29,7 @@ public class BroadcastDeviceStatus {
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
}
if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) {
if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
splitted = BroadcastTreatment.splitArray(statuses);
for (JSONArray part : splitted) {
Bundle bundle = new Bundle();

View file

@ -31,7 +31,7 @@ public class BroadcastFood {
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
}
if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) {
if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
for (JSONArray part : splitted) {
Bundle bundle = new Bundle();
bundle.putString("foods", part.toString());
@ -57,7 +57,7 @@ public class BroadcastFood {
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
}
if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) {
if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
for (JSONArray part : splitted) {
Bundle bundle = new Bundle();
bundle.putString("foods", part.toString());
@ -81,7 +81,7 @@ public class BroadcastFood {
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) {
if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
bundle = new Bundle();
bundle.putString("foods", foods.toString());
bundle.putBoolean("delta", isDelta);

View file

@ -26,7 +26,7 @@ public class BroadcastMbgs {
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) {
if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
bundle = new Bundle();
bundle.putString("mbgs", mbgs.toString());
bundle.putBoolean("delta", isDelta);

View file

@ -26,7 +26,7 @@ public class BroadcastProfile {
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) {
if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
bundle = new Bundle();
bundle.putString("profile", profile.getData().toString());
bundle.putBoolean("delta", isDelta);

View file

@ -31,7 +31,7 @@ public class BroadcastSgvs {
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
}
if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) {
if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
for (JSONArray part : splitted) {
Bundle bundle = new Bundle();
bundle.putString("sgvs", part.toString());

View file

@ -27,7 +27,7 @@ public class BroadcastStatus {
LocalBroadcastManager.getInstance(MainApp.instance())
.sendBroadcast(createIntent(status, isDelta));
if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) {
if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
context.sendBroadcast(createIntent(status, isDelta));
}
}

View file

@ -36,7 +36,7 @@ public class BroadcastTreatment {
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) {
if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
bundle = new Bundle();
bundle.putString("treatment", treatment.toString());
bundle.putBoolean("delta", isDelta);
@ -60,7 +60,7 @@ public class BroadcastTreatment {
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
}
if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) {
if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
splitted = splitArray(treatments);
for (JSONArray part : splitted) {
Bundle bundle = new Bundle();
@ -87,7 +87,7 @@ public class BroadcastTreatment {
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
}
if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) {
if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
splitted = splitArray(treatments);
for (JSONArray part : splitted) {
Bundle bundle = new Bundle();
@ -112,7 +112,7 @@ public class BroadcastTreatment {
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) {
if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
bundle = new Bundle();
bundle.putString("treatments", treatments.toString());
bundle.putBoolean("delta", isDelta);

View file

@ -24,7 +24,7 @@ public class BroadcastUrgentAlarm {
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) {
if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
bundle = new Bundle();
bundle.putString("data", urgentalarm.toString());
intent = new Intent(Intents.ACTION_URGENT_ALARM);

View file

@ -15,6 +15,7 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin;
@ -107,8 +108,8 @@ public class NSDeviceStatus {
setData(devicestatusJson);
if (devicestatusJson.has("pump")) {
// Objectives 0
ObjectivesPlugin.pumpStatusIsAvailableInNS = true;
ObjectivesPlugin.saveProgress();
ObjectivesPlugin.getPlugin().pumpStatusIsAvailableInNS = true;
ObjectivesPlugin.getPlugin().saveProgress();
}
}
if (bundle.containsKey("devicestatuses")) {
@ -119,8 +120,8 @@ public class NSDeviceStatus {
setData(devicestatusJson);
if (devicestatusJson.has("pump")) {
// Objectives 0
ObjectivesPlugin.pumpStatusIsAvailableInNS = true;
ObjectivesPlugin.saveProgress();
ObjectivesPlugin.getPlugin().pumpStatusIsAvailableInNS = true;
ObjectivesPlugin.getPlugin().saveProgress();
}
}
}
@ -174,10 +175,14 @@ public class NSDeviceStatus {
public Spanned getPumpStatus() {
//String[] ALL_STATUS_FIELDS = {"reservoir", "battery", "clock", "status", "device"};
StringBuilder string = new StringBuilder();
string.append("<span style=\"color:" + MainApp.gs(R.color.defaulttext).replace("#ff", "#") + "\">");
string.append(MainApp.gs(R.string.pump));
string.append(": </span>");
if (deviceStatusPumpData == null)
return Html.fromHtml("");
StringBuilder string = new StringBuilder();
// test warning level
int level = Levels.INFO;
long now = System.currentTimeMillis();
@ -329,6 +334,10 @@ public class NSDeviceStatus {
public Spanned getOpenApsStatus() {
StringBuilder string = new StringBuilder();
string.append("<span style=\"color:" + MainApp.gs(R.color.defaulttext).replace("#ff", "#") + "\">");
string.append(MainApp.gs(R.string.openaps_short));
string.append(": </span>");
// test warning level
int level = Levels.INFO;
long now = System.currentTimeMillis();
@ -426,6 +435,26 @@ public class NSDeviceStatus {
return minBattery + "%";
}
public Spanned getUploaderStatusSpanned() {
StringBuilder string = new StringBuilder();
string.append("<span style=\"color:" + MainApp.gs(R.color.defaulttext).replace("#ff", "#") + "\">");
string.append(MainApp.gs(R.string.uploader_short));
string.append(": </span>");
Iterator iter = uploaders.entrySet().iterator();
int minBattery = 100;
while (iter.hasNext()) {
Map.Entry pair = (Map.Entry) iter.next();
Uploader uploader = (Uploader) pair.getValue();
if (minBattery > uploader.battery)
minBattery = uploader.battery;
}
string.append(minBattery);
string.append("%");
return Html.fromHtml(string.toString());
}
public Spanned getExtendedUploaderStatus() {
StringBuilder string = new StringBuilder();

View file

@ -39,7 +39,7 @@ public class DBAccessReceiver extends BroadcastReceiver {
if (!bundles.containsKey("action")) return;
if (L.isEnabled(L.NSCLIENT))
BundleLogger.log(bundles);
log.debug(BundleLogger.log(bundles));
String collection = null;
String _id = null;
@ -49,16 +49,21 @@ public class DBAccessReceiver extends BroadcastReceiver {
collection = bundles.getString("collection");
} catch (Exception e) {
log.error("Unhandled exception", e);
return;
}
try {
_id = bundles.getString("_id");
if (!action.equals("dbAdd"))
_id = bundles.getString("_id");
} catch (Exception e) {
log.error("Unhandled exception", e);
return;
}
try {
data = new JSONObject(bundles.getString("data"));
if (!action.equals("dbRemove"))
data = new JSONObject(bundles.getString("data"));
} catch (Exception e) {
log.error("Unhandled exception", e);
return;
}
if (data == null && !action.equals("dbRemove") || _id == null && action.equals("dbRemove")) {
@ -87,7 +92,7 @@ public class DBAccessReceiver extends BroadcastReceiver {
DbRequest dbr = new DbRequest(action, collection, nsclientid.toString(), _id);
UploadQueue.add(dbr);
}
} else if (action.equals("dbUpdate")) {
} else if (action.equals("dbUpdate")) {
if (shouldUpload()) {
DbRequest dbr = new DbRequest(action, collection, nsclientid.toString(), _id, data);
UploadQueue.add(dbr);

View file

@ -324,7 +324,8 @@ public class NSClientService extends Service {
return;
}
MainApp.bus().post(new EventNSClientNewLog("AUTH", "requesting auth"));
mSocket.emit("authorize", authMessage, ack);
if (mSocket != null)
mSocket.emit("authorize", authMessage, ack);
}
@Subscribe

View file

@ -55,21 +55,10 @@ public class DetermineBasalResultAMA extends APSResult {
@Override
public DetermineBasalResultAMA clone() {
DetermineBasalResultAMA newResult = new DetermineBasalResultAMA();
newResult.reason = reason;
newResult.rate = rate;
newResult.duration = duration;
newResult.tempBasalRequested = tempBasalRequested;
newResult.rate = rate;
newResult.duration = duration;
doClone(newResult);
try {
newResult.json = new JSONObject(json.toString());
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
newResult.eventualBG = eventualBG;
newResult.snoozeBG = snoozeBG;
newResult.date = date;
return newResult;
}

View file

@ -67,13 +67,13 @@ public class OpenAPSAMAPlugin extends PluginBase implements APSInterface {
@Override
public boolean specialEnableCondition() {
PumpInterface pump = ConfigBuilderPlugin.getActivePump();
PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
return pump == null || pump.getPumpDescription().isTempBasalCapable;
}
@Override
public boolean specialShowInListCondition() {
PumpInterface pump = ConfigBuilderPlugin.getActivePump();
PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
return pump == null || pump.getPumpDescription().isTempBasalCapable;
}
@ -97,7 +97,7 @@ public class OpenAPSAMAPlugin extends PluginBase implements APSInterface {
GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData();
Profile profile = ProfileFunctions.getInstance().getProfile();
PumpInterface pump = ConfigBuilderPlugin.getActivePump();
PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
if (profile == null) {
MainApp.bus().post(new EventOpenAPSUpdateResultGui(MainApp.gs(R.string.noprofileselected)));
@ -188,7 +188,7 @@ public class OpenAPSAMAPlugin extends PluginBase implements APSInterface {
start = System.currentTimeMillis();
try {
determineBasalAdapterAMAJS.setData(profile, maxIob, maxBasal, minBg, maxBg, targetBg, ConfigBuilderPlugin.getActivePump().getBaseBasalRate(), iobArray, glucoseStatus, mealData,
determineBasalAdapterAMAJS.setData(profile, maxIob, maxBasal, minBg, maxBg, targetBg, ConfigBuilderPlugin.getPlugin().getActivePump().getBaseBasalRate(), iobArray, glucoseStatus, mealData,
lastAutosensResult.ratio, //autosensDataRatio
isTempTarget
);
@ -203,17 +203,6 @@ public class OpenAPSAMAPlugin extends PluginBase implements APSInterface {
// Fix bug determine basal
if (determineBasalResultAMA.rate == 0d && determineBasalResultAMA.duration == 0 && !TreatmentsPlugin.getPlugin().isTempBasalInProgress())
determineBasalResultAMA.tempBasalRequested = false;
// limit requests on openloop mode
if (!MainApp.getConstraintChecker().isClosedLoopAllowed().value()) {
long now = System.currentTimeMillis();
TemporaryBasal activeTemp = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(now);
if (activeTemp != null && determineBasalResultAMA.rate == 0 && determineBasalResultAMA.duration == 0) {
// going to cancel
} else if (activeTemp != null && Math.abs(determineBasalResultAMA.rate - activeTemp.tempBasalConvertedToAbsolute(now, profile)) < 0.1) {
determineBasalResultAMA.tempBasalRequested = false;
} else if (activeTemp == null && Math.abs(determineBasalResultAMA.rate - ConfigBuilderPlugin.getActivePump().getBaseBasalRate()) < 0.1)
determineBasalResultAMA.tempBasalRequested = false;
}
determineBasalResultAMA.iob = iobArray[0];

View file

@ -12,7 +12,6 @@ import info.nightscout.androidaps.plugins.Loop.APSResult;
public class DetermineBasalResultMA extends APSResult {
private static Logger log = LoggerFactory.getLogger(L.APS);
public JSONObject json = new JSONObject();
private double eventualBG;
private double snoozeBG;
private String mealAssist;
@ -56,19 +55,8 @@ public class DetermineBasalResultMA extends APSResult {
@Override
public DetermineBasalResultMA clone() {
DetermineBasalResultMA newResult = new DetermineBasalResultMA();
newResult.reason = new String(reason);
newResult.rate = rate;
newResult.duration = duration;
newResult.tempBasalRequested = isChangeRequested();
newResult.rate = rate;
newResult.duration = duration;
newResult.tempBasalRequested = isChangeRequested();
doClone(newResult);
try {
newResult.json = new JSONObject(json.toString());
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
newResult.eventualBG = eventualBG;
newResult.snoozeBG = snoozeBG;
newResult.mealAssist = mealAssist;

View file

@ -66,13 +66,13 @@ public class OpenAPSMAPlugin extends PluginBase implements APSInterface {
@Override
public boolean specialEnableCondition() {
PumpInterface pump = ConfigBuilderPlugin.getActivePump();
PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
return pump == null || pump.getPumpDescription().isTempBasalCapable;
}
@Override
public boolean specialShowInListCondition() {
PumpInterface pump = ConfigBuilderPlugin.getActivePump();
PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
return pump == null || pump.getPumpDescription().isTempBasalCapable;
}
@ -96,7 +96,7 @@ public class OpenAPSMAPlugin extends PluginBase implements APSInterface {
GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData();
Profile profile = ProfileFunctions.getInstance().getProfile();
PumpInterface pump = ConfigBuilderPlugin.getActivePump();
PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
if (profile == null) {
MainApp.bus().post(new EventOpenAPSUpdateResultGui(MainApp.gs(R.string.noprofileselected)));
@ -168,7 +168,7 @@ public class OpenAPSMAPlugin extends PluginBase implements APSInterface {
start = System.currentTimeMillis();
try {
determineBasalAdapterMAJS.setData(profile, maxIob, maxBasal, minBg, maxBg, targetBg, ConfigBuilderPlugin.getActivePump().getBaseBasalRate(), iobTotal, glucoseStatus, mealData);
determineBasalAdapterMAJS.setData(profile, maxIob, maxBasal, minBg, maxBg, targetBg, ConfigBuilderPlugin.getPlugin().getActivePump().getBaseBasalRate(), iobTotal, glucoseStatus, mealData);
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
@ -182,16 +182,6 @@ public class OpenAPSMAPlugin extends PluginBase implements APSInterface {
// Fix bug determinef basal
if (determineBasalResultMA.rate == 0d && determineBasalResultMA.duration == 0 && !TreatmentsPlugin.getPlugin().isTempBasalInProgress())
determineBasalResultMA.tempBasalRequested = false;
// limit requests on openloop mode
if (!MainApp.getConstraintChecker().isClosedLoopAllowed().value()) {
TemporaryBasal activeTemp = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(now);
if (activeTemp != null && determineBasalResultMA.rate == 0 && determineBasalResultMA.duration == 0) {
// going to cancel
} else if (activeTemp != null && Math.abs(determineBasalResultMA.rate - activeTemp.tempBasalConvertedToAbsolute(now, profile)) < 0.1) {
determineBasalResultMA.tempBasalRequested = false;
} else if (activeTemp == null && Math.abs(determineBasalResultMA.rate - ConfigBuilderPlugin.getActivePump().getBaseBasalRate()) < 0.1)
determineBasalResultMA.tempBasalRequested = false;
}
determineBasalResultMA.iob = iobTotal;

View file

@ -211,6 +211,7 @@ public class DetermineBasalAdapterSMBJS {
double autosensDataRatio,
boolean tempTargetSet,
boolean microBolusAllowed,
boolean uamAllowed,
boolean advancedFiltering
) throws JSONException {
@ -240,14 +241,14 @@ public class DetermineBasalAdapterSMBJS {
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);
//align with max-absorption model in AMA sensitivity
if (mealData.usedMinCarbsImpact > 0) {
mProfile.put("min_5m_carbimpact", mealData.usedMinCarbsImpact);
} else {
mProfile.put("min_5m_carbimpact", SP.getDouble(R.string.key_openapsama_min_5m_carbimpact, SMBDefaults.min_5m_carbimpact));
}
// min_5m_carbimpact is not used within SMB determinebasal
//if (mealData.usedMinCarbsImpact > 0) {
// mProfile.put("min_5m_carbimpact", mealData.usedMinCarbsImpact);
//} else {
// mProfile.put("min_5m_carbimpact", SP.getDouble(R.string.key_openapsama_min_5m_carbimpact, SMBDefaults.min_5m_carbimpact));
//}
mProfile.put("remainingCarbsCap", SMBDefaults.remainingCarbsCap);
mProfile.put("enableUAM", SP.getBoolean(R.string.key_use_uam, false));
mProfile.put("enableUAM", uamAllowed);
mProfile.put("A52_risk_enable", SMBDefaults.A52_risk_enable);
mProfile.put("enableSMB_with_COB", SP.getBoolean(R.string.key_enableSMB_with_COB, false));
mProfile.put("enableSMB_with_temptarget", SP.getBoolean(R.string.key_enableSMB_with_temptarget, false));

View file

@ -14,8 +14,6 @@ public class DetermineBasalResultSMB extends APSResult {
private double eventualBG;
private double snoozeBG;
//public double insulinReq;
//public double carbsReq;
DetermineBasalResultSMB(JSONObject result) {
this();
@ -70,24 +68,10 @@ public class DetermineBasalResultSMB extends APSResult {
@Override
public DetermineBasalResultSMB clone() {
DetermineBasalResultSMB newResult = new DetermineBasalResultSMB();
newResult.reason = reason;
newResult.rate = rate;
newResult.duration = duration;
newResult.tempBasalRequested = tempBasalRequested;
newResult.bolusRequested = bolusRequested;
newResult.rate = rate;
newResult.duration = duration;
newResult.smb = smb;
newResult.deliverAt = deliverAt;
doClone(newResult);
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;
}

View file

@ -72,13 +72,13 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface {
@Override
public boolean specialEnableCondition() {
PumpInterface pump = ConfigBuilderPlugin.getActivePump();
PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
return pump == null || pump.getPumpDescription().isTempBasalCapable;
}
@Override
public boolean specialShowInListCondition() {
PumpInterface pump = ConfigBuilderPlugin.getActivePump();
PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
return pump == null || pump.getPumpDescription().isTempBasalCapable;
}
@ -102,7 +102,7 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface {
GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData();
Profile profile = ProfileFunctions.getInstance().getProfile();
PumpInterface pump = ConfigBuilderPlugin.getActivePump();
PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
if (profile == null) {
MainApp.bus().post(new EventOpenAPSUpdateResultGui(MainApp.gs(R.string.noprofileselected)));
@ -198,6 +198,10 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface {
MainApp.getConstraintChecker().isAdvancedFilteringEnabled(advancedFiltering);
inputConstraints.copyReasons(advancedFiltering);
Constraint<Boolean> uam = new Constraint<>(true);
MainApp.getConstraintChecker().isUAMEnabled(uam);
inputConstraints.copyReasons(uam);
if (L.isEnabled(L.APS))
Profiler.log(log, "detectSensitivityandCarbAbsorption()", startPart);
if (L.isEnabled(L.APS))
@ -205,10 +209,11 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface {
start = System.currentTimeMillis();
try {
determineBasalAdapterSMBJS.setData(profile, maxIob, maxBasal, minBg, maxBg, targetBg, ConfigBuilderPlugin.getActivePump().getBaseBasalRate(), iobArray, glucoseStatus, mealData,
determineBasalAdapterSMBJS.setData(profile, maxIob, maxBasal, minBg, maxBg, targetBg, ConfigBuilderPlugin.getPlugin().getActivePump().getBaseBasalRate(), iobArray, glucoseStatus, mealData,
lastAutosensResult.ratio, //autosensDataRatio
isTempTarget,
smbAllowed.value(),
uam.value(),
advancedFiltering.value()
);
} catch (JSONException e) {
@ -225,16 +230,6 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface {
// Fix bug determine basal
if (determineBasalResultSMB.rate == 0d && determineBasalResultSMB.duration == 0 && !TreatmentsPlugin.getPlugin().isTempBasalInProgress())
determineBasalResultSMB.tempBasalRequested = false;
// limit requests on openloop mode
if (!MainApp.getConstraintChecker().isClosedLoopAllowed().value()) {
TemporaryBasal activeTemp = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(now);
if (activeTemp != null && determineBasalResultSMB.rate == 0 && determineBasalResultSMB.duration == 0) {
// going to cancel
} else if (activeTemp != null && Math.abs(determineBasalResultSMB.rate - activeTemp.tempBasalConvertedToAbsolute(now, profile)) < 0.1) {
determineBasalResultSMB.tempBasalRequested = false;
} else if (activeTemp == null && Math.abs(determineBasalResultSMB.rate - ConfigBuilderPlugin.getActivePump().getBaseBasalRate()) < 0.1)
determineBasalResultSMB.tempBasalRequested = false;
}
determineBasalResultSMB.iob = iobArray[0];

View file

@ -73,7 +73,7 @@ public class BolusProgressDialog extends DialogFragment implements View.OnClickL
super.onResume();
if (L.isEnabled(L.UI))
log.debug("onResume");
if (!ConfigBuilderPlugin.getCommandQueue().bolusInQueue()) {
if (!ConfigBuilderPlugin.getPlugin().getCommandQueue().bolusInQueue()) {
bolusEnded = true;
}
if (bolusEnded) {
@ -107,9 +107,9 @@ public class BolusProgressDialog extends DialogFragment implements View.OnClickL
@Override
public void onPause() {
running = false;
super.onPause();
MainApp.unsubscribe(this);
running = false;
if (L.isEnabled(L.UI))
log.debug("onPause");
}
@ -123,7 +123,7 @@ public class BolusProgressDialog extends DialogFragment implements View.OnClickL
stopPressed = true;
stopPressedView.setVisibility(View.VISIBLE);
stopButton.setVisibility(View.INVISIBLE);
ConfigBuilderPlugin.getCommandQueue().cancelAllBoluses();
ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelAllBoluses();
break;
}
}
@ -173,10 +173,12 @@ public class BolusProgressDialog extends DialogFragment implements View.OnClickL
Activity activity = getActivity();
if (activity != null) {
activity.runOnUiThread(() -> {
if (L.isEnabled(L.UI))
log.debug("executing");
try {
dismiss();
if (running) {
if (L.isEnabled(L.UI))
log.debug("executing");
dismiss();
}
} catch (Exception e) {
log.error("Unhandled exception", e);
}

View file

@ -74,7 +74,7 @@ public class ErrorDialog extends DialogFragment implements View.OnClickListener
@Override
public void dismiss() {
super.dismiss();
super.dismissAllowingStateLoss();
if (helperActivity != null) {
helperActivity.finish();
}

View file

@ -39,6 +39,7 @@ import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
@ -49,6 +50,7 @@ import info.nightscout.utils.FabricPrivacy;
import info.nightscout.utils.NumberPicker;
import info.nightscout.utils.SP;
import info.nightscout.utils.SafeParse;
import info.nightscout.utils.T;
import info.nightscout.utils.ToastUtils;
import static info.nightscout.utils.DateUtil.now;
@ -131,7 +133,7 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener
maxInsulin = MainApp.getConstraintChecker().getMaxBolusAllowed().value();
editInsulin = view.findViewById(R.id.newinsulin_amount);
editInsulin.setParams(0d, 0d, maxInsulin, ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep, DecimalFormatter.pumpSupportedBolusFormat(), false, textWatcher);
editInsulin.setParams(0d, 0d, maxInsulin, ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().bolusStep, DecimalFormatter.pumpSupportedBolusFormat(), false, textWatcher);
Button plus1Button = view.findViewById(R.id.newinsulin_plus05);
plus1Button.setOnClickListener(this);
@ -210,7 +212,8 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener
try {
Profile currentProfile = ProfileFunctions.getInstance().getProfile();
if (currentProfile == null)
final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
if (currentProfile == null || pump == null)
return;
Double insulin = SafeParse.stringToDouble(editInsulin.getText());
@ -218,13 +221,13 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener
List<String> actions = new LinkedList<>();
if (insulin > 0) {
actions.add(MainApp.gs(R.string.bolus) + ": " + "<font color='" + MainApp.gc(R.color.bolus) + "'>" + insulinAfterConstraints + "U" + "</font>");
actions.add(MainApp.gs(R.string.bolus) + ": " + "<font color='" + MainApp.gc(R.color.bolus) + "'>" + DecimalFormatter.toPumpSupportedBolus(insulinAfterConstraints) + "U" + "</font>");
if (recordOnlyCheckbox.isChecked()) {
actions.add("<font color='" + MainApp.gc(R.color.warning) + "'>" + MainApp.gs(R.string.bolusrecordedonly) + "</font>");
}
}
if (!insulinAfterConstraints.equals(insulin))
if (Math.abs(insulinAfterConstraints - insulin) > pump.getPumpDescription().pumpType.determineCorrectBolusSize(insulinAfterConstraints))
actions.add("<font color='" + MainApp.gc(R.color.warning) + "'>" + MainApp.gs(R.string.bolusconstraintapplied) + "</font>");
int eatingSoonTTDuration = SP.getInt(R.string.key_eatingsoon_duration, Constants.defaultEatingSoonTTDuration);
@ -240,7 +243,7 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener
}
int timeOffset = editTime.getValue().intValue();
final long time = now() + timeOffset * 1000 * 60;
final long time = now() + T.mins(timeOffset).msecs();
if (timeOffset != 0) {
actions.add(MainApp.gs(R.string.time) + ": " + DateUtil.dateAndTimeString(time));
}
@ -290,7 +293,7 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false);
} else {
detailedBolusInfo.date = now();
ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() {
ConfigBuilderPlugin.getPlugin().getCommandQueue().bolus(detailedBolusInfo, new Callback() {
@Override
public void run() {
if (!result.success) {

View file

@ -31,6 +31,7 @@ import info.nightscout.androidaps.data.DetailedBolusInfo;
import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
import info.nightscout.androidaps.queue.Callback;
@ -104,7 +105,7 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene
editInsulin = (NumberPicker) view.findViewById(R.id.treatments_newtreatment_insulinamount);
editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false, textWatcher);
editInsulin.setParams(0d, 0d, maxInsulin, ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep, DecimalFormatter.pumpSupportedBolusFormat(), false, textWatcher);
editInsulin.setParams(0d, 0d, maxInsulin, ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().bolusStep, DecimalFormatter.pumpSupportedBolusFormat(), false, textWatcher);
recordOnlyCheckbox = (CheckBox) view.findViewById(R.id.newtreatment_record_only);
@ -125,6 +126,11 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene
okClicked = true;
try {
final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
if (pump == null)
return;
Double insulin = SafeParse.stringToDouble(editInsulin.getText());
final Integer carbs = SafeParse.stringToInt(editCarbs.getText());
@ -134,15 +140,15 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene
Integer carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(carbs)).value();
if (insulin > 0) {
confirmMessage += MainApp.gs(R.string.bolus) + ": " + "<font color='" + MainApp.gc(R.color.colorCarbsButton) + "'>" + insulinAfterConstraints + "U" + "</font>";
confirmMessage += MainApp.gs(R.string.bolus) + ": " + "<font color='" + MainApp.gc(R.color.bolus) + "'>" + DecimalFormatter.toPumpSupportedBolus(insulinAfterConstraints) + "U" + "</font>";
if (recordOnlyCheckbox.isChecked()) {
confirmMessage += "<br/><font color='" + MainApp.gc(R.color.low) + "'>" + MainApp.gs(R.string.bolusrecordedonly) + "</font>";
confirmMessage += "<br/><font color='" + MainApp.gc(R.color.warning) + "'>" + MainApp.gs(R.string.bolusrecordedonly) + "</font>";
}
if (Math.abs(insulinAfterConstraints - insulin) > pump.getPumpDescription().pumpType.determineCorrectBolusSize(insulinAfterConstraints) || !Objects.equals(carbsAfterConstraints, carbs))
confirmMessage += "<br/><font color='" + MainApp.gc(R.color.warning) + "'>" + MainApp.gs(R.string.bolusconstraintapplied) + "</font>";
}
if (carbsAfterConstraints > 0)
confirmMessage += "<br/>" + MainApp.gs(R.string.carbs) + ": " + carbsAfterConstraints + "g";
if (insulinAfterConstraints - insulin != 0 || !Objects.equals(carbsAfterConstraints, carbs))
confirmMessage += "<br/>" + MainApp.gs(R.string.constraintapllied);
confirmMessage += "<br/>" + MainApp.gs(R.string.carbs) + ": " + "<font color='" + MainApp.gc(R.color.carbs) + "'>" + carbsAfterConstraints + "g" + "</font>";
final double finalInsulinAfterConstraints = insulinAfterConstraints;
@ -171,8 +177,8 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene
detailedBolusInfo.carbs = finalCarbsAfterConstraints;
detailedBolusInfo.context = context;
detailedBolusInfo.source = Source.USER;
if (!(recordOnlyCheckbox.isChecked() && (detailedBolusInfo.insulin > 0 || ConfigBuilderPlugin.getActivePump().getPumpDescription().storesCarbInfo))) {
ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() {
if (!(recordOnlyCheckbox.isChecked() && (detailedBolusInfo.insulin > 0 || ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().storesCarbInfo))) {
ConfigBuilderPlugin.getPlugin().getCommandQueue().bolus(detailedBolusInfo, new Callback() {
@Override
public void run() {
if (!result.success) {

View file

@ -55,6 +55,7 @@ import info.nightscout.androidaps.events.EventNewBG;
import info.nightscout.androidaps.events.EventRefreshOverview;
import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.IobCobCalculator.CobInfo;
@ -164,7 +165,6 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
}
@Subscribe
public void onStatusEvent(final EventNewBG e) {
Activity activity = getActivity();
@ -207,7 +207,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.overview_wizard_dialog, null, false);
View view = inflater.inflate(R.layout.overview_wizard_dialog, container, false);
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
@ -270,7 +270,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
editBg.setParams(0d, 0d, 500d, 0.1d, new DecimalFormat("0.0"), false, textWatcher);
editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false, textWatcher);
double bolusstep = ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep;
double bolusstep = ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().bolusStep;
editCorr.setParams(0d, -maxCorrection, maxCorrection, bolusstep, DecimalFormatter.pumpSupportedBolusFormat(), false, textWatcher);
editCarbTime.setParams(0d, -60d, 60d, 5d, new DecimalFormat("0"), false);
initDialog();
@ -327,8 +327,9 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
}
okClicked = true;
final Profile profile = ProfileFunctions.getInstance().getProfile();
final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
if (profile != null && (calculatedTotalInsulin > 0d || calculatedCarbs > 0d)) {
if (pump != null && profile != null && (calculatedTotalInsulin > 0d || calculatedCarbs > 0d)) {
String confirmMessage = MainApp.gs(R.string.entertreatmentquestion);
Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(calculatedTotalInsulin)).value();
@ -339,14 +340,8 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
if (carbsAfterConstraints > 0)
confirmMessage += "<br/>" + MainApp.gs(R.string.carbs) + ": " + "<font color='" + MainApp.gc(R.color.carbs) + "'>" + carbsAfterConstraints + "g" + "</font>";
if (insulinAfterConstraints - calculatedTotalInsulin != 0 || !carbsAfterConstraints.equals(calculatedCarbs)) {
okClicked = false;
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(MainApp.gs(R.string.treatmentdeliveryerror));
builder.setMessage(MainApp.gs(R.string.constraints_violation) + "\n" + MainApp.gs(R.string.changeyourinput));
builder.setPositiveButton(MainApp.gs(R.string.ok), null);
builder.show();
return;
if (Math.abs(insulinAfterConstraints - calculatedTotalInsulin) > pump.getPumpDescription().pumpType.determineCorrectBolusSize(insulinAfterConstraints) || !carbsAfterConstraints.equals(calculatedCarbs)) {
confirmMessage += "<br/><font color='" + MainApp.gc(R.color.warning) + "'>" + MainApp.gs(R.string.bolusconstraintapplied) + "</font>";
}
final Double finalInsulinAfterConstraints = insulinAfterConstraints;
@ -374,7 +369,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
loopPlugin.superBolusTo(System.currentTimeMillis() + 2 * 60L * 60 * 1000);
MainApp.bus().post(new EventRefreshOverview("WizardDialog"));
}
ConfigBuilderPlugin.getCommandQueue().tempBasalPercent(0, 120, true, profile, new Callback() {
ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalPercent(0, 120, true, profile, new Callback() {
@Override
public void run() {
if (!result.success) {
@ -399,8 +394,8 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
detailedBolusInfo.boluscalc = boluscalcJSON;
detailedBolusInfo.source = Source.USER;
detailedBolusInfo.notes = finalNotes;
if (detailedBolusInfo.insulin > 0 || ConfigBuilderPlugin.getActivePump().getPumpDescription().storesCarbInfo) {
ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() {
if (detailedBolusInfo.insulin > 0 || ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().storesCarbInfo) {
ConfigBuilderPlugin.getPlugin().getCommandQueue().bolus(detailedBolusInfo, new Callback() {
@Override
public void run() {
if (!result.success) {
@ -434,7 +429,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
private void initDialog() {
Profile profile = ProfileFunctions.getInstance().getProfile();
ProfileStore profileStore = MainApp.getConfigBuilder().getActiveProfileInterface() != null ? MainApp.getConfigBuilder().getActiveProfileInterface().getProfile() : null;
ProfileStore profileStore = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface() != null ? ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getProfile() : null;
if (profile == null || profileStore == null) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.noprofile));
@ -478,14 +473,15 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
}
private void calculateInsulin() {
ProfileStore profileStore = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile();
ProfileStore profileStore = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getProfile();
if (profileSpinner == null || profileSpinner.getSelectedItem() == null || profileStore == null)
return; // not initialized yet
String selectedAlternativeProfile = profileSpinner.getSelectedItem().toString();
Profile specificProfile;
if (selectedAlternativeProfile.equals(MainApp.gs(R.string.active)))
if (selectedAlternativeProfile.equals(MainApp.gs(R.string.active))) {
specificProfile = ProfileFunctions.getInstance().getProfile();
else
selectedAlternativeProfile = ProfileFunctions.getInstance().getProfileName();
} else
specificProfile = profileStore.getSpecificProfile(selectedAlternativeProfile);
// Entered values
@ -495,13 +491,13 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
Double corrAfterConstraint = c_correction;
if (c_correction > 0)
c_correction = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(c_correction)).value();
if (c_correction - corrAfterConstraint != 0) { // c_correction != corrAfterConstraint doesn't work
if (Math.abs(c_correction - corrAfterConstraint) > 0.01d) { // c_correction != corrAfterConstraint doesn't work
editCorr.setValue(0d);
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.bolusconstraintapplied));
return;
}
Integer carbsAfterConstraint = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(c_carbs)).value();
if (c_carbs - carbsAfterConstraint != 0) {
if (Math.abs(c_carbs - carbsAfterConstraint) > 0.01d) {
editCarbs.setValue(0d);
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.carbsconstraintapplied));
return;
@ -579,12 +575,15 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
boluscalcJSON = new JSONObject();
try {
boluscalcJSON.put("profile", selectedAlternativeProfile);
boluscalcJSON.put("notes", notesEdit.getText());
boluscalcJSON.put("eventTime", DateUtil.toISOString(new Date()));
boluscalcJSON.put("targetBGLow", wizard.targetBGLow);
boluscalcJSON.put("targetBGHigh", wizard.targetBGHigh);
boluscalcJSON.put("isf", wizard.sens);
boluscalcJSON.put("ic", wizard.ic);
boluscalcJSON.put("iob", -(wizard.insulingFromBolusIOB + wizard.insulingFromBasalsIOB));
boluscalcJSON.put("bolusiob", wizard.insulingFromBolusIOB);
boluscalcJSON.put("basaliob", wizard.insulingFromBasalsIOB);
boluscalcJSON.put("bolusiobused", bolusIobCheckbox.isChecked());
boluscalcJSON.put("basaliobused", basalIobCheckbox.isChecked());
boluscalcJSON.put("bg", c_bg);
@ -594,11 +593,18 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
boluscalcJSON.put("insulincarbs", wizard.insulinFromCarbs);
boluscalcJSON.put("carbs", c_carbs);
boluscalcJSON.put("cob", c_cob);
boluscalcJSON.put("cobused", cobCheckbox.isChecked());
boluscalcJSON.put("insulincob", wizard.insulinFromCOB);
boluscalcJSON.put("othercorrection", corrAfterConstraint);
boluscalcJSON.put("insulinsuperbolus", wizard.insulinFromSuperBolus);
boluscalcJSON.put("insulintrend", wizard.insulinFromTrend);
boluscalcJSON.put("insulin", calculatedTotalInsulin);
boluscalcJSON.put("superbolusused", superbolusCheckbox.isChecked());
boluscalcJSON.put("insulinsuperbolus", wizard.insulinFromSuperBolus);
boluscalcJSON.put("trendused", bgtrendCheckbox.isChecked());
boluscalcJSON.put("insulintrend", wizard.insulinFromTrend);
boluscalcJSON.put("trend", bgTrend.getText());
boluscalcJSON.put("ttused", ttCheckbox.isChecked());
} catch (JSONException e) {
log.error("Unhandled exception", e);
}

View file

@ -462,7 +462,8 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
super.onCreateContextMenu(menu, v, menuInfo);
if (v == apsModeView) {
final LoopPlugin loopPlugin = LoopPlugin.getPlugin();
final PumpDescription pumpDescription = ConfigBuilderPlugin.getActivePump().getPumpDescription();
final PumpDescription pumpDescription =
ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription();
if (!ProfileFunctions.getInstance().isProfileValid("ContexMenuCreation"))
return;
menu.setHeaderTitle(MainApp.gs(R.string.loop));
@ -473,23 +474,27 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
menu.add(MainApp.gs(R.string.suspendloopfor2h));
menu.add(MainApp.gs(R.string.suspendloopfor3h));
menu.add(MainApp.gs(R.string.suspendloopfor10h));
if (pumpDescription.tempDurationStep15mAllowed)
menu.add(MainApp.gs(R.string.disconnectpumpfor15m));
if (pumpDescription.tempDurationStep30mAllowed)
menu.add(MainApp.gs(R.string.disconnectpumpfor30m));
menu.add(MainApp.gs(R.string.disconnectpumpfor1h));
menu.add(MainApp.gs(R.string.disconnectpumpfor2h));
menu.add(MainApp.gs(R.string.disconnectpumpfor3h));
} else {
menu.add(MainApp.gs(R.string.resume));
} else {
if (!loopPlugin.isDisconnected()) {
menu.add(MainApp.gs(R.string.resume));
}
}
}
if (!loopPlugin.isEnabled(PluginType.LOOP))
if (!loopPlugin.isEnabled(PluginType.LOOP)) {
menu.add(MainApp.gs(R.string.enableloop));
}
if (!loopPlugin.isDisconnected()) {
showSuspendtPump(menu, pumpDescription);
} else {
menu.add(MainApp.gs(R.string.reconnect));
}
} else if (v == activeProfileView) {
menu.setHeaderTitle(MainApp.gs(R.string.profile));
menu.add(MainApp.gs(R.string.danar_viewprofile));
if (MainApp.getConfigBuilder().getActiveProfileInterface() != null && MainApp.getConfigBuilder().getActiveProfileInterface().getProfile() != null) {
if (ConfigBuilderPlugin.getPlugin().getActiveProfileInterface() != null && ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getProfile() != null) {
menu.add(MainApp.gs(R.string.careportal_profileswitch));
}
} else if (v == tempTargetView) {
@ -504,6 +509,17 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
}
}
private void showSuspendtPump(ContextMenu menu,
PumpDescription pumpDescription) {
if (pumpDescription.tempDurationStep15mAllowed)
menu.add(MainApp.gs(R.string.disconnectpumpfor15m));
if (pumpDescription.tempDurationStep30mAllowed)
menu.add(MainApp.gs(R.string.disconnectpumpfor30m));
menu.add(MainApp.gs(R.string.disconnectpumpfor1h));
menu.add(MainApp.gs(R.string.disconnectpumpfor2h));
menu.add(MainApp.gs(R.string.disconnectpumpfor3h));
}
@Override
public boolean onContextItemSelected(MenuItem item) {
final Profile profile = ProfileFunctions.getInstance().getProfile();
@ -513,9 +529,9 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
if (item.getTitle().equals(MainApp.gs(R.string.disableloop))) {
loopPlugin.setPluginEnabled(PluginType.LOOP, false);
loopPlugin.setFragmentVisible(PluginType.LOOP, false);
MainApp.getConfigBuilder().storeSettings("DisablingLoop");
ConfigBuilderPlugin.getPlugin().storeSettings("DisablingLoop");
updateGUI("suspendmenu");
ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, new Callback() {
ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(true, new Callback() {
@Override
public void run() {
if (!result.success) {
@ -528,14 +544,15 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
} else if (item.getTitle().equals(MainApp.gs(R.string.enableloop))) {
loopPlugin.setPluginEnabled(PluginType.LOOP, true);
loopPlugin.setFragmentVisible(PluginType.LOOP, true);
MainApp.getConfigBuilder().storeSettings("EnablingLoop");
ConfigBuilderPlugin.getPlugin().storeSettings("EnablingLoop");
updateGUI("suspendmenu");
NSUpload.uploadOpenAPSOffline(0);
return true;
} else if (item.getTitle().equals(MainApp.gs(R.string.resume))) {
} else if (item.getTitle().equals(MainApp.gs(R.string.resume)) ||
item.getTitle().equals(MainApp.gs(R.string.reconnect))) {
loopPlugin.suspendTo(0L);
updateGUI("suspendmenu");
ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, new Callback() {
ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(true, new Callback() {
@Override
public void run() {
if (!result.success) {
@ -697,8 +714,8 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
new NewCarbsDialog().show(manager, "CarbsDialog");
break;
case R.id.overview_pumpstatus:
if (ConfigBuilderPlugin.getActivePump().isSuspended() || !ConfigBuilderPlugin.getActivePump().isInitialized())
ConfigBuilderPlugin.getCommandQueue().readStatus("RefreshClicked", null);
if (ConfigBuilderPlugin.getPlugin().getActivePump().isSuspended() || !ConfigBuilderPlugin.getPlugin().getActivePump().isInitialized())
ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("RefreshClicked", null);
break;
}
@ -831,7 +848,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
loopPlugin.superBolusTo(System.currentTimeMillis() + T.hours(2).msecs());
MainApp.bus().post(new EventRefreshOverview("WizardDialog"));
}
ConfigBuilderPlugin.getCommandQueue().tempBasalPercent(0, 120, true, profile, new Callback() {
ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalPercent(0, 120, true, profile, new Callback() {
@Override
public void run() {
if (!result.success) {
@ -852,8 +869,8 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
detailedBolusInfo.context = context;
detailedBolusInfo.boluscalc = boluscalcJSON;
detailedBolusInfo.source = Source.USER;
if (finalInsulinAfterConstraints > 0 || ConfigBuilderPlugin.getActivePump().getPumpDescription().storesCarbInfo) {
ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() {
if (finalInsulinAfterConstraints > 0 || ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().storesCarbInfo) {
ConfigBuilderPlugin.getPlugin().getCommandQueue().bolus(detailedBolusInfo, new Callback() {
@Override
public void run() {
if (!result.success) {
@ -1059,7 +1076,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
BgReading actualBG = DatabaseHelper.actualBg();
BgReading lastBG = DatabaseHelper.lastBg();
final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
final Profile profile = ProfileFunctions.getInstance().getProfile();
@ -1111,7 +1128,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
apsModeView.setBackgroundColor(MainApp.gc(R.color.ribbonWarning));
apsModeView.setText(String.format(MainApp.gs(R.string.loopsuperbolusfor), loopPlugin.minutesToEndOfSuspend()));
apsModeView.setTextColor(MainApp.gc(R.color.ribbonTextWarning));
} else if (loopPlugin.isEnabled(PluginType.LOOP) && loopPlugin.isDisconnected()) {
} else if (loopPlugin.isDisconnected()) {
apsModeView.setBackgroundColor(MainApp.gc(R.color.ribbonCritical));
apsModeView.setText(String.format(MainApp.gs(R.string.loopdisconnectedfor), loopPlugin.minutesToEndOfSuspend()));
apsModeView.setTextColor(MainApp.gc(R.color.ribbonTextCritical));
@ -1270,7 +1287,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
// **** Various treatment buttons ****
if (carbsButton != null) {
if (SP.getBoolean(R.string.key_show_carbs_button, true)
&& (!ConfigBuilderPlugin.getActivePump().getPumpDescription().storesCarbInfo ||
&& (!ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().storesCarbInfo ||
(pump.isInitialized() && !pump.isSuspended()))) {
carbsButton.setVisibility(View.VISIBLE);
} else {
@ -1286,14 +1303,14 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
treatmentButton.setVisibility(View.GONE);
}
}
if (wizardButton != null) {
if (pump.isInitialized() && !pump.isSuspended() && 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 (pump.isInitialized() && !pump.isSuspended() && insulinButton != null) {
if (SP.getBoolean(R.string.key_show_insulin_button, true)) {
insulinButton.setVisibility(View.VISIBLE);
} else {
@ -1430,13 +1447,13 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
// Uploader status from ns
if (uploaderDeviceStatusView != null) {
uploaderDeviceStatusView.setText(NSDeviceStatus.getInstance().getUploaderStatus());
uploaderDeviceStatusView.setText(NSDeviceStatus.getInstance().getUploaderStatusSpanned());
uploaderDeviceStatusView.setOnClickListener(v -> OKDialog.show(getActivity(), MainApp.gs(R.string.uploader), NSDeviceStatus.getInstance().getExtendedUploaderStatus(), null));
}
// Sensitivity
if (sensitivityView != null) {
AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getLastAutosensDataSynchronized("Overview");
AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getLastAutosensData("Overview");
if (autosensData != null)
sensitivityView.setText(String.format("%.0f%%", autosensData.autosensResult.ratio * 100));
else

View file

@ -303,7 +303,7 @@ public class GraphData {
}
// Extended bolus
if (!ConfigBuilderPlugin.getActivePump().isFakingTempsByExtendedBoluses()) {
if (!ConfigBuilderPlugin.getPlugin().getActivePump().isFakingTempsByExtendedBoluses()) {
List<ExtendedBolus> extendedBoluses = TreatmentsPlugin.getPlugin().getExtendedBolusesFromHistory().getList();
for (int tx = 0; tx < extendedBoluses.size(); tx++) {

View file

@ -67,6 +67,11 @@ public class Notification {
public static final int MAXIMUM_BASAL_VALUE_REPLACED = 39;
public static final int NSMALFUNCTION = 40;
public static final int NEWVERSIONDETECTED = 41;
public static final int SENDLOGFILES = 42;
public static final int DEVICENOTPAIRED = 43;
public static final int MEDTRONIC_PUMP_ALARM = 44;
public static final int RILEYLINK_CONNECTION = 45;
public static final int PERMISSION_PHONESTATE = 46;
public int id;

View file

@ -13,6 +13,14 @@ import android.os.Build;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.TaskStackBuilder;
// Android Auto
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;
import android.support.v4.app.RemoteInput;
import com.squareup.otto.Subscribe;
import info.nightscout.androidaps.Config;
@ -60,6 +68,18 @@ public class PersistentNotificationPlugin extends PluginBase {
public static final int ONGOING_NOTIFICATION_ID = 4711;
private final Context ctx;
/// For Android Auto
/// Intents are not declared in manifest and not consumed, this is intentionally because actually we can't do anything with
private static final String PACKAGE = "info.nightscout";
private static final String READ_ACTION =
"info.nightscout.androidaps.ACTION_MESSAGE_READ";
private static final String REPLY_ACTION =
"info.nightscout.androidaps.ACTION_MESSAGE_REPLY";
private static final String CONVERSATION_ID = "conversation_id";
private static final String EXTRA_VOICE_REPLY = "extra_voice_reply";
/// End Android Auto
public PersistentNotificationPlugin(Context ctx) {
super(new PluginDescription()
.mainType(PluginType.GENERAL)
@ -107,9 +127,10 @@ public class PersistentNotificationPlugin extends PluginBase {
return null;
}
String line1 = "";
String line1;
String line1_aa;
if (MainApp.getConfigBuilder().getActiveProfileInterface() == null || !ProfileFunctions.getInstance().isProfileValid("Notificiation"))
if (ConfigBuilderPlugin.getPlugin().getActiveProfileInterface() == null || !ProfileFunctions.getInstance().isProfileValid("Notificiation"))
return null;
String units = ProfileFunctions.getInstance().getProfileUnits();
@ -118,22 +139,25 @@ public class PersistentNotificationPlugin extends PluginBase {
GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData();
if (lastBG != null) {
line1 = lastBG.valueToUnitsToString(units);
line1 = line1_aa = lastBG.valueToUnitsToString(units);
if (glucoseStatus != null) {
line1 += " Δ" + deltastring(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units)
+ " avgΔ" + deltastring(glucoseStatus.avgdelta, glucoseStatus.avgdelta * Constants.MGDL_TO_MMOLL, units);
line1_aa += " " + lastBG.directionToSymbol();
} else {
line1 += " " +
MainApp.gs(R.string.old_data) +
" ";
line1_aa += line1 + ".";
}
} else {
line1 = MainApp.gs(R.string.missed_bg_readings);
line1 = line1_aa = MainApp.gs(R.string.missed_bg_readings);
}
TemporaryBasal activeTemp = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(System.currentTimeMillis());
if (activeTemp != null) {
line1 += " " + activeTemp.toStringShort();
line1_aa += " " + activeTemp.toStringShort() + ".";
}
//IOB
@ -143,12 +167,55 @@ public class PersistentNotificationPlugin extends PluginBase {
IobTotal basalIob = TreatmentsPlugin.getPlugin().getLastCalculationTempBasals().round();
String line2 = MainApp.gs(R.string.treatments_iob_label_string) + " " + DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U " + MainApp.gs(R.string.cob)+": " + IobCobCalculatorPlugin.getPlugin().getCobInfo(false, "PersistentNotificationPlugin").generateCOBString();;
String line3 = DecimalFormatter.to2Decimal(ConfigBuilderPlugin.getActivePump().getBaseBasalRate()) + " U/h";
String line2 = MainApp.gs(R.string.treatments_iob_label_string) + " " + DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U " + MainApp.gs(R.string.cob)+": " + IobCobCalculatorPlugin.getPlugin().getCobInfo(false, "PersistentNotificationPlugin").generateCOBString();
String line2_aa = MainApp.gs(R.string.treatments_iob_label_string) + " " + DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U. " + MainApp.gs(R.string.cob)+": " + IobCobCalculatorPlugin.getPlugin().getCobInfo(false, "PersistentNotificationPlugin").generateCOBString() + ".";
String line3 = DecimalFormatter.to2Decimal(ConfigBuilderPlugin.getPlugin().getActivePump().getBaseBasalRate()) + " U/h";
String line3_aa = DecimalFormatter.to2Decimal(ConfigBuilderPlugin.getPlugin().getActivePump().getBaseBasalRate()) + " U/h.";
line3 += " - " + ProfileFunctions.getInstance().getProfileName();
line3_aa += " - " + ProfileFunctions.getInstance().getProfileName() + ".";
/// For Android Auto
Intent msgReadIntent = new Intent()
.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
.setAction(READ_ACTION)
.putExtra(CONVERSATION_ID, ONGOING_NOTIFICATION_ID)
.setPackage(PACKAGE);
PendingIntent msgReadPendingIntent =
PendingIntent.getBroadcast(ctx,
ONGOING_NOTIFICATION_ID,
msgReadIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
Intent msgReplyIntent = new Intent()
.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
.setAction(REPLY_ACTION)
.putExtra(CONVERSATION_ID, ONGOING_NOTIFICATION_ID)
.setPackage(PACKAGE);
PendingIntent msgReplyPendingIntent = PendingIntent.getBroadcast(
ctx,
ONGOING_NOTIFICATION_ID,
msgReplyIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
// Build a RemoteInput for receiving voice input from devices
RemoteInput remoteInput = new RemoteInput.Builder(EXTRA_VOICE_REPLY).build();
// Create the UnreadConversation
NotificationCompat.CarExtender.UnreadConversation.Builder unreadConversationBuilder =
new NotificationCompat.CarExtender.UnreadConversation.Builder(line1_aa + "\n" + line2_aa)
.setLatestTimestamp(System.currentTimeMillis())
.setReadPendingIntent(msgReadPendingIntent)
.setReplyAction(msgReplyPendingIntent, remoteInput);
/// Add dot to produce a "more natural sounding result"
unreadConversationBuilder.addMessage(line3_aa);
/// End Android Auto
NotificationCompat.Builder builder = new NotificationCompat.Builder(ctx, CHANNEL_ID);
@ -167,6 +234,11 @@ public class PersistentNotificationPlugin extends PluginBase {
builder.setContentTitle(line1);
builder.setContentText(line2);
builder.setSubText(line3);
/// Android Auto
builder.extend(new NotificationCompat.CarExtender()
.setUnreadConversation(unreadConversationBuilder.build()));
/// End Android Auto
Intent resultIntent = new Intent(ctx, MainActivity.class);

View file

@ -79,7 +79,7 @@ public class LocalProfileFragment extends SubscriberFragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
PumpDescription pumpDescription = ConfigBuilderPlugin.getActivePump().getPumpDescription();
PumpDescription pumpDescription = ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription();
View layout = inflater.inflate(R.layout.localprofile_fragment, container, false);
diaView = (NumberPicker) layout.findViewById(R.id.localprofile_dia);
diaView.setParams(LocalProfilePlugin.getPlugin().dia, 2d, 48d, 0.1d, new DecimalFormat("0.0"), false, textWatch);
@ -96,7 +96,7 @@ public class LocalProfileFragment extends SubscriberFragment {
invalidProfile = (TextView) layout.findViewById(R.id.invalidprofile);
if (!ConfigBuilderPlugin.getActivePump().getPumpDescription().isTempBasalCapable) {
if (!ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().isTempBasalCapable) {
layout.findViewById(R.id.localprofile_basal).setVisibility(View.GONE);
}
@ -156,7 +156,7 @@ public class LocalProfileFragment extends SubscriberFragment {
public String getSumLabel() {
ProfileStore profile = LocalProfilePlugin.getPlugin().createProfileStore();
if (profile != null)
return "" + DecimalFormatter.to2Decimal(profile.getDefaultProfile().baseBasalSum()) + "U";
return "" + DecimalFormatter.to2Decimal(profile.getDefaultProfile().baseBasalSum()) + MainApp.gs(R.string.insulin_unit_shortname);
else
return MainApp.gs(R.string.localprofile);
}

View file

@ -52,6 +52,8 @@ public class NSProfileFragment extends SubscriberFragment {
TextView isf;
@BindView(R.id.profileview_basal)
TextView basal;
@BindView(R.id.profileview_basaltotal)
TextView basaltotal;
@BindView(R.id.profileview_target)
TextView target;
@BindView(R.id.basal_graph)
@ -116,6 +118,7 @@ public class NSProfileFragment extends SubscriberFragment {
ic.setText(profile.getIcList());
isf.setText(profile.getIsfList());
basal.setText(profile.getBasalList());
basaltotal.setText(String.format(MainApp.gs(R.string.profile_total), DecimalFormatter.to2Decimal(profile.baseBasalSum())));
target.setText(profile.getTargetList());
basalGraph.show(profile);
}
@ -141,6 +144,7 @@ public class NSProfileFragment extends SubscriberFragment {
ic.setText("");
isf.setText("");
basal.setText("");
basaltotal.setText("");
target.setText("");
activateButton.setVisibility(View.GONE);
}

View file

@ -55,7 +55,7 @@ public class SimpleProfileFragment extends SubscriberFragment {
profileswitchButton = (Button) layout.findViewById(R.id.simpleprofile_profileswitch);
invalidProfile = (TextView) layout.findViewById(R.id.invalidprofile);
if (!ConfigBuilderPlugin.getActivePump().getPumpDescription().isTempBasalCapable) {
if (!ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().isTempBasalCapable) {
layout.findViewById(R.id.simpleprofile_basalrate).setVisibility(View.GONE);
layout.findViewById(R.id.simpleprofile_basalrate_label).setVisibility(View.GONE);
}
@ -136,7 +136,7 @@ public class SimpleProfileFragment extends SubscriberFragment {
if (activity != null)
activity.runOnUiThread(() -> {
boolean isValid = SimpleProfilePlugin.getPlugin().getProfile() != null && SimpleProfilePlugin.getPlugin().getProfile().getDefaultProfile().isValid(MainApp.gs(R.string.simpleprofile));
if (!ConfigBuilderPlugin.getActivePump().isInitialized() || ConfigBuilderPlugin.getActivePump().isSuspended() || !isValid) {
if (!ConfigBuilderPlugin.getPlugin().getActivePump().isInitialized() || ConfigBuilderPlugin.getPlugin().getActivePump().isSuspended() || !isValid) {
profileswitchButton.setVisibility(View.GONE);
} else {
profileswitchButton.setVisibility(View.VISIBLE);

View file

@ -77,7 +77,7 @@ public class ComboFragment extends SubscriberFragment implements View.OnClickLis
switch (view.getId()) {
case R.id.combo_refresh_button:
refreshButton.setEnabled(false);
ConfigBuilderPlugin.getCommandQueue().readStatus("User request", new Callback() {
ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("User request", new Callback() {
@Override
public void run() {
runOnUiThread(() -> refreshButton.setEnabled(true));
@ -124,7 +124,7 @@ public class ComboFragment extends SubscriberFragment implements View.OnClickLis
activityView.setTextColor(Color.WHITE);
activityView.setTextSize(14);
activityView.setText(activity);
} else if (ConfigBuilderPlugin.getCommandQueue().size() > 0) {
} else if (ConfigBuilderPlugin.getPlugin().getCommandQueue().size() > 0) {
activityView.setTextColor(Color.WHITE);
activityView.setTextSize(14);
activityView.setText("");

View file

@ -7,8 +7,6 @@ import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import android.support.v7.app.AlertDialog;
import com.crashlytics.android.answers.CustomEvent;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -61,10 +59,10 @@ import info.nightscout.androidaps.plugins.PumpCombo.ruffyscripter.history.Bolus;
import info.nightscout.androidaps.plugins.PumpCombo.ruffyscripter.history.PumpHistory;
import info.nightscout.androidaps.plugins.PumpCombo.ruffyscripter.history.PumpHistoryRequest;
import info.nightscout.androidaps.plugins.PumpCombo.ruffyscripter.history.Tdd;
import info.nightscout.androidaps.plugins.PumpCommon.defs.PumpType;
import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.FabricPrivacy;
import info.nightscout.utils.SP;
/**
@ -85,42 +83,6 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
private final static PumpDescription pumpDescription = new PumpDescription();
static {
// these properties can't be changed on the pump, some via desktop configuration software
pumpDescription.isBolusCapable = true;
pumpDescription.bolusStep = 0.1d;
pumpDescription.isExtendedBolusCapable = false;
pumpDescription.extendedBolusStep = 0.1d;
pumpDescription.extendedBolusDurationStep = 15;
pumpDescription.extendedBolusMaxDuration = 12 * 60;
pumpDescription.isTempBasalCapable = true;
pumpDescription.tempBasalStyle = PumpDescription.PERCENT;
pumpDescription.maxTempPercent = 500;
pumpDescription.tempPercentStep = 10;
pumpDescription.tempDurationStep = 15;
pumpDescription.tempDurationStep15mAllowed = true;
pumpDescription.tempDurationStep30mAllowed = true;
pumpDescription.tempMaxDuration = 24 * 60;
pumpDescription.isSetBasalProfileCapable = true;
pumpDescription.basalStep = 0.01d;
pumpDescription.basalMinimumRate = 0.05d;
pumpDescription.isRefillingCapable = true;
pumpDescription.storesCarbInfo = false;
pumpDescription.is30minBasalRatesCapable = false;
pumpDescription.supportsTDDs = true;
pumpDescription.needsManualTDDLoad = true;
}
@NonNull
private final RuffyCommands ruffyScripter;
@ -173,6 +135,7 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
.description(R.string.description_pump_combo)
);
ruffyScripter = new RuffyScripter(MainApp.instance().getApplicationContext());
pumpDescription.setPumpDescription(PumpType.AccuChekCombo);
}
public ComboPump getPump() {
@ -250,6 +213,15 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
return false;
}
@Override
public boolean isHandshakeInProgress() {
return false;
}
@Override
public void finishHandshaking() {
}
@Override
public void connect(String reason) {
// ruffyscripter establishes a connection as needed.
@ -353,7 +325,6 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
return basalProfile;
}
@NonNull
@Override
public long lastDataTime() {
return pump.lastSuccessfulCmdTime;
@ -597,10 +568,6 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
}
if (waitLoops > 0) {
long waitDuration = (System.currentTimeMillis() - waitStartTime) / 1000;
FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboBolusTimestampWait")
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION)
.putCustomAttribute("waitTimeSecs", String.valueOf(waitDuration)));
if (L.isEnabled(L.PUMP))
log.debug("Waited " + waitDuration + "s for pump to switch to a fresh minute before bolusing");
}
@ -703,11 +670,7 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
}
}
/**
* Updates a DetailedBolusInfo from a pump bolus and adds it as a Treatment to the DB.
* Handles edge cases when dates aren't unique which are extremely unlikely to occur,
* but if they do, the user should be warned since a bolus will be missing from calculations.
*/
/** Creates a treatment record based on the request in DetailBolusInfo and the delivered bolus. */
private boolean addBolusToTreatments(DetailedBolusInfo detailedBolusInfo, Bolus lastPumpBolus) {
DetailedBolusInfo dbi = detailedBolusInfo.copy();
dbi.date = calculateFakeBolusDate(lastPumpBolus);
@ -715,30 +678,12 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
dbi.source = Source.PUMP;
dbi.insulin = lastPumpBolus.amount;
try {
boolean treatmentCreated = TreatmentsPlugin.getPlugin().addToHistoryTreatment(dbi, false);
if (!treatmentCreated) {
log.error("Adding treatment record overrode an existing record: " + dbi);
if (dbi.isSMB) {
Notification notification = new Notification(Notification.COMBO_PUMP_ALARM, MainApp.gs(R.string.combo_error_updating_treatment_record), Notification.URGENT);
MainApp.bus().post(new EventNewNotification(notification));
}
FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboBolusToDbError")
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION)
.putCustomAttribute("bolus", String.valueOf(lastPumpBolus.amount))
.putCustomAttribute("issue", "record with same timestamp existed and was overridden"));
return false;
}
TreatmentsPlugin.getPlugin().addToHistoryTreatment(dbi, true);
} catch (Exception e) {
log.error("Adding treatment record failed", e);
if (dbi.isSMB) {
Notification notification = new Notification(Notification.COMBO_PUMP_ALARM, MainApp.gs(R.string.combo_error_updating_treatment_record), Notification.URGENT);
MainApp.bus().post(new EventNewNotification(notification));
FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboBolusToDbError")
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION)
.putCustomAttribute("bolus", String.valueOf(lastPumpBolus.amount))
.putCustomAttribute("issue", "adding record caused exception"));
}
return false;
}
@ -958,7 +903,7 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
Notification.URGENT);
n.soundId = R.raw.alarm;
MainApp.bus().post(new EventNewNotification(n));
ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, null);
ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(true, null);
}
updateLocalData(commandResult);
}
@ -1137,7 +1082,7 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
n.soundId = R.raw.alarm;
MainApp.bus().post(new EventNewNotification(n));
violationWarningRaisedForBolusAt = lowSuspendOnlyLoopEnforcedUntil;
ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, null);
ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(true, null);
}
}
}
@ -1152,10 +1097,6 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
if (aapsTbr == null && state.tbrActive && state.tbrRemainingDuration > 2) {
if (L.isEnabled(L.PUMP))
log.debug("Creating temp basal from pump TBR");
FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboTbrMismatch")
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION)
.putCustomAttribute("type", "new TBR on pump"));
TemporaryBasal newTempBasal = new TemporaryBasal()
.date(now)
.percent(state.tbrPercent)
@ -1165,10 +1106,6 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
} else if (aapsTbr != null && aapsTbr.getPlannedRemainingMinutes() > 2 && !state.tbrActive) {
if (L.isEnabled(L.PUMP))
log.debug("Ending AAPS-TBR since pump has no TBR active");
FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboTbrMismatch")
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION)
.putCustomAttribute("type", "TBR cancelled on pump"));
TemporaryBasal tempStop = new TemporaryBasal()
.date(now)
.duration(0)
@ -1179,10 +1116,6 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
Math.abs(aapsTbr.getPlannedRemainingMinutes() - state.tbrRemainingDuration) > 2)) {
if (L.isEnabled(L.PUMP))
log.debug("AAPSs and pump-TBR differ; ending AAPS-TBR and creating new TBR based on pump TBR");
FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboTbrMismatch")
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION)
.putCustomAttribute("type", "TBR on pump differs from AAPS TBR"));
TemporaryBasal tempStop = new TemporaryBasal()
.date(now - 1000)
.duration(0)
@ -1221,6 +1154,7 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
return historyResult.success;
}
/** Return value indicates whether a new record was created. */
private boolean updateDbFromPumpHistory(@NonNull PumpHistory history) {
boolean updated = false;
for (Bolus pumpBolus : history.bolusHistory) {
@ -1230,8 +1164,7 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
dbi.source = Source.PUMP;
dbi.insulin = pumpBolus.amount;
dbi.eventType = CareportalEvent.CORRECTIONBOLUS;
if (TreatmentsPlugin.getPlugin().getService().getPumpRecordById(dbi.pumpId) == null) {
TreatmentsPlugin.getPlugin().addToHistoryTreatment(dbi, false);
if (TreatmentsPlugin.getPlugin().addToHistoryTreatment(dbi, true)) {
updated = true;
}
}
@ -1303,20 +1236,14 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
if (bolusSet.size() != historyResult.history.bolusHistory.size()) {
if (L.isEnabled(L.PUMP))
log.debug("Bolus with same amount within the same minute imported. Only one will make it to the DB.");
FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboBolusToDbError")
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION)
.putCustomAttribute("bolus", "")
.putCustomAttribute("issue", "multiple pump history records with the same time and amount"));
Notification notification = new Notification(Notification.COMBO_PUMP_ALARM, MainApp.gs(R.string.
combo_error_multiple_boluses_with_identical_timestamp), Notification.URGENT);
MainApp.bus().post(new EventNewNotification(notification));
}
pumpHistoryChanged = updateDbFromPumpHistory(historyResult.history);
if (pumpHistoryChanged) {
if (L.isEnabled(L.PUMP))
log.debug("Setting 'pumpHistoryChanged' true");
if (L.isEnabled(L.PUMP) && pumpHistoryChanged) {
log.debug("Setting 'pumpHistoryChanged' true");
}
List<Bolus> updatedPumpBolusHistory = historyResult.history.bolusHistory;

View file

@ -10,7 +10,6 @@ import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.crashlytics.android.answers.CustomEvent;
import com.google.common.base.Joiner;
import org.monkey.d.ruffy.ruffy.driver.IRTHandler;
@ -39,8 +38,6 @@ import info.nightscout.androidaps.plugins.PumpCombo.ruffyscripter.commands.ReadH
import info.nightscout.androidaps.plugins.PumpCombo.ruffyscripter.commands.ReadPumpStateCommand;
import info.nightscout.androidaps.plugins.PumpCombo.ruffyscripter.commands.SetBasalProfileCommand;
import info.nightscout.androidaps.plugins.PumpCombo.ruffyscripter.commands.SetTbrCommand;
import info.nightscout.androidaps.BuildConfig;
import info.nightscout.utils.FabricPrivacy;
/**
* Provides scripting 'runtime' and operations. consider moving operations into a separate
@ -57,8 +54,6 @@ public class RuffyScripter implements RuffyCommands {
private volatile long menuLastUpdated = 0;
private volatile boolean unparsableMenuEncountered;
private String previousCommand = "<none>";
private volatile Command activeCmd = null;
private boolean started = false;
@ -67,51 +62,43 @@ public class RuffyScripter implements RuffyCommands {
private IRTHandler mHandler = new IRTHandler.Stub() {
@Override
public void log(String message) throws RemoteException {
public void log(String message) {
if (log.isTraceEnabled()) {
log.trace("Ruffy says: " + message);
}
}
@Override
public void fail(String message) throws RemoteException {
public void fail(String message) {
log.warn("Ruffy warns: " + message);
if (message.startsWith("no connection possible"))
FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboRuffyWarning").putCustomAttribute("message", "no connection possible"));
else if (message.startsWith("Error sending keep alive while rtModeRunning is still true"))
FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboRuffyWarning").putCustomAttribute("message", "Error sending keep alive while rtModeRunning is still true"));
else if (message.startsWith("Error sending keep alive. rtModeRunning is false, so this is most likely a race condition during disconnect"))
FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboRuffyWarning").putCustomAttribute("message", "Error sending keep alive. rtModeRunning is false, so this is most likely a race condition during disconnect"));
else
FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboRuffyWarning").putCustomAttribute("message", message.substring(0, 98)));
}
@Override
public void requestBluetooth() throws RemoteException {
public void requestBluetooth() {
log.trace("Ruffy invoked requestBluetooth callback");
}
@Override
public void rtStopped() throws RemoteException {
public void rtStopped() {
log.debug("rtStopped callback invoked");
currentMenu = null;
}
@Override
public void rtStarted() throws RemoteException {
public void rtStarted() {
log.debug("rtStarted callback invoked");
}
@Override
public void rtClearDisplay() throws RemoteException {
public void rtClearDisplay() {
}
@Override
public void rtUpdateDisplay(byte[] quarter, int which) throws RemoteException {
public void rtUpdateDisplay(byte[] quarter, int which) {
}
@Override
public void rtDisplayHandleMenu(Menu menu) throws RemoteException {
public void rtDisplayHandleMenu(Menu menu) {
// method is called every ~500ms
log.debug("rtDisplayHandleMenu: " + menu);
@ -124,7 +111,7 @@ public class RuffyScripter implements RuffyCommands {
}
@Override
public void rtDisplayHandleNoMenu() throws RemoteException {
public void rtDisplayHandleNoMenu() {
log.warn("rtDisplayHandleNoMenu callback invoked");
unparsableMenuEncountered = true;
}
@ -173,10 +160,6 @@ public class RuffyScripter implements RuffyCommands {
if (!boundSucceeded) {
log.error("No connection to ruffy. Pump control unavailable.");
} else {
FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboScripterInit")
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION));
}
}
@ -227,9 +210,6 @@ public class RuffyScripter implements RuffyCommands {
@Override
public CommandResult readQuickInfo(int numberOfBolusRecordsToRetrieve) {
FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboReadQuickInfoCmd")
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION));
return runCommand(new ReadQuickInfoCommand(numberOfBolusRecordsToRetrieve));
}
@ -366,7 +346,6 @@ public class RuffyScripter implements RuffyCommands {
// ignore
}
}
previousCommand = "" + activeCmd;
activeCmd = null;
}
}
@ -435,11 +414,6 @@ public class RuffyScripter implements RuffyCommands {
}
}
log.debug("Recovery from connection loss " + (connected ? "succeeded" : "failed"));
FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboRecoveryFromConnectionLoss")
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION)
.putCustomAttribute("activeCommand", "" + (activeCmd != null ? activeCmd.getClass().getSimpleName() : ""))
.putCustomAttribute("success", connected ? "true" : "else"));
return connected;
}
@ -450,12 +424,6 @@ public class RuffyScripter implements RuffyCommands {
private PumpState recoverFromCommandFailure() {
Menu menu = this.currentMenu;
if (menu == null) {
FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboRecoveryFromCommandFailure")
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION)
.putCustomAttribute("activeCommand", "" + (activeCmd != null ? activeCmd.getClass().getSimpleName() : ""))
.putCustomAttribute("exit", "1")
.putCustomAttribute("success", "false"));
return new PumpState();
}
MenuType type = menu.getType();
@ -469,21 +437,8 @@ public class RuffyScripter implements RuffyCommands {
}
try {
PumpState pumpState = readPumpStateInternal();
FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboRecoveryFromCommandFailure")
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION)
.putCustomAttribute("activeCommand", "" + (activeCmd != null ? activeCmd.getClass().getSimpleName() : ""))
.putCustomAttribute("exit", "2")
.putCustomAttribute("success", "true"));
return pumpState;
} catch (Exception e) {
FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboRecoveryFromCommandFailure")
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION)
.putCustomAttribute("exit", "3")
.putCustomAttribute("activeCommand", "" + (activeCmd != null ? activeCmd.getClass().getSimpleName() : ""))
.putCustomAttribute("success", "false"));
log.debug("Reading pump state during recovery failed", e);
return new PumpState();
}
@ -505,11 +460,6 @@ public class RuffyScripter implements RuffyCommands {
long initialUpdateTime = menuLastUpdated;
while (initialUpdateTime == menuLastUpdated) {
if (System.currentTimeMillis() > timeoutExpired) {
FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboConnectTimeout")
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION)
.putCustomAttribute("activeCommand", "" + (activeCmd != null ? activeCmd.getClass().getSimpleName() : ""))
.putCustomAttribute("previousCommand", previousCommand));
throw new CommandException("Timeout connecting to pump");
}
SystemClock.sleep(50);
@ -818,18 +768,12 @@ public class RuffyScripter implements RuffyCommands {
@Override
public CommandResult deliverBolus(double amount, BolusProgressReporter bolusProgressReporter) {
FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboBolusCmd")
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION));
return runCommand(new BolusCommand(amount, bolusProgressReporter));
}
@Override
public void cancelBolus() {
if (activeCmd instanceof BolusCommand) {
FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboBolusCmdCancel")
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION));
((BolusCommand) activeCmd).requestCancellation();
} else {
log.error("cancelBolus called, but active command is not a bolus:" + activeCmd);
@ -838,49 +782,31 @@ public class RuffyScripter implements RuffyCommands {
@Override
public CommandResult setTbr(int percent, int duration) {
FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboSetTbrCmd")
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION));
return runCommand(new SetTbrCommand(percent, duration));
}
@Override
public CommandResult cancelTbr() {
FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboCancelTbrCmd")
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION));
return runCommand(new CancelTbrCommand());
}
@Override
public CommandResult confirmAlert(int warningCode) {
FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboConfirmAlertCmd")
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION));
return runCommand(new ConfirmAlertCommand(warningCode));
}
@Override
public CommandResult readHistory(PumpHistoryRequest request) {
FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboReadHistoryCmd")
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION));
return runCommand(new ReadHistoryCommand(request));
}
@Override
public CommandResult readBasalProfile() {
FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboReadBasalProfileCmd")
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION));
return runCommand(new ReadBasalProfileCommand());
}
@Override
public CommandResult setBasalProfile(BasalProfile basalProfile) {
FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboSetBasalProfileCmd")
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION));
return runCommand(new SetBasalProfileCommand(basalProfile));
}

View file

@ -0,0 +1,49 @@
package info.nightscout.androidaps.plugins.PumpCommon.data;
/**
* Created by andy on 02/05/2018.
*/
public class DoseSettings {
private double step;
private int durationStep;
private int maxDuration;
private double minDose;
private Double maxDose;
public DoseSettings(double step, int durationStep, int maxDuration, double minDose, Double maxDose)
{
this.step = step;
this.durationStep = durationStep;
this.maxDuration = maxDuration;
this.minDose = minDose;
this.maxDose = maxDose;
}
public DoseSettings(double step, int durationStep, int maxDuration, double minDose)
{
this(step, durationStep, maxDuration, minDose, Double.MAX_VALUE);
}
public double getStep() {
return step;
}
public int getDurationStep() {
return durationStep;
}
public int getMaxDuration() {
return maxDuration;
}
public double getMinDose() {
return minDose;
}
public Double getMaxDose() {
return maxDose;
}
}

View file

@ -0,0 +1,90 @@
package info.nightscout.androidaps.plugins.PumpCommon.defs;
/**
* Created by andy on 02/05/2018.
*/
public enum DoseStepSize
{
ComboBasal( //
new DoseStepSizeEntry(0f, 1f, 0.01f), //
new DoseStepSizeEntry(1f, 10f, 0.05f), //
new DoseStepSizeEntry(10f, Double.MAX_VALUE, 0.1f)), //
InsightBolus(
new DoseStepSizeEntry(0f, 2f, 0.05f), //
new DoseStepSizeEntry(2f, 5f, 0.1f), //
new DoseStepSizeEntry(5f, 10f, 0.2f), //
new DoseStepSizeEntry(10f, Double.MAX_VALUE, 0.5f)),
MedtronicVeoBasal( //
new DoseStepSizeEntry(0f, 1f, 0.025f), //
new DoseStepSizeEntry(1f, 10f, 0.05f), //
new DoseStepSizeEntry(10f, Double.MAX_VALUE, 0.1f)), //
;
DoseStepSizeEntry[] entries;
DoseStepSize(DoseStepSizeEntry...entries)
{
this.entries = entries;
}
public double getStepSizeForAmount(double amount)
{
for (DoseStepSizeEntry entry : entries) {
if (entry.from <= amount && entry.to > amount)
return entry.value;
}
// should never come to this
return entries[entries.length-1].value;
}
public String getDescription() {
StringBuilder sb = new StringBuilder();
for (DoseStepSizeEntry entry : entries) {
sb.append(entry.value);
sb.append(" {");
sb.append(entry.from);
sb.append("-");
if (entry.to == Double.MAX_VALUE)
{
sb.append("~}");
}
else
{
sb.append(entry.to);
sb.append("}, ");
}
}
return sb.toString();
}
static class DoseStepSizeEntry
{
double from;
double to;
double value;
// to = this value is not included, but would actually mean <, so for rates between 0.025-0.975 u/h, we would have [from=0, to=10]
DoseStepSizeEntry(double from, double to, double value)
{
this.from = from;
this.to = to;
this.value = value;
}
}
}

View file

@ -0,0 +1,72 @@
package info.nightscout.androidaps.plugins.PumpCommon.defs;
/**
* Created by andy on 03/05/2018.
*/
public enum PumpCapability {
Bolus, // isBolusCapable
ExtendedBolus, // isExtendedBolusCapable
TempBasal, // isTempBasalCapable
BasalProfileSet, // isSetBasalProfileCapable
Refill, // isRefillingCapable
StoreCarbInfo, // storesCarbInfo
TDD, // supportsTDDs
ManualTDDLoad, // needsManualTDDLoad
BasalRate30min, // is30minBasalRatesCapable
// grouped by pump
VirtualPumpCapabilities(Bolus, ExtendedBolus, TempBasal, BasalProfileSet, Refill), //
ComboCapabilities(Bolus, TempBasal, BasalProfileSet, Refill, TDD, ManualTDDLoad), //
DanaCapabilities(Bolus, ExtendedBolus, TempBasal, BasalProfileSet, Refill, TDD, ManualTDDLoad), //
DanaWithHistoryCapabilities(Bolus, ExtendedBolus, TempBasal, BasalProfileSet, Refill, StoreCarbInfo, TDD, ManualTDDLoad), //
InsightCapabilities(Bolus, ExtendedBolus, TempBasal, BasalProfileSet, Refill,TDD,BasalRate30min), //
// BasalRates (separately grouped)
BasalRate_Duration15minAllowed, //
BasalRate_Duration30minAllowed, //
BasalRate_Duration15and30minAllowed(BasalRate_Duration15minAllowed, BasalRate_Duration30minAllowed), //
BasalRate_Duration15and30minNotAllowed, //
;
PumpCapability[] children;
PumpCapability()
{
}
PumpCapability(PumpCapability...children)
{
this.children = children;
}
public boolean hasCapability(PumpCapability capability)
{
// we can only check presense of simple capabilities
if (capability.children != null)
return false;
if (this == capability)
return true;
if (this.children!=null)
{
for (PumpCapability child : children) {
if (child == capability)
return true;
}
return false;
}
else
return false;
}
}

View file

@ -0,0 +1,10 @@
package info.nightscout.androidaps.plugins.PumpCommon.defs;
/**
* Created by andy on 02/05/2018.
*/
public enum PumpTempBasalType {
Percent, //
Absolute,
}

Some files were not shown because too many files have changed in this diff Show more