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 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 the problem
- Note the Build version (found in the About dialog in the app, when pressing the three dots in the - Note the Build version (found in the About dialog in the app, when pressing the three dots in the
upper-right corner). upper-right corner).
- Obtain the app's log files, which can be found on the phone in - Obtain the app's log files, which can be found on the phone in
_/storage/emulated/0/Android/data/info.nightscout.androidaps/_ _/storage/emulated/0/Android/data/info.nightscout.androidaps/_
See https://github.com/MilosKozak/AndroidAPS/wiki/Accessing-logfiles 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 # 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 * 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) [![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 = { -> def generateGitBuild = { ->
StringBuilder stringBuilder = new StringBuilder(); StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append('"')
try { try {
def stdout = new ByteArrayOutputStream() def stdout = new ByteArrayOutputStream()
exec { exec {
@ -43,9 +41,12 @@ def generateGitBuild = { ->
} catch (ignored) { } catch (ignored) {
stringBuilder.append('NoGitSystemAvailable') 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((new Date()).format('yyyy.MM.dd-HH:mm'))
stringBuilder.append('"')
return stringBuilder.toString() return stringBuilder.toString()
} }
@ -62,9 +63,10 @@ android {
targetSdkVersion 25 targetSdkVersion 25
multiDexEnabled true multiDexEnabled true
versionCode 1500 versionCode 1500
version "2.0d-dev" version "2.0"
buildConfigField "String", "VERSION", '"' + version + '"' buildConfigField "String", "VERSION", '"' + version + '"'
buildConfigField "String", "BUILDVERSION", generateGitBuild() buildConfigField "String", "BUILDVERSION", '"' + generateGitBuild() + '-' + generateDate() + '"'
buildConfigField "String", "HEAD", '"' + generateGitBuild() + '"'
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
ndk { ndk {

View file

@ -12,6 +12,7 @@
<uses-permission android:name="android.permission.RECEIVE_SMS" /> <uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.RECEIVE_MMS" /> <uses-permission android:name="android.permission.RECEIVE_MMS" />
<uses-permission android:name="android.permission.SEND_SMS" /> <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.SEND_MMS" />
<uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
@ -34,6 +35,9 @@
android:label="@string/app_name" android:label="@string/app_name"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/AppTheme.NoActionBar"> 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"> <activity android:name=".MainActivity">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />

View file

@ -9,33 +9,32 @@ var tempBasalFunctions = {};
tempBasalFunctions.getMaxSafeBasal = function getMaxSafeBasal(profile) { 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 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; 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); 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) { 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 = Math.min(profile.max_basal, 3 * profile.max_daily_basal, 4 * profile.current_basal);
var maxSafeBasal = tempBasalFunctions.getMaxSafeBasal(profile); var maxSafeBasal = tempBasalFunctions.getMaxSafeBasal(profile);
var round_basal = require('./round-basal'); var round_basal = require('./round-basal');
if (rate < 0) { if (rate < 0) {
rate = 0; rate = 0;
} // if >30m @ 0 required, zero temp will be extended to 30m instead } else if (rate > maxSafeBasal) {
else if (rate > maxSafeBasal) { rate = maxSafeBasal;
rate = maxSafeBasal;
} }
var suggestedRate = round_basal(rate, profile); 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"; rT.reason += " "+currenttemp.duration+"m left and " + currenttemp.rate + " ~ req " + suggestedRate + "U/hr: no temp required";
return rT; return rT;
} }
if (suggestedRate === profile.current_basal) { 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) { 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'); reason(rT, 'Suggested rate is same as profile rate, a temp basal is active, canceling current temp');
rT.duration = 0; 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> <maxHistory>120</maxHistory>
</rollingPolicy> </rollingPolicy>
<encoder> <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> </encoder>
</appender> </appender>

View file

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

View file

@ -182,7 +182,7 @@ public class MainActivity extends AppCompatActivity {
@Subscribe @Subscribe
public void onStatusEvent(final EventRefreshGui ev) { 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); LocaleHelper.setLocale(getApplicationContext(), lang);
runOnUiThread(() -> { runOnUiThread(() -> {
if (ev.recreate) { if (ev.recreate) {
@ -326,6 +326,7 @@ public class MainActivity extends AppCompatActivity {
case AndroidPermission.CASE_LOCATION: case AndroidPermission.CASE_LOCATION:
case AndroidPermission.CASE_SMS: case AndroidPermission.CASE_SMS:
case AndroidPermission.CASE_BATTERY: case AndroidPermission.CASE_BATTERY:
case AndroidPermission.CASE_PHONESTATE:
break; break;
} }
} }

View file

@ -93,7 +93,6 @@ public class MainApp extends Application {
public static Resources sResources; public static Resources sResources;
private static DatabaseHelper sDatabaseHelper = null; private static DatabaseHelper sDatabaseHelper = null;
private static ConfigBuilderPlugin sConfigBuilder = null;
private static ConstraintChecker sConstraintsChecker = null; private static ConstraintChecker sConstraintsChecker = null;
private static ArrayList<PluginBase> pluginsList = null; private static ArrayList<PluginBase> pluginsList = null;
@ -137,7 +136,7 @@ public class MainApp extends Application {
engineeringMode = engineeringModeSemaphore.exists() && engineeringModeSemaphore.isFile(); engineeringMode = engineeringModeSemaphore.exists() && engineeringModeSemaphore.isFile();
devBranch = BuildConfig.VERSION.contains("dev"); 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(); registerLocalBroadcastReceiver();
@ -189,18 +188,18 @@ public class MainApp extends Application {
pluginsList.add(NSClientPlugin.getPlugin()); pluginsList.add(NSClientPlugin.getPlugin());
pluginsList.add(MaintenancePlugin.initPlugin(this)); pluginsList.add(MaintenancePlugin.initPlugin(this));
pluginsList.add(sConfigBuilder = ConfigBuilderPlugin.getPlugin()); pluginsList.add(ConfigBuilderPlugin.getPlugin());
MainApp.getConfigBuilder().initialize(); ConfigBuilderPlugin.getPlugin().initialize();
} }
NSUpload.uploadAppStart(); NSUpload.uploadAppStart();
final PumpInterface pump = ConfigBuilderPlugin.getActivePump(); final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
if (pump != null) { if (pump != null) {
new Thread(() -> { new Thread(() -> {
SystemClock.sleep(5000); SystemClock.sleep(5000);
ConfigBuilderPlugin.getCommandQueue().readStatus("Initialization", null); ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("Initialization", null);
startKeepAliveService(); startKeepAliveService();
}).start(); }).start();
} }
@ -297,10 +296,6 @@ public class MainApp extends Application {
} }
} }
public static ConfigBuilderPlugin getConfigBuilder() {
return sConfigBuilder;
}
public static ConstraintChecker getConstraintChecker() { public static ConstraintChecker getConstraintChecker() {
return sConstraintsChecker; 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) if (noProfile == null || buttonDate == null || buttonZoom == null || bgGraph == null || iobGraph == null || seekBar == null)
return; return;
final PumpInterface pump = ConfigBuilderPlugin.getActivePump(); final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
final Profile profile = ProfileFunctions.getInstance().getProfile(); final Profile profile = ProfileFunctions.getInstance().getProfile();
if (profile == null) { if (profile == null) {

View file

@ -90,7 +90,7 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
pref.setSummary("******"); pref.setSummary("******");
} else if (pref.getKey().equals(MainApp.gs(R.string.key_danars_name))) { } else if (pref.getKey().equals(MainApp.gs(R.string.key_danars_name))) {
pref.setSummary(SP.getString(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()); ((EditTextPreference) pref).setDialogMessage(editTextPref.getDialogMessage());
pref.setSummary(editTextPref.getText()); pref.setSummary(editTextPref.getText());
} else if (pref.getKey().contains("smscommunicator_allowednumbers") && TextUtils.isEmpty(editTextPref.getText().trim())) { } 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(NSClientPlugin.getPlugin(), PluginType.GENERAL);
addPreferencesFromResourceIfEnabled(SmsCommunicatorPlugin.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); addPreferencesFromResource(R.xml.pref_datachoices);
addPreferencesFromResourceIfEnabled(WearPlugin.getPlugin(), PluginType.GENERAL); addPreferencesFromResourceIfEnabled(WearPlugin.getPlugin(), PluginType.GENERAL);

View file

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

View file

@ -42,6 +42,10 @@ public class ConstraintChecker implements ConstraintsInterface {
return isSMBModeEnabled(new Constraint<>(true)); return isSMBModeEnabled(new Constraint<>(true));
} }
public Constraint<Boolean> isUAMEnabled() {
return isUAMEnabled(new Constraint<>(true));
}
public Constraint<Boolean> isAdvancedFilteringEnabled() { public Constraint<Boolean> isAdvancedFilteringEnabled() {
return isAdvancedFilteringEnabled(new Constraint<>(true)); return isAdvancedFilteringEnabled(new Constraint<>(true));
} }
@ -58,6 +62,10 @@ public class ConstraintChecker implements ConstraintsInterface {
return applyBolusConstraints(new Constraint<>(Constants.REALLYHIGHBOLUS)); return applyBolusConstraints(new Constraint<>(Constants.REALLYHIGHBOLUS));
} }
public Constraint<Double> getMaxExtendedBolusAllowed() {
return applyExtendedBolusConstraints(new Constraint<>(Constants.REALLYHIGHBOLUS));
}
public Constraint<Integer> getMaxCarbsAllowed() { public Constraint<Integer> getMaxCarbsAllowed() {
return applyCarbsConstraints(new Constraint<>(Constants.REALLYHIGHCARBS)); return applyCarbsConstraints(new Constraint<>(Constants.REALLYHIGHCARBS));
} }
@ -126,6 +134,18 @@ public class ConstraintChecker implements ConstraintsInterface {
return value; 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 @Override
public Constraint<Boolean> isAdvancedFilteringEnabled(Constraint<Boolean> value) { public Constraint<Boolean> isAdvancedFilteringEnabled(Constraint<Boolean> value) {
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
@ -170,6 +190,17 @@ public class ConstraintChecker implements ConstraintsInterface {
return insulin; 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 @Override
public Constraint<Integer> applyCarbsConstraints(Constraint<Integer> carbs) { public Constraint<Integer> applyCarbsConstraints(Constraint<Integer> carbs) {
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -11,6 +11,7 @@ import org.json.JSONObject;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.Objects; import java.util.Objects;
import info.nightscout.androidaps.MainApp; 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.androidaps.plugins.ProfileLocal.LocalProfilePlugin;
import info.nightscout.utils.DateUtil; import info.nightscout.utils.DateUtil;
import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.T;
@DatabaseTable(tableName = DatabaseHelper.DATABASE_PROFILESWITCHES) @DatabaseTable(tableName = DatabaseHelper.DATABASE_PROFILESWITCHES)
public class ProfileSwitch implements Interval, DataPointWithLabelInterface { public class ProfileSwitch implements Interval, DataPointWithLabelInterface {
@ -99,6 +101,11 @@ public class ProfileSwitch implements Interval, DataPointWithLabelInterface {
return profile; 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() { public String getCustomizedName() {
String name = profileName; String name = profileName;
if(LocalProfilePlugin.LOCAL_PROFILE.equals(name)){ if(LocalProfilePlugin.LOCAL_PROFILE.equals(name)){
@ -218,6 +225,26 @@ public class ProfileSwitch implements Interval, DataPointWithLabelInterface {
MainApp.bus().post(new EventNewNotification(notification)); 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 --------- // -------- Interval interface end ---------
// ----------------- DataPointInterface -------------------- // ----------------- DataPointInterface --------------------

View file

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

View file

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

View file

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

View file

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

View file

@ -10,6 +10,7 @@ import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderFragment; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderFragment;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.queue.CommandQueue;
/** /**
* Created by mike on 09.06.2016. * Created by mike on 09.06.2016.
@ -168,7 +169,9 @@ public abstract class PluginBase {
if (getType() == PluginType.PUMP) { if (getType() == PluginType.PUMP) {
new Thread(() -> { new Thread(() -> {
SystemClock.sleep(3000); 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(); }).start();
} }
} }

View file

@ -1,48 +1,139 @@
package info.nightscout.androidaps.interfaces; 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. * Created by mike on 08.12.2016.
*/ */
public class PumpDescription { public class PumpDescription {
public PumpType pumpType = PumpType.GenericAAPS;
public PumpDescription () {
resetSettings();
}
public static final int NONE = 0; public static final int NONE = 0;
public static final int PERCENT = 0x01; public static final int PERCENT = 0x01;
public static final int ABSOLUTE = 0x02; public static final int ABSOLUTE = 0x02;
public boolean isBolusCapable = true; public boolean isBolusCapable;
public double bolusStep = 0.1d; public double bolusStep;
public boolean isExtendedBolusCapable = true; public boolean isExtendedBolusCapable;
public double extendedBolusStep = 0.1d; public double extendedBolusStep;
public double extendedBolusDurationStep = 30; public double extendedBolusDurationStep;
public double extendedBolusMaxDuration = 12 * 60; public double extendedBolusMaxDuration;
public boolean isTempBasalCapable = true; public boolean isTempBasalCapable;
public int tempBasalStyle = PERCENT; public int tempBasalStyle;
public int maxTempPercent = 200; public int maxTempPercent;
public int tempPercentStep = 10; public int tempPercentStep;
public double maxTempAbsolute = 10; public double maxTempAbsolute;
public double tempAbsoluteStep = 0.05d; public double tempAbsoluteStep;
public int tempDurationStep = 60; public int tempDurationStep;
public boolean tempDurationStep15mAllowed = false; public boolean tempDurationStep15mAllowed;
public boolean tempDurationStep30mAllowed = false; public boolean tempDurationStep30mAllowed;
public int tempMaxDuration = 12 * 60; 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 void resetSettings() {
public double basalStep = 0.01d; isBolusCapable = true;
public double basalMinimumRate = 0.04d; bolusStep = 0.1d;
public double basalMaximumRate = 25d;
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 { public interface PumpInterface {
boolean isInitialized(); boolean isInitialized(); // true if pump status has been read and is ready to accept commands
boolean isSuspended(); boolean isSuspended(); // true if suspended (not delivering insulin)
boolean isBusy(); boolean isBusy(); // if true pump is not ready to accept commands right now
boolean isConnected(); boolean isConnected(); // true if BT connection is established
boolean isConnecting(); 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 connect(String reason);
void disconnect(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 DATAFOOD = "DATAFOOD";
public static final String DATATREATMENTS = "DATATREATMENTS"; public static final String DATATREATMENTS = "DATATREATMENTS";
public static final String NSCLIENT = "NSCLIENT"; 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 PUMP = "PUMP";
public static final String PUMPQUEUE = "PUMPQUEUE"; public static final String PUMPQUEUE = "PUMPQUEUE";
public static final String PUMPCOMM = "PUMPCOMM"; public static final String PUMPCOMM = "PUMPCOMM";
@ -101,16 +101,16 @@ public class L {
logElements.add(new LogElement(APS, true)); logElements.add(new LogElement(APS, true));
logElements.add(new LogElement(AUTOSENS, false)); logElements.add(new LogElement(AUTOSENS, false));
logElements.add(new LogElement(BGSOURCE, true)); 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(CORE, true));
logElements.add(new LogElement(DATABASE, 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(DATASERVICE, true));
logElements.add(new LogElement(DATATREATMENTS, true)); logElements.add(new LogElement(DATATREATMENTS, true));
logElements.add(new LogElement(EVENTS, false, true)); logElements.add(new LogElement(EVENTS, false, true));
logElements.add(new LogElement(NOTIFICATION, true)); logElements.add(new LogElement(NOTIFICATION, true));
logElements.add(new LogElement(NSCLIENT, true)); logElements.add(new LogElement(NSCLIENT, true));
logElements.add(new LogElement(OBJECTIVES, false));
logElements.add(new LogElement(OVERVIEW, true)); logElements.add(new LogElement(OVERVIEW, true));
logElements.add(new LogElement(PROFILE, true)); logElements.add(new LogElement(PROFILE, true));
logElements.add(new LogElement(PUMP, 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() { activity.runOnUiThread(new Runnable() {
@Override @Override
public void run() { 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); profileSwitch.setVisibility(View.VISIBLE);
} else { } else {
profileSwitch.setVisibility(View.GONE); profileSwitch.setVisibility(View.GONE);
@ -142,7 +142,7 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL
return; return;
} }
final PumpInterface pump = ConfigBuilderPlugin.getActivePump(); final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
final boolean basalprofileEnabled = MainApp.isEngineeringModeOrRelease() final boolean basalprofileEnabled = MainApp.isEngineeringModeOrRelease()
&& pump.getPumpDescription().isSetBasalProfileCapable; && pump.getPumpDescription().isSetBasalProfileCapable;
@ -192,7 +192,7 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL
else else
tempTarget.setVisibility(View.VISIBLE); 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); else tddStats.setVisibility(View.VISIBLE);
} }
}); });
@ -223,13 +223,13 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL
break; break;
case R.id.actions_extendedbolus_cancel: case R.id.actions_extendedbolus_cancel:
if (TreatmentsPlugin.getPlugin().isInHistoryExtendedBoluslInProgress()) { if (TreatmentsPlugin.getPlugin().isInHistoryExtendedBoluslInProgress()) {
ConfigBuilderPlugin.getCommandQueue().cancelExtended(null); ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelExtended(null);
FabricPrivacy.getInstance().logCustom(new CustomEvent("CancelExtended")); FabricPrivacy.getInstance().logCustom(new CustomEvent("CancelExtended"));
} }
break; break;
case R.id.actions_canceltempbasal: case R.id.actions_canceltempbasal:
if (TreatmentsPlugin.getPlugin().isTempBasalInProgress()) { if (TreatmentsPlugin.getPlugin().isTempBasalInProgress()) {
ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, null); ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(true, null);
FabricPrivacy.getInstance().logCustom(new CustomEvent("CancelTemp")); FabricPrivacy.getInstance().logCustom(new CustomEvent("CancelTemp"));
} }
break; break;

View file

@ -91,7 +91,7 @@ public class FillDialog extends DialogFragment implements OnClickListener {
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { 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.ok).setOnClickListener(this);
view.findViewById(R.id.cancel).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); insulinCartridgeChangeCheckbox = view.findViewById(R.id.fill_cartridge_change);
Double maxInsulin = MainApp.getConstraintChecker().getMaxBolusAllowed().value(); 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 = view.findViewById(R.id.fill_insulinamount);
editInsulin.setParams(0d, 0d, maxInsulin, bolusstep, DecimalFormatter.pumpSupportedBolusFormat(), false, textWatcher); editInsulin.setParams(0d, 0d, maxInsulin, bolusstep, DecimalFormatter.pumpSupportedBolusFormat(), false, textWatcher);
@ -184,8 +184,8 @@ public class FillDialog extends DialogFragment implements OnClickListener {
if (insulinAfterConstraints > 0) { if (insulinAfterConstraints > 0) {
confirmMessage.add(MainApp.gs(R.string.fillwarning)); confirmMessage.add(MainApp.gs(R.string.fillwarning));
confirmMessage.add(""); confirmMessage.add("");
confirmMessage.add(MainApp.gs(R.string.bolus) + ": " + "<font color='" + MainApp.gc(R.color.colorCarbsButton) + "'>" + insulinAfterConstraints + "U" + "</font>"); confirmMessage.add(MainApp.gs(R.string.bolus) + ": " + "<font color='" + MainApp.gc(R.color.colorCarbsButton) + "'>" + DecimalFormatter.toPumpSupportedBolus(insulinAfterConstraints) + "U" + "</font>");
if (!insulinAfterConstraints.equals(insulin)) if (Math.abs(insulinAfterConstraints - insulin) > 0.01d)
confirmMessage.add("<font color='" + MainApp.gc(R.color.low) + "'>" + MainApp.gs(R.string.bolusconstraintapplied) + "</font>"); 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.source = Source.USER;
detailedBolusInfo.isValid = false; // do not count it in IOB (for pump history) detailedBolusInfo.isValid = false; // do not count it in IOB (for pump history)
detailedBolusInfo.notes = notes; detailedBolusInfo.notes = notes;
ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() { ConfigBuilderPlugin.getPlugin().getCommandQueue().bolus(detailedBolusInfo, new Callback() {
@Override @Override
public void run() { public void run() {
if (!result.success) { 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); 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 = (NumberPicker) view.findViewById(R.id.overview_newextendedbolus_insulin);
editInsulin.setParams(0d, 0d, maxInsulin, 0.1d, new DecimalFormat("0.00"), false); editInsulin.setParams(0d, 0d, maxInsulin, 0.1d, new DecimalFormat("0.00"), false);
double extendedDurationStep = ConfigBuilderPlugin.getActivePump().getPumpDescription().extendedBolusDurationStep; double extendedDurationStep = ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().extendedBolusDurationStep;
double extendedMaxDuration = ConfigBuilderPlugin.getActivePump().getPumpDescription().extendedBolusMaxDuration; double extendedMaxDuration = ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().extendedBolusMaxDuration;
editDuration = (NumberPicker) view.findViewById(R.id.overview_newextendedbolus_duration); editDuration = (NumberPicker) view.findViewById(R.id.overview_newextendedbolus_duration);
editDuration.setParams(extendedDurationStep, extendedDurationStep, extendedMaxDuration, extendedDurationStep, new DecimalFormat("0"), false); 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); 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 += " " + insulinAfterConstraint + " U ";
confirmMessage += MainApp.gs(R.string.duration) + " " + durationInMinutes + "min ?"; 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); confirmMessage += "\n" + MainApp.gs(R.string.constraintapllied);
insulin = insulinAfterConstraint; insulin = insulinAfterConstraint;
@ -87,7 +87,7 @@ public class NewExtendedBolusDialog extends DialogFragment implements View.OnCli
builder.setMessage(confirmMessage); builder.setMessage(confirmMessage);
builder.setPositiveButton(MainApp.gs(R.string.ok), new DialogInterface.OnClickListener() { builder.setPositiveButton(MainApp.gs(R.string.ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) { public void onClick(DialogInterface dialog, int id) {
ConfigBuilderPlugin.getCommandQueue().extendedBolus(finalInsulin, finalDurationInMinutes, new Callback() { ConfigBuilderPlugin.getPlugin().getCommandQueue().extendedBolus(finalInsulin, finalDurationInMinutes, new Callback() {
@Override @Override
public void run() { public void run() {
if (!result.success) { 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); absoluteRadio = (RadioButton) view.findViewById(R.id.overview_newtempbasal_absolute_radio);
typeSelectorLayout = (LinearLayout) view.findViewById(R.id.overview_newtempbasal_typeselector_layout); 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); basalPercent = (NumberPicker) view.findViewById(R.id.overview_newtempbasal_basalpercentinput);
double maxTempPercent = pumpDescription.maxTempPercent; 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(); absolute = MainApp.getConstraintChecker().applyBasalConstraints(new Constraint<>(basalAbsoluteInput), profile).value();
confirmMessage += "\n" + absolute + " U/h "; confirmMessage += "\n" + absolute + " U/h ";
confirmMessage += "\n" + MainApp.gs(R.string.duration) + " " + durationInMinutes + "min ?"; 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); confirmMessage += "\n" + MainApp.gs(R.string.constraintapllied);
} }
@ -163,9 +163,9 @@ public class NewTempBasalDialog extends DialogFragment implements View.OnClickLi
} }
}; };
if (setAsPercent) { if (setAsPercent) {
ConfigBuilderPlugin.getCommandQueue().tempBasalPercent(finalBasalPercent, finalDurationInMinutes, true, profile, callback); ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalPercent(finalBasalPercent, finalDurationInMinutes, true, profile, callback);
} else { } else {
ConfigBuilderPlugin.getCommandQueue().tempBasalAbsolute(finalBasal, finalDurationInMinutes, true, profile, callback); ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalAbsolute(finalBasal, finalDurationInMinutes, true, profile, callback);
} }
FabricPrivacy.getInstance().logCustom(new CustomEvent("TempBasal")); 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.events.EventCareportalEventChange;
import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialog; import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialog;
import info.nightscout.androidaps.plugins.Common.SubscriberFragment; 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.NSClientInternal.data.NSSettingsStatus;
import info.nightscout.androidaps.plugins.Overview.OverviewFragment; import info.nightscout.androidaps.plugins.Overview.OverviewFragment;
import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.FabricPrivacy;
@ -100,7 +101,7 @@ public class CareportalFragment extends SubscriberFragment implements View.OnCli
noProfileView = view.findViewById(R.id.profileview_noprofile); noProfileView = view.findViewById(R.id.profileview_noprofile);
butonsLayout = (LinearLayout) view.findViewById(R.id.careportal_buttons); 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) { if (profileStore == null) {
noProfileView.setVisibility(View.VISIBLE); noProfileView.setVisibility(View.VISIBLE);
butonsLayout.setVisibility(View.GONE); 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.Source;
import info.nightscout.androidaps.db.TempTarget; import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.androidaps.plugins.Careportal.OptionsToShow; import info.nightscout.androidaps.plugins.Careportal.OptionsToShow;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload;
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
import info.nightscout.utils.DateUtil; import info.nightscout.utils.DateUtil;
import info.nightscout.utils.DefaultValueHelper; import info.nightscout.utils.DefaultValueHelper;
import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.FabricPrivacy;
import info.nightscout.utils.HardLimits; import info.nightscout.utils.HardLimits;
import info.nightscout.utils.JsonHelper; import info.nightscout.utils.JsonHelper;
import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload;
import info.nightscout.utils.NumberPicker; import info.nightscout.utils.NumberPicker;
import info.nightscout.utils.SP; import info.nightscout.utils.SP;
import info.nightscout.utils.SafeParse; import info.nightscout.utils.SafeParse;
@ -173,7 +174,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
// profile // profile
profile = ProfileFunctions.getInstance().getProfile(); profile = ProfileFunctions.getInstance().getProfile();
profileStore = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile(); profileStore = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getProfile();
if (profileStore == null) { if (profileStore == null) {
if (options.eventType == R.id.careportal_profileswitch) { if (options.eventType == R.id.careportal_profileswitch) {
log.error("Profile switch called but plugin doesn't contain valid profile"); 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) { if (profile == null) {
editBg.setParams(bg, 0d, 500d, 0.1d, new DecimalFormat("0.0"), false, bgTextWatcher); 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); 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); 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); editTemptarget.setParams(bg, 0d, 30d, 0.1d, new DecimalFormat("0.0"), false);
} else { } else {
@ -278,7 +279,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
} }
sensorRadioButton.setOnCheckedChangeListener((buttonView, isChecked) -> { 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) { if (savedInstanceState != null && savedInstanceState.getDouble("editBg") != bg1) {
editBg.setValue(savedInstanceState.getDouble("editBg")); editBg.setValue(savedInstanceState.getDouble("editBg"));
} else { } else {
@ -321,7 +322,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
if (profile != null) if (profile != null)
maxPercent = MainApp.getConstraintChecker().getMaxBasalPercentAllowed(profile).value(); maxPercent = MainApp.getConstraintChecker().getMaxBasalPercentAllowed(profile).value();
editPercent = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_percentinput); 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() { TextWatcher absoluteTextWatcher = new TextWatcher() {
@Override @Override
@ -458,7 +459,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
if ((data.size() > 0) && if ((data.size() > 0) &&
(data.get(0).date > millis - 7 * 60 * 1000L) && (data.get(0).date > millis - 7 * 60 * 1000L) &&
(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) .reason(reason)
.source(Source.USER); .source(Source.USER);
if (tempTarget.durationInMinutes != 0) { if (tempTarget.durationInMinutes != 0) {
tempTarget.low(Profile.toMgdl(targetBottom, profile.getUnits())) tempTarget.low(Profile.toMgdl(targetBottom, units))
.high(Profile.toMgdl(targetTop, profile.getUnits())); .high(Profile.toMgdl(targetTop, units));
} else { } else {
tempTarget.low(0).high(0); tempTarget.low(0).high(0);
} }
@ -767,7 +768,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
profileSwitch.source = Source.USER; profileSwitch.source = Source.USER;
profileSwitch.profileName = profileName; profileSwitch.profileName = profileName;
profileSwitch.profileJson = profileStore.getSpecificProfile(profileName).getData().toString(); 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.durationInMinutes = duration;
profileSwitch.isCPP = percentage != 100 || timeshift != 0; profileSwitch.isCPP = percentage != 100 || timeshift != 0;
profileSwitch.timeshift = timeshift; profileSwitch.timeshift = timeshift;
@ -789,7 +790,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
profileSwitch.source = Source.USER; profileSwitch.source = Source.USER;
profileSwitch.profileName = ProfileFunctions.getInstance().getProfileName(System.currentTimeMillis(), false); profileSwitch.profileName = ProfileFunctions.getInstance().getProfileName(System.currentTimeMillis(), false);
profileSwitch.profileJson = ProfileFunctions.getInstance().getProfile().getData().toString(); 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.durationInMinutes = duration;
profileSwitch.isCPP = percentage != 100 || timeshift != 0; profileSwitch.isCPP = percentage != 100 || timeshift != 0;
profileSwitch.timeshift = timeshift; 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.ProfileInterface;
import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.interfaces.SensitivityInterface; import info.nightscout.androidaps.interfaces.SensitivityInterface;
import info.nightscout.androidaps.interfaces.TreatmentsInterface;
import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.Insulin.InsulinOrefRapidActingPlugin; import info.nightscout.androidaps.plugins.Insulin.InsulinOrefRapidActingPlugin;
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin; import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
@ -42,16 +41,15 @@ public class ConfigBuilderPlugin extends PluginBase {
} }
private BgSourceInterface activeBgSource; private BgSourceInterface activeBgSource;
private static PumpInterface activePump; private PumpInterface activePump;
private static ProfileInterface activeProfile; private ProfileInterface activeProfile;
private static TreatmentsInterface activeTreatments; private APSInterface activeAPS;
private static APSInterface activeAPS; private InsulinInterface activeInsulin;
private static InsulinInterface activeInsulin; private SensitivityInterface activeSensitivity;
private static SensitivityInterface activeSensitivity;
private static ArrayList<PluginBase> pluginList; private ArrayList<PluginBase> pluginList;
private static CommandQueue commandQueue = new CommandQueue(); private CommandQueue commandQueue = new CommandQueue();
public ConfigBuilderPlugin() { public ConfigBuilderPlugin() {
super(new PluginDescription() super(new PluginDescription()
@ -230,7 +228,7 @@ public class ConfigBuilderPlugin extends PluginBase {
} }
} }
public static CommandQueue getCommandQueue() { public CommandQueue getCommandQueue() {
return commandQueue; return commandQueue;
} }
@ -242,19 +240,19 @@ public class ConfigBuilderPlugin extends PluginBase {
return activeProfile; return activeProfile;
} }
public static InsulinInterface getActiveInsulin() { public InsulinInterface getActiveInsulin() {
return activeInsulin; return activeInsulin;
} }
public static APSInterface getActiveAPS() { public APSInterface getActiveAPS() {
return activeAPS; return activeAPS;
} }
public static PumpInterface getActivePump() { public PumpInterface getActivePump() {
return activePump; return activePump;
} }
public static SensitivityInterface getActiveSensitivity() { public SensitivityInterface getActiveSensitivity() {
return activeSensitivity; return activeSensitivity;
} }
@ -322,7 +320,6 @@ public class ConfigBuilderPlugin extends PluginBase {
this.setFragmentVisiblities(((PluginBase) activePump).getName(), pluginsInCategory, PluginType.PUMP); this.setFragmentVisiblities(((PluginBase) activePump).getName(), pluginsInCategory, PluginType.PUMP);
// PluginType.TREATMENT // PluginType.TREATMENT
activeTreatments = this.determineActivePlugin(PluginType.TREATMENT);
} }
/** /**

View file

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

View file

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

View file

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

View file

@ -9,6 +9,7 @@ import java.util.List;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.utils.SP; import info.nightscout.utils.SP;
import info.nightscout.utils.T;
public abstract class Objective { public abstract class Objective {
@ -128,9 +129,9 @@ public abstract class Objective {
} }
private String getDurationText(long duration) { private String getDurationText(long duration) {
int days = (int) Math.floor((double) duration / (24D * 60D * 60D * 1000D)); int days = (int) Math.floor((double) duration / T.days(1).msecs());
int hours = (int) Math.floor((double) duration / (60D * 60D * 1000D)); int hours = (int) Math.floor((double) duration / T.hours(1).msecs());
int minutes = (int) Math.floor((double) duration / (60D * 1000D)); int minutes = (int) Math.floor((double) duration / T.mins(1).msecs());
if (days > 0) return MainApp.gq(R.plurals.objective_days, days, days); 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 if (hours > 0) return MainApp.gq(R.plurals.objective_hours, hours, hours);
else return MainApp.gq(R.plurals.objective_minutes, minutes, minutes); 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) { tasks.add(new Task(R.string.objectives_bgavailableinns) {
@Override @Override
public boolean isCompleted() { public boolean isCompleted() {
return ObjectivesPlugin.bgIsAvailableInNS; return ObjectivesPlugin.getPlugin().bgIsAvailableInNS;
} }
}); });
tasks.add(new Task(R.string.nsclienthaswritepermission) { tasks.add(new Task(R.string.nsclienthaswritepermission) {
@ -50,7 +50,7 @@ public class Objective1 extends Objective {
tasks.add(new Task(R.string.objectives_pumpstatusavailableinns) { tasks.add(new Task(R.string.objectives_pumpstatusavailableinns) {
@Override @Override
public boolean isCompleted() { public boolean isCompleted() {
return ObjectivesPlugin.pumpStatusIsAvailableInNS; return ObjectivesPlugin.getPlugin().pumpStatusIsAvailableInNS;
} }
}); });
tasks.add(new Task(R.string.hasbgdata) { tasks.add(new Task(R.string.hasbgdata) {
@ -68,7 +68,7 @@ public class Objective1 extends Objective {
tasks.add(new Task(R.string.apsselected) { tasks.add(new Task(R.string.apsselected) {
@Override @Override
public boolean isCompleted() { public boolean isCompleted() {
APSInterface usedAPS = ConfigBuilderPlugin.getActiveAPS(); APSInterface usedAPS = ConfigBuilderPlugin.getPlugin().getActiveAPS();
if (usedAPS != null && ((PluginBase) usedAPS).isEnabled(PluginType.APS)) if (usedAPS != null && ((PluginBase) usedAPS).isEnabled(PluginType.APS))
return true; return true;
return false; return false;

View file

@ -5,10 +5,11 @@ import java.util.List;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin; import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin;
import info.nightscout.utils.T;
public class Objective2 extends Objective { public class Objective2 extends Objective {
public static final int MANUAL_ENACTS_NEEDED = 20; public final int MANUAL_ENACTS_NEEDED = 20;
public Objective2() { public Objective2() {
super(1, R.string.objectives_1_objective, R.string.objectives_1_gate); super(1, R.string.objectives_1_objective, R.string.objectives_1_gate);
@ -16,17 +17,19 @@ public class Objective2 extends Objective {
@Override @Override
protected void setupTasks(List<Task> tasks) { 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) { tasks.add(new Task(R.string.objectives_manualenacts) {
@Override @Override
public boolean isCompleted() { public boolean isCompleted() {
return ObjectivesPlugin.manualEnacts >= MANUAL_ENACTS_NEEDED; return ObjectivesPlugin.getPlugin().manualEnacts >= MANUAL_ENACTS_NEEDED;
} }
@Override @Override
public String getProgress() { public String getProgress() {
if (ObjectivesPlugin.manualEnacts >= MANUAL_ENACTS_NEEDED) return MainApp.gs(R.string.completed_well_done); if (ObjectivesPlugin.getPlugin().manualEnacts >= MANUAL_ENACTS_NEEDED)
else return ObjectivesPlugin.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.R;
import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.plugins.ConstraintsSafety.SafetyPlugin; import info.nightscout.androidaps.plugins.ConstraintsSafety.SafetyPlugin;
import info.nightscout.utils.T;
public class Objective4 extends Objective { public class Objective4 extends Objective {
@ -14,7 +15,7 @@ public class Objective4 extends Objective {
@Override @Override
protected void setupTasks(List<Task> tasks) { 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) { tasks.add(new Task(R.string.closedmodeenabled) {
@Override @Override
public boolean isCompleted() { public boolean isCompleted() {

View file

@ -4,6 +4,7 @@ import java.util.List;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.utils.T;
public class Objective5 extends Objective { public class Objective5 extends Objective {
@ -13,7 +14,7 @@ public class Objective5 extends Objective {
@Override @Override
protected void setupTasks(List<Task> tasks) { 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) { tasks.add(new Task(R.string.maxiobset) {
@Override @Override
public boolean isCompleted() { public boolean isCompleted() {

View file

@ -3,6 +3,7 @@ package info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives;
import java.util.List; import java.util.List;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.utils.T;
public class Objective6 extends Objective { public class Objective6 extends Objective {
@ -12,6 +13,6 @@ public class Objective6 extends Objective {
@Override @Override
protected void setupTasks(List<Task> tasks) { 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 java.util.List;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.utils.T;
public class Objective7 extends Objective { public class Objective7 extends Objective {
@ -12,6 +13,6 @@ public class Objective7 extends Objective {
@Override @Override
protected void setupTasks(List<Task> tasks) { 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 java.util.List;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.utils.T;
public class Objective8 extends Objective { public class Objective8 extends Objective {
@ -12,6 +13,6 @@ public class Objective8 extends Objective {
@Override @Override
protected void setupTasks(List<Task> tasks) { 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.PluginBase;
import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginDescription;
import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.interfaces.PumpDescription;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.OpenAPSAMA.OpenAPSAMAPlugin; import info.nightscout.androidaps.plugins.OpenAPSAMA.OpenAPSAMAPlugin;
import info.nightscout.androidaps.plugins.OpenAPSMA.OpenAPSMAPlugin; import info.nightscout.androidaps.plugins.OpenAPSMA.OpenAPSMAPlugin;
import info.nightscout.androidaps.plugins.OpenAPSSMB.OpenAPSSMBPlugin; import info.nightscout.androidaps.plugins.OpenAPSSMB.OpenAPSSMBPlugin;
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
import info.nightscout.androidaps.plugins.Overview.notifications.Notification; import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityOref1Plugin;
import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.HardLimits; import info.nightscout.utils.HardLimits;
import info.nightscout.utils.Round; import info.nightscout.utils.Round;
@ -50,7 +53,7 @@ public class SafetyPlugin extends PluginBase implements ConstraintsInterface {
**/ **/
@Override @Override
public Constraint<Boolean> isLoopInvocationAllowed(Constraint<Boolean> value) { 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); value.set(false, MainApp.gs(R.string.pumpisnottempbasalcapable), this);
return value; return value;
} }
@ -92,9 +95,20 @@ public class SafetyPlugin extends PluginBase implements ConstraintsInterface {
return value; 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 @Override
public Constraint<Boolean> isAdvancedFilteringEnabled(Constraint<Boolean> value) { public Constraint<Boolean> isAdvancedFilteringEnabled(Constraint<Boolean> value) {
BgSourceInterface bgSource = MainApp.getConfigBuilder().getActiveBgSource(); BgSourceInterface bgSource = ConfigBuilderPlugin.getPlugin().getActiveBgSource();
if (bgSource != null) { if (bgSource != null) {
if (!bgSource.advancedFilteringSupported()) 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(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); 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; return absoluteRate;
} }
@ -136,13 +162,23 @@ public class SafetyPlugin extends PluginBase implements ConstraintsInterface {
applyBasalConstraints(absoluteConstraint, profile); applyBasalConstraints(absoluteConstraint, profile);
percentRate.copyReasons(absoluteConstraint); percentRate.copyReasons(absoluteConstraint);
PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
Integer percentRateAfterConst = Double.valueOf(absoluteConstraint.value() / currentBasal * 100).intValue(); Integer percentRateAfterConst = Double.valueOf(absoluteConstraint.value() / currentBasal * 100).intValue();
if (percentRateAfterConst < 100) if (pump != null) {
percentRateAfterConst = Round.ceilTo((double) percentRateAfterConst, 10d).intValue(); if (percentRateAfterConst < 100)
else percentRateAfterConst = Round.floorTo((double) percentRateAfterConst, 10d).intValue(); 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); 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; 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(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); 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; return insulin;
} }

View file

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

View file

@ -50,10 +50,10 @@ public class InsulinFragment extends Fragment {
} }
private void updateGUI() { private void updateGUI() {
insulinName.setText(ConfigBuilderPlugin.getActiveInsulin().getFriendlyName()); insulinName.setText(ConfigBuilderPlugin.getPlugin().getActiveInsulin().getFriendlyName());
insulinComment.setText(ConfigBuilderPlugin.getActiveInsulin().getComment()); insulinComment.setText(ConfigBuilderPlugin.getPlugin().getActiveInsulin().getComment());
insulinDia.setText(MainApp.gs(R.string.dia) + " " + Double.toString(ConfigBuilderPlugin.getActiveInsulin().getDia()) + "h"); insulinDia.setText(MainApp.gs(R.string.dia) + " " + Double.toString(ConfigBuilderPlugin.getPlugin().getActiveInsulin().getDia()) + "h");
insulinGraph.show(ConfigBuilderPlugin.getActiveInsulin()); 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.SensitivityAAPSPlugin;
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityWeightedAveragePlugin; import info.nightscout.androidaps.plugins.Sensitivity.SensitivityWeightedAveragePlugin;
import info.nightscout.androidaps.plugins.Treatments.Treatment; import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.SP; import info.nightscout.utils.SP;
/** /**
@ -40,7 +41,7 @@ public class AutosensData implements DataPointWithLabelInterface {
double min5minCarbImpact = 0d; double min5minCarbImpact = 0d;
double remaining = 0d; double remaining = 0d;
public CarbsInPast(Treatment t) { CarbsInPast(Treatment t) {
time = t.date; time = t.date;
carbs = t.carbs; carbs = t.carbs;
remaining = 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); 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; public long time = 0L;
@ -89,11 +102,18 @@ public class AutosensData implements DataPointWithLabelInterface {
@Override @Override
public String toString() { public String toString() {
return "AutosensData: " + new Date(time).toLocaleString() + " " + pastSensitivity + " Delta=" + delta + " avgDelta=" + avgDelta + " Bgi=" + bgi + " Deviation=" + deviation + " avgDeviation=" + avgDeviation + " Absorbed=" + absorbed + " CarbsFromBolus=" + carbsFromBolus + " COB=" + cob + " autosensRatio=" + 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() { public List<CarbsInPast> cloneCarbsList() {
return (int) ((System.currentTimeMillis() - time) / 1000 / 60); List<CarbsInPast> newActiveCarbsList = new ArrayList<>();
for(CarbsInPast c: activeCarbsList) {
newActiveCarbsList.add(new CarbsInPast(c));
}
return newActiveCarbsList;
} }
// remove carbs older than timeframe // remove carbs older than timeframe
@ -111,7 +131,7 @@ public class AutosensData implements DataPointWithLabelInterface {
if (c.remaining > 0) if (c.remaining > 0)
cob -= c.remaining; cob -= c.remaining;
if (L.isEnabled(L.AUTOSENS)) 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 bgTime = bgReadings.get(i).date;
long lastbgTime = bgReadings.get(i - 1).date; long lastbgTime = bgReadings.get(i - 1).date;
long diff = lastbgTime - bgTime; 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; 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)) 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; return false;
} }
} }
double intervals = totalDiff / (5 * 60 * 1000d); long averageDiff = totalDiff / bgReadings.size() / 1000;
double variability = Math.abs(intervals - Math.round(intervals)); boolean is5mindata = averageDiff < 1;
boolean is5mindata = variability < 0.02;
if (L.isEnabled(L.AUTOSENS)) 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; return is5mindata;
} }
} }
@ -165,7 +168,7 @@ public class IobCobCalculatorPlugin extends PluginBase {
for (int i = 1; i < bgReadings.size(); ++i) { for (int i = 1; i < bgReadings.size(); ++i) {
if (bgReadings.get(i).date == time) return bgReadings.get(i); if (bgReadings.get(i).date == time) return bgReadings.get(i);
if (bgReadings.get(i).date > time) continue; if (bgReadings.get(i).date > time) continue;
lastFound = bgReadings.get(i-1); lastFound = bgReadings.get(i - 1);
if (bgReadings.get(i).date < time) break; if (bgReadings.get(i).date < time) break;
} }
return lastFound; return lastFound;
@ -228,13 +231,15 @@ public class IobCobCalculatorPlugin extends PluginBase {
bucketed_data = new ArrayList<>(); bucketed_data = new ArrayList<>();
bucketed_data.add(bgReadings.get(0)); 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; int j = 0;
for (int i = 1; i < bgReadings.size(); ++i) { for (int i = 1; i < bgReadings.size(); ++i) {
long bgTime = bgReadings.get(i).date; long bgTime = bgReadings.get(i).date;
long lastbgTime = bgReadings.get(i - 1).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); //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) { if (bgReadings.get(i).value < 39 || bgReadings.get(i - 1).value < 39) {
continue; throw new IllegalStateException("<39");
} }
long elapsed_minutes = (bgTime - lastbgTime) / (60 * 1000); long elapsed_minutes = (bgTime - lastbgTime) / (60 * 1000);
@ -255,7 +260,8 @@ public class IobCobCalculatorPlugin extends PluginBase {
newBgreading.value = Math.round(nextbg); newBgreading.value = Math.round(nextbg);
//console.error("Interpolated", bucketed_data[j]); //console.error("Interpolated", bucketed_data[j]);
bucketed_data.add(newBgreading); 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; elapsed_minutes = elapsed_minutes - 5;
lastbg = nextbg; lastbg = nextbg;
@ -266,14 +272,16 @@ public class IobCobCalculatorPlugin extends PluginBase {
newBgreading.value = bgReadings.get(i).value; newBgreading.value = bgReadings.get(i).value;
newBgreading.date = bgTime; newBgreading.date = bgTime;
bucketed_data.add(newBgreading); 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) { } else if (Math.abs(elapsed_minutes) > 2) {
j++; j++;
BgReading newBgreading = new BgReading(); BgReading newBgreading = new BgReading();
newBgreading.value = bgReadings.get(i).value; newBgreading.value = bgReadings.get(i).value;
newBgreading.date = bgTime; newBgreading.date = bgTime;
bucketed_data.add(newBgreading); 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 { } else {
bucketed_data.get(j).value = (bucketed_data.get(j).value + bgReadings.get(i).value) / 2; bucketed_data.get(j).value = (bucketed_data.get(j).value + bgReadings.get(i).value) / 2;
//log.error("***** Average"); //log.error("***** Average");
@ -281,12 +289,20 @@ public class IobCobCalculatorPlugin extends PluginBase {
} }
// Normalize bucketed data // 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 current = bucketed_data.get(i);
BgReading previous = bucketed_data.get(i + 1); BgReading previous = bucketed_data.get(i + 1);
long msecDiff = current.date - previous.date; long msecDiff = current.date - previous.date;
long adjusted = (msecDiff - T.mins(5).msecs()) / 1000; 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(); current.date = previous.date + T.mins(5).msecs();
} }
@ -523,7 +539,7 @@ public class IobCobCalculatorPlugin extends PluginBase {
public AutosensResult detectSensitivityWithLock(long fromTime, long toTime) { public AutosensResult detectSensitivityWithLock(long fromTime, long toTime) {
synchronized (dataLock) { 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"); log.debug("Ignoring event for non default instance");
return; return;
} }
if (MainApp.getConfigBuilder() == null) if (ConfigBuilderPlugin.getPlugin() == null)
return; // app still initializing return; // app still initializing
Profile profile = ProfileFunctions.getInstance().getProfile(); Profile profile = ProfileFunctions.getInstance().getProfile();
if (profile == null) 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.db.TempTarget;
import info.nightscout.androidaps.events.Event; import info.nightscout.androidaps.events.Event;
import info.nightscout.androidaps.logging.L; 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.ConfigBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished; import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished;
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventIobCalculationProgress; import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventIobCalculationProgress;
import info.nightscout.androidaps.plugins.OpenAPSSMB.SMBDefaults; import info.nightscout.androidaps.plugins.OpenAPSSMB.SMBDefaults;
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
import info.nightscout.androidaps.plugins.Treatments.Treatment; import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
import info.nightscout.utils.DateUtil; import info.nightscout.utils.DateUtil;
import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.FabricPrivacy;
import info.nightscout.utils.MidnightTime;
import info.nightscout.utils.Profiler;
import info.nightscout.utils.SP; import info.nightscout.utils.SP;
import static info.nightscout.utils.DateUtil.now; import static info.nightscout.utils.DateUtil.now;
@ -71,11 +77,12 @@ public class IobCobOref1Thread extends Thread {
@Override @Override
public final void run() { public final void run() {
long start = DateUtil.now();
mWakeLock.acquire(); mWakeLock.acquire();
try { try {
if (L.isEnabled(L.AUTOSENS)) if (L.isEnabled(L.AUTOSENS))
log.debug("AUTOSENSDATA thread started: " + from); log.debug("AUTOSENSDATA thread started: " + from);
if (MainApp.getConfigBuilder() == null) { if (ConfigBuilderPlugin.getPlugin() == null) {
if (L.isEnabled(L.AUTOSENS)) if (L.isEnabled(L.AUTOSENS))
log.debug("Aborting calculation thread (ConfigBuilder not ready): " + from); log.debug("Aborting calculation thread (ConfigBuilder not ready): " + from);
return; // app still initializing return; // app still initializing
@ -145,7 +152,7 @@ public class IobCobOref1Thread extends Thread {
AutosensData autosensData = new AutosensData(); AutosensData autosensData = new AutosensData();
autosensData.time = bgTime; autosensData.time = bgTime;
if (previous != null) if (previous != null)
autosensData.activeCarbsList = new ArrayList<>(previous.activeCarbsList); autosensData.activeCarbsList = previous.cloneCarbsList();
else else
autosensData.activeCarbsList = new ArrayList<>(); autosensData.activeCarbsList = new ArrayList<>();
@ -180,11 +187,24 @@ public class IobCobOref1Thread extends Thread {
if (hourAgoData != null) { if (hourAgoData != null) {
int initialIndex = autosensDataTable.indexOfKey(hourAgoData.time); int initialIndex = autosensDataTable.indexOfKey(hourAgoData.time);
if (L.isEnabled(L.AUTOSENS)) 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; int past = 1;
try { try {
for (; past < 12; past++) { for (; past < 12; past++) {
AutosensData ad = autosensDataTable.valueAt(initialIndex + 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; double deviationSlope = (ad.avgDeviation - avgDeviation) / (ad.time - bgTime) * 1000 * 60 * 5;
if (ad.avgDeviation > maxDeviation) { if (ad.avgDeviation > maxDeviation) {
slopeFromMaxDeviation = Math.min(0, deviationSlope); 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("for_data", ">>>>> bucketed_data.size()=" + bucketed_data.size() + " i=" + i + "hourAgoData=" + hourAgoData.toString())
.putCustomAttribute("past", past) .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++) { for (int ir = 0; ir < recentTreatments.size(); ir++) {
autosensData.carbsFromBolus += recentTreatments.get(ir).carbs; autosensData.carbsFromBolus += recentTreatments.get(ir).carbs;
autosensData.activeCarbsList.add(new AutosensData.CarbsInPast(recentTreatments.get(ir))); 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 // Exclude meal-related deviations (carb absorption) from autosens
if (autosensData.type.equals("non-meal")) { if (autosensData.type.equals("non-meal")) {
if (Math.abs(deviation) < Constants.DEVIATION_TO_BE_EQUAL) { if (Math.abs(deviation) < Constants.DEVIATION_TO_BE_EQUAL) {
autosensData.pastSensitivity = "="; autosensData.pastSensitivity += "=";
autosensData.validDeviation = true; autosensData.validDeviation = true;
} else if (deviation > 0) { } else if (deviation > 0) {
autosensData.pastSensitivity = "+"; autosensData.pastSensitivity += "+";
autosensData.validDeviation = true; autosensData.validDeviation = true;
} else { } else {
autosensData.pastSensitivity = "-"; autosensData.pastSensitivity += "-";
autosensData.validDeviation = true; autosensData.validDeviation = true;
} }
} else if (autosensData.type.equals("uam")) { } else if (autosensData.type.equals("uam")) {
autosensData.pastSensitivity = "u"; autosensData.pastSensitivity += "u";
} else { } 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); //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 { } finally {
mWakeLock.release(); mWakeLock.release();
MainApp.bus().post(new EventIobCalculationProgress("")); MainApp.bus().post(new EventIobCalculationProgress(""));
if (L.isEnabled(L.AUTOSENS)) if (L.isEnabled(L.AUTOSENS)) {
log.debug("AUTOSENSDATA thread ended: " + from); 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.events.Event;
import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.logging.L; 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.ConfigBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished; import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished;
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventIobCalculationProgress; import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventIobCalculationProgress;
import info.nightscout.androidaps.plugins.OpenAPSSMB.SMBDefaults; import info.nightscout.androidaps.plugins.OpenAPSSMB.SMBDefaults;
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityAAPSPlugin; import info.nightscout.androidaps.plugins.Sensitivity.SensitivityAAPSPlugin;
import info.nightscout.androidaps.plugins.Sensitivity.SensitivityWeightedAveragePlugin; import info.nightscout.androidaps.plugins.Sensitivity.SensitivityWeightedAveragePlugin;
import info.nightscout.androidaps.plugins.Treatments.Treatment; import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
import info.nightscout.utils.DateUtil; import info.nightscout.utils.DateUtil;
import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.FabricPrivacy;
import info.nightscout.utils.MidnightTime;
import info.nightscout.utils.Profiler;
import info.nightscout.utils.SP; import info.nightscout.utils.SP;
import static info.nightscout.utils.DateUtil.now; import static info.nightscout.utils.DateUtil.now;
@ -70,11 +76,12 @@ public class IobCobThread extends Thread {
@Override @Override
public final void run() { public final void run() {
long start = DateUtil.now();
mWakeLock.acquire(); mWakeLock.acquire();
try { try {
if (L.isEnabled(L.AUTOSENS)) if (L.isEnabled(L.AUTOSENS))
log.debug("AUTOSENSDATA thread started: " + from); log.debug("AUTOSENSDATA thread started: " + from);
if (MainApp.getConfigBuilder() == null) { if (ConfigBuilderPlugin.getPlugin() == null) {
if (L.isEnabled(L.AUTOSENS)) if (L.isEnabled(L.AUTOSENS))
log.debug("Aborting calculation thread (ConfigBuilder not ready): " + from); log.debug("Aborting calculation thread (ConfigBuilder not ready): " + from);
return; // app still initializing return; // app still initializing
@ -144,7 +151,7 @@ public class IobCobThread extends Thread {
AutosensData autosensData = new AutosensData(); AutosensData autosensData = new AutosensData();
autosensData.time = bgTime; autosensData.time = bgTime;
if (previous != null) if (previous != null)
autosensData.activeCarbsList = new ArrayList<>(previous.activeCarbsList); autosensData.activeCarbsList = previous.cloneCarbsList();
else else
autosensData.activeCarbsList = new ArrayList<>(); autosensData.activeCarbsList = new ArrayList<>();
@ -179,11 +186,24 @@ public class IobCobThread extends Thread {
if (hourAgoData != null) { if (hourAgoData != null) {
int initialIndex = autosensDataTable.indexOfKey(hourAgoData.time); int initialIndex = autosensDataTable.indexOfKey(hourAgoData.time);
if (L.isEnabled(L.AUTOSENS)) 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; int past = 1;
try { try {
for (; past < 12; past++) { for (; past < 12; past++) {
AutosensData ad = autosensDataTable.valueAt(initialIndex + 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; double deviationSlope = (ad.avgDeviation - avgDeviation) / (ad.time - bgTime) * 1000 * 60 * 5;
if (ad.avgDeviation > maxDeviation) { if (ad.avgDeviation > maxDeviation) {
slopeFromMaxDeviation = Math.min(0, deviationSlope); 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("for_data", ">>>>> bucketed_data.size()=" + bucketed_data.size() + " i=" + i + "hourAgoData=" + hourAgoData.toString())
.putCustomAttribute("past", past) .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++) { for (int ir = 0; ir < recentTreatments.size(); ir++) {
autosensData.carbsFromBolus += recentTreatments.get(ir).carbs; autosensData.carbsFromBolus += recentTreatments.get(ir).carbs;
autosensData.activeCarbsList.add(new AutosensData.CarbsInPast(recentTreatments.get(ir))); 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 // calculate autosens only without COB
if (autosensData.cob <= 0) { if (autosensData.cob <= 0) {
if (Math.abs(deviation) < Constants.DEVIATION_TO_BE_EQUAL) { if (Math.abs(deviation) < Constants.DEVIATION_TO_BE_EQUAL) {
autosensData.pastSensitivity = "="; autosensData.pastSensitivity += "=";
autosensData.validDeviation = true; autosensData.validDeviation = true;
} else if (deviation > 0) { } else if (deviation > 0) {
autosensData.pastSensitivity = "+"; autosensData.pastSensitivity += "+";
autosensData.validDeviation = true; autosensData.validDeviation = true;
} else { } else {
autosensData.pastSensitivity = "-"; autosensData.pastSensitivity += "-";
autosensData.validDeviation = true; autosensData.validDeviation = true;
} }
} else { } else {
autosensData.pastSensitivity = "C"; autosensData.pastSensitivity += "C";
} }
//log.debug("TIME: " + new Date(bgTime).toString() + " BG: " + bg + " SENS: " + sens + " DELTA: " + delta + " AVGDELTA: " + avgDelta + " IOB: " + iob.iob + " ACTIVITY: " + iob.activity + " BGI: " + bgi + " DEVIATION: " + deviation); //log.debug("TIME: " + new Date(bgTime).toString() + " BG: " + bg + " SENS: " + sens + " DELTA: " + delta + " AVGDELTA: " + avgDelta + " IOB: " + iob.iob + " ACTIVITY: " + iob.activity + " BGI: " + bgi + " DEVIATION: " + deviation);
@ -292,8 +323,11 @@ public class IobCobThread extends Thread {
} finally { } finally {
mWakeLock.release(); mWakeLock.release();
MainApp.bus().post(new EventIobCalculationProgress("")); MainApp.bus().post(new EventIobCalculationProgress(""));
if (L.isEnabled(L.AUTOSENS)) if (L.isEnabled(L.AUTOSENS)) {
log.debug("AUTOSENSDATA thread ended: " + from); 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.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.IobTotal;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.db.BgReading; import info.nightscout.androidaps.db.BgReading;
import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.interfaces.PumpDescription;
import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; 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.DecimalFormatter;
import info.nightscout.utils.SP;
/** /**
* Created by mike on 09.06.2016. * Created by mike on 09.06.2016.
@ -31,6 +37,8 @@ public class APSResult {
public long date = 0; public long date = 0;
public String reason; public String reason;
public double rate; public double rate;
public int percent;
public boolean usePercent = false;
public int duration; public int duration;
public boolean tempBasalRequested = false; public boolean tempBasalRequested = false;
public boolean bolusRequested = false; public boolean bolusRequested = false;
@ -43,11 +51,42 @@ public class APSResult {
public Constraint<Double> inputConstraints; public Constraint<Double> inputConstraints;
public Constraint<Double> rateConstraint; public Constraint<Double> rateConstraint;
public Constraint<Integer> percentConstraint;
public Constraint<Double> smbConstraint; 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 @Override
public String toString() { public String toString() {
final PumpInterface pump = ConfigBuilderPlugin.getActivePump(); final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
if (isChangeRequested()) { if (isChangeRequested()) {
String ret; String ret;
// rate // rate
@ -55,6 +94,10 @@ public class APSResult {
ret = MainApp.gs(R.string.canceltemp) + "\n"; ret = MainApp.gs(R.string.canceltemp) + "\n";
else if (rate == -1) else if (rate == -1)
ret = MainApp.gs(R.string.let_temp_basal_run) + "\n"; 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 else
ret = MainApp.gs(R.string.rate) + ": " + DecimalFormatter.to2Decimal(rate) + " U/h " + ret = MainApp.gs(R.string.rate) + ": " + DecimalFormatter.to2Decimal(rate) + " U/h " +
"(" + DecimalFormatter.to2Decimal(rate / pump.getBaseBasalRate() * 100) + "%) \n" + "(" + DecimalFormatter.to2Decimal(rate / pump.getBaseBasalRate() * 100) + "%) \n" +
@ -72,7 +115,7 @@ public class APSResult {
} }
public Spanned toSpanned() { public Spanned toSpanned() {
final PumpInterface pump = ConfigBuilderPlugin.getActivePump(); final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
if (isChangeRequested()) { if (isChangeRequested()) {
String ret; String ret;
// rate // rate
@ -80,9 +123,13 @@ public class APSResult {
ret = MainApp.gs(R.string.canceltemp) + "<br>"; ret = MainApp.gs(R.string.canceltemp) + "<br>";
else if (rate == -1) else if (rate == -1)
ret = MainApp.gs(R.string.let_temp_basal_run) + "<br>"; 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 else
ret = "<b>" + MainApp.gs(R.string.rate) + "</b>: " + DecimalFormatter.to2Decimal(rate) + " U/h " + 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>"; "<b>" + MainApp.gs(R.string.duration) + "</b>: " + DecimalFormatter.to2Decimal(duration) + " min<br>";
// smb // smb
@ -101,21 +148,33 @@ public class APSResult {
public APSResult clone() { public APSResult clone() {
APSResult newResult = new APSResult(); 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.rate = rate;
newResult.duration = duration; newResult.duration = duration;
newResult.tempBasalRequested = tempBasalRequested; newResult.tempBasalRequested = tempBasalRequested;
newResult.bolusRequested = bolusRequested; newResult.bolusRequested = bolusRequested;
newResult.iob = iob; 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.hasPredictions = hasPredictions;
newResult.smb = smb; newResult.smb = smb;
newResult.deliverAt = deliverAt; newResult.deliverAt = deliverAt;
newResult.rateConstraint = rateConstraint; newResult.rateConstraint = rateConstraint;
newResult.smbConstraint = smbConstraint; newResult.smbConstraint = smbConstraint;
return newResult; newResult.percent = percent;
newResult.usePercent = usePercent;
} }
public JSONObject json() { public JSONObject json() {
JSONObject json = new JSONObject(); JSONObject json = new JSONObject();
try { try {
@ -228,6 +287,119 @@ public class APSResult {
} }
public boolean isChangeRequested() { 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.DatabaseHelper;
import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.events.Event;
import info.nightscout.androidaps.events.EventNewBG; import info.nightscout.androidaps.events.EventNewBG;
import info.nightscout.androidaps.interfaces.APSInterface; import info.nightscout.androidaps.interfaces.APSInterface;
import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginDescription;
import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.interfaces.PumpDescription;
import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.interfaces.TreatmentsInterface; import info.nightscout.androidaps.interfaces.TreatmentsInterface;
import info.nightscout.androidaps.logging.L; 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.EventLoopUpdateGui;
import info.nightscout.androidaps.plugins.Loop.events.EventNewOpenLoopNotification; import info.nightscout.androidaps.plugins.Loop.events.EventNewOpenLoopNotification;
import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; 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.Treatments.TreatmentsPlugin;
import info.nightscout.androidaps.plugins.Wear.ActionStringHandler; import info.nightscout.androidaps.plugins.Wear.ActionStringHandler;
import info.nightscout.androidaps.events.EventAcceptOpenLoopChange; 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.androidaps.queue.commands.Command;
import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.FabricPrivacy;
import info.nightscout.utils.SP; import info.nightscout.utils.SP;
import info.nightscout.utils.T;
import info.nightscout.utils.ToastUtils; import info.nightscout.utils.ToastUtils;
/** /**
@ -103,7 +105,7 @@ public class LoopPlugin extends PluginBase {
.fragmentClass(LoopFragment.class.getName()) .fragmentClass(LoopFragment.class.getName())
.pluginName(R.string.loop) .pluginName(R.string.loop)
.shortName(R.string.loop_shortname) .shortName(R.string.loop_shortname)
.preferencesId(R.xml.pref_closedmode) .preferencesId(R.xml.pref_loop)
.description(R.string.description_loop) .description(R.string.description_loop)
); );
loopSuspendedTill = SP.getLong("loopSuspendedTill", 0L); loopSuspendedTill = SP.getLong("loopSuspendedTill", 0L);
@ -138,7 +140,7 @@ public class LoopPlugin extends PluginBase {
@Override @Override
public boolean specialEnableCondition() { public boolean specialEnableCondition() {
PumpInterface pump = ConfigBuilderPlugin.getActivePump(); PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
return pump == null || pump.getPumpDescription().isTempBasalCapable; 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 * 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. * the event causing the calculation is not EventNewBg.
* <p> * <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 @Subscribe
public void onStatusEvent(final EventAutosensCalculationFinished ev) { public void onStatusEvent(final EventAutosensCalculationFinished ev) {
@ -275,7 +275,7 @@ public class LoopPlugin extends PluginBase {
MainApp.bus().post(new EventLoopSetLastRunGui(message)); MainApp.bus().post(new EventLoopSetLastRunGui(message));
return; return;
} }
final PumpInterface pump = ConfigBuilderPlugin.getActivePump(); final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
APSResult result = null; APSResult result = null;
if (!isEnabled(PluginType.LOOP)) if (!isEnabled(PluginType.LOOP))
@ -293,7 +293,7 @@ public class LoopPlugin extends PluginBase {
// Check if pump info is loaded // Check if pump info is loaded
if (pump.getBaseBasalRate() < 0.01d) return; if (pump.getBaseBasalRate() < 0.01d) return;
APSInterface usedAPS = ConfigBuilderPlugin.getActiveAPS(); APSInterface usedAPS = ConfigBuilderPlugin.getPlugin().getActiveAPS();
if (usedAPS != null && ((PluginBase) usedAPS).isEnabled(PluginType.APS)) { if (usedAPS != null && ((PluginBase) usedAPS).isEnabled(PluginType.APS)) {
usedAPS.invoke(initiator, tempBasalFallback); usedAPS.invoke(initiator, tempBasalFallback);
result = usedAPS.getLastAPSResult(); result = usedAPS.getLastAPSResult();
@ -305,16 +305,26 @@ public class LoopPlugin extends PluginBase {
return; 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 // check rate for constrais
final APSResult resultAfterConstraints = result.clone(); final APSResult resultAfterConstraints = result.clone();
resultAfterConstraints.rateConstraint = new Constraint<>(resultAfterConstraints.rate); resultAfterConstraints.rateConstraint = new Constraint<>(resultAfterConstraints.rate);
resultAfterConstraints.rate = MainApp.getConstraintChecker().applyBasalConstraints(resultAfterConstraints.rateConstraint, profile).value(); 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.smbConstraint = new Constraint<>(resultAfterConstraints.smb);
resultAfterConstraints.smb = MainApp.getConstraintChecker().applyBolusConstraints(resultAfterConstraints.smbConstraint).value(); resultAfterConstraints.smb = MainApp.getConstraintChecker().applyBolusConstraints(resultAfterConstraints.smbConstraint).value();
// safety check for multiple SMBs // safety check for multiple SMBs
long lastBolusTime = TreatmentsPlugin.getPlugin().getLastBolusTime(); 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)) if (L.isEnabled(L.APS))
log.debug("SMB requsted but still in 3 min interval"); log.debug("SMB requsted but still in 3 min interval");
resultAfterConstraints.smb = 0; resultAfterConstraints.smb = 0;
@ -347,9 +357,9 @@ public class LoopPlugin extends PluginBase {
Constraint<Boolean> closedLoopEnabled = MainApp.getConstraintChecker().isClosedLoopAllowed(); Constraint<Boolean> closedLoopEnabled = MainApp.getConstraintChecker().isClosedLoopAllowed();
if (closedLoopEnabled.value()) { if (closedLoopEnabled.value()) {
if (result.isChangeRequested() if (resultAfterConstraints.isChangeRequested()
&& !ConfigBuilderPlugin.getCommandQueue().bolusInQueue() && !ConfigBuilderPlugin.getPlugin().getCommandQueue().bolusInQueue()
&& !ConfigBuilderPlugin.getCommandQueue().isRunning(Command.CommandType.BOLUS)) { && !ConfigBuilderPlugin.getPlugin().getCommandQueue().isRunning(Command.CommandType.BOLUS)) {
final PumpEnactResult waiting = new PumpEnactResult(); final PumpEnactResult waiting = new PumpEnactResult();
waiting.queued = true; waiting.queued = true;
if (resultAfterConstraints.tempBasalRequested) if (resultAfterConstraints.tempBasalRequested)
@ -390,7 +400,7 @@ public class LoopPlugin extends PluginBase {
lastRun.smbSetByPump = null; lastRun.smbSetByPump = null;
} }
} else { } else {
if (result.isChangeRequested() && allowNotification) { if (resultAfterConstraints.isChangeRequested() && allowNotification) {
NotificationCompat.Builder builder = NotificationCompat.Builder builder =
new NotificationCompat.Builder(MainApp.instance().getApplicationContext(), CHANNEL_ID); new NotificationCompat.Builder(MainApp.instance().getApplicationContext(), CHANNEL_ID);
builder.setSmallIcon(R.drawable.notif_icon) builder.setSmallIcon(R.drawable.notif_icon)
@ -399,8 +409,10 @@ public class LoopPlugin extends PluginBase {
.setAutoCancel(true) .setAutoCancel(true)
.setPriority(Notification.PRIORITY_HIGH) .setPriority(Notification.PRIORITY_HIGH)
.setCategory(Notification.CATEGORY_ALARM) .setCategory(Notification.CATEGORY_ALARM)
.setVisibility(Notification.VISIBILITY_PUBLIC) .setVisibility(Notification.VISIBILITY_PUBLIC);
.setLocalOnly(true); if (SP.getBoolean("wearcontrol", false)) {
builder.setLocalOnly(true);
}
// Creates an explicit intent for an Activity in your app // Creates an explicit intent for an Activity in your app
Intent resultIntent = new Intent(MainApp.instance().getApplicationContext(), MainActivity.class); Intent resultIntent = new Intent(MainApp.instance().getApplicationContext(), MainActivity.class);
@ -454,8 +466,8 @@ public class LoopPlugin extends PluginBase {
NSUpload.uploadDeviceStatus(); NSUpload.uploadDeviceStatus();
ObjectivesPlugin objectivesPlugin = MainApp.getSpecificPlugin(ObjectivesPlugin.class); ObjectivesPlugin objectivesPlugin = MainApp.getSpecificPlugin(ObjectivesPlugin.class);
if (objectivesPlugin != null) { if (objectivesPlugin != null) {
ObjectivesPlugin.manualEnacts++; ObjectivesPlugin.getPlugin().manualEnacts++;
ObjectivesPlugin.saveProgress(); ObjectivesPlugin.getPlugin().saveProgress();
} }
} }
MainApp.bus().post(new EventAcceptOpenLoopChange()); 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 * 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) { public void applyTBRRequest(APSResult request, Profile profile, Callback callback) {
boolean allowPercentage = VirtualPumpPlugin.getPlugin().isEnabled(PluginType.PUMP);
if (!request.tempBasalRequested) { if (!request.tempBasalRequested) {
if (callback != null) { if (callback != null) {
callback.result(new PumpEnactResult().enacted(false).success(true).comment(MainApp.gs(R.string.nochangerequested))).run(); 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; return;
} }
PumpInterface pump = MainApp.getConfigBuilder().getActivePump(); PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
TreatmentsInterface activeTreatments = TreatmentsPlugin.getPlugin(); TreatmentsInterface activeTreatments = TreatmentsPlugin.getPlugin();
request.rateConstraint = new Constraint<>(request.rate);
request.rate = MainApp.getConstraintChecker().applyBasalConstraints(request.rateConstraint, profile).value();
if (!pump.isInitialized()) { if (!pump.isInitialized()) {
if (L.isEnabled(L.APS)) if (L.isEnabled(L.APS))
log.debug("applyAPSRequest: " + MainApp.gs(R.string.pumpNotInitialized)); log.debug("applyAPSRequest: " + MainApp.gs(R.string.pumpNotInitialized));
@ -504,34 +517,66 @@ public class LoopPlugin extends PluginBase {
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
TemporaryBasal activeTemp = activeTreatments.getTempBasalFromHistory(now); TemporaryBasal activeTemp = activeTreatments.getTempBasalFromHistory(now);
if ((request.rate == 0 && request.duration == 0) || Math.abs(request.rate - pump.getBaseBasalRate()) < pump.getPumpDescription().basalStep) { if (request.usePercent && allowPercentage) {
if (activeTemp != null) { 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)) if (L.isEnabled(L.APS))
log.debug("applyAPSRequest: cancelTempBasal()"); log.debug("applyAPSRequest: Temp basal set correctly");
MainApp.getConfigBuilder().getCommandQueue().cancelTempBasal(false, callback); 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 { } else {
if (L.isEnabled(L.APS)) if (L.isEnabled(L.APS))
log.debug("applyAPSRequest: Basal set correctly"); log.debug("applyAPSRequest: tempBasalPercent()");
if (callback != null) { ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalPercent(request.percent, request.duration, false, profile, callback);
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 { } else {
if (L.isEnabled(L.APS)) if ((request.rate == 0 && request.duration == 0) || Math.abs(request.rate - pump.getBaseBasalRate()) < pump.getPumpDescription().basalStep) {
log.debug("applyAPSRequest: setTempBasalAbsolute()"); if (activeTemp != null) {
MainApp.getConfigBuilder().getCommandQueue().tempBasalAbsolute(request.rate, request.duration, false, profile, callback); 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; return;
} }
PumpInterface pump = MainApp.getConfigBuilder().getActivePump(); PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
TreatmentsInterface activeTreatments = TreatmentsPlugin.getPlugin(); TreatmentsInterface activeTreatments = TreatmentsPlugin.getPlugin();
long lastBolusTime = activeTreatments.getLastBolusTime(); long lastBolusTime = activeTreatments.getLastBolusTime();
@ -586,15 +631,15 @@ public class LoopPlugin extends PluginBase {
detailedBolusInfo.deliverAt = request.deliverAt; detailedBolusInfo.deliverAt = request.deliverAt;
if (L.isEnabled(L.APS)) if (L.isEnabled(L.APS))
log.debug("applyAPSRequest: bolus()"); log.debug("applyAPSRequest: bolus()");
MainApp.getConfigBuilder().getCommandQueue().bolus(detailedBolusInfo, callback); ConfigBuilderPlugin.getPlugin().getCommandQueue().bolus(detailedBolusInfo, callback);
} }
public void disconnectPump(int durationInMinutes, Profile profile) { public void disconnectPump(int durationInMinutes, Profile profile) {
PumpInterface pump = MainApp.getConfigBuilder().getActivePump(); PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
TreatmentsInterface activeTreatments = TreatmentsPlugin.getPlugin(); TreatmentsInterface activeTreatments = TreatmentsPlugin.getPlugin();
LoopPlugin.getPlugin().disconnectTo(System.currentTimeMillis() + durationInMinutes * 60 * 1000L); 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 @Override
public void run() { public void run() {
if (!result.success) { if (!result.success) {
@ -603,7 +648,7 @@ public class LoopPlugin extends PluginBase {
} }
}); });
if (pump.getPumpDescription().isExtendedBolusCapable && activeTreatments.isInHistoryExtendedBoluslInProgress()) { if (pump.getPumpDescription().isExtendedBolusCapable && activeTreatments.isInHistoryExtendedBoluslInProgress()) {
MainApp.getConfigBuilder().getCommandQueue().cancelExtended(new Callback() { ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelExtended(new Callback() {
@Override @Override
public void run() { public void run() {
if (!result.success) { if (!result.success) {
@ -617,7 +662,7 @@ public class LoopPlugin extends PluginBase {
public void suspendLoop(int durationInMinutes) { public void suspendLoop(int durationInMinutes) {
LoopPlugin.getPlugin().suspendTo(System.currentTimeMillis() + durationInMinutes * 60 * 1000); LoopPlugin.getPlugin().suspendTo(System.currentTimeMillis() + durationInMinutes * 60 * 1000);
MainApp.getConfigBuilder().getCommandQueue().cancelTempBasal(true, new Callback() { ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(true, new Callback() {
@Override @Override
public void run() { public void run() {
if (!result.success) { if (!result.success) {

View file

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

View file

@ -4,13 +4,14 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.LoggerContext; 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). * This class provides serveral methods for log-handling (eg. sending logs as emails).
*/ */
public class LoggerUtils { 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"; public static String SUFFIX = ".log.zip";

View file

@ -21,15 +21,19 @@ import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream; import java.util.zip.ZipOutputStream;
import info.nightscout.androidaps.BuildConfig; import info.nightscout.androidaps.BuildConfig;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginDescription;
import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.NSClientInternal.data.NSSettingsStatus;
import info.nightscout.utils.SP; import info.nightscout.utils.SP;
public class MaintenancePlugin extends PluginBase { 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; private final Context ctx;
@ -69,8 +73,8 @@ public class MaintenancePlugin extends PluginBase {
} }
public void sendLogs() { public void sendLogs() {
String recipient = SP.getString("key_maintenance_logs_email", "logs@androidaps.org"); String recipient = SP.getString(R.string.key_maintenance_logs_email, "logs@androidaps.org");
int amount = SP.getInt("key_maintenance_logs_amount", 2); int amount = SP.getInt(R.string.key_maintenance_logs_amount, 2);
String logDirectory = LoggerUtils.getLogDirectory(); String logDirectory = LoggerUtils.getLogDirectory();
List<File> logs = this.getLogfiles(logDirectory, amount); 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())); Arrays.sort(files, (f1, f2) -> f1.getName().compareTo(f2.getName()));
List<File> delFiles = Arrays.asList(files); 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; int keepIndex = amount - 1;
if (keepIndex < delFiles.size()) { if (keepIndex < delFiles.size()) {
@ -203,6 +207,30 @@ public class MaintenancePlugin extends PluginBase {
out.close(); 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. * 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 attachementUri
* @param recipient * @param recipient
* @param subject * @param subject
* @param body
*
* @return * @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); LOG.debug("sending email to {} with subject {}", recipient, subject);
Intent emailIntent = new Intent(Intent.ACTION_SEND); Intent emailIntent = new Intent(Intent.ACTION_SEND);
emailIntent.setType("text/plain"); emailIntent.setType("text/plain");
emailIntent.putExtra(Intent.EXTRA_EMAIL , new String[]{recipient}); emailIntent.putExtra(Intent.EXTRA_EMAIL , new String[]{recipient});
emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject); emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
emailIntent.putExtra(Intent.EXTRA_TEXT, ""); emailIntent.putExtra(Intent.EXTRA_TEXT, body);
LOG.debug("put path {}", attachementUri.toString()); LOG.debug("put path {}", attachementUri.toString());
emailIntent.putExtra(Intent.EXTRA_STREAM, attachementUri); emailIntent.putExtra(Intent.EXTRA_STREAM, attachementUri);

View file

@ -249,7 +249,7 @@ public class NSUpload {
log.debug("OpenAPS data too old to upload"); log.debug("OpenAPS data too old to upload");
} }
deviceStatus.device = "openaps://" + Build.MANUFACTURER + " " + Build.MODEL; 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) { if (pumpstatus != null) {
deviceStatus.pump = pumpstatus; deviceStatus.pump = pumpstatus;
} }

View file

@ -28,7 +28,7 @@ public class BroadcastAckAlarm {
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); 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 = new Bundle();
bundle.putInt("level", originalAlarm.getLevel()); bundle.putInt("level", originalAlarm.getLevel());
bundle.putString("group", originalAlarm.getGroup()); bundle.putString("group", originalAlarm.getGroup());

View file

@ -24,7 +24,7 @@ public class BroadcastAlarm {
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); 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 = new Bundle();
bundle.putString("data", alarm.toString()); bundle.putString("data", alarm.toString());
intent = new Intent(Intents.ACTION_ALARM); intent = new Intent(Intents.ACTION_ALARM);

View file

@ -24,7 +24,7 @@ public class BroadcastAnnouncement {
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); 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 = new Bundle();
bundle.putString("data", announcement.toString()); bundle.putString("data", announcement.toString());
intent = new Intent(Intents.ACTION_ANNOUNCEMENT); intent = new Intent(Intents.ACTION_ANNOUNCEMENT);

View file

@ -26,7 +26,7 @@ public class BroadcastCals {
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); 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 = new Bundle();
bundle.putString("cals", cals.toString()); bundle.putString("cals", cals.toString());
bundle.putBoolean("delta", isDelta); bundle.putBoolean("delta", isDelta);

View file

@ -24,7 +24,7 @@ public class BroadcastClearAlarm {
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); 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 = new Bundle();
bundle.putString("data", clearalarm.toString()); bundle.putString("data", clearalarm.toString());
intent = new Intent(Intents.ACTION_CLEAR_ALARM); intent = new Intent(Intents.ACTION_CLEAR_ALARM);

View file

@ -29,7 +29,7 @@ public class BroadcastDeviceStatus {
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); 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); splitted = BroadcastTreatment.splitArray(statuses);
for (JSONArray part : splitted) { for (JSONArray part : splitted) {
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();

View file

@ -31,7 +31,7 @@ public class BroadcastFood {
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); 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) { for (JSONArray part : splitted) {
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.putString("foods", part.toString()); bundle.putString("foods", part.toString());
@ -57,7 +57,7 @@ public class BroadcastFood {
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); 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) { for (JSONArray part : splitted) {
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.putString("foods", part.toString()); bundle.putString("foods", part.toString());
@ -81,7 +81,7 @@ public class BroadcastFood {
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); 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 = new Bundle();
bundle.putString("foods", foods.toString()); bundle.putString("foods", foods.toString());
bundle.putBoolean("delta", isDelta); bundle.putBoolean("delta", isDelta);

View file

@ -26,7 +26,7 @@ public class BroadcastMbgs {
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); 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 = new Bundle();
bundle.putString("mbgs", mbgs.toString()); bundle.putString("mbgs", mbgs.toString());
bundle.putBoolean("delta", isDelta); bundle.putBoolean("delta", isDelta);

View file

@ -26,7 +26,7 @@ public class BroadcastProfile {
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); 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 = new Bundle();
bundle.putString("profile", profile.getData().toString()); bundle.putString("profile", profile.getData().toString());
bundle.putBoolean("delta", isDelta); bundle.putBoolean("delta", isDelta);

View file

@ -31,7 +31,7 @@ public class BroadcastSgvs {
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); 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) { for (JSONArray part : splitted) {
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.putString("sgvs", part.toString()); bundle.putString("sgvs", part.toString());

View file

@ -27,7 +27,7 @@ public class BroadcastStatus {
LocalBroadcastManager.getInstance(MainApp.instance()) LocalBroadcastManager.getInstance(MainApp.instance())
.sendBroadcast(createIntent(status, isDelta)); .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)); context.sendBroadcast(createIntent(status, isDelta));
} }
} }

View file

@ -36,7 +36,7 @@ public class BroadcastTreatment {
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); 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 = new Bundle();
bundle.putString("treatment", treatment.toString()); bundle.putString("treatment", treatment.toString());
bundle.putBoolean("delta", isDelta); bundle.putBoolean("delta", isDelta);
@ -60,7 +60,7 @@ public class BroadcastTreatment {
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); 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); splitted = splitArray(treatments);
for (JSONArray part : splitted) { for (JSONArray part : splitted) {
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
@ -87,7 +87,7 @@ public class BroadcastTreatment {
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); 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); splitted = splitArray(treatments);
for (JSONArray part : splitted) { for (JSONArray part : splitted) {
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
@ -112,7 +112,7 @@ public class BroadcastTreatment {
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); 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 = new Bundle();
bundle.putString("treatments", treatments.toString()); bundle.putString("treatments", treatments.toString());
bundle.putBoolean("delta", isDelta); bundle.putBoolean("delta", isDelta);

View file

@ -24,7 +24,7 @@ public class BroadcastUrgentAlarm {
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); 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 = new Bundle();
bundle.putString("data", urgentalarm.toString()); bundle.putString("data", urgentalarm.toString());
intent = new Intent(Intents.ACTION_URGENT_ALARM); intent = new Intent(Intents.ACTION_URGENT_ALARM);

View file

@ -15,6 +15,7 @@ import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin; import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin;
@ -107,8 +108,8 @@ public class NSDeviceStatus {
setData(devicestatusJson); setData(devicestatusJson);
if (devicestatusJson.has("pump")) { if (devicestatusJson.has("pump")) {
// Objectives 0 // Objectives 0
ObjectivesPlugin.pumpStatusIsAvailableInNS = true; ObjectivesPlugin.getPlugin().pumpStatusIsAvailableInNS = true;
ObjectivesPlugin.saveProgress(); ObjectivesPlugin.getPlugin().saveProgress();
} }
} }
if (bundle.containsKey("devicestatuses")) { if (bundle.containsKey("devicestatuses")) {
@ -119,8 +120,8 @@ public class NSDeviceStatus {
setData(devicestatusJson); setData(devicestatusJson);
if (devicestatusJson.has("pump")) { if (devicestatusJson.has("pump")) {
// Objectives 0 // Objectives 0
ObjectivesPlugin.pumpStatusIsAvailableInNS = true; ObjectivesPlugin.getPlugin().pumpStatusIsAvailableInNS = true;
ObjectivesPlugin.saveProgress(); ObjectivesPlugin.getPlugin().saveProgress();
} }
} }
} }
@ -174,10 +175,14 @@ public class NSDeviceStatus {
public Spanned getPumpStatus() { public Spanned getPumpStatus() {
//String[] ALL_STATUS_FIELDS = {"reservoir", "battery", "clock", "status", "device"}; //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) if (deviceStatusPumpData == null)
return Html.fromHtml(""); return Html.fromHtml("");
StringBuilder string = new StringBuilder();
// test warning level // test warning level
int level = Levels.INFO; int level = Levels.INFO;
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
@ -329,6 +334,10 @@ public class NSDeviceStatus {
public Spanned getOpenApsStatus() { public Spanned getOpenApsStatus() {
StringBuilder string = new StringBuilder(); 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 // test warning level
int level = Levels.INFO; int level = Levels.INFO;
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
@ -426,6 +435,26 @@ public class NSDeviceStatus {
return minBattery + "%"; 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() { public Spanned getExtendedUploaderStatus() {
StringBuilder string = new StringBuilder(); StringBuilder string = new StringBuilder();

View file

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

View file

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

View file

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

View file

@ -67,13 +67,13 @@ public class OpenAPSAMAPlugin extends PluginBase implements APSInterface {
@Override @Override
public boolean specialEnableCondition() { public boolean specialEnableCondition() {
PumpInterface pump = ConfigBuilderPlugin.getActivePump(); PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
return pump == null || pump.getPumpDescription().isTempBasalCapable; return pump == null || pump.getPumpDescription().isTempBasalCapable;
} }
@Override @Override
public boolean specialShowInListCondition() { public boolean specialShowInListCondition() {
PumpInterface pump = ConfigBuilderPlugin.getActivePump(); PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
return pump == null || pump.getPumpDescription().isTempBasalCapable; return pump == null || pump.getPumpDescription().isTempBasalCapable;
} }
@ -97,7 +97,7 @@ public class OpenAPSAMAPlugin extends PluginBase implements APSInterface {
GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData(); GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData();
Profile profile = ProfileFunctions.getInstance().getProfile(); Profile profile = ProfileFunctions.getInstance().getProfile();
PumpInterface pump = ConfigBuilderPlugin.getActivePump(); PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
if (profile == null) { if (profile == null) {
MainApp.bus().post(new EventOpenAPSUpdateResultGui(MainApp.gs(R.string.noprofileselected))); MainApp.bus().post(new EventOpenAPSUpdateResultGui(MainApp.gs(R.string.noprofileselected)));
@ -188,7 +188,7 @@ public class OpenAPSAMAPlugin extends PluginBase implements APSInterface {
start = System.currentTimeMillis(); start = System.currentTimeMillis();
try { 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 lastAutosensResult.ratio, //autosensDataRatio
isTempTarget isTempTarget
); );
@ -203,17 +203,6 @@ public class OpenAPSAMAPlugin extends PluginBase implements APSInterface {
// Fix bug determine basal // Fix bug determine basal
if (determineBasalResultAMA.rate == 0d && determineBasalResultAMA.duration == 0 && !TreatmentsPlugin.getPlugin().isTempBasalInProgress()) if (determineBasalResultAMA.rate == 0d && determineBasalResultAMA.duration == 0 && !TreatmentsPlugin.getPlugin().isTempBasalInProgress())
determineBasalResultAMA.tempBasalRequested = false; 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]; determineBasalResultAMA.iob = iobArray[0];

View file

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

View file

@ -66,13 +66,13 @@ public class OpenAPSMAPlugin extends PluginBase implements APSInterface {
@Override @Override
public boolean specialEnableCondition() { public boolean specialEnableCondition() {
PumpInterface pump = ConfigBuilderPlugin.getActivePump(); PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
return pump == null || pump.getPumpDescription().isTempBasalCapable; return pump == null || pump.getPumpDescription().isTempBasalCapable;
} }
@Override @Override
public boolean specialShowInListCondition() { public boolean specialShowInListCondition() {
PumpInterface pump = ConfigBuilderPlugin.getActivePump(); PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
return pump == null || pump.getPumpDescription().isTempBasalCapable; return pump == null || pump.getPumpDescription().isTempBasalCapable;
} }
@ -96,7 +96,7 @@ public class OpenAPSMAPlugin extends PluginBase implements APSInterface {
GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData(); GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData();
Profile profile = ProfileFunctions.getInstance().getProfile(); Profile profile = ProfileFunctions.getInstance().getProfile();
PumpInterface pump = ConfigBuilderPlugin.getActivePump(); PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
if (profile == null) { if (profile == null) {
MainApp.bus().post(new EventOpenAPSUpdateResultGui(MainApp.gs(R.string.noprofileselected))); MainApp.bus().post(new EventOpenAPSUpdateResultGui(MainApp.gs(R.string.noprofileselected)));
@ -168,7 +168,7 @@ public class OpenAPSMAPlugin extends PluginBase implements APSInterface {
start = System.currentTimeMillis(); start = System.currentTimeMillis();
try { 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) { } catch (JSONException e) {
log.error("Unhandled exception", e); log.error("Unhandled exception", e);
} }
@ -182,16 +182,6 @@ public class OpenAPSMAPlugin extends PluginBase implements APSInterface {
// Fix bug determinef basal // Fix bug determinef basal
if (determineBasalResultMA.rate == 0d && determineBasalResultMA.duration == 0 && !TreatmentsPlugin.getPlugin().isTempBasalInProgress()) if (determineBasalResultMA.rate == 0d && determineBasalResultMA.duration == 0 && !TreatmentsPlugin.getPlugin().isTempBasalInProgress())
determineBasalResultMA.tempBasalRequested = false; 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; determineBasalResultMA.iob = iobTotal;

View file

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

View file

@ -14,8 +14,6 @@ public class DetermineBasalResultSMB extends APSResult {
private double eventualBG; private double eventualBG;
private double snoozeBG; private double snoozeBG;
//public double insulinReq;
//public double carbsReq;
DetermineBasalResultSMB(JSONObject result) { DetermineBasalResultSMB(JSONObject result) {
this(); this();
@ -70,24 +68,10 @@ public class DetermineBasalResultSMB extends APSResult {
@Override @Override
public DetermineBasalResultSMB clone() { public DetermineBasalResultSMB clone() {
DetermineBasalResultSMB newResult = new DetermineBasalResultSMB(); DetermineBasalResultSMB newResult = new DetermineBasalResultSMB();
newResult.reason = reason; doClone(newResult);
newResult.rate = rate;
newResult.duration = duration;
newResult.tempBasalRequested = tempBasalRequested;
newResult.bolusRequested = bolusRequested;
newResult.rate = rate;
newResult.duration = duration;
newResult.smb = smb;
newResult.deliverAt = deliverAt;
try {
newResult.json = new JSONObject(json.toString());
} catch (JSONException e) {
log.error("Error clone parsing determine-basal result", e);
}
newResult.eventualBG = eventualBG; newResult.eventualBG = eventualBG;
newResult.snoozeBG = snoozeBG; newResult.snoozeBG = snoozeBG;
newResult.date = date;
return newResult; return newResult;
} }

View file

@ -72,13 +72,13 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface {
@Override @Override
public boolean specialEnableCondition() { public boolean specialEnableCondition() {
PumpInterface pump = ConfigBuilderPlugin.getActivePump(); PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
return pump == null || pump.getPumpDescription().isTempBasalCapable; return pump == null || pump.getPumpDescription().isTempBasalCapable;
} }
@Override @Override
public boolean specialShowInListCondition() { public boolean specialShowInListCondition() {
PumpInterface pump = ConfigBuilderPlugin.getActivePump(); PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
return pump == null || pump.getPumpDescription().isTempBasalCapable; return pump == null || pump.getPumpDescription().isTempBasalCapable;
} }
@ -102,7 +102,7 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface {
GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData(); GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData();
Profile profile = ProfileFunctions.getInstance().getProfile(); Profile profile = ProfileFunctions.getInstance().getProfile();
PumpInterface pump = ConfigBuilderPlugin.getActivePump(); PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
if (profile == null) { if (profile == null) {
MainApp.bus().post(new EventOpenAPSUpdateResultGui(MainApp.gs(R.string.noprofileselected))); 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); MainApp.getConstraintChecker().isAdvancedFilteringEnabled(advancedFiltering);
inputConstraints.copyReasons(advancedFiltering); inputConstraints.copyReasons(advancedFiltering);
Constraint<Boolean> uam = new Constraint<>(true);
MainApp.getConstraintChecker().isUAMEnabled(uam);
inputConstraints.copyReasons(uam);
if (L.isEnabled(L.APS)) if (L.isEnabled(L.APS))
Profiler.log(log, "detectSensitivityandCarbAbsorption()", startPart); Profiler.log(log, "detectSensitivityandCarbAbsorption()", startPart);
if (L.isEnabled(L.APS)) if (L.isEnabled(L.APS))
@ -205,10 +209,11 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface {
start = System.currentTimeMillis(); start = System.currentTimeMillis();
try { 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 lastAutosensResult.ratio, //autosensDataRatio
isTempTarget, isTempTarget,
smbAllowed.value(), smbAllowed.value(),
uam.value(),
advancedFiltering.value() advancedFiltering.value()
); );
} catch (JSONException e) { } catch (JSONException e) {
@ -225,16 +230,6 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface {
// Fix bug determine basal // Fix bug determine basal
if (determineBasalResultSMB.rate == 0d && determineBasalResultSMB.duration == 0 && !TreatmentsPlugin.getPlugin().isTempBasalInProgress()) if (determineBasalResultSMB.rate == 0d && determineBasalResultSMB.duration == 0 && !TreatmentsPlugin.getPlugin().isTempBasalInProgress())
determineBasalResultSMB.tempBasalRequested = false; 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]; determineBasalResultSMB.iob = iobArray[0];

View file

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

View file

@ -74,7 +74,7 @@ public class ErrorDialog extends DialogFragment implements View.OnClickListener
@Override @Override
public void dismiss() { public void dismiss() {
super.dismiss(); super.dismissAllowingStateLoss();
if (helperActivity != null) { if (helperActivity != null) {
helperActivity.finish(); 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.Source;
import info.nightscout.androidaps.db.TempTarget; import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; 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.NumberPicker;
import info.nightscout.utils.SP; import info.nightscout.utils.SP;
import info.nightscout.utils.SafeParse; import info.nightscout.utils.SafeParse;
import info.nightscout.utils.T;
import info.nightscout.utils.ToastUtils; import info.nightscout.utils.ToastUtils;
import static info.nightscout.utils.DateUtil.now; import static info.nightscout.utils.DateUtil.now;
@ -131,7 +133,7 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener
maxInsulin = MainApp.getConstraintChecker().getMaxBolusAllowed().value(); maxInsulin = MainApp.getConstraintChecker().getMaxBolusAllowed().value();
editInsulin = view.findViewById(R.id.newinsulin_amount); 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); Button plus1Button = view.findViewById(R.id.newinsulin_plus05);
plus1Button.setOnClickListener(this); plus1Button.setOnClickListener(this);
@ -210,7 +212,8 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener
try { try {
Profile currentProfile = ProfileFunctions.getInstance().getProfile(); Profile currentProfile = ProfileFunctions.getInstance().getProfile();
if (currentProfile == null) final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
if (currentProfile == null || pump == null)
return; return;
Double insulin = SafeParse.stringToDouble(editInsulin.getText()); Double insulin = SafeParse.stringToDouble(editInsulin.getText());
@ -218,13 +221,13 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener
List<String> actions = new LinkedList<>(); List<String> actions = new LinkedList<>();
if (insulin > 0) { 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()) { if (recordOnlyCheckbox.isChecked()) {
actions.add("<font color='" + MainApp.gc(R.color.warning) + "'>" + MainApp.gs(R.string.bolusrecordedonly) + "</font>"); 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>"); 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); 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(); int timeOffset = editTime.getValue().intValue();
final long time = now() + timeOffset * 1000 * 60; final long time = now() + T.mins(timeOffset).msecs();
if (timeOffset != 0) { if (timeOffset != 0) {
actions.add(MainApp.gs(R.string.time) + ": " + DateUtil.dateAndTimeString(time)); 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); TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false);
} else { } else {
detailedBolusInfo.date = now(); detailedBolusInfo.date = now();
ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() { ConfigBuilderPlugin.getPlugin().getCommandQueue().bolus(detailedBolusInfo, new Callback() {
@Override @Override
public void run() { public void run() {
if (!result.success) { 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.CareportalEvent;
import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.interfaces.Constraint; 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.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
import info.nightscout.androidaps.queue.Callback; import info.nightscout.androidaps.queue.Callback;
@ -104,7 +105,7 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene
editInsulin = (NumberPicker) view.findViewById(R.id.treatments_newtreatment_insulinamount); editInsulin = (NumberPicker) view.findViewById(R.id.treatments_newtreatment_insulinamount);
editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false, textWatcher); 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); recordOnlyCheckbox = (CheckBox) view.findViewById(R.id.newtreatment_record_only);
@ -125,6 +126,11 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene
okClicked = true; okClicked = true;
try { try {
final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
if (pump == null)
return;
Double insulin = SafeParse.stringToDouble(editInsulin.getText()); Double insulin = SafeParse.stringToDouble(editInsulin.getText());
final Integer carbs = SafeParse.stringToInt(editCarbs.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(); Integer carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(carbs)).value();
if (insulin > 0) { 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()) { 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) if (carbsAfterConstraints > 0)
confirmMessage += "<br/>" + MainApp.gs(R.string.carbs) + ": " + carbsAfterConstraints + "g"; confirmMessage += "<br/>" + MainApp.gs(R.string.carbs) + ": " + "<font color='" + MainApp.gc(R.color.carbs) + "'>" + carbsAfterConstraints + "g" + "</font>";
if (insulinAfterConstraints - insulin != 0 || !Objects.equals(carbsAfterConstraints, carbs))
confirmMessage += "<br/>" + MainApp.gs(R.string.constraintapllied);
final double finalInsulinAfterConstraints = insulinAfterConstraints; final double finalInsulinAfterConstraints = insulinAfterConstraints;
@ -171,8 +177,8 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene
detailedBolusInfo.carbs = finalCarbsAfterConstraints; detailedBolusInfo.carbs = finalCarbsAfterConstraints;
detailedBolusInfo.context = context; detailedBolusInfo.context = context;
detailedBolusInfo.source = Source.USER; detailedBolusInfo.source = Source.USER;
if (!(recordOnlyCheckbox.isChecked() && (detailedBolusInfo.insulin > 0 || ConfigBuilderPlugin.getActivePump().getPumpDescription().storesCarbInfo))) { if (!(recordOnlyCheckbox.isChecked() && (detailedBolusInfo.insulin > 0 || ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().storesCarbInfo))) {
ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() { ConfigBuilderPlugin.getPlugin().getCommandQueue().bolus(detailedBolusInfo, new Callback() {
@Override @Override
public void run() { public void run() {
if (!result.success) { 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.events.EventRefreshOverview;
import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.interfaces.PluginType; 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.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.IobCobCalculator.CobInfo; import info.nightscout.androidaps.plugins.IobCobCalculator.CobInfo;
@ -164,7 +165,6 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
} }
@Subscribe @Subscribe
public void onStatusEvent(final EventNewBG e) { public void onStatusEvent(final EventNewBG e) {
Activity activity = getActivity(); Activity activity = getActivity();
@ -207,7 +207,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { 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().requestFeature(Window.FEATURE_NO_TITLE);
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); 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); 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); 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); editCorr.setParams(0d, -maxCorrection, maxCorrection, bolusstep, DecimalFormatter.pumpSupportedBolusFormat(), false, textWatcher);
editCarbTime.setParams(0d, -60d, 60d, 5d, new DecimalFormat("0"), false); editCarbTime.setParams(0d, -60d, 60d, 5d, new DecimalFormat("0"), false);
initDialog(); initDialog();
@ -327,8 +327,9 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
} }
okClicked = true; okClicked = true;
final Profile profile = ProfileFunctions.getInstance().getProfile(); 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); String confirmMessage = MainApp.gs(R.string.entertreatmentquestion);
Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(calculatedTotalInsulin)).value(); Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(calculatedTotalInsulin)).value();
@ -339,14 +340,8 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
if (carbsAfterConstraints > 0) if (carbsAfterConstraints > 0)
confirmMessage += "<br/>" + MainApp.gs(R.string.carbs) + ": " + "<font color='" + MainApp.gc(R.color.carbs) + "'>" + carbsAfterConstraints + "g" + "</font>"; confirmMessage += "<br/>" + MainApp.gs(R.string.carbs) + ": " + "<font color='" + MainApp.gc(R.color.carbs) + "'>" + carbsAfterConstraints + "g" + "</font>";
if (insulinAfterConstraints - calculatedTotalInsulin != 0 || !carbsAfterConstraints.equals(calculatedCarbs)) { if (Math.abs(insulinAfterConstraints - calculatedTotalInsulin) > pump.getPumpDescription().pumpType.determineCorrectBolusSize(insulinAfterConstraints) || !carbsAfterConstraints.equals(calculatedCarbs)) {
okClicked = false; confirmMessage += "<br/><font color='" + MainApp.gc(R.color.warning) + "'>" + MainApp.gs(R.string.bolusconstraintapplied) + "</font>";
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;
} }
final Double finalInsulinAfterConstraints = insulinAfterConstraints; final Double finalInsulinAfterConstraints = insulinAfterConstraints;
@ -374,7 +369,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
loopPlugin.superBolusTo(System.currentTimeMillis() + 2 * 60L * 60 * 1000); loopPlugin.superBolusTo(System.currentTimeMillis() + 2 * 60L * 60 * 1000);
MainApp.bus().post(new EventRefreshOverview("WizardDialog")); 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 @Override
public void run() { public void run() {
if (!result.success) { if (!result.success) {
@ -399,8 +394,8 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
detailedBolusInfo.boluscalc = boluscalcJSON; detailedBolusInfo.boluscalc = boluscalcJSON;
detailedBolusInfo.source = Source.USER; detailedBolusInfo.source = Source.USER;
detailedBolusInfo.notes = finalNotes; detailedBolusInfo.notes = finalNotes;
if (detailedBolusInfo.insulin > 0 || ConfigBuilderPlugin.getActivePump().getPumpDescription().storesCarbInfo) { if (detailedBolusInfo.insulin > 0 || ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().storesCarbInfo) {
ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() { ConfigBuilderPlugin.getPlugin().getCommandQueue().bolus(detailedBolusInfo, new Callback() {
@Override @Override
public void run() { public void run() {
if (!result.success) { if (!result.success) {
@ -434,7 +429,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
private void initDialog() { private void initDialog() {
Profile profile = ProfileFunctions.getInstance().getProfile(); 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) { if (profile == null || profileStore == null) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.noprofile)); ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.noprofile));
@ -478,14 +473,15 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
} }
private void calculateInsulin() { private void calculateInsulin() {
ProfileStore profileStore = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile(); ProfileStore profileStore = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getProfile();
if (profileSpinner == null || profileSpinner.getSelectedItem() == null || profileStore == null) if (profileSpinner == null || profileSpinner.getSelectedItem() == null || profileStore == null)
return; // not initialized yet return; // not initialized yet
String selectedAlternativeProfile = profileSpinner.getSelectedItem().toString(); String selectedAlternativeProfile = profileSpinner.getSelectedItem().toString();
Profile specificProfile; Profile specificProfile;
if (selectedAlternativeProfile.equals(MainApp.gs(R.string.active))) if (selectedAlternativeProfile.equals(MainApp.gs(R.string.active))) {
specificProfile = ProfileFunctions.getInstance().getProfile(); specificProfile = ProfileFunctions.getInstance().getProfile();
else selectedAlternativeProfile = ProfileFunctions.getInstance().getProfileName();
} else
specificProfile = profileStore.getSpecificProfile(selectedAlternativeProfile); specificProfile = profileStore.getSpecificProfile(selectedAlternativeProfile);
// Entered values // Entered values
@ -495,13 +491,13 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
Double corrAfterConstraint = c_correction; Double corrAfterConstraint = c_correction;
if (c_correction > 0) if (c_correction > 0)
c_correction = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(c_correction)).value(); 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); editCorr.setValue(0d);
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.bolusconstraintapplied)); ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.bolusconstraintapplied));
return; return;
} }
Integer carbsAfterConstraint = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(c_carbs)).value(); 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); editCarbs.setValue(0d);
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.carbsconstraintapplied)); ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.carbsconstraintapplied));
return; return;
@ -579,12 +575,15 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
boluscalcJSON = new JSONObject(); boluscalcJSON = new JSONObject();
try { try {
boluscalcJSON.put("profile", selectedAlternativeProfile); boluscalcJSON.put("profile", selectedAlternativeProfile);
boluscalcJSON.put("notes", notesEdit.getText());
boluscalcJSON.put("eventTime", DateUtil.toISOString(new Date())); boluscalcJSON.put("eventTime", DateUtil.toISOString(new Date()));
boluscalcJSON.put("targetBGLow", wizard.targetBGLow); boluscalcJSON.put("targetBGLow", wizard.targetBGLow);
boluscalcJSON.put("targetBGHigh", wizard.targetBGHigh); boluscalcJSON.put("targetBGHigh", wizard.targetBGHigh);
boluscalcJSON.put("isf", wizard.sens); boluscalcJSON.put("isf", wizard.sens);
boluscalcJSON.put("ic", wizard.ic); boluscalcJSON.put("ic", wizard.ic);
boluscalcJSON.put("iob", -(wizard.insulingFromBolusIOB + wizard.insulingFromBasalsIOB)); boluscalcJSON.put("iob", -(wizard.insulingFromBolusIOB + wizard.insulingFromBasalsIOB));
boluscalcJSON.put("bolusiob", wizard.insulingFromBolusIOB);
boluscalcJSON.put("basaliob", wizard.insulingFromBasalsIOB);
boluscalcJSON.put("bolusiobused", bolusIobCheckbox.isChecked()); boluscalcJSON.put("bolusiobused", bolusIobCheckbox.isChecked());
boluscalcJSON.put("basaliobused", basalIobCheckbox.isChecked()); boluscalcJSON.put("basaliobused", basalIobCheckbox.isChecked());
boluscalcJSON.put("bg", c_bg); boluscalcJSON.put("bg", c_bg);
@ -594,11 +593,18 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
boluscalcJSON.put("insulincarbs", wizard.insulinFromCarbs); boluscalcJSON.put("insulincarbs", wizard.insulinFromCarbs);
boluscalcJSON.put("carbs", c_carbs); boluscalcJSON.put("carbs", c_carbs);
boluscalcJSON.put("cob", c_cob); boluscalcJSON.put("cob", c_cob);
boluscalcJSON.put("cobused", cobCheckbox.isChecked());
boluscalcJSON.put("insulincob", wizard.insulinFromCOB); boluscalcJSON.put("insulincob", wizard.insulinFromCOB);
boluscalcJSON.put("othercorrection", corrAfterConstraint); boluscalcJSON.put("othercorrection", corrAfterConstraint);
boluscalcJSON.put("insulinsuperbolus", wizard.insulinFromSuperBolus); boluscalcJSON.put("insulinsuperbolus", wizard.insulinFromSuperBolus);
boluscalcJSON.put("insulintrend", wizard.insulinFromTrend); boluscalcJSON.put("insulintrend", wizard.insulinFromTrend);
boluscalcJSON.put("insulin", calculatedTotalInsulin); 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) { } catch (JSONException e) {
log.error("Unhandled exception", 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); super.onCreateContextMenu(menu, v, menuInfo);
if (v == apsModeView) { if (v == apsModeView) {
final LoopPlugin loopPlugin = LoopPlugin.getPlugin(); final LoopPlugin loopPlugin = LoopPlugin.getPlugin();
final PumpDescription pumpDescription = ConfigBuilderPlugin.getActivePump().getPumpDescription(); final PumpDescription pumpDescription =
ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription();
if (!ProfileFunctions.getInstance().isProfileValid("ContexMenuCreation")) if (!ProfileFunctions.getInstance().isProfileValid("ContexMenuCreation"))
return; return;
menu.setHeaderTitle(MainApp.gs(R.string.loop)); 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.suspendloopfor2h));
menu.add(MainApp.gs(R.string.suspendloopfor3h)); menu.add(MainApp.gs(R.string.suspendloopfor3h));
menu.add(MainApp.gs(R.string.suspendloopfor10h)); menu.add(MainApp.gs(R.string.suspendloopfor10h));
if (pumpDescription.tempDurationStep15mAllowed) } else {
menu.add(MainApp.gs(R.string.disconnectpumpfor15m)); if (!loopPlugin.isDisconnected()) {
if (pumpDescription.tempDurationStep30mAllowed) menu.add(MainApp.gs(R.string.resume));
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));
} }
} }
if (!loopPlugin.isEnabled(PluginType.LOOP))
if (!loopPlugin.isEnabled(PluginType.LOOP)) {
menu.add(MainApp.gs(R.string.enableloop)); 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) { } else if (v == activeProfileView) {
menu.setHeaderTitle(MainApp.gs(R.string.profile)); menu.setHeaderTitle(MainApp.gs(R.string.profile));
menu.add(MainApp.gs(R.string.danar_viewprofile)); menu.add(MainApp.gs(R.string.danar_viewprofile));
if (MainApp.getConfigBuilder().getActiveProfileInterface() != null && MainApp.getConfigBuilder().getActiveProfileInterface().getProfile() != null) { if (ConfigBuilderPlugin.getPlugin().getActiveProfileInterface() != null && ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getProfile() != null) {
menu.add(MainApp.gs(R.string.careportal_profileswitch)); menu.add(MainApp.gs(R.string.careportal_profileswitch));
} }
} else if (v == tempTargetView) { } 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 @Override
public boolean onContextItemSelected(MenuItem item) { public boolean onContextItemSelected(MenuItem item) {
final Profile profile = ProfileFunctions.getInstance().getProfile(); 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))) { if (item.getTitle().equals(MainApp.gs(R.string.disableloop))) {
loopPlugin.setPluginEnabled(PluginType.LOOP, false); loopPlugin.setPluginEnabled(PluginType.LOOP, false);
loopPlugin.setFragmentVisible(PluginType.LOOP, false); loopPlugin.setFragmentVisible(PluginType.LOOP, false);
MainApp.getConfigBuilder().storeSettings("DisablingLoop"); ConfigBuilderPlugin.getPlugin().storeSettings("DisablingLoop");
updateGUI("suspendmenu"); updateGUI("suspendmenu");
ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, new Callback() { ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(true, new Callback() {
@Override @Override
public void run() { public void run() {
if (!result.success) { 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))) { } else if (item.getTitle().equals(MainApp.gs(R.string.enableloop))) {
loopPlugin.setPluginEnabled(PluginType.LOOP, true); loopPlugin.setPluginEnabled(PluginType.LOOP, true);
loopPlugin.setFragmentVisible(PluginType.LOOP, true); loopPlugin.setFragmentVisible(PluginType.LOOP, true);
MainApp.getConfigBuilder().storeSettings("EnablingLoop"); ConfigBuilderPlugin.getPlugin().storeSettings("EnablingLoop");
updateGUI("suspendmenu"); updateGUI("suspendmenu");
NSUpload.uploadOpenAPSOffline(0); NSUpload.uploadOpenAPSOffline(0);
return true; 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); loopPlugin.suspendTo(0L);
updateGUI("suspendmenu"); updateGUI("suspendmenu");
ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, new Callback() { ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(true, new Callback() {
@Override @Override
public void run() { public void run() {
if (!result.success) { if (!result.success) {
@ -697,8 +714,8 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
new NewCarbsDialog().show(manager, "CarbsDialog"); new NewCarbsDialog().show(manager, "CarbsDialog");
break; break;
case R.id.overview_pumpstatus: case R.id.overview_pumpstatus:
if (ConfigBuilderPlugin.getActivePump().isSuspended() || !ConfigBuilderPlugin.getActivePump().isInitialized()) if (ConfigBuilderPlugin.getPlugin().getActivePump().isSuspended() || !ConfigBuilderPlugin.getPlugin().getActivePump().isInitialized())
ConfigBuilderPlugin.getCommandQueue().readStatus("RefreshClicked", null); ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("RefreshClicked", null);
break; break;
} }
@ -831,7 +848,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
loopPlugin.superBolusTo(System.currentTimeMillis() + T.hours(2).msecs()); loopPlugin.superBolusTo(System.currentTimeMillis() + T.hours(2).msecs());
MainApp.bus().post(new EventRefreshOverview("WizardDialog")); MainApp.bus().post(new EventRefreshOverview("WizardDialog"));
} }
ConfigBuilderPlugin.getCommandQueue().tempBasalPercent(0, 120, true, profile, new Callback() { ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalPercent(0, 120, true, profile, new Callback() {
@Override @Override
public void run() { public void run() {
if (!result.success) { if (!result.success) {
@ -852,8 +869,8 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
detailedBolusInfo.context = context; detailedBolusInfo.context = context;
detailedBolusInfo.boluscalc = boluscalcJSON; detailedBolusInfo.boluscalc = boluscalcJSON;
detailedBolusInfo.source = Source.USER; detailedBolusInfo.source = Source.USER;
if (finalInsulinAfterConstraints > 0 || ConfigBuilderPlugin.getActivePump().getPumpDescription().storesCarbInfo) { if (finalInsulinAfterConstraints > 0 || ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().storesCarbInfo) {
ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() { ConfigBuilderPlugin.getPlugin().getCommandQueue().bolus(detailedBolusInfo, new Callback() {
@Override @Override
public void run() { public void run() {
if (!result.success) { if (!result.success) {
@ -1059,7 +1076,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
BgReading actualBG = DatabaseHelper.actualBg(); BgReading actualBG = DatabaseHelper.actualBg();
BgReading lastBG = DatabaseHelper.lastBg(); BgReading lastBG = DatabaseHelper.lastBg();
final PumpInterface pump = ConfigBuilderPlugin.getActivePump(); final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
final Profile profile = ProfileFunctions.getInstance().getProfile(); 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.setBackgroundColor(MainApp.gc(R.color.ribbonWarning));
apsModeView.setText(String.format(MainApp.gs(R.string.loopsuperbolusfor), loopPlugin.minutesToEndOfSuspend())); apsModeView.setText(String.format(MainApp.gs(R.string.loopsuperbolusfor), loopPlugin.minutesToEndOfSuspend()));
apsModeView.setTextColor(MainApp.gc(R.color.ribbonTextWarning)); 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.setBackgroundColor(MainApp.gc(R.color.ribbonCritical));
apsModeView.setText(String.format(MainApp.gs(R.string.loopdisconnectedfor), loopPlugin.minutesToEndOfSuspend())); apsModeView.setText(String.format(MainApp.gs(R.string.loopdisconnectedfor), loopPlugin.minutesToEndOfSuspend()));
apsModeView.setTextColor(MainApp.gc(R.color.ribbonTextCritical)); apsModeView.setTextColor(MainApp.gc(R.color.ribbonTextCritical));
@ -1270,7 +1287,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
// **** Various treatment buttons **** // **** Various treatment buttons ****
if (carbsButton != null) { if (carbsButton != null) {
if (SP.getBoolean(R.string.key_show_carbs_button, true) if (SP.getBoolean(R.string.key_show_carbs_button, true)
&& (!ConfigBuilderPlugin.getActivePump().getPumpDescription().storesCarbInfo || && (!ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().storesCarbInfo ||
(pump.isInitialized() && !pump.isSuspended()))) { (pump.isInitialized() && !pump.isSuspended()))) {
carbsButton.setVisibility(View.VISIBLE); carbsButton.setVisibility(View.VISIBLE);
} else { } else {
@ -1286,14 +1303,14 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
treatmentButton.setVisibility(View.GONE); treatmentButton.setVisibility(View.GONE);
} }
} }
if (wizardButton != null) { if (pump.isInitialized() && !pump.isSuspended() && wizardButton != null) {
if (SP.getBoolean(R.string.key_show_wizard_button, true)) { if (SP.getBoolean(R.string.key_show_wizard_button, true)) {
wizardButton.setVisibility(View.VISIBLE); wizardButton.setVisibility(View.VISIBLE);
} else { } else {
wizardButton.setVisibility(View.GONE); wizardButton.setVisibility(View.GONE);
} }
} }
if (insulinButton != null) { if (pump.isInitialized() && !pump.isSuspended() && insulinButton != null) {
if (SP.getBoolean(R.string.key_show_insulin_button, true)) { if (SP.getBoolean(R.string.key_show_insulin_button, true)) {
insulinButton.setVisibility(View.VISIBLE); insulinButton.setVisibility(View.VISIBLE);
} else { } else {
@ -1430,13 +1447,13 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
// Uploader status from ns // Uploader status from ns
if (uploaderDeviceStatusView != null) { 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)); uploaderDeviceStatusView.setOnClickListener(v -> OKDialog.show(getActivity(), MainApp.gs(R.string.uploader), NSDeviceStatus.getInstance().getExtendedUploaderStatus(), null));
} }
// Sensitivity // Sensitivity
if (sensitivityView != null) { if (sensitivityView != null) {
AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getLastAutosensDataSynchronized("Overview"); AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getLastAutosensData("Overview");
if (autosensData != null) if (autosensData != null)
sensitivityView.setText(String.format("%.0f%%", autosensData.autosensResult.ratio * 100)); sensitivityView.setText(String.format("%.0f%%", autosensData.autosensResult.ratio * 100));
else else

View file

@ -303,7 +303,7 @@ public class GraphData {
} }
// Extended bolus // Extended bolus
if (!ConfigBuilderPlugin.getActivePump().isFakingTempsByExtendedBoluses()) { if (!ConfigBuilderPlugin.getPlugin().getActivePump().isFakingTempsByExtendedBoluses()) {
List<ExtendedBolus> extendedBoluses = TreatmentsPlugin.getPlugin().getExtendedBolusesFromHistory().getList(); List<ExtendedBolus> extendedBoluses = TreatmentsPlugin.getPlugin().getExtendedBolusesFromHistory().getList();
for (int tx = 0; tx < extendedBoluses.size(); tx++) { 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 MAXIMUM_BASAL_VALUE_REPLACED = 39;
public static final int NSMALFUNCTION = 40; public static final int NSMALFUNCTION = 40;
public static final int NEWVERSIONDETECTED = 41; 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; public int id;

View file

@ -13,6 +13,14 @@ import android.os.Build;
import android.support.v4.app.NotificationCompat; import android.support.v4.app.NotificationCompat;
import android.support.v4.app.TaskStackBuilder; 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 com.squareup.otto.Subscribe;
import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Config;
@ -60,6 +68,18 @@ public class PersistentNotificationPlugin extends PluginBase {
public static final int ONGOING_NOTIFICATION_ID = 4711; public static final int ONGOING_NOTIFICATION_ID = 4711;
private final Context ctx; 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) { public PersistentNotificationPlugin(Context ctx) {
super(new PluginDescription() super(new PluginDescription()
.mainType(PluginType.GENERAL) .mainType(PluginType.GENERAL)
@ -107,9 +127,10 @@ public class PersistentNotificationPlugin extends PluginBase {
return null; 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; return null;
String units = ProfileFunctions.getInstance().getProfileUnits(); String units = ProfileFunctions.getInstance().getProfileUnits();
@ -118,22 +139,25 @@ public class PersistentNotificationPlugin extends PluginBase {
GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData(); GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData();
if (lastBG != null) { if (lastBG != null) {
line1 = lastBG.valueToUnitsToString(units); line1 = line1_aa = lastBG.valueToUnitsToString(units);
if (glucoseStatus != null) { if (glucoseStatus != null) {
line1 += " Δ" + deltastring(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units) line1 += " Δ" + deltastring(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units)
+ " avgΔ" + deltastring(glucoseStatus.avgdelta, glucoseStatus.avgdelta * Constants.MGDL_TO_MMOLL, units); + " avgΔ" + deltastring(glucoseStatus.avgdelta, glucoseStatus.avgdelta * Constants.MGDL_TO_MMOLL, units);
line1_aa += " " + lastBG.directionToSymbol();
} else { } else {
line1 += " " + line1 += " " +
MainApp.gs(R.string.old_data) + MainApp.gs(R.string.old_data) +
" "; " ";
line1_aa += line1 + ".";
} }
} else { } 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()); TemporaryBasal activeTemp = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(System.currentTimeMillis());
if (activeTemp != null) { if (activeTemp != null) {
line1 += " " + activeTemp.toStringShort(); line1 += " " + activeTemp.toStringShort();
line1_aa += " " + activeTemp.toStringShort() + ".";
} }
//IOB //IOB
@ -143,12 +167,55 @@ public class PersistentNotificationPlugin extends PluginBase {
IobTotal basalIob = TreatmentsPlugin.getPlugin().getLastCalculationTempBasals().round(); 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 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.getActivePump().getBaseBasalRate()) + " U/h";
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 += " - " + 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); NotificationCompat.Builder builder = new NotificationCompat.Builder(ctx, CHANNEL_ID);
@ -167,6 +234,11 @@ public class PersistentNotificationPlugin extends PluginBase {
builder.setContentTitle(line1); builder.setContentTitle(line1);
builder.setContentText(line2); builder.setContentText(line2);
builder.setSubText(line3); builder.setSubText(line3);
/// Android Auto
builder.extend(new NotificationCompat.CarExtender()
.setUnreadConversation(unreadConversationBuilder.build()));
/// End Android Auto
Intent resultIntent = new Intent(ctx, MainActivity.class); Intent resultIntent = new Intent(ctx, MainActivity.class);

View file

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

View file

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

View file

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

View file

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

View file

@ -7,8 +7,6 @@ import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentActivity;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
import com.crashlytics.android.answers.CustomEvent;
import org.json.JSONObject; import org.json.JSONObject;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; 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.PumpHistory;
import info.nightscout.androidaps.plugins.PumpCombo.ruffyscripter.history.PumpHistoryRequest; import info.nightscout.androidaps.plugins.PumpCombo.ruffyscripter.history.PumpHistoryRequest;
import info.nightscout.androidaps.plugins.PumpCombo.ruffyscripter.history.Tdd; import info.nightscout.androidaps.plugins.PumpCombo.ruffyscripter.history.Tdd;
import info.nightscout.androidaps.plugins.PumpCommon.defs.PumpType;
import info.nightscout.androidaps.plugins.Treatments.Treatment; import info.nightscout.androidaps.plugins.Treatments.Treatment;
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
import info.nightscout.utils.DateUtil; import info.nightscout.utils.DateUtil;
import info.nightscout.utils.FabricPrivacy;
import info.nightscout.utils.SP; import info.nightscout.utils.SP;
/** /**
@ -85,42 +83,6 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
private final static PumpDescription pumpDescription = new PumpDescription(); 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 @NonNull
private final RuffyCommands ruffyScripter; private final RuffyCommands ruffyScripter;
@ -173,6 +135,7 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
.description(R.string.description_pump_combo) .description(R.string.description_pump_combo)
); );
ruffyScripter = new RuffyScripter(MainApp.instance().getApplicationContext()); ruffyScripter = new RuffyScripter(MainApp.instance().getApplicationContext());
pumpDescription.setPumpDescription(PumpType.AccuChekCombo);
} }
public ComboPump getPump() { public ComboPump getPump() {
@ -250,6 +213,15 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
return false; return false;
} }
@Override
public boolean isHandshakeInProgress() {
return false;
}
@Override
public void finishHandshaking() {
}
@Override @Override
public void connect(String reason) { public void connect(String reason) {
// ruffyscripter establishes a connection as needed. // ruffyscripter establishes a connection as needed.
@ -353,7 +325,6 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
return basalProfile; return basalProfile;
} }
@NonNull
@Override @Override
public long lastDataTime() { public long lastDataTime() {
return pump.lastSuccessfulCmdTime; return pump.lastSuccessfulCmdTime;
@ -597,10 +568,6 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
} }
if (waitLoops > 0) { if (waitLoops > 0) {
long waitDuration = (System.currentTimeMillis() - waitStartTime) / 1000; 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)) if (L.isEnabled(L.PUMP))
log.debug("Waited " + waitDuration + "s for pump to switch to a fresh minute before bolusing"); 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
} }
} }
/** /** Creates a treatment record based on the request in DetailBolusInfo and the delivered bolus. */
* 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.
*/
private boolean addBolusToTreatments(DetailedBolusInfo detailedBolusInfo, Bolus lastPumpBolus) { private boolean addBolusToTreatments(DetailedBolusInfo detailedBolusInfo, Bolus lastPumpBolus) {
DetailedBolusInfo dbi = detailedBolusInfo.copy(); DetailedBolusInfo dbi = detailedBolusInfo.copy();
dbi.date = calculateFakeBolusDate(lastPumpBolus); dbi.date = calculateFakeBolusDate(lastPumpBolus);
@ -715,30 +678,12 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
dbi.source = Source.PUMP; dbi.source = Source.PUMP;
dbi.insulin = lastPumpBolus.amount; dbi.insulin = lastPumpBolus.amount;
try { try {
boolean treatmentCreated = TreatmentsPlugin.getPlugin().addToHistoryTreatment(dbi, false); TreatmentsPlugin.getPlugin().addToHistoryTreatment(dbi, true);
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;
}
} catch (Exception e) { } catch (Exception e) {
log.error("Adding treatment record failed", e); log.error("Adding treatment record failed", e);
if (dbi.isSMB) { if (dbi.isSMB) {
Notification notification = new Notification(Notification.COMBO_PUMP_ALARM, MainApp.gs(R.string.combo_error_updating_treatment_record), Notification.URGENT); 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)); 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; return false;
} }
@ -958,7 +903,7 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
Notification.URGENT); Notification.URGENT);
n.soundId = R.raw.alarm; n.soundId = R.raw.alarm;
MainApp.bus().post(new EventNewNotification(n)); MainApp.bus().post(new EventNewNotification(n));
ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, null); ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(true, null);
} }
updateLocalData(commandResult); updateLocalData(commandResult);
} }
@ -1137,7 +1082,7 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
n.soundId = R.raw.alarm; n.soundId = R.raw.alarm;
MainApp.bus().post(new EventNewNotification(n)); MainApp.bus().post(new EventNewNotification(n));
violationWarningRaisedForBolusAt = lowSuspendOnlyLoopEnforcedUntil; 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 (aapsTbr == null && state.tbrActive && state.tbrRemainingDuration > 2) {
if (L.isEnabled(L.PUMP)) if (L.isEnabled(L.PUMP))
log.debug("Creating temp basal from pump TBR"); 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() TemporaryBasal newTempBasal = new TemporaryBasal()
.date(now) .date(now)
.percent(state.tbrPercent) .percent(state.tbrPercent)
@ -1165,10 +1106,6 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
} else if (aapsTbr != null && aapsTbr.getPlannedRemainingMinutes() > 2 && !state.tbrActive) { } else if (aapsTbr != null && aapsTbr.getPlannedRemainingMinutes() > 2 && !state.tbrActive) {
if (L.isEnabled(L.PUMP)) if (L.isEnabled(L.PUMP))
log.debug("Ending AAPS-TBR since pump has no TBR active"); 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() TemporaryBasal tempStop = new TemporaryBasal()
.date(now) .date(now)
.duration(0) .duration(0)
@ -1179,10 +1116,6 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
Math.abs(aapsTbr.getPlannedRemainingMinutes() - state.tbrRemainingDuration) > 2)) { Math.abs(aapsTbr.getPlannedRemainingMinutes() - state.tbrRemainingDuration) > 2)) {
if (L.isEnabled(L.PUMP)) if (L.isEnabled(L.PUMP))
log.debug("AAPSs and pump-TBR differ; ending AAPS-TBR and creating new TBR based on pump TBR"); 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() TemporaryBasal tempStop = new TemporaryBasal()
.date(now - 1000) .date(now - 1000)
.duration(0) .duration(0)
@ -1221,6 +1154,7 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
return historyResult.success; return historyResult.success;
} }
/** Return value indicates whether a new record was created. */
private boolean updateDbFromPumpHistory(@NonNull PumpHistory history) { private boolean updateDbFromPumpHistory(@NonNull PumpHistory history) {
boolean updated = false; boolean updated = false;
for (Bolus pumpBolus : history.bolusHistory) { for (Bolus pumpBolus : history.bolusHistory) {
@ -1230,8 +1164,7 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
dbi.source = Source.PUMP; dbi.source = Source.PUMP;
dbi.insulin = pumpBolus.amount; dbi.insulin = pumpBolus.amount;
dbi.eventType = CareportalEvent.CORRECTIONBOLUS; dbi.eventType = CareportalEvent.CORRECTIONBOLUS;
if (TreatmentsPlugin.getPlugin().getService().getPumpRecordById(dbi.pumpId) == null) { if (TreatmentsPlugin.getPlugin().addToHistoryTreatment(dbi, true)) {
TreatmentsPlugin.getPlugin().addToHistoryTreatment(dbi, false);
updated = true; updated = true;
} }
} }
@ -1303,20 +1236,14 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
if (bolusSet.size() != historyResult.history.bolusHistory.size()) { if (bolusSet.size() != historyResult.history.bolusHistory.size()) {
if (L.isEnabled(L.PUMP)) if (L.isEnabled(L.PUMP))
log.debug("Bolus with same amount within the same minute imported. Only one will make it to the DB."); 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. Notification notification = new Notification(Notification.COMBO_PUMP_ALARM, MainApp.gs(R.string.
combo_error_multiple_boluses_with_identical_timestamp), Notification.URGENT); combo_error_multiple_boluses_with_identical_timestamp), Notification.URGENT);
MainApp.bus().post(new EventNewNotification(notification)); MainApp.bus().post(new EventNewNotification(notification));
} }
pumpHistoryChanged = updateDbFromPumpHistory(historyResult.history); pumpHistoryChanged = updateDbFromPumpHistory(historyResult.history);
if (pumpHistoryChanged) { if (L.isEnabled(L.PUMP) && pumpHistoryChanged) {
if (L.isEnabled(L.PUMP)) log.debug("Setting 'pumpHistoryChanged' true");
log.debug("Setting 'pumpHistoryChanged' true");
} }
List<Bolus> updatedPumpBolusHistory = historyResult.history.bolusHistory; 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.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import com.crashlytics.android.answers.CustomEvent;
import com.google.common.base.Joiner; import com.google.common.base.Joiner;
import org.monkey.d.ruffy.ruffy.driver.IRTHandler; 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.ReadPumpStateCommand;
import info.nightscout.androidaps.plugins.PumpCombo.ruffyscripter.commands.SetBasalProfileCommand; import info.nightscout.androidaps.plugins.PumpCombo.ruffyscripter.commands.SetBasalProfileCommand;
import info.nightscout.androidaps.plugins.PumpCombo.ruffyscripter.commands.SetTbrCommand; 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 * 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 long menuLastUpdated = 0;
private volatile boolean unparsableMenuEncountered; private volatile boolean unparsableMenuEncountered;
private String previousCommand = "<none>";
private volatile Command activeCmd = null; private volatile Command activeCmd = null;
private boolean started = false; private boolean started = false;
@ -67,51 +62,43 @@ public class RuffyScripter implements RuffyCommands {
private IRTHandler mHandler = new IRTHandler.Stub() { private IRTHandler mHandler = new IRTHandler.Stub() {
@Override @Override
public void log(String message) throws RemoteException { public void log(String message) {
if (log.isTraceEnabled()) { if (log.isTraceEnabled()) {
log.trace("Ruffy says: " + message); log.trace("Ruffy says: " + message);
} }
} }
@Override @Override
public void fail(String message) throws RemoteException { public void fail(String message) {
log.warn("Ruffy warns: " + 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 @Override
public void requestBluetooth() throws RemoteException { public void requestBluetooth() {
log.trace("Ruffy invoked requestBluetooth callback"); log.trace("Ruffy invoked requestBluetooth callback");
} }
@Override @Override
public void rtStopped() throws RemoteException { public void rtStopped() {
log.debug("rtStopped callback invoked"); log.debug("rtStopped callback invoked");
currentMenu = null; currentMenu = null;
} }
@Override @Override
public void rtStarted() throws RemoteException { public void rtStarted() {
log.debug("rtStarted callback invoked"); log.debug("rtStarted callback invoked");
} }
@Override @Override
public void rtClearDisplay() throws RemoteException { public void rtClearDisplay() {
} }
@Override @Override
public void rtUpdateDisplay(byte[] quarter, int which) throws RemoteException { public void rtUpdateDisplay(byte[] quarter, int which) {
} }
@Override @Override
public void rtDisplayHandleMenu(Menu menu) throws RemoteException { public void rtDisplayHandleMenu(Menu menu) {
// method is called every ~500ms // method is called every ~500ms
log.debug("rtDisplayHandleMenu: " + menu); log.debug("rtDisplayHandleMenu: " + menu);
@ -124,7 +111,7 @@ public class RuffyScripter implements RuffyCommands {
} }
@Override @Override
public void rtDisplayHandleNoMenu() throws RemoteException { public void rtDisplayHandleNoMenu() {
log.warn("rtDisplayHandleNoMenu callback invoked"); log.warn("rtDisplayHandleNoMenu callback invoked");
unparsableMenuEncountered = true; unparsableMenuEncountered = true;
} }
@ -173,10 +160,6 @@ public class RuffyScripter implements RuffyCommands {
if (!boundSucceeded) { if (!boundSucceeded) {
log.error("No connection to ruffy. Pump control unavailable."); 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 @Override
public CommandResult readQuickInfo(int numberOfBolusRecordsToRetrieve) { public CommandResult readQuickInfo(int numberOfBolusRecordsToRetrieve) {
FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboReadQuickInfoCmd")
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION));
return runCommand(new ReadQuickInfoCommand(numberOfBolusRecordsToRetrieve)); return runCommand(new ReadQuickInfoCommand(numberOfBolusRecordsToRetrieve));
} }
@ -366,7 +346,6 @@ public class RuffyScripter implements RuffyCommands {
// ignore // ignore
} }
} }
previousCommand = "" + activeCmd;
activeCmd = null; activeCmd = null;
} }
} }
@ -435,11 +414,6 @@ public class RuffyScripter implements RuffyCommands {
} }
} }
log.debug("Recovery from connection loss " + (connected ? "succeeded" : "failed")); 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; return connected;
} }
@ -450,12 +424,6 @@ public class RuffyScripter implements RuffyCommands {
private PumpState recoverFromCommandFailure() { private PumpState recoverFromCommandFailure() {
Menu menu = this.currentMenu; Menu menu = this.currentMenu;
if (menu == null) { 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(); return new PumpState();
} }
MenuType type = menu.getType(); MenuType type = menu.getType();
@ -469,21 +437,8 @@ public class RuffyScripter implements RuffyCommands {
} }
try { try {
PumpState pumpState = readPumpStateInternal(); 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; return pumpState;
} catch (Exception e) { } 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); log.debug("Reading pump state during recovery failed", e);
return new PumpState(); return new PumpState();
} }
@ -505,11 +460,6 @@ public class RuffyScripter implements RuffyCommands {
long initialUpdateTime = menuLastUpdated; long initialUpdateTime = menuLastUpdated;
while (initialUpdateTime == menuLastUpdated) { while (initialUpdateTime == menuLastUpdated) {
if (System.currentTimeMillis() > timeoutExpired) { 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"); throw new CommandException("Timeout connecting to pump");
} }
SystemClock.sleep(50); SystemClock.sleep(50);
@ -818,18 +768,12 @@ public class RuffyScripter implements RuffyCommands {
@Override @Override
public CommandResult deliverBolus(double amount, BolusProgressReporter bolusProgressReporter) { 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)); return runCommand(new BolusCommand(amount, bolusProgressReporter));
} }
@Override @Override
public void cancelBolus() { public void cancelBolus() {
if (activeCmd instanceof BolusCommand) { if (activeCmd instanceof BolusCommand) {
FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboBolusCmdCancel")
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION));
((BolusCommand) activeCmd).requestCancellation(); ((BolusCommand) activeCmd).requestCancellation();
} else { } else {
log.error("cancelBolus called, but active command is not a bolus:" + activeCmd); log.error("cancelBolus called, but active command is not a bolus:" + activeCmd);
@ -838,49 +782,31 @@ public class RuffyScripter implements RuffyCommands {
@Override @Override
public CommandResult setTbr(int percent, int duration) { 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)); return runCommand(new SetTbrCommand(percent, duration));
} }
@Override @Override
public CommandResult cancelTbr() { public CommandResult cancelTbr() {
FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboCancelTbrCmd")
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION));
return runCommand(new CancelTbrCommand()); return runCommand(new CancelTbrCommand());
} }
@Override @Override
public CommandResult confirmAlert(int warningCode) { public CommandResult confirmAlert(int warningCode) {
FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboConfirmAlertCmd")
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION));
return runCommand(new ConfirmAlertCommand(warningCode)); return runCommand(new ConfirmAlertCommand(warningCode));
} }
@Override @Override
public CommandResult readHistory(PumpHistoryRequest request) { public CommandResult readHistory(PumpHistoryRequest request) {
FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboReadHistoryCmd")
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION));
return runCommand(new ReadHistoryCommand(request)); return runCommand(new ReadHistoryCommand(request));
} }
@Override @Override
public CommandResult readBasalProfile() { public CommandResult readBasalProfile() {
FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboReadBasalProfileCmd")
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION));
return runCommand(new ReadBasalProfileCommand()); return runCommand(new ReadBasalProfileCommand());
} }
@Override @Override
public CommandResult setBasalProfile(BasalProfile basalProfile) { public CommandResult setBasalProfile(BasalProfile basalProfile) {
FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboSetBasalProfileCmd")
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION));
return runCommand(new SetBasalProfileCommand(basalProfile)); 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