diff --git a/.gitignore b/.gitignore index 7dc3c7a865..98b73cb7cb 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,6 @@ build/ app/src/main/jniLibs full/ debug/ -release/ \ No newline at end of file +release/ +app/com.crashlytics.settings.json +app/session_analytics.tap \ No newline at end of file diff --git a/README.md b/README.md index a9dd5a41f4..deeea159bc 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,10 @@ [![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) [![Build status](https://travis-ci.org/MilosKozak/AndroidAPS.svg?branch=master)](https://travis-ci.org/MilosKozak/AndroidAPS) +[![Crowdin](https://d322cqt584bo4o.cloudfront.net/androidaps/localized.svg)](https://translations.androidaps.org/project/androidaps) +[![Documentation Status](https://readthedocs.org/projects/androidaps/badge/?version=latest)](https://androidaps.readthedocs.io/en/latest/?badge=latest) [![codecov](https://codecov.io/gh/MilosKozak/AndroidAPS/branch/master/graph/badge.svg)](https://codecov.io/gh/MilosKozak/AndroidAPS) dev: [![codecov](https://codecov.io/gh/MilosKozak/AndroidAPS/branch/dev/graph/badge.svg)](https://codecov.io/gh/MilosKozak/AndroidAPS) + [![Donate via PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=Y4LHGJJESAVB8) diff --git a/app/build.gradle b/app/build.gradle index 1c50a05093..02e0c46295 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -29,9 +29,7 @@ repositories { } def generateGitBuild = { -> - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.append('"') try { def stdout = new ByteArrayOutputStream() exec { @@ -43,9 +41,12 @@ def generateGitBuild = { -> } catch (ignored) { stringBuilder.append('NoGitSystemAvailable') } - stringBuilder.append('-') + return stringBuilder.toString() +} + +def generateDate = { -> + StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append((new Date()).format('yyyy.MM.dd-HH:mm')) - stringBuilder.append('"') return stringBuilder.toString() } @@ -58,14 +59,14 @@ android { compileSdkVersion 27 defaultConfig { - applicationId "info.nightscout.androidaps" minSdkVersion 21 targetSdkVersion 25 multiDexEnabled true versionCode 1500 - version "1.60e-dev" + version "2.0i-dev" buildConfigField "String", "VERSION", '"' + version + '"' - buildConfigField "String", "BUILDVERSION", generateGitBuild() + buildConfigField "String", "BUILDVERSION", '"' + generateGitBuild() + '-' + generateDate() + '"' + buildConfigField "String", "HEAD", '"' + generateGitBuild() + '"' testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" ndk { @@ -95,56 +96,44 @@ android { productFlavors { flavorDimensions "standard" full { + applicationId "info.nightscout.androidaps" dimension "standard" resValue "string", "app_name", "AndroidAPS" versionName version manifestPlaceholders = [ - appIcon: "@mipmap/blueowl" + appIcon: "@mipmap/ic_launcher", + appIconRound: "@mipmap/ic_launcher_round" ] - buildConfigField "boolean", "APS", "true" - buildConfigField "boolean", "PUMPDRIVERS", "true" - buildConfigField "boolean", "NSCLIENTOLNY", "false" - buildConfigField "boolean", "G5UPLOADER", "false" - buildConfigField "boolean", "PUMPCONTROL", "false" } pumpcontrol { + applicationId "info.nightscout.androidaps" dimension "standard" resValue "string", "app_name", "AndroidAPS" versionName version manifestPlaceholders = [ - appIcon: "@mipmap/blueowl" + appIcon: "@mipmap/blueowl", + appIconRound: "@null" ] - buildConfigField "boolean", "APS", "false" - buildConfigField "boolean", "PUMPDRIVERS", "true" - buildConfigField "boolean", "NSCLIENTOLNY", "false" - buildConfigField "boolean", "G5UPLOADER", "false" - buildConfigField "boolean", "PUMPCONTROL", "true" } nsclient { + applicationId "info.nightscout.nsclient" dimension "standard" resValue "string", "app_name", "NSClient" versionName version + "-nsclient" manifestPlaceholders = [ - appIcon: "@mipmap/yellowowl" + appIcon: "@mipmap/yellowowl", + appIconRound: "@null" ] - buildConfigField "boolean", "APS", "false" - buildConfigField "boolean", "PUMPDRIVERS", "false" - buildConfigField "boolean", "NSCLIENTOLNY", "true" - buildConfigField "boolean", "G5UPLOADER", "false" - buildConfigField "boolean", "PUMPCONTROL", "false" } - g5uploader { + nsclient2 { + applicationId "info.nightscout.nsclient2" dimension "standard" - resValue "string", "app_name", "NSClient" + resValue "string", "app_name", "NSClient2" versionName version + "-nsclient" manifestPlaceholders = [ - appIcon: "@mipmap/yellowowl" + appIcon: "@mipmap/yellowowl", + appIconRound: "@null" ] - buildConfigField "boolean", "APS", "false" - buildConfigField "boolean", "PUMPDRIVERS", "false" - buildConfigField "boolean", "NSCLIENTOLNY", "false" - buildConfigField "boolean", "G5UPLOADER", "true" - buildConfigField "boolean", "PUMPCONTROL", "false" } } compileOptions { @@ -156,6 +145,8 @@ android { unitTests.returnDefaultValues = true unitTests.includeAndroidResources = true } + + useLibrary "org.apache.http.legacy" } allprojects { @@ -184,6 +175,7 @@ dependencies { libs "MilosKozak:danars-support-lib:master@zip" implementation "com.android.support:appcompat-v7:${supportLibraryVersion}" + implementation "com.android.support:support-v13:${supportLibraryVersion}" implementation "com.android.support:support-v4:${supportLibraryVersion}" implementation "com.android.support:cardview-v7:${supportLibraryVersion}" implementation "com.android.support:recyclerview-v7:${supportLibraryVersion}" diff --git a/app/libs/sightparser-release.aar b/app/libs/sightparser-release.aar index 302b9e836d..1f0c16ee34 100644 Binary files a/app/libs/sightparser-release.aar and b/app/libs/sightparser-release.aar differ diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 982682e035..264132de25 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -30,26 +30,27 @@ android:name=".MainApp" android:allowBackup="true" android:icon="${appIcon}" + android:roundIcon="${appIconRound}" android:label="@string/app_name" android:supportsRtl="true" - android:theme="@style/AppTheme"> + android:theme="@style/AppTheme.NoActionBar"> - - + - + - + + @@ -65,7 +66,7 @@ - + + + @@ -124,9 +127,19 @@ + + + + + + @@ -170,8 +185,12 @@ + android:theme="@style/AppTheme.NoActionBar" + android:label="@string/title_activity_setup_wizard" /> + + + \ No newline at end of file diff --git a/app/src/main/assets/OpenAPSSMB/basal-set-temp.js b/app/src/main/assets/OpenAPSSMB/basal-set-temp.js index 1686ea2c47..9cb932022c 100644 --- a/app/src/main/assets/OpenAPSSMB/basal-set-temp.js +++ b/app/src/main/assets/OpenAPSSMB/basal-set-temp.js @@ -9,33 +9,32 @@ var tempBasalFunctions = {}; tempBasalFunctions.getMaxSafeBasal = function getMaxSafeBasal(profile) { - var max_daily_safety_multiplier = (isNaN(profile.max_daily_safety_multiplier) || profile.max_daily_safety_multiplier == null) ? 3 : profile.max_daily_safety_multiplier; - var current_basal_safety_multiplier = (isNaN(profile.current_basal_safety_multiplier) || profile.current_basal_safety_multiplier == null) ? 4 : profile.current_basal_safety_multiplier; - - return Math.min(profile.max_basal, max_daily_safety_multiplier * profile.max_daily_basal, current_basal_safety_multiplier * profile.current_basal); + var max_daily_safety_multiplier = (isNaN(profile.max_daily_safety_multiplier) || profile.max_daily_safety_multiplier == null) ? 3 : profile.max_daily_safety_multiplier; + var current_basal_safety_multiplier = (isNaN(profile.current_basal_safety_multiplier) || profile.current_basal_safety_multiplier == null) ? 4 : profile.current_basal_safety_multiplier; + + return Math.min(profile.max_basal, max_daily_safety_multiplier * profile.max_daily_basal, current_basal_safety_multiplier * profile.current_basal); }; tempBasalFunctions.setTempBasal = function setTempBasal(rate, duration, profile, rT, currenttemp) { //var maxSafeBasal = Math.min(profile.max_basal, 3 * profile.max_daily_basal, 4 * profile.current_basal); - + var maxSafeBasal = tempBasalFunctions.getMaxSafeBasal(profile); -var round_basal = require('./round-basal'); - - if (rate < 0) { - rate = 0; - } // if >30m @ 0 required, zero temp will be extended to 30m instead - else if (rate > maxSafeBasal) { - rate = maxSafeBasal; + var round_basal = require('./round-basal'); + + if (rate < 0) { + rate = 0; + } else if (rate > maxSafeBasal) { + rate = maxSafeBasal; } var suggestedRate = round_basal(rate, profile); - if (typeof(currenttemp) !== 'undefined' && typeof(currenttemp.duration) !== 'undefined' && typeof(currenttemp.rate) !== 'undefined' && currenttemp.duration > (duration-10) && currenttemp.duration <= 120 && suggestedRate <= currenttemp.rate * 1.2 && suggestedRate >= currenttemp.rate * 0.8) { + if (typeof(currenttemp) !== 'undefined' && typeof(currenttemp.duration) !== 'undefined' && typeof(currenttemp.rate) !== 'undefined' && currenttemp.duration > (duration-10) && currenttemp.duration <= 120 && suggestedRate <= currenttemp.rate * 1.2 && suggestedRate >= currenttemp.rate * 0.8 && duration > 0 ) { rT.reason += " "+currenttemp.duration+"m left and " + currenttemp.rate + " ~ req " + suggestedRate + "U/hr: no temp required"; return rT; } if (suggestedRate === profile.current_basal) { - if (profile.skip_neutral_temps) { + if (profile.skip_neutral_temps === true) { if (typeof(currenttemp) !== 'undefined' && typeof(currenttemp.duration) !== 'undefined' && currenttemp.duration > 0) { reason(rT, 'Suggested rate is same as profile rate, a temp basal is active, canceling current temp'); rT.duration = 0; @@ -58,4 +57,4 @@ var round_basal = require('./round-basal'); } }; -module.exports = tempBasalFunctions; \ No newline at end of file +module.exports = tempBasalFunctions; diff --git a/app/src/main/assets/OpenAPSSMB/determine-basal.js b/app/src/main/assets/OpenAPSSMB/determine-basal.js index 84bd684cf6..c2db0f270b 100644 --- a/app/src/main/assets/OpenAPSSMB/determine-basal.js +++ b/app/src/main/assets/OpenAPSSMB/determine-basal.js @@ -406,8 +406,8 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_ } else { console.error("SMB disabled (no enableSMB preferences active)"); } - // enable UAM (if enabled in preferences) if SMB is enabled - var enableUAM=(profile.enableUAM && enableSMB); + // enable UAM (if enabled in preferences) + var enableUAM=(profile.enableUAM); //console.error(meal_data); @@ -942,10 +942,10 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_ var durationReq = round(60*worstCaseInsulinReq / profile.current_basal); if (durationReq < 0) { durationReq = 0; - // don't set a temp longer than 120 minutes + // don't set an SMB zero temp longer than 60 minutess } else { durationReq = round(durationReq/30)*30; - durationReq = Math.min(120,Math.max(0,durationReq)); + durationReq = Math.min(60,Math.max(0,durationReq)); } //console.error(durationReq); //rT.reason += "insulinReq " + insulinReq + "; " diff --git a/app/src/main/assets/logback.xml b/app/src/main/assets/logback.xml index d6facdb7dd..ae1594f639 100644 --- a/app/src/main/assets/logback.xml +++ b/app/src/main/assets/logback.xml @@ -1,36 +1,39 @@ - - - - ${EXT_FILES_DIR}/AndroidAPS.log - + + + + ${EXT_FILES_DIR}/AndroidAPS.log + - ${EXT_FILES_DIR}/AndroidAPS._%d{yyyy-MM-dd}_%d{HH-mm-ss, aux}_.%i.zip + ${EXT_FILES_DIR}/AndroidAPS._%d{yyyy-MM-dd}_%d{HH-mm-ss, aux}_.%i.zip + - + 5MB 120 - - - %d{HH:mm:ss.SSS} [%thread] %-5level [%class:%line]: %msg%n - - + + + %d{HH:mm:ss.SSS} [%thread] %.-1level/%logger: [%class{0}.%M\(\):%line]: %msg%n + + - - %logger{0} - - - [%thread] %-5level [%class:%line]: %msg%n - - - - - - - - + + %logger{0} + + + [%thread] [%class{0}.%M\(\):%line]: %msg%n + + + + + + + + diff --git a/app/src/main/blueowl-web.png b/app/src/main/blueowl-web.png new file mode 100644 index 0000000000..22339763e2 Binary files /dev/null and b/app/src/main/blueowl-web.png differ diff --git a/app/src/main/ic_launcher-web.png b/app/src/main/ic_launcher-web.png new file mode 100644 index 0000000000..22339763e2 Binary files /dev/null and b/app/src/main/ic_launcher-web.png differ diff --git a/app/src/main/ic_launcher_round-web.png b/app/src/main/ic_launcher_round-web.png new file mode 100644 index 0000000000..22339763e2 Binary files /dev/null and b/app/src/main/ic_launcher_round-web.png differ diff --git a/app/src/main/java/com/squareup/otto/LoggingBus.java b/app/src/main/java/com/squareup/otto/LoggingBus.java index 3417e7dd41..d9758a9a24 100644 --- a/app/src/main/java/com/squareup/otto/LoggingBus.java +++ b/app/src/main/java/com/squareup/otto/LoggingBus.java @@ -5,20 +5,23 @@ import org.slf4j.LoggerFactory; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.util.ConcurrentModificationException; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import info.nightscout.androidaps.events.Event; +import info.nightscout.androidaps.logging.L; -/** Logs events has they're being posted to and dispatched from the event bus. - * +/** + * Logs events has they're being posted to and dispatched from the event bus. + *

* A summary of event-receiver calls that occurred so far is logged * after 10s (after startup) and then again every 60s. - * */ + */ public class LoggingBus extends Bus { - private static Logger log = LoggerFactory.getLogger(LoggingBus.class); + private static Logger log = LoggerFactory.getLogger(L.EVENTS); private static long everyMinute = System.currentTimeMillis() + 10 * 1000; private Map> event2Receiver = new HashMap<>(); @@ -48,7 +51,10 @@ public class LoggingBus extends Bus { log.debug(" source: "); } - super.post(event); + try { + super.post(event); + } catch (IllegalStateException ignored) { + } } @Override @@ -70,16 +76,19 @@ public class LoggingBus extends Bus { log.debug(" receiver: "); } - if (everyMinute < System.currentTimeMillis()) { - log.debug("***************** Event -> receiver pairings seen so far ****************"); - for (Map.Entry> stringSetEntry : event2Receiver.entrySet()) { - log.debug(" " + stringSetEntry.getKey()); - for (String s : stringSetEntry.getValue()) { - log.debug(" -> " + s); + try { + if (everyMinute < System.currentTimeMillis()) { + log.debug("***************** Event -> receiver pairings seen so far ****************"); + for (Map.Entry> stringSetEntry : event2Receiver.entrySet()) { + log.debug(" " + stringSetEntry.getKey()); + for (String s : stringSetEntry.getValue()) { + log.debug(" -> " + s); + } } + log.debug("*************************************************************************"); + everyMinute = System.currentTimeMillis() + 60 * 1000; } - log.debug("*************************************************************************"); - everyMinute = System.currentTimeMillis() + 60 * 1000; + } catch (ConcurrentModificationException ignored) { } super.dispatch(event, wrapper); diff --git a/app/src/main/java/info/nightscout/androidaps/Config.java b/app/src/main/java/info/nightscout/androidaps/Config.java index a12e0a9ea0..ae0e14c9b6 100644 --- a/app/src/main/java/info/nightscout/androidaps/Config.java +++ b/app/src/main/java/info/nightscout/androidaps/Config.java @@ -6,39 +6,19 @@ package info.nightscout.androidaps; public class Config { public static int SUPPORTEDNSVERSION = 1002; // 0.10.00 - // MAIN FUCTIONALITY - public static final boolean APS = BuildConfig.APS; - // PLUGINS - public static final boolean NSCLIENT = BuildConfig.NSCLIENTOLNY; - public static final boolean G5UPLOADER = BuildConfig.G5UPLOADER; - public static final boolean PUMPCONTROL = BuildConfig.PUMPCONTROL; + public static final boolean APS = BuildConfig.FLAVOR.equals("full"); - public static final boolean HWPUMPS = BuildConfig.PUMPDRIVERS; + public static final boolean NSCLIENT = BuildConfig.FLAVOR.equals("nsclient") || BuildConfig.FLAVOR.equals("nsclient2"); + public static final boolean PUMPCONTROL = BuildConfig.FLAVOR.equals("pumpcontrol"); - public static final boolean ACTION = !BuildConfig.NSCLIENTOLNY && !BuildConfig.G5UPLOADER; - public static final boolean MDI = !BuildConfig.NSCLIENTOLNY && !BuildConfig.G5UPLOADER; - public static final boolean OTHERPROFILES = !BuildConfig.NSCLIENTOLNY && !BuildConfig.G5UPLOADER; - public static final boolean SAFETY = !BuildConfig.NSCLIENTOLNY && !BuildConfig.G5UPLOADER; + public static final boolean PUMPDRIVERS = BuildConfig.FLAVOR.equals("full") || BuildConfig.FLAVOR.equals("pumpcontrol"); - public static final boolean SMSCOMMUNICATORENABLED = !BuildConfig.NSCLIENTOLNY && !BuildConfig.G5UPLOADER; + public static final boolean ACTION = !NSCLIENT; + public static final boolean MDI = !NSCLIENT; + public static final boolean OTHERPROFILES = !NSCLIENT; + public static final boolean SAFETY = !NSCLIENT; + + public static final boolean SMSCOMMUNICATORENABLED = !NSCLIENT; - public static final boolean detailedLog = true; - public static final boolean logFunctionCalls = true; - public static final boolean logIncommingData = true; - public static final boolean logAPSResult = true; - public static final boolean logPumpComm = true; - public static final boolean logPrefsChange = true; - public static final boolean logConfigBuilder = true; - public static final boolean logNSUpload = true; - public static final boolean logPumpActions = true; - public static final boolean logCongigBuilderActions = true; - public static final boolean logAutosensData = false; - public static final boolean logEvents = false; - public static final boolean logProfile = false; - - // DanaR specific - public static final boolean logDanaBTComm = true; - public static boolean logDanaMessageDetail = true; - public static final boolean logDanaSerialEngine = true; } diff --git a/app/src/main/java/info/nightscout/androidaps/Constants.java b/app/src/main/java/info/nightscout/androidaps/Constants.java index a66d4e77f1..ffe227dc1b 100644 --- a/app/src/main/java/info/nightscout/androidaps/Constants.java +++ b/app/src/main/java/info/nightscout/androidaps/Constants.java @@ -67,4 +67,5 @@ public class Constants { //SMS Communicator public static final long SMS_CONFIRM_TIMEOUT = T.mins(5).msecs(); + } diff --git a/app/src/main/java/info/nightscout/androidaps/HistoryBrowseActivity.java b/app/src/main/java/info/nightscout/androidaps/HistoryBrowseActivity.java deleted file mode 100644 index c308cd2efe..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/HistoryBrowseActivity.java +++ /dev/null @@ -1,404 +0,0 @@ -package info.nightscout.androidaps; - -import android.app.Activity; -import android.os.Bundle; -import android.support.v4.content.res.ResourcesCompat; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.PopupMenu; -import android.text.SpannableString; -import android.text.style.ForegroundColorSpan; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.widget.Button; -import android.widget.ImageButton; -import android.widget.SeekBar; -import android.widget.TextView; - -import com.jjoe64.graphview.GraphView; -import com.squareup.otto.Subscribe; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Calendar; - -import butterknife.BindView; -import butterknife.ButterKnife; -import butterknife.OnClick; -import butterknife.OnLongClick; -import info.nightscout.androidaps.data.Profile; -import info.nightscout.androidaps.events.EventCustomCalculationFinished; -import info.nightscout.androidaps.interfaces.PumpInterface; -import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; -import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin; -import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished; -import info.nightscout.androidaps.plugins.Overview.OverviewFragment; -import info.nightscout.androidaps.plugins.Overview.OverviewPlugin; -import info.nightscout.androidaps.plugins.Overview.graphData.GraphData; -import info.nightscout.utils.DateUtil; -import info.nightscout.utils.SP; - -public class HistoryBrowseActivity extends AppCompatActivity { - private static Logger log = LoggerFactory.getLogger(HistoryBrowseActivity.class); - - - ImageButton chartButton; - - boolean showBasal = true; - boolean showIob, showCob, showDev, showRat, showDevslope; - - - @BindView(R.id.historybrowse_date) - Button buttonDate; - @BindView(R.id.historybrowse_zoom) - Button buttonZoom; - @BindView(R.id.historyybrowse_bggraph) - GraphView bgGraph; - @BindView(R.id.historybrowse_iobgraph) - GraphView iobGraph; - @BindView(R.id.historybrowse_seekBar) - SeekBar seekBar; - @BindView(R.id.historybrowse_noprofile) - TextView noProfile; - - private int rangeToDisplay = 24; // for graph - private long start; - - IobCobCalculatorPlugin iobCobCalculatorPlugin; - - EventCustomCalculationFinished eventCustomCalculationFinished = new EventCustomCalculationFinished(); - - public HistoryBrowseActivity() { - iobCobCalculatorPlugin = new IobCobCalculatorPlugin(); - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_historybrowse); - - ButterKnife.bind(this); - - bgGraph.getGridLabelRenderer().setGridColor(MainApp.gc(R.color.graphgrid)); - bgGraph.getGridLabelRenderer().reloadStyles(); - iobGraph.getGridLabelRenderer().setGridColor(MainApp.gc(R.color.graphgrid)); - iobGraph.getGridLabelRenderer().reloadStyles(); - iobGraph.getGridLabelRenderer().setHorizontalLabelsVisible(false); - bgGraph.getGridLabelRenderer().setLabelVerticalWidth(50); - iobGraph.getGridLabelRenderer().setLabelVerticalWidth(50); - iobGraph.getGridLabelRenderer().setNumVerticalLabels(5); - - setupChartMenu(); - - // set start of current day - Calendar calendar = Calendar.getInstance(); - calendar.setTimeInMillis(System.currentTimeMillis()); - calendar.set(Calendar.MILLISECOND, 0); - calendar.set(Calendar.SECOND, 0); - calendar.set(Calendar.MINUTE, 0); - calendar.set(Calendar.HOUR_OF_DAY, 0); - start = calendar.getTimeInMillis(); - } - - @Override - protected void onResume() { - super.onResume(); - updateGUI("onResume"); - } - - - @OnClick(R.id.historybrowse_start) - void onClickStart() { - } - - @OnClick(R.id.historybrowse_left) - void onClickLeft() { - start -= rangeToDisplay * 60 * 60 * 1000L; - updateGUI("left"); - iobCobCalculatorPlugin.clearCache(); - iobCobCalculatorPlugin.runCalculation("onClickLeft", start, true, eventCustomCalculationFinished); - } - - @OnClick(R.id.historybrowse_right) - void onClickRight() { - start += rangeToDisplay * 60 * 60 * 1000L; - updateGUI("right"); - iobCobCalculatorPlugin.clearCache(); - iobCobCalculatorPlugin.runCalculation("onClickRight", start, true, eventCustomCalculationFinished); - } - - @OnClick(R.id.historybrowse_end) - void onClickEnd() { - Calendar calendar = Calendar.getInstance(); - calendar.setTimeInMillis(System.currentTimeMillis()); - calendar.set(Calendar.MILLISECOND, 0); - calendar.set(Calendar.SECOND, 0); - calendar.set(Calendar.MINUTE, 0); - calendar.set(Calendar.HOUR_OF_DAY, 0); - start = calendar.getTimeInMillis(); - updateGUI("resetToMidnight"); - iobCobCalculatorPlugin.clearCache(); - iobCobCalculatorPlugin.runCalculation("onClickEnd", start, true, eventCustomCalculationFinished); - } - - @OnClick(R.id.historybrowse_zoom) - void onClickZoom() { - rangeToDisplay += 6; - rangeToDisplay = rangeToDisplay > 24 ? 6 : rangeToDisplay; - updateGUI("rangeChange"); - } - - @OnLongClick(R.id.historybrowse_zoom) - boolean onLongClickZoom() { - Calendar calendar = Calendar.getInstance(); - calendar.setTimeInMillis(start); - calendar.set(Calendar.MILLISECOND, 0); - calendar.set(Calendar.SECOND, 0); - calendar.set(Calendar.MINUTE, 0); - calendar.set(Calendar.HOUR_OF_DAY, 0); - start = calendar.getTimeInMillis(); - updateGUI("resetToMidnight"); - iobCobCalculatorPlugin.clearCache(); - iobCobCalculatorPlugin.runCalculation("onLongClickZoom", start, true, eventCustomCalculationFinished); - return true; - } - - @OnClick(R.id.historybrowse_date) - void onClickDate() { - } - - @Subscribe - public void onStatusEvent(final EventAutosensCalculationFinished e) { - Activity activity = this; - if (activity != null && e.cause == eventCustomCalculationFinished) { - log.debug("EventAutosensCalculationFinished"); - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - updateGUI("EventAutosensCalculationFinished"); - } - }); - } - } - - void updateGUI(String from) { - final PumpInterface pump = ConfigBuilderPlugin.getActivePump(); - final Profile profile = MainApp.getConfigBuilder().getProfile(); - - if (profile == null) { - noProfile.setVisibility(View.VISIBLE); - return; - } else { - noProfile.setVisibility(View.GONE); - } - - final String units = profile.getUnits(); - - double lowLineSetting = SP.getDouble("low_mark", Profile.fromMgdlToUnits(OverviewPlugin.bgTargetLow, units)); - double highLineSetting = SP.getDouble("high_mark", Profile.fromMgdlToUnits(OverviewPlugin.bgTargetHigh, units)); - - if (lowLineSetting < 1) - lowLineSetting = Profile.fromMgdlToUnits(76d, units); - if (highLineSetting < 1) - highLineSetting = Profile.fromMgdlToUnits(180d, units); - - final double lowLine = lowLineSetting; - final double highLine = highLineSetting; - - final boolean showPrediction = false; - - int hoursToFetch; - final long toTime; - final long fromTime; - //if (showPrediction) { - //int predHours = (int) (Math.ceil(((DetermineBasalResultAMA) finalLastRun.constraintsProcessed).getLatestPredictionsTime() - System.currentTimeMillis()) / (60 * 60 * 1000)); - //predHours = Math.min(2, predHours); - //predHours = Math.max(0, predHours); - //hoursToFetch = rangeToDisplay - predHours; - //toTime = calendar.getTimeInMillis() + 100000; // little bit more to avoid wrong rounding - Graphview specific - //fromTime = toTime - hoursToFetch * 60 * 60 * 1000L; - //endTime = toTime + predHours * 60 * 60 * 1000L; - //} else { - fromTime = start + 100000; - toTime = start + rangeToDisplay * 60 * 60 * 1000L; - //} - - buttonDate.setText(DateUtil.dateAndTimeString(start)); - buttonZoom.setText(String.valueOf(rangeToDisplay)); - - log.debug("Period: " + DateUtil.dateAndTimeString(fromTime) + " - " + DateUtil.dateAndTimeString(toTime)); - - final long pointer = System.currentTimeMillis(); - - // ------------------ 1st graph - - final GraphData graphData = new GraphData(bgGraph, IobCobCalculatorPlugin.getPlugin()); - - // **** In range Area **** - graphData.addInRangeArea(fromTime, toTime, lowLine, highLine); - - // **** BG **** - if (showPrediction) -//graphData.addBgReadings(fromTime, toTime, lowLine, highLine, (DetermineBasalResultAMA) finalLastRun.constraintsProcessed); - ; - else - graphData.addBgReadings(fromTime, toTime, lowLine, highLine, null); - - // set manual x bounds to have nice steps - graphData.formatAxis(fromTime, toTime); - - // Treatments - graphData.addTreatments(fromTime, toTime); - - // add basal data - if (pump.getPumpDescription().isTempBasalCapable && showBasal) { - graphData.addBasals(fromTime, toTime, lowLine / graphData.maxY / 1.2d); - } - - // **** NOW line **** - graphData.addNowLine(pointer); - - // ------------------ 2nd graph - - final GraphData secondGraphData = new GraphData(iobGraph, iobCobCalculatorPlugin); - - boolean useIobForScale = false; - boolean useCobForScale = false; - boolean useDevForScale = false; - boolean useRatioForScale = false; - boolean useDevSlopeForScale = false; - - if (showIob) { - useIobForScale = true; - } else if (showCob) { - useCobForScale = true; - } else if (showDev) { - useDevForScale = true; - } else if (showRat) { - useRatioForScale = true; - } else if (showDevslope) { - useDevSlopeForScale = true; - } - - if (showIob) - secondGraphData.addIob(fromTime, toTime, useIobForScale, 1d); - if (showCob) - secondGraphData.addCob(fromTime, toTime, useCobForScale, useCobForScale ? 1d : 0.5d); - if (showDev) - secondGraphData.addDeviations(fromTime, toTime, useDevForScale, 1d); - if (showRat) - secondGraphData.addRatio(fromTime, toTime, useRatioForScale, 1d); - if (showDevslope) - secondGraphData.addDeviationSlope(fromTime, toTime, useDevSlopeForScale, 1d); - - // **** NOW line **** - // set manual x bounds to have nice steps - secondGraphData.formatAxis(fromTime, toTime); - secondGraphData.addNowLine(pointer); - - // do GUI update - if (showIob || showCob || showDev || showRat || showDevslope) { - iobGraph.setVisibility(View.VISIBLE); - } else { - iobGraph.setVisibility(View.GONE); - } - // finally enforce drawing of graphs - graphData.performUpdate(); - secondGraphData.performUpdate(); - } - - private void setupChartMenu() { - chartButton = (ImageButton) findViewById(R.id.overview_chartMenuButton); - chartButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - MenuItem item; - CharSequence title; - SpannableString s; - PopupMenu popup = new PopupMenu(v.getContext(), v); - - - item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.BAS.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_basals)); - title = item.getTitle(); - s = new SpannableString(title); - s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.basal, null)), 0, s.length(), 0); - item.setTitle(s); - item.setCheckable(true); - item.setChecked(showBasal); - - item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.IOB.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_iob)); - title = item.getTitle(); - s = new SpannableString(title); - s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.iob, null)), 0, s.length(), 0); - item.setTitle(s); - item.setCheckable(true); - item.setChecked(showIob); - - item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.COB.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_cob)); - title = item.getTitle(); - s = new SpannableString(title); - s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.cob, null)), 0, s.length(), 0); - item.setTitle(s); - item.setCheckable(true); - item.setChecked(showCob); - - item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.DEV.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_deviations)); - title = item.getTitle(); - s = new SpannableString(title); - s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.deviations, null)), 0, s.length(), 0); - item.setTitle(s); - item.setCheckable(true); - item.setChecked(showDev); - - item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.SEN.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_sensitivity)); - title = item.getTitle(); - s = new SpannableString(title); - s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.ratio, null)), 0, s.length(), 0); - item.setTitle(s); - item.setCheckable(true); - item.setChecked(showRat); - - if (MainApp.devBranch) { - item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.DEVSLOPE.ordinal(), Menu.NONE, "Deviation slope"); - title = item.getTitle(); - s = new SpannableString(title); - s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.devslopepos, null)), 0, s.length(), 0); - item.setTitle(s); - item.setCheckable(true); - item.setChecked(showDevslope); - } - - popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem item) { - if (item.getItemId() == OverviewFragment.CHARTTYPE.BAS.ordinal()) { - showBasal = !item.isChecked(); - } else if (item.getItemId() == OverviewFragment.CHARTTYPE.IOB.ordinal()) { - showIob = !item.isChecked(); - } else if (item.getItemId() == OverviewFragment.CHARTTYPE.COB.ordinal()) { - showCob = !item.isChecked(); - } else if (item.getItemId() == OverviewFragment.CHARTTYPE.DEV.ordinal()) { - showDev = !item.isChecked(); - } else if (item.getItemId() == OverviewFragment.CHARTTYPE.SEN.ordinal()) { - showRat = !item.isChecked(); - } else if (item.getItemId() == OverviewFragment.CHARTTYPE.DEVSLOPE.ordinal()) { - showDevslope = !item.isChecked(); - } - updateGUI("onGraphCheckboxesCheckedChanged"); - return true; - } - }); - chartButton.setImageResource(R.drawable.ic_arrow_drop_up_white_24dp); - popup.setOnDismissListener(new PopupMenu.OnDismissListener() { - @Override - public void onDismiss(PopupMenu menu) { - chartButton.setImageResource(R.drawable.ic_arrow_drop_down_white_24dp); - } - }); - popup.show(); - } - }); - } - -} diff --git a/app/src/main/java/info/nightscout/androidaps/MainActivity.java b/app/src/main/java/info/nightscout/androidaps/MainActivity.java index 9d869cdde6..1595e6cb02 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/MainActivity.java @@ -1,30 +1,34 @@ package info.nightscout.androidaps; -import android.app.Activity; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.graphics.Rect; -import android.os.Build; import android.os.Bundle; +import android.os.PersistableBundle; import android.os.PowerManager; +import android.support.annotation.Nullable; +import android.support.design.widget.NavigationView; +import android.support.design.widget.TabLayout; import android.support.v4.app.ActivityCompat; import android.support.v4.view.ViewPager; +import android.support.v4.widget.DrawerLayout; +import android.support.v7.app.ActionBarDrawerToggle; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.PopupMenu; +import android.support.v7.widget.Toolbar; import android.text.SpannableString; import android.text.method.LinkMovementMethod; import android.text.util.Linkify; -import android.view.MenuInflater; +import android.util.TypedValue; +import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.view.WindowManager; import android.view.inputmethod.InputMethodManager; import android.widget.EditText; -import android.widget.ImageButton; +import android.widget.LinearLayout; import android.widget.TextView; import com.joanzapata.iconify.Iconify; @@ -34,59 +38,105 @@ import com.squareup.otto.Subscribe; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import info.nightscout.androidaps.activities.AgreementActivity; +import info.nightscout.androidaps.activities.HistoryBrowseActivity; +import info.nightscout.androidaps.activities.PreferencesActivity; +import info.nightscout.androidaps.activities.SingleFragmentActivity; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.events.EventAppExit; import info.nightscout.androidaps.events.EventFeatureRunning; import info.nightscout.androidaps.events.EventPreferenceChange; import info.nightscout.androidaps.events.EventRefreshGui; import info.nightscout.androidaps.interfaces.PluginBase; -import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; -import info.nightscout.androidaps.plugins.Food.FoodPlugin; -import info.nightscout.androidaps.plugins.Overview.events.EventSetWakeLock; -import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; +import info.nightscout.androidaps.plugins.NSClientInternal.data.NSSettingsStatus; import info.nightscout.androidaps.setupwizard.SetupWizardActivity; -import info.nightscout.androidaps.tabs.SlidingTabLayout; import info.nightscout.androidaps.tabs.TabPageAdapter; import info.nightscout.utils.AndroidPermission; -import info.nightscout.utils.ImportExportPrefs; import info.nightscout.utils.LocaleHelper; -import info.nightscout.utils.LogDialog; import info.nightscout.utils.OKDialog; import info.nightscout.utils.PasswordProtection; import info.nightscout.utils.SP; +import info.nightscout.utils.VersionChecker; -public class MainActivity extends AppCompatActivity implements View.OnClickListener { - private static Logger log = LoggerFactory.getLogger(MainActivity.class); - - ImageButton menuButton; +public class MainActivity extends AppCompatActivity { + private static Logger log = LoggerFactory.getLogger(L.CORE); protected PowerManager.WakeLock mWakeLock; + private ActionBarDrawerToggle actionBarDrawerToggle; + + private MenuItem pluginPreferencesMenuItem; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - if (Config.logFunctionCalls) + if (L.isEnabled(L.CORE)) log.debug("onCreate"); Iconify.with(new FontAwesomeModule()); LocaleHelper.onCreate(this, "en"); - setContentView(R.layout.activity_main); - menuButton = (ImageButton) findViewById(R.id.overview_menuButton); - menuButton.setOnClickListener(this); - onStatusEvent(new EventSetWakeLock(SP.getBoolean("lockscreen", false))); + setContentView(R.layout.activity_main); + setSupportActionBar(findViewById(R.id.toolbar)); + getSupportActionBar().setDisplayShowTitleEnabled(false); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setHomeButtonEnabled(true); + + DrawerLayout drawerLayout = findViewById(R.id.drawer_layout); + actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.string.open_navigation, R.string.close_navigation); + drawerLayout.addDrawerListener(actionBarDrawerToggle); + actionBarDrawerToggle.syncState(); + + // initialize screen wake lock + onEventPreferenceChange(new EventPreferenceChange(R.string.key_keep_screen_on)); doMigrations(); registerBus(); - setUpTabs(false); + setupTabs(); + setupViews(false); + + final ViewPager viewPager = findViewById(R.id.pager); + viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + } + + @Override + public void onPageSelected(int position) { + checkPluginPreferences(viewPager); + } + + @Override + public void onPageScrollStateChanged(int state) { + } + }); + VersionChecker.check(); + } + + private void checkPluginPreferences(ViewPager viewPager) { + if (pluginPreferencesMenuItem == null) return; + if (((TabPageAdapter) viewPager.getAdapter()).getPluginAt(viewPager.getCurrentItem()).getPreferencesId() != -1) + pluginPreferencesMenuItem.setEnabled(true); + else pluginPreferencesMenuItem.setEnabled(false); + } + + @Override + public void onPostCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) { + super.onPostCreate(savedInstanceState, persistentState); + actionBarDrawerToggle.syncState(); } @Override protected void onResume() { super.onResume(); + if (L.isEnabled(L.CORE)) + log.debug("onResume"); + if (!SP.getBoolean(R.string.key_setupwizard_processed, false)) { Intent intent = new Intent(this, SetupWizardActivity.class); startActivity(intent); @@ -96,14 +146,18 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe AndroidPermission.notifyForStoragePermission(this); AndroidPermission.notifyForBatteryOptimizationPermission(this); - AndroidPermission.notifyForLocationPermissions(this); - AndroidPermission.notifyForSMSPermissions(this); + if (Config.PUMPDRIVERS) { + AndroidPermission.notifyForLocationPermissions(this); + AndroidPermission.notifyForSMSPermissions(this); + } MainApp.bus().post(new EventFeatureRunning(EventFeatureRunning.Feature.MAIN)); } @Override public void onDestroy() { + if (L.isEnabled(L.CORE)) + log.debug("onDestroy"); if (mWakeLock != null) if (mWakeLock.isHeld()) mWakeLock.release(); @@ -111,55 +165,94 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe } @Subscribe - public void onStatusEvent(final EventSetWakeLock ev) { - final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); - if (ev.lock) { - mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "AAPS"); - if (!mWakeLock.isHeld()) - mWakeLock.acquire(); - } else { - if (mWakeLock != null && mWakeLock.isHeld()) - mWakeLock.release(); + public void onEventPreferenceChange(final EventPreferenceChange ev) { + if (ev.isChanged(R.string.key_keep_screen_on)) { + boolean keepScreenOn = SP.getBoolean(R.string.key_keep_screen_on, false); + final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); + if (keepScreenOn) { + mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "AAPS"); + if (!mWakeLock.isHeld()) + mWakeLock.acquire(); + } else { + if (mWakeLock != null && mWakeLock.isHeld()) + mWakeLock.release(); + } } } @Subscribe public void onStatusEvent(final EventRefreshGui ev) { - String lang = SP.getString("language", "en"); + String lang = SP.getString(R.string.key_language, "en"); LocaleHelper.setLocale(getApplicationContext(), lang); - runOnUiThread(new Runnable() { - @Override - public void run() { - if (ev.recreate) { - recreate(); - } else { - try { // activity may be destroyed - setUpTabs(true); - } catch (IllegalStateException e) { - log.error("Unhandled exception", e); - } + runOnUiThread(() -> { + if (ev.recreate) { + recreate(); + } else { + try { // activity may be destroyed + setupTabs(); + setupViews(true); + } catch (IllegalStateException e) { + log.error("Unhandled exception", e); } - - boolean lockScreen = BuildConfig.NSCLIENTOLNY && SP.getBoolean("lockscreen", false); - if (lockScreen) - getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); - else - getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } + + boolean keepScreenOn = Config.NSCLIENT && SP.getBoolean(R.string.key_keep_screen_on, false); + if (keepScreenOn) + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + else + getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); }); } - private void setUpTabs(boolean switchToLast) { + private void setupViews(boolean switchToLast) { TabPageAdapter pageAdapter = new TabPageAdapter(getSupportFragmentManager(), this); + NavigationView navigationView = findViewById(R.id.navigation_view); + navigationView.setNavigationItemSelectedListener(menuItem -> { + return true; + }); + Menu menu = navigationView.getMenu(); + menu.clear(); for (PluginBase p : MainApp.getPluginsList()) { pageAdapter.registerNewFragment(p); + if (p.hasFragment() && !p.isFragmentVisible() && p.isEnabled(p.pluginDescription.getType()) && !p.pluginDescription.neverVisible) { + MenuItem menuItem = menu.add(p.getName()); + menuItem.setCheckable(true); + menuItem.setOnMenuItemClickListener(item -> { + Intent intent = new Intent(this, SingleFragmentActivity.class); + intent.putExtra("plugin", MainApp.getPluginsList().indexOf(p)); + startActivity(intent); + ((DrawerLayout) findViewById(R.id.drawer_layout)).closeDrawers(); + return true; + }); + } } - ViewPager mPager = (ViewPager) findViewById(R.id.pager); + ViewPager mPager = findViewById(R.id.pager); mPager.setAdapter(pageAdapter); - SlidingTabLayout mTabs = (SlidingTabLayout) findViewById(R.id.tabs); - mTabs.setViewPager(mPager); if (switchToLast) mPager.setCurrentItem(pageAdapter.getCount() - 1, false); + checkPluginPreferences(mPager); + } + + private void setupTabs() { + ViewPager viewPager = findViewById(R.id.pager); + TabLayout normalTabs = findViewById(R.id.tabs_normal); + normalTabs.setupWithViewPager(viewPager, true); + TabLayout compactTabs = findViewById(R.id.tabs_compact); + compactTabs.setupWithViewPager(viewPager, true); + Toolbar toolbar = findViewById(R.id.toolbar); + if (SP.getBoolean("short_tabtitles", false)) { + normalTabs.setVisibility(View.GONE); + compactTabs.setVisibility(View.VISIBLE); + toolbar.setLayoutParams(new LinearLayout.LayoutParams(Toolbar.LayoutParams.MATCH_PARENT, (int) getResources().getDimension(R.dimen.compact_height))); + } else { + normalTabs.setVisibility(View.VISIBLE); + compactTabs.setVisibility(View.GONE); + TypedValue typedValue = new TypedValue(); + if (getTheme().resolveAttribute(R.attr.actionBarSize, typedValue, true)) { + toolbar.setLayoutParams(new LinearLayout.LayoutParams(Toolbar.LayoutParams.MATCH_PARENT, + TypedValue.complexToDimensionPixelSize(typedValue.data, getResources().getDisplayMetrics()))); + } + } } private void registerBus() { @@ -197,7 +290,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe private void checkUpgradeToProfileTarget() { // TODO: can be removed in the future boolean oldKeyExists = SP.contains("openapsma_min_bg"); if (oldKeyExists) { - Profile profile = MainApp.getConfigBuilder().getProfile(); + Profile profile = ProfileFunctions.getInstance().getProfile(); String oldRange = SP.getDouble("openapsma_min_bg", 0d) + " - " + SP.getDouble("openapsma_max_bg", 0d); String newRange = ""; if (profile != null) { @@ -257,99 +350,70 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe } @Override - public void onClick(final View v) { - final Activity activity = this; - switch (v.getId()) { - case R.id.overview_menuButton: - PopupMenu popup = new PopupMenu(v.getContext(), v); - MenuInflater inflater = popup.getMenuInflater(); - inflater.inflate(R.menu.menu_main, popup.getMenu()); - popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem item) { - int id = item.getItemId(); - switch (id) { - case R.id.nav_preferences: - PasswordProtection.QueryPassword(v.getContext(), R.string.settings_password, "settings_password", new Runnable() { - @Override - public void run() { - Intent i = new Intent(v.getContext(), PreferencesActivity.class); - i.putExtra("id", -1); - startActivity(i); - } - }, null); - break; - case R.id.nav_historybrowser: - startActivity(new Intent(v.getContext(), HistoryBrowseActivity.class)); - break; - case R.id.nav_setupwizard: - startActivity(new Intent(v.getContext(), SetupWizardActivity.class)); - break; - case R.id.nav_resetdb: - new AlertDialog.Builder(v.getContext()) - .setTitle(R.string.nav_resetdb) - .setMessage(R.string.reset_db_confirm) - .setNegativeButton(android.R.string.cancel, null) - .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - MainApp.getDbHelper().resetDatabases(); - // should be handled by Plugin-Interface and - // additional service interface and plugin registry - FoodPlugin.getPlugin().getService().resetFood(); - TreatmentsPlugin.getPlugin().getService().resetTreatments(); - } - }) - .create() - .show(); - break; - case R.id.nav_export: - ImportExportPrefs.verifyStoragePermissions(activity); - ImportExportPrefs.exportSharedPreferences(activity); - break; - case R.id.nav_import: - ImportExportPrefs.verifyStoragePermissions(activity); - ImportExportPrefs.importSharedPreferences(activity); - break; - case R.id.nav_show_logcat: - LogDialog.showLogcat(v.getContext()); - break; - case R.id.nav_about: - AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext()); - builder.setTitle(MainApp.gs(R.string.app_name) + " " + BuildConfig.VERSION); - if (Config.NSCLIENT || Config.G5UPLOADER) - builder.setIcon(R.mipmap.yellowowl); - else - builder.setIcon(R.mipmap.blueowl); - String message = "Build: " + BuildConfig.BUILDVERSION + "\n"; - message += "Flavor: " + BuildConfig.FLAVOR + BuildConfig.BUILD_TYPE + "\n"; - message += MainApp.gs(R.string.configbuilder_nightscoutversion_label) + " " + ConfigBuilderPlugin.nightscoutVersionName; - if (MainApp.engineeringMode) - message += "\n" + MainApp.gs(R.string.engineering_mode_enabled); - message += MainApp.gs(R.string.about_link_urls); - final SpannableString messageSpanned = new SpannableString(message); - Linkify.addLinks(messageSpanned, Linkify.WEB_URLS); - builder.setMessage(messageSpanned); - builder.setPositiveButton(MainApp.gs(R.string.ok), null); - AlertDialog alertDialog = builder.create(); - alertDialog.show(); - ((TextView) alertDialog.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance()); - break; - case R.id.nav_exit: - log.debug("Exiting"); - MainApp.instance().stopKeepAliveService(); - MainApp.bus().post(new EventAppExit()); - MainApp.closeDbHelper(); - finish(); - System.runFinalization(); - System.exit(0); - break; - } - return false; - } - }); - popup.show(); - break; + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.menu_main, menu); + pluginPreferencesMenuItem = menu.findItem(R.id.nav_plugin_preferences); + checkPluginPreferences(findViewById(R.id.pager)); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + int id = item.getItemId(); + switch (id) { + case R.id.nav_preferences: + PasswordProtection.QueryPassword(this, R.string.settings_password, "settings_password", () -> { + Intent i = new Intent(this, PreferencesActivity.class); + i.putExtra("id", -1); + startActivity(i); + }, null); + return true; + case R.id.nav_historybrowser: + startActivity(new Intent(this, HistoryBrowseActivity.class)); + return true; + case R.id.nav_setupwizard: + startActivity(new Intent(this, SetupWizardActivity.class)); + return true; + case R.id.nav_about: + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(MainApp.gs(R.string.app_name) + " " + BuildConfig.VERSION); + if (Config.NSCLIENT) + builder.setIcon(R.mipmap.yellowowl); + else + builder.setIcon(R.mipmap.blueowl); + String message = "Build: " + BuildConfig.BUILDVERSION + "\n"; + message += "Flavor: " + BuildConfig.FLAVOR + BuildConfig.BUILD_TYPE + "\n"; + message += MainApp.gs(R.string.configbuilder_nightscoutversion_label) + " " + NSSettingsStatus.getInstance().nightscoutVersionName; + if (MainApp.engineeringMode) + message += "\n" + MainApp.gs(R.string.engineering_mode_enabled); + message += MainApp.gs(R.string.about_link_urls); + final SpannableString messageSpanned = new SpannableString(message); + Linkify.addLinks(messageSpanned, Linkify.WEB_URLS); + builder.setMessage(messageSpanned); + builder.setPositiveButton(MainApp.gs(R.string.ok), null); + AlertDialog alertDialog = builder.create(); + alertDialog.show(); + ((TextView) alertDialog.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance()); + return true; + case R.id.nav_exit: + log.debug("Exiting"); + MainApp.instance().stopKeepAliveService(); + MainApp.bus().post(new EventAppExit()); + MainApp.closeDbHelper(); + finish(); + System.runFinalization(); + System.exit(0); + return true; + case R.id.nav_plugin_preferences: + ViewPager viewPager = findViewById(R.id.pager); + final PluginBase plugin = ((TabPageAdapter) viewPager.getAdapter()).getPluginAt(viewPager.getCurrentItem()); + PasswordProtection.QueryPassword(this, R.string.settings_password, "settings_password", () -> { + Intent i = new Intent(this, PreferencesActivity.class); + i.putExtra("id", plugin.getPreferencesId()); + startActivity(i); + }, null); + return true; } + return actionBarDrawerToggle.onOptionsItemSelected(item); } } diff --git a/app/src/main/java/info/nightscout/androidaps/MainApp.java b/app/src/main/java/info/nightscout/androidaps/MainApp.java index 45aff91654..327e451225 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainApp.java +++ b/app/src/main/java/info/nightscout/androidaps/MainApp.java @@ -5,11 +5,11 @@ import android.content.IntentFilter; import android.content.res.Resources; import android.os.SystemClock; import android.support.annotation.Nullable; +import android.support.annotation.PluralsRes; import android.support.v4.content.LocalBroadcastManager; import com.crashlytics.android.Crashlytics; import com.crashlytics.android.answers.Answers; -import com.crashlytics.android.answers.CustomEvent; import com.j256.ormlite.android.apptools.OpenHelperManager; import com.squareup.otto.Bus; import com.squareup.otto.LoggingBus; @@ -23,13 +23,12 @@ import org.slf4j.LoggerFactory; import java.io.File; import java.util.ArrayList; -import ch.qos.logback.classic.LoggerContext; -import info.nightscout.androidaps.Services.Intents; import info.nightscout.androidaps.data.ConstraintChecker; import info.nightscout.androidaps.db.DatabaseHelper; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.Actions.ActionsFragment; import info.nightscout.androidaps.plugins.Careportal.CareportalPlugin; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; @@ -40,15 +39,16 @@ import info.nightscout.androidaps.plugins.Insulin.InsulinOrefFreePeakPlugin; import info.nightscout.androidaps.plugins.Insulin.InsulinOrefRapidActingPlugin; import info.nightscout.androidaps.plugins.Insulin.InsulinOrefUltraRapidActingPlugin; import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin; +import info.nightscout.androidaps.plugins.Maintenance.MaintenancePlugin; import info.nightscout.androidaps.plugins.Loop.LoopPlugin; import info.nightscout.androidaps.plugins.NSClientInternal.NSClientPlugin; +import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; import info.nightscout.androidaps.plugins.NSClientInternal.receivers.AckAlarmReceiver; +import info.nightscout.androidaps.plugins.NSClientInternal.receivers.DBAccessReceiver; import info.nightscout.androidaps.plugins.OpenAPSAMA.OpenAPSAMAPlugin; import info.nightscout.androidaps.plugins.OpenAPSMA.OpenAPSMAPlugin; import info.nightscout.androidaps.plugins.OpenAPSSMB.OpenAPSSMBPlugin; import info.nightscout.androidaps.plugins.Overview.OverviewPlugin; -import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; -import info.nightscout.androidaps.plugins.Overview.notifications.Notification; import info.nightscout.androidaps.plugins.Persistentnotification.PersistentNotificationPlugin; import info.nightscout.androidaps.plugins.ProfileLocal.LocalProfilePlugin; import info.nightscout.androidaps.plugins.ProfileNS.NSProfilePlugin; @@ -61,14 +61,16 @@ import info.nightscout.androidaps.plugins.PumpDanaRv2.DanaRv2Plugin; import info.nightscout.androidaps.plugins.PumpInsight.InsightPlugin; import info.nightscout.androidaps.plugins.PumpMDI.MDIPlugin; import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin; -import info.nightscout.androidaps.plugins.SensitivityAAPS.SensitivityAAPSPlugin; -import info.nightscout.androidaps.plugins.SensitivityOref0.SensitivityOref0Plugin; -import info.nightscout.androidaps.plugins.SensitivityWeightedAverage.SensitivityWeightedAveragePlugin; +import info.nightscout.androidaps.plugins.Sensitivity.SensitivityAAPSPlugin; +import info.nightscout.androidaps.plugins.Sensitivity.SensitivityOref0Plugin; +import info.nightscout.androidaps.plugins.Sensitivity.SensitivityOref1Plugin; +import info.nightscout.androidaps.plugins.Sensitivity.SensitivityWeightedAveragePlugin; import info.nightscout.androidaps.plugins.SmsCommunicator.SmsCommunicatorPlugin; import info.nightscout.androidaps.plugins.Source.SourceDexcomG5Plugin; import info.nightscout.androidaps.plugins.Source.SourceGlimpPlugin; import info.nightscout.androidaps.plugins.Source.SourceMM640gPlugin; import info.nightscout.androidaps.plugins.Source.SourceNSClientPlugin; +import info.nightscout.androidaps.plugins.Source.SourcePoctechPlugin; import info.nightscout.androidaps.plugins.Source.SourceXdripPlugin; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.androidaps.plugins.Wear.WearPlugin; @@ -76,13 +78,14 @@ import info.nightscout.androidaps.plugins.XDripStatusline.StatuslinePlugin; import info.nightscout.androidaps.receivers.DataReceiver; import info.nightscout.androidaps.receivers.KeepAliveReceiver; import info.nightscout.androidaps.receivers.NSAlarmReceiver; +import info.nightscout.androidaps.services.Intents; import info.nightscout.utils.FabricPrivacy; -import info.nightscout.utils.NSUpload; +import info.nightscout.androidaps.plugins.Maintenance.LoggerUtils; import io.fabric.sdk.android.Fabric; public class MainApp extends Application { - private static Logger log = LoggerFactory.getLogger(MainApp.class); + private static Logger log = LoggerFactory.getLogger(L.CORE); private static KeepAliveReceiver keepAliveReceiver; private static Bus sBus; @@ -90,7 +93,6 @@ public class MainApp extends Application { public static Resources sResources; private static DatabaseHelper sDatabaseHelper = null; - private static ConfigBuilderPlugin sConfigBuilder = null; private static ConstraintChecker sConstraintsChecker = null; private static ArrayList pluginsList = null; @@ -98,6 +100,7 @@ public class MainApp extends Application { private static DataReceiver dataReceiver = new DataReceiver(); private static NSAlarmReceiver alarmReciever = new NSAlarmReceiver(); private static AckAlarmReceiver ackAlarmReciever = new AckAlarmReceiver(); + private static DBAccessReceiver dbAccessReciever = new DBAccessReceiver(); private LocalBroadcastManager lbm; public static boolean devBranch; @@ -106,6 +109,7 @@ public class MainApp extends Application { @Override public void onCreate() { super.onCreate(); + log.debug("onCreate"); sInstance = this; sResources = getResources(); sConstraintsChecker = new ConstraintChecker(this); @@ -118,7 +122,7 @@ public class MainApp extends Application { Crashlytics.setString("BUILDVERSION", BuildConfig.BUILDVERSION); } } catch (Exception e) { - android.util.Log.e("ANDROIDAPS", "Error with Fabric init! " + e); + log.error("Error with Fabric init! " + e); } JodaTimeAndroid.init(this); @@ -126,13 +130,13 @@ public class MainApp extends Application { log.info("Version: " + BuildConfig.VERSION_NAME); log.info("BuildVersion: " + BuildConfig.BUILDVERSION); - String extFilesDir = this.getLogDirectory(); + String extFilesDir = LoggerUtils.getLogDirectory(); File engineeringModeSemaphore = new File(extFilesDir, "engineering_mode"); engineeringMode = engineeringModeSemaphore.exists() && engineeringModeSemaphore.isFile(); devBranch = BuildConfig.VERSION.contains("dev"); - sBus = Config.logEvents ? new LoggingBus(ThreadEnforcer.ANY) : new Bus(ThreadEnforcer.ANY); + sBus = L.isEnabled(L.EVENTS) && devBranch ? new LoggingBus(ThreadEnforcer.ANY) : new Bus(ThreadEnforcer.ANY); registerLocalBroadcastReceiver(); @@ -148,14 +152,15 @@ public class MainApp extends Application { pluginsList.add(SensitivityOref0Plugin.getPlugin()); pluginsList.add(SensitivityAAPSPlugin.getPlugin()); pluginsList.add(SensitivityWeightedAveragePlugin.getPlugin()); - if (Config.HWPUMPS) pluginsList.add(DanaRPlugin.getPlugin()); - if (Config.HWPUMPS) pluginsList.add(DanaRKoreanPlugin.getPlugin()); - if (Config.HWPUMPS) pluginsList.add(DanaRv2Plugin.getPlugin()); - if (Config.HWPUMPS) pluginsList.add(DanaRSPlugin.getPlugin()); + pluginsList.add(SensitivityOref1Plugin.getPlugin()); + if (Config.PUMPDRIVERS) pluginsList.add(DanaRPlugin.getPlugin()); + if (Config.PUMPDRIVERS) pluginsList.add(DanaRKoreanPlugin.getPlugin()); + if (Config.PUMPDRIVERS) pluginsList.add(DanaRv2Plugin.getPlugin()); + if (Config.PUMPDRIVERS) pluginsList.add(DanaRSPlugin.getPlugin()); pluginsList.add(CareportalPlugin.getPlugin()); - if (Config.HWPUMPS && engineeringMode) + if (Config.PUMPDRIVERS && engineeringMode) pluginsList.add(InsightPlugin.getPlugin()); // <-- Enable Insight plugin here - if (Config.HWPUMPS) pluginsList.add(ComboPlugin.getPlugin()); + if (Config.PUMPDRIVERS) pluginsList.add(ComboPlugin.getPlugin()); if (Config.MDI) pluginsList.add(MDIPlugin.getPlugin()); pluginsList.add(VirtualPumpPlugin.getPlugin()); if (Config.APS) pluginsList.add(LoopPlugin.getPlugin()); @@ -168,46 +173,33 @@ public class MainApp extends Application { pluginsList.add(TreatmentsPlugin.getPlugin()); if (Config.SAFETY) pluginsList.add(SafetyPlugin.getPlugin()); if (Config.APS) pluginsList.add(ObjectivesPlugin.getPlugin()); - if (!Config.NSCLIENT && !Config.G5UPLOADER) - pluginsList.add(SourceXdripPlugin.getPlugin()); - if (!Config.G5UPLOADER) - pluginsList.add(SourceNSClientPlugin.getPlugin()); - if (!Config.NSCLIENT && !Config.G5UPLOADER) - pluginsList.add(SourceMM640gPlugin.getPlugin()); - if (!Config.NSCLIENT && !Config.G5UPLOADER) - pluginsList.add(SourceGlimpPlugin.getPlugin()); - if (!Config.NSCLIENT) - pluginsList.add(SourceDexcomG5Plugin.getPlugin()); + pluginsList.add(SourceXdripPlugin.getPlugin()); + pluginsList.add(SourceNSClientPlugin.getPlugin()); + pluginsList.add(SourceMM640gPlugin.getPlugin()); + pluginsList.add(SourceGlimpPlugin.getPlugin()); + pluginsList.add(SourceDexcomG5Plugin.getPlugin()); + pluginsList.add(SourcePoctechPlugin.getPlugin()); if (Config.SMSCOMMUNICATORENABLED) pluginsList.add(SmsCommunicatorPlugin.getPlugin()); pluginsList.add(FoodPlugin.getPlugin()); pluginsList.add(WearPlugin.initPlugin(this)); pluginsList.add(StatuslinePlugin.initPlugin(this)); - pluginsList.add(new PersistentNotificationPlugin(this)); + pluginsList.add(PersistentNotificationPlugin.getPlugin()); pluginsList.add(NSClientPlugin.getPlugin()); + pluginsList.add(MaintenancePlugin.initPlugin(this)); - pluginsList.add(sConfigBuilder = ConfigBuilderPlugin.getPlugin()); + pluginsList.add(ConfigBuilderPlugin.getPlugin()); - MainApp.getConfigBuilder().initialize(); + ConfigBuilderPlugin.getPlugin().initialize(); } + NSUpload.uploadAppStart(); - if (Config.NSCLIENT) - FabricPrivacy.getInstance().logCustom(new CustomEvent("AppStart-NSClient")); - else if (Config.G5UPLOADER) - FabricPrivacy.getInstance().logCustom(new CustomEvent("AppStart-G5Uploader")); - else if (Config.PUMPCONTROL) - FabricPrivacy.getInstance().logCustom(new CustomEvent("AppStart-PumpControl")); - else if (MainApp.getConstraintChecker().isClosedLoopAllowed().value()) - FabricPrivacy.getInstance().logCustom(new CustomEvent("AppStart-ClosedLoop")); - else - FabricPrivacy.getInstance().logCustom(new CustomEvent("AppStart-OpenLoop")); - - final PumpInterface pump = ConfigBuilderPlugin.getActivePump(); + final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); if (pump != null) { new Thread(() -> { SystemClock.sleep(5000); - ConfigBuilderPlugin.getCommandQueue().readStatus("Initialization", null); + ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("Initialization", null); startKeepAliveService(); }).start(); } @@ -236,6 +228,9 @@ public class MainApp extends Application { //register ack alarm lbm.registerReceiver(ackAlarmReciever, new IntentFilter(Intents.ACTION_ACK_ALARM)); + + //register dbaccess + lbm.registerReceiver(dbAccessReciever, new IntentFilter(Intents.ACTION_DATABASE)); } private void startKeepAliveService() { @@ -278,6 +273,10 @@ public class MainApp extends Application { return sResources.getString(id, args); } + public static String gq(@PluralsRes int id, int quantity, Object... args) { + return sResources.getQuantityString(id, quantity, args); + } + public static int gc(int id) { return sResources.getColor(id); } @@ -297,10 +296,6 @@ public class MainApp extends Application { } } - public static ConfigBuilderPlugin getConfigBuilder() { - return sConfigBuilder; - } - public static ConstraintChecker getConstraintChecker() { return sConstraintsChecker; } @@ -381,7 +376,7 @@ public class MainApp extends Application { } public static boolean isEngineeringModeOrRelease() { - if (!BuildConfig.APS) + if (!Config.APS) return true; return engineeringMode || !devBranch; } @@ -390,13 +385,10 @@ public class MainApp extends Application { return devBranch; } - public String getLogDirectory() { - LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory(); - return lc.getProperty("EXT_FILES_DIR"); - } - @Override public void onTerminate() { + if (L.isEnabled(L.CORE)) + log.debug("onTerminate"); super.onTerminate(); if (sDatabaseHelper != null) { sDatabaseHelper.close(); diff --git a/app/src/main/java/info/nightscout/androidaps/Services/DataService.java b/app/src/main/java/info/nightscout/androidaps/Services/DataService.java deleted file mode 100644 index 881f2e3bac..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/Services/DataService.java +++ /dev/null @@ -1,558 +0,0 @@ -package info.nightscout.androidaps.Services; - -import android.app.IntentService; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.os.Bundle; -import android.provider.Telephony; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import info.nightscout.androidaps.Config; -import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.R; -import info.nightscout.androidaps.data.ProfileStore; -import info.nightscout.androidaps.db.BgReading; -import info.nightscout.androidaps.db.CareportalEvent; -import info.nightscout.androidaps.events.EventNsFood; -import info.nightscout.androidaps.events.EventNsTreatment; -import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; -import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin; -import info.nightscout.androidaps.plugins.NSClientInternal.data.NSDeviceStatus; -import info.nightscout.androidaps.plugins.NSClientInternal.data.NSMbg; -import info.nightscout.androidaps.plugins.NSClientInternal.data.NSSettingsStatus; -import info.nightscout.androidaps.plugins.NSClientInternal.data.NSSgv; -import info.nightscout.androidaps.plugins.Overview.OverviewPlugin; -import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification; -import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; -import info.nightscout.androidaps.plugins.Overview.notifications.Notification; -import info.nightscout.androidaps.plugins.ProfileNS.NSProfilePlugin; -import info.nightscout.androidaps.plugins.ProfileNS.events.EventNSProfileUpdateGUI; -import info.nightscout.androidaps.plugins.PumpDanaR.activities.DanaRNSHistorySync; -import info.nightscout.androidaps.plugins.SmsCommunicator.events.EventNewSMS; -import info.nightscout.androidaps.plugins.Source.SourceDexcomG5Plugin; -import info.nightscout.androidaps.plugins.Source.SourceGlimpPlugin; -import info.nightscout.androidaps.plugins.Source.SourceMM640gPlugin; -import info.nightscout.androidaps.plugins.Source.SourceNSClientPlugin; -import info.nightscout.androidaps.plugins.Source.SourceXdripPlugin; -import info.nightscout.androidaps.receivers.DataReceiver; -import info.nightscout.utils.BundleLogger; -import info.nightscout.utils.JsonHelper; -import info.nightscout.utils.NSUpload; -import info.nightscout.utils.SP; - - -public class DataService extends IntentService { - private static Logger log = LoggerFactory.getLogger(DataService.class); - - boolean xDripEnabled = false; - boolean nsClientEnabled = true; - boolean mm640gEnabled = false; - boolean glimpEnabled = false; - boolean dexcomG5Enabled = false; - - public DataService() { - super("DataService"); - registerBus(); - } - - @Override - protected void onHandleIntent(final Intent intent) { - if (Config.logFunctionCalls) - log.debug("onHandleIntent " + BundleLogger.log(intent.getExtras())); - if (ConfigBuilderPlugin.getPlugin().getActiveBgSource() == null) { - xDripEnabled = true; - nsClientEnabled = false; - mm640gEnabled = false; - glimpEnabled = false; - dexcomG5Enabled = false; - } else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceXdripPlugin.class)) { - xDripEnabled = true; - nsClientEnabled = false; - mm640gEnabled = false; - glimpEnabled = false; - dexcomG5Enabled = false; - } else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceNSClientPlugin.class)) { - xDripEnabled = false; - nsClientEnabled = true; - mm640gEnabled = false; - glimpEnabled = false; - dexcomG5Enabled = false; - } else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceMM640gPlugin.class)) { - xDripEnabled = false; - nsClientEnabled = false; - mm640gEnabled = true; - glimpEnabled = false; - dexcomG5Enabled = false; - } else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceGlimpPlugin.class)) { - xDripEnabled = false; - nsClientEnabled = false; - mm640gEnabled = false; - glimpEnabled = true; - dexcomG5Enabled = false; - } else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceDexcomG5Plugin.class)) { - xDripEnabled = false; - nsClientEnabled = false; - mm640gEnabled = false; - glimpEnabled = false; - dexcomG5Enabled = true; - } - - boolean isNSProfile = MainApp.getConfigBuilder().getActiveProfileInterface() != null && MainApp.getConfigBuilder().getActiveProfileInterface().getClass().equals(NSProfilePlugin.class); - - boolean acceptNSData = !SP.getBoolean(R.string.key_ns_upload_only, false); - Bundle bundles = intent.getExtras(); - if (bundles != null && bundles.containsKey("islocal")) { - acceptNSData = acceptNSData || bundles.getBoolean("islocal"); - } - - - if (intent != null) { - final String action = intent.getAction(); - if (Intents.ACTION_NEW_BG_ESTIMATE.equals(action)) { - if (xDripEnabled) { - handleNewDataFromXDrip(intent); - } - } else if (Intents.NS_EMULATOR.equals(action)) { - if (mm640gEnabled) { - handleNewDataFromMM640g(intent); - } - } else if (Intents.GLIMP_BG.equals(action)) { - if (glimpEnabled) { - handleNewDataFromGlimp(intent); - } - } else if (Intents.DEXCOMG5_BG.equals(action)) { - if (dexcomG5Enabled) { - handleNewDataFromDexcomG5(intent); - } - } else if (Intents.ACTION_NEW_SGV.equals(action)) { - if (nsClientEnabled || SP.getBoolean(R.string.key_ns_autobackfill, true)) - handleNewDataFromNSClient(intent); - // Objectives 0 - ObjectivesPlugin.bgIsAvailableInNS = true; - ObjectivesPlugin.saveProgress(); - } else if (isNSProfile && Intents.ACTION_NEW_PROFILE.equals(action) || Intents.ACTION_NEW_DEVICESTATUS.equals(action)) { - // always handle Profile if NSProfile is enabled without looking at nsUploadOnly - handleNewDataFromNSClient(intent); - } else if (acceptNSData && - (Intents.ACTION_NEW_TREATMENT.equals(action) || - Intents.ACTION_CHANGED_TREATMENT.equals(action) || - Intents.ACTION_REMOVED_TREATMENT.equals(action) || - Intents.ACTION_NEW_STATUS.equals(action) || - Intents.ACTION_NEW_DEVICESTATUS.equals(action) || - Intents.ACTION_NEW_FOOD.equals(action) || - Intents.ACTION_CHANGED_FOOD.equals(action) || - Intents.ACTION_REMOVED_FOOD.equals(action) || - Intents.ACTION_NEW_CAL.equals(action) || - Intents.ACTION_NEW_MBG.equals(action)) - ) { - handleNewDataFromNSClient(intent); - } else if (Telephony.Sms.Intents.SMS_RECEIVED_ACTION.equals(action)) { - handleNewSMS(intent); - } - } - if (Config.logFunctionCalls) - log.debug("onHandleIntent exit " + intent); - DataReceiver.completeWakefulIntent(intent); - } - -/* - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - super.onStartCommand(intent, flags, startId); - - if (Config.logFunctionCalls) - log.debug("onStartCommand"); - - return START_STICKY; - } -*/ - - @Override - public void onDestroy() { - super.onDestroy(); - MainApp.bus().unregister(this); - } - - private void registerBus() { - try { - MainApp.bus().unregister(this); - } catch (RuntimeException x) { - // Ignore - } - MainApp.bus().register(this); - } - - private void handleNewDataFromXDrip(Intent intent) { - Bundle bundle = intent.getExtras(); - if (bundle == null) return; - - BgReading bgReading = new BgReading(); - - bgReading.value = bundle.getDouble(Intents.EXTRA_BG_ESTIMATE); - bgReading.direction = bundle.getString(Intents.EXTRA_BG_SLOPE_NAME); - bgReading.date = bundle.getLong(Intents.EXTRA_TIMESTAMP); - bgReading.raw = bundle.getDouble(Intents.EXTRA_RAW); - String source = bundle.getString(Intents.XDRIP_DATA_SOURCE_DESCRIPTION, "no Source specified"); - SourceXdripPlugin.getPlugin().setSource(source); - MainApp.getDbHelper().createIfNotExists(bgReading, "XDRIP"); - } - - private void handleNewDataFromGlimp(Intent intent) { - Bundle bundle = intent.getExtras(); - if (bundle == null) return; - - BgReading bgReading = new BgReading(); - - bgReading.value = bundle.getDouble("mySGV"); - bgReading.direction = bundle.getString("myTrend"); - bgReading.date = bundle.getLong("myTimestamp"); - bgReading.raw = 0; - - MainApp.getDbHelper().createIfNotExists(bgReading, "GLIMP"); - } - - private void handleNewDataFromDexcomG5(Intent intent) { - // onHandleIntent Bundle{ data => [{"m_time":1511939180,"m_trend":"NotComputable","m_value":335}]; android.support.content.wakelockid => 95; }Bundle - - Bundle bundle = intent.getExtras(); - if (bundle == null) return; - - BgReading bgReading = new BgReading(); - - String data = bundle.getString("data"); - log.debug("Received Dexcom Data", data); - - try { - JSONArray jsonArray = new JSONArray(data); - log.debug("Received Dexcom Data size:" + jsonArray.length()); - for (int i = 0; i < jsonArray.length(); i++) { - JSONObject json = jsonArray.getJSONObject(i); - bgReading.value = json.getInt("m_value"); - bgReading.direction = json.getString("m_trend"); - bgReading.date = json.getLong("m_time") * 1000L; - bgReading.raw = 0; - boolean isNew = MainApp.getDbHelper().createIfNotExists(bgReading, "DexcomG5"); - if (isNew && SP.getBoolean(R.string.key_dexcomg5_nsupload, false)) { - NSUpload.uploadBg(bgReading); - } - if (isNew && SP.getBoolean(R.string.key_dexcomg5_xdripupload, false)) { - NSUpload.sendToXdrip(bgReading); - } - } - - } catch (JSONException e) { - e.printStackTrace(); - } - } - - private void handleNewDataFromMM640g(Intent intent) { - Bundle bundle = intent.getExtras(); - if (bundle == null) return; - - final String collection = bundle.getString("collection"); - if (collection == null) return; - - if (collection.equals("entries")) { - final String data = bundle.getString("data"); - - if ((data != null) && (data.length() > 0)) { - try { - final JSONArray json_array = new JSONArray(data); - for (int i = 0; i < json_array.length(); i++) { - final JSONObject json_object = json_array.getJSONObject(i); - final String type = json_object.getString("type"); - switch (type) { - case "sgv": - BgReading bgReading = new BgReading(); - - bgReading.value = json_object.getDouble("sgv"); - bgReading.direction = json_object.getString("direction"); - bgReading.date = json_object.getLong("date"); - bgReading.raw = json_object.getDouble("sgv"); - - MainApp.getDbHelper().createIfNotExists(bgReading, "MM640g"); - break; - default: - log.debug("Unknown entries type: " + type); - } - } - } catch (JSONException e) { - log.error("Got JSON exception: " + e); - } - } - } - } - - private void handleNewDataFromNSClient(Intent intent) { - Bundle bundles = intent.getExtras(); - if (bundles == null) return; - if (Config.logIncommingData) - log.debug("Got intent: " + intent.getAction()); - - - if (intent.getAction().equals(Intents.ACTION_NEW_STATUS)) { - if (bundles.containsKey("nsclientversioncode")) { - ConfigBuilderPlugin.nightscoutVersionCode = bundles.getInt("nightscoutversioncode"); // for ver 1.2.3 contains 10203 - ConfigBuilderPlugin.nightscoutVersionName = bundles.getString("nightscoutversionname"); - ConfigBuilderPlugin.nsClientVersionCode = bundles.getInt("nsclientversioncode"); // for ver 1.17 contains 117 - ConfigBuilderPlugin.nsClientVersionName = bundles.getString("nsclientversionname"); - log.debug("Got versions: NSClient: " + ConfigBuilderPlugin.nsClientVersionName + " Nightscout: " + ConfigBuilderPlugin.nightscoutVersionName); - try { - if (ConfigBuilderPlugin.nsClientVersionCode < MainApp.instance().getPackageManager().getPackageInfo(MainApp.instance().getPackageName(), 0).versionCode) { - Notification notification = new Notification(Notification.OLD_NSCLIENT, MainApp.gs(R.string.unsupportedclientver), Notification.URGENT); - MainApp.bus().post(new EventNewNotification(notification)); - } else { - MainApp.bus().post(new EventDismissNotification(Notification.OLD_NSCLIENT)); - } - } catch (PackageManager.NameNotFoundException e) { - log.error("Unhandled exception", e); - } - if (ConfigBuilderPlugin.nightscoutVersionCode < Config.SUPPORTEDNSVERSION) { - Notification notification = new Notification(Notification.OLD_NS, MainApp.gs(R.string.unsupportednsversion), Notification.NORMAL); - MainApp.bus().post(new EventNewNotification(notification)); - } else { - MainApp.bus().post(new EventDismissNotification(Notification.OLD_NS)); - } - } else { - Notification notification = new Notification(Notification.OLD_NSCLIENT, MainApp.gs(R.string.unsupportedclientver), Notification.URGENT); - MainApp.bus().post(new EventNewNotification(notification)); - } - if (bundles.containsKey("status")) { - try { - JSONObject statusJson = new JSONObject(bundles.getString("status")); - NSSettingsStatus.getInstance().setData(statusJson); - if (Config.logIncommingData) - log.debug("Received status: " + statusJson.toString()); - Double targetHigh = NSSettingsStatus.getInstance().getThreshold("bgTargetTop"); - Double targetlow = NSSettingsStatus.getInstance().getThreshold("bgTargetBottom"); - if (targetHigh != null) - OverviewPlugin.bgTargetHigh = targetHigh; - if (targetlow != null) - OverviewPlugin.bgTargetLow = targetlow; - } catch (JSONException e) { - log.error("Unhandled exception", e); - } - } - } - if (intent.getAction().equals(Intents.ACTION_NEW_DEVICESTATUS)) { - try { - if (bundles.containsKey("devicestatus")) { - JSONObject devicestatusJson = new JSONObject(bundles.getString("devicestatus")); - NSDeviceStatus.getInstance().setData(devicestatusJson); - if (devicestatusJson.has("pump")) { - // Objectives 0 - ObjectivesPlugin.pumpStatusIsAvailableInNS = true; - ObjectivesPlugin.saveProgress(); - } - } - if (bundles.containsKey("devicestatuses")) { - String devicestatusesstring = bundles.getString("devicestatuses"); - JSONArray jsonArray = new JSONArray(devicestatusesstring); - for (int i = 0; i < jsonArray.length(); i++) { - JSONObject devicestatusJson = jsonArray.getJSONObject(i); - NSDeviceStatus.getInstance().setData(devicestatusJson); - if (devicestatusJson.has("pump")) { - // Objectives 0 - ObjectivesPlugin.pumpStatusIsAvailableInNS = true; - ObjectivesPlugin.saveProgress(); - } - } - } - } catch (Exception e) { - log.error("Unhandled exception", e); - } - } - // Handle profile - if (intent.getAction().equals(Intents.ACTION_NEW_PROFILE)) { - try { - String activeProfile = bundles.getString("activeprofile"); - String profile = bundles.getString("profile"); - ProfileStore profileStore = new ProfileStore(new JSONObject(profile)); - NSProfilePlugin.getPlugin().storeNewProfile(profileStore); - MainApp.bus().post(new EventNSProfileUpdateGUI()); - if (Config.logIncommingData) - log.debug("Received profileStore: " + activeProfile + " " + profile); - } catch (JSONException e) { - log.error("Unhandled exception", e); - } - } - - if (intent.getAction().equals(Intents.ACTION_NEW_TREATMENT) || intent.getAction().equals(Intents.ACTION_CHANGED_TREATMENT)) { - try { - if (bundles.containsKey("treatment")) { - JSONObject json = new JSONObject(bundles.getString("treatment")); - handleTreatmentFromNS(json, intent); - } - if (bundles.containsKey("treatments")) { - String trstring = bundles.getString("treatments"); - JSONArray jsonArray = new JSONArray(trstring); - for (int i = 0; i < jsonArray.length(); i++) { - JSONObject json = jsonArray.getJSONObject(i); - handleTreatmentFromNS(json, intent); - } - } - } catch (JSONException e) { - log.error("Unhandled exception", e); - } - } - - if (intent.getAction().equals(Intents.ACTION_REMOVED_TREATMENT)) { - try { - if (bundles.containsKey("treatment")) { - String trstring = bundles.getString("treatment"); - JSONObject json = new JSONObject(trstring); - handleTreatmentFromNS(json); - } - - if (bundles.containsKey("treatments")) { - String trstring = bundles.getString("treatments"); - JSONArray jsonArray = new JSONArray(trstring); - for (int i = 0; i < jsonArray.length(); i++) { - JSONObject json = jsonArray.getJSONObject(i); - handleTreatmentFromNS(json); - } - } - } catch (JSONException e) { - log.error("Unhandled exception", e); - } - } - - if (intent.getAction().equals(Intents.ACTION_NEW_SGV)) { - try { - if (bundles.containsKey("sgv")) { - String sgvstring = bundles.getString("sgv"); - JSONObject sgvJson = new JSONObject(sgvstring); - NSSgv nsSgv = new NSSgv(sgvJson); - BgReading bgReading = new BgReading(nsSgv); - MainApp.getDbHelper().createIfNotExists(bgReading, "NS"); - } - - if (bundles.containsKey("sgvs")) { - String sgvstring = bundles.getString("sgvs"); - JSONArray jsonArray = new JSONArray(sgvstring); - for (int i = 0; i < jsonArray.length(); i++) { - JSONObject sgvJson = jsonArray.getJSONObject(i); - NSSgv nsSgv = new NSSgv(sgvJson); - BgReading bgReading = new BgReading(nsSgv); - MainApp.getDbHelper().createIfNotExists(bgReading, "NS"); - } - } - } catch (Exception e) { - log.error("Unhandled exception", e); - } - } - - if (intent.getAction().equals(Intents.ACTION_NEW_MBG)) { - try { - if (bundles.containsKey("mbg")) { - String mbgstring = bundles.getString("mbg"); - JSONObject mbgJson = new JSONObject(mbgstring); - NSMbg nsMbg = new NSMbg(mbgJson); - CareportalEvent careportalEvent = new CareportalEvent(nsMbg); - MainApp.getDbHelper().createOrUpdate(careportalEvent); - if (Config.logIncommingData) - log.debug("Adding/Updating new MBG: " + careportalEvent.log()); - } - - if (bundles.containsKey("mbgs")) { - String sgvstring = bundles.getString("mbgs"); - JSONArray jsonArray = new JSONArray(sgvstring); - for (int i = 0; i < jsonArray.length(); i++) { - JSONObject mbgJson = jsonArray.getJSONObject(i); - NSMbg nsMbg = new NSMbg(mbgJson); - CareportalEvent careportalEvent = new CareportalEvent(nsMbg); - MainApp.getDbHelper().createOrUpdate(careportalEvent); - if (Config.logIncommingData) - log.debug("Adding/Updating new MBG: " + careportalEvent.log()); - } - } - } catch (Exception e) { - log.error("Unhandled exception", e); - } - } - - if (intent.getAction().equals(Intents.ACTION_NEW_FOOD) - || intent.getAction().equals(Intents.ACTION_CHANGED_FOOD)) { - int mode = Intents.ACTION_NEW_FOOD.equals(intent.getAction()) ? EventNsFood.ADD : EventNsFood.UPDATE; - EventNsFood evt = new EventNsFood(mode, bundles); - MainApp.bus().post(evt); - } - - if (intent.getAction().equals(Intents.ACTION_REMOVED_FOOD)) { - EventNsFood evt = new EventNsFood(EventNsFood.REMOVE, bundles); - MainApp.bus().post(evt); - } - } - - private void handleTreatmentFromNS(JSONObject json) { - // new DB model - EventNsTreatment evtTreatment = new EventNsTreatment(EventNsTreatment.REMOVE, json); - MainApp.bus().post(evtTreatment); - // old DB model - String _id = JsonHelper.safeGetString(json, "_id"); - MainApp.getDbHelper().deleteTempTargetById(_id); - MainApp.getDbHelper().deleteTempBasalById(_id); - MainApp.getDbHelper().deleteExtendedBolusById(_id); - MainApp.getDbHelper().deleteCareportalEventById(_id); - MainApp.getDbHelper().deleteProfileSwitchById(_id); - } - - private void handleTreatmentFromNS(JSONObject json, Intent intent) throws JSONException { - // new DB model - int mode = Intents.ACTION_NEW_TREATMENT.equals(intent.getAction()) ? EventNsTreatment.ADD : EventNsTreatment.UPDATE; - double insulin = JsonHelper.safeGetDouble(json, "insulin"); - double carbs = JsonHelper.safeGetDouble(json, "carbs"); - String eventType = JsonHelper.safeGetString(json, "eventType"); - if (insulin > 0 || carbs > 0) { - EventNsTreatment evtTreatment = new EventNsTreatment(mode, json); - MainApp.bus().post(evtTreatment); - } else if (json.has(DanaRNSHistorySync.DANARSIGNATURE)) { - // old DB model - MainApp.getDbHelper().updateDanaRHistoryRecordId(json); - } else if (eventType.equals(CareportalEvent.TEMPORARYTARGET)) { - MainApp.getDbHelper().createTemptargetFromJsonIfNotExists(json); - } else if (eventType.equals(CareportalEvent.TEMPBASAL)) { - MainApp.getDbHelper().createTempBasalFromJsonIfNotExists(json); - } else if (eventType.equals(CareportalEvent.COMBOBOLUS)) { - MainApp.getDbHelper().createExtendedBolusFromJsonIfNotExists(json); - } else if (eventType.equals(CareportalEvent.PROFILESWITCH)) { - MainApp.getDbHelper().createProfileSwitchFromJsonIfNotExists(json); - } else if (eventType.equals(CareportalEvent.SITECHANGE) || - eventType.equals(CareportalEvent.INSULINCHANGE) || - eventType.equals(CareportalEvent.SENSORCHANGE) || - eventType.equals(CareportalEvent.BGCHECK) || - eventType.equals(CareportalEvent.NOTE) || - eventType.equals(CareportalEvent.NONE) || - eventType.equals(CareportalEvent.ANNOUNCEMENT) || - eventType.equals(CareportalEvent.QUESTION) || - eventType.equals(CareportalEvent.EXERCISE) || - eventType.equals(CareportalEvent.OPENAPSOFFLINE) || - eventType.equals(CareportalEvent.PUMPBATTERYCHANGE)) { - MainApp.getDbHelper().createCareportalEventFromJsonIfNotExists(json); - } - - if (eventType.equals(CareportalEvent.ANNOUNCEMENT)) { - long date = JsonHelper.safeGetLong(json,"mills"); - long now = System.currentTimeMillis(); - String enteredBy = JsonHelper.safeGetString(json, "enteredBy", ""); - String notes = JsonHelper.safeGetString(json, "notes", ""); - if (date > now - 15 * 60 * 1000L && !notes.isEmpty() - && !enteredBy.equals(SP.getString("careportal_enteredby", "AndroidAPS"))) { - Notification announcement = new Notification(Notification.NSANNOUNCEMENT, notes, Notification.ANNOUNCEMENT, 60); - MainApp.bus().post(new EventNewNotification(announcement)); - } - } - } - - private void handleNewSMS(Intent intent) { - Bundle bundle = intent.getExtras(); - if (bundle == null) return; - MainApp.bus().post(new EventNewSMS(bundle)); - } - -} diff --git a/app/src/main/java/info/nightscout/androidaps/AgreementActivity.java b/app/src/main/java/info/nightscout/androidaps/activities/AgreementActivity.java similarity index 91% rename from app/src/main/java/info/nightscout/androidaps/AgreementActivity.java rename to app/src/main/java/info/nightscout/androidaps/activities/AgreementActivity.java index 3a30659884..582b10d57d 100644 --- a/app/src/main/java/info/nightscout/androidaps/AgreementActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/activities/AgreementActivity.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps; +package info.nightscout.androidaps.activities; import android.app.Activity; import android.content.Intent; @@ -9,6 +9,8 @@ import android.view.View; import android.widget.Button; import android.widget.CheckBox; +import info.nightscout.androidaps.MainActivity; +import info.nightscout.androidaps.R; import info.nightscout.utils.SP; public class AgreementActivity extends Activity { diff --git a/app/src/main/java/info/nightscout/androidaps/activities/HistoryBrowseActivity.java b/app/src/main/java/info/nightscout/androidaps/activities/HistoryBrowseActivity.java new file mode 100644 index 0000000000..7303eb9d97 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/activities/HistoryBrowseActivity.java @@ -0,0 +1,435 @@ +package info.nightscout.androidaps.activities; + +import android.os.Bundle; +import android.os.SystemClock; +import android.support.v4.content.res.ResourcesCompat; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.PopupMenu; +import android.text.SpannableString; +import android.text.style.ForegroundColorSpan; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.Button; +import android.widget.ImageButton; +import android.widget.SeekBar; +import android.widget.TextView; + +import com.jjoe64.graphview.GraphView; +import com.squareup.otto.Subscribe; +import com.wdullaer.materialdatetimepicker.date.DatePickerDialog; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Calendar; +import java.util.Date; + +import butterknife.BindView; +import butterknife.ButterKnife; +import butterknife.OnClick; +import butterknife.OnLongClick; +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.data.Profile; +import info.nightscout.androidaps.events.EventCustomCalculationFinished; +import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; +import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin; +import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished; +import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventIobCalculationProgress; +import info.nightscout.androidaps.plugins.Overview.OverviewFragment; +import info.nightscout.androidaps.plugins.Overview.OverviewPlugin; +import info.nightscout.androidaps.plugins.Overview.graphData.GraphData; +import info.nightscout.utils.DateUtil; +import info.nightscout.utils.T; + +public class HistoryBrowseActivity extends AppCompatActivity { + private static Logger log = LoggerFactory.getLogger(HistoryBrowseActivity.class); + + + ImageButton chartButton; + + boolean showBasal = true; + boolean showIob, showCob, showDev, showRat, showDevslope; + + + @BindView(R.id.historybrowse_date) + Button buttonDate; + @BindView(R.id.historybrowse_zoom) + Button buttonZoom; + @BindView(R.id.historyybrowse_bggraph) + GraphView bgGraph; + @BindView(R.id.historybrowse_iobgraph) + GraphView iobGraph; + @BindView(R.id.historybrowse_seekBar) + SeekBar seekBar; + @BindView(R.id.historybrowse_noprofile) + TextView noProfile; + @BindView(R.id.overview_iobcalculationprogess) + TextView iobCalculationProgressView; + + private int rangeToDisplay = 24; // for graph + private long start = 0; + + IobCobCalculatorPlugin iobCobCalculatorPlugin; + + EventCustomCalculationFinished eventCustomCalculationFinished = new EventCustomCalculationFinished(); + + public HistoryBrowseActivity() { + iobCobCalculatorPlugin = new IobCobCalculatorPlugin(); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_historybrowse); + + ButterKnife.bind(this); + + bgGraph.getGridLabelRenderer().setGridColor(MainApp.gc(R.color.graphgrid)); + bgGraph.getGridLabelRenderer().reloadStyles(); + iobGraph.getGridLabelRenderer().setGridColor(MainApp.gc(R.color.graphgrid)); + iobGraph.getGridLabelRenderer().reloadStyles(); + iobGraph.getGridLabelRenderer().setHorizontalLabelsVisible(false); + bgGraph.getGridLabelRenderer().setLabelVerticalWidth(50); + iobGraph.getGridLabelRenderer().setLabelVerticalWidth(50); + iobGraph.getGridLabelRenderer().setNumVerticalLabels(5); + + setupChartMenu(); + } + + @Override + public void onPause() { + super.onPause(); + MainApp.bus().unregister(this); + iobCobCalculatorPlugin.stopCalculation("onPause"); + } + + @Override + public void onResume() { + super.onResume(); + MainApp.bus().register(this); + // set start of current day + Calendar calendar = Calendar.getInstance(); + calendar.setTimeInMillis(System.currentTimeMillis()); + calendar.set(Calendar.MILLISECOND, 0); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.HOUR_OF_DAY, 0); + start = calendar.getTimeInMillis(); + runCalculation("onResume"); + SystemClock.sleep(1000); + updateGUI("onResume"); + } + + @OnClick(R.id.historybrowse_left) + void onClickLeft() { + start -= T.hours(rangeToDisplay).msecs(); + updateGUI("onClickLeft"); + runCalculation("onClickLeft"); + } + + @OnClick(R.id.historybrowse_right) + void onClickRight() { + start += T.hours(rangeToDisplay).msecs(); + updateGUI("onClickRight"); + runCalculation("onClickRight"); + } + + @OnClick(R.id.historybrowse_end) + void onClickEnd() { + Calendar calendar = Calendar.getInstance(); + calendar.setTimeInMillis(System.currentTimeMillis()); + calendar.set(Calendar.MILLISECOND, 0); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.HOUR_OF_DAY, 0); + start = calendar.getTimeInMillis(); + updateGUI("onClickEnd"); + runCalculation("onClickEnd"); + } + + @OnClick(R.id.historybrowse_zoom) + void onClickZoom() { + rangeToDisplay += 6; + rangeToDisplay = rangeToDisplay > 24 ? 6 : rangeToDisplay; + updateGUI("rangeChange"); + } + + @OnLongClick(R.id.historybrowse_zoom) + boolean onLongClickZoom() { + Calendar calendar = Calendar.getInstance(); + calendar.setTimeInMillis(start); + calendar.set(Calendar.MILLISECOND, 0); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.HOUR_OF_DAY, 0); + start = calendar.getTimeInMillis(); + updateGUI("resetToMidnight"); + runCalculation("onLongClickZoom"); + return true; + } + + @OnClick(R.id.historybrowse_date) + void onClickDate() { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(new Date(start)); + DatePickerDialog dpd = DatePickerDialog.newInstance( + (view, year, monthOfYear, dayOfMonth) -> { + Date date = new Date(0); + date.setYear(year - 1900); + date.setMonth(monthOfYear); + date.setDate(dayOfMonth); + date.setHours(0); + start = date.getTime(); + updateGUI("onClickDate"); + runCalculation("onClickDate"); + }, + calendar.get(Calendar.YEAR), + calendar.get(Calendar.MONTH), + calendar.get(Calendar.DAY_OF_MONTH) + ); + dpd.setThemeDark(true); + dpd.dismissOnPause(true); + dpd.show(getFragmentManager(), "Datepickerdialog"); + } + + private void runCalculation(String from) { + long end = start + T.hours(rangeToDisplay).msecs(); + iobCobCalculatorPlugin.stopCalculation(from); + iobCobCalculatorPlugin.clearCache(); + iobCobCalculatorPlugin.runCalculation(from, end, true, false, eventCustomCalculationFinished); + } + + @Subscribe + public void onStatusEvent(final EventAutosensCalculationFinished e) { + if (e.cause == eventCustomCalculationFinished) { + log.debug("EventAutosensCalculationFinished"); + runOnUiThread(() -> { + synchronized (HistoryBrowseActivity.this) { + updateGUI("EventAutosensCalculationFinished"); + } + }); + } + } + + @Subscribe + public void onStatusEvent(final EventIobCalculationProgress e) { + runOnUiThread(() -> { + if (iobCalculationProgressView != null) + iobCalculationProgressView.setText(e.progress); + }); + } + + void updateGUI(String from) { + log.debug("updateGUI from: " + from); + + if (noProfile == null || buttonDate == null || buttonZoom == null || bgGraph == null || iobGraph == null || seekBar == null) + return; + + final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); + final Profile profile = ProfileFunctions.getInstance().getProfile(); + + if (profile == null) { + noProfile.setVisibility(View.VISIBLE); + return; + } else { + noProfile.setVisibility(View.GONE); + } + + final String units = profile.getUnits(); + final double lowLine = OverviewPlugin.getPlugin().determineLowLine(units); + final double highLine = OverviewPlugin.getPlugin().determineHighLine(units); + + buttonDate.setText(DateUtil.dateAndTimeString(start)); + buttonZoom.setText(String.valueOf(rangeToDisplay)); + + final boolean showPrediction = false; + + int hoursToFetch; + final long toTime; + final long fromTime; + //if (showPrediction) { + //int predHours = (int) (Math.ceil(((DetermineBasalResultAMA) finalLastRun.constraintsProcessed).getLatestPredictionsTime() - System.currentTimeMillis()) / (60 * 60 * 1000)); + //predHours = Math.min(2, predHours); + //predHours = Math.max(0, predHours); + //hoursToFetch = rangeToDisplay - predHours; + //toTime = calendar.getTimeInMillis() + 100000; // little bit more to avoid wrong rounding - Graphview specific + //fromTime = toTime - hoursToFetch * 60 * 60 * 1000L; + //endTime = toTime + predHours * 60 * 60 * 1000L; + //} else { + fromTime = start + T.secs(100).msecs(); + toTime = start + T.hours(rangeToDisplay).msecs(); + //} + + log.debug("Period: " + DateUtil.dateAndTimeString(fromTime) + " - " + DateUtil.dateAndTimeString(toTime)); + + final long pointer = System.currentTimeMillis(); + + // ------------------ 1st graph + + final GraphData graphData = new GraphData(bgGraph, iobCobCalculatorPlugin); + + // **** In range Area **** + graphData.addInRangeArea(fromTime, toTime, lowLine, highLine); + + // **** BG **** + if (showPrediction) +//graphData.addBgReadings(fromTime, toTime, lowLine, highLine, (DetermineBasalResultAMA) finalLastRun.constraintsProcessed); + ; + else + graphData.addBgReadings(fromTime, toTime, lowLine, highLine, null); + + // set manual x bounds to have nice steps + graphData.formatAxis(fromTime, toTime); + + // Treatments + graphData.addTreatments(fromTime, toTime); + + // add basal data + if (pump.getPumpDescription().isTempBasalCapable && showBasal) { + graphData.addBasals(fromTime, toTime, lowLine / graphData.maxY / 1.2d); + } + + // **** NOW line **** + graphData.addNowLine(pointer); + + // ------------------ 2nd graph + + new Thread(() -> { + final GraphData secondGraphData = new GraphData(iobGraph, iobCobCalculatorPlugin); + + boolean useIobForScale = false; + boolean useCobForScale = false; + boolean useDevForScale = false; + boolean useRatioForScale = false; + boolean useDSForScale = false; + + if (showIob) { + useIobForScale = true; + } else if (showCob) { + useCobForScale = true; + } else if (showDev) { + useDevForScale = true; + } else if (showRat) { + useRatioForScale = true; + } else if (showDevslope) { + useDSForScale = true; + } + + if (showIob) + secondGraphData.addIob(fromTime, toTime, useIobForScale, 1d); + if (showCob) + secondGraphData.addCob(fromTime, toTime, useCobForScale, useCobForScale ? 1d : 0.5d); + if (showDev) + secondGraphData.addDeviations(fromTime, toTime, useDevForScale, 1d); + if (showRat) + secondGraphData.addRatio(fromTime, toTime, useRatioForScale, 1d); + if (showDevslope) + secondGraphData.addDeviationSlope(fromTime, toTime, useDSForScale, 1d); + + // **** NOW line **** + // set manual x bounds to have nice steps + secondGraphData.formatAxis(fromTime, toTime); + secondGraphData.addNowLine(pointer); + + // do GUI update + runOnUiThread(() -> { + if (showIob || showCob || showDev || showRat || showDevslope) { + iobGraph.setVisibility(View.VISIBLE); + } else { + iobGraph.setVisibility(View.GONE); + } + // finally enforce drawing of graphs + graphData.performUpdate(); + if (showIob || showCob || showDev || showRat || showDevslope) + secondGraphData.performUpdate(); + }); + }).start(); + } + + private void setupChartMenu() { + chartButton = (ImageButton) findViewById(R.id.overview_chartMenuButton); + chartButton.setOnClickListener(v -> { + MenuItem item; + CharSequence title; + SpannableString s; + PopupMenu popup = new PopupMenu(v.getContext(), v); + + + item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.BAS.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_basals)); + title = item.getTitle(); + s = new SpannableString(title); + s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.basal, null)), 0, s.length(), 0); + item.setTitle(s); + item.setCheckable(true); + item.setChecked(showBasal); + + item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.IOB.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_iob)); + title = item.getTitle(); + s = new SpannableString(title); + s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.iob, null)), 0, s.length(), 0); + item.setTitle(s); + item.setCheckable(true); + item.setChecked(showIob); + + item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.COB.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_cob)); + title = item.getTitle(); + s = new SpannableString(title); + s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.cob, null)), 0, s.length(), 0); + item.setTitle(s); + item.setCheckable(true); + item.setChecked(showCob); + + item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.DEV.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_deviations)); + title = item.getTitle(); + s = new SpannableString(title); + s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.deviations, null)), 0, s.length(), 0); + item.setTitle(s); + item.setCheckable(true); + item.setChecked(showDev); + + item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.SEN.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_sensitivity)); + title = item.getTitle(); + s = new SpannableString(title); + s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.ratio, null)), 0, s.length(), 0); + item.setTitle(s); + item.setCheckable(true); + item.setChecked(showRat); + + if (MainApp.devBranch) { + item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.DEVSLOPE.ordinal(), Menu.NONE, "Deviation slope"); + title = item.getTitle(); + s = new SpannableString(title); + s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.devslopepos, null)), 0, s.length(), 0); + item.setTitle(s); + item.setCheckable(true); + item.setChecked(showDevslope); + } + + popup.setOnMenuItemClickListener(item1 -> { + if (item1.getItemId() == OverviewFragment.CHARTTYPE.BAS.ordinal()) { + showBasal = !item1.isChecked(); + } else if (item1.getItemId() == OverviewFragment.CHARTTYPE.IOB.ordinal()) { + showIob = !item1.isChecked(); + } else if (item1.getItemId() == OverviewFragment.CHARTTYPE.COB.ordinal()) { + showCob = !item1.isChecked(); + } else if (item1.getItemId() == OverviewFragment.CHARTTYPE.DEV.ordinal()) { + showDev = !item1.isChecked(); + } else if (item1.getItemId() == OverviewFragment.CHARTTYPE.SEN.ordinal()) { + showRat = !item1.isChecked(); + } else if (item1.getItemId() == OverviewFragment.CHARTTYPE.DEVSLOPE.ordinal()) { + showDevslope = !item1.isChecked(); + } + updateGUI("onGraphCheckboxesCheckedChanged"); + return true; + }); + chartButton.setImageResource(R.drawable.ic_arrow_drop_up_white_24dp); + popup.setOnDismissListener(menu -> chartButton.setImageResource(R.drawable.ic_arrow_drop_down_white_24dp)); + popup.show(); + }); + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/PreferencesActivity.java b/app/src/main/java/info/nightscout/androidaps/activities/PreferencesActivity.java similarity index 91% rename from app/src/main/java/info/nightscout/androidaps/PreferencesActivity.java rename to app/src/main/java/info/nightscout/androidaps/activities/PreferencesActivity.java index 014dfcd863..10a9487da0 100644 --- a/app/src/main/java/info/nightscout/androidaps/PreferencesActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/activities/PreferencesActivity.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps; +package info.nightscout.androidaps.activities; import android.content.SharedPreferences; import android.os.Bundle; @@ -11,6 +11,9 @@ import android.preference.PreferenceGroup; import android.preference.PreferenceManager; import android.text.TextUtils; +import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; import info.nightscout.androidaps.events.EventPreferenceChange; import info.nightscout.androidaps.events.EventRefreshGui; import info.nightscout.androidaps.interfaces.PluginBase; @@ -30,9 +33,10 @@ import info.nightscout.androidaps.plugins.PumpDanaRS.DanaRSPlugin; import info.nightscout.androidaps.plugins.PumpDanaRv2.DanaRv2Plugin; import info.nightscout.androidaps.plugins.PumpInsight.InsightPlugin; import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin; -import info.nightscout.androidaps.plugins.SensitivityAAPS.SensitivityAAPSPlugin; -import info.nightscout.androidaps.plugins.SensitivityOref0.SensitivityOref0Plugin; -import info.nightscout.androidaps.plugins.SensitivityWeightedAverage.SensitivityWeightedAveragePlugin; +import info.nightscout.androidaps.plugins.Sensitivity.SensitivityAAPSPlugin; +import info.nightscout.androidaps.plugins.Sensitivity.SensitivityOref0Plugin; +import info.nightscout.androidaps.plugins.Sensitivity.SensitivityOref1Plugin; +import info.nightscout.androidaps.plugins.Sensitivity.SensitivityWeightedAveragePlugin; import info.nightscout.androidaps.plugins.SmsCommunicator.SmsCommunicatorPlugin; import info.nightscout.androidaps.plugins.Source.SourceDexcomG5Plugin; import info.nightscout.androidaps.plugins.Wear.WearPlugin; @@ -85,7 +89,7 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre pref.setSummary("******"); } else if (pref.getKey().equals(MainApp.gs(R.string.key_danars_name))) { pref.setSummary(SP.getString(R.string.key_danars_name, "")); - } else if (editTextPref.getText() != null && !editTextPref.getText().equals("")) { + } else if (editTextPref.getText() != null) { ((EditTextPreference) pref).setDialogMessage(editTextPref.getDialogMessage()); pref.setSummary(editTextPref.getText()); } else if (pref.getKey().contains("smscommunicator_allowednumbers") && TextUtils.isEmpty(editTextPref.getText().trim())) { @@ -131,7 +135,7 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre addPreferencesFromResource(id); } else { - if (!Config.NSCLIENT && !Config.G5UPLOADER) { + if (!Config.NSCLIENT) { addPreferencesFromResource(R.xml.pref_password); } addPreferencesFromResource(R.xml.pref_age); @@ -152,8 +156,9 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre addPreferencesFromResourceIfEnabled(SensitivityAAPSPlugin.getPlugin(), PluginType.SENSITIVITY); addPreferencesFromResourceIfEnabled(SensitivityWeightedAveragePlugin.getPlugin(), PluginType.SENSITIVITY); addPreferencesFromResourceIfEnabled(SensitivityOref0Plugin.getPlugin(), PluginType.SENSITIVITY); + addPreferencesFromResourceIfEnabled(SensitivityOref1Plugin.getPlugin(), PluginType.SENSITIVITY); - if (Config.HWPUMPS) { + if (Config.PUMPDRIVERS) { addPreferencesFromResourceIfEnabled(DanaRPlugin.getPlugin(), PluginType.PUMP); addPreferencesFromResourceIfEnabled(DanaRKoreanPlugin.getPlugin(), PluginType.PUMP); addPreferencesFromResourceIfEnabled(DanaRv2Plugin.getPlugin(), PluginType.PUMP); @@ -169,7 +174,7 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre } } - if (!Config.NSCLIENT && !Config.G5UPLOADER) { + if (!Config.NSCLIENT) { addPreferencesFromResourceIfEnabled(VirtualPumpPlugin.getPlugin(), PluginType.PUMP); } @@ -178,9 +183,7 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre addPreferencesFromResourceIfEnabled(NSClientPlugin.getPlugin(), PluginType.GENERAL); addPreferencesFromResourceIfEnabled(SmsCommunicatorPlugin.getPlugin(), PluginType.GENERAL); - if (!Config.NSCLIENT && !Config.G5UPLOADER) { - addPreferencesFromResource(R.xml.pref_others); - } + addPreferencesFromResource(R.xml.pref_others); addPreferencesFromResource(R.xml.pref_datachoices); addPreferencesFromResourceIfEnabled(WearPlugin.getPlugin(), PluginType.GENERAL); diff --git a/app/src/main/java/info/nightscout/androidaps/activities/SingleFragmentActivity.java b/app/src/main/java/info/nightscout/androidaps/activities/SingleFragmentActivity.java new file mode 100644 index 0000000000..04fd7a6be7 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/activities/SingleFragmentActivity.java @@ -0,0 +1,60 @@ +package info.nightscout.androidaps.activities; + +import android.content.Intent; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.support.v7.app.AppCompatActivity; +import android.view.Menu; +import android.view.MenuItem; + +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.activities.PreferencesActivity; +import info.nightscout.androidaps.interfaces.PluginBase; +import info.nightscout.utils.PasswordProtection; + +public class SingleFragmentActivity extends AppCompatActivity { + + private PluginBase plugin; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_single_fragment); + + this.plugin = MainApp.getPluginsList().get(getIntent().getIntExtra("plugin", -1)); + setTitle(plugin.getName()); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + + if (savedInstanceState == null) { + getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout, + Fragment.instantiate(this, plugin.pluginDescription.getFragmentClass())).commit(); + } + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + return true; + } + else if (item.getItemId() == R.id.nav_plugin_preferences) { + PasswordProtection.QueryPassword(this, R.string.settings_password, "settings_password", () -> { + Intent i = new Intent(this, PreferencesActivity.class); + i.putExtra("id", plugin.getPreferencesId()); + startActivity(i); + }, null); + return true; + } + return false; + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + if (plugin.getPreferencesId() != -1) + getMenuInflater().inflate(R.menu.menu_single_fragment, menu); + return super.onCreateOptionsMenu(menu); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/TDDStatsActivity.java b/app/src/main/java/info/nightscout/androidaps/activities/TDDStatsActivity.java similarity index 97% rename from app/src/main/java/info/nightscout/androidaps/TDDStatsActivity.java rename to app/src/main/java/info/nightscout/androidaps/activities/TDDStatsActivity.java index 7bc3ee31c5..b46faec980 100644 --- a/app/src/main/java/info/nightscout/androidaps/TDDStatsActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/activities/TDDStatsActivity.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps; +package info.nightscout.androidaps.activities; import android.app.Activity; import android.graphics.Color; @@ -33,14 +33,15 @@ import java.util.Date; import java.util.LinkedList; import java.util.List; +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.Profile; -import info.nightscout.androidaps.db.DanaRHistoryRecord; import info.nightscout.androidaps.db.TDD; import info.nightscout.androidaps.events.EventPumpStatusChanged; import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPlugin; -import info.nightscout.androidaps.plugins.PumpDanaR.comm.RecordTypes; import info.nightscout.androidaps.plugins.PumpDanaR.events.EventDanaRSyncStatus; import info.nightscout.androidaps.plugins.PumpDanaRKorean.DanaRKoreanPlugin; import info.nightscout.androidaps.plugins.PumpDanaRS.DanaRSPlugin; @@ -121,7 +122,7 @@ public class TDDStatsActivity extends Activity { TBB = SP.getString("TBB", "10.00"); - Profile profile = MainApp.getConfigBuilder().getProfile(); + Profile profile = ProfileFunctions.getInstance().getProfile(); if (profile != null) { double cppTBB = profile.baseBasalSum(); TBB = decimalFormat.format(cppTBB); @@ -129,7 +130,7 @@ public class TDDStatsActivity extends Activity { } totalBaseBasal.setText(TBB); - if (!ConfigBuilderPlugin.getActivePump().getPumpDescription().needsManualTDDLoad) + if (!ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().needsManualTDDLoad) reloadButton.setVisibility(View.GONE); // stats table @@ -238,7 +239,7 @@ public class TDDStatsActivity extends Activity { statsMessage.setText(MainApp.gs(R.string.danar_stats_warning_Message)); } }); - ConfigBuilderPlugin.getCommandQueue().loadTDDs( new Callback() { + ConfigBuilderPlugin.getPlugin().getCommandQueue().loadTDDs( new Callback() { @Override public void run() { loadDataFromDB(); @@ -439,7 +440,7 @@ public class TDDStatsActivity extends Activity { TableLayout.LayoutParams.WRAP_CONTENT)); } - if (isOldData(historyList) && ConfigBuilderPlugin.getActivePump().getPumpDescription().needsManualTDDLoad) { + if (isOldData(historyList) && ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().needsManualTDDLoad) { statsMessage.setVisibility(View.VISIBLE); statsMessage.setText(MainApp.gs(R.string.danar_stats_olddata_Message)); @@ -544,7 +545,7 @@ public class TDDStatsActivity extends Activity { public static boolean isOldData(List historyList) { - Object activePump = MainApp.getConfigBuilder().getActivePump(); + Object activePump = ConfigBuilderPlugin.getPlugin().getActivePump(); PumpInterface dana = MainApp.getSpecificPlugin(DanaRPlugin.class); PumpInterface danaRS = MainApp.getSpecificPlugin(DanaRSPlugin.class); PumpInterface danaV2 = MainApp.getSpecificPlugin(DanaRv2Plugin.class); diff --git a/app/src/main/java/info/nightscout/androidaps/data/ConstraintChecker.java b/app/src/main/java/info/nightscout/androidaps/data/ConstraintChecker.java index 3161cb19f3..ceb85c6967 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/ConstraintChecker.java +++ b/app/src/main/java/info/nightscout/androidaps/data/ConstraintChecker.java @@ -4,12 +4,10 @@ import java.util.ArrayList; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.interfaces.BgSourceInterface; import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.ConstraintsInterface; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginType; -import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; /** * Created by mike on 19.03.2018. @@ -25,7 +23,7 @@ public class ConstraintChecker implements ConstraintsInterface { public Constraint isLoopInvokationAllowed() { - return isLoopInvokationAllowed(new Constraint<>(true)); + return isLoopInvocationAllowed(new Constraint<>(true)); } public Constraint isClosedLoopAllowed() { @@ -44,6 +42,10 @@ public class ConstraintChecker implements ConstraintsInterface { return isSMBModeEnabled(new Constraint<>(true)); } + public Constraint isUAMEnabled() { + return isUAMEnabled(new Constraint<>(true)); + } + public Constraint isAdvancedFilteringEnabled() { return isAdvancedFilteringEnabled(new Constraint<>(true)); } @@ -60,6 +62,10 @@ public class ConstraintChecker implements ConstraintsInterface { return applyBolusConstraints(new Constraint<>(Constants.REALLYHIGHBOLUS)); } + public Constraint getMaxExtendedBolusAllowed() { + return applyExtendedBolusConstraints(new Constraint<>(Constants.REALLYHIGHBOLUS)); + } + public Constraint getMaxCarbsAllowed() { return applyCarbsConstraints(new Constraint<>(Constants.REALLYHIGHCARBS)); } @@ -69,13 +75,13 @@ public class ConstraintChecker implements ConstraintsInterface { } @Override - public Constraint isLoopInvokationAllowed(Constraint value) { + public Constraint isLoopInvocationAllowed(Constraint value) { ArrayList constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); for (PluginBase p : constraintsPlugins) { ConstraintsInterface constraint = (ConstraintsInterface) p; if (!p.isEnabled(PluginType.CONSTRAINTS)) continue; - constraint.isLoopInvokationAllowed(value); + constraint.isLoopInvocationAllowed(value); } return value; } @@ -128,6 +134,18 @@ public class ConstraintChecker implements ConstraintsInterface { return value; } + @Override + public Constraint isUAMEnabled(Constraint value) { + + ArrayList constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); + for (PluginBase p : constraintsPlugins) { + ConstraintsInterface constraint = (ConstraintsInterface) p; + if (!p.isEnabled(PluginType.CONSTRAINTS)) continue; + constraint.isUAMEnabled(value); + } + return value; + } + @Override public Constraint isAdvancedFilteringEnabled(Constraint value) { ArrayList constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); @@ -172,6 +190,17 @@ public class ConstraintChecker implements ConstraintsInterface { return insulin; } + @Override + public Constraint applyExtendedBolusConstraints(Constraint insulin) { + ArrayList constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); + for (PluginBase p : constraintsPlugins) { + ConstraintsInterface constrain = (ConstraintsInterface) p; + if (!p.isEnabled(PluginType.CONSTRAINTS)) continue; + constrain.applyExtendedBolusConstraints(insulin); + } + return insulin; + } + @Override public Constraint applyCarbsConstraints(Constraint carbs) { ArrayList constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); diff --git a/app/src/main/java/info/nightscout/androidaps/data/DetailedBolusInfo.java b/app/src/main/java/info/nightscout/androidaps/data/DetailedBolusInfo.java index c2f9d16dc3..51a1e18685 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/DetailedBolusInfo.java +++ b/app/src/main/java/info/nightscout/androidaps/data/DetailedBolusInfo.java @@ -10,6 +10,7 @@ import java.util.Date; import info.nightscout.androidaps.db.CareportalEvent; import info.nightscout.androidaps.db.Source; +import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; /** * Created by mike on 29.05.2017. @@ -17,6 +18,7 @@ import info.nightscout.androidaps.db.Source; public class DetailedBolusInfo { public long date = System.currentTimeMillis(); + public long lastKnownBolusTime; public String eventType = CareportalEvent.MEALBOLUS; public double insulin = 0; public double carbs = 0; @@ -55,6 +57,7 @@ public class DetailedBolusInfo { @Override public String toString() { return new Date(date).toLocaleString() + + " date: " + date + " insulin: " + insulin + " carbs: " + carbs + " isValid: " + isValid + diff --git a/app/src/main/java/info/nightscout/androidaps/data/Profile.java b/app/src/main/java/info/nightscout/androidaps/data/Profile.java index 374612f2f5..0595c2f84d 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/Profile.java +++ b/app/src/main/java/info/nightscout/androidaps/data/Profile.java @@ -12,17 +12,18 @@ import java.text.DecimalFormat; import java.util.Calendar; import java.util.TimeZone; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.interfaces.PumpDescription; import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.Overview.notifications.Notification; import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.FabricPrivacy; +import info.nightscout.utils.MidnightTime; public class Profile { private static Logger log = LoggerFactory.getLogger(Profile.class); @@ -52,6 +53,14 @@ public class Profile { protected Profile() { } + @Override + public String toString() { + if (json != null) + return json.toString(); + else + return "Profile has no JSON"; + } + // Constructor from profileStore JSON public Profile(JSONObject json, String units) { init(json, 100, 0); @@ -202,12 +211,18 @@ public class Profile { if (targetHigh_v == null) targetHigh_v = convertToSparseArray(targetHigh); validate(targetHigh_v); + + if (targetHigh_v.size() != targetLow_v.size()) isValid = false; + else for (int i = 0; i < targetHigh_v.size(); i++) + if (targetHigh_v.valueAt(i) < targetLow_v.valueAt(i)) + isValid = false; + isValidated = true; } if (isValid) { // Check for hours alignment - PumpInterface pump = MainApp.getConfigBuilder().getActivePump(); + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); if (pump != null && !pump.getPumpDescription().is30minBasalRatesCapable) { for (int index = 0; index < basal_v.size(); index++) { long secondsFromMidnight = basal_v.keyAt(index); @@ -226,6 +241,10 @@ public class Profile { basal_v.setValueAt(i, description.basalMinimumRate); if (notify) sendBelowMinimumNotification(from); + } else if (basal_v.valueAt(i) > description.basalMaximumRate) { + basal_v.setValueAt(i, description.basalMaximumRate); + if (notify) + sendAboveMaximumNotification(from); } } } else { @@ -235,12 +254,16 @@ public class Profile { isValidated = false; } - } + } return isValid; } protected void sendBelowMinimumNotification(String from) { - MainApp.bus().post(new EventNewNotification(new Notification(Notification.MINIMAL_BASAL_VALUE_REPLACED, String.format(MainApp.gs(R.string.minimalbasalvaluereplaced), from), Notification.NORMAL))); + MainApp.bus().post(new EventNewNotification(new Notification(Notification.MINIMAL_BASAL_VALUE_REPLACED, String.format(MainApp.gs(R.string.minimalbasalvaluereplaced), from), Notification.NORMAL))); + } + + protected void sendAboveMaximumNotification(String from) { + MainApp.bus().post(new EventNewNotification(new Notification(Notification.MAXIMUM_BASAL_VALUE_REPLACED, String.format(MainApp.gs(R.string.maximumbasalvaluereplaced), from), Notification.NORMAL))); } private void validate(LongSparseArray array) { @@ -281,8 +304,6 @@ public class Profile { Integer getShitfTimeSecs(Integer originalTime) { Integer shiftedTime = originalTime + timeshift * 60 * 60; shiftedTime = (shiftedTime + 24 * 60 * 60) % (24 * 60 * 60); - if (timeshift != 0 && Config.logProfile) - log.debug("(Sec) Original time: " + originalTime + " ShiftedTime: " + shiftedTime); return shiftedTime; } @@ -361,7 +382,7 @@ public class Profile { } public double getIsf() { - return getIsfTimeFromMidnight(secondsFromMidnight(System.currentTimeMillis())); + return getIsfTimeFromMidnight(secondsFromMidnight()); } public double getIsf(long time) { @@ -381,7 +402,7 @@ public class Profile { } public double getIc() { - return getIcTimeFromMidnight(secondsFromMidnight(System.currentTimeMillis())); + return getIcTimeFromMidnight(secondsFromMidnight()); } public double getIc(long time) { @@ -401,7 +422,7 @@ public class Profile { } public double getBasal() { - return getBasalTimeFromMidnight(secondsFromMidnight(System.currentTimeMillis())); + return getBasalTimeFromMidnight(secondsFromMidnight()); } public double getBasal(long time) { @@ -444,16 +465,16 @@ public class Profile { return ret; } - public double getTarget(){ - return getTarget(secondsFromMidnight(System.currentTimeMillis())); + public double getTarget() { + return getTarget(secondsFromMidnight()); } protected double getTarget(int timeAsSeconds) { - return (getTargetLowTimeFromMidnight(timeAsSeconds) + getTargetHighTimeFromMidnight(timeAsSeconds))/2; + return (getTargetLowTimeFromMidnight(timeAsSeconds) + getTargetHighTimeFromMidnight(timeAsSeconds)) / 2; } public double getTargetLow() { - return getTargetLowTimeFromMidnight(secondsFromMidnight(System.currentTimeMillis())); + return getTargetLowTimeFromMidnight(secondsFromMidnight()); } public double getTargetLow(long time) { @@ -467,7 +488,7 @@ public class Profile { } public double getTargetHigh() { - return getTargetHighTimeFromMidnight(secondsFromMidnight(System.currentTimeMillis())); + return getTargetHighTimeFromMidnight(secondsFromMidnight()); } public double getTargetHigh(long time) { @@ -498,24 +519,13 @@ public class Profile { } public static int secondsFromMidnight() { - Calendar c = Calendar.getInstance(); - long now = c.getTimeInMillis(); - c.set(Calendar.HOUR_OF_DAY, 0); - c.set(Calendar.MINUTE, 0); - c.set(Calendar.SECOND, 0); - c.set(Calendar.MILLISECOND, 0); - long passed = now - c.getTimeInMillis(); + long passed = DateUtil.now() - MidnightTime.calc(); return (int) (passed / 1000); } public static int secondsFromMidnight(long date) { - Calendar c = Calendar.getInstance(); - c.setTimeInMillis(date); - c.set(Calendar.HOUR_OF_DAY, 0); - c.set(Calendar.MINUTE, 0); - c.set(Calendar.SECOND, 0); - c.set(Calendar.MILLISECOND, 0); - long passed = date - c.getTimeInMillis(); + long midnight = MidnightTime.calc(date); + long passed = date - midnight; return (int) (passed / 1000); } @@ -544,6 +554,12 @@ public class Profile { else return DecimalFormatter.to1Decimal(valueInMmol); } + public static String toSignedUnitsString(Double valueInMgdl, Double valueInMmol, String units) { + if (units.equals(Constants.MGDL)) + return (valueInMgdl > 0 ? "+" : "") + DecimalFormatter.to0Decimal(valueInMgdl); + else return (valueInMmol > 0 ? "+" : "") + DecimalFormatter.to1Decimal(valueInMmol); + } + // targets are stored in mg/dl but profile vary public static String toTargetRangeString(double low, double high, String sourceUnits, String units) { double lowMgdl = toMgdl(low, sourceUnits); diff --git a/app/src/main/java/info/nightscout/androidaps/data/PumpEnactResult.java b/app/src/main/java/info/nightscout/androidaps/data/PumpEnactResult.java index eebd42f5d2..404833b77c 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/PumpEnactResult.java +++ b/app/src/main/java/info/nightscout/androidaps/data/PumpEnactResult.java @@ -10,11 +10,12 @@ import org.slf4j.LoggerFactory; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.logging.L; import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.Round; public class PumpEnactResult { - private static Logger log = LoggerFactory.getLogger(PumpEnactResult.class); + private static Logger log = LoggerFactory.getLogger(L.APS); public boolean success = false; // request was processed successfully (but possible no change was needed) public boolean enacted = false; // request was processed successfully and change has been made @@ -107,7 +108,7 @@ public class PumpEnactResult { if (bolusDelivered > 0) { ret += "\n" + MainApp.gs(R.string.enacted) + ": " + enacted; ret += "\n" + MainApp.gs(R.string.comment) + ": " + comment; - ret += "\n" + MainApp.gs(R.string.smb_shortname) + ret += "\n" + MainApp.gs(R.string.configbuilder_insulin) + ": " + bolusDelivered + " " + MainApp.gs(R.string.insulin_unit_shortname); } else if (isTempCancel) { ret += "\n" + MainApp.gs(R.string.enacted) + ": " + enacted; diff --git a/app/src/main/java/info/nightscout/androidaps/db/BgReading.java b/app/src/main/java/info/nightscout/androidaps/db/BgReading.java index 5ddb7a80b2..3b5963b83b 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/BgReading.java +++ b/app/src/main/java/info/nightscout/androidaps/db/BgReading.java @@ -15,6 +15,8 @@ import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.Profile; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.NSClientInternal.data.NSSgv; import info.nightscout.androidaps.plugins.Overview.OverviewPlugin; import info.nightscout.androidaps.plugins.Overview.graphExtensions.DataPointWithLabelInterface; @@ -24,7 +26,7 @@ import info.nightscout.utils.SP; @DatabaseTable(tableName = DatabaseHelper.DATABASE_BGREADINGS) public class BgReading implements DataPointWithLabelInterface { - private static Logger log = LoggerFactory.getLogger(BgReading.class); + private static Logger log = LoggerFactory.getLogger(L.DATABASE); @DatabaseField(id = true) public long date; @@ -142,7 +144,7 @@ public class BgReading implements DataPointWithLabelInterface { return false; if (raw != other.raw) return false; - if (!direction.equals(other.direction)) + if (!Objects.equals(direction, other.direction)) return false; if (!Objects.equals(_id, other._id)) return false; @@ -160,6 +162,21 @@ public class BgReading implements DataPointWithLabelInterface { _id = other._id; } + public BgReading date(long date) { + this.date = date; + return this; + } + + public BgReading date(Date date) { + this.date = date.getTime(); + return this; + } + + public BgReading value(double value) { + this.value = value; + return this; + } + // ------------------ DataPointWithLabelInterface ------------------ @Override public double getX() { @@ -168,7 +185,7 @@ public class BgReading implements DataPointWithLabelInterface { @Override public double getY() { - String units = MainApp.getConfigBuilder().getProfileUnits(); + String units = ProfileFunctions.getInstance().getProfileUnits(); return valueToUnits(units); } @@ -202,15 +219,9 @@ public class BgReading implements DataPointWithLabelInterface { @Override public int getColor() { - String units = MainApp.getConfigBuilder().getProfileUnits(); - Double lowLine = SP.getDouble("low_mark", 0d); - Double highLine = SP.getDouble("high_mark", 0d); - if (lowLine < 1) { - lowLine = Profile.fromMgdlToUnits(OverviewPlugin.bgTargetLow, units); - } - if (highLine < 1) { - highLine = Profile.fromMgdlToUnits(OverviewPlugin.bgTargetHigh, units); - } + String units = ProfileFunctions.getInstance().getProfileUnits(); + Double lowLine = OverviewPlugin.getPlugin().determineLowLine(units); + Double highLine = OverviewPlugin.getPlugin().determineHighLine(units); int color = MainApp.gc(R.color.inrange); if (isPrediction()) return getPredectionColor(); diff --git a/app/src/main/java/info/nightscout/androidaps/db/CareportalEvent.java b/app/src/main/java/info/nightscout/androidaps/db/CareportalEvent.java index d5a1c90100..60c7553cc3 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/CareportalEvent.java +++ b/app/src/main/java/info/nightscout/androidaps/db/CareportalEvent.java @@ -24,16 +24,20 @@ import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.Profile; +import info.nightscout.androidaps.interfaces.Interval; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.NSClientInternal.data.NSMbg; import info.nightscout.androidaps.plugins.Overview.OverviewFragment; import info.nightscout.androidaps.plugins.Overview.graphExtensions.DataPointWithLabelInterface; import info.nightscout.androidaps.plugins.Overview.graphExtensions.PointsWithLabelGraphSeries; import info.nightscout.utils.DateUtil; +import info.nightscout.utils.T; import info.nightscout.utils.Translator; @DatabaseTable(tableName = DatabaseHelper.DATABASE_CAREPORTALEVENTS) -public class CareportalEvent implements DataPointWithLabelInterface { - private static Logger log = LoggerFactory.getLogger(CareportalEvent.class); +public class CareportalEvent implements DataPointWithLabelInterface, Interval { + private static Logger log = LoggerFactory.getLogger(L.DATABASE); @DatabaseField(id = true) public long date; @@ -87,26 +91,23 @@ public class CareportalEvent implements DataPointWithLabelInterface { } public long getHoursFromStart() { - return (System.currentTimeMillis() - date) / (60 * 1000); + return (System.currentTimeMillis() - date) / (60 * 60 * 1000); } public String age() { Map diff = computeDiff(date, System.currentTimeMillis()); if (OverviewFragment.shorttextmode) - return diff.get(TimeUnit.DAYS) +"d" + diff.get(TimeUnit.HOURS) + "h"; + return diff.get(TimeUnit.DAYS) + "d" + diff.get(TimeUnit.HOURS) + "h"; else return diff.get(TimeUnit.DAYS) + " " + MainApp.gs(R.string.days) + " " + diff.get(TimeUnit.HOURS) + " " + MainApp.gs(R.string.hours); } public boolean isOlderThan(double hours) { - Map diff = computeDiff(date, System.currentTimeMillis()); - if(diff.get(TimeUnit.DAYS)*24 + diff.get(TimeUnit.HOURS) > hours) - return true; - else - return false; + return getHoursFromStart() > hours; } - public String log() { + @Override + public String toString() { return "CareportalEvent{" + "date= " + date + ", date= " + DateUtil.dateAndTimeString(date) + @@ -133,6 +134,19 @@ public class CareportalEvent implements DataPointWithLabelInterface { return result; } + + public static boolean isEvent5minBack(List list, long time) { + for (int i = 0; i < list.size(); i++) { + CareportalEvent event = list.get(i); + if (event.date <= time && event.date > (time - T.mins(5).msecs())) { + if (L.isEnabled(L.DATABASE)) + log.debug("Found event for time: " + DateUtil.dateAndTimeFullString(time) + " " + event.toString()); + return true; + } + } + return false; + } + // -------- DataPointWithLabelInterface ------- @Override @@ -144,7 +158,7 @@ public class CareportalEvent implements DataPointWithLabelInterface { @Override public double getY() { - String units = MainApp.getConfigBuilder().getProfileUnits(); + String units = ProfileFunctions.getInstance().getProfileUnits(); if (eventType.equals(MBG)) { double mbg = 0d; try { @@ -213,14 +227,7 @@ public class CareportalEvent implements DataPointWithLabelInterface { @Override public long getDuration() { - try { - JSONObject object = new JSONObject(json); - if (object.has("duration")) - return object.getInt("duration") * 60 * 1000L; - } catch (JSONException e) { - log.error("Unhandled exception", e); - } - return 0; + return end() - start(); } @Override @@ -259,8 +266,79 @@ public class CareportalEvent implements DataPointWithLabelInterface { if (eventType.equals(EXERCISE)) return Color.BLUE; if (eventType.equals(OPENAPSOFFLINE)) - return Color.GRAY; + return Color.GRAY & 0x80FFFFFF; return Color.GRAY; } + // Interval interface + Long cuttedEnd = null; + + @Override + public long durationInMsec() { + try { + JSONObject object = new JSONObject(json); + if (object.has("duration")) + return object.getInt("duration") * 60 * 1000L; + } catch (JSONException e) { + log.error("Unhandled exception", e); + } + return 0; + } + + @Override + public long start() { + return date; + } + + @Override + public long originalEnd() { + return date + durationInMsec(); + } + + @Override + public long end() { + if (cuttedEnd != null) + return cuttedEnd; + return originalEnd(); + } + + @Override + public void cutEndTo(long end) { + cuttedEnd = end; + } + + @Override + public boolean match(long time) { + if (start() <= time && end() >= time) + return true; + return false; + } + + public boolean before(long time) { + if (end() < time) + return true; + return false; + } + + public boolean after(long time) { + if (start() > time) + return true; + return false; + } + + @Override + public boolean isInProgress() { + return match(System.currentTimeMillis()); + } + + @Override + public boolean isEndingEvent() { + return durationInMsec() == 0; + } + + @Override + public boolean isValid() { + return eventType.equals(OPENAPSOFFLINE); + } + } diff --git a/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java b/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java index 7174c19ec4..831e5bcc0d 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java +++ b/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java @@ -27,9 +27,9 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.data.OverlappingIntervals; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.ProfileStore; import info.nightscout.androidaps.events.EventCareportalEventChange; @@ -42,12 +42,16 @@ import info.nightscout.androidaps.events.EventReloadTempBasalData; import info.nightscout.androidaps.events.EventReloadTreatmentData; import info.nightscout.androidaps.events.EventTempBasalChange; import info.nightscout.androidaps.events.EventTempTargetChange; +import info.nightscout.androidaps.interfaces.ProfileInterface; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventNewHistoryData; +import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; import info.nightscout.androidaps.plugins.PumpDanaR.activities.DanaRNSHistorySync; import info.nightscout.androidaps.plugins.PumpDanaR.comm.RecordTypes; import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin; import info.nightscout.utils.JsonHelper; -import info.nightscout.utils.NSUpload; import info.nightscout.utils.PercentageSplitter; import info.nightscout.utils.ToastUtils; @@ -60,7 +64,7 @@ import info.nightscout.utils.ToastUtils; * direct calls to the corresponding methods (eg. resetDatabases) should be done by a central service. */ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { - private static Logger log = LoggerFactory.getLogger(DatabaseHelper.class); + private static Logger log = LoggerFactory.getLogger(L.DATABASE); public static final String DATABASE_NAME = "AndroidAPSDb"; public static final String DATABASE_BGREADINGS = "BgReadings"; @@ -73,7 +77,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { public static final String DATABASE_PROFILESWITCHES = "ProfileSwitches"; public static final String DATABASE_TDDS = "TDDs"; - private static final int DATABASE_VERSION = 8; + private static final int DATABASE_VERSION = 9; public static Long earliestDataChange = null; @@ -107,7 +111,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { @Override public void onCreate(SQLiteDatabase database, ConnectionSource connectionSource) { try { - log.info("onCreate"); + if (L.isEnabled(L.DATABASE)) + log.info("onCreate"); TableUtils.createTableIfNotExists(connectionSource, TempTarget.class); TableUtils.createTableIfNotExists(connectionSource, BgReading.class); TableUtils.createTableIfNotExists(connectionSource, DanaRHistoryRecord.class); @@ -131,6 +136,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { if (oldVersion == 7 && newVersion == 8) { log.debug("Upgrading database from v7 to v8"); + } else if (oldVersion == 8 && newVersion == 9) { + log.debug("Upgrading database from v8 to v9"); } else { log.info(DatabaseHelper.class.getName(), "onUpgrade"); TableUtils.dropTable(connectionSource, TempTarget.class, true); @@ -196,7 +203,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { } catch (SQLException e) { log.error("Unhandled exception", e); } - VirtualPumpPlugin.setFakingStatus(true); + VirtualPumpPlugin.getPlugin().setFakingStatus(true); scheduleBgChange(null); // trigger refresh scheduleTemporaryBasalChange(); scheduleExtendedBolusChange(); @@ -232,7 +239,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { } catch (SQLException e) { log.error("Unhandled exception", e); } - VirtualPumpPlugin.setFakingStatus(false); + VirtualPumpPlugin.getPlugin().setFakingStatus(false); scheduleTemporaryBasalChange(); } @@ -315,7 +322,11 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { } public static long roundDateToSec(long date) { - return date - date % 1000; + long rounded = date - date % 1000; + if (rounded != date) + if (L.isEnabled(L.DATABASE)) + log.debug("Rounding " + date + " to " + rounded); + return rounded; } // ------------------- BgReading handling ----------------------- @@ -325,15 +336,18 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { BgReading old = getDaoBgReadings().queryForId(bgReading.date); if (old == null) { getDaoBgReadings().create(bgReading); - log.debug("BG: New record from: " + from + " " + bgReading.toString()); + if (L.isEnabled(L.DATABASE)) + log.debug("BG: New record from: " + from + " " + bgReading.toString()); scheduleBgChange(bgReading); return true; } if (!old.isEqual(bgReading)) { - log.debug("BG: Similiar found: " + old.toString()); + if (L.isEnabled(L.DATABASE)) + log.debug("BG: Similiar found: " + old.toString()); old.copyFrom(bgReading); getDaoBgReadings().update(old); - log.debug("BG: Updating record from: " + from + " New data: " + old.toString()); + if (L.isEnabled(L.DATABASE)) + log.debug("BG: Updating record from: " + from + " New data: " + old.toString()); scheduleBgChange(bgReading); return false; } @@ -355,7 +369,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { private static void scheduleBgChange(@Nullable final BgReading bgReading) { class PostRunnable implements Runnable { public void run() { - log.debug("Firing EventNewBg"); + if (L.isEnabled(L.DATABASE)) + log.debug("Firing EventNewBg"); MainApp.bus().post(new EventNewBG(bgReading)); scheduledBgPost = null; } @@ -382,12 +397,12 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { QueryBuilder queryBuilder = daoBgReadings.queryBuilder(); queryBuilder.orderBy("date", false); queryBuilder.limit(1L); - queryBuilder.where().gt("value", 38).and().eq("isValid", true); + queryBuilder.where().ge("value", 39).and().eq("isValid", true); PreparedQuery preparedQuery = queryBuilder.prepare(); bgList = daoBgReadings.query(preparedQuery); } catch (SQLException e) { - log.debug(e.getMessage(), e); + log.error("Unhandled exception", e); } if (bgList != null && bgList.size() > 0) return bgList.get(0); @@ -420,7 +435,24 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { QueryBuilder queryBuilder = daoBgreadings.queryBuilder(); queryBuilder.orderBy("date", ascending); Where where = queryBuilder.where(); - where.ge("date", mills).and().gt("value", 38).and().eq("isValid", true); + where.ge("date", mills).and().ge("value", 39).and().eq("isValid", true); + PreparedQuery preparedQuery = queryBuilder.prepare(); + bgReadings = daoBgreadings.query(preparedQuery); + return bgReadings; + } catch (SQLException e) { + log.error("Unhandled exception", e); + } + return new ArrayList(); + } + + public List getBgreadingsDataFromTime(long start, long end, boolean ascending) { + try { + Dao daoBgreadings = getDaoBgReadings(); + List bgReadings; + QueryBuilder queryBuilder = daoBgreadings.queryBuilder(); + queryBuilder.orderBy("date", ascending); + Where where = queryBuilder.where(); + where.between("date", start, end).and().ge("value", 39).and().eq("isValid", true); PreparedQuery preparedQuery = queryBuilder.prepare(); bgReadings = daoBgreadings.query(preparedQuery); return bgReadings; @@ -578,7 +610,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { getDaoTempTargets().delete(old); // need to delete/create because date may change too old.copyFrom(tempTarget); getDaoTempTargets().create(old); - log.debug("TEMPTARGET: Updating record by date from: " + Source.getString(tempTarget.source) + " " + old.toString()); + if (L.isEnabled(L.DATABASE)) + log.debug("TEMPTARGET: Updating record by date from: " + Source.getString(tempTarget.source) + " " + old.toString()); scheduleTemporaryTargetChange(); return true; } @@ -597,20 +630,23 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { getDaoTempTargets().delete(old); // need to delete/create because date may change too old.copyFrom(tempTarget); getDaoTempTargets().create(old); - log.debug("TEMPTARGET: Updating record by _id from: " + Source.getString(tempTarget.source) + " " + old.toString()); + if (L.isEnabled(L.DATABASE)) + log.debug("TEMPTARGET: Updating record by _id from: " + Source.getString(tempTarget.source) + " " + old.toString()); scheduleTemporaryTargetChange(); return true; } } } getDaoTempTargets().create(tempTarget); - log.debug("TEMPTARGET: New record from: " + Source.getString(tempTarget.source) + " " + tempTarget.toString()); + if (L.isEnabled(L.DATABASE)) + log.debug("TEMPTARGET: New record from: " + Source.getString(tempTarget.source) + " " + tempTarget.toString()); scheduleTemporaryTargetChange(); return true; } if (tempTarget.source == Source.USER) { getDaoTempTargets().create(tempTarget); - log.debug("TEMPTARGET: New record from: " + Source.getString(tempTarget.source) + " " + tempTarget.toString()); + if (L.isEnabled(L.DATABASE)) + log.debug("TEMPTARGET: New record from: " + Source.getString(tempTarget.source) + " " + tempTarget.toString()); scheduleTemporaryTargetChange(); return true; } @@ -632,7 +668,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { private static void scheduleTemporaryTargetChange() { class PostRunnable implements Runnable { public void run() { - log.debug("Firing EventTempTargetChange"); + if (L.isEnabled(L.DATABASE)) + log.debug("Firing EventTempTargetChange"); MainApp.bus().post(new EventTempTargetChange()); scheduledTemTargetPost = null; } @@ -664,18 +701,18 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { public void createTemptargetFromJsonIfNotExists(JSONObject trJson) { try { - String units = JsonHelper.safeGetString(trJson, "units", MainApp.getConfigBuilder().getProfileUnits()); + String units = JsonHelper.safeGetString(trJson, "units", Constants.MGDL); TempTarget tempTarget = new TempTarget() .date(trJson.getLong("mills")) .duration(trJson.getInt("duration")) .low(Profile.toMgdl(trJson.getDouble("targetBottom"), units)) .high(Profile.toMgdl(trJson.getDouble("targetTop"), units)) - .reason(trJson.getString("reason")) + .reason(JsonHelper.safeGetString(trJson, "reason", "")) ._id(trJson.getString("_id")) .source(Source.NIGHTSCOUT); createOrUpdate(tempTarget); } catch (JSONException e) { - log.error("Unhandled exception", e); + log.error("Unhandled exception: " + trJson.toString(), e); } } @@ -752,7 +789,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { } else if (list.size() == 1) { DanaRHistoryRecord record = list.get(0); if (record._id == null || !record._id.equals(trJson.getString("_id"))) { - if (Config.logIncommingData) + if (L.isEnabled(L.DATABASE)) log.debug("Updating _id in DanaR history database: " + trJson.getString("_id")); record._id = trJson.getString("_id"); getDaoDanaRHistory().update(record); @@ -761,7 +798,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { } } } catch (SQLException | JSONException e) { - log.error("Unhandled exception", e); + log.error("Unhandled exception: " + trJson.toString(), e); } } @@ -782,11 +819,13 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { List trList = getDaoTemporaryBasal().query(preparedQuery); if (trList.size() > 0) { // do nothing, pump history record cannot be changed - log.debug("TEMPBASAL: Already exists from: " + Source.getString(tempBasal.source) + " " + tempBasal.toString()); + if (L.isEnabled(L.DATABASE)) + log.debug("TEMPBASAL: Already exists from: " + Source.getString(tempBasal.source) + " " + tempBasal.toString()); return false; } getDaoTemporaryBasal().create(tempBasal); - log.debug("TEMPBASAL: New record from: " + Source.getString(tempBasal.source) + " " + tempBasal.toString()); + if (L.isEnabled(L.DATABASE)) + log.debug("TEMPBASAL: New record from: " + Source.getString(tempBasal.source) + " " + tempBasal.toString()); updateEarliestDataChange(tempBasal.date); scheduleTemporaryBasalChange(); return true; @@ -803,7 +842,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { getDaoTemporaryBasal().delete(old); // need to delete/create because date may change too old.copyFrom(tempBasal); getDaoTemporaryBasal().create(old); - log.debug("TEMPBASAL: Updating record by date from: " + Source.getString(tempBasal.source) + " " + old.toString()); + if (L.isEnabled(L.DATABASE)) + log.debug("TEMPBASAL: Updating record by date from: " + Source.getString(tempBasal.source) + " " + old.toString()); updateEarliestDataChange(oldDate); updateEarliestDataChange(old.date); scheduleTemporaryBasalChange(); @@ -825,7 +865,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { getDaoTemporaryBasal().delete(old); // need to delete/create because date may change too old.copyFrom(tempBasal); getDaoTemporaryBasal().create(old); - log.debug("TEMPBASAL: Updating record by _id from: " + Source.getString(tempBasal.source) + " " + old.toString()); + if (L.isEnabled(L.DATABASE)) + log.debug("TEMPBASAL: Updating record by _id from: " + Source.getString(tempBasal.source) + " " + old.toString()); updateEarliestDataChange(oldDate); updateEarliestDataChange(old.date); scheduleTemporaryBasalChange(); @@ -834,14 +875,16 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { } } getDaoTemporaryBasal().create(tempBasal); - log.debug("TEMPBASAL: New record from: " + Source.getString(tempBasal.source) + " " + tempBasal.toString()); + if (L.isEnabled(L.DATABASE)) + log.debug("TEMPBASAL: New record from: " + Source.getString(tempBasal.source) + " " + tempBasal.toString()); updateEarliestDataChange(tempBasal.date); scheduleTemporaryBasalChange(); return true; } if (tempBasal.source == Source.USER) { getDaoTemporaryBasal().create(tempBasal); - log.debug("TEMPBASAL: New record from: " + Source.getString(tempBasal.source) + " " + tempBasal.toString()); + if (L.isEnabled(L.DATABASE)) + log.debug("TEMPBASAL: New record from: " + Source.getString(tempBasal.source) + " " + tempBasal.toString()); updateEarliestDataChange(tempBasal.date); scheduleTemporaryBasalChange(); return true; @@ -881,7 +924,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { private static void scheduleTemporaryBasalChange() { class PostRunnable implements Runnable { public void run() { - log.debug("Firing EventTempBasalChange"); + if (L.isEnabled(L.DATABASE)) + log.debug("Firing EventTempBasalChange"); MainApp.bus().post(new EventReloadTempBasalData()); MainApp.bus().post(new EventTempBasalChange()); if (earliestDataChange != null) @@ -919,15 +963,16 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { public void createTempBasalFromJsonIfNotExists(JSONObject trJson) { try { if (trJson.has("originalExtendedAmount")) { // extended bolus uploaded as temp basal - ExtendedBolus extendedBolus = new ExtendedBolus(); - extendedBolus.source = Source.NIGHTSCOUT; - extendedBolus.date = trJson.getLong("mills"); - extendedBolus.pumpId = trJson.has("pumpId") ? trJson.getLong("pumpId") : 0; - extendedBolus.durationInMinutes = trJson.getInt("duration"); - extendedBolus.insulin = trJson.getDouble("originalExtendedAmount"); - extendedBolus._id = trJson.getString("_id"); - if (!VirtualPumpPlugin.getFakingStatus()) { - VirtualPumpPlugin.setFakingStatus(true); + ExtendedBolus extendedBolus = new ExtendedBolus() + .source(Source.NIGHTSCOUT) + .date(trJson.getLong("mills")) + .pumpId(trJson.has("pumpId") ? trJson.getLong("pumpId") : 0) + .durationInMinutes(trJson.getInt("duration")) + .insulin(trJson.getDouble("originalExtendedAmount")) + ._id(trJson.getString("_id")); + // if faking found in NS, adapt AAPS to use it too + if (!VirtualPumpPlugin.getPlugin().getFakingStatus()) { + VirtualPumpPlugin.getPlugin().setFakingStatus(true); updateEarliestDataChange(0); scheduleTemporaryBasalChange(); } @@ -940,8 +985,9 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { extendedBolus.durationInMinutes = 0; extendedBolus.insulin = 0; extendedBolus._id = trJson.getString("_id"); - if (!VirtualPumpPlugin.getFakingStatus()) { - VirtualPumpPlugin.setFakingStatus(true); + // if faking found in NS, adapt AAPS to use it too + if (!VirtualPumpPlugin.getPlugin().getFakingStatus()) { + VirtualPumpPlugin.getPlugin().setFakingStatus(true); updateEarliestDataChange(0); scheduleTemporaryBasalChange(); } @@ -966,14 +1012,15 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { createOrUpdate(tempBasal); } } catch (JSONException e) { - log.error("Unhandled exception", e); + log.error("Unhandled exception: " + trJson.toString(), e); } } public void deleteTempBasalById(String _id) { TemporaryBasal stored = findTempBasalById(_id); if (stored != null) { - log.debug("TEMPBASAL: Removing TempBasal record from database: " + stored.toString()); + if (L.isEnabled(L.DATABASE)) + log.debug("TEMPBASAL: Removing TempBasal record from database: " + stored.toString()); delete(stored); updateEarliestDataChange(stored.date); scheduleTemporaryBasalChange(); @@ -1004,22 +1051,33 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { public boolean createOrUpdate(ExtendedBolus extendedBolus) { try { + if (L.isEnabled(L.DATABASE)) + log.debug("EXTENDEDBOLUS: createOrUpdate: " + Source.getString(extendedBolus.source) + " " + extendedBolus.log()); + ExtendedBolus old; extendedBolus.date = roundDateToSec(extendedBolus.date); if (extendedBolus.source == Source.PUMP) { - // check for changed from pump change in NS - QueryBuilder queryBuilder = getDaoExtendedBolus().queryBuilder(); - Where where = queryBuilder.where(); - where.eq("pumpId", extendedBolus.pumpId); - PreparedQuery preparedQuery = queryBuilder.prepare(); - List trList = getDaoExtendedBolus().query(preparedQuery); - if (trList.size() > 0) { - // do nothing, pump history record cannot be changed - return false; + // if pumpId == 0 do not check for existing pumpId + // used with pumps without history + // and insight where record as added first without pumpId + // and then is record updated with pumpId + if (extendedBolus.pumpId == 0) { + getDaoExtendedBolus().createOrUpdate(extendedBolus); + } else { + QueryBuilder queryBuilder = getDaoExtendedBolus().queryBuilder(); + Where where = queryBuilder.where(); + where.eq("pumpId", extendedBolus.pumpId); + PreparedQuery preparedQuery = queryBuilder.prepare(); + List 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); - log.debug("EXTENDEDBOLUS: New record from: " + Source.getString(extendedBolus.source) + " " + extendedBolus.toString()); + if (L.isEnabled(L.DATABASE)) + log.debug("EXTENDEDBOLUS: New record from: " + Source.getString(extendedBolus.source) + " " + extendedBolus.log()); updateEarliestDataChange(extendedBolus.date); scheduleExtendedBolusChange(); return true; @@ -1032,7 +1090,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { getDaoExtendedBolus().delete(old); // need to delete/create because date may change too old.copyFrom(extendedBolus); getDaoExtendedBolus().create(old); - log.debug("EXTENDEDBOLUS: Updating record by date from: " + Source.getString(extendedBolus.source) + " " + old.toString()); + if (L.isEnabled(L.DATABASE)) + log.debug("EXTENDEDBOLUS: Updating record by date from: " + Source.getString(extendedBolus.source) + " " + old.log()); updateEarliestDataChange(oldDate); updateEarliestDataChange(old.date); scheduleExtendedBolusChange(); @@ -1054,7 +1113,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { getDaoExtendedBolus().delete(old); // need to delete/create because date may change too old.copyFrom(extendedBolus); getDaoExtendedBolus().create(old); - log.debug("EXTENDEDBOLUS: Updating record by _id from: " + Source.getString(extendedBolus.source) + " " + old.toString()); + if (L.isEnabled(L.DATABASE)) + log.debug("EXTENDEDBOLUS: Updating record by _id from: " + Source.getString(extendedBolus.source) + " " + old.log()); updateEarliestDataChange(oldDate); updateEarliestDataChange(old.date); scheduleExtendedBolusChange(); @@ -1063,14 +1123,16 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { } } getDaoExtendedBolus().create(extendedBolus); - log.debug("EXTENDEDBOLUS: New record from: " + Source.getString(extendedBolus.source) + " " + extendedBolus.toString()); + if (L.isEnabled(L.DATABASE)) + log.debug("EXTENDEDBOLUS: New record from: " + Source.getString(extendedBolus.source) + " " + extendedBolus.log()); updateEarliestDataChange(extendedBolus.date); scheduleExtendedBolusChange(); return true; } if (extendedBolus.source == Source.USER) { getDaoExtendedBolus().create(extendedBolus); - log.debug("EXTENDEDBOLUS: New record from: " + Source.getString(extendedBolus.source) + " " + extendedBolus.toString()); + if (L.isEnabled(L.DATABASE)) + log.debug("EXTENDEDBOLUS: New record from: " + Source.getString(extendedBolus.source) + " " + extendedBolus.log()); updateEarliestDataChange(extendedBolus.date); scheduleExtendedBolusChange(); return true; @@ -1110,7 +1172,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { public void deleteExtendedBolusById(String _id) { ExtendedBolus stored = findExtendedBolusById(_id); if (stored != null) { - log.debug("EXTENDEDBOLUS: Removing ExtendedBolus record from database: " + stored.toString()); + if (L.isEnabled(L.DATABASE)) + log.debug("EXTENDEDBOLUS: Removing ExtendedBolus record from database: " + stored.toString()); delete(stored); updateEarliestDataChange(stored.date); scheduleExtendedBolusChange(); @@ -1163,7 +1226,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { private static void scheduleExtendedBolusChange() { class PostRunnable implements Runnable { public void run() { - log.debug("Firing EventExtendedBolusChange"); + if (L.isEnabled(L.DATABASE)) + log.debug("Firing EventExtendedBolusChange"); MainApp.bus().post(new EventReloadTreatmentData(new EventExtendedBolusChange())); if (earliestDataChange != null) MainApp.bus().post(new EventNewHistoryData(earliestDataChange)); @@ -1242,6 +1306,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { where.ge("date", mills); PreparedQuery preparedQuery = queryBuilder.prepare(); careportalEvents = getDaoCareportalEvents().query(preparedQuery); + preprocessOpenAPSOfflineEvents(careportalEvents); return careportalEvents; } catch (SQLException e) { log.error("Unhandled exception", e); @@ -1249,13 +1314,41 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { return new ArrayList<>(); } - public List getCareportalEventsFromTime(boolean ascending) { + public void preprocessOpenAPSOfflineEvents(List list) { + OverlappingIntervals offlineEvents = new OverlappingIntervals(); + for (int i = 0; i < list.size(); i++) { + CareportalEvent event = list.get(i); + if (!event.eventType.equals(CareportalEvent.OPENAPSOFFLINE)) continue; + offlineEvents.add(event); + } + + } + + public List getCareportalEventsFromTime(long mills, String type, boolean ascending) { + try { + List careportalEvents; + QueryBuilder queryBuilder = getDaoCareportalEvents().queryBuilder(); + queryBuilder.orderBy("date", ascending); + Where where = queryBuilder.where(); + where.ge("date", mills).and().eq("eventType", type); + PreparedQuery preparedQuery = queryBuilder.prepare(); + careportalEvents = getDaoCareportalEvents().query(preparedQuery); + preprocessOpenAPSOfflineEvents(careportalEvents); + return careportalEvents; + } catch (SQLException e) { + log.error("Unhandled exception", e); + } + return new ArrayList<>(); + } + + public List getCareportalEvents(boolean ascending) { try { List careportalEvents; QueryBuilder queryBuilder = getDaoCareportalEvents().queryBuilder(); queryBuilder.orderBy("date", ascending); PreparedQuery preparedQuery = queryBuilder.prepare(); careportalEvents = getDaoCareportalEvents().query(preparedQuery); + preprocessOpenAPSOfflineEvents(careportalEvents); return careportalEvents; } catch (SQLException e) { log.error("Unhandled exception", e); @@ -1274,11 +1367,11 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { if (list.size() == 1) { CareportalEvent record = list.get(0); - if (Config.logIncommingData) - log.debug("Removing CareportalEvent record from database: " + record.log()); + if (L.isEnabled(L.DATABASE)) + log.debug("Removing CareportalEvent record from database: " + record.toString()); delete(record); } else { - if (Config.logIncommingData) + if (L.isEnabled(L.DATABASE)) log.debug("CareportalEvent not found database: " + _id); } } catch (SQLException e) { @@ -1298,12 +1391,12 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { if (list.size() == 0) { careportalEvent = new CareportalEvent(); careportalEvent.source = Source.NIGHTSCOUT; - if (Config.logIncommingData) + if (L.isEnabled(L.DATABASE)) log.debug("Adding CareportalEvent record to database: " + trJson.toString()); // Record does not exists. add } else if (list.size() == 1) { careportalEvent = list.get(0); - if (Config.logIncommingData) + if (L.isEnabled(L.DATABASE)) log.debug("Updating CareportalEvent record in database: " + trJson.toString()); } else { log.error("Something went wrong"); @@ -1315,14 +1408,15 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { careportalEvent._id = trJson.getString("_id"); createOrUpdate(careportalEvent); } catch (SQLException | JSONException e) { - log.error("Unhandled exception", e); + log.error("Unhandled exception: " + trJson.toString(), e); } } private static void scheduleCareportalEventChange() { class PostRunnable implements Runnable { public void run() { - log.debug("Firing scheduleCareportalEventChange"); + if (L.isEnabled(L.DATABASE)) + log.debug("Firing scheduleCareportalEventChange"); MainApp.bus().post(new EventCareportalEventChange()); scheduledCareportalEventPost = null; } @@ -1355,6 +1449,24 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { return new ArrayList<>(); } + public List getProfileSwitchEventsFromTime(long mills, boolean ascending) { + try { + Dao daoProfileSwitch = getDaoProfileSwitch(); + List profileSwitches; + QueryBuilder queryBuilder = daoProfileSwitch.queryBuilder(); + queryBuilder.orderBy("date", ascending); + queryBuilder.limit(100L); + Where where = queryBuilder.where(); + where.ge("date", mills); + PreparedQuery preparedQuery = queryBuilder.prepare(); + profileSwitches = daoProfileSwitch.query(preparedQuery); + return profileSwitches; + } catch (SQLException e) { + log.error("Unhandled exception", e); + } + return new ArrayList<>(); + } + public boolean createOrUpdate(ProfileSwitch profileSwitch) { try { ProfileSwitch old; @@ -1368,7 +1480,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { profileSwitch.profileName = old.profileName; // preserver profileName to prevent multiple CPP extension getDaoProfileSwitch().delete(old); // need to delete/create because date may change too getDaoProfileSwitch().create(profileSwitch); - log.debug("PROFILESWITCH: Updating record by date from: " + Source.getString(profileSwitch.source) + " " + old.toString()); + if (L.isEnabled(L.DATABASE)) + log.debug("PROFILESWITCH: Updating record by date from: " + Source.getString(profileSwitch.source) + " " + old.toString()); scheduleProfileSwitchChange(); return true; } @@ -1387,7 +1500,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { getDaoProfileSwitch().delete(old); // need to delete/create because date may change too old.copyFrom(profileSwitch); getDaoProfileSwitch().create(old); - log.debug("PROFILESWITCH: Updating record by _id from: " + Source.getString(profileSwitch.source) + " " + old.toString()); + if (L.isEnabled(L.DATABASE)) + log.debug("PROFILESWITCH: Updating record by _id from: " + Source.getString(profileSwitch.source) + " " + old.toString()); scheduleProfileSwitchChange(); return true; } @@ -1396,13 +1510,15 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { // look for already added percentage from NS profileSwitch.profileName = PercentageSplitter.pureName(profileSwitch.profileName); getDaoProfileSwitch().create(profileSwitch); - log.debug("PROFILESWITCH: New record from: " + Source.getString(profileSwitch.source) + " " + profileSwitch.toString()); + if (L.isEnabled(L.DATABASE)) + log.debug("PROFILESWITCH: New record from: " + Source.getString(profileSwitch.source) + " " + profileSwitch.toString()); scheduleProfileSwitchChange(); return true; } if (profileSwitch.source == Source.USER) { getDaoProfileSwitch().create(profileSwitch); - log.debug("PROFILESWITCH: New record from: " + Source.getString(profileSwitch.source) + " " + profileSwitch.toString()); + if (L.isEnabled(L.DATABASE)) + log.debug("PROFILESWITCH: New record from: " + Source.getString(profileSwitch.source) + " " + profileSwitch.toString()); scheduleProfileSwitchChange(); return true; } @@ -1424,7 +1540,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { private static void scheduleProfileSwitchChange() { class PostRunnable implements Runnable { public void run() { - log.debug("Firing EventProfileSwitchChange"); + if (L.isEnabled(L.DATABASE)) + log.debug("Firing EventProfileSwitchChange"); MainApp.bus().post(new EventReloadProfileSwitchData()); MainApp.bus().post(new EventProfileSwitchChange()); scheduledProfileSwitchEventPost = null; @@ -1469,15 +1586,30 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { if (trJson.has("profileJson")) profileSwitch.profileJson = trJson.getString("profileJson"); else { - ProfileStore store = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile(); - Profile profile = store.getSpecificProfile(profileSwitch.profileName); - if (profile != null) { - profileSwitch.profileJson = profile.getData().toString(); - log.debug("Profile switch prefilled with JSON from local store"); - // Update data in NS - NSUpload.updateProfileSwitch(profileSwitch); + ProfileInterface profileInterface = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface(); + if (profileInterface != null) { + ProfileStore store = profileInterface.getProfile(); + if (store != null) { + Profile profile = store.getSpecificProfile(profileSwitch.profileName); + if (profile != null) { + profileSwitch.profileJson = profile.getData().toString(); + if (L.isEnabled(L.DATABASE)) + log.debug("Profile switch prefilled with JSON from local store"); + // Update data in NS + NSUpload.updateProfileSwitch(profileSwitch); + } else { + if (L.isEnabled(L.DATABASE)) + log.debug("JSON for profile switch doesn't exist. Ignoring: " + trJson.toString()); + return; + } + } else { + if (L.isEnabled(L.DATABASE)) + log.debug("Store for profile switch doesn't exist. Ignoring: " + trJson.toString()); + return; + } } else { - log.debug("JSON for profile switch doesn't exist. Ignoring: " + trJson.toString()); + if (L.isEnabled(L.DATABASE)) + log.debug("No active profile interface. Ignoring: " + trJson.toString()); return; } } @@ -1485,14 +1617,15 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { profileSwitch.profilePlugin = trJson.getString("profilePlugin"); createOrUpdate(profileSwitch); } catch (JSONException e) { - log.error("Unhandled exception", e); + log.error("Unhandled exception: " + trJson.toString(), e); } } public void deleteProfileSwitchById(String _id) { ProfileSwitch stored = findProfileSwitchById(_id); if (stored != null) { - log.debug("PROFILESWITCH: Removing ProfileSwitch record from database: " + stored.toString()); + if (L.isEnabled(L.DATABASE)) + log.debug("PROFILESWITCH: Removing ProfileSwitch record from database: " + stored.toString()); delete(stored); scheduleTemporaryTargetChange(); } diff --git a/app/src/main/java/info/nightscout/androidaps/db/DbRequest.java b/app/src/main/java/info/nightscout/androidaps/db/DbRequest.java index fcda5c9c04..f287e169ce 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/DbRequest.java +++ b/app/src/main/java/info/nightscout/androidaps/db/DbRequest.java @@ -10,6 +10,8 @@ import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import info.nightscout.androidaps.logging.L; + /** * Created by mike on 27.02.2016. *

@@ -17,7 +19,7 @@ import org.slf4j.LoggerFactory; */ @DatabaseTable(tableName = DatabaseHelper.DATABASE_DBREQUESTS) public class DbRequest { - private static Logger log = LoggerFactory.getLogger(DbRequest.class); + private static Logger log = LoggerFactory.getLogger(L.DATABASE); @DatabaseField(id = true) public String nsClientID = null; diff --git a/app/src/main/java/info/nightscout/androidaps/db/ExtendedBolus.java b/app/src/main/java/info/nightscout/androidaps/db/ExtendedBolus.java index ea97f4ddca..b4fda73ab6 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/ExtendedBolus.java +++ b/app/src/main/java/info/nightscout/androidaps/db/ExtendedBolus.java @@ -21,6 +21,7 @@ import info.nightscout.androidaps.data.Iob; import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.interfaces.InsulinInterface; import info.nightscout.androidaps.interfaces.Interval; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.Overview.graphExtensions.DataPointWithLabelInterface; import info.nightscout.androidaps.plugins.Overview.graphExtensions.PointsWithLabelGraphSeries; @@ -36,7 +37,7 @@ import info.nightscout.utils.Round; @DatabaseTable(tableName = DatabaseHelper.DATABASE_EXTENDEDBOLUSES) public class ExtendedBolus implements Interval, DataPointWithLabelInterface { - private static Logger log = LoggerFactory.getLogger(ExtendedBolus.class); + private static Logger log = LoggerFactory.getLogger(L.DATABASE); @DatabaseField(id = true) public long date; @@ -69,6 +70,36 @@ public class ExtendedBolus implements Interval, DataPointWithLabelInterface { this.date = date; } + public ExtendedBolus date(long date) { + this.date = date; + return this; + } + + public ExtendedBolus insulin(double insulin) { + this.insulin = insulin; + return this; + } + + public ExtendedBolus pumpId(long pumpId) { + this.pumpId = pumpId; + return this; + } + + public ExtendedBolus source(int source) { + this.source = source; + return this; + } + + public ExtendedBolus durationInMinutes(int durationInMinutes) { + this.durationInMinutes = durationInMinutes; + return this; + } + + public ExtendedBolus _id(String _id) { + this._id = _id; + return this; + } + public boolean isEqual(ExtendedBolus other) { if (date != other.date) { return false; @@ -93,13 +124,13 @@ public class ExtendedBolus implements Interval, DataPointWithLabelInterface { } public static ExtendedBolus createFromJson(JSONObject json) { - ExtendedBolus extendedBolus = new ExtendedBolus(); - extendedBolus.source = Source.NIGHTSCOUT; - extendedBolus.date = JsonHelper.safeGetLong(json, "mills"); - extendedBolus.durationInMinutes = JsonHelper.safeGetInt(json, "duration"); - extendedBolus.insulin = JsonHelper.safeGetDouble(json, "relative") / 60 * extendedBolus.durationInMinutes; - extendedBolus._id = JsonHelper.safeGetString(json, "_id"); - extendedBolus.pumpId = JsonHelper.safeGetLong(json, "pumpId"); + ExtendedBolus extendedBolus = new ExtendedBolus() + .source(Source.NIGHTSCOUT) + .date(JsonHelper.safeGetLong(json, "mills")) + .durationInMinutes(JsonHelper.safeGetInt(json, "duration")) + .insulin(JsonHelper.safeGetDouble(json, "relative") / 60 * JsonHelper.safeGetInt(json, "duration")) + ._id(JsonHelper.safeGetString(json, "_id")) + .pumpId(JsonHelper.safeGetLong(json, "pumpId")); return extendedBolus; } // -------- Interval interface --------- @@ -166,7 +197,7 @@ public class ExtendedBolus implements Interval, DataPointWithLabelInterface { // -------- Interval interface end --------- public String log() { - return "Bolus{" + + return "ExtendedBolus{" + "date= " + date + ", date= " + DateUtil.dateAndTimeString(date) + ", isValid=" + isValid + @@ -187,7 +218,7 @@ public class ExtendedBolus implements Interval, DataPointWithLabelInterface { public IobTotal iobCalc(long time) { IobTotal result = new IobTotal(time); - InsulinInterface insulinInterface = ConfigBuilderPlugin.getActiveInsulin(); + InsulinInterface insulinInterface = ConfigBuilderPlugin.getPlugin().getActiveInsulin(); int realDuration = getDurationToTime(time); diff --git a/app/src/main/java/info/nightscout/androidaps/db/ProfileSwitch.java b/app/src/main/java/info/nightscout/androidaps/db/ProfileSwitch.java index 40c8e50c6d..0527864fd2 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/ProfileSwitch.java +++ b/app/src/main/java/info/nightscout/androidaps/db/ProfileSwitch.java @@ -11,12 +11,14 @@ import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.List; import java.util.Objects; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.interfaces.Interval; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.Overview.graphExtensions.DataPointWithLabelInterface; import info.nightscout.androidaps.plugins.Overview.graphExtensions.PointsWithLabelGraphSeries; @@ -24,10 +26,11 @@ import info.nightscout.androidaps.plugins.Overview.notifications.Notification; import info.nightscout.androidaps.plugins.ProfileLocal.LocalProfilePlugin; import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; +import info.nightscout.utils.T; @DatabaseTable(tableName = DatabaseHelper.DATABASE_PROFILESWITCHES) public class ProfileSwitch implements Interval, DataPointWithLabelInterface { - private static Logger log = LoggerFactory.getLogger(ProfileSwitch.class); + private static Logger log = LoggerFactory.getLogger(L.DATABASE); @DatabaseField(id = true) public long date; @@ -217,6 +220,26 @@ public class ProfileSwitch implements Interval, DataPointWithLabelInterface { MainApp.bus().post(new EventNewNotification(notification)); } + public static boolean isEvent5minBack(List list, long time, boolean zeroDurationOnly) { + for (int i = 0; i < list.size(); i++) { + ProfileSwitch event = list.get(i); + if (event.date <= time && event.date > (time - T.mins(5).msecs())) { + if (zeroDurationOnly) { + if (event.durationInMinutes == 0) { + if (L.isEnabled(L.DATABASE)) + log.debug("Found ProfileSwitch event for time: " + DateUtil.dateAndTimeFullString(time) + " " + event.toString()); + return true; + } + } else { + if (L.isEnabled(L.DATABASE)) + log.debug("Found ProfileSwitch event for time: " + DateUtil.dateAndTimeFullString(time) + " " + event.toString()); + return true; + } + } + } + return false; + } + // -------- Interval interface end --------- // ----------------- DataPointInterface -------------------- diff --git a/app/src/main/java/info/nightscout/androidaps/db/TDD.java b/app/src/main/java/info/nightscout/androidaps/db/TDD.java index f34c79ff1a..9ca849b7b6 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/TDD.java +++ b/app/src/main/java/info/nightscout/androidaps/db/TDD.java @@ -8,6 +8,8 @@ import org.slf4j.LoggerFactory; import java.util.Objects; +import info.nightscout.androidaps.logging.L; + /** * Created by mike on 20.09.2017. */ @@ -15,7 +17,7 @@ import java.util.Objects; @DatabaseTable(tableName = DatabaseHelper.DATABASE_TDDS) public class TDD { - private static Logger log = LoggerFactory.getLogger(TDD.class); + private static Logger log = LoggerFactory.getLogger(L.DATABASE); @DatabaseField(id = true) public long date; diff --git a/app/src/main/java/info/nightscout/androidaps/db/TempTarget.java b/app/src/main/java/info/nightscout/androidaps/db/TempTarget.java index ae016a0f29..15692cbdfe 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/TempTarget.java +++ b/app/src/main/java/info/nightscout/androidaps/db/TempTarget.java @@ -11,12 +11,13 @@ import java.util.Objects; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.interfaces.Interval; +import info.nightscout.androidaps.logging.L; import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; @DatabaseTable(tableName = DatabaseHelper.DATABASE_TEMPTARGETS) public class TempTarget implements Interval { - private static Logger log = LoggerFactory.getLogger(TempTarget.class); + private static Logger log = LoggerFactory.getLogger(L.DATABASE); @DatabaseField(id = true) public long date; diff --git a/app/src/main/java/info/nightscout/androidaps/db/TemporaryBasal.java b/app/src/main/java/info/nightscout/androidaps/db/TemporaryBasal.java index 733027b188..eeaa8c0ee7 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/TemporaryBasal.java +++ b/app/src/main/java/info/nightscout/androidaps/db/TemporaryBasal.java @@ -15,7 +15,9 @@ import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.interfaces.InsulinInterface; import info.nightscout.androidaps.interfaces.Interval; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.Treatments.Treatment; import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; @@ -27,7 +29,7 @@ import info.nightscout.utils.SP; @DatabaseTable(tableName = DatabaseHelper.DATABASE_TEMPORARYBASALS) public class TemporaryBasal implements Interval { - private static Logger log = LoggerFactory.getLogger(TemporaryBasal.class); + private static Logger log = LoggerFactory.getLogger(L.DATABASE); @DatabaseField(id = true) public long date; @@ -93,7 +95,7 @@ public class TemporaryBasal implements Interval { } public TemporaryBasal(ExtendedBolus extendedBolus) { - double basal = MainApp.getConfigBuilder().getProfile(extendedBolus.date).getBasal(extendedBolus.date); + double basal = ProfileFunctions.getInstance().getProfile(extendedBolus.date).getBasal(extendedBolus.date); this.date = extendedBolus.date; this.isValid = extendedBolus.isValid; this.source = extendedBolus.source; @@ -103,6 +105,7 @@ public class TemporaryBasal implements Interval { this.isFakeExtended = true; this.netExtendedRate = extendedBolus.absoluteRate(); this.absoluteRate = basal + extendedBolus.absoluteRate(); + this.pumpId = extendedBolus.pumpId; } public TemporaryBasal clone() { @@ -219,15 +222,15 @@ public class TemporaryBasal implements Interval { public IobTotal iobCalc(long time, Profile profile) { - if(isFakeExtended){ + if (isFakeExtended) { log.error("iobCalc should only be called on Extended boluses separately"); return new IobTotal(time); } IobTotal result = new IobTotal(time); - InsulinInterface insulinInterface = ConfigBuilderPlugin.getActiveInsulin(); + InsulinInterface insulinInterface = ConfigBuilderPlugin.getPlugin().getActiveInsulin(); - int realDuration = getDurationToTime(time); + int realDuration = getDurationToTime(time); double netBasalAmount = 0d; if (realDuration > 0) { @@ -290,12 +293,22 @@ public class TemporaryBasal implements Interval { } public double tempBasalConvertedToAbsolute(long time, Profile profile) { - if(isFakeExtended){ + if (isFakeExtended) { return profile.getBasal(time) + netExtendedRate; } else if (isAbsolute) { return absoluteRate; } else { - return profile.getBasal(time) * percentRate / 100; + return profile.getBasal(time) * percentRate / 100; + } + } + + public int tempBasalConvertedToPercent(long time, Profile profile) { + if (isFakeExtended) { + return (int) ((profile.getBasal(time) + netExtendedRate) / profile.getBasal(time)) * 100; + } else if (isAbsolute) { + return (int) (absoluteRate / profile.getBasal(time)) * 100; + } else { + return percentRate; } } @@ -316,12 +329,12 @@ public class TemporaryBasal implements Interval { } public String toStringFull() { - if(isFakeExtended){ + if (isFakeExtended) { - Profile profile = MainApp.getConfigBuilder().getProfile(); + Profile profile = ProfileFunctions.getInstance().getProfile(); Double currentBasalRate = profile.getBasal(); - double rate = (currentBasalRate == null)?0d:(currentBasalRate+netExtendedRate); - return getCalcuatedPercentageIfNeeded() + DecimalFormatter.to2Decimal(rate) + "U/h ("+DecimalFormatter.to2Decimal(netExtendedRate)+"E) @" + + double rate = (currentBasalRate == null) ? 0d : (currentBasalRate + netExtendedRate); + return getCalcuatedPercentageIfNeeded() + DecimalFormatter.to2Decimal(rate) + "U/h (" + DecimalFormatter.to2Decimal(netExtendedRate) + "E) @" + DateUtil.timeString(date) + " " + getRealDuration() + "/" + durationInMinutes + "'"; } else if (isAbsolute) { @@ -338,21 +351,21 @@ public class TemporaryBasal implements Interval { public String toStringShort() { if (isAbsolute || isFakeExtended) { - double rate = 0d; + double rate = 0d; if (isFakeExtended) { - Profile profile = MainApp.getConfigBuilder().getProfile(); + Profile profile = ProfileFunctions.getInstance().getProfile(); Double currentBasalRate = profile.getBasal(); - rate = (currentBasalRate == null)?0d:(currentBasalRate+netExtendedRate); - } else if (isAbsolute){ + rate = (currentBasalRate == null) ? 0d : (currentBasalRate + netExtendedRate); + } else if (isAbsolute) { rate = absoluteRate; } - if(SP.getBoolean(R.string.key_danar_visualizeextendedaspercentage, false) && SP.getBoolean(R.string.key_danar_useextended, false)){ - Profile profile = MainApp.getConfigBuilder().getProfile(); - if(profile != null) { + if (SP.getBoolean(R.string.key_danar_visualizeextendedaspercentage, false) && SP.getBoolean(R.string.key_danar_useextended, false)) { + Profile profile = ProfileFunctions.getInstance().getProfile(); + if (profile != null) { double basal = profile.getBasal(); - if(basal != 0){ - return Math.round(rate*100d/basal) + "%"; + if (basal != 0) { + return Math.round(rate * 100d / basal) + "%"; } } } @@ -362,24 +375,24 @@ public class TemporaryBasal implements Interval { } } - private String getCalcuatedPercentageIfNeeded(){ + private String getCalcuatedPercentageIfNeeded() { if (isAbsolute || isFakeExtended) { - double rate = 0d; + double rate = 0d; if (isFakeExtended) { - Profile profile = MainApp.getConfigBuilder().getProfile(); + Profile profile = ProfileFunctions.getInstance().getProfile(); Double currentBasalRate = profile.getBasal(); - rate = (currentBasalRate == null)?0d:(currentBasalRate+netExtendedRate); - } else if (isAbsolute){ + rate = (currentBasalRate == null) ? 0d : (currentBasalRate + netExtendedRate); + } else if (isAbsolute) { rate = absoluteRate; } - if(SP.getBoolean(R.string.key_danar_visualizeextendedaspercentage, false) && SP.getBoolean(R.string.key_danar_useextended, false)){ - Profile profile = MainApp.getConfigBuilder().getProfile(); - if(profile != null) { + if (SP.getBoolean(R.string.key_danar_visualizeextendedaspercentage, false) && SP.getBoolean(R.string.key_danar_useextended, false)) { + Profile profile = ProfileFunctions.getInstance().getProfile(); + if (profile != null) { double basal = profile.getBasal(); - if(basal != 0){ - return Math.round(rate*100d/basal) + "% "; + if (basal != 0) { + return Math.round(rate * 100d / basal) + "% "; } } } @@ -390,12 +403,12 @@ public class TemporaryBasal implements Interval { public String toStringVeryShort() { if (isAbsolute || isFakeExtended) { - double rate = 0d; + double rate = 0d; if (isFakeExtended) { - Profile profile = MainApp.getConfigBuilder().getProfile(); + Profile profile = ProfileFunctions.getInstance().getProfile(); Double currentBasalRate = profile.getBasal(); - rate = (currentBasalRate == null)?0d:(currentBasalRate+netExtendedRate); - } else if (isAbsolute){ + rate = (currentBasalRate == null) ? 0d : (currentBasalRate + netExtendedRate); + } else if (isAbsolute) { rate = absoluteRate; } return DecimalFormatter.to2Decimal(rate) + "U/h "; diff --git a/app/src/main/java/info/nightscout/androidaps/events/EventAcceptOpenLoopChange.java b/app/src/main/java/info/nightscout/androidaps/events/EventAcceptOpenLoopChange.java new file mode 100644 index 0000000000..2dfbf9ae35 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/events/EventAcceptOpenLoopChange.java @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.events; + +/** Base class for events to update the UI, mostly a specific tab. */ +public class EventAcceptOpenLoopChange extends Event { +} diff --git a/app/src/main/java/info/nightscout/androidaps/events/EventNetworkChange.java b/app/src/main/java/info/nightscout/androidaps/events/EventNetworkChange.java index 03df71f31b..57050bdcc9 100644 --- a/app/src/main/java/info/nightscout/androidaps/events/EventNetworkChange.java +++ b/app/src/main/java/info/nightscout/androidaps/events/EventNetworkChange.java @@ -1,5 +1,8 @@ package info.nightscout.androidaps.events; + +import info.nightscout.utils.StringUtils; + public class EventNetworkChange extends Event { public boolean mobileConnected = false; @@ -9,6 +12,6 @@ public class EventNetworkChange extends Event { public boolean roaming = false; public String getSsid() { - return ssid.replace("SSID: ","").replaceAll("\"",""); + return StringUtils.removeSurroundingQuotes(ssid); } } diff --git a/app/src/main/java/info/nightscout/androidaps/events/EventPumpStatusChanged.java b/app/src/main/java/info/nightscout/androidaps/events/EventPumpStatusChanged.java index 7d810702b9..6729a4e703 100644 --- a/app/src/main/java/info/nightscout/androidaps/events/EventPumpStatusChanged.java +++ b/app/src/main/java/info/nightscout/androidaps/events/EventPumpStatusChanged.java @@ -10,9 +10,10 @@ import info.nightscout.androidaps.R; public class EventPumpStatusChanged extends Event { public static final int CONNECTING = 0; public static final int CONNECTED = 1; - public static final int PERFORMING = 2; - public static final int DISCONNECTING = 3; - public static final int DISCONNECTED = 4; + public static final int HANDSHAKING = 2; + public static final int PERFORMING = 3; + public static final int DISCONNECTING = 4; + public static final int DISCONNECTED = 5; public int sStatus = DISCONNECTED; public int sSecondsElapsed = 0; @@ -47,6 +48,8 @@ public class EventPumpStatusChanged extends Event { public String textStatus() { if (sStatus == CONNECTING) return String.format(MainApp.gs(R.string.danar_history_connectingfor), sSecondsElapsed); + else if (sStatus == HANDSHAKING) + return MainApp.gs(R.string.handshaking); else if (sStatus == CONNECTED) return MainApp.gs(R.string.connected); else if (sStatus == PERFORMING) diff --git a/app/src/main/java/info/nightscout/androidaps/interfaces/APSInterface.java b/app/src/main/java/info/nightscout/androidaps/interfaces/APSInterface.java index 0b965d48af..2f37c47391 100644 --- a/app/src/main/java/info/nightscout/androidaps/interfaces/APSInterface.java +++ b/app/src/main/java/info/nightscout/androidaps/interfaces/APSInterface.java @@ -1,7 +1,5 @@ package info.nightscout.androidaps.interfaces; -import java.util.Date; - import info.nightscout.androidaps.plugins.Loop.APSResult; /** @@ -9,7 +7,7 @@ import info.nightscout.androidaps.plugins.Loop.APSResult; */ public interface APSInterface { public APSResult getLastAPSResult(); - public Date getLastAPSRun(); + public long getLastAPSRun(); public void invoke(String initiator, boolean tempBasalFallback); } diff --git a/app/src/main/java/info/nightscout/androidaps/interfaces/BgSourceInterface.java b/app/src/main/java/info/nightscout/androidaps/interfaces/BgSourceInterface.java index a45ab083e7..d42ead7950 100644 --- a/app/src/main/java/info/nightscout/androidaps/interfaces/BgSourceInterface.java +++ b/app/src/main/java/info/nightscout/androidaps/interfaces/BgSourceInterface.java @@ -1,8 +1,12 @@ package info.nightscout.androidaps.interfaces; +import android.content.Intent; + /** * Created by mike on 20.06.2016. */ public interface BgSourceInterface { boolean advancedFilteringSupported(); + + void handleNewData(Intent intent); } diff --git a/app/src/main/java/info/nightscout/androidaps/interfaces/Constraint.java b/app/src/main/java/info/nightscout/androidaps/interfaces/Constraint.java index 58e6045bd1..417f02199d 100644 --- a/app/src/main/java/info/nightscout/androidaps/interfaces/Constraint.java +++ b/app/src/main/java/info/nightscout/androidaps/interfaces/Constraint.java @@ -6,12 +6,14 @@ import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.List; +import info.nightscout.androidaps.logging.L; + /** * Created by mike on 19.03.2018. */ public class Constraint { - private static Logger log = LoggerFactory.getLogger(Constraint.class); + private static Logger log = LoggerFactory.getLogger(L.CONSTRAINTS); T value; T originalValue; @@ -35,18 +37,35 @@ public class Constraint { public Constraint set(T value) { this.value = value; this.originalValue = value; + if (L.isEnabled(L.CONSTRAINTS)) + log.debug("Setting value " + value); return this; } public Constraint set(T value, String reason, Object from) { + if (L.isEnabled(L.CONSTRAINTS)) + log.debug("Setting value " + this.value + " -> " + value + " (" + reason + ")[" + translateFrom(from) + "]"); this.value = value; addReason(reason, from); addMostLimingReason(reason, from); return this; } + public Constraint 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 setIfSmaller(T value, String reason, Object from) { if (value.compareTo(this.value) < 0) { + if (L.isEnabled(L.CONSTRAINTS)) + log.debug("Setting because of smaller value " + this.value + " -> " + value + " (" + reason + ")[" + translateFrom(from) + "]"); this.value = value; mostLimiting.clear(); addMostLimingReason(reason, from); @@ -57,8 +76,10 @@ public class Constraint { return this; } - public Constraint setIfGreater(T value, String reason, Object from) { + public Constraint setIfGreater(T value, String reason, Object from) { if (value.compareTo(this.value) > 0) { + if (L.isEnabled(L.CONSTRAINTS)) + log.debug("Setting because of greater value " + this.value + " -> " + value + " (" + reason + ")[" + translateFrom(from) + "]"); this.value = value; mostLimiting.clear(); addMostLimingReason(reason, from); @@ -69,13 +90,17 @@ public class Constraint { return this; } + private String translateFrom(Object from) { + return from.getClass().getSimpleName().replace("Plugin", ""); + } + public Constraint addReason(String reason, Object from) { - reasons.add(from.getClass().getSimpleName().replace("Plugin", "") + ": " + reason); + reasons.add(translateFrom(from) + ": " + reason); return this; } - public Constraint addMostLimingReason(String reason, Object from) { - mostLimiting.add(from.getClass().getSimpleName().replace("Plugin", "") + ": " + reason); + public Constraint addMostLimingReason(String reason, Object from) { + mostLimiting.add(translateFrom(from) + ": " + reason); return this; } @@ -86,7 +111,8 @@ public class Constraint { if (count++ != 0) sb.append("\n"); sb.append(r); } - log.debug("Limiting origial value: " + originalValue + " to " + value + ". Reason: " + sb.toString()); + if (L.isEnabled(L.CONSTRAINTS)) + log.debug("Limiting origial value: " + originalValue + " to " + value + ". Reason: " + sb.toString()); return sb.toString(); } @@ -101,7 +127,8 @@ public class Constraint { if (count++ != 0) sb.append("\n"); sb.append(r); } - log.debug("Limiting origial value: " + originalValue + " to " + value + ". Reason: " + sb.toString()); + if (L.isEnabled(L.CONSTRAINTS)) + log.debug("Limiting origial value: " + originalValue + " to " + value + ". Reason: " + sb.toString()); return sb.toString(); } @@ -110,7 +137,7 @@ public class Constraint { } public void copyReasons(Constraint another) { - for (String s: another.getReasonList()) { + for (String s : another.getReasonList()) { reasons.add(s); } } diff --git a/app/src/main/java/info/nightscout/androidaps/interfaces/ConstraintsInterface.java b/app/src/main/java/info/nightscout/androidaps/interfaces/ConstraintsInterface.java index a1daa08a56..5ac8cc83f7 100644 --- a/app/src/main/java/info/nightscout/androidaps/interfaces/ConstraintsInterface.java +++ b/app/src/main/java/info/nightscout/androidaps/interfaces/ConstraintsInterface.java @@ -7,7 +7,7 @@ import info.nightscout.androidaps.data.Profile; */ public interface ConstraintsInterface { - default Constraint isLoopInvokationAllowed(Constraint value) { + default Constraint isLoopInvocationAllowed(Constraint value) { return value; } @@ -27,6 +27,10 @@ public interface ConstraintsInterface { return value; } + default Constraint isUAMEnabled(Constraint value) { + return value; + } + default Constraint isAdvancedFilteringEnabled(Constraint value) { return value; } @@ -43,6 +47,10 @@ public interface ConstraintsInterface { return insulin; } + default Constraint applyExtendedBolusConstraints(Constraint insulin) { + return insulin; + } + default Constraint applyCarbsConstraints(Constraint carbs) { return carbs; } diff --git a/app/src/main/java/info/nightscout/androidaps/interfaces/DanaRInterface.java b/app/src/main/java/info/nightscout/androidaps/interfaces/DanaRInterface.java index 1c5ee83834..374d96890a 100644 --- a/app/src/main/java/info/nightscout/androidaps/interfaces/DanaRInterface.java +++ b/app/src/main/java/info/nightscout/androidaps/interfaces/DanaRInterface.java @@ -9,4 +9,5 @@ import info.nightscout.androidaps.data.PumpEnactResult; public interface DanaRInterface { PumpEnactResult loadHistory(byte type); // for history browser PumpEnactResult loadEvents(); // events history to build treatments from + PumpEnactResult setUserOptions(); // like AnyDana does } diff --git a/app/src/main/java/info/nightscout/androidaps/interfaces/PluginBase.java b/app/src/main/java/info/nightscout/androidaps/interfaces/PluginBase.java index 1173936430..a1a35b7413 100644 --- a/app/src/main/java/info/nightscout/androidaps/interfaces/PluginBase.java +++ b/app/src/main/java/info/nightscout/androidaps/interfaces/PluginBase.java @@ -1,18 +1,22 @@ package info.nightscout.androidaps.interfaces; import android.os.SystemClock; +import android.support.v4.app.FragmentActivity; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderFragment; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.queue.CommandQueue; /** * Created by mike on 09.06.2016. */ public abstract class PluginBase { - private static Logger log = LoggerFactory.getLogger(PluginBase.class); + private static Logger log = LoggerFactory.getLogger(L.CORE); public enum State { NOT_INITIALIZED, @@ -32,6 +36,12 @@ public abstract class PluginBase { this.pluginDescription = pluginDescription; } + // Default always calls invoke + // Plugins that have special constraints if they get switched to may override this method + public void switchAllowed(ConfigBuilderFragment.PluginViewHolder.PluginSwitcher pluginSwitcher, FragmentActivity activity) { + pluginSwitcher.invoke(); + } + // public PluginType getType() { // return mainType; // } @@ -57,6 +67,11 @@ public abstract class PluginBase { return getName(); } + public String getDescription() { + if (pluginDescription.description == -1) return null; + else return MainApp.gs(pluginDescription.description); + } + public PluginType getType() { return pluginDescription.mainType; } @@ -100,15 +115,17 @@ public abstract class PluginBase { if (state != State.ENABLED) { onStateChange(type, state, State.ENABLED); state = State.ENABLED; - log.debug("Starting: " + getName()); + if (L.isEnabled(L.CORE)) + log.debug("Starting: " + getName()); onStart(); } } else { // disabling plugin if (state == State.ENABLED) { - onStateChange(type, state, State.ENABLED); + onStateChange(type, state, State.DISABLED); state = State.DISABLED; onStop(); - log.debug("Stopping: " + getName()); + if (L.isEnabled(L.CORE)) + log.debug("Stopping: " + getName()); } } } else if (type == PluginType.PROFILE) { @@ -152,7 +169,9 @@ public abstract class PluginBase { if (getType() == PluginType.PUMP) { new Thread(() -> { SystemClock.sleep(3000); - ConfigBuilderPlugin.getCommandQueue().readStatus("Pump driver changed.", null); + CommandQueue commandQueue = ConfigBuilderPlugin.getPlugin().getCommandQueue(); + if (commandQueue != null) + commandQueue.readStatus("Pump driver changed.", null); }).start(); } } diff --git a/app/src/main/java/info/nightscout/androidaps/interfaces/PluginDescription.java b/app/src/main/java/info/nightscout/androidaps/interfaces/PluginDescription.java index c86ae639fa..1634fc672d 100644 --- a/app/src/main/java/info/nightscout/androidaps/interfaces/PluginDescription.java +++ b/app/src/main/java/info/nightscout/androidaps/interfaces/PluginDescription.java @@ -9,6 +9,7 @@ public class PluginDescription { boolean showInList = true; int pluginName = -1; int shortName = -1; + int description = -1; int preferencesId = -1; int advancedPreferencesId = -1; public boolean enableByDefault = false; @@ -74,6 +75,11 @@ public class PluginDescription { return this; } + public PluginDescription description(int description) { + this.description = description; + return this; + } + public String getFragmentClass() { return fragmentClass; } diff --git a/app/src/main/java/info/nightscout/androidaps/interfaces/PumpDescription.java b/app/src/main/java/info/nightscout/androidaps/interfaces/PumpDescription.java index ec6976a2c7..34221b203f 100644 --- a/app/src/main/java/info/nightscout/androidaps/interfaces/PumpDescription.java +++ b/app/src/main/java/info/nightscout/androidaps/interfaces/PumpDescription.java @@ -1,47 +1,139 @@ package info.nightscout.androidaps.interfaces; +import info.nightscout.androidaps.plugins.PumpCommon.defs.PumpCapability; +import info.nightscout.androidaps.plugins.PumpCommon.defs.PumpTempBasalType; +import info.nightscout.androidaps.plugins.PumpCommon.defs.PumpType; + /** * Created by mike on 08.12.2016. */ public class PumpDescription { + public PumpType pumpType = PumpType.GenericAAPS; + + public PumpDescription () { + resetSettings(); + } + public static final int NONE = 0; public static final int PERCENT = 0x01; public static final int ABSOLUTE = 0x02; - public boolean isBolusCapable = true; - public double bolusStep = 0.1d; + public boolean isBolusCapable; + public double bolusStep; - public boolean isExtendedBolusCapable = true; - public double extendedBolusStep = 0.1d; - public double extendedBolusDurationStep = 30; - public double extendedBolusMaxDuration = 12 * 60; + public boolean isExtendedBolusCapable; + public double extendedBolusStep; + public double extendedBolusDurationStep; + public double extendedBolusMaxDuration; - public boolean isTempBasalCapable = true; - public int tempBasalStyle = PERCENT; + public boolean isTempBasalCapable; + public int tempBasalStyle; - public int maxTempPercent = 200; - public int tempPercentStep = 10; + public int maxTempPercent; + public int tempPercentStep; - public double maxTempAbsolute = 10; - public double tempAbsoluteStep = 0.05d; + public double maxTempAbsolute; + public double tempAbsoluteStep; - public int tempDurationStep = 60; - public boolean tempDurationStep15mAllowed = false; - public boolean tempDurationStep30mAllowed = false; - public int tempMaxDuration = 12 * 60; + public int tempDurationStep; + public boolean tempDurationStep15mAllowed; + public boolean tempDurationStep30mAllowed; + public int tempMaxDuration; + + public boolean isSetBasalProfileCapable; + public double basalStep; + public double basalMinimumRate; + public double basalMaximumRate; + + public boolean isRefillingCapable; + + public boolean storesCarbInfo; + + public boolean is30minBasalRatesCapable; + + public boolean supportsTDDs; + public boolean needsManualTDDLoad; - public boolean isSetBasalProfileCapable = true; - public double basalStep = 0.01d; - public double basalMinimumRate = 0.04d; + public void resetSettings() { + isBolusCapable = true; + bolusStep = 0.1d; - public boolean isRefillingCapable = false; + isExtendedBolusCapable = true; + extendedBolusStep = 0.1d; + extendedBolusDurationStep = 30; + extendedBolusMaxDuration = 12 * 60; - public boolean storesCarbInfo = true; + isTempBasalCapable = true; + tempBasalStyle = PERCENT; + maxTempPercent = 200; + tempPercentStep = 10; + maxTempAbsolute = 10; + tempAbsoluteStep = 0.05d; + tempDurationStep = 60; + tempMaxDuration = 12 * 60; + tempDurationStep15mAllowed = false; + tempDurationStep30mAllowed = false; - public boolean is30minBasalRatesCapable = false; + isSetBasalProfileCapable = true; + basalStep = 0.01d; + basalMinimumRate = 0.04d; + basalMaximumRate = 25d; + is30minBasalRatesCapable = false; + + isRefillingCapable = false; + storesCarbInfo = true; + + supportsTDDs = false; + needsManualTDDLoad = true; + } + + public void setPumpDescription(PumpType pumpType) { + resetSettings(); + this.pumpType = pumpType; + + PumpCapability pumpCapability = pumpType.getPumpCapability(); + + isBolusCapable = pumpCapability.hasCapability(PumpCapability.Bolus); + bolusStep = pumpType.getBolusSize(); + + isExtendedBolusCapable = pumpCapability.hasCapability(PumpCapability.ExtendedBolus); + extendedBolusStep = pumpType.getExtendedBolusSettings().getStep(); + extendedBolusDurationStep = pumpType.getExtendedBolusSettings().getDurationStep(); + extendedBolusMaxDuration = pumpType.getExtendedBolusSettings().getMaxDuration(); + + isTempBasalCapable = pumpCapability.hasCapability(PumpCapability.TempBasal); + + if (pumpType.getPumpTempBasalType() == PumpTempBasalType.Percent) { + tempBasalStyle = PERCENT; + maxTempPercent = pumpType.getTbrSettings().getMaxDose().intValue(); + tempPercentStep = (int) pumpType.getTbrSettings().getStep(); + } else { + tempBasalStyle = ABSOLUTE; + maxTempAbsolute = pumpType.getTbrSettings().getMaxDose(); + tempAbsoluteStep = pumpType.getTbrSettings().getStep(); + } + + tempDurationStep = pumpType.getTbrSettings().getDurationStep(); + tempMaxDuration = pumpType.getTbrSettings().getMaxDuration(); + + tempDurationStep15mAllowed = pumpType.getSpecialBasalDurations() + .hasCapability(PumpCapability.BasalRate_Duration15minAllowed); + tempDurationStep30mAllowed = pumpType.getSpecialBasalDurations() + .hasCapability(PumpCapability.BasalRate_Duration30minAllowed); + + isSetBasalProfileCapable = pumpCapability.hasCapability(PumpCapability.BasalProfileSet); + basalStep = pumpType.getBaseBasalStep(); + basalMinimumRate = pumpType.getBaseBasalMinValue(); + + isRefillingCapable = pumpCapability.hasCapability(PumpCapability.Refill); + storesCarbInfo = pumpCapability.hasCapability(PumpCapability.StoreCarbInfo); + + supportsTDDs = pumpCapability.hasCapability(PumpCapability.TDD); + needsManualTDDLoad = pumpCapability.hasCapability(PumpCapability.ManualTDDLoad); + + is30minBasalRatesCapable = pumpCapability.hasCapability(PumpCapability.BasalRate30min); + } - public boolean supportsTDDs = false; - public boolean needsManualTDDLoad = true; } diff --git a/app/src/main/java/info/nightscout/androidaps/interfaces/PumpInterface.java b/app/src/main/java/info/nightscout/androidaps/interfaces/PumpInterface.java index 65911f82c6..614c6033d3 100644 --- a/app/src/main/java/info/nightscout/androidaps/interfaces/PumpInterface.java +++ b/app/src/main/java/info/nightscout/androidaps/interfaces/PumpInterface.java @@ -2,8 +2,6 @@ package info.nightscout.androidaps.interfaces; import org.json.JSONObject; -import java.util.Date; - import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.PumpEnactResult; @@ -13,11 +11,13 @@ import info.nightscout.androidaps.data.PumpEnactResult; */ public interface PumpInterface { - boolean isInitialized(); - boolean isSuspended(); - boolean isBusy(); - boolean isConnected(); - boolean isConnecting(); + boolean isInitialized(); // true if pump status has been read and is ready to accept commands + boolean isSuspended(); // true if suspended (not delivering insulin) + boolean isBusy(); // if true pump is not ready to accept commands right now + boolean isConnected(); // true if BT connection is established + boolean isConnecting(); // true if BT connection is in progress + boolean isHandshakeInProgress(); // true if BT is connected but initial handshake is still in progress + void finishHandshaking(); // set initial handshake completed void connect(String reason); void disconnect(String reason); @@ -29,7 +29,7 @@ public interface PumpInterface { PumpEnactResult setNewBasalProfile(Profile profile); boolean isThisProfileSet(Profile profile); - Date lastDataTime(); + long lastDataTime(); double getBaseBasalRate(); // base basal rate, not temp basal diff --git a/app/src/main/java/info/nightscout/androidaps/interfaces/SensitivityInterface.java b/app/src/main/java/info/nightscout/androidaps/interfaces/SensitivityInterface.java index deb649c21f..f4514ad572 100644 --- a/app/src/main/java/info/nightscout/androidaps/interfaces/SensitivityInterface.java +++ b/app/src/main/java/info/nightscout/androidaps/interfaces/SensitivityInterface.java @@ -1,11 +1,17 @@ package info.nightscout.androidaps.interfaces; import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensResult; +import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin; /** * Created by mike on 24.06.2017. */ public interface SensitivityInterface { - AutosensResult detectSensitivity(long fromTime, long toTime); + + double MIN_HOURS = 1; + double MIN_HOURS_FULL_AUTOSENS = 4; + + AutosensResult detectSensitivity(IobCobCalculatorPlugin plugin, long fromTime, long toTime); + } diff --git a/app/src/main/java/info/nightscout/androidaps/interfaces/TreatmentsInterface.java b/app/src/main/java/info/nightscout/androidaps/interfaces/TreatmentsInterface.java index 27a6a0846b..dc437e04ab 100644 --- a/app/src/main/java/info/nightscout/androidaps/interfaces/TreatmentsInterface.java +++ b/app/src/main/java/info/nightscout/androidaps/interfaces/TreatmentsInterface.java @@ -50,7 +50,7 @@ public interface TreatmentsInterface { boolean addToHistoryExtendedBolus(ExtendedBolus extendedBolus); - boolean addToHistoryTreatment(DetailedBolusInfo detailedBolusInfo); + boolean addToHistoryTreatment(DetailedBolusInfo detailedBolusInfo, boolean allowUpdate); TempTarget getTempTargetFromHistory(); TempTarget getTempTargetFromHistory(long time); diff --git a/app/src/main/java/info/nightscout/utils/BundleLogger.java b/app/src/main/java/info/nightscout/androidaps/logging/BundleLogger.java similarity index 90% rename from app/src/main/java/info/nightscout/utils/BundleLogger.java rename to app/src/main/java/info/nightscout/androidaps/logging/BundleLogger.java index ba6ffff869..b559c7af7e 100644 --- a/app/src/main/java/info/nightscout/utils/BundleLogger.java +++ b/app/src/main/java/info/nightscout/androidaps/logging/BundleLogger.java @@ -1,4 +1,4 @@ -package info.nightscout.utils; +package info.nightscout.androidaps.logging; import android.os.Bundle; diff --git a/app/src/main/java/info/nightscout/androidaps/logging/L.java b/app/src/main/java/info/nightscout/androidaps/logging/L.java new file mode 100644 index 0000000000..c44d2516c2 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/logging/L.java @@ -0,0 +1,123 @@ +package info.nightscout.androidaps.logging; + +import java.util.ArrayList; +import java.util.List; + +import info.nightscout.utils.SP; + +public class L { + + public static class LogElement { + public String name; + boolean defaultValue; + public boolean enabled; + boolean requiresRestart = false; + + LogElement(String name, boolean defaultValue) { + this.name = name; + this.defaultValue = defaultValue; + enabled = SP.getBoolean(getSPName(), defaultValue); + } + + LogElement(String name, boolean defaultValue, boolean requiresRestart) { + this.name = name; + this.defaultValue = defaultValue; + this.requiresRestart = requiresRestart; + enabled = SP.getBoolean(getSPName(), defaultValue); + } + + LogElement(boolean defaultValue) { + this.name = "NONEXISTING"; + this.defaultValue = defaultValue; + enabled = defaultValue; + } + + private String getSPName() { + return "log_" + name; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + SP.putBoolean(getSPName(), enabled); + } + + void resetToDefault() { + setEnabled(defaultValue); + } + } + + private static List logElements; + + static { + initialize(); + } + + private static LogElement findByName(String name) { + for (LogElement element : logElements) { + if (element.name.equals(name)) + return element; + } + return new LogElement(false); + } + + public static boolean isEnabled(String name) { + return findByName(name).enabled; + } + + public static List getLogElements() { + return logElements; + } + + public static void resetToDefaults() { + for (LogElement element : logElements) { + element.resetToDefault(); + } + } + + + public static final String CORE = "CORE"; + public static final String AUTOSENS = "AUTOSENS"; + public static final String EVENTS = "EVENTS"; + public static final String BGSOURCE = "BGSOURCE"; + public static final String OVERVIEW = "OVERVIEW"; + public static final String NOTIFICATION = "NOTIFICATION"; + public static final String DATASERVICE = "DATASERVICE"; + public static final String DATABASE = "DATABASE"; + public static final String DATAFOOD = "DATAFOOD"; + public static final String DATATREATMENTS = "DATATREATMENTS"; + public static final String NSCLIENT = "NSCLIENT"; + public static final String CONSTRAINTS = "CONSTRAINTS"; + public static final String PUMP = "PUMP"; + public static final String PUMPQUEUE = "PUMPQUEUE"; + public static final String PUMPCOMM = "PUMPCOMM"; + public static final String PUMPBTCOMM = "PUMPBTCOMM"; + public static final String APS = "APS"; + public static final String PROFILE = "PROFILE"; + public static final String CONFIGBUILDER = "CONFIGBUILDER"; + public static final String UI = "UI"; + + private static void initialize() { + logElements = new ArrayList<>(); + logElements.add(new LogElement(APS, true)); + logElements.add(new LogElement(AUTOSENS, true)); + logElements.add(new LogElement(BGSOURCE, true)); + logElements.add(new LogElement(CONFIGBUILDER, true)); + logElements.add(new LogElement(CONSTRAINTS, true)); + logElements.add(new LogElement(CORE, true)); + logElements.add(new LogElement(DATABASE, true)); + logElements.add(new LogElement(DATAFOOD, true)); + logElements.add(new LogElement(DATASERVICE, true)); + logElements.add(new LogElement(DATATREATMENTS, true)); + logElements.add(new LogElement(EVENTS, false, true)); + logElements.add(new LogElement(NOTIFICATION, true)); + logElements.add(new LogElement(NSCLIENT, true)); + logElements.add(new LogElement(OVERVIEW, true)); + logElements.add(new LogElement(PROFILE, true)); + logElements.add(new LogElement(PUMP, true)); + logElements.add(new LogElement(PUMPBTCOMM, false)); + logElements.add(new LogElement(PUMPCOMM, true)); + logElements.add(new LogElement(PUMPQUEUE, true)); + logElements.add(new LogElement(UI, true)); + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Actions/ActionsFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Actions/ActionsFragment.java index 84086d6117..a71b447d82 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Actions/ActionsFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Actions/ActionsFragment.java @@ -14,10 +14,10 @@ import com.crashlytics.android.answers.CustomEvent; import com.squareup.otto.Subscribe; import info.nightscout.androidaps.Config; -import info.nightscout.androidaps.HistoryBrowseActivity; +import info.nightscout.androidaps.activities.HistoryBrowseActivity; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.TDDStatsActivity; +import info.nightscout.androidaps.activities.TDDStatsActivity; import info.nightscout.androidaps.db.ExtendedBolus; import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.events.EventExtendedBolusChange; @@ -33,6 +33,7 @@ import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialo import info.nightscout.androidaps.plugins.Careportal.OptionsToShow; import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.SingleClickButton; @@ -125,13 +126,13 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL activity.runOnUiThread(new Runnable() { @Override public void run() { - if (MainApp.getConfigBuilder().getActiveProfileInterface().getProfile() != null) { + if (ConfigBuilderPlugin.getPlugin().getActiveProfileInterface() != null && ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getProfile() != null) { profileSwitch.setVisibility(View.VISIBLE); } else { profileSwitch.setVisibility(View.GONE); } - if (MainApp.getConfigBuilder().getProfile() == null) { + if (ProfileFunctions.getInstance().getProfile() == null) { tempTarget.setVisibility(View.GONE); extendedBolus.setVisibility(View.GONE); extendedBolusCancel.setVisibility(View.GONE); @@ -141,7 +142,7 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL return; } - final PumpInterface pump = ConfigBuilderPlugin.getActivePump(); + final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); final boolean basalprofileEnabled = MainApp.isEngineeringModeOrRelease() && pump.getPumpDescription().isSetBasalProfileCapable; @@ -191,7 +192,7 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL else tempTarget.setVisibility(View.VISIBLE); - if (!ConfigBuilderPlugin.getActivePump().getPumpDescription().supportsTDDs) tddStats.setVisibility(View.GONE); + if (!ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().supportsTDDs) tddStats.setVisibility(View.GONE); else tddStats.setVisibility(View.VISIBLE); } }); @@ -222,13 +223,13 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL break; case R.id.actions_extendedbolus_cancel: if (TreatmentsPlugin.getPlugin().isInHistoryExtendedBoluslInProgress()) { - ConfigBuilderPlugin.getCommandQueue().cancelExtended(null); + ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelExtended(null); FabricPrivacy.getInstance().logCustom(new CustomEvent("CancelExtended")); } break; case R.id.actions_canceltempbasal: if (TreatmentsPlugin.getPlugin().isTempBasalInProgress()) { - ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, null); + ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(true, null); FabricPrivacy.getInstance().logCustom(new CustomEvent("CancelTemp")); } break; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Actions/ActionsPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Actions/ActionsPlugin.java index 2397410693..ff6275c9c9 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Actions/ActionsPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Actions/ActionsPlugin.java @@ -17,6 +17,7 @@ public class ActionsPlugin extends PluginBase { .fragmentClass(ActionsFragment.class.getName()) .pluginName(R.string.actions) .shortName(R.string.actions_shortname) + .description(R.string.description_actions) ); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/FillDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/FillDialog.java index 7b9b8570d6..aed10c9e2f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/FillDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/FillDialog.java @@ -39,7 +39,7 @@ import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity; import info.nightscout.androidaps.queue.Callback; import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.FabricPrivacy; -import info.nightscout.utils.NSUpload; +import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; import info.nightscout.utils.NumberPicker; import info.nightscout.utils.SP; import info.nightscout.utils.SafeParse; @@ -61,6 +61,10 @@ public class FillDialog extends DialogFragment implements OnClickListener { private EditText notesEdit; + //one shot guards + private boolean accepted; + private boolean okClicked; + final private TextWatcher textWatcher = new TextWatcher() { @Override public void afterTextChanged(Editable s) { @@ -87,7 +91,7 @@ public class FillDialog extends DialogFragment implements OnClickListener { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.actions_fill_dialog, null, false); + View view = inflater.inflate(R.layout.actions_fill_dialog, container, false); view.findViewById(R.id.ok).setOnClickListener(this); view.findViewById(R.id.cancel).setOnClickListener(this); @@ -99,7 +103,7 @@ public class FillDialog extends DialogFragment implements OnClickListener { insulinCartridgeChangeCheckbox = view.findViewById(R.id.fill_cartridge_change); Double maxInsulin = MainApp.getConstraintChecker().getMaxBolusAllowed().value(); - double bolusstep = ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep; + double bolusstep = ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().bolusStep; editInsulin = view.findViewById(R.id.fill_insulinamount); editInsulin.setParams(0d, 0d, maxInsulin, bolusstep, DecimalFormatter.pumpSupportedBolusFormat(), false, textWatcher); @@ -163,7 +167,14 @@ public class FillDialog extends DialogFragment implements OnClickListener { } - private void confirmAndDeliver() { + private synchronized void confirmAndDeliver() { + if (okClicked) { + log.debug("guarding: ok already clicked"); + dismiss(); + return; + } + okClicked = true; + try { Double insulin = SafeParse.stringToDouble(editInsulin.getText()); @@ -173,8 +184,8 @@ public class FillDialog extends DialogFragment implements OnClickListener { if (insulinAfterConstraints > 0) { confirmMessage.add(MainApp.gs(R.string.fillwarning)); confirmMessage.add(""); - confirmMessage.add(MainApp.gs(R.string.bolus) + ": " + "" + insulinAfterConstraints + "U" + ""); - if (!insulinAfterConstraints.equals(insulin)) + confirmMessage.add(MainApp.gs(R.string.bolus) + ": " + "" + DecimalFormatter.toPumpSupportedBolus(insulinAfterConstraints) + "U" + ""); + if (Math.abs(insulinAfterConstraints - insulin) > 0.01d) confirmMessage.add("" + MainApp.gs(R.string.bolusconstraintapplied) + ""); } @@ -198,32 +209,40 @@ public class FillDialog extends DialogFragment implements OnClickListener { if (insulinAfterConstraints > 0 || pumpSiteChangeCheckbox.isChecked() || insulinCartridgeChangeCheckbox.isChecked()) { builder.setMessage(Html.fromHtml(Joiner.on("
").join(confirmMessage))); builder.setPositiveButton(MainApp.gs(R.string.primefill), (dialog, id) -> { - if (finalInsulinAfterConstraints > 0) { - DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo(); - detailedBolusInfo.insulin = finalInsulinAfterConstraints; - detailedBolusInfo.context = context; - detailedBolusInfo.source = Source.USER; - detailedBolusInfo.isValid = false; // do not count it in IOB (for pump history) - detailedBolusInfo.notes = notes; - ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() { - @Override - public void run() { - if (!result.success) { - Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class); - i.putExtra("soundid", R.raw.boluserror); - i.putExtra("status", result.comment); - i.putExtra("title", MainApp.gs(R.string.treatmentdeliveryerror)); - i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - MainApp.instance().startActivity(i); + synchronized (builder) { + if (accepted) { + log.debug("guarding: already accepted"); + return; + } + accepted = true; + + if (finalInsulinAfterConstraints > 0) { + DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo(); + detailedBolusInfo.insulin = finalInsulinAfterConstraints; + detailedBolusInfo.context = context; + detailedBolusInfo.source = Source.USER; + detailedBolusInfo.isValid = false; // do not count it in IOB (for pump history) + detailedBolusInfo.notes = notes; + ConfigBuilderPlugin.getPlugin().getCommandQueue().bolus(detailedBolusInfo, new Callback() { + @Override + public void run() { + if (!result.success) { + Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class); + i.putExtra("soundid", R.raw.boluserror); + i.putExtra("status", result.comment); + i.putExtra("title", MainApp.gs(R.string.treatmentdeliveryerror)); + i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + MainApp.instance().startActivity(i); + } } - } - }); - FabricPrivacy.getInstance().logCustom(new CustomEvent("Fill")); + }); + FabricPrivacy.getInstance().logCustom(new CustomEvent("Fill")); + } + if (pumpSiteChangeCheckbox.isChecked()) + NSUpload.uploadEvent(CareportalEvent.SITECHANGE, now(), notes); + if (insulinCartridgeChangeCheckbox.isChecked()) + NSUpload.uploadEvent(CareportalEvent.INSULINCHANGE, now() + 1000, notes); } - if (pumpSiteChangeCheckbox.isChecked()) - NSUpload.uploadEvent(CareportalEvent.SITECHANGE, now(), notes); - if (insulinCartridgeChangeCheckbox.isChecked()) - NSUpload.uploadEvent(CareportalEvent.INSULINCHANGE, now() + 1000, notes); }); } else { builder.setMessage(MainApp.gs(R.string.no_action_selected)); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/NewExtendedBolusDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/NewExtendedBolusDialog.java index 45b6460392..710874a790 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/NewExtendedBolusDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/NewExtendedBolusDialog.java @@ -44,12 +44,12 @@ public class NewExtendedBolusDialog extends DialogFragment implements View.OnCli View view = inflater.inflate(R.layout.overview_newextendedbolus_dialog, container, false); - Double maxInsulin = MainApp.getConstraintChecker().getMaxBolusAllowed().value(); + Double maxInsulin = MainApp.getConstraintChecker().getMaxExtendedBolusAllowed().value(); editInsulin = (NumberPicker) view.findViewById(R.id.overview_newextendedbolus_insulin); editInsulin.setParams(0d, 0d, maxInsulin, 0.1d, new DecimalFormat("0.00"), false); - double extendedDurationStep = ConfigBuilderPlugin.getActivePump().getPumpDescription().extendedBolusDurationStep; - double extendedMaxDuration = ConfigBuilderPlugin.getActivePump().getPumpDescription().extendedBolusMaxDuration; + double extendedDurationStep = ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().extendedBolusDurationStep; + double extendedMaxDuration = ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().extendedBolusMaxDuration; editDuration = (NumberPicker) view.findViewById(R.id.overview_newextendedbolus_duration); editDuration.setParams(extendedDurationStep, extendedDurationStep, extendedMaxDuration, extendedDurationStep, new DecimalFormat("0"), false); @@ -71,10 +71,10 @@ public class NewExtendedBolusDialog extends DialogFragment implements View.OnCli String confirmMessage = MainApp.gs(R.string.setextendedbolusquestion); - Double insulinAfterConstraint = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(insulin)).value(); + Double insulinAfterConstraint = MainApp.getConstraintChecker().applyExtendedBolusConstraints(new Constraint<>(insulin)).value(); confirmMessage += " " + insulinAfterConstraint + " U "; confirmMessage += MainApp.gs(R.string.duration) + " " + durationInMinutes + "min ?"; - if (insulinAfterConstraint - insulin != 0d) + if (Math.abs(insulinAfterConstraint - insulin) > 0.01d) confirmMessage += "\n" + MainApp.gs(R.string.constraintapllied); insulin = insulinAfterConstraint; @@ -87,7 +87,7 @@ public class NewExtendedBolusDialog extends DialogFragment implements View.OnCli builder.setMessage(confirmMessage); builder.setPositiveButton(MainApp.gs(R.string.ok), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { - ConfigBuilderPlugin.getCommandQueue().extendedBolus(finalInsulin, finalDurationInMinutes, new Callback() { + ConfigBuilderPlugin.getPlugin().getCommandQueue().extendedBolus(finalInsulin, finalDurationInMinutes, new Callback() { @Override public void run() { if (!result.success) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/NewTempBasalDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/NewTempBasalDialog.java index 7a03887cf6..95abf173db 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/NewTempBasalDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/NewTempBasalDialog.java @@ -25,6 +25,7 @@ import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.PumpDescription; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity; import info.nightscout.androidaps.queue.Callback; import info.nightscout.utils.FabricPrivacy; @@ -63,14 +64,14 @@ public class NewTempBasalDialog extends DialogFragment implements View.OnClickLi absoluteRadio = (RadioButton) view.findViewById(R.id.overview_newtempbasal_absolute_radio); typeSelectorLayout = (LinearLayout) view.findViewById(R.id.overview_newtempbasal_typeselector_layout); - PumpDescription pumpDescription = ConfigBuilderPlugin.getActivePump().getPumpDescription(); + PumpDescription pumpDescription = ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription(); basalPercent = (NumberPicker) view.findViewById(R.id.overview_newtempbasal_basalpercentinput); double maxTempPercent = pumpDescription.maxTempPercent; double tempPercentStep = pumpDescription.tempPercentStep; basalPercent.setParams(100d, 0d, maxTempPercent, tempPercentStep, new DecimalFormat("0"), true); - Profile profile = MainApp.getConfigBuilder().getProfile(); + Profile profile = ProfileFunctions.getInstance().getProfile(); Double currentBasal = profile != null ? profile.getBasal() : 0d; basalAbsolute = (NumberPicker) view.findViewById(R.id.overview_newtempbasal_basalabsoluteinput); basalAbsolute.setParams(currentBasal, 0d, pumpDescription.maxTempAbsolute, pumpDescription.tempAbsoluteStep, new DecimalFormat("0.00"), true); @@ -118,7 +119,7 @@ public class NewTempBasalDialog extends DialogFragment implements View.OnClickLi final boolean setAsPercent = percentRadio.isChecked(); int durationInMinutes = SafeParse.stringToInt(duration.getText()); - Profile profile = MainApp.getConfigBuilder().getProfile(); + Profile profile = ProfileFunctions.getInstance().getProfile(); if (profile == null) return; @@ -135,7 +136,7 @@ public class NewTempBasalDialog extends DialogFragment implements View.OnClickLi absolute = MainApp.getConstraintChecker().applyBasalConstraints(new Constraint<>(basalAbsoluteInput), profile).value(); confirmMessage += "\n" + absolute + " U/h "; confirmMessage += "\n" + MainApp.gs(R.string.duration) + " " + durationInMinutes + "min ?"; - if (absolute - basalAbsoluteInput != 0d) + if (Math.abs(absolute - basalAbsoluteInput) > 0.01d) confirmMessage += "\n" + MainApp.gs(R.string.constraintapllied); } @@ -162,9 +163,9 @@ public class NewTempBasalDialog extends DialogFragment implements View.OnClickLi } }; if (setAsPercent) { - ConfigBuilderPlugin.getCommandQueue().tempBasalPercent(finalBasalPercent, finalDurationInMinutes, true, profile, callback); + ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalPercent(finalBasalPercent, finalDurationInMinutes, true, profile, callback); } else { - ConfigBuilderPlugin.getCommandQueue().tempBasalAbsolute(finalBasal, finalDurationInMinutes, true, profile, callback); + ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalAbsolute(finalBasal, finalDurationInMinutes, true, profile, callback); } FabricPrivacy.getInstance().logCustom(new CustomEvent("TempBasal")); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/CareportalFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/CareportalFragment.java index 4a4210f29e..e39480691e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/CareportalFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/CareportalFragment.java @@ -24,6 +24,7 @@ import info.nightscout.androidaps.db.CareportalEvent; import info.nightscout.androidaps.events.EventCareportalEventChange; import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialog; import info.nightscout.androidaps.plugins.Common.SubscriberFragment; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.NSClientInternal.data.NSSettingsStatus; import info.nightscout.androidaps.plugins.Overview.OverviewFragment; import info.nightscout.utils.FabricPrivacy; @@ -100,7 +101,7 @@ public class CareportalFragment extends SubscriberFragment implements View.OnCli noProfileView = view.findViewById(R.id.profileview_noprofile); butonsLayout = (LinearLayout) view.findViewById(R.id.careportal_buttons); - ProfileStore profileStore = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile(); + ProfileStore profileStore = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface() != null ? ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getProfile() : null; if (profileStore == null) { noProfileView.setVisibility(View.VISIBLE); butonsLayout.setVisibility(View.GONE); @@ -109,7 +110,7 @@ public class CareportalFragment extends SubscriberFragment implements View.OnCli butonsLayout.setVisibility(View.VISIBLE); } - if (Config.NSCLIENT || Config.G5UPLOADER) + if (Config.NSCLIENT) statsLayout.setVisibility(View.GONE); // visible on overview updateGUI(); @@ -218,50 +219,19 @@ public class CareportalFragment extends SubscriberFragment implements View.OnCli double iageUrgent = nsSettings.getExtendedWarnValue("iage", "urgent", 96); double iageWarn = nsSettings.getExtendedWarnValue("iage", "warn", 72); + handleAge(iage, CareportalEvent.INSULINCHANGE, iageWarn, iageUrgent); + double cageUrgent = nsSettings.getExtendedWarnValue("cage", "urgent", 72); double cageWarn = nsSettings.getExtendedWarnValue("cage", "warn", 48); + handleAge(cage, CareportalEvent.SITECHANGE, cageWarn, cageUrgent); + double sageUrgent = nsSettings.getExtendedWarnValue("sage", "urgent", 166); double sageWarn = nsSettings.getExtendedWarnValue("sage", "warn", 164); + handleAge(sage, CareportalEvent.SENSORCHANGE, sageWarn, sageUrgent); + double pbageUrgent = nsSettings.getExtendedWarnValue("pgage", "urgent", 360); double pbageWarn = nsSettings.getExtendedWarnValue("pgage", "warn", 240); - - String notavailable = OverviewFragment.shorttextmode ? "-" : MainApp.gs(R.string.notavailable); - if (sage != null) { - careportalEvent = MainApp.getDbHelper().getLastCareportalEvent(CareportalEvent.SENSORCHANGE); - if (careportalEvent != null) { - sage.setTextColor(CareportalFragment.determineTextColor(careportalEvent, sageWarn, sageUrgent)); - sage.setText(careportalEvent.age()); - } else { - sage.setText(notavailable); - } - } - if (iage != null) { - careportalEvent = MainApp.getDbHelper().getLastCareportalEvent(CareportalEvent.INSULINCHANGE); - if (careportalEvent != null) { - iage.setTextColor(CareportalFragment.determineTextColor(careportalEvent, iageWarn, iageUrgent)); - iage.setText(careportalEvent.age()); - } else { - iage.setText(notavailable); - } - } - if (cage != null) { - careportalEvent = MainApp.getDbHelper().getLastCareportalEvent(CareportalEvent.SITECHANGE); - if (careportalEvent != null) { - cage.setTextColor(CareportalFragment.determineTextColor(careportalEvent, cageWarn, cageUrgent)); - cage.setText(careportalEvent.age()); - } else { - cage.setText(notavailable); - } - } - if (pbage != null) { - careportalEvent = MainApp.getDbHelper().getLastCareportalEvent(CareportalEvent.PUMPBATTERYCHANGE); - if (careportalEvent != null) { - pbage.setTextColor(CareportalFragment.determineTextColor(careportalEvent, pbageWarn, pbageUrgent)); - pbage.setText(careportalEvent.age()); - } else { - pbage.setText(notavailable); - } - } + handleAge(pbage, CareportalEvent.PUMPBATTERYCHANGE, pbageWarn, pbageUrgent); } ); } @@ -277,5 +247,21 @@ public class CareportalFragment extends SubscriberFragment implements View.OnCli } } + + private static TextView handleAge(final TextView age, String eventType, double warnThreshold, double urgentThreshold) { + String notavailable = OverviewFragment.shorttextmode ? "-" : MainApp.gs(R.string.notavailable); + + if (age != null) { + CareportalEvent careportalEvent = MainApp.getDbHelper().getLastCareportalEvent(eventType); + if (careportalEvent != null) { + age.setTextColor(CareportalFragment.determineTextColor(careportalEvent, warnThreshold, urgentThreshold)); + age.setText(careportalEvent.age()); + } else { + age.setText(notavailable); + } + } + + return age; + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/CareportalPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/CareportalPlugin.java index 1428880a81..22aa4686b2 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/CareportalPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/CareportalPlugin.java @@ -23,6 +23,9 @@ public class CareportalPlugin extends PluginBase { .fragmentClass(CareportalFragment.class.getName()) .pluginName(R.string.careportal) .shortName(R.string.careportal_shortname) + .visibleByDefault(true) + .enableByDefault(true) + .description(R.string.description_careportal) ); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/Dialogs/NewNSTreatmentDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/Dialogs/NewNSTreatmentDialog.java index 46c1e3666d..cb495059b8 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/Dialogs/NewNSTreatmentDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/Dialogs/NewNSTreatmentDialog.java @@ -49,13 +49,15 @@ import info.nightscout.androidaps.db.ProfileSwitch; import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.TempTarget; import info.nightscout.androidaps.plugins.Careportal.OptionsToShow; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; +import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.utils.DateUtil; import info.nightscout.utils.DefaultValueHelper; import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.HardLimits; import info.nightscout.utils.JsonHelper; -import info.nightscout.utils.NSUpload; import info.nightscout.utils.NumberPicker; import info.nightscout.utils.SP; import info.nightscout.utils.SafeParse; @@ -171,8 +173,8 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick view.findViewById(R.id.cancel).setOnClickListener(this); // profile - profile = MainApp.getConfigBuilder().getProfile(); - profileStore = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile(); + profile = ProfileFunctions.getInstance().getProfile(); + profileStore = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getProfile(); if (profileStore == null) { if (options.eventType == R.id.careportal_profileswitch) { log.error("Profile switch called but plugin doesn't contain valid profile"); @@ -186,7 +188,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick profileSpinner.setAdapter(adapter); // set selected to actual profile for (int p = 0; p < profileList.size(); p++) { - if (profileList.get(p).equals(MainApp.getConfigBuilder().getProfileName(false))) + if (profileList.get(p).equals(ProfileFunctions.getInstance().getProfileName(false))) profileSpinner.setSelection(p); } } @@ -206,12 +208,15 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick public void onItemSelected(AdapterView parent, View view, int position, long id) { double defaultDuration; double defaultTarget = 0; - if (profile != null) { + if (profile != null && editTemptarget.getValue() == bg) { defaultTarget = bg; + } else { + //prevent changes on screen rotate + defaultTarget = editTemptarget.getValue(); } boolean erase = false; - String units = MainApp.getConfigBuilder().getProfileUnits(); + String units = ProfileFunctions.getInstance().getProfileUnits(); DefaultValueHelper helper = new DefaultValueHelper(); if (MainApp.gs(R.string.eatingsoon).equals(reasonList.get(position))) { defaultDuration = helper.determineEatingSoonTTDuration(); @@ -222,6 +227,8 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick } else if (MainApp.gs(R.string.hypo).equals(reasonList.get(position))) { defaultDuration = helper.determineHypoTTDuration(); defaultTarget = helper.determineHypoTT(units); + } else if (editDuration.getValue() != 0) { + defaultDuration = editDuration.getValue(); } else { defaultDuration = 0; erase = true; @@ -258,22 +265,26 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick if (sensorRadioButton.isChecked()) meterRadioButton.setChecked(true); } }; - editBg = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_bginput); editTemptarget = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_temptarget); if (profile == null) { editBg.setParams(bg, 0d, 500d, 0.1d, new DecimalFormat("0.0"), false, bgTextWatcher); editTemptarget.setParams(bg, 0d, 500d, 0.1d, new DecimalFormat("0.0"), false); - } else if (profile.getUnits().equals(Constants.MMOL)) { + } else if (units.equals(Constants.MMOL)) { editBg.setParams(bg, 0d, 30d, 0.1d, new DecimalFormat("0.0"), false, bgTextWatcher); editTemptarget.setParams(bg, 0d, 30d, 0.1d, new DecimalFormat("0.0"), false); } else { editBg.setParams(bg, 0d, 500d, 1d, new DecimalFormat("0"), false, bgTextWatcher); editTemptarget.setParams(bg, 0d, 500d, 1d, new DecimalFormat("0"), false); } + sensorRadioButton.setOnCheckedChangeListener((buttonView, isChecked) -> { - Double bg1 = Profile.fromMgdlToUnits(GlucoseStatus.getGlucoseStatusData() != null ? GlucoseStatus.getGlucoseStatusData().glucose : 0d, profile.getUnits()); - editBg.setValue(bg1); + Double bg1 = Profile.fromMgdlToUnits(GlucoseStatus.getGlucoseStatusData() != null ? GlucoseStatus.getGlucoseStatusData().glucose : 0d, units); + if (savedInstanceState != null && savedInstanceState.getDouble("editBg") != bg1) { + editBg.setValue(savedInstanceState.getDouble("editBg")); + } else { + editBg.setValue(bg1); + } }); Integer maxCarbs = MainApp.getConstraintChecker().getMaxCarbsAllowed().value(); @@ -311,7 +322,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick if (profile != null) maxPercent = MainApp.getConstraintChecker().getMaxBasalPercentAllowed(profile).value(); editPercent = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_percentinput); - editPercent.setParams(0d, 0d, (double) maxPercent, 5d, new DecimalFormat("0"), true, percentTextWatcher); + editPercent.setParams(0d, -100d, (double) maxPercent, 5d, new DecimalFormat("0"), true, percentTextWatcher); TextWatcher absoluteTextWatcher = new TextWatcher() { @Override @@ -378,6 +389,25 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick setCancelable(true); getDialog().setCanceledOnTouchOutside(false); + //recovering state if there is something + // only numberPickers and editTexts + if (savedInstanceState != null) { + editBg.setValue(savedInstanceState.getDouble("editBg")); + editTemptarget.setValue(savedInstanceState.getDouble("editTemptarget")); + notesEdit.setText(savedInstanceState.getString("notesEdit")); + editCarbs.setValue(savedInstanceState.getDouble("editCarbs")); + editCarbs.setValue(savedInstanceState.getDouble("editCarbs")); + editInsulin.setValue(savedInstanceState.getDouble("editInsulin")); + editDuration.setValue(savedInstanceState.getDouble("editDuration")); + editPercent.setValue(savedInstanceState.getDouble("editPercent")); + editAbsolute.setValue(savedInstanceState.getDouble("editAbsolute")); + editCarbTime.setValue(savedInstanceState.getDouble("editCarbTime")); + editPercentage.setValue(savedInstanceState.getDouble("editPercentage")); + editTimeshift.setValue(savedInstanceState.getDouble("editTimeshift")); + // time and date + dateButton.setText(savedInstanceState.getString("dateButton")); + timeButton.setText(savedInstanceState.getString("timeButton")); + } return view; } @@ -429,7 +459,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick if ((data.size() > 0) && (data.get(0).date > millis - 7 * 60 * 1000L) && (data.get(0).date < millis + 7 * 60 * 1000L)) { - editBg.setValue(Profile.fromMgdlToUnits(data.get(0).value, profile != null ? profile.getUnits() : Constants.MGDL)); + editBg.setValue(Profile.fromMgdlToUnits(data.get(0).value, units)); } } @@ -706,8 +736,8 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick .reason(reason) .source(Source.USER); if (tempTarget.durationInMinutes != 0) { - tempTarget.low(Profile.toMgdl(targetBottom, profile.getUnits())) - .high(Profile.toMgdl(targetTop, profile.getUnits())); + tempTarget.low(Profile.toMgdl(targetBottom, units)) + .high(Profile.toMgdl(targetTop, units)); } else { tempTarget.low(0).high(0); } @@ -738,7 +768,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick profileSwitch.source = Source.USER; profileSwitch.profileName = profileName; profileSwitch.profileJson = profileStore.getSpecificProfile(profileName).getData().toString(); - profileSwitch.profilePlugin = MainApp.getConfigBuilder().getActiveProfileInterface().getClass().getName(); + profileSwitch.profilePlugin = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getClass().getName(); profileSwitch.durationInMinutes = duration; profileSwitch.isCPP = percentage != 100 || timeshift != 0; profileSwitch.timeshift = timeshift; @@ -758,9 +788,9 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick profileSwitch = new ProfileSwitch(); profileSwitch.date = System.currentTimeMillis(); profileSwitch.source = Source.USER; - profileSwitch.profileName = MainApp.getConfigBuilder().getProfileName(System.currentTimeMillis(), false); - profileSwitch.profileJson = MainApp.getConfigBuilder().getProfile().getData().toString(); - profileSwitch.profilePlugin = MainApp.getConfigBuilder().getActiveProfileInterface().getClass().getName(); + profileSwitch.profileName = ProfileFunctions.getInstance().getProfileName(System.currentTimeMillis(), false); + profileSwitch.profileJson = ProfileFunctions.getInstance().getProfile().getData().toString(); + profileSwitch.profilePlugin = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getClass().getName(); profileSwitch.durationInMinutes = duration; profileSwitch.isCPP = percentage != 100 || timeshift != 0; profileSwitch.timeshift = timeshift; @@ -772,4 +802,22 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick } } + @Override + public void onSaveInstanceState(Bundle savedInstanceState) { + savedInstanceState.putString("notesEdit", notesEdit.getText().toString()); + savedInstanceState.putString("dateButton", dateButton.getText().toString()); + savedInstanceState.putString("timeButton", timeButton.getText().toString()); + savedInstanceState.putDouble("editBg", editBg.getValue()); + savedInstanceState.putDouble("editCarbs", editCarbs.getValue()); + savedInstanceState.putDouble("editInsulin", editInsulin.getValue()); + savedInstanceState.putDouble("editDuration", editDuration.getValue()); + savedInstanceState.putDouble("editPercent", editPercent.getValue()); + savedInstanceState.putDouble("editAbsolute", editAbsolute.getValue()); + savedInstanceState.putDouble("editCarbTime", editCarbTime.getValue()); + savedInstanceState.putDouble("editTemptarget", editTemptarget.getValue()); + savedInstanceState.putDouble("editPercentage", editPercentage.getValue()); + savedInstanceState.putDouble("editTimeshift", editTimeshift.getValue()); + super.onSaveInstanceState(savedInstanceState); + } + } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Common/SubscriberFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Common/SubscriberFragment.java index 5ca9232646..fabd83f0ea 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Common/SubscriberFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Common/SubscriberFragment.java @@ -21,7 +21,7 @@ abstract public class SubscriberFragment extends Fragment { updateGUI(); } - @Override public void onDestroyView() { + @Override public synchronized void onDestroyView() { super.onDestroyView(); if (unbinder != null) unbinder.unbind(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderFragment.java index e92ca52cd9..3df78c9a28 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderFragment.java @@ -1,32 +1,32 @@ package info.nightscout.androidaps.plugins.ConfigBuilder; -import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.support.annotation.NonNull; +import android.support.annotation.StringRes; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.CheckBox; -import android.widget.ImageView; +import android.widget.ImageButton; import android.widget.LinearLayout; -import android.widget.ListAdapter; -import android.widget.ListView; +import android.widget.RadioButton; +import android.widget.ScrollView; import android.widget.TextView; import com.crashlytics.android.answers.CustomEvent; import java.util.ArrayList; +import java.util.List; import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnClick; -import info.nightscout.androidaps.Config; +import butterknife.Unbinder; import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.PreferencesActivity; +import info.nightscout.androidaps.activities.PreferencesActivity; import info.nightscout.androidaps.R; import info.nightscout.androidaps.events.EventConfigBuilderChange; import info.nightscout.androidaps.events.EventRefreshGui; @@ -43,76 +43,36 @@ import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.Insulin.InsulinOrefRapidActingPlugin; import info.nightscout.androidaps.plugins.ProfileNS.NSProfilePlugin; import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin; -import info.nightscout.androidaps.plugins.SensitivityOref0.SensitivityOref0Plugin; +import info.nightscout.androidaps.plugins.Sensitivity.SensitivityOref0Plugin; import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.PasswordProtection; public class ConfigBuilderFragment extends SubscriberFragment { - @BindView(R.id.configbuilder_insulinlistview) - ListView insulinListView; - @BindView(R.id.configbuilder_sensitivitylistview) - ListView sensitivityListView; - @BindView(R.id.configbuilder_bgsourcelistview) - ListView bgsourceListView; - @BindView(R.id.configbuilder_bgsourcelabel) - TextView bgsourceLabel; - @BindView(R.id.configbuilder_pumplistview) - ListView pumpListView; - @BindView(R.id.configbuilder_pumplabel) - TextView pumpLabel; - @BindView(R.id.configbuilder_looplistview) - ListView loopListView; - @BindView(R.id.configbuilder_looplabel) - TextView loopLabel; - @BindView(R.id.configbuilder_treatmentslistview) - ListView treatmentsListView; - @BindView(R.id.configbuilder_treatmentslabel) - TextView treatmentsLabel; - @BindView(R.id.configbuilder_profilelistview) - ListView profileListView; - @BindView(R.id.configbuilder_profilelabel) - TextView profileLabel; - @BindView(R.id.configbuilder_apslistview) - ListView apsListView; - @BindView(R.id.configbuilder_apslabel) - TextView apsLabel; - @BindView(R.id.configbuilder_constraintslistview) - ListView constraintsListView; - @BindView(R.id.configbuilder_constraintslabel) - TextView constraintsLabel; - @BindView(R.id.configbuilder_generallistview) - ListView generalListView; + private List pluginViewHolders = new ArrayList<>(); - @BindView(R.id.configbuilder_mainlayout) - LinearLayout mainLayout; - @BindView(R.id.configbuilder_unlock) + @BindView(R.id.categories) + LinearLayout categories; + + @BindView(R.id.main_layout) + ScrollView mainLayout; + @BindView(R.id.unlock) Button unlock; - PluginCustomAdapter insulinDataAdapter = null; - PluginCustomAdapter sensivityDataAdapter = null; - PluginCustomAdapter bgsourceDataAdapter = null; - PluginCustomAdapter pumpDataAdapter = null; - PluginCustomAdapter loopDataAdapter = null; - PluginCustomAdapter treatmentDataAdapter = null; - PluginCustomAdapter profileDataAdapter = null; - PluginCustomAdapter apsDataAdapter = null; - PluginCustomAdapter constraintsDataAdapter = null; - PluginCustomAdapter generalDataAdapter = null; - @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { try { View view = inflater.inflate(R.layout.configbuilder_fragment, container, false); - unbinder = ButterKnife.bind(this, view); if (PasswordProtection.isLocked("settings_password")) mainLayout.setVisibility(View.GONE); - else - unlock.setVisibility(View.GONE); + else unlock.setVisibility(View.GONE); + + createViews(); + return view; } catch (Exception e) { FabricPrivacy.logException(e); @@ -121,222 +81,55 @@ public class ConfigBuilderFragment extends SubscriberFragment { return null; } - @OnClick(R.id.configbuilder_unlock) - public void onClickUnlock() { + @OnClick(R.id.unlock) + void onClickUnlock() { PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", () -> { mainLayout.setVisibility(View.VISIBLE); unlock.setVisibility(View.GONE); }, null); } + @Override + public void onDestroyView() { + super.onDestroyView(); + for (PluginViewHolder pluginViewHolder : pluginViewHolders) pluginViewHolder.unbind(); + pluginViewHolders.clear(); + } @Override protected void updateGUI() { - - insulinDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInListByInterface(InsulinInterface.class, PluginType.INSULIN), PluginType.INSULIN); - insulinListView.setAdapter(insulinDataAdapter); - setListViewHeightBasedOnChildren(insulinListView); - bgsourceDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInListByInterface(BgSourceInterface.class, PluginType.BGSOURCE), PluginType.BGSOURCE); - bgsourceListView.setAdapter(bgsourceDataAdapter); - if (MainApp.getSpecificPluginsVisibleInList(PluginType.BGSOURCE).size() == 0) - bgsourceLabel.setVisibility(View.GONE); - setListViewHeightBasedOnChildren(bgsourceListView); - pumpDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInList(PluginType.PUMP), PluginType.PUMP); - pumpListView.setAdapter(pumpDataAdapter); - if (MainApp.getSpecificPluginsVisibleInList(PluginType.PUMP).size() == 0 || Config.NSCLIENT || Config.G5UPLOADER) { - pumpLabel.setVisibility(View.GONE); - pumpListView.setVisibility(View.GONE); - } - setListViewHeightBasedOnChildren(pumpListView); - loopDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInList(PluginType.LOOP), PluginType.LOOP); - loopListView.setAdapter(loopDataAdapter); - setListViewHeightBasedOnChildren(loopListView); - if (MainApp.getSpecificPluginsVisibleInList(PluginType.LOOP).size() == 0) - loopLabel.setVisibility(View.GONE); - treatmentDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInList(PluginType.TREATMENT), PluginType.TREATMENT); - treatmentsListView.setAdapter(treatmentDataAdapter); - setListViewHeightBasedOnChildren(treatmentsListView); - if (MainApp.getSpecificPluginsVisibleInList(PluginType.TREATMENT).size() == 0) - treatmentsLabel.setVisibility(View.GONE); - profileDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInListByInterface(ProfileInterface.class, PluginType.PROFILE), PluginType.PROFILE); - profileListView.setAdapter(profileDataAdapter); - if (MainApp.getSpecificPluginsVisibleInList(PluginType.PROFILE).size() == 0) - profileLabel.setVisibility(View.GONE); - setListViewHeightBasedOnChildren(profileListView); - apsDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInList(PluginType.APS), PluginType.APS); - apsListView.setAdapter(apsDataAdapter); - setListViewHeightBasedOnChildren(apsListView); - if (MainApp.getSpecificPluginsVisibleInList(PluginType.APS).size() == 0) - apsLabel.setVisibility(View.GONE); - sensivityDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInListByInterface(SensitivityInterface.class, PluginType.SENSITIVITY), PluginType.SENSITIVITY); - sensitivityListView.setAdapter(sensivityDataAdapter); - setListViewHeightBasedOnChildren(sensitivityListView); - constraintsDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInListByInterface(ConstraintsInterface.class, PluginType.CONSTRAINTS), PluginType.CONSTRAINTS); - constraintsListView.setAdapter(constraintsDataAdapter); - setListViewHeightBasedOnChildren(constraintsListView); - if (MainApp.getSpecificPluginsVisibleInList(PluginType.CONSTRAINTS).size() == 0) - constraintsLabel.setVisibility(View.GONE); - generalDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInList(PluginType.GENERAL), PluginType.GENERAL); - generalListView.setAdapter(generalDataAdapter); - setListViewHeightBasedOnChildren(generalListView); + for (PluginViewHolder pluginViewHolder : pluginViewHolders) pluginViewHolder.update(); } - /* - * ConfigBuilderFragment code - */ - - private class PluginCustomAdapter extends ArrayAdapter { - - private ArrayList pluginList; - final private PluginType type; - - PluginCustomAdapter(Context context, int textViewResourceId, - ArrayList pluginList, PluginType type) { - super(context, textViewResourceId, pluginList); - this.pluginList = new ArrayList<>(); - this.pluginList.addAll(pluginList); - this.type = type; - } - - private class PluginViewHolder { - TextView name; - CheckBox checkboxEnabled; - CheckBox checkboxVisible; - ImageView settings; - } - - @NonNull - @Override - public View getView(int position, View view, @NonNull ViewGroup parent) { - - PluginViewHolder holder; - PluginBase plugin = pluginList.get(position); - - if (view == null) { - view = LayoutInflater.from(parent.getContext()).inflate(R.layout.configbuilder_simpleitem, null); - - holder = new PluginViewHolder(); - holder.name = (TextView) view.findViewById(R.id.configbuilder_simpleitem_name); - holder.checkboxEnabled = (CheckBox) view.findViewById(R.id.configbuilder_simpleitem_checkboxenabled); - holder.checkboxVisible = (CheckBox) view.findViewById(R.id.configbuilder_simpleitem_checkboxvisible); - holder.settings = (ImageView) view.findViewById(R.id.configbuilder_simpleitem_settings); - - if (plugin.isEnabled(type) && plugin.getPreferencesId() != -1) - holder.settings.setVisibility(View.VISIBLE); - else - holder.settings.setVisibility(View.INVISIBLE); - - view.setTag(holder); - - holder.checkboxEnabled.setOnClickListener(v -> { - CheckBox cb = (CheckBox) v; - PluginBase plugin1 = (PluginBase) cb.getTag(); - plugin1.setPluginEnabled(type, cb.isChecked()); - plugin1.setFragmentVisible(type, cb.isChecked()); - onEnabledCategoryChanged(plugin1, type); - ConfigBuilderPlugin.getPlugin().storeSettings("CheckedCheckboxEnabled"); - MainApp.bus().post(new EventRefreshGui()); - MainApp.bus().post(new EventConfigBuilderChange()); - ConfigBuilderPlugin.getPlugin().logPluginStatus(); - FabricPrivacy.getInstance().logCustom(new CustomEvent("ConfigurationChange")); - }); - - holder.checkboxVisible.setOnClickListener(v -> { - CheckBox cb = (CheckBox) v; - PluginBase plugin12 = (PluginBase) cb.getTag(); - plugin12.setFragmentVisible(type, cb.isChecked()); - ConfigBuilderPlugin.getPlugin().storeSettings("CheckedCheckboxVisible"); - MainApp.bus().post(new EventRefreshGui()); - ConfigBuilderPlugin.getPlugin().logPluginStatus(); - }); - - holder.settings.setOnClickListener(v -> { - final PluginBase plugin13 = (PluginBase) v.getTag(); - PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", () -> { - Intent i = new Intent(getContext(), PreferencesActivity.class); - i.putExtra("id", plugin13.getPreferencesId()); - startActivity(i); - }, null); - }); - - holder.name.setOnLongClickListener(v -> { - final PluginBase plugin14 = (PluginBase) v.getTag(); - PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", () -> { - Intent i = new Intent(getContext(), PreferencesActivity.class); - i.putExtra("id", plugin14.getPreferencesId()); - startActivity(i); - }, null); - return false; - }); - - } else { - holder = (PluginViewHolder) view.getTag(); - } - - holder.name.setText(plugin.getName()); - holder.checkboxEnabled.setChecked(plugin.isEnabled(type)); - holder.checkboxVisible.setChecked(plugin.isFragmentVisible()); - holder.name.setTag(plugin); - holder.checkboxEnabled.setTag(plugin); - holder.checkboxVisible.setTag(plugin); - holder.settings.setTag(plugin); - - if (plugin.pluginDescription.alwaysEnabled) { - holder.checkboxEnabled.setEnabled(false); - } - - if (plugin.pluginDescription.alwayVisible) { - holder.checkboxEnabled.setEnabled(false); - } - - if (!plugin.isEnabled(type)) { - holder.checkboxVisible.setEnabled(false); - } - - if (!plugin.hasFragment()) { - holder.checkboxVisible.setVisibility(View.INVISIBLE); - } - - // Hide enabled control and force enabled plugin if there is only one plugin available - if (type == PluginType.INSULIN || type == PluginType.PUMP || type == PluginType.SENSITIVITY) - if (pluginList.size() < 2) { - holder.checkboxEnabled.setEnabled(false); - plugin.setPluginEnabled(type, true); - ConfigBuilderPlugin.getPlugin().storeSettings("ForceEnable"); - } - - // Constraints cannot be disabled - if (type == PluginType.CONSTRAINTS) - holder.checkboxEnabled.setEnabled(false); - - // Hide disabled profiles by default - if (type == PluginType.PROFILE) { - if (!plugin.isEnabled(type)) { - holder.checkboxVisible.setEnabled(false); - holder.checkboxVisible.setChecked(false); - } else { - holder.checkboxVisible.setEnabled(true); - } - } - - // Disable profile control for pump profiles if pump is not enabled - if (type == PluginType.PROFILE) { - if (PumpInterface.class.isAssignableFrom(plugin.getClass())) { - if (!plugin.isEnabled(PluginType.PUMP)) { - holder.checkboxEnabled.setEnabled(false); - holder.checkboxEnabled.setChecked(false); - } - } - } - - if (plugin.isEnabled(type)) { - view.setBackgroundColor(MainApp.gc(R.color.configBuilderSelectedBackground)); - } - - return view; + private void createViews() { + createViewsForPlugins(R.string.configbuilder_profile, R.string.configbuilder_profile_description, PluginType.PROFILE, MainApp.getSpecificPluginsVisibleInListByInterface(ProfileInterface.class, PluginType.PROFILE)); + createViewsForPlugins(R.string.configbuilder_insulin, R.string.configbuilder_insulin_description, PluginType.INSULIN, MainApp.getSpecificPluginsVisibleInListByInterface(InsulinInterface.class, PluginType.INSULIN)); + createViewsForPlugins(R.string.configbuilder_bgsource, R.string.configbuilder_bgsource_description, PluginType.BGSOURCE, MainApp.getSpecificPluginsVisibleInListByInterface(BgSourceInterface.class, PluginType.BGSOURCE)); + createViewsForPlugins(R.string.configbuilder_pump, R.string.configbuilder_pump_description, PluginType.PUMP, MainApp.getSpecificPluginsVisibleInList(PluginType.PUMP)); + createViewsForPlugins(R.string.configbuilder_sensitivity, R.string.configbuilder_sensitivity_description, PluginType.SENSITIVITY, MainApp.getSpecificPluginsVisibleInListByInterface(SensitivityInterface.class, PluginType.SENSITIVITY)); + createViewsForPlugins(R.string.configbuilder_aps, R.string.configbuilder_aps_description, PluginType.APS, MainApp.getSpecificPluginsVisibleInList(PluginType.APS)); + createViewsForPlugins(R.string.configbuilder_loop, R.string.configbuilder_loop_description, PluginType.LOOP, MainApp.getSpecificPluginsVisibleInList(PluginType.LOOP)); + createViewsForPlugins(R.string.constraints, R.string.configbuilder_constraints_description, PluginType.CONSTRAINTS, MainApp.getSpecificPluginsVisibleInListByInterface(ConstraintsInterface.class, PluginType.CONSTRAINTS)); + createViewsForPlugins(R.string.configbuilder_treatments, R.string.configbuilder_treatments_description, PluginType.TREATMENT, MainApp.getSpecificPluginsVisibleInList(PluginType.TREATMENT)); + createViewsForPlugins(R.string.configbuilder_general, R.string.configbuilder_general_description, PluginType.GENERAL, MainApp.getSpecificPluginsVisibleInList(PluginType.GENERAL)); + } + private void createViewsForPlugins(@StringRes int title, @StringRes int description, PluginType pluginType, List plugins) { + if (plugins.size() == 0) return; + LinearLayout parent = (LinearLayout) getLayoutInflater().inflate(R.layout.configbuilder_single_category, null); + ((TextView) parent.findViewById(R.id.category_title)).setText(MainApp.gs(title)); + ((TextView) parent.findViewById(R.id.category_description)).setText(MainApp.gs(description)); + LinearLayout pluginContainer = parent.findViewById(R.id.category_plugins); + for (PluginBase plugin: plugins) { + PluginViewHolder pluginViewHolder = new PluginViewHolder(pluginType, plugin); + pluginContainer.addView(pluginViewHolder.getBaseView()); + pluginViewHolders.add(pluginViewHolder); } + categories.addView(parent); + } + private boolean areMultipleSelectionsAllowed(PluginType type) { + return type == PluginType.GENERAL || type == PluginType.CONSTRAINTS ||type == PluginType.LOOP; } public static void processOnEnabledCategoryChanged(PluginBase changedPlugin, PluginType type) { @@ -394,35 +187,100 @@ public class ConfigBuilderFragment extends SubscriberFragment { } } - void onEnabledCategoryChanged(PluginBase changedPlugin, PluginType type) { - processOnEnabledCategoryChanged(changedPlugin, type); - updateGUI(); - } + public class PluginViewHolder { - /**** - * Method for Setting the Height of the ListView dynamically. - * *** Hack to fix the issue of not showing all the items of the ListView - * *** when placed inside a ScrollView - ****/ - public static void setListViewHeightBasedOnChildren(ListView listView) { - ListAdapter listAdapter = listView.getAdapter(); - if (listAdapter == null) - return; + private Unbinder unbinder; + private PluginType pluginType; + private PluginBase plugin; - int desiredWidth = View.MeasureSpec.makeMeasureSpec(listView.getWidth(), View.MeasureSpec.UNSPECIFIED); - int totalHeight = 0; - View view = null; - for (int i = 0; i < listAdapter.getCount(); i++) { - view = listAdapter.getView(i, view, listView); - if (i == 0) - view.setLayoutParams(new ViewGroup.LayoutParams(desiredWidth, ViewGroup.LayoutParams.WRAP_CONTENT)); + LinearLayout baseView; + @BindView(R.id.plugin_enabled_exclusive) + RadioButton enabledExclusive; + @BindView(R.id.plugin_enabled_inclusive) + CheckBox enabledInclusive; + @BindView(R.id.plugin_name) + TextView pluginName; + @BindView(R.id.plugin_description) + TextView pluginDescription; + @BindView(R.id.plugin_preferences) + ImageButton pluginPreferences; + @BindView(R.id.plugin_visibility) + CheckBox pluginVisibility; - view.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED); - totalHeight += view.getMeasuredHeight(); + public PluginViewHolder(PluginType pluginType, PluginBase plugin) { + this.pluginType = pluginType; + this.plugin = plugin; + baseView = (LinearLayout) getLayoutInflater().inflate(R.layout.configbuilder_single_plugin, null); + unbinder = ButterKnife.bind(this, baseView); + update(); } - ViewGroup.LayoutParams params = listView.getLayoutParams(); - params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1)); - listView.setLayoutParams(params); - } + public LinearLayout getBaseView() { + return baseView; + } + + public void update() { + enabledExclusive.setVisibility(areMultipleSelectionsAllowed(pluginType) ? View.GONE : View.VISIBLE); + enabledInclusive.setVisibility(areMultipleSelectionsAllowed(pluginType) ? View.VISIBLE : View.GONE); + enabledExclusive.setChecked(plugin.isEnabled(pluginType)); + enabledInclusive.setChecked(plugin.isEnabled(pluginType)); + enabledInclusive.setEnabled(!plugin.pluginDescription.alwaysEnabled); + enabledExclusive.setEnabled(!plugin.pluginDescription.alwaysEnabled); + pluginName.setText(plugin.getName()); + if (plugin.getDescription() == null) pluginDescription.setVisibility(View.GONE); + else { + pluginDescription.setVisibility(View.VISIBLE); + pluginDescription.setText(plugin.getDescription()); + } + pluginPreferences.setVisibility(plugin.getPreferencesId() == -1 || !plugin.isEnabled(pluginType) ? View.INVISIBLE : View.VISIBLE); + pluginVisibility.setVisibility(plugin.hasFragment() ? View.VISIBLE : View.INVISIBLE); + pluginVisibility.setEnabled(!(plugin.pluginDescription.neverVisible || plugin.pluginDescription.alwayVisible) && plugin.isEnabled(pluginType)); + pluginVisibility.setChecked(plugin.isFragmentVisible()); + } + + @OnClick(R.id.plugin_visibility) + void onVisibilityChanged() { + plugin.setFragmentVisible(pluginType, pluginVisibility.isChecked()); + ConfigBuilderPlugin.getPlugin().storeSettings("CheckedCheckboxVisible"); + MainApp.bus().post(new EventRefreshGui()); + ConfigBuilderPlugin.getPlugin().logPluginStatus(); + } + + @OnClick({R.id.plugin_enabled_exclusive, R.id.plugin_enabled_inclusive}) + void onEnabledChanged() { + plugin.switchAllowed(new PluginSwitcher(), getActivity()); + } + + @OnClick(R.id.plugin_preferences) + void onPluginPreferencesClicked() { + PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", () -> { + Intent i = new Intent(getContext(), PreferencesActivity.class); + i.putExtra("id", plugin.getPreferencesId()); + startActivity(i); + }, null); + } + + public void unbind() { + unbinder.unbind(); + } + + public class PluginSwitcher { + public void invoke() { + boolean enabled = enabledExclusive.getVisibility() == View.VISIBLE ? enabledExclusive.isChecked() : enabledInclusive.isChecked(); + plugin.setPluginEnabled(pluginType, enabled); + plugin.setFragmentVisible(pluginType, enabled); + processOnEnabledCategoryChanged(plugin, pluginType); + updateGUI(); + ConfigBuilderPlugin.getPlugin().storeSettings("CheckedCheckboxEnabled"); + MainApp.bus().post(new EventRefreshGui()); + MainApp.bus().post(new EventConfigBuilderChange()); + ConfigBuilderPlugin.getPlugin().logPluginStatus(); + FabricPrivacy.getInstance().logCustom(new CustomEvent("ConfigurationChange")); + } + + public void cancel(){ + updateGUI(); + } + } + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderPlugin.java index 35130c5209..588ba2ac93 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderPlugin.java @@ -1,35 +1,17 @@ package info.nightscout.androidaps.plugins.ConfigBuilder; -import android.content.Intent; import android.support.annotation.Nullable; -import com.crashlytics.android.answers.CustomEvent; -import com.squareup.otto.Subscribe; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; -import info.nightscout.androidaps.BuildConfig; -import info.nightscout.androidaps.Config; -import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.data.DetailedBolusInfo; -import info.nightscout.androidaps.data.Profile; -import info.nightscout.androidaps.data.ProfileStore; -import info.nightscout.androidaps.data.PumpEnactResult; -import info.nightscout.androidaps.db.CareportalEvent; -import info.nightscout.androidaps.db.ProfileSwitch; -import info.nightscout.androidaps.db.Source; -import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.events.EventAppInitialized; -import info.nightscout.androidaps.events.EventNewBasalProfile; -import info.nightscout.androidaps.events.EventProfileSwitchChange; import info.nightscout.androidaps.interfaces.APSInterface; import info.nightscout.androidaps.interfaces.BgSourceInterface; -import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.InsulinInterface; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginDescription; @@ -37,25 +19,18 @@ import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.ProfileInterface; import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.interfaces.SensitivityInterface; -import info.nightscout.androidaps.interfaces.TreatmentsInterface; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.Insulin.InsulinOrefRapidActingPlugin; -import info.nightscout.androidaps.plugins.Loop.APSResult; -import info.nightscout.androidaps.plugins.Loop.LoopPlugin; -import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity; import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin; -import info.nightscout.androidaps.plugins.SensitivityOref0.SensitivityOref0Plugin; -import info.nightscout.androidaps.queue.Callback; +import info.nightscout.androidaps.plugins.Sensitivity.SensitivityOref0Plugin; import info.nightscout.androidaps.queue.CommandQueue; -import info.nightscout.utils.FabricPrivacy; -import info.nightscout.utils.NSUpload; import info.nightscout.utils.SP; -import info.nightscout.utils.ToastUtils; /** * Created by mike on 05.08.2016. */ public class ConfigBuilderPlugin extends PluginBase { - private static Logger log = LoggerFactory.getLogger(ConfigBuilderPlugin.class); + private Logger log = LoggerFactory.getLogger(L.CONFIGBUILDER); private static ConfigBuilderPlugin configBuilderPlugin; @@ -66,32 +41,26 @@ public class ConfigBuilderPlugin extends PluginBase { } private BgSourceInterface activeBgSource; - private static PumpInterface activePump; - private static ProfileInterface activeProfile; - private static TreatmentsInterface activeTreatments; - private static APSInterface activeAPS; - private static LoopPlugin activeLoop; - private static InsulinInterface activeInsulin; - private static SensitivityInterface activeSensitivity; + private PumpInterface activePump; + private ProfileInterface activeProfile; + private APSInterface activeAPS; + private InsulinInterface activeInsulin; + private SensitivityInterface activeSensitivity; - static public String nightscoutVersionName = ""; - static public Integer nightscoutVersionCode = 0; - static public String nsClientVersionName = ""; - static public Integer nsClientVersionCode = 0; + private ArrayList pluginList; - private static ArrayList pluginList; - - private static CommandQueue commandQueue = new CommandQueue(); + private CommandQueue commandQueue = new CommandQueue(); public ConfigBuilderPlugin() { super(new PluginDescription() .mainType(PluginType.GENERAL) .fragmentClass(ConfigBuilderFragment.class.getName()) - .showInList(false) + .showInList(true) .alwaysEnabled(true) - .alwayVisible(true) + .alwayVisible(false) .pluginName(R.string.configbuilder) .shortName(R.string.configbuilder_shortname) + .description(R.string.description_config_builder) ); } @@ -112,14 +81,25 @@ public class ConfigBuilderPlugin extends PluginBase { pluginList = MainApp.getPluginsList(); upgradeSettings(); loadSettings(); + setAlwaysEnabledPluginsEnabled(); MainApp.bus().post(new EventAppInitialized()); } + private void setAlwaysEnabledPluginsEnabled() { + for (PluginBase plugin : pluginList) { + if (plugin.pluginDescription.alwaysEnabled) + plugin.setPluginEnabled(plugin.getType(), true); + } + storeSettings("setAlwaysEnabledPluginsEnabled"); + } + public void storeSettings(String from) { if (pluginList != null) { - if (Config.logPrefsChange) + if (L.isEnabled(L.CONFIGBUILDER)) log.debug("Storing settings from: " + from); + verifySelectionInCategories(); + for (PluginBase p : pluginList) { PluginType type = p.getType(); if (p.pluginDescription.alwaysEnabled && p.pluginDescription.alwayVisible) @@ -133,23 +113,24 @@ public class ConfigBuilderPlugin extends PluginBase { } } } - verifySelectionInCategories(); } } private void savePref(PluginBase p, PluginType type, boolean storeVisible) { String settingEnabled = "ConfigBuilder_" + type.name() + "_" + p.getClass().getSimpleName() + "_Enabled"; SP.putBoolean(settingEnabled, p.isEnabled(type)); - log.debug("Storing: " + settingEnabled + ":" + p.isEnabled(type)); + if (L.isEnabled(L.CONFIGBUILDER)) + log.debug("Storing: " + settingEnabled + ":" + p.isEnabled(type)); if (storeVisible) { String settingVisible = "ConfigBuilder_" + type.name() + "_" + p.getClass().getSimpleName() + "_Visible"; SP.putBoolean(settingVisible, p.isFragmentVisible()); - log.debug("Storing: " + settingVisible + ":" + p.isFragmentVisible()); + if (L.isEnabled(L.CONFIGBUILDER)) + log.debug("Storing: " + settingVisible + ":" + p.isFragmentVisible()); } } private void loadSettings() { - if (Config.logPrefsChange) + if (L.isEnabled(L.CONFIGBUILDER)) log.debug("Loading stored settings"); for (PluginBase p : pluginList) { PluginType type = p.getType(); @@ -170,7 +151,8 @@ public class ConfigBuilderPlugin extends PluginBase { else if (p.getType() == type && (p.pluginDescription.enableByDefault || p.pluginDescription.alwaysEnabled)) { p.setPluginEnabled(type, true); } - log.debug("Loaded: " + settingEnabled + ":" + p.isEnabled(type)); + if (L.isEnabled(L.CONFIGBUILDER)) + log.debug("Loaded: " + settingEnabled + ":" + p.isEnabled(type)); if (loadVisible) { String settingVisible = "ConfigBuilder_" + type.name() + "_" + p.getClass().getSimpleName() + "_Visible"; if (SP.contains(settingVisible)) @@ -178,7 +160,8 @@ public class ConfigBuilderPlugin extends PluginBase { else if (p.getType() == type && p.pluginDescription.visibleByDefault) { p.setFragmentVisible(type, true); } - log.debug("Loaded: " + settingVisible + ":" + p.isFragmentVisible()); + if (L.isEnabled(L.CONFIGBUILDER)) + log.debug("Loaded: " + settingVisible + ":" + p.isFragmentVisible()); } } @@ -186,10 +169,11 @@ public class ConfigBuilderPlugin extends PluginBase { private void upgradeSettings() { if (!SP.contains("ConfigBuilder_1_NSProfilePlugin_Enabled")) return; - if (Config.logPrefsChange) + if (L.isEnabled(L.CONFIGBUILDER)) log.debug("Upgrading stored settings"); for (PluginBase p : pluginList) { - log.debug("Processing " + p.getName()); + if (L.isEnabled(L.CONFIGBUILDER)) + log.debug("Processing " + p.getName()); for (int type = 1; type < 11; type++) { PluginType newType; switch (type) { @@ -244,7 +228,7 @@ public class ConfigBuilderPlugin extends PluginBase { } } - public static CommandQueue getCommandQueue() { + public CommandQueue getCommandQueue() { return commandQueue; } @@ -256,37 +240,38 @@ public class ConfigBuilderPlugin extends PluginBase { return activeProfile; } - public static InsulinInterface getActiveInsulin() { + public InsulinInterface getActiveInsulin() { return activeInsulin; } - public static APSInterface getActiveAPS() { + public APSInterface getActiveAPS() { return activeAPS; } - public static PumpInterface getActivePump() { + public PumpInterface getActivePump() { return activePump; } - public static SensitivityInterface getActiveSensitivity() { + public SensitivityInterface getActiveSensitivity() { return activeSensitivity; } void logPluginStatus() { - for (PluginBase p : pluginList) { - log.debug(p.getName() + ":" + - (p.isEnabled(PluginType.GENERAL) ? " GENERAL" : "") + - (p.isEnabled(PluginType.TREATMENT) ? " TREATMENT" : "") + - (p.isEnabled(PluginType.SENSITIVITY) ? " SENSITIVITY" : "") + - (p.isEnabled(PluginType.PROFILE) ? " PROFILE" : "") + - (p.isEnabled(PluginType.APS) ? " APS" : "") + - (p.isEnabled(PluginType.PUMP) ? " PUMP" : "") + - (p.isEnabled(PluginType.CONSTRAINTS) ? " CONSTRAINTS" : "") + - (p.isEnabled(PluginType.LOOP) ? " LOOP" : "") + - (p.isEnabled(PluginType.BGSOURCE) ? " BGSOURCE" : "") + - (p.isEnabled(PluginType.INSULIN) ? " INSULIN" : "") - ); - } + if (L.isEnabled(L.CONFIGBUILDER)) + for (PluginBase p : pluginList) { + log.debug(p.getName() + ":" + + (p.isEnabled(PluginType.GENERAL) ? " GENERAL" : "") + + (p.isEnabled(PluginType.TREATMENT) ? " TREATMENT" : "") + + (p.isEnabled(PluginType.SENSITIVITY) ? " SENSITIVITY" : "") + + (p.isEnabled(PluginType.PROFILE) ? " PROFILE" : "") + + (p.isEnabled(PluginType.APS) ? " APS" : "") + + (p.isEnabled(PluginType.PUMP) ? " PUMP" : "") + + (p.isEnabled(PluginType.CONSTRAINTS) ? " CONSTRAINTS" : "") + + (p.isEnabled(PluginType.LOOP) ? " LOOP" : "") + + (p.isEnabled(PluginType.BGSOURCE) ? " BGSOURCE" : "") + + (p.isEnabled(PluginType.INSULIN) ? " INSULIN" : "") + ); + } } private void verifySelectionInCategories() { @@ -301,6 +286,8 @@ public class ConfigBuilderPlugin extends PluginBase { if (activeInsulin == null) { activeInsulin = InsulinOrefRapidActingPlugin.getPlugin(); InsulinOrefRapidActingPlugin.getPlugin().setPluginEnabled(PluginType.INSULIN, true); + if (L.isEnabled(L.CONFIGBUILDER)) + log.debug("Defaulting InsulinOrefRapidActingPlugin"); } this.setFragmentVisiblities(((PluginBase) activeInsulin).getName(), pluginsInCategory, PluginType.INSULIN); @@ -310,6 +297,8 @@ public class ConfigBuilderPlugin extends PluginBase { if (activeSensitivity == null) { activeSensitivity = SensitivityOref0Plugin.getPlugin(); SensitivityOref0Plugin.getPlugin().setPluginEnabled(PluginType.SENSITIVITY, true); + if (L.isEnabled(L.CONFIGBUILDER)) + log.debug("Defaulting SensitivityOref0Plugin"); } this.setFragmentVisiblities(((PluginBase) activeSensitivity).getName(), pluginsInCategory, PluginType.SENSITIVITY); @@ -325,14 +314,12 @@ public class ConfigBuilderPlugin extends PluginBase { if (activePump == null) { activePump = VirtualPumpPlugin.getPlugin(); VirtualPumpPlugin.getPlugin().setPluginEnabled(PluginType.PUMP, true); + if (L.isEnabled(L.CONFIGBUILDER)) + log.debug("Defaulting VirtualPumpPlugin"); } this.setFragmentVisiblities(((PluginBase) activePump).getName(), pluginsInCategory, PluginType.PUMP); - // PluginType.LOOP - activeLoop = this.determineActivePlugin(PluginType.LOOP); - // PluginType.TREATMENT - activeTreatments = this.determineActivePlugin(PluginType.TREATMENT); } /** @@ -386,7 +373,7 @@ public class ConfigBuilderPlugin extends PluginBase { private void setFragmentVisiblities(String activePluginName, ArrayList pluginsInCategory, PluginType pluginType) { - if (Config.logConfigBuilder) + if (L.isEnabled(L.CONFIGBUILDER)) log.debug("Selected interface: " + activePluginName); for (PluginBase p : pluginsInCategory) { if (!p.getName().equals(activePluginName)) { @@ -412,246 +399,4 @@ public class ConfigBuilderPlugin extends PluginBase { return found; } - /** - * expect absolute request and allow both absolute and percent response based on pump capabilities - */ - public void applyTBRRequest(APSResult request, Profile profile, Callback callback) { - if (!request.tempBasalRequested) { - if (callback != null) { - callback.result(new PumpEnactResult().enacted(false).success(true).comment(MainApp.gs(R.string.nochangerequested))).run(); - } - return; - } - - PumpInterface pump = getActivePump(); - - request.rateConstraint = new Constraint<>(request.rate); - request.rate = MainApp.getConstraintChecker().applyBasalConstraints(request.rateConstraint, profile).value(); - - if (!pump.isInitialized()) { - log.debug("applyAPSRequest: " + MainApp.gs(R.string.pumpNotInitialized)); - if (callback != null) { - callback.result(new PumpEnactResult().comment(MainApp.gs(R.string.pumpNotInitialized)).enacted(false).success(false)).run(); - } - return; - } - - if (pump.isSuspended()) { - log.debug("applyAPSRequest: " + MainApp.gs(R.string.pumpsuspended)); - if (callback != null) { - callback.result(new PumpEnactResult().comment(MainApp.gs(R.string.pumpsuspended)).enacted(false).success(false)).run(); - } - return; - } - - if (Config.logCongigBuilderActions) - log.debug("applyAPSRequest: " + request.toString()); - - long now = System.currentTimeMillis(); - TemporaryBasal activeTemp = activeTreatments.getTempBasalFromHistory(now); - if ((request.rate == 0 && request.duration == 0) || Math.abs(request.rate - pump.getBaseBasalRate()) < pump.getPumpDescription().basalStep) { - if (activeTemp != null) { - if (Config.logCongigBuilderActions) - log.debug("applyAPSRequest: cancelTempBasal()"); - getCommandQueue().cancelTempBasal(false, callback); - } else { - if (Config.logCongigBuilderActions) - log.debug("applyAPSRequest: Basal set correctly"); - if (callback != null) { - callback.result(new PumpEnactResult().absolute(request.rate).duration(0) - .enacted(false).success(true).comment(MainApp.gs(R.string.basal_set_correctly))).run(); - } - } - } else if (activeTemp != null - && activeTemp.getPlannedRemainingMinutes() > 5 - && request.duration - activeTemp.getPlannedRemainingMinutes() < 30 - && Math.abs(request.rate - activeTemp.tempBasalConvertedToAbsolute(now, profile)) < pump.getPumpDescription().basalStep) { - if (Config.logCongigBuilderActions) - log.debug("applyAPSRequest: Temp basal set correctly"); - if (callback != null) { - callback.result(new PumpEnactResult().absolute(activeTemp.tempBasalConvertedToAbsolute(now, profile)) - .enacted(false).success(true).duration(activeTemp.getPlannedRemainingMinutes()) - .comment(MainApp.gs(R.string.let_temp_basal_run))).run(); - } - } else { - if (Config.logCongigBuilderActions) - log.debug("applyAPSRequest: setTempBasalAbsolute()"); - getCommandQueue().tempBasalAbsolute(request.rate, request.duration, false, profile, callback); - } - } - - public void applySMBRequest(APSResult request, Callback callback) { - if (!request.bolusRequested) { - return; - } - - long lastBolusTime = activeTreatments.getLastBolusTime(); - if (lastBolusTime != 0 && lastBolusTime + 3 * 60 * 1000 > System.currentTimeMillis()) { - log.debug("SMB requested but still in 3 min interval"); - if (callback != null) { - callback.result(new PumpEnactResult() - .comment(MainApp.gs(R.string.smb_frequency_exceeded)) - .enacted(false).success(false)).run(); - } - return; - } - - PumpInterface pump = getActivePump(); - - if (!pump.isInitialized()) { - log.debug("applySMBRequest: " + MainApp.gs(R.string.pumpNotInitialized)); - if (callback != null) { - callback.result(new PumpEnactResult().comment(MainApp.gs(R.string.pumpNotInitialized)).enacted(false).success(false)).run(); - } - return; - } - - if (pump.isSuspended()) { - log.debug("applySMBRequest: " + MainApp.gs(R.string.pumpsuspended)); - if (callback != null) { - callback.result(new PumpEnactResult().comment(MainApp.gs(R.string.pumpsuspended)).enacted(false).success(false)).run(); - } - return; - } - - if (Config.logCongigBuilderActions) - log.debug("applySMBRequest: " + request.toString()); - - // deliver SMB - DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo(); - detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS; - detailedBolusInfo.insulin = request.smb; - detailedBolusInfo.isSMB = true; - detailedBolusInfo.source = Source.USER; - detailedBolusInfo.deliverAt = request.deliverAt; - if (Config.logCongigBuilderActions) - log.debug("applyAPSRequest: bolus()"); - getCommandQueue().bolus(detailedBolusInfo, callback); - } - - @Subscribe - public void onProfileSwitch(EventProfileSwitchChange ignored) { - getCommandQueue().setProfile(getProfile(), new Callback() { - @Override - public void run() { - if (!result.success) { - Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class); - i.putExtra("soundid", R.raw.boluserror); - i.putExtra("status", result.comment); - i.putExtra("title", MainApp.gs(R.string.failedupdatebasalprofile)); - i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - MainApp.instance().startActivity(i); - } - MainApp.bus().post(new EventNewBasalProfile()); - } - }); - } - - public String getProfileName() { - return getProfileName(System.currentTimeMillis()); - } - - public String getProfileName(boolean customized) { - return getProfileName(System.currentTimeMillis(), customized); - } - - public String getProfileName(long time) { - return getProfileName(time, true); - } - - public String getProfileName(long time, boolean customized) { - ProfileSwitch profileSwitch = activeTreatments.getProfileSwitchFromHistory(time); - if (profileSwitch != null) { - if (profileSwitch.profileJson != null) { - return customized ? profileSwitch.getCustomizedName() : profileSwitch.profileName; - } else { - ProfileStore profileStore = activeProfile.getProfile(); - if (profileStore != null) { - Profile profile = profileStore.getSpecificProfile(profileSwitch.profileName); - if (profile != null) - return profileSwitch.profileName; - } - } - } - return MainApp.gs(R.string.noprofileselected); - } - - public boolean isProfileValid(String from) { - return getProfile() != null && getProfile().isValid(from); - } - - @Nullable - public Profile getProfile() { - return getProfile(System.currentTimeMillis()); - } - - public String getProfileUnits() { - Profile profile = getProfile(); - return profile != null ? profile.getUnits() : Constants.MGDL; - } - - @Nullable - public Profile getProfile(long time) { - if (activeTreatments == null) { - log.debug("getProfile activeTreatments == null: returning null"); - return null; //app not initialized - } - //log.debug("Profile for: " + new Date(time).toLocaleString() + " : " + getProfileName(time)); - ProfileSwitch profileSwitch = activeTreatments.getProfileSwitchFromHistory(time); - if (profileSwitch != null) { - if (profileSwitch.profileJson != null) { - return profileSwitch.getProfileObject(); - } else if (activeProfile.getProfile() != null) { - Profile profile = activeProfile.getProfile().getSpecificProfile(profileSwitch.profileName); - if (profile != null) - return profile; - } - } - if (activeTreatments.getProfileSwitchesFromHistory().size() > 0) { - FabricPrivacy.getInstance().logCustom(new CustomEvent("CatchedError") - .putCustomAttribute("buildversion", BuildConfig.BUILDVERSION) - .putCustomAttribute("version", BuildConfig.VERSION) - .putCustomAttribute("time", time) - .putCustomAttribute("getProfileSwitchesFromHistory", activeTreatments.getProfileSwitchesFromHistory().toString()) - ); - } - log.debug("getProfile at the end: returning null"); - return null; - } - - public void disconnectPump(int durationInMinutes, Profile profile) { - LoopPlugin.getPlugin().disconnectTo(System.currentTimeMillis() + durationInMinutes * 60 * 1000L); - getCommandQueue().tempBasalPercent(0, durationInMinutes, true, profile, new Callback() { - @Override - public void run() { - if (!result.success) { - ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.tempbasaldeliveryerror)); - } - } - }); - if (getActivePump().getPumpDescription().isExtendedBolusCapable && activeTreatments.isInHistoryExtendedBoluslInProgress()) { - getCommandQueue().cancelExtended(new Callback() { - @Override - public void run() { - if (!result.success) { - ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.extendedbolusdeliveryerror)); - } - } - }); - } - NSUpload.uploadOpenAPSOffline(durationInMinutes); - } - - public void suspendLoop(int durationInMinutes) { - LoopPlugin.getPlugin().suspendTo(System.currentTimeMillis() + durationInMinutes * 60 * 1000); - getCommandQueue().cancelTempBasal(true, new Callback() { - @Override - public void run() { - if (!result.success) { - ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.tempbasaldeliveryerror)); - } - } - }); - NSUpload.uploadOpenAPSOffline(durationInMinutes); - } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/DetailedBolusInfoStorage.java b/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/DetailedBolusInfoStorage.java index 7a4e99b584..9b4e1d0a28 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/DetailedBolusInfoStorage.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/DetailedBolusInfoStorage.java @@ -6,17 +6,17 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; -import java.util.Date; import java.util.List; import info.nightscout.androidaps.data.DetailedBolusInfo; +import info.nightscout.androidaps.logging.L; /** * Created by mike on 08.08.2017. */ public class DetailedBolusInfoStorage { - private static Logger log = LoggerFactory.getLogger(DetailedBolusInfoStorage.class); + private static Logger log = LoggerFactory.getLogger(L.PUMP); private static List store = new ArrayList<>(); public static synchronized void add(DetailedBolusInfo detailedBolusInfo) { @@ -29,23 +29,16 @@ public class DetailedBolusInfoStorage { DetailedBolusInfo found = null; for (int i = 0; i < store.size(); i++) { long infoTime = store.get(i).date; - log.debug("Existing bolus info: " + store.get(i)); + if (L.isEnabled(L.PUMP)) + log.debug("Existing bolus info: " + store.get(i)); if (bolustime > infoTime - 60 * 1000 && bolustime < infoTime + 60 * 1000) { found = store.get(i); + if (L.isEnabled(L.PUMP)) + log.debug("Using & removing bolus info: " + store.get(i)); + store.remove(i); break; } } return found; } - - public static synchronized void remove(long bolustime) { - for (int i = 0; i < store.size(); i++) { - long infoTime = store.get(i).date; - if (bolustime > infoTime - 60 * 1000 && bolustime < infoTime + 60 * 1000) { - log.debug("Removing bolus info: " + store.get(i)); - store.remove(i); - break; - } - } - } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ProfileFunctions.java b/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ProfileFunctions.java new file mode 100644 index 0000000000..312c0cd9ae --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ProfileFunctions.java @@ -0,0 +1,142 @@ +package info.nightscout.androidaps.plugins.ConfigBuilder; + +import android.content.Intent; +import android.support.annotation.Nullable; + +import com.crashlytics.android.answers.CustomEvent; +import com.squareup.otto.Subscribe; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import info.nightscout.androidaps.BuildConfig; +import info.nightscout.androidaps.Constants; +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.data.Profile; +import info.nightscout.androidaps.data.ProfileStore; +import info.nightscout.androidaps.db.ProfileSwitch; +import info.nightscout.androidaps.events.EventNewBasalProfile; +import info.nightscout.androidaps.events.EventProfileSwitchChange; +import info.nightscout.androidaps.interfaces.ProfileInterface; +import info.nightscout.androidaps.interfaces.TreatmentsInterface; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity; +import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; +import info.nightscout.androidaps.queue.Callback; +import info.nightscout.utils.FabricPrivacy; + +public class ProfileFunctions { + private static Logger log = LoggerFactory.getLogger(L.PROFILE); + + private static ProfileFunctions profileFunctions = null; + + public static ProfileFunctions getInstance() { + if (profileFunctions == null) + profileFunctions = new ProfileFunctions(); + return profileFunctions; + } + + static { + ProfileFunctions.getInstance(); // register to bus at start + } + + ProfileFunctions() { + MainApp.bus().register(this); + } + + @Subscribe + public void onProfileSwitch(EventProfileSwitchChange ignored) { + if (L.isEnabled(L.PROFILE)) + log.debug("onProfileSwitch"); + ConfigBuilderPlugin.getPlugin().getCommandQueue().setProfile(getProfile(), new Callback() { + @Override + public void run() { + if (!result.success) { + Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class); + i.putExtra("soundid", R.raw.boluserror); + i.putExtra("status", result.comment); + i.putExtra("title", MainApp.gs(R.string.failedupdatebasalprofile)); + i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + MainApp.instance().startActivity(i); + } + MainApp.bus().post(new EventNewBasalProfile()); + } + }); + } + + public String getProfileName() { + return getProfileName(System.currentTimeMillis()); + } + + public String getProfileName(boolean customized) { + return getProfileName(System.currentTimeMillis(), customized); + } + + public String getProfileName(long time) { + return getProfileName(time, true); + } + + public String getProfileName(long time, boolean customized) { + TreatmentsInterface activeTreatments = TreatmentsPlugin.getPlugin(); + ProfileInterface activeProfile = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface(); + + ProfileSwitch profileSwitch = activeTreatments.getProfileSwitchFromHistory(time); + if (profileSwitch != null) { + if (profileSwitch.profileJson != null) { + return customized ? profileSwitch.getCustomizedName() : profileSwitch.profileName; + } else { + ProfileStore profileStore = activeProfile.getProfile(); + if (profileStore != null) { + Profile profile = profileStore.getSpecificProfile(profileSwitch.profileName); + if (profile != null) + return profileSwitch.profileName; + } + } + } + return MainApp.gs(R.string.noprofileselected); + } + + public boolean isProfileValid(String from) { + return getProfile() != null && getProfile().isValid(from); + } + + @Nullable + public Profile getProfile() { + return getProfile(System.currentTimeMillis()); + } + + public String getProfileUnits() { + Profile profile = getProfile(); + return profile != null ? profile.getUnits() : Constants.MGDL; + } + + @Nullable + public Profile getProfile(long time) { + TreatmentsInterface activeTreatments = TreatmentsPlugin.getPlugin(); + ProfileInterface activeProfile = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface(); + + //log.debug("Profile for: " + new Date(time).toLocaleString() + " : " + getProfileName(time)); + ProfileSwitch profileSwitch = activeTreatments.getProfileSwitchFromHistory(time); + if (profileSwitch != null) { + if (profileSwitch.profileJson != null) { + return profileSwitch.getProfileObject(); + } else if (activeProfile.getProfile() != null) { + Profile profile = activeProfile.getProfile().getSpecificProfile(profileSwitch.profileName); + if (profile != null) + return profile; + } + } + if (activeTreatments.getProfileSwitchesFromHistory().size() > 0) { + FabricPrivacy.getInstance().logCustom(new CustomEvent("CatchedError") + .putCustomAttribute("buildversion", BuildConfig.BUILDVERSION) + .putCustomAttribute("version", BuildConfig.VERSION) + .putCustomAttribute("time", time) + .putCustomAttribute("getProfileSwitchesFromHistory", activeTreatments.getProfileSwitchesFromHistory().toString()) + ); + } + log.error("getProfile at the end: returning null"); + return null; + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/ObjectivesFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/ObjectivesFragment.java index 4f2cfa65e0..3dcec0920f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/ObjectivesFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/ObjectivesFragment.java @@ -1,12 +1,15 @@ package info.nightscout.androidaps.plugins.ConstraintsObjectives; import android.app.Activity; -import android.content.Context; import android.os.Bundle; -import android.support.v4.app.Fragment; +import android.os.Handler; +import android.os.Looper; +import android.support.annotation.NonNull; import android.support.v7.widget.CardView; import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.LinearSmoothScroller; import android.support.v7.widget.RecyclerView; +import android.text.Html; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -15,200 +18,28 @@ import android.widget.CheckBox; import android.widget.LinearLayout; import android.widget.TextView; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.util.Date; -import java.util.List; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.plugins.Common.SubscriberFragment; +import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective; import info.nightscout.utils.FabricPrivacy; -import info.nightscout.utils.T; public class ObjectivesFragment extends SubscriberFragment { - private static Logger log = LoggerFactory.getLogger(ObjectivesFragment.class); - RecyclerView recyclerView; - LinearLayoutManager llm; CheckBox enableFake; - LinearLayout fake_layout; TextView reset; + ObjectivesAdapter objectivesAdapter = new ObjectivesAdapter(); + Handler handler = new Handler(Looper.getMainLooper()); - public class RecyclerViewAdapter extends RecyclerView.Adapter { - - List objectives; - - RecyclerViewAdapter(List objectives) { - this.objectives = objectives; - } - + private Runnable objectiveUpdater = new Runnable() { @Override - public ObjectiveViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { - View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.objectives_item, viewGroup, false); - return new ObjectiveViewHolder(v); + public void run() { + handler.postDelayed(this, 60 * 1000); + updateGUI(); } - - @Override - public void onBindViewHolder(ObjectiveViewHolder holder, int position) { - ObjectivesPlugin.Objective o = objectives.get(position); - ObjectivesPlugin.RequirementResult requirementsMet = ObjectivesPlugin.getPlugin().requirementsMet(position); - Context context = MainApp.instance().getApplicationContext(); - holder.position.setText(String.valueOf(position + 1)); - holder.objective.setText(o.objective); - holder.gate.setText(o.gate); - holder.duration.setText(MainApp.gs(R.string.objectives_minimalduration) + " " + o.durationInDays + " " + MainApp.gs(R.string.days)); - holder.progress.setText(requirementsMet.comment); - holder.started.setText(o.started.toLocaleString()); - holder.accomplished.setText(o.accomplished.toLocaleString()); - - holder.startButton.setTag(o); - holder.verifyButton.setTag(o); - - holder.startButton.setOnClickListener(v -> { - ObjectivesPlugin.Objective o1 = (ObjectivesPlugin.Objective) v.getTag(); - o1.started = new Date(); - updateGUI(); - ObjectivesPlugin.saveProgress(); - }); - holder.verifyButton.setOnClickListener(v -> { - ObjectivesPlugin.Objective o12 = (ObjectivesPlugin.Objective) v.getTag(); - if (ObjectivesPlugin.getPlugin().requirementsMet(o12.num).done || enableFake.isChecked()) { - o12.accomplished = new Date(); - updateGUI(); - ObjectivesPlugin.saveProgress(); - } - }); - - long prevObjectiveAccomplishedTime = position > 0 ? - objectives.get(position - 1).accomplished.getTime() : -1; - - int phase = modifyVisibility(position, prevObjectiveAccomplishedTime, - o.started.getTime(), o.durationInDays, - o.accomplished.getTime(), requirementsMet.done, enableFake.isChecked()); - - switch (phase) { - case 0: - // Phase 0: previous not completed - holder.startedLayout.setVisibility(View.GONE); - holder.durationLayout.setVisibility(View.GONE); - holder.progressLayout.setVisibility(View.GONE); - holder.verifyLayout.setVisibility(View.GONE); - break; - case 1: - // Phase 1: not started - holder.durationLayout.setVisibility(View.GONE); - holder.progressLayout.setVisibility(View.GONE); - holder.verifyLayout.setVisibility(View.GONE); - holder.started.setVisibility(View.GONE); - break; - case 2: - // Phase 2: started, waiting for duration and met requirements - holder.startButton.setEnabled(false); - holder.verifyLayout.setVisibility(View.GONE); - break; - case 3: - // Phase 3: started, after duration, requirements met - holder.startButton.setEnabled(false); - holder.accomplished.setVisibility(View.INVISIBLE); - break; - case 4: - // Phase 4: verified - holder.gateLayout.setVisibility(View.GONE); - holder.startedLayout.setVisibility(View.GONE); - holder.durationLayout.setVisibility(View.GONE); - holder.progressLayout.setVisibility(View.GONE); - holder.verifyButton.setVisibility(View.INVISIBLE); - break; - default: - // should not happen - } - } - - - @Override - public int getItemCount() { - return objectives.size(); - } - - @Override - public void onAttachedToRecyclerView(RecyclerView recyclerView) { - super.onAttachedToRecyclerView(recyclerView); - } - - public class ObjectiveViewHolder extends RecyclerView.ViewHolder { - CardView cv; - TextView position; - TextView objective; - LinearLayout gateLayout; - TextView gate; - TextView duration; - LinearLayout durationLayout; - TextView progress; - LinearLayout progressLayout; - TextView started; - Button startButton; - LinearLayout startedLayout; - TextView accomplished; - Button verifyButton; - LinearLayout verifyLayout; - - ObjectiveViewHolder(View itemView) { - super(itemView); - cv = (CardView) itemView.findViewById(R.id.objectives_cardview); - position = (TextView) itemView.findViewById(R.id.objectives_position); - objective = (TextView) itemView.findViewById(R.id.objectives_objective); - durationLayout = (LinearLayout) itemView.findViewById(R.id.objectives_duration_linearlayout); - duration = (TextView) itemView.findViewById(R.id.objectives_duration); - progressLayout = (LinearLayout) itemView.findViewById(R.id.objectives_progresslayout); - progress = (TextView) itemView.findViewById(R.id.objectives_progress); - gateLayout = (LinearLayout) itemView.findViewById(R.id.objectives_gate_linearlayout); - gate = (TextView) itemView.findViewById(R.id.objectives_gate); - startedLayout = (LinearLayout) itemView.findViewById(R.id.objectives_start_linearlayout); - started = (TextView) itemView.findViewById(R.id.objectives_started); - startButton = (Button) itemView.findViewById(R.id.objectives_start); - verifyLayout = (LinearLayout) itemView.findViewById(R.id.objectives_verify_linearlayout); - accomplished = (TextView) itemView.findViewById(R.id.objectives_accomplished); - verifyButton = (Button) itemView.findViewById(R.id.objectives_verify); - } - } - } - - /** - * returns an int, which represents the phase the current objective is at. - * - * this is mainly used for unit-testing the conditions - * - * @param currentPosition - * @param prevObjectiveAccomplishedTime - * @param objectiveStartedTime - * @param durationInDays - * @param objectiveAccomplishedTime - * @param requirementsMet - * @return - */ - public int modifyVisibility(int currentPosition, - long prevObjectiveAccomplishedTime, - long objectiveStartedTime, int durationInDays, - long objectiveAccomplishedTime, boolean requirementsMet, - boolean enableFakeValue) { - Long now = System.currentTimeMillis(); - if (currentPosition > 0 && prevObjectiveAccomplishedTime == 0) { - return 0; - } else if (objectiveStartedTime == 0) { - return 1; - } else if (objectiveStartedTime > 0 && !enableFakeValue - && objectiveAccomplishedTime == 0 - && !(objectiveStartedTime + T.days(durationInDays).msecs() < now && requirementsMet)) { - return 2; - } else if (objectiveAccomplishedTime == 0) { - return 3; - } else { - return 4; - } - } + }; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, @@ -216,45 +47,20 @@ public class ObjectivesFragment extends SubscriberFragment { try { View view = inflater.inflate(R.layout.objectives_fragment, container, false); - recyclerView = (RecyclerView) view.findViewById(R.id.objectives_recyclerview); - recyclerView.setHasFixedSize(true); - llm = new LinearLayoutManager(view.getContext()); - recyclerView.setLayoutManager(llm); - enableFake = (CheckBox) view.findViewById(R.id.objectives_fake); - fake_layout = (LinearLayout) view.findViewById(R.id.objectives_fake_layout); - reset = (TextView) view.findViewById(R.id.objectives_reset); - enableFake.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - updateGUI(); - } + recyclerView = view.findViewById(R.id.objectives_recyclerview); + recyclerView.setLayoutManager(new LinearLayoutManager(view.getContext())); + recyclerView.setAdapter(objectivesAdapter); + enableFake = view.findViewById(R.id.objectives_fake); + reset = view.findViewById(R.id.objectives_reset); + enableFake.setOnClickListener(v -> updateGUI()); + reset.setOnClickListener(v -> { + ObjectivesPlugin.getPlugin().reset(); + ObjectivesPlugin.getPlugin().saveProgress(); + recyclerView.getAdapter().notifyDataSetChanged(); + scrollToCurrentObjective(); }); - reset.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - ObjectivesPlugin.getPlugin().initializeData(); - ObjectivesPlugin.saveProgress(); - updateGUI(); - } - }); - - // Add correct translations to array after app is initialized - ObjectivesPlugin.objectives.get(0).objective = MainApp.gs(R.string.objectives_0_objective); - ObjectivesPlugin.objectives.get(1).objective = MainApp.gs(R.string.objectives_1_objective); - ObjectivesPlugin.objectives.get(2).objective = MainApp.gs(R.string.objectives_2_objective); - ObjectivesPlugin.objectives.get(3).objective = MainApp.gs(R.string.objectives_3_objective); - ObjectivesPlugin.objectives.get(4).objective = MainApp.gs(R.string.objectives_4_objective); - ObjectivesPlugin.objectives.get(5).objective = MainApp.gs(R.string.objectives_5_objective); - ObjectivesPlugin.objectives.get(6).objective = MainApp.gs(R.string.objectives_6_objective); - ObjectivesPlugin.objectives.get(7).objective = MainApp.gs(R.string.objectives_7_objective); - ObjectivesPlugin.objectives.get(0).gate = MainApp.gs(R.string.objectives_0_gate); - ObjectivesPlugin.objectives.get(1).gate = MainApp.gs(R.string.objectives_1_gate); - ObjectivesPlugin.objectives.get(2).gate = MainApp.gs(R.string.objectives_2_gate); - ObjectivesPlugin.objectives.get(3).gate = MainApp.gs(R.string.objectives_3_gate); - ObjectivesPlugin.objectives.get(4).gate = MainApp.gs(R.string.objectives_4_gate); - ObjectivesPlugin.objectives.get(5).gate = MainApp.gs(R.string.objectives_5_gate); - ObjectivesPlugin.objectives.get(7).gate = MainApp.gs(R.string.objectives_7_gate); - - updateGUI(); - + scrollToCurrentObjective(); + startUpdateTimer(); return view; } catch (Exception e) { FabricPrivacy.logException(e); @@ -263,13 +69,142 @@ public class ObjectivesFragment extends SubscriberFragment { return null; } + @Override + public synchronized void onDestroyView() { + super.onDestroyView(); + handler.removeCallbacks(objectiveUpdater); + } + + private void startUpdateTimer() { + handler.removeCallbacks(objectiveUpdater); + for (Objective objective : ObjectivesPlugin.getPlugin().getObjectives()) { + if (objective.isStarted() && !objective.isAccomplished()) { + long timeTillNextMinute = (System.currentTimeMillis() - objective.getStartedOn().getTime()) % (60 * 1000); + handler.postDelayed(objectiveUpdater, timeTillNextMinute); + break; + } + } + } + + private void scrollToCurrentObjective() { + for (int i = 0; i < ObjectivesPlugin.getPlugin().getObjectives().size(); i++) { + Objective objective = ObjectivesPlugin.getPlugin().getObjectives().get(i); + if (!objective.isStarted() || !objective.isAccomplished()) { + RecyclerView.SmoothScroller smoothScroller = new LinearSmoothScroller(getContext()) { + @Override + protected int getVerticalSnapPreference() { + return LinearSmoothScroller.SNAP_TO_START; + } + + @Override + protected int calculateTimeForScrolling(int dx) { + return super.calculateTimeForScrolling(dx) * 4; + } + }; + smoothScroller.setTargetPosition(i); + recyclerView.getLayoutManager().startSmoothScroll(smoothScroller); + break; + } + } + } + + private class ObjectivesAdapter extends RecyclerView.Adapter { + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.objectives_item, parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder holder, int position) { + Objective objective = ObjectivesPlugin.getPlugin().getObjectives().get(position); + holder.title.setText(MainApp.gs(R.string.nth_objective, position + 1)); + if (objective.getObjective() != 0) { + holder.objective.setVisibility(View.VISIBLE); + holder.objective.setText(MainApp.gs(objective.getObjective())); + } else holder.objective.setVisibility(View.GONE); + if (objective.getGate() != 0) { + holder.gate.setVisibility(View.VISIBLE); + holder.gate.setText(MainApp.gs(objective.getGate())); + } else holder.gate.setVisibility(View.GONE); + if (!objective.isStarted()) { + holder.gate.setTextColor(0xFFFFFFFF); + holder.verify.setVisibility(View.GONE); + holder.progress.setVisibility(View.GONE); + if (position == 0 || ObjectivesPlugin.getPlugin().getObjectives().get(position - 1).isAccomplished()) + holder.start.setVisibility(View.VISIBLE); + else holder.start.setVisibility(View.GONE); + } else if (objective.isAccomplished()) { + holder.gate.setTextColor(0xFF4CAF50); + holder.verify.setVisibility(View.GONE); + holder.progress.setVisibility(View.GONE); + holder.start.setVisibility(View.GONE); + } else if (objective.isStarted()) { + holder.gate.setTextColor(0xFFFFFFFF); + holder.verify.setVisibility(View.VISIBLE); + holder.verify.setEnabled(objective.isCompleted() || enableFake.isChecked()); + holder.start.setVisibility(View.GONE); + holder.progress.setVisibility(View.VISIBLE); + holder.progress.removeAllViews(); + for (Objective.Task task : objective.getTasks()) { + if (task.shouldBeIgnored()) continue; + TextView textView = new TextView(holder.progress.getContext()); + textView.setTextColor(0xFFFFFFFF); + String basicHTML = "%2$s: %3$s"; + String formattedHTML = String.format(basicHTML, task.isCompleted() ? "#4CAF50" : "#FF9800", MainApp.gs(task.getTask()), task.getProgress()); + textView.setText(Html.fromHtml(formattedHTML)); + holder.progress.addView(textView, LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); + } + } + holder.verify.setOnClickListener((view) -> { + objective.setAccomplishedOn(new Date()); + notifyDataSetChanged(); + scrollToCurrentObjective(); + startUpdateTimer(); + }); + holder.start.setOnClickListener((view) -> { + objective.setStartedOn(new Date()); + notifyDataSetChanged(); + scrollToCurrentObjective(); + startUpdateTimer(); + }); + } + + @Override + public int getItemCount() { + return ObjectivesPlugin.getPlugin().getObjectives().size(); + } + + public class ViewHolder extends RecyclerView.ViewHolder { + + public CardView cardView; + public TextView title; + public TextView objective; + public TextView gate; + public LinearLayout progress; + public Button verify; + public Button start; + + public ViewHolder(View itemView) { + super(itemView); + cardView = (CardView) itemView; + title = itemView.findViewById(R.id.objective_title); + objective = itemView.findViewById(R.id.objective_objective); + gate = itemView.findViewById(R.id.objective_gate); + progress = itemView.findViewById(R.id.objective_progress); + verify = itemView.findViewById(R.id.objective_verify); + start = itemView.findViewById(R.id.objective_start); + } + } + } + @Override public void updateGUI() { Activity activity = getActivity(); if (activity != null) activity.runOnUiThread(() -> { - RecyclerViewAdapter adapter = new RecyclerViewAdapter(ObjectivesPlugin.objectives); - recyclerView.setAdapter(adapter); + objectivesAdapter.notifyDataSetChanged(); }); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/ObjectivesPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/ObjectivesPlugin.java index 293029b80f..cc50189346 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/ObjectivesPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/ObjectivesPlugin.java @@ -1,44 +1,47 @@ package info.nightscout.androidaps.plugins.ConstraintsObjectives; -import android.content.SharedPreferences; -import android.preference.PreferenceManager; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; -import java.util.Date; import java.util.List; import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.db.DatabaseHelper; -import info.nightscout.androidaps.interfaces.APSInterface; import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.ConstraintsInterface; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.ConstraintsObjectives.events.EventObjectivesSaved; -import info.nightscout.androidaps.plugins.ConstraintsSafety.SafetyPlugin; -import info.nightscout.androidaps.plugins.Loop.LoopPlugin; -import info.nightscout.androidaps.plugins.NSClientInternal.NSClientPlugin; -import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin; -import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; -import info.nightscout.utils.DateUtil; +import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective; +import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective1; +import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective2; +import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective3; +import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective4; +import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective5; +import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective6; +import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective7; +import info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives.Objective8; import info.nightscout.utils.SP; /** * Created by mike on 05.08.2016. */ public class ObjectivesPlugin extends PluginBase implements ConstraintsInterface { - private static Logger log = LoggerFactory.getLogger(ObjectivesPlugin.class); + private static Logger log = LoggerFactory.getLogger(L.CONSTRAINTS); private static ObjectivesPlugin objectivesPlugin; + public List objectives = new ArrayList<>(); + public boolean bgIsAvailableInNS = false; + public boolean pumpStatusIsAvailableInNS = false; + public Integer manualEnacts = 0; + public static ObjectivesPlugin getPlugin() { if (objectivesPlugin == null) { objectivesPlugin = new ObjectivesPlugin(); @@ -46,208 +49,58 @@ public class ObjectivesPlugin extends PluginBase implements ConstraintsInterface return objectivesPlugin; } - public static List objectives; - private ObjectivesPlugin() { super(new PluginDescription() .mainType(PluginType.CONSTRAINTS) .fragmentClass(ObjectivesFragment.class.getName()) - .alwaysEnabled(!Config.NSCLIENT && !Config.G5UPLOADER) - .showInList(!Config.NSCLIENT && !Config.G5UPLOADER) + .alwaysEnabled(!Config.NSCLIENT) + .showInList(!Config.NSCLIENT) .pluginName(R.string.objectives) .shortName(R.string.objectives_shortname) + .description(R.string.description_objectives) ); - initializeData(); + setupObjectives(); loadProgress(); } @Override public boolean specialEnableCondition() { - PumpInterface pump = ConfigBuilderPlugin.getActivePump(); + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); return pump == null || pump.getPumpDescription().isTempBasalCapable; } - public class Objective { - Integer num; - String objective; - String gate; - Date started; - Integer durationInDays; - Date accomplished; - - Objective(Integer num, String objective, String gate, Date started, Integer durationInDays, Date accomplished) { - this.num = num; - this.objective = objective; - this.gate = gate; - this.started = started; - this.durationInDays = durationInDays; - this.accomplished = accomplished; - } - - public void setStarted(Date started) { - this.started = started; - } - - public boolean isStarted() { - return started.getTime() > 0; - } - - boolean isFinished() { - return accomplished.getTime() != 0; - } + private void setupObjectives() { + objectives.add(new Objective1()); + objectives.add(new Objective2()); + objectives.add(new Objective3()); + objectives.add(new Objective4()); + objectives.add(new Objective5()); + objectives.add(new Objective6()); + objectives.add(new Objective7()); + objectives.add(new Objective8()); } - // Objective 0 - public static boolean bgIsAvailableInNS = false; - public static boolean pumpStatusIsAvailableInNS = false; - // Objective 1 - public static Integer manualEnacts = 0; - private static final Integer manualEnactsNeeded = 20; - - class RequirementResult { - boolean done = false; - String comment = ""; - - RequirementResult(boolean done, String comment) { - this.done = done; - this.comment = comment; + public void reset() { + for (Objective objective : objectives) { + objective.setStartedOn(null); + objective.setAccomplishedOn(null); } - } - - private String yesOrNo(boolean yes) { - if (yes) return "☺"; - else return "---"; - } - - RequirementResult requirementsMet(Integer objNum) { - switch (objNum) { - case 0: - boolean isVirtualPump = VirtualPumpPlugin.getPlugin().isEnabled(PluginType.PUMP); - boolean vpUploadEnabled = SP.getBoolean("virtualpump_uploadstatus", false); - boolean vpUploadNeeded = !isVirtualPump || vpUploadEnabled; - boolean hasBGData = DatabaseHelper.lastBg() != null; - - boolean apsEnabled = false; - APSInterface usedAPS = ConfigBuilderPlugin.getActiveAPS(); - if (usedAPS != null && ((PluginBase) usedAPS).isEnabled(PluginType.APS)) - apsEnabled = true; - - boolean profileSwitchExists = TreatmentsPlugin.getPlugin().getProfileSwitchFromHistory(DateUtil.now()) != null; - - return new RequirementResult(hasBGData && bgIsAvailableInNS && pumpStatusIsAvailableInNS && NSClientPlugin.getPlugin().hasWritePermission() && LoopPlugin.getPlugin().isEnabled(PluginType.LOOP) && apsEnabled && vpUploadNeeded && profileSwitchExists, - MainApp.gs(R.string.objectives_bgavailableinns) + ": " + yesOrNo(bgIsAvailableInNS) - + "\n" + MainApp.gs(R.string.nsclienthaswritepermission) + ": " + yesOrNo(NSClientPlugin.getPlugin().hasWritePermission()) - + (isVirtualPump ? "\n" + MainApp.gs(R.string.virtualpump_uploadstatus_title) + ": " + yesOrNo(vpUploadEnabled) : "") - + "\n" + MainApp.gs(R.string.objectives_pumpstatusavailableinns) + ": " + yesOrNo(pumpStatusIsAvailableInNS) - + "\n" + MainApp.gs(R.string.hasbgdata) + ": " + yesOrNo(hasBGData) - + "\n" + MainApp.gs(R.string.loopenabled) + ": " + yesOrNo(LoopPlugin.getPlugin().isEnabled(PluginType.LOOP)) - + "\n" + MainApp.gs(R.string.apsselected) + ": " + yesOrNo(apsEnabled) - + "\n" + MainApp.gs(R.string.activate_profile) + ": " + yesOrNo(profileSwitchExists) - ); - case 1: - return new RequirementResult(manualEnacts >= manualEnactsNeeded, - MainApp.gs(R.string.objectives_manualenacts) + ": " + manualEnacts + "/" + manualEnactsNeeded); - case 2: - return new RequirementResult(true, ""); - case 3: - Constraint closedLoopEnabled = new Constraint<>(true); - SafetyPlugin.getPlugin().isClosedLoopAllowed(closedLoopEnabled); - return new RequirementResult(closedLoopEnabled.value(), MainApp.gs(R.string.closedmodeenabled) + ": " + yesOrNo(closedLoopEnabled.value())); - case 4: - double maxIOB = MainApp.getConstraintChecker().getMaxIOBAllowed().value(); - boolean maxIobSet = maxIOB > 0; - return new RequirementResult(maxIobSet, MainApp.gs(R.string.maxiobset) + ": " + yesOrNo(maxIobSet)); - default: - return new RequirementResult(true, ""); - } - } - - - void initializeData() { bgIsAvailableInNS = false; pumpStatusIsAvailableInNS = false; manualEnacts = 0; - - objectives = new ArrayList<>(); - objectives.add(new Objective(0, - MainApp.gs(R.string.objectives_0_objective), - MainApp.gs(R.string.objectives_0_gate), - new Date(0), - 0, // 0 day - new Date(0))); - objectives.add(new Objective(1, - MainApp.gs(R.string.objectives_1_objective), - MainApp.gs(R.string.objectives_1_gate), - new Date(0), - 7, // 7 days - new Date(0))); - objectives.add(new Objective(2, - MainApp.gs(R.string.objectives_2_objective), - MainApp.gs(R.string.objectives_2_gate), - new Date(0), - 0, // 0 days - new Date(0))); - objectives.add(new Objective(3, - MainApp.gs(R.string.objectives_3_objective), - MainApp.gs(R.string.objectives_3_gate), - new Date(0), - 5, // 5 days - new Date(0))); - objectives.add(new Objective(4, - MainApp.gs(R.string.objectives_4_objective), - MainApp.gs(R.string.objectives_4_gate), - new Date(0), - 1, - new Date(0))); - objectives.add(new Objective(5, - MainApp.gs(R.string.objectives_5_objective), - MainApp.gs(R.string.objectives_5_gate), - new Date(0), - 7, - new Date(0))); - objectives.add(new Objective(6, - MainApp.gs(R.string.objectives_6_objective), - "", - new Date(0), - 28, - new Date(0))); - objectives.add(new Objective(7, - MainApp.gs(R.string.objectives_7_objective), - "", - new Date(0), - 28, - new Date(0))); + saveProgress(); } - public static void saveProgress() { - if (objectives != null) { - SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext()); - SharedPreferences.Editor editor = settings.edit(); - for (int num = 0; num < objectives.size(); num++) { - Objective o = objectives.get(num); - editor.putString("Objectives" + num + "started", Long.toString(o.started.getTime())); - editor.putString("Objectives" + num + "accomplished", Long.toString(o.accomplished.getTime())); - } - editor.putBoolean("Objectives" + "bgIsAvailableInNS", bgIsAvailableInNS); - editor.putBoolean("Objectives" + "pumpStatusIsAvailableInNS", pumpStatusIsAvailableInNS); - editor.putString("Objectives" + "manualEnacts", Integer.toString(manualEnacts)); - editor.apply(); - if (Config.logPrefsChange) - log.debug("Objectives stored"); - MainApp.bus().post(new EventObjectivesSaved()); - } + public void saveProgress() { + SP.putBoolean("Objectives" + "bgIsAvailableInNS", bgIsAvailableInNS); + SP.putBoolean("Objectives" + "pumpStatusIsAvailableInNS", pumpStatusIsAvailableInNS); + SP.putString("Objectives" + "manualEnacts", Integer.toString(manualEnacts)); + if (L.isEnabled(L.CONSTRAINTS)) + log.debug("Objectives stored"); + MainApp.bus().post(new EventObjectivesSaved()); } private void loadProgress() { - for (int num = 0; num < objectives.size(); num++) { - Objective o = objectives.get(num); - try { - o.started = new Date(SP.getLong("Objectives" + num + "started", 0L)); - o.accomplished = new Date(SP.getLong("Objectives" + num + "accomplished", 0L)); - } catch (Exception e) { - log.error("Unhandled exception", e); - } - } bgIsAvailableInNS = SP.getBoolean("Objectives" + "bgIsAvailableInNS", false); pumpStatusIsAvailableInNS = SP.getBoolean("Objectives" + "pumpStatusIsAvailableInNS", false); try { @@ -255,15 +108,19 @@ public class ObjectivesPlugin extends PluginBase implements ConstraintsInterface } catch (Exception e) { log.error("Unhandled exception", e); } - if (Config.logPrefsChange) + if (L.isEnabled(L.CONSTRAINTS)) log.debug("Objectives loaded"); } + public List getObjectives() { + return objectives; + } + /** * Constraints interface **/ @Override - public Constraint isLoopInvokationAllowed(Constraint value) { + public Constraint isLoopInvocationAllowed(Constraint value) { if (!objectives.get(0).isStarted()) value.set(false, String.format(MainApp.gs(R.string.objectivenotstarted), 1), this); return value; @@ -299,7 +156,7 @@ public class ObjectivesPlugin extends PluginBase implements ConstraintsInterface @Override public Constraint applyMaxIOBConstraints(Constraint maxIob) { - if (objectives.get(3).isStarted() && !objectives.get(3).isFinished()) + if (objectives.get(3).isStarted() && !objectives.get(3).isAccomplished()) maxIob.set(0d, String.format(MainApp.gs(R.string.objectivenotfinished), 4), this); return maxIob; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/objectives/Objective.java b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/objectives/Objective.java new file mode 100644 index 0000000000..5127f64b34 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/objectives/Objective.java @@ -0,0 +1,141 @@ +package info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives; + +import android.support.annotation.StringRes; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.utils.SP; +import info.nightscout.utils.T; + +public abstract class Objective { + + private int number; + @StringRes + private int objective; + @StringRes + private int gate; + private Date startedOn; + private Date accomplishedOn; + private List tasks = new ArrayList<>(); + + public Objective(int number, @StringRes int objective, @StringRes int gate) { + this.number = number; + this.objective = objective; + this.gate = gate; + startedOn = new Date(SP.getLong("Objectives" + number + "started", 0L)); + if (startedOn.getTime() == 0L) startedOn = null; + accomplishedOn = new Date(SP.getLong("Objectives" + number + "accomplished", 0L)); + if (accomplishedOn.getTime() == 0L) accomplishedOn = null; + setupTasks(tasks); + for (Task task : tasks) task.objective = this; + } + + public boolean isCompleted() { + for (Task task : tasks) { + if (!task.shouldBeIgnored() && !task.isCompleted()) + return false; + } + return true; + } + + public boolean isAccomplished() { + return accomplishedOn != null; + } + + public boolean isStarted() { + return startedOn != null; + } + + public Date getStartedOn() { + return startedOn; + } + + public int getObjective() { + return objective; + } + + public int getGate() { + return gate; + } + + public void setStartedOn(Date startedOn) { + this.startedOn = startedOn; + SP.putLong("Objectives" + number + "started", startedOn == null ? 0 : startedOn.getTime()); + } + + public void setAccomplishedOn(Date accomplishedOn) { + this.accomplishedOn = accomplishedOn; + SP.putLong("Objectives" + number + "accomplished", accomplishedOn == null ? 0 : accomplishedOn.getTime()); + } + + protected void setupTasks(List tasks) { + + } + + public List getTasks() { + return tasks; + } + + public abstract class Task { + @StringRes + private int task; + private Objective objective; + + public Task(@StringRes int task) { + this.task = task; + } + + public int getTask() { + return task; + } + + protected Objective getObjective() { + return objective; + } + + public abstract boolean isCompleted(); + + public String getProgress() { + return MainApp.gs(isCompleted() ? R.string.completed_well_done : R.string.not_completed_yet); + } + + public boolean shouldBeIgnored() { + return false; + } + } + + public class MinimumDurationTask extends Task { + + private long minimumDuration; + + public MinimumDurationTask(long minimumDuration) { + super(R.string.time_elapsed); + this.minimumDuration = minimumDuration; + } + + @Override + public boolean isCompleted() { + return getObjective().isStarted() && System.currentTimeMillis() - getObjective().getStartedOn().getTime() >= minimumDuration; + } + + @Override + public String getProgress() { + return getDurationText(System.currentTimeMillis() - getObjective().getStartedOn().getTime()) + + " / " + getDurationText(minimumDuration); + } + + private String getDurationText(long duration) { + int days = (int) Math.floor((double) duration / T.days(1).msecs()); + int hours = (int) Math.floor((double) duration / T.hours(1).msecs()); + int minutes = (int) Math.floor((double) duration / T.mins(1).msecs()); + if (days > 0) return MainApp.gq(R.plurals.objective_days, days, days); + else if (hours > 0) return MainApp.gq(R.plurals.objective_hours, hours, hours); + else return MainApp.gq(R.plurals.objective_minutes, minutes, minutes); + } + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/objectives/Objective1.java b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/objectives/Objective1.java new file mode 100644 index 0000000000..39127c4d45 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/objectives/Objective1.java @@ -0,0 +1,84 @@ +package info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives; + +import java.util.List; + +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.db.DatabaseHelper; +import info.nightscout.androidaps.interfaces.APSInterface; +import info.nightscout.androidaps.interfaces.PluginBase; +import info.nightscout.androidaps.interfaces.PluginType; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin; +import info.nightscout.androidaps.plugins.Loop.LoopPlugin; +import info.nightscout.androidaps.plugins.NSClientInternal.NSClientPlugin; +import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin; +import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; +import info.nightscout.utils.DateUtil; +import info.nightscout.utils.SP; + +public class Objective1 extends Objective { + + public Objective1() { + super(0, R.string.objectives_0_objective, R.string.objectives_0_gate); + } + + @Override + protected void setupTasks(List tasks) { + tasks.add(new Task(R.string.objectives_bgavailableinns) { + @Override + public boolean isCompleted() { + return ObjectivesPlugin.getPlugin().bgIsAvailableInNS; + } + }); + tasks.add(new Task(R.string.nsclienthaswritepermission) { + @Override + public boolean isCompleted() { + return NSClientPlugin.getPlugin().hasWritePermission(); + } + }); + tasks.add(new Task(R.string.virtualpump_uploadstatus_title) { + @Override + public boolean isCompleted() { + return SP.getBoolean("virtualpump_uploadstatus", false); + } + + @Override + public boolean shouldBeIgnored() { + return !VirtualPumpPlugin.getPlugin().isEnabled(PluginType.PUMP); + } + }); + tasks.add(new Task(R.string.objectives_pumpstatusavailableinns) { + @Override + public boolean isCompleted() { + return ObjectivesPlugin.getPlugin().pumpStatusIsAvailableInNS; + } + }); + tasks.add(new Task(R.string.hasbgdata) { + @Override + public boolean isCompleted() { + return DatabaseHelper.lastBg() != null; + } + }); + tasks.add(new Task(R.string.loopenabled) { + @Override + public boolean isCompleted() { + return LoopPlugin.getPlugin().isEnabled(PluginType.LOOP); + } + }); + tasks.add(new Task(R.string.apsselected) { + @Override + public boolean isCompleted() { + APSInterface usedAPS = ConfigBuilderPlugin.getPlugin().getActiveAPS(); + if (usedAPS != null && ((PluginBase) usedAPS).isEnabled(PluginType.APS)) + return true; + return false; + } + }); + tasks.add(new Task(R.string.activate_profile) { + @Override + public boolean isCompleted() { + return TreatmentsPlugin.getPlugin().getProfileSwitchFromHistory(DateUtil.now()) != null; + } + }); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/objectives/Objective2.java b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/objectives/Objective2.java new file mode 100644 index 0000000000..ac5485f953 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/objectives/Objective2.java @@ -0,0 +1,36 @@ +package info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives; + +import java.util.List; + +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin; +import info.nightscout.utils.T; + +public class Objective2 extends Objective { + + public final int MANUAL_ENACTS_NEEDED = 20; + + public Objective2() { + super(1, R.string.objectives_1_objective, R.string.objectives_1_gate); + } + + @Override + protected void setupTasks(List tasks) { + tasks.add(new MinimumDurationTask(T.days(7).msecs())); + tasks.add(new Task(R.string.objectives_manualenacts) { + @Override + public boolean isCompleted() { + return ObjectivesPlugin.getPlugin().manualEnacts >= MANUAL_ENACTS_NEEDED; + } + + @Override + public String getProgress() { + if (ObjectivesPlugin.getPlugin().manualEnacts >= MANUAL_ENACTS_NEEDED) + return MainApp.gs(R.string.completed_well_done); + else + return ObjectivesPlugin.getPlugin().manualEnacts + " / " + MANUAL_ENACTS_NEEDED; + } + }); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/objectives/Objective3.java b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/objectives/Objective3.java new file mode 100644 index 0000000000..8a84e3c83c --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/objectives/Objective3.java @@ -0,0 +1,10 @@ +package info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives; + +import info.nightscout.androidaps.R; + +public class Objective3 extends Objective { + + public Objective3() { + super(2, R.string.objectives_2_objective, R.string.objectives_2_gate); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/objectives/Objective4.java b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/objectives/Objective4.java new file mode 100644 index 0000000000..4cac10e514 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/objectives/Objective4.java @@ -0,0 +1,28 @@ +package info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives; + +import java.util.List; + +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.interfaces.Constraint; +import info.nightscout.androidaps.plugins.ConstraintsSafety.SafetyPlugin; +import info.nightscout.utils.T; + +public class Objective4 extends Objective { + + public Objective4() { + super(3, R.string.objectives_3_objective, R.string.objectives_3_gate); + } + + @Override + protected void setupTasks(List tasks) { + tasks.add(new MinimumDurationTask(T.days(5).msecs())); + tasks.add(new Task(R.string.closedmodeenabled) { + @Override + public boolean isCompleted() { + Constraint closedLoopEnabled = new Constraint<>(true); + SafetyPlugin.getPlugin().isClosedLoopAllowed(closedLoopEnabled); + return closedLoopEnabled.value(); + } + }); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/objectives/Objective5.java b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/objectives/Objective5.java new file mode 100644 index 0000000000..8472f26c6c --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/objectives/Objective5.java @@ -0,0 +1,26 @@ +package info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives; + +import java.util.List; + +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.utils.T; + +public class Objective5 extends Objective { + + public Objective5() { + super(4, R.string.objectives_4_objective, R.string.objectives_4_gate); + } + + @Override + protected void setupTasks(List tasks) { + tasks.add(new MinimumDurationTask(T.days(1).msecs())); + tasks.add(new Task(R.string.maxiobset) { + @Override + public boolean isCompleted() { + double maxIOB = MainApp.getConstraintChecker().getMaxIOBAllowed().value(); + return maxIOB > 0; + } + }); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/objectives/Objective6.java b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/objectives/Objective6.java new file mode 100644 index 0000000000..7867b28e70 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/objectives/Objective6.java @@ -0,0 +1,18 @@ +package info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives; + +import java.util.List; + +import info.nightscout.androidaps.R; +import info.nightscout.utils.T; + +public class Objective6 extends Objective { + + public Objective6() { + super(5, R.string.objectives_5_objective, R.string.objectives_5_gate); + } + + @Override + protected void setupTasks(List tasks) { + tasks.add(new MinimumDurationTask(T.days(7).msecs())); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/objectives/Objective7.java b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/objectives/Objective7.java new file mode 100644 index 0000000000..670cffe746 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/objectives/Objective7.java @@ -0,0 +1,18 @@ +package info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives; + +import java.util.List; + +import info.nightscout.androidaps.R; +import info.nightscout.utils.T; + +public class Objective7 extends Objective { + + public Objective7() { + super(6, R.string.objectives_6_objective, 0); + } + + @Override + protected void setupTasks(List tasks) { + tasks.add(new MinimumDurationTask(T.days(28).msecs())); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/objectives/Objective8.java b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/objectives/Objective8.java new file mode 100644 index 0000000000..9ac4f9b6d7 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/objectives/Objective8.java @@ -0,0 +1,18 @@ +package info.nightscout.androidaps.plugins.ConstraintsObjectives.objectives; + +import java.util.List; + +import info.nightscout.androidaps.R; +import info.nightscout.utils.T; + +public class Objective8 extends Objective { + + public Objective8() { + super(7, R.string.objectives_7_objective, R.string.objectives_7_gate); + } + + @Override + protected void setupTasks(List tasks) { + tasks.add(new MinimumDurationTask(T.days(28).msecs())); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsSafety/SafetyPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsSafety/SafetyPlugin.java index 6a9613e92a..a1a9d5ff6e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsSafety/SafetyPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsSafety/SafetyPlugin.java @@ -10,12 +10,15 @@ import info.nightscout.androidaps.interfaces.ConstraintsInterface; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginType; +import info.nightscout.androidaps.interfaces.PumpDescription; +import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.OpenAPSAMA.OpenAPSAMAPlugin; import info.nightscout.androidaps.plugins.OpenAPSMA.OpenAPSMAPlugin; import info.nightscout.androidaps.plugins.OpenAPSSMB.OpenAPSSMBPlugin; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.Overview.notifications.Notification; +import info.nightscout.androidaps.plugins.Sensitivity.SensitivityOref1Plugin; import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.HardLimits; import info.nightscout.utils.Round; @@ -49,15 +52,15 @@ public class SafetyPlugin extends PluginBase implements ConstraintsInterface { * Constraints interface **/ @Override - public Constraint isLoopInvokationAllowed(Constraint value) { - if (!ConfigBuilderPlugin.getActivePump().getPumpDescription().isTempBasalCapable) + public Constraint isLoopInvocationAllowed(Constraint value) { + if (!ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().isTempBasalCapable) value.set(false, MainApp.gs(R.string.pumpisnottempbasalcapable), this); return value; } @Override public Constraint isClosedLoopAllowed(Constraint value) { - String mode = SP.getString("aps_mode", "open"); + String mode = SP.getString(R.string.key_aps_mode, "open"); if (!mode.equals("closed")) value.set(false, MainApp.gs(R.string.closedmodedisabledinpreferences), this); @@ -92,9 +95,20 @@ public class SafetyPlugin extends PluginBase implements ConstraintsInterface { return value; } + @Override + public Constraint isUAMEnabled(Constraint value) { + boolean enabled = SP.getBoolean(R.string.key_use_uam, false); + if (!enabled) + value.set(false, MainApp.gs(R.string.uamdisabledinpreferences), this); + boolean oref1Enabled = SensitivityOref1Plugin.getPlugin().isEnabled(PluginType.SENSITIVITY); + if (!oref1Enabled) + value.set(false, MainApp.gs(R.string.uamdisabledoref1notselected), this); + return value; + } + @Override public Constraint isAdvancedFilteringEnabled(Constraint value) { - BgSourceInterface bgSource = MainApp.getConfigBuilder().getActiveBgSource(); + BgSourceInterface bgSource = ConfigBuilderPlugin.getPlugin().getActiveBgSource(); if (bgSource != null) { if (!bgSource.advancedFilteringSupported()) @@ -121,6 +135,18 @@ public class SafetyPlugin extends PluginBase implements ConstraintsInterface { absoluteRate.setIfSmaller(maxFromDaily, String.format(MainApp.gs(R.string.limitingbasalratio), maxFromDaily, MainApp.gs(R.string.maxdailybasalmultiplier)), this); absoluteRate.setIfSmaller(HardLimits.maxBasal(), String.format(MainApp.gs(R.string.limitingbasalratio), HardLimits.maxBasal(), MainApp.gs(R.string.hardlimit)), this); + + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); + // check for pump max + if (pump != null && pump.getPumpDescription().tempBasalStyle == PumpDescription.ABSOLUTE) { + double pumpLimit = pump.getPumpDescription().pumpType.getTbrSettings().getMaxDose(); + absoluteRate.setIfSmaller(pumpLimit, String.format(MainApp.gs(R.string.limitingbasalratio), pumpLimit, MainApp.gs(R.string.pumplimit)), this); + } + + // do rounding + if (pump != null && pump.getPumpDescription().tempBasalStyle == PumpDescription.ABSOLUTE) { + absoluteRate.set(Round.roundTo(absoluteRate.value(), pump.getPumpDescription().tempAbsoluteStep)); + } return absoluteRate; } @@ -136,13 +162,23 @@ public class SafetyPlugin extends PluginBase implements ConstraintsInterface { applyBasalConstraints(absoluteConstraint, profile); percentRate.copyReasons(absoluteConstraint); + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); + Integer percentRateAfterConst = Double.valueOf(absoluteConstraint.value() / currentBasal * 100).intValue(); - if (percentRateAfterConst < 100) - percentRateAfterConst = Round.ceilTo((double) percentRateAfterConst, 10d).intValue(); - else percentRateAfterConst = Round.floorTo((double) percentRateAfterConst, 10d).intValue(); + if (pump != null) { + if (percentRateAfterConst < 100) + percentRateAfterConst = Round.ceilTo((double) percentRateAfterConst, (double) pump.getPumpDescription().tempPercentStep).intValue(); + else + percentRateAfterConst = Round.floorTo((double) percentRateAfterConst, (double) pump.getPumpDescription().tempPercentStep).intValue(); + } percentRate.set(percentRateAfterConst, String.format(MainApp.gs(R.string.limitingpercentrate), percentRateAfterConst, MainApp.gs(R.string.pumplimit)), this); + if (pump != null && pump.getPumpDescription().tempBasalStyle == PumpDescription.PERCENT) { + double pumpLimit = pump.getPumpDescription().pumpType.getTbrSettings().getMaxDose(); + percentRate.setIfSmaller((int) pumpLimit, String.format(MainApp.gs(R.string.limitingbasalratio), pumpLimit, MainApp.gs(R.string.pumplimit)), this); + } + return percentRate; } @@ -154,6 +190,29 @@ public class SafetyPlugin extends PluginBase implements ConstraintsInterface { insulin.setIfSmaller(maxBolus, String.format(MainApp.gs(R.string.limitingbolus), maxBolus, MainApp.gs(R.string.maxvalueinpreferences)), this); insulin.setIfSmaller(HardLimits.maxBolus(), String.format(MainApp.gs(R.string.limitingbolus), HardLimits.maxBolus(), MainApp.gs(R.string.hardlimit)), this); + + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); + if (pump != null) { + double rounded = Round.roundTo(insulin.value(), pump.getPumpDescription().pumpType.determineCorrectBolusSize(insulin.value())); + insulin.setIfDifferent(rounded, MainApp.gs(R.string.pumplimit), this); + } + return insulin; + } + + @Override + public Constraint applyExtendedBolusConstraints(Constraint 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; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Food/FoodFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Food/FoodFragment.java index 1acf6ea083..677fac5fb2 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Food/FoodFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Food/FoodFragment.java @@ -33,7 +33,7 @@ import info.nightscout.androidaps.R; import info.nightscout.androidaps.events.EventFoodDatabaseChanged; import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.utils.FabricPrivacy; -import info.nightscout.utils.NSUpload; +import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; import info.nightscout.utils.SpinnerHelper; /** diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Food/FoodPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Food/FoodPlugin.java index 14eb318af4..84996f1a37 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Food/FoodPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Food/FoodPlugin.java @@ -26,6 +26,7 @@ public class FoodPlugin extends PluginBase { .fragmentClass(FoodFragment.class.getName()) .pluginName(R.string.food) .shortName(R.string.food_short) + .description(R.string.description_food) ); this.service = new FoodService(); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Food/FoodService.java b/app/src/main/java/info/nightscout/androidaps/plugins/Food/FoodService.java index 44b96850ae..b2e23dfd69 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Food/FoodService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Food/FoodService.java @@ -33,13 +33,14 @@ import info.nightscout.androidaps.db.ICallback; import info.nightscout.androidaps.events.Event; import info.nightscout.androidaps.events.EventFoodDatabaseChanged; import info.nightscout.androidaps.events.EventNsFood; +import info.nightscout.androidaps.logging.L; /** * Created by mike on 24.09.2017. */ public class FoodService extends OrmLiteBaseService { - private static Logger log = LoggerFactory.getLogger(FoodService.class); + private Logger log = LoggerFactory.getLogger(L.DATAFOOD); private static final ScheduledExecutorService foodEventWorker = Executors.newSingleThreadScheduledExecutor(); private static ScheduledFuture scheduledFoodEventPost = null; @@ -110,7 +111,8 @@ public class FoodService extends OrmLiteBaseService { public void onCreate() { super.onCreate(); try { - log.info("onCreate"); + if (L.isEnabled(L.DATAFOOD)) + log.info("onCreate"); TableUtils.createTableIfNotExists(this.getConnectionSource(), Food.class); } catch (SQLException e) { log.error("Can't create database", e); @@ -119,12 +121,9 @@ public class FoodService extends OrmLiteBaseService { } public void onUpgrade(ConnectionSource connectionSource, int oldVersion, int newVersion) { - if (oldVersion == 7 && newVersion == 8) { - log.debug("Upgrading database from v7 to v8"); - } else { + if (L.isEnabled(L.DATAFOOD)) log.info("onUpgrade"); // this.resetFood(); - } } public void onDowngrade(ConnectionSource connectionSource, int oldVersion, int newVersion) { @@ -161,7 +160,8 @@ public class FoodService extends OrmLiteBaseService { class PostRunnable implements Runnable { public void run() { - log.debug("Firing EventFoodChange"); + if (L.isEnabled(L.DATAFOOD)) + log.debug("Firing EventFoodChange"); MainApp.bus().post(event); callback.setPost(null); } @@ -271,7 +271,8 @@ public class FoodService extends OrmLiteBaseService { public void deleteByNSId(String _id) throws SQLException { Food stored = this.findByNSId(_id); if (stored != null) { - log.debug("FOOD: Removing Food record from database: " + stored.toString()); + if (L.isEnabled(L.DATAFOOD)) + log.debug("Removing Food record from database: " + stored.toString()); this.delete(stored); } } @@ -324,7 +325,8 @@ public class FoodService extends OrmLiteBaseService { public void createOrUpdate(Food food) { try { this.getDao().createOrUpdate(food); - log.debug("FOOD: Created or Updated: " + food.toString()); + if (L.isEnabled(L.DATAFOOD)) + log.debug("Created or Updated: " + food.toString()); } catch (SQLException e) { log.error("Unable to createOrUpdate Food", e); } @@ -334,7 +336,8 @@ public class FoodService extends OrmLiteBaseService { public void create(Food food) { try { this.getDao().create(food); - log.debug("FOOD: New record: " + food.toString()); + if (L.isEnabled(L.DATAFOOD)) + log.debug("New record: " + food.toString()); } catch (SQLException e) { log.error("Unable to create Food", e); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinFragment.java index a524a5b318..79db5e1a8b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinFragment.java @@ -50,10 +50,10 @@ public class InsulinFragment extends Fragment { } private void updateGUI() { - insulinName.setText(ConfigBuilderPlugin.getActiveInsulin().getFriendlyName()); - insulinComment.setText(ConfigBuilderPlugin.getActiveInsulin().getComment()); - insulinDia.setText(MainApp.gs(R.string.dia) + " " + Double.toString(ConfigBuilderPlugin.getActiveInsulin().getDia()) + "h"); - insulinGraph.show(ConfigBuilderPlugin.getActiveInsulin()); + insulinName.setText(ConfigBuilderPlugin.getPlugin().getActiveInsulin().getFriendlyName()); + insulinComment.setText(ConfigBuilderPlugin.getPlugin().getActiveInsulin().getComment()); + insulinDia.setText(MainApp.gs(R.string.dia) + " " + Double.toString(ConfigBuilderPlugin.getPlugin().getActiveInsulin().getDia()) + "h"); + insulinGraph.show(ConfigBuilderPlugin.getPlugin().getActiveInsulin()); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefBasePlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefBasePlugin.java index 2c46cd7bb6..a2d80efd68 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefBasePlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefBasePlugin.java @@ -5,6 +5,7 @@ import com.squareup.otto.Bus; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.Iob; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.Treatments.Treatment; import info.nightscout.androidaps.interfaces.InsulinInterface; import info.nightscout.androidaps.interfaces.PluginBase; @@ -29,6 +30,7 @@ public abstract class InsulinOrefBasePlugin extends PluginBase implements Insuli .fragmentClass(InsulinFragment.class.getName()) .pluginName(R.string.fastactinginsulin) .shortName(R.string.insulin_shortname) + .visibleByDefault(false) ); } @@ -60,7 +62,7 @@ public abstract class InsulinOrefBasePlugin extends PluginBase implements Insuli } public double getUserDefinedDia() { - return MainApp.getConfigBuilder().getProfile() != null ? MainApp.getConfigBuilder().getProfile().getDia() : MIN_DIA; + return ProfileFunctions.getInstance().getProfile() != null ? ProfileFunctions.getInstance().getProfile().getDia() : MIN_DIA; } public Iob iobCalcForTreatment(Treatment treatment, long time) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefFreePeakPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefFreePeakPlugin.java index a710f742a7..c1fc44438f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefFreePeakPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefFreePeakPlugin.java @@ -24,7 +24,8 @@ public class InsulinOrefFreePeakPlugin extends InsulinOrefBasePlugin { super(); pluginDescription .pluginName(R.string.free_peak_oref) - .preferencesId(R.xml.pref_insulinoreffreepeak); + .preferencesId(R.xml.pref_insulinoreffreepeak) + .description(R.string.description_insulin_free_peak); } @Override diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefRapidActingPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefRapidActingPlugin.java index a8f9761771..c275aef3fd 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefRapidActingPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefRapidActingPlugin.java @@ -22,7 +22,8 @@ public class InsulinOrefRapidActingPlugin extends InsulinOrefBasePlugin { private InsulinOrefRapidActingPlugin() { super(); pluginDescription - .pluginName(R.string.rapid_acting_oref); + .pluginName(R.string.rapid_acting_oref) + .description(R.string.description_insulin_rapid); } @Override diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefUltraRapidActingPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefUltraRapidActingPlugin.java index ba5fc99011..94e5910470 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefUltraRapidActingPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefUltraRapidActingPlugin.java @@ -22,7 +22,8 @@ public class InsulinOrefUltraRapidActingPlugin extends InsulinOrefBasePlugin { private InsulinOrefUltraRapidActingPlugin() { super(); pluginDescription - .pluginName(R.string.ultrarapid_oref); + .pluginName(R.string.ultrarapid_oref) + .description(R.string.description_insulin_ultra_rapid); } @Override diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/AutosensData.java b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/AutosensData.java index 79ab63e2ac..56af4ba12f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/AutosensData.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/AutosensData.java @@ -12,13 +12,16 @@ import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.interfaces.PluginType; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.OpenAPSSMB.SMBDefaults; import info.nightscout.androidaps.plugins.Overview.graphExtensions.DataPointWithLabelInterface; import info.nightscout.androidaps.plugins.Overview.graphExtensions.PointsWithLabelGraphSeries; import info.nightscout.androidaps.plugins.Overview.graphExtensions.Scale; -import info.nightscout.androidaps.plugins.SensitivityAAPS.SensitivityAAPSPlugin; -import info.nightscout.androidaps.plugins.SensitivityWeightedAverage.SensitivityWeightedAveragePlugin; +import info.nightscout.androidaps.plugins.Sensitivity.SensitivityAAPSPlugin; +import info.nightscout.androidaps.plugins.Sensitivity.SensitivityWeightedAveragePlugin; import info.nightscout.androidaps.plugins.Treatments.Treatment; +import info.nightscout.utils.DateUtil; import info.nightscout.utils.SP; /** @@ -26,7 +29,7 @@ import info.nightscout.utils.SP; */ public class AutosensData implements DataPointWithLabelInterface { - private static Logger log = LoggerFactory.getLogger(AutosensData.class); + private static Logger log = LoggerFactory.getLogger(L.AUTOSENS); public void setChartTime(long chartTime) { this.chartTime = chartTime; @@ -38,29 +41,42 @@ public class AutosensData implements DataPointWithLabelInterface { double min5minCarbImpact = 0d; double remaining = 0d; - public CarbsInPast(Treatment t) { + CarbsInPast(Treatment t) { time = t.date; carbs = t.carbs; remaining = t.carbs; if (SensitivityAAPSPlugin.getPlugin().isEnabled(PluginType.SENSITIVITY) || SensitivityWeightedAveragePlugin.getPlugin().isEnabled(PluginType.SENSITIVITY)) { double maxAbsorptionHours = SP.getDouble(R.string.key_absorption_maxtime, Constants.DEFAULT_MAX_ABSORPTION_TIME); - Profile profile = MainApp.getConfigBuilder().getProfile(t.date); + Profile profile = ProfileFunctions.getInstance().getProfile(t.date); double sens = Profile.toMgdl(profile.getIsf(t.date), profile.getUnits()); double ic = profile.getIc(t.date); min5minCarbImpact = t.carbs / (maxAbsorptionHours * 60 / 5) * sens / ic; - log.debug("Min 5m carbs impact for " + carbs + "g @" + new Date(t.date).toLocaleString() + " for " + maxAbsorptionHours + "h calculated to " + min5minCarbImpact + " ISF: " + sens + " IC: " + ic); + if (L.isEnabled(L.AUTOSENS)) + log.debug("Min 5m carbs impact for " + carbs + "g @" + new Date(t.date).toLocaleString() + " for " + maxAbsorptionHours + "h calculated to " + min5minCarbImpact + " ISF: " + sens + " IC: " + ic); } else { min5minCarbImpact = SP.getDouble(R.string.key_openapsama_min_5m_carbimpact, SMBDefaults.min_5m_carbimpact); } } + + 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; - long chartTime; + public double bg = 0; // mgdl + private long chartTime; public String pastSensitivity = ""; public double deviation = 0d; - boolean nonCarbsDeviation = false; - public boolean nonEqualDeviation = false; + public boolean validDeviation = false; List activeCarbsList = new ArrayList<>(); double absorbed = 0d; public double carbsFromBolus = 0d; @@ -70,19 +86,34 @@ public class AutosensData implements DataPointWithLabelInterface { public double avgDelta = 0d; public double avgDeviation = 0d; - public double autosensRatio = 1d; + public AutosensResult autosensResult = new AutosensResult(); public double slopeFromMaxDeviation = 0; public double slopeFromMinDeviation = 999; public double usedMinCarbsImpact = 0d; public boolean failoverToMinAbsorbtionRate = false; + // Oref1 + public boolean absorbing = false; + public double mealCarbs = 0; + public int mealStartCounter = 999; + public String type = ""; + public boolean uam = false; + public List extraDeviation = new ArrayList<>(); + @Override public String toString() { - return "AutosensData: " + new Date(time).toLocaleString() + " " + pastSensitivity + " Delta=" + delta + " avgDelta=" + avgDelta + " Bgi=" + bgi + " Deviation=" + deviation + " avgDeviation=" + avgDeviation + " Absorbed=" + absorbed + " CarbsFromBolus=" + carbsFromBolus + " COB=" + cob + " autosensRatio=" + autosensRatio + " slopeFromMaxDeviation=" + slopeFromMaxDeviation + " slopeFromMinDeviation =" + slopeFromMinDeviation; + return String.format("AutosensData: %s pastSensitivity=%s delta=%.02f avgDelta=%.02f bgi=%.02f deviation=%.02f avgDeviation=%.02f absorbed=%.02f carbsFromBolus=%.02f cob=%.02f autosensRatio=%.02f slopeFromMaxDeviation=%.02f slopeFromMinDeviation=%.02f activeCarbsList=%s", + new Date(time).toLocaleString(), pastSensitivity, delta, avgDelta, bgi, deviation, avgDeviation, absorbed, carbsFromBolus, cob, autosensResult.ratio, slopeFromMaxDeviation, slopeFromMinDeviation, activeCarbsList.toString()); } - public int minOld() { - return (int) ((System.currentTimeMillis() - time) / 1000 / 60); + public List cloneCarbsList() { + List newActiveCarbsList = new ArrayList<>(); + + for(CarbsInPast c: activeCarbsList) { + newActiveCarbsList.add(new CarbsInPast(c)); + } + + return newActiveCarbsList; } // remove carbs older than timeframe @@ -99,7 +130,8 @@ public class AutosensData implements DataPointWithLabelInterface { activeCarbsList.remove(i--); if (c.remaining > 0) cob -= c.remaining; - log.debug("Removing carbs at " + new Date(toTime).toLocaleString() + " + after " + maxAbsorptionHours + "h :" + new Date(c.time).toLocaleString()); + if (L.isEnabled(L.AUTOSENS)) + log.debug("Removing carbs at " + new Date(toTime).toLocaleString() + " after " + maxAbsorptionHours + "h > " + c.toString()); } } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/AutosensResult.java b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/AutosensResult.java index 4e0f8ef107..7bd01fa7b2 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/AutosensResult.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/AutosensResult.java @@ -5,16 +5,18 @@ import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import info.nightscout.androidaps.logging.L; + /** * Created by mike on 06.01.2017. */ public class AutosensResult { - private static Logger log = LoggerFactory.getLogger(AutosensResult.class); + private static Logger log = LoggerFactory.getLogger(L.AUTOSENS); //default values to show when autosens algorithm is not called public double ratio = 1d; public double carbsAbsorbed = 0d; - public String sensResult = "autosens deactivated"; + public String sensResult = "autosens not available"; public String pastSensitivity = ""; public String ratioLimit = ""; @@ -32,4 +34,8 @@ public class AutosensResult { return ret; } + @Override + public String toString() { + return json().toString(); + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobCalculatorPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobCalculatorPlugin.java index 2e8e16a226..b94076a377 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobCalculatorPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobCalculatorPlugin.java @@ -12,10 +12,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; -import java.util.Date; import java.util.List; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; @@ -32,12 +30,16 @@ import info.nightscout.androidaps.events.EventPreferenceChange; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginType; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventNewHistoryData; import info.nightscout.androidaps.plugins.OpenAPSSMB.OpenAPSSMBPlugin; +import info.nightscout.androidaps.plugins.Sensitivity.SensitivityOref1Plugin; import info.nightscout.androidaps.plugins.Treatments.Treatment; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.utils.DateUtil; +import info.nightscout.utils.T; import static info.nightscout.utils.DateUtil.now; @@ -46,7 +48,7 @@ import static info.nightscout.utils.DateUtil.now; */ public class IobCobCalculatorPlugin extends PluginBase { - private Logger log = LoggerFactory.getLogger(IobCobCalculatorPlugin.class); + private Logger log = LoggerFactory.getLogger(L.AUTOSENS); private static IobCobCalculatorPlugin plugin = null; @@ -68,7 +70,7 @@ public class IobCobCalculatorPlugin extends PluginBase { final Object dataLock = new Object(); boolean stopCalculationTrigger = false; - private IobCobThread thread = null; + private Thread thread = null; public IobCobCalculatorPlugin() { super(new PluginDescription() @@ -96,50 +98,34 @@ public class IobCobCalculatorPlugin extends PluginBase { return autosensDataTable; } + public List getBgReadings() { + return bgReadings; + } + + public void setBgReadings(List bgReadings) { + this.bgReadings = bgReadings; + } + public List getBucketedData() { return bucketed_data; } - @Nullable - public List getBucketedData(long fromTime) { - //log.debug("Locking getBucketedData"); - synchronized (dataLock) { - if (bucketed_data == null) { - log.debug("No bucketed data available"); - return null; - } - int index = indexNewerThan(fromTime); - if (index > -1) { - List part = bucketed_data.subList(0, index); - log.debug("Bucketed data striped off: " + part.size() + "/" + bucketed_data.size()); - return part; - } - } - //log.debug("Releasing getBucketedData"); - return null; - } - - private int indexNewerThan(long time) { - for (int index = 0; index < bucketed_data.size(); index++) { - if (bucketed_data.get(index).date < time) - return index - 1; - } - return -1; - } - + // roundup to whole minute public static long roundUpTime(long time) { if (time % 60000 == 0) return time; - long rouded = (time / 60000 + 1) * 60000; - return rouded; + long rounded = (time / 60000 + 1) * 60000; + return rounded; } - void loadBgData(long start) { - bgReadings = MainApp.getDbHelper().getBgreadingsDataFromTime((long) (start - 60 * 60 * 1000L * (24 + dia)), false); - log.debug("BG data loaded. Size: " + bgReadings.size() + " Start date: " + DateUtil.dateAndTimeString(start)); + void loadBgData(long now) { + long start = (long) (now - 60 * 60 * 1000L * (24 + dia)); + bgReadings = MainApp.getDbHelper().getBgreadingsDataFromTime(start, now, false); + if (L.isEnabled(L.AUTOSENS)) + log.debug("BG data loaded. Size: " + bgReadings.size() + " Start date: " + DateUtil.dateAndTimeString(start) + " End date: " + DateUtil.dateAndTimeString(now)); } - private boolean isAbout5minData() { + public boolean isAbout5minData() { synchronized (dataLock) { if (bgReadings == null || bgReadings.size() < 3) { return true; @@ -149,21 +135,26 @@ public class IobCobCalculatorPlugin extends PluginBase { long bgTime = bgReadings.get(i).date; long lastbgTime = bgReadings.get(i - 1).date; long diff = lastbgTime - bgTime; + diff %= T.mins(5).msecs(); + if (diff > T.mins(2).plus(T.secs(30)).msecs()) + diff = diff - T.mins(5).msecs(); totalDiff += diff; - if (diff > 30 * 1000 && diff < 270 * 1000) { // 0:30 - 4:30 - log.debug("Interval detection: values: " + bgReadings.size() + " diff: " + (diff / 1000) + "sec is5minData: " + false); + diff = Math.abs(diff); + if (diff > T.secs(30).msecs()) { + if (L.isEnabled(L.AUTOSENS)) + log.debug("Interval detection: values: " + bgReadings.size() + " diff: " + (diff / 1000) + "[s] is5minData: " + false); return false; } } - double intervals = totalDiff / (5 * 60 * 1000d); - double variability = Math.abs(intervals - Math.round(intervals)); - boolean is5mindata = variability < 0.02; - log.debug("Interval detection: values: " + bgReadings.size() + " variability: " + variability + " is5minData: " + is5mindata); + long averageDiff = totalDiff / bgReadings.size() / 1000; + boolean is5mindata = averageDiff < 1; + if (L.isEnabled(L.AUTOSENS)) + log.debug("Interval detection: values: " + bgReadings.size() + " averageDiff: " + averageDiff + "[s] is5minData: " + is5mindata); return is5mindata; } } - void createBucketedData() { + public void createBucketedData() { if (isAbout5minData()) createBucketedData5min(); else @@ -171,24 +162,26 @@ public class IobCobCalculatorPlugin extends PluginBase { } @Nullable - private BgReading findNewer(long time) { + public BgReading findNewer(long time) { BgReading lastFound = bgReadings.get(0); if (lastFound.date < time) return null; for (int i = 1; i < bgReadings.size(); ++i) { + if (bgReadings.get(i).date == time) return bgReadings.get(i); if (bgReadings.get(i).date > time) continue; - lastFound = bgReadings.get(i); + lastFound = bgReadings.get(i - 1); if (bgReadings.get(i).date < time) break; } return lastFound; } @Nullable - private BgReading findOlder(long time) { + public BgReading findOlder(long time) { BgReading lastFound = bgReadings.get(bgReadings.size() - 1); if (lastFound.date > time) return null; for (int i = bgReadings.size() - 2; i >= 0; --i) { + if (bgReadings.get(i).date == time) return bgReadings.get(i); if (bgReadings.get(i).date < time) continue; - lastFound = bgReadings.get(i); + lastFound = bgReadings.get(i + 1); if (bgReadings.get(i).date > time) break; } return lastFound; @@ -201,7 +194,7 @@ public class IobCobCalculatorPlugin extends PluginBase { } bucketed_data = new ArrayList<>(); - long currentTime = bgReadings.get(0).date + 5 * 60 * 1000 - bgReadings.get(0).date % (5 * 60 * 1000) - 5 * 60 * 1000L; + long currentTime = bgReadings.get(0).date - bgReadings.get(0).date % T.mins(5).msecs(); //log.debug("First reading: " + new Date(currentTime).toLocaleString()); while (true) { @@ -211,16 +204,20 @@ public class IobCobCalculatorPlugin extends PluginBase { if (newer == null || older == null) break; - double bgDelta = newer.value - older.value; - long timeDiffToNew = newer.date - currentTime; + if (older.date == newer.date) { // direct hit + bucketed_data.add(newer); + } else { + double bgDelta = newer.value - older.value; + long timeDiffToNew = newer.date - currentTime; - double currentBg = newer.value - (double) timeDiffToNew / (newer.date - older.date) * bgDelta; - BgReading newBgreading = new BgReading(); - newBgreading.date = currentTime; - newBgreading.value = Math.round(currentBg); - bucketed_data.add(newBgreading); - //log.debug("BG: " + newBgreading.value + " (" + new Date(newBgreading.date).toLocaleString() + ") Prev: " + older.value + " (" + new Date(older.date).toLocaleString() + ") Newer: " + newer.value + " (" + new Date(newer.date).toLocaleString() + ")"); - currentTime -= 5 * 60 * 1000L; + double currentBg = newer.value - (double) timeDiffToNew / (newer.date - older.date) * bgDelta; + BgReading newBgreading = new BgReading(); + newBgreading.date = currentTime; + newBgreading.value = Math.round(currentBg); + bucketed_data.add(newBgreading); + //log.debug("BG: " + newBgreading.value + " (" + new Date(newBgreading.date).toLocaleString() + ") Prev: " + older.value + " (" + new Date(older.date).toLocaleString() + ") Newer: " + newer.value + " (" + new Date(newer.date).toLocaleString() + ")"); + } + currentTime -= T.mins(5).msecs(); } } @@ -234,13 +231,15 @@ public class IobCobCalculatorPlugin extends PluginBase { bucketed_data = new ArrayList<>(); bucketed_data.add(bgReadings.get(0)); + if (L.isEnabled(L.AUTOSENS)) + log.debug("Adding. bgTime: " + DateUtil.toISOString(bgReadings.get(0).date) + " lastbgTime: " + "none-first-value" + " " + bgReadings.get(0).toString()); int j = 0; for (int i = 1; i < bgReadings.size(); ++i) { long bgTime = bgReadings.get(i).date; long lastbgTime = bgReadings.get(i - 1).date; //log.error("Processing " + i + ": " + new Date(bgTime).toString() + " " + bgReadings.get(i).value + " Previous: " + new Date(lastbgTime).toString() + " " + bgReadings.get(i - 1).value); if (bgReadings.get(i).value < 39 || bgReadings.get(i - 1).value < 39) { - continue; + throw new IllegalStateException("<39"); } long elapsed_minutes = (bgTime - lastbgTime) / (60 * 1000); @@ -261,7 +260,8 @@ public class IobCobCalculatorPlugin extends PluginBase { newBgreading.value = Math.round(nextbg); //console.error("Interpolated", bucketed_data[j]); bucketed_data.add(newBgreading); - //log.error("******************************************************************************************************* Adding:" + new Date(newBgreading.date).toString() + " " + newBgreading.value); + if (L.isEnabled(L.AUTOSENS)) + log.debug("Adding. bgTime: " + DateUtil.toISOString(bgTime) + " lastbgTime: " + DateUtil.toISOString(lastbgTime) + " " + newBgreading.toString()); elapsed_minutes = elapsed_minutes - 5; lastbg = nextbg; @@ -272,28 +272,58 @@ public class IobCobCalculatorPlugin extends PluginBase { newBgreading.value = bgReadings.get(i).value; newBgreading.date = bgTime; bucketed_data.add(newBgreading); - //log.error("******************************************************************************************************* Copying:" + new Date(newBgreading.date).toString() + " " + newBgreading.value); + if (L.isEnabled(L.AUTOSENS)) + log.debug("Adding. bgTime: " + DateUtil.toISOString(bgTime) + " lastbgTime: " + DateUtil.toISOString(lastbgTime) + " " + newBgreading.toString()); } else if (Math.abs(elapsed_minutes) > 2) { j++; BgReading newBgreading = new BgReading(); newBgreading.value = bgReadings.get(i).value; newBgreading.date = bgTime; bucketed_data.add(newBgreading); - //log.error("******************************************************************************************************* Copying:" + new Date(newBgreading.date).toString() + " " + newBgreading.value); + if (L.isEnabled(L.AUTOSENS)) + log.debug("Adding. bgTime: " + DateUtil.toISOString(bgTime) + " lastbgTime: " + DateUtil.toISOString(lastbgTime) + " " + newBgreading.toString()); } else { bucketed_data.get(j).value = (bucketed_data.get(j).value + bgReadings.get(i).value) / 2; //log.error("***** Average"); } } - log.debug("Bucketed data created. Size: " + bucketed_data.size()); + + // Normalize bucketed data + for (int i = bucketed_data.size() - 2; i >= 0; i--) { + BgReading current = bucketed_data.get(i); + BgReading previous = bucketed_data.get(i + 1); + long msecDiff = current.date - previous.date; + long adjusted = (msecDiff - T.mins(5).msecs()) / 1000; + 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(); + } + + if (L.isEnabled(L.AUTOSENS)) + log.debug("Bucketed data created. Size: " + bucketed_data.size()); } - public long oldestDataAvailable() { - long now = System.currentTimeMillis(); + public long calculateDetectionStart(long from, boolean limitDataToOldestAvailable) { + Profile profile = ProfileFunctions.getInstance().getProfile(from); + double dia = Constants.defaultDIA; + if (profile != null) dia = profile.getDia(); long oldestDataAvailable = TreatmentsPlugin.getPlugin().oldestDataAvailable(); - long getBGDataFrom = Math.max(oldestDataAvailable, (long) (now - 60 * 60 * 1000L * (24 + MainApp.getConfigBuilder().getProfile().getDia()))); - log.debug("Limiting data to oldest available temps: " + new Date(oldestDataAvailable).toString()); + long getBGDataFrom; + if (limitDataToOldestAvailable) { + getBGDataFrom = Math.max(oldestDataAvailable, (long) (from - T.hours(1).msecs() * (24 + dia))); + if (getBGDataFrom == oldestDataAvailable) + if (L.isEnabled(L.AUTOSENS)) + log.debug("Limiting data to oldest available temps: " + DateUtil.dateAndTimeFullString(oldestDataAvailable)); + } else + getBGDataFrom = (long) (from - T.hours(1).msecs() * (24 + dia)); return getBGDataFrom; } @@ -337,11 +367,11 @@ public class IobCobCalculatorPlugin extends PluginBase { } @Nullable - private Long findPreviousTimeFromBucketedData(long time) { + public Long findPreviousTimeFromBucketedData(long time) { if (bucketed_data == null) return null; for (int index = 0; index < bucketed_data.size(); index++) { - if (bucketed_data.get(index).date < time) + if (bucketed_data.get(index).date <= time) return bucketed_data.get(index).date; } return null; @@ -376,22 +406,20 @@ public class IobCobCalculatorPlugin extends PluginBase { public AutosensData getAutosensData(long time) { synchronized (dataLock) { long now = System.currentTimeMillis(); - if (time > now) + if (time > now) { return null; + } Long previous = findPreviousTimeFromBucketedData(time); - if (previous == null) + if (previous == null) { return null; + } time = roundUpTime(previous); AutosensData data = autosensDataTable.get(time); if (data != null) { - //log.debug(">>> getAutosensData Cache hit " + data.log(time)); + //log.debug(">>> AUTOSENSDATA Cache hit " + data.toString()); return data; } else { - if (time > now) { - // data may not be calculated yet, use last data - return getLastAutosensData("getAutosensData"); - } - //log.debug(">>> getAutosensData Cache miss " + new Date(time).toLocaleString()); + //log.debug(">>> AUTOSENSDATA Cache miss " + new Date(time).toLocaleString()); return null; } } @@ -399,6 +427,16 @@ public class IobCobCalculatorPlugin extends PluginBase { @Nullable public AutosensData getLastAutosensDataSynchronized(String reason) { + if (thread != null && thread.isAlive()) { + if (L.isEnabled(L.AUTOSENS)) + log.debug("AUTOSENSDATA is waiting for calculation thread: " + reason); + try { + thread.join(5000); + } catch (InterruptedException ignored) { + } + if (L.isEnabled(L.AUTOSENS)) + log.debug("AUTOSENSDATA finished waiting for calculation thread: " + reason); + } synchronized (dataLock) { return getLastAutosensData(reason); } @@ -435,7 +473,8 @@ public class IobCobCalculatorPlugin extends PluginBase { @Nullable public AutosensData getLastAutosensData(String reason) { if (autosensDataTable.size() < 1) { - log.debug("AUTOSENSDATA null: autosensDataTable empty (" + reason + ")"); + if (L.isEnabled(L.AUTOSENS)) + log.debug("AUTOSENSDATA null: autosensDataTable empty (" + reason + ")"); return null; } AutosensData data; @@ -449,13 +488,23 @@ public class IobCobCalculatorPlugin extends PluginBase { return null; } if (data.time < System.currentTimeMillis() - 11 * 60 * 1000) { - log.debug("AUTOSENSDATA null: data is old (" + reason + ") size()=" + autosensDataTable.size() + " lastdata=" + DateUtil.dateAndTimeString(data.time)); + if (L.isEnabled(L.AUTOSENS)) + log.debug("AUTOSENSDATA null: data is old (" + reason + ") size()=" + autosensDataTable.size() + " lastdata=" + DateUtil.dateAndTimeString(data.time)); return null; } else { + if (L.isEnabled(L.AUTOSENS)) + log.debug("AUTOSENSDATA (" + reason + ") " + data.toString()); return data; } } + public String lastDataTime() { + if (autosensDataTable.size() > 0) + return DateUtil.dateAndTimeString(autosensDataTable.valueAt(autosensDataTable.size() - 1).time); + else + return "autosensDataTable empty"; + } + public IobTotal[] calculateIobArrayInDia(Profile profile) { // predict IOB out to DIA plus 30m long time = System.currentTimeMillis(); @@ -490,14 +539,10 @@ public class IobCobCalculatorPlugin extends PluginBase { public AutosensResult detectSensitivityWithLock(long fromTime, long toTime) { synchronized (dataLock) { - return detectSensitivity(fromTime, toTime); + return ConfigBuilderPlugin.getPlugin().getActiveSensitivity().detectSensitivity(this, fromTime, toTime); } } - static AutosensResult detectSensitivity(long fromTime, long toTime) { - return ConfigBuilderPlugin.getActiveSensitivity().detectSensitivity(fromTime, toTime); - } - public static JSONArray convertToJSONArray(IobTotal[] iobArray) { JSONArray array = new JSONArray(); for (int i = 0; i < iobArray.length; i++) { @@ -510,38 +555,46 @@ public class IobCobCalculatorPlugin extends PluginBase { @SuppressWarnings("unused") public void onEventAppInitialized(EventAppInitialized ev) { if (this != getPlugin()) { - log.debug("Ignoring event for non default instance"); + if (L.isEnabled(L.AUTOSENS)) + log.debug("Ignoring event for non default instance"); return; } - runCalculation("onEventAppInitialized", System.currentTimeMillis(), true, ev); + runCalculation("onEventAppInitialized", System.currentTimeMillis(), true, true, ev); } @Subscribe @SuppressWarnings("unused") public void onEventNewBG(EventNewBG ev) { if (this != getPlugin()) { - log.debug("Ignoring event for non default instance"); + if (L.isEnabled(L.AUTOSENS)) + log.debug("Ignoring event for non default instance"); return; } stopCalculation("onEventNewBG"); - runCalculation("onEventNewBG", System.currentTimeMillis(), true, ev); + runCalculation("onEventNewBG", System.currentTimeMillis(), true, true, ev); } - private void stopCalculation(String from) { + public void stopCalculation(String from) { if (thread != null && thread.getState() != Thread.State.TERMINATED) { stopCalculationTrigger = true; - log.debug("Stopping calculation thread: " + from); + if (L.isEnabled(L.AUTOSENS)) + log.debug("Stopping calculation thread: " + from); while (thread.getState() != Thread.State.TERMINATED) { SystemClock.sleep(100); } - log.debug("Calculation thread stopped: " + from); + if (L.isEnabled(L.AUTOSENS)) + log.debug("Calculation thread stopped: " + from); } } - public void runCalculation(String from, long start, boolean bgDataReload, Event cause) { - log.debug("Starting calculation thread: " + from); + public void runCalculation(String from, long end, boolean bgDataReload, boolean limitDataToOldestAvailable, Event cause) { + if (L.isEnabled(L.AUTOSENS)) + log.debug("Starting calculation thread: " + from + " to " + DateUtil.dateAndTimeString(end)); if (thread == null || thread.getState() == Thread.State.TERMINATED) { - thread = new IobCobThread(this, from, start, bgDataReload, cause); + if (SensitivityOref1Plugin.getPlugin().isEnabled(PluginType.SENSITIVITY)) + thread = new IobCobOref1Thread(this, from, end, bgDataReload, limitDataToOldestAvailable, cause); + else + thread = new IobCobThread(this, from, end, bgDataReload, limitDataToOldestAvailable, cause); thread.start(); } } @@ -549,12 +602,13 @@ public class IobCobCalculatorPlugin extends PluginBase { @Subscribe public void onNewProfile(EventNewBasalProfile ev) { if (this != getPlugin()) { - log.debug("Ignoring event for non default instance"); + if (L.isEnabled(L.AUTOSENS)) + log.debug("Ignoring event for non default instance"); return; } - if (MainApp.getConfigBuilder() == null) + if (ConfigBuilderPlugin.getPlugin() == null) return; // app still initializing - Profile profile = MainApp.getConfigBuilder().getProfile(); + Profile profile = ProfileFunctions.getInstance().getProfile(); if (profile == null) return; // app still initializing dia = profile.getDia(); @@ -563,55 +617,63 @@ public class IobCobCalculatorPlugin extends PluginBase { } stopCalculation("onNewProfile"); synchronized (dataLock) { - log.debug("Invalidating cached data because of new profile. IOB: " + iobTable.size() + " Autosens: " + autosensDataTable.size() + " records"); + if (L.isEnabled(L.AUTOSENS)) + log.debug("Invalidating cached data because of new profile. IOB: " + iobTable.size() + " Autosens: " + autosensDataTable.size() + " records"); iobTable = new LongSparseArray<>(); autosensDataTable = new LongSparseArray<>(); } - runCalculation("onNewProfile", System.currentTimeMillis(), false, ev); + runCalculation("onNewProfile", System.currentTimeMillis(), false, true, ev); } @Subscribe public void onEventPreferenceChange(EventPreferenceChange ev) { if (this != getPlugin()) { - log.debug("Ignoring event for non default instance"); + if (L.isEnabled(L.AUTOSENS)) + log.debug("Ignoring event for non default instance"); return; } if (ev.isChanged(R.string.key_openapsama_autosens_period) || ev.isChanged(R.string.key_age) || ev.isChanged(R.string.key_absorption_maxtime) || ev.isChanged(R.string.key_openapsama_min_5m_carbimpact) || - ev.isChanged(R.string.key_absorption_cutoff) + ev.isChanged(R.string.key_absorption_cutoff) || + ev.isChanged(R.string.key_openapsama_autosens_max) || + ev.isChanged(R.string.key_openapsama_autosens_min) ) { stopCalculation("onEventPreferenceChange"); synchronized (dataLock) { - log.debug("Invalidating cached data because of preference change. IOB: " + iobTable.size() + " Autosens: " + autosensDataTable.size() + " records"); + if (L.isEnabled(L.AUTOSENS)) + log.debug("Invalidating cached data because of preference change. IOB: " + iobTable.size() + " Autosens: " + autosensDataTable.size() + " records"); iobTable = new LongSparseArray<>(); autosensDataTable = new LongSparseArray<>(); } - runCalculation("onEventPreferenceChange", System.currentTimeMillis(), false, ev); + runCalculation("onEventPreferenceChange", System.currentTimeMillis(), false, true, ev); } } @Subscribe public void onEventConfigBuilderChange(EventConfigBuilderChange ev) { if (this != getPlugin()) { - log.debug("Ignoring event for non default instance"); + if (L.isEnabled(L.AUTOSENS)) + log.debug("Ignoring event for non default instance"); return; } stopCalculation("onEventConfigBuilderChange"); synchronized (dataLock) { - log.debug("Invalidating cached data because of configuration change. IOB: " + iobTable.size() + " Autosens: " + autosensDataTable.size() + " records"); + if (L.isEnabled(L.AUTOSENS)) + log.debug("Invalidating cached data because of configuration change. IOB: " + iobTable.size() + " Autosens: " + autosensDataTable.size() + " records"); iobTable = new LongSparseArray<>(); autosensDataTable = new LongSparseArray<>(); } - runCalculation("onEventConfigBuilderChange", System.currentTimeMillis(), false, ev); + runCalculation("onEventConfigBuilderChange", System.currentTimeMillis(), false, true, ev); } // When historical data is changed (comming from NS etc) finished calculations after this date must be invalidated @Subscribe public void onEventNewHistoryData(EventNewHistoryData ev) { if (this != getPlugin()) { - log.debug("Ignoring event for non default instance"); + if (L.isEnabled(L.AUTOSENS)) + log.debug("Ignoring event for non default instance"); return; } //log.debug("Locking onNewHistoryData"); @@ -619,11 +681,12 @@ public class IobCobCalculatorPlugin extends PluginBase { synchronized (dataLock) { // clear up 5 min back for proper COB calculation long time = ev.time - 5 * 60 * 1000L; - log.debug("Invalidating cached data to: " + new Date(time).toLocaleString()); + if (L.isEnabled(L.AUTOSENS)) + log.debug("Invalidating cached data to: " + DateUtil.dateAndTimeFullString(time)); for (int index = iobTable.size() - 1; index >= 0; index--) { if (iobTable.keyAt(index) > time) { - if (Config.logAutosensData) - log.debug("Removing from iobTable: " + new Date(iobTable.keyAt(index)).toLocaleString()); + if (L.isEnabled(L.AUTOSENS)) + log.debug("Removing from iobTable: " + DateUtil.dateAndTimeFullString(iobTable.keyAt(index))); iobTable.removeAt(index); } else { break; @@ -631,8 +694,8 @@ public class IobCobCalculatorPlugin extends PluginBase { } for (int index = autosensDataTable.size() - 1; index >= 0; index--) { if (autosensDataTable.keyAt(index) > time) { - if (Config.logAutosensData) - log.debug("Removing from autosensDataTable: " + new Date(autosensDataTable.keyAt(index)).toLocaleString()); + if (L.isEnabled(L.AUTOSENS)) + log.debug("Removing from autosensDataTable: " + DateUtil.dateAndTimeFullString(autosensDataTable.keyAt(index))); autosensDataTable.removeAt(index); } else { break; @@ -640,21 +703,22 @@ public class IobCobCalculatorPlugin extends PluginBase { } for (int index = basalDataTable.size() - 1; index >= 0; index--) { if (basalDataTable.keyAt(index) > time) { - if (Config.logAutosensData) - log.debug("Removing from basalDataTable: " + new Date(basalDataTable.keyAt(index)).toLocaleString()); + if (L.isEnabled(L.AUTOSENS)) + log.debug("Removing from basalDataTable: " + DateUtil.dateAndTimeFullString(basalDataTable.keyAt(index))); basalDataTable.removeAt(index); } else { break; } } } - runCalculation("onEventNewHistoryData", System.currentTimeMillis(), false, ev); + runCalculation("onEventNewHistoryData", System.currentTimeMillis(), false, true, ev); //log.debug("Releasing onNewHistoryData"); } public void clearCache() { synchronized (dataLock) { - log.debug("Clearing cached data."); + if (L.isEnabled(L.AUTOSENS)) + log.debug("Clearing cached data."); iobTable = new LongSparseArray<>(); autosensDataTable = new LongSparseArray<>(); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobOref1Thread.java b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobOref1Thread.java new file mode 100644 index 0000000000..172a6bbc47 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobOref1Thread.java @@ -0,0 +1,407 @@ +package info.nightscout.androidaps.plugins.IobCobCalculator; + +import android.content.Context; +import android.os.PowerManager; +import android.os.SystemClock; +import android.support.v4.util.LongSparseArray; + +import com.crashlytics.android.answers.CustomEvent; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.List; + +import info.nightscout.androidaps.BuildConfig; +import info.nightscout.androidaps.Constants; +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.data.IobTotal; +import info.nightscout.androidaps.data.Profile; +import info.nightscout.androidaps.db.BgReading; +import info.nightscout.androidaps.db.TempTarget; +import info.nightscout.androidaps.events.Event; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; +import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished; +import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventIobCalculationProgress; +import info.nightscout.androidaps.plugins.OpenAPSSMB.SMBDefaults; +import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; +import info.nightscout.androidaps.plugins.Overview.notifications.Notification; +import info.nightscout.androidaps.plugins.Treatments.Treatment; +import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; +import info.nightscout.utils.DateUtil; +import info.nightscout.utils.DecimalFormatter; +import info.nightscout.utils.FabricPrivacy; +import info.nightscout.utils.MidnightTime; +import info.nightscout.utils.Profiler; +import info.nightscout.utils.SP; + +import static info.nightscout.utils.DateUtil.now; +import static java.util.Calendar.MINUTE; + +/** + * Created by mike on 23.01.2018. + */ + +public class IobCobOref1Thread extends Thread { + private static Logger log = LoggerFactory.getLogger(L.AUTOSENS); + private final Event cause; + + private IobCobCalculatorPlugin iobCobCalculatorPlugin; + private boolean bgDataReload; + private boolean limitDataToOldestAvailable; + private String from; + private long end; + + private PowerManager.WakeLock mWakeLock; + + public IobCobOref1Thread(IobCobCalculatorPlugin plugin, String from, long end, boolean bgDataReload, boolean limitDataToOldestAvailable, Event cause) { + super(); + + this.iobCobCalculatorPlugin = plugin; + this.bgDataReload = bgDataReload; + this.limitDataToOldestAvailable = limitDataToOldestAvailable; + this.from = from; + this.cause = cause; + this.end = end; + + PowerManager powerManager = (PowerManager) MainApp.instance().getApplicationContext().getSystemService(Context.POWER_SERVICE); + mWakeLock = powerManager.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "iobCobThread"); + } + + @Override + public final void run() { + long start = DateUtil.now(); + mWakeLock.acquire(); + try { + if (L.isEnabled(L.AUTOSENS)) + log.debug("AUTOSENSDATA thread started: " + from); + if (ConfigBuilderPlugin.getPlugin() == null) { + if (L.isEnabled(L.AUTOSENS)) + log.debug("Aborting calculation thread (ConfigBuilder not ready): " + from); + return; // app still initializing + } + if (!ProfileFunctions.getInstance().isProfileValid("IobCobThread")) { + if (L.isEnabled(L.AUTOSENS)) + log.debug("Aborting calculation thread (No profile): " + from); + return; // app still initializing + } + //log.debug("Locking calculateSensitivityData"); + + long oldestTimeWithData = iobCobCalculatorPlugin.calculateDetectionStart(end, limitDataToOldestAvailable); + + synchronized (iobCobCalculatorPlugin.dataLock) { + if (bgDataReload) { + iobCobCalculatorPlugin.loadBgData(end); + iobCobCalculatorPlugin.createBucketedData(); + } + List bucketed_data = iobCobCalculatorPlugin.getBucketedData(); + LongSparseArray autosensDataTable = iobCobCalculatorPlugin.getAutosensDataTable(); + + if (bucketed_data == null || bucketed_data.size() < 3) { + if (L.isEnabled(L.AUTOSENS)) + log.debug("Aborting calculation thread (No bucketed data available): " + from); + return; + } + + long prevDataTime = IobCobCalculatorPlugin.roundUpTime(bucketed_data.get(bucketed_data.size() - 3).date); + if (L.isEnabled(L.AUTOSENS)) + log.debug("Prev data time: " + new Date(prevDataTime).toLocaleString()); + AutosensData previous = autosensDataTable.get(prevDataTime); + // start from oldest to be able sub cob + for (int i = bucketed_data.size() - 4; i >= 0; i--) { + String progress = i + (MainApp.isDev() ? " (" + from + ")" : ""); + MainApp.bus().post(new EventIobCalculationProgress(progress)); + + if (iobCobCalculatorPlugin.stopCalculationTrigger) { + iobCobCalculatorPlugin.stopCalculationTrigger = false; + if (L.isEnabled(L.AUTOSENS)) + log.debug("Aborting calculation thread (trigger): " + from); + return; + } + // check if data already exists + long bgTime = bucketed_data.get(i).date; + bgTime = IobCobCalculatorPlugin.roundUpTime(bgTime); + if (bgTime > IobCobCalculatorPlugin.roundUpTime(now())) + continue; + + AutosensData existing; + if ((existing = autosensDataTable.get(bgTime)) != null) { + previous = existing; + continue; + } + + Profile profile = ProfileFunctions.getInstance().getProfile(bgTime); + if (profile == null) { + if (L.isEnabled(L.AUTOSENS)) + log.debug("Aborting calculation thread (no profile): " + from); + return; // profile not set yet + } + + if (L.isEnabled(L.AUTOSENS)) + log.debug("Processing calculation thread: " + from + " (" + i + "/" + bucketed_data.size() + ")"); + + double sens = Profile.toMgdl(profile.getIsf(bgTime), profile.getUnits()); + + AutosensData autosensData = new AutosensData(); + autosensData.time = bgTime; + if (previous != null) + autosensData.activeCarbsList = previous.cloneCarbsList(); + else + autosensData.activeCarbsList = new ArrayList<>(); + + //console.error(bgTime , bucketed_data[i].glucose); + double bg; + double avgDelta; + double delta; + bg = bucketed_data.get(i).value; + if (bg < 39 || bucketed_data.get(i + 3).value < 39) { + log.error("! value < 39"); + continue; + } + autosensData.bg = bg; + delta = (bg - bucketed_data.get(i + 1).value); + avgDelta = (bg - bucketed_data.get(i + 3).value) / 3; + + IobTotal iob = iobCobCalculatorPlugin.calculateFromTreatmentsAndTemps(bgTime, profile); + + double bgi = -iob.activity * sens * 5; + double deviation = delta - bgi; + double avgDeviation = Math.round((avgDelta - bgi) * 1000) / 1000; + + double slopeFromMaxDeviation = 0; + double slopeFromMinDeviation = 999; + double maxDeviation = 0; + double minDeviation = 999; + + // https://github.com/openaps/oref0/blob/master/lib/determine-basal/cob-autosens.js#L169 + if (i < bucketed_data.size() - 16) { // we need 1h of data to calculate minDeviationSlope + long hourago = bgTime + 10 * 1000 - 60 * 60 * 1000L; + AutosensData hourAgoData = iobCobCalculatorPlugin.getAutosensData(hourago); + if (hourAgoData != null) { + int initialIndex = autosensDataTable.indexOfKey(hourAgoData.time); + if (L.isEnabled(L.AUTOSENS)) + log.debug(">>>>> bucketed_data.size()=" + bucketed_data.size() + " i=" + i + " hourAgoData=" + hourAgoData.toString()); + int past = 1; + try { + for (; past < 12; past++) { + AutosensData ad = autosensDataTable.valueAt(initialIndex + past); + if (L.isEnabled(L.AUTOSENS)) { + log.debug(">>>>> past=" + past + " ad=" + (ad != null ? ad.toString() : null)); + if (ad == null) { + log.debug(autosensDataTable.toString()); + log.debug(bucketed_data.toString()); + log.debug(IobCobCalculatorPlugin.getPlugin().getBgReadings().toString()); + Notification notification = new Notification(Notification.SENDLOGFILES, MainApp.gs(R.string.sendlogfiles), Notification.LOW); + MainApp.bus().post(new EventNewNotification(notification)); + SP.putBoolean("log_AUTOSENS", true); + break; + } + } + // let it here crash on NPE to get more data as i cannot reproduce this bug + double deviationSlope = (ad.avgDeviation - avgDeviation) / (ad.time - bgTime) * 1000 * 60 * 5; + if (ad.avgDeviation > maxDeviation) { + slopeFromMaxDeviation = Math.min(0, deviationSlope); + maxDeviation = ad.avgDeviation; + } + if (ad.avgDeviation < minDeviation) { + slopeFromMinDeviation = Math.max(0, deviationSlope); + minDeviation = ad.avgDeviation; + } + + //if (Config.isEnabled(L.AUTOSENS)) + // log.debug("Deviations: " + new Date(bgTime) + new Date(ad.time) + " avgDeviation=" + avgDeviation + " deviationSlope=" + deviationSlope + " slopeFromMaxDeviation=" + slopeFromMaxDeviation + " slopeFromMinDeviation=" + slopeFromMinDeviation); + } + } catch (Exception e) { + log.error("Unhandled exception", e); + FabricPrivacy.logException(e); + FabricPrivacy.getInstance().logCustom(new CustomEvent("CatchedError") + .putCustomAttribute("buildversion", BuildConfig.BUILDVERSION) + .putCustomAttribute("version", BuildConfig.VERSION) + .putCustomAttribute("autosensDataTable", iobCobCalculatorPlugin.getAutosensDataTable().toString()) + .putCustomAttribute("for_data", ">>>>> bucketed_data.size()=" + bucketed_data.size() + " i=" + i + "hourAgoData=" + hourAgoData.toString()) + .putCustomAttribute("past", past) + ); + 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"); + } + } + + List recentTreatments = TreatmentsPlugin.getPlugin().getTreatments5MinBackFromHistory(bgTime); + for (int ir = 0; ir < recentTreatments.size(); ir++) { + autosensData.carbsFromBolus += recentTreatments.get(ir).carbs; + autosensData.activeCarbsList.add(new AutosensData.CarbsInPast(recentTreatments.get(ir))); + autosensData.pastSensitivity += "[" + DecimalFormatter.to0Decimal(recentTreatments.get(ir).carbs) + "g]"; + } + + + // if we are absorbing carbs + if (previous != null && previous.cob > 0) { + // calculate sum of min carb impact from all active treatments + double totalMinCarbsImpact = 0d; +// if (SensitivityAAPSPlugin.getPlugin().isEnabled(PluginType.SENSITIVITY) || SensitivityWeightedAveragePlugin.getPlugin().isEnabled(PluginType.SENSITIVITY)) { + //when the impact depends on a max time, sum them up as smaller carb sizes make them smaller +// for (int ii = 0; ii < autosensData.activeCarbsList.size(); ++ii) { +// AutosensData.CarbsInPast c = autosensData.activeCarbsList.get(ii); +// totalMinCarbsImpact += c.min5minCarbImpact; +// } +// } else { + //Oref sensitivity + totalMinCarbsImpact = SP.getDouble(R.string.key_openapsama_min_5m_carbimpact, SMBDefaults.min_5m_carbimpact); +// } + + // figure out how many carbs that represents + // but always assume at least 3mg/dL/5m (default) absorption per active treatment + double ci = Math.max(deviation, totalMinCarbsImpact); + if (ci != deviation) + autosensData.failoverToMinAbsorbtionRate = true; + autosensData.absorbed = ci * profile.getIc(bgTime) / sens; + // and add that to the running total carbsAbsorbed + autosensData.cob = Math.max(previous.cob - autosensData.absorbed, 0d); + autosensData.mealCarbs = previous.mealCarbs; + autosensData.substractAbosorbedCarbs(); + autosensData.usedMinCarbsImpact = totalMinCarbsImpact; + autosensData.absorbing = previous.absorbing; + autosensData.mealStartCounter = previous.mealStartCounter; + autosensData.type = previous.type; + autosensData.uam = previous.uam; + } + + autosensData.removeOldCarbs(bgTime); + autosensData.cob += autosensData.carbsFromBolus; + autosensData.mealCarbs += autosensData.carbsFromBolus; + autosensData.deviation = deviation; + autosensData.bgi = bgi; + autosensData.delta = delta; + autosensData.avgDelta = avgDelta; + autosensData.avgDeviation = avgDeviation; + autosensData.slopeFromMaxDeviation = slopeFromMaxDeviation; + autosensData.slopeFromMinDeviation = slopeFromMinDeviation; + + + // If mealCOB is zero but all deviations since hitting COB=0 are positive, exclude from autosens + if (autosensData.cob > 0 || autosensData.absorbing || autosensData.mealCarbs > 0) { + if (deviation > 0) + autosensData.absorbing = true; + else + autosensData.absorbing = false; + // stop excluding positive deviations as soon as mealCOB=0 if meal has been absorbing for >5h + if (autosensData.mealStartCounter > 60 && autosensData.cob < 0.5) { + autosensData.absorbing = false; + } + if (!autosensData.absorbing && autosensData.cob < 0.5) { + autosensData.mealCarbs = 0; + } + // check previous "type" value, and if it wasn't csf, set a mealAbsorption start flag + if (!autosensData.type.equals("csf")) { +// process.stderr.write("("); + autosensData.mealStartCounter = 0; + } + autosensData.mealStartCounter++; + autosensData.type = "csf"; + } else { + // check previous "type" value, and if it was csf, set a mealAbsorption end flag + if (autosensData.type.equals("csf")) { +// process.stderr.write(")"); + } + + double currentBasal = profile.getBasal(bgTime); + // always exclude the first 45m after each carb entry + //if (iob.iob > currentBasal || uam ) { + if (iob.iob > 2 * currentBasal || autosensData.uam || autosensData.mealStartCounter < 9) { + autosensData.mealStartCounter++; + if (deviation > 0) + autosensData.uam = true; + else + autosensData.uam = false; + if (!autosensData.type.equals("uam")) { +// process.stderr.write("u("); + } + autosensData.type = "uam"; + } else { + if (autosensData.type.equals("uam")) { +// process.stderr.write(")"); + } + autosensData.type = "non-meal"; + } + } + + // Exclude meal-related deviations (carb absorption) from autosens + if (autosensData.type.equals("non-meal")) { + if (Math.abs(deviation) < Constants.DEVIATION_TO_BE_EQUAL) { + autosensData.pastSensitivity += "="; + autosensData.validDeviation = true; + } else if (deviation > 0) { + autosensData.pastSensitivity += "+"; + autosensData.validDeviation = true; + } else { + autosensData.pastSensitivity += "-"; + autosensData.validDeviation = true; + } + } else if (autosensData.type.equals("uam")) { + autosensData.pastSensitivity += "u"; + } else { + autosensData.pastSensitivity += "x"; + } + //log.debug("TIME: " + new Date(bgTime).toString() + " BG: " + bg + " SENS: " + sens + " DELTA: " + delta + " AVGDELTA: " + avgDelta + " IOB: " + iob.iob + " ACTIVITY: " + iob.activity + " BGI: " + bgi + " DEVIATION: " + deviation); + + // add an extra negative deviation if a high temptarget is running and exercise mode is set + if (SP.getBoolean(R.string.key_high_temptarget_raises_sensitivity, SMBDefaults.high_temptarget_raises_sensitivity)) { + TempTarget tempTarget = TreatmentsPlugin.getPlugin().getTempTargetFromHistory(bgTime); + if (tempTarget != null && tempTarget.target() >= 100) { + autosensData.extraDeviation.add(-(tempTarget.target() - 100) / 20); + } + } + + // add one neutral deviation every 2 hours to help decay over long exclusion periods + GregorianCalendar calendar = new GregorianCalendar(); + calendar.setTimeInMillis(bgTime); + int min = calendar.get(MINUTE); + int hours = calendar.get(Calendar.HOUR_OF_DAY); + if (min >= 0 && min < 5 && hours % 2 == 0) + autosensData.extraDeviation.add(0d); + + previous = autosensData; + if (bgTime < now()) + autosensDataTable.put(bgTime, autosensData); + if (L.isEnabled(L.AUTOSENS)) + log.debug("Running detectSensitivity from: " + DateUtil.dateAndTimeString(oldestTimeWithData) + " to: " + DateUtil.dateAndTimeString(bgTime) + " lastDataTime:" + iobCobCalculatorPlugin.lastDataTime()); + AutosensResult sensitivity = iobCobCalculatorPlugin.detectSensitivityWithLock(oldestTimeWithData, bgTime); + if (L.isEnabled(L.AUTOSENS)) + log.debug("Sensitivity result: " + sensitivity.toString()); + autosensData.autosensResult = sensitivity; + if (L.isEnabled(L.AUTOSENS)) + log.debug(autosensData.toString()); + } + } + new Thread(() -> { + SystemClock.sleep(1000); + MainApp.bus().post(new EventAutosensCalculationFinished(cause)); + }).start(); + } finally { + mWakeLock.release(); + MainApp.bus().post(new EventIobCalculationProgress("")); + if (L.isEnabled(L.AUTOSENS)) { + log.debug("AUTOSENSDATA thread ended: " + from); + log.debug("Midnights: " + MidnightTime.log()); + } + Profiler.log(log, "IobCobOref1Thread", start); + } + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobThread.java b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobThread.java index 9818ed17e4..aa1f09592e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobThread.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobThread.java @@ -2,6 +2,7 @@ package info.nightscout.androidaps.plugins.IobCobCalculator; import android.content.Context; import android.os.PowerManager; +import android.os.SystemClock; import android.support.v4.util.LongSparseArray; import com.crashlytics.android.answers.CustomEvent; @@ -14,7 +15,6 @@ import java.util.Date; import java.util.List; import info.nightscout.androidaps.BuildConfig; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; @@ -23,15 +23,23 @@ import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.db.BgReading; import info.nightscout.androidaps.events.Event; import info.nightscout.androidaps.interfaces.PluginType; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished; import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventIobCalculationProgress; import info.nightscout.androidaps.plugins.OpenAPSSMB.SMBDefaults; -import info.nightscout.androidaps.plugins.SensitivityAAPS.SensitivityAAPSPlugin; -import info.nightscout.androidaps.plugins.SensitivityWeightedAverage.SensitivityWeightedAveragePlugin; +import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; +import info.nightscout.androidaps.plugins.Overview.notifications.Notification; +import info.nightscout.androidaps.plugins.Sensitivity.SensitivityAAPSPlugin; +import info.nightscout.androidaps.plugins.Sensitivity.SensitivityWeightedAveragePlugin; import info.nightscout.androidaps.plugins.Treatments.Treatment; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.utils.DateUtil; +import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.FabricPrivacy; +import info.nightscout.utils.MidnightTime; +import info.nightscout.utils.Profiler; import info.nightscout.utils.SP; import static info.nightscout.utils.DateUtil.now; @@ -41,24 +49,26 @@ import static info.nightscout.utils.DateUtil.now; */ public class IobCobThread extends Thread { - private static Logger log = LoggerFactory.getLogger(IobCobThread.class); + private static Logger log = LoggerFactory.getLogger(L.AUTOSENS); private final Event cause; private IobCobCalculatorPlugin iobCobCalculatorPlugin; private boolean bgDataReload; + private boolean limitDataToOldestAvailable; private String from; - private long start; + private long end; private PowerManager.WakeLock mWakeLock; - public IobCobThread(IobCobCalculatorPlugin plugin, String from, long start, boolean bgDataReload, Event cause) { + public IobCobThread(IobCobCalculatorPlugin plugin, String from, long end, boolean bgDataReload, boolean limitDataToOldestAvailable, Event cause) { super(); this.iobCobCalculatorPlugin = plugin; this.bgDataReload = bgDataReload; + this.limitDataToOldestAvailable = limitDataToOldestAvailable; this.from = from; this.cause = cause; - this.start = start; + this.end = end; PowerManager powerManager = (PowerManager) MainApp.instance().getApplicationContext().getSystemService(Context.POWER_SERVICE); mWakeLock = powerManager.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "iobCobThread"); @@ -66,35 +76,42 @@ public class IobCobThread extends Thread { @Override public final void run() { + long start = DateUtil.now(); mWakeLock.acquire(); try { - if (MainApp.getConfigBuilder() == null) { - log.debug("Aborting calculation thread (ConfigBuilder not ready): " + from); + if (L.isEnabled(L.AUTOSENS)) + log.debug("AUTOSENSDATA thread started: " + from); + if (ConfigBuilderPlugin.getPlugin() == null) { + if (L.isEnabled(L.AUTOSENS)) + log.debug("Aborting calculation thread (ConfigBuilder not ready): " + from); return; // app still initializing } - if (!MainApp.getConfigBuilder().isProfileValid("IobCobThread")) { - log.debug("Aborting calculation thread (No profile): " + from); + if (!ProfileFunctions.getInstance().isProfileValid("IobCobThread")) { + if (L.isEnabled(L.AUTOSENS)) + log.debug("Aborting calculation thread (No profile): " + from); return; // app still initializing } //log.debug("Locking calculateSensitivityData"); - long oldestTimeWithData = iobCobCalculatorPlugin.oldestDataAvailable(); + long oldestTimeWithData = iobCobCalculatorPlugin.calculateDetectionStart(end, limitDataToOldestAvailable); synchronized (iobCobCalculatorPlugin.dataLock) { if (bgDataReload) { - iobCobCalculatorPlugin.loadBgData(start); + iobCobCalculatorPlugin.loadBgData(end); iobCobCalculatorPlugin.createBucketedData(); } List bucketed_data = iobCobCalculatorPlugin.getBucketedData(); - LongSparseArray autosensDataTable = IobCobCalculatorPlugin.getPlugin().getAutosensDataTable(); + LongSparseArray autosensDataTable = iobCobCalculatorPlugin.getAutosensDataTable(); if (bucketed_data == null || bucketed_data.size() < 3) { - log.debug("Aborting calculation thread (No bucketed data available): " + from); + if (L.isEnabled(L.AUTOSENS)) + log.debug("Aborting calculation thread (No bucketed data available): " + from); return; } long prevDataTime = IobCobCalculatorPlugin.roundUpTime(bucketed_data.get(bucketed_data.size() - 3).date); - log.debug("Prev data time: " + new Date(prevDataTime).toLocaleString()); + if (L.isEnabled(L.AUTOSENS)) + log.debug("Prev data time: " + new Date(prevDataTime).toLocaleString()); AutosensData previous = autosensDataTable.get(prevDataTime); // start from oldest to be able sub cob for (int i = bucketed_data.size() - 4; i >= 0; i--) { @@ -103,7 +120,8 @@ public class IobCobThread extends Thread { if (iobCobCalculatorPlugin.stopCalculationTrigger) { iobCobCalculatorPlugin.stopCalculationTrigger = false; - log.debug("Aborting calculation thread (trigger): " + from); + if (L.isEnabled(L.AUTOSENS)) + log.debug("Aborting calculation thread (trigger): " + from); return; } // check if data already exists @@ -118,13 +136,14 @@ public class IobCobThread extends Thread { continue; } - Profile profile = MainApp.getConfigBuilder().getProfile(bgTime); + Profile profile = ProfileFunctions.getInstance().getProfile(bgTime); if (profile == null) { - log.debug("Aborting calculation thread (no profile): " + from); + if (L.isEnabled(L.AUTOSENS)) + log.debug("Aborting calculation thread (no profile): " + from); return; // profile not set yet } - if (Config.logAutosensData) + if (L.isEnabled(L.AUTOSENS)) log.debug("Processing calculation thread: " + from + " (" + i + "/" + bucketed_data.size() + ")"); double sens = Profile.toMgdl(profile.getIsf(bgTime), profile.getUnits()); @@ -132,7 +151,7 @@ public class IobCobThread extends Thread { AutosensData autosensData = new AutosensData(); autosensData.time = bgTime; if (previous != null) - autosensData.activeCarbsList = new ArrayList<>(previous.activeCarbsList); + autosensData.activeCarbsList = previous.cloneCarbsList(); else autosensData.activeCarbsList = new ArrayList<>(); @@ -145,6 +164,7 @@ public class IobCobThread extends Thread { log.error("! value < 39"); continue; } + autosensData.bg = bg; delta = (bg - bucketed_data.get(i + 1).value); avgDelta = (bg - bucketed_data.get(i + 3).value) / 3; @@ -162,15 +182,28 @@ public class IobCobThread extends Thread { // https://github.com/openaps/oref0/blob/master/lib/determine-basal/cob-autosens.js#L169 if (i < bucketed_data.size() - 16) { // we need 1h of data to calculate minDeviationSlope long hourago = bgTime + 10 * 1000 - 60 * 60 * 1000L; - AutosensData hourAgoData = IobCobCalculatorPlugin.getPlugin().getAutosensData(hourago); + AutosensData hourAgoData = iobCobCalculatorPlugin.getAutosensData(hourago); if (hourAgoData != null) { int initialIndex = autosensDataTable.indexOfKey(hourAgoData.time); - if (Config.logAutosensData) - log.debug(">>>>> bucketed_data.size()=" + bucketed_data.size() + " i=" + i + "hourAgoData=" + hourAgoData.toString()); + if (L.isEnabled(L.AUTOSENS)) + log.debug(">>>>> bucketed_data.size()=" + bucketed_data.size() + " i=" + i + " hourAgoData=" + hourAgoData.toString()); int past = 1; try { for (; past < 12; past++) { AutosensData ad = autosensDataTable.valueAt(initialIndex + past); + if (L.isEnabled(L.AUTOSENS)) { + log.debug(">>>>> past=" + past + " ad=" + (ad != null ? ad.toString() : null)); + if (ad == null) { + log.debug(autosensDataTable.toString()); + log.debug(bucketed_data.toString()); + log.debug(IobCobCalculatorPlugin.getPlugin().getBgReadings().toString()); + Notification notification = new Notification(Notification.SENDLOGFILES, MainApp.gs(R.string.sendlogfiles), Notification.LOW); + MainApp.bus().post(new EventNewNotification(notification)); + SP.putBoolean("log_AUTOSENS", true); + break; + } + } + // let it here crash on NPE to get more data as i cannot reproduce this bug double deviationSlope = (ad.avgDeviation - avgDeviation) / (ad.time - bgTime) * 1000 * 60 * 5; if (ad.avgDeviation > maxDeviation) { slopeFromMaxDeviation = Math.min(0, deviationSlope); @@ -181,7 +214,7 @@ public class IobCobThread extends Thread { minDeviation = ad.avgDeviation; } - //if (Config.logAutosensData) + //if (Config.isEnabled(L.AUTOSENS)) // log.debug("Deviations: " + new Date(bgTime) + new Date(ad.time) + " avgDeviation=" + avgDeviation + " deviationSlope=" + deviationSlope + " slopeFromMaxDeviation=" + slopeFromMaxDeviation + " slopeFromMinDeviation=" + slopeFromMinDeviation); } } catch (Exception e) { @@ -194,7 +227,17 @@ public class IobCobThread extends Thread { .putCustomAttribute("for_data", ">>>>> bucketed_data.size()=" + bucketed_data.size() + " i=" + i + "hourAgoData=" + hourAgoData.toString()) .putCustomAttribute("past", past) ); + log.debug(autosensDataTable.toString()); + log.debug(bucketed_data.toString()); + log.debug(IobCobCalculatorPlugin.getPlugin().getBgReadings().toString()); + Notification notification = new Notification(Notification.SENDLOGFILES, MainApp.gs(R.string.sendlogfiles), Notification.LOW); + MainApp.bus().post(new EventNewNotification(notification)); + SP.putBoolean("log_AUTOSENS", true); + break; } + } else { + if (L.isEnabled(L.AUTOSENS)) + log.debug(">>>>> bucketed_data.size()=" + bucketed_data.size() + " i=" + i + " hourAgoData=" + "null"); } } @@ -202,6 +245,7 @@ public class IobCobThread extends Thread { for (int ir = 0; ir < recentTreatments.size(); ir++) { autosensData.carbsFromBolus += recentTreatments.get(ir).carbs; autosensData.activeCarbsList.add(new AutosensData.CarbsInPast(recentTreatments.get(ir))); + autosensData.pastSensitivity += "[" + DecimalFormatter.to0Decimal(recentTreatments.get(ir).carbs) + "g]"; } @@ -246,34 +290,44 @@ public class IobCobThread extends Thread { if (autosensData.cob <= 0) { if (Math.abs(deviation) < Constants.DEVIATION_TO_BE_EQUAL) { autosensData.pastSensitivity += "="; - autosensData.nonEqualDeviation = true; + autosensData.validDeviation = true; } else if (deviation > 0) { autosensData.pastSensitivity += "+"; - autosensData.nonEqualDeviation = true; + autosensData.validDeviation = true; } else { autosensData.pastSensitivity += "-"; - autosensData.nonEqualDeviation = true; + autosensData.validDeviation = true; } - autosensData.nonCarbsDeviation = true; } else { autosensData.pastSensitivity += "C"; } //log.debug("TIME: " + new Date(bgTime).toString() + " BG: " + bg + " SENS: " + sens + " DELTA: " + delta + " AVGDELTA: " + avgDelta + " IOB: " + iob.iob + " ACTIVITY: " + iob.activity + " BGI: " + bgi + " DEVIATION: " + deviation); previous = autosensData; - autosensDataTable.put(bgTime, autosensData); - if (Config.logAutosensData) - log.debug("Running detectSensitivity from: " + DateUtil.dateAndTimeString(oldestTimeWithData) + " to: " + DateUtil.dateAndTimeString(bgTime)); - autosensData.autosensRatio = iobCobCalculatorPlugin.detectSensitivity(oldestTimeWithData, bgTime).ratio; - if (Config.logAutosensData) + if (bgTime < now()) + autosensDataTable.put(bgTime, autosensData); + if (L.isEnabled(L.AUTOSENS)) + log.debug("Running detectSensitivity from: " + DateUtil.dateAndTimeString(oldestTimeWithData) + " to: " + DateUtil.dateAndTimeString(bgTime) + " lastDataTime:" + iobCobCalculatorPlugin.lastDataTime()); + AutosensResult sensitivity = iobCobCalculatorPlugin.detectSensitivityWithLock(oldestTimeWithData, bgTime); + if (L.isEnabled(L.AUTOSENS)) + log.debug("Sensitivity result: " + sensitivity.toString()); + autosensData.autosensResult = sensitivity; + if (L.isEnabled(L.AUTOSENS)) log.debug(autosensData.toString()); } } - MainApp.bus().post(new EventAutosensCalculationFinished(cause)); - log.debug("Finishing calculation thread: " + from); + new Thread(() -> { + SystemClock.sleep(1000); + MainApp.bus().post(new EventAutosensCalculationFinished(cause)); + }).start(); } finally { mWakeLock.release(); MainApp.bus().post(new EventIobCalculationProgress("")); + if (L.isEnabled(L.AUTOSENS)) { + log.debug("AUTOSENSDATA thread ended: " + from); + log.debug("Midnights: " + MidnightTime.log()); + } + Profiler.log(log, "IobCobThread", start); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Loop/APSResult.java b/app/src/main/java/info/nightscout/androidaps/plugins/Loop/APSResult.java index 87e55c7dc6..3678617c96 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Loop/APSResult.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Loop/APSResult.java @@ -10,27 +10,35 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; -import java.util.Date; import java.util.List; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.IobTotal; +import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.db.BgReading; +import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.interfaces.Constraint; +import info.nightscout.androidaps.interfaces.PumpDescription; import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; +import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.utils.DecimalFormatter; +import info.nightscout.utils.SP; /** * Created by mike on 09.06.2016. */ public class APSResult { - private static Logger log = LoggerFactory.getLogger(APSResult.class); + private static Logger log = LoggerFactory.getLogger(L.APS); - public Date date; + public long date = 0; public String reason; public double rate; + public int percent; + public boolean usePercent = false; public int duration; public boolean tempBasalRequested = false; public boolean bolusRequested = false; @@ -43,11 +51,42 @@ public class APSResult { public Constraint inputConstraints; public Constraint rateConstraint; + public Constraint percentConstraint; public Constraint smbConstraint; + public APSResult rate(double rate) { + this.rate = rate; + return this; + } + + public APSResult duration(int duration) { + this.duration = duration; + return this; + } + + public APSResult percent(int percent) { + this.percent = percent; + return this; + } + + public APSResult tempBasalRequested(boolean tempBasalRequested) { + this.tempBasalRequested = tempBasalRequested; + return this; + } + + public APSResult usePercent(boolean usePercent) { + this.usePercent = usePercent; + return this; + } + + public APSResult json(JSONObject json) { + this.json = json; + return this; + } + @Override public String toString() { - final PumpInterface pump = ConfigBuilderPlugin.getActivePump(); + final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); if (isChangeRequested()) { String ret; // rate @@ -55,6 +94,10 @@ public class APSResult { ret = MainApp.gs(R.string.canceltemp) + "\n"; else if (rate == -1) ret = MainApp.gs(R.string.let_temp_basal_run) + "\n"; + else if (usePercent) + ret = MainApp.gs(R.string.rate) + ": " + DecimalFormatter.to2Decimal(percent) + "% " + + "(" + DecimalFormatter.to2Decimal(percent * pump.getBaseBasalRate() / 100d) + " U/h)\n" + + MainApp.gs(R.string.duration) + ": " + DecimalFormatter.to2Decimal(duration) + " min\n"; else ret = MainApp.gs(R.string.rate) + ": " + DecimalFormatter.to2Decimal(rate) + " U/h " + "(" + DecimalFormatter.to2Decimal(rate / pump.getBaseBasalRate() * 100) + "%) \n" + @@ -72,7 +115,7 @@ public class APSResult { } public Spanned toSpanned() { - final PumpInterface pump = ConfigBuilderPlugin.getActivePump(); + final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); if (isChangeRequested()) { String ret; // rate @@ -80,9 +123,13 @@ public class APSResult { ret = MainApp.gs(R.string.canceltemp) + "
"; else if (rate == -1) ret = MainApp.gs(R.string.let_temp_basal_run) + "
"; + else if (usePercent) + ret = "" + MainApp.gs(R.string.rate) + ": " + DecimalFormatter.to2Decimal(percent) + "% " + + "(" + DecimalFormatter.to2Decimal(percent * pump.getBaseBasalRate() / 100d) + " U/h)
" + + "" + MainApp.gs(R.string.duration) + ": " + DecimalFormatter.to2Decimal(duration) + " min
"; else ret = "" + MainApp.gs(R.string.rate) + ": " + DecimalFormatter.to2Decimal(rate) + " U/h " + - "(" + DecimalFormatter.to2Decimal(rate / pump.getBaseBasalRate() * 100) + "%)
" + + "(" + DecimalFormatter.to2Decimal(rate / pump.getBaseBasalRate() * 100d) + "%)
" + "" + MainApp.gs(R.string.duration) + ": " + DecimalFormatter.to2Decimal(duration) + " min
"; // smb @@ -101,21 +148,33 @@ public class APSResult { public APSResult clone() { APSResult newResult = new APSResult(); - newResult.reason = reason; + doClone(newResult); + return newResult; + } + + protected void doClone(APSResult newResult) { + newResult.date = date; + newResult.reason = reason != null ? new String(reason) : null; newResult.rate = rate; newResult.duration = duration; newResult.tempBasalRequested = tempBasalRequested; newResult.bolusRequested = bolusRequested; newResult.iob = iob; - newResult.json = json; + try { + newResult.json = new JSONObject(json.toString()); + } catch (JSONException e) { + log.error("Unhandled exception", e); + } newResult.hasPredictions = hasPredictions; newResult.smb = smb; newResult.deliverAt = deliverAt; newResult.rateConstraint = rateConstraint; newResult.smbConstraint = smbConstraint; - return newResult; + newResult.percent = percent; + newResult.usePercent = usePercent; } + public JSONObject json() { JSONObject json = new JSONObject(); try { @@ -133,8 +192,8 @@ public class APSResult { public List getPredictions() { List array = new ArrayList<>(); try { - long startTime = date.getTime(); - if (json.has("predBGs")) { + long startTime = date; + if (json != null && json.has("predBGs")) { JSONObject predBGs = json.getJSONObject("predBGs"); if (predBGs.has("IOB")) { JSONArray iob = predBGs.getJSONArray("IOB"); @@ -196,8 +255,8 @@ public class APSResult { public long getLatestPredictionsTime() { long latest = 0; try { - long startTime = date != null ? date.getTime() : 0; - if (json.has("predBGs")) { + long startTime = date; + if (json != null && json.has("predBGs")) { JSONObject predBGs = json.getJSONObject("predBGs"); if (predBGs.has("IOB")) { JSONArray iob = predBGs.getJSONArray("IOB"); @@ -228,6 +287,119 @@ public class APSResult { } public boolean isChangeRequested() { - return tempBasalRequested || bolusRequested; + Constraint 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; + } + } } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Loop/DeviceStatus.java b/app/src/main/java/info/nightscout/androidaps/plugins/Loop/DeviceStatus.java index acf59865d1..2c2bb1a2ee 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Loop/DeviceStatus.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Loop/DeviceStatus.java @@ -1,17 +1,11 @@ package info.nightscout.androidaps.plugins.Loop; -import android.content.Context; -import android.content.Intent; -import android.os.Bundle; - import org.json.JSONException; import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.Services.Intents; -import info.nightscout.androidaps.plugins.NSClientInternal.data.DbLogger; +import info.nightscout.androidaps.logging.L; /* { @@ -371,7 +365,7 @@ import info.nightscout.androidaps.plugins.NSClientInternal.data.DbLogger; */ public class DeviceStatus { - private static Logger log = LoggerFactory.getLogger(DeviceStatus.class); + private static Logger log = LoggerFactory.getLogger(L.APS); public String device = null; public JSONObject pump = null; @@ -381,12 +375,12 @@ public class DeviceStatus { public int uploaderBattery = 0; public String created_at = null; - public JSONObject mongoRecord () { + public JSONObject mongoRecord() { JSONObject record = new JSONObject(); try { - if (device != null) record.put("device" , device); - if (pump != null) record.put("pump" , pump); + if (device != null) record.put("device", device); + if (pump != null) record.put("pump", pump); if (suggested != null) { JSONObject openaps = new JSONObject(); if (enacted != null) openaps.put("enacted", enacted); @@ -395,7 +389,7 @@ public class DeviceStatus { record.put("openaps", openaps); } if (uploaderBattery != 0) record.put("uploaderBattery", uploaderBattery); - if (created_at != null) record.put("created_at" , created_at); + if (created_at != null) record.put("created_at", created_at); } catch (JSONException e) { log.error("Unhandled exception", e); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Loop/LoopFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Loop/LoopFragment.java index 4ad35c0d02..0c0e31fb03 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Loop/LoopFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Loop/LoopFragment.java @@ -28,8 +28,6 @@ import info.nightscout.androidaps.plugins.Loop.events.EventLoopUpdateGui; import info.nightscout.utils.FabricPrivacy; public class LoopFragment extends SubscriberFragment { - private static Logger log = LoggerFactory.getLogger(LoopFragment.class); - @BindView(R.id.loop_run) Button runNowButton; @BindView(R.id.loop_lastrun) @@ -80,7 +78,7 @@ public class LoopFragment extends SubscriberFragment { clearGUI(); final Activity activity = getActivity(); if (activity != null) - activity.runOnUiThread(() -> lastRunView.setText(ev.text)); + activity.runOnUiThread(() -> { synchronized (LoopFragment.this) { if (lastRunView != null) lastRunView.setText(ev.text); } }); } @@ -89,26 +87,29 @@ public class LoopFragment extends SubscriberFragment { Activity activity = getActivity(); if (activity != null) activity.runOnUiThread(() -> { - LoopPlugin.LastRun lastRun = LoopPlugin.lastRun; - if (lastRun != null) { - requestView.setText(lastRun.request != null ? lastRun.request.toSpanned() : ""); - constraintsProcessedView.setText(lastRun.constraintsProcessed != null ? lastRun.constraintsProcessed.toSpanned() : ""); - sourceView.setText(lastRun.source != null ? lastRun.source : ""); - lastRunView.setText(lastRun.lastAPSRun != null && lastRun.lastAPSRun.getTime() != 0 ? lastRun.lastAPSRun.toLocaleString() : ""); - lastEnactView.setText(lastRun.lastEnact != null && lastRun.lastEnact.getTime() != 0 ? lastRun.lastEnact.toLocaleString() : ""); - tbrSetByPumpView.setText(lastRun.tbrSetByPump != null ? Html.fromHtml(lastRun.tbrSetByPump.toHtml()) : ""); - smbSetByPumpView.setText(lastRun.smbSetByPump != null ? Html.fromHtml(lastRun.smbSetByPump.toHtml()) : ""); + synchronized (LoopFragment.this) { + if (!isBound()) return; + LoopPlugin.LastRun lastRun = LoopPlugin.lastRun; + if (lastRun != null) { + requestView.setText(lastRun.request != null ? lastRun.request.toSpanned() : ""); + constraintsProcessedView.setText(lastRun.constraintsProcessed != null ? lastRun.constraintsProcessed.toSpanned() : ""); + sourceView.setText(lastRun.source != null ? lastRun.source : ""); + lastRunView.setText(lastRun.lastAPSRun != null && lastRun.lastAPSRun.getTime() != 0 ? lastRun.lastAPSRun.toLocaleString() : ""); + lastEnactView.setText(lastRun.lastEnact != null && lastRun.lastEnact.getTime() != 0 ? lastRun.lastEnact.toLocaleString() : ""); + tbrSetByPumpView.setText(lastRun.tbrSetByPump != null ? Html.fromHtml(lastRun.tbrSetByPump.toHtml()) : ""); + smbSetByPumpView.setText(lastRun.smbSetByPump != null ? Html.fromHtml(lastRun.smbSetByPump.toHtml()) : ""); - String constraints = ""; - if (lastRun.constraintsProcessed != null) { - Constraint allConstraints = new Constraint<>(0d); - if (lastRun.constraintsProcessed.rateConstraint != null) - allConstraints.copyReasons(lastRun.constraintsProcessed.rateConstraint); - if (lastRun.constraintsProcessed.smbConstraint != null) - allConstraints.copyReasons(lastRun.constraintsProcessed.smbConstraint); - constraints = allConstraints.getMostLimitedReasons(); + String constraints = ""; + if (lastRun.constraintsProcessed != null) { + Constraint allConstraints = new Constraint<>(0d); + if (lastRun.constraintsProcessed.rateConstraint != null) + allConstraints.copyReasons(lastRun.constraintsProcessed.rateConstraint); + if (lastRun.constraintsProcessed.smbConstraint != null) + allConstraints.copyReasons(lastRun.constraintsProcessed.smbConstraint); + constraints = allConstraints.getMostLimitedReasons(); + } + constraintsView.setText(constraints); } - constraintsView.setText(constraints); } }); } @@ -117,13 +118,29 @@ public class LoopFragment extends SubscriberFragment { Activity activity = getActivity(); if (activity != null) activity.runOnUiThread(() -> { - requestView.setText(""); - constraintsProcessedView.setText(""); - sourceView.setText(""); - lastRunView.setText(""); - lastEnactView.setText(""); - tbrSetByPumpView.setText(""); - smbSetByPumpView.setText(""); + synchronized (LoopFragment.this) { + if (isBound()) { + requestView.setText(""); + constraintsProcessedView.setText(""); + sourceView.setText(""); + lastRunView.setText(""); + lastEnactView.setText(""); + tbrSetByPumpView.setText(""); + smbSetByPumpView.setText(""); + } + } }); } + + boolean isBound() { + return requestView != null + && constraintsProcessedView != null + && sourceView != null + && lastRunView != null + && lastEnactView != null + && tbrSetByPumpView != null + && smbSetByPumpView != null + && constraintsView != null + && runNowButton != null; + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Loop/LoopPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Loop/LoopPlugin.java index f6ec0ff7ab..ac5076be72 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Loop/LoopPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Loop/LoopPlugin.java @@ -21,46 +21,58 @@ import org.slf4j.LoggerFactory; import java.util.Date; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainActivity; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.db.BgReading; +import info.nightscout.androidaps.db.CareportalEvent; import info.nightscout.androidaps.db.DatabaseHelper; -import info.nightscout.androidaps.events.Event; +import info.nightscout.androidaps.db.Source; +import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.events.EventNewBG; -import info.nightscout.androidaps.events.EventTreatmentChange; import info.nightscout.androidaps.interfaces.APSInterface; import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginType; +import info.nightscout.androidaps.interfaces.PumpDescription; import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.interfaces.TreatmentsInterface; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished; import info.nightscout.androidaps.plugins.Loop.events.EventLoopSetLastRunGui; import info.nightscout.androidaps.plugins.Loop.events.EventLoopUpdateGui; import info.nightscout.androidaps.plugins.Loop.events.EventNewOpenLoopNotification; +import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; +import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; +import info.nightscout.androidaps.plugins.Wear.ActionStringHandler; +import info.nightscout.androidaps.events.EventAcceptOpenLoopChange; import info.nightscout.androidaps.queue.Callback; +import info.nightscout.androidaps.queue.commands.Command; import info.nightscout.utils.FabricPrivacy; -import info.nightscout.utils.NSUpload; import info.nightscout.utils.SP; +import info.nightscout.utils.T; +import info.nightscout.utils.ToastUtils; /** * Created by mike on 05.08.2016. */ public class LoopPlugin extends PluginBase { - private static Logger log = LoggerFactory.getLogger(LoopPlugin.class); + private static Logger log = LoggerFactory.getLogger(L.APS); - public static final String CHANNEL_ID = "AndroidAPS-Openloop"; + private static final String CHANNEL_ID = "AndroidAPS-Openloop"; - long lastBgTriggeredRun = 0; + private long lastBgTriggeredRun = 0; - protected static LoopPlugin loopPlugin; + private static LoopPlugin loopPlugin; @NonNull public static LoopPlugin getPlugin() { @@ -93,7 +105,8 @@ public class LoopPlugin extends PluginBase { .fragmentClass(LoopFragment.class.getName()) .pluginName(R.string.loop) .shortName(R.string.loop_shortname) - .preferencesId(R.xml.pref_closedmode) + .preferencesId(R.xml.pref_loop) + .description(R.string.description_loop) ); loopSuspendedTill = SP.getLong("loopSuspendedTill", 0L); isSuperBolus = SP.getBoolean("isSuperBolus", false); @@ -127,18 +140,16 @@ public class LoopPlugin extends PluginBase { @Override public boolean specialEnableCondition() { - PumpInterface pump = ConfigBuilderPlugin.getActivePump(); + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); return pump == null || pump.getPumpDescription().isTempBasalCapable; } - + /** * This method is triggered once autosens calculation has completed, so the LoopPlugin * has current data to work with. However, autosens calculation can be triggered by multiple * sources and currently only a new BG should trigger a loop run. Hence we return early if * the event causing the calculation is not EventNewBg. - * - * Callers of {@link info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin#runCalculation(String, long, boolean, Event)} - * are sources triggering a calculation which triggers this method upon completion. + *

*/ @Subscribe public void onStatusEvent(final EventAutosensCalculationFinished ev) { @@ -247,32 +258,34 @@ public class LoopPlugin extends PluginBase { return isDisconnected; } - public synchronized void invoke(String initiator, boolean allowNotification){ + public synchronized void invoke(String initiator, boolean allowNotification) { invoke(initiator, allowNotification, false); } public synchronized void invoke(String initiator, boolean allowNotification, boolean tempBasalFallback) { try { - if (Config.logFunctionCalls) + if (L.isEnabled(L.APS)) log.debug("invoke from " + initiator); Constraint loopEnabled = MainApp.getConstraintChecker().isLoopInvokationAllowed(); if (!loopEnabled.value()) { String message = MainApp.gs(R.string.loopdisabled) + "\n" + loopEnabled.getReasons(); - log.debug(message); + if (L.isEnabled(L.APS)) + log.debug(message); MainApp.bus().post(new EventLoopSetLastRunGui(message)); return; } - final PumpInterface pump = ConfigBuilderPlugin.getActivePump(); + final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); APSResult result = null; if (!isEnabled(PluginType.LOOP)) return; - Profile profile = MainApp.getConfigBuilder().getProfile(); + Profile profile = ProfileFunctions.getInstance().getProfile(); - if (!MainApp.getConfigBuilder().isProfileValid("Loop")) { - log.debug(MainApp.gs(R.string.noprofileselected)); + if (!ProfileFunctions.getInstance().isProfileValid("Loop")) { + if (L.isEnabled(L.APS)) + log.debug(MainApp.gs(R.string.noprofileselected)); MainApp.bus().post(new EventLoopSetLastRunGui(MainApp.gs(R.string.noprofileselected))); return; } @@ -280,7 +293,7 @@ public class LoopPlugin extends PluginBase { // Check if pump info is loaded if (pump.getBaseBasalRate() < 0.01d) return; - APSInterface usedAPS = ConfigBuilderPlugin.getActiveAPS(); + APSInterface usedAPS = ConfigBuilderPlugin.getPlugin().getActiveAPS(); if (usedAPS != null && ((PluginBase) usedAPS).isEnabled(PluginType.APS)) { usedAPS.invoke(initiator, tempBasalFallback); result = usedAPS.getLastAPSResult(); @@ -292,17 +305,28 @@ public class LoopPlugin extends PluginBase { return; } + // Prepare for pumps using % basals + if (pump.getPumpDescription().tempBasalStyle == PumpDescription.PERCENT) { + result.usePercent = true; + } + result.percent = (int) (result.rate / profile.getBasal() * 100); + // check rate for constrais final APSResult resultAfterConstraints = result.clone(); resultAfterConstraints.rateConstraint = new Constraint<>(resultAfterConstraints.rate); resultAfterConstraints.rate = MainApp.getConstraintChecker().applyBasalConstraints(resultAfterConstraints.rateConstraint, profile).value(); + + resultAfterConstraints.percentConstraint = new Constraint<>(resultAfterConstraints.percent); + resultAfterConstraints.percent = MainApp.getConstraintChecker().applyBasalPercentConstraints(resultAfterConstraints.percentConstraint, profile).value(); + resultAfterConstraints.smbConstraint = new Constraint<>(resultAfterConstraints.smb); resultAfterConstraints.smb = MainApp.getConstraintChecker().applyBolusConstraints(resultAfterConstraints.smbConstraint).value(); // safety check for multiple SMBs long lastBolusTime = TreatmentsPlugin.getPlugin().getLastBolusTime(); - if (lastBolusTime != 0 && lastBolusTime + 3 * 60 * 1000 > System.currentTimeMillis()) { - log.debug("SMB requsted but still in 3 min interval"); + if (lastBolusTime != 0 && lastBolusTime + T.mins(3).msecs() > System.currentTimeMillis()) { + if (L.isEnabled(L.APS)) + log.debug("SMB requsted but still in 3 min interval"); resultAfterConstraints.smb = 0; } @@ -317,13 +341,15 @@ public class LoopPlugin extends PluginBase { NSUpload.uploadDeviceStatus(); if (isSuspended()) { - log.debug(MainApp.gs(R.string.loopsuspended)); + if (L.isEnabled(L.APS)) + log.debug(MainApp.gs(R.string.loopsuspended)); MainApp.bus().post(new EventLoopSetLastRunGui(MainApp.gs(R.string.loopsuspended))); return; } if (pump.isSuspended()) { - log.debug(MainApp.gs(R.string.pumpsuspended)); + if (L.isEnabled(L.APS)) + log.debug(MainApp.gs(R.string.pumpsuspended)); MainApp.bus().post(new EventLoopSetLastRunGui(MainApp.gs(R.string.pumpsuspended))); return; } @@ -331,7 +357,9 @@ public class LoopPlugin extends PluginBase { Constraint closedLoopEnabled = MainApp.getConstraintChecker().isClosedLoopAllowed(); if (closedLoopEnabled.value()) { - if (result.isChangeRequested()) { + if (resultAfterConstraints.isChangeRequested() + && !ConfigBuilderPlugin.getPlugin().getCommandQueue().bolusInQueue() + && !ConfigBuilderPlugin.getPlugin().getCommandQueue().isRunning(Command.CommandType.BOLUS)) { final PumpEnactResult waiting = new PumpEnactResult(); waiting.queued = true; if (resultAfterConstraints.tempBasalRequested) @@ -340,13 +368,13 @@ public class LoopPlugin extends PluginBase { lastRun.smbSetByPump = waiting; MainApp.bus().post(new EventLoopUpdateGui()); FabricPrivacy.getInstance().logCustom(new CustomEvent("APSRequest")); - MainApp.getConfigBuilder().applyTBRRequest(resultAfterConstraints, profile, new Callback() { + applyTBRRequest(resultAfterConstraints, profile, new Callback() { @Override public void run() { if (result.enacted || result.success) { lastRun.tbrSetByPump = result; lastRun.lastEnact = lastRun.lastAPSRun; - MainApp.getConfigBuilder().applySMBRequest(resultAfterConstraints, new Callback() { + applySMBRequest(resultAfterConstraints, new Callback() { @Override public void run() { //Callback is only called if a bolus was acutally requested @@ -372,7 +400,7 @@ public class LoopPlugin extends PluginBase { lastRun.smbSetByPump = null; } } else { - if (result.isChangeRequested() && allowNotification) { + if (resultAfterConstraints.isChangeRequested() && allowNotification) { NotificationCompat.Builder builder = new NotificationCompat.Builder(MainApp.instance().getApplicationContext(), CHANNEL_ID); builder.setSmallIcon(R.drawable.notif_icon) @@ -381,7 +409,8 @@ public class LoopPlugin extends PluginBase { .setAutoCancel(true) .setPriority(Notification.PRIORITY_HIGH) .setCategory(Notification.CATEGORY_ALARM) - .setVisibility(Notification.VISIBILITY_PUBLIC); + .setVisibility(Notification.VISIBILITY_PUBLIC) + .setLocalOnly(true); // Creates an explicit intent for an Activity in your app Intent resultIntent = new Intent(MainApp.instance().getApplicationContext(), MainActivity.class); @@ -403,14 +432,243 @@ public class LoopPlugin extends PluginBase { // mId allows you to update the notification later on. mNotificationManager.notify(Constants.notificationID, builder.build()); MainApp.bus().post(new EventNewOpenLoopNotification()); + + // Send to Wear + ActionStringHandler.handleInitiate("changeRequest"); + } else if (allowNotification) { + // dismiss notifications + NotificationManager notificationManager = + (NotificationManager) MainApp.instance().getSystemService(Context.NOTIFICATION_SERVICE); + notificationManager.cancel(Constants.notificationID); + ActionStringHandler.handleInitiate("cancelChangeRequest"); } } MainApp.bus().post(new EventLoopUpdateGui()); } finally { - if (Config.logFunctionCalls) + if (L.isEnabled(L.APS)) log.debug("invoke end"); } } + public void acceptChangeRequest() { + Profile profile = ProfileFunctions.getInstance().getProfile(); + + applyTBRRequest(lastRun.constraintsProcessed, profile, new Callback() { + @Override + public void run() { + if (result.enacted) { + lastRun.tbrSetByPump = result; + lastRun.lastEnact = new Date(); + lastRun.lastOpenModeAccept = new Date(); + NSUpload.uploadDeviceStatus(); + ObjectivesPlugin objectivesPlugin = MainApp.getSpecificPlugin(ObjectivesPlugin.class); + if (objectivesPlugin != null) { + ObjectivesPlugin.getPlugin().manualEnacts++; + ObjectivesPlugin.getPlugin().saveProgress(); + } + } + MainApp.bus().post(new EventAcceptOpenLoopChange()); + } + }); + FabricPrivacy.getInstance().logCustom(new CustomEvent("AcceptTemp")); + } + + /** + * expect absolute request and allow both absolute and percent response based on pump capabilities + * TODO: update pump drivers to support APS request in % + */ + + public void applyTBRRequest(APSResult request, Profile profile, Callback callback) { + boolean allowPercentage = VirtualPumpPlugin.getPlugin().isEnabled(PluginType.PUMP); + + if (!request.tempBasalRequested) { + if (callback != null) { + callback.result(new PumpEnactResult().enacted(false).success(true).comment(MainApp.gs(R.string.nochangerequested))).run(); + } + return; + } + + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); + TreatmentsInterface activeTreatments = TreatmentsPlugin.getPlugin(); + + if (!pump.isInitialized()) { + if (L.isEnabled(L.APS)) + log.debug("applyAPSRequest: " + MainApp.gs(R.string.pumpNotInitialized)); + if (callback != null) { + callback.result(new PumpEnactResult().comment(MainApp.gs(R.string.pumpNotInitialized)).enacted(false).success(false)).run(); + } + return; + } + + if (pump.isSuspended()) { + if (L.isEnabled(L.APS)) + log.debug("applyAPSRequest: " + MainApp.gs(R.string.pumpsuspended)); + if (callback != null) { + callback.result(new PumpEnactResult().comment(MainApp.gs(R.string.pumpsuspended)).enacted(false).success(false)).run(); + } + return; + } + + if (L.isEnabled(L.APS)) + log.debug("applyAPSRequest: " + request.toString()); + + long now = System.currentTimeMillis(); + TemporaryBasal activeTemp = activeTreatments.getTempBasalFromHistory(now); + if (request.usePercent && allowPercentage) { + if (request.percent == 100 && request.duration == 0) { + if (activeTemp != null) { + if (L.isEnabled(L.APS)) + log.debug("applyAPSRequest: cancelTempBasal()"); + ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(false, callback); + } else { + if (L.isEnabled(L.APS)) + log.debug("applyAPSRequest: Basal set correctly"); + if (callback != null) { + callback.result(new PumpEnactResult().percent(request.percent).duration(0) + .enacted(false).success(true).comment(MainApp.gs(R.string.basal_set_correctly))).run(); + } + } + } else if (activeTemp != null + && activeTemp.getPlannedRemainingMinutes() > 5 + && request.duration - activeTemp.getPlannedRemainingMinutes() < 30 + && request.percent == activeTemp.percentRate) { + if (L.isEnabled(L.APS)) + log.debug("applyAPSRequest: Temp basal set correctly"); + if (callback != null) { + callback.result(new PumpEnactResult().percent(request.percent) + .enacted(false).success(true).duration(activeTemp.getPlannedRemainingMinutes()) + .comment(MainApp.gs(R.string.let_temp_basal_run))).run(); + } + } else { + if (L.isEnabled(L.APS)) + log.debug("applyAPSRequest: tempBasalPercent()"); + ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalPercent(request.percent, request.duration, false, profile, callback); + } + } else { + if ((request.rate == 0 && request.duration == 0) || Math.abs(request.rate - pump.getBaseBasalRate()) < pump.getPumpDescription().basalStep) { + if (activeTemp != null) { + if (L.isEnabled(L.APS)) + log.debug("applyAPSRequest: cancelTempBasal()"); + ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(false, callback); + } else { + if (L.isEnabled(L.APS)) + log.debug("applyAPSRequest: Basal set correctly"); + if (callback != null) { + callback.result(new PumpEnactResult().absolute(request.rate).duration(0) + .enacted(false).success(true).comment(MainApp.gs(R.string.basal_set_correctly))).run(); + } + } + } else if (activeTemp != null + && activeTemp.getPlannedRemainingMinutes() > 5 + && request.duration - activeTemp.getPlannedRemainingMinutes() < 30 + && Math.abs(request.rate - activeTemp.tempBasalConvertedToAbsolute(now, profile)) < pump.getPumpDescription().basalStep) { + if (L.isEnabled(L.APS)) + log.debug("applyAPSRequest: Temp basal set correctly"); + if (callback != null) { + callback.result(new PumpEnactResult().absolute(activeTemp.tempBasalConvertedToAbsolute(now, profile)) + .enacted(false).success(true).duration(activeTemp.getPlannedRemainingMinutes()) + .comment(MainApp.gs(R.string.let_temp_basal_run))).run(); + } + } else { + if (L.isEnabled(L.APS)) + log.debug("applyAPSRequest: setTempBasalAbsolute()"); + ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalAbsolute(request.rate, request.duration, false, profile, callback); + } + } + } + + public void applySMBRequest(APSResult request, Callback callback) { + if (!request.bolusRequested) { + return; + } + + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); + TreatmentsInterface activeTreatments = TreatmentsPlugin.getPlugin(); + + long lastBolusTime = activeTreatments.getLastBolusTime(); + if (lastBolusTime != 0 && lastBolusTime + 3 * 60 * 1000 > System.currentTimeMillis()) { + if (L.isEnabled(L.APS)) + log.debug("SMB requested but still in 3 min interval"); + if (callback != null) { + callback.result(new PumpEnactResult() + .comment(MainApp.gs(R.string.smb_frequency_exceeded)) + .enacted(false).success(false)).run(); + } + return; + } + + if (!pump.isInitialized()) { + if (L.isEnabled(L.APS)) + log.debug("applySMBRequest: " + MainApp.gs(R.string.pumpNotInitialized)); + if (callback != null) { + callback.result(new PumpEnactResult().comment(MainApp.gs(R.string.pumpNotInitialized)).enacted(false).success(false)).run(); + } + return; + } + + if (pump.isSuspended()) { + if (L.isEnabled(L.APS)) + log.debug("applySMBRequest: " + MainApp.gs(R.string.pumpsuspended)); + if (callback != null) { + callback.result(new PumpEnactResult().comment(MainApp.gs(R.string.pumpsuspended)).enacted(false).success(false)).run(); + } + return; + } + + if (L.isEnabled(L.APS)) + log.debug("applySMBRequest: " + request.toString()); + + // deliver SMB + DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo(); + detailedBolusInfo.lastKnownBolusTime = activeTreatments.getLastBolusTime(); + detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS; + detailedBolusInfo.insulin = request.smb; + detailedBolusInfo.isSMB = true; + detailedBolusInfo.source = Source.USER; + detailedBolusInfo.deliverAt = request.deliverAt; + if (L.isEnabled(L.APS)) + log.debug("applyAPSRequest: bolus()"); + ConfigBuilderPlugin.getPlugin().getCommandQueue().bolus(detailedBolusInfo, callback); + } + + public void disconnectPump(int durationInMinutes, Profile profile) { + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); + TreatmentsInterface activeTreatments = TreatmentsPlugin.getPlugin(); + + LoopPlugin.getPlugin().disconnectTo(System.currentTimeMillis() + durationInMinutes * 60 * 1000L); + ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalPercent(0, durationInMinutes, true, profile, new Callback() { + @Override + public void run() { + if (!result.success) { + ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.tempbasaldeliveryerror)); + } + } + }); + if (pump.getPumpDescription().isExtendedBolusCapable && activeTreatments.isInHistoryExtendedBoluslInProgress()) { + ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelExtended(new Callback() { + @Override + public void run() { + if (!result.success) { + ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.extendedbolusdeliveryerror)); + } + } + }); + } + NSUpload.uploadOpenAPSOffline(durationInMinutes); + } + + public void suspendLoop(int durationInMinutes) { + LoopPlugin.getPlugin().suspendTo(System.currentTimeMillis() + durationInMinutes * 60 * 1000); + ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(true, new Callback() { + @Override + public void run() { + if (!result.success) { + ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.tempbasaldeliveryerror)); + } + } + }); + NSUpload.uploadOpenAPSOffline(durationInMinutes); + } + } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Maintenance/ImportExportPrefs.java b/app/src/main/java/info/nightscout/androidaps/plugins/Maintenance/ImportExportPrefs.java new file mode 100644 index 0000000000..d108382c92 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Maintenance/ImportExportPrefs.java @@ -0,0 +1,160 @@ +package info.nightscout.androidaps.plugins.Maintenance; + +import android.Manifest; +import android.app.Activity; +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.os.Environment; +import android.preference.PreferenceManager; +import android.support.v4.app.ActivityCompat; +import android.support.v4.app.Fragment; +import android.support.v4.content.ContextCompat; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Map; + +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.events.EventAppExit; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.utils.OKDialog; +import info.nightscout.utils.ToastUtils; + +/** + * Created by mike on 03.07.2016. + */ + +public class ImportExportPrefs { + private static Logger log = LoggerFactory.getLogger(L.CORE); + static File path = new File(Environment.getExternalStorageDirectory().toString()); + static public final File file = new File(path, MainApp.gs(R.string.app_name) + "Preferences"); + + private static final int REQUEST_EXTERNAL_STORAGE = 1; + private static String[] PERMISSIONS_STORAGE = { + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE + }; + + public static void verifyStoragePermissions(Activity activity) { + // Check if we have write permission + int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE); + + if (permission != PackageManager.PERMISSION_GRANTED) { + // We don't have permission so prompt the user + ActivityCompat.requestPermissions( + activity, + PERMISSIONS_STORAGE, + REQUEST_EXTERNAL_STORAGE + ); + } + } + + public static void verifyStoragePermissions(Fragment fragment) { + int permission = ContextCompat.checkSelfPermission(fragment.getContext(), + Manifest.permission.WRITE_EXTERNAL_STORAGE); + + if (permission != PackageManager.PERMISSION_GRANTED) { + // We don't have permission so prompt the user + fragment.requestPermissions(PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE); + } + + } + + public static void exportSharedPreferences(final Fragment f) { + exportSharedPreferences(f.getContext()); + } + + public static void exportSharedPreferences(final Context c) { + + new AlertDialog.Builder(c) + .setMessage(MainApp.gs(R.string.export_to) + " " + file + " ?") + .setPositiveButton(android.R.string.yes, (dialog, which) -> { + + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c); + try { + FileWriter fw = new FileWriter(file); + PrintWriter pw = new PrintWriter(fw); + Map prefsMap = prefs.getAll(); + for (Map.Entry entry : prefsMap.entrySet()) { + pw.println(entry.getKey() + "::" + entry.getValue().toString()); + } + pw.close(); + fw.close(); + ToastUtils.showToastInUiThread(c, MainApp.gs(R.string.exported)); + } catch (FileNotFoundException e) { + ToastUtils.showToastInUiThread(c, MainApp.gs(R.string.filenotfound) + " " + file); + log.error("Unhandled exception", e); + } catch (IOException e) { + log.error("Unhandled exception", e); + } + }) + .setNegativeButton(android.R.string.cancel, null) + .show(); + } + + public static void importSharedPreferences(final Fragment fragment) { + importSharedPreferences(fragment.getContext()); + } + + public static void importSharedPreferences(final Context context) { + new AlertDialog.Builder(context) + .setMessage(MainApp.gs(R.string.import_from) + " " + file + " ?") + .setPositiveButton(android.R.string.yes, (dialog, which) -> { + + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + SharedPreferences.Editor editor = prefs.edit(); + String line; + String[] lineParts; + try { + editor.clear(); + editor.commit(); + + BufferedReader reader = new BufferedReader(new FileReader(file)); + while ((line = reader.readLine()) != null) { + lineParts = line.split("::"); + if (lineParts.length == 2) { + if (lineParts[1].equals("true") || lineParts[1].equals("false")) { + editor.putBoolean(lineParts[0], Boolean.parseBoolean(lineParts[1])); + } else { + editor.putString(lineParts[0], lineParts[1]); + } + } + } + reader.close(); + editor.commit(); + OKDialog.show(context, MainApp.gs(R.string.setting_imported), MainApp.gs(R.string.restartingapp), () -> { + log.debug("Exiting"); + MainApp.instance().stopKeepAliveService(); + MainApp.bus().post(new EventAppExit()); + MainApp.closeDbHelper(); + if (context instanceof Activity) { + ((Activity)context).finish(); + } + System.runFinalization(); + System.exit(0); + }); + } catch (FileNotFoundException e) { + ToastUtils.showToastInUiThread(context, MainApp.gs(R.string.filenotfound) + " " + file); + log.error("Unhandled exception", e); + } catch (IOException e) { + log.error("Unhandled exception", e); + } + }) + .setNegativeButton(android.R.string.cancel, null) + .show(); + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Maintenance/LoggerUtils.java b/app/src/main/java/info/nightscout/androidaps/plugins/Maintenance/LoggerUtils.java new file mode 100644 index 0000000000..fc1cc0362a --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Maintenance/LoggerUtils.java @@ -0,0 +1,29 @@ +package info.nightscout.androidaps.plugins.Maintenance; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import ch.qos.logback.classic.LoggerContext; +import info.nightscout.androidaps.logging.L; + +/** + * This class provides serveral methods for log-handling (eg. sending logs as emails). + */ +public class LoggerUtils { + + private static final Logger LOGGER = LoggerFactory.getLogger(L.CORE); + + public static String SUFFIX = ".log.zip"; + + /** + * Returns the directory, in which the logs are stored on the system. This is configured in the + * logback.xml file. + * + * @return + */ + public static String getLogDirectory() { + LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory(); + return lc.getProperty("EXT_FILES_DIR"); + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Maintenance/MaintenanceFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Maintenance/MaintenanceFragment.java new file mode 100644 index 0000000000..f9c00d56c7 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Maintenance/MaintenanceFragment.java @@ -0,0 +1,83 @@ +package info.nightscout.androidaps.plugins.Maintenance; + +import android.content.Intent; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.support.v7.app.AlertDialog; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.plugins.Food.FoodPlugin; +import info.nightscout.androidaps.plugins.Maintenance.activities.LogSettingActivity; +import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; + +/** + * + */ +public class MaintenanceFragment extends Fragment { + + private Fragment f; + + @Override + public void onResume() { + super.onResume(); + + this.f = this; + } + + @Override + public void onPause() { + super.onPause(); + + this.f = null; + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.maintenance_fragment, container, false); + + final Fragment f = this; + + view.findViewById(R.id.log_send).setOnClickListener(view1 -> MaintenancePlugin.getPlugin().sendLogs()); + + view.findViewById(R.id.log_delete).setOnClickListener(view1 -> MaintenancePlugin.getPlugin().deleteLogs()); + + view.findViewById(R.id.nav_resetdb).setOnClickListener(view1 -> new AlertDialog.Builder(f.getContext()) + .setTitle(R.string.nav_resetdb) + .setMessage(R.string.reset_db_confirm) + .setNegativeButton(android.R.string.cancel, null) + .setPositiveButton(android.R.string.ok, (dialog, which) -> { + MainApp.getDbHelper().resetDatabases(); + // should be handled by Plugin-Interface and + // additional service interface and plugin registry + FoodPlugin.getPlugin().getService().resetFood(); + TreatmentsPlugin.getPlugin().getService().resetTreatments(); + }) + .create() + .show()); + + view.findViewById(R.id.nav_export).setOnClickListener(view1 -> { + // start activity for checking permissions... + ImportExportPrefs.verifyStoragePermissions(f); + ImportExportPrefs.exportSharedPreferences(f); + }); + + view.findViewById(R.id.nav_import).setOnClickListener(view1 -> { + // start activity for checking permissions... + ImportExportPrefs.verifyStoragePermissions(f); + ImportExportPrefs.importSharedPreferences(f); + }); + + view.findViewById(R.id.nav_logsettings).setOnClickListener(view1 -> { + startActivity(new Intent(getActivity(), LogSettingActivity.class)); + }); + + + return view; + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Maintenance/MaintenancePlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Maintenance/MaintenancePlugin.java new file mode 100644 index 0000000000..c73a5160ac --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Maintenance/MaintenancePlugin.java @@ -0,0 +1,265 @@ +package info.nightscout.androidaps.plugins.Maintenance; + +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.support.v4.content.FileProvider; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import info.nightscout.androidaps.BuildConfig; +import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.interfaces.PluginBase; +import info.nightscout.androidaps.interfaces.PluginDescription; +import info.nightscout.androidaps.interfaces.PluginType; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.NSClientInternal.data.NSSettingsStatus; +import info.nightscout.utils.SP; + +public class MaintenancePlugin extends PluginBase { + + private static final Logger LOG = LoggerFactory.getLogger(L.CORE); + + private final Context ctx; + + private static MaintenancePlugin maintenancePlugin; + + public static MaintenancePlugin getPlugin() { + return maintenancePlugin; + } + + public static MaintenancePlugin initPlugin(Context ctx) { + + if (maintenancePlugin == null) { + maintenancePlugin = new MaintenancePlugin(ctx); + } + + return maintenancePlugin; + } + + public MaintenancePlugin() { + // required for testing + super(null); + this.ctx = null; + } + + MaintenancePlugin(Context ctx) { + super(new PluginDescription() + .mainType(PluginType.GENERAL) + .fragmentClass(MaintenanceFragment.class.getName()) + .alwayVisible(false) + .alwaysEnabled(true) + .pluginName(R.string.maintenance) + .shortName(R.string.maintenance_shortname) + .preferencesId(R.xml.pref_maintenance) + .description(R.string.description_maintenance) + ); + this.ctx = ctx; + } + + public void sendLogs() { + String recipient = SP.getString(R.string.key_maintenance_logs_email, "logs@androidaps.org"); + int amount = SP.getInt(R.string.key_maintenance_logs_amount, 2); + + String logDirectory = LoggerUtils.getLogDirectory(); + List logs = this.getLogfiles(logDirectory, amount); + + File zipDir = this.ctx.getExternalFilesDir("exports"); + File zipFile = new File(zipDir, this.constructName()); + + LOG.debug("zipFile: {}", zipFile.getAbsolutePath()); + File zip = this.zipLogs(zipFile, logs); + + Uri attachementUri = FileProvider.getUriForFile(this.ctx, BuildConfig.APPLICATION_ID + ".fileprovider", zip); + Intent emailIntent = this.sendMail(attachementUri, recipient, "Log Export"); + LOG.debug("sending emailIntent"); + ctx.startActivity(emailIntent); + } + + //todo replace this with a call on startup of the application, specifically to remove + // unnecessary garbage from the log exports + public void deleteLogs() { + String logDirectory = LoggerUtils.getLogDirectory(); + File logDir = new File(logDirectory); + + File[] files = logDir.listFiles((file, name) -> name.startsWith("AndroidAPS") + && name.endsWith(".zip")); + + Arrays.sort(files, (f1, f2) -> f1.getName().compareTo(f2.getName())); + + List delFiles = Arrays.asList(files); + int amount = SP.getInt(R.string.key_logshipper_amount, 2); + int keepIndex = amount - 1; + + if (keepIndex < delFiles.size()) { + delFiles = delFiles.subList(keepIndex, delFiles.size()); + + for (File file : delFiles) { + file.delete(); + } + } + + File exportDir = new File(logDirectory, "exports"); + + if (exportDir.exists()) { + File[] expFiles = exportDir.listFiles(); + + for (File file : expFiles) { + file.delete(); + } + exportDir.delete(); + } + } + + /** + * returns a list of log files. The number of returned logs is given via the amount + * parameter. + * + * The log files are sorted by the name descending. + * + * @param directory + * @param amount + * @return + */ + public List getLogfiles(String directory, int amount) { + LOG.debug("getting {} logs from directory {}", amount, directory); + File logDir = new File(directory); + + File[] files = logDir.listFiles((file, name) -> name.startsWith("AndroidAPS") + && (name.endsWith(".log") + || (name.endsWith(".zip") && !name.endsWith(LoggerUtils.SUFFIX)))); + + Arrays.sort(files, (f1, f2) -> f2.getName().compareTo(f1.getName())); + + List result = Arrays.asList(files); + int toIndex = amount++; + + if (toIndex > result.size()) { + toIndex = result.size(); + } + + LOG.debug("returning sublist 0 to {}", toIndex); + return result.subList(0, toIndex); + } + + public File zipLogs(File zipFile, List files) { + LOG.debug("creating zip {}", zipFile.getAbsolutePath()); + + try { + zip(zipFile, files); + } catch (IOException e) { + LOG.error("Cannot retrieve zip", e); + } + + return zipFile; + } + + /** + * construct the name of zip file which is used to export logs. + * + * The name is constructed using the following scheme: + * AndroidAPS_LOG_ + Long Time + .log.zip + * + * @return + */ + public String constructName() { + return "AndroidAPS_LOG_" + String.valueOf(new Date().getTime()) + LoggerUtils.SUFFIX; + } + + public void zip(File zipFile, List files) throws IOException { + final int BUFFER_SIZE = 2048; + + ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFile))); + + for (File file : files) { + byte data[] = new byte[BUFFER_SIZE]; + + try(FileInputStream fileInputStream = new FileInputStream( file )) { + + try(BufferedInputStream origin = new BufferedInputStream(fileInputStream, BUFFER_SIZE)) { + ZipEntry entry = new ZipEntry(file.getName()); + + out.putNextEntry(entry); + int count; + while ((count = origin.read(data, 0, BUFFER_SIZE)) != -1) { + out.write(data, 0, count); + } + + } + } + } + + 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. + * + * the returned intent should be used to really send the mail using + * + * startActivity(Intent.createChooser(emailIntent , "Send email...")); + * + * @param attachementUri + * @param recipient + * @param subject + * @param body + * + * @return + */ + public static Intent sendMail(Uri attachementUri, String recipient, String subject, String body) { + LOG.debug("sending email to {} with subject {}", recipient, subject); + Intent emailIntent = new Intent(Intent.ACTION_SEND); + + emailIntent.setType("text/plain"); + emailIntent.putExtra(Intent.EXTRA_EMAIL , new String[]{recipient}); + emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject); + emailIntent.putExtra(Intent.EXTRA_TEXT, body); + + LOG.debug("put path {}", attachementUri.toString()); + emailIntent.putExtra(Intent.EXTRA_STREAM, attachementUri); + emailIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + + return emailIntent; + } + + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Maintenance/activities/LogSettingActivity.java b/app/src/main/java/info/nightscout/androidaps/plugins/Maintenance/activities/LogSettingActivity.java new file mode 100644 index 0000000000..7d21d561b9 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Maintenance/activities/LogSettingActivity.java @@ -0,0 +1,80 @@ +package info.nightscout.androidaps.plugins.Maintenance.activities; + +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.view.View; +import android.widget.CheckBox; +import android.widget.LinearLayout; +import android.widget.TextView; + +import java.util.List; + +import butterknife.BindView; +import butterknife.ButterKnife; +import butterknife.OnClick; +import butterknife.Unbinder; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.logging.L; + +public class LogSettingActivity extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_logsetting); + ButterKnife.bind(this); + + createViewsForSettings(L.getLogElements()); + } + + private void createViewsForSettings(List elements) { + if (elements.size() == 0) return; + LinearLayout container = (LinearLayout) findViewById(R.id.logsettings_placeholder); + container.removeAllViews(); + for (L.LogElement element : elements) { + PluginViewHolder pluginViewHolder = new PluginViewHolder(element); + container.addView(pluginViewHolder.getBaseView()); + } + } + + @OnClick(R.id.logsettings_reset) + public void onResetClick() { + L.resetToDefaults(); + createViewsForSettings(L.getLogElements()); + } + + public class PluginViewHolder { + + private Unbinder unbinder; + private L.LogElement element; + + LinearLayout baseView; + @BindView(R.id.logsettings_description) + TextView description; + @BindView(R.id.logsettings_visibility) + CheckBox enabled; + + public PluginViewHolder(L.LogElement element) { + this.element = element; + baseView = (LinearLayout) getLayoutInflater().inflate(R.layout.logsettings_item, null); + unbinder = ButterKnife.bind(this, baseView); + + description.setText(element.name); + enabled.setChecked(element.enabled); + } + + public View getBaseView() { + return baseView; + } + + @OnClick(R.id.logsettings_visibility) + void onEnagledChanged() { + element.setEnabled(enabled.isChecked()); + } + + public void unbind() { + unbinder.unbind(); + } + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientFragment.java index 3bff1c9be3..9eff2ca84c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientFragment.java @@ -34,8 +34,6 @@ import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.SP; public class NSClientFragment extends SubscriberFragment implements View.OnClickListener, CompoundButton.OnCheckedChangeListener { - private static Logger log = LoggerFactory.getLogger(NSClientFragment.class); - private TextView logTextView; private TextView queueTextView; private TextView urlTextView; @@ -133,9 +131,7 @@ public class NSClientFragment extends SubscriberFragment implements View.OnClick public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { switch (buttonView.getId()) { case R.id.nsclientinternal_paused: - SP.putBoolean(R.string.key_nsclientinternal_paused, isChecked); - NSClientPlugin.getPlugin().paused = isChecked; - MainApp.bus().post(new EventPreferenceChange(R.string.key_nsclientinternal_paused)); + NSClientPlugin.getPlugin().pause(isChecked); updateGUI(); FabricPrivacy.getInstance().logCustom(new CustomEvent("NSClientPause")); break; @@ -156,19 +152,17 @@ public class NSClientFragment extends SubscriberFragment implements View.OnClick protected void updateGUI() { Activity activity = getActivity(); if (activity != null) - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - NSClientPlugin.getPlugin().updateLog(); - logTextView.setText(NSClientPlugin.getPlugin().textLog); - if (NSClientPlugin.getPlugin().autoscroll) { - logScrollview.fullScroll(ScrollView.FOCUS_DOWN); - } - urlTextView.setText(NSClientPlugin.getPlugin().url()); - Spanned queuetext = Html.fromHtml(MainApp.gs(R.string.queue) + " " + UploadQueue.size() + ""); - queueTextView.setText(queuetext); - statusTextView.setText(NSClientPlugin.getPlugin().status); + activity.runOnUiThread(() -> { + NSClientPlugin.getPlugin().updateLog(); + pausedCheckbox.setChecked(SP.getBoolean(R.string.key_nsclientinternal_paused, false)); + logTextView.setText(NSClientPlugin.getPlugin().textLog); + if (NSClientPlugin.getPlugin().autoscroll) { + logScrollview.fullScroll(ScrollView.FOCUS_DOWN); } + urlTextView.setText(NSClientPlugin.getPlugin().url()); + Spanned queuetext = Html.fromHtml(MainApp.gs(R.string.queue) + " " + UploadQueue.size() + ""); + queueTextView.setText(queuetext); + statusTextView.setText(NSClientPlugin.getPlugin().status); }); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientPlugin.java index c43297ccf6..69de5934f8 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientPlugin.java @@ -29,6 +29,7 @@ import info.nightscout.androidaps.events.EventPreferenceChange; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginType; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.NSClientInternal.events.EventNSClientNewLog; import info.nightscout.androidaps.plugins.NSClientInternal.events.EventNSClientStatus; import info.nightscout.androidaps.plugins.NSClientInternal.events.EventNSClientUpdateGUI; @@ -37,7 +38,7 @@ import info.nightscout.utils.SP; import info.nightscout.utils.ToastUtils; public class NSClientPlugin extends PluginBase { - private static Logger log = LoggerFactory.getLogger(NSClientPlugin.class); + private Logger log = LoggerFactory.getLogger(L.NSCLIENT); static NSClientPlugin nsClientPlugin; @@ -53,8 +54,8 @@ public class NSClientPlugin extends PluginBase { private final List listLog = new ArrayList<>(); Spanned textLog = Html.fromHtml(""); - public boolean paused = false; - boolean autoscroll = true; + public boolean paused; + boolean autoscroll; public String status = ""; @@ -69,9 +70,10 @@ public class NSClientPlugin extends PluginBase { .pluginName(R.string.nsclientinternal) .shortName(R.string.nsclientinternal_shortname) .preferencesId(R.xml.pref_nsclientinternal) + .description(R.string.description_ns_client) ); - if (Config.NSCLIENT || Config.G5UPLOADER) { + if (Config.NSCLIENT) { pluginDescription.alwaysEnabled(true).visibleByDefault(true); } paused = SP.getBoolean(R.string.key_nsclientinternal_paused, false); @@ -131,12 +133,14 @@ public class NSClientPlugin extends PluginBase { private ServiceConnection mConnection = new ServiceConnection() { public void onServiceDisconnected(ComponentName name) { - log.debug("Service is disconnected"); + if (L.isEnabled(L.NSCLIENT)) + log.debug("Service is disconnected"); nsClientService = null; } public void onServiceConnected(ComponentName name, IBinder service) { - log.debug("Service is connected"); + if (L.isEnabled(L.NSCLIENT)) + log.debug("Service is connected"); NSClientService.LocalBinder mLocalBinder = (NSClientService.LocalBinder) service; if (mLocalBinder != null) // is null when running in roboelectric nsClientService = mLocalBinder.getServiceInstance(); @@ -154,7 +158,8 @@ public class NSClientPlugin extends PluginBase { @Subscribe public void onStatusEvent(final EventNSClientNewLog ev) { addToLog(ev); - log.debug(ev.action + " " + ev.logText); + if (L.isEnabled(L.NSCLIENT)) + log.debug(ev.action + " " + ev.logText); } @Subscribe @@ -164,30 +169,24 @@ public class NSClientPlugin extends PluginBase { } synchronized void clearLog() { - handler.post(new Runnable() { - @Override - public void run() { - synchronized (listLog) { - listLog.clear(); - } - MainApp.bus().post(new EventNSClientUpdateGUI()); + handler.post(() -> { + synchronized (listLog) { + listLog.clear(); } + MainApp.bus().post(new EventNSClientUpdateGUI()); }); } private synchronized void addToLog(final EventNSClientNewLog ev) { - handler.post(new Runnable() { - @Override - public void run() { - synchronized (listLog) { - listLog.add(ev); - // remove the first line if log is too large - if (listLog.size() >= Constants.MAX_LOG_LINES) { - listLog.remove(0); - } + handler.post(() -> { + synchronized (listLog) { + listLog.add(ev); + // remove the first line if log is too large + if (listLog.size() >= Constants.MAX_LOG_LINES) { + listLog.remove(0); } - MainApp.bus().post(new EventNSClientUpdateGUI()); } + MainApp.bus().post(new EventNSClientUpdateGUI()); }); } @@ -210,6 +209,12 @@ public class NSClientPlugin extends PluginBase { nsClientService.resend(reason); } + public void pause(boolean newState) { + SP.putBoolean(R.string.key_nsclientinternal_paused, newState); + paused = newState; + MainApp.bus().post(new EventPreferenceChange(R.string.key_nsclientinternal_paused)); + } + public UploadQueue queue() { return NSClientService.uploadQueue; } diff --git a/app/src/main/java/info/nightscout/utils/NSUpload.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSUpload.java similarity index 87% rename from app/src/main/java/info/nightscout/utils/NSUpload.java rename to app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSUpload.java index 2e5506f9c6..8f3f31f6e7 100644 --- a/app/src/main/java/info/nightscout/utils/NSUpload.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSUpload.java @@ -1,4 +1,4 @@ -package info.nightscout.utils; +package info.nightscout.androidaps.plugins.NSClientInternal; import android.content.Context; import android.content.Intent; @@ -8,6 +8,7 @@ import android.os.Build; import android.os.Bundle; import android.preference.PreferenceManager; import android.support.annotation.Nullable; +import android.support.v4.content.LocalBroadcastManager; import org.apache.commons.lang3.StringUtils; import org.json.JSONArray; @@ -23,7 +24,9 @@ import java.util.Locale; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.Services.Intents; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; +import info.nightscout.androidaps.services.Intents; import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.db.BgReading; @@ -37,13 +40,16 @@ import info.nightscout.androidaps.plugins.Loop.APSResult; import info.nightscout.androidaps.plugins.Loop.DeviceStatus; import info.nightscout.androidaps.plugins.Loop.LoopPlugin; import info.nightscout.androidaps.plugins.NSClientInternal.data.DbLogger; +import info.nightscout.utils.BatteryLevel; +import info.nightscout.utils.DateUtil; +import info.nightscout.utils.SP; /** * Created by mike on 26.05.2017. */ public class NSUpload { - private static Logger log = LoggerFactory.getLogger(NSUpload.class); + private static Logger log = LoggerFactory.getLogger(L.NSCLIENT); public static void uploadTempBasalStartAbsolute(TemporaryBasal temporaryBasal, Double originalExtendedAmount) { try { @@ -52,6 +58,7 @@ public class NSUpload { data.put("eventType", CareportalEvent.TEMPBASAL); data.put("duration", temporaryBasal.durationInMinutes); data.put("absolute", temporaryBasal.absoluteRate); + data.put("rate", temporaryBasal.absoluteRate); if (temporaryBasal.pumpId != 0) data.put("pumpId", temporaryBasal.pumpId); data.put("created_at", DateUtil.toISOString(temporaryBasal.date)); @@ -65,7 +72,7 @@ public class NSUpload { Intent intent = new Intent(Intents.ACTION_DATABASE); intent.putExtras(bundle); intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - context.sendBroadcast(intent); + LocalBroadcastManager.getInstance(context).sendBroadcast(intent); DbLogger.dbAdd(intent, data.toString()); } catch (JSONException e) { log.error("Unhandled exception", e); @@ -76,12 +83,16 @@ public class NSUpload { try { SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext()); boolean useAbsolute = SP.getBoolean("ns_sync_use_absolute", false); + Profile profile = ProfileFunctions.getInstance().getProfile(temporaryBasal.date); + double absoluteRate = 0; + if (profile != null) { + absoluteRate = profile.getBasal(temporaryBasal.date) * temporaryBasal.percentRate / 100d; + } if (useAbsolute) { TemporaryBasal t = temporaryBasal.clone(); t.isAbsolute = true; - Profile profile = MainApp.getConfigBuilder().getProfile(); if (profile != null) { - t.absoluteRate = profile.getBasal(temporaryBasal.date) * temporaryBasal.percentRate / 100d; + t.absoluteRate = absoluteRate; uploadTempBasalStartAbsolute(t, null); } } else { @@ -90,6 +101,8 @@ public class NSUpload { data.put("eventType", CareportalEvent.TEMPBASAL); data.put("duration", temporaryBasal.durationInMinutes); data.put("percent", temporaryBasal.percentRate - 100); + if (profile != null) + data.put("rate", absoluteRate); if (temporaryBasal.pumpId != 0) data.put("pumpId", temporaryBasal.pumpId); data.put("created_at", DateUtil.toISOString(temporaryBasal.date)); @@ -101,7 +114,7 @@ public class NSUpload { Intent intent = new Intent(Intents.ACTION_DATABASE); intent.putExtras(bundle); intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - context.sendBroadcast(intent); + LocalBroadcastManager.getInstance(context).sendBroadcast(intent); DbLogger.dbAdd(intent, data.toString()); } } catch (JSONException e) { @@ -127,7 +140,7 @@ public class NSUpload { Intent intent = new Intent(Intents.ACTION_DATABASE); intent.putExtras(bundle); intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - context.sendBroadcast(intent); + LocalBroadcastManager.getInstance(context).sendBroadcast(intent); DbLogger.dbAdd(intent, data.toString()); } catch (JSONException e) { log.error("Unhandled exception", e); @@ -155,7 +168,7 @@ public class NSUpload { Intent intent = new Intent(Intents.ACTION_DATABASE); intent.putExtras(bundle); intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - context.sendBroadcast(intent); + LocalBroadcastManager.getInstance(context).sendBroadcast(intent); DbLogger.dbAdd(intent, data.toString()); } catch (JSONException e) { log.error("Unhandled exception", e); @@ -183,7 +196,7 @@ public class NSUpload { Intent intent = new Intent(Intents.ACTION_DATABASE); intent.putExtras(bundle); intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - context.sendBroadcast(intent); + LocalBroadcastManager.getInstance(context).sendBroadcast(intent); DbLogger.dbAdd(intent, data.toString()); } catch (JSONException e) { log.error("Unhandled exception", e); @@ -191,8 +204,8 @@ public class NSUpload { } public static void uploadDeviceStatus() { - Profile profile = MainApp.getConfigBuilder().getProfile(); - String profileName = MainApp.getConfigBuilder().getProfileName(); + Profile profile = ProfileFunctions.getInstance().getProfile(); + String profileName = ProfileFunctions.getInstance().getProfileName(); if (profile == null || profileName == null) { log.error("Profile is null. Skipping upload"); @@ -232,10 +245,11 @@ public class NSUpload { deviceStatus.enacted.put("requested", requested); } } else { - log.debug("OpenAPS data too old to upload"); + if (L.isEnabled(L.NSCLIENT)) + log.debug("OpenAPS data too old to upload"); } deviceStatus.device = "openaps://" + Build.MANUFACTURER + " " + Build.MODEL; - JSONObject pumpstatus = ConfigBuilderPlugin.getActivePump().getJSONStatus(profile, profileName); + JSONObject pumpstatus = ConfigBuilderPlugin.getPlugin().getActivePump().getJSONStatus(profile, profileName); if (pumpstatus != null) { deviceStatus.pump = pumpstatus; } @@ -252,7 +266,7 @@ public class NSUpload { Intent intent = new Intent(Intents.ACTION_DATABASE); intent.putExtras(bundle); intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - context.sendBroadcast(intent); + LocalBroadcastManager.getInstance(context).sendBroadcast(intent); DbLogger.dbAdd(intent, deviceStatus.mongoRecord().toString()); } catch (JSONException e) { log.error("Unhandled exception", e); @@ -289,19 +303,7 @@ public class NSUpload { public static void uploadProfileSwitch(ProfileSwitch profileSwitch) { try { - JSONObject data = new JSONObject(); - data.put("eventType", CareportalEvent.PROFILESWITCH); - data.put("duration", profileSwitch.durationInMinutes); - data.put("profile", profileSwitch.getCustomizedName()); - data.put("profileJson", profileSwitch.profileJson); - data.put("profilePlugin", profileSwitch.profilePlugin); - if (profileSwitch.isCPP) { - data.put("CircadianPercentageProfile", true); - data.put("timeshift", profileSwitch.timeshift); - data.put("percentage", profileSwitch.percentage); - } - data.put("created_at", DateUtil.toISOString(profileSwitch.date)); - data.put("enteredBy", MainApp.gs(R.string.app_name)); + JSONObject data = getJson(profileSwitch); uploadCareportalEntryToNS(data); } catch (JSONException e) { log.error("Unhandled exception", e); @@ -310,7 +312,7 @@ public class NSUpload { public static void uploadTempTarget(TempTarget tempTarget) { try { - Profile profile = MainApp.getConfigBuilder().getProfile(); + Profile profile = ProfileFunctions.getInstance().getProfile(); if (profile == null) { log.error("Profile is null. Skipping upload"); @@ -334,19 +336,7 @@ public class NSUpload { public static void updateProfileSwitch(ProfileSwitch profileSwitch) { try { - JSONObject data = new JSONObject(); - data.put("eventType", CareportalEvent.PROFILESWITCH); - data.put("duration", profileSwitch.durationInMinutes); - data.put("profile", profileSwitch.getCustomizedName()); - data.put("profileJson", profileSwitch.profileJson); - data.put("profilePlugin", profileSwitch.profilePlugin); - if (profileSwitch.isCPP) { - data.put("CircadianPercentageProfile", true); - data.put("timeshift", profileSwitch.timeshift); - data.put("percentage", profileSwitch.percentage); - } - data.put("created_at", DateUtil.toISOString(profileSwitch.date)); - data.put("enteredBy", MainApp.gs(R.string.app_name)); + JSONObject data = getJson(profileSwitch); if (profileSwitch._id != null) { Context context = MainApp.instance().getApplicationContext(); Bundle bundle = new Bundle(); @@ -357,7 +347,7 @@ public class NSUpload { Intent intent = new Intent(Intents.ACTION_DATABASE); intent.putExtras(bundle); intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - context.sendBroadcast(intent); + LocalBroadcastManager.getInstance(context).sendBroadcast(intent); DbLogger.dbAdd(intent, data.toString()); } } catch (JSONException e) { @@ -365,6 +355,24 @@ public class NSUpload { } } + private static JSONObject getJson(ProfileSwitch profileSwitch) throws JSONException { + JSONObject data = new JSONObject(); + data.put("eventType", CareportalEvent.PROFILESWITCH); + data.put("duration", profileSwitch.durationInMinutes); + data.put("profile", profileSwitch.getCustomizedName()); + data.put("profileJson", profileSwitch.profileJson); + data.put("profilePlugin", profileSwitch.profilePlugin); + if (profileSwitch.isCPP) { + data.put("CircadianPercentageProfile", true); + data.put("timeshift", profileSwitch.timeshift); + data.put("percentage", profileSwitch.percentage); + } + data.put("created_at", DateUtil.toISOString(profileSwitch.date)); + data.put("enteredBy", MainApp.gs(R.string.app_name)); + + return data; + } + public static void uploadCareportalEntryToNS(JSONObject data) { try { if (data.has("preBolus") && data.has("carbs")) { @@ -387,7 +395,7 @@ public class NSUpload { Intent intent = new Intent(Intents.ACTION_DATABASE); intent.putExtras(bundle); intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - context.sendBroadcast(intent); + LocalBroadcastManager.getInstance(context).sendBroadcast(intent); DbLogger.dbAdd(intent, data.toString()); } catch (Exception e) { log.error("Unhandled exception", e); @@ -405,7 +413,7 @@ public class NSUpload { Intent intent = new Intent(Intents.ACTION_DATABASE); intent.putExtras(bundle); intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - context.sendBroadcast(intent); + LocalBroadcastManager.getInstance(context).sendBroadcast(intent); DbLogger.dbRemove(intent, _id); } catch (Exception e) { log.error("Unhandled exception", e); @@ -428,7 +436,7 @@ public class NSUpload { Intent intent = new Intent(Intents.ACTION_DATABASE); intent.putExtras(bundle); intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - context.sendBroadcast(intent); + LocalBroadcastManager.getInstance(context).sendBroadcast(intent); DbLogger.dbAdd(intent, data.toString()); } catch (JSONException e) { log.error("Unhandled exception", e); @@ -458,7 +466,7 @@ public class NSUpload { Intent intent = new Intent(Intents.ACTION_DATABASE); intent.putExtras(bundle); intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - context.sendBroadcast(intent); + LocalBroadcastManager.getInstance(context).sendBroadcast(intent); DbLogger.dbAdd(intent, data.toString()); } @@ -482,7 +490,7 @@ public class NSUpload { Intent intent = new Intent(Intents.ACTION_DATABASE); intent.putExtras(bundle); intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - context.sendBroadcast(intent); + LocalBroadcastManager.getInstance(context).sendBroadcast(intent); DbLogger.dbAdd(intent, data.toString()); } @@ -496,7 +504,7 @@ public class NSUpload { try { data.put("eventType", "Note"); data.put("created_at", DateUtil.toISOString(new Date())); - data.put("notes", MainApp.gs(R.string.androidaps_start)+" - "+ Build.MANUFACTURER + " "+ Build.MODEL); + data.put("notes", MainApp.gs(R.string.androidaps_start) + " - " + Build.MANUFACTURER + " " + Build.MODEL); } catch (JSONException e) { log.error("Unhandled exception", e); } @@ -504,9 +512,9 @@ public class NSUpload { Intent intent = new Intent(Intents.ACTION_DATABASE); intent.putExtras(bundle); intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - context.sendBroadcast(intent); + LocalBroadcastManager.getInstance(context).sendBroadcast(intent); DbLogger.dbAdd(intent, data.toString()); - } + } } public static void uploadEvent(String careportalEvent, long time, @Nullable String notes) { @@ -529,7 +537,7 @@ public class NSUpload { Intent intent = new Intent(Intents.ACTION_DATABASE); intent.putExtras(bundle); intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - context.sendBroadcast(intent); + LocalBroadcastManager.getInstance(context).sendBroadcast(intent); DbLogger.dbAdd(intent, data.toString()); } @@ -543,7 +551,7 @@ public class NSUpload { Intent intent = new Intent(Intents.ACTION_DATABASE); intent.putExtras(bundle); intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - context.sendBroadcast(intent); + LocalBroadcastManager.getInstance(context).sendBroadcast(intent); DbLogger.dbRemove(intent, _id); } catch (Exception e) { log.error("Unhandled exception", e); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NsClientReceiverDelegate.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NsClientReceiverDelegate.java index 04b587ca24..ba6ec2c80b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NsClientReceiverDelegate.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NsClientReceiverDelegate.java @@ -122,7 +122,8 @@ class NsClientReceiverDelegate { boolean newAllowedState = true; if (ev.wifiConnected) { - if (!allowedSSIDs.trim().isEmpty() && !allowedSSIDs.contains(ev.ssid)) { + if (!allowedSSIDs.trim().isEmpty() && + (!allowedSSIDs.contains(ev.getSsid()) && !allowedSSIDs.contains(ev.ssid))) { newAllowedState = false; } } else { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/UploadQueue.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/UploadQueue.java index 17cc1dced3..9c0284029c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/UploadQueue.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/UploadQueue.java @@ -16,13 +16,14 @@ import java.sql.SQLException; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.db.DatabaseHelper; import info.nightscout.androidaps.db.DbRequest; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.NSClientInternal.services.NSClientService; /** * Created by mike on 21.02.2016. */ public class UploadQueue { - private static Logger log = LoggerFactory.getLogger(UploadQueue.class); + private static Logger log = LoggerFactory.getLogger(L.NSCLIENT); public static String status() { return "QUEUE: " + MainApp.getDbHelper().size(DatabaseHelper.DATABASE_DBREQUESTS); @@ -43,15 +44,13 @@ public class UploadQueue { public static void add(final DbRequest dbr) { startService(); if (NSClientService.handler != null) { - NSClientService.handler.post(new Runnable() { - @Override - public void run() { - log.debug("QUEUE adding: " + dbr.data); - MainApp.getDbHelper().create(dbr); - NSClientPlugin plugin = NSClientPlugin.getPlugin(); - if (plugin != null) { - plugin.resend("newdata"); - } + NSClientService.handler.post(() -> { + if (L.isEnabled(L.NSCLIENT)) + log.debug("Adding to queue: " + dbr.data); + MainApp.getDbHelper().create(dbr); + NSClientPlugin plugin = NSClientPlugin.getPlugin(); + if (plugin != null) { + plugin.resend("newdata"); } }); } @@ -60,13 +59,12 @@ public class UploadQueue { public static void clearQueue() { startService(); if (NSClientService.handler != null) { - NSClientService.handler.post(new Runnable() { - @Override - public void run() { - log.debug("QUEUE ClearQueue"); - MainApp.getDbHelper().deleteAllDbRequests(); + NSClientService.handler.post(() -> { + if (L.isEnabled(L.NSCLIENT)) + log.debug("ClearQueue"); + MainApp.getDbHelper().deleteAllDbRequests(); + if (L.isEnabled(L.NSCLIENT)) log.debug(status()); - } }); } } @@ -74,22 +72,20 @@ public class UploadQueue { public static void removeID(final JSONObject record) { startService(); if (NSClientService.handler != null) { - NSClientService.handler.post(new Runnable() { - @Override - public void run() { - try { - String id; - if (record.has("NSCLIENT_ID")) { - id = record.getString("NSCLIENT_ID"); - } else { - return; - } - if (MainApp.getDbHelper().deleteDbRequest(id) == 1) { - log.debug("Removed item from UploadQueue. " + UploadQueue.status()); - } - } catch (JSONException e) { - log.error("Unhandled exception", e); + NSClientService.handler.post(() -> { + try { + String id; + if (record.has("NSCLIENT_ID")) { + id = record.getString("NSCLIENT_ID"); + } else { + return; } + if (MainApp.getDbHelper().deleteDbRequest(id) == 1) { + if (L.isEnabled(L.NSCLIENT)) + log.debug("Removed item from UploadQueue. " + UploadQueue.status()); + } + } catch (JSONException e) { + log.error("Unhandled exception", e); } }); } @@ -100,18 +96,17 @@ public class UploadQueue { return; startService(); if (NSClientService.handler != null) { - NSClientService.handler.post(new Runnable() { - @Override - public void run() { - MainApp.getDbHelper().deleteDbRequestbyMongoId(action, _id); - } + NSClientService.handler.post(() -> { + MainApp.getDbHelper().deleteDbRequestbyMongoId(action, _id); + if (L.isEnabled(L.NSCLIENT)) + log.debug("Removing " + _id + " from UploadQueue. " + UploadQueue.status()); }); } } public String textList() { String result = ""; - CloseableIterator iterator = null; + CloseableIterator iterator; try { iterator = MainApp.getDbHelper().getDbRequestInterator(); try { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/acks/NSAddAck.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/acks/NSAddAck.java index e90dce3bec..ed9c4c3013 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/acks/NSAddAck.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/acks/NSAddAck.java @@ -1,13 +1,13 @@ package info.nightscout.androidaps.plugins.NSClientInternal.acks; import org.json.JSONArray; -import org.json.JSONException; import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.events.Event; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.NSClientInternal.events.EventNSClientRestart; import io.socket.client.Ack; @@ -15,17 +15,18 @@ import io.socket.client.Ack; * Created by mike on 29.12.2015. */ public class NSAddAck extends Event implements Ack { - private static Logger log = LoggerFactory.getLogger(NSAddAck.class); + private static Logger log = LoggerFactory.getLogger(L.NSCLIENT); public String _id = null; public String nsClientID = null; public JSONObject json = null; - public void call(Object...args) { + + public void call(Object... args) { // Regular response try { JSONArray responsearray = (JSONArray) (args[0]); JSONObject response = null; - if (responsearray.length()>0) { - response = responsearray.getJSONObject(0); + if (responsearray.length() > 0) { + response = responsearray.getJSONObject(0); _id = response.getString("_id"); json = response; if (response.has("NSCLIENT_ID")) { @@ -35,6 +36,7 @@ public class NSAddAck extends Event implements Ack { MainApp.bus().post(this); return; } catch (Exception e) { + log.error("Unhandled exception", e); } // Check for not authorized try { @@ -45,7 +47,8 @@ public class NSAddAck extends Event implements Ack { MainApp.bus().post(new EventNSClientRestart()); return; } - log.debug("DBACCESS " + response.getString("result")); + if (L.isEnabled(L.NSCLIENT)) + log.debug("DBACCESS " + response.getString("result")); } return; } catch (Exception e) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/acks/NSUpdateAck.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/acks/NSUpdateAck.java index 2bf520da64..42534387b2 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/acks/NSUpdateAck.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/acks/NSUpdateAck.java @@ -7,15 +7,16 @@ import org.slf4j.LoggerFactory; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.events.Event; +import info.nightscout.androidaps.logging.L; import io.socket.client.Ack; /** * Created by mike on 21.02.2016. */ public class NSUpdateAck extends Event implements Ack { - private static Logger log = LoggerFactory.getLogger(NSUpdateAck.class); + private static Logger log = LoggerFactory.getLogger(L.NSCLIENT); public boolean result = false; - public String _id = null; + public String _id; public String action; public void call(Object...args) { JSONObject response = (JSONObject)args[0]; @@ -29,6 +30,7 @@ public class NSUpdateAck extends Event implements Ack { } MainApp.bus().post(this); } catch (JSONException e) { + log.error("Unhandled exception", e); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastAckAlarm.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastAckAlarm.java index 216fa3d19a..f94f9e51aa 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastAckAlarm.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastAckAlarm.java @@ -2,18 +2,12 @@ package info.nightscout.androidaps.plugins.NSClientInternal.broadcasts; import android.content.Context; import android.content.Intent; -import android.content.pm.ResolveInfo; import android.os.Bundle; import android.support.v4.content.LocalBroadcastManager; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.List; - import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.Services.Intents; +import info.nightscout.androidaps.services.Intents; import info.nightscout.androidaps.plugins.NSClientInternal.data.NSAlarm; import info.nightscout.utils.SP; @@ -22,7 +16,6 @@ import info.nightscout.utils.SP; */ public class BroadcastAckAlarm { - private static Logger log = LoggerFactory.getLogger(BroadcastAckAlarm.class); public static void handleClearAlarm(NSAlarm originalAlarm, Context context, long silenceTimeInMsec) { @@ -35,7 +28,7 @@ public class BroadcastAckAlarm { intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); - if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) { + if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) { bundle = new Bundle(); bundle.putInt("level", originalAlarm.getLevel()); bundle.putString("group", originalAlarm.getGroup()); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastAlarm.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastAlarm.java index 0fee6600bd..8f75d92365 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastAlarm.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastAlarm.java @@ -2,27 +2,20 @@ package info.nightscout.androidaps.plugins.NSClientInternal.broadcasts; import android.content.Context; import android.content.Intent; -import android.content.pm.ResolveInfo; import android.os.Bundle; import android.support.v4.content.LocalBroadcastManager; import org.json.JSONObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.List; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.Services.Intents; +import info.nightscout.androidaps.services.Intents; import info.nightscout.utils.SP; /** * Created by mike on 26.06.2016. */ public class BroadcastAlarm { - private static Logger log = LoggerFactory.getLogger(BroadcastAlarm.class); - public static void handleAlarm(JSONObject alarm, Context context) { Bundle bundle = new Bundle(); bundle.putString("data", alarm.toString()); @@ -31,7 +24,7 @@ public class BroadcastAlarm { intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); - if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) { + if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) { bundle = new Bundle(); bundle.putString("data", alarm.toString()); intent = new Intent(Intents.ACTION_ALARM); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastAnnouncement.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastAnnouncement.java index 9b133c2551..5e1b01f225 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastAnnouncement.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastAnnouncement.java @@ -2,28 +2,20 @@ package info.nightscout.androidaps.plugins.NSClientInternal.broadcasts; import android.content.Context; import android.content.Intent; -import android.content.pm.ResolveInfo; import android.os.Bundle; import android.support.v4.content.LocalBroadcastManager; -import org.json.JSONArray; import org.json.JSONObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.List; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.Services.Intents; +import info.nightscout.androidaps.services.Intents; import info.nightscout.utils.SP; /** * Created by mike on 26.06.2016. */ public class BroadcastAnnouncement { - private static Logger log = LoggerFactory.getLogger(BroadcastAnnouncement.class); - public static void handleAnnouncement(JSONObject announcement, Context context) { Bundle bundle = new Bundle(); bundle.putString("data", announcement.toString()); @@ -32,7 +24,7 @@ public class BroadcastAnnouncement { intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); - if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) { + if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) { bundle = new Bundle(); bundle.putString("data", announcement.toString()); intent = new Intent(Intents.ACTION_ANNOUNCEMENT); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastCals.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastCals.java index 7580a00088..4e49785f82 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastCals.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastCals.java @@ -2,27 +2,20 @@ package info.nightscout.androidaps.plugins.NSClientInternal.broadcasts; import android.content.Context; import android.content.Intent; -import android.content.pm.ResolveInfo; import android.os.Bundle; import android.support.v4.content.LocalBroadcastManager; import org.json.JSONArray; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.List; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.Services.Intents; +import info.nightscout.androidaps.services.Intents; import info.nightscout.utils.SP; /** * Created by mike on 26.06.2016. */ public class BroadcastCals { - private static Logger log = LoggerFactory.getLogger(BroadcastCals.class); - public static void handleNewCal(JSONArray cals, Context context, boolean isDelta) { Bundle bundle = new Bundle(); @@ -33,7 +26,7 @@ public class BroadcastCals { intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); - if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) { + if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) { bundle = new Bundle(); bundle.putString("cals", cals.toString()); bundle.putBoolean("delta", isDelta); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastClearAlarm.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastClearAlarm.java index 23406837a7..e6fec32ffa 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastClearAlarm.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastClearAlarm.java @@ -2,27 +2,20 @@ package info.nightscout.androidaps.plugins.NSClientInternal.broadcasts; import android.content.Context; import android.content.Intent; -import android.content.pm.ResolveInfo; import android.os.Bundle; import android.support.v4.content.LocalBroadcastManager; import org.json.JSONObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.List; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.Services.Intents; +import info.nightscout.androidaps.services.Intents; import info.nightscout.utils.SP; /** * Created by mike on 26.06.2016. */ public class BroadcastClearAlarm { - private static Logger log = LoggerFactory.getLogger(BroadcastClearAlarm.class); - public static void handleClearAlarm(JSONObject clearalarm, Context context) { Bundle bundle = new Bundle(); bundle.putString("data", clearalarm.toString()); @@ -31,7 +24,7 @@ public class BroadcastClearAlarm { intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); - if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) { + if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) { bundle = new Bundle(); bundle.putString("data", clearalarm.toString()); intent = new Intent(Intents.ACTION_CLEAR_ALARM); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastDeviceStatus.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastDeviceStatus.java index 59f5ab136c..4915608673 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastDeviceStatus.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastDeviceStatus.java @@ -2,45 +2,20 @@ package info.nightscout.androidaps.plugins.NSClientInternal.broadcasts; import android.content.Context; import android.content.Intent; -import android.content.pm.ResolveInfo; import android.os.Bundle; import android.support.v4.content.LocalBroadcastManager; import org.json.JSONArray; -import org.json.JSONObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.util.List; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.Services.Intents; +import info.nightscout.androidaps.services.Intents; import info.nightscout.utils.SP; public class BroadcastDeviceStatus { - private static Logger log = LoggerFactory.getLogger(BroadcastDeviceStatus.class); - - public static void handleNewDeviceStatus(JSONObject status, Context context, boolean isDelta) { - Bundle bundle = new Bundle(); - bundle.putString("devicestatus", status.toString()); - bundle.putBoolean("delta", isDelta); - Intent intent = new Intent(Intents.ACTION_NEW_DEVICESTATUS); - intent.putExtras(bundle); - intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); - - if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) { - bundle = new Bundle(); - bundle.putString("devicestatus", status.toString()); - bundle.putBoolean("delta", isDelta); - intent = new Intent(Intents.ACTION_NEW_DEVICESTATUS); - intent.putExtras(bundle); - intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - context.sendBroadcast(intent); - } - } public static void handleNewDeviceStatus(JSONArray statuses, Context context, boolean isDelta) { List splitted = BroadcastTreatment.splitArray(statuses); @@ -54,7 +29,7 @@ public class BroadcastDeviceStatus { LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); } - if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) { + if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) { splitted = BroadcastTreatment.splitArray(statuses); for (JSONArray part : splitted) { Bundle bundle = new Bundle(); @@ -67,31 +42,4 @@ public class BroadcastDeviceStatus { } } } - - public static void handleNewFoods(JSONArray foods, Context context, boolean isDelta) { - - List splitted = BroadcastTreatment.splitArray(foods); - for (JSONArray part: splitted) { - Bundle bundle = new Bundle(); - bundle.putString("foods", part.toString()); - bundle.putBoolean("delta", isDelta); - Intent intent = new Intent(Intents.ACTION_NEW_FOOD); - intent.putExtras(bundle); - intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); - } - - if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) { - splitted = BroadcastTreatment.splitArray(foods); - for (JSONArray part : splitted) { - Bundle bundle = new Bundle(); - bundle.putString("foods", part.toString()); - bundle.putBoolean("delta", isDelta); - Intent intent = new Intent(Intents.ACTION_NEW_FOOD); - intent.putExtras(bundle); - intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - context.sendBroadcast(intent); - } - } - } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastFood.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastFood.java index dbb3385fbb..f38141ec6d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastFood.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastFood.java @@ -6,26 +6,18 @@ import android.os.Bundle; import android.support.v4.content.LocalBroadcastManager; import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import java.util.ArrayList; import java.util.List; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.Services.Intents; -import info.nightscout.androidaps.plugins.NSClientInternal.data.NSTreatment; +import info.nightscout.androidaps.services.Intents; import info.nightscout.utils.SP; /** * Created by mike on 20.02.2016. */ public class BroadcastFood { - private static Logger log = LoggerFactory.getLogger(BroadcastFood.class); - public static void handleNewFood(JSONArray foods, Context context, boolean isDelta) { List splitted = BroadcastTreatment.splitArray(foods); @@ -39,7 +31,7 @@ public class BroadcastFood { LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); } - if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) { + if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) { for (JSONArray part : splitted) { Bundle bundle = new Bundle(); bundle.putString("foods", part.toString()); @@ -65,7 +57,7 @@ public class BroadcastFood { LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); } - if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) { + if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) { for (JSONArray part : splitted) { Bundle bundle = new Bundle(); bundle.putString("foods", part.toString()); @@ -89,7 +81,7 @@ public class BroadcastFood { LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); - if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) { + if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) { bundle = new Bundle(); bundle.putString("foods", foods.toString()); bundle.putBoolean("delta", isDelta); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastMbgs.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastMbgs.java index a715747791..e91c3e2fd6 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastMbgs.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastMbgs.java @@ -2,27 +2,20 @@ package info.nightscout.androidaps.plugins.NSClientInternal.broadcasts; import android.content.Context; import android.content.Intent; -import android.content.pm.ResolveInfo; import android.os.Bundle; import android.support.v4.content.LocalBroadcastManager; import org.json.JSONArray; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.List; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.Services.Intents; +import info.nightscout.androidaps.services.Intents; import info.nightscout.utils.SP; /** * Created by mike on 26.06.2016. */ public class BroadcastMbgs { - private static Logger log = LoggerFactory.getLogger(BroadcastMbgs.class); - public static void handleNewMbg(JSONArray mbgs, Context context, boolean isDelta) { Bundle bundle = new Bundle(); @@ -33,7 +26,7 @@ public class BroadcastMbgs { intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); - if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) { + if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) { bundle = new Bundle(); bundle.putString("mbgs", mbgs.toString()); bundle.putBoolean("delta", isDelta); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastProfile.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastProfile.java index 3802b09657..6bd6bbc81a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastProfile.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastProfile.java @@ -2,18 +2,12 @@ package info.nightscout.androidaps.plugins.NSClientInternal.broadcasts; import android.content.Context; import android.content.Intent; -import android.content.pm.ResolveInfo; import android.os.Bundle; import android.support.v4.content.LocalBroadcastManager; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.List; - import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.Services.Intents; +import info.nightscout.androidaps.services.Intents; import info.nightscout.androidaps.data.ProfileStore; import info.nightscout.utils.SP; @@ -22,8 +16,6 @@ import info.nightscout.utils.SP; * Created by mike on 20.02.2016. */ public class BroadcastProfile { - private static Logger log = LoggerFactory.getLogger(BroadcastProfile.class); - public static void handleNewTreatment(ProfileStore profile, Context context, boolean isDelta) { Bundle bundle = new Bundle(); @@ -34,7 +26,7 @@ public class BroadcastProfile { intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); - if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) { + if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) { bundle = new Bundle(); bundle.putString("profile", profile.getData().toString()); bundle.putBoolean("delta", isDelta); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastQueueStatus.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastQueueStatus.java deleted file mode 100644 index abc49be18a..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastQueueStatus.java +++ /dev/null @@ -1,35 +0,0 @@ -package info.nightscout.androidaps.plugins.NSClientInternal.broadcasts; - -import android.content.Context; -import android.content.Intent; -import android.os.Bundle; -import android.os.PowerManager; - -import info.nightscout.androidaps.R; -import info.nightscout.androidaps.Services.Intents; -import info.nightscout.utils.SP; - -/** - * Created by mike on 28.02.2016. - */ -public class BroadcastQueueStatus { - public static void handleNewStatus(int size, Context context) { - - if(!SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) return; - - PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); - PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, - "sendQueue"); - wakeLock.acquire(); - try { - Bundle bundle = new Bundle(); - bundle.putInt("size", size); - Intent intent = new Intent(Intents.ACTION_QUEUE_STATUS); - intent.putExtras(bundle); - intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - context.sendBroadcast(intent); - } finally { - wakeLock.release(); - } - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastSgvs.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastSgvs.java index 65a90f3b74..dea4cf8713 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastSgvs.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastSgvs.java @@ -2,49 +2,22 @@ package info.nightscout.androidaps.plugins.NSClientInternal.broadcasts; import android.content.Context; import android.content.Intent; -import android.content.pm.ResolveInfo; import android.os.Bundle; import android.support.v4.content.LocalBroadcastManager; import org.json.JSONArray; -import org.json.JSONObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.util.List; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.Services.Intents; +import info.nightscout.androidaps.services.Intents; import info.nightscout.utils.SP; /** * Created by mike on 22.02.2016. */ public class BroadcastSgvs { - private static Logger log = LoggerFactory.getLogger(BroadcastSgvs.class); - - public static void handleNewSgv(JSONObject sgv, Context context, boolean isDelta) { - - Bundle bundle = new Bundle(); - bundle.putString("sgv", sgv.toString()); - bundle.putBoolean("delta", isDelta); - Intent intent = new Intent(Intents.ACTION_NEW_SGV); - intent.putExtras(bundle); - intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); - - if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) { - bundle = new Bundle(); - bundle.putString("sgv", sgv.toString()); - bundle.putBoolean("delta", isDelta); - intent = new Intent(Intents.ACTION_NEW_SGV); - intent.putExtras(bundle); - intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - context.sendBroadcast(intent); - } - } - public static void handleNewSgv(JSONArray sgvs, Context context, boolean isDelta) { List splitted = BroadcastTreatment.splitArray(sgvs); @@ -58,7 +31,7 @@ public class BroadcastSgvs { LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); } - if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) { + if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) { for (JSONArray part : splitted) { Bundle bundle = new Bundle(); bundle.putString("sgvs", part.toString()); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastStatus.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastStatus.java index 4ee2427af8..a0e8607efc 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastStatus.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastStatus.java @@ -3,18 +3,16 @@ package info.nightscout.androidaps.plugins.NSClientInternal.broadcasts; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; import android.os.Bundle; import android.support.v4.content.LocalBroadcastManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.List; - import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.Services.Intents; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.services.Intents; import info.nightscout.androidaps.plugins.NSClientInternal.data.NSSettingsStatus; import info.nightscout.androidaps.plugins.NSClientInternal.services.NSClientService; import info.nightscout.utils.SP; @@ -23,17 +21,27 @@ import info.nightscout.utils.SP; * Created by mike on 24.02.2016. */ public class BroadcastStatus { - private static Logger log = LoggerFactory.getLogger(BroadcastStatus.class); + private static Logger log = LoggerFactory.getLogger(L.NSCLIENT); public static void handleNewStatus(NSSettingsStatus status, Context context, boolean isDelta) { + LocalBroadcastManager.getInstance(MainApp.instance()) + .sendBroadcast(createIntent(status, isDelta)); + if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) { + context.sendBroadcast(createIntent(status, isDelta)); + } + } + + private static Intent createIntent(NSSettingsStatus status, boolean isDelta) { Bundle bundle = new Bundle(); + try { bundle.putString("nsclientversionname", MainApp.instance().getPackageManager().getPackageInfo(MainApp.instance().getPackageName(), 0).versionName); bundle.putInt("nsclientversioncode", MainApp.instance().getPackageManager().getPackageInfo(MainApp.instance().getPackageName(), 0).versionCode); } catch (PackageManager.NameNotFoundException e) { log.error("Unhandled exception", e); } + bundle.putString("nightscoutversionname", NSClientService.nightscoutVersionName); bundle.putInt("nightscoutversioncode", NSClientService.nightscoutVersionCode); bundle.putString("status", status.getData().toString()); @@ -41,24 +49,7 @@ public class BroadcastStatus { Intent intent = new Intent(Intents.ACTION_NEW_STATUS); intent.putExtras(bundle); intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); - if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) { - bundle = new Bundle(); - try { - bundle.putString("nsclientversionname", MainApp.instance().getPackageManager().getPackageInfo(MainApp.instance().getPackageName(), 0).versionName); - bundle.putInt("nsclientversioncode", MainApp.instance().getPackageManager().getPackageInfo(MainApp.instance().getPackageName(), 0).versionCode); - } catch (PackageManager.NameNotFoundException e) { - log.error("Unhandled exception", e); - } - bundle.putString("nightscoutversionname", NSClientService.nightscoutVersionName); - bundle.putInt("nightscoutversioncode", NSClientService.nightscoutVersionCode); - bundle.putString("status", status.getData().toString()); - bundle.putBoolean("delta", isDelta); - intent = new Intent(Intents.ACTION_NEW_STATUS); - intent.putExtras(bundle); - intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - context.sendBroadcast(intent); - } + return intent; } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastTreatment.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastTreatment.java index 94b83c56bd..4f36d85348 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastTreatment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastTreatment.java @@ -15,14 +15,15 @@ import java.util.List; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.Services.Intents; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.services.Intents; import info.nightscout.utils.SP; /** * Created by mike on 20.02.2016. */ public class BroadcastTreatment { - private static Logger log = LoggerFactory.getLogger(BroadcastTreatment.class); + private static Logger log = LoggerFactory.getLogger(L.NSCLIENT); public static void handleNewTreatment(JSONObject treatment, boolean isDelta, boolean isLocalBypass) { @@ -35,7 +36,7 @@ public class BroadcastTreatment { intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); - if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) { + if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) { bundle = new Bundle(); bundle.putString("treatment", treatment.toString()); bundle.putBoolean("delta", isDelta); @@ -59,7 +60,7 @@ public class BroadcastTreatment { LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); } - if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) { + if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) { splitted = splitArray(treatments); for (JSONArray part : splitted) { Bundle bundle = new Bundle(); @@ -73,28 +74,6 @@ public class BroadcastTreatment { } } - public void handleChangedTreatment(JSONObject treatment, boolean isDelta) { - - Bundle bundle = new Bundle(); - bundle.putString("treatment", treatment.toString()); - bundle.putBoolean("delta", isDelta); - Intent intent = new Intent(Intents.ACTION_CHANGED_TREATMENT); - intent.putExtras(bundle); - intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); - - - if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) { - bundle = new Bundle(); - bundle.putString("treatment", treatment.toString()); - bundle.putBoolean("delta", isDelta); - intent = new Intent(Intents.ACTION_CHANGED_TREATMENT); - intent.putExtras(bundle); - intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - MainApp.instance().getApplicationContext().sendBroadcast(intent); - } - } - public static void handleChangedTreatment(JSONArray treatments, boolean isDelta) { List splitted = splitArray(treatments); @@ -108,7 +87,7 @@ public class BroadcastTreatment { LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); } - if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) { + if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) { splitted = splitArray(treatments); for (JSONArray part : splitted) { Bundle bundle = new Bundle(); @@ -122,28 +101,6 @@ public class BroadcastTreatment { } } - public static void handleRemovedTreatment(JSONObject treatment, boolean isDelta) { - - Bundle bundle = new Bundle(); - bundle.putString("treatment", treatment.toString()); - bundle.putBoolean("delta", isDelta); - Intent intent = new Intent(Intents.ACTION_REMOVED_TREATMENT); - intent.putExtras(bundle); - intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); - - - if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) { - bundle = new Bundle(); - bundle.putString("treatment", treatment.toString()); - bundle.putBoolean("delta", isDelta); - intent = new Intent(Intents.ACTION_REMOVED_TREATMENT); - intent.putExtras(bundle); - intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - MainApp.instance().getApplicationContext().sendBroadcast(intent); - } - } - public static void handleRemovedTreatment(JSONArray treatments, boolean isDelta) { Bundle bundle = new Bundle(); @@ -155,7 +112,7 @@ public class BroadcastTreatment { LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); - if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) { + if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) { bundle = new Bundle(); bundle.putString("treatments", treatments.toString()); bundle.putBoolean("delta", isDelta); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastUrgentAlarm.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastUrgentAlarm.java index c332be03af..c8988141d7 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastUrgentAlarm.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastUrgentAlarm.java @@ -2,27 +2,20 @@ package info.nightscout.androidaps.plugins.NSClientInternal.broadcasts; import android.content.Context; import android.content.Intent; -import android.content.pm.ResolveInfo; import android.os.Bundle; import android.support.v4.content.LocalBroadcastManager; import org.json.JSONObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.List; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.Services.Intents; +import info.nightscout.androidaps.services.Intents; import info.nightscout.utils.SP; /** * Created by mike on 26.06.2016. */ public class BroadcastUrgentAlarm { - private static Logger log = LoggerFactory.getLogger(BroadcastUrgentAlarm.class); - public static void handleUrgentAlarm(JSONObject urgentalarm, Context context) { Bundle bundle = new Bundle(); bundle.putString("data", urgentalarm.toString()); @@ -31,7 +24,7 @@ public class BroadcastUrgentAlarm { intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); - if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) { + if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, false)) { bundle = new Bundle(); bundle.putString("data", urgentalarm.toString()); intent = new Intent(Intents.ACTION_URGENT_ALARM); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/DbLogger.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/DbLogger.java index 2723fc0748..ec31141002 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/DbLogger.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/DbLogger.java @@ -8,32 +8,36 @@ import org.slf4j.LoggerFactory; import java.util.List; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.logging.L; import info.nightscout.utils.ToastUtils; /** * Created by mike on 02.07.2016. */ public class DbLogger { - private static Logger log = LoggerFactory.getLogger(DbLogger.class); + private static Logger log = LoggerFactory.getLogger(L.NSCLIENT); public static void dbAdd(Intent intent, String data) { List q = MainApp.instance().getApplicationContext().getPackageManager().queryBroadcastReceivers(intent, 0); if (q.size() < 1) { - ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(),MainApp.gs(R.string.nsclientnotinstalled)); + ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.nsclientnotinstalled)); log.error("DBADD No receivers"); - } else if (Config.logNSUpload) - log.debug("DBADD dbAdd " + q.size() + " receivers " + data); + } else if (L.isEnabled(L.NSCLIENT)) { + if (L.isEnabled(L.NSCLIENT)) + log.debug("DBADD dbAdd " + q.size() + " receivers " + data); + } } - public static void dbRemove(Intent intent, String data) { + public static void dbRemove(Intent intent, String data) { List q = MainApp.instance().getApplicationContext().getPackageManager().queryBroadcastReceivers(intent, 0); if (q.size() < 1) { - ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(),MainApp.gs(R.string.nsclientnotinstalled)); + ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.nsclientnotinstalled)); log.error("DBREMOVE No receivers"); - } else if (Config.logNSUpload) - log.debug("DBREMOVE dbRemove " + q.size() + " receivers " + data); + } else if (L.isEnabled(L.NSCLIENT)) { + if (L.isEnabled(L.NSCLIENT)) + log.debug("DBREMOVE dbRemove " + q.size() + " receivers " + data); + } } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/NSAlarm.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/NSAlarm.java index 1c28b790d7..7ad82220da 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/NSAlarm.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/NSAlarm.java @@ -5,12 +5,14 @@ import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import info.nightscout.androidaps.logging.L; + /** * Created by mike on 11.06.2017. */ public class NSAlarm { - private static Logger log = LoggerFactory.getLogger(NSAlarm.class); + private static Logger log = LoggerFactory.getLogger(L.NSCLIENT); JSONObject data; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/NSCal.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/NSCal.java index 93d46fa18e..83fe44073e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/NSCal.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/NSCal.java @@ -5,8 +5,10 @@ import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import info.nightscout.androidaps.logging.L; + public class NSCal { - private static Logger log = LoggerFactory.getLogger(NSCal.class); + private static Logger log = LoggerFactory.getLogger(L.NSCLIENT); public long date; public double slope; public double intercept; @@ -20,7 +22,7 @@ public class NSCal { scale = json.getDouble("scale"); } catch (JSONException e) { log.error("Unhandled exception", e); - log.debug("Data: " + json.toString()); + log.error("Data: " + json.toString()); } } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/NSDeviceStatus.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/NSDeviceStatus.java index d1755dd4c1..b48319f979 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/NSDeviceStatus.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/NSDeviceStatus.java @@ -1,8 +1,11 @@ package info.nightscout.androidaps.plugins.NSClientInternal.data; +import android.content.Intent; +import android.os.Bundle; import android.text.Html; import android.text.Spanned; +import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.slf4j.Logger; @@ -12,7 +15,12 @@ import java.util.HashMap; import java.util.Iterator; import java.util.Map; +import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin; +import info.nightscout.androidaps.plugins.Loop.APSResult; +import info.nightscout.androidaps.logging.BundleLogger; import info.nightscout.utils.DateUtil; import info.nightscout.utils.Round; import info.nightscout.utils.SP; @@ -72,7 +80,7 @@ import info.nightscout.utils.SP; } */ public class NSDeviceStatus { - private static Logger log = LoggerFactory.getLogger(NSDeviceStatus.class); + private Logger log = LoggerFactory.getLogger(L.NSCLIENT); private static NSDeviceStatus instance = null; @@ -87,6 +95,41 @@ public class NSDeviceStatus { public NSDeviceStatus() { } + public void handleNewData(Intent intent) { + Bundle bundle = intent.getExtras(); + if (bundle == null) return; + + if (L.isEnabled(L.NSCLIENT)) + log.debug("Got NS devicestatus: " + BundleLogger.log(bundle)); + + try { + if (bundle.containsKey("devicestatus")) { + JSONObject devicestatusJson = new JSONObject(bundle.getString("devicestatus")); + setData(devicestatusJson); + if (devicestatusJson.has("pump")) { + // Objectives 0 + ObjectivesPlugin.getPlugin().pumpStatusIsAvailableInNS = true; + ObjectivesPlugin.getPlugin().saveProgress(); + } + } + if (bundle.containsKey("devicestatuses")) { + String devicestatusesstring = bundle.getString("devicestatuses"); + JSONArray jsonArray = new JSONArray(devicestatusesstring); + for (int i = 0; i < jsonArray.length(); i++) { + JSONObject devicestatusJson = jsonArray.getJSONObject(i); + setData(devicestatusJson); + if (devicestatusJson.has("pump")) { + // Objectives 0 + ObjectivesPlugin.getPlugin().pumpStatusIsAvailableInNS = true; + ObjectivesPlugin.getPlugin().saveProgress(); + } + } + } + } catch (Exception e) { + log.error("Unhandled exception", e); + } + } + public NSDeviceStatus setData(JSONObject obj) { this.data = obj; updatePumpData(obj); @@ -132,10 +175,14 @@ public class NSDeviceStatus { public Spanned getPumpStatus() { //String[] ALL_STATUS_FIELDS = {"reservoir", "battery", "clock", "status", "device"}; + StringBuilder string = new StringBuilder(); + string.append(""); + string.append(MainApp.gs(R.string.pump)); + string.append(": "); + if (deviceStatusPumpData == null) return Html.fromHtml(""); - StringBuilder string = new StringBuilder(); // test warning level int level = Levels.INFO; long now = System.currentTimeMillis(); @@ -287,6 +334,10 @@ public class NSDeviceStatus { public Spanned getOpenApsStatus() { StringBuilder string = new StringBuilder(); + string.append(""); + string.append(MainApp.gs(R.string.openaps_short)); + string.append(": "); + // test warning level int level = Levels.INFO; long now = System.currentTimeMillis(); @@ -374,7 +425,7 @@ public class NSDeviceStatus { public String getUploaderStatus() { Iterator iter = uploaders.entrySet().iterator(); int minBattery = 100; - while(iter.hasNext()) { + while (iter.hasNext()) { Map.Entry pair = (Map.Entry) iter.next(); Uploader uploader = (Uploader) pair.getValue(); if (minBattery > uploader.battery) @@ -384,11 +435,31 @@ public class NSDeviceStatus { return minBattery + "%"; } + public Spanned getUploaderStatusSpanned() { + StringBuilder string = new StringBuilder(); + string.append(""); + string.append(MainApp.gs(R.string.uploader_short)); + string.append(": "); + + Iterator iter = uploaders.entrySet().iterator(); + int minBattery = 100; + while (iter.hasNext()) { + Map.Entry pair = (Map.Entry) iter.next(); + Uploader uploader = (Uploader) pair.getValue(); + if (minBattery > uploader.battery) + minBattery = uploader.battery; + } + + string.append(minBattery); + string.append("%"); + return Html.fromHtml(string.toString()); + } + public Spanned getExtendedUploaderStatus() { StringBuilder string = new StringBuilder(); Iterator iter = uploaders.entrySet().iterator(); - while(iter.hasNext()) { + while (iter.hasNext()) { Map.Entry pair = (Map.Entry) iter.next(); Uploader uploader = (Uploader) pair.getValue(); String device = (String) pair.getKey(); @@ -398,4 +469,11 @@ public class NSDeviceStatus { return Html.fromHtml(string.toString()); } + public static APSResult getAPSResult() { + APSResult result = new APSResult(); + result.json = deviceStatusOpenAPSData.suggested; + result.date = deviceStatusOpenAPSData.clockSuggested; + return result; + } + } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/NSMbg.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/NSMbg.java index 353dd49b74..cd4cd9cdba 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/NSMbg.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/NSMbg.java @@ -5,8 +5,10 @@ import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import info.nightscout.androidaps.logging.L; + public class NSMbg { - private static Logger log = LoggerFactory.getLogger(NSMbg.class); + private static Logger log = LoggerFactory.getLogger(L.NSCLIENT); public long date; public double mbg; public String json; @@ -18,7 +20,7 @@ public class NSMbg { this.json = json.toString(); } catch (JSONException e) { log.error("Unhandled exception", e); - log.debug("Data: " + json.toString()); + log.error("Data: " + json.toString()); } } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/NSSettingsStatus.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/NSSettingsStatus.java index 8d09a05146..dc3c9f742e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/NSSettingsStatus.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/NSSettingsStatus.java @@ -1,5 +1,8 @@ package info.nightscout.androidaps.plugins.NSClientInternal.data; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.os.Bundle; import android.support.annotation.Nullable; import org.json.JSONException; @@ -10,6 +13,16 @@ import org.slf4j.LoggerFactory; import java.util.Date; import java.util.Objects; +import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.Overview.OverviewPlugin; +import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification; +import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; +import info.nightscout.androidaps.plugins.Overview.notifications.Notification; +import info.nightscout.androidaps.logging.BundleLogger; + /* { "status": "ok", @@ -101,7 +114,7 @@ import java.util.Objects; } */ public class NSSettingsStatus { - private static Logger log = LoggerFactory.getLogger(NSSettingsStatus.class); + private Logger log = LoggerFactory.getLogger(L.NSCLIENT); private static NSSettingsStatus instance = null; @@ -111,6 +124,8 @@ public class NSSettingsStatus { return instance; } + public String nightscoutVersionName = ""; + private JSONObject data = null; public NSSettingsStatus() { @@ -121,6 +136,59 @@ public class NSSettingsStatus { return this; } + public void handleNewData(Intent intent) { + Bundle bundle = intent.getExtras(); + if (bundle == null) return; + + if (L.isEnabled(L.NSCLIENT)) + log.debug("Got NS status: " + BundleLogger.log(bundle)); + + if (bundle.containsKey("nsclientversioncode")) { + + Integer nightscoutVersionCode = bundle.getInt("nightscoutversioncode"); + nightscoutVersionName = bundle.getString("nightscoutversionname"); + Integer nsClientVersionCode = bundle.getInt("nsclientversioncode"); + String nsClientVersionName = bundle.getString("nsclientversionname"); + if (L.isEnabled(L.NSCLIENT)) + log.debug("Got versions: NSClient: " + nsClientVersionName + " Nightscout: " + nightscoutVersionName); + try { + if (nsClientVersionCode < MainApp.instance().getPackageManager().getPackageInfo(MainApp.instance().getPackageName(), 0).versionCode) { + Notification notification = new Notification(Notification.OLD_NSCLIENT, MainApp.gs(R.string.unsupportedclientver), Notification.URGENT); + MainApp.bus().post(new EventNewNotification(notification)); + } else { + MainApp.bus().post(new EventDismissNotification(Notification.OLD_NSCLIENT)); + } + } catch (PackageManager.NameNotFoundException e) { + log.error("Unhandled exception", e); + } + if (nightscoutVersionCode < Config.SUPPORTEDNSVERSION) { + Notification notification = new Notification(Notification.OLD_NS, MainApp.gs(R.string.unsupportednsversion), Notification.NORMAL); + MainApp.bus().post(new EventNewNotification(notification)); + } else { + MainApp.bus().post(new EventDismissNotification(Notification.OLD_NS)); + } + } else { + Notification notification = new Notification(Notification.OLD_NSCLIENT, MainApp.gs(R.string.unsupportedclientver), Notification.URGENT); + MainApp.bus().post(new EventNewNotification(notification)); + } + if (bundle.containsKey("status")) { + try { + JSONObject statusJson = new JSONObject(bundle.getString("status")); + setData(statusJson); + if (L.isEnabled(L.NSCLIENT)) + log.debug("Received status: " + statusJson.toString()); + Double targetHigh = getThreshold("bgTargetTop"); + Double targetlow = getThreshold("bgTargetBottom"); + if (targetHigh != null) + OverviewPlugin.bgTargetHigh = targetHigh; + if (targetlow != null) + OverviewPlugin.bgTargetLow = targetlow; + } catch (JSONException e) { + log.error("Unhandled exception", e); + } + } + } + public String getName() { return getStringOrNull("name"); } @@ -134,7 +202,7 @@ public class NSSettingsStatus { } public Date getServerTime() { - return getDateOrNull("versionNum"); + return getDateOrNull("serverTime"); } public boolean getApiEnabled() { @@ -202,13 +270,11 @@ public class NSSettingsStatus { if (settingsO.has("thresholds")) { JSONObject tObject = settingsO.getJSONObject("thresholds"); if (tObject.has(what)) { - Double result = tObject.getDouble(what); - return result; + return tObject.getDouble(what); } } if (settingsO.has("alarmTimeagoWarnMins") && Objects.equals(what, "alarmTimeagoWarnMins")) { - Double result = settingsO.getDouble(what); - return result; + return settingsO.getDouble(what); } } } catch (JSONException e) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/NSSgv.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/NSSgv.java index 50336a5f52..2212884a3e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/NSSgv.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/NSSgv.java @@ -5,12 +5,14 @@ import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import info.nightscout.androidaps.logging.L; + /** * * {"mgdl":105,"mills":1455136282375,"device":"xDrip-BluetoothWixel","direction":"Flat","filtered":98272,"unfiltered":98272,"noise":1,"rssi":100} */ public class NSSgv { - private static Logger log = LoggerFactory.getLogger(NSSgv.class); + private static Logger log = LoggerFactory.getLogger(L.NSCLIENT); private JSONObject data; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/NSTreatment.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/NSTreatment.java index a9f960edd0..d4ee20e2a1 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/NSTreatment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/NSTreatment.java @@ -7,8 +7,10 @@ import org.slf4j.LoggerFactory; import java.util.Date; +import info.nightscout.androidaps.logging.L; + public class NSTreatment { - private static Logger log = LoggerFactory.getLogger(NSTreatment.class); + private static Logger log = LoggerFactory.getLogger(L.NSCLIENT); private JSONObject data; private String action = null; // "update", "remove" or null (add) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/receivers/AckAlarmReceiver.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/receivers/AckAlarmReceiver.java index 2aae41538a..f23533e9ab 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/receivers/AckAlarmReceiver.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/receivers/AckAlarmReceiver.java @@ -11,15 +11,15 @@ import org.slf4j.LoggerFactory; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginType; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.NSClientInternal.NSClientPlugin; import info.nightscout.androidaps.plugins.NSClientInternal.data.AlarmAck; import info.nightscout.androidaps.plugins.NSClientInternal.services.NSClientService; import info.nightscout.utils.SP; public class AckAlarmReceiver extends BroadcastReceiver { - private static Logger log = LoggerFactory.getLogger(AckAlarmReceiver.class); + private static Logger log = LoggerFactory.getLogger(L.NSCLIENT); @Override @@ -32,7 +32,8 @@ public class AckAlarmReceiver extends BroadcastReceiver { return; } if (SP.getBoolean(R.string.key_ns_noupload, false)) { - log.debug("Upload disabled. Message dropped"); + if (L.isEnabled(L.NSCLIENT)) + log.debug("Upload disabled. Message dropped"); return; } wakeLock.acquire(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/receivers/DBAccessReceiver.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/receivers/DBAccessReceiver.java index 332ccc2ea3..896382d818 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/receivers/DBAccessReceiver.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/receivers/DBAccessReceiver.java @@ -15,6 +15,8 @@ import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.db.DbRequest; import info.nightscout.androidaps.interfaces.PluginType; +import info.nightscout.androidaps.logging.BundleLogger; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.NSClientInternal.NSClientPlugin; import info.nightscout.androidaps.plugins.NSClientInternal.UploadQueue; import info.nightscout.androidaps.plugins.NSClientInternal.broadcasts.BroadcastTreatment; @@ -22,7 +24,7 @@ import info.nightscout.utils.DateUtil; import info.nightscout.utils.SP; public class DBAccessReceiver extends BroadcastReceiver { - private static Logger log = LoggerFactory.getLogger(DBAccessReceiver.class); + private static Logger log = LoggerFactory.getLogger(L.NSCLIENT); @Override @@ -36,6 +38,9 @@ public class DBAccessReceiver extends BroadcastReceiver { if (bundles == null) return; if (!bundles.containsKey("action")) return; + if (L.isEnabled(L.NSCLIENT)) + log.debug(BundleLogger.log(bundles)); + String collection = null; String _id = null; JSONObject data = null; @@ -43,18 +48,26 @@ public class DBAccessReceiver extends BroadcastReceiver { try { collection = bundles.getString("collection"); } catch (Exception e) { + log.error("Unhandled exception", e); + return; } try { - _id = bundles.getString("_id"); + if (!action.equals("dbAdd")) + _id = bundles.getString("_id"); } catch (Exception e) { + log.error("Unhandled exception", e); + return; } try { - data = new JSONObject(bundles.getString("data")); + if (!action.equals("dbRemove")) + data = new JSONObject(bundles.getString("data")); } catch (Exception e) { + log.error("Unhandled exception", e); + return; } if (data == null && !action.equals("dbRemove") || _id == null && action.equals("dbRemove")) { - log.debug("DBACCESS no data inside record"); + log.error("DBACCESS no data inside record"); return; } @@ -70,7 +83,7 @@ public class DBAccessReceiver extends BroadcastReceiver { } if (!isAllowedCollection(collection)) { - log.debug("DBACCESS wrong collection specified"); + log.error("DBACCESS wrong collection specified"); return; } @@ -79,7 +92,7 @@ public class DBAccessReceiver extends BroadcastReceiver { DbRequest dbr = new DbRequest(action, collection, nsclientid.toString(), _id); UploadQueue.add(dbr); } - } else if (action.equals("dbUpdate")) { + } else if (action.equals("dbUpdate")) { if (shouldUpload()) { DbRequest dbr = new DbRequest(action, collection, nsclientid.toString(), _id, data); UploadQueue.add(dbr); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/services/NSClientService.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/services/NSClientService.java index fab9a181c4..2066aaa423 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/services/NSClientService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/services/NSClientService.java @@ -8,7 +8,7 @@ import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; import android.os.PowerManager; - +import android.os.SystemClock; import com.google.common.base.Charsets; import com.google.common.hash.Hashing; @@ -23,7 +23,7 @@ import org.slf4j.LoggerFactory; import java.net.URISyntaxException; import java.sql.SQLException; -import java.util.Date; +import java.util.ArrayList; import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; @@ -34,6 +34,7 @@ import info.nightscout.androidaps.events.EventAppExit; import info.nightscout.androidaps.events.EventConfigBuilderChange; import info.nightscout.androidaps.events.EventPreferenceChange; import info.nightscout.androidaps.interfaces.PluginType; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.NSClientInternal.NSClientPlugin; import info.nightscout.androidaps.plugins.NSClientInternal.UploadQueue; import info.nightscout.androidaps.plugins.NSClientInternal.acks.NSAddAck; @@ -58,6 +59,7 @@ import info.nightscout.androidaps.plugins.NSClientInternal.data.NSTreatment; import info.nightscout.androidaps.plugins.NSClientInternal.events.EventNSClientNewLog; import info.nightscout.androidaps.plugins.NSClientInternal.events.EventNSClientRestart; import info.nightscout.androidaps.plugins.NSClientInternal.events.EventNSClientStatus; +import info.nightscout.androidaps.plugins.NSClientInternal.events.EventNSClientUpdateGUI; import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.Overview.notifications.Notification; @@ -65,12 +67,13 @@ import info.nightscout.utils.DateUtil; import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.JsonHelper; import info.nightscout.utils.SP; +import info.nightscout.utils.T; import io.socket.client.IO; import io.socket.client.Socket; import io.socket.emitter.Emitter; public class NSClientService extends Service { - private static Logger log = LoggerFactory.getLogger(NSClientService.class); + private static Logger log = LoggerFactory.getLogger(L.NSCLIENT); static public PowerManager.WakeLock mWakeLock; private IBinder mBinder = new NSClientService.LocalBinder(); @@ -103,6 +106,11 @@ public class NSClientService extends Service { public static UploadQueue uploadQueue = new UploadQueue(); + private ArrayList reconnections = new ArrayList<>(); + private int WATCHDOG_INTERVAL_MINUTES = 2; + private int WATCHDOG_RECONNECT_IN = 15; + private int WATCHDOG_MAXCONNECTIONS = 5; + public NSClientService() { registerBus(); if (handler == null) { @@ -156,14 +164,12 @@ public class NSClientService extends Service { @Subscribe public void onStatusEvent(EventAppExit event) { - if (Config.logFunctionCalls) + if (L.isEnabled(L.NSCLIENT)) log.debug("EventAppExit received"); destroy(); stopSelf(); - if (Config.logFunctionCalls) - log.debug("EventAppExit finished"); } @Subscribe @@ -242,20 +248,50 @@ public class NSClientService extends Service { @Override public void call(Object... args) { connectCounter++; - MainApp.bus().post(new EventNSClientNewLog("NSCLIENT", "connect #" + connectCounter + " event. ID: " + mSocket.id())); - sendAuthMessage(new NSAuthAck()); + String socketId = mSocket != null ? mSocket.id() : "NULL"; + MainApp.bus().post(new EventNSClientNewLog("NSCLIENT", "connect #" + connectCounter + " event. ID: " + socketId)); + if (mSocket != null) + sendAuthMessage(new NSAuthAck()); + watchdog(); } }; + void watchdog() { + synchronized (reconnections) { + long now = DateUtil.now(); + reconnections.add(now); + for (int i = 0; i < reconnections.size(); i++) { + Long r = reconnections.get(i); + if (r < now - T.mins(WATCHDOG_INTERVAL_MINUTES).msecs()) { + reconnections.remove(r); + } + } + MainApp.bus().post(new EventNSClientNewLog("WATCHDOG", "connections in last " + WATCHDOG_INTERVAL_MINUTES + " mins: " + reconnections.size() + "/" + WATCHDOG_MAXCONNECTIONS)); + if (reconnections.size() >= WATCHDOG_MAXCONNECTIONS) { + Notification n = new Notification(Notification.NSMALFUNCTION, MainApp.gs(R.string.nsmalfunction), Notification.URGENT); + MainApp.bus().post(new EventNewNotification(n)); + MainApp.bus().post(new EventNSClientNewLog("WATCHDOG", "pausing for " + WATCHDOG_RECONNECT_IN + " mins")); + NSClientPlugin.getPlugin().pause(true); + MainApp.bus().post(new EventNSClientUpdateGUI()); + new Thread(() -> { + SystemClock.sleep(T.mins(WATCHDOG_RECONNECT_IN).msecs()); + MainApp.bus().post(new EventNSClientNewLog("WATCHDOG", "reenabling NSClient")); + NSClientPlugin.getPlugin().pause(false); + }).start(); + } + } + } + private Emitter.Listener onDisconnect = new Emitter.Listener() { @Override public void call(Object... args) { - log.debug("disconnect reason: {}", args); + if (L.isEnabled(L.NSCLIENT)) + log.debug("disconnect reason: {}", args); MainApp.bus().post(new EventNSClientNewLog("NSCLIENT", "disconnect event")); } }; - public void destroy() { + public synchronized void destroy() { if (mSocket != null) { mSocket.off(Socket.EVENT_CONNECT); mSocket.off(Socket.EVENT_DISCONNECT); @@ -288,7 +324,8 @@ public class NSClientService extends Service { return; } MainApp.bus().post(new EventNSClientNewLog("AUTH", "requesting auth")); - mSocket.emit("authorize", authMessage, ack); + if (mSocket != null) + mSocket.emit("authorize", authMessage, ack); } @Subscribe @@ -326,8 +363,7 @@ public class NSClientService extends Service { private Emitter.Listener onPing = new Emitter.Listener() { @Override public void call(final Object... args) { - if (Config.detailedLog) - MainApp.bus().post(new EventNSClientNewLog("PING", "received")); + MainApp.bus().post(new EventNSClientNewLog("PING", "received")); // send data if there is something waiting resend("Ping received"); } @@ -352,16 +388,18 @@ public class NSClientService extends Service { data = (JSONObject) args[0]; } catch (Exception e) { FabricPrivacy.log("Wrong Announcement from NS: " + args[0]); + log.error("Unhandled exception", e); return; } - if (Config.detailedLog) - try { - MainApp.bus().post(new EventNSClientNewLog("ANNOUNCEMENT", JsonHelper.safeGetString(data, "message", "received"))); - } catch (Exception e) { - FabricPrivacy.logException(e); - } + try { + MainApp.bus().post(new EventNSClientNewLog("ANNOUNCEMENT", JsonHelper.safeGetString(data, "message", "received"))); + } catch (Exception e) { + FabricPrivacy.logException(e); + log.error("Unhandled exception", e); + } BroadcastAnnouncement.handleAnnouncement(data, getApplicationContext()); - log.debug(data.toString()); + if (L.isEnabled(L.NSCLIENT)) + log.debug(data.toString()); } }; @@ -381,17 +419,18 @@ public class NSClientService extends Service { */ @Override public void call(final Object... args) { - if (Config.detailedLog) - MainApp.bus().post(new EventNSClientNewLog("ALARM", "received")); + MainApp.bus().post(new EventNSClientNewLog("ALARM", "received")); JSONObject data; try { data = (JSONObject) args[0]; } catch (Exception e) { FabricPrivacy.log("Wrong alarm from NS: " + args[0]); + log.error("Unhandled exception", e); return; } BroadcastAlarm.handleAlarm(data, getApplicationContext()); - log.debug(data.toString()); + if (L.isEnabled(L.NSCLIENT)) + log.debug(data.toString()); } }; @@ -416,12 +455,13 @@ public class NSClientService extends Service { data = (JSONObject) args[0]; } catch (Exception e) { FabricPrivacy.log("Wrong Urgent alarm from NS: " + args[0]); + log.error("Unhandled exception", e); return; } - if (Config.detailedLog) - MainApp.bus().post(new EventNSClientNewLog("URGENTALARM", "received")); + MainApp.bus().post(new EventNSClientNewLog("URGENTALARM", "received")); BroadcastUrgentAlarm.handleUrgentAlarm(data, getApplicationContext()); - log.debug(data.toString()); + if (L.isEnabled(L.NSCLIENT)) + log.debug(data.toString()); } }; @@ -441,12 +481,13 @@ public class NSClientService extends Service { data = (JSONObject) args[0]; } catch (Exception e) { FabricPrivacy.log("Wrong Urgent alarm from NS: " + args[0]); + log.error("Unhandled exception", e); return; } - if (Config.detailedLog) - MainApp.bus().post(new EventNSClientNewLog("CLEARALARM", "received")); + MainApp.bus().post(new EventNSClientNewLog("CLEARALARM", "received")); BroadcastClearAlarm.handleClearAlarm(data, getApplicationContext()); - log.debug(data.toString()); + if (L.isEnabled(L.NSCLIENT)) + log.debug(data.toString()); } }; @@ -743,17 +784,6 @@ public class NSClientService extends Service { } } - private boolean isCurrent(NSTreatment treatment) { - long now = (new Date()).getTime(); - long minPast = now - nsHours * 60L * 60 * 1000; - if (treatment.getMills() == null) { - log.debug("treatment.getMills() == null " + treatment.getData().toString()); - return false; - } - if (treatment.getMills() > minPast) return true; - return false; - } - public void resend(final String reason) { if (UploadQueue.size() == 0) return; @@ -766,7 +796,8 @@ public class NSClientService extends Service { if (mSocket == null || !mSocket.connected()) return; if (lastResendTime > System.currentTimeMillis() - 10 * 1000L) { - log.debug("Skipping resend by lastResendTime: " + ((System.currentTimeMillis() - lastResendTime) / 1000L) + " sec"); + if (L.isEnabled(L.NSCLIENT)) + log.debug("Skipping resend by lastResendTime: " + ((System.currentTimeMillis() - lastResendTime) / 1000L) + " sec"); return; } lastResendTime = System.currentTimeMillis(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/DetermineBasalAdapterAMAJS.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/DetermineBasalAdapterAMAJS.java index 4c8de10b9c..50e79d1e37 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/DetermineBasalAdapterAMAJS.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/DetermineBasalAdapterAMAJS.java @@ -3,7 +3,6 @@ package info.nightscout.androidaps.plugins.OpenAPSAMA; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; -import org.mozilla.javascript.Callable; import org.mozilla.javascript.Context; import org.mozilla.javascript.Function; import org.mozilla.javascript.NativeJSON; @@ -18,7 +17,6 @@ import org.slf4j.LoggerFactory; import java.io.IOException; import java.lang.reflect.InvocationTargetException; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; @@ -27,6 +25,7 @@ import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.MealData; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.db.TemporaryBasal; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin; import info.nightscout.androidaps.plugins.Loop.ScriptReader; import info.nightscout.androidaps.plugins.OpenAPSMA.LoggerCallback; @@ -35,7 +34,7 @@ import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.utils.SP; public class DetermineBasalAdapterAMAJS { - private static Logger log = LoggerFactory.getLogger(DetermineBasalAdapterAMAJS.class); + private static Logger log = LoggerFactory.getLogger(L.APS); private ScriptReader mScriptReader = null; @@ -56,23 +55,24 @@ public class DetermineBasalAdapterAMAJS { private String scriptDebug = ""; - public DetermineBasalAdapterAMAJS(ScriptReader scriptReader) throws IOException { + public DetermineBasalAdapterAMAJS(ScriptReader scriptReader) { mScriptReader = scriptReader; } public DetermineBasalResultAMA invoke() { - - log.debug(">>> Invoking detemine_basal <<<"); - log.debug("Glucose status: " + (storedGlucoseStatus = mGlucoseStatus.toString())); - log.debug("IOB data: " + (storedIobData = mIobData.toString())); - log.debug("Current temp: " + (storedCurrentTemp = mCurrentTemp.toString())); - log.debug("Profile: " + (storedProfile = mProfile.toString())); - log.debug("Meal data: " + (storedMeal_data = mMealData.toString())); - if (mAutosensData != null) - log.debug("Autosens data: " + (storedAutosens_data = mAutosensData.toString())); - else - log.debug("Autosens data: " + (storedAutosens_data = "undefined")); + if (L.isEnabled(L.APS)) { + log.debug(">>> Invoking detemine_basal <<<"); + log.debug("Glucose status: " + (storedGlucoseStatus = mGlucoseStatus.toString())); + log.debug("IOB data: " + (storedIobData = mIobData.toString())); + log.debug("Current temp: " + (storedCurrentTemp = mCurrentTemp.toString())); + log.debug("Profile: " + (storedProfile = mProfile.toString())); + log.debug("Meal data: " + (storedMeal_data = mMealData.toString())); + if (mAutosensData != null) + log.debug("Autosens data: " + (storedAutosens_data = mAutosensData.toString())); + else + log.debug("Autosens data: " + (storedAutosens_data = "undefined")); + } DetermineBasalResultAMA determineBasalResultAMA = null; @@ -119,7 +119,7 @@ public class DetermineBasalAdapterAMAJS { // Parse the jsResult object to a JSON-String String result = NativeJSON.stringify(rhino, scope, jsResult, null, null).toString(); - if (Config.logAPSResult) + if (L.isEnabled(L.APS)) log.debug("Result: " + result); try { determineBasalResultAMA = new DetermineBasalResultAMA(jsResult, new JSONObject(result)); @@ -127,17 +127,13 @@ public class DetermineBasalAdapterAMAJS { log.error("Unhandled exception", e); } } else { - log.debug("Problem loading JS Functions"); + log.error("Problem loading JS Functions"); } } catch (IOException e) { - log.debug("IOException"); + log.error("IOException"); } catch (RhinoException e) { log.error("RhinoException: (" + e.lineNumber() + "," + e.columnNumber() + ") " + e.toString()); - } catch (IllegalAccessException e) { - log.error(e.toString()); - } catch (InstantiationException e) { - log.error(e.toString()); - } catch (InvocationTargetException e) { + } catch (IllegalAccessException | InstantiationException | InvocationTargetException e) { log.error(e.toString()); } finally { Context.exit(); @@ -214,7 +210,7 @@ public class DetermineBasalAdapterAMAJS { mProfile.put("temptargetSet", tempTargetSet); mProfile.put("autosens_adjust_targets", SP.getBoolean(R.string.key_openapsama_autosens_adjusttargets, true)); //align with max-absorption model in AMA sensitivity - if(mealData.usedMinCarbsImpact > 0){ + if (mealData.usedMinCarbsImpact > 0) { mProfile.put("min_5m_carbimpact", mealData.usedMinCarbsImpact); } else { mProfile.put("min_5m_carbimpact", SP.getDouble(R.string.key_openapsama_min_5m_carbimpact, SMBDefaults.min_5m_carbimpact)); @@ -265,31 +261,21 @@ public class DetermineBasalAdapterAMAJS { } - public Object makeParam(JSONObject jsonObject, Context rhino, Scriptable scope) { + private Object makeParam(JSONObject jsonObject, Context rhino, Scriptable scope) { if (jsonObject == null) return Undefined.instance; - Object param = NativeJSON.parse(rhino, scope, jsonObject.toString(), new Callable() { - @Override - public Object call(Context context, Scriptable scriptable, Scriptable scriptable1, Object[] objects) { - return objects[1]; - } - }); + Object param = NativeJSON.parse(rhino, scope, jsonObject.toString(), (context, scriptable, scriptable1, objects) -> objects[1]); return param; } - public Object makeParamArray(JSONArray jsonArray, Context rhino, Scriptable scope) { + private Object makeParamArray(JSONArray jsonArray, Context rhino, Scriptable scope) { //Object param = NativeJSON.parse(rhino, scope, "{myarray: " + jsonArray.toString() + " }", new Callable() { - Object param = NativeJSON.parse(rhino, scope, jsonArray.toString(), new Callable() { - @Override - public Object call(Context context, Scriptable scriptable, Scriptable scriptable1, Object[] objects) { - return objects[1]; - } - }); + Object param = NativeJSON.parse(rhino, scope, jsonArray.toString(), (context, scriptable, scriptable1, objects) -> objects[1]); return param; } - public String readFile(String filename) throws IOException { + private String readFile(String filename) throws IOException { byte[] bytes = mScriptReader.readFile(filename); String string = new String(bytes, "UTF-8"); if (string.startsWith("#!/usr/bin/env node")) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/DetermineBasalResultAMA.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/DetermineBasalResultAMA.java index cb2b4a0091..77c8d8a860 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/DetermineBasalResultAMA.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/DetermineBasalResultAMA.java @@ -6,19 +6,19 @@ import org.mozilla.javascript.NativeObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Date; - +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.Loop.APSResult; +import info.nightscout.utils.DateUtil; public class DetermineBasalResultAMA extends APSResult { - private static Logger log = LoggerFactory.getLogger(DetermineBasalResultAMA.class); + private static Logger log = LoggerFactory.getLogger(L.APS); - public double eventualBG; - public double snoozeBG; + private double eventualBG; + private double snoozeBG; - public DetermineBasalResultAMA(NativeObject result, JSONObject j) { + DetermineBasalResultAMA(NativeObject result, JSONObject j) { this(); - date = new Date(); + date = DateUtil.now(); json = j; if (result.containsKey("error")) { reason = result.get("error").toString(); @@ -48,28 +48,17 @@ public class DetermineBasalResultAMA extends APSResult { bolusRequested = false; } - public DetermineBasalResultAMA() { + private DetermineBasalResultAMA() { hasPredictions = true; } @Override public DetermineBasalResultAMA clone() { DetermineBasalResultAMA newResult = new DetermineBasalResultAMA(); - newResult.reason = reason; - newResult.rate = rate; - newResult.duration = duration; - newResult.tempBasalRequested = tempBasalRequested; - newResult.rate = rate; - newResult.duration = duration; + doClone(newResult); - try { - newResult.json = new JSONObject(json.toString()); - } catch (JSONException e) { - log.error("Unhandled exception", e); - } newResult.eventualBG = eventualBG; newResult.snoozeBG = snoozeBG; - newResult.date = date; return newResult; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/OpenAPSAMAFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/OpenAPSAMAFragment.java index f05b0ac696..1874816ddc 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/OpenAPSAMAFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/OpenAPSAMAFragment.java @@ -2,7 +2,6 @@ package info.nightscout.androidaps.plugins.OpenAPSAMA; import android.app.Activity; import android.os.Bundle; -import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -19,14 +18,16 @@ import org.slf4j.LoggerFactory; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateGui; import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateResultGui; +import info.nightscout.utils.DateUtil; import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.JSONFormatter; public class OpenAPSAMAFragment extends SubscriberFragment implements View.OnClickListener { - private static Logger log = LoggerFactory.getLogger(OpenAPSAMAFragment.class); + private static Logger log = LoggerFactory.getLogger(L.APS); Button run; TextView lastRunView; @@ -43,29 +44,23 @@ public class OpenAPSAMAFragment extends SubscriberFragment implements View.OnCli @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - try { - View view = inflater.inflate(R.layout.openapsama_fragment, container, false); + View view = inflater.inflate(R.layout.openapsama_fragment, container, false); - run = (Button) view.findViewById(R.id.openapsma_run); - run.setOnClickListener(this); - lastRunView = (TextView) view.findViewById(R.id.openapsma_lastrun); - glucoseStatusView = (TextView) view.findViewById(R.id.openapsma_glucosestatus); - currentTempView = (TextView) view.findViewById(R.id.openapsma_currenttemp); - iobDataView = (TextView) view.findViewById(R.id.openapsma_iobdata); - profileView = (TextView) view.findViewById(R.id.openapsma_profile); - mealDataView = (TextView) view.findViewById(R.id.openapsma_mealdata); - autosensDataView = (TextView) view.findViewById(R.id.openapsma_autosensdata); - scriptdebugView = (TextView) view.findViewById(R.id.openapsma_scriptdebugdata); - resultView = (TextView) view.findViewById(R.id.openapsma_result); - requestView = (TextView) view.findViewById(R.id.openapsma_request); + run = (Button) view.findViewById(R.id.openapsma_run); + run.setOnClickListener(this); + lastRunView = (TextView) view.findViewById(R.id.openapsma_lastrun); + glucoseStatusView = (TextView) view.findViewById(R.id.openapsma_glucosestatus); + currentTempView = (TextView) view.findViewById(R.id.openapsma_currenttemp); + iobDataView = (TextView) view.findViewById(R.id.openapsma_iobdata); + profileView = (TextView) view.findViewById(R.id.openapsma_profile); + mealDataView = (TextView) view.findViewById(R.id.openapsma_mealdata); + autosensDataView = (TextView) view.findViewById(R.id.openapsma_autosensdata); + scriptdebugView = (TextView) view.findViewById(R.id.openapsma_scriptdebugdata); + resultView = (TextView) view.findViewById(R.id.openapsma_result); + requestView = (TextView) view.findViewById(R.id.openapsma_request); - updateGUI(); - return view; - } catch (Exception e) { - FabricPrivacy.logException(e); - } - - return null; + updateGUI(); + return view; } @Override @@ -93,35 +88,32 @@ public class OpenAPSAMAFragment extends SubscriberFragment implements View.OnCli protected void updateGUI() { Activity activity = getActivity(); if (activity != null) - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - DetermineBasalResultAMA lastAPSResult = OpenAPSAMAPlugin.getPlugin().lastAPSResult; - if (lastAPSResult != null) { - resultView.setText(JSONFormatter.format(lastAPSResult.json)); - requestView.setText(lastAPSResult.toSpanned()); - } - DetermineBasalAdapterAMAJS determineBasalAdapterAMAJS = OpenAPSAMAPlugin.getPlugin().lastDetermineBasalAdapterAMAJS; - if (determineBasalAdapterAMAJS != null) { - glucoseStatusView.setText(JSONFormatter.format(determineBasalAdapterAMAJS.getGlucoseStatusParam())); - currentTempView.setText(JSONFormatter.format(determineBasalAdapterAMAJS.getCurrentTempParam())); - try { - JSONArray iobArray = new JSONArray(determineBasalAdapterAMAJS.getIobDataParam()); - iobDataView.setText(String.format(MainApp.gs(R.string.array_of_elements), iobArray.length()) + "\n" + JSONFormatter.format(iobArray.getString(0))); - } catch (JSONException e) { - log.error("Unhandled exception", e); - iobDataView.setText("JSONException"); - } - profileView.setText(JSONFormatter.format(determineBasalAdapterAMAJS.getProfileParam())); - mealDataView.setText(JSONFormatter.format(determineBasalAdapterAMAJS.getMealDataParam())); - scriptdebugView.setText(determineBasalAdapterAMAJS.getScriptDebug()); - } - if (OpenAPSAMAPlugin.getPlugin().lastAPSRun != null) { - lastRunView.setText(OpenAPSAMAPlugin.getPlugin().lastAPSRun.toLocaleString()); - } - if (OpenAPSAMAPlugin.getPlugin().lastAutosensResult != null) { - autosensDataView.setText(JSONFormatter.format(OpenAPSAMAPlugin.getPlugin().lastAutosensResult.json())); + activity.runOnUiThread(() -> { + DetermineBasalResultAMA lastAPSResult = OpenAPSAMAPlugin.getPlugin().lastAPSResult; + if (lastAPSResult != null) { + resultView.setText(JSONFormatter.format(lastAPSResult.json)); + requestView.setText(lastAPSResult.toSpanned()); + } + DetermineBasalAdapterAMAJS determineBasalAdapterAMAJS = OpenAPSAMAPlugin.getPlugin().lastDetermineBasalAdapterAMAJS; + if (determineBasalAdapterAMAJS != null) { + glucoseStatusView.setText(JSONFormatter.format(determineBasalAdapterAMAJS.getGlucoseStatusParam())); + currentTempView.setText(JSONFormatter.format(determineBasalAdapterAMAJS.getCurrentTempParam())); + try { + JSONArray iobArray = new JSONArray(determineBasalAdapterAMAJS.getIobDataParam()); + iobDataView.setText(String.format(MainApp.gs(R.string.array_of_elements), iobArray.length()) + "\n" + JSONFormatter.format(iobArray.getString(0))); + } catch (JSONException e) { + log.error("Unhandled exception", e); + iobDataView.setText("JSONException"); } + profileView.setText(JSONFormatter.format(determineBasalAdapterAMAJS.getProfileParam())); + mealDataView.setText(JSONFormatter.format(determineBasalAdapterAMAJS.getMealDataParam())); + scriptdebugView.setText(determineBasalAdapterAMAJS.getScriptDebug()); + } + if (OpenAPSAMAPlugin.getPlugin().lastAPSRun != 0) { + lastRunView.setText(DateUtil.dateAndTimeFullString(OpenAPSAMAPlugin.getPlugin().lastAPSRun)); + } + if (OpenAPSAMAPlugin.getPlugin().lastAutosensResult != null) { + autosensDataView.setText(JSONFormatter.format(OpenAPSAMAPlugin.getPlugin().lastAutosensResult.json())); } }); } @@ -129,20 +121,17 @@ public class OpenAPSAMAFragment extends SubscriberFragment implements View.OnCli void updateResultGUI(final String text) { Activity activity = getActivity(); if (activity != null) - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - resultView.setText(text); - glucoseStatusView.setText(""); - currentTempView.setText(""); - iobDataView.setText(""); - profileView.setText(""); - mealDataView.setText(""); - autosensDataView.setText(""); - scriptdebugView.setText(""); - requestView.setText(""); - lastRunView.setText(""); - } + activity.runOnUiThread(() -> { + resultView.setText(text); + glucoseStatusView.setText(""); + currentTempView.setText(""); + iobDataView.setText(""); + profileView.setText(""); + mealDataView.setText(""); + autosensDataView.setText(""); + scriptdebugView.setText(""); + requestView.setText(""); + lastRunView.setText(""); }); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/OpenAPSAMAPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/OpenAPSAMAPlugin.java index 143456f6fc..3bf1301416 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/OpenAPSAMAPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/OpenAPSAMAPlugin.java @@ -4,10 +4,6 @@ import org.json.JSONException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; -import java.util.Date; - -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.GlucoseStatus; @@ -21,7 +17,10 @@ import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; +import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensData; import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensResult; import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin; import info.nightscout.androidaps.plugins.Loop.APSResult; @@ -38,7 +37,7 @@ import info.nightscout.utils.Round; * Created by mike on 05.08.2016. */ public class OpenAPSAMAPlugin extends PluginBase implements APSInterface { - private static Logger log = LoggerFactory.getLogger(OpenAPSAMAPlugin.class); + private static Logger log = LoggerFactory.getLogger(L.APS); private static OpenAPSAMAPlugin openAPSAMAPlugin; @@ -51,29 +50,30 @@ public class OpenAPSAMAPlugin extends PluginBase implements APSInterface { // last values DetermineBasalAdapterAMAJS lastDetermineBasalAdapterAMAJS = null; - Date lastAPSRun = null; + long lastAPSRun = 0; DetermineBasalResultAMA lastAPSResult = null; AutosensResult lastAutosensResult = null; - public OpenAPSAMAPlugin() { + private OpenAPSAMAPlugin() { super(new PluginDescription() .mainType(PluginType.APS) .fragmentClass(OpenAPSAMAFragment.class.getName()) .pluginName(R.string.openapsama) .shortName(R.string.oaps_shortname) .preferencesId(R.xml.pref_openapsama) + .description(R.string.description_ama) ); } @Override public boolean specialEnableCondition() { - PumpInterface pump = ConfigBuilderPlugin.getActivePump(); + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); return pump == null || pump.getPumpDescription().isTempBasalCapable; } @Override public boolean specialShowInListCondition() { - PumpInterface pump = ConfigBuilderPlugin.getActivePump(); + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); return pump == null || pump.getPumpDescription().isTempBasalCapable; } @@ -83,43 +83,39 @@ public class OpenAPSAMAPlugin extends PluginBase implements APSInterface { } @Override - public Date getLastAPSRun() { + public long getLastAPSRun() { return lastAPSRun; } @Override public void invoke(String initiator, boolean tempBasalFallback) { - log.debug("invoke from " + initiator + " tempBasalFallback: " + tempBasalFallback); + if (L.isEnabled(L.APS)) + log.debug("invoke from " + initiator + " tempBasalFallback: " + tempBasalFallback); lastAPSResult = null; DetermineBasalAdapterAMAJS determineBasalAdapterAMAJS; - try { - determineBasalAdapterAMAJS = new DetermineBasalAdapterAMAJS(new ScriptReader(MainApp.instance().getBaseContext())); - } catch (IOException e) { - log.error(e.getMessage(), e); - return; - } + determineBasalAdapterAMAJS = new DetermineBasalAdapterAMAJS(new ScriptReader(MainApp.instance().getBaseContext())); GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData(); - Profile profile = MainApp.getConfigBuilder().getProfile(); - PumpInterface pump = ConfigBuilderPlugin.getActivePump(); + Profile profile = ProfileFunctions.getInstance().getProfile(); + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); if (profile == null) { MainApp.bus().post(new EventOpenAPSUpdateResultGui(MainApp.gs(R.string.noprofileselected))); - if (Config.logAPSResult) + if (L.isEnabled(L.APS)) log.debug(MainApp.gs(R.string.noprofileselected)); return; } if (!isEnabled(PluginType.APS)) { MainApp.bus().post(new EventOpenAPSUpdateResultGui(MainApp.gs(R.string.openapsma_disabled))); - if (Config.logAPSResult) + if (L.isEnabled(L.APS)) log.debug(MainApp.gs(R.string.openapsma_disabled)); return; } if (glucoseStatus == null) { MainApp.bus().post(new EventOpenAPSUpdateResultGui(MainApp.gs(R.string.openapsma_noglucosedata))); - if (Config.logAPSResult) + if (L.isEnabled(L.APS)) log.debug(MainApp.gs(R.string.openapsma_noglucosedata)); return; } @@ -134,14 +130,16 @@ public class OpenAPSAMAPlugin extends PluginBase implements APSInterface { minBg = Round.roundTo(minBg, 0.1d); maxBg = Round.roundTo(maxBg, 0.1d); - Date start = new Date(); - Date startPart = new Date(); + long start = System.currentTimeMillis(); + long startPart = System.currentTimeMillis(); IobTotal[] iobArray = IobCobCalculatorPlugin.getPlugin().calculateIobArrayInDia(profile); - Profiler.log(log, "calculateIobArrayInDia()", startPart); + if (L.isEnabled(L.APS)) + Profiler.log(log, "calculateIobArrayInDia()", startPart); - startPart = new Date(); + startPart = System.currentTimeMillis(); MealData mealData = TreatmentsPlugin.getPlugin().getMealData(); - Profiler.log(log, "getMealData()", startPart); + if (L.isEnabled(L.APS)) + Profiler.log(log, "getMealData()", startPart); double maxIob = MainApp.getConstraintChecker().getMaxIOBAllowed().value(); @@ -161,7 +159,7 @@ public class OpenAPSAMAPlugin extends PluginBase implements APSInterface { if (!HardLimits.checkOnlyHardLimits(profile.getDia(), "dia", HardLimits.MINDIA, HardLimits.MAXDIA)) return; - if (!HardLimits.checkOnlyHardLimits(profile.getIcTimeFromMidnight(profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC)) + if (!HardLimits.checkOnlyHardLimits(profile.getIcTimeFromMidnight(Profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC)) return; if (!HardLimits.checkOnlyHardLimits(Profile.toMgdl(profile.getIsf(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF)) return; @@ -170,19 +168,27 @@ public class OpenAPSAMAPlugin extends PluginBase implements APSInterface { if (!HardLimits.checkOnlyHardLimits(pump.getBaseBasalRate(), "current_basal", 0.01, HardLimits.maxBasal())) return; - startPart = new Date(); + startPart = System.currentTimeMillis(); if (MainApp.getConstraintChecker().isAutosensModeEnabled().value()) { - lastAutosensResult = IobCobCalculatorPlugin.getPlugin().detectSensitivityWithLock(IobCobCalculatorPlugin.getPlugin().oldestDataAvailable(), System.currentTimeMillis()); + AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getLastAutosensDataSynchronized("OpenAPSPlugin"); + if (autosensData == null) { + MainApp.bus().post(new EventOpenAPSUpdateResultGui(MainApp.gs(R.string.openaps_noasdata))); + return; + } + lastAutosensResult = autosensData.autosensResult; } else { lastAutosensResult = new AutosensResult(); + lastAutosensResult.sensResult = "autosens disabled"; } - Profiler.log(log, "detectSensitivityandCarbAbsorption()", startPart); - Profiler.log(log, "AMA data gathering", start); + if (L.isEnabled(L.APS)) + Profiler.log(log, "detectSensitivityandCarbAbsorption()", startPart); + if (L.isEnabled(L.APS)) + Profiler.log(log, "AMA data gathering", start); - start = new Date(); + start = System.currentTimeMillis(); try { - determineBasalAdapterAMAJS.setData(profile, maxIob, maxBasal, minBg, maxBg, targetBg, ConfigBuilderPlugin.getActivePump().getBaseBasalRate(), iobArray, glucoseStatus, mealData, + determineBasalAdapterAMAJS.setData(profile, maxIob, maxBasal, minBg, maxBg, targetBg, ConfigBuilderPlugin.getPlugin().getActivePump().getBaseBasalRate(), iobArray, glucoseStatus, mealData, lastAutosensResult.ratio, //autosensDataRatio isTempTarget ); @@ -192,25 +198,15 @@ public class OpenAPSAMAPlugin extends PluginBase implements APSInterface { DetermineBasalResultAMA determineBasalResultAMA = determineBasalAdapterAMAJS.invoke(); - Profiler.log(log, "AMA calculation", start); + if (L.isEnabled(L.APS)) + Profiler.log(log, "AMA calculation", start); // Fix bug determine basal if (determineBasalResultAMA.rate == 0d && determineBasalResultAMA.duration == 0 && !TreatmentsPlugin.getPlugin().isTempBasalInProgress()) determineBasalResultAMA.tempBasalRequested = false; - // limit requests on openloop mode - if (!MainApp.getConstraintChecker().isClosedLoopAllowed().value()) { - long now = System.currentTimeMillis(); - TemporaryBasal activeTemp = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(now); - if (activeTemp != null && determineBasalResultAMA.rate == 0 && determineBasalResultAMA.duration == 0) { - // going to cancel - } else if (activeTemp != null && Math.abs(determineBasalResultAMA.rate - activeTemp.tempBasalConvertedToAbsolute(now, profile)) < 0.1) { - determineBasalResultAMA.tempBasalRequested = false; - } else if (activeTemp == null && Math.abs(determineBasalResultAMA.rate - ConfigBuilderPlugin.getActivePump().getBaseBasalRate()) < 0.1) - determineBasalResultAMA.tempBasalRequested = false; - } determineBasalResultAMA.iob = iobArray[0]; - Date now = new Date(); + long now = System.currentTimeMillis(); try { determineBasalResultAMA.json.put("timestamp", DateUtil.toISOString(now)); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/DetermineBasalAdapterMAJS.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/DetermineBasalAdapterMAJS.java index 6275154450..1574665dc4 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/DetermineBasalAdapterMAJS.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/DetermineBasalAdapterMAJS.java @@ -2,7 +2,6 @@ package info.nightscout.androidaps.plugins.OpenAPSMA; import org.json.JSONException; import org.json.JSONObject; -import org.mozilla.javascript.Callable; import org.mozilla.javascript.Context; import org.mozilla.javascript.Function; import org.mozilla.javascript.NativeJSON; @@ -16,7 +15,6 @@ import org.slf4j.LoggerFactory; import java.io.IOException; import java.lang.reflect.InvocationTargetException; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.GlucoseStatus; @@ -24,14 +22,15 @@ import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.MealData; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.db.TemporaryBasal; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.Loop.ScriptReader; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.utils.SP; public class DetermineBasalAdapterMAJS { - private static Logger log = LoggerFactory.getLogger(DetermineBasalAdapterMAJS.class); + private static Logger log = LoggerFactory.getLogger(L.APS); - private ScriptReader mScriptReader = null; + private ScriptReader mScriptReader; private JSONObject mProfile; private JSONObject mGlucoseStatus; private JSONObject mIobData; @@ -39,12 +38,12 @@ public class DetermineBasalAdapterMAJS { private JSONObject mCurrentTemp; private String storedCurrentTemp = null; - public String storedIobData = null; + private String storedIobData = null; private String storedGlucoseStatus = null; private String storedProfile = null; private String storedMeal_data = null; - public DetermineBasalAdapterMAJS(ScriptReader scriptReader) throws IOException { + DetermineBasalAdapterMAJS(ScriptReader scriptReader) { mScriptReader = scriptReader; } @@ -97,7 +96,7 @@ public class DetermineBasalAdapterMAJS { // Parse the jsResult object to a JSON-String String result = NativeJSON.stringify(rhino, scope, jsResult, null, null).toString(); - if (Config.logAPSResult) + if (L.isEnabled(L.APS)) log.debug("Result: " + result); try { determineBasalResultMA = new DetermineBasalResultMA(jsResult, new JSONObject(result)); @@ -108,14 +107,10 @@ public class DetermineBasalAdapterMAJS { log.debug("Problem loading JS Functions"); } } catch (IOException e) { - log.debug("IOException"); + log.error("IOException"); } catch (RhinoException e) { log.error("RhinoException: (" + e.lineNumber() + "," + e.columnNumber() + ") " + e.toString()); - } catch (IllegalAccessException e) { - log.error(e.toString()); - } catch (InstantiationException e) { - log.error(e.toString()); - } catch (InvocationTargetException e) { + } catch (IllegalAccessException | InstantiationException | InvocationTargetException e) { log.error(e.toString()); } finally { Context.exit(); @@ -210,7 +205,7 @@ public class DetermineBasalAdapterMAJS { mMealData.put("boluses", mealData.boluses); } - public String readFile(String filename) throws IOException { + private String readFile(String filename) throws IOException { byte[] bytes = mScriptReader.readFile(filename); String string = new String(bytes, "UTF-8"); if (string.startsWith("#!/usr/bin/env node")) { @@ -219,13 +214,8 @@ public class DetermineBasalAdapterMAJS { return string; } - public Object makeParam(JSONObject jsonObject, Context rhino, Scriptable scope) { - Object param = NativeJSON.parse(rhino, scope, jsonObject.toString(), new Callable() { - @Override - public Object call(Context context, Scriptable scriptable, Scriptable scriptable1, Object[] objects) { - return objects[1]; - } - }); + private Object makeParam(JSONObject jsonObject, Context rhino, Scriptable scope) { + Object param = NativeJSON.parse(rhino, scope, jsonObject.toString(), (context, scriptable, scriptable1, objects) -> objects[1]); return param; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/DetermineBasalResultMA.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/DetermineBasalResultMA.java index 75928f09d0..d3e1869f87 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/DetermineBasalResultMA.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/DetermineBasalResultMA.java @@ -6,17 +6,17 @@ import org.mozilla.javascript.NativeObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.Loop.APSResult; public class DetermineBasalResultMA extends APSResult { - private static Logger log = LoggerFactory.getLogger(DetermineBasalResultMA.class); + private static Logger log = LoggerFactory.getLogger(L.APS); - public JSONObject json = new JSONObject(); - public double eventualBG; - public double snoozeBG; - public String mealAssist; + private double eventualBG; + private double snoozeBG; + private String mealAssist; - public DetermineBasalResultMA(NativeObject result, JSONObject j) { + DetermineBasalResultMA(NativeObject result, JSONObject j) { json = j; if (result.containsKey("error")) { reason = (String) result.get("error"); @@ -49,25 +49,14 @@ public class DetermineBasalResultMA extends APSResult { } } - public DetermineBasalResultMA() { + private DetermineBasalResultMA() { } @Override public DetermineBasalResultMA clone() { DetermineBasalResultMA newResult = new DetermineBasalResultMA(); - newResult.reason = new String(reason); - newResult.rate = rate; - newResult.duration = duration; - newResult.tempBasalRequested = isChangeRequested(); - newResult.rate = rate; - newResult.duration = duration; - newResult.tempBasalRequested = isChangeRequested(); + doClone(newResult); - try { - newResult.json = new JSONObject(json.toString()); - } catch (JSONException e) { - log.error("Unhandled exception", e); - } newResult.eventualBG = eventualBG; newResult.snoozeBG = snoozeBG; newResult.mealAssist = mealAssist; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/LoggerCallback.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/LoggerCallback.java index 991ec2b25e..8907166951 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/LoggerCallback.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/LoggerCallback.java @@ -4,8 +4,7 @@ import org.mozilla.javascript.ScriptableObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.MainApp; -import info.nightscout.utils.ToastUtils; +import info.nightscout.androidaps.logging.L; /** * Created by adrian on 15/10/17. @@ -14,10 +13,10 @@ import info.nightscout.utils.ToastUtils; public class LoggerCallback extends ScriptableObject { - private static Logger log = LoggerFactory.getLogger(DetermineBasalAdapterMAJS.class); + private static Logger log = LoggerFactory.getLogger(L.APS); - static StringBuffer errorBuffer = new StringBuffer(); - static StringBuffer logBuffer = new StringBuffer(); + private static StringBuffer errorBuffer = new StringBuffer(); + private static StringBuffer logBuffer = new StringBuffer(); public LoggerCallback() { @@ -36,26 +35,27 @@ public class LoggerCallback extends ScriptableObject { } public void jsFunction_log(Object obj1) { - log.debug(obj1.toString()); + if (L.isEnabled(L.APS)) + log.debug(obj1.toString()); logBuffer.append(obj1.toString()); logBuffer.append(' '); } public void jsFunction_error(Object obj1) { - log.error(obj1.toString()); + if (L.isEnabled(L.APS)) + log.error(obj1.toString()); errorBuffer.append(obj1.toString()); errorBuffer.append(' '); } - - public static String getScriptDebug(){ + public static String getScriptDebug() { String ret = ""; - if(errorBuffer.length() > 0){ + if (errorBuffer.length() > 0) { ret += "e:\n" + errorBuffer.toString(); } - if(ret.length() > 0 && logBuffer.length() > 0) ret += '\n'; - if(logBuffer.length() > 0){ + if (ret.length() > 0 && logBuffer.length() > 0) ret += '\n'; + if (logBuffer.length() > 0) { ret += "d:\n" + logBuffer.toString(); } return ret; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/OpenAPSMAFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/OpenAPSMAFragment.java index 7360bb8b2a..12d7988a16 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/OpenAPSMAFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/OpenAPSMAFragment.java @@ -2,7 +2,6 @@ package info.nightscout.androidaps.plugins.OpenAPSMA; import android.app.Activity; import android.os.Bundle; -import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -12,20 +11,15 @@ import android.widget.TextView; import com.crashlytics.android.answers.CustomEvent; import com.squareup.otto.Subscribe; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateGui; import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateResultGui; +import info.nightscout.utils.DateUtil; import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.JSONFormatter; public class OpenAPSMAFragment extends SubscriberFragment implements View.OnClickListener { - private static Logger log = LoggerFactory.getLogger(OpenAPSMAFragment.class); - Button run; TextView lastRunView; TextView glucoseStatusView; @@ -87,25 +81,22 @@ public class OpenAPSMAFragment extends SubscriberFragment implements View.OnClic protected void updateGUI() { Activity activity = getActivity(); if (activity != null) - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - DetermineBasalResultMA lastAPSResult = OpenAPSMAPlugin.getPlugin().lastAPSResult; - if (lastAPSResult != null) { - resultView.setText(JSONFormatter.format(lastAPSResult.json)); - requestView.setText(lastAPSResult.toSpanned()); - } - DetermineBasalAdapterMAJS determineBasalAdapterMAJS = OpenAPSMAPlugin.getPlugin().lastDetermineBasalAdapterMAJS; - if (determineBasalAdapterMAJS != null) { - glucoseStatusView.setText(JSONFormatter.format(determineBasalAdapterMAJS.getGlucoseStatusParam())); - currentTempView.setText(JSONFormatter.format(determineBasalAdapterMAJS.getCurrentTempParam())); - iobDataView.setText(JSONFormatter.format(determineBasalAdapterMAJS.getIobDataParam())); - profileView.setText(JSONFormatter.format(determineBasalAdapterMAJS.getProfileParam())); - mealDataView.setText(JSONFormatter.format(determineBasalAdapterMAJS.getMealDataParam())); - } - if (OpenAPSMAPlugin.getPlugin().lastAPSRun != null) { - lastRunView.setText(OpenAPSMAPlugin.getPlugin().lastAPSRun.toLocaleString()); - } + activity.runOnUiThread(() -> { + DetermineBasalResultMA lastAPSResult = OpenAPSMAPlugin.getPlugin().lastAPSResult; + if (lastAPSResult != null) { + resultView.setText(JSONFormatter.format(lastAPSResult.json)); + requestView.setText(lastAPSResult.toSpanned()); + } + DetermineBasalAdapterMAJS determineBasalAdapterMAJS = OpenAPSMAPlugin.getPlugin().lastDetermineBasalAdapterMAJS; + if (determineBasalAdapterMAJS != null) { + glucoseStatusView.setText(JSONFormatter.format(determineBasalAdapterMAJS.getGlucoseStatusParam())); + currentTempView.setText(JSONFormatter.format(determineBasalAdapterMAJS.getCurrentTempParam())); + iobDataView.setText(JSONFormatter.format(determineBasalAdapterMAJS.getIobDataParam())); + profileView.setText(JSONFormatter.format(determineBasalAdapterMAJS.getProfileParam())); + mealDataView.setText(JSONFormatter.format(determineBasalAdapterMAJS.getMealDataParam())); + } + if (OpenAPSMAPlugin.getPlugin().lastAPSRun != 0) { + lastRunView.setText(DateUtil.dateAndTimeFullString(OpenAPSMAPlugin.getPlugin().lastAPSRun)); } }); } @@ -113,18 +104,15 @@ public class OpenAPSMAFragment extends SubscriberFragment implements View.OnClic private void updateResultGUI(final String text) { Activity activity = getActivity(); if (activity != null) - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - resultView.setText(text); - glucoseStatusView.setText(""); - currentTempView.setText(""); - iobDataView.setText(""); - profileView.setText(""); - mealDataView.setText(""); - requestView.setText(""); - lastRunView.setText(""); - } + activity.runOnUiThread(() -> { + resultView.setText(text); + glucoseStatusView.setText(""); + currentTempView.setText(""); + iobDataView.setText(""); + profileView.setText(""); + mealDataView.setText(""); + requestView.setText(""); + lastRunView.setText(""); }); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/OpenAPSMAPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/OpenAPSMAPlugin.java index 14dac65625..5b59252ea1 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/OpenAPSMAPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/OpenAPSMAPlugin.java @@ -4,10 +4,6 @@ import org.json.JSONException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; -import java.util.Date; - -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.GlucoseStatus; @@ -21,7 +17,9 @@ import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.Loop.APSResult; import info.nightscout.androidaps.plugins.Loop.ScriptReader; import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateGui; @@ -39,7 +37,7 @@ import static info.nightscout.utils.HardLimits.verifyHardLimits; * Created by mike on 05.08.2016. */ public class OpenAPSMAPlugin extends PluginBase implements APSInterface { - private static Logger log = LoggerFactory.getLogger(OpenAPSMAPlugin.class); + private static Logger log = LoggerFactory.getLogger(L.APS); private static OpenAPSMAPlugin openAPSMAPlugin; @@ -52,28 +50,29 @@ public class OpenAPSMAPlugin extends PluginBase implements APSInterface { // last values DetermineBasalAdapterMAJS lastDetermineBasalAdapterMAJS = null; - Date lastAPSRun = null; + long lastAPSRun = 0; DetermineBasalResultMA lastAPSResult = null; - public OpenAPSMAPlugin() { + private OpenAPSMAPlugin() { super(new PluginDescription() .mainType(PluginType.APS) .fragmentClass(OpenAPSMAFragment.class.getName()) .pluginName(R.string.openapsma) .shortName(R.string.oaps_shortname) .preferencesId(R.xml.pref_openapsma) + .description(R.string.description_ma) ); } @Override public boolean specialEnableCondition() { - PumpInterface pump = ConfigBuilderPlugin.getActivePump(); + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); return pump == null || pump.getPumpDescription().isTempBasalCapable; } @Override public boolean specialShowInListCondition() { - PumpInterface pump = ConfigBuilderPlugin.getActivePump(); + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); return pump == null || pump.getPumpDescription().isTempBasalCapable; } @@ -83,43 +82,39 @@ public class OpenAPSMAPlugin extends PluginBase implements APSInterface { } @Override - public Date getLastAPSRun() { + public long getLastAPSRun() { return lastAPSRun; } @Override public void invoke(String initiator, boolean tempBasalFallback) { - log.debug("invoke from " + initiator + " tempBasalFallback: " + tempBasalFallback); + if (L.isEnabled(L.APS)) + log.debug("invoke from " + initiator + " tempBasalFallback: " + tempBasalFallback); lastAPSResult = null; - DetermineBasalAdapterMAJS determineBasalAdapterMAJS = null; - try { - determineBasalAdapterMAJS = new DetermineBasalAdapterMAJS(new ScriptReader(MainApp.instance().getBaseContext())); - } catch (IOException e) { - log.error(e.getMessage(), e); - return; - } + DetermineBasalAdapterMAJS determineBasalAdapterMAJS; + determineBasalAdapterMAJS = new DetermineBasalAdapterMAJS(new ScriptReader(MainApp.instance().getBaseContext())); GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData(); - Profile profile = MainApp.getConfigBuilder().getProfile(); - PumpInterface pump = ConfigBuilderPlugin.getActivePump(); + Profile profile = ProfileFunctions.getInstance().getProfile(); + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); if (profile == null) { MainApp.bus().post(new EventOpenAPSUpdateResultGui(MainApp.gs(R.string.noprofileselected))); - if (Config.logAPSResult) + if (L.isEnabled(L.APS)) log.debug(MainApp.gs(R.string.noprofileselected)); return; } if (!isEnabled(PluginType.APS)) { MainApp.bus().post(new EventOpenAPSUpdateResultGui(MainApp.gs(R.string.openapsma_disabled))); - if (Config.logAPSResult) + if (L.isEnabled(L.APS)) log.debug(MainApp.gs(R.string.openapsma_disabled)); return; } if (glucoseStatus == null) { MainApp.bus().post(new EventOpenAPSUpdateResultGui(MainApp.gs(R.string.openapsma_noglucosedata))); - if (Config.logAPSResult) + if (L.isEnabled(L.APS)) log.debug(MainApp.gs(R.string.openapsma_noglucosedata)); return; } @@ -135,7 +130,7 @@ public class OpenAPSMAPlugin extends PluginBase implements APSInterface { minBg = Round.roundTo(minBg, 0.1d); maxBg = Round.roundTo(maxBg, 0.1d); - Date start = new Date(); + long start = System.currentTimeMillis(); TreatmentsPlugin.getPlugin().updateTotalIOBTreatments(); TreatmentsPlugin.getPlugin().updateTotalIOBTempBasals(); IobTotal bolusIob = TreatmentsPlugin.getPlugin().getLastCalculationTreatments(); @@ -146,7 +141,8 @@ public class OpenAPSMAPlugin extends PluginBase implements APSInterface { MealData mealData = TreatmentsPlugin.getPlugin().getMealData(); double maxIob = MainApp.getConstraintChecker().getMaxIOBAllowed().value(); - Profiler.log(log, "MA data gathering", start); + if (L.isEnabled(L.APS)) + Profiler.log(log, "MA data gathering", start); minBg = verifyHardLimits(minBg, "minBg", HardLimits.VERY_HARD_LIMIT_MIN_BG[0], HardLimits.VERY_HARD_LIMIT_MIN_BG[1]); maxBg = verifyHardLimits(maxBg, "maxBg", HardLimits.VERY_HARD_LIMIT_MAX_BG[0], HardLimits.VERY_HARD_LIMIT_MAX_BG[1]); @@ -161,7 +157,7 @@ public class OpenAPSMAPlugin extends PluginBase implements APSInterface { if (!checkOnlyHardLimits(profile.getDia(), "dia", HardLimits.MINDIA, HardLimits.MAXDIA)) return; - if (!checkOnlyHardLimits(profile.getIcTimeFromMidnight(profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC)) + if (!checkOnlyHardLimits(profile.getIcTimeFromMidnight(Profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC)) return; if (!checkOnlyHardLimits(Profile.toMgdl(profile.getIsf(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF)) return; @@ -170,13 +166,14 @@ public class OpenAPSMAPlugin extends PluginBase implements APSInterface { if (!checkOnlyHardLimits(pump.getBaseBasalRate(), "current_basal", 0.01, HardLimits.maxBasal())) return; - start = new Date(); + start = System.currentTimeMillis(); try { - determineBasalAdapterMAJS.setData(profile, maxIob, maxBasal, minBg, maxBg, targetBg, ConfigBuilderPlugin.getActivePump().getBaseBasalRate(), iobTotal, glucoseStatus, mealData); + determineBasalAdapterMAJS.setData(profile, maxIob, maxBasal, minBg, maxBg, targetBg, ConfigBuilderPlugin.getPlugin().getActivePump().getBaseBasalRate(), iobTotal, glucoseStatus, mealData); } catch (JSONException e) { log.error("Unhandled exception", e); } - Profiler.log(log, "MA calculation", start); + if (L.isEnabled(L.APS)) + Profiler.log(log, "MA calculation", start); long now = System.currentTimeMillis(); @@ -185,16 +182,6 @@ public class OpenAPSMAPlugin extends PluginBase implements APSInterface { // Fix bug determinef basal if (determineBasalResultMA.rate == 0d && determineBasalResultMA.duration == 0 && !TreatmentsPlugin.getPlugin().isTempBasalInProgress()) determineBasalResultMA.tempBasalRequested = false; - // limit requests on openloop mode - if (!MainApp.getConstraintChecker().isClosedLoopAllowed().value()) { - TemporaryBasal activeTemp = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(now); - if (activeTemp != null && determineBasalResultMA.rate == 0 && determineBasalResultMA.duration == 0) { - // going to cancel - } else if (activeTemp != null && Math.abs(determineBasalResultMA.rate - activeTemp.tempBasalConvertedToAbsolute(now, profile)) < 0.1) { - determineBasalResultMA.tempBasalRequested = false; - } else if (activeTemp == null && Math.abs(determineBasalResultMA.rate - ConfigBuilderPlugin.getActivePump().getBaseBasalRate()) < 0.1) - determineBasalResultMA.tempBasalRequested = false; - } determineBasalResultMA.iob = iobTotal; @@ -206,7 +193,7 @@ public class OpenAPSMAPlugin extends PluginBase implements APSInterface { lastDetermineBasalAdapterMAJS = determineBasalAdapterMAJS; lastAPSResult = determineBasalResultMA; - lastAPSRun = new Date(now); + lastAPSRun = now; MainApp.bus().post(new EventOpenAPSUpdateGui()); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/events/EventOpenAPSUpdateResultGui.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/events/EventOpenAPSUpdateResultGui.java index e65cdd2c57..177133f155 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/events/EventOpenAPSUpdateResultGui.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/events/EventOpenAPSUpdateResultGui.java @@ -6,7 +6,7 @@ import info.nightscout.androidaps.events.EventUpdateGui; * Created by mike on 05.08.2016. */ public class EventOpenAPSUpdateResultGui extends EventUpdateGui { - public String text = null; + public String text; public EventOpenAPSUpdateResultGui(String text) { this.text = text; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/DetermineBasalAdapterSMBJS.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/DetermineBasalAdapterSMBJS.java index 396338efa4..bdd06372d9 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/DetermineBasalAdapterSMBJS.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/DetermineBasalAdapterSMBJS.java @@ -3,7 +3,6 @@ package info.nightscout.androidaps.plugins.OpenAPSSMB; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; -import org.mozilla.javascript.Callable; import org.mozilla.javascript.Context; import org.mozilla.javascript.Function; import org.mozilla.javascript.NativeJSON; @@ -18,7 +17,6 @@ import org.slf4j.LoggerFactory; import java.io.IOException; import java.lang.reflect.InvocationTargetException; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; @@ -27,6 +25,7 @@ import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.MealData; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.db.TemporaryBasal; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin; import info.nightscout.androidaps.plugins.Loop.ScriptReader; import info.nightscout.androidaps.plugins.OpenAPSMA.LoggerCallback; @@ -35,10 +34,10 @@ import info.nightscout.utils.SP; import info.nightscout.utils.SafeParse; public class DetermineBasalAdapterSMBJS { - private static Logger log = LoggerFactory.getLogger(DetermineBasalAdapterSMBJS.class); + private static Logger log = LoggerFactory.getLogger(L.APS); - private ScriptReader mScriptReader = null; + private ScriptReader mScriptReader; private JSONObject mProfile; private JSONObject mGlucoseStatus; private JSONArray mIobData; @@ -64,7 +63,7 @@ public class DetermineBasalAdapterSMBJS { * Main code */ - public DetermineBasalAdapterSMBJS(ScriptReader scriptReader) throws IOException { + DetermineBasalAdapterSMBJS(ScriptReader scriptReader) { mScriptReader = scriptReader; } @@ -72,19 +71,21 @@ public class DetermineBasalAdapterSMBJS { public DetermineBasalResultSMB invoke() { - log.debug(">>> Invoking detemine_basal <<<"); - log.debug("Glucose status: " + (storedGlucoseStatus = mGlucoseStatus.toString())); - log.debug("IOB data: " + (storedIobData = mIobData.toString())); - log.debug("Current temp: " + (storedCurrentTemp = mCurrentTemp.toString())); - log.debug("Profile: " + (storedProfile = mProfile.toString())); - log.debug("Meal data: " + (storedMeal_data = mMealData.toString())); - if (mAutosensData != null) - log.debug("Autosens data: " + (storedAutosens_data = mAutosensData.toString())); - else - log.debug("Autosens data: " + (storedAutosens_data = "undefined")); - log.debug("Reservoir data: " + "undefined"); - log.debug("MicroBolusAllowed: " + (storedMicroBolusAllowed = "" + mMicrobolusAllowed)); - log.debug("SMBAlwaysAllowed: " + (storedSMBAlwaysAllowed = "" + mSMBAlwaysAllowed)); + if (L.isEnabled(L.APS)) { + log.debug(">>> Invoking detemine_basal <<<"); + log.debug("Glucose status: " + (storedGlucoseStatus = mGlucoseStatus.toString())); + log.debug("IOB data: " + (storedIobData = mIobData.toString())); + log.debug("Current temp: " + (storedCurrentTemp = mCurrentTemp.toString())); + log.debug("Profile: " + (storedProfile = mProfile.toString())); + log.debug("Meal data: " + (storedMeal_data = mMealData.toString())); + if (mAutosensData != null) + log.debug("Autosens data: " + (storedAutosens_data = mAutosensData.toString())); + else + log.debug("Autosens data: " + (storedAutosens_data = "undefined")); + log.debug("Reservoir data: " + "undefined"); + log.debug("MicroBolusAllowed: " + (storedMicroBolusAllowed = "" + mMicrobolusAllowed)); + log.debug("SMBAlwaysAllowed: " + (storedSMBAlwaysAllowed = "" + mSMBAlwaysAllowed)); + } DetermineBasalResultSMB determineBasalResultSMB = null; @@ -135,7 +136,7 @@ public class DetermineBasalAdapterSMBJS { // Parse the jsResult object to a JSON-String String result = NativeJSON.stringify(rhino, scope, jsResult, null, null).toString(); - if (Config.logAPSResult) + if (L.isEnabled(L.APS)) log.debug("Result: " + result); try { determineBasalResultSMB = new DetermineBasalResultSMB(new JSONObject(result)); @@ -143,17 +144,13 @@ public class DetermineBasalAdapterSMBJS { log.error("Unhandled exception", e); } } else { - log.debug("Problem loading JS Functions"); + log.error("Problem loading JS Functions"); } } catch (IOException e) { - log.debug("IOException"); + log.error("IOException"); } catch (RhinoException e) { log.error("RhinoException: (" + e.lineNumber() + "," + e.columnNumber() + ") " + e.toString()); - } catch (IllegalAccessException e) { - log.error(e.toString()); - } catch (InstantiationException e) { - log.error(e.toString()); - } catch (InvocationTargetException e) { + } catch (IllegalAccessException | InstantiationException | InvocationTargetException e) { log.error(e.toString()); } finally { Context.exit(); @@ -214,6 +211,7 @@ public class DetermineBasalAdapterSMBJS { double autosensDataRatio, boolean tempTargetSet, boolean microBolusAllowed, + boolean uamAllowed, boolean advancedFiltering ) throws JSONException { @@ -234,8 +232,8 @@ public class DetermineBasalAdapterSMBJS { mProfile.put("max_daily_safety_multiplier", SP.getInt(R.string.key_openapsama_max_daily_safety_multiplier, 3)); mProfile.put("current_basal_safety_multiplier", SP.getDouble(R.string.key_openapsama_current_basal_safety_multiplier, 4d)); - mProfile.put("high_temptarget_raises_sensitivity", SMBDefaults.high_temptarget_raises_sensitivity); - mProfile.put("low_temptarget_lowers_sensitivity", SMBDefaults.low_temptarget_lowers_sensitivity); + mProfile.put("high_temptarget_raises_sensitivity", SP.getBoolean(R.string.key_high_temptarget_raises_sensitivity, SMBDefaults.high_temptarget_raises_sensitivity)); + mProfile.put("low_temptarget_lowers_sensitivity", SP.getBoolean(R.string.key_low_temptarget_lowers_sensitivity, SMBDefaults.low_temptarget_lowers_sensitivity)); mProfile.put("sensitivity_raises_target", SMBDefaults.sensitivity_raises_target); mProfile.put("resistance_lowers_target", SMBDefaults.resistance_lowers_target); mProfile.put("adv_target_adjustments", SMBDefaults.adv_target_adjustments); @@ -243,14 +241,14 @@ public class DetermineBasalAdapterSMBJS { mProfile.put("half_basal_exercise_target", SMBDefaults.half_basal_exercise_target); mProfile.put("maxCOB", SMBDefaults.maxCOB); mProfile.put("skip_neutral_temps", SMBDefaults.skip_neutral_temps); - //align with max-absorption model in AMA sensitivity - if(mealData.usedMinCarbsImpact > 0){ - mProfile.put("min_5m_carbimpact", mealData.usedMinCarbsImpact); - } else { - mProfile.put("min_5m_carbimpact", SP.getDouble(R.string.key_openapsama_min_5m_carbimpact, SMBDefaults.min_5m_carbimpact)); - } + // min_5m_carbimpact is not used within SMB determinebasal + //if (mealData.usedMinCarbsImpact > 0) { + // mProfile.put("min_5m_carbimpact", mealData.usedMinCarbsImpact); + //} else { + // mProfile.put("min_5m_carbimpact", SP.getDouble(R.string.key_openapsama_min_5m_carbimpact, SMBDefaults.min_5m_carbimpact)); + //} mProfile.put("remainingCarbsCap", SMBDefaults.remainingCarbsCap); - mProfile.put("enableUAM", SP.getBoolean(R.string.key_use_uam, false)); + mProfile.put("enableUAM", uamAllowed); mProfile.put("A52_risk_enable", SMBDefaults.A52_risk_enable); mProfile.put("enableSMB_with_COB", SP.getBoolean(R.string.key_enableSMB_with_COB, false)); mProfile.put("enableSMB_with_temptarget", SP.getBoolean(R.string.key_enableSMB_with_temptarget, false)); @@ -319,31 +317,21 @@ public class DetermineBasalAdapterSMBJS { } - public Object makeParam(JSONObject jsonObject, Context rhino, Scriptable scope) { + private Object makeParam(JSONObject jsonObject, Context rhino, Scriptable scope) { if (jsonObject == null) return Undefined.instance; - Object param = NativeJSON.parse(rhino, scope, jsonObject.toString(), new Callable() { - @Override - public Object call(Context context, Scriptable scriptable, Scriptable scriptable1, Object[] objects) { - return objects[1]; - } - }); + Object param = NativeJSON.parse(rhino, scope, jsonObject.toString(), (context, scriptable, scriptable1, objects) -> objects[1]); return param; } - public Object makeParamArray(JSONArray jsonArray, Context rhino, Scriptable scope) { + private Object makeParamArray(JSONArray jsonArray, Context rhino, Scriptable scope) { //Object param = NativeJSON.parse(rhino, scope, "{myarray: " + jsonArray.toString() + " }", new Callable() { - Object param = NativeJSON.parse(rhino, scope, jsonArray.toString(), new Callable() { - @Override - public Object call(Context context, Scriptable scriptable, Scriptable scriptable1, Object[] objects) { - return objects[1]; - } - }); + Object param = NativeJSON.parse(rhino, scope, jsonArray.toString(), (context, scriptable, scriptable1, objects) -> objects[1]); return param; } - public String readFile(String filename) throws IOException { + private String readFile(String filename) throws IOException { byte[] bytes = mScriptReader.readFile(filename); String string = new String(bytes, "UTF-8"); if (string.startsWith("#!/usr/bin/env node")) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/DetermineBasalResultSMB.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/DetermineBasalResultSMB.java index 59c1dd95e3..364731bea5 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/DetermineBasalResultSMB.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/DetermineBasalResultSMB.java @@ -5,22 +5,19 @@ import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Date; - +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.Loop.APSResult; import info.nightscout.utils.DateUtil; public class DetermineBasalResultSMB extends APSResult { - private static final Logger log = LoggerFactory.getLogger(DetermineBasalResultSMB.class); + private static final Logger log = LoggerFactory.getLogger(L.APS); - public double eventualBG; - public double snoozeBG; - public double insulinReq; - public double carbsReq; + private double eventualBG; + private double snoozeBG; - public DetermineBasalResultSMB(JSONObject result) { + DetermineBasalResultSMB(JSONObject result) { this(); - date = new Date(); + date = DateUtil.now(); json = result; try { if (result.has("error")) { @@ -31,8 +28,8 @@ public class DetermineBasalResultSMB extends APSResult { reason = result.getString("reason"); if (result.has("eventualBG")) eventualBG = result.getDouble("eventualBG"); if (result.has("snoozeBG")) snoozeBG = result.getDouble("snoozeBG"); - if (result.has("insulinReq")) insulinReq = result.getDouble("insulinReq"); - if (result.has("carbsReq")) carbsReq = result.getDouble("carbsReq"); + //if (result.has("insulinReq")) insulinReq = result.getDouble("insulinReq"); + //if (result.has("carbsReq")) carbsReq = result.getDouble("carbsReq"); if (result.has("rate") && result.has("duration")) { tempBasalRequested = true; @@ -64,31 +61,17 @@ public class DetermineBasalResultSMB extends APSResult { } } - public DetermineBasalResultSMB() { + private DetermineBasalResultSMB() { hasPredictions = true; } @Override public DetermineBasalResultSMB clone() { DetermineBasalResultSMB newResult = new DetermineBasalResultSMB(); - newResult.reason = reason; - newResult.rate = rate; - newResult.duration = duration; - newResult.tempBasalRequested = tempBasalRequested; - newResult.bolusRequested = bolusRequested; - newResult.rate = rate; - newResult.duration = duration; - newResult.smb = smb; - newResult.deliverAt = deliverAt; + doClone(newResult); - try { - newResult.json = new JSONObject(json.toString()); - } catch (JSONException e) { - log.error("Error clone parsing determine-basal result", e); - } newResult.eventualBG = eventualBG; newResult.snoozeBG = snoozeBG; - newResult.date = date; return newResult; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/OpenAPSSMBFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/OpenAPSSMBFragment.java index 724bfcf86c..d27f8b31d0 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/OpenAPSSMBFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/OpenAPSSMBFragment.java @@ -21,14 +21,16 @@ import butterknife.ButterKnife; import butterknife.OnClick; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateGui; import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateResultGui; +import info.nightscout.utils.DateUtil; import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.JSONFormatter; public class OpenAPSSMBFragment extends SubscriberFragment { - private static Logger log = LoggerFactory.getLogger(OpenAPSSMBFragment.class); + private static Logger log = LoggerFactory.getLogger(L.APS); @BindView(R.id.openapsma_run) Button run; @@ -84,9 +86,9 @@ public class OpenAPSSMBFragment extends SubscriberFragment { protected void updateGUI() { Activity activity = getActivity(); if (activity != null) - activity.runOnUiThread(new Runnable() { - @Override - public void run() { + activity.runOnUiThread(() -> { + synchronized (OpenAPSSMBFragment.this) { + if (!isBound()) return; OpenAPSSMBPlugin plugin = OpenAPSSMBPlugin.getPlugin(); DetermineBasalResultSMB lastAPSResult = plugin.lastAPSResult; if (lastAPSResult != null) { @@ -110,8 +112,8 @@ public class OpenAPSSMBFragment extends SubscriberFragment { if (lastAPSResult != null && lastAPSResult.inputConstraints != null) constraintsView.setText(lastAPSResult.inputConstraints.getReasons().trim()); } - if (plugin.lastAPSRun != null) { - lastRunView.setText(plugin.lastAPSRun.toLocaleString().trim()); + if (plugin.lastAPSRun != 0) { + lastRunView.setText(DateUtil.dateAndTimeFullString(plugin.lastAPSRun)); } if (plugin.lastAutosensResult != null) { autosensDataView.setText(JSONFormatter.format(plugin.lastAutosensResult.json()).toString().trim()); @@ -123,20 +125,36 @@ public class OpenAPSSMBFragment extends SubscriberFragment { void updateResultGUI(final String text) { Activity activity = getActivity(); if (activity != null) - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - resultView.setText(text); - glucoseStatusView.setText(""); - currentTempView.setText(""); - iobDataView.setText(""); - profileView.setText(""); - mealDataView.setText(""); - autosensDataView.setText(""); - scriptdebugView.setText(""); - requestView.setText(""); - lastRunView.setText(""); + activity.runOnUiThread(() -> { + synchronized (OpenAPSSMBFragment.this) { + if (isBound()) { + resultView.setText(text); + glucoseStatusView.setText(""); + currentTempView.setText(""); + iobDataView.setText(""); + profileView.setText(""); + mealDataView.setText(""); + autosensDataView.setText(""); + scriptdebugView.setText(""); + requestView.setText(""); + lastRunView.setText(""); + } } }); } + + private boolean isBound() { + return run != null + && lastRunView != null + && constraintsView != null + && glucoseStatusView != null + && currentTempView != null + && iobDataView != null + && profileView != null + && mealDataView != null + && autosensDataView != null + && resultView != null + && scriptdebugView != null + && requestView != null; + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/OpenAPSSMBPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/OpenAPSSMBPlugin.java index 49a81ea612..1d6b558c74 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/OpenAPSSMBPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/OpenAPSSMBPlugin.java @@ -4,10 +4,8 @@ import org.json.JSONException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; import java.util.Date; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.GlucoseStatus; @@ -22,17 +20,20 @@ import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; +import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensData; import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensResult; import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin; import info.nightscout.androidaps.plugins.Loop.APSResult; import info.nightscout.androidaps.plugins.Loop.ScriptReader; +import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateGui; import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateResultGui; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.utils.DateUtil; import info.nightscout.utils.HardLimits; -import info.nightscout.utils.NSUpload; import info.nightscout.utils.Profiler; import info.nightscout.utils.Round; import info.nightscout.utils.ToastUtils; @@ -41,7 +42,7 @@ import info.nightscout.utils.ToastUtils; * Created by mike on 05.08.2016. */ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface { - private static Logger log = LoggerFactory.getLogger(OpenAPSSMBPlugin.class); + private static Logger log = LoggerFactory.getLogger(L.APS); private static OpenAPSSMBPlugin openAPSSMBPlugin; @@ -54,7 +55,7 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface { // last values DetermineBasalAdapterSMBJS lastDetermineBasalAdapterSMBJS = null; - Date lastAPSRun = null; + long lastAPSRun = 0; DetermineBasalResultSMB lastAPSResult = null; AutosensResult lastAutosensResult = null; @@ -65,18 +66,19 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface { .pluginName(R.string.openapssmb) .shortName(R.string.smb_shortname) .preferencesId(R.xml.pref_openapssmb) + .description(R.string.description_smb) ); } @Override public boolean specialEnableCondition() { - PumpInterface pump = ConfigBuilderPlugin.getActivePump(); + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); return pump == null || pump.getPumpDescription().isTempBasalCapable; } @Override public boolean specialShowInListCondition() { - PumpInterface pump = ConfigBuilderPlugin.getActivePump(); + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); return pump == null || pump.getPumpDescription().isTempBasalCapable; } @@ -86,43 +88,39 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface { } @Override - public Date getLastAPSRun() { + public long getLastAPSRun() { return lastAPSRun; } @Override public void invoke(String initiator, boolean tempBasalFallback) { - log.debug("invoke from " + initiator + " tempBasalFallback: " + tempBasalFallback); + if (L.isEnabled(L.APS)) + log.debug("invoke from " + initiator + " tempBasalFallback: " + tempBasalFallback); lastAPSResult = null; - DetermineBasalAdapterSMBJS determineBasalAdapterSMBJS = null; - try { - determineBasalAdapterSMBJS = new DetermineBasalAdapterSMBJS(new ScriptReader(MainApp.instance().getBaseContext())); - } catch (IOException e) { - log.error(e.getMessage(), e); - return; - } + DetermineBasalAdapterSMBJS determineBasalAdapterSMBJS; + determineBasalAdapterSMBJS = new DetermineBasalAdapterSMBJS(new ScriptReader(MainApp.instance().getBaseContext())); GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData(); - Profile profile = MainApp.getConfigBuilder().getProfile(); - PumpInterface pump = ConfigBuilderPlugin.getActivePump(); + Profile profile = ProfileFunctions.getInstance().getProfile(); + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); if (profile == null) { MainApp.bus().post(new EventOpenAPSUpdateResultGui(MainApp.gs(R.string.noprofileselected))); - if (Config.logAPSResult) + if (L.isEnabled(L.APS)) log.debug(MainApp.gs(R.string.noprofileselected)); return; } if (!isEnabled(PluginType.APS)) { MainApp.bus().post(new EventOpenAPSUpdateResultGui(MainApp.gs(R.string.openapsma_disabled))); - if (Config.logAPSResult) + if (L.isEnabled(L.APS)) log.debug(MainApp.gs(R.string.openapsma_disabled)); return; } if (glucoseStatus == null) { MainApp.bus().post(new EventOpenAPSUpdateResultGui(MainApp.gs(R.string.openapsma_noglucosedata))); - if (Config.logAPSResult) + if (L.isEnabled(L.APS)) log.debug(MainApp.gs(R.string.openapsma_noglucosedata)); return; } @@ -141,14 +139,16 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface { minBg = Round.roundTo(minBg, 0.1d); maxBg = Round.roundTo(maxBg, 0.1d); - Date start = new Date(); - Date startPart = new Date(); + long start = System.currentTimeMillis(); + long startPart = System.currentTimeMillis(); IobTotal[] iobArray = IobCobCalculatorPlugin.getPlugin().calculateIobArrayForSMB(profile); - Profiler.log(log, "calculateIobArrayInDia()", startPart); + if (L.isEnabled(L.APS)) + Profiler.log(log, "calculateIobArrayInDia()", startPart); - startPart = new Date(); + startPart = System.currentTimeMillis(); MealData mealData = TreatmentsPlugin.getPlugin().getMealData(); - Profiler.log(log, "getMealData()", startPart); + if (L.isEnabled(L.APS)) + Profiler.log(log, "getMealData()", startPart); double maxIob = MainApp.getConstraintChecker().getMaxIOBAllowed().value(); @@ -168,7 +168,7 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface { if (!checkOnlyHardLimits(profile.getDia(), "dia", HardLimits.MINDIA, HardLimits.MAXDIA)) return; - if (!checkOnlyHardLimits(profile.getIcTimeFromMidnight(profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC)) + if (!checkOnlyHardLimits(profile.getIcTimeFromMidnight(Profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC)) return; if (!checkOnlyHardLimits(Profile.toMgdl(profile.getIsf(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF)) return; @@ -177,11 +177,17 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface { if (!checkOnlyHardLimits(pump.getBaseBasalRate(), "current_basal", 0.01, HardLimits.maxBasal())) return; - startPart = new Date(); + startPart = System.currentTimeMillis(); if (MainApp.getConstraintChecker().isAutosensModeEnabled().value()) { - lastAutosensResult = IobCobCalculatorPlugin.getPlugin().detectSensitivityWithLock(IobCobCalculatorPlugin.getPlugin().oldestDataAvailable(), System.currentTimeMillis()); + AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getLastAutosensDataSynchronized("OpenAPSPlugin"); + if (autosensData == null) { + MainApp.bus().post(new EventOpenAPSUpdateResultGui(MainApp.gs(R.string.openaps_noasdata))); + return; + } + lastAutosensResult = autosensData.autosensResult; } else { lastAutosensResult = new AutosensResult(); + lastAutosensResult.sensResult = "autosens disabled"; } Constraint smbAllowed = new Constraint<>(!tempBasalFallback); @@ -192,15 +198,22 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface { MainApp.getConstraintChecker().isAdvancedFilteringEnabled(advancedFiltering); inputConstraints.copyReasons(advancedFiltering); - Profiler.log(log, "detectSensitivityandCarbAbsorption()", startPart); - Profiler.log(log, "SMB data gathering", start); + Constraint uam = new Constraint<>(true); + MainApp.getConstraintChecker().isUAMEnabled(uam); + inputConstraints.copyReasons(uam); - start = new Date(); + if (L.isEnabled(L.APS)) + Profiler.log(log, "detectSensitivityandCarbAbsorption()", startPart); + if (L.isEnabled(L.APS)) + Profiler.log(log, "SMB data gathering", start); + + start = System.currentTimeMillis(); try { - determineBasalAdapterSMBJS.setData(profile, maxIob, maxBasal, minBg, maxBg, targetBg, ConfigBuilderPlugin.getActivePump().getBaseBasalRate(), iobArray, glucoseStatus, mealData, + determineBasalAdapterSMBJS.setData(profile, maxIob, maxBasal, minBg, maxBg, targetBg, ConfigBuilderPlugin.getPlugin().getActivePump().getBaseBasalRate(), iobArray, glucoseStatus, mealData, lastAutosensResult.ratio, //autosensDataRatio isTempTarget, smbAllowed.value(), + uam.value(), advancedFiltering.value() ); } catch (JSONException e) { @@ -211,21 +224,12 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface { long now = System.currentTimeMillis(); DetermineBasalResultSMB determineBasalResultSMB = determineBasalAdapterSMBJS.invoke(); - Profiler.log(log, "SMB calculation", start); + if (L.isEnabled(L.APS)) + Profiler.log(log, "SMB calculation", start); // TODO still needed with oref1? // Fix bug determine basal if (determineBasalResultSMB.rate == 0d && determineBasalResultSMB.duration == 0 && !TreatmentsPlugin.getPlugin().isTempBasalInProgress()) determineBasalResultSMB.tempBasalRequested = false; - // limit requests on openloop mode - if (!MainApp.getConstraintChecker().isClosedLoopAllowed().value()) { - TemporaryBasal activeTemp = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(now); - if (activeTemp != null && determineBasalResultSMB.rate == 0 && determineBasalResultSMB.duration == 0) { - // going to cancel - } else if (activeTemp != null && Math.abs(determineBasalResultSMB.rate - activeTemp.tempBasalConvertedToAbsolute(now, profile)) < 0.1) { - determineBasalResultSMB.tempBasalRequested = false; - } else if (activeTemp == null && Math.abs(determineBasalResultSMB.rate - ConfigBuilderPlugin.getActivePump().getBaseBasalRate()) < 0.1) - determineBasalResultSMB.tempBasalRequested = false; - } determineBasalResultSMB.iob = iobArray[0]; @@ -239,7 +243,7 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface { lastDetermineBasalAdapterSMBJS = determineBasalAdapterSMBJS; lastAPSResult = determineBasalResultSMB; - lastAPSRun = new Date(now); + lastAPSRun = now; MainApp.bus().post(new EventOpenAPSUpdateGui()); //deviceStatus.suggested = determineBasalResultAMA.json; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/BolusProgressDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/BolusProgressDialog.java index 9974471528..6ac7d13cfa 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/BolusProgressDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/BolusProgressDialog.java @@ -20,12 +20,13 @@ import org.slf4j.LoggerFactory; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.events.EventPumpStatusChanged; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.Overview.events.EventDismissBolusprogressIfRunning; import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress; public class BolusProgressDialog extends DialogFragment implements View.OnClickListener { - private static Logger log = LoggerFactory.getLogger(BolusProgressDialog.class); + private static Logger log = LoggerFactory.getLogger(L.UI); Button stopButton; TextView statusView; TextView stopPressedView; @@ -70,7 +71,9 @@ public class BolusProgressDialog extends DialogFragment implements View.OnClickL @Override public void onResume() { super.onResume(); - if(!ConfigBuilderPlugin.getCommandQueue().bolusInQueue()) { + if (L.isEnabled(L.UI)) + log.debug("onResume"); + if (!ConfigBuilderPlugin.getPlugin().getCommandQueue().bolusInQueue()) { bolusEnded = true; } if (bolusEnded) { @@ -80,17 +83,22 @@ public class BolusProgressDialog extends DialogFragment implements View.OnClickL getDialog().getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); MainApp.subscribe(this); running = true; + if (L.isEnabled(L.UI)) + log.debug("onResume running"); } } @Override public void dismiss() { + if (L.isEnabled(L.UI)) + log.debug("dismiss"); try { super.dismiss(); } catch (IllegalStateException e) { // dialog not running yet. onResume will try again. Set bolusEnded to make extra // sure onResume will catch this bolusEnded = true; + log.error("Unhandled exception", e); } if (helperActivity != null) { helperActivity.finish(); @@ -99,20 +107,23 @@ public class BolusProgressDialog extends DialogFragment implements View.OnClickL @Override public void onPause() { + running = false; super.onPause(); MainApp.unsubscribe(this); - running = false; + if (L.isEnabled(L.UI)) + log.debug("onPause"); } @Override public void onClick(View view) { switch (view.getId()) { case R.id.overview_bolusprogress_stop: - log.debug("Stop bolus delivery button pressed"); + if (L.isEnabled(L.UI)) + log.debug("Stop bolus delivery button pressed"); stopPressed = true; stopPressedView.setVisibility(View.VISIBLE); stopButton.setVisibility(View.INVISIBLE); - ConfigBuilderPlugin.getCommandQueue().cancelAllBoluses(); + ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelAllBoluses(); break; } } @@ -122,7 +133,8 @@ public class BolusProgressDialog extends DialogFragment implements View.OnClickL Activity activity = getActivity(); if (activity != null) { activity.runOnUiThread(() -> { - log.debug("Status: " + ev.status + " Percent: " + ev.percent); + if (L.isEnabled(L.UI)) + log.debug("Status: " + ev.status + " Percent: " + ev.percent); statusView.setText(ev.status); progressBar.setProgress(ev.percent); if (ev.percent == 100) { @@ -135,6 +147,8 @@ public class BolusProgressDialog extends DialogFragment implements View.OnClickL @Subscribe public void onStatusEvent(final EventDismissBolusprogressIfRunning ev) { + if (L.isEnabled(L.UI)) + log.debug("EventDismissBolusprogressIfRunning"); if (BolusProgressDialog.running) { dismiss(); } @@ -142,6 +156,8 @@ public class BolusProgressDialog extends DialogFragment implements View.OnClickL @Subscribe public void onStatusEvent(final EventPumpStatusChanged c) { + if (L.isEnabled(L.UI)) + log.debug("EventPumpStatusChanged"); Activity activity = getActivity(); if (activity != null) { activity.runOnUiThread(() -> statusView.setText(c.textStatus())); @@ -149,6 +165,8 @@ public class BolusProgressDialog extends DialogFragment implements View.OnClickL } private void scheduleDismiss() { + if (L.isEnabled(L.UI)) + log.debug("scheduleDismiss"); Thread t = new Thread(() -> { SystemClock.sleep(5000); BolusProgressDialog.bolusEnded = true; @@ -156,11 +174,18 @@ public class BolusProgressDialog extends DialogFragment implements View.OnClickL if (activity != null) { activity.runOnUiThread(() -> { try { - dismiss(); + if (running) { + if (L.isEnabled(L.UI)) + log.debug("executing"); + dismiss(); + } } catch (Exception e) { log.error("Unhandled exception", e); } }); + } else { + if (L.isEnabled(L.UI)) + log.debug("activity == null"); } }); t.start(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/CalibrationDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/CalibrationDialog.java index f0ccdd9809..f1f62c0bc4 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/CalibrationDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/CalibrationDialog.java @@ -23,6 +23,7 @@ import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.GlucoseStatus; import info.nightscout.androidaps.data.Profile; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.NumberPicker; import info.nightscout.utils.SafeParse; @@ -63,7 +64,7 @@ public class CalibrationDialog extends DialogFragment implements View.OnClickLis view.findViewById(R.id.ok).setOnClickListener(this); view.findViewById(R.id.cancel).setOnClickListener(this); - String units = MainApp.getConfigBuilder().getProfileUnits(); + String units = ProfileFunctions.getInstance().getProfileUnits(); Double bg = Profile.fromMgdlToUnits(GlucoseStatus.getGlucoseStatusData() != null ? GlucoseStatus.getGlucoseStatusData().glucose : 0d, units); bgNumber = (NumberPicker) view.findViewById(R.id.overview_calibration_bg); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/ErrorDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/ErrorDialog.java index 7d45c35792..dc4fa21aca 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/ErrorDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/ErrorDialog.java @@ -15,7 +15,7 @@ import org.slf4j.LoggerFactory; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.Services.AlarmSoundService; +import info.nightscout.androidaps.services.AlarmSoundService; public class ErrorDialog extends DialogFragment implements View.OnClickListener { private static Logger log = LoggerFactory.getLogger(ErrorDialog.class); @@ -74,7 +74,7 @@ public class ErrorDialog extends DialogFragment implements View.OnClickListener @Override public void dismiss() { - super.dismiss(); + super.dismissAllowingStateLoss(); if (helperActivity != null) { helperActivity.finish(); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/ErrorHelperActivity.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/ErrorHelperActivity.java index 90cf9aecd5..c556a6c844 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/ErrorHelperActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/ErrorHelperActivity.java @@ -4,7 +4,7 @@ import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import info.nightscout.androidaps.R; -import info.nightscout.utils.NSUpload; +import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; import info.nightscout.utils.SP; public class ErrorHelperActivity extends AppCompatActivity { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewCarbsDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewCarbsDialog.java index 3951b8415f..40450adf77 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewCarbsDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewCarbsDialog.java @@ -21,6 +21,8 @@ import android.widget.RadioButton; import com.google.common.base.Joiner; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; +import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -32,7 +34,9 @@ import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.Profile; +import info.nightscout.androidaps.db.BgReading; import info.nightscout.androidaps.db.CareportalEvent; +import info.nightscout.androidaps.db.DatabaseHelper; import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.TempTarget; import info.nightscout.androidaps.interfaces.Constraint; @@ -124,7 +128,6 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, C startEatingSoonTTCheckbox = view.findViewById(R.id.newcarbs_eating_soon_tt); startEatingSoonTTCheckbox.setOnCheckedChangeListener(this); startHypoTTCheckbox = view.findViewById(R.id.newcarbs_hypo_tt); - startHypoTTCheckbox.setOnCheckedChangeListener(this); editTime = view.findViewById(R.id.newcarbs_time); editTime.setParams(0d, -12 * 60d, 12 * 60d, 5d, new DecimalFormat("0"), false, textWatcher); @@ -153,8 +156,24 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, C notesLayout.setVisibility(SP.getBoolean(R.string.key_show_notes_entry_dialogs, false) ? View.VISIBLE : View.GONE); notesEdit = view.findViewById(R.id.newcarbs_notes); + BgReading bgReading = DatabaseHelper.actualBg(); + if (bgReading != null && bgReading.value < 72) { + startHypoTTCheckbox.setChecked(true); + // see #onCheckedChanged why listeners are registered like this + startHypoTTCheckbox.setOnClickListener(this); + } else { + startHypoTTCheckbox.setOnCheckedChangeListener(this); + } + setCancelable(true); getDialog().setCanceledOnTouchOutside(false); + + //recovering state if there is something + if (savedInstanceState != null) { + editCarbs.setValue(savedInstanceState.getDouble("editCarbs")); + editTime.setValue(savedInstanceState.getDouble("editTime")); + editDuration.setValue(savedInstanceState.getDouble("editDuration")); + } return view; } @@ -162,6 +181,19 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, C return value > 0 ? "+" + value : String.valueOf(value); } + + @Override + public void onSaveInstanceState(Bundle carbsDialogState) { + carbsDialogState.putBoolean("startActivityTTCheckbox",startActivityTTCheckbox.isChecked()); + carbsDialogState.putBoolean("startEatingSoonTTCheckbox", startEatingSoonTTCheckbox.isChecked()); + carbsDialogState.putBoolean("startHypoTTCheckbox", startHypoTTCheckbox.isChecked()); + carbsDialogState.putDouble("editTime", editTime.getValue()); + carbsDialogState.putDouble("editDuration", editDuration.getValue()); + carbsDialogState.putDouble("editCarbs", editCarbs.getValue()); + super.onSaveInstanceState(carbsDialogState); + } + + @Override public synchronized void onClick(View view) { switch (view.getId()) { @@ -219,15 +251,17 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, C } } + + @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - // Logic to disable a selected radio when pressed. When a checked radio - // is pressed, no CheckChanged event is trigger, so register a Click event + // Logic to disable a selected radio when pressed: when a checked radio + // is pressed, no CheckChanged event is triggered, so register a Click event // when checking a radio. Since Click events come after CheckChanged events, - // the Click event is triggered immediately after this. Thus, set toggingTT + // the Click event is triggered immediately after this. Thus, set togglingTT // var to true, so that the first Click event fired after this is ignored. // Radios remove themselves from Click events once unchecked. - // Since radios are not in a group, manually update their state. + // Since radios are not in a group, their state is manually updated here. switch (buttonView.getId()) { case R.id.newcarbs_activity_tt: togglingTT = true; @@ -276,7 +310,7 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, C } okClicked = true; try { - final Profile currentProfile = MainApp.getConfigBuilder().getProfile(); + final Profile currentProfile = ProfileFunctions.getInstance().getProfile(); if (currentProfile == null) { return; } @@ -394,6 +428,7 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, C CarbsGenerator.createCarb(carbsAfterConstraints, time, CareportalEvent.CARBCORRECTION, notes); } else { CarbsGenerator.generateCarbs(carbsAfterConstraints, time, duration, notes); + NSUpload.uploadEvent(CareportalEvent.NOTE, now() - 2000, MainApp.gs(R.string.generated_ecarbs_note, carbsAfterConstraints, duration, timeOffset)); } } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewInsulinDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewInsulinDialog.java index c4aba7004a..8545858d4e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewInsulinDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewInsulinDialog.java @@ -39,7 +39,9 @@ import info.nightscout.androidaps.db.CareportalEvent; import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.TempTarget; import info.nightscout.androidaps.interfaces.Constraint; +import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.androidaps.queue.Callback; import info.nightscout.utils.DateUtil; @@ -48,6 +50,7 @@ import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.NumberPicker; import info.nightscout.utils.SP; import info.nightscout.utils.SafeParse; +import info.nightscout.utils.T; import info.nightscout.utils.ToastUtils; import static info.nightscout.utils.DateUtil.now; @@ -130,7 +133,7 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener maxInsulin = MainApp.getConstraintChecker().getMaxBolusAllowed().value(); editInsulin = view.findViewById(R.id.newinsulin_amount); - editInsulin.setParams(0d, 0d, maxInsulin, ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep, DecimalFormatter.pumpSupportedBolusFormat(), false, textWatcher); + editInsulin.setParams(0d, 0d, maxInsulin, ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().bolusStep, DecimalFormatter.pumpSupportedBolusFormat(), false, textWatcher); Button plus1Button = view.findViewById(R.id.newinsulin_plus05); plus1Button.setOnClickListener(this); @@ -148,6 +151,11 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener setCancelable(true); getDialog().setCanceledOnTouchOutside(false); + if (savedInstanceState != null) { +// log.debug("savedInstanceState in onCreate is:" + savedInstanceState.toString()); + editInsulin.setValue(savedInstanceState.getDouble("editInsulin")); + editTime.setValue(savedInstanceState.getDouble("editTime")); + } return view; } @@ -156,6 +164,17 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener return value > 0 ? "+" + formatted : formatted; } + @Override + public void onSaveInstanceState(Bundle insulinDialogState) { + insulinDialogState.putBoolean("startEatingSoonTTCheckbox", startEatingSoonTTCheckbox.isChecked()); + insulinDialogState.putBoolean("recordOnlyCheckbox", recordOnlyCheckbox.isChecked()); + insulinDialogState.putDouble("editTime", editTime.getValue()); + insulinDialogState.putDouble("editInsulin", editInsulin.getValue()); + insulinDialogState.putString("notesEdit",notesEdit.getText().toString()); + log.debug("Instance state saved:"+insulinDialogState.toString()); + super.onSaveInstanceState(insulinDialogState); + } + @Override public synchronized void onClick(View view) { switch (view.getId()) { @@ -192,8 +211,9 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener okClicked = true; try { - Profile currentProfile = MainApp.getConfigBuilder().getProfile(); - if (currentProfile == null) + Profile currentProfile = ProfileFunctions.getInstance().getProfile(); + final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); + if (currentProfile == null || pump == null) return; Double insulin = SafeParse.stringToDouble(editInsulin.getText()); @@ -201,13 +221,13 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener List actions = new LinkedList<>(); if (insulin > 0) { - actions.add(MainApp.gs(R.string.bolus) + ": " + "" + insulinAfterConstraints + "U" + ""); + actions.add(MainApp.gs(R.string.bolus) + ": " + "" + DecimalFormatter.toPumpSupportedBolus(insulinAfterConstraints) + "U" + ""); if (recordOnlyCheckbox.isChecked()) { actions.add("" + MainApp.gs(R.string.bolusrecordedonly) + ""); } } - if (!insulinAfterConstraints.equals(insulin)) + if (Math.abs(insulinAfterConstraints - insulin) > pump.getPumpDescription().pumpType.determineCorrectBolusSize(insulinAfterConstraints)) actions.add("" + MainApp.gs(R.string.bolusconstraintapplied) + ""); int eatingSoonTTDuration = SP.getInt(R.string.key_eatingsoon_duration, Constants.defaultEatingSoonTTDuration); @@ -223,7 +243,7 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener } int timeOffset = editTime.getValue().intValue(); - final long time = now() + timeOffset * 1000 * 60; + final long time = now() + T.mins(timeOffset).msecs(); if (timeOffset != 0) { actions.add(MainApp.gs(R.string.time) + ": " + DateUtil.dateAndTimeString(time)); } @@ -270,10 +290,10 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener detailedBolusInfo.notes = notes; if (recordOnlyCheckbox.isChecked()) { detailedBolusInfo.date = time; - TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo); + TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false); } else { detailedBolusInfo.date = now(); - ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() { + ConfigBuilderPlugin.getPlugin().getCommandQueue().bolus(detailedBolusInfo, new Callback() { @Override public void run() { if (!result.success) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewTreatmentDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewTreatmentDialog.java index a315310dc8..b1a8bf172a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewTreatmentDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewTreatmentDialog.java @@ -25,13 +25,13 @@ import org.slf4j.LoggerFactory; import java.text.DecimalFormat; import java.util.Objects; -import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.db.CareportalEvent; import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.interfaces.Constraint; +import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.androidaps.queue.Callback; @@ -105,7 +105,7 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene editInsulin = (NumberPicker) view.findViewById(R.id.treatments_newtreatment_insulinamount); editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false, textWatcher); - editInsulin.setParams(0d, 0d, maxInsulin, ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep, DecimalFormatter.pumpSupportedBolusFormat(), false, textWatcher); + editInsulin.setParams(0d, 0d, maxInsulin, ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().bolusStep, DecimalFormatter.pumpSupportedBolusFormat(), false, textWatcher); recordOnlyCheckbox = (CheckBox) view.findViewById(R.id.newtreatment_record_only); @@ -126,6 +126,11 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene okClicked = true; try { + final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); + + if (pump == null) + return; + Double insulin = SafeParse.stringToDouble(editInsulin.getText()); final Integer carbs = SafeParse.stringToInt(editCarbs.getText()); @@ -135,15 +140,15 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene Integer carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(carbs)).value(); if (insulin > 0) { - confirmMessage += MainApp.gs(R.string.bolus) + ": " + "" + insulinAfterConstraints + "U" + ""; + confirmMessage += MainApp.gs(R.string.bolus) + ": " + "" + DecimalFormatter.toPumpSupportedBolus(insulinAfterConstraints) + "U" + ""; if (recordOnlyCheckbox.isChecked()) { - confirmMessage += "
" + MainApp.gs(R.string.bolusrecordedonly) + ""; + confirmMessage += "
" + MainApp.gs(R.string.bolusrecordedonly) + ""; } + if (Math.abs(insulinAfterConstraints - insulin) > pump.getPumpDescription().pumpType.determineCorrectBolusSize(insulinAfterConstraints) || !Objects.equals(carbsAfterConstraints, carbs)) + confirmMessage += "
" + MainApp.gs(R.string.bolusconstraintapplied) + ""; } if (carbsAfterConstraints > 0) - confirmMessage += "
" + MainApp.gs(R.string.carbs) + ": " + carbsAfterConstraints + "g"; - if (insulinAfterConstraints - insulin != 0 || !Objects.equals(carbsAfterConstraints, carbs)) - confirmMessage += "
" + MainApp.gs(R.string.constraintapllied); + confirmMessage += "
" + MainApp.gs(R.string.carbs) + ": " + "" + carbsAfterConstraints + "g" + ""; final double finalInsulinAfterConstraints = insulinAfterConstraints; @@ -172,8 +177,8 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene detailedBolusInfo.carbs = finalCarbsAfterConstraints; detailedBolusInfo.context = context; detailedBolusInfo.source = Source.USER; - if (!(recordOnlyCheckbox.isChecked() && (detailedBolusInfo.insulin > 0 || ConfigBuilderPlugin.getActivePump().getPumpDescription().storesCarbInfo))) { - ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() { + if (!(recordOnlyCheckbox.isChecked() && (detailedBolusInfo.insulin > 0 || ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().storesCarbInfo))) { + ConfigBuilderPlugin.getPlugin().getCommandQueue().bolus(detailedBolusInfo, new Callback() { @Override public void run() { if (!result.success) { @@ -187,7 +192,7 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene } }); } else { - TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo); + TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false); } FabricPrivacy.getInstance().logCustom(new CustomEvent("Bolus")); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/WizardDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/WizardDialog.java index c38f41b825..1b6a4f2ff8 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/WizardDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/WizardDialog.java @@ -55,7 +55,9 @@ import info.nightscout.androidaps.events.EventNewBG; import info.nightscout.androidaps.events.EventRefreshOverview; import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.PluginType; +import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.IobCobCalculator.CobInfo; import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin; import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished; @@ -147,6 +149,22 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com MainApp.bus().unregister(this); } + @Override + public void onSaveInstanceState(Bundle savedInstanceState) { + savedInstanceState.putBoolean("bgCheckbox", bgCheckbox.isChecked()); + savedInstanceState.putBoolean("ttCheckbox", ttCheckbox.isChecked()); + savedInstanceState.putBoolean("bolusIobCheckbox", bolusIobCheckbox.isChecked()); + savedInstanceState.putBoolean("basalIobCheckbox", basalIobCheckbox.isChecked()); + savedInstanceState.putBoolean("bgtrendCheckbox", bgtrendCheckbox.isChecked()); + savedInstanceState.putBoolean("cobCheckbox", cobCheckbox.isChecked()); + savedInstanceState.putDouble("editBg", editBg.getValue()); + savedInstanceState.putDouble("editCarbs", editCarbs.getValue()); + savedInstanceState.putDouble("editCorr", editCorr.getValue()); + savedInstanceState.putDouble("editCarbTime", editCarbTime.getValue()); + super.onSaveInstanceState(savedInstanceState); + } + + @Subscribe public void onStatusEvent(final EventNewBG e) { Activity activity = getActivity(); @@ -189,7 +207,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.overview_wizard_dialog, null, false); + View view = inflater.inflate(R.layout.overview_wizard_dialog, container, false); getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE); getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); @@ -252,13 +270,20 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com editBg.setParams(0d, 0d, 500d, 0.1d, new DecimalFormat("0.0"), false, textWatcher); editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false, textWatcher); - double bolusstep = ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep; + double bolusstep = ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().bolusStep; editCorr.setParams(0d, -maxCorrection, maxCorrection, bolusstep, DecimalFormatter.pumpSupportedBolusFormat(), false, textWatcher); editCarbTime.setParams(0d, -60d, 60d, 5d, new DecimalFormat("0"), false); initDialog(); setCancelable(true); getDialog().setCanceledOnTouchOutside(false); + //recovering state if there is something + if (savedInstanceState != null) { + editCarbs.setValue(savedInstanceState.getDouble("editCarbs")); + editBg.setValue(savedInstanceState.getDouble("editBg")); + editCarbTime.setValue(savedInstanceState.getDouble("editCarbTime")); + editCorr.setValue(savedInstanceState.getDouble("editCorr")); + } return view; } @@ -301,9 +326,10 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com return; } okClicked = true; - final Profile profile = MainApp.getConfigBuilder().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); Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(calculatedTotalInsulin)).value(); @@ -314,13 +340,8 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com if (carbsAfterConstraints > 0) confirmMessage += "
" + MainApp.gs(R.string.carbs) + ": " + "" + carbsAfterConstraints + "g" + ""; - if (insulinAfterConstraints - calculatedTotalInsulin != 0 || !carbsAfterConstraints.equals(calculatedCarbs)) { - AlertDialog.Builder builder = new AlertDialog.Builder(context); - builder.setTitle(MainApp.gs(R.string.treatmentdeliveryerror)); - builder.setMessage(MainApp.gs(R.string.constraints_violation) + "\n" + MainApp.gs(R.string.changeyourinput)); - builder.setPositiveButton(MainApp.gs(R.string.ok), null); - builder.show(); - return; + if (Math.abs(insulinAfterConstraints - calculatedTotalInsulin) > pump.getPumpDescription().pumpType.determineCorrectBolusSize(insulinAfterConstraints) || !carbsAfterConstraints.equals(calculatedCarbs)) { + confirmMessage += "
" + MainApp.gs(R.string.bolusconstraintapplied) + ""; } final Double finalInsulinAfterConstraints = insulinAfterConstraints; @@ -348,7 +369,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com loopPlugin.superBolusTo(System.currentTimeMillis() + 2 * 60L * 60 * 1000); MainApp.bus().post(new EventRefreshOverview("WizardDialog")); } - ConfigBuilderPlugin.getCommandQueue().tempBasalPercent(0, 120, true, profile, new Callback() { + ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalPercent(0, 120, true, profile, new Callback() { @Override public void run() { if (!result.success) { @@ -373,8 +394,8 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com detailedBolusInfo.boluscalc = boluscalcJSON; detailedBolusInfo.source = Source.USER; detailedBolusInfo.notes = finalNotes; - if (detailedBolusInfo.insulin > 0 || ConfigBuilderPlugin.getActivePump().getPumpDescription().storesCarbInfo) { - ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() { + if (detailedBolusInfo.insulin > 0 || ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().storesCarbInfo) { + ConfigBuilderPlugin.getPlugin().getCommandQueue().bolus(detailedBolusInfo, new Callback() { @Override public void run() { if (!result.success) { @@ -388,7 +409,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com } }); } else { - TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo); + TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false); } FabricPrivacy.getInstance().logCustom(new CustomEvent("Wizard")); } @@ -407,10 +428,10 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com } private void initDialog() { - Profile profile = MainApp.getConfigBuilder().getProfile(); - ProfileStore profileStore = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile(); + Profile profile = ProfileFunctions.getInstance().getProfile(); + ProfileStore profileStore = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface() != null ? ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getProfile() : null; - if (profile == null) { + if (profile == null || profileStore == null) { ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.noprofile)); dismiss(); return; @@ -452,14 +473,15 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com } private void calculateInsulin() { - ProfileStore profileStore = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile(); + ProfileStore profileStore = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getProfile(); if (profileSpinner == null || profileSpinner.getSelectedItem() == null || profileStore == null) return; // not initialized yet String selectedAlternativeProfile = profileSpinner.getSelectedItem().toString(); Profile specificProfile; - if (selectedAlternativeProfile.equals(MainApp.gs(R.string.active))) - specificProfile = MainApp.getConfigBuilder().getProfile(); - else + if (selectedAlternativeProfile.equals(MainApp.gs(R.string.active))) { + specificProfile = ProfileFunctions.getInstance().getProfile(); + selectedAlternativeProfile = ProfileFunctions.getInstance().getProfileName(); + } else specificProfile = profileStore.getSpecificProfile(selectedAlternativeProfile); // Entered values @@ -469,13 +491,13 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com Double corrAfterConstraint = c_correction; if (c_correction > 0) c_correction = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(c_correction)).value(); - if (c_correction - corrAfterConstraint != 0) { // c_correction != corrAfterConstraint doesn't work + if (Math.abs(c_correction - corrAfterConstraint) > 0.01d) { // c_correction != corrAfterConstraint doesn't work editCorr.setValue(0d); ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.bolusconstraintapplied)); return; } Integer carbsAfterConstraint = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(c_carbs)).value(); - if (c_carbs - carbsAfterConstraint != 0) { + if (Math.abs(c_carbs - carbsAfterConstraint) > 0.01d) { editCarbs.setValue(0d); ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.carbsconstraintapplied)); return; @@ -553,12 +575,15 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com boluscalcJSON = new JSONObject(); try { boluscalcJSON.put("profile", selectedAlternativeProfile); + boluscalcJSON.put("notes", notesEdit.getText()); boluscalcJSON.put("eventTime", DateUtil.toISOString(new Date())); boluscalcJSON.put("targetBGLow", wizard.targetBGLow); boluscalcJSON.put("targetBGHigh", wizard.targetBGHigh); boluscalcJSON.put("isf", wizard.sens); boluscalcJSON.put("ic", wizard.ic); boluscalcJSON.put("iob", -(wizard.insulingFromBolusIOB + wizard.insulingFromBasalsIOB)); + boluscalcJSON.put("bolusiob", wizard.insulingFromBolusIOB); + boluscalcJSON.put("basaliob", wizard.insulingFromBasalsIOB); boluscalcJSON.put("bolusiobused", bolusIobCheckbox.isChecked()); boluscalcJSON.put("basaliobused", basalIobCheckbox.isChecked()); boluscalcJSON.put("bg", c_bg); @@ -568,11 +593,18 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com boluscalcJSON.put("insulincarbs", wizard.insulinFromCarbs); boluscalcJSON.put("carbs", c_carbs); boluscalcJSON.put("cob", c_cob); + boluscalcJSON.put("cobused", cobCheckbox.isChecked()); boluscalcJSON.put("insulincob", wizard.insulinFromCOB); boluscalcJSON.put("othercorrection", corrAfterConstraint); boluscalcJSON.put("insulinsuperbolus", wizard.insulinFromSuperBolus); boluscalcJSON.put("insulintrend", wizard.insulinFromTrend); boluscalcJSON.put("insulin", calculatedTotalInsulin); + boluscalcJSON.put("superbolusused", superbolusCheckbox.isChecked()); + boluscalcJSON.put("insulinsuperbolus", wizard.insulinFromSuperBolus); + boluscalcJSON.put("trendused", bgtrendCheckbox.isChecked()); + boluscalcJSON.put("insulintrend", wizard.insulinFromTrend); + boluscalcJSON.put("trend", bgTrend.getText()); + boluscalcJSON.put("ttused", ttCheckbox.isChecked()); } catch (JSONException e) { log.error("Unhandled exception", e); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java index 31aa098579..a414d38310 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java @@ -24,14 +24,11 @@ import android.text.style.ForegroundColorSpan; import android.util.DisplayMetrics; import android.util.TypedValue; import android.view.ContextMenu; -import android.view.HapticFeedbackConstants; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; -import android.widget.CheckBox; -import android.widget.CompoundButton; import android.widget.ImageButton; import android.widget.LinearLayout; import android.widget.TextView; @@ -69,6 +66,7 @@ import info.nightscout.androidaps.db.ExtendedBolus; import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.TempTarget; import info.nightscout.androidaps.db.TemporaryBasal; +import info.nightscout.androidaps.events.EventAcceptOpenLoopChange; import info.nightscout.androidaps.events.EventCareportalEventChange; import info.nightscout.androidaps.events.EventExtendedBolusChange; import info.nightscout.androidaps.events.EventInitializationChanged; @@ -83,17 +81,21 @@ import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.PumpDescription; import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.Careportal.CareportalFragment; import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialog; import info.nightscout.androidaps.plugins.Careportal.OptionsToShow; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; -import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; +import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensData; import info.nightscout.androidaps.plugins.IobCobCalculator.CobInfo; import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin; import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished; import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventIobCalculationProgress; +import info.nightscout.androidaps.plugins.Loop.APSResult; import info.nightscout.androidaps.plugins.Loop.LoopPlugin; import info.nightscout.androidaps.plugins.Loop.events.EventNewOpenLoopNotification; +import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; import info.nightscout.androidaps.plugins.NSClientInternal.data.NSDeviceStatus; import info.nightscout.androidaps.plugins.Overview.Dialogs.CalibrationDialog; import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity; @@ -102,7 +104,6 @@ import info.nightscout.androidaps.plugins.Overview.Dialogs.NewInsulinDialog; import info.nightscout.androidaps.plugins.Overview.Dialogs.NewTreatmentDialog; import info.nightscout.androidaps.plugins.Overview.Dialogs.WizardDialog; import info.nightscout.androidaps.plugins.Overview.activities.QuickWizardListActivity; -import info.nightscout.androidaps.plugins.Overview.events.EventSetWakeLock; import info.nightscout.androidaps.plugins.Overview.graphData.GraphData; import info.nightscout.androidaps.plugins.Overview.notifications.NotificationRecyclerViewAdapter; import info.nightscout.androidaps.plugins.Overview.notifications.NotificationStore; @@ -110,26 +111,33 @@ import info.nightscout.androidaps.plugins.Source.SourceDexcomG5Plugin; import info.nightscout.androidaps.plugins.Source.SourceXdripPlugin; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.androidaps.plugins.Treatments.fragments.ProfileViewerDialog; +import info.nightscout.androidaps.plugins.Wear.ActionStringHandler; import info.nightscout.androidaps.queue.Callback; import info.nightscout.utils.BolusWizard; import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; +import info.nightscout.utils.DefaultValueHelper; import info.nightscout.utils.FabricPrivacy; -import info.nightscout.utils.NSUpload; import info.nightscout.utils.OKDialog; import info.nightscout.utils.Profiler; import info.nightscout.utils.SP; import info.nightscout.utils.SingleClickButton; +import info.nightscout.utils.T; import info.nightscout.utils.ToastUtils; +import static info.nightscout.utils.DateUtil.now; + public class OverviewFragment extends Fragment implements View.OnClickListener, View.OnLongClickListener { - private static Logger log = LoggerFactory.getLogger(OverviewFragment.class); + private static Logger log = LoggerFactory.getLogger(L.OVERVIEW); TextView timeView; TextView bgView; TextView arrowView; + TextView sensitivityView; TextView timeAgoView; + TextView timeAgoShortView; TextView deltaView; + TextView deltaShortView; TextView avgdeltaView; TextView baseBasalView; TextView extendedBolusView; @@ -168,8 +176,6 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, SingleClickButton cgmButton; SingleClickButton quickWizardButton; - CheckBox lockScreen; - boolean smallWidth; boolean smallHeight; @@ -182,8 +188,6 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, Handler sLoopHandler = new Handler(); Runnable sRefreshLoop = null; - final Object updateSync = new Object(); - public enum CHARTTYPE {PRE, BAS, IOB, COB, DEV, SEN, DEVSLOPE} private static final ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor(); @@ -197,258 +201,242 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - try { - //check screen width - final DisplayMetrics dm = new DisplayMetrics(); - getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm); - int screen_width = dm.widthPixels; - int screen_height = dm.heightPixels; - smallWidth = screen_width <= Constants.SMALL_WIDTH; - smallHeight = screen_height <= Constants.SMALL_HEIGHT; - boolean landscape = screen_height < screen_width; + //check screen width + final DisplayMetrics dm = new DisplayMetrics(); + getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm); + int screen_width = dm.widthPixels; + int screen_height = dm.heightPixels; + smallWidth = screen_width <= Constants.SMALL_WIDTH; + smallHeight = screen_height <= Constants.SMALL_HEIGHT; + boolean landscape = screen_height < screen_width; - View view; + View view; - if (MainApp.sResources.getBoolean(R.bool.isTablet) && (Config.NSCLIENT || Config.G5UPLOADER)) { - view = inflater.inflate(R.layout.overview_fragment_nsclient_tablet, container, false); - } else if (Config.NSCLIENT || Config.G5UPLOADER) { - view = inflater.inflate(R.layout.overview_fragment_nsclient, container, false); - shorttextmode = true; - } else if (smallHeight || landscape) { - view = inflater.inflate(R.layout.overview_fragment_smallheight, container, false); - } else { - view = inflater.inflate(R.layout.overview_fragment, container, false); - } - - timeView = (TextView) view.findViewById(R.id.overview_time); - bgView = (TextView) view.findViewById(R.id.overview_bg); - arrowView = (TextView) view.findViewById(R.id.overview_arrow); - if (smallWidth) { - arrowView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 35); - } - timeAgoView = (TextView) view.findViewById(R.id.overview_timeago); - deltaView = (TextView) view.findViewById(R.id.overview_delta); - avgdeltaView = (TextView) view.findViewById(R.id.overview_avgdelta); - baseBasalView = (TextView) view.findViewById(R.id.overview_basebasal); - extendedBolusView = (TextView) view.findViewById(R.id.overview_extendedbolus); - activeProfileView = (TextView) view.findViewById(R.id.overview_activeprofile); - pumpStatusView = (TextView) view.findViewById(R.id.overview_pumpstatus); - pumpDeviceStatusView = (TextView) view.findViewById(R.id.overview_pump); - openapsDeviceStatusView = (TextView) view.findViewById(R.id.overview_openaps); - uploaderDeviceStatusView = (TextView) view.findViewById(R.id.overview_uploader); - iobCalculationProgressView = (TextView) view.findViewById(R.id.overview_iobcalculationprogess); - loopStatusLayout = (LinearLayout) view.findViewById(R.id.overview_looplayout); - pumpStatusLayout = (LinearLayout) view.findViewById(R.id.overview_pumpstatuslayout); - - pumpStatusView.setBackgroundColor(MainApp.gc(R.color.colorInitializingBorder)); - - iobView = (TextView) view.findViewById(R.id.overview_iob); - cobView = (TextView) view.findViewById(R.id.overview_cob); - apsModeView = (TextView) view.findViewById(R.id.overview_apsmode); - tempTargetView = (TextView) view.findViewById(R.id.overview_temptarget); - - iage = (TextView) view.findViewById(R.id.careportal_insulinage); - cage = (TextView) view.findViewById(R.id.careportal_canulaage); - sage = (TextView) view.findViewById(R.id.careportal_sensorage); - pbage = (TextView) view.findViewById(R.id.careportal_pbage); - - bgGraph = (GraphView) view.findViewById(R.id.overview_bggraph); - iobGraph = (GraphView) view.findViewById(R.id.overview_iobgraph); - - treatmentButton = (SingleClickButton) view.findViewById(R.id.overview_treatmentbutton); - treatmentButton.setOnClickListener(this); - wizardButton = (SingleClickButton) view.findViewById(R.id.overview_wizardbutton); - wizardButton.setOnClickListener(this); - insulinButton = (SingleClickButton) view.findViewById(R.id.overview_insulinbutton); - if (insulinButton != null) - insulinButton.setOnClickListener(this); - carbsButton = (SingleClickButton) view.findViewById(R.id.overview_carbsbutton); - if (carbsButton != null) - carbsButton.setOnClickListener(this); - acceptTempButton = (SingleClickButton) view.findViewById(R.id.overview_accepttempbutton); - if (acceptTempButton != null) - acceptTempButton.setOnClickListener(this); - quickWizardButton = (SingleClickButton) view.findViewById(R.id.overview_quickwizardbutton); - quickWizardButton.setOnClickListener(this); - quickWizardButton.setOnLongClickListener(this); - calibrationButton = (SingleClickButton) view.findViewById(R.id.overview_calibrationbutton); - if (calibrationButton != null) - calibrationButton.setOnClickListener(this); - cgmButton = (SingleClickButton) view.findViewById(R.id.overview_cgmbutton); - if (cgmButton != null) - cgmButton.setOnClickListener(this); - - acceptTempLayout = (LinearLayout) view.findViewById(R.id.overview_accepttemplayout); - - notificationsView = (RecyclerView) view.findViewById(R.id.overview_notifications); - notificationsView.setHasFixedSize(false); - llm = new LinearLayoutManager(view.getContext()); - notificationsView.setLayoutManager(llm); - - int axisWidth = 50; - - if (dm.densityDpi <= 120) - axisWidth = 3; - else if (dm.densityDpi <= 160) - axisWidth = 10; - else if (dm.densityDpi <= 320) - axisWidth = 35; - else if (dm.densityDpi <= 420) - axisWidth = 50; - else if (dm.densityDpi <= 560) - axisWidth = 70; - else - axisWidth = 80; - - bgGraph.getGridLabelRenderer().setGridColor(MainApp.gc(R.color.graphgrid)); - bgGraph.getGridLabelRenderer().reloadStyles(); - iobGraph.getGridLabelRenderer().setGridColor(MainApp.gc(R.color.graphgrid)); - iobGraph.getGridLabelRenderer().reloadStyles(); - iobGraph.getGridLabelRenderer().setHorizontalLabelsVisible(false); - bgGraph.getGridLabelRenderer().setLabelVerticalWidth(axisWidth); - iobGraph.getGridLabelRenderer().setLabelVerticalWidth(axisWidth); - iobGraph.getGridLabelRenderer().setNumVerticalLabels(5); - - rangeToDisplay = SP.getInt(R.string.key_rangetodisplay, 6); - - bgGraph.setOnLongClickListener(new View.OnLongClickListener() { - @Override - public boolean onLongClick(View v) { - rangeToDisplay += 6; - rangeToDisplay = rangeToDisplay > 24 ? 6 : rangeToDisplay; - SP.putInt(R.string.key_rangetodisplay, rangeToDisplay); - updateGUI("rangeChange"); - return false; - } - }); - - setupChartMenu(view); - - lockScreen = (CheckBox) view.findViewById(R.id.overview_lockscreen); - if (lockScreen != null) { - lockScreen.setChecked(SP.getBoolean("lockscreen", false)); - lockScreen.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - SP.putBoolean("lockscreen", isChecked); - MainApp.bus().post(new EventSetWakeLock(isChecked)); - } - }); - } - - return view; - } catch (Exception e) { - FabricPrivacy.logException(e); - log.debug("Runtime Exception", e); + if (MainApp.sResources.getBoolean(R.bool.isTablet) && (Config.NSCLIENT)) { + view = inflater.inflate(R.layout.overview_fragment_nsclient_tablet, container, false); + } else if (Config.NSCLIENT) { + view = inflater.inflate(R.layout.overview_fragment_nsclient, container, false); + shorttextmode = true; + } else if (smallHeight || landscape) { + view = inflater.inflate(R.layout.overview_fragment_smallheight, container, false); + } else { + view = inflater.inflate(R.layout.overview_fragment, container, false); } - return null; + timeView = (TextView) view.findViewById(R.id.overview_time); + bgView = (TextView) view.findViewById(R.id.overview_bg); + arrowView = (TextView) view.findViewById(R.id.overview_arrow); + if (smallWidth) { + arrowView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 35); + } + sensitivityView = (TextView) view.findViewById(R.id.overview_sensitivity); + timeAgoView = (TextView) view.findViewById(R.id.overview_timeago); + timeAgoShortView = (TextView) view.findViewById(R.id.overview_timeagoshort); + deltaView = (TextView) view.findViewById(R.id.overview_delta); + deltaShortView = (TextView) view.findViewById(R.id.overview_deltashort); + avgdeltaView = (TextView) view.findViewById(R.id.overview_avgdelta); + baseBasalView = (TextView) view.findViewById(R.id.overview_basebasal); + extendedBolusView = (TextView) view.findViewById(R.id.overview_extendedbolus); + activeProfileView = (TextView) view.findViewById(R.id.overview_activeprofile); + pumpStatusView = (TextView) view.findViewById(R.id.overview_pumpstatus); + pumpDeviceStatusView = (TextView) view.findViewById(R.id.overview_pump); + openapsDeviceStatusView = (TextView) view.findViewById(R.id.overview_openaps); + uploaderDeviceStatusView = (TextView) view.findViewById(R.id.overview_uploader); + iobCalculationProgressView = (TextView) view.findViewById(R.id.overview_iobcalculationprogess); + loopStatusLayout = (LinearLayout) view.findViewById(R.id.overview_looplayout); + pumpStatusLayout = (LinearLayout) view.findViewById(R.id.overview_pumpstatuslayout); + + pumpStatusView.setBackgroundColor(MainApp.gc(R.color.colorInitializingBorder)); + + iobView = (TextView) view.findViewById(R.id.overview_iob); + cobView = (TextView) view.findViewById(R.id.overview_cob); + apsModeView = (TextView) view.findViewById(R.id.overview_apsmode); + tempTargetView = (TextView) view.findViewById(R.id.overview_temptarget); + + iage = (TextView) view.findViewById(R.id.careportal_insulinage); + cage = (TextView) view.findViewById(R.id.careportal_canulaage); + sage = (TextView) view.findViewById(R.id.careportal_sensorage); + pbage = (TextView) view.findViewById(R.id.careportal_pbage); + + bgGraph = (GraphView) view.findViewById(R.id.overview_bggraph); + iobGraph = (GraphView) view.findViewById(R.id.overview_iobgraph); + + treatmentButton = (SingleClickButton) view.findViewById(R.id.overview_treatmentbutton); + treatmentButton.setOnClickListener(this); + wizardButton = (SingleClickButton) view.findViewById(R.id.overview_wizardbutton); + wizardButton.setOnClickListener(this); + insulinButton = (SingleClickButton) view.findViewById(R.id.overview_insulinbutton); + if (insulinButton != null) + insulinButton.setOnClickListener(this); + carbsButton = (SingleClickButton) view.findViewById(R.id.overview_carbsbutton); + if (carbsButton != null) + carbsButton.setOnClickListener(this); + acceptTempButton = (SingleClickButton) view.findViewById(R.id.overview_accepttempbutton); + if (acceptTempButton != null) + acceptTempButton.setOnClickListener(this); + quickWizardButton = (SingleClickButton) view.findViewById(R.id.overview_quickwizardbutton); + quickWizardButton.setOnClickListener(this); + quickWizardButton.setOnLongClickListener(this); + calibrationButton = (SingleClickButton) view.findViewById(R.id.overview_calibrationbutton); + if (calibrationButton != null) + calibrationButton.setOnClickListener(this); + cgmButton = (SingleClickButton) view.findViewById(R.id.overview_cgmbutton); + if (cgmButton != null) + cgmButton.setOnClickListener(this); + + acceptTempLayout = (LinearLayout) view.findViewById(R.id.overview_accepttemplayout); + + notificationsView = (RecyclerView) view.findViewById(R.id.overview_notifications); + notificationsView.setHasFixedSize(false); + llm = new LinearLayoutManager(view.getContext()); + notificationsView.setLayoutManager(llm); + + int axisWidth = 50; + + if (dm.densityDpi <= 120) + axisWidth = 3; + else if (dm.densityDpi <= 160) + axisWidth = 10; + else if (dm.densityDpi <= 320) + axisWidth = 35; + else if (dm.densityDpi <= 420) + axisWidth = 50; + else if (dm.densityDpi <= 560) + axisWidth = 70; + else + axisWidth = 80; + + bgGraph.getGridLabelRenderer().setGridColor(MainApp.gc(R.color.graphgrid)); + bgGraph.getGridLabelRenderer().reloadStyles(); + iobGraph.getGridLabelRenderer().setGridColor(MainApp.gc(R.color.graphgrid)); + iobGraph.getGridLabelRenderer().reloadStyles(); + iobGraph.getGridLabelRenderer().setHorizontalLabelsVisible(false); + bgGraph.getGridLabelRenderer().setLabelVerticalWidth(axisWidth); + iobGraph.getGridLabelRenderer().setLabelVerticalWidth(axisWidth); + iobGraph.getGridLabelRenderer().setNumVerticalLabels(3); + + rangeToDisplay = SP.getInt(R.string.key_rangetodisplay, 6); + + bgGraph.setOnLongClickListener(v -> { + rangeToDisplay += 6; + rangeToDisplay = rangeToDisplay > 24 ? 6 : rangeToDisplay; + SP.putInt(R.string.key_rangetodisplay, rangeToDisplay); + updateGUI("rangeChange"); + return false; + }); + + setupChartMenu(view); + + return view; } private void setupChartMenu(View view) { chartButton = (ImageButton) view.findViewById(R.id.overview_chartMenuButton); - chartButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - final LoopPlugin.LastRun finalLastRun = LoopPlugin.lastRun; - final boolean predictionsAvailable = finalLastRun != null && finalLastRun.request.hasPredictions; + chartButton.setOnClickListener(v -> { + final LoopPlugin.LastRun finalLastRun = LoopPlugin.lastRun; + boolean predictionsAvailable; + if (Config.APS) + predictionsAvailable = finalLastRun != null && finalLastRun.request.hasPredictions; + else if (Config.NSCLIENT) + predictionsAvailable = true; + else + predictionsAvailable = false; - MenuItem item; - CharSequence title; - SpannableString s; - PopupMenu popup = new PopupMenu(v.getContext(), v); + MenuItem item; + CharSequence title; + SpannableString s; + PopupMenu popup = new PopupMenu(v.getContext(), v); - if (predictionsAvailable) { - item = popup.getMenu().add(Menu.NONE, CHARTTYPE.PRE.ordinal(), Menu.NONE, "Predictions"); - title = item.getTitle(); - s = new SpannableString(title); - s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.prediction, null)), 0, s.length(), 0); - item.setTitle(s); - item.setCheckable(true); - item.setChecked(SP.getBoolean("showprediction", true)); - } - - item = popup.getMenu().add(Menu.NONE, CHARTTYPE.BAS.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_basals)); + if (predictionsAvailable) { + item = popup.getMenu().add(Menu.NONE, CHARTTYPE.PRE.ordinal(), Menu.NONE, "Predictions"); title = item.getTitle(); s = new SpannableString(title); - s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.basal, null)), 0, s.length(), 0); + s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.prediction, null)), 0, s.length(), 0); item.setTitle(s); item.setCheckable(true); - item.setChecked(SP.getBoolean("showbasals", true)); - - item = popup.getMenu().add(Menu.NONE, CHARTTYPE.IOB.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_iob)); - title = item.getTitle(); - s = new SpannableString(title); - s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.iob, null)), 0, s.length(), 0); - item.setTitle(s); - item.setCheckable(true); - item.setChecked(SP.getBoolean("showiob", true)); - - item = popup.getMenu().add(Menu.NONE, CHARTTYPE.COB.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_cob)); - title = item.getTitle(); - s = new SpannableString(title); - s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.cob, null)), 0, s.length(), 0); - item.setTitle(s); - item.setCheckable(true); - item.setChecked(SP.getBoolean("showcob", true)); - - item = popup.getMenu().add(Menu.NONE, CHARTTYPE.DEV.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_deviations)); - title = item.getTitle(); - s = new SpannableString(title); - s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.deviations, null)), 0, s.length(), 0); - item.setTitle(s); - item.setCheckable(true); - item.setChecked(SP.getBoolean("showdeviations", false)); - - item = popup.getMenu().add(Menu.NONE, CHARTTYPE.SEN.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_sensitivity)); - title = item.getTitle(); - s = new SpannableString(title); - s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.ratio, null)), 0, s.length(), 0); - item.setTitle(s); - item.setCheckable(true); - item.setChecked(SP.getBoolean("showratios", false)); - - if (MainApp.devBranch) { - item = popup.getMenu().add(Menu.NONE, CHARTTYPE.DEVSLOPE.ordinal(), Menu.NONE, "Deviation slope"); - title = item.getTitle(); - s = new SpannableString(title); - s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.devslopepos, null)), 0, s.length(), 0); - item.setTitle(s); - item.setCheckable(true); - item.setChecked(SP.getBoolean("showdevslope", false)); - } - - popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem item) { - if (item.getItemId() == CHARTTYPE.PRE.ordinal()) { - SP.putBoolean("showprediction", !item.isChecked()); - } else if (item.getItemId() == CHARTTYPE.BAS.ordinal()) { - SP.putBoolean("showbasals", !item.isChecked()); - } else if (item.getItemId() == CHARTTYPE.IOB.ordinal()) { - SP.putBoolean("showiob", !item.isChecked()); - } else if (item.getItemId() == CHARTTYPE.COB.ordinal()) { - SP.putBoolean("showcob", !item.isChecked()); - } else if (item.getItemId() == CHARTTYPE.DEV.ordinal()) { - SP.putBoolean("showdeviations", !item.isChecked()); - } else if (item.getItemId() == CHARTTYPE.SEN.ordinal()) { - SP.putBoolean("showratios", !item.isChecked()); - } else if (item.getItemId() == CHARTTYPE.DEVSLOPE.ordinal()) { - SP.putBoolean("showdevslope", !item.isChecked()); - } - scheduleUpdateGUI("onGraphCheckboxesCheckedChanged"); - return true; - } - }); - chartButton.setImageResource(R.drawable.ic_arrow_drop_up_white_24dp); - popup.setOnDismissListener(new PopupMenu.OnDismissListener() { - @Override - public void onDismiss(PopupMenu menu) { - chartButton.setImageResource(R.drawable.ic_arrow_drop_down_white_24dp); - } - }); - popup.show(); + item.setChecked(SP.getBoolean("showprediction", true)); } + + item = popup.getMenu().add(Menu.NONE, CHARTTYPE.BAS.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_basals)); + title = item.getTitle(); + s = new SpannableString(title); + s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.basal, null)), 0, s.length(), 0); + item.setTitle(s); + item.setCheckable(true); + item.setChecked(SP.getBoolean("showbasals", true)); + + item = popup.getMenu().add(Menu.NONE, CHARTTYPE.IOB.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_iob)); + title = item.getTitle(); + s = new SpannableString(title); + s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.iob, null)), 0, s.length(), 0); + item.setTitle(s); + item.setCheckable(true); + item.setChecked(SP.getBoolean("showiob", true)); + + item = popup.getMenu().add(Menu.NONE, CHARTTYPE.COB.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_cob)); + title = item.getTitle(); + s = new SpannableString(title); + s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.cob, null)), 0, s.length(), 0); + item.setTitle(s); + item.setCheckable(true); + item.setChecked(SP.getBoolean("showcob", true)); + + item = popup.getMenu().add(Menu.NONE, CHARTTYPE.DEV.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_deviations)); + title = item.getTitle(); + s = new SpannableString(title); + s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.deviations, null)), 0, s.length(), 0); + item.setTitle(s); + item.setCheckable(true); + item.setChecked(SP.getBoolean("showdeviations", false)); + + item = popup.getMenu().add(Menu.NONE, CHARTTYPE.SEN.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_sensitivity)); + title = item.getTitle(); + s = new SpannableString(title); + s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.ratio, null)), 0, s.length(), 0); + item.setTitle(s); + item.setCheckable(true); + item.setChecked(SP.getBoolean("showratios", false)); + + if (MainApp.devBranch) { + item = popup.getMenu().add(Menu.NONE, CHARTTYPE.DEVSLOPE.ordinal(), Menu.NONE, "Deviation slope"); + title = item.getTitle(); + s = new SpannableString(title); + s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.devslopepos, null)), 0, s.length(), 0); + item.setTitle(s); + item.setCheckable(true); + item.setChecked(SP.getBoolean("showdevslope", false)); + } + + popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + if (item.getItemId() == CHARTTYPE.PRE.ordinal()) { + SP.putBoolean("showprediction", !item.isChecked()); + } else if (item.getItemId() == CHARTTYPE.BAS.ordinal()) { + SP.putBoolean("showbasals", !item.isChecked()); + } else if (item.getItemId() == CHARTTYPE.IOB.ordinal()) { + SP.putBoolean("showiob", !item.isChecked()); + } else if (item.getItemId() == CHARTTYPE.COB.ordinal()) { + SP.putBoolean("showcob", !item.isChecked()); + } else if (item.getItemId() == CHARTTYPE.DEV.ordinal()) { + SP.putBoolean("showdeviations", !item.isChecked()); + } else if (item.getItemId() == CHARTTYPE.SEN.ordinal()) { + SP.putBoolean("showratios", !item.isChecked()); + } else if (item.getItemId() == CHARTTYPE.DEVSLOPE.ordinal()) { + SP.putBoolean("showdevslope", !item.isChecked()); + } + scheduleUpdateGUI("onGraphCheckboxesCheckedChanged"); + return true; + } + }); + chartButton.setImageResource(R.drawable.ic_arrow_drop_up_white_24dp); + popup.setOnDismissListener(new PopupMenu.OnDismissListener() { + @Override + public void onDismiss(PopupMenu menu) { + chartButton.setImageResource(R.drawable.ic_arrow_drop_down_white_24dp); + } + }); + popup.show(); }); } @@ -458,8 +446,8 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, super.onCreateContextMenu(menu, v, menuInfo); if (v == apsModeView) { final LoopPlugin loopPlugin = LoopPlugin.getPlugin(); - final PumpDescription pumpDescription = ConfigBuilderPlugin.getActivePump().getPumpDescription(); - if (loopPlugin == null || !MainApp.getConfigBuilder().isProfileValid("ContexMenuCreation")) + final PumpDescription pumpDescription = ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription(); + if (!ProfileFunctions.getInstance().isProfileValid("ContexMenuCreation")) return; menu.setHeaderTitle(MainApp.gs(R.string.loop)); if (loopPlugin.isEnabled(PluginType.LOOP)) { @@ -485,24 +473,33 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, } else if (v == activeProfileView) { menu.setHeaderTitle(MainApp.gs(R.string.profile)); menu.add(MainApp.gs(R.string.danar_viewprofile)); - if (MainApp.getConfigBuilder().getActiveProfileInterface().getProfile() != null) { + if (ConfigBuilderPlugin.getPlugin().getActiveProfileInterface() != null && ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getProfile() != null) { menu.add(MainApp.gs(R.string.careportal_profileswitch)); } + } else if (v == tempTargetView) { + menu.setHeaderTitle(MainApp.gs(R.string.careportal_temporarytarget)); + menu.add(MainApp.gs(R.string.custom)); + menu.add(MainApp.gs(R.string.eatingsoon)); + menu.add(MainApp.gs(R.string.activity)); + menu.add(MainApp.gs(R.string.hypo)); + if (TreatmentsPlugin.getPlugin().getTempTargetFromHistory() != null) { + menu.add(MainApp.gs(R.string.cancel)); + } } } @Override public boolean onContextItemSelected(MenuItem item) { - final Profile profile = MainApp.getConfigBuilder().getProfile(); + final Profile profile = ProfileFunctions.getInstance().getProfile(); if (profile == null) return true; final LoopPlugin loopPlugin = LoopPlugin.getPlugin(); if (item.getTitle().equals(MainApp.gs(R.string.disableloop))) { loopPlugin.setPluginEnabled(PluginType.LOOP, false); loopPlugin.setFragmentVisible(PluginType.LOOP, false); - MainApp.getConfigBuilder().storeSettings("DisablingLoop"); + ConfigBuilderPlugin.getPlugin().storeSettings("DisablingLoop"); updateGUI("suspendmenu"); - ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, new Callback() { + ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(true, new Callback() { @Override public void run() { if (!result.success) { @@ -515,14 +512,14 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, } else if (item.getTitle().equals(MainApp.gs(R.string.enableloop))) { loopPlugin.setPluginEnabled(PluginType.LOOP, true); loopPlugin.setFragmentVisible(PluginType.LOOP, true); - MainApp.getConfigBuilder().storeSettings("EnablingLoop"); + ConfigBuilderPlugin.getPlugin().storeSettings("EnablingLoop"); updateGUI("suspendmenu"); NSUpload.uploadOpenAPSOffline(0); return true; } else if (item.getTitle().equals(MainApp.gs(R.string.resume))) { loopPlugin.suspendTo(0L); updateGUI("suspendmenu"); - ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, new Callback() { + ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(true, new Callback() { @Override public void run() { if (!result.success) { @@ -533,39 +530,39 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, NSUpload.uploadOpenAPSOffline(0); return true; } else if (item.getTitle().equals(MainApp.gs(R.string.suspendloopfor1h))) { - MainApp.getConfigBuilder().suspendLoop(60); + LoopPlugin.getPlugin().suspendLoop(60); updateGUI("suspendmenu"); return true; } else if (item.getTitle().equals(MainApp.gs(R.string.suspendloopfor2h))) { - MainApp.getConfigBuilder().suspendLoop(120); + LoopPlugin.getPlugin().suspendLoop(120); updateGUI("suspendmenu"); return true; } else if (item.getTitle().equals(MainApp.gs(R.string.suspendloopfor3h))) { - MainApp.getConfigBuilder().suspendLoop(180); + LoopPlugin.getPlugin().suspendLoop(180); updateGUI("suspendmenu"); return true; } else if (item.getTitle().equals(MainApp.gs(R.string.suspendloopfor10h))) { - MainApp.getConfigBuilder().suspendLoop(600); + LoopPlugin.getPlugin().suspendLoop(600); updateGUI("suspendmenu"); return true; } else if (item.getTitle().equals(MainApp.gs(R.string.disconnectpumpfor15m))) { - MainApp.getConfigBuilder().disconnectPump(15, profile); + LoopPlugin.getPlugin().disconnectPump(15, profile); updateGUI("suspendmenu"); return true; } else if (item.getTitle().equals(MainApp.gs(R.string.disconnectpumpfor30m))) { - MainApp.getConfigBuilder().disconnectPump(30, profile); + LoopPlugin.getPlugin().disconnectPump(30, profile); updateGUI("suspendmenu"); return true; } else if (item.getTitle().equals(MainApp.gs(R.string.disconnectpumpfor1h))) { - MainApp.getConfigBuilder().disconnectPump(60, profile); + LoopPlugin.getPlugin().disconnectPump(60, profile); updateGUI("suspendmenu"); return true; } else if (item.getTitle().equals(MainApp.gs(R.string.disconnectpumpfor2h))) { - MainApp.getConfigBuilder().disconnectPump(120, profile); + LoopPlugin.getPlugin().disconnectPump(120, profile); updateGUI("suspendmenu"); return true; } else if (item.getTitle().equals(MainApp.gs(R.string.disconnectpumpfor3h))) { - MainApp.getConfigBuilder().disconnectPump(180, profile); + LoopPlugin.getPlugin().disconnectPump(180, profile); updateGUI("suspendmenu"); return true; } else if (item.getTitle().equals(MainApp.gs(R.string.careportal_profileswitch))) { @@ -578,6 +575,53 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, ProfileViewerDialog pvd = ProfileViewerDialog.newInstance(System.currentTimeMillis()); FragmentManager manager = getFragmentManager(); pvd.show(manager, "ProfileViewDialog"); + } else if (item.getTitle().equals(MainApp.gs(R.string.eatingsoon))) { + DefaultValueHelper defHelper = new DefaultValueHelper(); + double target = defHelper.determineEatingSoonTT(profile.getUnits()); + TempTarget tempTarget = new TempTarget() + .date(System.currentTimeMillis()) + .duration(defHelper.determineEatingSoonTTDuration()) + .reason(MainApp.gs(R.string.eatingsoon)) + .source(Source.USER) + .low(Profile.toMgdl(target, profile.getUnits())) + .high(Profile.toMgdl(target, profile.getUnits())); + TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget); + } else if (item.getTitle().equals(MainApp.gs(R.string.activity))) { + DefaultValueHelper defHelper = new DefaultValueHelper(); + double target = defHelper.determineActivityTT(profile.getUnits()); + TempTarget tempTarget = new TempTarget() + .date(now()) + .duration(defHelper.determineActivityTTDuration()) + .reason(MainApp.gs(R.string.activity)) + .source(Source.USER) + .low(Profile.toMgdl(target, profile.getUnits())) + .high(Profile.toMgdl(target, profile.getUnits())); + TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget); + } else if (item.getTitle().equals(MainApp.gs(R.string.hypo))) { + DefaultValueHelper defHelper = new DefaultValueHelper(); + double target = defHelper.determineHypoTT(profile.getUnits()); + TempTarget tempTarget = new TempTarget() + .date(now()) + .duration(defHelper.determineHypoTTDuration()) + .reason(MainApp.gs(R.string.hypo)) + .source(Source.USER) + .low(Profile.toMgdl(target, profile.getUnits())) + .high(Profile.toMgdl(target, profile.getUnits())); + TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget); + } else if (item.getTitle().equals(MainApp.gs(R.string.custom))) { + NewNSTreatmentDialog newTTDialog = new NewNSTreatmentDialog(); + final OptionsToShow temptarget = CareportalFragment.TEMPTARGET; + temptarget.executeTempTarget = true; + newTTDialog.setOptions(temptarget, R.string.careportal_temporarytarget); + newTTDialog.show(getFragmentManager(), "NewNSTreatmentDialog"); + } else if (item.getTitle().equals(MainApp.gs(R.string.cancel))) { + TempTarget tempTarget = new TempTarget() + .source(Source.USER) + .date(now()) + .duration(0) + .low(0) + .high(0); + TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget); } return super.onContextItemSelected(item); @@ -585,11 +629,15 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, @Override public void onClick(View v) { - boolean xdrip = MainApp.getSpecificPlugin(SourceXdripPlugin.class) != null && MainApp.getSpecificPlugin(SourceXdripPlugin.class).isEnabled(PluginType.BGSOURCE); - boolean g5 = MainApp.getSpecificPlugin(SourceDexcomG5Plugin.class) != null && MainApp.getSpecificPlugin(SourceDexcomG5Plugin.class).isEnabled(PluginType.BGSOURCE); - String units = MainApp.getConfigBuilder().getProfileUnits(); + boolean xdrip = SourceXdripPlugin.getPlugin().isEnabled(PluginType.BGSOURCE); + boolean g5 = SourceDexcomG5Plugin.getPlugin().isEnabled(PluginType.BGSOURCE); + String units = ProfileFunctions.getInstance().getProfileUnits(); FragmentManager manager = getFragmentManager(); + // try to fix https://fabric.io/nightscout3/android/apps/info.nightscout.androidaps/issues/5aca7a1536c7b23527eb4be7?time=last-seven-days + // https://stackoverflow.com/questions/14860239/checking-if-state-is-saved-before-committing-a-fragmenttransaction + if (manager.isStateSaved()) + return; switch (v.getId()) { case R.id.overview_accepttempbutton: onClickAcceptTemp(); @@ -633,8 +681,8 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, new NewCarbsDialog().show(manager, "CarbsDialog"); break; case R.id.overview_pumpstatus: - if (ConfigBuilderPlugin.getActivePump().isSuspended() || !ConfigBuilderPlugin.getActivePump().isInitialized()) - ConfigBuilderPlugin.getCommandQueue().readStatus("RefreshClicked", null); + if (ConfigBuilderPlugin.getPlugin().getActivePump().isSuspended() || !ConfigBuilderPlugin.getPlugin().getActivePump().isInitialized()) + ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("RefreshClicked", null); break; } @@ -671,36 +719,22 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, } private void onClickAcceptTemp() { - Profile profile = MainApp.getConfigBuilder().getProfile(); + Profile profile = ProfileFunctions.getInstance().getProfile(); + Context context = getContext(); + + if (context == null) return; if (LoopPlugin.getPlugin().isEnabled(PluginType.LOOP) && profile != null) { LoopPlugin.getPlugin().invoke("Accept temp button", false); final LoopPlugin.LastRun finalLastRun = LoopPlugin.lastRun; if (finalLastRun != null && finalLastRun.lastAPSRun != null && finalLastRun.constraintsProcessed.isChangeRequested()) { - AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); + AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setTitle(MainApp.gs(R.string.confirmation)); builder.setMessage(MainApp.gs(R.string.setbasalquestion) + "\n" + finalLastRun.constraintsProcessed); builder.setPositiveButton(MainApp.gs(R.string.ok), (dialog, id) -> { hideTempRecommendation(); clearNotification(); - MainApp.getConfigBuilder().applyTBRRequest(finalLastRun.constraintsProcessed, profile, new Callback() { - @Override - public void run() { - if (result.enacted) { - finalLastRun.tbrSetByPump = result; - finalLastRun.lastEnact = new Date(); - finalLastRun.lastOpenModeAccept = new Date(); - NSUpload.uploadDeviceStatus(); - ObjectivesPlugin objectivesPlugin = MainApp.getSpecificPlugin(ObjectivesPlugin.class); - if (objectivesPlugin != null) { - ObjectivesPlugin.manualEnacts++; - ObjectivesPlugin.saveProgress(); - } - } - scheduleUpdateGUI("onClickAcceptTemp"); - } - }); - FabricPrivacy.getInstance().logCustom(new CustomEvent("AcceptTemp")); + LoopPlugin.getPlugin().acceptChangeRequest(); }); builder.setNegativeButton(MainApp.gs(R.string.cancel), null); builder.show(); @@ -710,7 +744,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, void onClickQuickwizard() { final BgReading actualBg = DatabaseHelper.actualBg(); - final Profile profile = MainApp.getConfigBuilder().getProfile(); + final Profile profile = ProfileFunctions.getInstance().getProfile(); final TempTarget tempTarget = TreatmentsPlugin.getPlugin().getTempTargetFromHistory(); final QuickWizardEntry quickWizardEntry = OverviewPlugin.getPlugin().quickWizard.getActive(); @@ -769,7 +803,8 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, builder.setPositiveButton(MainApp.gs(R.string.ok), (dialog, id) -> { synchronized (builder) { if (accepted) { - log.debug("guarding: already accepted"); + if (L.isEnabled(L.OVERVIEW)) + log.debug("guarding: already accepted"); return; } accepted = true; @@ -777,10 +812,10 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, if (wizard.superBolus) { final LoopPlugin loopPlugin = LoopPlugin.getPlugin(); if (loopPlugin.isEnabled(PluginType.LOOP)) { - loopPlugin.superBolusTo(System.currentTimeMillis() + 2 * 60L * 60 * 1000); + loopPlugin.superBolusTo(System.currentTimeMillis() + T.hours(2).msecs()); MainApp.bus().post(new EventRefreshOverview("WizardDialog")); } - ConfigBuilderPlugin.getCommandQueue().tempBasalPercent(0, 120, true, profile, new Callback() { + ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalPercent(0, 120, true, profile, new Callback() { @Override public void run() { if (!result.success) { @@ -801,8 +836,8 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, detailedBolusInfo.context = context; detailedBolusInfo.boluscalc = boluscalcJSON; detailedBolusInfo.source = Source.USER; - if (finalInsulinAfterConstraints > 0 || ConfigBuilderPlugin.getActivePump().getPumpDescription().storesCarbInfo) { - ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() { + if (finalInsulinAfterConstraints > 0 || ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().storesCarbInfo) { + ConfigBuilderPlugin.getPlugin().getCommandQueue().bolus(detailedBolusInfo, new Callback() { @Override public void run() { if (!result.success) { @@ -816,7 +851,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, } }); } else { - TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo); + TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false); } FabricPrivacy.getInstance().logCustom(new CustomEvent("QuickWizard")); } @@ -836,6 +871,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, sLoopHandler.removeCallbacksAndMessages(null); unregisterForContextMenu(apsModeView); unregisterForContextMenu(activeProfileView); + unregisterForContextMenu(tempTargetView); } @Override @@ -849,6 +885,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, sLoopHandler.postDelayed(sRefreshLoop, 60 * 1000L); registerForContextMenu(apsModeView); registerForContextMenu(activeProfileView); + registerForContextMenu(tempTargetView); updateGUI("onResume"); } @@ -897,6 +934,11 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, scheduleUpdateGUI("EventNewOpenLoopNotification"); } + @Subscribe + public void onStatusEvent(final EventAcceptOpenLoopChange ev) { + scheduleUpdateGUI("EventAcceptOpenLoopChange"); + } + @Subscribe public void onStatusEvent(final EventTempTargetChange ev) { scheduleUpdateGUI("EventTempTargetChange"); @@ -937,6 +979,8 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, NotificationManager notificationManager = (NotificationManager) MainApp.instance().getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.cancel(Constants.notificationID); + + ActionStringHandler.handleInitiate("cancelChangeRequest"); } private void updatePumpStatus(String status) { @@ -972,8 +1016,9 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, @SuppressLint("SetTextI18n") public void updateGUI(final String from) { - log.debug("updateGUI entered from: " + from); - final Date updateGUIStart = new Date(); + if (L.isEnabled(L.OVERVIEW)) + log.debug("updateGUI entered from: " + from); + final long updateGUIStart = System.currentTimeMillis(); if (getActivity() == null) return; @@ -987,7 +1032,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, pumpStatusLayout.setVisibility(View.GONE); loopStatusLayout.setVisibility(View.GONE); - if (!MainApp.getConfigBuilder().isProfileValid("Overview")) { + if (!ProfileFunctions.getInstance().isProfileValid("Overview")) { pumpStatusView.setText(R.string.noprofileset); pumpStatusLayout.setVisibility(View.VISIBLE); return; @@ -998,9 +1043,9 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, BgReading actualBG = DatabaseHelper.actualBg(); BgReading lastBG = DatabaseHelper.lastBg(); - final PumpInterface pump = ConfigBuilderPlugin.getActivePump(); + final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); - final Profile profile = MainApp.getConfigBuilder().getProfile(); + final Profile profile = ProfileFunctions.getInstance().getProfile(); final String units = profile.getUnits(); final double lowLine = OverviewPlugin.getPlugin().determineLowLine(units); @@ -1020,12 +1065,18 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, arrowView.setTextColor(color); GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData(); if (glucoseStatus != null) { - deltaView.setText("Δ " + Profile.toUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units) + " " + units); + if (deltaView != null) + deltaView.setText("Δ " + Profile.toUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units) + " " + units); + if (deltaShortView != null) + deltaShortView.setText(Profile.toSignedUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units)); if (avgdeltaView != null) avgdeltaView.setText("øΔ15m: " + Profile.toUnitsString(glucoseStatus.short_avgdelta, glucoseStatus.short_avgdelta * Constants.MGDL_TO_MMOLL, units) + " øΔ40m: " + Profile.toUnitsString(glucoseStatus.long_avgdelta, glucoseStatus.long_avgdelta * Constants.MGDL_TO_MMOLL, units)); } else { - deltaView.setText("Δ " + MainApp.gs(R.string.notavailable)); + if (deltaView != null) + deltaView.setText("Δ " + MainApp.gs(R.string.notavailable)); + if (deltaShortView != null) + deltaShortView.setText("---"); if (avgdeltaView != null) avgdeltaView.setText(""); } @@ -1129,22 +1180,19 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, } else { basalText = DecimalFormatter.to2Decimal(profile.getBasal()) + "U/h"; } - baseBasalView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - String fullText = MainApp.gs(R.string.pump_basebasalrate_label) + ": " + DecimalFormatter.to2Decimal(profile.getBasal()) + "U/h\n"; - if (activeTemp != null) { - fullText += MainApp.gs(R.string.pump_tempbasal_label) + ": " + activeTemp.toStringFull(); - } - OKDialog.show(getActivity(), MainApp.gs(R.string.basal), fullText, null); + baseBasalView.setOnClickListener(v -> { + String fullText = MainApp.gs(R.string.pump_basebasalrate_label) + ": " + DecimalFormatter.to2Decimal(profile.getBasal()) + "U/h\n"; + if (activeTemp != null) { + fullText += MainApp.gs(R.string.pump_tempbasal_label) + ": " + activeTemp.toStringFull(); } + OKDialog.show(getActivity(), MainApp.gs(R.string.basal), fullText, null); }); } else { if (activeTemp != null) { basalText = activeTemp.toStringFull() + " "; } - if (Config.NSCLIENT || Config.G5UPLOADER) + if (Config.NSCLIENT) basalText += "(" + DecimalFormatter.to2Decimal(profile.getBasal()) + " U/h)"; else if (pump.getPumpDescription().isTempBasalCapable) { basalText += "(" + DecimalFormatter.to2Decimal(pump.getBaseBasalRate()) + "U/h)"; @@ -1166,40 +1214,24 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, if (extendedBolus != null && !pump.isFakingTempsByExtendedBoluses()) { extendedBolusText = DecimalFormatter.to2Decimal(extendedBolus.absoluteRate()) + "U/h"; } - extendedBolusView.setText(extendedBolusText); - extendedBolusView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - OKDialog.show(getActivity(), MainApp.gs(R.string.extendedbolus), extendedBolus.toString(), null); - } - }); - } else { if (extendedBolus != null && !pump.isFakingTempsByExtendedBoluses()) { extendedBolusText = extendedBolus.toString(); } - extendedBolusView.setText(extendedBolusText); + } + extendedBolusView.setText(extendedBolusText); + if (Config.NSCLIENT) { + extendedBolusView.setOnClickListener(v -> OKDialog.show(getActivity(), MainApp.gs(R.string.extendedbolus), extendedBolus.toString(), null)); } if (extendedBolusText.equals("")) - extendedBolusView.setVisibility(View.GONE); + extendedBolusView.setVisibility(Config.NSCLIENT ? View.INVISIBLE : View.GONE); else extendedBolusView.setVisibility(View.VISIBLE); } - activeProfileView.setText(MainApp.getConfigBuilder().getProfileName()); + activeProfileView.setText(ProfileFunctions.getInstance().getProfileName()); activeProfileView.setBackgroundColor(Color.GRAY); - tempTargetView.setOnLongClickListener(view -> { - view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); - NewNSTreatmentDialog newTTDialog = new NewNSTreatmentDialog(); - final OptionsToShow temptarget = CareportalFragment.TEMPTARGET; - temptarget.executeTempTarget = true; - newTTDialog.setOptions(temptarget, R.string.careportal_temporarytarget); - newTTDialog.show(getFragmentManager(), "NewNSTreatmentDialog"); - return true; - }); - tempTargetView.setLongClickable(true); - // QuickWizard button QuickWizardEntry quickWizardEntry = OverviewPlugin.getPlugin().quickWizard.getActive(); if (quickWizardEntry != null && lastBG != null && pump.isInitialized() && !pump.isSuspended()) { @@ -1216,7 +1248,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, // **** Various treatment buttons **** if (carbsButton != null) { if (SP.getBoolean(R.string.key_show_carbs_button, true) - && (!ConfigBuilderPlugin.getActivePump().getPumpDescription().storesCarbInfo || + && (!ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().storesCarbInfo || (pump.isInitialized() && !pump.isSuspended()))) { carbsButton.setVisibility(View.VISIBLE); } else { @@ -1232,14 +1264,14 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, treatmentButton.setVisibility(View.GONE); } } - if (wizardButton != null) { + if (pump.isInitialized() && !pump.isSuspended() && wizardButton != null) { if (SP.getBoolean(R.string.key_show_wizard_button, true)) { wizardButton.setVisibility(View.VISIBLE); } else { wizardButton.setVisibility(View.GONE); } } - if (insulinButton != null) { + if (pump.isInitialized() && !pump.isSuspended() && insulinButton != null) { if (SP.getBoolean(R.string.key_show_insulin_button, true)) { insulinButton.setVisibility(View.VISIBLE); } else { @@ -1259,7 +1291,10 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, flag &= ~Paint.STRIKE_THRU_TEXT_FLAG; bgView.setPaintFlags(flag); - timeAgoView.setText(DateUtil.minAgo(lastBG.date)); + if (timeAgoView != null) + timeAgoView.setText(DateUtil.minAgo(lastBG.date)); + if (timeAgoShortView != null) + timeAgoShortView.setText("(" + DateUtil.minAgoShort(lastBG.date) + ")"); // iob TreatmentsPlugin.getPlugin().updateTotalIOBTreatments(); @@ -1300,7 +1335,15 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, cobView.setText(cobText); } - final boolean predictionsAvailable = finalLastRun != null && finalLastRun.request.hasPredictions; + boolean predictionsAvailable; + if (Config.APS) + predictionsAvailable = finalLastRun != null && finalLastRun.request.hasPredictions; + else if (Config.NSCLIENT) + predictionsAvailable = true; + else + predictionsAvailable = false; + final boolean finalPredictionsAvailable = predictionsAvailable; + // pump status from ns if (pumpDeviceStatusView != null) { pumpDeviceStatusView.setText(NSDeviceStatus.getInstance().getPumpStatus()); @@ -1315,10 +1358,19 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, // Uploader status from ns if (uploaderDeviceStatusView != null) { - uploaderDeviceStatusView.setText(NSDeviceStatus.getInstance().getUploaderStatus()); + uploaderDeviceStatusView.setText(NSDeviceStatus.getInstance().getUploaderStatusSpanned()); uploaderDeviceStatusView.setOnClickListener(v -> OKDialog.show(getActivity(), MainApp.gs(R.string.uploader), NSDeviceStatus.getInstance().getExtendedUploaderStatus(), null)); } + // Sensitivity + if (sensitivityView != null) { + AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getLastAutosensDataSynchronized("Overview"); + if (autosensData != null) + sensitivityView.setText(String.format("%.0f%%", autosensData.autosensResult.ratio * 100)); + else + sensitivityView.setText(""); + } + // ****** GRAPH ******* new Thread(() -> { @@ -1334,18 +1386,25 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, final long toTime; final long fromTime; final long endTime; - if (predictionsAvailable && SP.getBoolean("showprediction", false)) { - int predHours = (int) (Math.ceil(finalLastRun.constraintsProcessed.getLatestPredictionsTime() - System.currentTimeMillis()) / (60 * 60 * 1000)); + + APSResult apsResult = null; + + if (finalPredictionsAvailable && SP.getBoolean("showprediction", false)) { + if (Config.APS) + apsResult = finalLastRun.constraintsProcessed; + else + apsResult = NSDeviceStatus.getAPSResult(); + int predHours = (int) (Math.ceil(apsResult.getLatestPredictionsTime() - System.currentTimeMillis()) / (60 * 60 * 1000)); predHours = Math.min(2, predHours); predHours = Math.max(0, predHours); hoursToFetch = rangeToDisplay - predHours; toTime = calendar.getTimeInMillis() + 100000; // little bit more to avoid wrong rounding - Graphview specific - fromTime = toTime - hoursToFetch * 60 * 60 * 1000L; - endTime = toTime + predHours * 60 * 60 * 1000L; + fromTime = toTime - T.hours(hoursToFetch).msecs(); + endTime = toTime + T.hours(predHours).msecs(); } else { hoursToFetch = rangeToDisplay; toTime = calendar.getTimeInMillis() + 100000; // little bit more to avoid wrong rounding - Graphview specific - fromTime = toTime - hoursToFetch * 60 * 60 * 1000L; + fromTime = toTime - T.hours(hoursToFetch).msecs(); endTime = toTime; } @@ -1353,7 +1412,8 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, final long now = System.currentTimeMillis(); // ------------------ 1st graph - Profiler.log(log, from + " - 1st graph - START", updateGUIStart); + if (L.isEnabled(L.OVERVIEW)) + Profiler.log(log, from + " - 1st graph - START", updateGUIStart); final GraphData graphData = new GraphData(bgGraph, IobCobCalculatorPlugin.getPlugin()); @@ -1361,9 +1421,9 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, graphData.addInRangeArea(fromTime, endTime, lowLine, highLine); // **** BG **** - if (predictionsAvailable && SP.getBoolean("showprediction", false)) + if (finalPredictionsAvailable && SP.getBoolean("showprediction", false)) graphData.addBgReadings(fromTime, toTime, lowLine, highLine, - finalLastRun.constraintsProcessed.getPredictions()); + apsResult.getPredictions()); else graphData.addBgReadings(fromTime, toTime, lowLine, highLine, null); @@ -1385,7 +1445,8 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, graphData.addNowLine(now); // ------------------ 2nd graph - Profiler.log(log, from + " - 2nd graph - START", updateGUIStart); + if (L.isEnabled(L.OVERVIEW)) + Profiler.log(log, from + " - 2nd graph - START", updateGUIStart); final GraphData secondGraphData = new GraphData(iobGraph, IobCobCalculatorPlugin.getPlugin()); @@ -1415,7 +1476,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, secondGraphData.addDeviations(fromTime, now, useDevForScale, 1d); if (SP.getBoolean("showratios", false)) secondGraphData.addRatio(fromTime, now, useRatioForScale, 1d); - if (SP.getBoolean("showdevslope", false)) + if (SP.getBoolean("showdevslope", false) && MainApp.devBranch) secondGraphData.addDeviationSlope(fromTime, now, useDSForScale, 1d); // **** NOW line **** @@ -1439,12 +1500,14 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, // finally enforce drawing of graphs graphData.performUpdate(); secondGraphData.performUpdate(); - Profiler.log(log, from + " - onDataChanged", updateGUIStart); + if (L.isEnabled(L.OVERVIEW)) + Profiler.log(log, from + " - onDataChanged", updateGUIStart); }); } }).start(); - Profiler.log(log, from, updateGUIStart); + if (L.isEnabled(L.OVERVIEW)) + Profiler.log(log, from, updateGUIStart); } //Notifications diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewPlugin.java index 67e494a76d..b184201908 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewPlugin.java @@ -15,6 +15,8 @@ import info.nightscout.androidaps.events.EventRefreshOverview; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginType; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.Overview.notifications.NotificationStore; @@ -24,7 +26,7 @@ import info.nightscout.utils.SP; * Created by mike on 05.08.2016. */ public class OverviewPlugin extends PluginBase { - private static Logger log = LoggerFactory.getLogger(OverviewPlugin.class); + private static Logger log = LoggerFactory.getLogger(L.OVERVIEW); private static OverviewPlugin overviewPlugin = new OverviewPlugin(); @@ -50,6 +52,7 @@ public class OverviewPlugin extends PluginBase { .pluginName(R.string.overview) .shortName(R.string.overview_shortname) .preferencesId(R.xml.pref_overview) + .description(R.string.description_overview) ); String storedData = SP.getString("QuickWizard", "[]"); try { @@ -90,7 +93,7 @@ public class OverviewPlugin extends PluginBase { } public double determineLowLine() { - Profile profile = MainApp.getConfigBuilder().getProfile(); + Profile profile = ProfileFunctions.getInstance().getProfile(); if (profile == null) { return bgTargetLow; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/events/EventOverviewBolusProgress.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/events/EventOverviewBolusProgress.java index 6f9526369e..18e8ff91bc 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/events/EventOverviewBolusProgress.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/events/EventOverviewBolusProgress.java @@ -7,7 +7,6 @@ import info.nightscout.androidaps.plugins.Treatments.Treatment; import info.nightscout.androidaps.events.Event; public class EventOverviewBolusProgress extends Event { - private static Logger log = LoggerFactory.getLogger(EventOverviewBolusProgress.class); public String status = ""; public Treatment t = null; public int percent = 0; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/events/EventSetWakeLock.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/events/EventSetWakeLock.java deleted file mode 100644 index 49ccf9fbfb..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/events/EventSetWakeLock.java +++ /dev/null @@ -1,15 +0,0 @@ -package info.nightscout.androidaps.plugins.Overview.events; - -import info.nightscout.androidaps.events.Event; - -/** - * Created by mike on 02.07.2017. - */ - -public class EventSetWakeLock extends Event { - public boolean lock = false; - - public EventSetWakeLock(boolean val) { - lock = val; - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphData/GraphData.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphData/GraphData.java index 30e2ad97e4..a4b3fc597a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphData/GraphData.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphData/GraphData.java @@ -11,6 +11,9 @@ import com.jjoe64.graphview.series.DataPoint; import com.jjoe64.graphview.series.LineGraphSeries; import com.jjoe64.graphview.series.Series; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -24,7 +27,9 @@ import info.nightscout.androidaps.db.CareportalEvent; import info.nightscout.androidaps.db.ExtendedBolus; import info.nightscout.androidaps.db.ProfileSwitch; import info.nightscout.androidaps.db.TempTarget; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensData; import info.nightscout.androidaps.plugins.IobCobCalculator.BasalData; import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin; @@ -47,9 +52,11 @@ import info.nightscout.utils.Round; */ public class GraphData { + private static Logger log = LoggerFactory.getLogger(L.OVERVIEW); private GraphView graph; - public double maxY = 0; + public double maxY = Double.MIN_VALUE; + public double minY = Double.MAX_VALUE; private List bgReadingsArray; private String units; private List series = new ArrayList<>(); @@ -57,21 +64,25 @@ public class GraphData { private IobCobCalculatorPlugin iobCobCalculatorPlugin; public GraphData(GraphView graph, IobCobCalculatorPlugin iobCobCalculatorPlugin) { - units = MainApp.getConfigBuilder().getProfileUnits(); + units = ProfileFunctions.getInstance().getProfileUnits(); this.graph = graph; this.iobCobCalculatorPlugin = iobCobCalculatorPlugin; } public void addBgReadings(long fromTime, long toTime, double lowLine, double highLine, List predictions) { - double maxBgValue = 0d; - bgReadingsArray = MainApp.getDbHelper().getBgreadingsDataFromTime(fromTime, true); + double maxBgValue = Double.MIN_VALUE; + //bgReadingsArray = MainApp.getDbHelper().getBgreadingsDataFromTime(fromTime, true); + bgReadingsArray = iobCobCalculatorPlugin.getBgReadings(); List bgListArray = new ArrayList<>(); - if (bgReadingsArray.size() == 0) { + if (bgReadingsArray == null || bgReadingsArray.size() == 0) { + if (L.isEnabled(L.OVERVIEW)) + log.debug("No BG data."); return; } for (BgReading bg : bgReadingsArray) { + if (bg.date < fromTime || bg.date > toTime) continue; if (bg.value > maxBgValue) maxBgValue = bg.value; bgListArray.add(bg); } @@ -93,10 +104,8 @@ public class GraphData { maxY = maxBgValue; + minY = 0; // set manual y bounds to have nice steps - graph.getViewport().setMaxY(maxY); - graph.getViewport().setMinY(0); - graph.getViewport().setYAxisBoundsManual(true); graph.getGridLabelRenderer().setNumVerticalLabels(numOfVertLines); addSeries(new PointsWithLabelGraphSeries<>(bg)); @@ -136,9 +145,9 @@ public class GraphData { double lastBaseBasal = 0; double lastTempBasal = 0; for (long time = fromTime; time < toTime; time += 60 * 1000L) { - Profile profile = MainApp.getConfigBuilder().getProfile(time); + Profile profile = ProfileFunctions.getInstance().getProfile(time); if (profile == null) continue; - BasalData basalData = IobCobCalculatorPlugin.getPlugin().getBasalData(profile, time); + BasalData basalData = iobCobCalculatorPlugin.getBasalData(profile, time); double baseBasalValue = basalData.basal; double absoluteLineValue = baseBasalValue; double tempBasalValue = 0; @@ -234,7 +243,7 @@ public class GraphData { targetsScale.setMultiplier(1); List targetsSeriesArray = new ArrayList<>(); - double lastTarget = 0; + double lastTarget = -1; if (LoopPlugin.lastRun != null && LoopPlugin.lastRun.constraintsProcessed != null) { APSResult apsResult = LoopPlugin.lastRun.constraintsProcessed; @@ -244,22 +253,22 @@ public class GraphData { } } - for (long time = fromTime; time < toTime; time += 60 * 1000L) { + for (long time = fromTime; time < toTime; time += 5 * 60 * 1000L) { TempTarget tt = TreatmentsPlugin.getPlugin().getTempTargetFromHistory(time); double value; if (tt == null) { value = (profile.getTargetLow(time) + profile.getTargetHigh(time)) / 2; } else { - value = tt.target(); - value = Profile.fromMgdlToUnits(value, profile.getUnits()); + value = Profile.fromMgdlToUnits(tt.target(), profile.getUnits()); } - if (lastTarget > 0 && lastTarget != value) { - targetsSeriesArray.add(new DataPoint(time, lastTarget)); + if (lastTarget != value) { + if (lastTarget != -1) + targetsSeriesArray.add(new DataPoint(time, lastTarget)); + targetsSeriesArray.add(new DataPoint(time, value)); } lastTarget = value; - - targetsSeriesArray.add(new DataPoint(time, value)); } + targetsSeriesArray.add(new DataPoint(toTime, lastTarget)); DataPoint[] targets = new DataPoint[targetsSeriesArray.size()]; targets = targetsSeriesArray.toArray(targets); @@ -294,7 +303,7 @@ public class GraphData { } // Extended bolus - if (!ConfigBuilderPlugin.getActivePump().isFakingTempsByExtendedBoluses()) { + if (!ConfigBuilderPlugin.getPlugin().getActivePump().isFakingTempsByExtendedBoluses()) { List extendedBoluses = TreatmentsPlugin.getPlugin().getExtendedBolusesFromHistory().getList(); for (int tx = 0; tx < extendedBoluses.size(); tx++) { @@ -322,28 +331,30 @@ public class GraphData { } private double getNearestBg(long date) { - for (int r = bgReadingsArray.size() - 1; r >= 0; r--) { + if (bgReadingsArray == null) + return Profile.fromMgdlToUnits(100, units); + for (int r = 0; r < bgReadingsArray.size(); r++) { BgReading reading = bgReadingsArray.get(r); if (reading.date > date) continue; return Profile.fromMgdlToUnits(reading.value, units); } return bgReadingsArray.size() > 0 - ? Profile.fromMgdlToUnits(bgReadingsArray.get(0).value, units) : 0; + ? Profile.fromMgdlToUnits(bgReadingsArray.get(0).value, units) : Profile.fromMgdlToUnits(100, units); } // scale in % of vertical size (like 0.3) public void addIob(long fromTime, long toTime, boolean useForScale, double scale) { FixedLineGraphSeries iobSeries; List iobArray = new ArrayList<>(); - Double maxIobValueFound = 0d; + Double maxIobValueFound = Double.MIN_VALUE; double lastIob = 0; Scale iobScale = new Scale(); for (long time = fromTime; time <= toTime; time += 5 * 60 * 1000L) { - Profile profile = MainApp.getConfigBuilder().getProfile(time); + Profile profile = ProfileFunctions.getInstance().getProfile(time); double iob = 0d; if (profile != null) - iob = IobCobCalculatorPlugin.getPlugin().calculateFromTreatmentsAndTempsSynchronized(time, profile).iob; + iob = iobCobCalculatorPlugin.calculateFromTreatmentsAndTempsSynchronized(time, profile).iob; if (Math.abs(lastIob - iob) > 0.02) { if (Math.abs(lastIob - iob) > 0.2) iobArray.add(new ScaledDataPoint(time, lastIob, iobScale)); @@ -361,8 +372,10 @@ public class GraphData { iobSeries.setColor(MainApp.gc(R.color.iob)); iobSeries.setThickness(3); - if (useForScale) + if (useForScale) { maxY = maxIobValueFound; + minY = -maxIobValueFound; + } iobScale.setMultiplier(maxY * scale / maxIobValueFound); @@ -379,7 +392,7 @@ public class GraphData { Scale cobScale = new Scale(); for (long time = fromTime; time <= toTime; time += 5 * 60 * 1000L) { - AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getAutosensData(time); + AutosensData autosensData = iobCobCalculatorPlugin.getAutosensData(time); if (autosensData != null) { int cob = (int) autosensData.cob; if (cob != lastCob) { @@ -406,8 +419,10 @@ public class GraphData { cobSeries.setColor(MainApp.gc(R.color.cob)); cobSeries.setThickness(3); - if (useForScale) + if (useForScale) { maxY = maxCobValueFound; + minY = 0; + } cobScale.setMultiplier(maxY * scale / maxCobValueFound); @@ -435,12 +450,21 @@ public class GraphData { Scale devScale = new Scale(); for (long time = fromTime; time <= toTime; time += 5 * 60 * 1000L) { - AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getAutosensData(time); + AutosensData autosensData = iobCobCalculatorPlugin.getAutosensData(time); if (autosensData != null) { int color = MainApp.gc(R.color.deviationblack); // "=" - if (autosensData.pastSensitivity.equals("C")) color = MainApp.gc(R.color.deviationgrey); - if (autosensData.pastSensitivity.equals("+")) color = MainApp.gc(R.color.deviationgreen); - if (autosensData.pastSensitivity.equals("-")) color = MainApp.gc(R.color.deviationred); + if (autosensData.type.equals("") || autosensData.type.equals("non-meal")) { + if (autosensData.pastSensitivity.equals("C")) + color = MainApp.gc(R.color.deviationgrey); + if (autosensData.pastSensitivity.equals("+")) + color = MainApp.gc(R.color.deviationgreen); + if (autosensData.pastSensitivity.equals("-")) + color = MainApp.gc(R.color.deviationred); + } else if (autosensData.type.equals("uam")) { + color = MainApp.gc(R.color.uam); + } else if (autosensData.type.equals("csf")) { + color = MainApp.gc(R.color.deviationgrey); + } devArray.add(new DeviationDataPoint(time, autosensData.deviation, color, devScale)); maxDevValueFound = Math.max(maxDevValueFound, Math.abs(autosensData.deviation)); } @@ -457,8 +481,10 @@ public class GraphData { } }); - if (useForScale) + if (useForScale) { maxY = maxDevValueFound; + minY = -maxY; + } devScale.setMultiplier(maxY * scale / maxDevValueFound); @@ -469,14 +495,16 @@ public class GraphData { public void addRatio(long fromTime, long toTime, boolean useForScale, double scale) { LineGraphSeries ratioSeries; List ratioArray = new ArrayList<>(); - Double maxRatioValueFound = 0d; - Scale ratioScale = new Scale(-1d); + Double maxRatioValueFound = Double.MIN_VALUE; + Double minRatioValueFound = Double.MAX_VALUE; + Scale ratioScale = new Scale(); for (long time = fromTime; time <= toTime; time += 5 * 60 * 1000L) { - AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getAutosensData(time); + AutosensData autosensData = iobCobCalculatorPlugin.getAutosensData(time); if (autosensData != null) { - ratioArray.add(new ScaledDataPoint(time, autosensData.autosensRatio, ratioScale)); - maxRatioValueFound = Math.max(maxRatioValueFound, Math.abs(autosensData.autosensRatio)); + ratioArray.add(new ScaledDataPoint(time, autosensData.autosensResult.ratio - 1, ratioScale)); + maxRatioValueFound = Math.max(maxRatioValueFound, autosensData.autosensResult.ratio - 1); + minRatioValueFound = Math.min(minRatioValueFound, autosensData.autosensResult.ratio - 1); } } @@ -487,10 +515,12 @@ public class GraphData { ratioSeries.setColor(MainApp.gc(R.color.ratio)); ratioSeries.setThickness(3); - if (useForScale) - maxY = maxRatioValueFound; + if (useForScale) { + maxY = Math.max(maxRatioValueFound, Math.abs(minRatioValueFound)); + minY = -maxY; + } - ratioScale.setMultiplier(maxY * scale / maxRatioValueFound); + ratioScale.setMultiplier(maxY * scale / Math.max(maxRatioValueFound, Math.abs(minRatioValueFound))); addSeries(ratioSeries); } @@ -507,7 +537,7 @@ public class GraphData { Scale dsMinScale = new Scale(); for (long time = fromTime; time <= toTime; time += 5 * 60 * 1000L) { - AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getAutosensData(time); + AutosensData autosensData = iobCobCalculatorPlugin.getAutosensData(time); if (autosensData != null) { dsMaxArray.add(new ScaledDataPoint(time, autosensData.slopeFromMaxDeviation, dsMaxScale)); dsMinArray.add(new ScaledDataPoint(time, autosensData.slopeFromMinDeviation, dsMinScale)); @@ -529,8 +559,10 @@ public class GraphData { dsMinSeries.setColor(MainApp.gc(R.color.devslopeneg)); dsMinSeries.setThickness(3); - if (useForScale) + if (useForScale) { maxY = Math.max(maxFromMaxValueFound, maxFromMinValueFound); + minY = -maxY; + } dsMaxScale.setMultiplier(maxY * scale / maxFromMaxValueFound); dsMinScale.setMultiplier(maxY * scale / maxFromMinValueFound); @@ -584,6 +616,12 @@ public class GraphData { } } + double step = 1d; + if (maxY < 1) step = 0.1d; + graph.getViewport().setMaxY(Round.ceilTo(maxY, step)); + graph.getViewport().setMinY(Round.floorTo(minY, step)); + graph.getViewport().setYAxisBoundsManual(true); + // draw it graph.onDataChanged(false, false); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphExtensions/PointsWithLabelGraphSeries.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphExtensions/PointsWithLabelGraphSeries.java index 5f39cedafe..4a87a8508e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphExtensions/PointsWithLabelGraphSeries.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphExtensions/PointsWithLabelGraphSeries.java @@ -312,20 +312,20 @@ public class PointsWithLabelGraphSeries e mPaint.setStrokeWidth(5); canvas.drawRect(px - 3, bounds.top + py - 3, xpluslength + 3, bounds.bottom + py + 3, mPaint); } - } else if (value.getShape() == Shape.OPENAPSOFFLINE) { + } else if (value.getShape() == Shape.OPENAPSOFFLINE && value.getDuration() != 0) { mPaint.setStrokeWidth(0); if (value.getLabel() != null) { - mPaint.setStrokeWidth(0); - mPaint.setTextSize(scaledTextSize); - mPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD)); + //mPaint.setStrokeWidth(0); + //mPaint.setTextSize(scaledTextSize); + //mPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD)); Rect bounds = new Rect(); - mPaint.getTextBounds(value.getLabel(), 0, value.getLabel().length(), bounds); - mPaint.setStyle(Paint.Style.STROKE); + //mPaint.getTextBounds(value.getLabel(), 0, value.getLabel().length(), bounds); + mPaint.setStyle(Paint.Style.FILL_AND_STROKE); float px = endX; float py = graphTop + 50; - canvas.drawText(value.getLabel(), px, py, mPaint); + //canvas.drawText(value.getLabel(), px, py, mPaint); mPaint.setStrokeWidth(5); - canvas.drawRect(px - 3, bounds.top + py - 3, xpluslength + 3, bounds.bottom + py + 3, mPaint); + canvas.drawRect(px - 3, graphTop, xpluslength + 3, graphTop + graphHeight, mPaint); } } else if (value.getShape() == Shape.GENERALWITHDURATION) { mPaint.setStrokeWidth(0); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/notifications/Notification.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/notifications/Notification.java index 9a374bf3f3..f6f291ddc2 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/notifications/Notification.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/notifications/Notification.java @@ -20,8 +20,6 @@ import info.nightscout.utils.SP; */ public class Notification { - private static Logger log = LoggerFactory.getLogger(Notification.class); - public static final int URGENT = 0; public static final int NORMAL = 1; public static final int LOW = 2; @@ -42,6 +40,8 @@ public class Notification { public static final int APPROACHING_DAILY_LIMIT = 11; public static final int NSCLIENT_NO_WRITE_PERMISSION = 12; public static final int MISSING_SMS_PERMISSION = 13; + public static final int PUMPERROR = 14; + public static final int WRONGSERIALNUMBER = 15; public static final int NSANNOUNCEMENT = 18; public static final int NSALARM = 19; @@ -64,6 +64,13 @@ public class Notification { public static final int PERMISSION_LOCATION = 36; public static final int PERMISSION_BATTERY = 37; public static final int PERMISSION_SMS = 38; + public static final int MAXIMUM_BASAL_VALUE_REPLACED = 39; + public static final int NSMALFUNCTION = 40; + public static final int NEWVERSIONDETECTED = 41; + public static final int SENDLOGFILES = 42; + public static final int DEVICENOTPAIRED = 43; + public static final int MEDTRONIC_PUMP_ALARM = 44; + public static final int RILEYLINK_CONNECTION = 45; public int id; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/notifications/NotificationRecyclerViewAdapter.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/notifications/NotificationRecyclerViewAdapter.java index 895b99a43e..9af6be3be3 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/notifications/NotificationRecyclerViewAdapter.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/notifications/NotificationRecyclerViewAdapter.java @@ -17,6 +17,7 @@ import java.util.Objects; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.NSClientInternal.broadcasts.BroadcastAckAlarm; import info.nightscout.androidaps.plugins.Overview.OverviewPlugin; import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification; @@ -24,7 +25,7 @@ import info.nightscout.utils.DateUtil; import info.nightscout.utils.SP; public class NotificationRecyclerViewAdapter extends RecyclerView.Adapter { - private static Logger log = LoggerFactory.getLogger(NotificationRecyclerViewAdapter.class); + private static Logger log = LoggerFactory.getLogger(L.NOTIFICATION); private List notificationsList; @@ -96,11 +97,13 @@ public class NotificationRecyclerViewAdapter extends RecyclerView.Adapter store = new ArrayList(); - public long snoozedUntil = 0L; + private static Logger log = LoggerFactory.getLogger(L.NOTIFICATION); + public List store = new ArrayList<>(); private boolean usesChannels; public NotificationStore() { @@ -51,7 +52,8 @@ public class NotificationStore { } public synchronized boolean add(Notification n) { - log.info("Notification received: " + n.text); + if (L.isEnabled(L.NOTIFICATION)) + log.debug("Notification received: " + n.text); for (Notification storeNotification : store) { if (storeNotification.id == n.id) { storeNotification.date = n.date; @@ -106,7 +108,8 @@ public class NotificationStore { } public void snoozeTo(long timeToSnooze) { - log.debug("Snoozing alarm until: " + timeToSnooze); + if (L.isEnabled(L.NOTIFICATION)) + log.debug("Snoozing alarm until: " + timeToSnooze); SP.putLong("snoozedTo", timeToSnooze); } @@ -115,7 +118,8 @@ public class NotificationStore { Notification notification = new Notification(Notification.NSALARM, MainApp.gs(R.string.nsalarm_staledata), Notification.URGENT); SP.putLong("snoozedTo", System.currentTimeMillis()); add(notification); - log.debug("Snoozed to current time and added back notification!"); + if (L.isEnabled(L.NOTIFICATION)) + log.debug("Snoozed to current time and added back notification!"); } } @@ -123,10 +127,15 @@ public class NotificationStore { Context context = MainApp.instance().getApplicationContext(); NotificationManager mgr = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); Bitmap largeIcon = BitmapFactory.decodeResource(context.getResources(), R.mipmap.blueowl); + int smallIcon = R.drawable.ic_notification; + if (Config.NSCLIENT) { + largeIcon = BitmapFactory.decodeResource(MainApp.instance().getResources(), R.mipmap.yellowowl); + smallIcon = R.drawable.nsclient_smallicon; + } Uri sound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM); NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, CHANNEL_ID) - .setSmallIcon(R.drawable.ic_notification) + .setSmallIcon(smallIcon) .setLargeIcon(largeIcon) .setContentText(n.text) .setPriority(NotificationCompat.PRIORITY_MAX) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Persistentnotification/DummyService.java b/app/src/main/java/info/nightscout/androidaps/plugins/Persistentnotification/DummyService.java new file mode 100644 index 0000000000..56b3a2cd09 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Persistentnotification/DummyService.java @@ -0,0 +1,58 @@ +package info.nightscout.androidaps.plugins.Persistentnotification; + +import android.app.Notification; +import android.app.Service; +import android.content.Intent; +import android.os.IBinder; +import android.support.annotation.Nullable; + +import com.squareup.otto.Subscribe; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.events.EventAppExit; +import info.nightscout.androidaps.logging.L; + +/** + * Keeps AndroidAPS in foreground state, so it won't be terminated by Android nor get restricted by the background execution limits + */ +public class DummyService extends Service { + private static Logger log = LoggerFactory.getLogger(L.CORE); + + @Nullable + @Override + public IBinder onBind(Intent intent) { + return null; + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + Notification notification = PersistentNotificationPlugin.getPlugin().updateNotification(); + if (notification != null) + startForeground(PersistentNotificationPlugin.ONGOING_NOTIFICATION_ID, notification); + return START_STICKY; + } + + @Subscribe + public void onStatusEvent(EventAppExit event) { + if (L.isEnabled(L.CORE)) + log.debug("EventAppExit received"); + + stopSelf(); + } + + @Override + public void onCreate() { + MainApp.bus().register(this); + } + + @Override + public void onDestroy() { + if (L.isEnabled(L.CORE)) + log.debug("onDestroy"); + MainApp.bus().unregister(this); + stopForeground(true); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Persistentnotification/PersistentNotificationPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Persistentnotification/PersistentNotificationPlugin.java index ed57652d1f..cd69e88210 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Persistentnotification/PersistentNotificationPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Persistentnotification/PersistentNotificationPlugin.java @@ -1,6 +1,7 @@ package info.nightscout.androidaps.plugins.Persistentnotification; import android.annotation.SuppressLint; +import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; @@ -14,6 +15,7 @@ import android.support.v4.app.TaskStackBuilder; import com.squareup.otto.Subscribe; +import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainActivity; import info.nightscout.androidaps.MainApp; @@ -35,7 +37,7 @@ import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; -import info.nightscout.androidaps.plugins.IobCobCalculator.CobInfo; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.utils.DecimalFormatter; @@ -46,9 +48,16 @@ import info.nightscout.utils.DecimalFormatter; public class PersistentNotificationPlugin extends PluginBase { + private static PersistentNotificationPlugin plugin; + + public static PersistentNotificationPlugin getPlugin() { + if (plugin == null) plugin = new PersistentNotificationPlugin(MainApp.instance()); + return plugin; + } + public static final String CHANNEL_ID = "AndroidAPS-Ongoing"; - private static final int ONGOING_NOTIFICATION_ID = 4711; + public static final int ONGOING_NOTIFICATION_ID = 4711; private final Context ctx; public PersistentNotificationPlugin(Context ctx) { @@ -57,6 +66,8 @@ public class PersistentNotificationPlugin extends PluginBase { .neverVisible(true) .pluginName(R.string.ongoingnotificaction) .enableByDefault(true) + .alwaysEnabled(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) + .description(R.string.description_persistent_notification) ); this.ctx = ctx; } @@ -65,7 +76,7 @@ public class PersistentNotificationPlugin extends PluginBase { protected void onStart() { MainApp.bus().register(this); createNotificationChannel(); - updateNotification(); + triggerNotificationUpdate(); super.onStart(); } @@ -84,21 +95,23 @@ public class PersistentNotificationPlugin extends PluginBase { @Override protected void onStop() { MainApp.bus().unregister(this); - NotificationManager mNotificationManager = - (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE); - mNotificationManager.cancel(ONGOING_NOTIFICATION_ID); + MainApp.instance().stopService(new Intent(MainApp.instance(), DummyService.class)); } - private void updateNotification() { + private void triggerNotificationUpdate() { + MainApp.instance().startService(new Intent(MainApp.instance(), DummyService.class)); + } + + Notification updateNotification() { if (!isEnabled(PluginType.GENERAL)) { - return; + return null; } String line1 = ""; - if (MainApp.getConfigBuilder().getActiveProfileInterface() == null || !MainApp.getConfigBuilder().isProfileValid("Notificiation")) - return; - String units = MainApp.getConfigBuilder().getProfileUnits(); + if (ConfigBuilderPlugin.getPlugin().getActiveProfileInterface() == null || !ProfileFunctions.getInstance().isProfileValid("Notificiation")) + return null; + String units = ProfileFunctions.getInstance().getProfileUnits(); BgReading lastBG = DatabaseHelper.lastBg(); @@ -132,19 +145,25 @@ public class PersistentNotificationPlugin extends PluginBase { String line2 = MainApp.gs(R.string.treatments_iob_label_string) + " " + DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U " + MainApp.gs(R.string.cob)+": " + IobCobCalculatorPlugin.getPlugin().getCobInfo(false, "PersistentNotificationPlugin").generateCOBString();; - String line3 = DecimalFormatter.to2Decimal(ConfigBuilderPlugin.getActivePump().getBaseBasalRate()) + " U/h"; + String line3 = DecimalFormatter.to2Decimal(ConfigBuilderPlugin.getPlugin().getActivePump().getBaseBasalRate()) + " U/h"; - line3 += " - " + MainApp.getConfigBuilder().getProfileName(); + line3 += " - " + ProfileFunctions.getInstance().getProfileName(); NotificationCompat.Builder builder = new NotificationCompat.Builder(ctx, CHANNEL_ID); builder.setOngoing(true); builder.setOnlyAlertOnce(true); builder.setCategory(NotificationCompat.CATEGORY_STATUS); - builder.setSmallIcon(R.drawable.ic_notification); - Bitmap largeIcon = BitmapFactory.decodeResource(ctx.getResources(), R.mipmap.blueowl); - builder.setLargeIcon(largeIcon); + if (Config.NSCLIENT){ + builder.setSmallIcon(R.drawable.nsclient_smallicon); + Bitmap largeIcon = BitmapFactory.decodeResource(ctx.getResources(), R.mipmap.yellowowl); + builder.setLargeIcon(largeIcon); + } else { + builder.setSmallIcon(R.drawable.ic_notification); + Bitmap largeIcon = BitmapFactory.decodeResource(ctx.getResources(), R.mipmap.blueowl); + builder.setLargeIcon(largeIcon); + } builder.setContentTitle(line1); builder.setContentText(line2); builder.setSubText(line3); @@ -165,7 +184,7 @@ public class PersistentNotificationPlugin extends PluginBase { android.app.Notification notification = builder.build(); mNotificationManager.notify(ONGOING_NOTIFICATION_ID, notification); - + return notification; } private String deltastring(double deltaMGDL, double deltaMMOL, String units) { @@ -187,42 +206,42 @@ public class PersistentNotificationPlugin extends PluginBase { @Subscribe public void onStatusEvent(final EventPreferenceChange ev) { - updateNotification(); + triggerNotificationUpdate(); } @Subscribe public void onStatusEvent(final EventTreatmentChange ev) { - updateNotification(); + triggerNotificationUpdate(); } @Subscribe public void onStatusEvent(final EventTempBasalChange ev) { - updateNotification(); + triggerNotificationUpdate(); } @Subscribe public void onStatusEvent(final EventExtendedBolusChange ev) { - updateNotification(); + triggerNotificationUpdate(); } @Subscribe public void onStatusEvent(final EventNewBG ev) { - updateNotification(); + triggerNotificationUpdate(); } @Subscribe public void onStatusEvent(final EventNewBasalProfile ev) { - updateNotification(); + triggerNotificationUpdate(); } @Subscribe public void onStatusEvent(final EventInitializationChanged ev) { - updateNotification(); + triggerNotificationUpdate(); } @Subscribe public void onStatusEvent(final EventRefreshOverview ev) { - updateNotification(); + triggerNotificationUpdate(); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileLocal/LocalProfileFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileLocal/LocalProfileFragment.java index 39d0f9829d..fc45928f89 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileLocal/LocalProfileFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileLocal/LocalProfileFragment.java @@ -25,20 +25,18 @@ import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.ProfileStore; import info.nightscout.androidaps.events.EventInitializationChanged; import info.nightscout.androidaps.interfaces.PumpDescription; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.Careportal.CareportalFragment; import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialog; import info.nightscout.androidaps.plugins.Careportal.OptionsToShow; import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.utils.DecimalFormatter; -import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.NumberPicker; import info.nightscout.utils.SafeParse; import info.nightscout.utils.TimeListEdit; public class LocalProfileFragment extends SubscriberFragment { - private static Logger log = LoggerFactory.getLogger(LocalProfileFragment.class); - NumberPicker diaView; RadioButton mgdlView; RadioButton mmolView; @@ -81,80 +79,72 @@ public class LocalProfileFragment extends SubscriberFragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - try { + PumpDescription pumpDescription = ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription(); + View layout = inflater.inflate(R.layout.localprofile_fragment, container, false); + diaView = (NumberPicker) layout.findViewById(R.id.localprofile_dia); + diaView.setParams(LocalProfilePlugin.getPlugin().dia, 2d, 48d, 0.1d, new DecimalFormat("0.0"), false, textWatch); + mgdlView = (RadioButton) layout.findViewById(R.id.localprofile_mgdl); + mmolView = (RadioButton) layout.findViewById(R.id.localprofile_mmol); + icView = new TimeListEdit(getContext(), layout, R.id.localprofile_ic, MainApp.gs(R.string.nsprofileview_ic_label) + ":", LocalProfilePlugin.getPlugin().ic, null, 0.5, 50d, 0.1d, new DecimalFormat("0.0"), save); + isfView = new TimeListEdit(getContext(), layout, R.id.localprofile_isf, MainApp.gs(R.string.nsprofileview_isf_label) + ":", LocalProfilePlugin.getPlugin().isf, null, 0.5, 500d, 0.1d, new DecimalFormat("0.0"), save); + basalView = new TimeListEdit(getContext(), layout, R.id.localprofile_basal, MainApp.gs(R.string.nsprofileview_basal_label) + ": " + getSumLabel(), LocalProfilePlugin.getPlugin().basal, null, pumpDescription.basalMinimumRate, 10, 0.01d, new DecimalFormat("0.00"), save); + targetView = new TimeListEdit(getContext(), layout, R.id.localprofile_target, MainApp.gs(R.string.nsprofileview_target_label) + ":", LocalProfilePlugin.getPlugin().targetLow, LocalProfilePlugin.getPlugin().targetHigh, 3d, 200, 0.1d, new DecimalFormat("0.0"), save); + profileswitchButton = (Button) layout.findViewById(R.id.localprofile_profileswitch); + resetButton = (Button) layout.findViewById(R.id.localprofile_reset); + saveButton = (Button) layout.findViewById(R.id.localprofile_save); - PumpDescription pumpDescription = ConfigBuilderPlugin.getActivePump().getPumpDescription(); - View layout = inflater.inflate(R.layout.localprofile_fragment, container, false); - diaView = (NumberPicker) layout.findViewById(R.id.localprofile_dia); - diaView.setParams(LocalProfilePlugin.getPlugin().dia, 2d, 48d, 0.1d, new DecimalFormat("0.0"), false, textWatch); - mgdlView = (RadioButton) layout.findViewById(R.id.localprofile_mgdl); - mmolView = (RadioButton) layout.findViewById(R.id.localprofile_mmol); + + invalidProfile = (TextView) layout.findViewById(R.id.invalidprofile); + + if (!ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().isTempBasalCapable) { + layout.findViewById(R.id.localprofile_basal).setVisibility(View.GONE); + } + + mgdlView.setChecked(LocalProfilePlugin.getPlugin().mgdl); + mmolView.setChecked(LocalProfilePlugin.getPlugin().mmol); + + mgdlView.setOnClickListener(v -> { + LocalProfilePlugin.getPlugin().mgdl = mgdlView.isChecked(); + LocalProfilePlugin.getPlugin().mmol = !LocalProfilePlugin.getPlugin().mgdl; + mmolView.setChecked(LocalProfilePlugin.getPlugin().mmol); + doEdit(); + }); + mmolView.setOnClickListener(v -> { + LocalProfilePlugin.getPlugin().mmol = mmolView.isChecked(); + LocalProfilePlugin.getPlugin().mgdl = !LocalProfilePlugin.getPlugin().mmol; + mgdlView.setChecked(LocalProfilePlugin.getPlugin().mgdl); + doEdit(); + }); + + profileswitchButton.setOnClickListener(view -> { + NewNSTreatmentDialog newDialog = new NewNSTreatmentDialog(); + final OptionsToShow profileswitch = CareportalFragment.PROFILESWITCHDIRECT; + profileswitch.executeProfileSwitch = true; + newDialog.setOptions(profileswitch, R.string.careportal_profileswitch); + newDialog.show(getFragmentManager(), "NewNSTreatmentDialog"); + }); + + resetButton.setOnClickListener(view -> { + LocalProfilePlugin.getPlugin().loadSettings(); + mgdlView.setChecked(LocalProfilePlugin.getPlugin().mgdl); + mmolView.setChecked(LocalProfilePlugin.getPlugin().mmol); + diaView.setParams(LocalProfilePlugin.getPlugin().dia, 5d, 12d, 0.1d, new DecimalFormat("0.0"), false, textWatch); icView = new TimeListEdit(getContext(), layout, R.id.localprofile_ic, MainApp.gs(R.string.nsprofileview_ic_label) + ":", LocalProfilePlugin.getPlugin().ic, null, 0.5, 50d, 0.1d, new DecimalFormat("0.0"), save); isfView = new TimeListEdit(getContext(), layout, R.id.localprofile_isf, MainApp.gs(R.string.nsprofileview_isf_label) + ":", LocalProfilePlugin.getPlugin().isf, null, 0.5, 500d, 0.1d, new DecimalFormat("0.0"), save); basalView = new TimeListEdit(getContext(), layout, R.id.localprofile_basal, MainApp.gs(R.string.nsprofileview_basal_label) + ": " + getSumLabel(), LocalProfilePlugin.getPlugin().basal, null, pumpDescription.basalMinimumRate, 10, 0.01d, new DecimalFormat("0.00"), save); targetView = new TimeListEdit(getContext(), layout, R.id.localprofile_target, MainApp.gs(R.string.nsprofileview_target_label) + ":", LocalProfilePlugin.getPlugin().targetLow, LocalProfilePlugin.getPlugin().targetHigh, 3d, 200, 0.1d, new DecimalFormat("0.0"), save); - profileswitchButton = (Button) layout.findViewById(R.id.localprofile_profileswitch); - resetButton = (Button) layout.findViewById(R.id.localprofile_reset); - saveButton = (Button) layout.findViewById(R.id.localprofile_save); + updateGUI(); + }); - - invalidProfile = (TextView) layout.findViewById(R.id.invalidprofile); - - if (!ConfigBuilderPlugin.getActivePump().getPumpDescription().isTempBasalCapable) { - layout.findViewById(R.id.localprofile_basal).setVisibility(View.GONE); + saveButton.setOnClickListener(view -> { + if (!LocalProfilePlugin.getPlugin().isValidEditState()) { + return; //Should not happen as saveButton should not be visible if not valid } + LocalProfilePlugin.getPlugin().storeSettings(); + updateGUI(); + }); - mgdlView.setChecked(LocalProfilePlugin.getPlugin().mgdl); - mmolView.setChecked(LocalProfilePlugin.getPlugin().mmol); - - mgdlView.setOnClickListener(v -> { - LocalProfilePlugin.getPlugin().mgdl = mgdlView.isChecked(); - LocalProfilePlugin.getPlugin().mmol = !LocalProfilePlugin.getPlugin().mgdl; - mmolView.setChecked(LocalProfilePlugin.getPlugin().mmol); - doEdit(); - }); - mmolView.setOnClickListener(v -> { - LocalProfilePlugin.getPlugin().mmol = mmolView.isChecked(); - LocalProfilePlugin.getPlugin().mgdl = !LocalProfilePlugin.getPlugin().mmol; - mgdlView.setChecked(LocalProfilePlugin.getPlugin().mgdl); - doEdit(); - }); - - profileswitchButton.setOnClickListener(view -> { - NewNSTreatmentDialog newDialog = new NewNSTreatmentDialog(); - final OptionsToShow profileswitch = CareportalFragment.PROFILESWITCHDIRECT; - profileswitch.executeProfileSwitch = true; - newDialog.setOptions(profileswitch, R.string.careportal_profileswitch); - newDialog.show(getFragmentManager(), "NewNSTreatmentDialog"); - }); - - resetButton.setOnClickListener(view -> { - LocalProfilePlugin.getPlugin().loadSettings(); - mgdlView.setChecked(LocalProfilePlugin.getPlugin().mgdl); - mmolView.setChecked(LocalProfilePlugin.getPlugin().mmol); - diaView.setParams(LocalProfilePlugin.getPlugin().dia, 2d, 48d, 0.1d, new DecimalFormat("0.0"), false, textWatch); - icView = new TimeListEdit(getContext(), layout, R.id.localprofile_ic, MainApp.gs(R.string.nsprofileview_ic_label) + ":", LocalProfilePlugin.getPlugin().ic, null, 0.5, 50d, 0.1d, new DecimalFormat("0.0"), save); - isfView = new TimeListEdit(getContext(), layout, R.id.localprofile_isf, MainApp.gs(R.string.nsprofileview_isf_label) + ":", LocalProfilePlugin.getPlugin().isf, null, 0.5, 500d, 0.1d, new DecimalFormat("0.0"), save); - basalView = new TimeListEdit(getContext(), layout, R.id.localprofile_basal, MainApp.gs(R.string.nsprofileview_basal_label) + ": " + getSumLabel(), LocalProfilePlugin.getPlugin().basal, null, pumpDescription.basalMinimumRate, 10, 0.01d, new DecimalFormat("0.00"), save); - targetView = new TimeListEdit(getContext(), layout, R.id.localprofile_target, MainApp.gs(R.string.nsprofileview_target_label) + ":", LocalProfilePlugin.getPlugin().targetLow, LocalProfilePlugin.getPlugin().targetHigh, 3d, 200, 0.1d, new DecimalFormat("0.0"), save); - updateGUI(); - }); - - saveButton.setOnClickListener(view -> { - if(!LocalProfilePlugin.getPlugin().isValidEditState()){ - return; //Should not happen as saveButton should not be visible if not valid - } - LocalProfilePlugin.getPlugin().storeSettings(); - updateGUI(); - }); - - return layout; - } catch (Exception e) { - log.error("Unhandled exception: ", e); - FabricPrivacy.logException(e); - } - - return null; + return layout; } public void doEdit() { @@ -203,7 +193,7 @@ public class LocalProfileFragment extends SubscriberFragment { } //Show reset button iff data was edited - if(isEdited) { + if (isEdited) { resetButton.setVisibility(View.VISIBLE); } else { resetButton.setVisibility(View.GONE); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileLocal/LocalProfilePlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileLocal/LocalProfilePlugin.java index 95cfd60c99..7a06860327 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileLocal/LocalProfilePlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileLocal/LocalProfilePlugin.java @@ -8,7 +8,6 @@ import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; @@ -18,6 +17,7 @@ import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.ProfileInterface; +import info.nightscout.androidaps.logging.L; import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.SP; @@ -26,7 +26,7 @@ import info.nightscout.utils.SP; */ public class LocalProfilePlugin extends PluginBase implements ProfileInterface { public static final String LOCAL_PROFILE = "LocalProfile"; - private static Logger log = LoggerFactory.getLogger(LocalProfilePlugin.class); + private static Logger log = LoggerFactory.getLogger(L.PROFILE); private static LocalProfilePlugin localProfilePlugin; @@ -64,6 +64,7 @@ public class LocalProfilePlugin extends PluginBase implements ProfileInterface { .fragmentClass(LocalProfileFragment.class.getName()) .pluginName(R.string.localprofile) .shortName(R.string.localprofile_shortname) + .description(R.string.description_profile_local) ); loadSettings(); } @@ -80,13 +81,13 @@ public class LocalProfilePlugin extends PluginBase implements ProfileInterface { createAndStoreConvertedProfile(); edited = false; - if (Config.logPrefsChange) + if (L.isEnabled(L.PROFILE)) log.debug("Storing settings: " + getRawProfile().getData().toString()); MainApp.bus().post(new EventProfileStoreChanged()); } public synchronized void loadSettings() { - if (Config.logPrefsChange) + if (L.isEnabled(L.PROFILE)) log.debug("Loading stored settings"); mgdl = SP.getBoolean(LOCAL_PROFILE + "mgdl", false); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileNS/NSProfileFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileNS/NSProfileFragment.java index dca9b183a3..e3aeca0c45 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileNS/NSProfileFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileNS/NSProfileFragment.java @@ -24,10 +24,10 @@ import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.ProfileStore; import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialog; import info.nightscout.androidaps.plugins.Common.SubscriberFragment; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.ProfileNS.events.EventNSProfileUpdateGUI; import info.nightscout.androidaps.plugins.Treatments.fragments.ProfileGraph; import info.nightscout.utils.DecimalFormatter; -import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.OKDialog; import static butterknife.OnItemSelected.Callback.NOTHING_SELECTED; @@ -62,28 +62,29 @@ public class NSProfileFragment extends SubscriberFragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - try { - View view = inflater.inflate(R.layout.nsprofile_fragment, container, false); + View view = inflater.inflate(R.layout.nsprofile_fragment, container, false); - unbinder = ButterKnife.bind(this, view); - updateGUI(); - return view; - } catch (Exception e) { - FabricPrivacy.logException(e); - } - - return null; + unbinder = ButterKnife.bind(this, view); + updateGUI(); + return view; } @Subscribe public void onStatusEvent(final EventNSProfileUpdateGUI ev) { Activity activity = getActivity(); if (activity != null) - activity.runOnUiThread(() -> updateGUI()); + activity.runOnUiThread(() -> { + synchronized (NSProfileFragment.this) { + updateGUI(); + } + }); } @Override protected void updateGUI() { + if (noProfile == null || profileSpinner == null) + return; + ProfileStore profileStore = NSProfilePlugin.getPlugin().getProfile(); if (profileStore != null) { ArrayList profileList = profileStore.getProfileList(); @@ -92,7 +93,7 @@ public class NSProfileFragment extends SubscriberFragment { profileSpinner.setAdapter(adapter); // set selected to actual profile for (int p = 0; p < profileList.size(); p++) { - if (profileList.get(p).equals(MainApp.getConfigBuilder().getProfileName())) + if (profileList.get(p).equals(ProfileFunctions.getInstance().getProfileName())) profileSpinner.setSelection(p); } noProfile.setVisibility(View.GONE); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileNS/NSProfilePlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileNS/NSProfilePlugin.java index 3a66d57dad..99e4ad9115 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileNS/NSProfilePlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileNS/NSProfilePlugin.java @@ -1,10 +1,9 @@ package info.nightscout.androidaps.plugins.ProfileNS; import android.content.Intent; +import android.os.Bundle; import android.support.annotation.Nullable; -import com.squareup.otto.Subscribe; - import org.json.JSONException; import org.json.JSONObject; import org.slf4j.Logger; @@ -14,7 +13,8 @@ import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.Services.Intents; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.services.Intents; import info.nightscout.androidaps.data.ProfileStore; import info.nightscout.androidaps.events.EventProfileStoreChanged; import info.nightscout.androidaps.interfaces.PluginBase; @@ -28,7 +28,7 @@ import info.nightscout.utils.SP; * Created by mike on 05.08.2016. */ public class NSProfilePlugin extends PluginBase implements ProfileInterface { - private static Logger log = LoggerFactory.getLogger(NSProfilePlugin.class); + private static Logger log = LoggerFactory.getLogger(L.PROFILE); private static NSProfilePlugin nsProfilePlugin; @@ -49,6 +49,7 @@ public class NSProfilePlugin extends PluginBase implements ProfileInterface { .alwaysEnabled(Config.NSCLIENT) .alwayVisible(Config.NSCLIENT) .showInList(!Config.NSCLIENT) + .description(R.string.description_profile_nightscout) ); loadNSProfile(); } @@ -64,41 +65,51 @@ public class NSProfilePlugin extends PluginBase implements ProfileInterface { MainApp.bus().unregister(this); } - @Subscribe - public void storeNewProfile(ProfileStore newProfile) { - profile = new ProfileStore(newProfile.getData()); - storeNSProfile(); - MainApp.bus().post(new EventNSProfileUpdateGUI()); - MainApp.bus().post(new EventProfileStoreChanged()); + public void handleNewData(Intent intent) { + try { + Bundle bundles = intent.getExtras(); + if (bundles == null) return; + + String activeProfile = bundles.getString("activeprofile"); + String profileString = bundles.getString("profile"); + profile = new ProfileStore(new JSONObject(profileString)); + storeNSProfile(); + if (isEnabled(PluginType.PROFILE)) { + MainApp.bus().post(new EventProfileStoreChanged()); + MainApp.bus().post(new EventNSProfileUpdateGUI()); + } + if (L.isEnabled(L.PROFILE)) + log.debug("Received profileStore: " + activeProfile + " " + profile); + } catch (JSONException e) { + log.error("Unhandled exception", e); + } } private void storeNSProfile() { SP.putString("profile", profile.getData().toString()); - if (Config.logPrefsChange) + if (L.isEnabled(L.PROFILE)) log.debug("Storing profile"); } private void loadNSProfile() { - if (Config.logPrefsChange) + if (L.isEnabled(L.PROFILE)) log.debug("Loading stored profile"); String profileString = SP.getString("profile", null); if (profileString != null) { - if (Config.logPrefsChange) { + if (L.isEnabled(L.PROFILE)) log.debug("Loaded profile: " + profileString); - try { - profile = new ProfileStore(new JSONObject(profileString)); - } catch (JSONException e) { - log.error("Unhandled exception", e); - profile = null; - } + try { + profile = new ProfileStore(new JSONObject(profileString)); + } catch (JSONException e) { + log.error("Unhandled exception", e); + profile = null; } } else { - if (Config.logPrefsChange) { + if (L.isEnabled(L.PROFILE)) log.debug("Stored profile not found"); - // force restart of nsclient to fetch profile - Intent restartNSClient = new Intent(Intents.ACTION_RESTART); - MainApp.instance().getApplicationContext().sendBroadcast(restartNSClient); - } + // force restart of nsclient to fetch profile + Intent restartNSClient = new Intent(Intents.ACTION_RESTART); + MainApp.instance().getApplicationContext().sendBroadcast(restartNSClient); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileSimple/SimpleProfileFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileSimple/SimpleProfileFragment.java index 1315413e38..b4338366bd 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileSimple/SimpleProfileFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileSimple/SimpleProfileFragment.java @@ -26,12 +26,9 @@ import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialo import info.nightscout.androidaps.plugins.Careportal.OptionsToShow; import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; -import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.SafeParse; public class SimpleProfileFragment extends SubscriberFragment { - private static Logger log = LoggerFactory.getLogger(SimpleProfileFragment.class); - EditText diaView; RadioButton mgdlView; RadioButton mmolView; @@ -46,92 +43,86 @@ public class SimpleProfileFragment extends SubscriberFragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - try { - View layout = inflater.inflate(R.layout.simpleprofile_fragment, container, false); - diaView = (EditText) layout.findViewById(R.id.simpleprofile_dia); - mgdlView = (RadioButton) layout.findViewById(R.id.simpleprofile_mgdl); - mmolView = (RadioButton) layout.findViewById(R.id.simpleprofile_mmol); - icView = (EditText) layout.findViewById(R.id.simpleprofile_ic); - isfView = (EditText) layout.findViewById(R.id.simpleprofile_isf); - basalView = (EditText) layout.findViewById(R.id.simpleprofile_basalrate); - targetlowView = (EditText) layout.findViewById(R.id.simpleprofile_targetlow); - targethighView = (EditText) layout.findViewById(R.id.simpleprofile_targethigh); - profileswitchButton = (Button) layout.findViewById(R.id.simpleprofile_profileswitch); - invalidProfile = (TextView) layout.findViewById(R.id.invalidprofile); + View layout = inflater.inflate(R.layout.simpleprofile_fragment, container, false); + diaView = (EditText) layout.findViewById(R.id.simpleprofile_dia); + mgdlView = (RadioButton) layout.findViewById(R.id.simpleprofile_mgdl); + mmolView = (RadioButton) layout.findViewById(R.id.simpleprofile_mmol); + icView = (EditText) layout.findViewById(R.id.simpleprofile_ic); + isfView = (EditText) layout.findViewById(R.id.simpleprofile_isf); + basalView = (EditText) layout.findViewById(R.id.simpleprofile_basalrate); + targetlowView = (EditText) layout.findViewById(R.id.simpleprofile_targetlow); + targethighView = (EditText) layout.findViewById(R.id.simpleprofile_targethigh); + profileswitchButton = (Button) layout.findViewById(R.id.simpleprofile_profileswitch); + invalidProfile = (TextView) layout.findViewById(R.id.invalidprofile); - if (!ConfigBuilderPlugin.getActivePump().getPumpDescription().isTempBasalCapable) { - layout.findViewById(R.id.simpleprofile_basalrate).setVisibility(View.GONE); - layout.findViewById(R.id.simpleprofile_basalrate_label).setVisibility(View.GONE); - } - - mgdlView.setChecked(SimpleProfilePlugin.getPlugin().mgdl); - mmolView.setChecked(SimpleProfilePlugin.getPlugin().mmol); - diaView.setText(SimpleProfilePlugin.getPlugin().dia.toString()); - icView.setText(SimpleProfilePlugin.getPlugin().ic.toString()); - isfView.setText(SimpleProfilePlugin.getPlugin().isf.toString()); - basalView.setText(SimpleProfilePlugin.getPlugin().basal.toString()); - targetlowView.setText(SimpleProfilePlugin.getPlugin().targetLow.toString()); - targethighView.setText(SimpleProfilePlugin.getPlugin().targetHigh.toString()); - - mgdlView.setOnClickListener(v -> { - SimpleProfilePlugin.getPlugin().mgdl = mgdlView.isChecked(); - SimpleProfilePlugin.getPlugin().mmol = !SimpleProfilePlugin.getPlugin().mgdl; - mmolView.setChecked(SimpleProfilePlugin.getPlugin().mmol); - SimpleProfilePlugin.getPlugin().storeSettings(); - }); - mmolView.setOnClickListener(v -> { - SimpleProfilePlugin.getPlugin().mmol = mmolView.isChecked(); - SimpleProfilePlugin.getPlugin().mgdl = !SimpleProfilePlugin.getPlugin().mmol; - mgdlView.setChecked(SimpleProfilePlugin.getPlugin().mgdl); - SimpleProfilePlugin.getPlugin().storeSettings(); - }); - - profileswitchButton.setOnClickListener(view -> { - NewNSTreatmentDialog newDialog = new NewNSTreatmentDialog(); - final OptionsToShow profileswitch = CareportalFragment.PROFILESWITCH; - profileswitch.executeProfileSwitch = true; - newDialog.setOptions(profileswitch, R.string.careportal_profileswitch); - newDialog.show(getFragmentManager(), "NewNSTreatmentDialog"); - }); - - TextWatcher textWatch = new TextWatcher() { - - @Override - public void afterTextChanged(Editable s) { - } - - @Override - public void beforeTextChanged(CharSequence s, int start, - int count, int after) { - } - - @Override - public void onTextChanged(CharSequence s, int start, - int before, int count) { - SimpleProfilePlugin.getPlugin().dia = SafeParse.stringToDouble(diaView.getText().toString()); - SimpleProfilePlugin.getPlugin().ic = SafeParse.stringToDouble(icView.getText().toString()); - SimpleProfilePlugin.getPlugin().isf = SafeParse.stringToDouble(isfView.getText().toString()); - SimpleProfilePlugin.getPlugin().basal = SafeParse.stringToDouble(basalView.getText().toString()); - SimpleProfilePlugin.getPlugin().targetLow = SafeParse.stringToDouble(targetlowView.getText().toString()); - SimpleProfilePlugin.getPlugin().targetHigh = SafeParse.stringToDouble(targethighView.getText().toString()); - SimpleProfilePlugin.getPlugin().storeSettings(); - updateGUI(); - } - }; - - diaView.addTextChangedListener(textWatch); - icView.addTextChangedListener(textWatch); - isfView.addTextChangedListener(textWatch); - basalView.addTextChangedListener(textWatch); - targetlowView.addTextChangedListener(textWatch); - targethighView.addTextChangedListener(textWatch); - - return layout; - } catch (Exception e) { - FabricPrivacy.logException(e); + if (!ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().isTempBasalCapable) { + layout.findViewById(R.id.simpleprofile_basalrate).setVisibility(View.GONE); + layout.findViewById(R.id.simpleprofile_basalrate_label).setVisibility(View.GONE); } - return null; + mgdlView.setChecked(SimpleProfilePlugin.getPlugin().mgdl); + mmolView.setChecked(SimpleProfilePlugin.getPlugin().mmol); + diaView.setText(SimpleProfilePlugin.getPlugin().dia.toString()); + icView.setText(SimpleProfilePlugin.getPlugin().ic.toString()); + isfView.setText(SimpleProfilePlugin.getPlugin().isf.toString()); + basalView.setText(SimpleProfilePlugin.getPlugin().basal.toString()); + targetlowView.setText(SimpleProfilePlugin.getPlugin().targetLow.toString()); + targethighView.setText(SimpleProfilePlugin.getPlugin().targetHigh.toString()); + + mgdlView.setOnClickListener(v -> { + SimpleProfilePlugin.getPlugin().mgdl = mgdlView.isChecked(); + SimpleProfilePlugin.getPlugin().mmol = !SimpleProfilePlugin.getPlugin().mgdl; + mmolView.setChecked(SimpleProfilePlugin.getPlugin().mmol); + SimpleProfilePlugin.getPlugin().storeSettings(); + }); + mmolView.setOnClickListener(v -> { + SimpleProfilePlugin.getPlugin().mmol = mmolView.isChecked(); + SimpleProfilePlugin.getPlugin().mgdl = !SimpleProfilePlugin.getPlugin().mmol; + mgdlView.setChecked(SimpleProfilePlugin.getPlugin().mgdl); + SimpleProfilePlugin.getPlugin().storeSettings(); + }); + + profileswitchButton.setOnClickListener(view -> { + NewNSTreatmentDialog newDialog = new NewNSTreatmentDialog(); + final OptionsToShow profileswitch = CareportalFragment.PROFILESWITCH; + profileswitch.executeProfileSwitch = true; + newDialog.setOptions(profileswitch, R.string.careportal_profileswitch); + newDialog.show(getFragmentManager(), "NewNSTreatmentDialog"); + }); + + TextWatcher textWatch = new TextWatcher() { + + @Override + public void afterTextChanged(Editable s) { + } + + @Override + public void beforeTextChanged(CharSequence s, int start, + int count, int after) { + } + + @Override + public void onTextChanged(CharSequence s, int start, + int before, int count) { + SimpleProfilePlugin.getPlugin().dia = SafeParse.stringToDouble(diaView.getText().toString()); + SimpleProfilePlugin.getPlugin().ic = SafeParse.stringToDouble(icView.getText().toString()); + SimpleProfilePlugin.getPlugin().isf = SafeParse.stringToDouble(isfView.getText().toString()); + SimpleProfilePlugin.getPlugin().basal = SafeParse.stringToDouble(basalView.getText().toString()); + SimpleProfilePlugin.getPlugin().targetLow = SafeParse.stringToDouble(targetlowView.getText().toString()); + SimpleProfilePlugin.getPlugin().targetHigh = SafeParse.stringToDouble(targethighView.getText().toString()); + SimpleProfilePlugin.getPlugin().storeSettings(); + updateGUI(); + } + }; + + diaView.addTextChangedListener(textWatch); + icView.addTextChangedListener(textWatch); + isfView.addTextChangedListener(textWatch); + basalView.addTextChangedListener(textWatch); + targetlowView.addTextChangedListener(textWatch); + targethighView.addTextChangedListener(textWatch); + + return layout; } @Subscribe @@ -145,7 +136,7 @@ public class SimpleProfileFragment extends SubscriberFragment { if (activity != null) activity.runOnUiThread(() -> { boolean isValid = SimpleProfilePlugin.getPlugin().getProfile() != null && SimpleProfilePlugin.getPlugin().getProfile().getDefaultProfile().isValid(MainApp.gs(R.string.simpleprofile)); - if (!ConfigBuilderPlugin.getActivePump().isInitialized() || ConfigBuilderPlugin.getActivePump().isSuspended() || !isValid) { + if (!ConfigBuilderPlugin.getPlugin().getActivePump().isInitialized() || ConfigBuilderPlugin.getPlugin().getActivePump().isSuspended() || !isValid) { profileswitchButton.setVisibility(View.GONE); } else { profileswitchButton.setVisibility(View.VISIBLE); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileSimple/SimpleProfilePlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileSimple/SimpleProfilePlugin.java index b321faca50..09742bd3f9 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileSimple/SimpleProfilePlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileSimple/SimpleProfilePlugin.java @@ -9,7 +9,6 @@ import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; @@ -19,13 +18,14 @@ import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.ProfileInterface; +import info.nightscout.androidaps.logging.L; import info.nightscout.utils.SP; /** * Created by mike on 05.08.2016. */ public class SimpleProfilePlugin extends PluginBase implements ProfileInterface { - private static Logger log = LoggerFactory.getLogger(SimpleProfilePlugin.class); + private static Logger log = LoggerFactory.getLogger(L.PROFILE); private static SimpleProfilePlugin simpleProfilePlugin; @@ -52,12 +52,13 @@ public class SimpleProfilePlugin extends PluginBase implements ProfileInterface .fragmentClass(SimpleProfileFragment.class.getName()) .pluginName(R.string.simpleprofile) .shortName(R.string.simpleprofile_shortname) + .description(R.string.description_profile_simple) ); loadSettings(); } public void storeSettings() { - if (Config.logPrefsChange) + if (L.isEnabled(L.PROFILE)) log.debug("Storing settings"); SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext()); SharedPreferences.Editor editor = settings.edit(); @@ -72,13 +73,13 @@ public class SimpleProfilePlugin extends PluginBase implements ProfileInterface editor.apply(); createConvertedProfile(); - if (Config.logPrefsChange) + if (L.isEnabled(L.PROFILE)) log.debug("Storing settings: " + getRawProfile().getData().toString()); MainApp.bus().post(new EventProfileStoreChanged()); } private void loadSettings() { - if (Config.logPrefsChange) + if (L.isEnabled(L.PROFILE)) log.debug("Loading stored settings"); mgdl = SP.getBoolean("SimpleProfile" + "mgdl", true); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboFragment.java index a37069c71d..e1ae0286de 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboFragment.java @@ -77,7 +77,7 @@ public class ComboFragment extends SubscriberFragment implements View.OnClickLis switch (view.getId()) { case R.id.combo_refresh_button: refreshButton.setEnabled(false); - ConfigBuilderPlugin.getCommandQueue().readStatus("User request", new Callback() { + ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("User request", new Callback() { @Override public void run() { runOnUiThread(() -> refreshButton.setEnabled(true)); @@ -124,7 +124,7 @@ public class ComboFragment extends SubscriberFragment implements View.OnClickLis activityView.setTextColor(Color.WHITE); activityView.setTextSize(14); activityView.setText(activity); - } else if (ConfigBuilderPlugin.getCommandQueue().size() > 0) { + } else if (ConfigBuilderPlugin.getPlugin().getCommandQueue().size() > 0) { activityView.setTextColor(Color.WHITE); activityView.setTextSize(14); activityView.setText(""); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboPlugin.java index eb06d4055d..ee7feb5eaf 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboPlugin.java @@ -1,10 +1,11 @@ package info.nightscout.androidaps.plugins.PumpCombo; +import android.content.DialogInterface; import android.os.SystemClock; import android.support.annotation.NonNull; import android.support.annotation.Nullable; - -import com.crashlytics.android.answers.CustomEvent; +import android.support.v4.app.FragmentActivity; +import android.support.v7.app.AlertDialog; import org.json.JSONObject; import org.slf4j.Logger; @@ -28,7 +29,6 @@ import info.nightscout.androidaps.db.CareportalEvent; import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.TDD; import info.nightscout.androidaps.db.TemporaryBasal; -import info.nightscout.androidaps.plugins.Treatments.Treatment; import info.nightscout.androidaps.events.EventInitializationChanged; import info.nightscout.androidaps.events.EventRefreshOverview; import info.nightscout.androidaps.interfaces.Constraint; @@ -38,7 +38,10 @@ import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.PumpDescription; import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderFragment; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress; @@ -56,19 +59,17 @@ import info.nightscout.androidaps.plugins.PumpCombo.ruffyscripter.history.Bolus; import info.nightscout.androidaps.plugins.PumpCombo.ruffyscripter.history.PumpHistory; import info.nightscout.androidaps.plugins.PumpCombo.ruffyscripter.history.PumpHistoryRequest; import info.nightscout.androidaps.plugins.PumpCombo.ruffyscripter.history.Tdd; +import info.nightscout.androidaps.plugins.PumpCommon.defs.PumpType; import info.nightscout.androidaps.plugins.Treatments.Treatment; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; -import info.nightscout.androidaps.queue.Callback; -import info.nightscout.androidaps.queue.CommandQueue; import info.nightscout.utils.DateUtil; -import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.SP; /** * Created by mike on 05.08.2016. */ public class ComboPlugin extends PluginBase implements PumpInterface, ConstraintsInterface { - private static final Logger log = LoggerFactory.getLogger(ComboPlugin.class); + private static final Logger log = LoggerFactory.getLogger(L.PUMP); static final String COMBO_TBRS_SET = "combo_tbrs_set"; static final String COMBO_BOLUSES_DELIVERED = "combo_boluses_delivered"; @@ -82,42 +83,6 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint private final static PumpDescription pumpDescription = new PumpDescription(); - static { - // these properties can't be changed on the pump, some via desktop configuration software - pumpDescription.isBolusCapable = true; - pumpDescription.bolusStep = 0.1d; - - pumpDescription.isExtendedBolusCapable = false; - pumpDescription.extendedBolusStep = 0.1d; - pumpDescription.extendedBolusDurationStep = 15; - pumpDescription.extendedBolusMaxDuration = 12 * 60; - - pumpDescription.isTempBasalCapable = true; - pumpDescription.tempBasalStyle = PumpDescription.PERCENT; - - pumpDescription.maxTempPercent = 500; - pumpDescription.tempPercentStep = 10; - - pumpDescription.tempDurationStep = 15; - pumpDescription.tempDurationStep15mAllowed = true; - pumpDescription.tempDurationStep30mAllowed = true; - pumpDescription.tempMaxDuration = 24 * 60; - - - pumpDescription.isSetBasalProfileCapable = true; - pumpDescription.basalStep = 0.01d; - pumpDescription.basalMinimumRate = 0.05d; - - pumpDescription.isRefillingCapable = true; - - pumpDescription.storesCarbInfo = false; - - pumpDescription.is30minBasalRatesCapable = false; - - pumpDescription.supportsTDDs = true; - pumpDescription.needsManualTDDLoad = true; - } - @NonNull private final RuffyCommands ruffyScripter; @@ -167,8 +132,10 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint .fragmentClass(ComboFragment.class.getName()) .pluginName(R.string.combopump) .shortName(R.string.combopump_shortname) + .description(R.string.description_pump_combo) ); ruffyScripter = new RuffyScripter(MainApp.instance().getApplicationContext()); + pumpDescription.setPumpDescription(PumpType.AccuChekCombo); } public ComboPump getPump() { @@ -193,6 +160,34 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint return MainApp.gs(R.string.combo_pump_state_running); } + @Override + public void switchAllowed(ConfigBuilderFragment.PluginViewHolder.PluginSwitcher pluginSwitcher, FragmentActivity context) { + boolean allowHardwarePump = SP.getBoolean("allow_hardware_pump", false); + if (allowHardwarePump || context == null) { + pluginSwitcher.invoke(); + } else { + AlertDialog.Builder builder = new AlertDialog.Builder(context); + builder.setMessage(R.string.allow_hardware_pump_text) + .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + pluginSwitcher.invoke(); + SP.putBoolean("allow_hardware_pump", true); + if (L.isEnabled(L.PUMP)) + log.debug("First time HW pump allowed!"); + } + }) + .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + pluginSwitcher.cancel(); + if (L.isEnabled(L.PUMP)) + log.debug("User does not allow switching to HW pump!"); + } + }); + builder.create().show(); + } + } + + @Override public boolean isInitialized() { return pump.initialized; @@ -218,6 +213,15 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint return false; } + @Override + public boolean isHandshakeInProgress() { + return false; + } + + @Override + public void finishHandshaking() { + } + @Override public void connect(String reason) { // ruffyscripter establishes a connection as needed. @@ -232,7 +236,8 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint @Override public void disconnect(String reason) { - log.debug("Disconnect called with reason: " + reason); + if (L.isEnabled(L.PUMP)) + log.debug("Disconnect called with reason: " + reason); ruffyScripter.disconnect(); } @@ -320,10 +325,9 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint return basalProfile; } - @NonNull @Override - public Date lastDataTime() { - return new Date(pump.lastSuccessfulCmdTime); + public long lastDataTime() { + return pump.lastSuccessfulCmdTime; } /** @@ -331,7 +335,8 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint */ @Override public synchronized void getPumpStatus() { - log.debug("getPumpStatus called"); + if (L.isEnabled(L.PUMP)) + log.debug("getPumpStatus called"); if (!pump.initialized) { initializePump(); } else { @@ -343,16 +348,23 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint private synchronized void initializePump() { long maxWait = System.currentTimeMillis() + 15 * 1000; while (!ruffyScripter.isPumpAvailable()) { - log.debug("Waiting for ruffy service to come up ..."); + if (L.isEnabled(L.PUMP)) + log.debug("Waiting for ruffy service to come up ..."); SystemClock.sleep(100); if (System.currentTimeMillis() > maxWait) { - log.debug("ruffy service unavailable, wtf"); + if (L.isEnabled(L.PUMP)) + log.debug("ruffy service unavailable, wtf"); return; } } // trigger a connect, which will update state and check history CommandResult stateResult = runCommand(null, 1, ruffyScripter::readPumpState); + if (stateResult.invalidSetup) { + MainApp.bus().post(new EventNewNotification( + new Notification(Notification.COMBO_PUMP_ALARM, MainApp.gs(R.string.combo_invalid_setup), Notification.URGENT))); + return; + } if (!stateResult.success) { return; } @@ -360,7 +372,8 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint // note that since the history is checked upon every connect, the above already updated // the DB with any changed history records if (pumpHistoryChanged) { - log.debug("Pump history has changed and was imported"); + if (L.isEnabled(L.PUMP)) + log.debug("Pump history has changed and was imported"); pumpHistoryChanged = false; } @@ -462,7 +475,7 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint return deliverBolus(detailedBolusInfo); } else { // no bolus required, carb only treatment - TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo); + TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false); EventOverviewBolusProgress bolusingEvent = EventOverviewBolusProgress.getInstance(); bolusingEvent.t = new Treatment(); @@ -509,7 +522,8 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint // within the last 1-2 minutes if (Math.abs(previousBolus.amount - detailedBolusInfo.insulin) < 0.01 && previousBolus.timestamp + 60 * 1000 > System.currentTimeMillis()) { - log.debug("Bolu request rejected, same bolus was successfully delivered very recently"); + if (L.isEnabled(L.PUMP)) + log.debug("Bolus request rejected, same bolus was successfully delivered very recently"); return new PumpEnactResult().success(false).enacted(false) .comment(MainApp.gs(R.string.bolus_frequency_exceeded)); } @@ -529,18 +543,16 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint return new PumpEnactResult().success(false).enacted(false) .comment(MainApp.gs(R.string.combo_error_no_connection_no_bolus_delivered)); } - log.debug("Waiting for pump clock to advance for the next unused bolus record timestamp"); + if (L.isEnabled(L.PUMP)) + log.debug("Waiting for pump clock to advance for the next unused bolus record timestamp"); SystemClock.sleep(2000); timeCheckResult = runCommand(null, 0, ruffyScripter::readPumpState); waitLoops++; } if (waitLoops > 0) { long waitDuration = (System.currentTimeMillis() - waitStartTime) / 1000; - FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboBolusTimestampWait") - .putCustomAttribute("buildversion", BuildConfig.BUILDVERSION) - .putCustomAttribute("version", BuildConfig.VERSION) - .putCustomAttribute("waitTimeSecs", String.valueOf(waitDuration))); - log.debug("Waited " + waitDuration + "s for pump to switch to a fresh minute before bolusing"); + if (L.isEnabled(L.PUMP)) + log.debug("Waited " + waitDuration + "s for pump to switch to a fresh minute before bolusing"); } if (cancelBolus) { @@ -641,11 +653,7 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint } } - /** - * Updates a DetailedBolusInfo from a pump bolus and adds it as a Treatment to the DB. - * Handles edge cases when dates aren't unique which are extremely unlikely to occur, - * but if they do, the user should be warned since a bolus will be missing from calculations. - */ + /** Creates a treatment record based on the request in DetailBolusInfo and the delivered bolus. */ private boolean addBolusToTreatments(DetailedBolusInfo detailedBolusInfo, Bolus lastPumpBolus) { DetailedBolusInfo dbi = detailedBolusInfo.copy(); dbi.date = calculateFakeBolusDate(lastPumpBolus); @@ -653,30 +661,12 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint dbi.source = Source.PUMP; dbi.insulin = lastPumpBolus.amount; try { - boolean treatmentCreated = TreatmentsPlugin.getPlugin().addToHistoryTreatment(dbi); - if (!treatmentCreated) { - log.error("Adding treatment record overrode an existing record: " + dbi); - if (dbi.isSMB) { - Notification notification = new Notification(Notification.COMBO_PUMP_ALARM, MainApp.gs(R.string.combo_error_updating_treatment_record), Notification.URGENT); - MainApp.bus().post(new EventNewNotification(notification)); - } - FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboBolusToDbError") - .putCustomAttribute("buildversion", BuildConfig.BUILDVERSION) - .putCustomAttribute("version", BuildConfig.VERSION) - .putCustomAttribute("bolus", String.valueOf(lastPumpBolus.amount)) - .putCustomAttribute("issue", "record with same timestamp existed and was overridden")); - return false; - } + TreatmentsPlugin.getPlugin().addToHistoryTreatment(dbi, true); } catch (Exception e) { log.error("Adding treatment record failed", e); if (dbi.isSMB) { Notification notification = new Notification(Notification.COMBO_PUMP_ALARM, MainApp.gs(R.string.combo_error_updating_treatment_record), Notification.URGENT); MainApp.bus().post(new EventNewNotification(notification)); - FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboBolusToDbError") - .putCustomAttribute("buildversion", BuildConfig.BUILDVERSION) - .putCustomAttribute("version", BuildConfig.VERSION) - .putCustomAttribute("bolus", String.valueOf(lastPumpBolus.amount)) - .putCustomAttribute("issue", "adding record caused exception")); } return false; } @@ -702,11 +692,13 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint */ @Override public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, Profile profile, boolean force) { - log.debug("setTempBasalAbsolute called with a rate of " + absoluteRate + " for " + durationInMinutes + " min."); + if (L.isEnabled(L.PUMP)) + log.debug("setTempBasalAbsolute called with a rate of " + absoluteRate + " for " + durationInMinutes + " min."); int unroundedPercentage = Double.valueOf(absoluteRate / getBaseBasalRate() * 100).intValue(); int roundedPercentage = (int) (Math.round(absoluteRate / getBaseBasalRate() * 10) * 10); if (unroundedPercentage != roundedPercentage) { - log.debug("Rounded requested rate " + unroundedPercentage + "% -> " + roundedPercentage + "%"); + if (L.isEnabled(L.PUMP)) + log.debug("Rounded requested rate " + unroundedPercentage + "% -> " + roundedPercentage + "%"); } return setTempBasalPercent(roundedPercentage, durationInMinutes); @@ -724,7 +716,8 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint } private PumpEnactResult setTempBasalPercent(Integer percent, final Integer durationInMinutes) { - log.debug("setTempBasalPercent called with " + percent + "% for " + durationInMinutes + "min"); + if (L.isEnabled(L.PUMP)) + log.debug("setTempBasalPercent called with " + percent + "% for " + durationInMinutes + "min"); if (pumpHistoryChanged && percent > 110) { return new PumpEnactResult().success(false).enacted(false) @@ -734,13 +727,15 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint int adjustedPercent = percent; if (adjustedPercent > pumpDescription.maxTempPercent) { - log.debug("Reducing requested TBR to the maximum support by the pump: " + percent + " -> " + pumpDescription.maxTempPercent); + if (L.isEnabled(L.PUMP)) + log.debug("Reducing requested TBR to the maximum support by the pump: " + percent + " -> " + pumpDescription.maxTempPercent); adjustedPercent = pumpDescription.maxTempPercent; } if (adjustedPercent % 10 != 0) { Long rounded = Math.round(adjustedPercent / 10d) * 10; - log.debug("Rounded requested percentage:" + adjustedPercent + " -> " + rounded); + if (L.isEnabled(L.PUMP)) + log.debug("Rounded requested percentage:" + adjustedPercent + " -> " + rounded); adjustedPercent = rounded.intValue(); } @@ -789,7 +784,8 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint */ @Override public PumpEnactResult cancelTempBasal(boolean enforceNew) { - log.debug("cancelTempBasal called"); + if (L.isEnabled(L.PUMP)) + log.debug("cancelTempBasal called"); final TemporaryBasal activeTemp = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(System.currentTimeMillis()); if (enforceNew) { CommandResult stateResult = runCommand(MainApp.gs(R.string.combo_pump_action_refreshing), 2, ruffyScripter::readPumpState); @@ -799,7 +795,8 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint if (!stateResult.state.tbrActive) { return new PumpEnactResult().success(true).enacted(false); } - log.debug("cancelTempBasal: hard-cancelling TBR since force requested"); + if (L.isEnabled(L.PUMP)) + log.debug("cancelTempBasal: hard-cancelling TBR since force requested"); CommandResult cancelResult = runCommand(MainApp.gs(R.string.combo_pump_action_cancelling_tbr), 2, ruffyScripter::cancelTbr); if (!cancelResult.success) { return new PumpEnactResult().success(false).enacted(false); @@ -820,7 +817,8 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint // Let fake neutral temp keep run (see below) // Note that since this runs on the queue a connection is opened regardless, but this // case doesn't occur all that often, so it's not worth optimizing (1.3k SetTBR vs 4 cancelTBR). - log.debug("cancelTempBasal: skipping changing tbr since it already is at " + activeTemp.percentRate + "% and running for another " + activeTemp.getPlannedRemainingMinutes() + " mins."); + if (L.isEnabled(L.PUMP)) + log.debug("cancelTempBasal: skipping changing tbr since it already is at " + activeTemp.percentRate + "% and running for another " + activeTemp.getPlannedRemainingMinutes() + " mins."); return new PumpEnactResult().success(true).enacted(true) .comment("cancelTempBasal skipping changing tbr since it already is at " + activeTemp.percentRate + "% and running for another " @@ -829,7 +827,8 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint // Set a fake neutral temp to avoid TBR cancel alert. Decide 90% vs 110% based on // on whether the TBR we're cancelling is above or below 100%. final int percentage = (activeTemp.percentRate > 100) ? 110 : 90; - log.debug("cancelTempBasal: changing TBR to " + percentage + "% for 15 mins."); + if (L.isEnabled(L.PUMP)) + log.debug("cancelTempBasal: changing TBR to " + percentage + "% for 15 mins."); return setTempBasalPercent(percentage, 15); } } @@ -868,7 +867,8 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint if (!commandResult.success && retries > 0) { for (int retryAttempts = 1; !commandResult.success && retryAttempts <= retries; retryAttempts++) { - log.debug("Command was not successful, retries requested, doing retry #" + retryAttempts); + if (L.isEnabled(L.PUMP)) + log.debug("Command was not successful, retries requested, doing retry #" + retryAttempts); commandResult = commandExecution.execute(); } } @@ -886,7 +886,7 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint Notification.URGENT); n.soundId = R.raw.alarm; MainApp.bus().post(new EventNewNotification(n)); - ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, null); + ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(true, null); } updateLocalData(commandResult); } @@ -949,7 +949,8 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint long now = System.currentTimeMillis(); TemporaryBasal aapsTbr = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(now); if (aapsTbr == null || aapsTbr.percentRate != 0) { - log.debug("Creating 15m zero temp since pump is suspended"); + if (L.isEnabled(L.PUMP)) + log.debug("Creating 15m zero temp since pump is suspended"); TemporaryBasal newTempBasal = new TemporaryBasal() .date(now) .percent(0) @@ -1009,11 +1010,13 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint if (state.pumpTime == 0) { // time couldn't be read (e.g. a warning is displayed on the menu , hiding the time field) } else if (Math.abs(state.pumpTime - System.currentTimeMillis()) >= 10 * 60 * 1000) { - log.debug("Pump clock needs update, pump time: " + state.pumpTime + " (" + new Date(state.pumpTime) + ")"); + if (L.isEnabled(L.PUMP)) + log.debug("Pump clock needs update, pump time: " + state.pumpTime + " (" + new Date(state.pumpTime) + ")"); Notification notification = new Notification(Notification.COMBO_PUMP_ALARM, MainApp.gs(R.string.combo_notification_check_time_date), Notification.URGENT); MainApp.bus().post(new EventNewNotification(notification)); } else if (Math.abs(state.pumpTime - System.currentTimeMillis()) >= 3 * 60 * 1000) { - log.debug("Pump clock needs update, pump time: " + state.pumpTime + " (" + new Date(state.pumpTime) + ")"); + if (L.isEnabled(L.PUMP)) + log.debug("Pump clock needs update, pump time: " + state.pumpTime + " (" + new Date(state.pumpTime) + ")"); Notification notification = new Notification(Notification.COMBO_PUMP_ALARM, MainApp.gs(R.string.combo_notification_check_time_date), Notification.NORMAL); MainApp.bus().post(new EventNewNotification(notification)); } @@ -1062,7 +1065,7 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint n.soundId = R.raw.alarm; MainApp.bus().post(new EventNewNotification(n)); violationWarningRaisedForBolusAt = lowSuspendOnlyLoopEnforcedUntil; - ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, null); + ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(true, null); } } } @@ -1075,11 +1078,8 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint long now = System.currentTimeMillis(); TemporaryBasal aapsTbr = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(now); if (aapsTbr == null && state.tbrActive && state.tbrRemainingDuration > 2) { - 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")); + if (L.isEnabled(L.PUMP)) + log.debug("Creating temp basal from pump TBR"); TemporaryBasal newTempBasal = new TemporaryBasal() .date(now) .percent(state.tbrPercent) @@ -1087,11 +1087,8 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint .source(Source.USER); TreatmentsPlugin.getPlugin().addToHistoryTempBasal(newTempBasal); } else if (aapsTbr != null && aapsTbr.getPlannedRemainingMinutes() > 2 && !state.tbrActive) { - 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")); + if (L.isEnabled(L.PUMP)) + log.debug("Ending AAPS-TBR since pump has no TBR active"); TemporaryBasal tempStop = new TemporaryBasal() .date(now) .duration(0) @@ -1100,11 +1097,8 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint } else if (aapsTbr != null && state.tbrActive && (aapsTbr.percentRate != state.tbrPercent || Math.abs(aapsTbr.getPlannedRemainingMinutes() - state.tbrRemainingDuration) > 2)) { - 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")); + if (L.isEnabled(L.PUMP)) + log.debug("AAPSs and pump-TBR differ; ending AAPS-TBR and creating new TBR based on pump TBR"); TemporaryBasal tempStop = new TemporaryBasal() .date(now - 1000) .duration(0) @@ -1143,6 +1137,7 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint return historyResult.success; } + /** Return value indicates whether a new record was created. */ private boolean updateDbFromPumpHistory(@NonNull PumpHistory history) { boolean updated = false; for (Bolus pumpBolus : history.bolusHistory) { @@ -1152,7 +1147,7 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint dbi.source = Source.PUMP; dbi.insulin = pumpBolus.amount; dbi.eventType = CareportalEvent.CORRECTIONBOLUS; - if (TreatmentsPlugin.getPlugin().addToHistoryTreatment(dbi)) { + if (TreatmentsPlugin.getPlugin().addToHistoryTreatment(dbi, true)) { updated = true; } } @@ -1184,7 +1179,8 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint // no history, nothing to check or complain about if (quickInfoResult.history == null || quickInfoResult.history.bolusHistory.isEmpty()) { - log.debug("Setting 'pumpHistoryChanged' false"); + if (L.isEnabled(L.PUMP)) + log.debug("Setting 'pumpHistoryChanged' false"); pumpHistoryChanged = false; return null; } @@ -1193,13 +1189,15 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint List initialPumpBolusHistory = quickInfoResult.history.bolusHistory; if (recentBoluses.size() == 1 && initialPumpBolusHistory.size() >= 1 && recentBoluses.get(0).equals(quickInfoResult.history.bolusHistory.get(0))) { - log.debug("Setting 'pumpHistoryChanged' false"); + if (L.isEnabled(L.PUMP)) + log.debug("Setting 'pumpHistoryChanged' false"); pumpHistoryChanged = false; return null; } else if (recentBoluses.size() == 2 && initialPumpBolusHistory.size() >= 2 && recentBoluses.get(0).equals(quickInfoResult.history.bolusHistory.get(0)) && recentBoluses.get(1).equals(quickInfoResult.history.bolusHistory.get(1))) { - log.debug("Setting 'pumpHistoryChanged' false"); + if (L.isEnabled(L.PUMP)) + log.debug("Setting 'pumpHistoryChanged' false"); pumpHistoryChanged = false; return null; } @@ -1219,19 +1217,15 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint // for. HashSet bolusSet = new HashSet<>(historyResult.history.bolusHistory); if (bolusSet.size() != historyResult.history.bolusHistory.size()) { - 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")); + if (L.isEnabled(L.PUMP)) + log.debug("Bolus with same amount within the same minute imported. Only one will make it to the DB."); Notification notification = new Notification(Notification.COMBO_PUMP_ALARM, MainApp.gs(R.string. combo_error_multiple_boluses_with_identical_timestamp), Notification.URGENT); MainApp.bus().post(new EventNewNotification(notification)); } pumpHistoryChanged = updateDbFromPumpHistory(historyResult.history); - if (pumpHistoryChanged) { + if (L.isEnabled(L.PUMP) && pumpHistoryChanged) { log.debug("Setting 'pumpHistoryChanged' true"); } @@ -1272,7 +1266,7 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint JSONObject extendedJson = new JSONObject(); extendedJson.put("Version", BuildConfig.VERSION_NAME + "-" + BuildConfig.BUILDVERSION); - extendedJson.put("ActiveProfile", MainApp.getConfigBuilder().getProfileName()); + extendedJson.put("ActiveProfile", ProfileFunctions.getInstance().getProfileName()); PumpState ps = pump.state; if (ps.tbrActive) { extendedJson.put("TempBasalAbsoluteRate", ps.basalRate); @@ -1356,7 +1350,7 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint private boolean validBasalRateProfileSelectedOnPump = true; @Override - public Constraint isLoopInvokationAllowed(Constraint value) { + public Constraint isLoopInvocationAllowed(Constraint value) { if (!validBasalRateProfileSelectedOnPump) value.set(false, MainApp.gs(R.string.novalidbasalrate), this); return value; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ruffyscripter/CommandResult.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ruffyscripter/CommandResult.java index 9da5d4d6fa..b595d13d28 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ruffyscripter/CommandResult.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ruffyscripter/CommandResult.java @@ -5,10 +5,11 @@ import android.support.annotation.Nullable; import java.util.LinkedList; import java.util.List; -import info.nightscout.androidaps.plugins.PumpCombo.ruffyscripter.history.Bolus; import info.nightscout.androidaps.plugins.PumpCombo.ruffyscripter.history.PumpHistory; public class CommandResult { + /** True if a condition indicating a broken pump setup/configuration is detected */ + public boolean invalidSetup; /** Whether the command was executed successfully. */ public boolean success; /** State of the pump *after* command execution. */ diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ruffyscripter/RuffyScripter.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ruffyscripter/RuffyScripter.java index 1e7e542e5f..e69cf3b462 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ruffyscripter/RuffyScripter.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ruffyscripter/RuffyScripter.java @@ -10,7 +10,6 @@ import android.os.SystemClock; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import com.crashlytics.android.answers.CustomEvent; import com.google.common.base.Joiner; import org.monkey.d.ruffy.ruffy.driver.IRTHandler; @@ -39,8 +38,6 @@ import info.nightscout.androidaps.plugins.PumpCombo.ruffyscripter.commands.ReadH import info.nightscout.androidaps.plugins.PumpCombo.ruffyscripter.commands.ReadPumpStateCommand; import info.nightscout.androidaps.plugins.PumpCombo.ruffyscripter.commands.SetBasalProfileCommand; import info.nightscout.androidaps.plugins.PumpCombo.ruffyscripter.commands.SetTbrCommand; -import info.nightscout.androidaps.BuildConfig; -import info.nightscout.utils.FabricPrivacy; /** * Provides scripting 'runtime' and operations. consider moving operations into a separate @@ -57,8 +54,6 @@ public class RuffyScripter implements RuffyCommands { private volatile long menuLastUpdated = 0; private volatile boolean unparsableMenuEncountered; - - private String previousCommand = ""; private volatile Command activeCmd = null; private boolean started = false; @@ -67,51 +62,43 @@ public class RuffyScripter implements RuffyCommands { private IRTHandler mHandler = new IRTHandler.Stub() { @Override - public void log(String message) throws RemoteException { + public void log(String message) { if (log.isTraceEnabled()) { log.trace("Ruffy says: " + message); } } @Override - public void fail(String message) throws RemoteException { + public void fail(String message) { log.warn("Ruffy warns: " + message); - if (message.startsWith("no connection possible")) - FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboRuffyWarning").putCustomAttribute("message", "no connection possible")); - else if (message.startsWith("Error sending keep alive while rtModeRunning is still true")) - FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboRuffyWarning").putCustomAttribute("message", "Error sending keep alive while rtModeRunning is still true")); - else if (message.startsWith("Error sending keep alive. rtModeRunning is false, so this is most likely a race condition during disconnect")) - FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboRuffyWarning").putCustomAttribute("message", "Error sending keep alive. rtModeRunning is false, so this is most likely a race condition during disconnect")); - else - FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboRuffyWarning").putCustomAttribute("message", message.substring(0, 98))); } @Override - public void requestBluetooth() throws RemoteException { + public void requestBluetooth() { log.trace("Ruffy invoked requestBluetooth callback"); } @Override - public void rtStopped() throws RemoteException { + public void rtStopped() { log.debug("rtStopped callback invoked"); currentMenu = null; } @Override - public void rtStarted() throws RemoteException { + public void rtStarted() { log.debug("rtStarted callback invoked"); } @Override - public void rtClearDisplay() throws RemoteException { + public void rtClearDisplay() { } @Override - public void rtUpdateDisplay(byte[] quarter, int which) throws RemoteException { + public void rtUpdateDisplay(byte[] quarter, int which) { } @Override - public void rtDisplayHandleMenu(Menu menu) throws RemoteException { + public void rtDisplayHandleMenu(Menu menu) { // method is called every ~500ms log.debug("rtDisplayHandleMenu: " + menu); @@ -124,7 +111,7 @@ public class RuffyScripter implements RuffyCommands { } @Override - public void rtDisplayHandleNoMenu() throws RemoteException { + public void rtDisplayHandleNoMenu() { log.warn("rtDisplayHandleNoMenu callback invoked"); unparsableMenuEncountered = true; } @@ -173,10 +160,6 @@ public class RuffyScripter implements RuffyCommands { if (!boundSucceeded) { log.error("No connection to ruffy. Pump control unavailable."); - } else { - FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboScripterInit") - .putCustomAttribute("buildversion", BuildConfig.BUILDVERSION) - .putCustomAttribute("version", BuildConfig.VERSION)); } } @@ -227,9 +210,6 @@ public class RuffyScripter implements RuffyCommands { @Override public CommandResult readQuickInfo(int numberOfBolusRecordsToRetrieve) { - FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboReadQuickInfoCmd") - .putCustomAttribute("buildversion", BuildConfig.BUILDVERSION) - .putCustomAttribute("version", BuildConfig.VERSION)); return runCommand(new ReadQuickInfoCommand(numberOfBolusRecordsToRetrieve)); } @@ -281,10 +261,10 @@ public class RuffyScripter implements RuffyCommands { log.debug("Executing " + cmd + " took " + (cmdEndTime - cmdStartTime) + "ms"); } catch (CommandException e) { log.error("CommandException running command", e); - activeCmd.getResult().success = false; + cmd.getResult().success = false; } catch (Exception e) { log.error("Unexpected exception running cmd", e); - activeCmd.getResult().success = false; + cmd.getResult().success = false; } }, cmd.getClass().getSimpleName()); long executionStart = System.currentTimeMillis(); @@ -328,6 +308,7 @@ public class RuffyScripter implements RuffyCommands { if (unparsableMenuEncountered) { log.error("UnparsableMenuEncountered flagged, aborting command"); cmdThread.interrupt(); + activeCmd.getResult().invalidSetup = true; activeCmd.getResult().success = false; } @@ -365,7 +346,6 @@ public class RuffyScripter implements RuffyCommands { // ignore } } - previousCommand = "" + activeCmd; activeCmd = null; } } @@ -434,11 +414,6 @@ public class RuffyScripter implements RuffyCommands { } } log.debug("Recovery from connection loss " + (connected ? "succeeded" : "failed")); - FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboRecoveryFromConnectionLoss") - .putCustomAttribute("buildversion", BuildConfig.BUILDVERSION) - .putCustomAttribute("version", BuildConfig.VERSION) - .putCustomAttribute("activeCommand", "" + (activeCmd != null ? activeCmd.getClass().getSimpleName() : "")) - .putCustomAttribute("success", connected ? "true" : "else")); return connected; } @@ -449,12 +424,6 @@ public class RuffyScripter implements RuffyCommands { private PumpState recoverFromCommandFailure() { Menu menu = this.currentMenu; if (menu == null) { - FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboRecoveryFromCommandFailure") - .putCustomAttribute("buildversion", BuildConfig.BUILDVERSION) - .putCustomAttribute("version", BuildConfig.VERSION) - .putCustomAttribute("activeCommand", "" + (activeCmd != null ? activeCmd.getClass().getSimpleName() : "")) - .putCustomAttribute("exit", "1") - .putCustomAttribute("success", "false")); return new PumpState(); } MenuType type = menu.getType(); @@ -468,21 +437,8 @@ public class RuffyScripter implements RuffyCommands { } try { PumpState pumpState = readPumpStateInternal(); - FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboRecoveryFromCommandFailure") - .putCustomAttribute("buildversion", BuildConfig.BUILDVERSION) - .putCustomAttribute("version", BuildConfig.VERSION) - .putCustomAttribute("activeCommand", "" + (activeCmd != null ? activeCmd.getClass().getSimpleName() : "")) - .putCustomAttribute("exit", "2") - .putCustomAttribute("success", "true")); return pumpState; } catch (Exception e) { - FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboRecoveryFromCommandFailure") - .putCustomAttribute("buildversion", BuildConfig.BUILDVERSION) - .putCustomAttribute("version", BuildConfig.VERSION) - .putCustomAttribute("exit", "3") - .putCustomAttribute("activeCommand", "" + (activeCmd != null ? activeCmd.getClass().getSimpleName() : "")) - .putCustomAttribute("success", "false")); - log.debug("Reading pump state during recovery failed", e); return new PumpState(); } @@ -504,11 +460,6 @@ public class RuffyScripter implements RuffyCommands { long initialUpdateTime = menuLastUpdated; while (initialUpdateTime == menuLastUpdated) { if (System.currentTimeMillis() > timeoutExpired) { - FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboConnectTimeout") - .putCustomAttribute("buildversion", BuildConfig.BUILDVERSION) - .putCustomAttribute("version", BuildConfig.VERSION) - .putCustomAttribute("activeCommand", "" + (activeCmd != null ? activeCmd.getClass().getSimpleName() : "")) - .putCustomAttribute("previousCommand", previousCommand)); throw new CommandException("Timeout connecting to pump"); } SystemClock.sleep(50); @@ -817,18 +768,12 @@ public class RuffyScripter implements RuffyCommands { @Override public CommandResult deliverBolus(double amount, BolusProgressReporter bolusProgressReporter) { - FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboBolusCmd") - .putCustomAttribute("buildversion", BuildConfig.BUILDVERSION) - .putCustomAttribute("version", BuildConfig.VERSION)); return runCommand(new BolusCommand(amount, bolusProgressReporter)); } @Override public void cancelBolus() { if (activeCmd instanceof BolusCommand) { - FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboBolusCmdCancel") - .putCustomAttribute("buildversion", BuildConfig.BUILDVERSION) - .putCustomAttribute("version", BuildConfig.VERSION)); ((BolusCommand) activeCmd).requestCancellation(); } else { log.error("cancelBolus called, but active command is not a bolus:" + activeCmd); @@ -837,49 +782,31 @@ public class RuffyScripter implements RuffyCommands { @Override public CommandResult setTbr(int percent, int duration) { - FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboSetTbrCmd") - .putCustomAttribute("buildversion", BuildConfig.BUILDVERSION) - .putCustomAttribute("version", BuildConfig.VERSION)); return runCommand(new SetTbrCommand(percent, duration)); } @Override public CommandResult cancelTbr() { - FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboCancelTbrCmd") - .putCustomAttribute("buildversion", BuildConfig.BUILDVERSION) - .putCustomAttribute("version", BuildConfig.VERSION)); return runCommand(new CancelTbrCommand()); } @Override public CommandResult confirmAlert(int warningCode) { - FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboConfirmAlertCmd") - .putCustomAttribute("buildversion", BuildConfig.BUILDVERSION) - .putCustomAttribute("version", BuildConfig.VERSION)); return runCommand(new ConfirmAlertCommand(warningCode)); } @Override public CommandResult readHistory(PumpHistoryRequest request) { - FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboReadHistoryCmd") - .putCustomAttribute("buildversion", BuildConfig.BUILDVERSION) - .putCustomAttribute("version", BuildConfig.VERSION)); return runCommand(new ReadHistoryCommand(request)); } @Override public CommandResult readBasalProfile() { - FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboReadBasalProfileCmd") - .putCustomAttribute("buildversion", BuildConfig.BUILDVERSION) - .putCustomAttribute("version", BuildConfig.VERSION)); return runCommand(new ReadBasalProfileCommand()); } @Override public CommandResult setBasalProfile(BasalProfile basalProfile) { - FabricPrivacy.getInstance().logCustom(new CustomEvent("ComboSetBasalProfileCmd") - .putCustomAttribute("buildversion", BuildConfig.BUILDVERSION) - .putCustomAttribute("version", BuildConfig.VERSION)); return runCommand(new SetBasalProfileCommand(basalProfile)); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ruffyscripter/commands/ReadQuickInfoCommand.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ruffyscripter/commands/ReadQuickInfoCommand.java index e55fb4d010..654861fddb 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ruffyscripter/commands/ReadQuickInfoCommand.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ruffyscripter/commands/ReadQuickInfoCommand.java @@ -39,17 +39,19 @@ public class ReadQuickInfoCommand extends BaseCommand { // read bolus records int totalRecords = (int) scripter.getCurrentMenu().getAttribute(MenuAttribute.TOTAL_RECORD); int record = (int) scripter.getCurrentMenu().getAttribute(MenuAttribute.CURRENT_RECORD); - while (true) { - bolusHistory.add(readBolusRecord()); - if (bolusHistory.size() == numberOfBolusRecordsToRetrieve || record == totalRecords) { - break; + if (record > 0) { + while (true) { + bolusHistory.add(readBolusRecord()); + if (bolusHistory.size() == numberOfBolusRecordsToRetrieve || record == totalRecords) { + break; + } + // advance to next record + scripter.pressDownKey(); + while (record == (int) scripter.getCurrentMenu().getAttribute(MenuAttribute.CURRENT_RECORD)) { + scripter.waitForScreenUpdate(); + } + record = (int) scripter.getCurrentMenu().getAttribute(MenuAttribute.CURRENT_RECORD); } - // advance to next record - scripter.pressDownKey(); - while (record == (int) scripter.getCurrentMenu().getAttribute(MenuAttribute.CURRENT_RECORD)) { - scripter.waitForScreenUpdate(); - } - record = (int) scripter.getCurrentMenu().getAttribute(MenuAttribute.CURRENT_RECORD); } if (log.isDebugEnabled()) { if (!result.history.bolusHistory.isEmpty()) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/data/DoseSettings.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/data/DoseSettings.java new file mode 100644 index 0000000000..21a893e943 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/data/DoseSettings.java @@ -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; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/defs/DoseStepSize.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/defs/DoseStepSize.java new file mode 100644 index 0000000000..421c441c32 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/defs/DoseStepSize.java @@ -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; + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/defs/PumpCapability.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/defs/PumpCapability.java new file mode 100644 index 0000000000..d3e29ded0a --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/defs/PumpCapability.java @@ -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; + } + + + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/defs/PumpTempBasalType.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/defs/PumpTempBasalType.java new file mode 100644 index 0000000000..167e886ea7 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/defs/PumpTempBasalType.java @@ -0,0 +1,10 @@ +package info.nightscout.androidaps.plugins.PumpCommon.defs; + +/** + * Created by andy on 02/05/2018. + */ + +public enum PumpTempBasalType { + Percent, // + Absolute, +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/defs/PumpType.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/defs/PumpType.java new file mode 100644 index 0000000000..ab97f2cff2 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCommon/defs/PumpType.java @@ -0,0 +1,393 @@ +package info.nightscout.androidaps.plugins.PumpCommon.defs; + + +import java.util.HashMap; +import java.util.Map; + +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.plugins.PumpCommon.data.DoseSettings; + + + +/** + * Created by andy on 02/05/2018. + * + * Most of this defintions is intended for VirtualPump only, but they can be used by other plugins. + */ + +public enum PumpType { + + GenericAAPS("Generic AAPS", 0.1d, null, // + new DoseSettings(0.05d, 30, 8*60, 0.05d), // + PumpTempBasalType.Percent, // + new DoseSettings(10,30, 24*60, 0d, 500d), PumpCapability.BasalRate_Duration15and30minAllowed, // + 0.01d, 0.01d, null, PumpCapability.VirtualPumpCapabilities), // + + // Cellnovo + + Cellnovo1("Cellnovo", 0.05d, null, // + new DoseSettings(0.05d, 30, 24*60, 1d, null), + PumpTempBasalType.Percent, + new DoseSettings(5,30, 24*60, 0d, 200d), PumpCapability.BasalRate_Duration30minAllowed, // + 0.05d, 0.05d, null, PumpCapability.VirtualPumpCapabilities), // + + // Accu-Chek + + AccuChekCombo("Accu-Chek Combo", 0.1d, null, // + new DoseSettings(0.1d, 15, 12*60, 0.1d), // + PumpTempBasalType.Percent, + new DoseSettings(10, 15, 12*60,0d, 500d), PumpCapability.BasalRate_Duration15and30minAllowed, // + 0.01d, 0.01d, DoseStepSize.ComboBasal, PumpCapability.ComboCapabilities), // + + AccuChekSpirit("Accu-Chek Spirit", 0.1d, null, // + new DoseSettings(0.1d, 15, 12*60, 0.1d), // + PumpTempBasalType.Percent, + new DoseSettings(10, 15, 12*60,0d, 500d), PumpCapability.BasalRate_Duration15and30minAllowed, // + 0.01d, 0.1d, null, PumpCapability.VirtualPumpCapabilities), // + + AccuChekInsight("Accu-Chek Insight", 0.05d, DoseStepSize.InsightBolus, // + new DoseSettings(0.05d, 15, 24*60, 0.05d), // + PumpTempBasalType.Percent, + new DoseSettings(10, 15, 12*60,0d, 250d), PumpCapability.BasalRate_Duration15and30minAllowed, // + 0.02d, 0.01d, null, PumpCapability.InsightCapabilities), // + + // Animas + AnimasVibe("Animas Vibe", 0.05d, null, // AnimasBolus? + new DoseSettings(0.05d, 30, 12*60, 0.05d), // + PumpTempBasalType.Percent, // + new DoseSettings(10, 30, 24*60, 0d, 300d), PumpCapability.BasalRate_Duration30minAllowed, // + 0.025d, 5d, 0d, null, PumpCapability.VirtualPumpCapabilities), // + + AnimasPing("Animas Ping", AnimasVibe), + + // Dana + DanaR("DanaR", 0.05d, null, // + new DoseSettings(0.05d, 30, 8*60, 0.05d), // + PumpTempBasalType.Percent, // + new DoseSettings(10d, 60, 24*60, 0d, 200d), PumpCapability.BasalRate_Duration15and30minNotAllowed, // + 0.04d, 0.01d, null, PumpCapability.DanaCapabilities), + + DanaRKorean("DanaR Korean", 0.05d, null, // + new DoseSettings(0.05d, 30, 8*60, 0.05d), // + PumpTempBasalType.Percent, // + new DoseSettings(10d, 60, 24*60, 0d, 200d), PumpCapability.BasalRate_Duration15and30minNotAllowed, // + 0.1d, 0.01d, null, PumpCapability.DanaCapabilities), + + DanaRS("DanaRS", 0.05d, null, // + new DoseSettings(0.05d, 30, 8*60, 0.05d), // + PumpTempBasalType.Percent, // + new DoseSettings(10d, 60, 24*60, 0d, 200d), PumpCapability.BasalRate_Duration15and30minAllowed, // + 0.04d, 0.01d, null, PumpCapability.DanaWithHistoryCapabilities), + + DanaRv2("DanaRv2", DanaRS), + + + // Insulet + Insulet_Omnipod("Insulet Omnipod", 0.05d, null, // + new DoseSettings(0.05d, 30, 8*60, 0.05d), // + PumpTempBasalType.Absolute, // + new DoseSettings(0.05d, 30, 12*60, 0d, 30.0d), PumpCapability.BasalRate_Duration30minAllowed, // cannot exceed max basal rate 30u/hr + 0.05d, 0.05d, null, PumpCapability.VirtualPumpCapabilities), + + // Medtronic + Medtronic_512_712("Medtronic 512/712", 0.05d, null, // + new DoseSettings(0.05d, 30, 8*60, 0.05d), // + PumpTempBasalType.Absolute, // + new DoseSettings(0.05d, 30, 24*60, 0d, 35d), PumpCapability.BasalRate_Duration30minAllowed, // + 0.05d, 0.05d, null, PumpCapability.VirtualPumpCapabilities), // TODO + + Medtronic_515_715("Medtronic 515/715", Medtronic_512_712), + Medtronic_522_722("Medtronic 522/722", Medtronic_512_712), + + Medtronic_523_723_Revel("Medtronic 523/723 (Revel)", 0.05d, null, // + new DoseSettings(0.05d, 30, 8*60, 0.05d), // + PumpTempBasalType.Absolute, // + new DoseSettings(0.05d, 30, 24*60, 0d, 35d), PumpCapability.BasalRate_Duration30minAllowed, // + 0.025d, 0.025d, DoseStepSize.MedtronicVeoBasal, PumpCapability.VirtualPumpCapabilities), // + + Medtronic_554_754_Veo("Medtronic 554/754 (Veo)", Medtronic_523_723_Revel), // TODO + + Medtronic_640G("Medtronic 640G", 0.025d, null, // + new DoseSettings(0.05d, 30, 8*60, 0.05d), // + PumpTempBasalType.Absolute, // + new DoseSettings(0.05d, 30, 24*60, 0d, 35d), PumpCapability.BasalRate_Duration30minAllowed, // + 0.025d, 0.025d, DoseStepSize.MedtronicVeoBasal, PumpCapability.VirtualPumpCapabilities), // + + // Tandem + TandemTSlim("Tandem t:slim", 0.01d, null, // + new DoseSettings(0.01d,15, 8*60, 0.4d), + PumpTempBasalType.Percent, + new DoseSettings(1,15, 8*60, 0d, 250d), PumpCapability.BasalRate_Duration15and30minAllowed, // + 0.1d, 0.001d, null, PumpCapability.VirtualPumpCapabilities), + + TandemTFlex("Tandem t:flex", TandemTSlim), // + TandemTSlimG4("Tandem t:slim G4", TandemTSlim), // + TandemTSlimX2("Tandem t:slim X2", TandemTSlim), // + ; + + private String description; + private double bolusSize; + private DoseStepSize specialBolusSize; + private DoseSettings extendedBolusSettings; + private PumpTempBasalType pumpTempBasalType; + private DoseSettings tbrSettings; + private PumpCapability specialBasalDurations; + private double baseBasalMinValue; // + private Double baseBasalMaxValue; + private double baseBasalStep; // + private DoseStepSize baseBasalSpecialSteps; // + private PumpCapability pumpCapability; + + private PumpType parent; + private static Map mapByDescription; + + static + { + mapByDescription = new HashMap<>(); + + for (PumpType pumpType : values()) { + mapByDescription.put(pumpType.getDescription(), pumpType); + } + } + + + PumpType(String description, PumpType parent) + { + this.description = description; + this.parent = parent; + } + + PumpType(String description, PumpType parent, PumpCapability pumpCapability) + { + this.description = description; + this.parent = parent; + this.pumpCapability = pumpCapability; + } + + PumpType(String description, double bolusSize, DoseStepSize specialBolusSize, // + DoseSettings extendedBolusSettings, // + PumpTempBasalType pumpTempBasalType, DoseSettings tbrSettings, PumpCapability specialBasalDurations, // + double baseBasalMinValue, double baseBasalStep, DoseStepSize baseBasalSpecialSteps, PumpCapability pumpCapability) + { + this(description, bolusSize, specialBolusSize, extendedBolusSettings, pumpTempBasalType, tbrSettings, specialBasalDurations, baseBasalMinValue, null, baseBasalStep, baseBasalSpecialSteps, pumpCapability); + } + + PumpType(String description, double bolusSize, DoseStepSize specialBolusSize, // + DoseSettings extendedBolusSettings, // + PumpTempBasalType pumpTempBasalType, DoseSettings tbrSettings, PumpCapability specialBasalDurations, // + double baseBasalMinValue, Double baseBasalMaxValue, double baseBasalStep, DoseStepSize baseBasalSpecialSteps, PumpCapability pumpCapability) + { + this.description = description; + this.bolusSize = bolusSize; + this.specialBolusSize = specialBolusSize; + this.extendedBolusSettings = extendedBolusSettings; + this.pumpTempBasalType = pumpTempBasalType; + this.tbrSettings = tbrSettings; + this.specialBasalDurations = specialBasalDurations; + this.baseBasalMinValue = baseBasalMinValue; + this.baseBasalMaxValue = baseBasalMaxValue; + this.baseBasalStep = baseBasalStep; + this.baseBasalSpecialSteps = baseBasalSpecialSteps; + this.pumpCapability = pumpCapability; + } + + + public String getDescription() { + return description; + } + + public PumpCapability getPumpCapability() { + + if (isParentSet()) + return this.pumpCapability == null ? parent.pumpCapability : pumpCapability; + else + return this.pumpCapability; + } + + public double getBolusSize() { + return isParentSet() ? parent.bolusSize : bolusSize; + } + + + public DoseStepSize getSpecialBolusSize() { + return isParentSet() ? parent.specialBolusSize : specialBolusSize; + } + + + public DoseSettings getExtendedBolusSettings() { + return isParentSet() ? parent.extendedBolusSettings : extendedBolusSettings; + } + + + public PumpTempBasalType getPumpTempBasalType() { + return isParentSet() ? parent.pumpTempBasalType : pumpTempBasalType; + } + + + public DoseSettings getTbrSettings() { + return isParentSet() ? parent.tbrSettings : tbrSettings; + } + + + public double getBaseBasalMinValue() { + return isParentSet() ? parent.baseBasalMinValue : baseBasalMinValue; + } + + + public Double getBaseBasalMaxValue() { + return isParentSet() ? parent.baseBasalMaxValue : baseBasalMaxValue; + } + + + public double getBaseBasalStep() { + return isParentSet() ? parent.baseBasalStep : baseBasalStep; + } + + + public DoseStepSize getBaseBasalSpecialSteps() { + return isParentSet() ? parent.baseBasalSpecialSteps : baseBasalSpecialSteps; + } + + + public PumpType getParent() { + return parent; + } + + + private boolean isParentSet() + { + return this.parent!=null; + } + + + public static PumpType getByDescription(String desc) + { + if (mapByDescription.containsKey(desc)) + { + return mapByDescription.get(desc); + } + else + { + return PumpType.GenericAAPS; + } + } + + + public String getFullDescription(String i18nTemplate, boolean hasExtendedBasals) { + + String unit = getPumpTempBasalType()==PumpTempBasalType.Percent ? "%" : ""; + + DoseSettings eb = getExtendedBolusSettings(); + DoseSettings tbr = getTbrSettings(); + + String extendedNote = hasExtendedBasals ? MainApp.gs(R.string.virtualpump_pump_def_extended_note) : ""; + + return String.format(i18nTemplate, // + getStep("" + getBolusSize(), getSpecialBolusSize()), // + eb.getStep(), eb.getDurationStep(), eb.getMaxDuration()/60, // + getStep(getBaseBasalRange(), getBaseBasalSpecialSteps()), // + tbr.getMinDose() + unit + "-" + tbr.getMaxDose() + unit, tbr.getStep() + unit, + tbr.getDurationStep(), tbr.getMaxDuration()/60, extendedNote); + } + + + private String getBaseBasalRange() + { + Double maxValue = getBaseBasalMaxValue(); + + return maxValue==null ? "" + getBaseBasalMinValue() : getBaseBasalMinValue() + "-" + maxValue; + } + + + private String getStep(String step, DoseStepSize stepSize) + { + if (stepSize!=null) + return step + " [" + stepSize.getDescription() + "] *"; + else + return "" + step; + } + + + public boolean hasExtendedBasals() { + return ((getBaseBasalSpecialSteps() !=null) || (getSpecialBolusSize() != null)); + } + + + public PumpCapability getSpecialBasalDurations() { + + if (isParentSet()) + { + return parent.getSpecialBasalDurations(); + } + else + { + return specialBasalDurations == null ? // + PumpCapability.BasalRate_Duration15and30minNotAllowed : specialBasalDurations; + } + } + + public double determineCorrectBolusSize(double bolusAmount) { + if (bolusAmount == 0.0d) { + return bolusAmount; + } + + double bolusStepSize; + + if (getSpecialBolusSize() == null) { + bolusStepSize = getBolusSize(); + } else { + DoseStepSize specialBolusSize = getSpecialBolusSize(); + + bolusStepSize = specialBolusSize.getStepSizeForAmount((double)bolusAmount); + } + + return Math.round(bolusAmount / bolusStepSize) * bolusStepSize; + } + + + public double determineCorrectExtendedBolusSize(double bolusAmount) { + if (bolusAmount == 0.0d) { + return bolusAmount; + } + + double bolusStepSize; + + if (getExtendedBolusSettings() == null) { // this should be never null + return 0.0d; + } + + DoseSettings extendedBolusSettings = getExtendedBolusSettings(); + + bolusStepSize = extendedBolusSettings.getStep(); + + if (bolusAmount > extendedBolusSettings.getMaxDose()) { + bolusAmount = extendedBolusSettings.getMaxDose(); + } + + return Math.round(bolusAmount / bolusStepSize) * bolusStepSize; + } + + + public double determineCorrectBasalSize(double basalAmount) { + if (basalAmount == 0.0d) { + return basalAmount; + } + + double basalStepSize; + + if (getBaseBasalSpecialSteps() == null) { + basalStepSize = getBaseBasalStep(); + } else { + DoseStepSize specialBolusSize = getBaseBasalSpecialSteps(); + + basalStepSize = specialBolusSize.getStepSizeForAmount((double) basalAmount); + } + + if (basalAmount > getTbrSettings().getMaxDose()) + basalAmount = getTbrSettings().getMaxDose().doubleValue(); + + return Math.round(basalAmount / basalStepSize) * basalStepSize; + + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/AbstractDanaRPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/AbstractDanaRPlugin.java index 903be558b9..c50e635eb8 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/AbstractDanaRPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/AbstractDanaRPlugin.java @@ -5,11 +5,11 @@ import android.support.annotation.Nullable; import org.json.JSONException; import org.json.JSONObject; import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.Date; import info.nightscout.androidaps.BuildConfig; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.Profile; @@ -26,6 +26,7 @@ import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.ProfileInterface; import info.nightscout.androidaps.interfaces.PumpDescription; import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.Overview.notifications.Notification; @@ -43,11 +44,10 @@ import info.nightscout.utils.SP; */ public abstract class AbstractDanaRPlugin extends PluginBase implements PumpInterface, DanaRInterface, ConstraintsInterface, ProfileInterface { - protected Logger log; + protected Logger log = LoggerFactory.getLogger(L.PUMP); protected AbstractDanaRExecutionService sExecutionService; - protected DanaRPump pump = DanaRPump.getInstance(); protected boolean useExtendedBoluses = false; public PumpDescription pumpDescription = new PumpDescription(); @@ -59,13 +59,14 @@ public abstract class AbstractDanaRPlugin extends PluginBase implements PumpInte .pluginName(R.string.danarspump) .shortName(R.string.danarpump_shortname) .preferencesId(R.xml.pref_danars) + .description(R.string.description_pump_dana_r) ); } @Override public void onStateChange(PluginType type, State oldState, State newState) { // if pump profile was enabled need to switch to another too - if (type == PluginType.PUMP && newState == State.ENABLED && newState == State.DISABLED && isProfileInterfaceEnabled) { + if (type == PluginType.PUMP && newState == State.DISABLED && isProfileInterfaceEnabled) { setPluginEnabled(PluginType.PROFILE, false); NSProfilePlugin.getPlugin().setPluginEnabled(PluginType.PROFILE, true); NSProfilePlugin.getPlugin().setFragmentVisible(PluginType.PROFILE, true); @@ -74,7 +75,7 @@ public abstract class AbstractDanaRPlugin extends PluginBase implements PumpInte @Override public boolean isSuspended() { - return pump.pumpSuspended; + return DanaRPump.getInstance().pumpSuspended; } @Override @@ -123,6 +124,7 @@ public abstract class AbstractDanaRPlugin extends PluginBase implements PumpInte public boolean isThisProfileSet(Profile profile) { if (!isInitialized()) return true; // TODO: not sure what's better. so far TRUE to prevent too many SMS + DanaRPump pump = DanaRPump.getInstance(); if (pump.pumpProfiles == null) return true; // TODO: not sure what's better. so far TRUE to prevent too many SMS int basalValues = pump.basal48Enable ? 48 : 24; @@ -132,7 +134,8 @@ public abstract class AbstractDanaRPlugin extends PluginBase implements PumpInte Double profileValue = profile.getBasalTimeFromMidnight(h * basalIncrement); if (profileValue == null) return true; if (Math.abs(pumpValue - profileValue) > getPumpDescription().basalStep) { - log.debug("Diff found. Hour: " + h + " Pump: " + pumpValue + " Profile: " + profileValue); + if (L.isEnabled(L.PUMP)) + log.debug("Diff found. Hour: " + h + " Pump: " + pumpValue + " Profile: " + profileValue); return false; } } @@ -140,13 +143,13 @@ public abstract class AbstractDanaRPlugin extends PluginBase implements PumpInte } @Override - public Date lastDataTime() { - return new Date(pump.lastConnection); + public long lastDataTime() { + return DanaRPump.getInstance().lastConnection; } @Override public double getBaseBasalRate() { - return pump.currentBasal; + return DanaRPump.getInstance().currentBasal; } @Override @@ -160,6 +163,7 @@ public abstract class AbstractDanaRPlugin extends PluginBase implements PumpInte @Override public PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes, Profile profile, boolean enforceNew) { + DanaRPump pump = DanaRPump.getInstance(); PumpEnactResult result = new PumpEnactResult(); percent = MainApp.getConstraintChecker().applyBasalPercentConstraints(new Constraint<>(percent), profile).value(); if (percent < 0) { @@ -182,7 +186,7 @@ public abstract class AbstractDanaRPlugin extends PluginBase implements PumpInte result.duration = pump.tempBasalRemainingMin; result.percent = pump.tempBasalPercent; result.isPercent = true; - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalPercent: Correct value already set"); return result; } @@ -196,7 +200,7 @@ public abstract class AbstractDanaRPlugin extends PluginBase implements PumpInte result.duration = pump.tempBasalRemainingMin; result.percent = pump.tempBasalPercent; result.isPercent = true; - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalPercent: OK"); return result; } @@ -209,7 +213,8 @@ public abstract class AbstractDanaRPlugin extends PluginBase implements PumpInte @Override public PumpEnactResult setExtendedBolus(Double insulin, Integer durationInMinutes) { - insulin = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(insulin)).value(); + DanaRPump pump = DanaRPump.getInstance(); + insulin = MainApp.getConstraintChecker().applyExtendedBolusConstraints(new Constraint<>(insulin)).value(); // needs to be rounded int durationInHalfHours = Math.max(durationInMinutes / 30, 1); insulin = Round.roundTo(insulin, getPumpDescription().extendedBolusStep); @@ -224,7 +229,7 @@ public abstract class AbstractDanaRPlugin extends PluginBase implements PumpInte result.absolute = pump.extendedBolusAbsoluteRate; result.isPercent = false; result.isTempCancel = false; - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setExtendedBolus: Correct extended bolus already set. Current: " + pump.extendedBolusAmount + " Asked: " + insulin); return result; } @@ -239,7 +244,7 @@ public abstract class AbstractDanaRPlugin extends PluginBase implements PumpInte if (!SP.getBoolean("danar_useextended", false)) result.bolusDelivered = pump.extendedBolusAmount; result.isPercent = false; - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setExtendedBolus: OK"); return result; } @@ -259,10 +264,10 @@ public abstract class AbstractDanaRPlugin extends PluginBase implements PumpInte result.enacted = true; result.isTempCancel = true; } - if (!pump.isExtendedInProgress) { + if (!DanaRPump.getInstance().isExtendedInProgress) { result.success = true; result.comment = MainApp.gs(R.string.virtualpump_resultok); - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("cancelExtendedBolus: OK"); return result; } else { @@ -277,8 +282,8 @@ public abstract class AbstractDanaRPlugin extends PluginBase implements PumpInte public void connect(String from) { if (sExecutionService != null) { sExecutionService.connect(); - pumpDescription.basalStep = pump.basalStep; - pumpDescription.bolusStep = pump.bolusStep; + pumpDescription.basalStep = DanaRPump.getInstance().basalStep; + pumpDescription.bolusStep = DanaRPump.getInstance().bolusStep; } } @@ -306,13 +311,14 @@ public abstract class AbstractDanaRPlugin extends PluginBase implements PumpInte public void getPumpStatus() { if (sExecutionService != null) { sExecutionService.getPumpStatus(); - pumpDescription.basalStep = pump.basalStep; - pumpDescription.bolusStep = pump.bolusStep; + pumpDescription.basalStep = DanaRPump.getInstance().basalStep; + pumpDescription.bolusStep = DanaRPump.getInstance().bolusStep; } } @Override public JSONObject getJSONStatus(Profile profile, String profilename) { + DanaRPump pump = DanaRPump.getInstance(); long now = System.currentTimeMillis(); if (pump.lastConnection + 5 * 60 * 1000L < System.currentTimeMillis()) { return null; @@ -327,8 +333,8 @@ public abstract class AbstractDanaRPlugin extends PluginBase implements PumpInte status.put("timestamp", DateUtil.toISOString(pump.lastConnection)); extended.put("Version", BuildConfig.VERSION_NAME + "-" + BuildConfig.BUILDVERSION); extended.put("PumpIOB", pump.iob); - if (pump.lastBolusTime.getTime() != 0) { - extended.put("LastBolus", pump.lastBolusTime.toLocaleString()); + if (pump.lastBolusTime != 0) { + extended.put("LastBolus", DateUtil.dateAndTimeFullString(pump.lastBolusTime)); extended.put("LastBolusAmount", pump.lastBolusAmount); } TemporaryBasal tb = TreatmentsPlugin.getPlugin().getRealTempBasalFromHistory(now); @@ -362,7 +368,7 @@ public abstract class AbstractDanaRPlugin extends PluginBase implements PumpInte @Override public String deviceID() { - return pump.serialNumber; + return DanaRPump.getInstance().serialNumber; } @Override @@ -385,8 +391,7 @@ public abstract class AbstractDanaRPlugin extends PluginBase implements PumpInte @Override public Constraint applyBasalConstraints(Constraint absoluteRate, Profile profile) { - if (pump != null) - absoluteRate.setIfSmaller(pump.maxBasal, String.format(MainApp.gs(R.string.limitingbasalratio), pump.maxBasal, MainApp.gs(R.string.pumplimit)), this); + absoluteRate.setIfSmaller(DanaRPump.getInstance().maxBasal, String.format(MainApp.gs(R.string.limitingbasalratio), DanaRPump.getInstance().maxBasal, MainApp.gs(R.string.pumplimit)), this); return absoluteRate; } @@ -400,27 +405,31 @@ public abstract class AbstractDanaRPlugin extends PluginBase implements PumpInte @Override public Constraint applyBolusConstraints(Constraint insulin) { - if (pump != null) - insulin.setIfSmaller(pump.maxBolus, String.format(MainApp.gs(R.string.limitingbolus), pump.maxBolus, MainApp.gs(R.string.pumplimit)), this); + insulin.setIfSmaller(DanaRPump.getInstance().maxBolus, String.format(MainApp.gs(R.string.limitingbolus), DanaRPump.getInstance().maxBolus, MainApp.gs(R.string.pumplimit)), this); return insulin; } + @Override + public Constraint applyExtendedBolusConstraints(Constraint insulin) { + return applyBolusConstraints(insulin); + } + @Nullable @Override public ProfileStore getProfile() { - if (pump.lastSettingsRead == 0) + if (DanaRPump.getInstance().lastSettingsRead == 0) return null; // no info now - return pump.createConvertedProfile(); + return DanaRPump.getInstance().createConvertedProfile(); } @Override public String getUnits() { - return pump.getUnits(); + return DanaRPump.getInstance().getUnits(); } @Override public String getProfileName() { - return pump.createConvertedProfileName(); + return DanaRPump.getInstance().createConvertedProfileName(); } @Override @@ -430,13 +439,14 @@ public abstract class AbstractDanaRPlugin extends PluginBase implements PumpInte // Reply for sms communicator public String shortStatus(boolean veryShort) { + DanaRPump pump = DanaRPump.getInstance(); String ret = ""; if (pump.lastConnection != 0) { Long agoMsec = System.currentTimeMillis() - pump.lastConnection; int agoMin = (int) (agoMsec / 60d / 1000d); ret += "LastConn: " + agoMin + " minago\n"; } - if (pump.lastBolusTime.getTime() != 0) { + if (pump.lastBolusTime != 0) { ret += "LastBolus: " + DecimalFormatter.to2Decimal(pump.lastBolusAmount) + "U @" + android.text.format.DateFormat.format("HH:mm", pump.lastBolusTime) + "\n"; } TemporaryBasal activeTemp = TreatmentsPlugin.getPlugin().getRealTempBasalFromHistory(System.currentTimeMillis()); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRFragment.java index b11cd87278..33d371dca3 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRFragment.java @@ -1,7 +1,6 @@ package info.nightscout.androidaps.plugins.PumpDanaR; -import android.annotation.SuppressLint; import android.app.Activity; import android.content.Intent; import android.os.Bundle; @@ -11,6 +10,7 @@ import android.text.Spanned; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.Button; import android.widget.LinearLayout; import android.widget.TextView; @@ -24,25 +24,29 @@ import butterknife.ButterKnife; import butterknife.OnClick; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.TDDStatsActivity; +import info.nightscout.androidaps.activities.TDDStatsActivity; import info.nightscout.androidaps.db.ExtendedBolus; +import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.events.EventExtendedBolusChange; import info.nightscout.androidaps.events.EventPumpStatusChanged; import info.nightscout.androidaps.events.EventTempBasalChange; +import info.nightscout.androidaps.interfaces.PluginType; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.PumpDanaR.Dialogs.ProfileViewDialog; import info.nightscout.androidaps.plugins.PumpDanaR.activities.DanaRHistoryActivity; +import info.nightscout.androidaps.plugins.PumpDanaR.activities.DanaRUserOptionsActivity; import info.nightscout.androidaps.plugins.PumpDanaR.events.EventDanaRNewStatus; +import info.nightscout.androidaps.plugins.PumpDanaRKorean.DanaRKoreanPlugin; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.androidaps.queue.events.EventQueueChanged; import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; -import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.SetWarnColor; public class DanaRFragment extends SubscriberFragment { - private static Logger log = LoggerFactory.getLogger(DanaRFragment.class); + private static Logger log = LoggerFactory.getLogger(L.PUMP); private Handler loopHandler = new Handler(); private Runnable refreshLoop = new Runnable() { @@ -88,6 +92,8 @@ public class DanaRFragment extends SubscriberFragment { LinearLayout pumpStatusLayout; @BindView(R.id.overview_pumpstatus) TextView pumpStatusView; + @BindView(R.id.danar_user_options) + Button danar_user_options; public DanaRFragment() { } @@ -107,18 +113,12 @@ public class DanaRFragment extends SubscriberFragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - try { - View view = inflater.inflate(R.layout.danar_fragment, container, false); - unbinder = ButterKnife.bind(this, view); + View view = inflater.inflate(R.layout.danar_fragment, container, false); + unbinder = ButterKnife.bind(this, view); - pumpStatusView.setBackgroundColor(MainApp.gc(R.color.colorInitializingBorder)); + pumpStatusView.setBackgroundColor(MainApp.gc(R.color.colorInitializingBorder)); - return view; - } catch (Exception e) { - FabricPrivacy.logException(e); - } - - return null; + return view; } @OnClick(R.id.danar_history) @@ -138,11 +138,17 @@ public class DanaRFragment extends SubscriberFragment { startActivity(new Intent(getContext(), TDDStatsActivity.class)); } + @OnClick(R.id.danar_user_options) + void onUserOptionsClick() { + startActivity(new Intent(getContext(), DanaRUserOptionsActivity.class)); + } + @OnClick(R.id.danar_btconnection) void onBtConnectionClick() { - log.debug("Clicked connect to pump"); + if (L.isEnabled(L.PUMP)) + log.debug("Clicked connect to pump"); DanaRPump.getInstance().lastConnection = 0; - ConfigBuilderPlugin.getCommandQueue().readStatus("Clicked connect to pump", null); + ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("Clicked connect to pump", null); } @Subscribe @@ -151,9 +157,12 @@ public class DanaRFragment extends SubscriberFragment { final String status = c.textStatus(); if (activity != null) { activity.runOnUiThread( - new Runnable() { - @Override - public void run() { + () -> { + synchronized (DanaRFragment.this) { + + if (btConnectionView == null || pumpStatusView == null || pumpStatusLayout == null) + return; + if (c.sStatus == EventPumpStatusChanged.CONNECTING) btConnectionView.setText("{fa-bluetooth-b spin} " + c.sSecondsElapsed + "s"); else if (c.sStatus == EventPumpStatusChanged.CONNECTED) @@ -198,10 +207,10 @@ public class DanaRFragment extends SubscriberFragment { protected void updateGUI() { Activity activity = getActivity(); if (activity != null && basaBasalRateView != null) - activity.runOnUiThread(new Runnable() { - @SuppressLint("SetTextI18n") - @Override - public void run() { + activity.runOnUiThread(() -> { + synchronized (DanaRFragment.this) { + if (!isBound()) return; + DanaRPump pump = DanaRPump.getInstance(); if (pump.lastConnection != 0) { Long agoMsec = System.currentTimeMillis() - pump.lastConnection; @@ -209,19 +218,19 @@ public class DanaRFragment extends SubscriberFragment { lastConnectionView.setText(DateUtil.timeString(pump.lastConnection) + " (" + String.format(MainApp.gs(R.string.minago), agoMin) + ")"); SetWarnColor.setColor(lastConnectionView, agoMin, 16d, 31d); } - if (pump.lastBolusTime.getTime() != 0) { - Long agoMsec = System.currentTimeMillis() - pump.lastBolusTime.getTime(); + if (pump.lastBolusTime != 0) { + Long agoMsec = System.currentTimeMillis() - pump.lastBolusTime; double agoHours = agoMsec / 60d / 60d / 1000d; if (agoHours < 6) // max 6h back - lastBolusView.setText(DateUtil.timeString(pump.lastBolusTime) + " " + DateUtil.sinceString(pump.lastBolusTime.getTime()) + " " + DecimalFormatter.to2Decimal(DanaRPump.getInstance().lastBolusAmount) + " U"); + lastBolusView.setText(DateUtil.timeString(pump.lastBolusTime) + " " + DateUtil.sinceString(pump.lastBolusTime) + " " + DecimalFormatter.to2Decimal(DanaRPump.getInstance().lastBolusAmount) + " U"); else lastBolusView.setText(""); } dailyUnitsView.setText(DecimalFormatter.to0Decimal(pump.dailyTotalUnits) + " / " + pump.maxDailyTotalUnits + " U"); SetWarnColor.setColor(dailyUnitsView, pump.dailyTotalUnits, pump.maxDailyTotalUnits * 0.75d, pump.maxDailyTotalUnits * 0.9d); - basaBasalRateView.setText("( " + (pump.activeProfile + 1) + " ) " + DecimalFormatter.to2Decimal(ConfigBuilderPlugin.getActivePump().getBaseBasalRate()) + " U/h"); + basaBasalRateView.setText("( " + (pump.activeProfile + 1) + " ) " + DecimalFormatter.to2Decimal(ConfigBuilderPlugin.getPlugin().getActivePump().getBaseBasalRate()) + " U/h"); // DanaRPlugin, DanaRKoreanPlugin - if (ConfigBuilderPlugin.getActivePump().isFakingTempsByExtendedBoluses()) { + if (ConfigBuilderPlugin.getPlugin().getActivePump().isFakingTempsByExtendedBoluses()) { if (TreatmentsPlugin.getPlugin().isInHistoryRealTempBasalInProgress()) { tempBasalView.setText(TreatmentsPlugin.getPlugin().getRealTempBasalFromHistory(System.currentTimeMillis()).toStringFull()); } else { @@ -229,8 +238,9 @@ public class DanaRFragment extends SubscriberFragment { } } else { // v2 plugin - if (TreatmentsPlugin.getPlugin().isTempBasalInProgress()) { - tempBasalView.setText(TreatmentsPlugin.getPlugin().getTempBasalFromHistory(System.currentTimeMillis()).toStringFull()); + TemporaryBasal tb = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(System.currentTimeMillis()); + if (tb != null) { + tempBasalView.setText(tb.toStringFull()); } else { tempBasalView.setText(""); } @@ -255,7 +265,7 @@ public class DanaRFragment extends SubscriberFragment { bolusStepView.setText("" + pump.bolusStep); serialNumberView.setText("" + pump.serialNumber); if (queueView != null) { - Spanned status = ConfigBuilderPlugin.getCommandQueue().spannedStatus(); + Spanned status = ConfigBuilderPlugin.getPlugin().getCommandQueue().spannedStatus(); if (status.toString().equals("")) { queueView.setVisibility(View.GONE); } else { @@ -263,8 +273,32 @@ public class DanaRFragment extends SubscriberFragment { queueView.setText(status); } } + //hide user options button if not an RS pump or old firmware + // also excludes pump with model 03 because of untested error + boolean isKorean = DanaRKoreanPlugin.getPlugin().isEnabled(PluginType.PUMP); + if (isKorean || firmwareView.getText() == "OLD" || pump.model == 3) { + danar_user_options.setVisibility(View.GONE); + } } }); } + private boolean isBound() { + return lastConnectionView != null + && lastBolusView != null + && dailyUnitsView != null + && basaBasalRateView != null + && tempBasalView != null + && extendedBolusView != null + && reservoirView != null + && batteryView != null + && iobView != null + && firmwareView != null + && basalStepView != null + && bolusStepView != null + && serialNumberView != null + && danar_user_options != null + && queueView != null; + } + } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPlugin.java index 279a93340f..dfdca746cb 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPlugin.java @@ -5,12 +5,11 @@ import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.IBinder; +import android.support.v4.app.FragmentActivity; +import android.support.v7.app.AlertDialog; import com.squareup.otto.Subscribe; -import org.slf4j.LoggerFactory; - -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.DetailedBolusInfo; @@ -18,14 +17,16 @@ import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.db.ExtendedBolus; import info.nightscout.androidaps.db.TemporaryBasal; -import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgBolusStartWithSpeed; -import info.nightscout.androidaps.plugins.Treatments.Treatment; import info.nightscout.androidaps.events.EventAppExit; import info.nightscout.androidaps.events.EventPreferenceChange; import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.PluginType; -import info.nightscout.androidaps.interfaces.PumpDescription; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderFragment; +import info.nightscout.androidaps.plugins.PumpCommon.defs.PumpType; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgBolusStartWithSpeed; import info.nightscout.androidaps.plugins.PumpDanaR.services.DanaRExecutionService; +import info.nightscout.androidaps.plugins.Treatments.Treatment; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.utils.Round; import info.nightscout.utils.SP; @@ -45,37 +46,31 @@ public class DanaRPlugin extends AbstractDanaRPlugin { public DanaRPlugin() { super(); - log = LoggerFactory.getLogger(DanaRPlugin.class); - useExtendedBoluses = SP.getBoolean("danar_useextended", false); + useExtendedBoluses = SP.getBoolean(R.string.key_danar_useextended, false); + pumpDescription.setPumpDescription(PumpType.DanaR); + } - pumpDescription.isBolusCapable = true; - pumpDescription.bolusStep = 0.05d; - - pumpDescription.isExtendedBolusCapable = true; - pumpDescription.extendedBolusStep = 0.05d; - pumpDescription.extendedBolusDurationStep = 30; - pumpDescription.extendedBolusMaxDuration = 8 * 60; - - pumpDescription.isTempBasalCapable = true; - pumpDescription.tempBasalStyle = PumpDescription.PERCENT; - - pumpDescription.maxTempPercent = 200; - pumpDescription.tempPercentStep = 10; - - pumpDescription.tempDurationStep = 60; - pumpDescription.tempMaxDuration = 24 * 60; - - - pumpDescription.isSetBasalProfileCapable = true; - pumpDescription.basalStep = 0.01d; - pumpDescription.basalMinimumRate = 0.04d; - - pumpDescription.isRefillingCapable = true; - - pumpDescription.storesCarbInfo = false; - - pumpDescription.supportsTDDs = true; - pumpDescription.needsManualTDDLoad = true; + @Override + public void switchAllowed(ConfigBuilderFragment.PluginViewHolder.PluginSwitcher pluginSwitcher, FragmentActivity context) { + boolean allowHardwarePump = SP.getBoolean("allow_hardware_pump", false); + if (allowHardwarePump || context == null) { + pluginSwitcher.invoke(); + } else { + AlertDialog.Builder builder = new AlertDialog.Builder(context); + builder.setMessage(R.string.allow_hardware_pump_text) + .setPositiveButton(R.string.yes, (dialog, id) -> { + pluginSwitcher.invoke(); + SP.putBoolean("allow_hardware_pump", true); + if (L.isEnabled(L.PUMP)) + log.debug("First time HW pump allowed!"); + }) + .setNegativeButton(R.string.cancel, (dialog, id) -> { + pluginSwitcher.cancel(); + if (L.isEnabled(L.PUMP)) + log.debug("User does not allow switching to HW pump!"); + }); + builder.create().show(); + } } @Override @@ -98,12 +93,14 @@ public class DanaRPlugin extends AbstractDanaRPlugin { private ServiceConnection mConnection = new ServiceConnection() { public void onServiceDisconnected(ComponentName name) { - log.debug("Service is disconnected"); + if (L.isEnabled(L.PUMP)) + log.debug("Service is disconnected"); sExecutionService = null; } public void onServiceConnected(ComponentName name, IBinder service) { - log.debug("Service is connected"); + if (L.isEnabled(L.PUMP)) + log.debug("Service is connected"); DanaRExecutionService.LocalBinder mLocalBinder = (DanaRExecutionService.LocalBinder) service; sExecutionService = mLocalBinder.getServiceInstance(); } @@ -119,7 +116,7 @@ public class DanaRPlugin extends AbstractDanaRPlugin { public void onStatusEvent(final EventPreferenceChange s) { if (isEnabled(PluginType.PUMP)) { boolean previousValue = useExtendedBoluses; - useExtendedBoluses = SP.getBoolean("danar_useextended", false); + useExtendedBoluses = SP.getBoolean(R.string.key_danar_useextended, false); if (useExtendedBoluses != previousValue && TreatmentsPlugin.getPlugin().isInHistoryExtendedBoluslInProgress()) { sExecutionService.extendedBolusStop(); @@ -146,7 +143,18 @@ public class DanaRPlugin extends AbstractDanaRPlugin { @Override public boolean isInitialized() { - return pump.lastConnection > 0 && pump.isExtendedBolusEnabled && pump.maxBasal > 0; + DanaRPump pump = DanaRPump.getInstance(); + return pump.lastConnection > 0 && pump.isExtendedBolusEnabled && pump.maxBasal > 0 && pump.isPasswordOK(); + } + + @Override + public boolean isHandshakeInProgress() { + return sExecutionService != null && sExecutionService.isHandshakeInProgress(); + } + + @Override + public void finishHandshaking() { + sExecutionService.finishHandshaking(); } @Override @@ -166,11 +174,11 @@ public class DanaRPlugin extends AbstractDanaRPlugin { result.comment = String.format(MainApp.gs(R.string.boluserrorcode), detailedBolusInfo.insulin, t.insulin, MsgBolusStartWithSpeed.errorCode); else result.comment = MainApp.gs(R.string.virtualpump_resultok); - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("deliverTreatment: OK. Asked: " + detailedBolusInfo.insulin + " Delivered: " + result.bolusDelivered); detailedBolusInfo.insulin = t.insulin; detailedBolusInfo.date = System.currentTimeMillis(); - TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo); + TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false); return result; } else { PumpEnactResult result = new PumpEnactResult(); @@ -191,6 +199,7 @@ public class DanaRPlugin extends AbstractDanaRPlugin { //if (pump.lastConnection.getTime() + 30 * 60 * 1000L < System.currentTimeMillis()) { // connect("setTempBasalAbsolute old data"); //} + DanaRPump pump = DanaRPump.getInstance(); PumpEnactResult result = new PumpEnactResult(); @@ -208,13 +217,13 @@ public class DanaRPlugin extends AbstractDanaRPlugin { if (doTempOff) { // If extended in progress if (activeExtended != null && useExtendedBoluses) { - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalAbsolute: Stopping extended bolus (doTempOff)"); return cancelExtendedBolus(); } // If temp in progress if (activeTemp != null) { - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalAbsolute: Stopping temp basal (doTempOff)"); return cancelRealTempBasal(); } @@ -223,7 +232,7 @@ public class DanaRPlugin extends AbstractDanaRPlugin { result.percent = 100; result.isPercent = true; result.isTempCancel = true; - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalAbsolute: doTempOff OK"); return result; } @@ -235,12 +244,12 @@ public class DanaRPlugin extends AbstractDanaRPlugin { if (percentRate > getPumpDescription().maxTempPercent) { percentRate = getPumpDescription().maxTempPercent; } - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalAbsolute: Calculated percent rate: " + percentRate); // If extended in progress if (activeExtended != null && useExtendedBoluses) { - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalAbsolute: Stopping extended bolus (doLowTemp || doHighTemp)"); result = cancelExtendedBolus(); if (!result.success) { @@ -251,7 +260,7 @@ public class DanaRPlugin extends AbstractDanaRPlugin { // Check if some temp is already in progress if (activeTemp != null) { // Correct basal already set ? - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalAbsolute: currently running: " + activeTemp.toString()); if (activeTemp.percentRate == percentRate) { if (enforceNew) { @@ -263,21 +272,21 @@ public class DanaRPlugin extends AbstractDanaRPlugin { result.duration = activeTemp.getPlannedRemainingMinutes(); result.isPercent = true; result.isTempCancel = false; - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalAbsolute: Correct temp basal already set (doLowTemp || doHighTemp)"); return result; } } } // Convert duration from minutes to hours - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalAbsolute: Setting temp basal " + percentRate + "% for " + durationInMinutes + " mins (doLowTemp || doHighTemp)"); return setTempBasalPercent(percentRate, durationInMinutes, profile, false); } if (doExtendedTemp) { // Check if some temp is already in progress if (activeTemp != null) { - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalAbsolute: Stopping temp basal (doExtendedTemp)"); result = cancelRealTempBasal(); // Check for proper result @@ -296,7 +305,7 @@ public class DanaRPlugin extends AbstractDanaRPlugin { extendedRateToSet = Round.roundTo(extendedRateToSet, pumpDescription.extendedBolusStep * 2); // *2 because of halfhours // What is current rate of extended bolusing in u/h? - if (Config.logPumpActions) { + if (L.isEnabled(L.PUMP)) { log.debug("setTempBasalAbsolute: Extended bolus in progress: " + (activeExtended != null) + " rate: " + pump.extendedBolusAbsoluteRate + "U/h duration remaining: " + pump.extendedBolusRemainingMinutes + "min"); log.debug("setTempBasalAbsolute: Rate to set: " + extendedRateToSet + "U/h"); } @@ -310,21 +319,21 @@ public class DanaRPlugin extends AbstractDanaRPlugin { result.duration = pump.extendedBolusRemainingMinutes; result.isPercent = false; result.isTempCancel = false; - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalAbsolute: Correct extended already set"); return result; } // Now set new extended, no need to to stop previous (if running) because it's replaced Double extendedAmount = extendedRateToSet / 2 * durationInHalfHours; - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalAbsolute: Setting extended: " + extendedAmount + "U halfhours: " + durationInHalfHours); result = setExtendedBolus(extendedAmount, durationInMinutes); if (!result.success) { log.error("setTempBasalAbsolute: Failed to set extended bolus"); return result; } - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalAbsolute: Extended bolus set ok"); result.absolute = result.absolute + getBaseBasalRate(); return result; @@ -351,7 +360,7 @@ public class DanaRPlugin extends AbstractDanaRPlugin { return result; } - public PumpEnactResult cancelRealTempBasal() { + private PumpEnactResult cancelRealTempBasal() { PumpEnactResult result = new PumpEnactResult(); TemporaryBasal runningTB = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(System.currentTimeMillis()); if (runningTB != null) { @@ -359,11 +368,11 @@ public class DanaRPlugin extends AbstractDanaRPlugin { result.enacted = true; result.isTempCancel = true; } - if (!pump.isTempBasalInProgress) { + if (!DanaRPump.getInstance().isTempBasalInProgress) { result.success = true; result.isTempCancel = true; result.comment = MainApp.gs(R.string.virtualpump_resultok); - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("cancelRealTempBasal: OK"); return result; } else { @@ -379,4 +388,9 @@ public class DanaRPlugin extends AbstractDanaRPlugin { public PumpEnactResult loadEvents() { return null; // no history, not needed } + + @Override + public PumpEnactResult setUserOptions() { + return sExecutionService.setUserOptions(); + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPump.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPump.java index 1e346695e3..df9b48f795 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPump.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPump.java @@ -9,18 +9,18 @@ import org.slf4j.LoggerFactory; import java.text.DecimalFormat; import java.util.Date; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.ProfileStore; +import info.nightscout.androidaps.logging.L; import info.nightscout.utils.SP; /** * Created by mike on 04.07.2016. */ public class DanaRPump { - private static Logger log = LoggerFactory.getLogger(DanaRPump.class); + private static Logger log = LoggerFactory.getLogger(L.PUMP); private static DanaRPump instance = null; @@ -30,6 +30,7 @@ public class DanaRPump { } public static void reset() { + log.debug("DanaRPump reset"); instance = null; } @@ -65,11 +66,11 @@ public class DanaRPump { // Info public String serialNumber = ""; - public Date shippingDate = new Date(0); + public long shippingDate = 0; public String shippingCountry = ""; public boolean isNewPump = true; public int password = -1; - public Date pumpTime = new Date(0); + public long pumpTime = 0; public static final int DOMESTIC_MODEL = 0x01; public static final int EXPORT_MODEL = 0x03; @@ -98,7 +99,7 @@ public class DanaRPump { public int batteryRemaining; public boolean bolusBlocked; - public Date lastBolusTime = new Date(0); + public long lastBolusTime = 0; public double lastBolusAmount; public double currentBasal; @@ -107,7 +108,7 @@ public class DanaRPump { public int tempBasalPercent; public int tempBasalRemainingMin; public int tempBasalTotalSec; - public Date tempBasalStart; + public long tempBasalStart; public boolean isDualBolusInProgress; public boolean isExtendedInProgress; @@ -115,7 +116,7 @@ public class DanaRPump { public double extendedBolusAmount; public double extendedBolusAbsoluteRate; public int extendedBolusSoFarInMinutes; - public Date extendedBolusStart; + public long extendedBolusStart; public int extendedBolusRemainingMinutes; public double extendedBolusDeliveredSoFar; //RS only @@ -161,7 +162,7 @@ public class DanaRPump { public int lowReservoirRate; public int cannulaVolume; public int refillAmount; - + public byte[] userOptionsFrompump; public double initialBolusAmount; // Bolus settings public int bolusCalculationOption; @@ -236,17 +237,23 @@ public class DanaRPump { return PROFILE_PREFIX + (activeProfile + 1); } - public static double[] buildDanaRProfileRecord(Profile nsProfile) { + public double[] buildDanaRProfileRecord(Profile nsProfile) { double[] record = new double[24]; for (Integer hour = 0; hour < 24; hour++) { //Some values get truncated to the next lower one. // -> round them to two decimals and make sure we are a small delta larger (that will get truncated) double value = Math.round(100d * nsProfile.getBasalTimeFromMidnight((Integer) (hour * 60 * 60)))/100d + 0.00001; - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMP)) log.debug("NS basal value for " + hour + ":00 is " + value); record[hour] = value; } return record; } + public boolean isPasswordOK() { + if (password != -1 && password != SP.getInt(R.string.key_danar_password, -1)) { + return false; + } + return true; + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/Dialogs/ProfileViewDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/Dialogs/ProfileViewDialog.java index d8157281bd..06906aa0b4 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/Dialogs/ProfileViewDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/Dialogs/ProfileViewDialog.java @@ -1,8 +1,6 @@ package info.nightscout.androidaps.plugins.PumpDanaR.Dialogs; import android.os.Bundle; -import android.os.Handler; -import android.os.HandlerThread; import android.support.v4.app.DialogFragment; import android.view.LayoutInflater; import android.view.View; @@ -10,22 +8,12 @@ import android.view.ViewGroup; import android.widget.Button; import android.widget.TextView; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Date; - import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.data.ProfileStore; -import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.data.Profile; +import info.nightscout.androidaps.data.ProfileStore; import info.nightscout.androidaps.interfaces.ProfileInterface; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; -import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPlugin; -import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; -import info.nightscout.androidaps.plugins.PumpDanaRKorean.DanaRKoreanPlugin; -import info.nightscout.androidaps.plugins.PumpDanaRv2.DanaRv2Plugin; import info.nightscout.androidaps.plugins.Treatments.fragments.ProfileGraph; import info.nightscout.utils.DecimalFormatter; @@ -33,8 +21,6 @@ import info.nightscout.utils.DecimalFormatter; * Created by mike on 10.07.2016. */ public class ProfileViewDialog extends DialogFragment { - private static Logger log = LoggerFactory.getLogger(ProfileViewDialog.class); - private TextView noProfile; private TextView units; private TextView dia; @@ -69,7 +55,7 @@ public class ProfileViewDialog extends DialogFragment { refreshButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - ConfigBuilderPlugin.getCommandQueue().readStatus("ProfileViewDialog", null); + ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("ProfileViewDialog", null); dismiss(); } }); @@ -85,13 +71,13 @@ public class ProfileViewDialog extends DialogFragment { } private void setContent() { - ProfileStore store = ((ProfileInterface)MainApp.getConfigBuilder().getActivePump()).getProfile(); + ProfileStore store = ((ProfileInterface)ConfigBuilderPlugin.getPlugin().getActivePump()).getProfile(); if (store != null) { noProfile.setVisibility(View.GONE); Profile profile = store.getDefaultProfile(); units.setText(profile.getUnits()); dia.setText(DecimalFormatter.to2Decimal(profile.getDia()) + " h"); - activeProfile.setText(((ProfileInterface) MainApp.getConfigBuilder().getActivePump()).getProfileName()); + activeProfile.setText(((ProfileInterface) ConfigBuilderPlugin.getPlugin().getActivePump()).getProfileName()); ic.setText(profile.getIcList()); isf.setText(profile.getIsfList()); basal.setText(profile.getBasalList()); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/SerialIOThread.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/SerialIOThread.java index 2f377a566a..a319353d63 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/SerialIOThread.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/SerialIOThread.java @@ -10,7 +10,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageHashTable; import info.nightscout.androidaps.plugins.PumpDanaR.services.AbstractSerialIOThread; @@ -20,7 +20,7 @@ import info.nightscout.utils.CRC; * Created by mike on 17.07.2016. */ public class SerialIOThread extends AbstractSerialIOThread { - private static Logger log = LoggerFactory.getLogger(SerialIOThread.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPBTCOMM); private InputStream mInputStream = null; private OutputStream mOutputStream = null; @@ -71,7 +71,7 @@ public class SerialIOThread extends AbstractSerialIOThread { message = MessageHashTable.findMessage(command); } - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPBTCOMM)) log.debug("<<<<< " + message.getMessageName() + " " + message.toHexString(extractedBuff)); // process the message content @@ -83,7 +83,7 @@ public class SerialIOThread extends AbstractSerialIOThread { } } } catch (Exception e) { - if (Config.logDanaSerialEngine && e.getMessage().indexOf("bt socket closed") < 0) + if (e.getMessage().indexOf("bt socket closed") < 0) log.error("Thread exception: ", e); mKeepRunning = false; } @@ -147,7 +147,7 @@ public class SerialIOThread extends AbstractSerialIOThread { processedMessage = message; byte[] messageBytes = message.getRawMessageBytes(); - if (Config.logDanaSerialEngine) + if (L.isEnabled(L.PUMPBTCOMM)) log.debug(">>>>> " + message.getMessageName() + " " + message.toHexString(messageBytes)); try { @@ -169,7 +169,8 @@ public class SerialIOThread extends AbstractSerialIOThread { log.warn("Reply not received " + message.getMessageName()); if (message.getCommand() == 0xF0F1) { DanaRPump.getInstance().isNewPump = false; - log.debug("Old firmware detected"); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("Old firmware detected"); } } } @@ -180,24 +181,29 @@ public class SerialIOThread extends AbstractSerialIOThread { try { mInputStream.close(); } catch (Exception e) { - if (Config.logDanaSerialEngine) log.debug(e.getMessage()); + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug(e.getMessage()); } try { mOutputStream.close(); } catch (Exception e) { - if (Config.logDanaSerialEngine) log.debug(e.getMessage()); + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug(e.getMessage()); } try { mRfCommSocket.close(); } catch (Exception e) { - if (Config.logDanaSerialEngine) log.debug(e.getMessage()); + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug(e.getMessage()); } try { System.runFinalization(); } catch (Exception e) { - if (Config.logDanaSerialEngine) log.debug(e.getMessage()); + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug(e.getMessage()); } - if (Config.logDanaSerialEngine) log.debug("Disconnected: " + reason); + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug("Disconnected: " + reason); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/activities/DanaRHistoryActivity.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/activities/DanaRHistoryActivity.java index 97c5569b4b..5a3e127b9a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/activities/DanaRHistoryActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/activities/DanaRHistoryActivity.java @@ -31,7 +31,9 @@ import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.db.DanaRHistoryRecord; import info.nightscout.androidaps.events.EventPumpStatusChanged; import info.nightscout.androidaps.interfaces.PluginType; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.PumpDanaR.comm.RecordTypes; import info.nightscout.androidaps.plugins.PumpDanaR.events.EventDanaRSyncStatus; import info.nightscout.androidaps.plugins.PumpDanaRKorean.DanaRKoreanPlugin; @@ -42,12 +44,9 @@ import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.ToastUtils; public class DanaRHistoryActivity extends Activity { - private static Logger log = LoggerFactory.getLogger(DanaRHistoryActivity.class); - - private boolean mBounded; + private static Logger log = LoggerFactory.getLogger(L.PUMP); private Handler mHandler; - private static HandlerThread mHandlerThread; static Profile profile = null; @@ -65,7 +64,7 @@ public class DanaRHistoryActivity extends Activity { public byte type; String name; - public TypeList(byte type, String name) { + TypeList(byte type, String name) { this.type = type; this.name = name; } @@ -78,7 +77,7 @@ public class DanaRHistoryActivity extends Activity { public DanaRHistoryActivity() { super(); - mHandlerThread = new HandlerThread(DanaRHistoryActivity.class.getSimpleName()); + HandlerThread mHandlerThread = new HandlerThread(DanaRHistoryActivity.class.getSimpleName()); mHandlerThread.start(); this.mHandler = new Handler(mHandlerThread.getLooper()); } @@ -116,8 +115,8 @@ public class DanaRHistoryActivity extends Activity { statusView.setVisibility(View.GONE); - boolean isKorean = MainApp.getSpecificPlugin(DanaRKoreanPlugin.class) != null && MainApp.getSpecificPlugin(DanaRKoreanPlugin.class).isEnabled(PluginType.PUMP); - boolean isRS = MainApp.getSpecificPlugin(DanaRSPlugin.class) != null && MainApp.getSpecificPlugin(DanaRSPlugin.class).isEnabled(PluginType.PUMP); + boolean isKorean = DanaRKoreanPlugin.getPlugin().isEnabled(PluginType.PUMP); + boolean isRS = DanaRSPlugin.getPlugin().isEnabled(PluginType.PUMP); // Types @@ -141,10 +140,30 @@ public class DanaRHistoryActivity extends Activity { R.layout.spinner_centered, typeList); historyTypeSpinner.setAdapter(spinnerAdapter); - reloadButton.setOnClickListener(new View.OnClickListener() { + reloadButton.setOnClickListener(v -> { + final TypeList selected = (TypeList) historyTypeSpinner.getSelectedItem(); + runOnUiThread(() -> { + reloadButton.setVisibility(View.GONE); + syncButton.setVisibility(View.GONE); + statusView.setVisibility(View.VISIBLE); + }); + clearCardView(); + ConfigBuilderPlugin.getPlugin().getCommandQueue().loadHistory(selected.type, new Callback() { + @Override + public void run() { + loadDataFromDB(selected.type); + runOnUiThread(() -> { + reloadButton.setVisibility(View.VISIBLE); + syncButton.setVisibility(View.VISIBLE); + statusView.setVisibility(View.GONE); + }); + } + }); + }); + + syncButton.setOnClickListener(v -> mHandler.post(new Runnable() { @Override - public void onClick(View v) { - final TypeList selected = (TypeList) historyTypeSpinner.getSelectedItem(); + public void run() { runOnUiThread(new Runnable() { @Override public void run() { @@ -153,52 +172,18 @@ public class DanaRHistoryActivity extends Activity { statusView.setVisibility(View.VISIBLE); } }); - clearCardView(); - ConfigBuilderPlugin.getCommandQueue().loadHistory(selected.type, new Callback() { + DanaRNSHistorySync sync = new DanaRNSHistorySync(historyList); + sync.sync(DanaRNSHistorySync.SYNC_ALL); + runOnUiThread(new Runnable() { @Override public void run() { - loadDataFromDB(selected.type); - runOnUiThread(new Runnable() { - @Override - public void run() { - reloadButton.setVisibility(View.VISIBLE); - syncButton.setVisibility(View.VISIBLE); - statusView.setVisibility(View.GONE); - } - }); + reloadButton.setVisibility(View.VISIBLE); + syncButton.setVisibility(View.VISIBLE); + statusView.setVisibility(View.GONE); } }); } - }); - - syncButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - mHandler.post(new Runnable() { - @Override - public void run() { - runOnUiThread(new Runnable() { - @Override - public void run() { - reloadButton.setVisibility(View.GONE); - syncButton.setVisibility(View.GONE); - statusView.setVisibility(View.VISIBLE); - } - }); - DanaRNSHistorySync sync = new DanaRNSHistorySync(historyList); - sync.sync(DanaRNSHistorySync.SYNC_ALL); - runOnUiThread(new Runnable() { - @Override - public void run() { - reloadButton.setVisibility(View.VISIBLE); - syncButton.setVisibility(View.VISIBLE); - statusView.setVisibility(View.GONE); - } - }); - } - }); - } - }); + })); historyTypeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override @@ -213,7 +198,7 @@ public class DanaRHistoryActivity extends Activity { clearCardView(); } }); - profile = MainApp.getConfigBuilder().getProfile(); + profile = ProfileFunctions.getInstance().getProfile(); if (profile == null) { ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.noprofile)); finish(); @@ -324,7 +309,7 @@ public class DanaRHistoryActivity extends Activity { super.onAttachedToRecyclerView(recyclerView); } - public static class HistoryViewHolder extends RecyclerView.ViewHolder { + static class HistoryViewHolder extends RecyclerView.ViewHolder { CardView cv; TextView time; TextView value; @@ -355,45 +340,26 @@ public class DanaRHistoryActivity extends Activity { private void loadDataFromDB(byte type) { historyList = MainApp.getDbHelper().getDanaRHistoryRecordsByType(type); - runOnUiThread(new Runnable() { - @Override - public void run() { - recyclerView.swapAdapter(new RecyclerViewAdapter(historyList), false); - } - }); + runOnUiThread(() -> recyclerView.swapAdapter(new RecyclerViewAdapter(historyList), false)); } private void clearCardView() { historyList = new ArrayList<>(); - runOnUiThread(new Runnable() { - @Override - public void run() { - recyclerView.swapAdapter(new RecyclerViewAdapter(historyList), false); - } - }); + runOnUiThread(() -> recyclerView.swapAdapter(new RecyclerViewAdapter(historyList), false)); } @Subscribe public void onStatusEvent(final EventDanaRSyncStatus s) { - log.debug("EventDanaRSyncStatus: " + s.message); + if (L.isEnabled(L.PUMP)) + log.debug("EventDanaRSyncStatus: " + s.message); runOnUiThread( - new Runnable() { - @Override - public void run() { - statusView.setText(s.message); - } - }); + () -> statusView.setText(s.message)); } @Subscribe public void onStatusEvent(final EventPumpStatusChanged s) { runOnUiThread( - new Runnable() { - @Override - public void run() { - statusView.setText(s.textStatus()); - } - } + () -> statusView.setText(s.textStatus()) ); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/activities/DanaRNSHistorySync.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/activities/DanaRNSHistorySync.java index d505443c1d..eab9e8bc6e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/activities/DanaRNSHistorySync.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/activities/DanaRNSHistorySync.java @@ -10,22 +10,22 @@ import java.util.List; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.db.CareportalEvent; import info.nightscout.androidaps.db.DanaRHistoryRecord; -import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; -import info.nightscout.androidaps.data.Profile; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.PumpDanaR.comm.RecordTypes; import info.nightscout.androidaps.plugins.PumpDanaR.events.EventDanaRSyncStatus; import info.nightscout.utils.DateUtil; -import info.nightscout.utils.NSUpload; -import info.nightscout.utils.ToastUtils; +import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; /** * Created by mike on 20.07.2016. */ public class DanaRNSHistorySync { - private static Logger log = LoggerFactory.getLogger(DanaRNSHistorySync.class); + private static Logger log = LoggerFactory.getLogger(L.PUMP); private List historyRecords; public final static int SYNC_BOLUS = 0b00000001; @@ -50,7 +50,8 @@ public class DanaRNSHistorySync { long records = historyRecords.size(); long processing = 0; long uploaded = 0; - log.debug("Database contains " + records + " records"); + if (L.isEnabled(L.PUMP)) + log.debug("Database contains " + records + " records"); EventDanaRSyncStatus ev = new EventDanaRSyncStatus(); for (DanaRHistoryRecord record : historyRecords) { processing++; @@ -63,7 +64,8 @@ public class DanaRNSHistorySync { if ((what & SYNC_BOLUS) == 0) break; switch (record.bolusType) { case "S": - log.debug("Syncing standard bolus record " + record.recordValue + "U " + DateUtil.toISOString(record.recordDate)); + if (L.isEnabled(L.PUMP)) + log.debug("Syncing standard bolus record " + record.recordValue + "U " + DateUtil.toISOString(record.recordDate)); nsrec.put(DANARSIGNATURE, record.bytes); nsrec.put("eventType", "Meal Bolus"); nsrec.put("insulin", record.recordValue); @@ -75,7 +77,8 @@ public class DanaRNSHistorySync { break; case "E": if (record.recordDuration > 0) { - log.debug("Syncing extended bolus record " + record.recordValue + "U " + DateUtil.toISOString(record.recordDate)); + if (L.isEnabled(L.PUMP)) + log.debug("Syncing extended bolus record " + record.recordValue + "U " + DateUtil.toISOString(record.recordDate)); nsrec.put(DANARSIGNATURE, record.bytes); nsrec.put("eventType", CareportalEvent.COMBOBOLUS); nsrec.put("insulin", 0); @@ -91,11 +94,13 @@ public class DanaRNSHistorySync { uploaded++; ev.message += MainApp.gs(R.string.danar_ebolus); } else { - log.debug("NOT Syncing extended bolus record " + record.recordValue + "U " + DateUtil.toISOString(record.recordDate) + " zero duration"); + if (L.isEnabled(L.PUMP)) + log.debug("NOT Syncing extended bolus record " + record.recordValue + "U " + DateUtil.toISOString(record.recordDate) + " zero duration"); } break; case "DS": - log.debug("Syncing dual(S) bolus record " + record.recordValue + "U " + DateUtil.toISOString(record.recordDate)); + if (L.isEnabled(L.PUMP)) + log.debug("Syncing dual(S) bolus record " + record.recordValue + "U " + DateUtil.toISOString(record.recordDate)); nsrec.put(DANARSIGNATURE, record.bytes); nsrec.put("eventType", CareportalEvent.COMBOBOLUS); nsrec.put("insulin", record.recordValue); @@ -108,7 +113,8 @@ public class DanaRNSHistorySync { ev.message += MainApp.gs(R.string.danar_dsbolus); break; case "DE": - log.debug("Syncing dual(E) bolus record " + record.recordValue + "U " + DateUtil.toISOString(record.recordDate)); + if (L.isEnabled(L.PUMP)) + log.debug("Syncing dual(E) bolus record " + record.recordValue + "U " + DateUtil.toISOString(record.recordDate)); nsrec.put(DANARSIGNATURE, record.bytes); nsrec.put("eventType", CareportalEvent.COMBOBOLUS); nsrec.put("duration", record.recordDuration); @@ -124,13 +130,14 @@ public class DanaRNSHistorySync { ev.message += MainApp.gs(R.string.danar_debolus); break; default: - log.debug("Unknown bolus record"); + log.error("Unknown bolus record"); break; } break; case RecordTypes.RECORD_TYPE_ERROR: if ((what & SYNC_ERROR) == 0) break; - log.debug("Syncing error record " + DateUtil.toISOString(record.recordDate)); + if (L.isEnabled(L.PUMP)) + log.debug("Syncing error record " + DateUtil.toISOString(record.recordDate)); nsrec.put(DANARSIGNATURE, record.bytes); nsrec.put("eventType", "Note"); nsrec.put("notes", "Error"); @@ -142,7 +149,8 @@ public class DanaRNSHistorySync { break; case RecordTypes.RECORD_TYPE_REFILL: if ((what & SYNC_REFILL) == 0) break; - log.debug("Syncing refill record " + record.recordValue + " " + DateUtil.toISOString(record.recordDate)); + if (L.isEnabled(L.PUMP)) + log.debug("Syncing refill record " + record.recordValue + " " + DateUtil.toISOString(record.recordDate)); nsrec.put(DANARSIGNATURE, record.bytes); nsrec.put("eventType", "Insulin Change"); nsrec.put("notes", "Refill " + record.recordValue + "U"); @@ -154,7 +162,8 @@ public class DanaRNSHistorySync { break; case RecordTypes.RECORD_TYPE_BASALHOUR: if ((what & SYNC_BASALHOURS) == 0) break; - log.debug("Syncing basal hour record " + record.recordValue + " " + DateUtil.toISOString(record.recordDate)); + if (L.isEnabled(L.PUMP)) + log.debug("Syncing basal hour record " + record.recordValue + " " + DateUtil.toISOString(record.recordDate)); nsrec.put(DANARSIGNATURE, record.bytes); nsrec.put("eventType", CareportalEvent.TEMPBASAL); nsrec.put("absolute", record.recordValue); @@ -170,10 +179,11 @@ public class DanaRNSHistorySync { break; case RecordTypes.RECORD_TYPE_GLUCOSE: if ((what & SYNC_GLUCOSE) == 0) break; - log.debug("Syncing glucose record " + record.recordValue + " " + DateUtil.toISOString(record.recordDate)); + if (L.isEnabled(L.PUMP)) + log.debug("Syncing glucose record " + record.recordValue + " " + DateUtil.toISOString(record.recordDate)); nsrec.put(DANARSIGNATURE, record.bytes); nsrec.put("eventType", "BG Check"); - nsrec.put("glucose", Profile.fromMgdlToUnits(record.recordValue, MainApp.getConfigBuilder().getProfileUnits())); + nsrec.put("glucose", Profile.fromMgdlToUnits(record.recordValue, ProfileFunctions.getInstance().getProfileUnits())); nsrec.put("glucoseType", "Finger"); nsrec.put("created_at", DateUtil.toISOString(record.recordDate)); nsrec.put("enteredBy", "openaps://" + MainApp.gs(R.string.app_name)); @@ -183,7 +193,8 @@ public class DanaRNSHistorySync { break; case RecordTypes.RECORD_TYPE_CARBO: if ((what & SYNC_CARBO) == 0) break; - log.debug("Syncing carbo record " + record.recordValue + "g " + DateUtil.toISOString(record.recordDate)); + if (L.isEnabled(L.PUMP)) + log.debug("Syncing carbo record " + record.recordValue + "g " + DateUtil.toISOString(record.recordDate)); nsrec.put(DANARSIGNATURE, record.bytes); nsrec.put("eventType", "Meal Bolus"); nsrec.put("carbs", record.recordValue); @@ -195,7 +206,8 @@ public class DanaRNSHistorySync { break; case RecordTypes.RECORD_TYPE_ALARM: if ((what & SYNC_ALARM) == 0) break; - log.debug("Syncing alarm record " + record.recordAlarm + " " + DateUtil.toISOString(record.recordDate)); + if (L.isEnabled(L.PUMP)) + log.debug("Syncing alarm record " + record.recordAlarm + " " + DateUtil.toISOString(record.recordDate)); nsrec.put(DANARSIGNATURE, record.bytes); nsrec.put("eventType", "Note"); nsrec.put("notes", "Alarm: " + record.recordAlarm); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/activities/DanaRUserOptionsActivity.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/activities/DanaRUserOptionsActivity.java new file mode 100644 index 0000000000..d2d08a5d0b --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/activities/DanaRUserOptionsActivity.java @@ -0,0 +1,212 @@ +package info.nightscout.androidaps.plugins.PumpDanaR.activities; + +import android.app.Activity; +import android.os.Bundle; +import android.widget.Button; +import android.widget.RadioButton; +import android.widget.RadioGroup; +import android.widget.Switch; + +import com.squareup.otto.Subscribe; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.text.DecimalFormat; + +import info.nightscout.androidaps.Constants; +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.events.EventInitializationChanged; +import info.nightscout.androidaps.interfaces.PluginType; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPlugin; +import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; +import info.nightscout.androidaps.plugins.PumpDanaRS.DanaRSPlugin; +import info.nightscout.androidaps.plugins.PumpDanaRv2.DanaRv2Plugin; +import info.nightscout.utils.NumberPicker; + +/** + * Created by Rumen Georgiev on 5/31/2018. + */ + +public class DanaRUserOptionsActivity extends Activity { + private static Logger log = LoggerFactory.getLogger(L.PUMP); + + Switch timeFormat; + Switch buttonScroll; + Switch beep; + RadioGroup pumpAlarm; + RadioButton pumpAlarmSound; + RadioButton pumpAlarmVibrate; + RadioButton pumpAlarmBoth; + Switch pumpUnits; + NumberPicker screenTimeout; + NumberPicker backlightTimeout; + NumberPicker shutdown; + NumberPicker lowReservoir; + Button saveToPumpButton; + // This is for Dana pumps only + boolean isRS = MainApp.getSpecificPlugin(DanaRSPlugin.class) != null && MainApp.getSpecificPlugin(DanaRSPlugin.class).isEnabled(PluginType.PUMP); + boolean isDanaR = MainApp.getSpecificPlugin(DanaRPlugin.class) != null && MainApp.getSpecificPlugin(DanaRPlugin.class).isEnabled(PluginType.PUMP); + boolean isDanaRv2 = MainApp.getSpecificPlugin(DanaRv2Plugin.class) != null && MainApp.getSpecificPlugin(DanaRv2Plugin.class).isEnabled(PluginType.PUMP); + + @Override + protected void onResume() { + super.onResume(); + MainApp.bus().register(this); + } + + @Override + protected void onPause() { + super.onPause(); + MainApp.bus().unregister(this); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.danar_user_options); + + timeFormat = (Switch) findViewById(R.id.danar_timeformat); + buttonScroll = (Switch) findViewById(R.id.danar_buttonscroll); + beep = (Switch) findViewById(R.id.danar_beep); + pumpAlarm = (RadioGroup) findViewById(R.id.danar_pumpalarm); + pumpAlarmSound = (RadioButton) findViewById(R.id.danar_pumpalarm_sound); + pumpAlarmVibrate = (RadioButton) findViewById(R.id.danar_pumpalarm_vibrate); + pumpAlarmBoth = (RadioButton) findViewById(R.id.danar_pumpalarm_both); + screenTimeout = (NumberPicker) findViewById(R.id.danar_screentimeout); + backlightTimeout = (NumberPicker) findViewById(R.id.danar_backlight); + pumpUnits = (Switch) findViewById(R.id.danar_units); + shutdown = (NumberPicker) findViewById(R.id.danar_shutdown); + lowReservoir = (NumberPicker) findViewById(R.id.danar_lowreservoir); + saveToPumpButton = (Button) findViewById(R.id.save_user_options); + + saveToPumpButton.setOnClickListener(v -> onSaveClick()); + + DanaRPump pump = DanaRPump.getInstance(); + //used for debugging + if (L.isEnabled(L.PUMP)) + log.debug("UserOptionsLoaded:" + (System.currentTimeMillis() - pump.lastConnection) / 1000 + " s ago" + + "\ntimeDisplayType:" + pump.timeDisplayType + + "\nbuttonScroll:" + pump.buttonScrollOnOff + + "\ntimeDisplayType:" + pump.timeDisplayType + + "\nlcdOnTimeSec:" + pump.lcdOnTimeSec + + "\nbacklight:" + pump.backlightOnTimeSec + + "\npumpUnits:" + pump.units + + "\nlowReservoir:" + pump.lowReservoirRate); + + screenTimeout.setParams((double) pump.lcdOnTimeSec, 5d, 240d, 5d, new DecimalFormat("1"), false); + backlightTimeout.setParams((double) pump.backlightOnTimeSec, 1d, 60d, 1d, new DecimalFormat("1"), false); + shutdown.setParams((double) pump.shutdownHour, 0d, 24d, 1d, new DecimalFormat("1"), true); + lowReservoir.setParams((double) pump.lowReservoirRate, 10d, 60d, 10d, new DecimalFormat("10"), false); + switch (pump.beepAndAlarm) { + case 0x01: + pumpAlarmSound.setChecked(true); + break; + case 0x02: + pumpAlarmVibrate.setChecked(true); + break; + case 0x11: + pumpAlarmBoth.setChecked(true); + break; + case 0x101: + pumpAlarmSound.setChecked(true); + beep.setChecked(true); + break; + case 0x110: + pumpAlarmVibrate.setChecked(true); + beep.setChecked(true); + break; + case 0x111: + pumpAlarmBoth.setChecked(true); + beep.setChecked(true); + break; + } + if (pump.lastSettingsRead == 0) + log.error("No settings loaded from pump!"); + else + setData(); + } + + public void setData() { + DanaRPump pump = DanaRPump.getInstance(); + // in DanaRS timeDisplay values are reversed + timeFormat.setChecked((!isRS && pump.timeDisplayType != 0) || (isRS && pump.timeDisplayType == 0)); + buttonScroll.setChecked(pump.buttonScrollOnOff != 0); + beep.setChecked(pump.beepAndAlarm > 4); + screenTimeout.setValue((double) pump.lcdOnTimeSec); + backlightTimeout.setValue((double) pump.backlightOnTimeSec); + pumpUnits.setChecked(pump.getUnits() != null && pump.getUnits().equals(Constants.MMOL)); + shutdown.setValue((double) pump.shutdownHour); + lowReservoir.setValue((double) pump.lowReservoirRate); + } + + @Subscribe + public void onEventInitializationChanged(EventInitializationChanged ignored) { + runOnUiThread(this::setData); + } + + public void onSaveClick() { + if (!isRS && !isDanaR && !isDanaRv2) { + //exit if pump is not DanaRS, Dana!, or DanaR with upgraded firmware + return; + } + DanaRPump pump = DanaRPump.getInstance(); + if (timeFormat.isChecked()) + pump.timeDisplayType = 1; + else + pump.timeDisplayType = 0; + // displayTime on RS is reversed + if (isRS) { + if (timeFormat.isChecked()) + pump.timeDisplayType = 0; + else + pump.timeDisplayType = 1; + } + if (buttonScroll.isChecked()) + pump.buttonScrollOnOff = 1; + else + pump.buttonScrollOnOff = 0; + + pump.beepAndAlarm = 1; // default + if (pumpAlarmSound.isChecked()) pump.beepAndAlarm = 1; + else if (pumpAlarmVibrate.isChecked()) pump.beepAndAlarm = 2; + else if (pumpAlarmBoth.isChecked()) pump.beepAndAlarm = 3; + if (beep.isChecked()) pump.beepAndAlarm += 4; + + + // step is 5 seconds + int screenTimeoutValue = !screenTimeout.getText().isEmpty() ? (Integer.parseInt(screenTimeout.getText().toString()) / 5) * 5 : 5; + if (screenTimeoutValue > 4 && screenTimeoutValue < 241) { + pump.lcdOnTimeSec = screenTimeoutValue; + } else { + pump.lcdOnTimeSec = 5; + } + int backlightTimeoutValue = !backlightTimeout.getText().isEmpty() ? Integer.parseInt(backlightTimeout.getText().toString()) : 1; + if (backlightTimeoutValue > 0 && backlightTimeoutValue < 61) { + pump.backlightOnTimeSec = backlightTimeoutValue; + } + if (pumpUnits.isChecked()) { + pump.units = 1; + } else { + pump.units = 0; + } + int shutDownValue = !shutdown.getText().isEmpty() ? Integer.parseInt(shutdown.getText().toString()) : 0; + if (shutDownValue > -1 && shutDownValue < 25) { + pump.shutdownHour = shutDownValue; + } else { + pump.shutdownHour = 0; + } + int lowReservoirValue = !lowReservoir.getText().isEmpty() ? (Integer.parseInt(lowReservoir.getText().toString()) * 10) / 10 : 10; + if (lowReservoirValue > 9 && lowReservoirValue < 51) { + pump.lowReservoirRate = lowReservoirValue; + } else + pump.lowReservoirRate = 10; + + ConfigBuilderPlugin.getPlugin().getCommandQueue().setUserOptions(null); + finish(); + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MessageBase.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MessageBase.java index 2e6c02458e..0fd444412f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MessageBase.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MessageBase.java @@ -12,7 +12,7 @@ import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; import info.nightscout.utils.CRC; /* @@ -22,7 +22,7 @@ import info.nightscout.utils.CRC; */ public class MessageBase { - private static Logger log = LoggerFactory.getLogger(MessageBase.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); protected byte[] buffer = new byte[512]; private int position = 6; @@ -95,7 +95,7 @@ public class MessageBase { } public void handleMessage(byte[] bytes) { - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { if (bytes.length > 6) { int command = (bytes[5] & 0xFF) | ((bytes[4] << 8) & 0xFF00); log.debug("UNPROCESSED MSG: " + getMessageName() + " Command: " + String.format("%04X", command) + " Data: " + toHexString(bytes)); @@ -129,8 +129,8 @@ public class MessageBase { return 0; } - public static Date dateTimeFromBuff(byte[] buff, int offset) { - Date date = + public static long dateTimeFromBuff(byte[] buff, int offset) { + return new Date( 100 + intFromBuff(buff, offset, 1), intFromBuff(buff, offset + 1, 1) - 1, @@ -138,12 +138,11 @@ public class MessageBase { intFromBuff(buff, offset + 3, 1), intFromBuff(buff, offset + 4, 1), 0 - ); - return date; + ).getTime(); } - public static Date dateTimeSecFromBuff(byte[] buff, int offset) { - Date date = + public static synchronized long dateTimeSecFromBuff(byte[] buff, int offset) { + return new Date( 100 + intFromBuff(buff, offset, 1), intFromBuff(buff, offset + 1, 1) - 1, @@ -151,18 +150,16 @@ public class MessageBase { intFromBuff(buff, offset + 3, 1), intFromBuff(buff, offset + 4, 1), intFromBuff(buff, offset + 5, 1) - ); - return date; + ).getTime(); } - public static Date dateFromBuff(byte[] buff, int offset) { - Date date = + public static long dateFromBuff(byte[] buff, int offset) { + return new Date( 100 + intFromBuff(buff, offset, 1), intFromBuff(buff, offset + 1, 1) - 1, intFromBuff(buff, offset + 2, 1) - ); - return date; + ).getTime(); } @TargetApi(Build.VERSION_CODES.KITKAT) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MessageHashTable.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MessageHashTable.java index 10d2c0b091..e7f1adca07 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MessageHashTable.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MessageHashTable.java @@ -9,8 +9,6 @@ import java.util.HashMap; * Created by mike on 28.05.2016. */ public class MessageHashTable { - private static Logger log = LoggerFactory.getLogger(MessageHashTable.class); - public static HashMap messages = null; static { @@ -60,6 +58,7 @@ public class MessageHashTable { put(new MsgSettingProfileRatiosAll()); // 0x320D CMD_SETTING_V_CIR_CF_VALUE put(new MsgSetSingleBasalProfile()); // 0x3302 CMD_SETTING_BASAL_INS_S put(new MsgSetBasalProfile()); // 0x3306 CMD_SETTING_BASAL_PROFILE_S + put(new MsgSetUserOptions()); // 0x330B CMD_SETTING_USER_OPTIONS_S put(new MsgSetActivateBasalProfile()); // 0x330C CMD_SETTING_PROFILE_NUMBER_S put(new MsgHistoryAllDone()); // 0x41F1 CMD_HISTORY_ALL_DONE put(new MsgHistoryAll()); // 0x41F2 CMD_HISTORY_ALL diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MessageOriginalNames.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MessageOriginalNames.java index 3712945094..a285ce5120 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MessageOriginalNames.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MessageOriginalNames.java @@ -5,13 +5,15 @@ import org.slf4j.LoggerFactory; import java.util.HashMap; +import info.nightscout.androidaps.logging.L; + /** * Created by mike on 28.05.2016. */ public class MessageOriginalNames { - private static Logger log = LoggerFactory.getLogger(MessageOriginalNames.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); - public static HashMap messageNames; + private static HashMap messageNames; static { messageNames = new HashMap<>(); @@ -162,7 +164,7 @@ public class MessageOriginalNames { if (messageNames.containsKey(command)) return messageNames.get(command); else { - log.debug("Unknown command: " + String.format("%04X", command)); + log.error("Unknown command: " + String.format("%04X", command)); return "UNKNOWN_COMMAND"; } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgBolusProgress.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgBolusProgress.java index cb01a7d901..873824f966 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgBolusProgress.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgBolusProgress.java @@ -3,14 +3,14 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.plugins.Treatments.Treatment; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress; +import info.nightscout.androidaps.plugins.Treatments.Treatment; public class MsgBolusProgress extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgBolusProgress.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); private static Treatment t; private static double amount; @@ -27,6 +27,8 @@ public class MsgBolusProgress extends MessageBase { this.amount = amount; this.t = t; lastReceive = System.currentTimeMillis(); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message: amount: " + amount + " treatment: " + t.toString()); } @Override @@ -40,7 +42,7 @@ public class MsgBolusProgress extends MessageBase { bolusingEvent.t = t; bolusingEvent.percent = Math.min((int) (done / amount * 100), 100); - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Bolus remaining: " + progress + " delivered: " + done); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgBolusStart.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgBolusStart.java index 7586edf825..06200d1f0c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgBolusStart.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgBolusStart.java @@ -3,13 +3,12 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.interfaces.Constraint; -import info.nightscout.utils.HardLimits; +import info.nightscout.androidaps.logging.L; public class MsgBolusStart extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgBolusStart.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public static int errorCode; @@ -25,7 +24,7 @@ public class MsgBolusStart extends MessageBase { AddParamInt((int) (amount * 100)); - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Bolus start : " + amount); } @@ -34,9 +33,10 @@ public class MsgBolusStart extends MessageBase { errorCode = intFromBuff(bytes, 0, 1); if (errorCode != 2) { failed = true; - log.debug("Messsage response: " + errorCode + " FAILED!!"); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("Messsage response: " + errorCode + " FAILED!!"); } else { - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Messsage response: " + errorCode + " OK"); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgBolusStartWithSpeed.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgBolusStartWithSpeed.java index dd4251a350..a3160ff887 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgBolusStartWithSpeed.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgBolusStartWithSpeed.java @@ -3,13 +3,12 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.interfaces.Constraint; -import info.nightscout.utils.HardLimits; +import info.nightscout.androidaps.logging.L; public class MsgBolusStartWithSpeed extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgBolusStartWithSpeed.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public static int errorCode; @@ -26,7 +25,7 @@ public class MsgBolusStartWithSpeed extends MessageBase { AddParamInt((int) (amount * 100)); AddParamByte((byte) speed); - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Bolus start : " + amount + " speed: " + speed); } @@ -35,9 +34,10 @@ public class MsgBolusStartWithSpeed extends MessageBase { errorCode = intFromBuff(bytes, 0, 1); if (errorCode != 2) { failed = true; - log.debug("Messsage response: " + errorCode + " FAILED!!"); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("Messsage response: " + errorCode + " FAILED!!"); } else { - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Messsage response: " + errorCode + " OK"); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgBolusStop.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgBolusStop.java index 5c677b813e..fe5d47c131 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgBolusStop.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgBolusStop.java @@ -5,11 +5,12 @@ import org.slf4j.LoggerFactory; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.plugins.Treatments.Treatment; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress; +import info.nightscout.androidaps.plugins.Treatments.Treatment; public class MsgBolusStop extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgBolusStop.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); private static Treatment t; private static Double amount; @@ -26,10 +27,14 @@ public class MsgBolusStop extends MessageBase { this.t = t; this.amount = amount; forced = false; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("Bolus stop: amount: " + amount + " treatment: " + t.toString()); } @Override public void handleMessage(byte[] bytes) { + if (L.isEnabled(L.PUMPCOMM)) + log.debug("Messsage received"); EventOverviewBolusProgress bolusingEvent = EventOverviewBolusProgress.getInstance(); stopped = true; if (!forced) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgCheckValue.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgCheckValue.java index 3f0c306940..e04d9243e7 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgCheckValue.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgCheckValue.java @@ -3,21 +3,21 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.R; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPlugin; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; -import info.nightscout.utils.ToastUtils; /** * Created by mike on 30.06.2016. */ public class MsgCheckValue extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgCheckValue.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgCheckValue() { SetCommand(0xF0F1); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override @@ -25,7 +25,8 @@ public class MsgCheckValue extends MessageBase { DanaRPump pump = DanaRPump.getInstance(); pump.isNewPump = true; - log.debug("New firmware confirmed"); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New firmware confirmed"); pump.model = intFromBuff(bytes, 0, 1); pump.protocol = intFromBuff(bytes, 1, 1); @@ -35,7 +36,7 @@ public class MsgCheckValue extends MessageBase { log.debug("Wrong model selected"); } - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Model: " + String.format("%02X ", pump.model)); log.debug("Protocol: " + String.format("%02X ", pump.protocol)); log.debug("Product Code: " + String.format("%02X ", pump.productCode)); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgError.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgError.java index e42327c3b0..a8e67a98a0 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgError.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgError.java @@ -3,17 +3,19 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress; -import info.nightscout.utils.NSUpload; +import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; public class MsgError extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgError.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgError() { SetCommand(0x0601); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override @@ -46,8 +48,9 @@ public class MsgError extends MessageBase { MsgBolusStop.stopped = true; bolusingEvent.status = errorString; MainApp.bus().post(bolusingEvent); + failed=true; } - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Error detected: " + errorString); NSUpload.uploadError(errorString); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryAlarm.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryAlarm.java index 24ea6d0f37..7adb335e93 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryAlarm.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryAlarm.java @@ -3,13 +3,17 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import info.nightscout.androidaps.logging.L; + /** * Created by mike on 20.07.2016. */ public class MsgHistoryAlarm extends MsgHistoryAll { - private static Logger log = LoggerFactory.getLogger(MsgHistoryAlarm.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgHistoryAlarm() { SetCommand(0x3105); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } // Handle message taken from MsgHistoryAll } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryAll.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryAll.java index 4e4bc759f5..0fe64a20f5 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryAll.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryAll.java @@ -7,22 +7,25 @@ import java.util.Date; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.db.DanaRHistoryRecord; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.events.EventDanaRSyncStatus; import info.nightscout.utils.DateUtil; public class MsgHistoryAll extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgHistoryAll.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgHistoryAll() { SetCommand(0x41F2); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override public void handleMessage(byte[] bytes) { byte recordCode = (byte) intFromBuff(bytes, 0, 1); - Date date = dateFromBuff(bytes, 1); // 3 bytes - Date datetime = dateTimeFromBuff(bytes, 1); // 5 bytes - Date datetimewihtsec = dateTimeSecFromBuff(bytes, 1); // 6 bytes + long date = dateFromBuff(bytes, 1); // 3 bytes + long datetime = dateTimeFromBuff(bytes, 1); // 5 bytes + long datetimewihtsec = dateTimeSecFromBuff(bytes, 1); // 6 bytes double dailyBasal = intFromBuff(bytes, 4, 2) * 0.01d; double dailyBolus = intFromBuff(bytes, 6, 2) * 0.01d; @@ -43,7 +46,7 @@ public class MsgHistoryAll extends MessageBase { switch (recordCode) { case RecordTypes.RECORD_TYPE_BOLUS: - danaRHistoryRecord.recordDate = datetime.getTime(); + danaRHistoryRecord.recordDate = datetime; switch (0xF0 & paramByte8) { case 0xA0: danaRHistoryRecord.bolusType = "DS"; @@ -70,48 +73,48 @@ public class MsgHistoryAll extends MessageBase { break; case RecordTypes.RECORD_TYPE_DAILY: messageType += "dailyinsulin"; - danaRHistoryRecord.recordDate = date.getTime(); + danaRHistoryRecord.recordDate = date; danaRHistoryRecord.recordDailyBasal = dailyBasal; danaRHistoryRecord.recordDailyBolus = dailyBolus; break; case RecordTypes.RECORD_TYPE_PRIME: messageType += "prime"; - danaRHistoryRecord.recordDate = datetimewihtsec.getTime(); + danaRHistoryRecord.recordDate = datetimewihtsec; danaRHistoryRecord.recordValue = value * 0.01; break; case RecordTypes.RECORD_TYPE_ERROR: messageType += "error"; - danaRHistoryRecord.recordDate = datetimewihtsec.getTime(); + danaRHistoryRecord.recordDate = datetimewihtsec; danaRHistoryRecord.recordValue = value * 0.01; break; case RecordTypes.RECORD_TYPE_REFILL: messageType += "refill"; - danaRHistoryRecord.recordDate = datetimewihtsec.getTime(); + danaRHistoryRecord.recordDate = datetimewihtsec; danaRHistoryRecord.recordValue = value * 0.01; break; case RecordTypes.RECORD_TYPE_BASALHOUR: messageType += "basal hour"; - danaRHistoryRecord.recordDate = datetimewihtsec.getTime(); + danaRHistoryRecord.recordDate = datetimewihtsec; danaRHistoryRecord.recordValue = value * 0.01; break; case RecordTypes.RECORD_TYPE_TB: messageType += "tb"; - danaRHistoryRecord.recordDate = datetimewihtsec.getTime(); + danaRHistoryRecord.recordDate = datetimewihtsec; danaRHistoryRecord.recordValue = value * 0.01; break; case RecordTypes.RECORD_TYPE_GLUCOSE: messageType += "glucose"; - danaRHistoryRecord.recordDate = datetimewihtsec.getTime(); + danaRHistoryRecord.recordDate = datetimewihtsec; danaRHistoryRecord.recordValue = value; break; case RecordTypes.RECORD_TYPE_CARBO: messageType += "carbo"; - danaRHistoryRecord.recordDate = datetimewihtsec.getTime(); + danaRHistoryRecord.recordDate = datetimewihtsec; danaRHistoryRecord.recordValue = value; break; case RecordTypes.RECORD_TYPE_ALARM: messageType += "alarm"; - danaRHistoryRecord.recordDate = datetimewihtsec.getTime(); + danaRHistoryRecord.recordDate = datetimewihtsec; String strAlarm = "None"; switch ((int) paramByte8) { case 67: @@ -132,12 +135,15 @@ public class MsgHistoryAll extends MessageBase { break; case RecordTypes.RECORD_TYPE_SUSPEND: messageType += "suspend"; - danaRHistoryRecord.recordDate = datetimewihtsec.getTime(); + danaRHistoryRecord.recordDate = datetimewihtsec; String strRecordValue = "Off"; if ((int) paramByte8 == 79) strRecordValue = "On"; danaRHistoryRecord.stringRecordValue = strRecordValue; break; + case 17: + failed = true; + break; } MainApp.getDbHelper().createOrUpdate(danaRHistoryRecord); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryAllDone.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryAllDone.java index 6ce3325715..e78771f99d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryAllDone.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryAllDone.java @@ -3,21 +3,23 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; public class MsgHistoryAllDone extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgHistoryAllDone.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public static boolean received = false; public MsgHistoryAllDone() { SetCommand(0x41F1); received = false; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override public void handleMessage(byte[] bytes) { received = true; - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("History all done received"); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryBasalHour.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryBasalHour.java index 3fd97135f0..f56e2af273 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryBasalHour.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryBasalHour.java @@ -3,13 +3,17 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import info.nightscout.androidaps.logging.L; + /** * Created by mike on 20.07.2016. */ public class MsgHistoryBasalHour extends MsgHistoryAll { - private static Logger log = LoggerFactory.getLogger(MsgHistoryBasalHour.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgHistoryBasalHour() { SetCommand(0x310A); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } // Handle message taken from MsgHistoryAll } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryBolus.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryBolus.java index b213ba52fd..d675ddc488 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryBolus.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryBolus.java @@ -3,13 +3,18 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import info.nightscout.androidaps.logging.L; + /** * Created by mike on 20.07.2016. */ public class MsgHistoryBolus extends MsgHistoryAll { - private static Logger log = LoggerFactory.getLogger(MsgHistoryBolus.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); + public MsgHistoryBolus() { SetCommand(0x3101); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } // Handle message taken from MsgHistoryAll } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryCarbo.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryCarbo.java index 115dc73e02..6755800bba 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryCarbo.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryCarbo.java @@ -3,13 +3,17 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import info.nightscout.androidaps.logging.L; + /** * Created by mike on 20.07.2016. */ public class MsgHistoryCarbo extends MsgHistoryAll { - private static Logger log = LoggerFactory.getLogger(MsgHistoryCarbo.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgHistoryCarbo() { SetCommand(0x3107); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } // Handle message taken from MsgHistoryAll } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryDailyInsulin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryDailyInsulin.java index 77933c40da..68d46f0d20 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryDailyInsulin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryDailyInsulin.java @@ -3,13 +3,17 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import info.nightscout.androidaps.logging.L; + /** * Created by mike on 20.07.2016. */ public class MsgHistoryDailyInsulin extends MsgHistoryAll { - private static Logger log = LoggerFactory.getLogger(MsgHistoryDailyInsulin.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgHistoryDailyInsulin() { SetCommand(0x3102); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } // Handle message taken from MsgHistoryAll } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryDone.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryDone.java index 04d3cb3faf..63e51e24ba 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryDone.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryDone.java @@ -3,24 +3,26 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; /** * Created by mike on 20.07.2016. */ public class MsgHistoryDone extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgHistoryDone.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public static boolean received = false; public MsgHistoryDone() { SetCommand(0x31F1); received = false; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override public void handleMessage(byte[] bytes) { received = true; - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("History done received"); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryError.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryError.java index 3358a88fea..8d6d0615d4 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryError.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryError.java @@ -3,13 +3,18 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import info.nightscout.androidaps.logging.L; + /** * Created by mike on 20.07.2016. */ public class MsgHistoryError extends MsgHistoryAll { - private static Logger log = LoggerFactory.getLogger(MsgHistoryError.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); + public MsgHistoryError() { SetCommand(0x3106); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } // Handle message taken from MsgHistoryAll } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryGlucose.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryGlucose.java index f07b91e9d8..10fd68e3ab 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryGlucose.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryGlucose.java @@ -3,13 +3,18 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import info.nightscout.androidaps.logging.L; + /** * Created by mike on 20.07.2016. */ public class MsgHistoryGlucose extends MsgHistoryAll { - private static Logger log = LoggerFactory.getLogger(MsgHistoryGlucose.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); + public MsgHistoryGlucose() { SetCommand(0x3104); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } // Handle message taken from MsgHistoryAll } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryNew.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryNew.java index 5de685f65b..01f7197434 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryNew.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryNew.java @@ -3,13 +3,18 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import info.nightscout.androidaps.logging.L; + /** * Created by mike on 20.07.2016. */ public class MsgHistoryNew extends MsgHistoryAll { - private static Logger log = LoggerFactory.getLogger(MsgHistoryNew.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); + public MsgHistoryNew() { SetCommand(0x42F2); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } // Handle message taken from MsgHistoryAll } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryNewDone.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryNewDone.java index 2cde92bf9a..fb9118e629 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryNewDone.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryNewDone.java @@ -3,24 +3,26 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; /** * Created by mike on 20.07.2016. */ public class MsgHistoryNewDone extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgHistoryNewDone.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public static boolean received = false; public MsgHistoryNewDone() { SetCommand(0x42F1); received = false; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override public void handleMessage(byte[] bytes) { received = true; - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("History new done received"); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryRefill.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryRefill.java index daaed79023..238a606cfb 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryRefill.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistoryRefill.java @@ -3,13 +3,18 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import info.nightscout.androidaps.logging.L; + /** * Created by mike on 20.07.2016. */ public class MsgHistoryRefill extends MsgHistoryAll { - private static Logger log = LoggerFactory.getLogger(MsgHistoryRefill.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); + public MsgHistoryRefill() { SetCommand(0x3108); - } + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); + } // Handle message taken from MsgHistoryAll } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistorySuspend.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistorySuspend.java index db807a31b5..7182722f97 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistorySuspend.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgHistorySuspend.java @@ -3,13 +3,18 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import info.nightscout.androidaps.logging.L; + /** * Created by mike on 20.07.2016. */ public class MsgHistorySuspend extends MsgHistoryAll { - private static Logger log = LoggerFactory.getLogger(MsgHistorySuspend.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); + public MsgHistorySuspend() { SetCommand(0x3109); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } // Handle message taken from MsgHistoryAll } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgInitConnStatusBasic.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgInitConnStatusBasic.java index e7f6032c00..61150079cd 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgInitConnStatusBasic.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgInitConnStatusBasic.java @@ -3,14 +3,16 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; public class MsgInitConnStatusBasic extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgInitConnStatusBasic.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgInitConnStatusBasic() { SetCommand(0x0303); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override @@ -39,14 +41,17 @@ public class MsgInitConnStatusBasic extends MessageBase { boolean deliveryStepBolus = (bolusConfig & DanaRPump.DELIVERY_STEP_BOLUS) != 0; boolean deliveryBasal = (bolusConfig & DanaRPump.DELIVERY_BASAL) != 0; boolean deliveryExtBolus = (bolusConfig & DanaRPump.DELIVERY_EXT_BOLUS) != 0; - log.debug("Delivery prime: " + deliveryPrime); - log.debug("Delivery step bolus: " + deliveryStepBolus); - log.debug("Delivery basal: " + deliveryBasal); - log.debug("Delivery ext bolus: " + deliveryExtBolus); + if (L.isEnabled(L.PUMPCOMM)) { + log.debug("Delivery prime: " + deliveryPrime); + log.debug("Delivery step bolus: " + deliveryStepBolus); + log.debug("Delivery basal: " + deliveryBasal); + log.debug("Delivery ext bolus: " + deliveryExtBolus); + } } catch (Exception e) { + log.error("Unhadled exception", e); } - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Pump suspended: " + pump.pumpSuspended); log.debug("Calculator enabled: " + pump.calculatorEnabled); log.debug("Daily total units: " + pump.dailyTotalUnits); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgInitConnStatusBolus.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgInitConnStatusBolus.java index 4fc9844b0d..df9447cc45 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgInitConnStatusBolus.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgInitConnStatusBolus.java @@ -3,27 +3,30 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; -import info.nightscout.androidaps.plugins.Overview.notifications.Notification; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; +import info.nightscout.androidaps.plugins.Overview.notifications.Notification; +import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; /** * Created by mike on 28.05.2016. */ public class MsgInitConnStatusBolus extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgInitConnStatusBolus.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgInitConnStatusBolus() { SetCommand(0x0302); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override public void handleMessage(byte[] bytes) { if (bytes.length - 10 > 12) { + failed = true; return; } DanaRPump pump = DanaRPump.getInstance(); @@ -34,7 +37,7 @@ public class MsgInitConnStatusBolus extends MessageBase { pump.maxBolus = intFromBuff(bytes, 2, 2) / 100d; //int bolusRate = intFromBuff(bytes, 4, 8); - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Is Extended bolus enabled: " + pump.isExtendedBolusEnabled); log.debug("Bolus increment: " + pump.bolusStep); log.debug("Bolus max: " + pump.maxBolus); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgInitConnStatusOption.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgInitConnStatusOption.java index 560ed8b332..f8f82e16d0 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgInitConnStatusOption.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgInitConnStatusOption.java @@ -3,17 +3,25 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification; +import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; +import info.nightscout.androidaps.plugins.Overview.notifications.Notification; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; /** * Created by mike on 28.05.2016. */ public class MsgInitConnStatusOption extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgInitConnStatusOption.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgInitConnStatusOption() { SetCommand(0x0304); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override @@ -29,9 +37,22 @@ public class MsgInitConnStatusOption extends MessageBase { //int none = intFromBuff(bytes, 8, 1); if (bytes.length >= 21) { DanaRPump.getInstance().password = intFromBuff(bytes, 9, 2) ^ 0x3463; - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Pump password: " + DanaRPump.getInstance().password); + } else { + failed = true; } + + if (!DanaRPump.getInstance().isPasswordOK()) { + Notification notification = new Notification(Notification.WRONG_PUMP_PASSWORD, MainApp.gs(R.string.wrongpumppassword), Notification.URGENT); + MainApp.bus().post(new EventNewNotification(notification)); + } else { + MainApp.bus().post(new EventDismissNotification(Notification.WRONG_PUMP_PASSWORD)); + } + + // This is last message of initial sequence + if (ConfigBuilderPlugin.getPlugin().getActivePump() != null ) + ConfigBuilderPlugin.getPlugin().getActivePump().finishHandshaking(); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgInitConnStatusTime.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgInitConnStatusTime.java index 84d9c413bf..5404c58837 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgInitConnStatusTime.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgInitConnStatusTime.java @@ -5,32 +5,35 @@ import org.slf4j.LoggerFactory; import java.util.Date; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.events.EventRefreshGui; import info.nightscout.androidaps.interfaces.PluginType; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.Overview.notifications.Notification; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPlugin; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; import info.nightscout.androidaps.plugins.PumpDanaRKorean.DanaRKoreanPlugin; +import info.nightscout.utils.DateUtil; public class MsgInitConnStatusTime extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgInitConnStatusTime.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgInitConnStatusTime() { SetCommand(0x0301); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override public void handleMessage(byte[] bytes) { if (bytes.length - 10 > 7) { - Notification notification = new Notification(Notification.WRONG_DRIVER, MainApp.gs(R.string.pumpdrivercorrected), Notification.NORMAL); + Notification notification = new Notification(Notification.WRONG_DRIVER, MainApp.gs(R.string.pumpdrivercorrected), Notification.NORMAL); MainApp.bus().post(new EventNewNotification(notification)); MainApp.getSpecificPlugin(DanaRPlugin.class).disconnect("Wrong Model"); - log.debug("Wrong model selected. Switching to Korean DanaR"); + log.error("Wrong model selected. Switching to Korean DanaR"); MainApp.getSpecificPlugin(DanaRKoreanPlugin.class).setPluginEnabled(PluginType.PUMP, true); MainApp.getSpecificPlugin(DanaRKoreanPlugin.class).setFragmentVisible(PluginType.PUMP, true); MainApp.getSpecificPlugin(DanaRPlugin.class).setPluginEnabled(PluginType.PUMP, false); @@ -39,22 +42,25 @@ public class MsgInitConnStatusTime extends MessageBase { DanaRPump.reset(); // mark not initialized //If profile coming from pump, switch it as well - if(MainApp.getSpecificPlugin(DanaRPlugin.class).isEnabled(PluginType.PROFILE)){ + if (MainApp.getSpecificPlugin(DanaRPlugin.class).isEnabled(PluginType.PROFILE)) { (MainApp.getSpecificPlugin(DanaRPlugin.class)).setPluginEnabled(PluginType.PROFILE, false); (MainApp.getSpecificPlugin(DanaRKoreanPlugin.class)).setPluginEnabled(PluginType.PROFILE, true); } - MainApp.getConfigBuilder().storeSettings("ChangingDanaDriver"); + ConfigBuilderPlugin.getPlugin().storeSettings("ChangingDanaDriver"); MainApp.bus().post(new EventRefreshGui()); - ConfigBuilderPlugin.getCommandQueue().readStatus("PumpDriverChange", null); // force new connection + ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("PumpDriverChange", null); // force new connection + failed = false; return; + } else { + failed = true; } - Date time = dateTimeSecFromBuff(bytes, 0); + long time = dateTimeSecFromBuff(bytes, 0); int versionCode = intFromBuff(bytes, 6, 1); - if (Config.logDanaMessageDetail) { - log.debug("Pump time: " + time); + if (L.isEnabled(L.PUMPCOMM)) { + log.debug("Pump time: " + DateUtil.dateAndTimeFullString(time)); log.debug("Version code: " + versionCode); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgPCCommStart.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgPCCommStart.java index 619bbd9461..6f92c3241c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgPCCommStart.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgPCCommStart.java @@ -3,17 +3,20 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; public class MsgPCCommStart extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgPCCommStart.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); + public MsgPCCommStart() { SetCommand(0x3001); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override public void handleMessage(byte[] bytes) { - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("PC comm start received"); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgPCCommStop.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgPCCommStop.java index 20dd4e060f..255bb17532 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgPCCommStop.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgPCCommStop.java @@ -3,17 +3,19 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; public class MsgPCCommStop extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgPCCommStop.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgPCCommStop() { SetCommand(0x3002); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override public void handleMessage(byte[] bytes) { - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("PC comm stop received"); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetActivateBasalProfile.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetActivateBasalProfile.java index 64ed0488a4..2d222f9601 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetActivateBasalProfile.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetActivateBasalProfile.java @@ -3,20 +3,22 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; public class MsgSetActivateBasalProfile extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgSetActivateBasalProfile.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgSetActivateBasalProfile() { SetCommand(0x330C); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } // index 0-3 public MsgSetActivateBasalProfile(byte index) { this(); AddParamByte(index); - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Activate basal profile: " + index); } @@ -25,9 +27,10 @@ public class MsgSetActivateBasalProfile extends MessageBase { int result = intFromBuff(bytes, 0, 1); if (result != 1) { failed = true; - log.debug("Activate basal profile result: " + result + " FAILED!!!"); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("Activate basal profile result: " + result + " FAILED!!!"); } else { - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Activate basal profile result: " + result); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetBasalProfile.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetBasalProfile.java index 9f945e8b26..3e87e4bf41 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetBasalProfile.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetBasalProfile.java @@ -3,17 +3,19 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.plugins.Overview.notifications.Notification; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; +import info.nightscout.androidaps.plugins.Overview.notifications.Notification; public class MsgSetBasalProfile extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgSetBasalProfile.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgSetBasalProfile() { SetCommand(0x3306); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } // index 0-3 @@ -23,7 +25,7 @@ public class MsgSetBasalProfile extends MessageBase { for (Integer i = 0; i < 24; i++) { AddParamInt((int) (values[i] * 100)); } - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Set basal profile: " + index); } @@ -32,11 +34,12 @@ public class MsgSetBasalProfile extends MessageBase { int result = intFromBuff(bytes, 0, 1); if (result != 1) { failed = true; - log.debug("Set basal profile result: " + result + " FAILED!!!"); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("Set basal profile result: " + result + " FAILED!!!"); Notification reportFail = new Notification(Notification.PROFILE_SET_FAILED, MainApp.gs(R.string.profile_set_failed), Notification.URGENT); MainApp.bus().post(new EventNewNotification(reportFail)); } else { - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Set basal profile result: " + result); Notification reportOK = new Notification(Notification.PROFILE_SET_OK, MainApp.gs(R.string.profile_set_ok), Notification.INFO, 60); MainApp.bus().post(new EventNewNotification(reportOK)); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetCarbsEntry.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetCarbsEntry.java index 4fcd6dee9c..59cbcdafa0 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetCarbsEntry.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetCarbsEntry.java @@ -5,13 +5,15 @@ import org.slf4j.LoggerFactory; import java.util.Calendar; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; public class MsgSetCarbsEntry extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgSetCarbsEntry.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgSetCarbsEntry() { SetCommand(0x0402); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } public MsgSetCarbsEntry(long time, int amount) { @@ -27,7 +29,7 @@ public class MsgSetCarbsEntry extends MessageBase { AddParamByte((byte) (calendar.get(Calendar.SECOND))); AddParamByte((byte) 0x43); //?? AddParamInt(amount); - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Set carb entry: " + amount + " date " + calendar.getTime().toString()); } @@ -36,9 +38,10 @@ public class MsgSetCarbsEntry extends MessageBase { int result = intFromBuff(bytes, 0, 1); if (result != 1) { failed = true; - log.debug("Set carb entry result: " + result + " FAILED!!!"); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("Set carb entry result: " + result + " FAILED!!!"); } else { - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Set carb entry result: " + result); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetExtendedBolusStart.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetExtendedBolusStart.java index 420f0ccbf9..2577435e11 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetExtendedBolusStart.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetExtendedBolusStart.java @@ -3,16 +3,17 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.interfaces.Constraint; -import info.nightscout.utils.HardLimits; +import info.nightscout.androidaps.logging.L; public class MsgSetExtendedBolusStart extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgSetExtendedBolusStart.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgSetExtendedBolusStart() { SetCommand(0x0407); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } public MsgSetExtendedBolusStart(double amount, byte halfhours) { @@ -21,11 +22,15 @@ public class MsgSetExtendedBolusStart extends MessageBase { // HARDCODED LIMITS if (halfhours < 1) halfhours = 1; if (halfhours > 16) halfhours = 16; - amount = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(amount)).value(); - - AddParamInt((int) (amount * 100)); + Constraint constrainedAmount = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(amount)); + if (constrainedAmount != null) { + AddParamInt((int) (constrainedAmount.value() * 100)); + } else { + log.error("constrainedAmount of insulin is null!!"); + AddParamInt(0); + } AddParamByte(halfhours); - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Set extended bolus start: " + (((int) (amount * 100)) / 100d) + "U halfhours: " + (int) halfhours); } @@ -34,9 +39,10 @@ public class MsgSetExtendedBolusStart extends MessageBase { int result = intFromBuff(bytes, 0, 1); if (result != 1) { failed = true; - log.debug("Set extended bolus start result: " + result + " FAILED!!!"); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("Set extended bolus start result: " + result + " FAILED!!!"); } else { - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Set extended bolus start result: " + result); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetExtendedBolusStop.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetExtendedBolusStop.java index 7084949daa..504db719ea 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetExtendedBolusStop.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetExtendedBolusStop.java @@ -3,15 +3,15 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; public class MsgSetExtendedBolusStop extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgSetExtendedBolusStop.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgSetExtendedBolusStop() { SetCommand(0x0406); - if (Config.logDanaMessageDetail) - log.debug("Set extended bolus stop"); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override @@ -19,9 +19,10 @@ public class MsgSetExtendedBolusStop extends MessageBase { int result = intFromBuff(bytes, 0, 1); if (result != 1) { failed = true; - log.debug("Set extended bolus stop result: " + result + " FAILED!!!"); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("Set extended bolus stop result: " + result + " FAILED!!!"); } else { - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Set extended bolus stop result: " + result); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetSingleBasalProfile.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetSingleBasalProfile.java index 7dd9ca522b..eabf383b94 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetSingleBasalProfile.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetSingleBasalProfile.java @@ -3,14 +3,14 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.Overview.notifications.Notification; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; public class MsgSetSingleBasalProfile extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgSetSingleBasalProfile.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgSetSingleBasalProfile() { SetCommand(0x3302); @@ -22,8 +22,8 @@ public class MsgSetSingleBasalProfile extends MessageBase { for (Integer i = 0; i < 24; i++) { AddParamInt((int) (values[i] * 100)); } - if (Config.logDanaMessageDetail) - log.debug("Set basal profile"); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override @@ -31,11 +31,12 @@ public class MsgSetSingleBasalProfile extends MessageBase { int result = intFromBuff(bytes, 0, 1); if (result != 1) { failed = true; - log.debug("Set basal profile result: " + result + " FAILED!!!"); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("Set basal profile result: " + result + " FAILED!!!"); Notification reportFail = new Notification(Notification.PROFILE_SET_FAILED, MainApp.gs(R.string.profile_set_failed), Notification.URGENT); MainApp.bus().post(new EventNewNotification(reportFail)); } else { - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Set basal profile result: " + result); Notification reportOK = new Notification(Notification.PROFILE_SET_OK, MainApp.gs(R.string.profile_set_ok), Notification.INFO, 60); MainApp.bus().post(new EventNewNotification(reportOK)); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetTempBasalStart.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetTempBasalStart.java index 2b72c35749..c756af3491 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetTempBasalStart.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetTempBasalStart.java @@ -3,10 +3,10 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; public class MsgSetTempBasalStart extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgSetTempBasalStart.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgSetTempBasalStart() { SetCommand(0x0401); @@ -24,7 +24,7 @@ public class MsgSetTempBasalStart extends MessageBase { AddParamByte((byte) (percent & 255)); AddParamByte((byte) (durationInHours & 255)); - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Temp basal start percent: " + percent + " duration hours: " + durationInHours); } @@ -32,9 +32,10 @@ public class MsgSetTempBasalStart extends MessageBase { int result = intFromBuff(bytes, 0, 1); if (result != 1) { failed = true; - log.debug("Set temp basal start result: " + result + " FAILED!!!"); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("Set temp basal start result: " + result + " FAILED!!!"); } else { - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Set temp basal start result: " + result); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetTempBasalStop.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetTempBasalStop.java index 39582ac399..7b14e8e3e3 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetTempBasalStop.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetTempBasalStop.java @@ -3,14 +3,14 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; public class MsgSetTempBasalStop extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgSetTempBasalStop.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgSetTempBasalStop() { SetCommand(0x0403); - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Temp basal stop"); } @@ -18,9 +18,10 @@ public class MsgSetTempBasalStop extends MessageBase { int result = intFromBuff(bytes, 0, 1); if (result != 1) { failed = true; - log.debug("Set temp basal stop result: " + result + " FAILED!!!"); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("Set temp basal stop result: " + result + " FAILED!!!"); } else { - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Set temp basal stop result: " + result); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetTime.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetTime.java index 3910d52c97..6842344959 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetTime.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetTime.java @@ -5,26 +5,32 @@ import org.slf4j.LoggerFactory; import java.util.Date; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; +import info.nightscout.utils.DateUtil; /** * Created by mike on 09.12.2016. */ public class MsgSetTime extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgSetTime.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); private static Date time; public MsgSetTime(Date time) { SetCommand(0x330a); this.time = time; AddParamDateTime(time); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message: time:" + DateUtil.dateAndTimeString(time)); } public void handleMessage(byte[] bytes) { int result = intFromBuff(bytes, 0, 1); + if (result != 1) { + failed = true; + } - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Result of setting time: " + time + " is " + result); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetUserOptions.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetUserOptions.java new file mode 100644 index 0000000000..7484966dba --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetUserOptions.java @@ -0,0 +1,54 @@ +package info.nightscout.androidaps.plugins.PumpDanaR.comm; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; + +/** + * Created by mike on 05.07.2016. + */ +public class MsgSetUserOptions extends MessageBase { + + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); + + public boolean done; + + public MsgSetUserOptions() { + SetCommand(0x330B); + DanaRPump pump = DanaRPump.getInstance(); + if (pump.userOptionsFrompump == null) { + // No options set -> Exitting + log.error("NO USER OPTIONS LOADED EXITTING!"); + return; + } + pump.userOptionsFrompump[0] = (byte) (pump.timeDisplayType == 1 ? 0 : 1); + pump.userOptionsFrompump[1] = (byte) pump.buttonScrollOnOff; + pump.userOptionsFrompump[2] = (byte) pump.beepAndAlarm; + pump.userOptionsFrompump[3] = (byte) pump.lcdOnTimeSec; + pump.userOptionsFrompump[4] = (byte) pump.backlightOnTimeSec; + pump.userOptionsFrompump[5] = (byte) pump.selectedLanguage; + pump.userOptionsFrompump[8] = (byte) pump.units; + pump.userOptionsFrompump[9] = (byte) pump.shutdownHour; + pump.userOptionsFrompump[27] = (byte) pump.lowReservoirRate; + for (int i = 0; i < pump.userOptionsFrompump.length; i++) { + AddParamByte(pump.userOptionsFrompump[i]); + } + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); + } + + public void handleMessage(byte[] bytes) { + int result = intFromBuff(bytes, 0, 1); + if (result != 1) { + failed = true; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("Setting user options: " + result + " FAILED!!!"); + } else { + if (L.isEnabled(L.PUMPCOMM)) + log.debug("Setting user options: " + result); + } + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingActiveProfile.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingActiveProfile.java index 20498e28e7..57ab6367b0 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingActiveProfile.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingActiveProfile.java @@ -3,23 +3,25 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; /** * Created by mike on 05.07.2016. */ public class MsgSettingActiveProfile extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgSettingBasal.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgSettingActiveProfile() { SetCommand(0x320C); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } public void handleMessage(byte[] bytes) { DanaRPump.getInstance().activeProfile = intFromBuff(bytes, 0, 1); - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Active profile number: " + DanaRPump.getInstance().activeProfile); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingBasal.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingBasal.java index a47803c1b0..899a5a08f0 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingBasal.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingBasal.java @@ -3,7 +3,7 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPlugin; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; @@ -11,10 +11,12 @@ import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; * Created by mike on 05.07.2016. */ public class MsgSettingBasal extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgSettingBasal.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgSettingBasal() { SetCommand(0x3202); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } public void handleMessage(byte[] bytes) { @@ -27,7 +29,7 @@ public class MsgSettingBasal extends MessageBase { pump.pumpProfiles[pump.activeProfile][index] = basal / 100d; } - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) for (int index = 0; index < 24; index++) { log.debug("Basal " + String.format("%02d", index) + "h: " + pump.pumpProfiles[pump.activeProfile][index]); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingBasalProfileAll.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingBasalProfileAll.java index 24b5043769..f231412e06 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingBasalProfileAll.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingBasalProfileAll.java @@ -3,7 +3,7 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; @@ -14,10 +14,12 @@ import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; * THIS IS BROKEN IN PUMP... SENDING ONLY 1 PROFILE */ public class MsgSettingBasalProfileAll extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgSettingBasalProfileAll.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgSettingBasalProfileAll() { SetCommand(0x3206); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } public void handleMessage(byte[] bytes) { @@ -37,31 +39,40 @@ public class MsgSettingBasalProfileAll extends MessageBase { pump.pumpProfiles = new double[4][]; for (int profile = 0; profile < 4; profile++) { int position = intFromBuff(bytes, 49 * profile, 1); - log.debug("position " + position); pump.pumpProfiles[position] = new double[24]; for (int index = 0; index < 24; index++) { int basal = intFromBuff(bytes, 59 * profile + 2 * index + 1, 2); if (basal < 10) basal = 0; - log.debug("position " + position + " index " + index); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("position " + position + " index " + index); pump.pumpProfiles[position][index] = basal / 100d; } } } - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { if (pump.basal48Enable) { for (int profile = 0; profile < 4; profile++) { - for (int index = 0; index < 24; index++) { - log.debug("Basal profile " + profile + ": " + String.format("%02d", index) + "h: " + pump.pumpProfiles[profile][index]); + for (int index = 0; index < 48; index++) { + try { + log.debug("Basal profile " + profile + ": " + String.format("%02d", index) + "h: " + pump.pumpProfiles[profile][index]); + } catch (Exception e){ + log.error("Unhandled exception" , e); + } } } } else { for (int profile = 0; profile < 4; profile++) { - for (int index = 0; index < 48; index++) { - log.debug("Basal profile " + profile + ": " + - String.format("%02d", (index / 2)) + - ":" + String.format("%02d", (index % 2) * 30) + " : " + - pump.pumpProfiles[profile][index]); + for (int index = 0; index < 24; index++) { + //this is absurd pump.pumpProfiles[profile][index] returns nullPointerException + try { + log.debug("Basal profile " + profile + ": " + + String.format("%02d", (index / 2)) + + ":" + String.format("%02d", (index % 2) * 30) + " : " + + pump.pumpProfiles[profile][index]); + } catch (Exception e){ + log.error("Unhandled exception" , e); + } } } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingGlucose.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingGlucose.java index 0f20c0843a..ded78c6272 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingGlucose.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingGlucose.java @@ -3,17 +3,19 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; /** * Created by mike on 05.07.2016. */ public class MsgSettingGlucose extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgSettingGlucose.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgSettingGlucose() { SetCommand(0x3209); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } public void handleMessage(byte[] bytes) { @@ -21,7 +23,7 @@ public class MsgSettingGlucose extends MessageBase { pump.units = intFromBuff(bytes, 0, 1); pump.easyBasalMode = intFromBuff(bytes, 1, 1); - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Pump units: " + (pump.units == DanaRPump.UNITS_MGDL ? "MGDL" : "MMOL")); log.debug("Easy basal mode: " + pump.easyBasalMode); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingMaxValues.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingMaxValues.java index 9279f2b1ba..3c640e1870 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingMaxValues.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingMaxValues.java @@ -3,7 +3,7 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; @@ -11,10 +11,12 @@ import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; * Created by mike on 05.07.2016. */ public class MsgSettingMaxValues extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgSettingMaxValues.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgSettingMaxValues() { SetCommand(0x3205); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } public void handleMessage(byte[] bytes) { @@ -23,7 +25,7 @@ public class MsgSettingMaxValues extends MessageBase { pump.maxBasal = intFromBuff(bytes, 2, 2) / 100d; pump.maxDailyTotalUnits = intFromBuff(bytes, 4, 2) / 100; - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Max bolus: " + pump.maxBolus); log.debug("Max basal: " + pump.maxBasal); log.debug("Total daily max units: " + pump.maxDailyTotalUnits); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingMeal.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingMeal.java index 8d94a1784d..558b8953c0 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingMeal.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingMeal.java @@ -3,10 +3,10 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.interfaces.PluginType; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.Overview.notifications.Notification; @@ -18,10 +18,12 @@ import info.nightscout.androidaps.plugins.PumpDanaRKorean.DanaRKoreanPlugin; */ public class MsgSettingMeal extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgSettingMeal.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgSettingMeal() { SetCommand(0x3203); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } public void handleMessage(byte[] bytes) { @@ -33,7 +35,7 @@ public class MsgSettingMeal extends MessageBase { int blockTime = intFromBuff(bytes, 4, 1); pump.isConfigUD = intFromBuff(bytes, 5, 1) == 1; - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Basal step: " + pump.basalStep); log.debug("Bolus step: " + pump.bolusStep); log.debug("Bolus enabled: " + bolusEnabled); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingProfileRatios.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingProfileRatios.java index 0b5150fc84..5b6ea9b6cf 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingProfileRatios.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingProfileRatios.java @@ -3,17 +3,19 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; /** * Created by mike on 05.07.2016. */ public class MsgSettingProfileRatios extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgSettingProfileRatios.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgSettingProfileRatios() { SetCommand(0x3204); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } public void handleMessage(byte[] bytes) { @@ -32,7 +34,7 @@ public class MsgSettingProfileRatios extends MessageBase { pump.currentAIDR = intFromBuff(bytes, 8, 1); } - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Pump units (saved): " + (pump.units == DanaRPump.UNITS_MGDL ? "MGDL" : "MMOL")); log.debug("Current pump CIR: " + pump.currentCIR); log.debug("Current pump CF: " + pump.currentCF); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingProfileRatiosAll.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingProfileRatiosAll.java index 9dd5a0070d..10d424657b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingProfileRatiosAll.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingProfileRatiosAll.java @@ -3,17 +3,19 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; /** * Created by mike on 05.07.2016. */ public class MsgSettingProfileRatiosAll extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgSettingProfileRatiosAll.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgSettingProfileRatiosAll() { SetCommand(0x320D); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } public void handleMessage(byte[] bytes) { @@ -38,7 +40,7 @@ public class MsgSettingProfileRatiosAll extends MessageBase { pump.nightCF = intFromBuff(bytes, 14, 2) / 100d; } - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Pump units: " + (pump.units == DanaRPump.UNITS_MGDL ? "MGDL" : "MMOL")); log.debug("Current pump morning CIR: " + pump.morningCIR); log.debug("Current pump morning CF: " + pump.morningCF); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingPumpTime.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingPumpTime.java index 3da1451899..0e57c6c2f8 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingPumpTime.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingPumpTime.java @@ -5,18 +5,21 @@ import org.slf4j.LoggerFactory; import java.util.Date; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; +import info.nightscout.utils.DateUtil; public class MsgSettingPumpTime extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgSettingPumpTime.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgSettingPumpTime() { SetCommand(0x320A); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } public void handleMessage(byte[] bytes) { - Date time = + long time = new Date( 100 + intFromBuff(bytes, 5, 1), intFromBuff(bytes, 4, 1) - 1, @@ -24,10 +27,10 @@ public class MsgSettingPumpTime extends MessageBase { intFromBuff(bytes, 2, 1), intFromBuff(bytes, 1, 1), intFromBuff(bytes, 0, 1) - ); + ).getTime(); - if (Config.logDanaMessageDetail) - log.debug("Pump time: " + time + " Phone time: " + new Date()); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("Pump time: " + DateUtil.dateAndTimeFullString(time) + " Phone time: " + new Date()); DanaRPump.getInstance().pumpTime = time; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingShippingInfo.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingShippingInfo.java index 9670d92a88..b700b0baa0 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingShippingInfo.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingShippingInfo.java @@ -3,17 +3,19 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; /** * Created by mike on 05.07.2016. */ public class MsgSettingShippingInfo extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgSettingShippingInfo.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgSettingShippingInfo() { SetCommand(0x3207); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } public void handleMessage(byte[] bytes) { @@ -21,7 +23,7 @@ public class MsgSettingShippingInfo extends MessageBase { pump.serialNumber = stringFromBuff(bytes, 0, 10); pump.shippingDate = dateFromBuff(bytes, 10); pump.shippingCountry = asciiStringFromBuff(bytes, 13, 3); - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Serial number: " + pump.serialNumber); log.debug("Shipping date: " + pump.shippingDate); log.debug("Shipping country: " + pump.shippingCountry); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingUserOptions.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingUserOptions.java index 8fb1e4f712..e45e2050db 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingUserOptions.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSettingUserOptions.java @@ -3,18 +3,68 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Arrays; + +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; + /** - * Created by mike on 05.07.2016. + * Created by Rumen Georgiev on 6/11/2018. */ + public class MsgSettingUserOptions extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgSettingShippingInfo.class); + + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgSettingUserOptions() { SetCommand(0x320B); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } - public void handleMessage(byte[] bytes) { + public void handleMessage(byte[] packet) { + DanaRPump pump = DanaRPump.getInstance(); + byte[] bytes = getDataBytes(packet, 0, packet.length - 10); + pump.userOptionsFrompump = Arrays.copyOf(bytes, bytes.length);// saving pumpDataBytes to use it in MsgSetUserOptions + for(int pos=0; pos < bytes.length; pos++) { + log.debug("[" + pos + "]" + bytes[pos]); + } + pump.timeDisplayType = bytes[0] == (byte) 1 ? 0 : 1; // 1 -> 24h 0 -> 12h + pump.buttonScrollOnOff = bytes[1] == (byte) 1 ? 1 : 0; // 1 -> ON, 0-> OFF + pump.beepAndAlarm = bytes[2]; // 1 -> Sound on alarm 2-> Vibrate on alarm 3-> Both on alarm 5-> Sound + beep 6-> vibrate + beep 7-> both + beep Beep adds 4 + pump.lcdOnTimeSec = bytes[3] & 255; + pump.backlightOnTimeSec = bytes[4] & 255; + pump.selectedLanguage = bytes[5]; // on DanaRv2 is that needed ? + pump.units = bytes[8]; + pump.shutdownHour = bytes[9]; + pump.lowReservoirRate = bytes[32] & 255; + /* int selectableLanguage1 = bytes[10]; + int selectableLanguage2 = bytes[11]; + int selectableLanguage3 = bytes[12]; + int selectableLanguage4 = bytes[13]; + int selectableLanguage5 = bytes[14]; + */ + if (L.isEnabled(L.PUMPCOMM)) { + + log.debug("timeDisplayType: " + pump.timeDisplayType); + log.debug("Button scroll: " + pump.buttonScrollOnOff); + log.debug("BeepAndAlarm: " + pump.beepAndAlarm); + log.debug("screen timeout: " + pump.lcdOnTimeSec); + log.debug("Backlight: " + pump.backlightOnTimeSec); + log.debug("Selected language: " + pump.selectedLanguage); + log.debug("Units: " + pump.getUnits()); + log.debug("Shutdown: " + pump.shutdownHour); + log.debug("Low reservoir: " + pump.lowReservoirRate); + } } + public static byte[] getDataBytes(byte[] bytes, int start, int len) { + if (bytes == null) { + return null; + } + byte[] ret = new byte[len]; + System.arraycopy(bytes, start + 6, ret, 0, len); + return ret; + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgStatus.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgStatus.java index fb75bfef0e..474c29daa1 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgStatus.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgStatus.java @@ -3,14 +3,16 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; public class MsgStatus extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgStatus.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgStatus() { SetCommand(0x020B); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } public void handleMessage(byte[] bytes) { @@ -26,7 +28,7 @@ public class MsgStatus extends MessageBase { } pump.iob = intFromBuff(bytes, 15, 2) / 100d; - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Daily total: " + pump.dailyTotalUnits); log.debug("Is extended bolus running: " + pump.isExtendedInProgress); log.debug("Extended bolus min: " + pump.extendedBolusMinutes); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgStatusBasic.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgStatusBasic.java index 2aba028250..8f81220885 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgStatusBasic.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgStatusBasic.java @@ -3,15 +3,17 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; public class MsgStatusBasic extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgStatusBasic.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgStatusBasic() { SetCommand(0x020A); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } public void handleMessage(byte[] bytes) { @@ -30,7 +32,7 @@ public class MsgStatusBasic extends MessageBase { //pump.isTempBasalInProgress = intFromBuff(bytes, 15, 1) == 1; pump.batteryRemaining = intFromBuff(bytes, 20, 1); - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Pump suspended: " + pump.pumpSuspended); log.debug("Calculator enabled: " + pump.calculatorEnabled); log.debug("Daily total units: " + pump.dailyTotalUnits); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgStatusBolusExtended.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgStatusBolusExtended.java index 048cc35e6a..30e41e2704 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgStatusBolusExtended.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgStatusBolusExtended.java @@ -5,20 +5,23 @@ import android.support.annotation.NonNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Date; - -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.db.ExtendedBolus; import info.nightscout.androidaps.db.Source; +import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.TreatmentsInterface; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; +import info.nightscout.utils.DateUtil; public class MsgStatusBolusExtended extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgStatusBolusExtended.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgStatusBolusExtended() { SetCommand(0x0207); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } public void handleMessage(byte[] bytes) { @@ -34,7 +37,7 @@ public class MsgStatusBolusExtended extends MessageBase { int extendedBolusSoFarInMinutes = extendedBolusSoFarInSecs / 60; double extendedBolusAbsoluteRate = isExtendedInProgress ? extendedBolusAmount / extendedBolusMinutes * 60 : 0d; - Date extendedBolusStart = isExtendedInProgress ? getDateFromSecAgo(extendedBolusSoFarInSecs) : new Date(0); + long extendedBolusStart = isExtendedInProgress ? getDateFromSecAgo(extendedBolusSoFarInSecs) : 0; int extendedBolusRemainingMinutes = extendedBolusMinutes - extendedBolusSoFarInMinutes; DanaRPump pump = DanaRPump.getInstance(); @@ -45,23 +48,22 @@ public class MsgStatusBolusExtended extends MessageBase { pump.extendedBolusAbsoluteRate = extendedBolusAbsoluteRate; pump.extendedBolusStart = extendedBolusStart; pump.extendedBolusRemainingMinutes = extendedBolusRemainingMinutes; - updateExtendedBolusInDB(); - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Is extended bolus running: " + isExtendedInProgress); log.debug("Extended bolus min: " + extendedBolusMinutes); log.debug("Extended bolus amount: " + extendedBolusAmount); log.debug("Extended bolus so far in minutes: " + extendedBolusSoFarInMinutes); log.debug("Extended bolus absolute rate: " + extendedBolusAbsoluteRate); - log.debug("Extended bolus start: " + extendedBolusStart); + log.debug("Extended bolus start: " + DateUtil.dateAndTimeFullString(extendedBolusStart)); log.debug("Extended bolus remaining minutes: " + extendedBolusRemainingMinutes); } } @NonNull - private Date getDateFromSecAgo(int tempBasalAgoSecs) { - return new Date((long) (Math.ceil(System.currentTimeMillis() / 1000d) - tempBasalAgoSecs) * 1000); + private long getDateFromSecAgo(int tempBasalAgoSecs) { + return (long) (Math.ceil(System.currentTimeMillis() / 1000d) - tempBasalAgoSecs) * 1000; } public static void updateExtendedBolusInDB() { @@ -74,31 +76,31 @@ public class MsgStatusBolusExtended extends MessageBase { if (pump.isExtendedInProgress) { if (extendedBolus.absoluteRate() != pump.extendedBolusAbsoluteRate) { // Close current extended - ExtendedBolus exStop = new ExtendedBolus(pump.extendedBolusStart.getTime() - 1000); + ExtendedBolus exStop = new ExtendedBolus(pump.extendedBolusStart - 1000); exStop.source = Source.USER; treatmentsInterface.addToHistoryExtendedBolus(exStop); // Create new - ExtendedBolus newExtended = new ExtendedBolus(); - newExtended.date = pump.extendedBolusStart.getTime(); - newExtended.insulin = pump.extendedBolusAmount; - newExtended.durationInMinutes = pump.extendedBolusMinutes; - newExtended.source = Source.USER; + ExtendedBolus newExtended = new ExtendedBolus() + .date(pump.extendedBolusStart) + .insulin(pump.extendedBolusAmount) + .durationInMinutes(pump.extendedBolusMinutes) + .source(Source.USER); treatmentsInterface.addToHistoryExtendedBolus(newExtended); } } else { // Close curent temp basal - ExtendedBolus exStop = new ExtendedBolus(now); - exStop.source = Source.USER; + ExtendedBolus exStop = new ExtendedBolus(now) + .source(Source.USER); treatmentsInterface.addToHistoryExtendedBolus(exStop); } } else { if (pump.isExtendedInProgress) { // Create new - ExtendedBolus newExtended = new ExtendedBolus(); - newExtended.date = pump.extendedBolusStart.getTime(); - newExtended.insulin = pump.extendedBolusAmount; - newExtended.durationInMinutes = pump.extendedBolusMinutes; - newExtended.source = Source.USER; + ExtendedBolus newExtended = new ExtendedBolus() + .date(pump.extendedBolusStart) + .insulin(pump.extendedBolusAmount) + .durationInMinutes(pump.extendedBolusMinutes) + .source(Source.USER); treatmentsInterface.addToHistoryExtendedBolus(newExtended); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgStatusProfile.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgStatusProfile.java index 70b67c3b77..079357c6ee 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgStatusProfile.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgStatusProfile.java @@ -3,17 +3,19 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; /** * Created by mike on 05.07.2016. */ public class MsgStatusProfile extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgStatusProfile.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgStatusProfile() { SetCommand(0x0204); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } public void handleMessage(byte[] bytes) { @@ -30,7 +32,7 @@ public class MsgStatusProfile extends MessageBase { pump.currentTarget = intFromBuff(bytes, 6, 2) / 100d; } - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Pump units (saved): " + (pump.units == DanaRPump.UNITS_MGDL ? "MGDL" : "MMOL")); log.debug("Current pump CIR: " + pump.currentCIR); log.debug("Current pump CF: " + pump.currentCF); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgStatusTempBasal.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgStatusTempBasal.java index 48e88897e6..db6080f74a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgStatusTempBasal.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgStatusTempBasal.java @@ -5,19 +5,19 @@ import android.support.annotation.NonNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Date; - -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.TemporaryBasal; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; public class MsgStatusTempBasal extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgStatusTempBasal.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgStatusTempBasal() { SetCommand(0x0205); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } public void handleMessage(byte[] bytes) { @@ -31,7 +31,7 @@ public class MsgStatusTempBasal extends MessageBase { else tempBasalTotalSec = intFromBuff(bytes, 2, 1) * 60 * 60; int tempBasalRunningSeconds = intFromBuff(bytes, 3, 3); int tempBasalRemainingMin = (tempBasalTotalSec - tempBasalRunningSeconds) / 60; - Date tempBasalStart = isTempBasalInProgress ? getDateFromTempBasalSecAgo(tempBasalRunningSeconds) : new Date(0); + long tempBasalStart = isTempBasalInProgress ? getDateFromTempBasalSecAgo(tempBasalRunningSeconds) : 0; DanaRPump pump = DanaRPump.getInstance(); pump.isTempBasalInProgress = isTempBasalInProgress; @@ -42,7 +42,7 @@ public class MsgStatusTempBasal extends MessageBase { updateTempBasalInDB(); - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Is temp basal running: " + isTempBasalInProgress); log.debug("Is APS temp basal running: " + isAPSTempBasalInProgress); log.debug("Current temp basal percent: " + tempBasalPercent); @@ -53,8 +53,8 @@ public class MsgStatusTempBasal extends MessageBase { } @NonNull - private Date getDateFromTempBasalSecAgo(int tempBasalAgoSecs) { - return new Date((long) (Math.ceil(System.currentTimeMillis() / 1000d) - tempBasalAgoSecs) * 1000); + private long getDateFromTempBasalSecAgo(int tempBasalAgoSecs) { + return (long) (Math.ceil(System.currentTimeMillis() / 1000d) - tempBasalAgoSecs) * 1000; } public static void updateTempBasalInDB() { @@ -66,11 +66,11 @@ public class MsgStatusTempBasal extends MessageBase { if (danaRPump.isTempBasalInProgress) { if (tempBasal.percentRate != danaRPump.tempBasalPercent) { // Close current temp basal - TemporaryBasal tempStop = new TemporaryBasal().date(danaRPump.tempBasalStart.getTime() - 1000).source(Source.USER); + TemporaryBasal tempStop = new TemporaryBasal().date(danaRPump.tempBasalStart - 1000).source(Source.USER); TreatmentsPlugin.getPlugin().addToHistoryTempBasal(tempStop); // Create new TemporaryBasal newTempBasal = new TemporaryBasal() - .date(danaRPump.tempBasalStart.getTime()) + .date(danaRPump.tempBasalStart) .percent(danaRPump.tempBasalPercent) .duration(danaRPump.tempBasalTotalSec / 60) .source(Source.USER); @@ -85,7 +85,7 @@ public class MsgStatusTempBasal extends MessageBase { if (danaRPump.isTempBasalInProgress) { // Create new TemporaryBasal newTempBasal = new TemporaryBasal() - .date(danaRPump.tempBasalStart.getTime()) + .date(danaRPump.tempBasalStart) .percent(danaRPump.tempBasalPercent) .duration(danaRPump.tempBasalTotalSec / 60) .source(Source.USER); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/events/EventDanaRBolusStart.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/events/EventDanaRBolusStart.java deleted file mode 100644 index 9e3af48fb2..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/events/EventDanaRBolusStart.java +++ /dev/null @@ -1,9 +0,0 @@ -package info.nightscout.androidaps.plugins.PumpDanaR.events; - -import info.nightscout.androidaps.events.Event; - -/** - * Created by mike on 03.08.2016. - */ -public class EventDanaRBolusStart extends Event { -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/events/EventDanaRSyncStatus.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/events/EventDanaRSyncStatus.java index 4e3f28de9d..f2a5dc7b2a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/events/EventDanaRSyncStatus.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/events/EventDanaRSyncStatus.java @@ -11,7 +11,4 @@ public class EventDanaRSyncStatus extends Event { public EventDanaRSyncStatus() { } - EventDanaRSyncStatus(String message) { - this.message = message; - } -} + } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/AbstractDanaRExecutionService.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/AbstractDanaRExecutionService.java index 17db916dae..ae09281c91 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/AbstractDanaRExecutionService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/AbstractDanaRExecutionService.java @@ -11,18 +11,18 @@ import android.os.IBinder; import android.os.SystemClock; import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.IOException; import java.util.Set; import java.util.UUID; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.PumpEnactResult; -import info.nightscout.androidaps.plugins.Treatments.Treatment; import info.nightscout.androidaps.events.EventPumpStatusChanged; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgBolusStop; @@ -39,6 +39,8 @@ import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistorySuspend; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgPCCommStart; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgPCCommStop; import info.nightscout.androidaps.plugins.PumpDanaR.comm.RecordTypes; +import info.nightscout.androidaps.plugins.Treatments.Treatment; +import info.nightscout.utils.DateUtil; import info.nightscout.utils.SP; import info.nightscout.utils.ToastUtils; @@ -47,17 +49,17 @@ import info.nightscout.utils.ToastUtils; */ public abstract class AbstractDanaRExecutionService extends Service { - protected Logger log; + protected Logger log = LoggerFactory.getLogger(L.PUMP); protected String mDevName; protected BluetoothSocket mRfcommSocket; protected BluetoothDevice mBTDevice; - protected DanaRPump mDanaRPump = DanaRPump.getInstance(); protected Treatment mBolusingTreatment = null; - protected Boolean mConnectionInProgress = false; + protected boolean mConnectionInProgress = false; + protected boolean mHandshakeInProgress = false; protected AbstractSerialIOThread mSerialIOThread; @@ -65,8 +67,6 @@ public abstract class AbstractDanaRExecutionService extends Service { protected final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb"); - protected long lastWrongPumpPassword = 0; - protected long lastApproachingDailyLimit = 0; @@ -92,6 +92,7 @@ public abstract class AbstractDanaRExecutionService extends Service { public abstract boolean extendedBolusStop(); + public abstract PumpEnactResult setUserOptions(); protected BroadcastReceiver receiver = new BroadcastReceiver() { @Override @@ -99,7 +100,8 @@ public abstract class AbstractDanaRExecutionService extends Service { BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); String action = intent.getAction(); if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) { - log.debug("Device was disconnected " + device.getName());//Device was disconnected + if (L.isEnabled(L.PUMP)) + log.debug("Device was disconnected " + device.getName());//Device was disconnected if (mBTDevice != null && mBTDevice.getName() != null && mBTDevice.getName().equals(device.getName())) { if (mSerialIOThread != null) { mSerialIOThread.disconnect("BT disconnection broadcast"); @@ -128,6 +130,15 @@ public abstract class AbstractDanaRExecutionService extends Service { return mConnectionInProgress; } + public boolean isHandshakeInProgress() { + return isConnected() && mHandshakeInProgress; + } + + public void finishHandshaking() { + mHandshakeInProgress = false; + MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.CONNECTED, 0)); + } + public void disconnect(String from) { if (mSerialIOThread != null) mSerialIOThread.disconnect(from); @@ -165,7 +176,7 @@ public abstract class AbstractDanaRExecutionService extends Service { } public void bolusStop() { - if (Config.logDanaBTComm) + if (L.isEnabled(L.PUMP)) log.debug("bolusStop >>>>> @ " + (mBolusingTreatment == null ? "" : mBolusingTreatment.insulin)); MsgBolusStop stop = new MsgBolusStop(); stop.forced = true; @@ -227,5 +238,14 @@ public abstract class AbstractDanaRExecutionService extends Service { return result; } - + protected void waitForWholeMinute() { + while (true) { + long time = DateUtil.now(); + long timeToWholeMinute = (60000 - time % 60000); + if (timeToWholeMinute > 59800 || timeToWholeMinute < 3000) + break; + MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.waitingfortimesynchronization, (int) (timeToWholeMinute / 1000)))); + SystemClock.sleep(Math.min(timeToWholeMinute, 100)); + } + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/DanaRExecutionService.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/DanaRExecutionService.java index 3d4245fb2a..268d5378c1 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/DanaRExecutionService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/DanaRExecutionService.java @@ -7,28 +7,28 @@ import android.os.SystemClock; import com.squareup.otto.Subscribe; -import org.slf4j.LoggerFactory; - import java.io.IOException; import java.util.Date; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.PumpEnactResult; -import info.nightscout.androidaps.plugins.Treatments.Treatment; import info.nightscout.androidaps.events.EventAppExit; import info.nightscout.androidaps.events.EventInitializationChanged; import info.nightscout.androidaps.events.EventPreferenceChange; +import info.nightscout.androidaps.events.EventProfileSwitchChange; import info.nightscout.androidaps.events.EventPumpStatusChanged; +import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; +import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; import info.nightscout.androidaps.plugins.Overview.Dialogs.BolusProgressDialog; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress; import info.nightscout.androidaps.plugins.Overview.notifications.Notification; -import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPlugin; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; import info.nightscout.androidaps.plugins.PumpDanaR.SerialIOThread; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase; @@ -45,6 +45,7 @@ import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetExtendedBolusStop import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetTempBasalStart; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetTempBasalStop; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetTime; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetUserOptions; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingActiveProfile; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingBasal; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingGlucose; @@ -54,20 +55,21 @@ import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingProfileRatios import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingProfileRatiosAll; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingPumpTime; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingShippingInfo; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingUserOptions; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgStatus; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgStatusBasic; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgStatusBolusExtended; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgStatusTempBasal; import info.nightscout.androidaps.plugins.PumpDanaR.events.EventDanaRNewStatus; +import info.nightscout.androidaps.plugins.Treatments.Treatment; import info.nightscout.androidaps.queue.Callback; -import info.nightscout.utils.NSUpload; +import info.nightscout.androidaps.queue.commands.Command; +import info.nightscout.utils.DateUtil; import info.nightscout.utils.SP; -import info.nightscout.utils.ToastUtils; -public class DanaRExecutionService extends AbstractDanaRExecutionService{ +public class DanaRExecutionService extends AbstractDanaRExecutionService { public DanaRExecutionService() { - log = LoggerFactory.getLogger(DanaRExecutionService.class); mBinder = new LocalBinder(); registerBus(); @@ -96,51 +98,42 @@ public class DanaRExecutionService extends AbstractDanaRExecutionService{ } public void connect() { - if (mDanaRPump.password != -1 && mDanaRPump.password != SP.getInt(R.string.key_danar_password, -1)) { - if(System.currentTimeMillis() > lastWrongPumpPassword + 30 * 1000) { - Notification notification = new Notification(Notification.WRONG_PUMP_PASSWORD, MainApp.gs(R.string.wrongpumppassword), Notification.URGENT); - notification.soundId = R.raw.error; - lastWrongPumpPassword = System.currentTimeMillis(); - } - return; - } - if (mConnectionInProgress) return; - new Thread(new Runnable() { - @Override - public void run() { - mConnectionInProgress = true; - getBTSocketForSelectedPump(); - if (mRfcommSocket == null || mBTDevice == null) { - mConnectionInProgress = false; - return; // Device not found - } - - try { - mRfcommSocket.connect(); - } catch (IOException e) { - //log.error("Unhandled exception", e); - if (e.getMessage().contains("socket closed")) { - log.error("Unhandled exception", e); - } - } - - if (isConnected()) { - if (mSerialIOThread != null) { - mSerialIOThread.disconnect("Recreate SerialIOThread"); - } - mSerialIOThread = new SerialIOThread(mRfcommSocket); - MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.CONNECTED, 0)); - } - + new Thread(() -> { + mHandshakeInProgress = false; + mConnectionInProgress = true; + getBTSocketForSelectedPump(); + if (mRfcommSocket == null || mBTDevice == null) { mConnectionInProgress = false; + return; // Device not found } + + try { + mRfcommSocket.connect(); + } catch (IOException e) { + //log.error("Unhandled exception", e); + if (e.getMessage().contains("socket closed")) { + log.error("Unhandled exception", e); + } + } + + if (isConnected()) { + if (mSerialIOThread != null) { + mSerialIOThread.disconnect("Recreate SerialIOThread"); + } + mSerialIOThread = new SerialIOThread(mRfcommSocket); + mHandshakeInProgress = true; + MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.HANDSHAKING, 0)); + } + + mConnectionInProgress = false; }).start(); } public void getPumpStatus() { + DanaRPump danaRPump = DanaRPump.getInstance(); try { MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.gettingpumpstatus))); MsgStatus statusMsg = new MsgStatus(); @@ -149,7 +142,7 @@ public class DanaRExecutionService extends AbstractDanaRExecutionService{ MsgStatusBolusExtended exStatusMsg = new MsgStatusBolusExtended(); MsgCheckValue checkValue = new MsgCheckValue(); - if (mDanaRPump.isNewPump) { + if (danaRPump.isNewPump) { mSerialIOThread.sendMessage(checkValue); if (!checkValue.received) { return; @@ -165,7 +158,19 @@ public class DanaRExecutionService extends AbstractDanaRExecutionService{ MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.gettingbolusstatus))); long now = System.currentTimeMillis(); - if (mDanaRPump.lastSettingsRead + 60 * 60 * 1000L < now || !MainApp.getSpecificPlugin(DanaRPlugin.class).isInitialized()) { + danaRPump.lastConnection = now; + + Profile profile = ProfileFunctions.getInstance().getProfile(); + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); + if (profile != null && Math.abs(danaRPump.currentBasal - profile.getBasal()) >= pump.getPumpDescription().basalStep) { + MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.gettingpumpsettings))); + mSerialIOThread.sendMessage(new MsgSettingBasal()); + if (!pump.isThisProfileSet(profile) && !ConfigBuilderPlugin.getPlugin().getCommandQueue().isRunning(Command.CommandType.BASALPROFILE)) { + MainApp.bus().post(new EventProfileSwitchChange()); + } + } + + if (danaRPump.lastSettingsRead + 60 * 60 * 1000L < now || !pump.isInitialized()) { MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.gettingpumpsettings))); mSerialIOThread.sendMessage(new MsgSettingShippingInfo()); mSerialIOThread.sendMessage(new MsgSettingActiveProfile()); @@ -177,29 +182,32 @@ public class DanaRExecutionService extends AbstractDanaRExecutionService{ mSerialIOThread.sendMessage(new MsgSettingActiveProfile()); mSerialIOThread.sendMessage(new MsgSettingProfileRatios()); mSerialIOThread.sendMessage(new MsgSettingProfileRatiosAll()); + mSerialIOThread.sendMessage(new MsgSettingUserOptions()); MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.gettingpumptime))); mSerialIOThread.sendMessage(new MsgSettingPumpTime()); - long timeDiff = (mDanaRPump.pumpTime.getTime() - System.currentTimeMillis()) / 1000L; - log.debug("Pump time difference: " + timeDiff + " seconds"); + long timeDiff = (danaRPump.pumpTime - System.currentTimeMillis()) / 1000L; + if (L.isEnabled(L.PUMP)) + log.debug("Pump time difference: " + timeDiff + " seconds"); if (Math.abs(timeDiff) > 10) { mSerialIOThread.sendMessage(new MsgSetTime(new Date())); mSerialIOThread.sendMessage(new MsgSettingPumpTime()); - timeDiff = (mDanaRPump.pumpTime.getTime() - System.currentTimeMillis()) / 1000L; - log.debug("Pump time difference: " + timeDiff + " seconds"); + timeDiff = (danaRPump.pumpTime - System.currentTimeMillis()) / 1000L; + if (L.isEnabled(L.PUMP)) + log.debug("Pump time difference: " + timeDiff + " seconds"); } - mDanaRPump.lastSettingsRead = now; + danaRPump.lastSettingsRead = now; } - mDanaRPump.lastConnection = now; MainApp.bus().post(new EventDanaRNewStatus()); MainApp.bus().post(new EventInitializationChanged()); NSUpload.uploadDeviceStatus(); - if (mDanaRPump.dailyTotalUnits > mDanaRPump.maxDailyTotalUnits * Constants.dailyLimitWarning) { - log.debug("Approaching daily limit: " + mDanaRPump.dailyTotalUnits + "/" + mDanaRPump.maxDailyTotalUnits); - if(System.currentTimeMillis() > lastApproachingDailyLimit + 30 * 60 * 1000) { + if (danaRPump.dailyTotalUnits > danaRPump.maxDailyTotalUnits * Constants.dailyLimitWarning) { + if (L.isEnabled(L.PUMP)) + log.debug("Approaching daily limit: " + danaRPump.dailyTotalUnits + "/" + danaRPump.maxDailyTotalUnits); + if (System.currentTimeMillis() > lastApproachingDailyLimit + 30 * 60 * 1000) { Notification reportFail = new Notification(Notification.APPROACHING_DAILY_LIMIT, MainApp.gs(R.string.approachingdailylimit), Notification.URGENT); MainApp.bus().post(new EventNewNotification(reportFail)); - NSUpload.uploadError(MainApp.gs(R.string.approachingdailylimit) + ": " + mDanaRPump.dailyTotalUnits + "/" + mDanaRPump.maxDailyTotalUnits + "U"); + NSUpload.uploadError(MainApp.gs(R.string.approachingdailylimit) + ": " + danaRPump.dailyTotalUnits + "/" + danaRPump.maxDailyTotalUnits + "U"); lastApproachingDailyLimit = System.currentTimeMillis(); } } @@ -209,8 +217,9 @@ public class DanaRExecutionService extends AbstractDanaRExecutionService{ } public boolean tempBasal(int percent, int durationInHours) { + DanaRPump danaRPump = DanaRPump.getInstance(); if (!isConnected()) return false; - if (mDanaRPump.isTempBasalInProgress) { + if (danaRPump.isTempBasalInProgress) { MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.stoppingtempbasal))); mSerialIOThread.sendMessage(new MsgSetTempBasalStop()); SystemClock.sleep(500); @@ -255,6 +264,7 @@ public class DanaRExecutionService extends AbstractDanaRExecutionService{ } public boolean bolus(double amount, int carbs, long carbtime, final Treatment t) { + DanaRPump danaRPump = DanaRPump.getInstance(); if (!isConnected()) return false; if (BolusProgressDialog.stopPressed) return false; @@ -286,7 +296,8 @@ public class DanaRExecutionService extends AbstractDanaRExecutionService{ if ((System.currentTimeMillis() - progress.lastReceive) > 15 * 1000L) { // if i didn't receive status for more than 15 sec expecting broken comm stop.stopped = true; stop.forced = true; - log.debug("Communication stopped"); + if (L.isEnabled(L.PUMP)) + log.debug("Communication stopped"); } } SystemClock.sleep(300); @@ -324,14 +335,16 @@ public class DanaRExecutionService extends AbstractDanaRExecutionService{ final Object o = new Object(); synchronized (o) { - ConfigBuilderPlugin.getCommandQueue().independentConnect("bolusingInterrupted", new Callback() { + ConfigBuilderPlugin.getPlugin().getCommandQueue().independentConnect("bolusingInterrupted", new Callback() { @Override public void run() { - if (mDanaRPump.lastBolusTime.getTime() > System.currentTimeMillis() - 60 * 1000L) { // last bolus max 1 min old - t.insulin = mDanaRPump.lastBolusAmount; - log.debug("Used bolus amount from history: " + mDanaRPump.lastBolusAmount); + if (danaRPump.lastBolusTime > System.currentTimeMillis() - 60 * 1000L) { // last bolus max 1 min old + t.insulin = danaRPump.lastBolusAmount; + if (L.isEnabled(L.PUMP)) + log.debug("Used bolus amount from history: " + danaRPump.lastBolusAmount); } else { - log.debug("Bolus amount in history too old: " + mDanaRPump.lastBolusTime.toLocaleString()); + if (L.isEnabled(L.PUMP)) + log.debug("Bolus amount in history too old: " + DateUtil.dateAndTimeFullString(danaRPump.lastBolusTime)); } synchronized (o) { o.notify(); @@ -345,7 +358,7 @@ public class DanaRExecutionService extends AbstractDanaRExecutionService{ } } } else { - ConfigBuilderPlugin.getCommandQueue().readStatus("bolusOK", null); + ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("bolusOK", null); } } return !start.failed; @@ -369,14 +382,15 @@ public class DanaRExecutionService extends AbstractDanaRExecutionService{ } public boolean updateBasalsInPump(final Profile profile) { + DanaRPump danaRPump = DanaRPump.getInstance(); if (!isConnected()) return false; MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.updatingbasalrates))); - double[] basal = DanaRPump.buildDanaRProfileRecord(profile); + double[] basal = DanaRPump.getInstance().buildDanaRProfileRecord(profile); MsgSetBasalProfile msgSet = new MsgSetBasalProfile((byte) 0, basal); mSerialIOThread.sendMessage(msgSet); MsgSetActivateBasalProfile msgActivate = new MsgSetActivateBasalProfile((byte) 0); mSerialIOThread.sendMessage(msgActivate); - mDanaRPump.lastSettingsRead = 0; // force read full settings + danaRPump.lastSettingsRead = 0; // force read full settings getPumpStatus(); MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.DISCONNECTING)); return true; @@ -384,7 +398,7 @@ public class DanaRExecutionService extends AbstractDanaRExecutionService{ @Subscribe public void onStatusEvent(EventAppExit event) { - if (Config.logFunctionCalls) + if (L.isEnabled(L.PUMP)) log.debug("EventAppExit received"); if (mSerialIOThread != null) @@ -393,8 +407,15 @@ public class DanaRExecutionService extends AbstractDanaRExecutionService{ MainApp.instance().getApplicationContext().unregisterReceiver(receiver); stopSelf(); - if (Config.logFunctionCalls) - log.debug("EventAppExit finished"); } + public PumpEnactResult setUserOptions() { + if (!isConnected()) + return new PumpEnactResult().success(false); + SystemClock.sleep(300); + MsgSetUserOptions msg = new MsgSetUserOptions(); + mSerialIOThread.sendMessage(msg); + SystemClock.sleep(200); + return new PumpEnactResult().success(!msg.failed); + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/DanaRKoreanPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/DanaRKoreanPlugin.java index 092febec61..54f0beb89b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/DanaRKoreanPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/DanaRKoreanPlugin.java @@ -5,12 +5,11 @@ import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.IBinder; +import android.support.v4.app.FragmentActivity; +import android.support.v7.app.AlertDialog; import com.squareup.otto.Subscribe; -import org.slf4j.LoggerFactory; - -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.DetailedBolusInfo; @@ -22,8 +21,11 @@ import info.nightscout.androidaps.events.EventAppExit; import info.nightscout.androidaps.events.EventPreferenceChange; import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.PluginType; -import info.nightscout.androidaps.interfaces.PumpDescription; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderFragment; +import info.nightscout.androidaps.plugins.PumpCommon.defs.PumpType; import info.nightscout.androidaps.plugins.PumpDanaR.AbstractDanaRPlugin; +import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgBolusStart; import info.nightscout.androidaps.plugins.PumpDanaRKorean.services.DanaRKoreanExecutionService; import info.nightscout.androidaps.plugins.Treatments.Treatment; @@ -45,40 +47,36 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin { } public DanaRKoreanPlugin() { - super(); - log = LoggerFactory.getLogger(DanaRKoreanPlugin.class); - useExtendedBoluses = SP.getBoolean("danar_useextended", false); + pluginDescription.description(R.string.description_pump_dana_r_korean); - pumpDescription.isBolusCapable = true; - pumpDescription.bolusStep = 0.1d; - - pumpDescription.isExtendedBolusCapable = true; - pumpDescription.extendedBolusStep = 0.05d; - pumpDescription.extendedBolusDurationStep = 30; - pumpDescription.extendedBolusMaxDuration = 8 * 60; - - pumpDescription.isTempBasalCapable = true; - pumpDescription.tempBasalStyle = PumpDescription.PERCENT; - - pumpDescription.maxTempPercent = 200; - pumpDescription.tempPercentStep = 10; - - pumpDescription.tempDurationStep = 60; - pumpDescription.tempMaxDuration = 24 * 60; - - - pumpDescription.isSetBasalProfileCapable = true; - pumpDescription.basalStep = 0.01d; - pumpDescription.basalMinimumRate = 0.1d; - - pumpDescription.isRefillingCapable = true; - - pumpDescription.storesCarbInfo = false; - - pumpDescription.supportsTDDs = true; - pumpDescription.needsManualTDDLoad = true; + useExtendedBoluses = SP.getBoolean(R.string.key_danar_useextended, false); + pumpDescription.setPumpDescription(PumpType.DanaRKorean); } + @Override + public void switchAllowed(ConfigBuilderFragment.PluginViewHolder.PluginSwitcher pluginSwitcher, FragmentActivity context) { + boolean allowHardwarePump = SP.getBoolean("allow_hardware_pump", false); + if (allowHardwarePump || context == null) { + pluginSwitcher.invoke(); + } else { + AlertDialog.Builder builder = new AlertDialog.Builder(context); + builder.setMessage(R.string.allow_hardware_pump_text) + .setPositiveButton(R.string.yes, (dialog, id) -> { + pluginSwitcher.invoke(); + SP.putBoolean("allow_hardware_pump", true); + if (L.isEnabled(L.PUMP)) + log.debug("First time HW pump allowed!"); + }) + .setNegativeButton(R.string.cancel, (dialog, id) -> { + pluginSwitcher.cancel(); + if (L.isEnabled(L.PUMP)) + log.debug("User does not allow switching to HW pump!"); + }); + builder.create().show(); + } + } + + @Override protected void onStart() { Context context = MainApp.instance().getApplicationContext(); @@ -99,12 +97,14 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin { private ServiceConnection mConnection = new ServiceConnection() { public void onServiceDisconnected(ComponentName name) { - log.debug("Service is disconnected"); + if (L.isEnabled(L.PUMP)) + log.debug("Service is disconnected"); sExecutionService = null; } public void onServiceConnected(ComponentName name, IBinder service) { - log.debug("Service is connected"); + if (L.isEnabled(L.PUMP)) + log.debug("Service is connected"); DanaRKoreanExecutionService.LocalBinder mLocalBinder = (DanaRKoreanExecutionService.LocalBinder) service; sExecutionService = mLocalBinder.getServiceInstance(); } @@ -120,7 +120,7 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin { public void onStatusEvent(final EventPreferenceChange s) { if (isEnabled(PluginType.PUMP)) { boolean previousValue = useExtendedBoluses; - useExtendedBoluses = SP.getBoolean("danar_useextended", false); + useExtendedBoluses = SP.getBoolean(R.string.key_danar_useextended, false); if (useExtendedBoluses != previousValue && TreatmentsPlugin.getPlugin().isInHistoryExtendedBoluslInProgress()) { sExecutionService.extendedBolusStop(); @@ -147,7 +147,18 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin { @Override public boolean isInitialized() { - return pump.lastConnection > 0 && pump.maxBasal > 0 && !pump.isConfigUD && !pump.isEasyModeEnabled && pump.isExtendedBolusEnabled; + DanaRPump pump = DanaRPump.getInstance(); + return pump.lastConnection > 0 && pump.maxBasal > 0 && !pump.isConfigUD && !pump.isEasyModeEnabled && pump.isExtendedBolusEnabled && pump.isPasswordOK(); + } + + @Override + public boolean isHandshakeInProgress() { + return sExecutionService != null && sExecutionService.isHandshakeInProgress(); + } + + @Override + public void finishHandshaking() { + sExecutionService.finishHandshaking(); } @Override @@ -167,11 +178,11 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin { result.comment = String.format(MainApp.gs(R.string.boluserrorcode), detailedBolusInfo.insulin, t.insulin, MsgBolusStart.errorCode); else result.comment = MainApp.gs(R.string.virtualpump_resultok); - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("deliverTreatment: OK. Asked: " + detailedBolusInfo.insulin + " Delivered: " + result.bolusDelivered); detailedBolusInfo.insulin = t.insulin; detailedBolusInfo.date = System.currentTimeMillis(); - TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo); + TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false); return result; } else { PumpEnactResult result = new PumpEnactResult(); @@ -192,6 +203,7 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin { //if (pump.lastConnection.getTime() + 30 * 60 * 1000L < System.currentTimeMillis()) { // connect("setTempBasalAbsolute old data"); //} + DanaRPump pump = DanaRPump.getInstance(); PumpEnactResult result = new PumpEnactResult(); @@ -209,13 +221,13 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin { if (doTempOff) { // If extended in progress if (activeExtended != null && useExtendedBoluses) { - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalAbsolute: Stopping extended bolus (doTempOff)"); return cancelExtendedBolus(); } // If temp in progress if (activeTemp != null) { - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalAbsolute: Stopping temp basal (doTempOff)"); return cancelRealTempBasal(); } @@ -224,7 +236,7 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin { result.percent = 100; result.isPercent = true; result.isTempCancel = true; - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalAbsolute: doTempOff OK"); return result; } @@ -236,12 +248,12 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin { if (percentRate > getPumpDescription().maxTempPercent) { percentRate = getPumpDescription().maxTempPercent; } - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalAbsolute: Calculated percent rate: " + percentRate); // If extended in progress if (activeExtended != null && useExtendedBoluses) { - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalAbsolute: Stopping extended bolus (doLowTemp || doHighTemp)"); result = cancelExtendedBolus(); if (!result.success) { @@ -252,7 +264,7 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin { // Check if some temp is already in progress if (activeTemp != null) { // Correct basal already set ? - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalAbsolute: currently running: " + activeTemp.toString()); if (activeTemp.percentRate == percentRate) { if (enforceNew) { @@ -264,21 +276,21 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin { result.duration = activeTemp.getPlannedRemainingMinutes(); result.isPercent = true; result.isTempCancel = false; - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalAbsolute: Correct temp basal already set (doLowTemp || doHighTemp)"); return result; } } } // Convert duration from minutes to hours - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalAbsolute: Setting temp basal " + percentRate + "% for " + durationInMinutes + " mins (doLowTemp || doHighTemp)"); return setTempBasalPercent(percentRate, durationInMinutes, profile, false); } if (doExtendedTemp) { // Check if some temp is already in progress if (activeTemp != null) { - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalAbsolute: Stopping temp basal (doExtendedTemp)"); result = cancelRealTempBasal(); // Check for proper result @@ -297,7 +309,7 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin { extendedRateToSet = Round.roundTo(extendedRateToSet, pumpDescription.extendedBolusStep * 2); // *2 because of halfhours // What is current rate of extended bolusing in u/h? - if (Config.logPumpActions) { + if (L.isEnabled(L.PUMP)) { log.debug("setTempBasalAbsolute: Extended bolus in progress: " + (activeExtended != null) + " rate: " + pump.extendedBolusAbsoluteRate + "U/h duration remaining: " + pump.extendedBolusRemainingMinutes + "min"); log.debug("setTempBasalAbsolute: Rate to set: " + extendedRateToSet + "U/h"); } @@ -311,21 +323,21 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin { result.duration = pump.extendedBolusRemainingMinutes; result.isPercent = false; result.isTempCancel = false; - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalAbsolute: Correct extended already set"); return result; } // Now set new extended, no need to to stop previous (if running) because it's replaced Double extendedAmount = extendedRateToSet / 2 * durationInHalfHours; - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalAbsolute: Setting extended: " + extendedAmount + "U halfhours: " + durationInHalfHours); result = setExtendedBolus(extendedAmount, durationInMinutes); if (!result.success) { log.error("setTempBasalAbsolute: Failed to set extended bolus"); return result; } - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalAbsolute: Extended bolus set ok"); result.absolute = result.absolute + getBaseBasalRate(); return result; @@ -352,7 +364,7 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin { return result; } - public PumpEnactResult cancelRealTempBasal() { + private PumpEnactResult cancelRealTempBasal() { PumpEnactResult result = new PumpEnactResult(); TemporaryBasal runningTB = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(System.currentTimeMillis()); if (runningTB != null) { @@ -360,11 +372,11 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin { result.enacted = true; result.isTempCancel = true; } - if (!pump.isTempBasalInProgress) { + if (!DanaRPump.getInstance().isTempBasalInProgress) { result.success = true; result.isTempCancel = true; result.comment = MainApp.gs(R.string.virtualpump_resultok); - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("cancelRealTempBasal: OK"); return result; } else { @@ -380,4 +392,9 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin { public PumpEnactResult loadEvents() { return null; // no history, not needed } + + @Override + public PumpEnactResult setUserOptions() { + return null; + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/SerialIOThread.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/SerialIOThread.java index 9a8f3edb05..ea12b2b9c4 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/SerialIOThread.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/SerialIOThread.java @@ -10,7 +10,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase; import info.nightscout.androidaps.plugins.PumpDanaR.services.AbstractSerialIOThread; @@ -21,7 +21,7 @@ import info.nightscout.utils.CRC; * Created by mike on 17.07.2016. */ public class SerialIOThread extends AbstractSerialIOThread { - private static Logger log = LoggerFactory.getLogger(SerialIOThread.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPBTCOMM); private InputStream mInputStream = null; private OutputStream mOutputStream = null; @@ -72,7 +72,7 @@ public class SerialIOThread extends AbstractSerialIOThread { message = MessageHashTable_k.findMessage(command); } - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPBTCOMM)) log.debug("<<<<< " + message.getMessageName() + " " + message.toHexString(extractedBuff)); // process the message content @@ -84,7 +84,7 @@ public class SerialIOThread extends AbstractSerialIOThread { } } } catch (Exception e) { - if (Config.logDanaSerialEngine && e.getMessage().indexOf("bt socket closed") < 0) + if (e.getMessage().indexOf("bt socket closed") < 0) log.error("Thread exception: ", e); mKeepRunning = false; } @@ -148,7 +148,7 @@ public class SerialIOThread extends AbstractSerialIOThread { processedMessage = message; byte[] messageBytes = message.getRawMessageBytes(); - if (Config.logDanaSerialEngine) + if (L.isEnabled(L.PUMPBTCOMM)) log.debug(">>>>> " + message.getMessageName() + " " + message.toHexString(messageBytes)); try { @@ -167,10 +167,11 @@ public class SerialIOThread extends AbstractSerialIOThread { SystemClock.sleep(200); if (!message.received) { - log.warn("Reply not received " + message.getMessageName()); + if (L.isEnabled(L.PUMPBTCOMM)) + log.warn("Reply not received " + message.getMessageName()); if (message.getCommand() == 0xF0F1) { DanaRPump.getInstance().isNewPump = false; - log.debug("Old firmware detected"); + log.error("Old firmware detected"); } } } @@ -181,24 +182,29 @@ public class SerialIOThread extends AbstractSerialIOThread { try { mInputStream.close(); } catch (Exception e) { - if (Config.logDanaSerialEngine) log.debug(e.getMessage()); + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug(e.getMessage()); } try { mOutputStream.close(); } catch (Exception e) { - if (Config.logDanaSerialEngine) log.debug(e.getMessage()); + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug(e.getMessage()); } try { mRfCommSocket.close(); } catch (Exception e) { - if (Config.logDanaSerialEngine) log.debug(e.getMessage()); + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug(e.getMessage()); } try { System.runFinalization(); } catch (Exception e) { - if (Config.logDanaSerialEngine) log.debug(e.getMessage()); + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug(e.getMessage()); } - if (Config.logDanaSerialEngine) log.debug("Disconnected: " + reason); + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug("Disconnected: " + reason); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgCheckValue_k.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgCheckValue_k.java index 684fa30997..7bde73d5a1 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgCheckValue_k.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgCheckValue_k.java @@ -3,22 +3,21 @@ package info.nightscout.androidaps.plugins.PumpDanaRKorean.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; -import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.R; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase; import info.nightscout.androidaps.plugins.PumpDanaRKorean.DanaRKoreanPlugin; -import info.nightscout.utils.ToastUtils; /** * Created by mike on 30.06.2016. */ public class MsgCheckValue_k extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgCheckValue_k.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgCheckValue_k() { SetCommand(0xF0F1); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override @@ -26,17 +25,18 @@ public class MsgCheckValue_k extends MessageBase { DanaRPump pump = DanaRPump.getInstance(); pump.isNewPump = true; - log.debug("New firmware confirmed"); + if (L.isEnabled(L.PUMP)) + log.debug("New firmware confirmed"); pump.model = intFromBuff(bytes, 0, 1); pump.protocol = intFromBuff(bytes, 1, 1); pump.productCode = intFromBuff(bytes, 2, 1); if (pump.model != DanaRPump.DOMESTIC_MODEL) { DanaRKoreanPlugin.getPlugin().disconnect("Wrong Model"); - log.debug("Wrong model selected"); + log.error("Wrong model selected"); } - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMP)) { log.debug("Model: " + String.format("%02X ", pump.model)); log.debug("Protocol: " + String.format("%02X ", pump.protocol)); log.debug("Product Code: " + String.format("%02X ", pump.productCode)); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgInitConnStatusBasic_k.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgInitConnStatusBasic_k.java index fa28e664ed..32253b0007 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgInitConnStatusBasic_k.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgInitConnStatusBasic_k.java @@ -3,20 +3,22 @@ package info.nightscout.androidaps.plugins.PumpDanaRKorean.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.plugins.Overview.notifications.Notification; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; +import info.nightscout.androidaps.plugins.Overview.notifications.Notification; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase; public class MsgInitConnStatusBasic_k extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgInitConnStatusBasic_k.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgInitConnStatusBasic_k() { SetCommand(0x0303); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override @@ -30,7 +32,7 @@ public class MsgInitConnStatusBasic_k extends MessageBase { pump.isEasyModeEnabled = intFromBuff(bytes, 2, 1) == 1; int easyUIMode = intFromBuff(bytes, 3, 1); pump.password = intFromBuff(bytes, 4, 2) ^ 0x3463; - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("isStatusSuspendOn: " + pump.pumpSuspended); log.debug("isUtilityEnable: " + isUtilityEnable); log.debug("Is EasyUI Enabled: " + pump.isEasyModeEnabled); @@ -44,5 +46,12 @@ public class MsgInitConnStatusBasic_k extends MessageBase { } else { MainApp.bus().post(new EventDismissNotification(Notification.EASYMODE_ENABLED)); } + + if (!DanaRPump.getInstance().isPasswordOK()) { + Notification notification = new Notification(Notification.WRONG_PUMP_PASSWORD, MainApp.gs(R.string.wrongpumppassword), Notification.URGENT); + MainApp.bus().post(new EventNewNotification(notification)); + } else { + MainApp.bus().post(new EventDismissNotification(Notification.WRONG_PUMP_PASSWORD)); + } } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgInitConnStatusBolus_k.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgInitConnStatusBolus_k.java index 552511cf7c..b8bdfd053c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgInitConnStatusBolus_k.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgInitConnStatusBolus_k.java @@ -3,23 +3,26 @@ package info.nightscout.androidaps.plugins.PumpDanaRKorean.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; -import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase; -import info.nightscout.androidaps.plugins.Overview.notifications.Notification; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; +import info.nightscout.androidaps.plugins.Overview.notifications.Notification; +import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase; /** * Created by mike on 28.05.2016. */ public class MsgInitConnStatusBolus_k extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgInitConnStatusBolus_k.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgInitConnStatusBolus_k() { SetCommand(0x0302); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override @@ -36,7 +39,7 @@ public class MsgInitConnStatusBolus_k extends MessageBase { //int bolusRate = intFromBuff(bytes, 4, 8); int deliveryStatus = intFromBuff(bytes, 12, 1); - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Is Extended bolus enabled: " + pump.isExtendedBolusEnabled); log.debug("Bolus increment: " + pump.bolusStep); log.debug("Bolus max: " + pump.maxBolus); @@ -49,5 +52,9 @@ public class MsgInitConnStatusBolus_k extends MessageBase { } else { MainApp.bus().post(new EventDismissNotification(Notification.EXTENDED_BOLUS_DISABLED)); } + + // This is last message of initial sequence + if (ConfigBuilderPlugin.getPlugin().getActivePump() != null) + ConfigBuilderPlugin.getPlugin().getActivePump().finishHandshaking(); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgInitConnStatusTime_k.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgInitConnStatusTime_k.java index 7553b0cc37..d713bb5a6c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgInitConnStatusTime_k.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgInitConnStatusTime_k.java @@ -3,13 +3,11 @@ package info.nightscout.androidaps.plugins.PumpDanaRKorean.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Date; - -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.events.EventRefreshGui; import info.nightscout.androidaps.interfaces.PluginType; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.Overview.notifications.Notification; @@ -17,12 +15,15 @@ import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPlugin; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase; import info.nightscout.androidaps.plugins.PumpDanaRKorean.DanaRKoreanPlugin; +import info.nightscout.utils.DateUtil; public class MsgInitConnStatusTime_k extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgInitConnStatusTime_k.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgInitConnStatusTime_k() { SetCommand(0x0301); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override @@ -32,7 +33,7 @@ public class MsgInitConnStatusTime_k extends MessageBase { Notification notification = new Notification(Notification.WRONG_DRIVER, MainApp.gs(R.string.pumpdrivercorrected), Notification.NORMAL); MainApp.bus().post(new EventNewNotification(notification)); DanaRKoreanPlugin.getPlugin().disconnect("Wrong Model"); - log.debug("Wrong model selected. Switching to export DanaR"); + log.error("Wrong model selected. Switching to export DanaR"); MainApp.getSpecificPlugin(DanaRKoreanPlugin.class).setPluginEnabled(PluginType.PUMP, false); MainApp.getSpecificPlugin(DanaRKoreanPlugin.class).setFragmentVisible(PluginType.PUMP, false); MainApp.getSpecificPlugin(DanaRPlugin.class).setPluginEnabled(PluginType.PUMP, true); @@ -46,20 +47,20 @@ public class MsgInitConnStatusTime_k extends MessageBase { (MainApp.getSpecificPlugin(DanaRPlugin.class)).setPluginEnabled(PluginType.PROFILE, true); } - MainApp.getConfigBuilder().storeSettings("ChangingKoreanDanaDriver"); + ConfigBuilderPlugin.getPlugin().storeSettings("ChangingKoreanDanaDriver"); MainApp.bus().post(new EventRefreshGui()); - ConfigBuilderPlugin.getCommandQueue().readStatus("PumpDriverChange", null); // force new connection + ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("PumpDriverChange", null); // force new connection return; } - Date time = dateTimeSecFromBuff(bytes, 0); + long time = dateTimeSecFromBuff(bytes, 0); int versionCode1 = intFromBuff(bytes, 6, 1); int versionCode2 = intFromBuff(bytes, 7, 1); int versionCode3 = intFromBuff(bytes, 8, 1); int versionCode4 = intFromBuff(bytes, 9, 1); - if (Config.logDanaMessageDetail) { - log.debug("Pump time: " + time); + if (L.isEnabled(L.PUMPCOMM)) { + log.debug("Pump time: " + DateUtil.dateAndTimeFullString(time)); log.debug("Version code1: " + versionCode1); log.debug("Version code2: " + versionCode2); log.debug("Version code3: " + versionCode3); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgSettingBasalProfileAll_k.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgSettingBasalProfileAll_k.java index 304ec9fc37..2455f59e14 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgSettingBasalProfileAll_k.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgSettingBasalProfileAll_k.java @@ -3,7 +3,7 @@ package info.nightscout.androidaps.plugins.PumpDanaRKorean.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase; @@ -15,10 +15,12 @@ import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase; * THIS IS BROKEN IN PUMP... SENDING ONLY 1 PROFILE */ public class MsgSettingBasalProfileAll_k extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgSettingBasalProfileAll_k.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgSettingBasalProfileAll_k() { SetCommand(0x3206); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } public void handleMessage(byte[] bytes) { @@ -49,7 +51,7 @@ public class MsgSettingBasalProfileAll_k extends MessageBase { } } - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { if (pump.basal48Enable) { for (int profile = 0; profile < 4; profile++) { for (int index = 0; index < 24; index++) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgSettingBasal_k.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgSettingBasal_k.java index 5c8b40b959..b149ceb2ad 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgSettingBasal_k.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgSettingBasal_k.java @@ -3,7 +3,7 @@ package info.nightscout.androidaps.plugins.PumpDanaRKorean.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase; import info.nightscout.androidaps.plugins.PumpDanaRKorean.DanaRKoreanPlugin; @@ -12,10 +12,12 @@ import info.nightscout.androidaps.plugins.PumpDanaRKorean.DanaRKoreanPlugin; * Created by mike on 05.07.2016. */ public class MsgSettingBasal_k extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgSettingBasal_k.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgSettingBasal_k() { SetCommand(0x3202); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } public void handleMessage(byte[] bytes) { @@ -28,7 +30,7 @@ public class MsgSettingBasal_k extends MessageBase { pump.pumpProfiles[pump.activeProfile][index] = basal / 100d; } - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) for (int index = 0; index < 24; index++) { log.debug("Basal " + String.format("%02d", index) + "h: " + pump.pumpProfiles[pump.activeProfile][index]); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgStatusBasic_k.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgStatusBasic_k.java index 0fcaf17d83..d22c6e376a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgStatusBasic_k.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgStatusBasic_k.java @@ -3,16 +3,18 @@ package info.nightscout.androidaps.plugins.PumpDanaRKorean.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase; public class MsgStatusBasic_k extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgStatusBasic_k.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgStatusBasic_k() { SetCommand(0x020A); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } public void handleMessage(byte[] bytes) { @@ -29,7 +31,7 @@ public class MsgStatusBasic_k extends MessageBase { pump.currentBasal = currentBasal; pump.batteryRemaining = batteryRemaining; - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Daily total units: " + dailyTotalUnits); log.debug("Max daily total units: " + maxDailyTotalUnits); log.debug("Reservoir remaining units: " + reservoirRemainingUnits); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgStatus_k.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgStatus_k.java index 1fdcf26917..4d8b012244 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgStatus_k.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgStatus_k.java @@ -3,15 +3,17 @@ package info.nightscout.androidaps.plugins.PumpDanaRKorean.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase; public class MsgStatus_k extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgStatus_k.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgStatus_k() { SetCommand(0x020B); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } public void handleMessage(byte[] bytes) { @@ -27,7 +29,7 @@ public class MsgStatus_k extends MessageBase { // } pump.iob = intFromBuff(bytes, 15, 2) / 100d; - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Daily total: " + pump.dailyTotalUnits); log.debug("Is extended bolus running: " + pump.isExtendedInProgress); log.debug("Extended bolus min: " + pump.extendedBolusMinutes); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/services/DanaRKoreanExecutionService.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/services/DanaRKoreanExecutionService.java index e46e3d6caf..f3588c4efa 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/services/DanaRKoreanExecutionService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/services/DanaRKoreanExecutionService.java @@ -7,23 +7,24 @@ import android.os.SystemClock; import com.squareup.otto.Subscribe; -import org.slf4j.LoggerFactory; - import java.io.IOException; import java.util.Date; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.PumpEnactResult; -import info.nightscout.androidaps.plugins.Treatments.Treatment; import info.nightscout.androidaps.events.EventAppExit; import info.nightscout.androidaps.events.EventInitializationChanged; import info.nightscout.androidaps.events.EventPreferenceChange; +import info.nightscout.androidaps.events.EventProfileSwitchChange; import info.nightscout.androidaps.events.EventPumpStatusChanged; +import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; +import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; import info.nightscout.androidaps.plugins.Overview.Dialogs.BolusProgressDialog; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.Overview.notifications.Notification; @@ -38,6 +39,7 @@ import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetSingleBasalProfil import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetTempBasalStart; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetTempBasalStop; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetTime; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingBasal; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingGlucose; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingMaxValues; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingMeal; @@ -48,19 +50,18 @@ import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgStatusBolusExtended; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgStatusTempBasal; import info.nightscout.androidaps.plugins.PumpDanaR.events.EventDanaRNewStatus; import info.nightscout.androidaps.plugins.PumpDanaR.services.AbstractDanaRExecutionService; -import info.nightscout.androidaps.plugins.PumpDanaRKorean.DanaRKoreanPlugin; import info.nightscout.androidaps.plugins.PumpDanaRKorean.SerialIOThread; import info.nightscout.androidaps.plugins.PumpDanaRKorean.comm.MsgCheckValue_k; import info.nightscout.androidaps.plugins.PumpDanaRKorean.comm.MsgSettingBasal_k; import info.nightscout.androidaps.plugins.PumpDanaRKorean.comm.MsgStatusBasic_k; -import info.nightscout.utils.NSUpload; -import info.nightscout.utils.SP; -import info.nightscout.utils.ToastUtils; +import info.nightscout.androidaps.plugins.Treatments.Treatment; +import info.nightscout.androidaps.queue.commands.Command; +import info.nightscout.utils.DateUtil; +import info.nightscout.utils.T; public class DanaRKoreanExecutionService extends AbstractDanaRExecutionService { public DanaRKoreanExecutionService() { - log = LoggerFactory.getLogger(DanaRKoreanExecutionService.class); mBinder = new LocalBinder(); registerBus(); @@ -84,7 +85,7 @@ public class DanaRKoreanExecutionService extends AbstractDanaRExecutionService { @Subscribe public void onStatusEvent(EventAppExit event) { - if (Config.logFunctionCalls) + if (L.isEnabled(L.PUMP)) log.debug("EventAppExit received"); if (mSerialIOThread != null) @@ -93,8 +94,6 @@ public class DanaRKoreanExecutionService extends AbstractDanaRExecutionService { MainApp.instance().getApplicationContext().unregisterReceiver(receiver); stopSelf(); - if (Config.logFunctionCalls) - log.debug("EventAppExit finished"); } @Subscribe @@ -104,51 +103,42 @@ public class DanaRKoreanExecutionService extends AbstractDanaRExecutionService { } public void connect() { - if (mDanaRPump.password != -1 && mDanaRPump.password != SP.getInt(R.string.key_danar_password, -1)) { - if(System.currentTimeMillis() > lastWrongPumpPassword + 30 * 1000) { - Notification notification = new Notification(Notification.WRONG_PUMP_PASSWORD, MainApp.gs(R.string.wrongpumppassword), Notification.URGENT); - notification.soundId = R.raw.error; - lastWrongPumpPassword = System.currentTimeMillis(); - } - return; - } - if (mConnectionInProgress) return; - new Thread(new Runnable() { - @Override - public void run() { - mConnectionInProgress = true; - getBTSocketForSelectedPump(); - if (mRfcommSocket == null || mBTDevice == null) { - mConnectionInProgress = false; - return; // Device not found - } - - try { - mRfcommSocket.connect(); - } catch (IOException e) { - //log.error("Unhandled exception", e); - if (e.getMessage().contains("socket closed")) { - log.error("Unhandled exception", e); - } - } - - if (isConnected()) { - if (mSerialIOThread != null) { - mSerialIOThread.disconnect("Recreate SerialIOThread"); - } - mSerialIOThread = new SerialIOThread(mRfcommSocket); - MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.CONNECTED, 0)); - } - + new Thread(() -> { + mHandshakeInProgress = false; + mConnectionInProgress = true; + getBTSocketForSelectedPump(); + if (mRfcommSocket == null || mBTDevice == null) { mConnectionInProgress = false; + return; // Device not found } + + try { + mRfcommSocket.connect(); + } catch (IOException e) { + //log.error("Unhandled exception", e); + if (e.getMessage().contains("socket closed")) { + log.error("Unhandled exception", e); + } + } + + if (isConnected()) { + if (mSerialIOThread != null) { + mSerialIOThread.disconnect("Recreate SerialIOThread"); + } + mSerialIOThread = new SerialIOThread(mRfcommSocket); + mHandshakeInProgress = true; + MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.HANDSHAKING, 0)); + } + + mConnectionInProgress = false; }).start(); } public void getPumpStatus() { + DanaRPump danaRPump = DanaRPump.getInstance(); try { MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.gettingpumpstatus))); //MsgStatus_k statusMsg = new MsgStatus_k(); @@ -157,7 +147,7 @@ public class DanaRKoreanExecutionService extends AbstractDanaRExecutionService { MsgStatusBolusExtended exStatusMsg = new MsgStatusBolusExtended(); MsgCheckValue_k checkValue = new MsgCheckValue_k(); - if (mDanaRPump.isNewPump) { + if (danaRPump.isNewPump) { mSerialIOThread.sendMessage(checkValue); if (!checkValue.received) { return; @@ -173,7 +163,19 @@ public class DanaRKoreanExecutionService extends AbstractDanaRExecutionService { MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.gettingbolusstatus))); long now = System.currentTimeMillis(); - if (mDanaRPump.lastSettingsRead + 60 * 60 * 1000L < now || !MainApp.getSpecificPlugin(DanaRKoreanPlugin.class).isInitialized()) { + danaRPump.lastConnection = now; + + Profile profile = ProfileFunctions.getInstance().getProfile(); + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); + if (profile != null && Math.abs(danaRPump.currentBasal - profile.getBasal()) >= pump.getPumpDescription().basalStep) { + MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.gettingpumpsettings))); + mSerialIOThread.sendMessage(new MsgSettingBasal()); + if (!pump.isThisProfileSet(profile) && !ConfigBuilderPlugin.getPlugin().getCommandQueue().isRunning(Command.CommandType.BASALPROFILE)) { + MainApp.bus().post(new EventProfileSwitchChange()); + } + } + + if (danaRPump.lastSettingsRead + 60 * 60 * 1000L < now || !pump.isInitialized()) { MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.gettingpumpsettings))); mSerialIOThread.sendMessage(new MsgSettingShippingInfo()); mSerialIOThread.sendMessage(new MsgSettingMeal()); @@ -184,27 +186,31 @@ public class DanaRKoreanExecutionService extends AbstractDanaRExecutionService { mSerialIOThread.sendMessage(new MsgSettingProfileRatios()); MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.gettingpumptime))); mSerialIOThread.sendMessage(new MsgSettingPumpTime()); - long timeDiff = (mDanaRPump.pumpTime.getTime() - System.currentTimeMillis()) / 1000L; - log.debug("Pump time difference: " + timeDiff + " seconds"); - if (Math.abs(timeDiff) > 10) { - mSerialIOThread.sendMessage(new MsgSetTime(new Date())); - mSerialIOThread.sendMessage(new MsgSettingPumpTime()); - timeDiff = (mDanaRPump.pumpTime.getTime() - System.currentTimeMillis()) / 1000L; + long timeDiff = (danaRPump.pumpTime - System.currentTimeMillis()) / 1000L; + if (L.isEnabled(L.PUMP)) log.debug("Pump time difference: " + timeDiff + " seconds"); + if (Math.abs(timeDiff) > 10) { + waitForWholeMinute(); // Dana can set only whole minute + // add 10sec to be sure we are over minute (will be cutted off anyway) + mSerialIOThread.sendMessage(new MsgSetTime(new Date(DateUtil.now() + T.secs(10).msecs()))); + mSerialIOThread.sendMessage(new MsgSettingPumpTime()); + timeDiff = (danaRPump.pumpTime - System.currentTimeMillis()) / 1000L; + if (L.isEnabled(L.PUMP)) + log.debug("Pump time difference: " + timeDiff + " seconds"); } - mDanaRPump.lastSettingsRead = now; + danaRPump.lastSettingsRead = now; } - mDanaRPump.lastConnection = now; MainApp.bus().post(new EventDanaRNewStatus()); MainApp.bus().post(new EventInitializationChanged()); NSUpload.uploadDeviceStatus(); - if (mDanaRPump.dailyTotalUnits > mDanaRPump.maxDailyTotalUnits * Constants.dailyLimitWarning) { - log.debug("Approaching daily limit: " + mDanaRPump.dailyTotalUnits + "/" + mDanaRPump.maxDailyTotalUnits); - if(System.currentTimeMillis() > lastApproachingDailyLimit + 30 * 60 * 1000) { + if (danaRPump.dailyTotalUnits > danaRPump.maxDailyTotalUnits * Constants.dailyLimitWarning) { + if (L.isEnabled(L.PUMP)) + log.debug("Approaching daily limit: " + danaRPump.dailyTotalUnits + "/" + danaRPump.maxDailyTotalUnits); + if (System.currentTimeMillis() > lastApproachingDailyLimit + 30 * 60 * 1000) { Notification reportFail = new Notification(Notification.APPROACHING_DAILY_LIMIT, MainApp.gs(R.string.approachingdailylimit), Notification.URGENT); MainApp.bus().post(new EventNewNotification(reportFail)); - NSUpload.uploadError(MainApp.gs(R.string.approachingdailylimit) + ": " + mDanaRPump.dailyTotalUnits + "/" + mDanaRPump.maxDailyTotalUnits + "U"); + NSUpload.uploadError(MainApp.gs(R.string.approachingdailylimit) + ": " + danaRPump.dailyTotalUnits + "/" + danaRPump.maxDailyTotalUnits + "U"); lastApproachingDailyLimit = System.currentTimeMillis(); } } @@ -214,8 +220,9 @@ public class DanaRKoreanExecutionService extends AbstractDanaRExecutionService { } public boolean tempBasal(int percent, int durationInHours) { + DanaRPump danaRPump = DanaRPump.getInstance(); if (!isConnected()) return false; - if (mDanaRPump.isTempBasalInProgress) { + if (danaRPump.isTempBasalInProgress) { MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.stoppingtempbasal))); mSerialIOThread.sendMessage(new MsgSetTempBasalStop()); SystemClock.sleep(500); @@ -273,7 +280,6 @@ public class DanaRKoreanExecutionService extends AbstractDanaRExecutionService { if (amount > 0) { MsgBolusProgress progress = new MsgBolusProgress(amount, t); // initialize static variables - long bolusStart = System.currentTimeMillis(); if (!stop.stopped) { mSerialIOThread.sendMessage(start); @@ -286,13 +292,14 @@ public class DanaRKoreanExecutionService extends AbstractDanaRExecutionService { if ((System.currentTimeMillis() - progress.lastReceive) > 15 * 1000L) { // if i didn't receive status for more than 15 sec expecting broken comm stop.stopped = true; stop.forced = true; - log.debug("Communication stopped"); + if (L.isEnabled(L.PUMP)) + log.debug("Communication stopped"); } } SystemClock.sleep(300); mBolusingTreatment = null; - ConfigBuilderPlugin.getCommandQueue().readStatus("bolusOK", null); + ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("bolusOK", null); } return !start.failed; @@ -316,15 +323,21 @@ public class DanaRKoreanExecutionService extends AbstractDanaRExecutionService { } public boolean updateBasalsInPump(final Profile profile) { + DanaRPump danaRPump = DanaRPump.getInstance(); if (!isConnected()) return false; MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.updatingbasalrates))); - double[] basal = DanaRPump.buildDanaRProfileRecord(profile); + double[] basal = DanaRPump.getInstance().buildDanaRProfileRecord(profile); MsgSetSingleBasalProfile msgSet = new MsgSetSingleBasalProfile(basal); mSerialIOThread.sendMessage(msgSet); - mDanaRPump.lastSettingsRead = 0; // force read full settings + danaRPump.lastSettingsRead = 0; // force read full settings getPumpStatus(); MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.DISCONNECTING)); return true; } + @Override + public PumpEnactResult setUserOptions() { + return null; + } + } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/DanaRSPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/DanaRSPlugin.java index 1cbb256c1e..d6a4dd015b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/DanaRSPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/DanaRSPlugin.java @@ -6,6 +6,8 @@ import android.content.Intent; import android.content.ServiceConnection; import android.os.IBinder; import android.support.annotation.Nullable; +import android.support.v4.app.FragmentActivity; +import android.support.v7.app.AlertDialog; import com.squareup.otto.Subscribe; @@ -14,10 +16,7 @@ import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Date; - import info.nightscout.androidaps.BuildConfig; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.DetailedBolusInfo; @@ -26,8 +25,6 @@ import info.nightscout.androidaps.data.ProfileStore; import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.db.ExtendedBolus; import info.nightscout.androidaps.db.TemporaryBasal; -import info.nightscout.androidaps.plugins.PumpDanaRS.comm.DanaRS_Packet_Bolus_Set_Step_Bolus_Start; -import info.nightscout.androidaps.plugins.Treatments.Treatment; import info.nightscout.androidaps.events.EventAppExit; import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.ConstraintsInterface; @@ -38,28 +35,35 @@ import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.ProfileInterface; import info.nightscout.androidaps.interfaces.PumpDescription; import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderFragment; import info.nightscout.androidaps.plugins.ConfigBuilder.DetailedBolusInfoStorage; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.Overview.notifications.Notification; import info.nightscout.androidaps.plugins.ProfileNS.NSProfilePlugin; +import info.nightscout.androidaps.plugins.PumpCommon.defs.PumpType; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRFragment; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; import info.nightscout.androidaps.plugins.PumpDanaR.comm.RecordTypes; +import info.nightscout.androidaps.plugins.PumpDanaRS.comm.DanaRS_Packet_Bolus_Set_Step_Bolus_Start; import info.nightscout.androidaps.plugins.PumpDanaRS.events.EventDanaRSDeviceChange; import info.nightscout.androidaps.plugins.PumpDanaRS.services.DanaRSService; +import info.nightscout.androidaps.plugins.Treatments.Treatment; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.Round; import info.nightscout.utils.SP; +import info.nightscout.utils.T; /** * Created by mike on 03.09.2017. */ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInterface, ConstraintsInterface, ProfileInterface { - private static Logger log = LoggerFactory.getLogger(DanaRSPlugin.class); + private Logger log = LoggerFactory.getLogger(L.PUMP); private static DanaRSPlugin plugin = null; public static DanaRSPlugin getPlugin() { @@ -68,53 +72,24 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte return plugin; } - public static DanaRSService danaRSService; + private static DanaRSService danaRSService; - public static String mDeviceAddress = ""; + private static String mDeviceAddress = ""; public static String mDeviceName = ""; - private static DanaRPump pump = DanaRPump.getInstance(); public static PumpDescription pumpDescription = new PumpDescription(); - DanaRSPlugin() { + private DanaRSPlugin() { super(new PluginDescription() .mainType(PluginType.PUMP) .fragmentClass(DanaRFragment.class.getName()) .pluginName(R.string.danarspump) .shortName(R.string.danarspump_shortname) .preferencesId(R.xml.pref_danars) + .description(R.string.description_pump_dana_rs) ); - pumpDescription.isBolusCapable = true; - pumpDescription.bolusStep = 0.05d; - - pumpDescription.isExtendedBolusCapable = true; - pumpDescription.extendedBolusStep = 0.05d; - pumpDescription.extendedBolusDurationStep = 30; - pumpDescription.extendedBolusMaxDuration = 8 * 60; - - pumpDescription.isTempBasalCapable = true; - pumpDescription.tempBasalStyle = PumpDescription.PERCENT; - - pumpDescription.maxTempPercent = 200; - pumpDescription.tempPercentStep = 10; - - pumpDescription.tempDurationStep = 60; - pumpDescription.tempDurationStep15mAllowed = true; - pumpDescription.tempDurationStep30mAllowed = true; - pumpDescription.tempMaxDuration = 24 * 60; - - - pumpDescription.isSetBasalProfileCapable = true; - pumpDescription.basalStep = 0.01d; - pumpDescription.basalMinimumRate = 0.04d; - - pumpDescription.isRefillingCapable = true; - - pumpDescription.storesCarbInfo = true; - - pumpDescription.supportsTDDs = true; - pumpDescription.needsManualTDDLoad = true; + pumpDescription.setPumpDescription(PumpType.DanaRS); } @Override @@ -146,15 +121,40 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte MainApp.bus().unregister(this); } + @Override + public void switchAllowed(ConfigBuilderFragment.PluginViewHolder.PluginSwitcher pluginSwitcher, FragmentActivity context) { + boolean allowHardwarePump = SP.getBoolean("allow_hardware_pump", false); + if (allowHardwarePump || context == null) { + pluginSwitcher.invoke(); + } else { + AlertDialog.Builder builder = new AlertDialog.Builder(context); + builder.setMessage(R.string.allow_hardware_pump_text) + .setPositiveButton(R.string.yes, (dialog, id) -> { + pluginSwitcher.invoke(); + SP.putBoolean("allow_hardware_pump", true); + if (L.isEnabled(L.PUMP)) + log.debug("First time HW pump allowed!"); + }) + .setNegativeButton(R.string.cancel, (dialog, id) -> { + pluginSwitcher.cancel(); + if (L.isEnabled(L.PUMP)) + log.debug("User does not allow switching to HW pump!"); + }); + builder.create().show(); + } + } + private ServiceConnection mConnection = new ServiceConnection() { public void onServiceDisconnected(ComponentName name) { - log.debug("Service is disconnected"); + if (L.isEnabled(L.PUMP)) + log.debug("Service is disconnected"); danaRSService = null; } public void onServiceConnected(ComponentName name, IBinder service) { - log.debug("Service is connected"); + if (L.isEnabled(L.PUMP)) + log.debug("Service is connected"); DanaRSService.LocalBinder mLocalBinder = (DanaRSService.LocalBinder) service; danaRSService = mLocalBinder.getServiceInstance(); } @@ -174,7 +174,8 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte @Override public void connect(String from) { - log.debug("RS connect from: " + from); + if (L.isEnabled(L.PUMP)) + log.debug("RS connect from: " + from); if (danaRSService != null && !mDeviceAddress.equals("") && !mDeviceName.equals("")) { final Object o = new Object(); @@ -192,8 +193,19 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte return danaRSService != null && danaRSService.isConnecting(); } + @Override + public boolean isHandshakeInProgress() { + return false; + } + + @Override + public void finishHandshaking() { + } + @Override public void disconnect(String from) { + if (L.isEnabled(L.PUMP)) + log.debug("RS disconnect from: " + from); if (danaRSService != null) danaRSService.disconnect(from); } @@ -206,8 +218,8 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte public void getPumpStatus() { if (danaRSService != null) { danaRSService.getPumpStatus(); - pumpDescription.basalStep = pump.basalStep; - pumpDescription.bolusStep = pump.bolusStep; + pumpDescription.basalStep = DanaRPump.getInstance().basalStep; + pumpDescription.bolusStep = DanaRPump.getInstance().bolusStep; } } @@ -223,12 +235,16 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte return danaRSService.loadEvents(); } + @Override + public PumpEnactResult setUserOptions() { + return danaRSService.setUserSettings(); + } + // Constraints interface @Override public Constraint applyBasalConstraints(Constraint absoluteRate, Profile profile) { - if (pump != null) - absoluteRate.setIfSmaller(pump.maxBasal, String.format(MainApp.gs(R.string.limitingbasalratio), pump.maxBasal, MainApp.gs(R.string.pumplimit)), this); + absoluteRate.setIfSmaller(DanaRPump.getInstance().maxBasal, String.format(MainApp.gs(R.string.limitingbasalratio), DanaRPump.getInstance().maxBasal, MainApp.gs(R.string.pumplimit)), this); return absoluteRate; } @@ -243,41 +259,45 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte @Override public Constraint applyBolusConstraints(Constraint insulin) { - if (pump != null) - insulin.setIfSmaller(pump.maxBolus, String.format(MainApp.gs(R.string.limitingbolus), pump.maxBolus, MainApp.gs(R.string.pumplimit)), this); + insulin.setIfSmaller(DanaRPump.getInstance().maxBolus, String.format(MainApp.gs(R.string.limitingbolus), DanaRPump.getInstance().maxBolus, MainApp.gs(R.string.pumplimit)), this); return insulin; } + @Override + public Constraint applyExtendedBolusConstraints(Constraint insulin) { + return applyBolusConstraints(insulin); + } + // Profile interface @Nullable @Override public ProfileStore getProfile() { - if (pump.lastSettingsRead == 0) + if (DanaRPump.getInstance().lastSettingsRead == 0) return null; // no info now - return pump.createConvertedProfile(); + return DanaRPump.getInstance().createConvertedProfile(); } @Override public String getUnits() { - return pump.getUnits(); + return DanaRPump.getInstance().getUnits(); } @Override public String getProfileName() { - return pump.createConvertedProfileName(); + return DanaRPump.getInstance().createConvertedProfileName(); } // Pump interface @Override public boolean isInitialized() { - return pump.lastConnection > 0 && pump.maxBasal > 0; + return DanaRPump.getInstance().lastConnection > 0 && DanaRPump.getInstance().maxBasal > 0; } @Override public boolean isSuspended() { - return pump.pumpSuspended; + return DanaRPump.getInstance().pumpSuspended; } @Override @@ -325,6 +345,7 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte public boolean isThisProfileSet(Profile profile) { if (!isInitialized()) return true; // TODO: not sure what's better. so far TRUE to prevent too many SMS + DanaRPump pump = DanaRPump.getInstance(); if (pump.pumpProfiles == null) return true; // TODO: not sure what's better. so far TRUE to prevent too many SMS int basalValues = pump.basal48Enable ? 48 : 24; @@ -334,7 +355,8 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte Double profileValue = profile.getBasalTimeFromMidnight((Integer) (h * basalIncrement)); if (profileValue == null) return true; if (Math.abs(pumpValue - profileValue) > getPumpDescription().basalStep) { - log.debug("Diff found. Hour: " + h + " Pump: " + pumpValue + " Profile: " + profileValue); + if (L.isEnabled(L.PUMP)) + log.debug("Diff found. Hour: " + h + " Pump: " + pumpValue + " Profile: " + profileValue); return false; } } @@ -342,13 +364,13 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte } @Override - public Date lastDataTime() { - return new Date(pump.lastConnection); + public long lastDataTime() { + return DanaRPump.getInstance().lastConnection; } @Override public double getBaseBasalRate() { - return pump.currentBasal; + return DanaRPump.getInstance().currentBasal; } @Override @@ -376,6 +398,7 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte double carbs = detailedBolusInfo.carbs; detailedBolusInfo.carbs = 0; int carbTime = detailedBolusInfo.carbTime; + if (carbTime == 0) carbTime--; // better set 1 min back to prevents clash with insulin detailedBolusInfo.carbTime = 0; DetailedBolusInfoStorage.add(detailedBolusInfo); // will be picked up on reading history @@ -384,16 +407,32 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte t.isSMB = detailedBolusInfo.isSMB; boolean connectionOK = false; if (detailedBolusInfo.insulin > 0 || carbs > 0) - connectionOK = danaRSService.bolus(detailedBolusInfo.insulin, (int) carbs, DateUtil.now() + carbTime * 60 * 1000, t); + connectionOK = danaRSService.bolus(detailedBolusInfo.insulin, (int) carbs, DateUtil.now() + T.mins(carbTime).msecs(), t); PumpEnactResult result = new PumpEnactResult(); result.success = connectionOK && Math.abs(detailedBolusInfo.insulin - t.insulin) < pumpDescription.bolusStep; result.bolusDelivered = t.insulin; result.carbsDelivered = detailedBolusInfo.carbs; - if (!result.success) - result.comment = String.format(MainApp.gs(R.string.boluserrorcode), detailedBolusInfo.insulin, t.insulin, DanaRS_Packet_Bolus_Set_Step_Bolus_Start.errorCode); - else + if (!result.success) { + String error = "" + DanaRS_Packet_Bolus_Set_Step_Bolus_Start.errorCode; + switch (DanaRS_Packet_Bolus_Set_Step_Bolus_Start.errorCode) { + // 4 reported as max bolus violation. Check later + case 0x10: + error = MainApp.gs(R.string.maxbolusviolation); + break; + case 0x20: + error = MainApp.gs(R.string.commanderror); + break; + case 0x40: + error = MainApp.gs(R.string.speederror); + break; + case 0x80: + error = MainApp.gs(R.string.insulinlimitviolation); + break; + } + result.comment = String.format(MainApp.gs(R.string.boluserrorcode), detailedBolusInfo.insulin, t.insulin, error); + } else result.comment = MainApp.gs(R.string.virtualpump_resultok); - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("deliverTreatment: OK. Asked: " + detailedBolusInfo.insulin + " Delivered: " + result.bolusDelivered); return result; } else { @@ -437,7 +476,7 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte if (doTempOff) { // If temp in progress if (TreatmentsPlugin.getPlugin().isTempBasalInProgress()) { - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalAbsolute: Stopping temp basal (doTempOff)"); return cancelTempBasal(false); } @@ -446,7 +485,7 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte result.percent = 100; result.isPercent = true; result.isTempCancel = true; - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalAbsolute: doTempOff OK"); return result; } @@ -460,7 +499,7 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte // Check if some temp is already in progress TemporaryBasal activeTemp = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(System.currentTimeMillis()); if (activeTemp != null) { - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalAbsolute: currently running: " + activeTemp.toString()); // Correct basal already set ? if (activeTemp.percentRate == percentRate) { @@ -471,22 +510,26 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte result.duration = activeTemp.getPlannedRemainingMinutes(); result.isPercent = true; result.isTempCancel = false; - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalAbsolute: Correct temp basal already set (doLowTemp || doHighTemp)"); return result; } } } // Convert duration from minutes to hours - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalAbsolute: Setting temp basal " + percentRate + "% for " + durationInMinutes + " mins (doLowTemp || doHighTemp)"); - // use special APS temp basal call ... 100+/15min .... 100-/30min - result = setHighTempBasalPercent(percentRate); + if (percentRate == 0 && durationInMinutes > 30) { + result = setTempBasalPercent(percentRate, durationInMinutes, profile, false); + } else { + // use special APS temp basal call ... 100+/15min .... 100-/30min + result = setHighTempBasalPercent(percentRate); + } if (!result.success) { log.error("setTempBasalAbsolute: Failed to set hightemp basal"); return result; } - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalAbsolute: hightemp basal set ok"); return result; } @@ -499,6 +542,7 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte @Override public synchronized PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes, Profile profile, boolean enforceNew) { + DanaRPump pump = DanaRPump.getInstance(); PumpEnactResult result = new PumpEnactResult(); percent = MainApp.getConstraintChecker().applyBasalPercentConstraints(new Constraint<>(percent), profile).value(); if (percent < 0) { @@ -521,7 +565,7 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte result.duration = pump.tempBasalRemainingMin; result.percent = pump.tempBasalPercent; result.isPercent = true; - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalPercent: Correct value already set"); return result; } @@ -540,7 +584,7 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte result.duration = pump.tempBasalRemainingMin; result.percent = pump.tempBasalPercent; result.isPercent = true; - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalPercent: OK"); return result; } @@ -551,7 +595,8 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte return result; } - public synchronized PumpEnactResult setHighTempBasalPercent(Integer percent) { + private synchronized PumpEnactResult setHighTempBasalPercent(Integer percent) { + DanaRPump pump = DanaRPump.getInstance(); PumpEnactResult result = new PumpEnactResult(); boolean connectionOK = danaRSService.highTempBasal(percent); if (connectionOK && pump.isTempBasalInProgress && pump.tempBasalPercent == percent) { @@ -562,7 +607,7 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte result.duration = pump.tempBasalRemainingMin; result.percent = pump.tempBasalPercent; result.isPercent = true; - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setHighTempBasalPercent: OK"); return result; } @@ -575,7 +620,8 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte @Override public synchronized PumpEnactResult setExtendedBolus(Double insulin, Integer durationInMinutes) { - insulin = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(insulin)).value(); + DanaRPump pump = DanaRPump.getInstance(); + insulin = MainApp.getConstraintChecker().applyExtendedBolusConstraints(new Constraint<>(insulin)).value(); // needs to be rounded int durationInHalfHours = Math.max(durationInMinutes / 30, 1); insulin = Round.roundTo(insulin, getPumpDescription().extendedBolusStep); @@ -589,7 +635,7 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte result.absolute = pump.extendedBolusAbsoluteRate; result.isPercent = false; result.isTempCancel = false; - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setExtendedBolus: Correct extended bolus already set. Current: " + pump.extendedBolusAmount + " Asked: " + insulin); return result; } @@ -603,7 +649,7 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte result.absolute = pump.extendedBolusAbsoluteRate; result.bolusDelivered = pump.extendedBolusAmount; result.isPercent = false; - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setExtendedBolus: OK"); return result; } @@ -623,11 +669,11 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte result.enacted = true; result.isTempCancel = true; } - if (!pump.isTempBasalInProgress) { + if (!DanaRPump.getInstance().isTempBasalInProgress) { result.success = true; result.isTempCancel = true; result.comment = MainApp.gs(R.string.virtualpump_resultok); - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("cancelRealTempBasal: OK"); return result; } else { @@ -648,10 +694,10 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte result.enacted = true; result.isTempCancel = true; } - if (!pump.isExtendedInProgress) { + if (!DanaRPump.getInstance().isExtendedInProgress) { result.success = true; result.comment = MainApp.gs(R.string.virtualpump_resultok); - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("cancelExtendedBolus: OK"); return result; } else { @@ -664,6 +710,7 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte @Override public JSONObject getJSONStatus(Profile profile, String profileName) { + DanaRPump pump = DanaRPump.getInstance(); long now = System.currentTimeMillis(); if (pump.lastConnection + 5 * 60 * 1000L < System.currentTimeMillis()) { return null; @@ -678,8 +725,8 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte status.put("timestamp", DateUtil.toISOString(pump.lastConnection)); extended.put("Version", BuildConfig.VERSION_NAME + "-" + BuildConfig.BUILDVERSION); extended.put("PumpIOB", pump.iob); - if (pump.lastBolusTime.getTime() != 0) { - extended.put("LastBolus", pump.lastBolusTime.toLocaleString()); + if (pump.lastBolusTime != 0) { + extended.put("LastBolus", DateUtil.dateAndTimeFullString(pump.lastBolusTime)); extended.put("LastBolusAmount", pump.lastBolusAmount); } TemporaryBasal tb = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(now); @@ -696,7 +743,7 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte } extended.put("BaseBasalRate", getBaseBasalRate()); try { - extended.put("ActiveProfile", MainApp.getConfigBuilder().getProfileName()); + extended.put("ActiveProfile", ProfileFunctions.getInstance().getProfileName()); } catch (Exception e) { } @@ -713,7 +760,7 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte @Override public String deviceID() { - return pump.serialNumber; + return DanaRPump.getInstance().serialNumber; } @Override @@ -723,13 +770,14 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte @Override public String shortStatus(boolean veryShort) { + DanaRPump pump = DanaRPump.getInstance(); String ret = ""; if (pump.lastConnection != 0) { Long agoMsec = System.currentTimeMillis() - pump.lastConnection; int agoMin = (int) (agoMsec / 60d / 1000d); ret += "LastConn: " + agoMin + " minago\n"; } - if (pump.lastBolusTime.getTime() != 0) { + if (pump.lastBolusTime != 0) { ret += "LastBolus: " + DecimalFormatter.to2Decimal(pump.lastBolusAmount) + "U @" + android.text.format.DateFormat.format("HH:mm", pump.lastBolusTime) + "\n"; } TemporaryBasal activeTemp = TreatmentsPlugin.getPlugin().getRealTempBasalFromHistory(System.currentTimeMillis()); @@ -758,4 +806,5 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte public PumpEnactResult loadTDDs() { return loadHistory(RecordTypes.RECORD_TYPE_DAILY); } + } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/activities/BLEScanActivity.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/activities/BLEScanActivity.java index 3b6bcaf099..7594e917c5 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/activities/BLEScanActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/activities/BLEScanActivity.java @@ -31,9 +31,6 @@ import info.nightscout.androidaps.plugins.PumpDanaRS.events.EventDanaRSDeviceCha import info.nightscout.utils.SP; public class BLEScanActivity extends AppCompatActivity { - private static Logger log = LoggerFactory.getLogger(BLEScanActivity.class); - - private ListView listView = null; private ListAdapter mListAdapter = null; private ArrayList mDevices = new ArrayList<>(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/activities/PairingProgressDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/activities/PairingProgressDialog.java index 9f72e1d08f..08c0ce0372 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/activities/PairingProgressDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/activities/PairingProgressDialog.java @@ -9,7 +9,6 @@ import android.support.v4.app.DialogFragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.view.Window; import android.widget.Button; import android.widget.ProgressBar; import android.widget.TextView; @@ -52,8 +51,8 @@ public class PairingProgressDialog extends DialogFragment implements View.OnClic Bundle savedInstanceState) { View view = inflater.inflate(R.layout.danars_pairingprogressdialog, container, false); getDialog().setTitle(MainApp.gs(R.string.pairing)); - statusView = (TextView) view.findViewById(R.id.danars_paringprogress_status); - progressBar = (ProgressBar) view.findViewById(R.id.danars_paringprogress_progressbar); + statusView = (TextView) view.findViewById(R.id.danars_pairingprogress_status); + progressBar = (ProgressBar) view.findViewById(R.id.danars_pairingprogress_progressbar); button = (Button) view.findViewById(R.id.ok); progressBar.setMax(100); @@ -63,46 +62,37 @@ public class PairingProgressDialog extends DialogFragment implements View.OnClic button.setOnClickListener(this); setCancelable(false); - sHandler.post(new Runnable() { - @Override - public void run() { - for (int i = 0; i < 20; i++) { - if (pairingEnded) { - Activity activity = getActivity(); - if (activity != null) { - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - progressBar.setProgress(100); - statusView.setText(R.string.pairingok); - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - } - dismiss(); - } - }); - } else - dismiss(); - return; - } - progressBar.setProgress(i * 5); - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - } - } - Activity activity = getActivity(); - if (activity != null) { - activity.runOnUiThread(new Runnable() { - @Override - public void run() { + sHandler.post(() -> { + for (int i = 0; i < 20; i++) { + if (pairingEnded) { + Activity activity = getActivity(); + if (activity != null) { + activity.runOnUiThread(() -> { progressBar.setProgress(100); - statusView.setText(R.string.pairingtimedout); - button.setVisibility(View.VISIBLE); - } - }); + statusView.setText(R.string.pairingok); + try { + Thread.sleep(1000); + } catch (InterruptedException ignored) { + } + dismiss(); + }); + } else + dismiss(); + return; } + progressBar.setProgress(i * 5); + try { + Thread.sleep(1000); + } catch (InterruptedException ignored) { + } + } + Activity activity = getActivity(); + if (activity != null) { + activity.runOnUiThread(() -> { + progressBar.setProgress(100); + statusView.setText(R.string.pairingtimedout); + button.setVisibility(View.VISIBLE); + }); } }); return view; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRSMessageHashTable.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRSMessageHashTable.java index 5457bb4155..bda5d42207 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRSMessageHashTable.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRSMessageHashTable.java @@ -1,25 +1,17 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.util.HashMap; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; /** * Created by mike on 28.05.2016. */ public class DanaRSMessageHashTable { - private static Logger log = LoggerFactory.getLogger(DanaRSMessageHashTable.class); - public static HashMap messages = null; static { if (messages == null) { - boolean savedState = Config.logDanaMessageDetail; - Config.logDanaMessageDetail = false; - messages = new HashMap<>(); put(new DanaRS_Packet_Basal_Set_Cancel_Temporary_Basal()); put(new DanaRS_Packet_Basal_Get_Basal_Rate()); @@ -89,7 +81,6 @@ public class DanaRSMessageHashTable { put(new DanaRS_Packet_APS_History_Events()); put(new DanaRS_Packet_APS_Set_Event_History()); - Config.logDanaMessageDetail = savedState; } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet.java index 8ac5bfac13..d913f50b94 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet.java @@ -100,8 +100,8 @@ public class DanaRS_Packet { return ret; } - public static Date dateTimeSecFromBuff(byte[] buff, int offset) { - Date date = + public static synchronized long dateTimeSecFromBuff(byte[] buff, int offset) { + return new Date( 100 + intFromBuff(buff, offset, 1), intFromBuff(buff, offset + 1, 1) - 1, @@ -109,8 +109,7 @@ public class DanaRS_Packet { intFromBuff(buff, offset + 3, 1), intFromBuff(buff, offset + 4, 1), intFromBuff(buff, offset + 5, 1) - ); - return date; + ).getTime(); } protected static int intFromBuff(byte[] b, int srcStart, int srcLength) { @@ -143,14 +142,13 @@ public class DanaRS_Packet { return new String(strbuff, StandardCharsets.UTF_8); } - public static Date dateFromBuff(byte[] buff, int offset) { - Date date = + public static long dateFromBuff(byte[] buff, int offset) { + return new Date( 100 + byteArrayToInt(getBytes(buff, offset, 1)), byteArrayToInt(getBytes(buff, offset + 1, 1)) - 1, byteArrayToInt(getBytes(buff, offset + 2, 1)) - ); - return date; + ).getTime(); } @TargetApi(Build.VERSION_CODES.KITKAT) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_APS_Basal_Set_Temporary_Basal.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_APS_Basal_Set_Temporary_Basal.java index 5da3655ceb..c33cd7b405 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_APS_Basal_Set_Temporary_Basal.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_APS_Basal_Set_Temporary_Basal.java @@ -5,10 +5,10 @@ import com.cozmo.danar.util.BleCommandUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; public class DanaRS_Packet_APS_Basal_Set_Temporary_Basal extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_APS_Basal_Set_Temporary_Basal.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); int temporaryBasalRatio; int temporaryBasalDuration; @@ -25,6 +25,8 @@ public class DanaRS_Packet_APS_Basal_Set_Temporary_Basal extends DanaRS_Packet { public DanaRS_Packet_APS_Basal_Set_Temporary_Basal(int percent) { this(); setParams(percent); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message: percent: " + percent); } protected void setParams(int percent) { @@ -35,16 +37,16 @@ public class DanaRS_Packet_APS_Basal_Set_Temporary_Basal extends DanaRS_Packet { temporaryBasalRatio = percent; if (percent < 100) { temporaryBasalDuration = PARAM30MIN; - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("APS Temp basal start percent: " + percent + " duration 30 min"); } else { temporaryBasalDuration = PARAM15MIN; - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("APS Temp basal start percent: " + percent + " duration 15 min"); } } - public DanaRS_Packet_APS_Basal_Set_Temporary_Basal(int percent, boolean fifteenMinutes, boolean thirtyMinutes ) { + public DanaRS_Packet_APS_Basal_Set_Temporary_Basal(int percent, boolean fifteenMinutes, boolean thirtyMinutes) { this(); setParams(percent, fifteenMinutes, thirtyMinutes); } @@ -57,11 +59,11 @@ public class DanaRS_Packet_APS_Basal_Set_Temporary_Basal extends DanaRS_Packet { temporaryBasalRatio = percent; if (thirtyMinutes && percent <= 200) { // 30 min is allowed up to 200% temporaryBasalDuration = PARAM30MIN; - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("APS Temp basal start percent: " + percent + " duration 30 min"); } else { temporaryBasalDuration = PARAM15MIN; - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("APS Temp basal start percent: " + percent + " duration 15 min"); } } @@ -80,10 +82,11 @@ public class DanaRS_Packet_APS_Basal_Set_Temporary_Basal extends DanaRS_Packet { int result = byteArrayToInt(getBytes(data, DATA_START, 1)); if (result != 0) { failed = true; - log.error("Set APS temp basal start result: " + result + " FAILED!!!"); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("Set APS temp basal start result: " + result + " FAILED!!!"); } else { failed = false; - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Set APS temp basal start result: " + result); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_APS_History_Events.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_APS_History_Events.java index 181584df8e..98e08a7ee3 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_APS_History_Events.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_APS_History_Events.java @@ -16,13 +16,14 @@ import info.nightscout.androidaps.db.ExtendedBolus; import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.events.EventPumpStatusChanged; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.DetailedBolusInfoStorage; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.utils.DateUtil; public class DanaRS_Packet_APS_History_Events extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_APS_History_Events.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); private int year = 0; private int month = 0; @@ -32,7 +33,6 @@ public class DanaRS_Packet_APS_History_Events extends DanaRS_Packet { private int sec = 0; public static boolean done; - private static int totalCount; public static long lastEventTimeLoaded = 0; @@ -40,12 +40,17 @@ public class DanaRS_Packet_APS_History_Events extends DanaRS_Packet { super(); opCode = BleCommandUtil.DANAR_PACKET__OPCODE__APS_HISTORY_EVENTS; done = false; - totalCount = 0; } public DanaRS_Packet_APS_History_Events(long from) { this(); GregorianCalendar cal = new GregorianCalendar(); + + if (from > DateUtil.now()) { + log.debug("Asked to load from the future"); + from = 0; + } + if (from != 0) cal.setTimeInMillis(from); else @@ -56,7 +61,8 @@ public class DanaRS_Packet_APS_History_Events extends DanaRS_Packet { hour = cal.get(Calendar.HOUR_OF_DAY); min = cal.get(Calendar.MINUTE); sec = cal.get(Calendar.SECOND); - log.debug("Loading event history from: " + new Date(cal.getTimeInMillis()).toLocaleString()); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("Loading event history from: " + new Date(cal.getTimeInMillis()).toLocaleString()); } @Override @@ -78,127 +84,144 @@ public class DanaRS_Packet_APS_History_Events extends DanaRS_Packet { // Last record if (recordCode == (byte) 0xFF) { done = true; - log.debug("Last record received"); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("Last record received"); return; } - Date datetime = dateTimeSecFromBuff(data, 1); // 6 bytes + long datetime = dateTimeSecFromBuff(data, 1); // 6 bytes int param1 = ((intFromBuff(data, 7, 1) << 8) & 0xFF00) + (intFromBuff(data, 8, 1) & 0xFF); int param2 = ((intFromBuff(data, 9, 1) << 8) & 0xFF00) + (intFromBuff(data, 10, 1) & 0xFF); - TemporaryBasal temporaryBasal = new TemporaryBasal().date(datetime.getTime()).source(Source.PUMP).pumpId(datetime.getTime()); + TemporaryBasal temporaryBasal = new TemporaryBasal().date(datetime).source(Source.PUMP).pumpId(datetime); - ExtendedBolus extendedBolus = new ExtendedBolus(); - extendedBolus.date = datetime.getTime(); - extendedBolus.source = Source.PUMP; - extendedBolus.pumpId = datetime.getTime(); - - DetailedBolusInfo detailedBolusInfo = DetailedBolusInfoStorage.findDetailedBolusInfo(datetime.getTime()); - if (detailedBolusInfo == null) { - log.debug("Detailed bolus info not found for " + datetime.toLocaleString()); - detailedBolusInfo = new DetailedBolusInfo(); - } else { - log.debug("Detailed bolus info found: " + detailedBolusInfo); - } - detailedBolusInfo.date = datetime.getTime(); - detailedBolusInfo.source = Source.PUMP; - detailedBolusInfo.pumpId = datetime.getTime(); + ExtendedBolus extendedBolus = new ExtendedBolus().date(datetime).source(Source.PUMP).pumpId(datetime); String status; switch (recordCode) { case DanaRPump.TEMPSTART: - log.debug("EVENT TEMPSTART (" + recordCode + ") " + datetime.toLocaleString() + " Ratio: " + param1 + "% Duration: " + param2 + "min"); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("EVENT TEMPSTART (" + recordCode + ") " + DateUtil.dateAndTimeFullString(datetime) + " (" + datetime + ")" + " Ratio: " + param1 + "% Duration: " + param2 + "min"); temporaryBasal.percentRate = param1; temporaryBasal.durationInMinutes = param2; TreatmentsPlugin.getPlugin().addToHistoryTempBasal(temporaryBasal); status = "TEMPSTART " + DateUtil.timeString(datetime); break; case DanaRPump.TEMPSTOP: - log.debug("EVENT TEMPSTOP (" + recordCode + ") " + datetime.toLocaleString()); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("EVENT TEMPSTOP (" + recordCode + ") " + DateUtil.dateAndTimeFullString(datetime)); TreatmentsPlugin.getPlugin().addToHistoryTempBasal(temporaryBasal); status = "TEMPSTOP " + DateUtil.timeString(datetime); break; case DanaRPump.EXTENDEDSTART: - log.debug("EVENT EXTENDEDSTART (" + recordCode + ") " + datetime.toLocaleString() + " Amount: " + (param1 / 100d) + "U Duration: " + param2 + "min"); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("EVENT EXTENDEDSTART (" + recordCode + ") " + DateUtil.dateAndTimeFullString(datetime) + " (" + datetime + ")" + " Amount: " + (param1 / 100d) + "U Duration: " + param2 + "min"); extendedBolus.insulin = param1 / 100d; extendedBolus.durationInMinutes = param2; TreatmentsPlugin.getPlugin().addToHistoryExtendedBolus(extendedBolus); status = "EXTENDEDSTART " + DateUtil.timeString(datetime); break; case DanaRPump.EXTENDEDSTOP: - log.debug("EVENT EXTENDEDSTOP (" + recordCode + ") " + datetime.toLocaleString() + " Delivered: " + (param1 / 100d) + "U RealDuration: " + param2 + "min"); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("EVENT EXTENDEDSTOP (" + recordCode + ") " + DateUtil.dateAndTimeFullString(datetime) + " (" + datetime + ")" + " Delivered: " + (param1 / 100d) + "U RealDuration: " + param2 + "min"); TreatmentsPlugin.getPlugin().addToHistoryExtendedBolus(extendedBolus); status = "EXTENDEDSTOP " + DateUtil.timeString(datetime); break; case DanaRPump.BOLUS: + DetailedBolusInfo detailedBolusInfo = DetailedBolusInfoStorage.findDetailedBolusInfo(datetime); + if (detailedBolusInfo == null) { + detailedBolusInfo = new DetailedBolusInfo(); + } + detailedBolusInfo.date = datetime; + detailedBolusInfo.source = Source.PUMP; + detailedBolusInfo.pumpId = datetime; + detailedBolusInfo.insulin = param1 / 100d; - boolean newRecord = TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo); - log.debug((newRecord ? "**NEW** " : "") + "EVENT BOLUS (" + recordCode + ") " + datetime.toLocaleString() + " Bolus: " + (param1 / 100d) + "U Duration: " + param2 + "min"); - DetailedBolusInfoStorage.remove(detailedBolusInfo.date); + boolean newRecord = TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false); + if (L.isEnabled(L.PUMPCOMM)) + log.debug((newRecord ? "**NEW** " : "") + "EVENT BOLUS (" + recordCode + ") " + DateUtil.dateAndTimeFullString(datetime) + " (" + datetime + ")" + " Bolus: " + (param1 / 100d) + "U Duration: " + param2 + "min"); status = "BOLUS " + DateUtil.timeString(datetime); break; case DanaRPump.DUALBOLUS: + detailedBolusInfo = DetailedBolusInfoStorage.findDetailedBolusInfo(datetime); + if (detailedBolusInfo == null) { + detailedBolusInfo = new DetailedBolusInfo(); + } + detailedBolusInfo.date = datetime; + detailedBolusInfo.source = Source.PUMP; + detailedBolusInfo.pumpId = datetime; + detailedBolusInfo.insulin = param1 / 100d; - newRecord = TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo); - log.debug((newRecord ? "**NEW** " : "") + "EVENT DUALBOLUS (" + recordCode + ") " + datetime.toLocaleString() + " Bolus: " + (param1 / 100d) + "U Duration: " + param2 + "min"); - DetailedBolusInfoStorage.remove(detailedBolusInfo.date); + newRecord = TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false); + if (L.isEnabled(L.PUMPCOMM)) + log.debug((newRecord ? "**NEW** " : "") + "EVENT DUALBOLUS (" + recordCode + ") " + DateUtil.dateAndTimeFullString(datetime) + " (" + datetime + ")" + " Bolus: " + (param1 / 100d) + "U Duration: " + param2 + "min"); status = "DUALBOLUS " + DateUtil.timeString(datetime); break; case DanaRPump.DUALEXTENDEDSTART: - log.debug("EVENT DUALEXTENDEDSTART (" + recordCode + ") " + datetime.toLocaleString() + " Amount: " + (param1 / 100d) + "U Duration: " + param2 + "min"); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("EVENT DUALEXTENDEDSTART (" + recordCode + ") " + DateUtil.dateAndTimeFullString(datetime) + " (" + datetime + ")" + " Amount: " + (param1 / 100d) + "U Duration: " + param2 + "min"); extendedBolus.insulin = param1 / 100d; extendedBolus.durationInMinutes = param2; TreatmentsPlugin.getPlugin().addToHistoryExtendedBolus(extendedBolus); status = "DUALEXTENDEDSTART " + DateUtil.timeString(datetime); break; case DanaRPump.DUALEXTENDEDSTOP: - log.debug("EVENT DUALEXTENDEDSTOP (" + recordCode + ") " + datetime.toLocaleString() + " Delivered: " + (param1 / 100d) + "U RealDuration: " + param2 + "min"); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("EVENT DUALEXTENDEDSTOP (" + recordCode + ") " + DateUtil.dateAndTimeFullString(datetime) + " (" + datetime + ")" + " Delivered: " + (param1 / 100d) + "U RealDuration: " + param2 + "min"); TreatmentsPlugin.getPlugin().addToHistoryExtendedBolus(extendedBolus); status = "DUALEXTENDEDSTOP " + DateUtil.timeString(datetime); break; case DanaRPump.SUSPENDON: - log.debug("EVENT SUSPENDON (" + recordCode + ") " + datetime.toLocaleString()); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("EVENT SUSPENDON (" + recordCode + ") " + DateUtil.dateAndTimeFullString(datetime) + " (" + datetime + ")"); status = "SUSPENDON " + DateUtil.timeString(datetime); break; case DanaRPump.SUSPENDOFF: - log.debug("EVENT SUSPENDOFF (" + recordCode + ") " + datetime.toLocaleString()); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("EVENT SUSPENDOFF (" + recordCode + ") " + DateUtil.dateAndTimeFullString(datetime) + " (" + datetime + ")"); status = "SUSPENDOFF " + DateUtil.timeString(datetime); break; case DanaRPump.REFILL: - log.debug("EVENT REFILL (" + recordCode + ") " + datetime.toLocaleString() + " Amount: " + param1 / 100d + "U"); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("EVENT REFILL (" + recordCode + ") " + DateUtil.dateAndTimeFullString(datetime) + " (" + datetime + ")" + " Amount: " + param1 / 100d + "U"); status = "REFILL " + DateUtil.timeString(datetime); break; case DanaRPump.PRIME: - log.debug("EVENT PRIME (" + recordCode + ") " + datetime.toLocaleString() + " Amount: " + param1 / 100d + "U"); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("EVENT PRIME (" + recordCode + ") " + DateUtil.dateAndTimeFullString(datetime) + " (" + datetime + ")" + " Amount: " + param1 / 100d + "U"); status = "PRIME " + DateUtil.timeString(datetime); break; case DanaRPump.PROFILECHANGE: - log.debug("EVENT PROFILECHANGE (" + recordCode + ") " + datetime.toLocaleString() + " No: " + param1 + " CurrentRate: " + (param2 / 100d) + "U/h"); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("EVENT PROFILECHANGE (" + recordCode + ") " + DateUtil.dateAndTimeFullString(datetime) + " (" + datetime + ")" + " No: " + param1 + " CurrentRate: " + (param2 / 100d) + "U/h"); status = "PROFILECHANGE " + DateUtil.timeString(datetime); break; case DanaRPump.CARBS: DetailedBolusInfo emptyCarbsInfo = new DetailedBolusInfo(); emptyCarbsInfo.carbs = param1; - emptyCarbsInfo.date = datetime.getTime(); + emptyCarbsInfo.date = datetime; emptyCarbsInfo.source = Source.PUMP; - emptyCarbsInfo.pumpId = datetime.getTime(); - newRecord = TreatmentsPlugin.getPlugin().addToHistoryTreatment(emptyCarbsInfo); - log.debug((newRecord ? "**NEW** " : "") + "EVENT CARBS (" + recordCode + ") " + datetime.toLocaleString() + " Carbs: " + param1 + "g"); + emptyCarbsInfo.pumpId = datetime; + newRecord = TreatmentsPlugin.getPlugin().addToHistoryTreatment(emptyCarbsInfo, false); + if (L.isEnabled(L.PUMPCOMM)) + log.debug((newRecord ? "**NEW** " : "") + "EVENT CARBS (" + recordCode + ") " + DateUtil.dateAndTimeFullString(datetime) + " (" + datetime + ")" + " Carbs: " + param1 + "g"); status = "CARBS " + DateUtil.timeString(datetime); break; case DanaRPump.PRIMECANNULA: - log.debug("EVENT PRIMECANNULA(" + recordCode + ") " + datetime.toLocaleString() + " Amount: " + param1 / 100d + "U"); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("EVENT PRIMECANNULA(" + recordCode + ") " + DateUtil.dateAndTimeFullString(datetime) + " (" + datetime + ")" + " Amount: " + param1 / 100d + "U"); status = "PRIMECANNULA " + DateUtil.timeString(datetime); break; default: - log.debug("Event: " + recordCode + " " + datetime.toLocaleString() + " Param1: " + param1 + " Param2: " + param2); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("Event: " + recordCode + " " + DateUtil.dateAndTimeFullString(datetime) + " (" + datetime + ")" + " Param1: " + param1 + " Param2: " + param2); status = "UNKNOWN " + DateUtil.timeString(datetime); break; } - if (datetime.getTime() > lastEventTimeLoaded) - lastEventTimeLoaded = datetime.getTime(); + if (datetime > lastEventTimeLoaded) + lastEventTimeLoaded = datetime; MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.processinghistory) + ": " + status)); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_APS_Set_Event_History.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_APS_Set_Event_History.java index 84ead83665..f31bdf66e2 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_APS_Set_Event_History.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_APS_Set_Event_History.java @@ -8,16 +8,17 @@ import org.slf4j.LoggerFactory; import java.util.Calendar; import java.util.GregorianCalendar; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; import info.nightscout.utils.DateUtil; public class DanaRS_Packet_APS_Set_Event_History extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_APS_Set_Event_History.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); private int type; private long time; - public int param1; - public int param2; + private int param1; + private int param2; public DanaRS_Packet_APS_Set_Event_History() { super(); @@ -31,7 +32,9 @@ public class DanaRS_Packet_APS_Set_Event_History extends DanaRS_Packet { this.time = time; this.param1 = param1; this.param2 = param2; - if (Config.logDanaMessageDetail) + if ((type == DanaRPump.CARBS || type == DanaRPump.BOLUS) && param1 <= 0) + this.param1 = 0; + if (L.isEnabled(L.PUMPCOMM)) log.debug("Set history entry: " + DateUtil.dateAndTimeString(time) + " type: " + type + " param1: " + param1 + " param2: " + param2); } @@ -66,9 +69,10 @@ public class DanaRS_Packet_APS_Set_Event_History extends DanaRS_Packet { int result = intFromBuff(data, 0, 1); if (result != 0) { failed = true; - log.error("Set history entry result: " + result + " FAILED!!!"); + if (L.isEnabled(L.PUMPCOMM)) + log.error("Set history entry result: " + result + " FAILED!!!"); } else { - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Set history entry result: " + result); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Get_Basal_Rate.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Get_Basal_Rate.java index f3fef0d49d..3cb5523dfc 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Get_Basal_Rate.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Get_Basal_Rate.java @@ -1,30 +1,30 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.plugins.Overview.notifications.Notification; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; +import info.nightscout.androidaps.plugins.Overview.notifications.Notification; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; -import com.cozmo.danar.util.BleCommandUtil; - public class DanaRS_Packet_Basal_Get_Basal_Rate extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Basal_Set_Cancel_Temporary_Basal.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); - public DanaRS_Packet_Basal_Get_Basal_Rate() { - super(); - opCode = BleCommandUtil.DANAR_PACKET__OPCODE_BASAL__GET_BASAL_RATE; - if (Config.logDanaMessageDetail) { - log.debug("Requesting basal rates"); - } - } + public DanaRS_Packet_Basal_Get_Basal_Rate() { + super(); + opCode = BleCommandUtil.DANAR_PACKET__OPCODE_BASAL__GET_BASAL_RATE; + if (L.isEnabled(L.PUMPCOMM)) { + log.debug("Requesting basal rates"); + } + } @Override public void handleMessage(byte[] data) { @@ -45,7 +45,7 @@ public class DanaRS_Packet_Basal_Get_Basal_Rate extends DanaRS_Packet { dataSize = 2; pump.pumpProfiles[pump.activeProfile][i] = byteArrayToInt(getBytes(data, dataIndex, dataSize)) / 100d; } - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Max basal: " + pump.maxBasal + " U"); log.debug("Basal step: " + pump.basalStep + " U"); for (int index = 0; index < 24; index++) @@ -53,6 +53,7 @@ public class DanaRS_Packet_Basal_Get_Basal_Rate extends DanaRS_Packet { } if (pump.basalStep != 0.01d) { + failed = true; Notification notification = new Notification(Notification.WRONGBASALSTEP, MainApp.gs(R.string.danar_setbasalstep001), Notification.URGENT); MainApp.bus().post(new EventNewNotification(notification)); } else { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Get_Profile_Basal_Rate.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Get_Profile_Basal_Rate.java index 8eadb8298d..60b9f6da51 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Get_Profile_Basal_Rate.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Get_Profile_Basal_Rate.java @@ -1,17 +1,20 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; -import com.cozmo.danar.util.BleCommandUtil; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; public class DanaRS_Packet_Basal_Get_Profile_Basal_Rate extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Basal_Get_Profile_Basal_Rate.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); private int profileNumber; + DanaRPump pump = DanaRPump.getInstance(); + public DanaRS_Packet_Basal_Get_Profile_Basal_Rate() { super(); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_BASAL__GET_PROFILE_BASAL_RATE; @@ -21,7 +24,7 @@ public class DanaRS_Packet_Basal_Get_Profile_Basal_Rate extends DanaRS_Packet { public DanaRS_Packet_Basal_Get_Profile_Basal_Rate(int profileNumber) { this(); this.profileNumber = profileNumber; - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Requesting basal rates for profile " + profileNumber); } } @@ -35,7 +38,6 @@ public class DanaRS_Packet_Basal_Get_Profile_Basal_Rate extends DanaRS_Packet { @Override public void handleMessage(byte[] data) { - DanaRPump pump = DanaRPump.getInstance(); int dataIndex = DATA_START; int dataSize = 2; @@ -47,7 +49,7 @@ public class DanaRS_Packet_Basal_Get_Profile_Basal_Rate extends DanaRS_Packet { dataIndex += dataSize; dataSize = 2; } - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { for (int index = 0; index < 24; index++) log.debug("Basal " + String.format("%02d", index) + "h: " + pump.pumpProfiles[profileNumber][index]); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Get_Profile_Number.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Get_Profile_Number.java index 39e230a29e..1beadfd705 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Get_Profile_Number.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Get_Profile_Number.java @@ -1,19 +1,20 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; -import com.cozmo.danar.util.BleCommandUtil; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; public class DanaRS_Packet_Basal_Get_Profile_Number extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Basal_Get_Profile_Number.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public DanaRS_Packet_Basal_Get_Profile_Number() { super(); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_BASAL__GET_PROFILE_NUMBER; - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Requesting active profile"); } } @@ -25,7 +26,7 @@ public class DanaRS_Packet_Basal_Get_Profile_Number extends DanaRS_Packet { int dataIndex = DATA_START; int dataSize = 1; pump.activeProfile = byteArrayToInt(getBytes(data, dataIndex, dataSize)); - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Active profile: " + pump.activeProfile); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Get_Temporary_Basal_State.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Get_Temporary_Basal_State.java index dbf917874d..748d88f242 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Get_Temporary_Basal_State.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Get_Temporary_Basal_State.java @@ -2,22 +2,22 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; import android.support.annotation.NonNull; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Date; - -import info.nightscout.androidaps.Config; -import com.cozmo.danar.util.BleCommandUtil; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; +import info.nightscout.utils.DateUtil; public class DanaRS_Packet_Basal_Get_Temporary_Basal_State extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Basal_Get_Temporary_Basal_State.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public DanaRS_Packet_Basal_Get_Temporary_Basal_State() { super(); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_BASAL__TEMPORARY_BASAL_STATE; - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Requesting temporary basal status"); } } @@ -30,6 +30,9 @@ public class DanaRS_Packet_Basal_Get_Temporary_Basal_State extends DanaRS_Packet int dataSize = 1; int error = byteArrayToInt(getBytes(data, dataIndex, dataSize)); + if (error == 1) + failed = true; + dataIndex += dataSize; dataSize = 1; pump.isTempBasalInProgress = byteArrayToInt(getBytes(data, dataIndex, dataSize)) == 0x01; @@ -51,16 +54,16 @@ public class DanaRS_Packet_Basal_Get_Temporary_Basal_State extends DanaRS_Packet dataSize = 2; int runningMin = byteArrayToInt(getBytes(data, dataIndex, dataSize)); int tempBasalRemainingMin = (pump.tempBasalTotalSec - runningMin * 60) / 60; - Date tempBasalStart = pump.isTempBasalInProgress ? getDateFromTempBasalSecAgo(runningMin * 60) : new Date(0); + long tempBasalStart = pump.isTempBasalInProgress ? getDateFromTempBasalSecAgo(runningMin * 60) : 0; - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Error code: " + error); log.debug("Is temp basal running: " + pump.isTempBasalInProgress); log.debug("Is APS temp basal running: " + isAPSTempBasalInProgress); log.debug("Current temp basal percent: " + pump.tempBasalPercent); log.debug("Current temp basal remaining min: " + tempBasalRemainingMin); log.debug("Current temp basal total sec: " + pump.tempBasalTotalSec); - log.debug("Current temp basal start: " + tempBasalStart); + log.debug("Current temp basal start: " + DateUtil.dateAndTimeFullString(tempBasalStart)); } } @@ -70,8 +73,8 @@ public class DanaRS_Packet_Basal_Get_Temporary_Basal_State extends DanaRS_Packet } @NonNull - private Date getDateFromTempBasalSecAgo(int tempBasalAgoSecs) { - return new Date((long) (Math.ceil(System.currentTimeMillis() / 1000d) - tempBasalAgoSecs) * 1000); + private long getDateFromTempBasalSecAgo(int tempBasalAgoSecs) { + return (long) (Math.ceil(System.currentTimeMillis() / 1000d) - tempBasalAgoSecs) * 1000; } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Set_Basal_Rate.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Set_Basal_Rate.java index a64da24bf3..188c1df093 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Set_Basal_Rate.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Set_Basal_Rate.java @@ -3,12 +3,12 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; import com.cozmo.danar.util.BleCommandUtil; public class DanaRS_Packet_Basal_Set_Basal_Rate extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Basal_Set_Basal_Rate.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); private double[] profileBasalRate; @@ -20,7 +20,7 @@ public class DanaRS_Packet_Basal_Set_Basal_Rate extends DanaRS_Packet { public DanaRS_Packet_Basal_Set_Basal_Rate(double[] profileBasalRate) { this(); this.profileBasalRate = profileBasalRate; - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Setting new basal rates"); } } @@ -39,7 +39,9 @@ public class DanaRS_Packet_Basal_Set_Basal_Rate extends DanaRS_Packet { @Override public void handleMessage(byte[] data) { int result = intFromBuff(data, 0, 1); - if (Config.logDanaMessageDetail) { + if(result != 0) + failed = true; + if (L.isEnabled(L.PUMPCOMM)) { if (result == 0) log.debug("Result OK"); else diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Set_Cancel_Temporary_Basal.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Set_Cancel_Temporary_Basal.java index 538750a45b..f0f2691315 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Set_Cancel_Temporary_Basal.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Set_Cancel_Temporary_Basal.java @@ -1,19 +1,19 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; - -import com.cozmo.danar.util.BleCommandUtil; +import info.nightscout.androidaps.logging.L; public class DanaRS_Packet_Basal_Set_Cancel_Temporary_Basal extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Basal_Set_Cancel_Temporary_Basal.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public DanaRS_Packet_Basal_Set_Cancel_Temporary_Basal() { super(); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_BASAL__CANCEL_TEMPORARY_BASAL; - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Canceling temp basal"); } } @@ -21,11 +21,13 @@ public class DanaRS_Packet_Basal_Set_Cancel_Temporary_Basal extends DanaRS_Packe @Override public void handleMessage(byte[] data) { int result = intFromBuff(data, 0, 1); - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { if (result == 0) log.debug("Result OK"); - else + else { log.error("Result Error: " + result); + failed = true; + } } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Set_Profile_Basal_Rate.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Set_Profile_Basal_Rate.java index 66d0e7b4bb..a42176cc59 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Set_Profile_Basal_Rate.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Set_Profile_Basal_Rate.java @@ -1,13 +1,14 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; -import com.cozmo.danar.util.BleCommandUtil; +import info.nightscout.androidaps.logging.L; public class DanaRS_Packet_Basal_Set_Profile_Basal_Rate extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Basal_Set_Profile_Basal_Rate.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); private int profileNumber; // 0 - 4 private double[] profileBasalRate; @@ -21,7 +22,7 @@ public class DanaRS_Packet_Basal_Set_Profile_Basal_Rate extends DanaRS_Packet { this(); this.profileNumber = profileNumber; this.profileBasalRate = profileBasalRate; - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Setting new basal rates for profile " + profileNumber); } } @@ -41,7 +42,9 @@ public class DanaRS_Packet_Basal_Set_Profile_Basal_Rate extends DanaRS_Packet { @Override public void handleMessage(byte[] data) { int result = intFromBuff(data, 0, 1); - if (Config.logDanaMessageDetail) { + if (result != 0) + failed = true; + if (L.isEnabled(L.PUMPCOMM)) { if (result == 0) log.debug("Result OK"); else diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Set_Profile_Number.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Set_Profile_Number.java index 69f7eae8dd..4f39fcfd2f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Set_Profile_Number.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Set_Profile_Number.java @@ -1,48 +1,51 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; - -import com.cozmo.danar.util.BleCommandUtil; +import info.nightscout.androidaps.logging.L; public class DanaRS_Packet_Basal_Set_Profile_Number extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Basal_Set_Profile_Number.class); - private int profileNumber; + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); + private int profileNumber; - public DanaRS_Packet_Basal_Set_Profile_Number() { + public DanaRS_Packet_Basal_Set_Profile_Number() { super(); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_BASAL__SET_PROFILE_NUMBER; } - public DanaRS_Packet_Basal_Set_Profile_Number(int profileNumber) { - this(); - this.profileNumber = profileNumber; - if (Config.logDanaMessageDetail) { - log.debug("Setting profile number " + profileNumber); - } - } - @Override - public byte[] getRequestParams() { - byte[] request = new byte[1]; - request[0] = (byte) (profileNumber & 0xff); - return request; - } + public DanaRS_Packet_Basal_Set_Profile_Number(int profileNumber) { + this(); + this.profileNumber = profileNumber; + if (L.isEnabled(L.PUMPCOMM)) { + log.debug("Setting profile number " + profileNumber); + } + } @Override - public void handleMessage(byte[] data) { - int result = intFromBuff(data, 0, 1); - if (Config.logDanaMessageDetail) { - if (result == 0) - log.debug("Result OK"); - else - log.error("Result Error: " + result); - } - } + public byte[] getRequestParams() { + byte[] request = new byte[1]; + request[0] = (byte) (profileNumber & 0xff); + return request; + } - @Override - public String getFriendlyName() { - return "BASAL__SET_PROFILE_NUMBER"; - } + @Override + public void handleMessage(byte[] data) { + int result = intFromBuff(data, 0, 1); + if (result != 0) + failed = true; + if (L.isEnabled(L.PUMPCOMM)) { + if (result == 0) + log.debug("Result OK"); + else + log.error("Result Error: " + result); + } + } + + @Override + public String getFriendlyName() { + return "BASAL__SET_PROFILE_NUMBER"; + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Set_Suspend_Off.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Set_Suspend_Off.java index 4c78038162..65ef6ae1b1 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Set_Suspend_Off.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Set_Suspend_Off.java @@ -1,18 +1,19 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; -import com.cozmo.danar.util.BleCommandUtil; +import info.nightscout.androidaps.logging.L; public class DanaRS_Packet_Basal_Set_Suspend_Off extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Basal_Set_Suspend_Off.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public DanaRS_Packet_Basal_Set_Suspend_Off() { super(); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_BASAL__SET_SUSPEND_OFF; - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Turning off suspend"); } } @@ -20,11 +21,13 @@ public class DanaRS_Packet_Basal_Set_Suspend_Off extends DanaRS_Packet { @Override public void handleMessage(byte[] data) { int result = intFromBuff(data, 0, 1); - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { if (result == 0) log.debug("Result OK"); - else + else { log.error("Result Error: " + result); + failed = true; + } } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Set_Suspend_On.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Set_Suspend_On.java index 75a2a5fada..bde3b622db 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Set_Suspend_On.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Set_Suspend_On.java @@ -1,18 +1,19 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; -import com.cozmo.danar.util.BleCommandUtil; +import info.nightscout.androidaps.logging.L; public class DanaRS_Packet_Basal_Set_Suspend_On extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Basal_Set_Suspend_On.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public DanaRS_Packet_Basal_Set_Suspend_On() { super(); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_BASAL__SET_SUSPEND_ON; - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Turning on suspend"); } } @@ -20,11 +21,13 @@ public class DanaRS_Packet_Basal_Set_Suspend_On extends DanaRS_Packet { @Override public void handleMessage(byte[] data) { int result = intFromBuff(data, 0, 1); - if (Config.logDanaMessageDetail) { + if(result != 0) + failed = true; + if (L.isEnabled(L.PUMPCOMM)) { if (result == 0) log.debug("Result OK"); else - log.error("Result Error: " + result); + failed = true; } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Set_Temporary_Basal.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Set_Temporary_Basal.java index d2f68ff864..1f6106ab83 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Set_Temporary_Basal.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Basal_Set_Temporary_Basal.java @@ -1,13 +1,14 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; -import com.cozmo.danar.util.BleCommandUtil; +import info.nightscout.androidaps.logging.L; public class DanaRS_Packet_Basal_Set_Temporary_Basal extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Basal_Set_Temporary_Basal.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); private int temporaryBasalRatio; private int temporaryBasalDuration; @@ -21,7 +22,7 @@ public class DanaRS_Packet_Basal_Set_Temporary_Basal extends DanaRS_Packet { this(); this.temporaryBasalRatio = temporaryBasalRatio; this.temporaryBasalDuration = temporaryBasalDuration; - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Setting temporary basal of " + temporaryBasalRatio + "% for " + temporaryBasalDuration + " hours"); } } @@ -37,7 +38,9 @@ public class DanaRS_Packet_Basal_Set_Temporary_Basal extends DanaRS_Packet { @Override public void handleMessage(byte[] data) { int result = intFromBuff(data, 0, 1); - if (Config.logDanaMessageDetail) { + if (result != 0) + failed = true; + if (L.isEnabled(L.PUMPCOMM)) { if (result == 0) log.debug("Result OK"); else diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_Bolus_Option.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_Bolus_Option.java index 69c2f75ba6..0e5a3d79c4 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_Bolus_Option.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_Bolus_Option.java @@ -1,24 +1,26 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; -import com.cozmo.danar.util.BleCommandUtil; - import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.plugins.Overview.notifications.Notification; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; +import info.nightscout.androidaps.plugins.Overview.notifications.Notification; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; public class DanaRS_Packet_Bolus_Get_Bolus_Option extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Bolus_Get_Bolus_Option.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public DanaRS_Packet_Bolus_Get_Bolus_Option() { super(); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_BOLUS__GET_BOLUS_OPTION; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override @@ -104,11 +106,12 @@ public class DanaRS_Packet_Bolus_Get_Bolus_Option extends DanaRS_Packet { if (!pump.isExtendedBolusEnabled) { Notification notification = new Notification(Notification.EXTENDED_BOLUS_DISABLED, MainApp.gs(R.string.danar_enableextendedbolus), Notification.URGENT); MainApp.bus().post(new EventNewNotification(notification)); + failed = true; } else { MainApp.bus().post(new EventDismissNotification(Notification.EXTENDED_BOLUS_DISABLED)); } - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Extended bolus enabled: " + pump.isExtendedBolusEnabled); log.debug("Missed bolus config: " + pump.missedBolusConfig); log.debug("missedBolus01StartHour: " + missedBolus01StartHour); @@ -134,4 +137,6 @@ public class DanaRS_Packet_Bolus_Get_Bolus_Option extends DanaRS_Packet { public String getFriendlyName() { return "BOLUS__GET_BOLUS_OPTION"; } + + } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_CIR_CF_Array.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_CIR_CF_Array.java index b8a86cc078..9b5636eaaf 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_CIR_CF_Array.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_CIR_CF_Array.java @@ -1,21 +1,22 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; - -import com.cozmo.danar.util.BleCommandUtil; - +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; public class DanaRS_Packet_Bolus_Get_CIR_CF_Array extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Bolus_Get_CIR_CF_Array.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public DanaRS_Packet_Bolus_Get_CIR_CF_Array() { super(); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_BOLUS__GET_CIR_CF_ARRAY; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override @@ -117,8 +118,9 @@ public class DanaRS_Packet_Bolus_Get_CIR_CF_Array extends DanaRS_Packet { dataSize = 2; pump.nightCF = byteArrayToInt(getBytes(data, dataIndex, dataSize)) / 100d; } - - if (Config.logDanaMessageDetail) { + if (pump.units < 0 || pump.units > 1) + failed = true; + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Language: " + language); log.debug("Pump units: " + (pump.units == DanaRPump.UNITS_MGDL ? "MGDL" : "MMOL")); log.debug("Current pump morning CIR: " + pump.morningCIR); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_Calculation_Information.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_Calculation_Information.java index f5acedf3ba..194edd5d55 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_Calculation_Information.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_Calculation_Information.java @@ -1,20 +1,21 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; - -import com.cozmo.danar.util.BleCommandUtil; - +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; public class DanaRS_Packet_Bolus_Get_Calculation_Information extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Bolus_Get_Calculation_Information.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public DanaRS_Packet_Bolus_Get_Calculation_Information() { super(); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_BOLUS__GET_CALCULATION_INFORMATION; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override @@ -58,7 +59,9 @@ public class DanaRS_Packet_Bolus_Get_Calculation_Information extends DanaRS_Pack pump.currentTarget = pump.currentTarget / 100d; currentBG = currentBG / 100d; } - if (Config.logDanaMessageDetail) { + if (error != 0) + failed = true; + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Result: " + error); log.debug("Pump units: " + (pump.units == DanaRPump.UNITS_MGDL ? "MGDL" : "MMOL")); log.debug("Current BG: " + currentBG); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_Carbohydrate_Calculation_Information.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_Carbohydrate_Calculation_Information.java index c581320c54..476ae7167f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_Carbohydrate_Calculation_Information.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_Carbohydrate_Calculation_Information.java @@ -1,20 +1,21 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; - -import com.cozmo.danar.util.BleCommandUtil; - +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; public class DanaRS_Packet_Bolus_Get_Carbohydrate_Calculation_Information extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Bolus_Get_Carbohydrate_Calculation_Information.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public DanaRS_Packet_Bolus_Get_Carbohydrate_Calculation_Information() { super(); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_BOLUS__GET_CARBOHYDRATE_CALCULATION_INFORMATION; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override @@ -32,8 +33,9 @@ public class DanaRS_Packet_Bolus_Get_Carbohydrate_Calculation_Information extend dataIndex += dataSize; dataSize = 2; pump.currentCIR = byteArrayToInt(getBytes(data, dataIndex, dataSize)); - - if (Config.logDanaMessageDetail) { + if (error != 0) + failed = true; + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Result: " + error); log.debug("Carbs: " + carbs); log.debug("Current CIR: " + pump.currentCIR); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_Dual_Bolus.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_Dual_Bolus.java index bd7a0b9ee6..7d561bd679 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_Dual_Bolus.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_Dual_Bolus.java @@ -1,18 +1,21 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; -import com.cozmo.danar.util.BleCommandUtil; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; public class DanaRS_Packet_Bolus_Get_Dual_Bolus extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Bolus_Get_Dual_Bolus.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public DanaRS_Packet_Bolus_Get_Dual_Bolus() { super(); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_BOLUS__GET_DUAL_BOLUS; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override @@ -38,8 +41,9 @@ public class DanaRS_Packet_Bolus_Get_Dual_Bolus extends DanaRS_Packet { dataIndex += dataSize; dataSize = 1; double bolusIncrement = byteArrayToInt(getBytes(data, dataIndex, dataSize)) / 100d; - - if (Config.logDanaMessageDetail) { + if (error != 0) + failed = true; + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Result: " + error); log.debug("Bolus step: " + pump.bolusStep + " U"); log.debug("Extended bolus running: " + pump.extendedBolusAbsoluteRate + " U/h"); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_Extended_Bolus.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_Extended_Bolus.java index 682d9b14bb..785d8d3fbe 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_Extended_Bolus.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_Extended_Bolus.java @@ -1,20 +1,21 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; - -import com.cozmo.danar.util.BleCommandUtil; - +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; public class DanaRS_Packet_Bolus_Get_Extended_Bolus extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Bolus_Get_Extended_Bolus.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public DanaRS_Packet_Bolus_Get_Extended_Bolus() { super(); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_BOLUS__GET_EXTENDED_BOLUS; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override @@ -36,8 +37,9 @@ public class DanaRS_Packet_Bolus_Get_Extended_Bolus extends DanaRS_Packet { dataIndex += dataSize; dataSize = 1; pump.bolusStep = byteArrayToInt(getBytes(data, dataIndex, dataSize)) / 100d; - - if (Config.logDanaMessageDetail) { + if (error != 0) + failed = true; + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Result: " + error); log.debug("Extended bolus running: " + pump.extendedBolusAbsoluteRate + " U/h"); log.debug("Max bolus: " + pump.maxBolus + " U"); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_Extended_Bolus_State.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_Extended_Bolus_State.java index b22a9dfb47..a07652218f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_Extended_Bolus_State.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_Extended_Bolus_State.java @@ -1,20 +1,21 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; - -import com.cozmo.danar.util.BleCommandUtil; - +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; public class DanaRS_Packet_Bolus_Get_Extended_Bolus_State extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Bolus_Get_Extended_Bolus_State.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public DanaRS_Packet_Bolus_Get_Extended_Bolus_State() { super(); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_BOLUS__GET_EXTENDED_BOLUS_STATE; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override @@ -44,8 +45,9 @@ public class DanaRS_Packet_Bolus_Get_Extended_Bolus_State extends DanaRS_Packet dataIndex += dataSize; dataSize = 2; pump.extendedBolusDeliveredSoFar = byteArrayToInt(getBytes(data, dataIndex, dataSize)) / 100d; - - if (Config.logDanaMessageDetail) { + if (error != 0) + failed = true; + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Result: " + error); log.debug("Is extended bolus running: " + pump.isExtendedInProgress); log.debug("Extended bolus running: " + pump.extendedBolusAbsoluteRate + " U/h"); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_Extended_Menu_Option_State.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_Extended_Menu_Option_State.java index 5a7ca55e30..fda8778d08 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_Extended_Menu_Option_State.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_Extended_Menu_Option_State.java @@ -1,20 +1,21 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; - -import com.cozmo.danar.util.BleCommandUtil; - +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; public class DanaRS_Packet_Bolus_Get_Extended_Menu_Option_State extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Bolus_Get_Extended_Menu_Option_State.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public DanaRS_Packet_Bolus_Get_Extended_Menu_Option_State() { super(); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_BOLUS__GET_EXTENDED_MENU_OPTION_STATE; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override @@ -29,7 +30,7 @@ public class DanaRS_Packet_Bolus_Get_Extended_Menu_Option_State extends DanaRS_P dataSize = 1; pump.isExtendedInProgress = byteArrayToInt(getBytes(data, dataIndex, dataSize)) == 0x01; - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("extendedMenuOption: " + extendedMenuOption); log.debug("Is extended bolus running: " + pump.isExtendedInProgress); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_Initial_Bolus.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_Initial_Bolus.java index 58fa4674ad..15ad57d83a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_Initial_Bolus.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_Initial_Bolus.java @@ -1,37 +1,49 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; -import com.cozmo.danar.util.BleCommandUtil; +import info.nightscout.androidaps.logging.L; public class DanaRS_Packet_Bolus_Get_Initial_Bolus extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Bolus_Get_Initial_Bolus.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); + private double initialBolusValue01; + private double initialBolusValue02; + private double initialBolusValue03; + double initialBolusValue04; public DanaRS_Packet_Bolus_Get_Initial_Bolus() { super(); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_BOLUS__GET_BOLUS_RATE; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override public void handleMessage(byte[] data) { int dataIndex = DATA_START; int dataSize = 2; - double initialBolusValue01 = byteArrayToInt(getBytes(data, dataIndex, dataSize)) / 100d; + initialBolusValue01 = byteArrayToInt(getBytes(data, dataIndex, dataSize)) / 100d; dataIndex += dataSize; dataSize = 2; - double initialBolusValue02 = byteArrayToInt(getBytes(data, dataIndex, dataSize)) / 100d; + initialBolusValue02 = byteArrayToInt(getBytes(data, dataIndex, dataSize)) / 100d; dataIndex += dataSize; dataSize = 2; - double initialBolusValue03 = byteArrayToInt(getBytes(data, dataIndex, dataSize)) / 100d; + initialBolusValue03 = byteArrayToInt(getBytes(data, dataIndex, dataSize)) / 100d; dataIndex += dataSize; dataSize = 2; - double initialBolusValue04 = byteArrayToInt(getBytes(data, dataIndex, dataSize)) / 100d; - if (Config.logDanaMessageDetail) { + initialBolusValue04 = byteArrayToInt(getBytes(data, dataIndex, dataSize)) / 100d; + if (initialBolusValue01 == 0d && initialBolusValue02 == 0d && initialBolusValue03 == 0d && initialBolusValue04 == 0d) + failed = true; + else + failed = false; + + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Initial bolus amount 01: " + initialBolusValue01); log.debug("Initial bolus amount 02: " + initialBolusValue02); log.debug("Initial bolus amount 03: " + initialBolusValue03); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_Step_Bolus_Information.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_Step_Bolus_Information.java index 6166f7b0fb..a9968eb7eb 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_Step_Bolus_Information.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Get_Step_Bolus_Information.java @@ -1,20 +1,24 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Date; -import info.nightscout.androidaps.Config; -import com.cozmo.danar.util.BleCommandUtil; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; +import info.nightscout.utils.DateUtil; public class DanaRS_Packet_Bolus_Get_Step_Bolus_Information extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Bolus_Get_Step_Bolus_Information.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public DanaRS_Packet_Bolus_Get_Step_Bolus_Information() { super(); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_BOLUS__GET_STEP_BOLUS_INFORMATION; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override @@ -33,14 +37,16 @@ public class DanaRS_Packet_Bolus_Get_Step_Bolus_Information extends DanaRS_Packe dataSize = 2; pump.initialBolusAmount = byteArrayToInt(getBytes(data, dataIndex, dataSize)) / 100d; - pump.lastBolusTime = new Date(); // it doesn't provide day only hour+min, workaround: expecting today + Date lbt = new Date(); // it doesn't provide day only hour+min, workaround: expecting today dataIndex += dataSize; dataSize = 1; - pump.lastBolusTime.setHours(byteArrayToInt(getBytes(data, dataIndex, dataSize))); + lbt.setHours(byteArrayToInt(getBytes(data, dataIndex, dataSize))); dataIndex += dataSize; dataSize = 1; - pump.lastBolusTime.setMinutes(byteArrayToInt(getBytes(data, dataIndex, dataSize))); + lbt.setMinutes(byteArrayToInt(getBytes(data, dataIndex, dataSize))); + + pump.lastBolusTime = lbt.getTime(); dataIndex += dataSize; dataSize = 2; @@ -53,12 +59,13 @@ public class DanaRS_Packet_Bolus_Get_Step_Bolus_Information extends DanaRS_Packe dataIndex += dataSize; dataSize = 1; pump.bolusStep = byteArrayToInt(getBytes(data, dataIndex, dataSize)) / 100d; - - if (Config.logDanaMessageDetail) { + if (error != 0) + failed = true; + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Result: " + error); log.debug("BolusType: " + bolusType); log.debug("Initial bolus amount: " + pump.initialBolusAmount + " U"); - log.debug("Last bolus time: " + pump.lastBolusTime.toLocaleString()); + log.debug("Last bolus time: " + DateUtil.dateAndTimeFullString(pump.lastBolusTime)); log.debug("Last bolus amount: " + pump.lastBolusAmount); log.debug("Max bolus: " + pump.maxBolus + " U"); log.debug("Bolus step: " + pump.bolusStep + " U"); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Set_Bolus_Option.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Set_Bolus_Option.java index 103bac3ecf..cc4a26f24f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Set_Bolus_Option.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Set_Bolus_Option.java @@ -1,13 +1,14 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; -import com.cozmo.danar.util.BleCommandUtil; +import info.nightscout.androidaps.logging.L; public class DanaRS_Packet_Bolus_Set_Bolus_Option extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Bolus_Set_Bolus_Option.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); private int extendedBolusOptionOnOff; private int bolusCalculationOption; @@ -75,7 +76,7 @@ public class DanaRS_Packet_Bolus_Set_Bolus_Option extends DanaRS_Packet { this.missedBolus04EndHour = missedBolus04EndHour; this.missedBolus04EndMin = missedBolus04EndMin; - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Setting bolus options"); } } @@ -112,7 +113,9 @@ public class DanaRS_Packet_Bolus_Set_Bolus_Option extends DanaRS_Packet { @Override public void handleMessage(byte[] data) { int result = intFromBuff(data, 0, 1); - if (Config.logDanaMessageDetail) { + if ( result != 0) + failed = true; + if (L.isEnabled(L.PUMPCOMM)) { if (result == 0) log.debug("Result OK"); else diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Set_CIR_CF_Array.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Set_CIR_CF_Array.java index 062ae00712..15bde78a76 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Set_CIR_CF_Array.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Set_CIR_CF_Array.java @@ -1,13 +1,14 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; -import com.cozmo.danar.util.BleCommandUtil; +import info.nightscout.androidaps.logging.L; public class DanaRS_Packet_Bolus_Set_CIR_CF_Array extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Bolus_Set_CIR_CF_Array.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); private int cir01; private int cir02; @@ -45,6 +46,8 @@ public class DanaRS_Packet_Bolus_Set_CIR_CF_Array extends DanaRS_Packet { this.cf05 = cf05; this.cf06 = cf06; this.cf07 = cf07; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override @@ -84,7 +87,9 @@ public class DanaRS_Packet_Bolus_Set_CIR_CF_Array extends DanaRS_Packet { @Override public void handleMessage(byte[] data) { int result = intFromBuff(data, 0, 1); - if (Config.logDanaMessageDetail) { + if (result != 0) + failed = true; + if (L.isEnabled(L.PUMPCOMM)) { if (result == 0) log.debug("Result OK"); else diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Set_Dual_Bolus.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Set_Dual_Bolus.java index e769bea195..023458e5dc 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Set_Dual_Bolus.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Set_Dual_Bolus.java @@ -1,13 +1,14 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; -import com.cozmo.danar.util.BleCommandUtil; +import info.nightscout.androidaps.logging.L; public class DanaRS_Packet_Bolus_Set_Dual_Bolus extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Bolus_Set_Dual_Bolus.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); private double amount; private double extendedAmount; @@ -24,7 +25,7 @@ public class DanaRS_Packet_Bolus_Set_Dual_Bolus extends DanaRS_Packet { this.extendedAmount = extendedAmount; this.extendedBolusDurationInHalfHours = extendedBolusDurationInHalfHours; - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Dual bolus start : " + amount + " U extended: " + extendedAmount + " U halfhours: " + extendedBolusDurationInHalfHours); } @@ -45,7 +46,9 @@ public class DanaRS_Packet_Bolus_Set_Dual_Bolus extends DanaRS_Packet { @Override public void handleMessage(byte[] data) { int result = intFromBuff(data, 0, 1); - if (Config.logDanaMessageDetail) { + if (result!=0) + failed = true; + if (L.isEnabled(L.PUMPCOMM)) { if (result == 0) log.debug("Result OK"); else diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Set_Extended_Bolus.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Set_Extended_Bolus.java index 887a9d852a..504b21bbc9 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Set_Extended_Bolus.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Set_Extended_Bolus.java @@ -1,14 +1,14 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; - -import com.cozmo.danar.util.BleCommandUtil; +import info.nightscout.androidaps.logging.L; public class DanaRS_Packet_Bolus_Set_Extended_Bolus extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Bolus_Set_Extended_Bolus.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); private double extendedAmount; private int extendedBolusDurationInHalfHours; @@ -23,7 +23,7 @@ public class DanaRS_Packet_Bolus_Set_Extended_Bolus extends DanaRS_Packet { this.extendedAmount = extendedAmount; this.extendedBolusDurationInHalfHours = extendedBolusDurationInHalfHours; - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Extended bolus start : " + extendedAmount + " U halfhours: " + extendedBolusDurationInHalfHours); } @@ -41,7 +41,9 @@ public class DanaRS_Packet_Bolus_Set_Extended_Bolus extends DanaRS_Packet { @Override public void handleMessage(byte[] data) { int result = intFromBuff(data, 0, 1); - if (Config.logDanaMessageDetail) { + if (result!=0) + failed=true; + if (L.isEnabled(L.PUMPCOMM)) { if (result == 0) log.debug("Result OK"); else diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Set_Extended_Bolus_Cancel.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Set_Extended_Bolus_Cancel.java index 132de649cf..587e87df9d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Set_Extended_Bolus_Cancel.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Set_Extended_Bolus_Cancel.java @@ -1,26 +1,29 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; -import com.cozmo.danar.util.BleCommandUtil; +import info.nightscout.androidaps.logging.L; public class DanaRS_Packet_Bolus_Set_Extended_Bolus_Cancel extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Bolus_Set_Extended_Bolus_Cancel.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public DanaRS_Packet_Bolus_Set_Extended_Bolus_Cancel() { super(); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_BOLUS__SET_EXTENDED_BOLUS_CANCEL; - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Cancel extended bolus"); } @Override public void handleMessage(byte[] data) { int result = intFromBuff(data, 0, 1); - if (Config.logDanaMessageDetail) { + if (result != 0) + failed = true; + if (L.isEnabled(L.PUMPCOMM)) { if (result == 0) log.debug("Result OK"); else diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Set_Initial_Bolus.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Set_Initial_Bolus.java index a174d39b53..2e7b9be1ff 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Set_Initial_Bolus.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Set_Initial_Bolus.java @@ -1,14 +1,14 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; - -import com.cozmo.danar.util.BleCommandUtil; +import info.nightscout.androidaps.logging.L; public class DanaRS_Packet_Bolus_Set_Initial_Bolus extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Bolus_Set_Initial_Bolus.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); private int bolusRate01; private int bolusRate02; @@ -26,6 +26,8 @@ public class DanaRS_Packet_Bolus_Set_Initial_Bolus extends DanaRS_Packet { this.bolusRate02 = (int) (bolusRate02 / 100d); this.bolusRate03 = (int) (bolusRate03 / 100d); this.bolusRate04 = (int) (bolusRate04 / 100d); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override @@ -45,7 +47,9 @@ public class DanaRS_Packet_Bolus_Set_Initial_Bolus extends DanaRS_Packet { @Override public void handleMessage(byte[] data) { int result = intFromBuff(data, 0, 1); - if (Config.logDanaMessageDetail) { + if (result!=0) + failed = true; + if (L.isEnabled(L.PUMPCOMM)) { if (result == 0) log.debug("Result OK"); else diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Set_Step_Bolus_Start.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Set_Step_Bolus_Start.java index 44e5d308dc..e50fbd70b5 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Set_Step_Bolus_Start.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Set_Step_Bolus_Start.java @@ -5,14 +5,13 @@ import com.cozmo.danar.util.BleCommandUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.R; +import info.nightscout.androidaps.data.ConstraintChecker; import info.nightscout.androidaps.interfaces.Constraint; -import info.nightscout.androidaps.plugins.Overview.notifications.Notification; +import info.nightscout.androidaps.logging.L; public class DanaRS_Packet_Bolus_Set_Step_Bolus_Start extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Bolus_Set_Step_Bolus_Start.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); private double amount; private int speed; @@ -29,13 +28,13 @@ public class DanaRS_Packet_Bolus_Set_Step_Bolus_Start extends DanaRS_Packet { public DanaRS_Packet_Bolus_Set_Step_Bolus_Start(double amount, int speed) { this(); - // HARDCODED LIMIT + // HARDCODED LIMIT - if there is one that could be created amount = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(amount)).value(); this.amount = amount; this.speed = speed; - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Bolus start : " + amount + " speed: " + speed); } @@ -52,12 +51,12 @@ public class DanaRS_Packet_Bolus_Set_Step_Bolus_Start extends DanaRS_Packet { @Override public void handleMessage(byte[] data) { errorCode = intFromBuff(data, 0, 1); - if (Config.logDanaMessageDetail) { + if (errorCode != 0) + failed = true; + if (L.isEnabled(L.PUMPCOMM)) { if (errorCode == 0) { log.debug("Result OK"); - failed = false; } else { - failed = true; log.error("Result Error: " + errorCode); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Set_Step_Bolus_Stop.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Set_Step_Bolus_Stop.java index 78548ecab3..e12b3db7f1 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Set_Step_Bolus_Stop.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Set_Step_Bolus_Stop.java @@ -3,17 +3,17 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import com.cozmo.danar.util.BleCommandUtil; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.Treatments.Treatment; import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress; public class DanaRS_Packet_Bolus_Set_Step_Bolus_Stop extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Bolus_Set_Step_Bolus_Stop.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); private static Treatment t; private static Double amount; @@ -31,16 +31,20 @@ public class DanaRS_Packet_Bolus_Set_Step_Bolus_Stop extends DanaRS_Packet { this.amount = amount; forced = false; stopped = false; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("Stop bolus: amount: " + amount + " treatment: " + t.toString()); } @Override public void handleMessage(byte[] data) { int result = intFromBuff(data, 0, 1); - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { if (result == 0) log.debug("Result OK"); - else + else { log.error("Result Error: " + result); + failed = true; + } } EventOverviewBolusProgress bolusingEvent = EventOverviewBolusProgress.getInstance(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Etc_Keep_Connection.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Etc_Keep_Connection.java index d30be3abf8..8adf46f742 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Etc_Keep_Connection.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Etc_Keep_Connection.java @@ -3,16 +3,18 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; import com.cozmo.danar.util.BleCommandUtil; public class DanaRS_Packet_Etc_Keep_Connection extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Etc_Keep_Connection.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public DanaRS_Packet_Etc_Keep_Connection() { super(); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_ETC__KEEP_CONNECTION; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override @@ -20,7 +22,9 @@ public class DanaRS_Packet_Etc_Keep_Connection extends DanaRS_Packet { int dataIndex = DATA_START; int dataSize = 1; int error = byteArrayToInt(getBytes(data, dataIndex, dataSize)); - if (Config.logDanaMessageDetail) { + if (error!=0) + failed=true; + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Result: " + error); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Etc_Set_History_Save.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Etc_Set_History_Save.java index 6538b77932..1c9af359e2 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Etc_Set_History_Save.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Etc_Set_History_Save.java @@ -3,12 +3,12 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; import com.cozmo.danar.util.BleCommandUtil; public class DanaRS_Packet_Etc_Set_History_Save extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Etc_Set_History_Save.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); private int historyType; private int historyYear; @@ -36,6 +36,8 @@ public class DanaRS_Packet_Etc_Set_History_Save extends DanaRS_Packet { this.historySecond = historySecond; this.historyCode = historyCode; this.historyValue = historyValue; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override @@ -59,7 +61,9 @@ public class DanaRS_Packet_Etc_Set_History_Save extends DanaRS_Packet { int dataIndex = DATA_START; int dataSize = 1; int error = byteArrayToInt(getBytes(data, dataIndex, dataSize)); - if (Config.logDanaMessageDetail) { + if (error != 0) + failed = true; + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Result: " + error); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Delivery_Status.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Delivery_Status.java index d9e2599eb2..c64680379f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Delivery_Status.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Delivery_Status.java @@ -1,18 +1,20 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; - -import com.cozmo.danar.util.BleCommandUtil; +import info.nightscout.androidaps.logging.L; public class DanaRS_Packet_General_Delivery_Status extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_General_Delivery_Status.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public DanaRS_Packet_General_Delivery_Status() { super(); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__DELIVERY_STATUS; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override @@ -20,7 +22,9 @@ public class DanaRS_Packet_General_Delivery_Status extends DanaRS_Packet { int dataIndex = DATA_START; int dataSize = 1; int status = byteArrayToInt(getBytes(data, dataIndex, dataSize)); - if (Config.logDanaMessageDetail) { + if (status != 0) + failed = true; + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Status: " + status); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Get_More_Information.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Get_More_Information.java index cd2de4094f..b1553a2c05 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Get_More_Information.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Get_More_Information.java @@ -1,45 +1,52 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Date; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; -import com.cozmo.danar.util.BleCommandUtil; public class DanaRS_Packet_General_Get_More_Information extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_General_Get_More_Information.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); - public DanaRS_Packet_General_Get_More_Information() { - super(); - opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__GET_MORE_INFORMATION; - } + public DanaRS_Packet_General_Get_More_Information() { + super(); + opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__GET_MORE_INFORMATION; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); + } - @Override - public void handleMessage(byte[] data) { - DanaRPump pump = DanaRPump.getInstance(); + @Override + public void handleMessage(byte[] data) { + if (data.length < 15){ + failed = true; + return; + } + DanaRPump pump = DanaRPump.getInstance(); - int dataIndex = DATA_START; - int dataSize = 2; - pump.iob = byteArrayToInt(getBytes(data, dataIndex, dataSize)); + int dataIndex = DATA_START; + int dataSize = 2; + pump.iob = byteArrayToInt(getBytes(data, dataIndex, dataSize)); - dataIndex += dataSize; - dataSize = 2; - pump.dailyTotalUnits = byteArrayToInt(getBytes(data, dataIndex, dataSize)) / 100d; + dataIndex += dataSize; + dataSize = 2; + pump.dailyTotalUnits = byteArrayToInt(getBytes(data, dataIndex, dataSize)) / 100d; - dataIndex += dataSize; - dataSize = 1; - pump.isExtendedInProgress = byteArrayToInt(getBytes(data, dataIndex, dataSize)) == 0x01; + dataIndex += dataSize; + dataSize = 1; + pump.isExtendedInProgress = byteArrayToInt(getBytes(data, dataIndex, dataSize)) == 0x01; - dataIndex += dataSize; - dataSize = 2; - pump.extendedBolusRemainingMinutes = byteArrayToInt(getBytes(data, dataIndex, dataSize)); + dataIndex += dataSize; + dataSize = 2; + pump.extendedBolusRemainingMinutes = byteArrayToInt(getBytes(data, dataIndex, dataSize)); - dataIndex += dataSize; - dataSize = 2; - double remainRate = byteArrayToInt(getBytes(data, dataIndex, dataSize)) / 100d; + dataIndex += dataSize; + dataSize = 2; + double remainRate = byteArrayToInt(getBytes(data, dataIndex, dataSize)) / 100d; Date lastBolusTime = new Date(); // it doesn't provide day only hour+min, workaround: expecting today dataIndex += dataSize; @@ -50,21 +57,23 @@ public class DanaRS_Packet_General_Get_More_Information extends DanaRS_Packet { dataSize = 1; lastBolusTime.setMinutes(byteArrayToInt(getBytes(data, dataIndex, dataSize))); - dataIndex += dataSize; - dataSize = 2; - pump.lastBolusAmount = byteArrayToInt(getBytes(data, dataIndex, dataSize)); - - if (Config.logDanaMessageDetail) { + dataIndex += dataSize; + dataSize = 2; + pump.lastBolusAmount = byteArrayToInt(getBytes(data, dataIndex, dataSize)); + // On DanaRS DailyUnits can't be more than 160 + if(pump.dailyTotalUnits > 160) + failed = true; + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Daily total units: " + pump.dailyTotalUnits + " U"); log.debug("Is extended in progress: " + pump.isExtendedInProgress); log.debug("Extended bolus remaining minutes: " + pump.extendedBolusRemainingMinutes); log.debug("Last bolus time: " + lastBolusTime.toLocaleString()); log.debug("Last bolus amount: " + pump.lastBolusAmount); } - } + } - @Override - public String getFriendlyName() { - return "REVIEW__GET_MORE_INFORMATION"; - } + @Override + public String getFriendlyName() { + return "REVIEW__GET_MORE_INFORMATION"; + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Get_Password.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Get_Password.java index 0d250db919..dc5cbc59f0 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Get_Password.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Get_Password.java @@ -1,30 +1,36 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; - -import com.cozmo.danar.util.BleCommandUtil; - +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; public class DanaRS_Packet_General_Get_Password extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_General_Get_Password.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public DanaRS_Packet_General_Get_Password() { super(); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__GET_PASSWORD; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override public void handleMessage(byte[] data) { + if (data.length < 2){ + // returned data size is too small + failed = true; + return; + } DanaRPump pump = DanaRPump.getInstance(); int pass = ((data[DATA_START + 1] & 0x000000FF) << 8) + (data[DATA_START + 0] & 0x000000FF); pass = pass ^ 3463; pump.rs_password = Integer.toHexString(pass); - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Pump password: " + pump.rs_password); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Get_Pump_Check.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Get_Pump_Check.java index bdc5ab8d9b..5c26e2ce74 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Get_Pump_Check.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Get_Pump_Check.java @@ -5,23 +5,29 @@ import com.cozmo.danar.util.BleCommandUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.Overview.notifications.Notification; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; public class DanaRS_Packet_General_Get_Pump_Check extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_General_Get_Pump_Check.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public DanaRS_Packet_General_Get_Pump_Check() { super(); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__GET_PUMP_CHECK; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override public void handleMessage(byte[] data) { + if (data.length <5){ + failed = true; + return; + } DanaRPump pump = DanaRPump.getInstance(); int dataIndex = DATA_START; @@ -36,7 +42,7 @@ public class DanaRS_Packet_General_Get_Pump_Check extends DanaRS_Packet { dataSize = 1; pump.productCode = byteArrayToInt(getBytes(data, dataIndex, dataSize)); - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Model: " + String.format("%02X ", pump.model)); log.debug("Protocol: " + String.format("%02X ", pump.protocol)); log.debug("Product Code: " + String.format("%02X ", pump.productCode)); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Get_Shipping_Information.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Get_Shipping_Information.java index 2cf9b1f124..f2cb14cf73 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Get_Shipping_Information.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Get_Shipping_Information.java @@ -1,46 +1,53 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; - -import com.cozmo.danar.util.BleCommandUtil; +import info.nightscout.utils.DateUtil; public class DanaRS_Packet_General_Get_Shipping_Information extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Bolus_Set_Step_Bolus_Stop.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); - public DanaRS_Packet_General_Get_Shipping_Information() { - super(); - opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__GET_SHIPPING_INFORMATION; - } + public DanaRS_Packet_General_Get_Shipping_Information() { + super(); + opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__GET_SHIPPING_INFORMATION; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); + } - @Override - public void handleMessage(byte[] data) { - DanaRPump pump = DanaRPump.getInstance(); + @Override + public void handleMessage(byte[] data) { + if (data.length < 18) { + failed = true; + return; + } + DanaRPump pump = DanaRPump.getInstance(); - int dataIndex = DATA_START; - int dataSize = 10; - pump.serialNumber = stringFromBuff(data, dataIndex, dataSize); + int dataIndex = DATA_START; + int dataSize = 10; + pump.serialNumber = stringFromBuff(data, dataIndex, dataSize); - dataIndex += dataSize; - dataSize = 3; - pump.shippingDate = dateFromBuff(data, dataIndex); + dataIndex += dataSize; + dataSize = 3; + pump.shippingDate = dateFromBuff(data, dataIndex); - dataIndex += dataSize; - dataSize = 3; - pump.shippingCountry = asciiStringFromBuff(data, dataIndex, dataSize); + dataIndex += dataSize; + dataSize = 3; + pump.shippingCountry = asciiStringFromBuff(data, dataIndex, dataSize); - if (Config.logDanaMessageDetail) { - log.debug("Serial number: " + pump.serialNumber); - log.debug("Shipping date: " + pump.shippingDate); - log.debug("Shipping country: " + pump.shippingCountry); - } - } + if (L.isEnabled(L.PUMPCOMM)) { + log.debug("Serial number: " + pump.serialNumber); + log.debug("Shipping date: " + DateUtil.dateAndTimeString(pump.shippingDate)); + log.debug("Shipping country: " + pump.shippingCountry); + } + } - @Override - public String getFriendlyName() { - return "REVIEW__GET_SHIPPING_INFORMATION"; - } + @Override + public String getFriendlyName() { + return "REVIEW__GET_SHIPPING_INFORMATION"; + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Get_Today_Delivery_Total.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Get_Today_Delivery_Total.java index a40d572611..2a3b136279 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Get_Today_Delivery_Total.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Get_Today_Delivery_Total.java @@ -1,47 +1,52 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; - -import com.cozmo.danar.util.BleCommandUtil; - +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; public class DanaRS_Packet_General_Get_Today_Delivery_Total extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_General_Get_Today_Delivery_Total.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); - public DanaRS_Packet_General_Get_Today_Delivery_Total() { - super(); - opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__GET_TODAY_DELIVERY_TOTAL; - } + public DanaRS_Packet_General_Get_Today_Delivery_Total() { + super(); + opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__GET_TODAY_DELIVERY_TOTAL; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); + } - @Override - public void handleMessage(byte[] data) { - DanaRPump pump = DanaRPump.getInstance(); + @Override + public void handleMessage(byte[] data) { + if (data.length < 8){ + failed = true; + return; + } + DanaRPump pump = DanaRPump.getInstance(); - int dataIndex = DATA_START; - int dataSize = 2; - pump.dailyTotalUnits = byteArrayToInt(getBytes(data, dataIndex, dataSize)) / 100d; + int dataIndex = DATA_START; + int dataSize = 2; + pump.dailyTotalUnits = byteArrayToInt(getBytes(data, dataIndex, dataSize)) / 100d; - dataIndex += dataSize; - dataSize = 2; - pump.dailyTotalBasalUnits = byteArrayToInt(getBytes(data, dataIndex, dataSize)) / 100d; + dataIndex += dataSize; + dataSize = 2; + pump.dailyTotalBasalUnits = byteArrayToInt(getBytes(data, dataIndex, dataSize)) / 100d; - dataIndex += dataSize; - dataSize = 2; - pump.dailyTotalBolusUnits = byteArrayToInt(getBytes(data, dataIndex, dataSize)) / 100d; + dataIndex += dataSize; + dataSize = 2; + pump.dailyTotalBolusUnits = byteArrayToInt(getBytes(data, dataIndex, dataSize)) / 100d; - if (Config.logDanaMessageDetail) { - log.debug("Daily total: " + pump.dailyTotalUnits + " U"); - log.debug("Daily total bolus: " + pump.dailyTotalBolusUnits + " U"); - log.debug("Daily total basal: " + pump.dailyTotalBasalUnits + " U"); - } - } + if (L.isEnabled(L.PUMPCOMM)) { + log.debug("Daily total: " + pump.dailyTotalUnits + " U"); + log.debug("Daily total bolus: " + pump.dailyTotalBolusUnits + " U"); + log.debug("Daily total basal: " + pump.dailyTotalBasalUnits + " U"); + } + } - @Override - public String getFriendlyName() { - return "REVIEW__GET_TODAY_DELIVERY_TOTAL"; - } + @Override + public String getFriendlyName() { + return "REVIEW__GET_TODAY_DELIVERY_TOTAL"; + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Get_User_Time_Change_Flag.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Get_User_Time_Change_Flag.java index 695e3eace4..0d07ecc33d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Get_User_Time_Change_Flag.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Get_User_Time_Change_Flag.java @@ -1,26 +1,33 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; -import com.cozmo.danar.util.BleCommandUtil; +import info.nightscout.androidaps.logging.L; public class DanaRS_Packet_General_Get_User_Time_Change_Flag extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_General_Get_User_Time_Change_Flag.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public DanaRS_Packet_General_Get_User_Time_Change_Flag() { super(); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__GET_USER_TIME_CHANGE_FLAG; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override public void handleMessage(byte[] data) { + if (data.length < 3){ + failed = true; + return; + } int dataIndex = DATA_START; int dataSize = 1; int userTimeChangeFlag = byteArrayToInt(getBytes(data, dataIndex, dataSize)); - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("UserTimeChangeFlag: " + userTimeChangeFlag); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Initial_Screen_Information.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Initial_Screen_Information.java index d05777d20d..d8e5b95c14 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Initial_Screen_Information.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Initial_Screen_Information.java @@ -1,25 +1,30 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; - -import com.cozmo.danar.util.BleCommandUtil; - +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; public class DanaRS_Packet_General_Initial_Screen_Information extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Bolus_Get_Step_Bolus_Information.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public DanaRS_Packet_General_Initial_Screen_Information() { super(); type = BleCommandUtil.DANAR_PACKET__TYPE_RESPONSE; opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__INITIAL_SCREEN_INFORMATION; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override public void handleMessage(byte[] data) { + if (data.length < 17) { + failed = true; + return; + } DanaRPump pump = DanaRPump.getInstance(); int dataIndex = DATA_START; @@ -63,7 +68,7 @@ public class DanaRS_Packet_General_Initial_Screen_Information extends DanaRS_Pac dataSize = 2; pump.iob = byteArrayToInt(getBytes(data, dataIndex, dataSize)) / 100d; - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Pump suspended: " + pump.pumpSuspended); log.debug("Temp basal in progress: " + pump.isTempBasalInProgress); log.debug("Extended in progress: " + pump.isExtendedInProgress); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Set_History_Upload_Mode.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Set_History_Upload_Mode.java index 878cfd64dd..f66c3c4afe 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Set_History_Upload_Mode.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Set_History_Upload_Mode.java @@ -1,13 +1,14 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; -import com.cozmo.danar.util.BleCommandUtil; +import info.nightscout.androidaps.logging.L; public class DanaRS_Packet_General_Set_History_Upload_Mode extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_General_Set_History_Upload_Mode.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); private int mode; @@ -19,6 +20,8 @@ public class DanaRS_Packet_General_Set_History_Upload_Mode extends DanaRS_Packet public DanaRS_Packet_General_Set_History_Upload_Mode(int mode) { this(); this.mode = mode; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message: mode: " + mode); } @Override @@ -32,7 +35,9 @@ public class DanaRS_Packet_General_Set_History_Upload_Mode extends DanaRS_Packet @Override public void handleMessage(byte[] data) { int result = intFromBuff(data, 0, 1); - if (Config.logDanaMessageDetail) { + if (result != 0) + failed = true; + if (L.isEnabled(L.PUMPCOMM)) { if (result == 0) log.debug("Result OK"); else diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Set_User_Time_Change_Flag_Clear.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Set_User_Time_Change_Flag_Clear.java index 3917f31050..9f7570d4ce 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Set_User_Time_Change_Flag_Clear.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_General_Set_User_Time_Change_Flag_Clear.java @@ -1,24 +1,28 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; - -import com.cozmo.danar.util.BleCommandUtil; +import info.nightscout.androidaps.logging.L; public class DanaRS_Packet_General_Set_User_Time_Change_Flag_Clear extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_General_Set_User_Time_Change_Flag_Clear.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public DanaRS_Packet_General_Set_User_Time_Change_Flag_Clear() { super(); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__SET_USER_TIME_CHANGE_FLAG_CLEAR; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override public void handleMessage(byte[] data) { int result = intFromBuff(data, 0, 1); - if (Config.logDanaMessageDetail) { + if (result != 0) + failed = true; + if (L.isEnabled(L.PUMPCOMM)) { if (result == 0) log.debug("Result OK"); else diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_.java index 6bae4ab8c1..aab933e787 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_.java @@ -1,7 +1,5 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; -import com.cozmo.danar.util.BleCommandUtil; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -11,12 +9,13 @@ import java.util.GregorianCalendar; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.db.DanaRHistoryRecord; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.comm.RecordTypes; import info.nightscout.androidaps.plugins.PumpDanaR.events.EventDanaRSyncStatus; import info.nightscout.utils.DateUtil; public abstract class DanaRS_Packet_History_ extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_History_.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); private int year = 0; private int month = 0; @@ -34,11 +33,11 @@ public abstract class DanaRS_Packet_History_ extends DanaRS_Packet { totalCount = 0; } - public DanaRS_Packet_History_(Date from) { + public DanaRS_Packet_History_(long from) { this(); GregorianCalendar cal = new GregorianCalendar(); - if (from.getTime() != 0) - cal.setTime(from); + if (from != 0) + cal.setTimeInMillis(from); else cal.set(2000, 0, 1, 0, 0, 0); year = cal.get(Calendar.YEAR) - 1900 - 100; @@ -47,7 +46,8 @@ public abstract class DanaRS_Packet_History_ extends DanaRS_Packet { hour = cal.get(Calendar.HOUR_OF_DAY); min = cal.get(Calendar.MINUTE); sec = cal.get(Calendar.SECOND); - log.debug("Loading event history from: " + new Date(cal.getTimeInMillis()).toLocaleString()); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("Loading event history from: " + new Date(cal.getTimeInMillis()).toLocaleString()); } @Override @@ -71,7 +71,8 @@ public abstract class DanaRS_Packet_History_ extends DanaRS_Packet { int dataSize = 1; error = byteArrayToInt(getBytes(data, dataIndex, dataSize)); done = true; - log.debug("History end. Code: " + error + " Success: " + (error == 0x00)); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("History end. Code: " + error + " Success: " + (error == 0x00)); } else if (data.length == 5) { int dataIndex = DATA_START; int dataSize = 1; @@ -81,11 +82,12 @@ public abstract class DanaRS_Packet_History_ extends DanaRS_Packet { dataIndex += dataSize; dataSize = 2; totalCount = byteArrayToInt(getBytes(data, dataIndex, dataSize)); - log.debug("History end. Code: " + error + " Success: " + (error == 0x00) + " Toatal count: " + totalCount); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("History end. Code: " + error + " Success: " + (error == 0x00) + " Toatal count: " + totalCount); } else { int recordCode = byteArrayToInt(getBytes(data, DATA_START, 1)); int historyYear = byteArrayToInt(getBytes(data, DATA_START + 1, 1)); - int historyMonth = byteArrayToInt(getBytes(data, DATA_START +2 , 1)); + int historyMonth = byteArrayToInt(getBytes(data, DATA_START + 2, 1)); int historyDay = byteArrayToInt(getBytes(data, DATA_START + 3, 1)); int historyHour = byteArrayToInt(getBytes(data, DATA_START + 4, 1)); double dailyBasal = (((data[DATA_START + 4] & 0xFF) << 8) + (data[DATA_START + 5] & 0xFF)) * 0.01d; @@ -103,7 +105,8 @@ public abstract class DanaRS_Packet_History_ extends DanaRS_Packet { int value = ((data[DATA_START + 8] & 0xFF) << 8) + (data[DATA_START + 9] & 0xFF); - log.debug("History packet: " + recordCode + " Date: " + datetimewihtsec.toLocaleString() + " Code: " + historyCode + " Value: " + value); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("History packet: " + recordCode + " Date: " + datetimewihtsec.toLocaleString() + " Code: " + historyCode + " Value: " + value); EventDanaRSyncStatus ev = new EventDanaRSyncStatus(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Alarm.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Alarm.java index 5fe57fefe4..e586166783 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Alarm.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Alarm.java @@ -1,19 +1,27 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; -import java.util.Date; - import com.cozmo.danar.util.BleCommandUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Date; + +import info.nightscout.androidaps.logging.L; + public class DanaRS_Packet_History_Alarm extends DanaRS_Packet_History_ { + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public DanaRS_Packet_History_Alarm() { super(); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__ALARM; } - public DanaRS_Packet_History_Alarm(Date from) { + public DanaRS_Packet_History_Alarm(long from) { super(from); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__ALARM; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_All_History.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_All_History.java index a514d4eac7..f6411dca5f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_All_History.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_All_History.java @@ -1,19 +1,25 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; -import java.util.Date; - import com.cozmo.danar.util.BleCommandUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import info.nightscout.androidaps.logging.L; + public class DanaRS_Packet_History_All_History extends DanaRS_Packet_History_ { + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public DanaRS_Packet_History_All_History() { super(); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__ALL_HISTORY; } - public DanaRS_Packet_History_All_History(Date from) { + public DanaRS_Packet_History_All_History(long from) { super(from); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__ALL_HISTORY; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Basal.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Basal.java index 4aec1d0352..76d485695c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Basal.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Basal.java @@ -1,19 +1,25 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; -import java.util.Date; - import com.cozmo.danar.util.BleCommandUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import info.nightscout.androidaps.logging.L; + public class DanaRS_Packet_History_Basal extends DanaRS_Packet_History_ { + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public DanaRS_Packet_History_Basal() { super(); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__BASAL; } - public DanaRS_Packet_History_Basal(Date from) { + public DanaRS_Packet_History_Basal(long from) { super(from); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__BASAL; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Blood_Glucose.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Blood_Glucose.java index 22bb3b5c2e..e66db9bb78 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Blood_Glucose.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Blood_Glucose.java @@ -1,19 +1,25 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; -import java.util.Date; - import com.cozmo.danar.util.BleCommandUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import info.nightscout.androidaps.logging.L; + public class DanaRS_Packet_History_Blood_Glucose extends DanaRS_Packet_History_ { + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public DanaRS_Packet_History_Blood_Glucose() { super(); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__BLOOD_GLUCOSE; } - public DanaRS_Packet_History_Blood_Glucose(Date from) { + public DanaRS_Packet_History_Blood_Glucose(long from) { super(from); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__BLOOD_GLUCOSE; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Bolus.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Bolus.java index 7451f921be..41a2bd0995 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Bolus.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Bolus.java @@ -1,23 +1,29 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; -import java.util.Date; - import com.cozmo.danar.util.BleCommandUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import info.nightscout.androidaps.logging.L; + public class DanaRS_Packet_History_Bolus extends DanaRS_Packet_History_ { + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); - public DanaRS_Packet_History_Bolus() { - super(); - opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__BOLUS; - } + public DanaRS_Packet_History_Bolus() { + super(); + opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__BOLUS; + } - public DanaRS_Packet_History_Bolus(Date from) { - super(from); - opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__BOLUS; - } + public DanaRS_Packet_History_Bolus(long from) { + super(from); + opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__BOLUS; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); + } - @Override - public String getFriendlyName() { - return "REVIEW__BOLUS"; - } + @Override + public String getFriendlyName() { + return "REVIEW__BOLUS"; + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Carbohydrate.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Carbohydrate.java index df2f5c762d..58d9fac3dc 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Carbohydrate.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Carbohydrate.java @@ -1,23 +1,29 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; -import java.util.Date; - import com.cozmo.danar.util.BleCommandUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import info.nightscout.androidaps.logging.L; + public class DanaRS_Packet_History_Carbohydrate extends DanaRS_Packet_History_ { + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); - public DanaRS_Packet_History_Carbohydrate() { - super(); - opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__CARBOHYDRATE; - } + public DanaRS_Packet_History_Carbohydrate() { + super(); + opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__CARBOHYDRATE; + } - public DanaRS_Packet_History_Carbohydrate(Date from) { - super(from); - opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__CARBOHYDRATE; - } + public DanaRS_Packet_History_Carbohydrate(long from) { + super(from); + opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__CARBOHYDRATE; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); + } - @Override - public String getFriendlyName() { - return "REVIEW__CARBOHYDRATE"; - } + @Override + public String getFriendlyName() { + return "REVIEW__CARBOHYDRATE"; + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Daily.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Daily.java index b55754ba2f..b480f76258 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Daily.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Daily.java @@ -1,19 +1,25 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; -import java.util.Date; - import com.cozmo.danar.util.BleCommandUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import info.nightscout.androidaps.logging.L; + public class DanaRS_Packet_History_Daily extends DanaRS_Packet_History_ { + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public DanaRS_Packet_History_Daily() { super(); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__DAILY; } - public DanaRS_Packet_History_Daily(Date from) { + public DanaRS_Packet_History_Daily(long from) { super(from); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__DAILY; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Prime.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Prime.java index b5dbf7ff93..28ea4c30f0 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Prime.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Prime.java @@ -1,19 +1,25 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; -import java.util.Date; - import com.cozmo.danar.util.BleCommandUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import info.nightscout.androidaps.logging.L; + public class DanaRS_Packet_History_Prime extends DanaRS_Packet_History_ { + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public DanaRS_Packet_History_Prime() { super(); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__PRIME; } - public DanaRS_Packet_History_Prime(Date from) { + public DanaRS_Packet_History_Prime(long from) { super(from); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__PRIME; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Refill.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Refill.java index 66094e3fb6..685c8e519e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Refill.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Refill.java @@ -1,23 +1,29 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; -import java.util.Date; - import com.cozmo.danar.util.BleCommandUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import info.nightscout.androidaps.logging.L; + public class DanaRS_Packet_History_Refill extends DanaRS_Packet_History_ { + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); - public DanaRS_Packet_History_Refill() { - super(); - opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__REFILL; - } + public DanaRS_Packet_History_Refill() { + super(); + opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__REFILL; + } - public DanaRS_Packet_History_Refill(Date from) { - super(from); - opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__REFILL; - } + public DanaRS_Packet_History_Refill(long from) { + super(from); + opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__REFILL; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); + } - @Override - public String getFriendlyName() { - return "REVIEW__REFILL"; - } + @Override + public String getFriendlyName() { + return "REVIEW__REFILL"; + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Suspend.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Suspend.java index 20f1c3d6ff..ef787746ce 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Suspend.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Suspend.java @@ -1,19 +1,25 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; -import java.util.Date; - import com.cozmo.danar.util.BleCommandUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import info.nightscout.androidaps.logging.L; + public class DanaRS_Packet_History_Suspend extends DanaRS_Packet_History_ { + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public DanaRS_Packet_History_Suspend() { super(); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__SUSPEND; } - public DanaRS_Packet_History_Suspend(Date from) { + public DanaRS_Packet_History_Suspend(long from) { super(from); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__SUSPEND; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Temporary.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Temporary.java index 7d63e1bfff..68526b5fb2 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Temporary.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_History_Temporary.java @@ -1,19 +1,25 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; -import java.util.Date; - import com.cozmo.danar.util.BleCommandUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import info.nightscout.androidaps.logging.L; + public class DanaRS_Packet_History_Temporary extends DanaRS_Packet_History_ { + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public DanaRS_Packet_History_Temporary() { super(); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__TEMPORARY; } - public DanaRS_Packet_History_Temporary(Date from) { + public DanaRS_Packet_History_Temporary(long from) { super(from); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__TEMPORARY; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Notify_Alarm.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Notify_Alarm.java index 04737f0bdc..799b3c248c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Notify_Alarm.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Notify_Alarm.java @@ -1,18 +1,17 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; - -import com.cozmo.danar.util.BleCommandUtil; - -import info.nightscout.utils.NSUpload; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; public class DanaRS_Packet_Notify_Alarm extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Notify_Alarm.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); private int alarmCode; @@ -20,6 +19,8 @@ public class DanaRS_Packet_Notify_Alarm extends DanaRS_Packet { super(); type = BleCommandUtil.DANAR_PACKET__TYPE_NOTIFY; opCode = BleCommandUtil.DANAR_PACKET__OPCODE_NOTIFY__ALARM; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override @@ -75,9 +76,14 @@ public class DanaRS_Packet_Notify_Alarm extends DanaRS_Packet { errorString = "Blood sugar check miss alarm ???"; break; } + // No error no need to upload anything + if(errorString == "") { + failed = true; - if (Config.logDanaMessageDetail) - log.debug("Error detected: " + errorString); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("Error detected: " + errorString); + return; + } NSUpload.uploadError(errorString); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Notify_Delivery_Complete.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Notify_Delivery_Complete.java index 2598c5efc9..836a52cb65 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Notify_Delivery_Complete.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Notify_Delivery_Complete.java @@ -1,19 +1,18 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; - -import com.cozmo.danar.util.BleCommandUtil; - -import info.nightscout.androidaps.plugins.Treatments.Treatment; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress; +import info.nightscout.androidaps.plugins.Treatments.Treatment; public class DanaRS_Packet_Notify_Delivery_Complete extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Notify_Delivery_Complete.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); private static Treatment t; private static double amount; @@ -30,6 +29,8 @@ public class DanaRS_Packet_Notify_Delivery_Complete extends DanaRS_Packet { this.amount = amount; this.t = t; done = false; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message: amount: " + amount + " treatment: " + t.toString()); } @Override @@ -46,7 +47,7 @@ public class DanaRS_Packet_Notify_Delivery_Complete extends DanaRS_Packet { MainApp.bus().post(bolusingEvent); } - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Delivered insulin: " + deliveredInsulin); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Notify_Delivery_Rate_Display.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Notify_Delivery_Rate_Display.java index 34621d07ee..c2eb232dac 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Notify_Delivery_Rate_Display.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Notify_Delivery_Rate_Display.java @@ -1,18 +1,18 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import com.cozmo.danar.util.BleCommandUtil; -import info.nightscout.androidaps.plugins.Treatments.Treatment; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress; +import info.nightscout.androidaps.plugins.Treatments.Treatment; public class DanaRS_Packet_Notify_Delivery_Rate_Display extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Notify_Delivery_Rate_Display.class); - + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); private static Treatment t; private static double amount; @@ -29,6 +29,8 @@ public class DanaRS_Packet_Notify_Delivery_Rate_Display extends DanaRS_Packet { this.amount = amount; this.t = t; lastReceive = System.currentTimeMillis(); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message: amount: " + amount + " treatment: " + t.toString()); } @Override @@ -42,10 +44,11 @@ public class DanaRS_Packet_Notify_Delivery_Rate_Display extends DanaRS_Packet { bolusingEvent.status = String.format(MainApp.gs(R.string.bolusdelivering), deliveredInsulin); bolusingEvent.t = t; bolusingEvent.percent = Math.min((int) (deliveredInsulin / amount * 100), 100); + failed = bolusingEvent.percent < 100? true: false; MainApp.bus().post(bolusingEvent); } - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Delivered insulin so far: " + deliveredInsulin); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Notify_Missed_Bolus_Alarm.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Notify_Missed_Bolus_Alarm.java index 3af0c209b5..8239bb34b7 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Notify_Missed_Bolus_Alarm.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Notify_Missed_Bolus_Alarm.java @@ -1,19 +1,21 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; - -import com.cozmo.danar.util.BleCommandUtil; +import info.nightscout.androidaps.logging.L; public class DanaRS_Packet_Notify_Missed_Bolus_Alarm extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Notify_Missed_Bolus_Alarm.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public DanaRS_Packet_Notify_Missed_Bolus_Alarm() { super(); type = BleCommandUtil.DANAR_PACKET__TYPE_NOTIFY; opCode = BleCommandUtil.DANAR_PACKET__OPCODE_NOTIFY__MISSED_BOLUS_ALARM; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override @@ -38,7 +40,11 @@ public class DanaRS_Packet_Notify_Missed_Bolus_Alarm extends DanaRS_Packet { dataIndex += dataSize; dataSize = 1; endMin = byteArrayToInt(getBytes(data, dataIndex, dataSize)); - if (Config.logDanaMessageDetail) { + + if(endMin == 1 && endMin == endHour && startHour == endHour &&startHour == startMin ) + failed = true; + + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Start hour: " + startHour); log.debug("Start min: " + startMin); log.debug("End hour: " + endHour); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Option_Get_Pump_Time.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Option_Get_Pump_Time.java index 4bfebb5211..b4bcbaef98 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Option_Get_Pump_Time.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Option_Get_Pump_Time.java @@ -1,21 +1,22 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Date; -import info.nightscout.androidaps.Config; -import com.cozmo.danar.util.BleCommandUtil; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; public class DanaRS_Packet_Option_Get_Pump_Time extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Option_Get_Pump_Time.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public DanaRS_Packet_Option_Get_Pump_Time() { super(); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_OPTION__GET_PUMP_TIME; - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Requesting pump time"); } } @@ -47,9 +48,12 @@ public class DanaRS_Packet_Option_Get_Pump_Time extends DanaRS_Packet { int sec = byteArrayToInt(getBytes(data, dataIndex, dataSize)); Date time = new Date(100 + year, month - 1, day, hour, min, sec); - DanaRPump.getInstance().pumpTime = time; + DanaRPump.getInstance().pumpTime = time.getTime(); - if (Config.logDanaMessageDetail) { + if ( year == month && month == day && day == hour && hour == min && min == sec && sec == 1) + failed = true; + + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Pump time " + time.toLocaleString()); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Option_Get_User_Option.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Option_Get_User_Option.java index b4df373f9c..6c6d7d7185 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Option_Get_User_Option.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Option_Get_User_Option.java @@ -1,114 +1,117 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; -import com.cozmo.danar.util.BleCommandUtil; public class DanaRS_Packet_Option_Get_User_Option extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Option_Get_User_Option.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); - public DanaRS_Packet_Option_Get_User_Option() { - super(); - opCode = BleCommandUtil.DANAR_PACKET__OPCODE_OPTION__GET_USER_OPTION; - if (Config.logDanaMessageDetail) { - log.debug("Requesting user settings"); - } - } + public DanaRS_Packet_Option_Get_User_Option() { + super(); + opCode = BleCommandUtil.DANAR_PACKET__OPCODE_OPTION__GET_USER_OPTION; + if (L.isEnabled(L.PUMPCOMM)) { + log.debug("Requesting user settings"); + } + } - @Override - public void handleMessage(byte[] data) { - DanaRPump pump = DanaRPump.getInstance(); + @Override + public void handleMessage(byte[] data) { + DanaRPump pump = DanaRPump.getInstance(); - int dataIndex = DATA_START; - int dataSize = 1; - pump.timeDisplayType = byteArrayToInt(getBytes(data, dataIndex, dataSize)); + int dataIndex = DATA_START; + int dataSize = 1; + pump.timeDisplayType = byteArrayToInt(getBytes(data, dataIndex, dataSize)); - dataIndex += dataSize; - dataSize = 1; - pump.buttonScrollOnOff = byteArrayToInt(getBytes(data, dataIndex, dataSize)); + dataIndex += dataSize; + dataSize = 1; + pump.buttonScrollOnOff = byteArrayToInt(getBytes(data, dataIndex, dataSize)); - dataIndex += dataSize; - dataSize = 1; - pump.beepAndAlarm = byteArrayToInt(getBytes(data, dataIndex, dataSize)); + dataIndex += dataSize; + dataSize = 1; + pump.beepAndAlarm = byteArrayToInt(getBytes(data, dataIndex, dataSize)); - dataIndex += dataSize; - dataSize = 1; - pump.lcdOnTimeSec = byteArrayToInt(getBytes(data, dataIndex, dataSize)); + dataIndex += dataSize; + dataSize = 1; + pump.lcdOnTimeSec = byteArrayToInt(getBytes(data, dataIndex, dataSize)); - dataIndex += dataSize; - dataSize = 1; - pump.backlightOnTimeSec = byteArrayToInt(getBytes(data, dataIndex, dataSize)); + dataIndex += dataSize; + dataSize = 1; + pump.backlightOnTimeSec = byteArrayToInt(getBytes(data, dataIndex, dataSize)); - dataIndex += dataSize; - dataSize = 1; - pump.selectedLanguage = byteArrayToInt(getBytes(data, dataIndex, dataSize)); + dataIndex += dataSize; + dataSize = 1; + pump.selectedLanguage = byteArrayToInt(getBytes(data, dataIndex, dataSize)); - dataIndex += dataSize; - dataSize = 1; - pump.units = byteArrayToInt(getBytes(data, dataIndex, dataSize)); + dataIndex += dataSize; + dataSize = 1; + pump.units = byteArrayToInt(getBytes(data, dataIndex, dataSize)); - dataIndex += dataSize; - dataSize = 1; - pump.shutdownHour = byteArrayToInt(getBytes(data, dataIndex, dataSize)); + dataIndex += dataSize; + dataSize = 1; + pump.shutdownHour = byteArrayToInt(getBytes(data, dataIndex, dataSize)); - dataIndex += dataSize; - dataSize = 1; - pump.lowReservoirRate = byteArrayToInt(getBytes(data, dataIndex, dataSize)); + dataIndex += dataSize; + dataSize = 1; + pump.lowReservoirRate = byteArrayToInt(getBytes(data, dataIndex, dataSize)); - dataIndex += dataSize; - dataSize = 2; - pump.cannulaVolume = byteArrayToInt(getBytes(data, dataIndex, dataSize)); + dataIndex += dataSize; + dataSize = 2; + pump.cannulaVolume = byteArrayToInt(getBytes(data, dataIndex, dataSize)); - dataIndex += dataSize; - dataSize = 2; - pump.refillAmount = byteArrayToInt(getBytes(data, dataIndex, dataSize)); + dataIndex += dataSize; + dataSize = 2; + pump.refillAmount = byteArrayToInt(getBytes(data, dataIndex, dataSize)); - dataIndex += dataSize; - dataSize = 1; - int selectableLanguage1 = byteArrayToInt(getBytes(data, dataIndex, dataSize)); + dataIndex += dataSize; + dataSize = 1; + int selectableLanguage1 = byteArrayToInt(getBytes(data, dataIndex, dataSize)); - dataIndex += dataSize; - dataSize = 1; - int selectableLanguage2 = byteArrayToInt(getBytes(data, dataIndex, dataSize)); + dataIndex += dataSize; + dataSize = 1; + int selectableLanguage2 = byteArrayToInt(getBytes(data, dataIndex, dataSize)); - dataIndex += dataSize; - dataSize = 1; - int selectableLanguage3 = byteArrayToInt(getBytes(data, dataIndex, dataSize)); + dataIndex += dataSize; + dataSize = 1; + int selectableLanguage3 = byteArrayToInt(getBytes(data, dataIndex, dataSize)); - dataIndex += dataSize; - dataSize = 1; - int selectableLanguage4 = byteArrayToInt(getBytes(data, dataIndex, dataSize)); + dataIndex += dataSize; + dataSize = 1; + int selectableLanguage4 = byteArrayToInt(getBytes(data, dataIndex, dataSize)); - dataIndex += dataSize; - dataSize = 1; - int selectableLanguage5 = byteArrayToInt(getBytes(data, dataIndex, dataSize)); + dataIndex += dataSize; + dataSize = 1; + int selectableLanguage5 = byteArrayToInt(getBytes(data, dataIndex, dataSize)); + // Pump's screen on time can't be less than 5 + failed = pump.lcdOnTimeSec < 5 ? true : false; - if (Config.logDanaMessageDetail) { - log.debug("timeDisplayType: " + pump.timeDisplayType); - log.debug("buttonScrollOnOff: " + pump.buttonScrollOnOff); - log.debug("beepAndAlarm: " + pump.beepAndAlarm); - log.debug("lcdOnTimeSec: " + pump.lcdOnTimeSec); - log.debug("backlightOnTimeSec: " + pump.backlightOnTimeSec); - log.debug("selectedLanguage: " + pump.selectedLanguage); - log.debug("Pump units: " + (pump.units == DanaRPump.UNITS_MGDL ? "MGDL" : "MMOL")); - log.debug("shutdownHour: " + pump.shutdownHour); - log.debug("lowReservoirRate: " + pump.lowReservoirRate); - log.debug("refillAmount: " + pump.refillAmount); - log.debug("selectableLanguage1: " + selectableLanguage1); - log.debug("selectableLanguage2: " + selectableLanguage2); - log.debug("selectableLanguage3: " + selectableLanguage3); - log.debug("selectableLanguage4: " + selectableLanguage4); - log.debug("selectableLanguage5: " + selectableLanguage5); - } - } + if (L.isEnabled(L.PUMPCOMM)) { + log.debug("timeDisplayType: " + pump.timeDisplayType); + log.debug("buttonScrollOnOff: " + pump.buttonScrollOnOff); + log.debug("beepAndAlarm: " + pump.beepAndAlarm); + log.debug("lcdOnTimeSec: " + pump.lcdOnTimeSec); + log.debug("backlightOnTimeSec: " + pump.backlightOnTimeSec); + log.debug("selectedLanguage: " + pump.selectedLanguage); + log.debug("Pump units: " + (pump.units == DanaRPump.UNITS_MGDL ? "MGDL" : "MMOL")); + log.debug("shutdownHour: " + pump.shutdownHour); + log.debug("lowReservoirRate: " + pump.lowReservoirRate); + log.debug("refillAmount: " + pump.refillAmount); + log.debug("selectableLanguage1: " + selectableLanguage1); + log.debug("selectableLanguage2: " + selectableLanguage2); + log.debug("selectableLanguage3: " + selectableLanguage3); + log.debug("selectableLanguage4: " + selectableLanguage4); + log.debug("selectableLanguage5: " + selectableLanguage5); + } + } - @Override - public String getFriendlyName() { - return "OPTION__GET_USER_OPTION"; - } + @Override + public String getFriendlyName() { + return "OPTION__GET_USER_OPTION"; + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Option_Set_Pump_Time.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Option_Set_Pump_Time.java index 007623afca..f43f82fb15 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Option_Set_Pump_Time.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Option_Set_Pump_Time.java @@ -1,16 +1,16 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Date; -import info.nightscout.androidaps.Config; - -import com.cozmo.danar.util.BleCommandUtil; +import info.nightscout.androidaps.logging.L; public class DanaRS_Packet_Option_Set_Pump_Time extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Option_Set_Pump_Time.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); private Date date; public int error; @@ -22,7 +22,7 @@ public class DanaRS_Packet_Option_Set_Pump_Time extends DanaRS_Packet { public DanaRS_Packet_Option_Set_Pump_Time(Date date) { this(); this.date = date; - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Setting pump time " + date.toLocaleString()); } } @@ -44,7 +44,8 @@ public class DanaRS_Packet_Option_Set_Pump_Time extends DanaRS_Packet { int dataIndex = DATA_START; int dataSize = 1; error = byteArrayToInt(getBytes(data, dataIndex, dataSize)); - if (Config.logDanaMessageDetail) { + failed = error != 0; + if (L.isEnabled(L.PUMPCOMM)) { if (error == 0) log.debug("Result OK"); else diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Option_Set_User_Option.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Option_Set_User_Option.java index e5d9374f32..a64e1e5142 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Option_Set_User_Option.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Option_Set_User_Option.java @@ -1,21 +1,22 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; -import com.cozmo.danar.util.BleCommandUtil; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; public class DanaRS_Packet_Option_Set_User_Option extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Option_Set_User_Option.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); private int error; public DanaRS_Packet_Option_Set_User_Option() { super(); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_OPTION__SET_USER_OPTION; - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Setting user settings"); } } @@ -23,7 +24,15 @@ public class DanaRS_Packet_Option_Set_User_Option extends DanaRS_Packet { @Override public byte[] getRequestParams() { DanaRPump pump = DanaRPump.getInstance(); - + if (L.isEnabled(L.PUMPCOMM)) + log.debug("UserOptions:" + (System.currentTimeMillis() - pump.lastConnection) / 1000 + " s ago" + + "\ntimeDisplayType:" + pump.timeDisplayType + + "\nbuttonScroll:" + pump.buttonScrollOnOff + + "\ntimeDisplayType:" + pump.timeDisplayType + + "\nlcdOnTimeSec:" + pump.lcdOnTimeSec + + "\nbacklight:" + pump.backlightOnTimeSec + + "\npumpUnits:" + pump.units + + "\nlowReservoir:" + pump.lowReservoirRate); byte[] request = new byte[13]; request[0] = (byte) (pump.timeDisplayType & 0xff); request[1] = (byte) (pump.buttonScrollOnOff & 0xff); @@ -46,7 +55,8 @@ public class DanaRS_Packet_Option_Set_User_Option extends DanaRS_Packet { int dataIndex = DATA_START; int dataSize = 1; error = byteArrayToInt(getBytes(data, dataIndex, dataSize)); - if (Config.logDanaMessageDetail) { + failed = error != 0; + if (L.isEnabled(L.PUMPCOMM)) { if (error == 0) log.debug("Result OK"); else diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Review_Bolus_Avg.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Review_Bolus_Avg.java index e8440b12d2..7a2421c310 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Review_Bolus_Avg.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Review_Bolus_Avg.java @@ -1,18 +1,20 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; - -import com.cozmo.danar.util.BleCommandUtil; +import info.nightscout.androidaps.logging.L; public class DanaRS_Packet_Review_Bolus_Avg extends DanaRS_Packet { - private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Review_Bolus_Avg.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public DanaRS_Packet_Review_Bolus_Avg() { super(); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_REVIEW__BOLUS_AVG; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override @@ -36,7 +38,11 @@ public class DanaRS_Packet_Review_Bolus_Avg extends DanaRS_Packet { dataIndex += dataSize; dataSize = 2; double bolusAvg28 = byteArrayToInt(getBytes(data, dataIndex, dataSize)) / 100d; - if (Config.logDanaMessageDetail) { + double required = (((1 & 0x000000FF) << 8) + (1 & 0x000000FF)) / 100d; + if ( bolusAvg03 == bolusAvg07 && bolusAvg07 == bolusAvg14 && bolusAvg14 == bolusAvg21 && bolusAvg21 == bolusAvg28 && bolusAvg28 == required ) + failed = true; + + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Bolus average 3d: " + bolusAvg03 + " U"); log.debug("Bolus average 7d: " + bolusAvg07 + " U"); log.debug("Bolus average 14d: " + bolusAvg14 + " U"); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/services/BLEComm.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/services/BLEComm.java index b552026279..48bb311385 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/services/BLEComm.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/services/BLEComm.java @@ -20,13 +20,14 @@ import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.List; import java.util.UUID; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.events.EventPumpStatusChanged; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; +import info.nightscout.androidaps.plugins.Overview.notifications.Notification; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; import info.nightscout.androidaps.plugins.PumpDanaRS.DanaRSPlugin; import info.nightscout.androidaps.plugins.PumpDanaRS.activities.PairingHelperActivity; @@ -34,6 +35,7 @@ import info.nightscout.androidaps.plugins.PumpDanaRS.comm.DanaRSMessageHashTable import info.nightscout.androidaps.plugins.PumpDanaRS.comm.DanaRS_Packet; import info.nightscout.androidaps.plugins.PumpDanaRS.events.EventDanaRSPacket; import info.nightscout.androidaps.plugins.PumpDanaRS.events.EventDanaRSPairingSuccess; +import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; import info.nightscout.utils.SP; /** @@ -41,15 +43,15 @@ import info.nightscout.utils.SP; */ public class BLEComm { - private static Logger log = LoggerFactory.getLogger(BLEComm.class); + private Logger log = LoggerFactory.getLogger(L.PUMPBTCOMM); - private static final long WRITE_DELAY_MILLIS = 50; + private final long WRITE_DELAY_MILLIS = 50; - public static String UART_READ_UUID = "0000fff1-0000-1000-8000-00805f9b34fb"; - public static String UART_WRITE_UUID = "0000fff2-0000-1000-8000-00805f9b34fb"; + private String UART_READ_UUID = "0000fff1-0000-1000-8000-00805f9b34fb"; + private String UART_WRITE_UUID = "0000fff2-0000-1000-8000-00805f9b34fb"; - private byte PACKET_START_BYTE = (byte) 0xA5; - private byte PACKET_END_BYTE = (byte) 0x5A; + private final byte PACKET_START_BYTE = (byte) 0xA5; + private final byte PACKET_END_BYTE = (byte) 0x5A; private static BLEComm instance = null; public static BLEComm getInstance(DanaRSService service) { @@ -58,16 +60,13 @@ public class BLEComm { return instance; } - private final ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor(); private ScheduledFuture scheduledDisconnection = null; private DanaRS_Packet processsedMessage = null; - private ArrayList mSendQueue = new ArrayList<>(); + private final ArrayList mSendQueue = new ArrayList<>(); private BluetoothManager mBluetoothManager = null; private BluetoothAdapter mBluetoothAdapter = null; - private BluetoothDevice mBluetoothDevice = null; - private String mBluetoothDeviceAddress = null; private String mBluetoothDeviceName = null; private BluetoothGatt mBluetoothGatt = null; @@ -79,25 +78,26 @@ public class BLEComm { private DanaRSService service; - BLEComm(DanaRSService service) { + private BLEComm(DanaRSService service) { this.service = service; initialize(); } private boolean initialize() { - log.debug("Initializing BLEComm."); + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug("Initializing BLEComm."); if (mBluetoothManager == null) { mBluetoothManager = ((BluetoothManager) MainApp.instance().getApplicationContext().getSystemService(Context.BLUETOOTH_SERVICE)); if (mBluetoothManager == null) { - log.debug("Unable to initialize BluetoothManager."); + log.error("Unable to initialize BluetoothManager."); return false; } } mBluetoothAdapter = mBluetoothManager.getAdapter(); if (mBluetoothAdapter == null) { - log.debug("Unable to obtain a BluetoothAdapter."); + log.error("Unable to obtain a BluetoothAdapter."); return false; } @@ -130,7 +130,7 @@ public class BLEComm { } if (address == null) { - log.debug("unspecified address."); + log.error("unspecified address."); return false; } @@ -138,16 +138,15 @@ public class BLEComm { BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address); if (device == null) { - log.debug("Device not found. Unable to connect."); + log.error("Device not found. Unable to connect from: " + from); return false; } - log.debug("Trying to create a new connection."); + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug("Trying to create a new connection from: " + from); + mBluetoothDeviceName = device.getName(); mBluetoothGatt = device.connectGatt(service.getApplicationContext(), false, mGattCallback); setCharacteristicNotification(getUARTReadBTGattChar(), true); - mBluetoothDevice = device; - mBluetoothDeviceAddress = address; - mBluetoothDeviceName = device.getName(); return true; } @@ -155,8 +154,9 @@ public class BLEComm { isConnecting = false; } - public void disconnect(String from) { - log.debug("disconnect from: " + from); + public synchronized void disconnect(String from) { + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug("disconnect from: " + from); // cancel previous scheduled disconnection to prevent closing upcomming connection if (scheduledDisconnection != null) @@ -164,8 +164,8 @@ public class BLEComm { scheduledDisconnection = null; if ((mBluetoothAdapter == null) || (mBluetoothGatt == null)) { - log.debug("disconnect not possible: (mBluetoothAdapter == null) " + (mBluetoothAdapter == null)); - log.debug("disconnect not possible: (mBluetoothGatt == null) " + (mBluetoothGatt == null)); + log.error("disconnect not possible: (mBluetoothAdapter == null) " + (mBluetoothAdapter == null)); + log.error("disconnect not possible: (mBluetoothGatt == null) " + (mBluetoothGatt == null)); return; } setCharacteristicNotification(getUARTReadBTGattChar(), false); @@ -174,8 +174,9 @@ public class BLEComm { SystemClock.sleep(2000); } - public void close() { - log.debug("BluetoothAdapter close"); + public synchronized void close() { + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug("BluetoothAdapter close"); if (mBluetoothGatt == null) { return; } @@ -184,35 +185,19 @@ public class BLEComm { mBluetoothGatt = null; } - public BluetoothDevice getConnectDevice() { - return mBluetoothDevice; - } - public String getConnectDeviceAddress() { - return mBluetoothDeviceAddress; - } - - public String getConnectDeviceName() { + private String getConnectDeviceName() { return mBluetoothDeviceName; } private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { - log.debug("onConnectionStateChange"); - - if (newState == BluetoothProfile.STATE_CONNECTED) { - mBluetoothGatt.discoverServices(); - } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { - close(); - isConnected = false; - isConnecting = false; - MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.DISCONNECTED)); - log.debug("Device was disconnected " + gatt.getDevice().getName());//Device was disconnected - } + onConnectionStateChangeSynchronized(gatt, status, newState); // call it synchronized } public void onServicesDiscovered(BluetoothGatt gatt, int status) { - log.debug("onServicesDiscovered"); + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug("onServicesDiscovered"); if (status == BluetoothGatt.GATT_SUCCESS) { findCharacteristic(); } @@ -221,44 +206,40 @@ public class BLEComm { } public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { - log.debug("onCharacteristicRead" + (characteristic != null ? ":" + DanaRS_Packet.toHexString(characteristic.getValue()) : "")); + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug("onCharacteristicRead" + (characteristic != null ? ":" + DanaRS_Packet.toHexString(characteristic.getValue()) : "")); addToReadBuffer(characteristic.getValue()); readDataParsing(); } public void onCharacteristicChanged(BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic) { - log.debug("onCharacteristicChanged" + (characteristic != null ? ":" + DanaRS_Packet.toHexString(characteristic.getValue()) : "")); + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug("onCharacteristicChanged" + (characteristic != null ? ":" + DanaRS_Packet.toHexString(characteristic.getValue()) : "")); addToReadBuffer(characteristic.getValue()); - new Thread(new Runnable() { - @Override - public void run() { - readDataParsing(); - } - }).start(); + new Thread(() -> readDataParsing()).start(); } public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { - log.debug("onCharacteristicWrite" + (characteristic != null ? ":" + DanaRS_Packet.toHexString(characteristic.getValue()) : "")); - new Thread(new Runnable() { - @Override - public void run() { - synchronized (mSendQueue) { - // after message sent, check if there is the rest of the message waiting and send it - if (mSendQueue.size() > 0) { - byte[] bytes = mSendQueue.get(0); - mSendQueue.remove(0); - writeCharacteristic_NO_RESPONSE(getUARTWriteBTGattChar(), bytes); - } + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug("onCharacteristicWrite" + (characteristic != null ? ":" + DanaRS_Packet.toHexString(characteristic.getValue()) : "")); + new Thread(() -> { + synchronized (mSendQueue) { + // after message sent, check if there is the rest of the message waiting and send it + if (mSendQueue.size() > 0) { + byte[] bytes = mSendQueue.get(0); + mSendQueue.remove(0); + writeCharacteristic_NO_RESPONSE(getUARTWriteBTGattChar(), bytes); } } }).start(); } }; - public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic, boolean enabled) { - log.debug("setCharacteristicNotification"); + private synchronized void setCharacteristicNotification(BluetoothGattCharacteristic characteristic, boolean enabled) { + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug("setCharacteristicNotification"); if ((mBluetoothAdapter == null) || (mBluetoothGatt == null)) { - log.debug("BluetoothAdapter not initialized_ERROR"); + log.error("BluetoothAdapter not initialized_ERROR"); isConnecting = false; isConnected = false; return; @@ -266,10 +247,11 @@ public class BLEComm { mBluetoothGatt.setCharacteristicNotification(characteristic, enabled); } - public void readCharacteristic(BluetoothGattCharacteristic characteristic) { - log.debug("readCharacteristic"); + public synchronized void readCharacteristic(BluetoothGattCharacteristic characteristic) { + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug("readCharacteristic"); if ((mBluetoothAdapter == null) || (mBluetoothGatt == null)) { - log.debug("BluetoothAdapter not initialized_ERROR"); + log.error("BluetoothAdapter not initialized_ERROR"); isConnecting = false; isConnected = false; return; @@ -277,44 +259,44 @@ public class BLEComm { mBluetoothGatt.readCharacteristic(characteristic); } - public void writeCharacteristic_NO_RESPONSE(final BluetoothGattCharacteristic characteristic, final byte[] data) { - new Thread(new Runnable() { - public void run() { - SystemClock.sleep(WRITE_DELAY_MILLIS); + private synchronized void writeCharacteristic_NO_RESPONSE(final BluetoothGattCharacteristic characteristic, final byte[] data) { + new Thread(() -> { + SystemClock.sleep(WRITE_DELAY_MILLIS); - if ((mBluetoothAdapter == null) || (mBluetoothGatt == null)) { - log.debug("BluetoothAdapter not initialized_ERROR"); - isConnecting = false; - isConnected = false; - return; - } - - characteristic.setValue(data); - characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE); - log.debug("writeCharacteristic:" + DanaRS_Packet.toHexString(data)); - mBluetoothGatt.writeCharacteristic(characteristic); + if ((mBluetoothAdapter == null) || (mBluetoothGatt == null)) { + log.error("BluetoothAdapter not initialized_ERROR"); + isConnecting = false; + isConnected = false; + return; } + + characteristic.setValue(data); + characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE); + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug("writeCharacteristic:" + DanaRS_Packet.toHexString(data)); + mBluetoothGatt.writeCharacteristic(characteristic); }).start(); } - public BluetoothGattCharacteristic getUARTReadBTGattChar() { + private BluetoothGattCharacteristic getUARTReadBTGattChar() { if (UART_Read == null) { UART_Read = new BluetoothGattCharacteristic(UUID.fromString(UART_READ_UUID), BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_NOTIFY, 0); } return UART_Read; } - public BluetoothGattCharacteristic getUARTWriteBTGattChar() { + private BluetoothGattCharacteristic getUARTWriteBTGattChar() { if (UART_Write == null) { UART_Write = new BluetoothGattCharacteristic(UUID.fromString(UART_WRITE_UUID), BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE, 0); } return UART_Write; } - public List getSupportedGattServices() { - log.debug("getSupportedGattServices"); + private List getSupportedGattServices() { + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug("getSupportedGattServices"); if ((mBluetoothAdapter == null) || (mBluetoothGatt == null)) { - log.debug("BluetoothAdapter not initialized_ERROR"); + log.error("BluetoothAdapter not initialized_ERROR"); isConnecting = false; isConnected = false; return null; @@ -329,7 +311,7 @@ public class BLEComm { if (gattServices == null) { return; } - String uuid = null; + String uuid; for (BluetoothGattService gattService : gattServices) { List gattCharacteristics = gattService.getCharacteristics(); @@ -346,7 +328,23 @@ public class BLEComm { } } - private byte[] readBuffer = new byte[1024]; + private synchronized void onConnectionStateChangeSynchronized(BluetoothGatt gatt, int status, int newState) { + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug("onConnectionStateChange"); + + if (newState == BluetoothProfile.STATE_CONNECTED) { + mBluetoothGatt.discoverServices(); + } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { + close(); + isConnected = false; + isConnecting = false; + MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.DISCONNECTED)); + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug("Device was disconnected " + gatt.getDevice().getName());//Device was disconnected + } + } + + private final byte[] readBuffer = new byte[1024]; private int bufferLength = 0; private void addToReadBuffer(byte[] buffer) { @@ -377,7 +375,8 @@ public class BLEComm { if ((readBuffer[idxStartByte] == PACKET_START_BYTE) && (readBuffer[idxStartByte + 1] == PACKET_START_BYTE)) { if (idxStartByte > 0) { // if buffer doesn't start with signature remove the leading trash - log.debug("Shifting the input buffer by " + idxStartByte + " bytes"); + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug("Shifting the input buffer by " + idxStartByte + " bytes"); System.arraycopy(readBuffer, idxStartByte, readBuffer, 0, bufferLength - idxStartByte); bufferLength -= idxStartByte; } @@ -407,7 +406,7 @@ public class BLEComm { try { System.arraycopy(readBuffer, length + 7, readBuffer, 0, bufferLength - (length + 7)); } catch (Exception e) { - log.debug("length: " + length + "bufferLength: " + bufferLength); + log.error("length: " + length + "bufferLength: " + bufferLength); throw e; } bufferLength -= (length + 7); @@ -420,7 +419,7 @@ public class BLEComm { inputBuffer = BleCommandUtil.getInstance().getDecryptedPacket(inputBuffer); if (inputBuffer == null) { - log.debug("Null decryptedInputBuffer"); + log.error("Null decryptedInputBuffer"); return; } @@ -431,33 +430,51 @@ public class BLEComm { // 1st packet case (byte) BleCommandUtil.DANAR_PACKET__OPCODE_ENCRYPTION__PUMP_CHECK: if (inputBuffer.length == 4 && inputBuffer[2] == 'O' && inputBuffer[3] == 'K') { - log.debug("<<<<< " + "ENCRYPTION__PUMP_CHECK (OK)" + " " + DanaRS_Packet.toHexString(inputBuffer)); + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug("<<<<< " + "ENCRYPTION__PUMP_CHECK (OK)" + " " + DanaRS_Packet.toHexString(inputBuffer)); // Grab pairing key from preferences if exists String pairingKey = SP.getString(MainApp.gs(R.string.key_danars_pairingkey) + DanaRSPlugin.mDeviceName, null); - log.debug("Using stored pairing key: " + pairingKey); + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug("Using stored pairing key: " + pairingKey); if (pairingKey != null) { byte[] encodedPairingKey = DanaRS_Packet.hexToBytes(pairingKey); byte[] bytes = BleCommandUtil.getInstance().getEncryptedPacket(BleCommandUtil.DANAR_PACKET__OPCODE_ENCRYPTION__CHECK_PASSKEY, encodedPairingKey, null); - log.debug(">>>>> " + "ENCRYPTION__CHECK_PASSKEY" + " " + DanaRS_Packet.toHexString(bytes)); + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug(">>>>> " + "ENCRYPTION__CHECK_PASSKEY" + " " + DanaRS_Packet.toHexString(bytes)); writeCharacteristic_NO_RESPONSE(getUARTWriteBTGattChar(), bytes); } else { // Stored pairing key does not exists, request pairing SendPairingRequest(); } + } else if (inputBuffer.length == 6 && inputBuffer[2] == 'P' && inputBuffer[3] == 'U' && inputBuffer[4] == 'M' && inputBuffer[5] == 'P') { + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug("<<<<< " + "ENCRYPTION__PUMP_CHECK (PUMP)" + " " + DanaRS_Packet.toHexString(inputBuffer)); + mSendQueue.clear(); + MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.DISCONNECTED, MainApp.gs(R.string.pumperror))); + NSUpload.uploadError(MainApp.gs(R.string.pumperror)); + Notification n = new Notification(Notification.PUMPERROR, MainApp.gs(R.string.pumperror), Notification.URGENT); + MainApp.bus().post(new EventNewNotification(n)); } else if (inputBuffer.length == 6 && inputBuffer[2] == 'B' && inputBuffer[3] == 'U' && inputBuffer[4] == 'S' && inputBuffer[5] == 'Y') { - log.debug("<<<<< " + "ENCRYPTION__PUMP_CHECK (BUSY)" + " " + DanaRS_Packet.toHexString(inputBuffer)); + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug("<<<<< " + "ENCRYPTION__PUMP_CHECK (BUSY)" + " " + DanaRS_Packet.toHexString(inputBuffer)); mSendQueue.clear(); MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.DISCONNECTED, MainApp.gs(R.string.pumpbusy))); } else { - log.debug("<<<<< " + "ENCRYPTION__PUMP_CHECK (ERROR)" + " " + DanaRS_Packet.toHexString(inputBuffer)); + // ERROR in response, wrong serial number + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug("<<<<< " + "ENCRYPTION__PUMP_CHECK (ERROR)" + " " + DanaRS_Packet.toHexString(inputBuffer)); mSendQueue.clear(); MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.DISCONNECTED, MainApp.gs(R.string.connectionerror))); + SP.remove(MainApp.gs(R.string.key_danars_pairingkey) + DanaRSPlugin.mDeviceName); + Notification n = new Notification(Notification.WRONGSERIALNUMBER, MainApp.gs(R.string.wrongpassword), Notification.URGENT); + MainApp.bus().post(new EventNewNotification(n)); } break; // 2nd packet, pairing key case (byte) BleCommandUtil.DANAR_PACKET__OPCODE_ENCRYPTION__CHECK_PASSKEY: - log.debug("<<<<< " + "ENCRYPTION__CHECK_PASSKEY" + " " + DanaRS_Packet.toHexString(inputBuffer)); + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug("<<<<< " + "ENCRYPTION__CHECK_PASSKEY" + " " + DanaRS_Packet.toHexString(inputBuffer)); if (inputBuffer[2] == (byte) 0x00) { // Paring is not requested, sending time info SendTimeInfo(); @@ -467,35 +484,41 @@ public class BLEComm { } break; case (byte) BleCommandUtil.DANAR_PACKET__OPCODE_ENCRYPTION__PASSKEY_REQUEST: - log.debug("<<<<< " + "ENCRYPTION__PASSKEY_REQUEST " + DanaRS_Packet.toHexString(inputBuffer)); + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug("<<<<< " + "ENCRYPTION__PASSKEY_REQUEST " + DanaRS_Packet.toHexString(inputBuffer)); if (inputBuffer[2] != (byte) 0x00) { disconnect("passkey request failed"); } break; // Paring response, OK button on pump pressed case (byte) BleCommandUtil.DANAR_PACKET__OPCODE_ENCRYPTION__PASSKEY_RETURN: - log.debug("<<<<< " + "ENCRYPTION__PASSKEY_RETURN " + DanaRS_Packet.toHexString(inputBuffer)); + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug("<<<<< " + "ENCRYPTION__PASSKEY_RETURN " + DanaRS_Packet.toHexString(inputBuffer)); // Paring is successfull, sending time info MainApp.bus().post(new EventDanaRSPairingSuccess()); SendTimeInfo(); byte[] pairingKey = {inputBuffer[2], inputBuffer[3]}; // store pairing key to preferences SP.putString(MainApp.gs(R.string.key_danars_pairingkey) + DanaRSPlugin.mDeviceName, DanaRS_Packet.bytesToHex(pairingKey)); - log.debug("Got pairing key: " + DanaRS_Packet.bytesToHex(pairingKey)); + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug("Got pairing key: " + DanaRS_Packet.bytesToHex(pairingKey)); break; // time and user password information. last packet in handshake case (byte) BleCommandUtil.DANAR_PACKET__OPCODE_ENCRYPTION__TIME_INFORMATION: - log.debug("<<<<< " + "ENCRYPTION__TIME_INFORMATION " + /*message.getMessageName() + " " + */ DanaRS_Packet.toHexString(inputBuffer)); + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug("<<<<< " + "ENCRYPTION__TIME_INFORMATION " + /*message.getMessageName() + " " + */ DanaRS_Packet.toHexString(inputBuffer)); int size = inputBuffer.length; int pass = ((inputBuffer[size - 1] & 0x000000FF) << 8) + ((inputBuffer[size - 2] & 0x000000FF)); pass = pass ^ 3463; DanaRPump.getInstance().rs_password = Integer.toHexString(pass); - log.debug("Pump user password: " + Integer.toHexString(pass)); + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug("Pump user password: " + Integer.toHexString(pass)); MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.CONNECTED)); isConnected = true; isConnecting = false; - log.debug("RS connected and status read"); + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug("RS connected and status read"); break; } break; @@ -513,7 +536,8 @@ public class BLEComm { message = DanaRSMessageHashTable.findMessage(receivedCommand); } if (message != null) { - log.debug("<<<<< " + message.getFriendlyName() + " " + DanaRS_Packet.toHexString(inputBuffer)); + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug("<<<<< " + message.getFriendlyName() + " " + DanaRS_Packet.toHexString(inputBuffer)); // process received data message.handleMessage(inputBuffer); message.setReceived(); @@ -550,7 +574,8 @@ public class BLEComm { byte[] command = {(byte) message.getType(), (byte) message.getOpCode()}; byte[] params = message.getRequestParams(); - log.debug(">>>>> " + message.getFriendlyName() + " " + DanaRS_Packet.toHexString(command) + " " + DanaRS_Packet.toHexString(params)); + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug(">>>>> " + message.getFriendlyName() + " " + DanaRS_Packet.toHexString(command) + " " + DanaRS_Packet.toHexString(params)); byte[] bytes = BleCommandUtil.getInstance().getEncryptedPacket(message.getOpCode(), params, null); // If there is another message not completely sent, add to queue only if (mSendQueue.size() > 0) { @@ -630,20 +655,29 @@ public class BLEComm { MainApp.instance().startActivity(i); byte[] bytes = BleCommandUtil.getInstance().getEncryptedPacket(BleCommandUtil.DANAR_PACKET__OPCODE_ENCRYPTION__PASSKEY_REQUEST, null, null); - log.debug(">>>>> " + "ENCRYPTION__PASSKEY_REQUEST" + " " + DanaRS_Packet.toHexString(bytes)); + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug(">>>>> " + "ENCRYPTION__PASSKEY_REQUEST" + " " + DanaRS_Packet.toHexString(bytes)); writeCharacteristic_NO_RESPONSE(getUARTWriteBTGattChar(), bytes); } - protected void SendPumpCheck() { + private void SendPumpCheck() { // 1st message sent to pump after connect - byte[] bytes = BleCommandUtil.getInstance().getEncryptedPacket(BleCommandUtil.DANAR_PACKET__OPCODE_ENCRYPTION__PUMP_CHECK, null, getConnectDeviceName()); - log.debug(">>>>> " + "ENCRYPTION__PUMP_CHECK (0x00)" + " " + DanaRS_Packet.toHexString(bytes)); + String devicename = getConnectDeviceName(); + if(devicename == null || devicename.equals("")){ + Notification n = new Notification(Notification.DEVICENOTPAIRED, MainApp.gs(R.string.pairfirst), Notification.URGENT); + MainApp.bus().post(new EventNewNotification(n)); + return; + } + byte[] bytes = BleCommandUtil.getInstance().getEncryptedPacket(BleCommandUtil.DANAR_PACKET__OPCODE_ENCRYPTION__PUMP_CHECK, null, devicename); + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug(">>>>> " + "ENCRYPTION__PUMP_CHECK (0x00)" + " " + DanaRS_Packet.toHexString(bytes)); writeCharacteristic_NO_RESPONSE(getUARTWriteBTGattChar(), bytes); } private void SendTimeInfo() { byte[] bytes = BleCommandUtil.getInstance().getEncryptedPacket(BleCommandUtil.DANAR_PACKET__OPCODE_ENCRYPTION__TIME_INFORMATION, null, null); - log.debug(">>>>> " + "ENCRYPTION__TIME_INFORMATION" + " " + DanaRS_Packet.toHexString(bytes)); + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug(">>>>> " + "ENCRYPTION__TIME_INFORMATION" + " " + DanaRS_Packet.toHexString(bytes)); writeCharacteristic_NO_RESPONSE(getUARTWriteBTGattChar(), bytes); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/services/DanaRSService.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/services/DanaRSService.java index 856b95492d..cb823a3c88 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/services/DanaRSService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/services/DanaRSService.java @@ -13,21 +13,24 @@ import org.slf4j.LoggerFactory; import java.util.Date; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.PumpEnactResult; -import info.nightscout.androidaps.plugins.Treatments.Treatment; import info.nightscout.androidaps.events.EventAppExit; import info.nightscout.androidaps.events.EventInitializationChanged; +import info.nightscout.androidaps.events.EventProfileSwitchChange; import info.nightscout.androidaps.events.EventPumpStatusChanged; +import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.Overview.Dialogs.BolusProgressDialog; -import info.nightscout.androidaps.plugins.Overview.notifications.Notification; +import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress; +import info.nightscout.androidaps.plugins.Overview.notifications.Notification; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; import info.nightscout.androidaps.plugins.PumpDanaR.comm.RecordTypes; import info.nightscout.androidaps.plugins.PumpDanaR.events.EventDanaRNewStatus; @@ -69,21 +72,24 @@ import info.nightscout.androidaps.plugins.PumpDanaRS.comm.DanaRS_Packet_History_ import info.nightscout.androidaps.plugins.PumpDanaRS.comm.DanaRS_Packet_Notify_Delivery_Complete; import info.nightscout.androidaps.plugins.PumpDanaRS.comm.DanaRS_Packet_Notify_Delivery_Rate_Display; import info.nightscout.androidaps.plugins.PumpDanaRS.comm.DanaRS_Packet_Option_Get_Pump_Time; +import info.nightscout.androidaps.plugins.PumpDanaRS.comm.DanaRS_Packet_Option_Get_User_Option; import info.nightscout.androidaps.plugins.PumpDanaRS.comm.DanaRS_Packet_Option_Set_Pump_Time; +import info.nightscout.androidaps.plugins.PumpDanaRS.comm.DanaRS_Packet_Option_Set_User_Option; +import info.nightscout.androidaps.plugins.Treatments.Treatment; import info.nightscout.androidaps.queue.Callback; +import info.nightscout.androidaps.queue.commands.Command; import info.nightscout.utils.DateUtil; -import info.nightscout.utils.NSUpload; +import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; import info.nightscout.utils.SP; import info.nightscout.utils.T; public class DanaRSService extends Service { - private static Logger log = LoggerFactory.getLogger(DanaRSService.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); private BLEComm bleComm = BLEComm.getInstance(this); private IBinder mBinder = new LocalBinder(); - private DanaRPump danaRPump = DanaRPump.getInstance(); private Treatment bolusingTreatment = null; private long lastHistoryFetched = 0; @@ -123,6 +129,7 @@ public class DanaRSService extends Service { } public void getPumpStatus() { + DanaRPump danaRPump = DanaRPump.getInstance(); try { MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.gettingpumpstatus))); @@ -134,8 +141,54 @@ public class DanaRSService extends Service { MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.gettingtempbasalstatus))); bleComm.sendMessage(new DanaRS_Packet_Basal_Get_Temporary_Basal_State()); + danaRPump.lastConnection = System.currentTimeMillis(); + + Profile profile = ProfileFunctions.getInstance().getProfile(); + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); + if (profile != null && Math.abs(danaRPump.currentBasal - profile.getBasal()) >= pump.getPumpDescription().basalStep) { + MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.gettingpumpsettings))); + bleComm.sendMessage(new DanaRS_Packet_Basal_Get_Basal_Rate()); // basal profile, basalStep, maxBasal + if (!pump.isThisProfileSet(profile) && !ConfigBuilderPlugin.getPlugin().getCommandQueue().isRunning(Command.CommandType.BASALPROFILE)) { + MainApp.bus().post(new EventProfileSwitchChange()); + } + } + + MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.gettingpumptime))); + bleComm.sendMessage(new DanaRS_Packet_Option_Get_Pump_Time()); + + long timeDiff = (danaRPump.pumpTime - System.currentTimeMillis()) / 1000L; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("Pump time difference: " + timeDiff + " seconds"); + if (Math.abs(timeDiff) > 3) { + if (Math.abs(timeDiff) > 60 * 60 * 1.5) { + if (L.isEnabled(L.PUMPCOMM)) + log.debug("Pump time difference: " + timeDiff + " seconds - large difference"); + //If time-diff is very large, warn user until we can synchronize history readings properly + Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class); + i.putExtra("soundid", R.raw.error); + i.putExtra("status", MainApp.gs(R.string.largetimediff)); + i.putExtra("title", MainApp.gs(R.string.largetimedifftitle)); + i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + MainApp.instance().startActivity(i); + + //deinitialize pump + danaRPump.lastConnection = 0; + MainApp.bus().post(new EventDanaRNewStatus()); + MainApp.bus().post(new EventInitializationChanged()); + return; + } else { + waitForWholeMinute(); // Dana can set only whole minute + // add 10sec to be sure we are over minute (will be cutted off anyway) + bleComm.sendMessage(new DanaRS_Packet_Option_Set_Pump_Time(new Date(DateUtil.now() + T.secs(10).msecs()))); + bleComm.sendMessage(new DanaRS_Packet_Option_Get_Pump_Time()); + timeDiff = (danaRPump.pumpTime - System.currentTimeMillis()) / 1000L; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("Pump time difference: " + timeDiff + " seconds"); + } + } + long now = System.currentTimeMillis(); - if (danaRPump.lastSettingsRead + 60 * 60 * 1000L < now || !MainApp.getSpecificPlugin(DanaRSPlugin.class).isInitialized()) { + if (danaRPump.lastSettingsRead + 60 * 60 * 1000L < now || !pump.isInitialized()) { MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.gettingpumpsettings))); bleComm.sendMessage(new DanaRS_Packet_General_Get_Shipping_Information()); // serial no bleComm.sendMessage(new DanaRS_Packet_General_Get_Pump_Check()); // firmware @@ -144,18 +197,7 @@ public class DanaRSService extends Service { bleComm.sendMessage(new DanaRS_Packet_Basal_Get_Basal_Rate()); // basal profile, basalStep, maxBasal bleComm.sendMessage(new DanaRS_Packet_Bolus_Get_Calculation_Information()); // target bleComm.sendMessage(new DanaRS_Packet_Bolus_Get_CIR_CF_Array()); - MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.gettingpumptime))); - bleComm.sendMessage(new DanaRS_Packet_Option_Get_Pump_Time()); - long timeDiff = (danaRPump.pumpTime.getTime() - System.currentTimeMillis()) / 1000L; - log.debug("Pump time difference: " + timeDiff + " seconds"); - if (Math.abs(timeDiff) > 3) { - waitForWholeMinute(); // Dana can set only whole minute - // add 10sec to be sure we are over minute (will be cutted off anyway) - bleComm.sendMessage(new DanaRS_Packet_Option_Set_Pump_Time(new Date(DateUtil.now() + T.secs(10).msecs()))); - bleComm.sendMessage(new DanaRS_Packet_Option_Get_Pump_Time()); - timeDiff = (danaRPump.pumpTime.getTime() - System.currentTimeMillis()) / 1000L; - log.debug("Pump time difference: " + timeDiff + " seconds"); - } + bleComm.sendMessage(new DanaRS_Packet_Option_Get_User_Option()); // Getting user options danaRPump.lastSettingsRead = now; } @@ -165,8 +207,9 @@ public class DanaRSService extends Service { MainApp.bus().post(new EventInitializationChanged()); NSUpload.uploadDeviceStatus(); if (danaRPump.dailyTotalUnits > danaRPump.maxDailyTotalUnits * Constants.dailyLimitWarning) { - log.debug("Approaching daily limit: " + danaRPump.dailyTotalUnits + "/" + danaRPump.maxDailyTotalUnits); - if(System.currentTimeMillis() > lastApproachingDailyLimit + 30 * 60 * 1000) { + if (L.isEnabled(L.PUMPCOMM)) + log.debug("Approaching daily limit: " + danaRPump.dailyTotalUnits + "/" + danaRPump.maxDailyTotalUnits); + if (System.currentTimeMillis() > lastApproachingDailyLimit + 30 * 60 * 1000) { Notification reportFail = new Notification(Notification.APPROACHING_DAILY_LIMIT, MainApp.gs(R.string.approachingdailylimit), Notification.URGENT); MainApp.bus().post(new EventNewNotification(reportFail)); NSUpload.uploadError(MainApp.gs(R.string.approachingdailylimit) + ": " + danaRPump.dailyTotalUnits + "/" + danaRPump.maxDailyTotalUnits + "U"); @@ -176,28 +219,48 @@ public class DanaRSService extends Service { } catch (Exception e) { log.error("Unhandled exception", e); } - log.debug("Pump status loaded"); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("Pump status loaded"); } public PumpEnactResult loadEvents() { + + if (!MainApp.getSpecificPlugin(DanaRSPlugin.class).isInitialized()) { + PumpEnactResult result = new PumpEnactResult().success(false); + result.comment = "pump not initialized"; + return result; + } + + SystemClock.sleep(1000); + DanaRS_Packet_APS_History_Events msg; if (lastHistoryFetched == 0) { msg = new DanaRS_Packet_APS_History_Events(0); - log.debug("Loading complete event history"); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("Loading complete event history"); } else { msg = new DanaRS_Packet_APS_History_Events(lastHistoryFetched); - log.debug("Loading event history from: " + new Date(lastHistoryFetched).toLocaleString()); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("Loading event history from: " +DateUtil.dateAndTimeFullString(lastHistoryFetched)); } bleComm.sendMessage(msg); while (!msg.done && bleComm.isConnected()) { SystemClock.sleep(100); } if (DanaRS_Packet_APS_History_Events.lastEventTimeLoaded != 0) - lastHistoryFetched = DanaRS_Packet_APS_History_Events.lastEventTimeLoaded - 45 * 60 * 1000L; // always load last 45 min + lastHistoryFetched = DanaRS_Packet_APS_History_Events.lastEventTimeLoaded - T.mins(1).msecs(); else lastHistoryFetched = 0; - log.debug("Events loaded"); - danaRPump.lastConnection = System.currentTimeMillis(); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("Events loaded"); + DanaRPump.getInstance().lastConnection = System.currentTimeMillis(); + return new PumpEnactResult().success(true); + } + + + public PumpEnactResult setUserSettings() { + bleComm.sendMessage(new DanaRS_Packet_Option_Set_User_Option()); + bleComm.sendMessage(new DanaRS_Packet_Option_Get_User_Option()); return new PumpEnactResult().success(true); } @@ -218,7 +281,7 @@ public class DanaRSService extends Service { // bleComm.sendMessage(msg); DanaRS_Packet_APS_Set_Event_History msgSetHistoryEntry_v2 = new DanaRS_Packet_APS_Set_Event_History(DanaRPump.CARBS, carbtime, carbs, 0); bleComm.sendMessage(msgSetHistoryEntry_v2); - lastHistoryFetched = carbtime - 60000; + lastHistoryFetched = Math.min(lastHistoryFetched, carbtime - T.mins(1).msecs()); } final long bolusStart = System.currentTimeMillis(); @@ -236,7 +299,8 @@ public class DanaRSService extends Service { if ((System.currentTimeMillis() - progress.lastReceive) > 15 * 1000L) { // if i didn't receive status for more than 20 sec expecting broken comm stop.stopped = true; stop.forced = true; - log.debug("Communication stopped"); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("Communication stopped"); } } } @@ -267,7 +331,7 @@ public class DanaRSService extends Service { SystemClock.sleep(1000); } // do not call loadEvents() directly, reconnection may be needed - ConfigBuilderPlugin.getCommandQueue().loadEvents(new Callback() { + ConfigBuilderPlugin.getPlugin().getCommandQueue().loadEvents(new Callback() { @Override public void run() { // reread bolus status @@ -281,7 +345,7 @@ public class DanaRSService extends Service { } public void bolusStop() { - if (Config.logDanaBTComm) + if (L.isEnabled(L.PUMPCOMM)) log.debug("bolusStop >>>>> @ " + (bolusingTreatment == null ? "" : bolusingTreatment.insulin)); DanaRS_Packet_Bolus_Set_Step_Bolus_Stop stop = new DanaRS_Packet_Bolus_Set_Step_Bolus_Stop(); stop.forced = true; @@ -298,7 +362,7 @@ public class DanaRSService extends Service { public boolean tempBasal(Integer percent, int durationInHours) { if (!isConnected()) return false; - if (danaRPump.isTempBasalInProgress) { + if (DanaRPump.getInstance().isTempBasalInProgress) { MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.stoppingtempbasal))); bleComm.sendMessage(new DanaRS_Packet_Basal_Set_Cancel_Temporary_Basal()); SystemClock.sleep(500); @@ -313,7 +377,7 @@ public class DanaRSService extends Service { } public boolean highTempBasal(Integer percent) { - if (danaRPump.isTempBasalInProgress) { + if (DanaRPump.getInstance().isTempBasalInProgress) { MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.stoppingtempbasal))); bleComm.sendMessage(new DanaRS_Packet_Basal_Set_Cancel_Temporary_Basal()); SystemClock.sleep(500); @@ -332,7 +396,7 @@ public class DanaRSService extends Service { return false; } - if (danaRPump.isTempBasalInProgress) { + if (DanaRPump.getInstance().isTempBasalInProgress) { MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.stoppingtempbasal))); bleComm.sendMessage(new DanaRS_Packet_Basal_Set_Cancel_Temporary_Basal()); SystemClock.sleep(500); @@ -379,12 +443,12 @@ public class DanaRSService extends Service { public boolean updateBasalsInPump(Profile profile) { if (!isConnected()) return false; MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.updatingbasalrates))); - double[] basal = DanaRPump.buildDanaRProfileRecord(profile); + double[] basal = DanaRPump.getInstance().buildDanaRProfileRecord(profile); DanaRS_Packet_Basal_Set_Profile_Basal_Rate msgSet = new DanaRS_Packet_Basal_Set_Profile_Basal_Rate(0, basal); bleComm.sendMessage(msgSet); DanaRS_Packet_Basal_Set_Profile_Number msgActivate = new DanaRS_Packet_Basal_Set_Profile_Number(0); bleComm.sendMessage(msgActivate); - danaRPump.lastSettingsRead = 0; // force read full settings + DanaRPump.getInstance().lastSettingsRead = 0; // force read full settings getPumpStatus(); MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.DISCONNECTING)); return true; @@ -458,12 +522,10 @@ public class DanaRSService extends Service { @Subscribe public void onStatusEvent(EventAppExit event) { - if (Config.logFunctionCalls) + if (L.isEnabled(L.PUMP)) log.debug("EventAppExit received"); stopSelf(); - if (Config.logFunctionCalls) - log.debug("EventAppExit finished"); } void waitForWholeMinute() { @@ -472,7 +534,7 @@ public class DanaRSService extends Service { long timeToWholeMinute = (60000 - time % 60000); if (timeToWholeMinute > 59800 || timeToWholeMinute < 300) break; - MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.waitingfortimesynchronization, (int)(timeToWholeMinute / 1000)))); + MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.waitingfortimesynchronization, (int) (timeToWholeMinute / 1000)))); SystemClock.sleep(Math.min(timeToWholeMinute, 100)); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/DanaRv2Plugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/DanaRv2Plugin.java index 7c13707949..86c07b89ff 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/DanaRv2Plugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/DanaRv2Plugin.java @@ -5,12 +5,11 @@ import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.IBinder; +import android.support.v4.app.FragmentActivity; +import android.support.v7.app.AlertDialog; import com.squareup.otto.Subscribe; -import org.slf4j.LoggerFactory; - -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.DetailedBolusInfo; @@ -19,9 +18,12 @@ import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.events.EventAppExit; import info.nightscout.androidaps.interfaces.Constraint; -import info.nightscout.androidaps.interfaces.PumpDescription; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderFragment; import info.nightscout.androidaps.plugins.ConfigBuilder.DetailedBolusInfoStorage; +import info.nightscout.androidaps.plugins.PumpCommon.defs.PumpType; import info.nightscout.androidaps.plugins.PumpDanaR.AbstractDanaRPlugin; +import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgBolusStartWithSpeed; import info.nightscout.androidaps.plugins.PumpDanaRv2.services.DanaRv2ExecutionService; import info.nightscout.androidaps.plugins.Treatments.Treatment; @@ -29,6 +31,7 @@ import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.utils.DateUtil; import info.nightscout.utils.Round; import info.nightscout.utils.SP; +import info.nightscout.utils.T; /** * Created by mike on 05.08.2016. @@ -44,39 +47,10 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin { } private DanaRv2Plugin() { - log = LoggerFactory.getLogger(DanaRv2Plugin.class); + pluginDescription.description(R.string.description_pump_dana_r_v2); + useExtendedBoluses = false; - - pumpDescription.isBolusCapable = true; - pumpDescription.bolusStep = 0.05d; - - pumpDescription.isExtendedBolusCapable = true; - pumpDescription.extendedBolusStep = 0.05d; - pumpDescription.extendedBolusDurationStep = 30; - pumpDescription.extendedBolusMaxDuration = 8 * 60; - - pumpDescription.isTempBasalCapable = true; - pumpDescription.tempBasalStyle = PumpDescription.PERCENT; - - pumpDescription.maxTempPercent = 200; - pumpDescription.tempPercentStep = 10; - - pumpDescription.tempDurationStep = 60; - pumpDescription.tempDurationStep15mAllowed = true; - pumpDescription.tempDurationStep30mAllowed = true; - pumpDescription.tempMaxDuration = 24 * 60; - - - pumpDescription.isSetBasalProfileCapable = true; - pumpDescription.basalStep = 0.01d; - pumpDescription.basalMinimumRate = 0.04d; - - pumpDescription.isRefillingCapable = true; - - pumpDescription.storesCarbInfo = true; - - pumpDescription.supportsTDDs = true; - pumpDescription.needsManualTDDLoad = true; + pumpDescription.setPumpDescription(PumpType.DanaRv2); } @Override @@ -100,12 +74,14 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin { private ServiceConnection mConnection = new ServiceConnection() { public void onServiceDisconnected(ComponentName name) { - log.debug("Service is disconnected"); + if (L.isEnabled(L.PUMP)) + log.debug("Service is disconnected"); sExecutionService = null; } public void onServiceConnected(ComponentName name, IBinder service) { - log.debug("Service is connected"); + if (L.isEnabled(L.PUMP)) + log.debug("Service is connected"); DanaRv2ExecutionService.LocalBinder mLocalBinder = (DanaRv2ExecutionService.LocalBinder) service; sExecutionService = mLocalBinder.getServiceInstance(); } @@ -135,7 +111,40 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin { @Override public boolean isInitialized() { - return pump.lastConnection > 0 && pump.maxBasal > 0; + return DanaRPump.getInstance().lastConnection > 0 && DanaRPump.getInstance().maxBasal > 0 && DanaRPump.getInstance().isPasswordOK(); + } + + @Override + public boolean isHandshakeInProgress() { + return sExecutionService != null && sExecutionService.isHandshakeInProgress(); + } + + @Override + public void finishHandshaking() { + sExecutionService.finishHandshaking(); + } + + @Override + public void switchAllowed(ConfigBuilderFragment.PluginViewHolder.PluginSwitcher pluginSwitcher, FragmentActivity context) { + boolean allowHardwarePump = SP.getBoolean("allow_hardware_pump", false); + if (allowHardwarePump || context == null) { + pluginSwitcher.invoke(); + } else { + AlertDialog.Builder builder = new AlertDialog.Builder(context); + builder.setMessage(R.string.allow_hardware_pump_text) + .setPositiveButton(R.string.yes, (dialog, id) -> { + pluginSwitcher.invoke(); + SP.putBoolean("allow_hardware_pump", true); + if (L.isEnabled(L.PUMP)) + log.debug("First time HW pump allowed!"); + }) + .setNegativeButton(R.string.cancel, (dialog, id) -> { + pluginSwitcher.cancel(); + if (L.isEnabled(L.PUMP)) + log.debug("User does not allow switching to HW pump!"); + }); + builder.create().show(); + } } // Pump interface @@ -158,12 +167,13 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin { speed = 60; break; } - detailedBolusInfo.date = DateUtil.now() + (long)(speed * detailedBolusInfo.insulin * 1000); + detailedBolusInfo.date = DateUtil.now() + (long) (speed * detailedBolusInfo.insulin * 1000); // clean carbs to prevent counting them as twice because they will picked up as another record // I don't think it's necessary to copy DetailedBolusInfo right now for carbs records double carbs = detailedBolusInfo.carbs; detailedBolusInfo.carbs = 0; int carbTime = detailedBolusInfo.carbTime; + if (carbTime == 0) carbTime--; // better set 1 man back to prevent clash with insulin detailedBolusInfo.carbTime = 0; DetailedBolusInfoStorage.add(detailedBolusInfo); // will be picked up on reading history @@ -172,7 +182,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin { t.isSMB = detailedBolusInfo.isSMB; boolean connectionOK = false; if (detailedBolusInfo.insulin > 0 || carbs > 0) - connectionOK = sExecutionService.bolus(detailedBolusInfo.insulin, (int) carbs, DateUtil.now() + carbTime * 60 * 1000, t); + connectionOK = sExecutionService.bolus(detailedBolusInfo.insulin, (int) carbs, DateUtil.now() + T.mins(carbTime).msecs(), t); PumpEnactResult result = new PumpEnactResult(); result.success = connectionOK && Math.abs(detailedBolusInfo.insulin - t.insulin) < pumpDescription.bolusStep; result.bolusDelivered = t.insulin; @@ -181,7 +191,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin { result.comment = String.format(MainApp.gs(R.string.boluserrorcode), detailedBolusInfo.insulin, t.insulin, MsgBolusStartWithSpeed.errorCode); else result.comment = MainApp.gs(R.string.virtualpump_resultok); - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("deliverTreatment: OK. Asked: " + detailedBolusInfo.insulin + " Delivered: " + result.bolusDelivered); // remove carbs because it's get from history seprately return result; @@ -225,7 +235,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin { if (doTempOff) { // If temp in progress if (TreatmentsPlugin.getPlugin().isTempBasalInProgress()) { - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalAbsolute: Stopping temp basal (doTempOff)"); return cancelTempBasal(false); } @@ -234,7 +244,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin { result.percent = 100; result.isPercent = true; result.isTempCancel = true; - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalAbsolute: doTempOff OK"); return result; } @@ -257,22 +267,26 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin { result.duration = activeTemp.getPlannedRemainingMinutes(); result.isPercent = true; result.isTempCancel = false; - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalAbsolute: Correct temp basal already set (doLowTemp || doHighTemp)"); return result; } } } // Convert duration from minutes to hours - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalAbsolute: Setting temp basal " + percentRate + "% for " + durationInMinutes + " mins (doLowTemp || doHighTemp)"); - // use special APS temp basal call ... 100+/15min .... 100-/30min - result = setHighTempBasalPercent(percentRate); + if (percentRate == 0 && durationInMinutes > 30) { + result = setTempBasalPercent(percentRate, durationInMinutes, profile, false); + } else { + // use special APS temp basal call ... 100+/15min .... 100-/30min + result = setHighTempBasalPercent(percentRate); + } if (!result.success) { log.error("setTempBasalAbsolute: Failed to set hightemp basal"); return result; } - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalAbsolute: hightemp basal set ok"); return result; } @@ -285,6 +299,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin { @Override public PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes, Profile profile, boolean enforceNew) { + DanaRPump pump = DanaRPump.getInstance(); PumpEnactResult result = new PumpEnactResult(); percent = MainApp.getConstraintChecker().applyBasalPercentConstraints(new Constraint<>(percent), profile).value(); if (percent < 0) { @@ -307,7 +322,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin { result.duration = pump.tempBasalRemainingMin; result.percent = pump.tempBasalPercent; result.isPercent = true; - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalPercent: Correct value already set"); return result; } @@ -326,7 +341,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin { result.duration = pump.tempBasalRemainingMin; result.percent = pump.tempBasalPercent; result.isPercent = true; - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setTempBasalPercent: OK"); return result; } @@ -337,7 +352,8 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin { return result; } - public PumpEnactResult setHighTempBasalPercent(Integer percent) { + private PumpEnactResult setHighTempBasalPercent(Integer percent) { + DanaRPump pump = DanaRPump.getInstance(); PumpEnactResult result = new PumpEnactResult(); boolean connectionOK = sExecutionService.highTempBasal(percent); if (connectionOK && pump.isTempBasalInProgress && pump.tempBasalPercent == percent) { @@ -348,7 +364,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin { result.duration = pump.tempBasalRemainingMin; result.percent = pump.tempBasalPercent; result.isPercent = true; - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("setHighTempBasalPercent: OK"); return result; } @@ -368,11 +384,11 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin { result.enacted = true; result.isTempCancel = true; } - if (!pump.isTempBasalInProgress) { + if (!DanaRPump.getInstance().isTempBasalInProgress) { result.success = true; result.isTempCancel = true; result.comment = MainApp.gs(R.string.virtualpump_resultok); - if (Config.logPumpActions) + if (L.isEnabled(L.PUMP)) log.debug("cancelRealTempBasal: OK"); return result; } else { @@ -389,4 +405,8 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin { return sExecutionService.loadEvents(); } + @Override + public PumpEnactResult setUserOptions() { + return sExecutionService.setUserOptions(); + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/SerialIOThread.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/SerialIOThread.java index a12e2085aa..61047a8d5a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/SerialIOThread.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/SerialIOThread.java @@ -10,7 +10,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase; import info.nightscout.androidaps.plugins.PumpDanaR.services.AbstractSerialIOThread; @@ -21,7 +21,7 @@ import info.nightscout.utils.CRC; * Created by mike on 17.07.2016. */ public class SerialIOThread extends AbstractSerialIOThread { - private static Logger log = LoggerFactory.getLogger(SerialIOThread.class); + private static Logger log = LoggerFactory.getLogger(L.PUMPBTCOMM); private InputStream mInputStream = null; private OutputStream mOutputStream = null; @@ -72,7 +72,7 @@ public class SerialIOThread extends AbstractSerialIOThread { message = MessageHashTable_v2.findMessage(command); } - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPBTCOMM)) log.debug("<<<<< " + message.getMessageName() + " " + message.toHexString(extractedBuff)); // process the message content @@ -84,7 +84,7 @@ public class SerialIOThread extends AbstractSerialIOThread { } } } catch (Exception e) { - if (Config.logDanaSerialEngine && e.getMessage().indexOf("bt socket closed") < 0) + if (e.getMessage().indexOf("bt socket closed") < 0) log.error("Thread exception: ", e); mKeepRunning = false; } @@ -148,7 +148,7 @@ public class SerialIOThread extends AbstractSerialIOThread { processedMessage = message; byte[] messageBytes = message.getRawMessageBytes(); - if (Config.logDanaSerialEngine) + if (L.isEnabled(L.PUMPBTCOMM)) log.debug(">>>>> " + message.getMessageName() + " " + message.toHexString(messageBytes)); try { @@ -167,10 +167,10 @@ public class SerialIOThread extends AbstractSerialIOThread { SystemClock.sleep(200); if (!message.received) { - log.warn("Reply not received " + message.getMessageName()); + log.error("Reply not received " + message.getMessageName()); if (message.getCommand() == 0xF0F1) { DanaRPump.getInstance().isNewPump = false; - log.debug("Old firmware detected"); + log.error("Old firmware detected"); } } } @@ -181,24 +181,29 @@ public class SerialIOThread extends AbstractSerialIOThread { try { mInputStream.close(); } catch (Exception e) { - if (Config.logDanaSerialEngine) log.debug(e.getMessage()); + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug(e.getMessage()); } try { mOutputStream.close(); } catch (Exception e) { - if (Config.logDanaSerialEngine) log.debug(e.getMessage()); + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug(e.getMessage()); } try { mRfCommSocket.close(); } catch (Exception e) { - if (Config.logDanaSerialEngine) log.debug(e.getMessage()); + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug(e.getMessage()); } try { System.runFinalization(); } catch (Exception e) { - if (Config.logDanaSerialEngine) log.debug(e.getMessage()); + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug(e.getMessage()); } - if (Config.logDanaSerialEngine) log.debug("Disconnected: " + reason); + if (L.isEnabled(L.PUMPBTCOMM)) + log.debug("Disconnected: " + reason); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MessageHashTable_v2.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MessageHashTable_v2.java index cafba32239..c95a800128 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MessageHashTable_v2.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MessageHashTable_v2.java @@ -1,8 +1,5 @@ package info.nightscout.androidaps.plugins.PumpDanaRv2.comm; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.util.HashMap; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase; @@ -13,8 +10,6 @@ import info.nightscout.androidaps.plugins.PumpDanaR.comm.*; * Created by mike on 28.05.2016. */ public class MessageHashTable_v2 { - private static Logger log = LoggerFactory.getLogger(MessageHashTable_v2.class); - public static HashMap messages = null; static { @@ -66,6 +61,7 @@ public class MessageHashTable_v2 { put(new MsgSettingProfileRatiosAll()); // 0x320D CMD_SETTING_V_CIR_CF_VALUE put(new MsgSetSingleBasalProfile()); // 0x3302 CMD_SETTING_BASAL_INS_S put(new MsgSetBasalProfile()); // 0x3306 CMD_SETTING_BASAL_PROFILE_S + put(new MsgSetUserOptions()); // 0x330B CMD_SETTING_USER_OPTIONS_S put(new MsgSetActivateBasalProfile()); // 0x330C CMD_SETTING_PROFILE_NUMBER_S put(new MsgHistoryAllDone()); // 0x41F1 CMD_HISTORY_ALL_DONE put(new MsgHistoryAll()); // 0x41F2 CMD_HISTORY_ALL diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgCheckValue_v2.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgCheckValue_v2.java index 0869844a1c..034c7648a0 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgCheckValue_v2.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgCheckValue_v2.java @@ -3,11 +3,11 @@ package info.nightscout.androidaps.plugins.PumpDanaRv2.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.events.EventRefreshGui; import info.nightscout.androidaps.interfaces.PluginType; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.Overview.notifications.Notification; @@ -21,10 +21,12 @@ import info.nightscout.androidaps.plugins.PumpDanaRv2.DanaRv2Plugin; * Created by mike on 30.06.2016. */ public class MsgCheckValue_v2 extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgCheckValue_v2.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgCheckValue_v2() { SetCommand(0xF0F1); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override @@ -32,7 +34,8 @@ public class MsgCheckValue_v2 extends MessageBase { DanaRPump pump = DanaRPump.getInstance(); pump.isNewPump = true; - log.debug("New firmware confirmed"); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New firmware confirmed"); pump.model = intFromBuff(bytes, 0, 1); pump.protocol = intFromBuff(bytes, 1, 1); @@ -42,7 +45,7 @@ public class MsgCheckValue_v2 extends MessageBase { Notification notification = new Notification(Notification.WRONG_DRIVER, MainApp.gs(R.string.pumpdrivercorrected), Notification.NORMAL); MainApp.bus().post(new EventNewNotification(notification)); MainApp.getSpecificPlugin(DanaRPlugin.class).disconnect("Wrong Model"); - log.debug("Wrong model selected. Switching to Korean DanaR"); + log.error("Wrong model selected. Switching to Korean DanaR"); MainApp.getSpecificPlugin(DanaRKoreanPlugin.class).setPluginEnabled(PluginType.PUMP, true); MainApp.getSpecificPlugin(DanaRKoreanPlugin.class).setFragmentVisible(PluginType.PUMP, true); MainApp.getSpecificPlugin(DanaRPlugin.class).setPluginEnabled(PluginType.PUMP, false); @@ -56,9 +59,9 @@ public class MsgCheckValue_v2 extends MessageBase { (MainApp.getSpecificPlugin(DanaRKoreanPlugin.class)).setPluginEnabled(PluginType.PROFILE, true); } - MainApp.getConfigBuilder().storeSettings("ChangingDanaRv2Driver"); + ConfigBuilderPlugin.getPlugin().storeSettings("ChangingDanaRv2Driver"); MainApp.bus().post(new EventRefreshGui()); - ConfigBuilderPlugin.getCommandQueue().readStatus("PumpDriverChange", null); // force new connection + ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("PumpDriverChange", null); // force new connection return; } @@ -67,7 +70,7 @@ public class MsgCheckValue_v2 extends MessageBase { Notification notification = new Notification(Notification.WRONG_DRIVER, MainApp.gs(R.string.pumpdrivercorrected), Notification.NORMAL); MainApp.bus().post(new EventNewNotification(notification)); DanaRKoreanPlugin.getPlugin().disconnect("Wrong Model"); - log.debug("Wrong model selected. Switching to non APS DanaR"); + log.error("Wrong model selected. Switching to non APS DanaR"); (MainApp.getSpecificPlugin(DanaRv2Plugin.class)).setPluginEnabled(PluginType.PUMP, false); (MainApp.getSpecificPlugin(DanaRv2Plugin.class)).setFragmentVisible(PluginType.PUMP, false); (MainApp.getSpecificPlugin(DanaRPlugin.class)).setPluginEnabled(PluginType.PUMP, true); @@ -79,12 +82,12 @@ public class MsgCheckValue_v2 extends MessageBase { (MainApp.getSpecificPlugin(DanaRPlugin.class)).setPluginEnabled(PluginType.PROFILE, true); } - MainApp.getConfigBuilder().storeSettings("ChangingDanaRv2Driver"); + ConfigBuilderPlugin.getPlugin().storeSettings("ChangingDanaRv2Driver"); MainApp.bus().post(new EventRefreshGui()); - ConfigBuilderPlugin.getCommandQueue().readStatus("PumpDriverChange", null); // force new connection + ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("PumpDriverChange", null); // force new connection return; } - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Model: " + String.format("%02X ", pump.model)); log.debug("Protocol: " + String.format("%02X ", pump.protocol)); log.debug("Product Code: " + String.format("%02X ", pump.productCode)); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgHistoryEvents_v2.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgHistoryEvents_v2.java index 05c4087dcb..32ac8862ee 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgHistoryEvents_v2.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgHistoryEvents_v2.java @@ -13,6 +13,7 @@ import info.nightscout.androidaps.db.ExtendedBolus; import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.events.EventPumpStatusChanged; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.DetailedBolusInfoStorage; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase; @@ -20,27 +21,38 @@ import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.utils.DateUtil; public class MsgHistoryEvents_v2 extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgHistoryEvents_v2.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public boolean done; public static long lastEventTimeLoaded = 0; - public MsgHistoryEvents_v2(long from) { - SetCommand(0xE003); - GregorianCalendar gfrom = new GregorianCalendar(); - gfrom.setTimeInMillis(from); - AddParamDate(gfrom); - done = false; + public MsgHistoryEvents_v2() { + this(0); } - public MsgHistoryEvents_v2() { + public MsgHistoryEvents_v2(long from) { SetCommand(0xE003); - AddParamByte((byte) 0); - AddParamByte((byte) 1); - AddParamByte((byte) 1); - AddParamByte((byte) 0); - AddParamByte((byte) 0); + + if (from > DateUtil.now()) { + log.debug("Asked to load from the future"); + from = 0; + } + + if (from == 0) { + AddParamByte((byte) 0); + AddParamByte((byte) 1); + AddParamByte((byte) 1); + AddParamByte((byte) 0); + AddParamByte((byte) 0); + } else { + GregorianCalendar gfrom = new GregorianCalendar(); + gfrom.setTimeInMillis(from); + AddParamDate(gfrom); + } + done = false; + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } @Override @@ -53,122 +65,140 @@ public class MsgHistoryEvents_v2 extends MessageBase { return; } - Date datetime = dateTimeSecFromBuff(bytes, 1); // 6 bytes + long datetime = dateTimeSecFromBuff(bytes, 1); // 6 bytes int param1 = intFromBuff(bytes, 7, 2); int param2 = intFromBuff(bytes, 9, 2); TemporaryBasal temporaryBasal = new TemporaryBasal() - .date(datetime.getTime()) + .date(datetime) .source(Source.PUMP) - .pumpId(datetime.getTime()); + .pumpId(datetime); - ExtendedBolus extendedBolus = new ExtendedBolus(); - extendedBolus.date = datetime.getTime(); - extendedBolus.source = Source.PUMP; - extendedBolus.pumpId = datetime.getTime(); - - DetailedBolusInfo detailedBolusInfo = DetailedBolusInfoStorage.findDetailedBolusInfo(datetime.getTime()); - if (detailedBolusInfo == null) { - log.debug("Detailed bolus info not found for " + datetime.toLocaleString()); - detailedBolusInfo = new DetailedBolusInfo(); - } else { - log.debug("Detailed bolus info found: " + detailedBolusInfo); - } - detailedBolusInfo.date = datetime.getTime(); - detailedBolusInfo.source = Source.PUMP; - detailedBolusInfo.pumpId = datetime.getTime(); + ExtendedBolus extendedBolus = new ExtendedBolus() + .date(datetime) + .source(Source.PUMP) + .pumpId(datetime); String status = ""; switch (recordCode) { case DanaRPump.TEMPSTART: - log.debug("EVENT TEMPSTART (" + recordCode + ") " + datetime.toLocaleString() + " Ratio: " + param1 + "% Duration: " + param2 + "min"); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("EVENT TEMPSTART (" + recordCode + ") " + DateUtil.dateAndTimeFullString(datetime) + " (" + datetime + ")" + " Ratio: " + param1 + "% Duration: " + param2 + "min"); temporaryBasal.percentRate = param1; temporaryBasal.durationInMinutes = param2; TreatmentsPlugin.getPlugin().addToHistoryTempBasal(temporaryBasal); status = "TEMPSTART " + DateUtil.timeString(datetime); break; case DanaRPump.TEMPSTOP: - log.debug("EVENT TEMPSTOP (" + recordCode + ") " + datetime.toLocaleString()); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("EVENT TEMPSTOP (" + recordCode + ") " + DateUtil.dateAndTimeFullString(datetime)); TreatmentsPlugin.getPlugin().addToHistoryTempBasal(temporaryBasal); status = "TEMPSTOP " + DateUtil.timeString(datetime); break; case DanaRPump.EXTENDEDSTART: - log.debug("EVENT EXTENDEDSTART (" + recordCode + ") " + datetime.toLocaleString() + " Amount: " + (param1 / 100d) + "U Duration: " + param2 + "min"); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("EVENT EXTENDEDSTART (" + recordCode + ") " + DateUtil.dateAndTimeFullString(datetime) + " (" + datetime + ")" + " Amount: " + (param1 / 100d) + "U Duration: " + param2 + "min"); extendedBolus.insulin = param1 / 100d; extendedBolus.durationInMinutes = param2; TreatmentsPlugin.getPlugin().addToHistoryExtendedBolus(extendedBolus); status = "EXTENDEDSTART " + DateUtil.timeString(datetime); break; case DanaRPump.EXTENDEDSTOP: - log.debug("EVENT EXTENDEDSTOP (" + recordCode + ") " + datetime.toLocaleString() + " Delivered: " + (param1 / 100d) + "U RealDuration: " + param2 + "min"); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("EVENT EXTENDEDSTOP (" + recordCode + ") " + DateUtil.dateAndTimeFullString(datetime) + " (" + datetime + ")" + " Delivered: " + (param1 / 100d) + "U RealDuration: " + param2 + "min"); TreatmentsPlugin.getPlugin().addToHistoryExtendedBolus(extendedBolus); status = "EXTENDEDSTOP " + DateUtil.timeString(datetime); break; case DanaRPump.BOLUS: + DetailedBolusInfo detailedBolusInfo = DetailedBolusInfoStorage.findDetailedBolusInfo(datetime); + if (detailedBolusInfo == null) { + detailedBolusInfo = new DetailedBolusInfo(); + } + detailedBolusInfo.date = datetime; + detailedBolusInfo.source = Source.PUMP; + detailedBolusInfo.pumpId = datetime; + detailedBolusInfo.insulin = param1 / 100d; - boolean newRecord = TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo); - log.debug((newRecord ? "**NEW** " : "") + "EVENT BOLUS (" + recordCode + ") " + datetime.toLocaleString() + " Bolus: " + (param1 / 100d) + "U Duration: " + param2 + "min"); - DetailedBolusInfoStorage.remove(detailedBolusInfo.date); + boolean newRecord = TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false); + if (L.isEnabled(L.PUMPCOMM)) + log.debug((newRecord ? "**NEW** " : "") + "EVENT BOLUS (" + recordCode + ") " + DateUtil.dateAndTimeFullString(datetime) + " (" + datetime + ")" + " Bolus: " + (param1 / 100d) + "U Duration: " + param2 + "min"); status = "BOLUS " + DateUtil.timeString(datetime); break; case DanaRPump.DUALBOLUS: + detailedBolusInfo = DetailedBolusInfoStorage.findDetailedBolusInfo(datetime); + if (detailedBolusInfo == null) { + detailedBolusInfo = new DetailedBolusInfo(); + } + detailedBolusInfo.date = datetime; + detailedBolusInfo.source = Source.PUMP; + detailedBolusInfo.pumpId = datetime; + detailedBolusInfo.insulin = param1 / 100d; - newRecord = TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo); - log.debug((newRecord ? "**NEW** " : "") + "EVENT DUALBOLUS (" + recordCode + ") " + datetime.toLocaleString() + " Bolus: " + (param1 / 100d) + "U Duration: " + param2 + "min"); - DetailedBolusInfoStorage.remove(detailedBolusInfo.date); + newRecord = TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false); + if (L.isEnabled(L.PUMPCOMM)) + log.debug((newRecord ? "**NEW** " : "") + "EVENT DUALBOLUS (" + recordCode + ") " + DateUtil.dateAndTimeFullString(datetime) + " (" + datetime + ")" + " Bolus: " + (param1 / 100d) + "U Duration: " + param2 + "min"); status = "DUALBOLUS " + DateUtil.timeString(datetime); break; case DanaRPump.DUALEXTENDEDSTART: - log.debug("EVENT DUALEXTENDEDSTART (" + recordCode + ") " + datetime.toLocaleString() + " Amount: " + (param1 / 100d) + "U Duration: " + param2 + "min"); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("EVENT DUALEXTENDEDSTART (" + recordCode + ") " + DateUtil.dateAndTimeFullString(datetime) + " (" + datetime + ")" + " Amount: " + (param1 / 100d) + "U Duration: " + param2 + "min"); extendedBolus.insulin = param1 / 100d; extendedBolus.durationInMinutes = param2; TreatmentsPlugin.getPlugin().addToHistoryExtendedBolus(extendedBolus); status = "DUALEXTENDEDSTART " + DateUtil.timeString(datetime); break; case DanaRPump.DUALEXTENDEDSTOP: - log.debug("EVENT DUALEXTENDEDSTOP (" + recordCode + ") " + datetime.toLocaleString() + " Delivered: " + (param1 / 100d) + "U RealDuration: " + param2 + "min"); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("EVENT DUALEXTENDEDSTOP (" + recordCode + ") " + DateUtil.dateAndTimeFullString(datetime) + " (" + datetime + ")" + " Delivered: " + (param1 / 100d) + "U RealDuration: " + param2 + "min"); TreatmentsPlugin.getPlugin().addToHistoryExtendedBolus(extendedBolus); status = "DUALEXTENDEDSTOP " + DateUtil.timeString(datetime); break; case DanaRPump.SUSPENDON: - log.debug("EVENT SUSPENDON (" + recordCode + ") " + datetime.toLocaleString()); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("EVENT SUSPENDON (" + recordCode + ") " + DateUtil.dateAndTimeFullString(datetime) + " (" + datetime + ")"); status = "SUSPENDON " + DateUtil.timeString(datetime); break; case DanaRPump.SUSPENDOFF: - log.debug("EVENT SUSPENDOFF (" + recordCode + ") " + datetime.toLocaleString()); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("EVENT SUSPENDOFF (" + recordCode + ") " + DateUtil.dateAndTimeFullString(datetime) + " (" + datetime + ")"); status = "SUSPENDOFF " + DateUtil.timeString(datetime); break; case DanaRPump.REFILL: - log.debug("EVENT REFILL (" + recordCode + ") " + datetime.toLocaleString() + " Amount: " + param1 / 100d + "U"); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("EVENT REFILL (" + recordCode + ") " + DateUtil.dateAndTimeFullString(datetime) + " (" + datetime + ")" + " Amount: " + param1 / 100d + "U"); status = "REFILL " + DateUtil.timeString(datetime); break; case DanaRPump.PRIME: - log.debug("EVENT PRIME (" + recordCode + ") " + datetime.toLocaleString() + " Amount: " + param1 / 100d + "U"); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("EVENT PRIME (" + recordCode + ") " + DateUtil.dateAndTimeFullString(datetime) + " (" + datetime + ")" + " Amount: " + param1 / 100d + "U"); status = "PRIME " + DateUtil.timeString(datetime); break; case DanaRPump.PROFILECHANGE: - log.debug("EVENT PROFILECHANGE (" + recordCode + ") " + datetime.toLocaleString() + " No: " + param1 + " CurrentRate: " + (param2 / 100d) + "U/h"); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("EVENT PROFILECHANGE (" + recordCode + ") " + DateUtil.dateAndTimeFullString(datetime) + " (" + datetime + ")" + " No: " + param1 + " CurrentRate: " + (param2 / 100d) + "U/h"); status = "PROFILECHANGE " + DateUtil.timeString(datetime); break; case DanaRPump.CARBS: DetailedBolusInfo emptyCarbsInfo = new DetailedBolusInfo(); emptyCarbsInfo.carbs = param1; - emptyCarbsInfo.date = datetime.getTime(); + emptyCarbsInfo.date = datetime; emptyCarbsInfo.source = Source.PUMP; - emptyCarbsInfo.pumpId = datetime.getTime(); - newRecord = TreatmentsPlugin.getPlugin().addToHistoryTreatment(emptyCarbsInfo); - log.debug((newRecord ? "**NEW** " : "") + "EVENT CARBS (" + recordCode + ") " + datetime.toLocaleString() + " Carbs: " + param1 + "g"); + emptyCarbsInfo.pumpId = datetime; + newRecord = TreatmentsPlugin.getPlugin().addToHistoryTreatment(emptyCarbsInfo, false); + if (L.isEnabled(L.PUMPCOMM)) + log.debug((newRecord ? "**NEW** " : "") + "EVENT CARBS (" + recordCode + ") " + DateUtil.dateAndTimeFullString(datetime) + " (" + datetime + ")" + " Carbs: " + param1 + "g"); status = "CARBS " + DateUtil.timeString(datetime); break; default: - log.debug("Event: " + recordCode + " " + datetime.toLocaleString() + " Param1: " + param1 + " Param2: " + param2); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("Event: " + recordCode + " " + DateUtil.dateAndTimeFullString(datetime) + " (" + datetime + ")" + " Param1: " + param1 + " Param2: " + param2); status = "UNKNOWN " + DateUtil.timeString(datetime); break; } - if (datetime.getTime() > lastEventTimeLoaded) - lastEventTimeLoaded = datetime.getTime(); + if (datetime > lastEventTimeLoaded) + lastEventTimeLoaded = datetime; MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.processinghistory) + ": " + status)); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgSetAPSTempBasalStart_v2.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgSetAPSTempBasalStart_v2.java index 6b6e3045de..42964a64c6 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgSetAPSTempBasalStart_v2.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgSetAPSTempBasalStart_v2.java @@ -3,11 +3,11 @@ package info.nightscout.androidaps.plugins.PumpDanaRv2.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase; public class MsgSetAPSTempBasalStart_v2 extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgSetAPSTempBasalStart_v2.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); protected final int PARAM30MIN = 160; protected final int PARAM15MIN = 150; @@ -19,6 +19,8 @@ public class MsgSetAPSTempBasalStart_v2 extends MessageBase { public MsgSetAPSTempBasalStart_v2(int percent) { this(); setParams(percent); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message: percent: " + percent); } protected void setParams(int percent) { @@ -29,11 +31,11 @@ public class MsgSetAPSTempBasalStart_v2 extends MessageBase { AddParamInt(percent); if (percent < 100) { AddParamByte((byte) PARAM30MIN); - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("APS Temp basal start percent: " + percent + " duration 30 min"); } else { AddParamByte((byte) PARAM15MIN); - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("APS Temp basal start percent: " + percent + " duration 15 min"); } } @@ -51,11 +53,11 @@ public class MsgSetAPSTempBasalStart_v2 extends MessageBase { AddParamInt(percent); if (thirtyMinutes && percent <= 200) { // 30 min is allowed up to 200% AddParamByte((byte) PARAM30MIN); - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("APS Temp basal start percent: " + percent + " duration 30 min"); } else { AddParamByte((byte) PARAM15MIN); - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("APS Temp basal start percent: " + percent + " duration 15 min"); } } @@ -64,10 +66,11 @@ public class MsgSetAPSTempBasalStart_v2 extends MessageBase { int result = intFromBuff(bytes, 0, 1); if (result != 1) { failed = true; - log.debug("Set APS temp basal start result: " + result + " FAILED!!!"); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("Set APS temp basal start result: " + result + " FAILED!!!"); } else { failed = false; - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Set APS temp basal start result: " + result); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgSetHistoryEntry_v2.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgSetHistoryEntry_v2.java index abeb656f03..0c55b29a3f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgSetHistoryEntry_v2.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgSetHistoryEntry_v2.java @@ -6,11 +6,11 @@ import org.slf4j.LoggerFactory; import java.util.Date; import java.util.GregorianCalendar; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase; public class MsgSetHistoryEntry_v2 extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgSetHistoryEntry_v2.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgSetHistoryEntry_v2() { SetCommand(0xE004); @@ -25,7 +25,7 @@ public class MsgSetHistoryEntry_v2 extends MessageBase { AddParamDateTime(gtime); AddParamInt(param1); AddParamInt(param2); - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Set history entry: type: " + type + " date: " + new Date(time).toString() + " param1: " + param1 + " param2: " + param2); } @@ -34,9 +34,10 @@ public class MsgSetHistoryEntry_v2 extends MessageBase { int result = intFromBuff(bytes, 0, 1); if (result != 1) { failed = true; - log.debug("Set history entry result: " + result + " FAILED!!!"); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("Set history entry result: " + result + " FAILED!!!"); } else { - if (Config.logDanaMessageDetail) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Set history entry result: " + result); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgStatusAPS_v2.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgStatusAPS_v2.java index c2f87ee36a..5d0238f2f7 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgStatusAPS_v2.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgStatusAPS_v2.java @@ -3,15 +3,17 @@ package info.nightscout.androidaps.plugins.PumpDanaRv2.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase; public class MsgStatusAPS_v2 extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgStatusAPS_v2.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgStatusAPS_v2() { SetCommand(0xE001); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } public void handleMessage(byte[] bytes) { @@ -21,7 +23,7 @@ public class MsgStatusAPS_v2 extends MessageBase { DanaRPump pump = DanaRPump.getInstance(); pump.iob = iob; - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Delivered so far: " + deliveredSoFar); log.debug("Current pump IOB: " + iob); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgStatusBolusExtended_v2.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgStatusBolusExtended_v2.java index f695f6a792..5a442e39c1 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgStatusBolusExtended_v2.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgStatusBolusExtended_v2.java @@ -5,20 +5,17 @@ import android.support.annotation.NonNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Date; - -import info.nightscout.androidaps.Config; -import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.db.ExtendedBolus; -import info.nightscout.androidaps.interfaces.TreatmentsInterface; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase; public class MsgStatusBolusExtended_v2 extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgStatusBolusExtended_v2.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgStatusBolusExtended_v2() { SetCommand(0x0207); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } public void handleMessage(byte[] bytes) { @@ -34,7 +31,7 @@ public class MsgStatusBolusExtended_v2 extends MessageBase { int extendedBolusSoFarInMinutes = extendedBolusSoFarInSecs / 60; double extendedBolusAbsoluteRate = isExtendedInProgress ? extendedBolusAmount / extendedBolusMinutes * 60 : 0d; - Date extendedBolusStart = isExtendedInProgress ? getDateFromSecAgo(extendedBolusSoFarInSecs) : new Date(0); + long extendedBolusStart = isExtendedInProgress ? getDateFromSecAgo(extendedBolusSoFarInSecs) : 0; int extendedBolusRemainingMinutes = extendedBolusMinutes - extendedBolusSoFarInMinutes; DanaRPump pump = DanaRPump.getInstance(); @@ -46,7 +43,7 @@ public class MsgStatusBolusExtended_v2 extends MessageBase { pump.extendedBolusStart = extendedBolusStart; pump.extendedBolusRemainingMinutes = extendedBolusRemainingMinutes; - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Is extended bolus running: " + isExtendedInProgress); log.debug("Extended bolus min: " + extendedBolusMinutes); log.debug("Extended bolus amount: " + extendedBolusAmount); @@ -58,8 +55,8 @@ public class MsgStatusBolusExtended_v2 extends MessageBase { } @NonNull - private Date getDateFromSecAgo(int tempBasalAgoSecs) { - return new Date((long) (Math.ceil(System.currentTimeMillis() / 1000d) - tempBasalAgoSecs) * 1000); + private long getDateFromSecAgo(int tempBasalAgoSecs) { + return (long) (Math.ceil(System.currentTimeMillis() / 1000d) - tempBasalAgoSecs) * 1000; } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgStatusTempBasal_v2.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgStatusTempBasal_v2.java index 256fa4cd8a..fb26d2c0de 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgStatusTempBasal_v2.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgStatusTempBasal_v2.java @@ -5,20 +5,18 @@ import android.support.annotation.NonNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Date; - -import info.nightscout.androidaps.Config; -import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.db.TemporaryBasal; -import info.nightscout.androidaps.interfaces.TreatmentsInterface; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase; +import info.nightscout.utils.DateUtil; public class MsgStatusTempBasal_v2 extends MessageBase { - private static Logger log = LoggerFactory.getLogger(MsgStatusTempBasal_v2.class); + private Logger log = LoggerFactory.getLogger(L.PUMPCOMM); public MsgStatusTempBasal_v2() { SetCommand(0x0205); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("New message"); } public void handleMessage(byte[] bytes) { @@ -32,7 +30,7 @@ public class MsgStatusTempBasal_v2 extends MessageBase { else tempBasalTotalSec = intFromBuff(bytes, 2, 1) * 60 * 60; int tempBasalRunningSeconds = intFromBuff(bytes, 3, 3); int tempBasalRemainingMin = (tempBasalTotalSec - tempBasalRunningSeconds) / 60; - Date tempBasalStart = isTempBasalInProgress ? getDateFromTempBasalSecAgo(tempBasalRunningSeconds) : new Date(0); + long tempBasalStart = isTempBasalInProgress ? getDateFromTempBasalSecAgo(tempBasalRunningSeconds) : 0; DanaRPump pump = DanaRPump.getInstance(); pump.isTempBasalInProgress = isTempBasalInProgress; @@ -41,19 +39,19 @@ public class MsgStatusTempBasal_v2 extends MessageBase { pump.tempBasalTotalSec = tempBasalTotalSec; pump.tempBasalStart = tempBasalStart; - if (Config.logDanaMessageDetail) { + if (L.isEnabled(L.PUMPCOMM)) { log.debug("Is temp basal running: " + isTempBasalInProgress); log.debug("Is APS temp basal running: " + isAPSTempBasalInProgress); log.debug("Current temp basal percent: " + tempBasalPercent); log.debug("Current temp basal remaining min: " + tempBasalRemainingMin); log.debug("Current temp basal total sec: " + tempBasalTotalSec); - log.debug("Current temp basal start: " + tempBasalStart); + log.debug("Current temp basal start: " + DateUtil.dateAndTimeFullString(tempBasalStart)); } } @NonNull - private Date getDateFromTempBasalSecAgo(int tempBasalAgoSecs) { - return new Date((long) (Math.ceil(System.currentTimeMillis() / 1000d) - tempBasalAgoSecs) * 1000); + private long getDateFromTempBasalSecAgo(int tempBasalAgoSecs) { + return (long) (Math.ceil(System.currentTimeMillis() / 1000d) - tempBasalAgoSecs) * 1000; } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/services/DanaRv2ExecutionService.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/services/DanaRv2ExecutionService.java index 2e27122abb..f51f846978 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/services/DanaRv2ExecutionService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/services/DanaRv2ExecutionService.java @@ -1,30 +1,33 @@ package info.nightscout.androidaps.plugins.PumpDanaRv2.services; import android.bluetooth.BluetoothDevice; +import android.content.Intent; import android.content.IntentFilter; import android.os.Binder; import android.os.SystemClock; import com.squareup.otto.Subscribe; -import org.slf4j.LoggerFactory; - import java.io.IOException; import java.util.Date; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.PumpEnactResult; -import info.nightscout.androidaps.plugins.Treatments.Treatment; import info.nightscout.androidaps.events.EventAppExit; import info.nightscout.androidaps.events.EventInitializationChanged; import info.nightscout.androidaps.events.EventPreferenceChange; +import info.nightscout.androidaps.events.EventProfileSwitchChange; import info.nightscout.androidaps.events.EventPumpStatusChanged; +import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; +import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; import info.nightscout.androidaps.plugins.Overview.Dialogs.BolusProgressDialog; +import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress; import info.nightscout.androidaps.plugins.Overview.notifications.Notification; @@ -42,6 +45,7 @@ import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetExtendedBolusStop import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetTempBasalStart; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetTempBasalStop; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetTime; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSetUserOptions; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingActiveProfile; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingBasal; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingGlucose; @@ -51,6 +55,7 @@ import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingProfileRatios import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingProfileRatiosAll; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingPumpTime; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingShippingInfo; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgSettingUserOptions; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgStatus; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgStatusBasic; import info.nightscout.androidaps.plugins.PumpDanaR.events.EventDanaRNewStatus; @@ -63,19 +68,18 @@ import info.nightscout.androidaps.plugins.PumpDanaRv2.comm.MsgSetAPSTempBasalSta import info.nightscout.androidaps.plugins.PumpDanaRv2.comm.MsgSetHistoryEntry_v2; import info.nightscout.androidaps.plugins.PumpDanaRv2.comm.MsgStatusBolusExtended_v2; import info.nightscout.androidaps.plugins.PumpDanaRv2.comm.MsgStatusTempBasal_v2; +import info.nightscout.androidaps.plugins.Treatments.Treatment; import info.nightscout.androidaps.queue.Callback; +import info.nightscout.androidaps.queue.commands.Command; import info.nightscout.utils.DateUtil; -import info.nightscout.utils.NSUpload; import info.nightscout.utils.SP; import info.nightscout.utils.T; -import info.nightscout.utils.ToastUtils; public class DanaRv2ExecutionService extends AbstractDanaRExecutionService { private long lastHistoryFetched = 0; public DanaRv2ExecutionService() { - log = LoggerFactory.getLogger(DanaRv2ExecutionService.class); mBinder = new LocalBinder(); registerBus(); @@ -99,7 +103,7 @@ public class DanaRv2ExecutionService extends AbstractDanaRExecutionService { @Subscribe public void onStatusEvent(EventAppExit event) { - if (Config.logFunctionCalls) + if (L.isEnabled(L.PUMP)) log.debug("EventAppExit received"); if (mSerialIOThread != null) @@ -108,8 +112,6 @@ public class DanaRv2ExecutionService extends AbstractDanaRExecutionService { MainApp.instance().getApplicationContext().unregisterReceiver(receiver); stopSelf(); - if (Config.logFunctionCalls) - log.debug("EventAppExit finished"); } @Subscribe @@ -119,51 +121,42 @@ public class DanaRv2ExecutionService extends AbstractDanaRExecutionService { } public void connect() { - if (mDanaRPump.password != -1 && mDanaRPump.password != SP.getInt(R.string.key_danar_password, -1)) { - if(System.currentTimeMillis() > lastWrongPumpPassword + 30 * 1000) { - Notification notification = new Notification(Notification.WRONG_PUMP_PASSWORD, MainApp.gs(R.string.wrongpumppassword), Notification.URGENT); - notification.soundId = R.raw.error; - lastWrongPumpPassword = System.currentTimeMillis(); - } - return; - } - if (mConnectionInProgress) return; - new Thread(new Runnable() { - @Override - public void run() { - mConnectionInProgress = true; - getBTSocketForSelectedPump(); - if (mRfcommSocket == null || mBTDevice == null) { - mConnectionInProgress = false; - return; // Device not found - } - - try { - mRfcommSocket.connect(); - } catch (IOException e) { - //log.error("Unhandled exception", e); - if (e.getMessage().contains("socket closed")) { - log.error("Unhandled exception", e); - } - } - - if (isConnected()) { - if (mSerialIOThread != null) { - mSerialIOThread.disconnect("Recreate SerialIOThread"); - } - mSerialIOThread = new SerialIOThread(mRfcommSocket); - MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.CONNECTED, 0)); - } - + new Thread(() -> { + mHandshakeInProgress = false; + mConnectionInProgress = true; + getBTSocketForSelectedPump(); + if (mRfcommSocket == null || mBTDevice == null) { mConnectionInProgress = false; + return; // Device not found } + + try { + mRfcommSocket.connect(); + } catch (IOException e) { + //log.error("Unhandled exception", e); + if (e.getMessage().contains("socket closed")) { + log.error("Unhandled exception", e); + } + } + + if (isConnected()) { + if (mSerialIOThread != null) { + mSerialIOThread.disconnect("Recreate SerialIOThread"); + } + mSerialIOThread = new SerialIOThread(mRfcommSocket); + mHandshakeInProgress = true; + MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.HANDSHAKING, 0)); + } + + mConnectionInProgress = false; }).start(); } public void getPumpStatus() { + DanaRPump danaRPump = DanaRPump.getInstance(); try { MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.gettingpumpstatus))); MsgStatus statusMsg = new MsgStatus(); @@ -172,7 +165,7 @@ public class DanaRv2ExecutionService extends AbstractDanaRExecutionService { MsgStatusBolusExtended_v2 exStatusMsg = new MsgStatusBolusExtended_v2(); MsgCheckValue_v2 checkValue = new MsgCheckValue_v2(); - if (mDanaRPump.isNewPump) { + if (danaRPump.isNewPump) { mSerialIOThread.sendMessage(checkValue); if (!checkValue.received) { return; @@ -187,8 +180,53 @@ public class DanaRv2ExecutionService extends AbstractDanaRExecutionService { MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.gettingextendedbolusstatus))); mSerialIOThread.sendMessage(exStatusMsg); + danaRPump.lastConnection = System.currentTimeMillis(); + + Profile profile = ProfileFunctions.getInstance().getProfile(); + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); + if (profile != null && Math.abs(danaRPump.currentBasal - profile.getBasal()) >= pump.getPumpDescription().basalStep) { + MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.gettingpumpsettings))); + mSerialIOThread.sendMessage(new MsgSettingBasal()); + if (!pump.isThisProfileSet(profile) && !ConfigBuilderPlugin.getPlugin().getCommandQueue().isRunning(Command.CommandType.BASALPROFILE)) { + MainApp.bus().post(new EventProfileSwitchChange()); + } + } + + MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.gettingpumptime))); + mSerialIOThread.sendMessage(new MsgSettingPumpTime()); + long timeDiff = (danaRPump.pumpTime - System.currentTimeMillis()) / 1000L; + if (L.isEnabled(L.PUMP)) + log.debug("Pump time difference: " + timeDiff + " seconds"); + if (Math.abs(timeDiff) > 3) { + if (Math.abs(timeDiff) > 60 * 60 * 1.5) { + if (L.isEnabled(L.PUMP)) + log.debug("Pump time difference: " + timeDiff + " seconds - large difference"); + //If time-diff is very large, warn user until we can synchronize history readings properly + Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class); + i.putExtra("soundid", R.raw.error); + i.putExtra("status", MainApp.gs(R.string.largetimediff)); + i.putExtra("title", MainApp.gs(R.string.largetimedifftitle)); + i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + MainApp.instance().startActivity(i); + + //deinitialize pump + danaRPump.lastConnection = 0; + MainApp.bus().post(new EventDanaRNewStatus()); + MainApp.bus().post(new EventInitializationChanged()); + return; + } else { + waitForWholeMinute(); // Dana can set only whole minute + // add 10sec to be sure we are over minute (will be cutted off anyway) + mSerialIOThread.sendMessage(new MsgSetTime(new Date(DateUtil.now() + T.secs(10).msecs()))); + mSerialIOThread.sendMessage(new MsgSettingPumpTime()); + timeDiff = (danaRPump.pumpTime - System.currentTimeMillis()) / 1000L; + if (L.isEnabled(L.PUMP)) + log.debug("Pump time difference: " + timeDiff + " seconds"); + } + } + long now = System.currentTimeMillis(); - if (mDanaRPump.lastSettingsRead + 60 * 60 * 1000L < now || !MainApp.getSpecificPlugin(DanaRv2Plugin.class).isInitialized()) { + if (danaRPump.lastSettingsRead + 60 * 60 * 1000L < now || !pump.isInitialized()) { MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.gettingpumpsettings))); mSerialIOThread.sendMessage(new MsgSettingShippingInfo()); mSerialIOThread.sendMessage(new MsgSettingActiveProfile()); @@ -199,20 +237,9 @@ public class DanaRv2ExecutionService extends AbstractDanaRExecutionService { mSerialIOThread.sendMessage(new MsgSettingGlucose()); mSerialIOThread.sendMessage(new MsgSettingActiveProfile()); mSerialIOThread.sendMessage(new MsgSettingProfileRatios()); + mSerialIOThread.sendMessage(new MsgSettingUserOptions()); mSerialIOThread.sendMessage(new MsgSettingProfileRatiosAll()); - MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.gettingpumptime))); - mSerialIOThread.sendMessage(new MsgSettingPumpTime()); - long timeDiff = (mDanaRPump.pumpTime.getTime() - System.currentTimeMillis()) / 1000L; - log.debug("Pump time difference: " + timeDiff + " seconds"); - if (Math.abs(timeDiff) > 3) { - waitForWholeMinute(); // Dana can set only whole minute - // add 10sec to be sure we are over minute (will be cutted off anyway) - mSerialIOThread.sendMessage(new MsgSetTime(new Date(DateUtil.now() + T.secs(10).msecs()))); - mSerialIOThread.sendMessage(new MsgSettingPumpTime()); - timeDiff = (mDanaRPump.pumpTime.getTime() - System.currentTimeMillis()) / 1000L; - log.debug("Pump time difference: " + timeDiff + " seconds"); - } - mDanaRPump.lastSettingsRead = now; + danaRPump.lastSettingsRead = now; } loadEvents(); @@ -220,24 +247,25 @@ public class DanaRv2ExecutionService extends AbstractDanaRExecutionService { MainApp.bus().post(new EventDanaRNewStatus()); MainApp.bus().post(new EventInitializationChanged()); NSUpload.uploadDeviceStatus(); - if (mDanaRPump.dailyTotalUnits > mDanaRPump.maxDailyTotalUnits * Constants.dailyLimitWarning) { - log.debug("Approaching daily limit: " + mDanaRPump.dailyTotalUnits + "/" + mDanaRPump.maxDailyTotalUnits); - if(System.currentTimeMillis() > lastApproachingDailyLimit + 30 * 60 * 1000) { + if (danaRPump.dailyTotalUnits > danaRPump.maxDailyTotalUnits * Constants.dailyLimitWarning) { + if (L.isEnabled(L.PUMP)) + log.debug("Approaching daily limit: " + danaRPump.dailyTotalUnits + "/" + danaRPump.maxDailyTotalUnits); + if (System.currentTimeMillis() > lastApproachingDailyLimit + 30 * 60 * 1000) { Notification reportFail = new Notification(Notification.APPROACHING_DAILY_LIMIT, MainApp.gs(R.string.approachingdailylimit), Notification.URGENT); MainApp.bus().post(new EventNewNotification(reportFail)); - NSUpload.uploadError(MainApp.gs(R.string.approachingdailylimit) + ": " + mDanaRPump.dailyTotalUnits + "/" + mDanaRPump.maxDailyTotalUnits + "U"); + NSUpload.uploadError(MainApp.gs(R.string.approachingdailylimit) + ": " + danaRPump.dailyTotalUnits + "/" + danaRPump.maxDailyTotalUnits + "U"); lastApproachingDailyLimit = System.currentTimeMillis(); } } } catch (Exception e) { log.error("Unhandled exception", e); } - return; } public boolean tempBasal(int percent, int durationInHours) { + DanaRPump danaRPump = DanaRPump.getInstance(); if (!isConnected()) return false; - if (mDanaRPump.isTempBasalInProgress) { + if (danaRPump.isTempBasalInProgress) { MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.stoppingtempbasal))); mSerialIOThread.sendMessage(new MsgSetTempBasalStop()); SystemClock.sleep(500); @@ -251,8 +279,9 @@ public class DanaRv2ExecutionService extends AbstractDanaRExecutionService { } public boolean highTempBasal(int percent) { + DanaRPump danaRPump = DanaRPump.getInstance(); if (!isConnected()) return false; - if (mDanaRPump.isTempBasalInProgress) { + if (danaRPump.isTempBasalInProgress) { MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.stoppingtempbasal))); mSerialIOThread.sendMessage(new MsgSetTempBasalStop()); SystemClock.sleep(500); @@ -266,19 +295,20 @@ public class DanaRv2ExecutionService extends AbstractDanaRExecutionService { } public boolean tempBasalShortDuration(int percent, int durationInMinutes) { + DanaRPump danaRPump = DanaRPump.getInstance(); if (durationInMinutes != 15 && durationInMinutes != 30) { log.error("Wrong duration param"); return false; } if (!isConnected()) return false; - if (mDanaRPump.isTempBasalInProgress) { + if (danaRPump.isTempBasalInProgress) { MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.stoppingtempbasal))); mSerialIOThread.sendMessage(new MsgSetTempBasalStop()); SystemClock.sleep(500); } MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.settingtempbasal))); - mSerialIOThread.sendMessage(new MsgSetAPSTempBasalStart_v2(percent, durationInMinutes == 15, durationInMinutes == 30)); + mSerialIOThread.sendMessage(new MsgSetAPSTempBasalStart_v2(percent, durationInMinutes == 15, durationInMinutes == 30)); mSerialIOThread.sendMessage(new MsgStatusTempBasal_v2()); loadEvents(); MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.DISCONNECTING)); @@ -334,7 +364,7 @@ public class DanaRv2ExecutionService extends AbstractDanaRExecutionService { mSerialIOThread.sendMessage(msg); MsgSetHistoryEntry_v2 msgSetHistoryEntry_v2 = new MsgSetHistoryEntry_v2(DanaRPump.CARBS, carbtime, carbs, 0); mSerialIOThread.sendMessage(msgSetHistoryEntry_v2); - lastHistoryFetched = carbtime - 60000; + lastHistoryFetched = Math.min(lastHistoryFetched, carbtime - T.mins(1).msecs()); } final long bolusStart = System.currentTimeMillis(); @@ -352,7 +382,7 @@ public class DanaRv2ExecutionService extends AbstractDanaRExecutionService { if ((System.currentTimeMillis() - progress.lastReceive) > 15 * 1000L) { // if i didn't receive status for more than 15 sec expecting broken comm stop.stopped = true; stop.forced = true; - log.debug("Communication stopped"); + log.error("Communication stopped"); } } } @@ -383,7 +413,7 @@ public class DanaRv2ExecutionService extends AbstractDanaRExecutionService { SystemClock.sleep(1000); } // do not call loadEvents() directly, reconnection may be needed - ConfigBuilderPlugin.getCommandQueue().loadEvents(new Callback() { + ConfigBuilderPlugin.getPlugin().getCommandQueue().loadEvents(new Callback() { @Override public void run() { // load last bolus status @@ -397,7 +427,7 @@ public class DanaRv2ExecutionService extends AbstractDanaRExecutionService { } public void bolusStop() { - if (Config.logDanaBTComm) + if (L.isEnabled(L.PUMP)) log.debug("bolusStop >>>>> @ " + (mBolusingTreatment == null ? "" : mBolusingTreatment.insulin)); MsgBolusStop stop = new MsgBolusStop(); stop.forced = true; @@ -418,57 +448,63 @@ public class DanaRv2ExecutionService extends AbstractDanaRExecutionService { mSerialIOThread.sendMessage(msg); MsgSetHistoryEntry_v2 msgSetHistoryEntry_v2 = new MsgSetHistoryEntry_v2(DanaRPump.CARBS, time, amount, 0); mSerialIOThread.sendMessage(msgSetHistoryEntry_v2); - lastHistoryFetched = time - 1; + lastHistoryFetched = Math.min(lastHistoryFetched, time - T.mins(1).msecs()); return true; } public PumpEnactResult loadEvents() { + DanaRPump danaRPump = DanaRPump.getInstance(); + + if (!MainApp.getSpecificPlugin(DanaRv2Plugin.class).isInitialized()) { + PumpEnactResult result = new PumpEnactResult().success(false); + result.comment = "pump not initialized"; + return result; + } + + if (!isConnected()) return new PumpEnactResult().success(false); SystemClock.sleep(300); - MsgHistoryEvents_v2 msg; - if (lastHistoryFetched == 0) { - msg = new MsgHistoryEvents_v2(); - log.debug("Loading complete event history"); - } else { - msg = new MsgHistoryEvents_v2(lastHistoryFetched); - log.debug("Loading event history from: " + new Date(lastHistoryFetched).toLocaleString()); - } + MsgHistoryEvents_v2 msg = new MsgHistoryEvents_v2(lastHistoryFetched); + if (L.isEnabled(L.PUMP)) + log.debug("Loading event history from: " + DateUtil.dateAndTimeFullString(lastHistoryFetched)); + mSerialIOThread.sendMessage(msg); while (!msg.done && mRfcommSocket.isConnected()) { SystemClock.sleep(100); } SystemClock.sleep(200); if (MsgHistoryEvents_v2.lastEventTimeLoaded != 0) - lastHistoryFetched = MsgHistoryEvents_v2.lastEventTimeLoaded - 45 * 60 * 1000L; //always load last 45 min; + lastHistoryFetched = MsgHistoryEvents_v2.lastEventTimeLoaded - T.mins(1).msecs(); else lastHistoryFetched = 0; - mDanaRPump.lastConnection = System.currentTimeMillis(); + danaRPump.lastConnection = System.currentTimeMillis(); return new PumpEnactResult().success(true); } public boolean updateBasalsInPump(final Profile profile) { + DanaRPump danaRPump = DanaRPump.getInstance(); if (!isConnected()) return false; MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.updatingbasalrates))); - double[] basal = DanaRPump.buildDanaRProfileRecord(profile); + double[] basal = DanaRPump.getInstance().buildDanaRProfileRecord(profile); MsgSetBasalProfile msgSet = new MsgSetBasalProfile((byte) 0, basal); mSerialIOThread.sendMessage(msgSet); MsgSetActivateBasalProfile msgActivate = new MsgSetActivateBasalProfile((byte) 0); mSerialIOThread.sendMessage(msgActivate); - mDanaRPump.lastSettingsRead = 0; // force read full settings + danaRPump.lastSettingsRead = 0; // force read full settings getPumpStatus(); MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.DISCONNECTING)); return true; } - void waitForWholeMinute() { - while (true) { - long time = DateUtil.now(); - long timeToWholeMinute = (60000 - time % 60000); - if (timeToWholeMinute > 59800 || timeToWholeMinute < 3000) - break; - MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.waitingfortimesynchronization, (int)(timeToWholeMinute / 1000)))); - SystemClock.sleep(Math.min(timeToWholeMinute, 100)); - } + public PumpEnactResult setUserOptions() { + if (!isConnected()) + return new PumpEnactResult().success(false); + SystemClock.sleep(300); + MsgSetUserOptions msg = new MsgSetUserOptions(); + mSerialIOThread.sendMessage(msg); + SystemClock.sleep(200); + return new PumpEnactResult().success(!msg.failed); } + } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/Cstatus.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/Cstatus.java deleted file mode 100644 index 53c0cf798f..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/Cstatus.java +++ /dev/null @@ -1,20 +0,0 @@ -package info.nightscout.androidaps.plugins.PumpInsight; - -/** - * Created by jamorham on 25/01/2018. - * - * Async command status - * - */ -enum Cstatus { - UNKNOWN, - PENDING, - SUCCESS, - FAILURE, - TIMEOUT; - - boolean success() { - return this == SUCCESS; - } - -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightAsyncAdapter.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightAsyncAdapter.java deleted file mode 100644 index 3759a3f721..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightAsyncAdapter.java +++ /dev/null @@ -1,95 +0,0 @@ -package info.nightscout.androidaps.plugins.PumpInsight; - -import android.os.PowerManager; - -import com.squareup.otto.Subscribe; - -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; - -import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.plugins.PumpInsight.events.EventInsightCallback; - -import static info.nightscout.androidaps.plugins.PumpInsight.utils.Helpers.getWakeLock; -import static info.nightscout.androidaps.plugins.PumpInsight.utils.Helpers.msSince; -import static info.nightscout.androidaps.plugins.PumpInsight.utils.Helpers.releaseWakeLock; -import static info.nightscout.androidaps.plugins.PumpInsight.utils.Helpers.tsl; - -/** - * Created by jamorham on 25/01/2018. - * - * Asynchronous adapter - * - */ - -public class InsightAsyncAdapter { - - private final ConcurrentHashMap commandResults = new ConcurrentHashMap<>(); - - InsightAsyncAdapter() { - MainApp.bus().register(this); - } - - // just log during debugging - private static void log(String msg) { - android.util.Log.e("INSIGHTPUMPASYNC", msg); - } - - @Subscribe - public void onStatusEvent(final EventInsightCallback ev) { - log("Received callback event: " + ev.toString()); - commandResults.put(ev.request_uuid, ev); - } - - // poll command result - private Cstatus checkCommandResult(UUID uuid) { - if (uuid == null) return Cstatus.FAILURE; - if (commandResults.containsKey(uuid)) { - if (commandResults.get(uuid).success) { - return Cstatus.SUCCESS; - } else { - return Cstatus.FAILURE; - } - } else { - return Cstatus.PENDING; - } - } - - // blocking call to wait for result callback - private Cstatus busyWaitForCommandInternal(final UUID uuid, long wait_time) { - final PowerManager.WakeLock wl = getWakeLock("insight-wait-cmd", 60000); - try { - log("busy wait for command " + uuid); - if (uuid == null) return Cstatus.FAILURE; - final long start_time = tsl(); - Cstatus status = checkCommandResult(uuid); - while ((status == Cstatus.PENDING) && msSince(start_time) < wait_time) { - //log("command result waiting"); - try { - Thread.sleep(200); - } catch (InterruptedException e) { - log("Got interrupted exception! " + e); - } - status = checkCommandResult(uuid); - } - if (status == Cstatus.PENDING) { - return Cstatus.TIMEOUT; - } else { - return status; - } - } finally { - releaseWakeLock(wl); - } - } - - // wait for and then package result, cleanup and return - Mstatus busyWaitForCommandResult(final UUID uuid, long wait_time) { - final Mstatus mstatus = new Mstatus(); - mstatus.cstatus = busyWaitForCommandInternal(uuid, wait_time); - mstatus.event = commandResults.get(uuid); - commandResults.remove(uuid); - return mstatus; - } - - -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightFragment.java index 156c8271e3..5d3c3850b3 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightFragment.java @@ -9,7 +9,6 @@ import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; - import com.squareup.otto.Subscribe; import org.slf4j.Logger; @@ -18,6 +17,7 @@ import org.slf4j.LoggerFactory; import java.util.List; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.PumpInsight.events.EventInsightUpdateGui; import info.nightscout.androidaps.plugins.PumpInsight.utils.StatusItem; @@ -26,7 +26,7 @@ import info.nightscout.utils.FabricPrivacy; public class InsightFragment extends SubscriberFragment { - private static final Logger log = LoggerFactory.getLogger(InsightFragment.class); + private static final Logger log = LoggerFactory.getLogger(L.PUMP); private static final Handler sLoopHandler = new Handler(); private static volatile boolean refresh = false; private static volatile boolean pending = false; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightPlugin.java index 824a449f38..c72da31fdf 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightPlugin.java @@ -1,5 +1,10 @@ package info.nightscout.androidaps.plugins.PumpInsight; +import android.content.DialogInterface; +import android.os.SystemClock; +import android.support.v4.app.FragmentActivity; +import android.support.v7.app.AlertDialog; + import org.json.JSONException; import org.json.JSONObject; import org.slf4j.Logger; @@ -7,9 +12,7 @@ import org.slf4j.LoggerFactory; import java.text.DecimalFormat; import java.util.ArrayList; -import java.util.Date; import java.util.List; -import java.util.UUID; import info.nightscout.androidaps.BuildConfig; import info.nightscout.androidaps.Config; @@ -21,7 +24,6 @@ import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.db.ExtendedBolus; import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.TemporaryBasal; -import info.nightscout.androidaps.plugins.Treatments.Treatment; import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.ConstraintsInterface; import info.nightscout.androidaps.interfaces.PluginBase; @@ -29,11 +31,17 @@ import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.PumpDescription; import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderFragment; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; +import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress; import info.nightscout.androidaps.plugins.Overview.notifications.Notification; -import info.nightscout.androidaps.plugins.PumpInsight.connector.CancelBolusTaskRunner; +import info.nightscout.androidaps.plugins.PumpCommon.defs.PumpType; +import info.nightscout.androidaps.plugins.PumpInsight.connector.CancelBolusSilentlyTaskRunner; +import info.nightscout.androidaps.plugins.PumpInsight.connector.CancelTBRSilentlyTaskRunner; import info.nightscout.androidaps.plugins.PumpInsight.connector.Connector; import info.nightscout.androidaps.plugins.PumpInsight.connector.SetTBRTaskRunner; import info.nightscout.androidaps.plugins.PumpInsight.connector.StatusTaskRunner; @@ -44,18 +52,18 @@ import info.nightscout.androidaps.plugins.PumpInsight.history.HistoryReceiver; import info.nightscout.androidaps.plugins.PumpInsight.history.LiveHistory; import info.nightscout.androidaps.plugins.PumpInsight.utils.Helpers; import info.nightscout.androidaps.plugins.PumpInsight.utils.StatusItem; +import info.nightscout.androidaps.plugins.Treatments.Treatment; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.utils.DateUtil; -import info.nightscout.utils.NSUpload; import info.nightscout.utils.SP; import sugar.free.sightparser.applayer.descriptors.ActiveBolus; import sugar.free.sightparser.applayer.descriptors.ActiveBolusType; +import sugar.free.sightparser.applayer.descriptors.MessagePriority; import sugar.free.sightparser.applayer.descriptors.PumpStatus; import sugar.free.sightparser.applayer.descriptors.configuration_blocks.BRProfileBlock; import sugar.free.sightparser.applayer.messages.AppLayerMessage; import sugar.free.sightparser.applayer.messages.remote_control.BolusMessage; import sugar.free.sightparser.applayer.messages.remote_control.CancelBolusMessage; -import sugar.free.sightparser.applayer.messages.remote_control.CancelTBRMessage; import sugar.free.sightparser.applayer.messages.remote_control.ExtendedBolusMessage; import sugar.free.sightparser.applayer.messages.remote_control.StandardBolusMessage; import sugar.free.sightparser.applayer.messages.status.ActiveBolusesMessage; @@ -78,6 +86,7 @@ import static info.nightscout.androidaps.plugins.PumpInsight.history.PumpIdCache @SuppressWarnings("AccessStaticViaInstance") public class InsightPlugin extends PluginBase implements PumpInterface, ConstraintsInterface { + private Logger log = LoggerFactory.getLogger(L.PUMP); private static volatile InsightPlugin plugin; @@ -93,11 +102,9 @@ public class InsightPlugin extends PluginBase implements PumpInterface, Constrai private static Integer reservoirInUnits = 0; private static boolean initialized = false; private static volatile boolean update_pending = false; - private static Logger log = LoggerFactory.getLogger(InsightPlugin.class); - private final InsightAsyncAdapter async = new InsightAsyncAdapter(); private StatusTaskRunner.Result statusResult; private long statusResultTime = -1; - private Date lastDataTime = new Date(0); + private long lastDataTime = 0; private boolean fauxTBRcancel = true; private PumpDescription pumpDescription = new PumpDescription(); private double basalRate = 0; @@ -112,47 +119,14 @@ public class InsightPlugin extends PluginBase implements PumpInterface, Constrai .pluginName(R.string.insightpump) .shortName(R.string.insightpump_shortname) .preferencesId(R.xml.pref_insightpump) + .description(R.string.description_pump_insight) ); - log("InsightPlugin instantiated"); - pumpDescription.isBolusCapable = true; - pumpDescription.bolusStep = 0.05d; // specification says 0.05U up to 2U then 0.1U @ 2-5U 0.2U @ 10-20U 0.5U 10-20U (are these just UI restrictions?) - - pumpDescription.isExtendedBolusCapable = true; - pumpDescription.extendedBolusStep = 0.05d; // specification probably same as above - pumpDescription.extendedBolusDurationStep = 15; // 15 minutes up to 24 hours - pumpDescription.extendedBolusMaxDuration = 24 * 60; - - pumpDescription.isTempBasalCapable = true; - //pumpDescription.tempBasalStyle = PumpDescription.PERCENT | PumpDescription.ABSOLUTE; - pumpDescription.tempBasalStyle = PumpDescription.PERCENT; - - pumpDescription.maxTempPercent = 250; // 0-250% - pumpDescription.tempPercentStep = 10; - - pumpDescription.tempDurationStep = 15; // 15 minutes up to 24 hours - pumpDescription.tempDurationStep15mAllowed = true; - pumpDescription.tempDurationStep30mAllowed = true; - pumpDescription.tempMaxDuration = 24 * 60; - - pumpDescription.isSetBasalProfileCapable = true; - pumpDescription.is30minBasalRatesCapable = true; - pumpDescription.basalStep = 0.01d; - pumpDescription.basalMinimumRate = 0.02d; - - pumpDescription.isRefillingCapable = true; - - pumpDescription.storesCarbInfo = false; - - pumpDescription.supportsTDDs = true; - pumpDescription.needsManualTDDLoad = false; + if (L.isEnabled(L.PUMP)) + log.debug("InsightPlugin instantiated"); + pumpDescription.setPumpDescription(PumpType.AccuChekInsight); } - // just log during debugging - private static void log(String msg) { - android.util.Log.e("INSIGHTPUMP", msg); - } - private static void updateGui() { update_pending = false; MainApp.bus().post(new EventInsightUpdateGui()); @@ -167,7 +141,8 @@ public class InsightPlugin extends PluginBase implements PumpInterface, Constrai if (!connector_enabled) { synchronized (this) { if (!connector_enabled) { - log("Instantiating connector"); + if (L.isEnabled(L.PUMP)) + log.debug("Instantiating connector"); connector_enabled = true; this.connector = Connector.get(); this.connector.init(); @@ -181,7 +156,8 @@ public class InsightPlugin extends PluginBase implements PumpInterface, Constrai if (connector_enabled) { synchronized (this) { if (connector_enabled) { - log("Shutting down connector"); + if (L.isEnabled(L.PUMP)) + log.debug("Shutting down connector"); Connector.get().shutdown(); connector_enabled = false; } @@ -191,7 +167,7 @@ public class InsightPlugin extends PluginBase implements PumpInterface, Constrai @Override public boolean isFakingTempsByExtendedBoluses() { - return false; + return true; } @Override @@ -201,6 +177,31 @@ public class InsightPlugin extends PluginBase implements PumpInterface, Constrai return result; } + @Override + public void switchAllowed(ConfigBuilderFragment.PluginViewHolder.PluginSwitcher pluginSwitcher, FragmentActivity context) { + boolean allowHardwarePump = SP.getBoolean("allow_hardware_pump", false); + if (allowHardwarePump || context == null) { + pluginSwitcher.invoke(); + } else { + AlertDialog.Builder builder = new AlertDialog.Builder(context); + builder.setMessage(R.string.allow_hardware_pump_text) + .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + pluginSwitcher.invoke(); + SP.putBoolean("allow_hardware_pump", true); + log.debug("First time HW pump allowed!"); + } + }) + .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + pluginSwitcher.cancel(); + log.debug("User does not allow switching to HW pump!"); + } + }); + builder.create().show(); + } + } + @Override public boolean isInitialized() { return initialized; @@ -226,79 +227,98 @@ public class InsightPlugin extends PluginBase implements PumpInterface, Constrai return Connector.get().isPumpConnecting(); } + @Override + public boolean isHandshakeInProgress() { + return false; + } + + @Override + public void finishHandshaking() { + } + @Override public void connect(String reason) { - log("InsightPlugin::connect()"); + if (L.isEnabled(L.PUMP)) + log.debug("InsightPlugin::connect()"); try { if (!connector.isPumpConnected()) { if (Helpers.ratelimit("insight-connect-timer", 40)) { - log("Actually requesting a connect"); + if (L.isEnabled(L.PUMP)) + log.debug("Actually requesting a connect"); connector.connectToPump(); } } else { - log("Already connected"); + if (L.isEnabled(L.PUMP)) + log.debug("Already connected"); } } catch (NullPointerException e) { - log("Could not sconnect - null pointer: " + e); + log.error("Could not sconnect - null pointer: " + e); } // TODO review - if (!Config.NSCLIENT && !Config.G5UPLOADER) + if (!Config.NSCLIENT) NSUpload.uploadDeviceStatus(); } @Override public void disconnect(String reason) { - log("InsightPlugin::disconnect()"); + if (L.isEnabled(L.PUMP)) + log.debug("InsightPlugin::disconnect()"); try { if (!SP.getBoolean("insight_always_connected", false)) { - log("Requesting disconnect"); + if (L.isEnabled(L.PUMP)) + log.debug("Requesting disconnect"); connector.disconnectFromPump(); } else { - log("Not disconnecting due to preference"); + if (L.isEnabled(L.PUMP)) + log.debug("Not disconnecting due to preference"); } } catch (NullPointerException e) { - log("Could not disconnect - null pointer: " + e); + log.error("Could not disconnect - null pointer: " + e); } } @Override public void stopConnecting() { - log("InsightPlugin::stopConnecting()"); + if (L.isEnabled(L.PUMP)) + log.debug("InsightPlugin::stopConnecting()"); try { if (isConnecting()) { if (!SP.getBoolean("insight_always_connected", false)) { - log("Requesting disconnect"); + if (L.isEnabled(L.PUMP)) + log.debug("Requesting disconnect"); connector.disconnectFromPump(); } else { - log("Not disconnecting due to preference"); + if (L.isEnabled(L.PUMP)) + log.debug("Not disconnecting due to preference"); } } else { - log("Not currently trying to connect so not stopping connection"); + if (L.isEnabled(L.PUMP)) + log.debug("Not currently trying to connect so not stopping connection"); } } catch (NullPointerException e) { - log("Could not stop connecting - null pointer: " + e); + log.error("Could not stop connecting - null pointer: " + e); } } @Override public void getPumpStatus() { - - log("getPumpStatus"); + if (L.isEnabled(L.PUMP)) + log.debug("getPumpStatus"); if (Connector.get().isPumpConnected()) { - log("is connected.. requesting status"); - final UUID uuid = aSyncTaskRunner(new StatusTaskRunner(connector.getServiceConnector()), "Status"); - Mstatus mstatus = async.busyWaitForCommandResult(uuid, BUSY_WAIT_TIME); - if (mstatus.success()) { - log("GOT STATUS RESULT!!! PARTY WOOHOO!!!"); - setStatusResult((StatusTaskRunner.Result) mstatus.getResponseObject()); + if (L.isEnabled(L.PUMP)) + log.debug("is connected.. requesting status"); + try { + setStatusResult(fetchTaskRunner(new StatusTaskRunner(connector.getServiceConnector()), StatusTaskRunner.Result.class)); + if (L.isEnabled(L.PUMP)) + log.debug("GOT STATUS RESULT!!! PARTY WOOHOO!!!"); statusResultTime = Helpers.tsl(); processStatusResult(); updateGui(); connector.requestHistoryReSync(); connector.requestHistorySync(); - } else { - log("StatusTaskRunner wasn't successful."); + } catch (Exception e) { + log.error("StatusTaskRunner wasn't successful."); if (connector.getServiceConnector().isConnectedToService() && connector.getServiceConnector().getStatus() != Status.CONNECTED) { if (Helpers.ratelimit("insight-reconnect", 2)) { Connector.connectToPump(); @@ -307,12 +327,15 @@ public class InsightPlugin extends PluginBase implements PumpInterface, Constrai } } } else { - log("not connected.. not requesting status"); + if (L.isEnabled(L.PUMP)) + log.debug("not connected.. not requesting status"); } } public void setStatusResult(StatusTaskRunner.Result result) { this.statusResult = result; + this.pumpDescription.basalMinimumRate = result.minimumBasalAmount; + this.pumpDescription.basalMaximumRate = result.maximumBasalAmount; } @Override @@ -333,11 +356,11 @@ public class InsightPlugin extends PluginBase implements PumpInterface, Constrai if (profile.getBasalValues().length > i + 1) nextValue = profile.getBasalValues()[i + 1]; profileBlocks.add(new BRProfileBlock.ProfileBlock((((nextValue != null ? nextValue.timeAsSeconds : 24 * 60 * 60) - basalValue.timeAsSeconds) / 60), Helpers.roundDouble(basalValue.value, 2))); - log("setNewBasalProfile: " + basalValue.value + " for " + Integer.toString(((nextValue != null ? nextValue.timeAsSeconds : 24 * 60 * 60) - basalValue.timeAsSeconds) / 60)); + if (L.isEnabled(L.PUMP)) + log.debug("setNewBasalProfile: " + basalValue.value + " for " + Integer.toString(((nextValue != null ? nextValue.timeAsSeconds : 24 * 60 * 60) - basalValue.timeAsSeconds) / 60)); } - final UUID uuid = aSyncTaskRunner(new WriteBasalProfileTaskRunner(connector.getServiceConnector(), profileBlocks), "Write basal profile"); - final Mstatus ms = async.busyWaitForCommandResult(uuid, BUSY_WAIT_TIME); - if (ms.success()) { + try { + fetchTaskRunner(new WriteBasalProfileTaskRunner(connector.getServiceConnector(), profileBlocks)); MainApp.bus().post(new EventDismissNotification(Notification.FAILED_UDPATE_PROFILE)); Notification notification = new Notification(Notification.PROFILE_SET_OK, MainApp.gs(R.string.profile_set_ok), Notification.INFO, 60); MainApp.bus().post(new EventNewNotification(notification)); @@ -345,7 +368,7 @@ public class InsightPlugin extends PluginBase implements PumpInterface, Constrai result.enacted = true; result.comment = "OK"; this.profileBlocks = profileBlocks; - } else { + } catch (Exception e) { Notification notification = new Notification(Notification.FAILED_UDPATE_PROFILE, MainApp.gs(R.string.failedupdatebasalprofile), Notification.URGENT); MainApp.bus().post(new EventNewNotification(notification)); result.comment = MainApp.gs(R.string.failedupdatebasalprofile); @@ -363,8 +386,9 @@ public class InsightPlugin extends PluginBase implements PumpInterface, Constrai Profile.BasalValue nextValue = null; if (profile.getBasalValues().length > i + 1) nextValue = profile.getBasalValues()[i + 1]; - log("isThisProfileSet - Comparing block: Pump: " + profileBlock.getAmount() + " for " + profileBlock.getDuration() - + " Profile: " + basalValue.value + " for " + Integer.toString(((nextValue != null ? nextValue.timeAsSeconds : 24 * 60 * 60) - basalValue.timeAsSeconds) / 60)); + if (L.isEnabled(L.PUMP)) + log.debug("isThisProfileSet - Comparing block: Pump: " + profileBlock.getAmount() + " for " + profileBlock.getDuration() + + " Profile: " + basalValue.value + " for " + Integer.toString(((nextValue != null ? nextValue.timeAsSeconds : 24 * 60 * 60) - basalValue.timeAsSeconds) / 60)); if (profileBlock.getDuration() * 60 != (nextValue != null ? nextValue.timeAsSeconds : 24 * 60 * 60) - basalValue.timeAsSeconds) return false; //Allow a little imprecision due to rounding errors @@ -375,7 +399,7 @@ public class InsightPlugin extends PluginBase implements PumpInterface, Constrai } @Override - public Date lastDataTime() { + public long lastDataTime() { return lastDataTime; } @@ -403,23 +427,20 @@ public class InsightPlugin extends PluginBase implements PumpInterface, Constrai // is there an insulin component to the treatment? if (detailedBolusInfo.insulin > 0) { - final UUID cmd = deliverBolus(detailedBolusInfo.insulin); // actually request delivery - if (cmd == null) { + try { + bolusId = deliverBolus(detailedBolusInfo.insulin); + result.success = true; + detailedBolusInfo.pumpId = getRecordUniqueID(bolusId); + } catch (Exception e) { return pumpEnactFailure(); } - final Mstatus ms = async.busyWaitForCommandResult(cmd, BUSY_WAIT_TIME); - - result.success = ms.success(); - if (ms.success()) { - detailedBolusInfo.pumpId = getRecordUniqueID(ms.getResponseID()); - bolusId = ms.getResponseID(); - } } else { result.success = true; // always true with carb only treatments } if (result.success) { - log("Success!"); + if (L.isEnabled(L.PUMP)) + log.debug("Success!"); Treatment t = new Treatment(); t.isSMB = detailedBolusInfo.isSMB; @@ -429,31 +450,23 @@ public class InsightPlugin extends PluginBase implements PumpInterface, Constrai bolusingEvent.bolusId = bolusId; bolusingEvent.percent = 0; MainApp.bus().post(bolusingEvent); - TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo); + TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, true); } else { - log.debug("Failure to deliver treatment"); + if (L.isEnabled(L.PUMP)) + log.debug("Failure to deliver treatment"); } - if (Config.logPumpComm) + if (L.isEnabled(L.PUMP)) log.debug("Delivering treatment insulin: " + detailedBolusInfo.insulin + "U carbs: " + detailedBolusInfo.carbs + "g " + result); updateGui(); connector.tryToGetPumpStatusAgain(); - connector.requestHistorySync(30000); - if (result.success) while (true) { try { - Thread.sleep(200); - } catch (InterruptedException e) { - e.printStackTrace(); - break; - } - final UUID uuid = aSyncSingleCommand(new ActiveBolusesMessage(), "Active boluses"); - Mstatus mstatus = async.busyWaitForCommandResult(uuid, BUSY_WAIT_TIME); - if (mstatus.success()) { + Thread.sleep(500); final EventOverviewBolusProgress bolusingEvent = EventOverviewBolusProgress.getInstance(); - ActiveBolusesMessage activeBolusesMessage = (ActiveBolusesMessage) mstatus.getResponseObject(); + ActiveBolusesMessage activeBolusesMessage = fetchSingleMessage(new ActiveBolusesMessage(), ActiveBolusesMessage.class); ActiveBolus activeBolus = null; if (activeBolusesMessage.getBolus1() != null && activeBolusesMessage.getBolus1().getBolusID() == bolusingEvent.bolusId) activeBolus = activeBolusesMessage.getBolus1(); @@ -463,170 +476,124 @@ public class InsightPlugin extends PluginBase implements PumpInterface, Constrai activeBolus = activeBolusesMessage.getBolus3(); if (activeBolus == null) break; else { + int percentBefore = bolusingEvent.percent; bolusingEvent.percent = (int) (100D / activeBolus.getInitialAmount() * (activeBolus.getInitialAmount() - activeBolus.getLeftoverAmount())); bolusingEvent.status = String.format(MainApp.gs(R.string.bolusdelivering), activeBolus.getInitialAmount() - activeBolus.getLeftoverAmount()); - MainApp.bus().post(bolusingEvent); + if (percentBefore != bolusingEvent.percent) MainApp.bus().post(bolusingEvent); } - } else break; + } catch (Exception e) { + break; + } } + + connector.requestHistorySync(2000); return result; } @Override public void stopBolusDelivering() { CancelBolusMessage cancelBolusMessage = new CancelBolusMessage(); + cancelBolusMessage.setMessagePriority(MessagePriority.HIGHEST); cancelBolusMessage.setBolusId(EventOverviewBolusProgress.getInstance().bolusId); - final UUID cmd = aSyncSingleCommand(cancelBolusMessage, "Cancel standard bolus"); - - if (cmd == null) { - return; + try { + fetchSingleMessage(cancelBolusMessage); + } catch (Exception e) { } - - final Mstatus cs = async.busyWaitForCommandResult(cmd, BUSY_WAIT_TIME); - log("Got command status: " + cs); } // Temporary Basals @Override public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, Profile profile, boolean enforceNew) { - absoluteRate = Helpers.roundDouble(absoluteRate, 3); - log("Set TBR absolute: " + absoluteRate); - final double base_basal = getBaseBasalRate(); - if (base_basal == 0) { - log("Base basal rate appears to be zero!"); + if (L.isEnabled(L.PUMP)) + log.debug("Set TBR absolute: " + absoluteRate); + if (getBaseBasalRate() == 0) { + if (L.isEnabled(L.PUMP)) + log.debug("Base basal rate appears to be zero!"); return pumpEnactFailure(); } - int percent_amount = (int) Math.round(100d / base_basal * absoluteRate); - log("Calculated requested rate: " + absoluteRate + " base rate: " + base_basal + " percentage: " + percent_amount + "%"); - percent_amount = (int) Math.round(((double) percent_amount) / 10d) * 10; - log("Calculated final rate: " + percent_amount + "%"); - - if (percent_amount == 100) { - return cancelTempBasal(false); - } - - if (percent_amount > 250) percent_amount = 250; - - - final SetTBRTaskRunner task = new SetTBRTaskRunner(connector.getServiceConnector(), percent_amount, durationInMinutes); - final UUID cmd = aSyncTaskRunner(task, "Set TBR abs: " + absoluteRate + " " + durationInMinutes + "m"); - - if (cmd == null) { + double percent = 100D / getBaseBasalRate() * absoluteRate; + if (L.isEnabled(L.PUMP)) + log.debug("Calculated requested rate: " + absoluteRate + " base rate: " + getBaseBasalRate() + " percentage: " + percent + "%"); + try { + if (percent > 250) { + if (L.isEnabled(L.PUMP)) + log.debug("Calculated rate is above 250%, switching to emulation using extended boluses"); + cancelTempBasal(true); + if (!setExtendedBolus((absoluteRate - getBaseBasalRate()) / 60D * ((double) durationInMinutes), durationInMinutes).success) { + //Fallback to TBR if setting an extended bolus didn't work + if (L.isEnabled(L.PUMP)) + log.debug("Setting an extended bolus didn't work, falling back to normal TBR"); + return setTempBasalPercent((int) percent, durationInMinutes, profile, true); + } + return new PumpEnactResult().success(true).enacted(true).absolute(absoluteRate).duration(durationInMinutes); + } else { + if (L.isEnabled(L.PUMP)) + log.debug("Calculated rate is below or equal to 250%, using normal TBRs"); + cancelExtendedBolus(); + return setTempBasalPercent((int) percent, durationInMinutes, profile, true); + } + } catch (Exception e) { return pumpEnactFailure(); } - - Mstatus ms = async.busyWaitForCommandResult(cmd, BUSY_WAIT_TIME); - log("Got command status: " + ms); - - PumpEnactResult pumpEnactResult = new PumpEnactResult().enacted(true).isPercent(true).duration(durationInMinutes); - pumpEnactResult.percent = percent_amount; - pumpEnactResult.success = ms.success(); - pumpEnactResult.comment = ms.getCommandComment(); - - - if (pumpEnactResult.success) { - // create log entry - final TemporaryBasal tempBasal = new TemporaryBasal() - .date(System.currentTimeMillis()) - .percent(percent_amount) - .duration(durationInMinutes) - .source(Source.USER); - TreatmentsPlugin.getPlugin().addToHistoryTempBasal(tempBasal); - } - - if (Config.logPumpComm) - log.debug("Setting temp basal absolute: " + pumpEnactResult.success); - - updateGui(); - - connector.requestHistorySync(5000); - connector.tryToGetPumpStatusAgain(); - - return pumpEnactResult; } @Override public PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes, Profile profile, boolean enforceNew) { - log("Set TBR %"); + if (L.isEnabled(L.PUMP)) + log.debug("Set TBR %"); percent = (int) Math.round(((double) percent) / 10d) * 10; if (percent == 100) { // This would cause a cancel if a tbr is in progress so treat as a cancel return cancelTempBasal(false); - } + } else if (percent > 250) percent = 250; - - final UUID cmd = aSyncTaskRunner(new SetTBRTaskRunner(connector.getServiceConnector(), percent, durationInMinutes), "Set TBR " + percent + "%" + " " + durationInMinutes + "m"); - - if (cmd == null) { - return pumpEnactFailure(); - } - - final Mstatus ms = async.busyWaitForCommandResult(cmd, BUSY_WAIT_TIME); - log("Got command status: " + ms); - - PumpEnactResult pumpEnactResult = new PumpEnactResult().enacted(true).isPercent(true).duration(durationInMinutes); - pumpEnactResult.percent = percent; - pumpEnactResult.success = ms.success(); - pumpEnactResult.comment = ms.getCommandComment(); - - if (pumpEnactResult.success) { - // create log entry + try { + fetchTaskRunner(new SetTBRTaskRunner(connector.getServiceConnector(), percent, durationInMinutes)); final TemporaryBasal tempBasal = new TemporaryBasal() .date(System.currentTimeMillis()) .percent(percent) .duration(durationInMinutes) - .source(Source.USER); // TODO check this is correct + .source(Source.USER); TreatmentsPlugin.getPlugin().addToHistoryTempBasal(tempBasal); + updateGui(); + if (L.isEnabled(L.PUMP)) + log.debug("Set temp basal " + percent + "% for " + durationInMinutes + "m"); + connector.requestHistorySync(5000); + connector.tryToGetPumpStatusAgain(); + return new PumpEnactResult().success(true).enacted(true).percent(percent); + } catch (Exception e) { + return pumpEnactFailure(); } - - updateGui(); - - if (Config.logPumpComm) - log.debug("Set temp basal " + percent + "% for " + durationInMinutes + "m"); - - connector.requestHistorySync(5000); - connector.tryToGetPumpStatusAgain(); - - return pumpEnactResult; } @Override public PumpEnactResult cancelTempBasal(boolean enforceNew) { - log("Cancel TBR"); + if (L.isEnabled(L.PUMP)) + log.debug("Cancel TBR called"); - - fauxTBRcancel = !SP.getBoolean("insight_real_tbr_cancel", false); - - final UUID cmd; - - if (fauxTBRcancel) { - cmd = aSyncTaskRunner(new SetTBRTaskRunner(connector.getServiceConnector(), 100, 1), "Faux Cancel TBR - setting " + "90%" + " 1m"); - } else { - cmd = aSyncSingleCommand(new CancelTBRMessage(), "Cancel Temp Basal"); - } - if (cmd == null) { + try { + cancelExtendedBolus(); + SystemClock.sleep(1100); // to be sure db records are at least 1 sec off (for NS) + realTBRCancel(); + SystemClock.sleep(1100); // to be sure db records are at least 1 sec off (for NS) + updateGui(); + connector.requestHistorySync(5000); + connector.tryToGetPumpStatusAgain(); + return new PumpEnactResult().success(true).enacted(true).isTempCancel(true); + } catch (Exception e) { return pumpEnactFailure(); } + } - // TODO isn't conditional on one apparently being in progress only the history change - final Mstatus ms = async.busyWaitForCommandResult(cmd, BUSY_WAIT_TIME); - - if (TreatmentsPlugin.getPlugin().isTempBasalInProgress()) { + private void realTBRCancel() throws Exception { + if (fetchTaskRunner(new CancelTBRSilentlyTaskRunner(connector.getServiceConnector()), Boolean.class) && TreatmentsPlugin.getPlugin().isTempBasalInProgress()) { TemporaryBasal tempStop = new TemporaryBasal().date(System.currentTimeMillis()).source(Source.USER); TreatmentsPlugin.getPlugin().addToHistoryTempBasal(tempStop); } - updateGui(); - if (Config.logPumpComm) - log.debug("Canceling temp basal: "); // TODO get more info - - connector.requestHistorySync(5000); - connector.tryToGetPumpStatusAgain(); - - return new PumpEnactResult().success(ms.success()).enacted(true).isTempCancel(true); } @@ -634,96 +601,69 @@ public class InsightPlugin extends PluginBase implements PumpInterface, Constrai @Override public PumpEnactResult setExtendedBolus(Double insulin, Integer durationInMinutes) { - log("Set Extended bolus " + insulin + " " + durationInMinutes); - ExtendedBolusMessage extendedBolusMessage = new ExtendedBolusMessage(); - extendedBolusMessage.setAmount(insulin); - extendedBolusMessage.setDuration(durationInMinutes); - final UUID cmd = aSyncSingleCommand(extendedBolusMessage, "Extended bolus U" + insulin + " mins:" + durationInMinutes); - if (cmd == null) { + if (L.isEnabled(L.PUMP)) + log.debug("Set Extended bolus " + insulin + " " + durationInMinutes); + try { + ExtendedBolusMessage extendedBolusMessage = new ExtendedBolusMessage(); + extendedBolusMessage.setAmount(insulin); + extendedBolusMessage.setDuration(durationInMinutes); + BolusMessage bolusMessage = fetchSingleMessage(extendedBolusMessage, BolusMessage.class); + final ExtendedBolus extendedBolus = new ExtendedBolus() + .date(System.currentTimeMillis()) + .insulin(insulin) + .durationInMinutes(durationInMinutes) + .source(Source.USER) + .pumpId(getRecordUniqueID(bolusMessage.getBolusId())); + TreatmentsPlugin.getPlugin().addToHistoryExtendedBolus(extendedBolus); + updateGui(); + connector.requestHistorySync(30000); + connector.tryToGetPumpStatusAgain(); + return new PumpEnactResult().success(true).enacted(true).duration(durationInMinutes).bolusDelivered(insulin); + } catch (Exception e) { return pumpEnactFailure(); } - - final Mstatus ms = async.busyWaitForCommandResult(cmd, BUSY_WAIT_TIME); - log("Got command status: " + ms); - - PumpEnactResult pumpEnactResult = new PumpEnactResult().enacted(true).bolusDelivered(insulin).duration(durationInMinutes); - pumpEnactResult.success = ms.success(); - pumpEnactResult.comment = ms.getCommandComment(); - - if (pumpEnactResult.success) { - // create log entry - final ExtendedBolus extendedBolus = new ExtendedBolus(); - extendedBolus.date = System.currentTimeMillis(); - extendedBolus.insulin = insulin; - extendedBolus.durationInMinutes = durationInMinutes; - extendedBolus.source = Source.USER; - extendedBolus.pumpId = getRecordUniqueID(ms.getResponseID()); - TreatmentsPlugin.getPlugin().addToHistoryExtendedBolus(extendedBolus); - } - - if (Config.logPumpComm) - log.debug("Setting extended bolus: " + insulin + " mins:" + durationInMinutes + " " + pumpEnactResult.comment); - - updateGui(); - - connector.requestHistorySync(30000); - connector.tryToGetPumpStatusAgain(); - - return pumpEnactResult; } @Override public PumpEnactResult cancelExtendedBolus() { + if (L.isEnabled(L.PUMP)) + log.debug("Cancel Extended bolus called"); - log("Cancel Extended bolus"); + Integer bolusId = null; - // TODO note always sends cancel to pump but only changes history if present - - final UUID cmd = aSyncTaskRunner(new CancelBolusTaskRunner(connector.getServiceConnector(), ActiveBolusType.EXTENDED), "Cancel extended bolus"); - - if (cmd == null) { + try { + bolusId = fetchTaskRunner(new CancelBolusSilentlyTaskRunner(connector.getServiceConnector(), ActiveBolusType.EXTENDED), Integer.class); + if (TreatmentsPlugin.getPlugin().isInHistoryExtendedBoluslInProgress()) { + ExtendedBolus exStop = new ExtendedBolus(System.currentTimeMillis()); + exStop.source = Source.USER; + TreatmentsPlugin.getPlugin().addToHistoryExtendedBolus(exStop); + } + if (bolusId != null) connector.requestHistorySync(5000); + connector.tryToGetPumpStatusAgain(); + updateGui(); + return new PumpEnactResult().success(true).enacted(bolusId != null); + } catch (Exception e) { return pumpEnactFailure(); } - - final Mstatus ms = async.busyWaitForCommandResult(cmd, BUSY_WAIT_TIME); - - if (TreatmentsPlugin.getPlugin().isInHistoryExtendedBoluslInProgress()) { - ExtendedBolus exStop = new ExtendedBolus(System.currentTimeMillis()); - exStop.source = Source.USER; - TreatmentsPlugin.getPlugin().addToHistoryExtendedBolus(exStop); - } - - if (Config.logPumpComm) - log.debug("Cancel extended bolus:"); - - updateGui(); - - connector.requestHistorySync(5000); - connector.tryToGetPumpStatusAgain(); - - return new PumpEnactResult().success(ms.success()).enacted(true); } - private synchronized UUID deliverBolus(double bolusValue) { - log("DeliverBolus: " + bolusValue); - - if (bolusValue == 0) return null; - if (bolusValue < 0) return null; - - // TODO check limits here or they already occur via a previous constraint interface? + private int deliverBolus(double bolusValue) throws Exception { + if (L.isEnabled(L.PUMP)) + log.debug("DeliverBolus: " + bolusValue); final StandardBolusMessage message = new StandardBolusMessage(); message.setAmount(bolusValue); - return aSyncSingleCommand(message, "Deliver Bolus " + bolusValue); + return fetchSingleMessage(message, BolusMessage.class).getBolusId(); } @Override public JSONObject getJSONStatus(Profile profile, String profileName) { long now = System.currentTimeMillis(); if (Helpers.msSince(connector.getLastContactTime()) > (60 * 60 * 1000)) { - log("getJSONStatus not returning as data likely stale"); + if (L.isEnabled(L.PUMP)) + log.debug("getJSONStatus not returning as data likely stale"); return null; } @@ -737,7 +677,7 @@ public class InsightPlugin extends PluginBase implements PumpInterface, Constrai status.put("timestamp", DateUtil.toISOString(connector.getLastContactTime())); extended.put("Version", BuildConfig.VERSION_NAME + "-" + BuildConfig.BUILDVERSION); try { - extended.put("ActiveProfile", MainApp.getConfigBuilder().getProfileName()); + extended.put("ActiveProfile", ProfileFunctions.getInstance().getProfileName()); } catch (Exception e) { } TemporaryBasal tb = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(now); @@ -927,86 +867,38 @@ public class InsightPlugin extends PluginBase implements PumpInterface, Constrai break; default: - log("ERROR: unknown bolus type! " + activeBolus.getBolusType()); + log.error("ERROR: unknown bolus type! " + activeBolus.getBolusType()); } } - // Utility - - private synchronized UUID aSyncSingleCommand(final AppLayerMessage msg, final String name) { - // if (!isConnected()) return false; - //if (isBusy()) return false; - log("asyncSinglecommand called: " + name); - final EventInsightCallback event = new EventInsightCallback(); - new Thread() { - @Override - public void run() { - log("asyncSingleCommand thread"); - final SingleMessageTaskRunner singleMessageTaskRunner = new SingleMessageTaskRunner(connector.getServiceConnector(), msg); - try { - singleMessageTaskRunner.fetch(new TaskRunner.ResultCallback() { - @Override - public void onResult(Object o) { - lastDataTime = new Date(); - log(name + " success"); - event.response_object = o; - if (o instanceof BolusMessage) { - event.response_id = ((BolusMessage) o).getBolusId(); - } - event.success = true; - pushCallbackEvent(event); - } - - @Override - public void onError(Exception e) { - log(name + " error"); - event.message = e.getMessage(); - pushCallbackEvent(event); - } - }); - - } catch (Exception e) { - log("EXCEPTION" + e.toString()); - } - } - }.start(); - return event.request_uuid; + private void fetchTaskRunner(TaskRunner taskRunner) throws Exception { + fetchTaskRunner(taskRunner, Object.class); } - private synchronized UUID aSyncTaskRunner(final TaskRunner task, final String name) { - // if (!isConnected()) return false; - //if (isBusy()) return false; - log("asyncTaskRunner called: " + name); - final EventInsightCallback event = new EventInsightCallback(); - new Thread() { - @Override - public void run() { - log("asyncTaskRunner thread"); - try { - task.fetch(new TaskRunner.ResultCallback() { - @Override - public void onResult(Object o) { - lastDataTime = new Date(); - log(name + " success"); - event.response_object = o; - event.success = true; - pushCallbackEvent(event); - } + private void fetchSingleMessage(AppLayerMessage message) throws Exception { + fetchSingleMessage(message, AppLayerMessage.class); + } - @Override - public void onError(Exception e) { - log(name + " error"); - event.message = e.getMessage(); - pushCallbackEvent(event); - } - }); + private T fetchTaskRunner(TaskRunner taskRunner, Class resultType) throws Exception { + try { + T result = (T) taskRunner.fetchAndWaitUsingLatch(BUSY_WAIT_TIME); + lastDataTime = System.currentTimeMillis(); + return result; + } catch (Exception e) { + log.error("Error while fetching " + taskRunner.getClass().getSimpleName() + ": " + e.getClass().getSimpleName()); + throw e; + } + } - } catch (Exception e) { - log("EXCEPTION" + e.toString()); - } - } - }.start(); - return event.request_uuid; + private T fetchSingleMessage(AppLayerMessage message, Class resultType) throws Exception { + try { + T result = (T) new SingleMessageTaskRunner(connector.getServiceConnector(), message).fetchAndWaitUsingLatch(BUSY_WAIT_TIME); + lastDataTime = System.currentTimeMillis(); + return result; + } catch (Exception e) { + log.error("Error while fetching " + message.getClass().getSimpleName() + ": " + e.getClass().getSimpleName()); + throw e; + } } @@ -1016,14 +908,6 @@ public class InsightPlugin extends PluginBase implements PumpInterface, Constrai // Constraints - @Override - public Constraint applyBasalConstraints(Constraint absoluteRate, Profile profile) { - if (statusResult != null) { - absoluteRate.setIfSmaller(statusResult.maximumBasalAmount, String.format(MainApp.gs(R.string.limitingbasalratio), statusResult.maximumBasalAmount, MainApp.gs(R.string.pumplimit)), this); - } - return absoluteRate; - } - @Override public Constraint applyBasalPercentConstraints(Constraint percentRate, Profile profile) { percentRate.setIfGreater(0, String.format(MainApp.gs(R.string.limitingpercentrate), 0, MainApp.gs(R.string.itmustbepositivevalue)), this); @@ -1034,8 +918,17 @@ public class InsightPlugin extends PluginBase implements PumpInterface, Constrai @Override public Constraint applyBolusConstraints(Constraint insulin) { - if (statusResult != null) + if (statusResult != null) { insulin.setIfSmaller(statusResult.maximumBolusAmount, String.format(MainApp.gs(R.string.limitingbolus), statusResult.maximumBolusAmount, MainApp.gs(R.string.pumplimit)), this); + if (insulin.value() < statusResult.minimumBolusAmount) { + + //TODO: Add function to Constraints or use different approach + // This only works if the interface of the InsightPlugin is called last. + // If not, another contraint could theoretically set the value between 0 and minimumBolusAmount + + insulin.set(0d, String.format(MainApp.gs(R.string.limitingbolus), statusResult.minimumBolusAmount, MainApp.gs(R.string.pumplimit)), this); + } + } return insulin; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/Mstatus.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/Mstatus.java deleted file mode 100644 index 8797325f7c..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/Mstatus.java +++ /dev/null @@ -1,50 +0,0 @@ -package info.nightscout.androidaps.plugins.PumpInsight; - -import info.nightscout.androidaps.plugins.PumpInsight.events.EventInsightCallback; - -/** - * Created by jamorham on 01/02/2018. - * - * Encapsulates results from commands - */ - -class Mstatus { - - Cstatus cstatus = Cstatus.UNKNOWN; - EventInsightCallback event; - - // comment field preparation for results - String getCommandComment() { - if (success()) { - return "OK"; - } else { - return (event == null) ? "EVENT DATA IS NULL - ERROR OR FIREWALL ENABLED?" : event.message; - } - } - - boolean success() { - return cstatus.success(); - } - - int getResponseID() { - if (success()) { - return event.response_id; - } else { - return -2; // invalid - } - } - - Object getResponseObject() { - if (success()) { - return event.response_object; - } else { - return null; - } - } - - @Override - public String toString() { - return cstatus + " " + event; - } - -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/connector/CancelBolusSilentlyTaskRunner.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/connector/CancelBolusSilentlyTaskRunner.java new file mode 100644 index 0000000000..7b3108602e --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/connector/CancelBolusSilentlyTaskRunner.java @@ -0,0 +1,66 @@ +package info.nightscout.androidaps.plugins.PumpInsight.connector; + +import sugar.free.sightparser.applayer.descriptors.ActiveBolusType; +import sugar.free.sightparser.applayer.descriptors.MessagePriority; +import sugar.free.sightparser.applayer.descriptors.alerts.Warning38BolusCancelled; +import sugar.free.sightparser.applayer.messages.AppLayerMessage; +import sugar.free.sightparser.applayer.messages.remote_control.CancelBolusMessage; +import sugar.free.sightparser.applayer.messages.remote_control.DismissAlertMessage; +import sugar.free.sightparser.applayer.messages.status.ActiveAlertMessage; +import sugar.free.sightparser.applayer.messages.status.ActiveBolusesMessage; +import sugar.free.sightparser.handling.SightServiceConnector; +import sugar.free.sightparser.handling.TaskRunner; + +// by Tebbe Ubben + +public class CancelBolusSilentlyTaskRunner extends TaskRunner { + + private ActiveBolusType bolusType; + private long cancelledAt; + private int bolusId; + + public CancelBolusSilentlyTaskRunner(SightServiceConnector serviceConnector, ActiveBolusType bolusType) { + super(serviceConnector); + this.bolusType = bolusType; + } + + @Override + protected AppLayerMessage run(AppLayerMessage message) throws Exception { + if (message == null) return new ActiveBolusesMessage(); + else if (message instanceof ActiveBolusesMessage) { + ActiveBolusesMessage bolusesMessage = (ActiveBolusesMessage) message; + CancelBolusMessage cancelBolusMessage = new CancelBolusMessage(); + if (bolusesMessage.getBolus1().getBolusType() == bolusType) + bolusId = bolusesMessage.getBolus1().getBolusID(); + else if (bolusesMessage.getBolus2().getBolusType() == bolusType) + bolusId = bolusesMessage.getBolus2().getBolusID(); + else if (bolusesMessage.getBolus3().getBolusType() == bolusType) + bolusId = bolusesMessage.getBolus3().getBolusID(); + else finish(null); + cancelBolusMessage.setBolusId(bolusId); + return cancelBolusMessage; + } else if (message instanceof CancelBolusMessage) { + cancelledAt = System.currentTimeMillis(); + ActiveAlertMessage activeAlertMessage = new ActiveAlertMessage(); + activeAlertMessage.setMessagePriority(MessagePriority.HIGHER); + return activeAlertMessage; + } else if (message instanceof ActiveAlertMessage) { + ActiveAlertMessage activeAlertMessage = (ActiveAlertMessage) message; + if (activeAlertMessage.getAlert() == null) { + if (System.currentTimeMillis() - cancelledAt >= 10000) finish(bolusId); + else { + ActiveAlertMessage activeAlertMessage2 = new ActiveAlertMessage(); + activeAlertMessage2.setMessagePriority(MessagePriority.HIGHER); + return activeAlertMessage2; + } + } else if (!(activeAlertMessage.getAlert() instanceof Warning38BolusCancelled)) finish(bolusId); + else { + DismissAlertMessage dismissAlertMessage = new DismissAlertMessage(); + dismissAlertMessage.setAlertID(activeAlertMessage.getAlertID()); + dismissAlertMessage.setMessagePriority(MessagePriority.HIGHER); + return dismissAlertMessage; + } + } else if (message instanceof DismissAlertMessage) finish(bolusId); + return null; + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/connector/CancelBolusTaskRunner.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/connector/CancelBolusTaskRunner.java deleted file mode 100644 index f350b80851..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/connector/CancelBolusTaskRunner.java +++ /dev/null @@ -1,38 +0,0 @@ -package info.nightscout.androidaps.plugins.PumpInsight.connector; - -import sugar.free.sightparser.applayer.messages.AppLayerMessage; -import sugar.free.sightparser.applayer.descriptors.ActiveBolusType; -import sugar.free.sightparser.applayer.messages.remote_control.CancelBolusMessage; -import sugar.free.sightparser.applayer.messages.status.ActiveBolusesMessage; -import sugar.free.sightparser.handling.SightServiceConnector; -import sugar.free.sightparser.handling.TaskRunner; - -// by Tebbe Ubben - -public class CancelBolusTaskRunner extends TaskRunner { - - private ActiveBolusType bolusType; - - public CancelBolusTaskRunner(SightServiceConnector serviceConnector, ActiveBolusType bolusType) { - super(serviceConnector); - this.bolusType = bolusType; - } - - @Override - protected AppLayerMessage run(AppLayerMessage message) throws Exception { - if (message == null) return new ActiveBolusesMessage(); - else if (message instanceof ActiveBolusesMessage) { - ActiveBolusesMessage bolusesMessage = (ActiveBolusesMessage) message; - CancelBolusMessage cancelBolusMessage = new CancelBolusMessage(); - if (bolusesMessage.getBolus1().getBolusType() == bolusType) - cancelBolusMessage.setBolusId(bolusesMessage.getBolus1().getBolusID()); - else if (bolusesMessage.getBolus2().getBolusType() == bolusType) - cancelBolusMessage.setBolusId(bolusesMessage.getBolus2().getBolusID()); - else if (bolusesMessage.getBolus3().getBolusType() == bolusType) - cancelBolusMessage.setBolusId(bolusesMessage.getBolus3().getBolusID()); - else finish(null); - return cancelBolusMessage; - } else if (message instanceof CancelBolusMessage) finish(null); - return null; - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/connector/CancelTBRSilentlyTaskRunner.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/connector/CancelTBRSilentlyTaskRunner.java new file mode 100644 index 0000000000..9a3068aef9 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/connector/CancelTBRSilentlyTaskRunner.java @@ -0,0 +1,50 @@ +package info.nightscout.androidaps.plugins.PumpInsight.connector; + +import sugar.free.sightparser.applayer.descriptors.MessagePriority; +import sugar.free.sightparser.applayer.descriptors.alerts.Warning36TBRCancelled; +import sugar.free.sightparser.applayer.messages.AppLayerMessage; +import sugar.free.sightparser.applayer.messages.remote_control.CancelTBRMessage; +import sugar.free.sightparser.applayer.messages.remote_control.DismissAlertMessage; +import sugar.free.sightparser.applayer.messages.status.ActiveAlertMessage; +import sugar.free.sightparser.applayer.messages.status.CurrentTBRMessage; +import sugar.free.sightparser.handling.SightServiceConnector; +import sugar.free.sightparser.handling.TaskRunner; + +public class CancelTBRSilentlyTaskRunner extends TaskRunner { + + private long cancelledAt; + + public CancelTBRSilentlyTaskRunner(SightServiceConnector serviceConnector) { + super(serviceConnector); + } + + @Override + protected AppLayerMessage run(AppLayerMessage message) throws Exception { + if (message == null) return new CurrentTBRMessage(); + else if (message instanceof CurrentTBRMessage) { + if (((CurrentTBRMessage) message).getPercentage() == 100) finish(false); + else return new CancelTBRMessage(); + } else if (message instanceof CancelTBRMessage) { + ActiveAlertMessage activeAlertMessage = new ActiveAlertMessage(); + activeAlertMessage.setMessagePriority(MessagePriority.HIGHER); + return activeAlertMessage; + } else if (message instanceof ActiveAlertMessage) { + ActiveAlertMessage activeAlertMessage = (ActiveAlertMessage) message; + if (activeAlertMessage.getAlert() == null) { + if (System.currentTimeMillis() - cancelledAt >= 10000) finish(true); + else { + ActiveAlertMessage activeAlertMessage2 = new ActiveAlertMessage(); + activeAlertMessage2.setMessagePriority(MessagePriority.HIGHER); + return activeAlertMessage2; + } + } else if (!(activeAlertMessage.getAlert() instanceof Warning36TBRCancelled)) finish(true); + else { + DismissAlertMessage dismissAlertMessage = new DismissAlertMessage(); + dismissAlertMessage.setAlertID(activeAlertMessage.getAlertID()); + dismissAlertMessage.setMessagePriority(MessagePriority.HIGHER); + return dismissAlertMessage; + } + } else if (message instanceof DismissAlertMessage) finish(true); + return null; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/connector/Connector.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/connector/Connector.java index 82b6cc3cc8..fdc2aff0a6 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/connector/Connector.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/connector/Connector.java @@ -5,6 +5,9 @@ import android.os.PowerManager; import com.squareup.otto.Subscribe; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.util.ArrayList; import java.util.Formatter; import java.util.HashMap; @@ -14,6 +17,8 @@ import java.util.Map; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.events.EventFeatureRunning; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.PumpInsight.events.EventInsightUpdateGui; import info.nightscout.androidaps.plugins.PumpInsight.history.HistoryReceiver; import info.nightscout.androidaps.plugins.PumpInsight.history.LiveHistory; @@ -31,16 +36,16 @@ import static sugar.free.sightparser.handling.SightService.COMPATIBILITY_VERSION /** * Created by jamorham on 23/01/2018. - * + *

* Connects to SightRemote app service using SightParser library - * + *

* SightRemote and SightParser created by Tebbe Ubben - * + *

* Original proof of concept SightProxy by jamorham - * */ public class Connector { + private static Logger log = LoggerFactory.getLogger(L.PUMP); // TODO connection statistics @@ -65,7 +70,8 @@ public class Connector { public synchronized void onStatusChange(Status status, long statusTime, long waitTime) { if ((status != lastStatus) || (Helpers.msSince(lastStatusTime) > 2000)) { - log("Status change: " + status); + if (L.isEnabled(L.PUMP)) + log.debug("Status change: " + status); updateStatusStatistics(lastStatus, lastStatusTime); lastStatus = status; @@ -78,7 +84,8 @@ public class Connector { MainApp.bus().post(new EventInsightUpdateGui()); } else { - log("Same status as before: " + status); + if (L.isEnabled(L.PUMP)) + log.debug("Same status as before: " + status); } } @@ -87,29 +94,32 @@ public class Connector { @Override public synchronized void onServiceConnected() { - log("On service connected"); + if (L.isEnabled(L.PUMP)) + log.debug("On service connected"); try { final String remoteVersion = serviceConnector.getRemoteVersion(); if (remoteVersion.equals(COMPATIBILITY_VERSION)) { serviceConnector.connect(); } else { - log("PROTOCOL VERSION MISMATCH! local: " + COMPATIBILITY_VERSION + " remote: " + remoteVersion); + log.error("PROTOCOL VERSION MISMATCH! local: " + COMPATIBILITY_VERSION + " remote: " + remoteVersion); statusCallback.onStatusChange(Status.INCOMPATIBLE, 0, 0); compatabilityMessage = MainApp.gs(R.string.insight_incompatible_compantion_app_we_need_version) + " " + getLocalVersion(); serviceConnector.disconnectFromService(); } } catch (NullPointerException e) { - log("ERROR: null pointer when trying to connect to pump"); + log.error("ERROR: null pointer when trying to connect to pump"); } statusCallback.onStatusChange(safeGetStatus(), 0, 0); } @Override public synchronized void onServiceDisconnected() { - log("Disconnected from service"); + if (L.isEnabled(L.PUMP)) + log.debug("Disconnected from service"); if (Helpers.ratelimit("insight-automatic-reconnect", 30)) { - log("Scheduling automatic service reconnection"); + if (L.isEnabled(L.PUMP)) + log.debug("Scheduling automatic service reconnection"); Helpers.runOnUiThreadDelayed(new Runnable() { @Override public void run() { @@ -147,11 +157,13 @@ public class Connector { } public synchronized static void connectToPump(long keep_alive) { - log("Attempting to connect to pump."); + if (L.isEnabled(L.PUMP)) + log.debug("Attempting to connect to pump."); if (keep_alive > 0 && Helpers.tsl() + keep_alive > stayConnectedTill) { stayConnectedTime = keep_alive; stayConnectedTill = Helpers.tsl() + keep_alive; - log("Staying connected till: " + Helpers.dateTimeText(stayConnectedTill)); + if (L.isEnabled(L.PUMP)) + log.debug("Staying connected till: " + Helpers.dateTimeText(stayConnectedTill)); delayedDisconnectionThread(); } get().getServiceConnector().connect(); @@ -159,18 +171,16 @@ public class Connector { public static void disconnectFromPump() { if (Helpers.tsl() >= stayConnectedTill) { - log("Requesting real pump disconnect"); + if (L.isEnabled(L.PUMP)) + log.debug("Requesting real pump disconnect"); get().getServiceConnector().disconnect(); } else { - log("Cannot disconnect as due to keep alive till: " + Helpers.dateTimeText(stayConnectedTill)); + if (L.isEnabled(L.PUMP)) + log.debug("Cannot disconnect as due to keep alive till: " + Helpers.dateTimeText(stayConnectedTill)); // TODO set a disconnection timer? } } - static void log(String msg) { - android.util.Log.e("INSIGHTPUMP", msg); - } - static String getLocalVersion() { return COMPATIBILITY_VERSION; } @@ -206,7 +216,8 @@ public class Connector { if (keepAliveActive()) { if (Helpers.ratelimit("extend-insight-keepalive", 10)) { stayConnectedTill = Helpers.tsl() + stayConnectedTime; - log("Keep-alive extended until: " + Helpers.dateTimeText(stayConnectedTill)); + if (L.isEnabled(L.PUMP)) + log.debug("Keep-alive extended until: " + Helpers.dateTimeText(stayConnectedTill)); } } } @@ -236,7 +247,8 @@ public class Connector { try { while (disconnect_thread_running && keepAliveActive()) { if (Helpers.ratelimit("insight-expiry-notice", 5)) { - log("Staying connected thread expires: " + Helpers.dateTimeText(stayConnectedTill)); + if (L.isEnabled(L.PUMP)) + log.debug("Staying connected thread expires: " + Helpers.dateTimeText(stayConnectedTill)); } try { Thread.sleep(1000); @@ -246,10 +258,12 @@ public class Connector { } if (disconnect_thread_running) { - log("Sending the real delayed disconnect"); + if (L.isEnabled(L.PUMP)) + log.debug("Sending the real delayed disconnect"); get().getServiceConnector().disconnect(); } else { - log("Disconnect thread already terminating"); + if (L.isEnabled(L.PUMP)) + log.debug("Disconnect thread already terminating"); } } finally { Helpers.releaseWakeLock(wl); @@ -258,7 +272,8 @@ public class Connector { } }).start(); } else { - log("Disconnect thread already running"); + if (L.isEnabled(L.PUMP)) + log.debug("Disconnect thread already running"); } } } @@ -269,7 +284,8 @@ public class Connector { public synchronized void shutdown() { if (instance != null) { - log("Attempting to shut down connector"); + if (L.isEnabled(L.PUMP)) + log.debug("Attempting to shut down connector"); try { disconnect_thread_running = false; try { @@ -285,17 +301,17 @@ public class Connector { try { instance.serviceConnector.disconnect(); } catch (Exception e) { - log("Exception disconnecting: " + e); + log.error("Exception disconnecting: " + e); } try { instance.serviceConnector.disconnectFromService(); } catch (Exception e) { - log("Excpetion disconnecting service: " + e); + log.error("Excpetion disconnecting service: " + e); } instance.serviceConnector = null; instance = null; } catch (Exception e) { - log("Exception shutting down: " + e); + log.error("Exception shutting down: " + e); } } } @@ -309,7 +325,8 @@ public class Connector { } public synchronized void init() { - log("Connector::init()"); + if (L.isEnabled(L.PUMP)) + log.debug("Connector::init()"); if (serviceConnector == null) { companionAppInstalled = isCompanionAppInstalled(); if (companionAppInstalled) { @@ -318,9 +335,11 @@ public class Connector { serviceConnector.addStatusCallback(statusCallback); serviceConnector.setConnectionCallback(connectionCallback); serviceConnector.connectToService(); - log("Trying to connect"); + if (L.isEnabled(L.PUMP)) + log.debug("Trying to connect"); } else { - log("Not trying init due to missing companion app"); + if (L.isEnabled(L.PUMP)) + log.debug("Not trying init due to missing companion app"); } } else { if (!serviceConnector.isConnectedToService()) { @@ -328,7 +347,8 @@ public class Connector { serviceConnector = null; init(); } else { - log("Trying to reconnect to service (" + serviceReconnects + ")"); + if (L.isEnabled(L.PUMP)) + log.debug("Trying to reconnect to service (" + serviceReconnects + ")"); serviceConnector.connectToService(); serviceReconnects++; } @@ -384,7 +404,8 @@ public class Connector { } if (!isConnected()) { - log("Not connected to companion"); + if (L.isEnabled(L.PUMP)) + log.debug("Not connected to companion"); if (Helpers.ratelimit("insight-app-not-connected", 5)) { init(); } @@ -439,7 +460,7 @@ public class Connector { public void tryToGetPumpStatusAgain() { if (Helpers.ratelimit("insight-retry-status-request", 5)) { try { - MainApp.getConfigBuilder().getCommandQueue().readStatus("Insight. Status missing", null); + ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("Insight. Status missing", null); } catch (NullPointerException e) { // } @@ -499,7 +520,8 @@ public class Connector { Long total = statistics.get(last); if (total == null) total = 0L; statistics.put(last, total + Helpers.msSince(since)); - log("Updated statistics for: " + last + " total: " + Helpers.niceTimeScalar(statistics.get(last))); + if (L.isEnabled(L.PUMP)) + log.debug("Updated statistics for: " + last + " total: " + Helpers.niceTimeScalar(statistics.get(last))); // TODO persist data } } @@ -534,11 +556,13 @@ public class Connector { if (SP.getBoolean("insight_preemptive_connect", true)) { switch (ev.getFeature()) { case WIZARD: - log("Wizard feature detected, preconnecting to pump"); + if (L.isEnabled(L.PUMP)) + log.debug("Wizard feature detected, preconnecting to pump"); connectToPump(120 * 1000); break; case MAIN: - log("Main feature detected, preconnecting to pump"); + if (L.isEnabled(L.PUMP)) + log.debug("Main feature detected, preconnecting to pump"); connectToPump(30 * 1000); break; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/connector/SetTBRTaskRunner.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/connector/SetTBRTaskRunner.java index 1506ecb4a9..f18bb0d487 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/connector/SetTBRTaskRunner.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/connector/SetTBRTaskRunner.java @@ -25,25 +25,15 @@ public class SetTBRTaskRunner extends TaskRunner { if (message == null) return new CurrentTBRMessage(); else if (message instanceof CurrentTBRMessage) { if (((CurrentTBRMessage) message).getPercentage() == 100) { - if (amount == 100) finish(amount); - else { - SetTBRMessage setTBRMessage = new SetTBRMessage(); - setTBRMessage.setDuration(duration); - setTBRMessage.setAmount(amount); - return setTBRMessage; - } + SetTBRMessage setTBRMessage = new SetTBRMessage(); + setTBRMessage.setDuration(duration); + setTBRMessage.setAmount(amount); + return setTBRMessage; } else { - if (amount == 100) { - ChangeTBRMessage changeTBRMessage = new ChangeTBRMessage(); - changeTBRMessage.setDuration(1); - changeTBRMessage.setAmount(90); - return changeTBRMessage; - } else { - ChangeTBRMessage changeTBRMessage = new ChangeTBRMessage(); - changeTBRMessage.setDuration(duration); - changeTBRMessage.setAmount(amount); - return changeTBRMessage; - } + ChangeTBRMessage changeTBRMessage = new ChangeTBRMessage(); + changeTBRMessage.setDuration(duration); + changeTBRMessage.setAmount(amount); + return changeTBRMessage; } } else if (message instanceof SetTBRMessage) finish(amount); return null; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/connector/StatusTaskRunner.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/connector/StatusTaskRunner.java index 86e01f98f8..1df56be468 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/connector/StatusTaskRunner.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/connector/StatusTaskRunner.java @@ -12,6 +12,8 @@ import sugar.free.sightparser.applayer.descriptors.configuration_blocks.BRProfil import sugar.free.sightparser.applayer.descriptors.configuration_blocks.BRProfile5Block; import sugar.free.sightparser.applayer.descriptors.configuration_blocks.BRProfileBlock; import sugar.free.sightparser.applayer.descriptors.configuration_blocks.ConfigurationBlock; +import sugar.free.sightparser.applayer.descriptors.configuration_blocks.FactoryMinBRAmountBlock; +import sugar.free.sightparser.applayer.descriptors.configuration_blocks.FactoryMinBolusAmountBlock; import sugar.free.sightparser.applayer.descriptors.configuration_blocks.MaxBRAmountBlock; import sugar.free.sightparser.applayer.descriptors.configuration_blocks.MaxBolusAmountBlock; import sugar.free.sightparser.applayer.messages.AppLayerMessage; @@ -102,6 +104,16 @@ public class StatusTaskRunner extends TaskRunner { return readMessage; } else if (configurationBlock instanceof MaxBRAmountBlock) { result.maximumBasalAmount = ((MaxBRAmountBlock) configurationBlock).getMaximumAmount(); + ReadConfigurationBlockMessage readMessage = new ReadConfigurationBlockMessage(); + readMessage.setConfigurationBlockID(FactoryMinBRAmountBlock.ID); + return readMessage; + } else if (configurationBlock instanceof FactoryMinBRAmountBlock) { + result.minimumBasalAmount = ((FactoryMinBRAmountBlock) configurationBlock).getMinimumAmount(); + ReadConfigurationBlockMessage readMessage = new ReadConfigurationBlockMessage(); + readMessage.setConfigurationBlockID(FactoryMinBolusAmountBlock.ID); + return readMessage; + } else if (configurationBlock instanceof FactoryMinBolusAmountBlock) { + result.minimumBolusAmount = ((FactoryMinBolusAmountBlock) configurationBlock).getMinimumAmount(); finish(result); } } @@ -122,5 +134,7 @@ public class StatusTaskRunner extends TaskRunner { public List basalProfile; public double maximumBolusAmount; public double maximumBasalAmount; + public double minimumBolusAmount; + public double minimumBasalAmount; } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/events/EventInsightCallback.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/events/EventInsightCallback.java index 16cb5af457..753ac7f0e6 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/events/EventInsightCallback.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/events/EventInsightCallback.java @@ -12,7 +12,6 @@ public class EventInsightCallback extends Event { public UUID request_uuid; public boolean success = false; public String message = null; - public int response_id = -1; public Object response_object = null; public EventInsightCallback() { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/history/HistoryIntentAdapter.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/history/HistoryIntentAdapter.java index e7784287b7..49836e9f3b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/history/HistoryIntentAdapter.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/history/HistoryIntentAdapter.java @@ -1,15 +1,22 @@ package info.nightscout.androidaps.plugins.PumpInsight.history; import android.content.Intent; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.db.CareportalEvent; import info.nightscout.androidaps.db.TDD; +import info.nightscout.androidaps.logging.L; import info.nightscout.utils.DateUtil; -import info.nightscout.utils.NSUpload; +import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; import info.nightscout.utils.SP; + import org.json.JSONException; import org.json.JSONObject; + import sugar.free.sightparser.handling.HistoryBroadcast; import java.util.Date; @@ -23,15 +30,12 @@ import static info.nightscout.androidaps.plugins.PumpInsight.history.PumpIdCache */ class HistoryIntentAdapter { + private Logger log = LoggerFactory.getLogger(L.PUMP); private HistoryLogAdapter logAdapter = new HistoryLogAdapter(); - private static Date getDateExtra(Intent intent, String name) { - return (Date) intent.getSerializableExtra(name); - } - - private static void log(String msg) { - android.util.Log.e("HistoryIntentAdapter", msg); + private static long getDateExtra(Intent intent, String name) { + return ((Date) intent.getSerializableExtra(name)).getTime(); } static long getRecordUniqueID(long pump_serial_number, long pump_record_id) { @@ -48,23 +52,18 @@ class HistoryIntentAdapter { pump_record_id = intent.getIntExtra(HistoryBroadcast.EXTRA_EVENT_NUMBER, -1); } final long pump_serial_number = Long.parseLong(intent.getStringExtra(HistoryBroadcast.EXTRA_PUMP_SERIAL_NUMBER)); - final Date event_time = getDateExtra(intent, HistoryBroadcast.EXTRA_EVENT_TIME); - final Date start_time = getDateExtra(intent, HistoryBroadcast.EXTRA_START_TIME); + final long start_time = getDateExtra(intent, HistoryBroadcast.EXTRA_START_TIME); if ((pump_tbr_duration == -1) || (pump_tbr_percent == -1) || (pump_record_id == -1)) { - log("Invalid TBR record!!!"); + log.error("Invalid TBR record!!!"); return; } final long record_unique_id = getRecordUniqueID(pump_serial_number, pump_record_id); - // other sanity checks - if ((pump_tbr_percent == 90) && (pump_tbr_duration <= 1)) { - log("Not creating TBR record for faux cancel"); - } else { - log("Creating TBR record: " + pump_tbr_percent + "% " + pump_tbr_duration + "m" + " id:" + record_unique_id); - logAdapter.createTBRrecord(start_time, pump_tbr_percent, pump_tbr_duration, record_unique_id); - } + if (L.isEnabled(L.PUMP)) + log.debug("Creating TBR record: " + pump_tbr_percent + "% " + pump_tbr_duration + "m" + " id:" + record_unique_id); + logAdapter.createTBRrecord(start_time, pump_tbr_percent, pump_tbr_duration, record_unique_id); } void processDeliveredBolusIntent(Intent intent) { @@ -76,8 +75,8 @@ class HistoryIntentAdapter { pump_record_id = intent.getIntExtra(HistoryBroadcast.EXTRA_EVENT_NUMBER, -1); } final long pump_serial_number = Long.parseLong(intent.getStringExtra(HistoryBroadcast.EXTRA_PUMP_SERIAL_NUMBER)); - final Date event_time = getDateExtra(intent, HistoryBroadcast.EXTRA_EVENT_TIME); - final Date start_time = getDateExtra(intent, HistoryBroadcast.EXTRA_START_TIME); + final long event_time = getDateExtra(intent, HistoryBroadcast.EXTRA_EVENT_TIME); + final long start_time = getDateExtra(intent, HistoryBroadcast.EXTRA_START_TIME); final double immediate_amount = intent.getDoubleExtra(HistoryBroadcast.EXTRA_IMMEDIATE_AMOUNT, -1); final double extended_insulin = intent.getDoubleExtra(HistoryBroadcast.EXTRA_EXTENDED_AMOUNT, -1); final int extended_minutes = intent.getIntExtra(HistoryBroadcast.EXTRA_DURATION, -1); @@ -87,62 +86,63 @@ class HistoryIntentAdapter { switch (bolus_type) { case "STANDARD": if (immediate_amount == -1) { - log("ERROR Standard bolus fails sanity check"); + log.error("ERROR Standard bolus fails sanity check"); return; } - LiveHistory.setStatus(bolus_type + " BOLUS\n" + immediate_amount + "U ", event_time.getTime()); + LiveHistory.setStatus(bolus_type + " BOLUS\n" + immediate_amount + "U ", event_time); logAdapter.createStandardBolusRecord(start_time, immediate_amount, record_unique_id); break; case "EXTENDED": if ((extended_insulin == -1) || (extended_minutes == -1)) { - log("ERROR: Extended bolus fails sanity check"); + log.error("ERROR: Extended bolus fails sanity check"); return; } - LiveHistory.setStatus(bolus_type + " BOLUS\n" + extended_insulin + "U over " + extended_minutes + " min, ", event_time.getTime()); + LiveHistory.setStatus(bolus_type + " BOLUS\n" + extended_insulin + "U over " + extended_minutes + " min, ", event_time); logAdapter.createExtendedBolusRecord(start_time, extended_insulin, extended_minutes, record_unique_id); break; case "MULTIWAVE": if ((immediate_amount == -1) || (extended_insulin == -1) || (extended_minutes == -1)) { - log("ERROR: Multiwave bolus fails sanity check"); + log.error("ERROR: Multiwave bolus fails sanity check"); return; } - LiveHistory.setStatus(bolus_type + " BOLUS\n" + immediate_amount + "U + " + extended_insulin + "U over " + extended_minutes + " min, ", event_time.getTime()); + LiveHistory.setStatus(bolus_type + " BOLUS\n" + immediate_amount + "U + " + extended_insulin + "U over " + extended_minutes + " min, ", event_time); logAdapter.createStandardBolusRecord(start_time, immediate_amount, pump_serial_number + pump_record_id); logAdapter.createExtendedBolusRecord(start_time, extended_insulin, extended_minutes, record_unique_id); break; default: - log("ERROR, UNKNWON BOLUS TYPE: " + bolus_type); + log.error("ERROR, UNKNWON BOLUS TYPE: " + bolus_type); } } void processDailyTotalIntent(Intent intent) { - Date date = getDateExtra(intent, HistoryBroadcast.EXTRA_TOTAL_DATE); + long date = getDateExtra(intent, HistoryBroadcast.EXTRA_TOTAL_DATE); double basal = intent.getDoubleExtra(HistoryBroadcast.EXTRA_BASAL_TOTAL, 0D); double bolus = intent.getDoubleExtra(HistoryBroadcast.EXTRA_BOLUS_TOTAL, 0D); - TDD tdd = new TDD(date.getTime(), bolus, basal, bolus + basal); + TDD tdd = new TDD(date, bolus, basal, bolus + basal); MainApp.getDbHelper().createOrUpdateTDD(tdd); } void processCannulaFilledIntent(Intent intent) { - Date date = getDateExtra(intent, HistoryBroadcast.EXTRA_EVENT_TIME); + long date = getDateExtra(intent, HistoryBroadcast.EXTRA_EVENT_TIME); uploadCareportalEvent(date, CareportalEvent.SITECHANGE); } void processCartridgeInsertedIntent(Intent intent) { - Date date = getDateExtra(intent, HistoryBroadcast.EXTRA_EVENT_TIME); + long date = getDateExtra(intent, HistoryBroadcast.EXTRA_EVENT_TIME); uploadCareportalEvent(date, CareportalEvent.INSULINCHANGE); } void processBatteryInsertedIntent(Intent intent) { - Date date = getDateExtra(intent, HistoryBroadcast.EXTRA_EVENT_TIME); + long date = getDateExtra(intent, HistoryBroadcast.EXTRA_EVENT_TIME); uploadCareportalEvent(date, CareportalEvent.PUMPBATTERYCHANGE); } - private void uploadCareportalEvent(Date date, String event) { + private void uploadCareportalEvent(long date, String event) { if (SP.getBoolean("insight_automatic_careportal_events", false)) { - if (MainApp.getDbHelper().getCareportalEventFromTimestamp(date.getTime()) != null) return; + if (MainApp.getDbHelper().getCareportalEventFromTimestamp(date) != null) + return; try { JSONObject data = new JSONObject(); String enteredBy = SP.getString("careportal_enteredby", ""); @@ -158,15 +158,18 @@ class HistoryIntentAdapter { void processOccurenceOfAlertIntent(Intent intent) { if (SP.getBoolean("insight_automatic_careportal_events", false)) { - Date date = getDateExtra(intent, HistoryBroadcast.EXTRA_EVENT_TIME); + long date = getDateExtra(intent, HistoryBroadcast.EXTRA_EVENT_TIME); String alertType = intent.getStringExtra(HistoryBroadcast.EXTRA_ALERT_TYPE); - if (MainApp.getDbHelper().getCareportalEventFromTimestamp(date.getTime()) != null) return; - logNote(date, MainApp.gs(getAlertText(alertType))); + int alertText = getAlertText(alertType); + if (alertText == 0) return; + if (MainApp.getDbHelper().getCareportalEventFromTimestamp(date) != null) + return; + logNote(date, MainApp.gs(alertText)); } } void processPumpStatusChangedIntent(Intent intent) { - Date newStatusTime = getDateExtra(intent, HistoryBroadcast.EXTRA_EVENT_TIME); + long newStatusTime = getDateExtra(intent, HistoryBroadcast.EXTRA_EVENT_TIME); if (SP.getBoolean("insight_automatic_careportal_events", false)) { String newStatus = intent.getStringExtra(HistoryBroadcast.EXTRA_NEW_STATUS); switch (newStatus) { @@ -184,8 +187,8 @@ class HistoryIntentAdapter { if (intent.hasExtra(HistoryBroadcast.EXTRA_OLD_STATUS_TIME)) { String oldStatus = intent.getStringExtra(HistoryBroadcast.EXTRA_OLD_STATUS); if (oldStatus.equals("STOPPED")) { - Date oldStatusTime = getDateExtra(intent, HistoryBroadcast.EXTRA_OLD_STATUS_TIME); - int duration = (int) ((newStatusTime.getTime() - oldStatusTime.getTime()) / 60000); + long oldStatusTime = getDateExtra(intent, HistoryBroadcast.EXTRA_OLD_STATUS_TIME); + int duration = (int) ((newStatusTime - oldStatusTime) / 60000); long serialNumber = Long.parseLong(intent.getStringExtra(HistoryBroadcast.EXTRA_PUMP_SERIAL_NUMBER)); long recordId = intent.getLongExtra(HistoryBroadcast.EXTRA_EVENT_NUMBER, -1); @@ -196,9 +199,10 @@ class HistoryIntentAdapter { } } - private void logNote(Date date, String note) { + private void logNote(long date, String note) { try { - if (MainApp.getDbHelper().getCareportalEventFromTimestamp(date.getTime()) != null) return; + if (MainApp.getDbHelper().getCareportalEventFromTimestamp(date) != null) + return; JSONObject data = new JSONObject(); String enteredBy = SP.getString("careportal_enteredby", ""); if (!enteredBy.equals("")) data.put("enteredBy", enteredBy); @@ -231,8 +235,8 @@ class HistoryIntentAdapter { if (type.equals("Warning32BatteryLow")) return R.string.alert_w32; if (type.equals("Warning33InvalidDateTime")) return R.string.alert_w33; if (type.equals("Warning34EndOfWarranty")) return R.string.alert_w34; - if (type.equals("Warning36TBRCancelled")) return R.string.alert_w36; - if (type.equals("Warning38BolusCancelled")) return R.string.alert_w38; + if (type.equals("Warning36TBRCancelled")) return 0; + if (type.equals("Warning38BolusCancelled")) return 0; if (type.equals("Warning39LoantimeWarning")) return R.string.alert_w39; return 0; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/history/HistoryLogAdapter.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/history/HistoryLogAdapter.java index 689eb9e981..fc44f25418 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/history/HistoryLogAdapter.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/history/HistoryLogAdapter.java @@ -1,13 +1,20 @@ package info.nightscout.androidaps.plugins.PumpInsight.history; -import java.util.Date; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.db.ExtendedBolus; import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.TemporaryBasal; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; +import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; +import info.nightscout.androidaps.plugins.NSClientInternal.UploadQueue; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; +import info.nightscout.utils.DateUtil; +import info.nightscout.utils.T; /** * Created by jamorham on 27/01/2018. @@ -16,37 +23,46 @@ import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; */ class HistoryLogAdapter { + private Logger log = LoggerFactory.getLogger(L.PUMP); - private static final long MAX_TIME_DIFFERENCE = 61000; + private static final long MAX_TIME_DIFFERENCE = T.secs(61).msecs(); - private static void log(String msg) { - android.util.Log.e("HISTORYLOG", msg); - } + void createTBRrecord(long eventDate, int percent, int duration, long record_id) { - void createTBRrecord(Date eventDate, int percent, int duration, long record_id) { + TemporaryBasal temporaryBasal = new TemporaryBasal().date(eventDate); - TemporaryBasal temporaryBasal = new TemporaryBasal().date(eventDate.getTime()); - - final TemporaryBasal temporaryBasalFromHistory = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(eventDate.getTime()); + final TemporaryBasal temporaryBasalFromHistory = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(eventDate); if (temporaryBasalFromHistory == null) { - log("Create new TBR: " + eventDate + " " + percent + " " + duration); + if (L.isEnabled(L.PUMP)) + log.debug("Create new TBR: " + eventDate + " " + percent + " " + duration); } else { - log("Loaded existing TBR record: " + temporaryBasalFromHistory.toString()); - if (Math.abs(eventDate.getTime() - temporaryBasalFromHistory.date) < MAX_TIME_DIFFERENCE) { + if (L.isEnabled(L.PUMP)) + log.debug("Loaded existing TBR record: " + temporaryBasalFromHistory.toString()); + if (Math.abs(eventDate - temporaryBasalFromHistory.date) < MAX_TIME_DIFFERENCE) { if (temporaryBasalFromHistory.source != Source.PUMP) { if (temporaryBasalFromHistory.percentRate == percent) { - log("Things seem to match: %" + percent); + if (L.isEnabled(L.PUMP)) + log.debug("Things seem to match: %" + percent); temporaryBasal = temporaryBasalFromHistory; + String _id = temporaryBasal._id; + if (NSUpload.isIdValid(_id)) { + NSUpload.removeCareportalEntryFromNS(_id); + } else { + UploadQueue.removeID("dbAdd", _id); + } MainApp.getDbHelper().delete(temporaryBasalFromHistory); } else { - log("This record has different percent rates: " + temporaryBasalFromHistory.percentRate + " vs us: " + percent); + if (L.isEnabled(L.PUMP)) + log.debug("This record has different percent rates: " + temporaryBasalFromHistory.percentRate + " vs us: " + percent); } } else { - log("This record is already a pump record!"); + if (L.isEnabled(L.PUMP)) + log.debug("This record is already a pump record!"); } } else { - log("Time difference too great! : " + (eventDate.getTime() - temporaryBasalFromHistory.date)); + if (L.isEnabled(L.PUMP)) + log.debug("Time difference too big! : " + (eventDate - temporaryBasalFromHistory.date)); } } @@ -58,31 +74,63 @@ class HistoryLogAdapter { TreatmentsPlugin.getPlugin().addToHistoryTempBasal(temporaryBasal); } - void createExtendedBolusRecord(Date eventDate, double insulin, int durationInMinutes, long record_id) { + void createExtendedBolusRecord(long eventDate, double insulin, int durationInMinutes, long record_id) { + + final ExtendedBolus extendedBolusFromHistory = TreatmentsPlugin.getPlugin().getExtendedBolusFromHistory(eventDate); + + if (extendedBolusFromHistory == null) { + if (L.isEnabled(L.PUMP)) + log.debug("Create new EB: " + eventDate + " " + insulin + " " + durationInMinutes); + } else { + if (L.isEnabled(L.PUMP)) + log.debug("Loaded existing EB record: " + extendedBolusFromHistory.log()); + if (Math.abs(eventDate - extendedBolusFromHistory.date) < MAX_TIME_DIFFERENCE) { + if (extendedBolusFromHistory.source != Source.PUMP) { + if (L.isEnabled(L.PUMP)) + log.debug("Date seem to match: " + DateUtil.dateAndTimeFullString(eventDate)); + String _id = extendedBolusFromHistory._id; + if (NSUpload.isIdValid(_id)) { + NSUpload.removeCareportalEntryFromNS(_id); + } else { + UploadQueue.removeID("dbAdd", _id); + } + MainApp.getDbHelper().delete(extendedBolusFromHistory); + } else { + if (L.isEnabled(L.PUMP)) + log.debug("This record is already a pump record!"); + } + } else { + if (L.isEnabled(L.PUMP)) + log.debug("Time difference too big! : " + (eventDate - extendedBolusFromHistory.date)); + } + } // TODO trap items below minimum period - final ExtendedBolus extendedBolus = new ExtendedBolus(); - extendedBolus.date = eventDate.getTime(); - extendedBolus.insulin = insulin; - extendedBolus.durationInMinutes = durationInMinutes; - extendedBolus.source = Source.PUMP; - extendedBolus.pumpId = record_id; + // TODO (mike) find and remove ending record with Source.USER - TreatmentsPlugin.getPlugin().addToHistoryExtendedBolus(extendedBolus); + ExtendedBolus extendedBolus = new ExtendedBolus() + .date(eventDate) + .insulin(insulin) + .durationInMinutes(durationInMinutes) + .source(Source.PUMP) + .pumpId(record_id); + + if (ProfileFunctions.getInstance().getProfile(extendedBolus.date) != null) // actual basal rate is needed for absolute rate calculation + TreatmentsPlugin.getPlugin().addToHistoryExtendedBolus(extendedBolus); } - void createStandardBolusRecord(Date eventDate, double insulin, long record_id) { + void createStandardBolusRecord(long eventDate, double insulin, long record_id) { //DetailedBolusInfo detailedBolusInfo = DetailedBolusInfoStorage.findDetailedBolusInfo(eventDate.getTime()); // TODO do we need to do the same delete + insert that we are doing for temporary basals here too? final DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo(); - detailedBolusInfo.date = eventDate.getTime(); + detailedBolusInfo.date = eventDate; detailedBolusInfo.source = Source.PUMP; detailedBolusInfo.pumpId = record_id; detailedBolusInfo.insulin = insulin; - TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo); + TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, true); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/history/HistoryReceiver.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/history/HistoryReceiver.java index ca68a389c8..a66378ba54 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/history/HistoryReceiver.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/history/HistoryReceiver.java @@ -54,10 +54,6 @@ public class HistoryReceiver { // History - private static void log(String msg) { - android.util.Log.e("INSIGHTPUMPHR", msg); - } - public static String getStatusString() { return status.toString(); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/history/PumpIdCache.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/history/PumpIdCache.java index 940a7af3cf..9a2bcfeff5 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/history/PumpIdCache.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/history/PumpIdCache.java @@ -1,5 +1,9 @@ package info.nightscout.androidaps.plugins.PumpInsight.history; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import info.nightscout.androidaps.logging.L; import info.nightscout.utils.SP; /** @@ -7,18 +11,16 @@ import info.nightscout.utils.SP; */ public class PumpIdCache { + private static Logger log = LoggerFactory.getLogger(L.PUMP); private static final String INSIGHT_PUMP_ID_PREF = "insight-pump-id"; private static long cachedPumpSerialNumber = -1; - private static void log(String msg) { - android.util.Log.e("PumpIdCache", msg); - } - static void updatePumpSerialNumber(long pump_serial_number) { if (pump_serial_number != cachedPumpSerialNumber) { cachedPumpSerialNumber = pump_serial_number; - log("Updating pump serial number: " + pump_serial_number); + if (L.isEnabled(L.PUMP)) + log.debug("Updating pump serial number: " + pump_serial_number); SP.putLong(INSIGHT_PUMP_ID_PREF, cachedPumpSerialNumber); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/utils/Helpers.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/utils/Helpers.java index 344bf638b2..bfdca16588 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/utils/Helpers.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/utils/Helpers.java @@ -7,6 +7,9 @@ import android.os.Handler; import android.os.PowerManager; import android.util.Log; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.math.BigDecimal; import java.math.RoundingMode; import java.text.DecimalFormat; @@ -16,17 +19,17 @@ import java.util.Map; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.logging.L; /** * Created by jamorham on 24/01/2018. - * + *

* Useful utility methods from xDrip+ - * */ public class Helpers { + private static Logger log = LoggerFactory.getLogger(L.PUMP); - private static final String TAG = "InsightHelpers"; private static final Map rateLimits = new HashMap<>(); // singletons to avoid repeated allocation @@ -37,7 +40,8 @@ public class Helpers { public static synchronized boolean ratelimit(String name, int seconds) { // check if over limit if ((rateLimits.containsKey(name)) && (tsl() - rateLimits.get(name) < (seconds * 1000))) { - Log.d(TAG, name + " rate limited: " + seconds + " seconds"); + if (L.isEnabled(L.PUMP)) + log.debug(name + " rate limited: " + seconds + " seconds"); return false; } // not over limit @@ -65,7 +69,7 @@ public class Helpers { } catch (PackageManager.NameNotFoundException e) { return false; } catch (Exception e) { - Log.wtf(TAG, "Exception trying to determine packages! " + e); + log.error("Exception trying to determine packages! " + e); return false; } } @@ -160,7 +164,7 @@ public class Helpers { public static String niceTimeScalarBrief(long t) { // TODO i18n wont work for non-latin characterset - return niceTimeScalar(t).replaceFirst("([a-z])[a-z]*", "$1").replace(" ",""); + return niceTimeScalar(t).replaceFirst("([a-z])[a-z]*", "$1").replace(" ", ""); } public static String hourMinuteString(long timestamp) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMDI/MDIPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMDI/MDIPlugin.java index fed0c01c64..7caca31891 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMDI/MDIPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMDI/MDIPlugin.java @@ -5,10 +5,7 @@ import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Date; - import info.nightscout.androidaps.BuildConfig; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.DetailedBolusInfo; @@ -19,6 +16,7 @@ import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.PumpDescription; import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.utils.DateUtil; @@ -42,6 +40,7 @@ public class MDIPlugin extends PluginBase implements PumpInterface { super(new PluginDescription() .mainType(PluginType.PUMP) .pluginName(R.string.mdi) + .description(R.string.description_pump_mdi) ); pumpDescription.isBolusCapable = true; pumpDescription.bolusStep = 0.5d; @@ -89,6 +88,15 @@ public class MDIPlugin extends PluginBase implements PumpInterface { return false; } + @Override + public boolean isHandshakeInProgress() { + return false; + } + + @Override + public void finishHandshaking() { + } + @Override public void connect(String reason) { } @@ -107,7 +115,7 @@ public class MDIPlugin extends PluginBase implements PumpInterface { @Override public PumpEnactResult setNewBasalProfile(Profile profile) { - // Do nothing here. we are using MainApp.getConfigBuilder().getActiveProfile().getProfile(); + // Do nothing here. we are using ConfigBuilderPlugin.getPlugin().getActiveProfile().getProfile(); PumpEnactResult result = new PumpEnactResult(); result.success = true; return result; @@ -119,8 +127,8 @@ public class MDIPlugin extends PluginBase implements PumpInterface { } @Override - public Date lastDataTime() { - return new Date(); + public long lastDataTime() { + return System.currentTimeMillis(); } @Override @@ -135,7 +143,7 @@ public class MDIPlugin extends PluginBase implements PumpInterface { result.bolusDelivered = detailedBolusInfo.insulin; result.carbsDelivered = detailedBolusInfo.carbs; result.comment = MainApp.gs(R.string.virtualpump_resultok); - TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo); + TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false); return result; } @@ -148,7 +156,7 @@ public class MDIPlugin extends PluginBase implements PumpInterface { PumpEnactResult result = new PumpEnactResult(); result.success = false; result.comment = MainApp.gs(R.string.pumperror); - if (Config.logPumpComm) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Setting temp basal absolute: " + result); return result; } @@ -158,7 +166,7 @@ public class MDIPlugin extends PluginBase implements PumpInterface { PumpEnactResult result = new PumpEnactResult(); result.success = false; result.comment = MainApp.gs(R.string.pumperror); - if (Config.logPumpComm) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Settings temp basal percent: " + result); return result; } @@ -168,7 +176,7 @@ public class MDIPlugin extends PluginBase implements PumpInterface { PumpEnactResult result = new PumpEnactResult(); result.success = false; result.comment = MainApp.gs(R.string.pumperror); - if (Config.logPumpComm) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Setting extended bolus: " + result); return result; } @@ -178,7 +186,7 @@ public class MDIPlugin extends PluginBase implements PumpInterface { PumpEnactResult result = new PumpEnactResult(); result.success = false; result.comment = MainApp.gs(R.string.pumperror); - if (Config.logPumpComm) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Cancel temp basal: " + result); return result; } @@ -188,8 +196,8 @@ public class MDIPlugin extends PluginBase implements PumpInterface { PumpEnactResult result = new PumpEnactResult(); result.success = false; result.comment = MainApp.gs(R.string.pumperror); - if (Config.logPumpComm) - log.debug("Canceling extended basal: " + result); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("Canceling extended bolus: " + result); return result; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpFragment.java index f5007ca121..ef4c85e0a7 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpFragment.java @@ -15,10 +15,12 @@ import com.squareup.otto.Subscribe; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.db.ExtendedBolus; import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.plugins.Common.SubscriberFragment; +import info.nightscout.androidaps.plugins.PumpCommon.defs.PumpType; import info.nightscout.androidaps.plugins.PumpVirtual.events.EventVirtualPumpUpdateGui; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.utils.FabricPrivacy; @@ -31,6 +33,9 @@ public class VirtualPumpFragment extends SubscriberFragment { TextView extendedBolusView; TextView batteryView; TextView reservoirView; + TextView pumpTypeView; + TextView pumpSettingsView; + private static Handler sLoopHandler = new Handler(); private static Runnable sRefreshLoop = null; @@ -60,6 +65,8 @@ public class VirtualPumpFragment extends SubscriberFragment { extendedBolusView = (TextView) view.findViewById(R.id.virtualpump_extendedbolus); batteryView = (TextView) view.findViewById(R.id.virtualpump_battery); reservoirView = (TextView) view.findViewById(R.id.virtualpump_reservoir); + pumpTypeView = (TextView) view.findViewById(R.id.virtualpump_type); + pumpSettingsView = (TextView) view.findViewById(R.id.virtualpump_type_def); return view; } catch (Exception e) { @@ -97,6 +104,18 @@ public class VirtualPumpFragment extends SubscriberFragment { } batteryView.setText(virtualPump.batteryPercent + "%"); reservoirView.setText(virtualPump.reservoirInUnits + "U"); + + virtualPump.refreshConfiguration(); + + PumpType pumpType = virtualPump.getPumpType(); + + pumpTypeView.setText(pumpType.getDescription()); + + String template = MainApp.gs(R.string.virtualpump_pump_def); + + + pumpSettingsView.setText(pumpType.getFullDescription(template, pumpType.hasExtendedBasals())); + } }); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpPlugin.java index 34d3fee80b..3207791b88 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpPlugin.java @@ -2,13 +2,13 @@ package info.nightscout.androidaps.plugins.PumpVirtual; import android.os.SystemClock; +import com.squareup.otto.Subscribe; + import org.json.JSONException; import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Date; - import info.nightscout.androidaps.BuildConfig; import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; @@ -19,57 +19,38 @@ import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.db.ExtendedBolus; import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.TemporaryBasal; +import info.nightscout.androidaps.events.EventPreferenceChange; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.PumpDescription; import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; +import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress; import info.nightscout.androidaps.plugins.Overview.notifications.Notification; +import info.nightscout.androidaps.plugins.PumpCommon.defs.PumpType; import info.nightscout.androidaps.plugins.PumpVirtual.events.EventVirtualPumpUpdateGui; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.utils.DateUtil; -import info.nightscout.utils.NSUpload; import info.nightscout.utils.SP; /** * Created by mike on 05.08.2016. */ public class VirtualPumpPlugin extends PluginBase implements PumpInterface { - private static Logger log = LoggerFactory.getLogger(VirtualPumpPlugin.class); + private Logger log = LoggerFactory.getLogger(L.PUMP); + Integer batteryPercent = 50; + Integer reservoirInUnits = 50; private static VirtualPumpPlugin plugin = null; - - public static VirtualPumpPlugin getPlugin() { - loadFakingStatus(); - if (plugin == null) - plugin = new VirtualPumpPlugin(); - return plugin; - } - - static Integer batteryPercent = 50; - static Integer reservoirInUnits = 50; - - private Date lastDataTime = new Date(0); - - private static boolean fromNSAreCommingFakedExtendedBoluses = false; - + private boolean fromNSAreCommingFakedExtendedBoluses = false; + private PumpType pumpType = null; + private long lastDataTime = 0; private PumpDescription pumpDescription = new PumpDescription(); - private static void loadFakingStatus() { - fromNSAreCommingFakedExtendedBoluses = SP.getBoolean(R.string.key_fromNSAreCommingFakedExtendedBoluses, false); - } - - public static void setFakingStatus(boolean newStatus) { - fromNSAreCommingFakedExtendedBoluses = newStatus; - SP.putBoolean(R.string.key_fromNSAreCommingFakedExtendedBoluses, fromNSAreCommingFakedExtendedBoluses); - } - - public static boolean getFakingStatus() { - return fromNSAreCommingFakedExtendedBoluses; - } - public VirtualPumpPlugin() { super(new PluginDescription() .mainType(PluginType.PUMP) @@ -77,6 +58,8 @@ public class VirtualPumpPlugin extends PluginBase implements PumpInterface { .pluginName(R.string.virtualpump) .shortName(R.string.virtualpump_shortname) .preferencesId(R.xml.pref_virtualpump) + .neverVisible(Config.NSCLIENT) + .description(R.string.description_pump_virtual) ); pumpDescription.isBolusCapable = true; pumpDescription.bolusStep = 0.1d; @@ -108,16 +91,53 @@ public class VirtualPumpPlugin extends PluginBase implements PumpInterface { pumpDescription.is30minBasalRatesCapable = true; } + public static VirtualPumpPlugin getPlugin() { + if (plugin == null) + plugin = new VirtualPumpPlugin(); + plugin.loadFakingStatus(); + return plugin; + } + + private void loadFakingStatus() { + fromNSAreCommingFakedExtendedBoluses = SP.getBoolean(R.string.key_fromNSAreCommingFakedExtendedBoluses, false); + } + + public boolean getFakingStatus() { + return fromNSAreCommingFakedExtendedBoluses; + } + + public void setFakingStatus(boolean newStatus) { + fromNSAreCommingFakedExtendedBoluses = newStatus; + SP.putBoolean(R.string.key_fromNSAreCommingFakedExtendedBoluses, fromNSAreCommingFakedExtendedBoluses); + } + + @Override + protected void onStart() { + super.onStart(); + MainApp.bus().register(this); + refreshConfiguration(); + } + + @Override + protected void onStop() { + MainApp.bus().unregister(this); + } + + @Subscribe + public void onStatusEvent(final EventPreferenceChange s) { + if (s.isChanged(R.string.key_virtualpump_type)) + refreshConfiguration(); + } + @Override public boolean isFakingTempsByExtendedBoluses() { - return (Config.NSCLIENT || Config.G5UPLOADER) && fromNSAreCommingFakedExtendedBoluses; + return (Config.NSCLIENT) && fromNSAreCommingFakedExtendedBoluses; } @Override public PumpEnactResult loadTDDs() { //no result, could read DB in the future? - PumpEnactResult result = new PumpEnactResult(); - return result; + return new PumpEnactResult(); } @Override @@ -145,11 +165,20 @@ public class VirtualPumpPlugin extends PluginBase implements PumpInterface { return false; } + @Override + public boolean isHandshakeInProgress() { + return false; + } + + @Override + public void finishHandshaking() { + } + @Override public void connect(String reason) { - if (!Config.NSCLIENT && !Config.G5UPLOADER) + if (!Config.NSCLIENT) NSUpload.uploadDeviceStatus(); - lastDataTime = new Date(); + lastDataTime = System.currentTimeMillis(); } @Override @@ -162,13 +191,13 @@ public class VirtualPumpPlugin extends PluginBase implements PumpInterface { @Override public void getPumpStatus() { - lastDataTime = new Date(); + lastDataTime = System.currentTimeMillis(); } @Override public PumpEnactResult setNewBasalProfile(Profile profile) { - lastDataTime = new Date(); - // Do nothing here. we are using MainApp.getConfigBuilder().getActiveProfile().getProfile(); + lastDataTime = System.currentTimeMillis(); + // Do nothing here. we are using ConfigBuilderPlugin.getPlugin().getActiveProfile().getProfile(); PumpEnactResult result = new PumpEnactResult(); result.success = true; Notification notification = new Notification(Notification.PROFILE_SET_OK, MainApp.gs(R.string.profile_set_ok), Notification.INFO, 60); @@ -182,21 +211,23 @@ public class VirtualPumpPlugin extends PluginBase implements PumpInterface { } @Override - public Date lastDataTime() { + public long lastDataTime() { return lastDataTime; } @Override public double getBaseBasalRate() { - Profile profile = MainApp.getConfigBuilder().getProfile(); + Profile profile = ProfileFunctions.getInstance().getProfile(); if (profile != null) return profile.getBasal(); else return 0d; } + @Override public PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo) { + PumpEnactResult result = new PumpEnactResult(); result.success = true; result.bolusDelivered = detailedBolusInfo.insulin; @@ -220,21 +251,21 @@ public class VirtualPumpPlugin extends PluginBase implements PumpInterface { bolusingEvent.percent = 100; MainApp.bus().post(bolusingEvent); SystemClock.sleep(1000); - if (Config.logPumpComm) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Delivering treatment insulin: " + detailedBolusInfo.insulin + "U carbs: " + detailedBolusInfo.carbs + "g " + result); MainApp.bus().post(new EventVirtualPumpUpdateGui()); - lastDataTime = new Date(); - TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo); + lastDataTime = System.currentTimeMillis(); + TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false); return result; } @Override public void stopBolusDelivering() { - } @Override public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, Profile profile, boolean enforceNew) { + TemporaryBasal tempBasal = new TemporaryBasal() .date(System.currentTimeMillis()) .absolute(absoluteRate) @@ -248,26 +279,21 @@ public class VirtualPumpPlugin extends PluginBase implements PumpInterface { result.duration = durationInMinutes; result.comment = MainApp.gs(R.string.virtualpump_resultok); TreatmentsPlugin.getPlugin().addToHistoryTempBasal(tempBasal); - if (Config.logPumpComm) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Setting temp basal absolute: " + result); MainApp.bus().post(new EventVirtualPumpUpdateGui()); - lastDataTime = new Date(); + lastDataTime = System.currentTimeMillis(); return result; } @Override public PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes, Profile profile, boolean enforceNew) { - PumpEnactResult result = new PumpEnactResult(); - if (TreatmentsPlugin.getPlugin().isTempBasalInProgress()) { - result = cancelTempBasal(false); - if (!result.success) - return result; - } TemporaryBasal tempBasal = new TemporaryBasal() .date(System.currentTimeMillis()) .percent(percent) .duration(durationInMinutes) .source(Source.USER); + PumpEnactResult result = new PumpEnactResult(); result.success = true; result.enacted = true; result.percent = percent; @@ -276,10 +302,10 @@ public class VirtualPumpPlugin extends PluginBase implements PumpInterface { result.duration = durationInMinutes; result.comment = MainApp.gs(R.string.virtualpump_resultok); TreatmentsPlugin.getPlugin().addToHistoryTempBasal(tempBasal); - if (Config.logPumpComm) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Settings temp basal percent: " + result); MainApp.bus().post(new EventVirtualPumpUpdateGui()); - lastDataTime = new Date(); + lastDataTime = System.currentTimeMillis(); return result; } @@ -288,11 +314,12 @@ public class VirtualPumpPlugin extends PluginBase implements PumpInterface { PumpEnactResult result = cancelExtendedBolus(); if (!result.success) return result; - ExtendedBolus extendedBolus = new ExtendedBolus(); - extendedBolus.date = System.currentTimeMillis(); - extendedBolus.insulin = insulin; - extendedBolus.durationInMinutes = durationInMinutes; - extendedBolus.source = Source.USER; + + ExtendedBolus extendedBolus = new ExtendedBolus() + .date(System.currentTimeMillis()) + .insulin(insulin) + .durationInMinutes(durationInMinutes) + .source(Source.USER); result.success = true; result.enacted = true; result.bolusDelivered = insulin; @@ -300,10 +327,10 @@ public class VirtualPumpPlugin extends PluginBase implements PumpInterface { result.duration = durationInMinutes; result.comment = MainApp.gs(R.string.virtualpump_resultok); TreatmentsPlugin.getPlugin().addToHistoryExtendedBolus(extendedBolus); - if (Config.logPumpComm) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Setting extended bolus: " + result); MainApp.bus().post(new EventVirtualPumpUpdateGui()); - lastDataTime = new Date(); + lastDataTime = System.currentTimeMillis(); return result; } @@ -318,11 +345,11 @@ public class VirtualPumpPlugin extends PluginBase implements PumpInterface { TemporaryBasal tempStop = new TemporaryBasal().date(System.currentTimeMillis()).source(Source.USER); TreatmentsPlugin.getPlugin().addToHistoryTempBasal(tempStop); //tempBasal = null; - if (Config.logPumpComm) + if (L.isEnabled(L.PUMPCOMM)) log.debug("Canceling temp basal: " + result); MainApp.bus().post(new EventVirtualPumpUpdateGui()); } - lastDataTime = new Date(); + lastDataTime = System.currentTimeMillis(); return result; } @@ -338,10 +365,10 @@ public class VirtualPumpPlugin extends PluginBase implements PumpInterface { result.enacted = true; result.isTempCancel = true; result.comment = MainApp.gs(R.string.virtualpump_resultok); - if (Config.logPumpComm) - log.debug("Canceling extended basal: " + result); + if (L.isEnabled(L.PUMPCOMM)) + log.debug("Canceling extended bolus: " + result); MainApp.bus().post(new EventVirtualPumpUpdateGui()); - lastDataTime = new Date(); + lastDataTime = System.currentTimeMillis(); return result; } @@ -361,7 +388,7 @@ public class VirtualPumpPlugin extends PluginBase implements PumpInterface { extended.put("Version", BuildConfig.VERSION_NAME + "-" + BuildConfig.BUILDVERSION); try { extended.put("ActiveProfile", profileName); - } catch (Exception e) { + } catch (Exception ignored) { } TemporaryBasal tb = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(now); if (tb != null) { @@ -403,4 +430,29 @@ public class VirtualPumpPlugin extends PluginBase implements PumpInterface { return "Virtual Pump"; } + public PumpType getPumpType() { + return pumpType; + } + + + public void refreshConfiguration() { + String pumptype = SP.getString(R.string.key_virtualpump_type, "Generic AAPS"); + + PumpType pumpTypeNew = PumpType.getByDescription(pumptype); + + if (L.isEnabled(L.PUMP)) + log.debug("Pump in configuration: {}, PumpType object: {}", pumptype, pumpTypeNew); + + if (pumpType == pumpTypeNew) + return; + + if (L.isEnabled(L.PUMP)) + log.debug("New pump configuration found ({}), changing from previous ({})", pumpTypeNew, pumpType); + + pumpDescription.setPumpDescription(pumpTypeNew); + + this.pumpType = pumpTypeNew; + + } + } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Sensitivity/AbstractSensitivityPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Sensitivity/AbstractSensitivityPlugin.java new file mode 100644 index 0000000000..9f72f1b119 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Sensitivity/AbstractSensitivityPlugin.java @@ -0,0 +1,70 @@ +package info.nightscout.androidaps.plugins.Sensitivity; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.interfaces.PluginBase; +import info.nightscout.androidaps.interfaces.PluginDescription; +import info.nightscout.androidaps.interfaces.SensitivityInterface; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensResult; +import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin; +import info.nightscout.utils.Round; +import info.nightscout.utils.SP; +import info.nightscout.utils.SafeParse; + +public abstract class AbstractSensitivityPlugin extends PluginBase implements SensitivityInterface { + + private static final Logger log = LoggerFactory.getLogger(L.AUTOSENS); + + public AbstractSensitivityPlugin(PluginDescription pluginDescription) { + super(pluginDescription); + } + + @Override + public abstract AutosensResult detectSensitivity(IobCobCalculatorPlugin plugin, long fromTime, long toTime); + + AutosensResult fillResult(double ratio, double carbsAbsorbed, String pastSensitivity, + String ratioLimit, String sensResult, int deviationsArraySize) { + return this.fillResult(ratio, carbsAbsorbed, pastSensitivity, ratioLimit, sensResult, + deviationsArraySize, + SafeParse.stringToDouble(SP.getString(R.string.key_openapsama_autosens_min, "0.7")), + SafeParse.stringToDouble(SP.getString(R.string.key_openapsama_autosens_max, "1.2"))); + } + + public AutosensResult fillResult(double ratio, double carbsAbsorbed, String pastSensitivity, + String ratioLimit, String sensResult, int deviationsArraySize, + double ratioMin, double ratioMax) { + double rawRatio = ratio; + ratio = Math.max(ratio, ratioMin); + ratio = Math.min(ratio, ratioMax); + + //If not-excluded data <= MIN_HOURS -> don't do Autosens + //If not-excluded data >= MIN_HOURS_FULL_AUTOSENS -> full Autosens + //Between MIN_HOURS and MIN_HOURS_FULL_AUTOSENS: gradually increase autosens + double autosensContrib = (Math.min(Math.max(MIN_HOURS, deviationsArraySize / 12d), + MIN_HOURS_FULL_AUTOSENS) - MIN_HOURS) / (MIN_HOURS_FULL_AUTOSENS - MIN_HOURS); + ratio = autosensContrib * (ratio - 1) + 1; + + if (autosensContrib != 1d) { + ratioLimit += "(" + deviationsArraySize + " of " + MIN_HOURS_FULL_AUTOSENS * 12 + " values) "; + } + + if (ratio != rawRatio) { + ratioLimit += "Ratio limited from " + rawRatio + " to " + ratio; + if (L.isEnabled(L.AUTOSENS)) + log.debug(ratioLimit); + } + + AutosensResult output = new AutosensResult(); + output.ratio = Round.roundTo(ratio, 0.01); + output.carbsAbsorbed = Round.roundTo(carbsAbsorbed, 0.01); + output.pastSensitivity = pastSensitivity; + output.ratioLimit = ratioLimit; + output.sensResult = sensResult; + return output; + } + + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/SensitivityAAPS/SensitivityAAPSPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Sensitivity/SensitivityAAPSPlugin.java similarity index 57% rename from app/src/main/java/info/nightscout/androidaps/plugins/SensitivityAAPS/SensitivityAAPSPlugin.java rename to app/src/main/java/info/nightscout/androidaps/plugins/Sensitivity/SensitivityAAPSPlugin.java index 75b1ea9675..432420df85 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/SensitivityAAPS/SensitivityAAPSPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Sensitivity/SensitivityAAPSPlugin.java @@ -1,37 +1,36 @@ -package info.nightscout.androidaps.plugins.SensitivityAAPS; +package info.nightscout.androidaps.plugins.Sensitivity; import android.support.v4.util.LongSparseArray; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.Profile; -import info.nightscout.androidaps.interfaces.PluginBase; +import info.nightscout.androidaps.db.CareportalEvent; +import info.nightscout.androidaps.db.ProfileSwitch; import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginType; -import info.nightscout.androidaps.interfaces.SensitivityInterface; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensData; import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensResult; import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin; -import info.nightscout.utils.Round; +import info.nightscout.utils.DateUtil; import info.nightscout.utils.SP; -import info.nightscout.utils.SafeParse; /** * Created by mike on 24.06.2017. */ -public class SensitivityAAPSPlugin extends PluginBase implements SensitivityInterface { - private static Logger log = LoggerFactory.getLogger(SensitivityAAPSPlugin.class); +public class SensitivityAAPSPlugin extends AbstractSensitivityPlugin { + private static Logger log = LoggerFactory.getLogger(L.AUTOSENS); static SensitivityAAPSPlugin plugin = null; @@ -47,12 +46,13 @@ public class SensitivityAAPSPlugin extends PluginBase implements SensitivityInte .pluginName(R.string.sensitivityaaps) .shortName(R.string.sensitivity_shortname) .preferencesId(R.xml.pref_absorption_aaps) + .description(R.string.description_sensitivity_aaps) ); } @Override - public AutosensResult detectSensitivity(long fromTime, long toTime) { - LongSparseArray autosensDataTable = IobCobCalculatorPlugin.getPlugin().getAutosensDataTable(); + public AutosensResult detectSensitivity(IobCobCalculatorPlugin iobCobCalculatorPlugin, long fromTime, long toTime) { + LongSparseArray autosensDataTable = iobCobCalculatorPlugin.getAutosensDataTable(); String age = SP.getString(R.string.key_age, ""); int defaultHours = 24; @@ -61,25 +61,30 @@ public class SensitivityAAPSPlugin extends PluginBase implements SensitivityInte if (age.equals(MainApp.gs(R.string.key_child))) defaultHours = 4; int hoursForDetection = SP.getInt(R.string.key_openapsama_autosens_period, defaultHours); - Profile profile = MainApp.getConfigBuilder().getProfile(); + Profile profile = ProfileFunctions.getInstance().getProfile(); if (profile == null) { - log.debug("No profile"); + log.error("No profile"); return new AutosensResult(); } if (autosensDataTable == null || autosensDataTable.size() < 4) { - log.debug("No autosens data available"); + if (L.isEnabled(L.AUTOSENS)) + log.debug("No autosens data available. lastDataTime=" + iobCobCalculatorPlugin.lastDataTime()); return new AutosensResult(); } - AutosensData current = IobCobCalculatorPlugin.getPlugin().getAutosensData(toTime); // this is running inside lock already + AutosensData current = iobCobCalculatorPlugin.getAutosensData(toTime); // this is running inside lock already if (current == null) { - log.debug("No autosens data available"); + if (L.isEnabled(L.AUTOSENS)) + log.debug("No autosens data available. toTime: " + DateUtil.dateAndTimeString(toTime) + " lastDataTime: " + iobCobCalculatorPlugin.lastDataTime()); return new AutosensResult(); } + List siteChanges = MainApp.getDbHelper().getCareportalEventsFromTime(fromTime, CareportalEvent.SITECHANGE, true); + List profileSwitches = MainApp.getDbHelper().getProfileSwitchEventsFromTime(fromTime, true); + List deviationsArray = new ArrayList<>(); String pastSensitivity = ""; int index = 0; @@ -96,8 +101,27 @@ public class SensitivityAAPSPlugin extends PluginBase implements SensitivityInte continue; } - if (autosensData.time > toTime - hoursForDetection * 60 * 60 * 1000L) - deviationsArray.add(autosensData.nonEqualDeviation ? autosensData.deviation : 0d); + // reset deviations after site change + if (CareportalEvent.isEvent5minBack(siteChanges, autosensData.time)) { + deviationsArray.clear(); + pastSensitivity += "(SITECHANGE)"; + } + + // reset deviations after profile switch + if (ProfileSwitch.isEvent5minBack(profileSwitches, autosensData.time, true)) { + deviationsArray.clear(); + pastSensitivity += "(PROFILESWITCH)"; + } + + double deviation = autosensData.deviation; + + //set positive deviations to zero if bg < 80 + if (autosensData.bg < 80 && deviation > 0) + deviation = 0; + + if (autosensData.validDeviation) + if (autosensData.time > toTime - hoursForDetection * 60 * 60 * 1000L) + deviationsArray.add(deviation); if (deviationsArray.size() > hoursForDetection * 60 / 5) deviationsArray.remove(0); @@ -118,7 +142,7 @@ public class SensitivityAAPSPlugin extends PluginBase implements SensitivityInte String ratioLimit = ""; String sensResult = ""; - if (Config.logAutosensData) + if (L.isEnabled(L.AUTOSENS)) log.debug("Records: " + index + " " + pastSensitivity); Arrays.sort(deviations); @@ -135,29 +159,19 @@ public class SensitivityAAPSPlugin extends PluginBase implements SensitivityInte sensResult = "Sensitivity normal"; } - if (Config.logAutosensData) + if (L.isEnabled(L.AUTOSENS)) log.debug(sensResult); - double rawRatio = ratio; - ratio = Math.max(ratio, SafeParse.stringToDouble(SP.getString(R.string.key_openapsama_autosens_min, "0.7"))); - ratio = Math.min(ratio, SafeParse.stringToDouble(SP.getString(R.string.key_openapsama_autosens_max, "1.2"))); + AutosensResult output = fillResult(ratio, current.cob, pastSensitivity, ratioLimit, + sensResult, deviationsArray.size()); - if (ratio != rawRatio) { - ratioLimit = "Ratio limited from " + rawRatio + " to " + ratio; - log.debug(ratioLimit); - } - - if (Config.logAutosensData) { - log.debug("Sensitivity to: " + new Date(toTime).toLocaleString() + " percentile: " + percentile + " ratio: " + ratio + " mealCOB: " + current.cob); + if (L.isEnabled(L.AUTOSENS)) { + log.debug("Sensitivity to: {}, percentile: {} ratio: {} mealCOB: ", + new Date(toTime).toLocaleString(), + percentile, output.ratio, ratio, current.cob); log.debug("Sensitivity to: deviations " + Arrays.toString(deviations)); } - AutosensResult output = new AutosensResult(); - output.ratio = Round.roundTo(ratio, 0.01); - output.carbsAbsorbed = Round.roundTo(current.cob, 0.01); - output.pastSensitivity = pastSensitivity; - output.ratioLimit = ratioLimit; - output.sensResult = sensResult; return output; } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/SensitivityOref0/SensitivityOref0Plugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Sensitivity/SensitivityOref0Plugin.java similarity index 57% rename from app/src/main/java/info/nightscout/androidaps/plugins/SensitivityOref0/SensitivityOref0Plugin.java rename to app/src/main/java/info/nightscout/androidaps/plugins/Sensitivity/SensitivityOref0Plugin.java index 15be72880d..53a8be8661 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/SensitivityOref0/SensitivityOref0Plugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Sensitivity/SensitivityOref0Plugin.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.SensitivityOref0; +package info.nightscout.androidaps.plugins.Sensitivity; import android.support.v4.util.LongSparseArray; @@ -10,27 +10,26 @@ import java.util.Arrays; import java.util.Date; import java.util.List; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.Profile; -import info.nightscout.androidaps.interfaces.PluginBase; +import info.nightscout.androidaps.db.CareportalEvent; +import info.nightscout.androidaps.db.ProfileSwitch; import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginType; -import info.nightscout.androidaps.interfaces.SensitivityInterface; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensData; import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensResult; import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin; -import info.nightscout.utils.Round; -import info.nightscout.utils.SP; -import info.nightscout.utils.SafeParse; +import info.nightscout.utils.DateUtil; /** * Created by mike on 24.06.2017. */ -public class SensitivityOref0Plugin extends PluginBase implements SensitivityInterface { - private static Logger log = LoggerFactory.getLogger(IobCobCalculatorPlugin.class); +public class SensitivityOref0Plugin extends AbstractSensitivityPlugin { + private static Logger log = LoggerFactory.getLogger(L.AUTOSENS); static SensitivityOref0Plugin plugin = null; @@ -46,40 +45,41 @@ public class SensitivityOref0Plugin extends PluginBase implements SensitivityInt .pluginName(R.string.sensitivityoref0) .shortName(R.string.sensitivity_shortname) .preferencesId(R.xml.pref_absorption_oref0) + .description(R.string.description_sensitivity_oref0) ); } @Override - public AutosensResult detectSensitivity(long fromTime, long toTime) { - LongSparseArray autosensDataTable = IobCobCalculatorPlugin.getPlugin().getAutosensDataTable(); + public AutosensResult detectSensitivity(IobCobCalculatorPlugin iobCobCalculatorPlugin, long fromTime, long toTime) { + LongSparseArray autosensDataTable = iobCobCalculatorPlugin.getAutosensDataTable(); - String age = SP.getString(R.string.key_age, ""); - int defaultHours = 24; - if (age.equals(MainApp.gs(R.string.key_adult))) defaultHours = 24; - if (age.equals(MainApp.gs(R.string.key_teenage))) defaultHours = 24; - if (age.equals(MainApp.gs(R.string.key_child))) defaultHours = 24; - int hoursForDetection = SP.getInt(R.string.key_openapsama_autosens_period, defaultHours); + int hoursForDetection = 24; long now = System.currentTimeMillis(); - Profile profile = MainApp.getConfigBuilder().getProfile(); + Profile profile = ProfileFunctions.getInstance().getProfile(); if (profile == null) { - log.debug("No profile"); + log.error("No profile"); return new AutosensResult(); } if (autosensDataTable == null || autosensDataTable.size() < 4) { - log.debug("No autosens data available"); + if (L.isEnabled(L.AUTOSENS)) + log.debug("No autosens data available. lastDataTime=" + iobCobCalculatorPlugin.lastDataTime()); return new AutosensResult(); } - AutosensData current = IobCobCalculatorPlugin.getPlugin().getAutosensData(toTime); // this is running inside lock already + AutosensData current = iobCobCalculatorPlugin.getAutosensData(toTime); // this is running inside lock already if (current == null) { - log.debug("No current autosens data available"); + if (L.isEnabled(L.AUTOSENS)) + log.debug("No autosens data available. toTime: " + DateUtil.dateAndTimeString(toTime) + " lastDataTime: " + iobCobCalculatorPlugin.lastDataTime()); return new AutosensResult(); } + List siteChanges = MainApp.getDbHelper().getCareportalEventsFromTime(fromTime, CareportalEvent.SITECHANGE, true); + List profileSwitches = MainApp.getDbHelper().getProfileSwitchEventsFromTime(fromTime, true); + List deviationsArray = new ArrayList<>(); String pastSensitivity = ""; int index = 0; @@ -96,8 +96,27 @@ public class SensitivityOref0Plugin extends PluginBase implements SensitivityInt continue; } - if (autosensData.time > toTime - hoursForDetection * 60 * 60 * 1000L) - deviationsArray.add(autosensData.nonEqualDeviation ? autosensData.deviation : 0d); + // reset deviations after site change + if (CareportalEvent.isEvent5minBack(siteChanges, autosensData.time)) { + deviationsArray.clear(); + pastSensitivity += "(SITECHANGE)"; + } + + // reset deviations after profile switch + if (ProfileSwitch.isEvent5minBack(profileSwitches, autosensData.time, true)) { + deviationsArray.clear(); + pastSensitivity += "(PROFILESWITCH)"; + } + + double deviation = autosensData.deviation; + + //set positive deviations to zero if bg < 80 + if (autosensData.bg < 80 && deviation > 0) + deviation = 0; + + if (autosensData.validDeviation) + if (autosensData.time > toTime - hoursForDetection * 60 * 60 * 1000L) + deviationsArray.add(deviation); if (deviationsArray.size() > hoursForDetection * 60 / 5) deviationsArray.remove(0); @@ -118,14 +137,14 @@ public class SensitivityOref0Plugin extends PluginBase implements SensitivityInt String ratioLimit = ""; String sensResult = ""; - if (Config.logAutosensData) + if (L.isEnabled(L.AUTOSENS)) log.debug("Records: " + index + " " + pastSensitivity); Arrays.sort(deviations); for (double i = 0.9; i > 0.1; i = i - 0.02) { if (IobCobCalculatorPlugin.percentile(deviations, (i + 0.02)) >= 0 && IobCobCalculatorPlugin.percentile(deviations, i) < 0) { - if (Config.logAutosensData) + if (L.isEnabled(L.AUTOSENS)) log.debug(Math.round(100 * i) + "% of non-meal deviations negative (target 45%-50%)"); } } @@ -144,29 +163,18 @@ public class SensitivityOref0Plugin extends PluginBase implements SensitivityInt sensResult = "Sensitivity normal"; } - if (Config.logAutosensData) + if (L.isEnabled(L.AUTOSENS)) log.debug(sensResult); ratio = 1 + (basalOff / profile.getMaxDailyBasal()); - double rawRatio = ratio; - ratio = Math.max(ratio, SafeParse.stringToDouble(SP.getString(R.string.key_openapsama_autosens_min, "0.7"))); - ratio = Math.min(ratio, SafeParse.stringToDouble(SP.getString(R.string.key_openapsama_autosens_max, "1.2"))); + AutosensResult output = fillResult(ratio, current.cob, pastSensitivity, ratioLimit, + sensResult, deviationsArray.size()); - if (ratio != rawRatio) { - ratioLimit = "Ratio limited from " + rawRatio + " to " + ratio; - log.debug(ratioLimit); - } + if (L.isEnabled(L.AUTOSENS)) + log.debug("Sensitivity to: {} ratio: {} mealCOB: {}", + new Date(toTime).toLocaleString(), output.ratio, current.cob); - if (Config.logAutosensData) - log.debug("Sensitivity to: " + new Date(toTime).toLocaleString() + " ratio: " + ratio + " mealCOB: " + current.cob); - - AutosensResult output = new AutosensResult(); - output.ratio = Round.roundTo(ratio, 0.01); - output.carbsAbsorbed = Round.roundTo(current.cob, 0.01); - output.pastSensitivity = pastSensitivity; - output.ratioLimit = ratioLimit; - output.sensResult = sensResult; return output; } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Sensitivity/SensitivityOref1Plugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Sensitivity/SensitivityOref1Plugin.java new file mode 100644 index 0000000000..7d91c7fc4a --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Sensitivity/SensitivityOref1Plugin.java @@ -0,0 +1,199 @@ +package info.nightscout.androidaps.plugins.Sensitivity; + +import android.support.v4.util.LongSparseArray; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.data.Profile; +import info.nightscout.androidaps.db.CareportalEvent; +import info.nightscout.androidaps.db.ProfileSwitch; +import info.nightscout.androidaps.interfaces.PluginDescription; +import info.nightscout.androidaps.interfaces.PluginType; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; +import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensData; +import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensResult; +import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin; +import info.nightscout.utils.DateUtil; + +/** + * Created by mike on 19.06.2018. + */ + +public class SensitivityOref1Plugin extends AbstractSensitivityPlugin { + private static Logger log = LoggerFactory.getLogger(L.AUTOSENS); + + static SensitivityOref1Plugin plugin = null; + + public static SensitivityOref1Plugin getPlugin() { + if (plugin == null) + plugin = new SensitivityOref1Plugin(); + return plugin; + } + + public SensitivityOref1Plugin() { + super(new PluginDescription() + .mainType(PluginType.SENSITIVITY) + .pluginName(R.string.sensitivityoref1) + .shortName(R.string.sensitivity_shortname) + .preferencesId(R.xml.pref_absorption_oref1) + .description(R.string.description_sensitivity_oref1) + ); + } + + @Override + public AutosensResult detectSensitivity(IobCobCalculatorPlugin iobCobCalculatorPlugin, long fromTime, long toTime) { + // todo this method is called from the IobCobCalculatorPlugin, which leads to a circular + // dependency, this should be avoided + LongSparseArray autosensDataTable = iobCobCalculatorPlugin.getAutosensDataTable(); + + Profile profile = ProfileFunctions.getInstance().getProfile(); + + if (profile == null) { + log.error("No profile"); + return new AutosensResult(); + } + + if (autosensDataTable == null || autosensDataTable.size() < 4) { + if (L.isEnabled(L.AUTOSENS)) + log.debug("No autosens data available. lastDataTime=" + iobCobCalculatorPlugin.lastDataTime()); + return new AutosensResult(); + } + + // the current + AutosensData current = iobCobCalculatorPlugin.getAutosensData(toTime); // this is running inside lock already + if (current == null) { + if (L.isEnabled(L.AUTOSENS)) + log.debug("No autosens data available. toTime: " + DateUtil.dateAndTimeString(toTime) + " lastDataTime: " + iobCobCalculatorPlugin.lastDataTime()); + return new AutosensResult(); + } + + List siteChanges = MainApp.getDbHelper().getCareportalEventsFromTime(fromTime, CareportalEvent.SITECHANGE, true); + List profileSwitches = MainApp.getDbHelper().getProfileSwitchEventsFromTime(fromTime, true); + + List deviationsArray = new ArrayList<>(); + String pastSensitivity = ""; + int index = 0; + while (index < autosensDataTable.size()) { + AutosensData autosensData = autosensDataTable.valueAt(index); + + if (autosensData.time < fromTime) { + index++; + continue; + } + + if (autosensData.time > toTime) { + index++; + continue; + } + + // reset deviations after site change + if (CareportalEvent.isEvent5minBack(siteChanges, autosensData.time)) { + deviationsArray.clear(); + pastSensitivity += "(SITECHANGE)"; + } + + // reset deviations after profile switch + if (ProfileSwitch.isEvent5minBack(profileSwitches, autosensData.time, true)) { + deviationsArray.clear(); + pastSensitivity += "(PROFILESWITCH)"; + } + + double deviation = autosensData.deviation; + + //set positive deviations to zero if bg < 80 + if (autosensData.bg < 80 && deviation > 0) + deviation = 0; + + if (autosensData.validDeviation) + deviationsArray.add(deviation); + + for (int i = 0; i < autosensData.extraDeviation.size(); i++) + deviationsArray.add(autosensData.extraDeviation.get(i)); + if (deviationsArray.size() > 96) + deviationsArray.remove(0); + + pastSensitivity += autosensData.pastSensitivity; + int secondsFromMidnight = Profile.secondsFromMidnight(autosensData.time); + if (secondsFromMidnight % 3600 < 2.5 * 60 || secondsFromMidnight % 3600 > 57.5 * 60) { + pastSensitivity += "(" + Math.round(secondsFromMidnight / 3600d) + ")"; + } + index++; + } + + // when we have less than 8h worth of deviation data, add up to 90m of zero deviations + // this dampens any large sensitivity changes detected based on too little data, without ignoring them completely + if (L.isEnabled(L.AUTOSENS)) + log.debug("Using most recent " + deviationsArray.size() + " deviations"); + if (deviationsArray.size() < 96) { + int pad = Math.round((1 - deviationsArray.size() / 96) * 18); + if (L.isEnabled(L.AUTOSENS)) + log.debug("Adding " + pad + " more zero deviations"); + for (int d = 0; d < pad; d++) { + //process.stderr.write("."); + deviationsArray.add(0d); + } + } + + Double[] deviations = new Double[deviationsArray.size()]; + deviations = deviationsArray.toArray(deviations); + + double sens = profile.getIsf(); + + double ratio = 1; + String ratioLimit = ""; + String sensResult = ""; + + if (L.isEnabled(L.AUTOSENS)) + log.debug("Records: " + index + " " + pastSensitivity); + + Arrays.sort(deviations); + + for (double i = 0.9; i > 0.1; i = i - 0.01) { + if (IobCobCalculatorPlugin.percentile(deviations, (i + 0.01)) >= 0 && IobCobCalculatorPlugin.percentile(deviations, i) < 0) { + if (L.isEnabled(L.AUTOSENS)) + log.debug(Math.round(100 * i) + "% of non-meal deviations negative (>50% = sensitivity)"); + } + if (IobCobCalculatorPlugin.percentile(deviations, (i + 0.01)) > 0 && IobCobCalculatorPlugin.percentile(deviations, i) <= 0) { + if (L.isEnabled(L.AUTOSENS)) + log.debug(Math.round(100 * i) + "% of non-meal deviations negative (>50% = resistance)"); + } + } + double pSensitive = IobCobCalculatorPlugin.percentile(deviations, 0.50); + double pResistant = IobCobCalculatorPlugin.percentile(deviations, 0.50); + + double basalOff = 0; + + if (pSensitive < 0) { // sensitive + basalOff = pSensitive * (60 / 5) / Profile.toMgdl(sens, profile.getUnits()); + sensResult = "Excess insulin sensitivity detected"; + } else if (pResistant > 0) { // resistant + basalOff = pResistant * (60 / 5) / Profile.toMgdl(sens, profile.getUnits()); + sensResult = "Excess insulin resistance detected"; + } else { + sensResult = "Sensitivity normal"; + } + + if (L.isEnabled(L.AUTOSENS)) + log.debug(sensResult); + + ratio = 1 + (basalOff / profile.getMaxDailyBasal()); + + AutosensResult output = fillResult(ratio, current.cob, pastSensitivity, ratioLimit, + sensResult, deviationsArray.size()); + + if (L.isEnabled(L.AUTOSENS)) + log.debug("Sensitivity to: {} ratio: {} mealCOB: {}", + new Date(toTime).toLocaleString(), output.ratio, current.cob); + + return output; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/SensitivityWeightedAverage/SensitivityWeightedAveragePlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Sensitivity/SensitivityWeightedAveragePlugin.java similarity index 57% rename from app/src/main/java/info/nightscout/androidaps/plugins/SensitivityWeightedAverage/SensitivityWeightedAveragePlugin.java rename to app/src/main/java/info/nightscout/androidaps/plugins/Sensitivity/SensitivityWeightedAveragePlugin.java index 58f59701d9..2aeb26bd1a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/SensitivityWeightedAverage/SensitivityWeightedAveragePlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Sensitivity/SensitivityWeightedAveragePlugin.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.SensitivityWeightedAverage; +package info.nightscout.androidaps.plugins.Sensitivity; import android.support.v4.util.LongSparseArray; @@ -6,28 +6,29 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Date; +import java.util.List; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.Profile; -import info.nightscout.androidaps.interfaces.PluginBase; +import info.nightscout.androidaps.db.CareportalEvent; +import info.nightscout.androidaps.db.ProfileSwitch; import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginType; -import info.nightscout.androidaps.interfaces.SensitivityInterface; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensData; import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensResult; import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin; -import info.nightscout.utils.Round; +import info.nightscout.utils.DateUtil; import info.nightscout.utils.SP; -import info.nightscout.utils.SafeParse; /** * Created by mike on 24.06.2017. */ -public class SensitivityWeightedAveragePlugin extends PluginBase implements SensitivityInterface { - private static Logger log = LoggerFactory.getLogger(SensitivityWeightedAveragePlugin.class); +public class SensitivityWeightedAveragePlugin extends AbstractSensitivityPlugin { + private static Logger log = LoggerFactory.getLogger(L.AUTOSENS); private static SensitivityWeightedAveragePlugin plugin = null; @@ -43,12 +44,13 @@ public class SensitivityWeightedAveragePlugin extends PluginBase implements Sens .pluginName(R.string.sensitivityweightedaverage) .shortName(R.string.sensitivity_shortname) .preferencesId(R.xml.pref_absorption_aaps) + .description(R.string.description_sensitivity_weighted_average) ); } @Override - public AutosensResult detectSensitivity(long fromTime, long toTime) { - LongSparseArray autosensDataTable = IobCobCalculatorPlugin.getPlugin().getAutosensDataTable(); + public AutosensResult detectSensitivity(IobCobCalculatorPlugin iobCobCalculatorPlugin, long fromTime, long toTime) { + LongSparseArray autosensDataTable = iobCobCalculatorPlugin.getAutosensDataTable(); String age = SP.getString(R.string.key_age, ""); int defaultHours = 24; @@ -58,26 +60,29 @@ public class SensitivityWeightedAveragePlugin extends PluginBase implements Sens int hoursForDetection = SP.getInt(R.string.key_openapsama_autosens_period, defaultHours); if (autosensDataTable == null || autosensDataTable.size() < 4) { - if (Config.logAutosensData) - log.debug("No autosens data available"); + if (L.isEnabled(L.AUTOSENS)) + log.debug("No autosens data available. lastDataTime=" + iobCobCalculatorPlugin.lastDataTime()); return new AutosensResult(); } - AutosensData current = IobCobCalculatorPlugin.getPlugin().getAutosensData(toTime); // this is running inside lock already + AutosensData current = iobCobCalculatorPlugin.getAutosensData(toTime); // this is running inside lock already if (current == null) { - if (Config.logAutosensData) - log.debug("No autosens data available"); + if (L.isEnabled(L.AUTOSENS)) + log.debug("No autosens data available. toTime: " + DateUtil.dateAndTimeString(toTime) + " lastDataTime: " + iobCobCalculatorPlugin.lastDataTime()); return new AutosensResult(); } - Profile profile = MainApp.getConfigBuilder().getProfile(); + Profile profile = ProfileFunctions.getInstance().getProfile(); if (profile == null) { - if (Config.logAutosensData) + if (L.isEnabled(L.AUTOSENS)) log.debug("No profile available"); return new AutosensResult(); } + List siteChanges = MainApp.getDbHelper().getCareportalEventsFromTime(fromTime, CareportalEvent.SITECHANGE, true); + List profileSwitches = MainApp.getDbHelper().getProfileSwitchEventsFromTime(fromTime, true); + String pastSensitivity = ""; int index = 0; LongSparseArray data = new LongSparseArray<>(); @@ -100,11 +105,30 @@ public class SensitivityWeightedAveragePlugin extends PluginBase implements Sens continue; } + // reset deviations after site change + if (CareportalEvent.isEvent5minBack(siteChanges, autosensData.time)) { + data.clear(); + pastSensitivity += "(SITECHANGE)"; + } + + // reset deviations after profile switch + if (ProfileSwitch.isEvent5minBack(profileSwitches, autosensData.time, true)) { + data.clear(); + pastSensitivity += "(PROFILESWITCH)"; + } + + double deviation = autosensData.deviation; + + //set positive deviations to zero if bg < 80 + if (autosensData.bg < 80 && deviation > 0) + deviation = 0; + //data.append(autosensData.time); long reverseWeight = (toTime - autosensData.time) / (5 * 60 * 1000L); - data.append(reverseWeight, autosensData.nonEqualDeviation ? autosensData.deviation : 0d); + if (autosensData.validDeviation) + data.append(reverseWeight, deviation); //weights += reverseWeight; - //weightedsum += reverseWeight * (autosensData.nonEqualDeviation ? autosensData.deviation : 0d); + //weightedsum += reverseWeight * (autosensData.validDeviation ? autosensData.deviation : 0d); pastSensitivity += autosensData.pastSensitivity; @@ -116,7 +140,12 @@ public class SensitivityWeightedAveragePlugin extends PluginBase implements Sens } if (data.size() == 0) { + if (L.isEnabled(L.AUTOSENS)) + log.debug("Data size: " + data.size() + " fromTime: " + DateUtil.dateAndTimeString(fromTime) + " toTime: " + DateUtil.dateAndTimeString(toTime)); return new AutosensResult(); + } else { + if (L.isEnabled(L.AUTOSENS)) + log.debug("Data size: " + data.size() + " fromTime: " + DateUtil.dateAndTimeString(fromTime) + " toTime: " + DateUtil.dateAndTimeString(toTime)); } double weightedsum = 0; @@ -140,7 +169,7 @@ public class SensitivityWeightedAveragePlugin extends PluginBase implements Sens String ratioLimit = ""; String sensResult; - if (Config.logAutosensData) + if (L.isEnabled(L.AUTOSENS)) log.debug("Records: " + index + " " + pastSensitivity); double average = weightedsum / weights; @@ -155,28 +184,16 @@ public class SensitivityWeightedAveragePlugin extends PluginBase implements Sens sensResult = "Sensitivity normal"; } - if (Config.logAutosensData) + if (L.isEnabled(L.AUTOSENS)) log.debug(sensResult); - double rawRatio = ratio; - ratio = Math.max(ratio, SafeParse.stringToDouble(SP.getString(R.string.key_openapsama_autosens_min, "0.7"))); - ratio = Math.min(ratio, SafeParse.stringToDouble(SP.getString(R.string.key_openapsama_autosens_max, "1.2"))); + AutosensResult output = fillResult(ratio, current.cob, pastSensitivity, ratioLimit, + sensResult, data.size()); - if (ratio != rawRatio) { - ratioLimit = "Ratio limited from " + rawRatio + " to " + ratio; - if (Config.logAutosensData) - log.debug(ratioLimit); - } + if (L.isEnabled(L.AUTOSENS)) + log.debug("Sensitivity to: {} weightedaverage: {} ratio: {} mealCOB: {}", new Date(toTime).toLocaleString(), + average, output.ratio, current.cob); - if (Config.logAutosensData) - log.debug("Sensitivity to: " + new Date(toTime).toLocaleString() + " weightedaverage: " + average + " ratio: " + ratio + " mealCOB: " + current.cob); - - AutosensResult output = new AutosensResult(); - output.ratio = Round.roundTo(ratio, 0.01); - output.carbsAbsorbed = Round.roundTo(current.cob, 0.01); - output.pastSensitivity = pastSensitivity; - output.ratioLimit = ratioLimit; - output.sensResult = sensResult; return output; } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/SmsCommunicatorFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/SmsCommunicatorFragment.java index d10786f8e5..3f218063ef 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/SmsCommunicatorFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/SmsCommunicatorFragment.java @@ -68,7 +68,7 @@ public class SmsCommunicatorFragment extends SubscriberFragment { public void run() { class CustomComparator implements Comparator { public int compare(SmsCommunicatorPlugin.Sms object1, SmsCommunicatorPlugin.Sms object2) { - return (int) (object1.date.getTime() - object2.date.getTime()); + return (int) (object1.date - object2.date); } } Collections.sort(SmsCommunicatorPlugin.getPlugin().messages, new CustomComparator()); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/SmsCommunicatorPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/SmsCommunicatorPlugin.java index 9de6cc6ad6..b3800cbe82 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/SmsCommunicatorPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/SmsCommunicatorPlugin.java @@ -2,6 +2,8 @@ package info.nightscout.androidaps.plugins.SmsCommunicator; import android.content.Intent; import android.content.pm.ResolveInfo; +import android.os.Bundle; +import android.os.SystemClock; import android.telephony.SmsManager; import android.telephony.SmsMessage; @@ -19,7 +21,8 @@ import java.util.List; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.Services.Intents; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; +import info.nightscout.androidaps.services.Intents; import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.data.GlucoseStatus; import info.nightscout.androidaps.data.IobTotal; @@ -38,15 +41,15 @@ import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.Loop.LoopPlugin; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.Overview.notifications.Notification; -import info.nightscout.androidaps.plugins.SmsCommunicator.events.EventNewSMS; import info.nightscout.androidaps.plugins.SmsCommunicator.events.EventSmsCommunicatorUpdateGui; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.androidaps.queue.Callback; import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.FabricPrivacy; -import info.nightscout.utils.NSUpload; +import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; import info.nightscout.utils.SP; import info.nightscout.utils.SafeParse; +import info.nightscout.utils.T; import info.nightscout.utils.XdripCalibrations; /** @@ -70,7 +73,7 @@ public class SmsCommunicatorPlugin extends PluginBase { class Sms { String phoneNumber; String text; - Date date; + long date; boolean received = false; boolean sent = false; boolean processed = false; @@ -84,18 +87,18 @@ public class SmsCommunicatorPlugin extends PluginBase { Sms(SmsMessage message) { phoneNumber = message.getOriginatingAddress(); text = message.getMessageBody(); - date = new Date(message.getTimestampMillis()); + date = message.getTimestampMillis(); received = true; } - Sms(String phoneNumber, String text, Date date) { + Sms(String phoneNumber, String text, long date) { this.phoneNumber = phoneNumber; this.text = text; this.date = date; sent = true; } - Sms(String phoneNumber, String text, Date date, String confirmCode) { + Sms(String phoneNumber, String text, long date, String confirmCode) { this.phoneNumber = phoneNumber; this.text = text; this.date = date; @@ -124,6 +127,7 @@ public class SmsCommunicatorPlugin extends PluginBase { .pluginName(R.string.smscommunicator) .shortName(R.string.smscommunicator_shortname) .preferencesId(R.xml.pref_smscommunicator) + .description(R.string.description_sms_communicator) ); processSettings(null); } @@ -162,10 +166,11 @@ public class SmsCommunicatorPlugin extends PluginBase { return false; } - @Subscribe - public void onStatusEvent(final EventNewSMS ev) { + public void handleNewData(Intent intent) { + Bundle bundle = intent.getExtras(); + if (bundle == null) return; - Object[] pdus = (Object[]) ev.bundle.get("pdus"); + Object[] pdus = (Object[]) bundle.get("pdus"); if (pdus != null) { // For every SMS message received for (Object pdu : pdus) { @@ -203,7 +208,7 @@ public class SmsCommunicatorPlugin extends PluginBase { BgReading actualBG = DatabaseHelper.actualBg(); BgReading lastBG = DatabaseHelper.lastBg(); - String units = MainApp.getConfigBuilder().getProfileUnits(); + String units = ProfileFunctions.getInstance().getProfileUnits(); if (actualBG != null) { reply = MainApp.gs(R.string.sms_actualbg) + " " + actualBG.valueToUnitsToString(units) + ", "; @@ -225,7 +230,7 @@ public class SmsCommunicatorPlugin extends PluginBase { + MainApp.gs(R.string.sms_bolus) + " " + DecimalFormatter.to2Decimal(bolusIob.iob) + "U " + MainApp.gs(R.string.sms_basal) + " " + DecimalFormatter.to2Decimal(basalIob.basaliob) + "U)"; - sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); + sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); receivedSms.processed = true; FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Bg")); break; @@ -237,13 +242,13 @@ public class SmsCommunicatorPlugin extends PluginBase { LoopPlugin loopPlugin = MainApp.getSpecificPlugin(LoopPlugin.class); if (loopPlugin != null && loopPlugin.isEnabled(PluginType.LOOP)) { loopPlugin.setPluginEnabled(PluginType.LOOP, false); - ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, new Callback() { + ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(true, new Callback() { @Override public void run() { MainApp.bus().post(new EventRefreshOverview("SMS_LOOP_STOP")); String reply = MainApp.gs(R.string.smscommunicator_loophasbeendisabled) + " " + MainApp.gs(result.success ? R.string.smscommunicator_tempbasalcanceled : R.string.smscommunicator_tempbasalcancelfailed); - sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); + sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); } }); } @@ -256,7 +261,7 @@ public class SmsCommunicatorPlugin extends PluginBase { if (loopPlugin != null && !loopPlugin.isEnabled(PluginType.LOOP)) { loopPlugin.setPluginEnabled(PluginType.LOOP, true); reply = MainApp.gs(R.string.smscommunicator_loophasbeenenabled); - sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); + sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); MainApp.bus().post(new EventRefreshOverview("SMS_LOOP_START")); } receivedSms.processed = true; @@ -273,7 +278,7 @@ public class SmsCommunicatorPlugin extends PluginBase { } else { reply = MainApp.gs(R.string.smscommunicator_loopisdisabled); } - sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); + sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); } receivedSms.processed = true; FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Loop_Status")); @@ -283,7 +288,7 @@ public class SmsCommunicatorPlugin extends PluginBase { MainApp.bus().post(new EventRefreshOverview("SMS_LOOP_RESUME")); NSUpload.uploadOpenAPSOffline(0); reply = MainApp.gs(R.string.smscommunicator_loopresumed); - sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply, new Date())); + sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Loop_Resume")); break; case "SUSPEND": @@ -293,18 +298,18 @@ public class SmsCommunicatorPlugin extends PluginBase { duration = Math.min(180, duration); if (duration == 0) { reply = MainApp.gs(R.string.smscommunicator_wrongduration); - sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); + sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); } else if (remoteCommandsAllowed) { passCode = generatePasscode(); reply = String.format(MainApp.gs(R.string.smscommunicator_suspendreplywithcode), duration, passCode); receivedSms.processed = true; resetWaitingMessages(); - sendSMS(suspendWaitingForConfirmation = new Sms(receivedSms.phoneNumber, reply, new Date(), passCode)); + sendSMS(suspendWaitingForConfirmation = new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis(), passCode)); suspendWaitingForConfirmation.duration = duration; FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Loop_Suspend")); } else { reply = MainApp.gs(R.string.smscommunicator_remotecommandnotallowed); - sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); + sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); } break; } @@ -318,7 +323,7 @@ public class SmsCommunicatorPlugin extends PluginBase { MainApp.instance().getApplicationContext().sendBroadcast(restartNSClient); List q = MainApp.instance().getApplicationContext().getPackageManager().queryBroadcastReceivers(restartNSClient, 0); reply = "TERATMENTS REFRESH " + q.size() + " receivers"; - sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); + sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); receivedSms.processed = true; FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Treatments_Refresh")); break; @@ -332,7 +337,7 @@ public class SmsCommunicatorPlugin extends PluginBase { MainApp.instance().getApplicationContext().sendBroadcast(restartNSClient); List q = MainApp.instance().getApplicationContext().getPackageManager().queryBroadcastReceivers(restartNSClient, 0); reply = "NSCLIENT RESTART " + q.size() + " receivers"; - sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); + sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); receivedSms.processed = true; FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Nsclient_Restart")); break; @@ -340,18 +345,18 @@ public class SmsCommunicatorPlugin extends PluginBase { break; case "PUMP": case "DANAR": - ConfigBuilderPlugin.getCommandQueue().readStatus("SMS", new Callback() { + ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("SMS", new Callback() { @Override public void run() { - PumpInterface pump = MainApp.getConfigBuilder().getActivePump(); + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); if (result.success) { if (pump != null) { String reply = pump.shortStatus(true); - sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply, new Date())); + sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); } } else { String reply = MainApp.gs(R.string.readstatusfailed); - sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); + sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); } } }); @@ -366,18 +371,18 @@ public class SmsCommunicatorPlugin extends PluginBase { reply = String.format(MainApp.gs(R.string.smscommunicator_basalstopreplywithcode), passCode); receivedSms.processed = true; resetWaitingMessages(); - sendSMS(cancelTempBasalWaitingForConfirmation = new Sms(receivedSms.phoneNumber, reply, new Date(), passCode)); + sendSMS(cancelTempBasalWaitingForConfirmation = new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis(), passCode)); FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Basal")); } else { reply = MainApp.gs(R.string.smscommunicator_remotebasalnotallowed); - sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); + sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); } } else { tempBasal = SafeParse.stringToDouble(splited[1]); - Profile profile = MainApp.getConfigBuilder().getProfile(); + Profile profile = ProfileFunctions.getInstance().getProfile(); if (profile == null) { reply = MainApp.gs(R.string.noprofile); - sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); + sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); } else { tempBasal = MainApp.getConstraintChecker().applyBasalConstraints(new Constraint<>(tempBasal), profile).value(); if (remoteCommandsAllowed) { @@ -385,12 +390,12 @@ public class SmsCommunicatorPlugin extends PluginBase { reply = String.format(MainApp.gs(R.string.smscommunicator_basalreplywithcode), tempBasal, passCode); receivedSms.processed = true; resetWaitingMessages(); - sendSMS(tempBasalWaitingForConfirmation = new Sms(receivedSms.phoneNumber, reply, new Date(), passCode)); + sendSMS(tempBasalWaitingForConfirmation = new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis(), passCode)); tempBasalWaitingForConfirmation.tempBasal = tempBasal; FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Basal")); } else { reply = MainApp.gs(R.string.smscommunicator_remotebasalnotallowed); - sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); + sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); } } } @@ -399,10 +404,10 @@ public class SmsCommunicatorPlugin extends PluginBase { case "BOLUS": if (System.currentTimeMillis() - lastRemoteBolusTime.getTime() < Constants.remoteBolusMinDistance) { reply = MainApp.gs(R.string.smscommunicator_remotebolusnotallowed); - sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); - } else if (ConfigBuilderPlugin.getActivePump().isSuspended()) { + sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); + } else if (ConfigBuilderPlugin.getPlugin().getActivePump().isSuspended()) { reply = MainApp.gs(R.string.pumpsuspended); - sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); + sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); } else if (splited.length > 1) { amount = SafeParse.stringToDouble(splited[1]); amount = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(amount)).value(); @@ -411,12 +416,12 @@ public class SmsCommunicatorPlugin extends PluginBase { reply = String.format(MainApp.gs(R.string.smscommunicator_bolusreplywithcode), amount, passCode); receivedSms.processed = true; resetWaitingMessages(); - sendSMS(bolusWaitingForConfirmation = new Sms(receivedSms.phoneNumber, reply, new Date(), passCode)); + sendSMS(bolusWaitingForConfirmation = new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis(), passCode)); bolusWaitingForConfirmation.bolusRequested = amount; FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Bolus")); } else { reply = MainApp.gs(R.string.smscommunicator_remotebolusnotallowed); - sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); + sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); } } break; @@ -428,109 +433,112 @@ public class SmsCommunicatorPlugin extends PluginBase { reply = String.format(MainApp.gs(R.string.smscommunicator_calibrationreplywithcode), amount, passCode); receivedSms.processed = true; resetWaitingMessages(); - sendSMS(calibrationWaitingForConfirmation = new Sms(receivedSms.phoneNumber, reply, new Date(), passCode)); + sendSMS(calibrationWaitingForConfirmation = new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis(), passCode)); calibrationWaitingForConfirmation.calibrationRequested = amount; FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Cal")); } else { reply = MainApp.gs(R.string.smscommunicator_remotecalibrationnotallowed); - sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); + sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); } } break; default: // expect passCode here if (bolusWaitingForConfirmation != null && !bolusWaitingForConfirmation.processed && - bolusWaitingForConfirmation.confirmCode.equals(splited[0]) && System.currentTimeMillis() - bolusWaitingForConfirmation.date.getTime() < Constants.SMS_CONFIRM_TIMEOUT) { + bolusWaitingForConfirmation.confirmCode.equals(splited[0]) && System.currentTimeMillis() - bolusWaitingForConfirmation.date < Constants.SMS_CONFIRM_TIMEOUT) { bolusWaitingForConfirmation.processed = true; DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo(); detailedBolusInfo.insulin = bolusWaitingForConfirmation.bolusRequested; detailedBolusInfo.source = Source.USER; - ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() { + ConfigBuilderPlugin.getPlugin().getCommandQueue().bolus(detailedBolusInfo, new Callback() { @Override public void run() { - PumpInterface pump = MainApp.getConfigBuilder().getActivePump(); + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); if (result.success) { + SystemClock.sleep(T.secs(15).msecs()); // wait some time to get history String reply = String.format(MainApp.gs(R.string.smscommunicator_bolusdelivered), result.bolusDelivered); if (pump != null) reply += "\n" + pump.shortStatus(true); lastRemoteBolusTime = new Date(); - sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply, new Date())); + sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); } else { + SystemClock.sleep(T.secs(60).msecs()); // wait some time to get history String reply = MainApp.gs(R.string.smscommunicator_bolusfailed); if (pump != null) reply += "\n" + pump.shortStatus(true); - sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); + sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); } } }); } else if (tempBasalWaitingForConfirmation != null && !tempBasalWaitingForConfirmation.processed && - tempBasalWaitingForConfirmation.confirmCode.equals(splited[0]) && System.currentTimeMillis() - tempBasalWaitingForConfirmation.date.getTime() < Constants.SMS_CONFIRM_TIMEOUT) { + tempBasalWaitingForConfirmation.confirmCode.equals(splited[0]) && System.currentTimeMillis() - tempBasalWaitingForConfirmation.date < Constants.SMS_CONFIRM_TIMEOUT) { tempBasalWaitingForConfirmation.processed = true; - Profile profile = MainApp.getConfigBuilder().getProfile(); + Profile profile = ProfileFunctions.getInstance().getProfile(); if (profile != null) - ConfigBuilderPlugin.getCommandQueue().tempBasalAbsolute(tempBasalWaitingForConfirmation.tempBasal, 30, true, profile, new Callback() { + ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalAbsolute(tempBasalWaitingForConfirmation.tempBasal, 30, true, profile, new Callback() { @Override public void run() { if (result.success) { String reply = String.format(MainApp.gs(R.string.smscommunicator_tempbasalset), result.absolute, result.duration); - reply += "\n" + ConfigBuilderPlugin.getActivePump().shortStatus(true); - sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply, new Date())); + reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); + sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); } else { String reply = MainApp.gs(R.string.smscommunicator_tempbasalfailed); - reply += "\n" + ConfigBuilderPlugin.getActivePump().shortStatus(true); - sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); + reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); + sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); } } }); } else if (cancelTempBasalWaitingForConfirmation != null && !cancelTempBasalWaitingForConfirmation.processed && - cancelTempBasalWaitingForConfirmation.confirmCode.equals(splited[0]) && System.currentTimeMillis() - cancelTempBasalWaitingForConfirmation.date.getTime() < Constants.SMS_CONFIRM_TIMEOUT) { + cancelTempBasalWaitingForConfirmation.confirmCode.equals(splited[0]) && System.currentTimeMillis() - cancelTempBasalWaitingForConfirmation.date < Constants.SMS_CONFIRM_TIMEOUT) { cancelTempBasalWaitingForConfirmation.processed = true; - ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, new Callback() { + ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(true, new Callback() { @Override public void run() { if (result.success) { String reply = MainApp.gs(R.string.smscommunicator_tempbasalcanceled); - reply += "\n" + ConfigBuilderPlugin.getActivePump().shortStatus(true); - sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply, new Date())); + reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); + sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); } else { String reply = MainApp.gs(R.string.smscommunicator_tempbasalcancelfailed); - reply += "\n" + ConfigBuilderPlugin.getActivePump().shortStatus(true); - sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); + reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); + sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); } } }); } else if (calibrationWaitingForConfirmation != null && !calibrationWaitingForConfirmation.processed && - calibrationWaitingForConfirmation.confirmCode.equals(splited[0]) && System.currentTimeMillis() - calibrationWaitingForConfirmation.date.getTime() < Constants.SMS_CONFIRM_TIMEOUT) { + calibrationWaitingForConfirmation.confirmCode.equals(splited[0]) && System.currentTimeMillis() - calibrationWaitingForConfirmation.date < Constants.SMS_CONFIRM_TIMEOUT) { calibrationWaitingForConfirmation.processed = true; boolean result = XdripCalibrations.sendIntent(calibrationWaitingForConfirmation.calibrationRequested); if (result) { reply = MainApp.gs(R.string.smscommunicator_calibrationsent); - sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply, new Date())); + sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); } else { reply = MainApp.gs(R.string.smscommunicator_calibrationfailed); - sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); + sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); } } else if (suspendWaitingForConfirmation != null && !suspendWaitingForConfirmation.processed && - suspendWaitingForConfirmation.confirmCode.equals(splited[0]) && System.currentTimeMillis() - suspendWaitingForConfirmation.date.getTime() < Constants.SMS_CONFIRM_TIMEOUT) { + suspendWaitingForConfirmation.confirmCode.equals(splited[0]) && System.currentTimeMillis() - suspendWaitingForConfirmation.date < Constants.SMS_CONFIRM_TIMEOUT) { suspendWaitingForConfirmation.processed = true; - ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, new Callback() { + final int dur = suspendWaitingForConfirmation.duration; + ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(true, new Callback() { @Override public void run() { if (result.success) { - LoopPlugin.getPlugin().suspendTo(System.currentTimeMillis() + suspendWaitingForConfirmation.duration * 60L * 1000); - NSUpload.uploadOpenAPSOffline(suspendWaitingForConfirmation.duration * 60); + LoopPlugin.getPlugin().suspendTo(System.currentTimeMillis() + dur * 60L * 1000); + NSUpload.uploadOpenAPSOffline(dur * 60); MainApp.bus().post(new EventRefreshOverview("SMS_LOOP_SUSPENDED")); String reply = MainApp.gs(R.string.smscommunicator_loopsuspended) + " " + MainApp.gs(result.success ? R.string.smscommunicator_tempbasalcanceled : R.string.smscommunicator_tempbasalcancelfailed); - sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply, new Date())); + sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); } else { String reply = MainApp.gs(R.string.smscommunicator_tempbasalcancelfailed); - reply += "\n" + ConfigBuilderPlugin.getActivePump().shortStatus(true); - sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); + reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); + sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); } } }); } else { - sendSMS(new Sms(receivedSms.phoneNumber, MainApp.gs(R.string.smscommunicator_unknowncommand), new Date())); + sendSMS(new Sms(receivedSms.phoneNumber, MainApp.gs(R.string.smscommunicator_unknowncommand), System.currentTimeMillis())); } resetWaitingMessages(); break; @@ -542,7 +550,7 @@ public class SmsCommunicatorPlugin extends PluginBase { public void sendNotificationToAllNumbers(String text) { for (int i = 0; i < allowedNumbers.size(); i++) { - Sms sms = new Sms(allowedNumbers.get(i), text, new Date()); + Sms sms = new Sms(allowedNumbers.get(i), text, System.currentTimeMillis()); sendSMS(sms); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/events/EventNewSMS.java b/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/events/EventNewSMS.java deleted file mode 100644 index dfaebb3942..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/events/EventNewSMS.java +++ /dev/null @@ -1,15 +0,0 @@ -package info.nightscout.androidaps.plugins.SmsCommunicator.events; - -import android.os.Bundle; - -import info.nightscout.androidaps.events.Event; - -/** - * Created by mike on 13.07.2016. - */ -public class EventNewSMS extends Event { - public Bundle bundle; - public EventNewSMS(Bundle bundle) { - this.bundle = bundle; - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Source/BGSourceFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Source/BGSourceFragment.java index 3e9a79d459..5c084eac29 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Source/BGSourceFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Source/BGSourceFragment.java @@ -4,6 +4,7 @@ import android.app.Activity; import android.content.DialogInterface; import android.graphics.Paint; import android.os.Bundle; +import android.support.annotation.NonNull; import android.support.v7.app.AlertDialog; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; @@ -14,33 +15,30 @@ import android.widget.TextView; import com.squareup.otto.Subscribe; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.util.List; +import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.db.BgReading; import info.nightscout.androidaps.events.EventNewBG; import info.nightscout.androidaps.plugins.Common.SubscriberFragment; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; import info.nightscout.utils.DateUtil; import info.nightscout.utils.FabricPrivacy; -import info.nightscout.utils.NSUpload; +import info.nightscout.utils.T; /** * Created by mike on 16.10.2017. */ public class BGSourceFragment extends SubscriberFragment { - private static Logger log = LoggerFactory.getLogger(BGSourceFragment.class); - RecyclerView recyclerView; - Profile profile; + String units = Constants.MGDL; - final long MILLS_TO_THE_PAST = 12 * 60 * 60 * 1000L; + final long MILLS_TO_THE_PAST = T.hours(12).msecs(); @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, @@ -57,7 +55,8 @@ public class BGSourceFragment extends SubscriberFragment { RecyclerViewAdapter adapter = new RecyclerViewAdapter(MainApp.getDbHelper().getAllBgreadingsDataFromTime(now - MILLS_TO_THE_PAST, false)); recyclerView.setAdapter(adapter); - profile = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile().getDefaultProfile(); + if (ConfigBuilderPlugin.getPlugin().getActiveProfileInterface() != null && ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getProfile() != null && ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getProfile().getDefaultProfile() != null) + units = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getProfile().getDefaultProfile().getUnits(); return view; } catch (Exception e) { @@ -68,8 +67,7 @@ public class BGSourceFragment extends SubscriberFragment { } @Subscribe - @SuppressWarnings("unused") - public void onStatusEvent(final EventNewBG ev) { + public void onStatusEvent(final EventNewBG unused) { updateGUI(); } @@ -77,12 +75,9 @@ public class BGSourceFragment extends SubscriberFragment { protected void updateGUI() { Activity activity = getActivity(); if (activity != null) - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - long now = System.currentTimeMillis(); - recyclerView.swapAdapter(new BGSourceFragment.RecyclerViewAdapter(MainApp.getDbHelper().getAllBgreadingsDataFromTime(now - MILLS_TO_THE_PAST, false)), true); - } + activity.runOnUiThread(() -> { + long now = System.currentTimeMillis(); + recyclerView.swapAdapter(new RecyclerViewAdapter(MainApp.getDbHelper().getAllBgreadingsDataFromTime(now - MILLS_TO_THE_PAST, false)), true); }); } @@ -101,12 +96,12 @@ public class BGSourceFragment extends SubscriberFragment { } @Override - public void onBindViewHolder(BgReadingsViewHolder holder, int position) { + public void onBindViewHolder(@NonNull BgReadingsViewHolder holder, int position) { BgReading bgReading = bgReadings.get(position); holder.ns.setVisibility(NSUpload.isIdValid(bgReading._id) ? View.VISIBLE : View.GONE); holder.invalid.setVisibility(!bgReading.isValid ? View.VISIBLE : View.GONE); holder.date.setText(DateUtil.dateAndTimeString(bgReading.date)); - holder.value.setText(bgReading.valueToUnitsToString(profile.getUnits())); + holder.value.setText(bgReading.valueToUnitsToString(units)); holder.direction.setText(bgReading.directionToSymbol()); holder.remove.setTag(bgReading); } @@ -144,7 +139,7 @@ public class BGSourceFragment extends SubscriberFragment { case R.id.bgsource_remove: AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); builder.setTitle(MainApp.gs(R.string.confirmation)); - builder.setMessage(MainApp.gs(R.string.removerecord) + "\n" + DateUtil.dateAndTimeString(bgReading.date) + "\n" + bgReading.valueToUnitsToString(profile.getUnits())); + builder.setMessage(MainApp.gs(R.string.removerecord) + "\n" + DateUtil.dateAndTimeString(bgReading.date) + "\n" + bgReading.valueToUnitsToString(units)); builder.setPositiveButton(MainApp.gs(R.string.ok), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { /* final String _id = bgReading._id; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Source/SourceDexcomG5Plugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Source/SourceDexcomG5Plugin.java index d526a12971..460e550b8e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Source/SourceDexcomG5Plugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Source/SourceDexcomG5Plugin.java @@ -1,17 +1,32 @@ package info.nightscout.androidaps.plugins.Source; +import android.content.Intent; +import android.os.Bundle; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.db.BgReading; import info.nightscout.androidaps.interfaces.BgSourceInterface; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginType; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; +import info.nightscout.utils.SP; /** * Created by mike on 28.11.2017. */ public class SourceDexcomG5Plugin extends PluginBase implements BgSourceInterface { + private static Logger log = LoggerFactory.getLogger(L.BGSOURCE); private static SourceDexcomG5Plugin plugin = null; @@ -27,8 +42,8 @@ public class SourceDexcomG5Plugin extends PluginBase implements BgSourceInterfac .fragmentClass(BGSourceFragment.class.getName()) .pluginName(R.string.DexcomG5) .shortName(R.string.dexcomG5_shortname) - .showInList(!Config.NSCLIENT) .preferencesId(R.xml.pref_dexcomg5) + .description(R.string.description_source_dexcom_g5) ); } @@ -36,4 +51,45 @@ public class SourceDexcomG5Plugin extends PluginBase implements BgSourceInterfac public boolean advancedFilteringSupported() { return true; } + + @Override + public void handleNewData(Intent intent) { + // onHandleIntent Bundle{ data => [{"m_time":1511939180,"m_trend":"NotComputable","m_value":335}]; android.support.content.wakelockid => 95; }Bundle + + if (!isEnabled(PluginType.BGSOURCE)) return; + + Bundle bundle = intent.getExtras(); + if (bundle == null) return; + + BgReading bgReading = new BgReading(); + + String data = bundle.getString("data"); + if (L.isEnabled(L.BGSOURCE)) + log.debug("Received Dexcom Data", data); + + if (data == null) return; + + try { + JSONArray jsonArray = new JSONArray(data); + if (L.isEnabled(L.BGSOURCE)) + log.debug("Received Dexcom Data size:" + jsonArray.length()); + for (int i = 0; i < jsonArray.length(); i++) { + JSONObject json = jsonArray.getJSONObject(i); + bgReading.value = json.getInt("m_value"); + bgReading.direction = json.getString("m_trend"); + bgReading.date = json.getLong("m_time") * 1000L; + bgReading.raw = 0; + boolean isNew = MainApp.getDbHelper().createIfNotExists(bgReading, "DexcomG5"); + if (isNew && SP.getBoolean(R.string.key_dexcomg5_nsupload, false)) { + NSUpload.uploadBg(bgReading); + } + if (isNew && SP.getBoolean(R.string.key_dexcomg5_xdripupload, false)) { + NSUpload.sendToXdrip(bgReading); + } + } + + } catch (JSONException e) { + log.error("Exception: ", e); + } + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Source/SourceGlimpPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Source/SourceGlimpPlugin.java index 0846885df7..07fdba51ee 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Source/SourceGlimpPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Source/SourceGlimpPlugin.java @@ -1,15 +1,26 @@ package info.nightscout.androidaps.plugins.Source; +import android.content.Intent; +import android.os.Bundle; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.db.BgReading; import info.nightscout.androidaps.interfaces.BgSourceInterface; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginType; +import info.nightscout.androidaps.logging.BundleLogger; +import info.nightscout.androidaps.logging.L; /** * Created by mike on 05.08.2016. */ public class SourceGlimpPlugin extends PluginBase implements BgSourceInterface { + private static Logger log = LoggerFactory.getLogger(L.BGSOURCE); private static SourceGlimpPlugin plugin = null; @@ -24,6 +35,7 @@ public class SourceGlimpPlugin extends PluginBase implements BgSourceInterface { .mainType(PluginType.BGSOURCE) .fragmentClass(BGSourceFragment.class.getName()) .pluginName(R.string.Glimp) + .description(R.string.description_source_glimp) ); } @@ -31,4 +43,25 @@ public class SourceGlimpPlugin extends PluginBase implements BgSourceInterface { public boolean advancedFilteringSupported() { return false; } + + @Override + public void handleNewData(Intent intent) { + + if (!isEnabled(PluginType.BGSOURCE)) return; + + Bundle bundle = intent.getExtras(); + if (bundle == null) return; + + if (L.isEnabled(L.BGSOURCE)) + log.debug("Received Glimp Data: " + BundleLogger.log(bundle)); + + BgReading bgReading = new BgReading(); + + bgReading.value = bundle.getDouble("mySGV"); + bgReading.direction = bundle.getString("myTrend"); + bgReading.date = bundle.getLong("myTimestamp"); + bgReading.raw = 0; + + MainApp.getDbHelper().createIfNotExists(bgReading, "GLIMP"); + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Source/SourceMM640gPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Source/SourceMM640gPlugin.java index 8df63df1e6..8bc6811ef4 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Source/SourceMM640gPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Source/SourceMM640gPlugin.java @@ -1,15 +1,29 @@ package info.nightscout.androidaps.plugins.Source; +import android.content.Intent; +import android.os.Bundle; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.db.BgReading; import info.nightscout.androidaps.interfaces.BgSourceInterface; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginType; +import info.nightscout.androidaps.logging.L; /** * Created by mike on 05.08.2016. */ public class SourceMM640gPlugin extends PluginBase implements BgSourceInterface { + private static Logger log = LoggerFactory.getLogger(L.BGSOURCE); + private static SourceMM640gPlugin plugin = null; public static SourceMM640gPlugin getPlugin() { @@ -23,6 +37,7 @@ public class SourceMM640gPlugin extends PluginBase implements BgSourceInterface .mainType(PluginType.BGSOURCE) .fragmentClass(BGSourceFragment.class.getName()) .pluginName(R.string.MM640g) + .description(R.string.description_source_mm640g) ); } @@ -30,4 +45,49 @@ public class SourceMM640gPlugin extends PluginBase implements BgSourceInterface public boolean advancedFilteringSupported() { return false; } + + @Override + public void handleNewData(Intent intent) { + + if (!isEnabled(PluginType.BGSOURCE)) return; + + Bundle bundle = intent.getExtras(); + if (bundle == null) return; + + final String collection = bundle.getString("collection"); + if (collection == null) return; + + if (collection.equals("entries")) { + final String data = bundle.getString("data"); + if (L.isEnabled(L.BGSOURCE)) + log.debug("Received MM640g Data: ", data); + + if ((data != null) && (data.length() > 0)) { + try { + final JSONArray json_array = new JSONArray(data); + for (int i = 0; i < json_array.length(); i++) { + final JSONObject json_object = json_array.getJSONObject(i); + final String type = json_object.getString("type"); + switch (type) { + case "sgv": + BgReading bgReading = new BgReading(); + + bgReading.value = json_object.getDouble("sgv"); + bgReading.direction = json_object.getString("direction"); + bgReading.date = json_object.getLong("date"); + bgReading.raw = json_object.getDouble("sgv"); + + MainApp.getDbHelper().createIfNotExists(bgReading, "MM640g"); + break; + default: + if (L.isEnabled(L.BGSOURCE)) + log.debug("Unknown entries type: " + type); + } + } + } catch (JSONException e) { + log.error("Exception: ", e); + } + } + } + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Source/SourceNSClientPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Source/SourceNSClientPlugin.java index 3ba85e97a6..de110edd4e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Source/SourceNSClientPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Source/SourceNSClientPlugin.java @@ -1,16 +1,32 @@ package info.nightscout.androidaps.plugins.Source; +import android.content.Intent; +import android.os.Bundle; + +import org.json.JSONArray; +import org.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.db.BgReading; import info.nightscout.androidaps.interfaces.BgSourceInterface; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginType; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin; +import info.nightscout.androidaps.plugins.NSClientInternal.data.NSSgv; +import info.nightscout.utils.JsonHelper; +import info.nightscout.utils.SP; /** * Created by mike on 05.08.2016. */ public class SourceNSClientPlugin extends PluginBase implements BgSourceInterface { + private static Logger log = LoggerFactory.getLogger(L.BGSOURCE); private static SourceNSClientPlugin plugin = null; @@ -20,18 +36,74 @@ public class SourceNSClientPlugin extends PluginBase implements BgSourceInterfac return plugin; } + private long lastBGTimeStamp = 0; + private boolean isAdvancedFilteringEnabled = false; + private SourceNSClientPlugin() { super(new PluginDescription() .mainType(PluginType.BGSOURCE) .fragmentClass(BGSourceFragment.class.getName()) .pluginName(R.string.nsclientbg) - .showInList(!Config.NSCLIENT) - .alwaysEnabled(Config.NSCLIENT) + .description(R.string.description_source_ns_client) ); } @Override public boolean advancedFilteringSupported() { - return true; + return isAdvancedFilteringEnabled; + } + + @Override + public void handleNewData(Intent intent) { + + if (!isEnabled(PluginType.BGSOURCE) && !SP.getBoolean(R.string.key_ns_autobackfill, true)) + return; + + Bundle bundles = intent.getExtras(); + + try { + if (bundles.containsKey("sgv")) { + String sgvstring = bundles.getString("sgv"); + if (L.isEnabled(L.BGSOURCE)) + log.debug("Received NS Data: " + sgvstring); + + JSONObject sgvJson = new JSONObject(sgvstring); + storeSgv(sgvJson); + } + + if (bundles.containsKey("sgvs")) { + String sgvstring = bundles.getString("sgvs"); + if (L.isEnabled(L.BGSOURCE)) + log.debug("Received NS Data: " + sgvstring); + JSONArray jsonArray = new JSONArray(sgvstring); + for (int i = 0; i < jsonArray.length(); i++) { + JSONObject sgvJson = jsonArray.getJSONObject(i); + storeSgv(sgvJson); + } + } + } catch (Exception e) { + log.error("Unhandled exception", e); + } + + // Objectives 0 + ObjectivesPlugin.getPlugin().bgIsAvailableInNS = true; + ObjectivesPlugin.getPlugin().saveProgress(); + } + + private void storeSgv(JSONObject sgvJson) { + NSSgv nsSgv = new NSSgv(sgvJson); + BgReading bgReading = new BgReading(nsSgv); + MainApp.getDbHelper().createIfNotExists(bgReading, "NS"); + SourceNSClientPlugin.getPlugin().detectSource(JsonHelper.safeGetString(sgvJson, "device", "none"), JsonHelper.safeGetLong(sgvJson, "mills")); + } + + public void detectSource(String source, long timeStamp) { + if (timeStamp > lastBGTimeStamp) { + if (source.contains("G5 Native") || source.contains("G6 Native") || source.contains("AndroidAPS-DexcomG5")) + isAdvancedFilteringEnabled = true; + else + isAdvancedFilteringEnabled = false; + lastBGTimeStamp = timeStamp; + } } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Source/SourcePoctechPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Source/SourcePoctechPlugin.java new file mode 100644 index 0000000000..df390522d3 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Source/SourcePoctechPlugin.java @@ -0,0 +1,95 @@ +package info.nightscout.androidaps.plugins.Source; + +import android.content.Intent; +import android.os.Bundle; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.Constants; +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.db.BgReading; +import info.nightscout.androidaps.interfaces.BgSourceInterface; +import info.nightscout.androidaps.interfaces.PluginBase; +import info.nightscout.androidaps.interfaces.PluginDescription; +import info.nightscout.androidaps.interfaces.PluginType; +import info.nightscout.androidaps.logging.L; +import info.nightscout.utils.JsonHelper; +import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; +import info.nightscout.utils.SP; + +/** + * Created by mike on 05.08.2016. + */ +public class SourcePoctechPlugin extends PluginBase implements BgSourceInterface { + private static Logger log = LoggerFactory.getLogger(L.BGSOURCE); + + private static SourcePoctechPlugin plugin = null; + + public static SourcePoctechPlugin getPlugin() { + if (plugin == null) + plugin = new SourcePoctechPlugin(); + return plugin; + } + + private SourcePoctechPlugin() { + super(new PluginDescription() + .mainType(PluginType.BGSOURCE) + .fragmentClass(BGSourceFragment.class.getName()) + .pluginName(R.string.poctech) + .preferencesId(R.xml.pref_poctech) + .description(R.string.description_source_poctech) + ); + } + + @Override + public boolean advancedFilteringSupported() { + return false; + } + + @Override + public void handleNewData(Intent intent) { + + if (!isEnabled(PluginType.BGSOURCE)) return; + + Bundle bundle = intent.getExtras(); + if (bundle == null) return; + + BgReading bgReading = new BgReading(); + + String data = bundle.getString("data"); + if (L.isEnabled(L.BGSOURCE)) + log.debug("Received Poctech Data", data); + + try { + JSONArray jsonArray = new JSONArray(data); + if (L.isEnabled(L.BGSOURCE)) + log.debug("Received Poctech Data size:" + jsonArray.length()); + for (int i = 0; i < jsonArray.length(); i++) { + JSONObject json = jsonArray.getJSONObject(i); + bgReading.value = json.getDouble("current"); + bgReading.direction = json.getString("direction"); + bgReading.date = json.getLong("date"); + bgReading.raw = json.getDouble("raw"); + if (JsonHelper.safeGetString(json, "units", Constants.MGDL).equals("mmol/L")) + bgReading.value = bgReading.value * Constants.MMOLL_TO_MGDL; + boolean isNew = MainApp.getDbHelper().createIfNotExists(bgReading, "Poctech"); + if (isNew && SP.getBoolean(R.string.key_dexcomg5_nsupload, false)) { + NSUpload.uploadBg(bgReading); + } + if (isNew && SP.getBoolean(R.string.key_dexcomg5_xdripupload, false)) { + NSUpload.sendToXdrip(bgReading); + } + } + + } catch (JSONException e) { + log.error("Exception: ", e); + } + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Source/SourceXdripPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Source/SourceXdripPlugin.java index bd3d96162e..a81bad41f4 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Source/SourceXdripPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Source/SourceXdripPlugin.java @@ -1,18 +1,30 @@ package info.nightscout.androidaps.plugins.Source; +import android.content.Intent; +import android.os.Bundle; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.services.Intents; +import info.nightscout.androidaps.db.BgReading; import info.nightscout.androidaps.interfaces.BgSourceInterface; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginType; +import info.nightscout.androidaps.logging.BundleLogger; /** * Created by mike on 05.08.2016. */ public class SourceXdripPlugin extends PluginBase implements BgSourceInterface { + private static Logger log = LoggerFactory.getLogger(L.BGSOURCE); private static SourceXdripPlugin plugin = null; - + boolean advancedFiltering; public static SourceXdripPlugin getPlugin() { @@ -26,6 +38,7 @@ public class SourceXdripPlugin extends PluginBase implements BgSourceInterface { .mainType(PluginType.BGSOURCE) .fragmentClass(BGSourceFragment.class.getName()) .pluginName(R.string.xdrip) + .description(R.string.description_source_xdrip) ); } @@ -34,7 +47,29 @@ public class SourceXdripPlugin extends PluginBase implements BgSourceInterface { return advancedFiltering; } + @Override + public void handleNewData(Intent intent) { + + if (!isEnabled(PluginType.BGSOURCE)) return; + + Bundle bundle = intent.getExtras(); + if (bundle == null) return; + + if (L.isEnabled(L.BGSOURCE)) + log.debug("Received xDrip data: " + BundleLogger.log(intent.getExtras())); + + BgReading bgReading = new BgReading(); + + bgReading.value = bundle.getDouble(Intents.EXTRA_BG_ESTIMATE); + bgReading.direction = bundle.getString(Intents.EXTRA_BG_SLOPE_NAME); + bgReading.date = bundle.getLong(Intents.EXTRA_TIMESTAMP); + bgReading.raw = bundle.getDouble(Intents.EXTRA_RAW); + String source = bundle.getString(Intents.XDRIP_DATA_SOURCE_DESCRIPTION, "no Source specified"); + SourceXdripPlugin.getPlugin().setSource(source); + MainApp.getDbHelper().createIfNotExists(bgReading, "XDRIP"); + } + public void setSource(String source) { - this.advancedFiltering = source.contains("G5 Native"); + this.advancedFiltering = source.contains("G5 Native")||source.contains("G6 Native"); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/CarbsGenerator.java b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/CarbsGenerator.java index 99168a2776..9eae9b9d07 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/CarbsGenerator.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/CarbsGenerator.java @@ -11,6 +11,7 @@ import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity; import info.nightscout.androidaps.queue.Callback; +import info.nightscout.utils.T; import static info.nightscout.utils.DateUtil.now; @@ -35,8 +36,8 @@ public class CarbsGenerator { carbInfo.context = MainApp.instance(); carbInfo.source = Source.USER; carbInfo.notes = notes; - if (ConfigBuilderPlugin.getActivePump().getPumpDescription().storesCarbInfo && carbInfo.date <= now()) { - ConfigBuilderPlugin.getCommandQueue().bolus(carbInfo, new Callback() { + if (ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().storesCarbInfo && carbInfo.date <= now() && carbInfo.date > now()- T.mins(2).msecs()) { + ConfigBuilderPlugin.getPlugin().getCommandQueue().bolus(carbInfo, new Callback() { @Override public void run() { if (!result.success) { @@ -50,7 +51,9 @@ public class CarbsGenerator { } }); } else { - TreatmentsPlugin.getPlugin().addToHistoryTreatment(carbInfo); + // Don't send to pump if it is in the future or more than 5 minutes in the past + // as pumps might return those as as "now" when reading the history. + TreatmentsPlugin.getPlugin().addToHistoryTreatment(carbInfo, false); } } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/Treatment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/Treatment.java index 4dcced443a..bd3526c043 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/Treatment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/Treatment.java @@ -1,6 +1,7 @@ package info.nightscout.androidaps.plugins.Treatments; import android.graphics.Color; +import android.support.annotation.Nullable; import com.j256.ormlite.field.DatabaseField; import com.j256.ormlite.table.DatabaseTable; @@ -10,6 +11,7 @@ import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Date; import java.util.Objects; import info.nightscout.androidaps.Constants; @@ -29,8 +31,6 @@ import info.nightscout.utils.JsonHelper; @DatabaseTable(tableName = Treatment.TABLE_TREATMENTS) public class Treatment implements DataPointWithLabelInterface { - private static Logger log = LoggerFactory.getLogger(Treatment.class); - public static final String TABLE_TREATMENTS = "Treatments"; @DatabaseField(id = true) @@ -60,6 +60,8 @@ public class Treatment implements DataPointWithLabelInterface { public int insulinInterfaceID = InsulinInterface.OREF_RAPID_ACTING; // currently unused, will be used in the future @DatabaseField public double dia = Constants.defaultDIA; // currently unused, will be used in the future + @DatabaseField + public String boluscalc; public Treatment() { } @@ -80,6 +82,7 @@ public class Treatment implements DataPointWithLabelInterface { double carbs = treatment.carbs; if (json.has("boluscalc")) { JSONObject boluscalc = json.getJSONObject("boluscalc"); + treatment.boluscalc = boluscalc.toString(); if (boluscalc.has("carbs")) { carbs = Math.max(boluscalc.getDouble("carbs"), carbs); } @@ -93,7 +96,7 @@ public class Treatment implements DataPointWithLabelInterface { public String toString() { return "Treatment{" + "date= " + date + - ", date= " + DateUtil.dateAndTimeString(date) + + ", date= " + new Date(date).toLocaleString() + ", isValid= " + isValid + ", isSMB= " + isSMB + ", _id= " + _id + @@ -132,6 +135,33 @@ public class Treatment implements DataPointWithLabelInterface { return true; } + @Nullable + public JSONObject getBoluscalc() { + try { + if (boluscalc != null) + return new JSONObject(boluscalc); + } catch (JSONException ignored) { + } + return null; + } + + /* + * mealBolus, _id and isSMB cannot be known coming from pump. Only compare rest + * TODO: remove debug toasts + */ + public boolean equalsRePumpHistory(Treatment other) { + if (date != other.date) { + return false; + } + if (insulin != other.insulin) { + return false; + } + if (carbs != other.carbs) { + return false; + } + return true; + } + public void copyFrom(Treatment t) { date = t.date; _id = t._id; @@ -142,6 +172,14 @@ public class Treatment implements DataPointWithLabelInterface { isSMB = t.isSMB; } + public void copyBasics(Treatment t) { + date = t.date; + insulin = t.insulin; + carbs = t.carbs; + pumpId = t.pumpId; + source = t.source; + } + // ----------------- DataPointInterface -------------------- @Override public double getX() { @@ -204,7 +242,7 @@ public class Treatment implements DataPointWithLabelInterface { if (!isValid) return new Iob(); - InsulinInterface insulinInterface = ConfigBuilderPlugin.getActiveInsulin(); + InsulinInterface insulinInterface = ConfigBuilderPlugin.getPlugin().getActiveInsulin(); return insulinInterface.iobCalcForTreatment(this, time, dia); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentService.java b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentService.java index 2a5b798018..8c01db13fd 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentService.java @@ -37,6 +37,7 @@ import info.nightscout.androidaps.events.Event; import info.nightscout.androidaps.events.EventNsTreatment; import info.nightscout.androidaps.events.EventReloadTreatmentData; import info.nightscout.androidaps.events.EventTreatmentChange; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventNewHistoryData; import info.nightscout.utils.JsonHelper; @@ -46,7 +47,7 @@ import info.nightscout.utils.JsonHelper; */ public class TreatmentService extends OrmLiteBaseService { - private static Logger log = LoggerFactory.getLogger(TreatmentService.class); + private static Logger log = LoggerFactory.getLogger(L.DATATREATMENTS); private static final ScheduledExecutorService treatmentEventWorker = Executors.newSingleThreadScheduledExecutor(); private static ScheduledFuture scheduledTreatmentEventPost = null; @@ -102,7 +103,8 @@ public class TreatmentService extends OrmLiteBaseService { public void onCreate() { super.onCreate(); try { - log.info("onCreate"); + if (L.isEnabled(L.DATATREATMENTS)) + log.info("onCreate"); TableUtils.createTableIfNotExists(this.getConnectionSource(), Treatment.class); } catch (SQLException e) { log.error("Can't create database", e); @@ -120,14 +122,28 @@ public class TreatmentService extends OrmLiteBaseService { log.error("Can't create database", e); throw new RuntimeException(e); } + } else if (oldVersion == 8 && newVersion == 9) { + log.debug("Upgrading database from v8 to v9"); + try { + getDao().executeRaw("ALTER TABLE `" + Treatment.TABLE_TREATMENTS + "` ADD COLUMN boluscalc STRING;"); + } catch (SQLException e) { + e.printStackTrace(); + } } else { - log.info("onUpgrade"); + if (L.isEnabled(L.DATATREATMENTS)) + log.info("onUpgrade"); // this.resetFood(); } } public void onDowngrade(ConnectionSource connectionSource, int oldVersion, int newVersion) { - // this method is not supported right now + if (oldVersion == 9 && newVersion == 8) { + try { + getDao().executeRaw("ALTER TABLE `" + Treatment.TABLE_TREATMENTS + "` DROP COLUMN boluscalc STRING;"); + } catch (SQLException e) { + e.printStackTrace(); + } + } } public void resetTreatments() { @@ -161,10 +177,14 @@ public class TreatmentService extends OrmLiteBaseService { class PostRunnable implements Runnable { public void run() { - log.debug("Firing EventFoodChange"); + if (L.isEnabled(L.DATATREATMENTS)) + log.debug("Firing EventReloadTreatmentData"); MainApp.bus().post(event); - if (DatabaseHelper.earliestDataChange != null) + if (DatabaseHelper.earliestDataChange != null) { + if (L.isEnabled(L.DATATREATMENTS)) + log.debug("Firing EventNewHistoryData"); MainApp.bus().post(new EventNewHistoryData(DatabaseHelper.earliestDataChange)); + } DatabaseHelper.earliestDataChange = null; callback.setPost(null); } @@ -224,45 +244,74 @@ public class TreatmentService extends OrmLiteBaseService { Treatment treatment = Treatment.createFromJson(json); if (treatment != null) createOrUpdate(treatment); - } catch (JSONException e) { - log.error("Unhandled exception", e); - } - } - - public void createFoodFromJsonIfNotExists(JSONArray array) { - try { - for (int n = 0; n < array.length(); n++) { - JSONObject json = array.getJSONObject(n); - createTreatmentFromJsonIfNotExists(json); - } + else + log.error("Date is null: " + treatment.toString()); } catch (JSONException e) { log.error("Unhandled exception", e); } } // return true if new record is created - public boolean createOrUpdate(Treatment treatment) { + public UpdateReturn createOrUpdate(Treatment treatment) { try { Treatment old; treatment.date = DatabaseHelper.roundDateToSec(treatment.date); if (treatment.source == Source.PUMP) { // check for changed from pump change in NS - QueryBuilder queryBuilder = getDao().queryBuilder(); - Where where = queryBuilder.where(); - where.eq("pumpId", treatment.pumpId); - PreparedQuery preparedQuery = queryBuilder.prepare(); - List trList = getDao().query(preparedQuery); - if (trList.size() > 0) { - // do nothing, pump history record cannot be changed - log.debug("TREATMENT: Pump record already found in database: " + treatment.toString()); - return false; + Treatment existingTreatment = getPumpRecordById(treatment.pumpId); + if (existingTreatment != null) { + boolean equalRePumpHistory = existingTreatment.equalsRePumpHistory(treatment); + boolean sameSource = existingTreatment.source == treatment.source; + if (!equalRePumpHistory) { + // another treatment exists. Update it with the treatment coming from the pump + if (L.isEnabled(L.DATATREATMENTS)) + log.debug("Pump record already found in database: " + existingTreatment.toString() + " wanting to add " + treatment.toString()); + long oldDate = existingTreatment.date; + + //preserve carbs + if (existingTreatment.isValid && existingTreatment.carbs > 0 && treatment.carbs == 0) { + treatment.carbs = existingTreatment.carbs; + } + + getDao().delete(existingTreatment); // need to delete/create because date may change too + existingTreatment.copyBasics(treatment); + getDao().create(existingTreatment); + DatabaseHelper.updateEarliestDataChange(oldDate); + DatabaseHelper.updateEarliestDataChange(existingTreatment.date); + scheduleTreatmentChange(treatment); + return new UpdateReturn(sameSource, false); //updating a pump treatment with another one from the pump is not counted as clash + } + return new UpdateReturn(equalRePumpHistory, false); + } + existingTreatment = getDao().queryForId(treatment.date); + if (existingTreatment != null) { + // another treatment exists with different pumpID. Update it with the treatment coming from the pump + boolean equalRePumpHistory = existingTreatment.equalsRePumpHistory(treatment); + boolean sameSource = existingTreatment.source == treatment.source; + long oldDate = existingTreatment.date; + if (L.isEnabled(L.DATATREATMENTS)) + log.debug("Pump record already found in database: " + existingTreatment.toString() + " wanting to add " + treatment.toString()); + + //preserve carbs + if (existingTreatment.isValid && existingTreatment.carbs > 0 && treatment.carbs == 0) { + treatment.carbs = existingTreatment.carbs; + } + + getDao().delete(existingTreatment); // need to delete/create because date may change too + existingTreatment.copyFrom(treatment); + getDao().create(existingTreatment); + DatabaseHelper.updateEarliestDataChange(oldDate); + DatabaseHelper.updateEarliestDataChange(existingTreatment.date); + scheduleTreatmentChange(treatment); + return new UpdateReturn(equalRePumpHistory || sameSource, false); } getDao().create(treatment); - log.debug("TREATMENT: New record from: " + Source.getString(treatment.source) + " " + treatment.toString()); + if (L.isEnabled(L.DATATREATMENTS)) + log.debug("New record from: " + Source.getString(treatment.source) + " " + treatment.toString()); DatabaseHelper.updateEarliestDataChange(treatment.date); scheduleTreatmentChange(treatment); - return true; + return new UpdateReturn(true, true); } if (treatment.source == Source.NIGHTSCOUT) { old = getDao().queryForId(treatment.date); @@ -273,15 +322,18 @@ public class TreatmentService extends OrmLiteBaseService { getDao().delete(old); // need to delete/create because date may change too old.copyFrom(treatment); getDao().create(old); - log.debug("TREATMENT: Updating record by date from: " + Source.getString(treatment.source) + " " + old.toString()); + if (L.isEnabled(L.DATATREATMENTS)) + log.debug("Updating record by date from: " + Source.getString(treatment.source) + " " + old.toString()); if (historyChange) { DatabaseHelper.updateEarliestDataChange(oldDate); DatabaseHelper.updateEarliestDataChange(old.date); } scheduleTreatmentChange(treatment); - return true; + return new UpdateReturn(true, true); } - return false; + if (L.isEnabled(L.DATATREATMENTS)) + log.debug("Equal record by date from: " + Source.getString(treatment.source) + " " + old.toString()); + return new UpdateReturn(true, false); } // find by NS _id if (treatment._id != null) { @@ -293,33 +345,62 @@ public class TreatmentService extends OrmLiteBaseService { getDao().delete(old); // need to delete/create because date may change too old.copyFrom(treatment); getDao().create(old); - log.debug("TREATMENT: Updating record by _id from: " + Source.getString(treatment.source) + " " + old.toString()); + if (L.isEnabled(L.DATATREATMENTS)) + log.debug("Updating record by _id from: " + Source.getString(treatment.source) + " " + old.toString()); if (historyChange) { DatabaseHelper.updateEarliestDataChange(oldDate); DatabaseHelper.updateEarliestDataChange(old.date); } scheduleTreatmentChange(treatment); - return true; + return new UpdateReturn(true, true); } + if (L.isEnabled(L.DATATREATMENTS)) + log.debug("Equal record by _id from: " + Source.getString(treatment.source) + " " + old.toString()); + return new UpdateReturn(true, false); } } getDao().create(treatment); - log.debug("TREATMENT: New record from: " + Source.getString(treatment.source) + " " + treatment.toString()); + if (L.isEnabled(L.DATATREATMENTS)) + log.debug("New record from: " + Source.getString(treatment.source) + " " + treatment.toString()); DatabaseHelper.updateEarliestDataChange(treatment.date); scheduleTreatmentChange(treatment); - return true; + return new UpdateReturn(true, true); } if (treatment.source == Source.USER) { getDao().create(treatment); - log.debug("TREATMENT: New record from: " + Source.getString(treatment.source) + " " + treatment.toString()); + if (L.isEnabled(L.DATATREATMENTS)) + log.debug("New record from: " + Source.getString(treatment.source) + " " + treatment.toString()); DatabaseHelper.updateEarliestDataChange(treatment.date); scheduleTreatmentChange(treatment); - return true; + return new UpdateReturn(true, true); } } catch (SQLException e) { log.error("Unhandled exception", e); } - return false; + return new UpdateReturn(false, false); + } + + /** + * Returns the record for the given id, null if none, throws RuntimeException + * if multiple records with the same pump id exist. + */ + @Nullable + public Treatment getPumpRecordById(long pumpId) { + try { + QueryBuilder queryBuilder = getDao().queryBuilder(); + Where where = queryBuilder.where(); + where.eq("pumpId", pumpId); + queryBuilder.orderBy("date", true); + + List result = getDao().query(queryBuilder.prepare()); + if (result.isEmpty()) + return null; + if (result.size() > 1) + log.warn("Multiple records with the same pump id found (returning first one): " + result.toString()); + return result.get(0); + } catch (SQLException e) { + throw new RuntimeException(e); + } } public void deleteNS(JSONObject json) { @@ -338,7 +419,8 @@ public class TreatmentService extends OrmLiteBaseService { private void deleteByNSId(String _id) { Treatment stored = findByNSId(_id); if (stored != null) { - log.debug("TREATMENT: Removing Treatment record from database: " + stored.toString()); + if (L.isEnabled(L.DATATREATMENTS)) + log.debug("Removing Treatment record from database: " + stored.toString()); delete(stored); DatabaseHelper.updateEarliestDataChange(stored.date); scheduleTreatmentChange(null); @@ -423,4 +505,15 @@ public class TreatmentService extends OrmLiteBaseService { public IBinder onBind(Intent intent) { return null; } + + public class UpdateReturn { + public UpdateReturn(boolean success, boolean newRecord) { + this.success = success; + this.newRecord = newRecord; + } + + boolean newRecord; + boolean success; + } + } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsFragment.java index ea75dfad6a..32feb9fe7f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsFragment.java @@ -27,8 +27,6 @@ import info.nightscout.androidaps.plugins.Treatments.fragments.TreatmentsTempora import info.nightscout.utils.FabricPrivacy; public class TreatmentsFragment extends SubscriberFragment implements View.OnClickListener { - private static Logger log = LoggerFactory.getLogger(TreatmentsFragment.class); - TextView treatmentsTab; TextView extendedBolusesTab; TextView tempBasalsTab; @@ -123,7 +121,7 @@ public class TreatmentsFragment extends SubscriberFragment implements View.OnCli @Override protected void updateGUI() { - if (ConfigBuilderPlugin.getActivePump().getPumpDescription().isExtendedBolusCapable + if (ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().isExtendedBolusCapable || TreatmentsPlugin.getPlugin().getExtendedBolusesFromHistory().size() > 0) { extendedBolusesTab.setVisibility(View.VISIBLE); } else { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsPlugin.java index 8ae2e6d7b1..aeacddb89c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsPlugin.java @@ -1,7 +1,9 @@ package info.nightscout.androidaps.plugins.Treatments; +import android.content.Intent; import android.support.annotation.Nullable; +import com.crashlytics.android.answers.CustomEvent; import com.squareup.otto.Subscribe; import org.slf4j.Logger; @@ -31,19 +33,24 @@ import info.nightscout.androidaps.events.EventReloadProfileSwitchData; import info.nightscout.androidaps.events.EventReloadTempBasalData; import info.nightscout.androidaps.events.EventReloadTreatmentData; import info.nightscout.androidaps.events.EventTempTargetChange; +import info.nightscout.androidaps.interfaces.InsulinInterface; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.TreatmentsInterface; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensData; import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin; +import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity; import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification; import info.nightscout.androidaps.plugins.Overview.notifications.Notification; -import info.nightscout.androidaps.plugins.SensitivityAAPS.SensitivityAAPSPlugin; -import info.nightscout.androidaps.plugins.SensitivityWeightedAverage.SensitivityWeightedAveragePlugin; +import info.nightscout.androidaps.plugins.Sensitivity.SensitivityAAPSPlugin; +import info.nightscout.androidaps.plugins.Sensitivity.SensitivityWeightedAveragePlugin; import info.nightscout.utils.DateUtil; -import info.nightscout.utils.NSUpload; +import info.nightscout.utils.FabricPrivacy; +import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; import info.nightscout.utils.SP; import info.nightscout.utils.T; @@ -51,7 +58,7 @@ import info.nightscout.utils.T; * Created by mike on 05.08.2016. */ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface { - private static Logger log = LoggerFactory.getLogger(TreatmentsPlugin.class); + private Logger log = LoggerFactory.getLogger(L.DATATREATMENTS); private static TreatmentsPlugin treatmentsPlugin; @@ -78,8 +85,8 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface .fragmentClass(TreatmentsFragment.class.getName()) .pluginName(R.string.treatments) .shortName(R.string.treatments_shortname) - .preferencesId(R.xml.pref_absorption_oref0) .alwaysEnabled(true) + .description(R.string.description_treatments) ); this.service = new TreatmentService(); } @@ -105,9 +112,11 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface } private void initializeTreatmentData() { + if (L.isEnabled(L.DATATREATMENTS)) + log.debug("initializeTreatmentData"); double dia = Constants.defaultDIA; - if (MainApp.getConfigBuilder() != null && MainApp.getConfigBuilder().getProfile() != null) - dia = MainApp.getConfigBuilder().getProfile().getDia(); + if (ConfigBuilderPlugin.getPlugin() != null && ProfileFunctions.getInstance().getProfile() != null) + dia = ProfileFunctions.getInstance().getProfile().getDia(); long fromMills = (long) (System.currentTimeMillis() - 60 * 60 * 1000L * (24 + dia)); synchronized (treatments) { treatments.clear(); @@ -116,9 +125,11 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface } private void initializeTempBasalData() { + if (L.isEnabled(L.DATATREATMENTS)) + log.debug("initializeTempBasalData"); double dia = Constants.defaultDIA; - if (MainApp.getConfigBuilder() != null && MainApp.getConfigBuilder().getProfile() != null) - dia = MainApp.getConfigBuilder().getProfile().getDia(); + if (ConfigBuilderPlugin.getPlugin() != null && ProfileFunctions.getInstance().getProfile() != null) + dia = ProfileFunctions.getInstance().getProfile().getDia(); long fromMills = (long) (System.currentTimeMillis() - 60 * 60 * 1000L * (24 + dia)); synchronized (tempBasals) { @@ -128,9 +139,11 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface } private void initializeExtendedBolusData() { + if (L.isEnabled(L.DATATREATMENTS)) + log.debug("initializeExtendedBolusData"); double dia = Constants.defaultDIA; - if (MainApp.getConfigBuilder() != null && MainApp.getConfigBuilder().getProfile() != null) - dia = MainApp.getConfigBuilder().getProfile().getDia(); + if (ConfigBuilderPlugin.getPlugin() != null && ProfileFunctions.getInstance().getProfile() != null) + dia = ProfileFunctions.getInstance().getProfile().getDia(); long fromMills = (long) (System.currentTimeMillis() - 60 * 60 * 1000L * (24 + dia)); synchronized (extendedBoluses) { @@ -140,6 +153,8 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface } private void initializeTempTargetData() { + if (L.isEnabled(L.DATATREATMENTS)) + log.debug("initializeTempTargetData"); synchronized (tempTargets) { long fromMills = System.currentTimeMillis() - 60 * 60 * 1000L * 24; tempTargets.reset().add(MainApp.getDbHelper().getTemptargetsDataFromTime(fromMills, false)); @@ -147,6 +162,8 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface } private void initializeProfileSwitchData() { + if (L.isEnabled(L.DATATREATMENTS)) + log.debug("initializeProfileSwitchData"); synchronized (profiles) { profiles.reset().add(MainApp.getDbHelper().getProfileSwitchData(false)); } @@ -161,10 +178,14 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface public IobTotal getCalculationToTimeTreatments(long time) { IobTotal total = new IobTotal(time); - Profile profile = MainApp.getConfigBuilder().getProfile(); + Profile profile = ProfileFunctions.getInstance().getProfile(); if (profile == null) return total; + InsulinInterface insulinInterface = ConfigBuilderPlugin.getPlugin().getActiveInsulin(); + if (insulinInterface == null) + return total; + double dia = profile.getDia(); synchronized (treatments) { @@ -188,7 +209,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface } } - if (!ConfigBuilderPlugin.getActivePump().isFakingTempsByExtendedBoluses()) + if (!ConfigBuilderPlugin.getPlugin().getActivePump().isFakingTempsByExtendedBoluses()) synchronized (extendedBoluses) { for (Integer pos = 0; pos < extendedBoluses.size(); pos++) { ExtendedBolus e = extendedBoluses.get(pos); @@ -209,7 +230,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface public MealData getMealData() { MealData result = new MealData(); - Profile profile = MainApp.getConfigBuilder().getProfile(); + Profile profile = ProfileFunctions.getInstance().getProfile(); if (profile == null) return result; long now = System.currentTimeMillis(); @@ -290,6 +311,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface last = t.date; } } + if (L.isEnabled(L.DATATREATMENTS)) log.debug("Last bolus time: " + new Date(last).toLocaleString()); return last; } @@ -318,6 +340,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface @Subscribe public void onStatusEvent(final EventReloadTreatmentData ev) { + if (L.isEnabled(L.DATATREATMENTS)) log.debug("EventReloadTreatmentData"); initializeTreatmentData(); initializeExtendedBolusData(); @@ -328,6 +351,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface @Subscribe @SuppressWarnings("unused") public void onStatusEvent(final EventReloadTempBasalData ev) { + if (L.isEnabled(L.DATATREATMENTS)) log.debug("EventReloadTempBasalData"); initializeTempBasalData(); updateTotalIOBTempBasals(); @@ -345,6 +369,11 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface public IobTotal getCalculationToTimeTempBasals(long time, Profile profile, boolean truncate, long truncateTime) { IobTotal total = new IobTotal(time); + + InsulinInterface insulinInterface = ConfigBuilderPlugin.getPlugin().getActiveInsulin(); + if (insulinInterface == null) + return total; + synchronized (tempBasals) { for (Integer pos = 0; pos < tempBasals.size(); pos++) { TemporaryBasal t = tempBasals.get(pos); @@ -362,7 +391,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface total.plus(calc); } } - if (ConfigBuilderPlugin.getActivePump().isFakingTempsByExtendedBoluses()) { + if (ConfigBuilderPlugin.getPlugin().getActivePump().isFakingTempsByExtendedBoluses()) { IobTotal totalExt = new IobTotal(time); synchronized (extendedBoluses) { for (Integer pos = 0; pos < extendedBoluses.size(); pos++) { @@ -392,7 +421,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface @Override public void updateTotalIOBTempBasals() { - Profile profile = MainApp.getConfigBuilder().getProfile(); + Profile profile = ProfileFunctions.getInstance().getProfile(); if (profile != null) lastTempBasalsCalculation = getCalculationToTimeTempBasals(DateUtil.now(), profile); } @@ -404,7 +433,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface if (tb != null) return tb; ExtendedBolus eb = getExtendedBolusFromHistory(time); - if (eb != null && ConfigBuilderPlugin.getActivePump().isFakingTempsByExtendedBoluses()) + if (eb != null && ConfigBuilderPlugin.getPlugin().getActivePump().isFakingTempsByExtendedBoluses()) return new TemporaryBasal(eb); return null; } @@ -422,11 +451,11 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface boolean newRecordCreated = MainApp.getDbHelper().createOrUpdate(extendedBolus); if (newRecordCreated) { if (extendedBolus.durationInMinutes == 0) { - if (MainApp.getConfigBuilder().getActivePump().isFakingTempsByExtendedBoluses()) + if (ConfigBuilderPlugin.getPlugin().getActivePump().isFakingTempsByExtendedBoluses()) NSUpload.uploadTempBasalEnd(extendedBolus.date, true, extendedBolus.pumpId); else NSUpload.uploadExtendedBolusEnd(extendedBolus.date, extendedBolus.pumpId); - } else if (MainApp.getConfigBuilder().getActivePump().isFakingTempsByExtendedBoluses()) + } else if (ConfigBuilderPlugin.getPlugin().getActivePump().isFakingTempsByExtendedBoluses()) NSUpload.uploadTempBasalStartAbsolute(new TemporaryBasal(extendedBolus), extendedBolus.insulin); else NSUpload.uploadExtendedBolus(extendedBolus); @@ -465,7 +494,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface // return true if new record is created @Override - public boolean addToHistoryTreatment(DetailedBolusInfo detailedBolusInfo) { + public boolean addToHistoryTreatment(DetailedBolusInfo detailedBolusInfo, boolean allowUpdate) { Treatment treatment = new Treatment(); treatment.date = detailedBolusInfo.date; treatment.source = detailedBolusInfo.source; @@ -477,7 +506,9 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface treatment.carbs = detailedBolusInfo.carbs; treatment.source = detailedBolusInfo.source; treatment.mealBolus = treatment.carbs > 0; - boolean newRecordCreated = getService().createOrUpdate(treatment); + treatment.boluscalc = detailedBolusInfo.boluscalc != null ? detailedBolusInfo.boluscalc.toString() : null; + TreatmentService.UpdateReturn creatOrUpdateResult = getService().createOrUpdate(treatment); + boolean newRecordCreated = creatOrUpdateResult.newRecord; //log.debug("Adding new Treatment record" + treatment.toString()); if (detailedBolusInfo.carbTime != 0) { Treatment carbsTreatment = new Treatment(); @@ -491,6 +522,24 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface } if (newRecordCreated && detailedBolusInfo.isValid) NSUpload.uploadTreatmentRecord(detailedBolusInfo); + + if (!allowUpdate && !creatOrUpdateResult.success) { + log.error("Treatment could not be added to DB", new Exception()); + + String status = String.format(MainApp.gs(R.string.error_adding_treatment_message), treatment.insulin, (int) treatment.carbs, DateUtil.dateAndTimeString(treatment.date)); + + Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class); + i.putExtra("soundid", R.raw.error); + i.putExtra("title", MainApp.gs(R.string.error_adding_treatment_title)); + i.putExtra("status", status); + i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + MainApp.instance().startActivity(i); + + CustomEvent customEvent = new CustomEvent("TreatmentClash"); + customEvent.putCustomAttribute("status", status); + FabricPrivacy.getInstance().logCustom(customEvent); + } + return newRecordCreated; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/dialogs/WizardInfoDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/dialogs/WizardInfoDialog.java new file mode 100644 index 0000000000..25ffc946a2 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/dialogs/WizardInfoDialog.java @@ -0,0 +1,88 @@ +package info.nightscout.androidaps.plugins.Treatments.dialogs; + +import android.os.Bundle; +import android.support.v4.app.DialogFragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; +import android.widget.CheckBox; +import android.widget.TextView; + +import org.json.JSONObject; + +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.utils.DecimalFormatter; +import info.nightscout.utils.JsonHelper; + +public class WizardInfoDialog extends DialogFragment implements OnClickListener { + JSONObject json; + + public WizardInfoDialog() { + super(); + } + + public void setData(JSONObject json) { + this.json = json; + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.treatments_wizardinfo_dialog, container, false); + + getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); + + view.findViewById(R.id.ok).setOnClickListener(this); + + // BG + ((TextView) view.findViewById(R.id.treatments_wizard_bg)).setText(DecimalFormatter.to1Decimal(JsonHelper.safeGetDouble(json, "bg")) + " ISF: " + DecimalFormatter.to1Decimal(JsonHelper.safeGetDouble(json, "isf"))); + ((TextView) view.findViewById(R.id.treatments_wizard_bginsulin)).setText(DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "insulinbg")) + "U"); + ((CheckBox) view.findViewById(R.id.treatments_wizard_bgcheckbox)).setChecked(JsonHelper.safeGetBoolean(json, "insulinbgused")); + ((CheckBox) view.findViewById(R.id.treatments_wizard_ttcheckbox)).setChecked(JsonHelper.safeGetBoolean(json, "ttused")); + // Trend + ((TextView) view.findViewById(R.id.treatments_wizard_bgtrend)).setText(JsonHelper.safeGetString(json, "trend")); + ((TextView) view.findViewById(R.id.treatments_wizard_bgtrendinsulin)).setText(DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "insulintrend")) + "U"); + ((CheckBox) view.findViewById(R.id.treatments_wizard_bgtrendcheckbox)).setChecked(JsonHelper.safeGetBoolean(json, "trendused")); + // COB + ((TextView) view.findViewById(R.id.treatments_wizard_cob)).setText(DecimalFormatter.to0Decimal(JsonHelper.safeGetDouble(json, "cob")) + "g IC: " + DecimalFormatter.to1Decimal(JsonHelper.safeGetDouble(json, "ic"))); + ((TextView) view.findViewById(R.id.treatments_wizard_cobinsulin)).setText(DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "insulincob")) + "U"); + ((CheckBox) view.findViewById(R.id.treatments_wizard_cobcheckbox)).setChecked(JsonHelper.safeGetBoolean(json, "cobused")); + // Bolus IOB + ((TextView) view.findViewById(R.id.treatments_wizard_bolusiobinsulin)).setText(DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "bolusiob")) + "U"); + ((CheckBox) view.findViewById(R.id.treatments_wizard_bolusiobcheckbox)).setChecked(JsonHelper.safeGetBoolean(json, "bolusiobused")); + // Basal IOB + ((TextView) view.findViewById(R.id.treatments_wizard_basaliobinsulin)).setText(DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "basaliob")) + "U"); + ((CheckBox) view.findViewById(R.id.treatments_wizard_basaliobcheckbox)).setChecked(JsonHelper.safeGetBoolean(json, "basaliobused")); + // Superbolus + ((TextView) view.findViewById(R.id.treatments_wizard_sbinsulin)).setText(DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "insulinsuperbolus")) + "U"); + ((CheckBox) view.findViewById(R.id.treatments_wizard_sbcheckbox)).setChecked(JsonHelper.safeGetBoolean(json, "superbolusused")); + // Carbs + ((TextView) view.findViewById(R.id.treatments_wizard_carbs)).setText(DecimalFormatter.to0Decimal(JsonHelper.safeGetDouble(json, "carbs")) + "g IC: " + DecimalFormatter.to1Decimal(JsonHelper.safeGetDouble(json, "ic"))); + ((TextView) view.findViewById(R.id.treatments_wizard_carbsinsulin)).setText(DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "insulincarbs")) + "U"); + // Correction + ((TextView) view.findViewById(R.id.treatments_wizard_correctioninsulin)).setText(DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "othercorrection")) + "U"); + // Profile + ((TextView) view.findViewById(R.id.treatments_wizard_profile)).setText(JsonHelper.safeGetString(json, "profile")); + // Notes + ((TextView) view.findViewById(R.id.treatments_wizard_notes)).setText(JsonHelper.safeGetString(json, "notes")); + // Total + ((TextView) view.findViewById(R.id.treatments_wizard_totalinsulin)).setText(DecimalFormatter.to2Decimal(JsonHelper.safeGetDouble(json, "insulin")) + "U"); + + setCancelable(true); + return view; + } + + @Override + public synchronized void onClick(View view) { + switch (view.getId()) { + case R.id.ok: + dismiss(); + break; + } + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/ProfileViewerDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/ProfileViewerDialog.java index 5f758c8a06..c2263d81b5 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/ProfileViewerDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/ProfileViewerDialog.java @@ -31,8 +31,6 @@ public class ProfileViewerDialog extends DialogFragment { private long time; - private static Logger log = LoggerFactory.getLogger(ProfileViewDialog.class); - @BindView(R.id.profileview_noprofile) TextView noProfile; @BindView(R.id.profileview_invalidprofile) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsBolusFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsBolusFragment.java index 57ad6833a9..b99ad97685 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsBolusFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsBolusFragment.java @@ -6,6 +6,7 @@ import android.content.DialogInterface; import android.content.Intent; import android.graphics.Paint; import android.os.Bundle; +import android.support.v4.app.FragmentManager; import android.support.v4.content.ContextCompat; import android.support.v7.app.AlertDialog; import android.support.v7.widget.CardView; @@ -20,38 +21,40 @@ import android.widget.TextView; import com.crashlytics.android.answers.CustomEvent; import com.squareup.otto.Subscribe; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.json.JSONObject; import java.util.List; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.Services.Intents; import info.nightscout.androidaps.data.Iob; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.db.Source; -import info.nightscout.androidaps.plugins.Treatments.Treatment; import info.nightscout.androidaps.events.EventNewBG; import info.nightscout.androidaps.events.EventTreatmentChange; import info.nightscout.androidaps.plugins.Common.SubscriberFragment; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; +import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; import info.nightscout.androidaps.plugins.NSClientInternal.UploadQueue; +import info.nightscout.androidaps.plugins.Treatments.Treatment; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; -import info.nightscout.utils.FabricPrivacy; +import info.nightscout.androidaps.plugins.Treatments.dialogs.WizardInfoDialog; +import info.nightscout.androidaps.services.Intents; import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; -import info.nightscout.utils.NSUpload; +import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.SP; -public class TreatmentsBolusFragment extends SubscriberFragment implements View.OnClickListener { - private static Logger log = LoggerFactory.getLogger(TreatmentsBolusFragment.class); +import static info.nightscout.utils.DateUtil.now; +public class TreatmentsBolusFragment extends SubscriberFragment implements View.OnClickListener { RecyclerView recyclerView; LinearLayoutManager llm; TextView iobTotal; TextView activityTotal; Button refreshFromNS; + Button deleteFutureTreatments; Context context; @@ -71,7 +74,7 @@ public class TreatmentsBolusFragment extends SubscriberFragment implements View. @Override public void onBindViewHolder(TreatmentsViewHolder holder, int position) { - Profile profile = MainApp.getConfigBuilder().getProfile(); + Profile profile = ProfileFunctions.getInstance().getProfile(); if (profile == null) return; Treatment t = treatments.get(position); @@ -80,7 +83,6 @@ public class TreatmentsBolusFragment extends SubscriberFragment implements View. holder.carbs.setText(DecimalFormatter.to0Decimal(t.carbs) + " g"); Iob iob = t.iobCalc(System.currentTimeMillis(), profile.getDia()); holder.iob.setText(DecimalFormatter.to2Decimal(iob.iobContrib) + " U"); - holder.activity.setText(DecimalFormatter.to3Decimal(iob.activityContrib) + " U"); holder.mealOrCorrection.setText(t.isSMB ? "SMB" : t.mealBolus ? MainApp.gs(R.string.mealbolus) : MainApp.gs(R.string.correctionbous)); holder.ph.setVisibility(t.source == Source.PUMP ? View.VISIBLE : View.GONE); holder.ns.setVisibility(NSUpload.isIdValid(t._id) ? View.VISIBLE : View.GONE); @@ -89,11 +91,13 @@ public class TreatmentsBolusFragment extends SubscriberFragment implements View. holder.iob.setTextColor(ContextCompat.getColor(MainApp.instance(), R.color.colorActive)); else holder.iob.setTextColor(holder.carbs.getCurrentTextColor()); - if (t.date > DateUtil.now()) + if (t.date > now()) holder.date.setTextColor(ContextCompat.getColor(MainApp.instance(), R.color.colorScheduled)); else holder.date.setTextColor(holder.carbs.getCurrentTextColor()); holder.remove.setTag(t); + holder.calculation.setTag(t); + holder.calculation.setVisibility(t.getBoluscalc() == null ? View.INVISIBLE : View.VISIBLE); } @Override @@ -112,9 +116,9 @@ public class TreatmentsBolusFragment extends SubscriberFragment implements View. TextView insulin; TextView carbs; TextView iob; - TextView activity; TextView mealOrCorrection; TextView remove; + TextView calculation; TextView ph; TextView ns; TextView invalid; @@ -126,11 +130,13 @@ public class TreatmentsBolusFragment extends SubscriberFragment implements View. insulin = (TextView) itemView.findViewById(R.id.treatments_insulin); carbs = (TextView) itemView.findViewById(R.id.treatments_carbs); iob = (TextView) itemView.findViewById(R.id.treatments_iob); - activity = (TextView) itemView.findViewById(R.id.treatments_activity); mealOrCorrection = (TextView) itemView.findViewById(R.id.treatments_mealorcorrection); ph = (TextView) itemView.findViewById(R.id.pump_sign); ns = (TextView) itemView.findViewById(R.id.ns_sign); invalid = (TextView) itemView.findViewById(R.id.invalid_sign); + calculation = (TextView) itemView.findViewById(R.id.treatments_calculation); + calculation.setOnClickListener(this); + calculation.setPaintFlags(calculation.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG); remove = (TextView) itemView.findViewById(R.id.treatments_remove); remove.setOnClickListener(this); remove.setPaintFlags(remove.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG); @@ -139,6 +145,8 @@ public class TreatmentsBolusFragment extends SubscriberFragment implements View. @Override public void onClick(View v) { final Treatment treatment = (Treatment) v.getTag(); + if (treatment == null) + return; switch (v.getId()) { case R.id.treatments_remove: AlertDialog.Builder builder = new AlertDialog.Builder(context); @@ -165,6 +173,18 @@ public class TreatmentsBolusFragment extends SubscriberFragment implements View. builder.setNegativeButton(MainApp.gs(R.string.cancel), null); builder.show(); break; + case R.id.treatments_calculation: + FragmentManager manager = getFragmentManager(); + // try to fix https://fabric.io/nightscout3/android/apps/info.nightscout.androidaps/issues/5aca7a1536c7b23527eb4be7?time=last-seven-days + // https://stackoverflow.com/questions/14860239/checking-if-state-is-saved-before-committing-a-fragmenttransaction + if (manager.isStateSaved()) + return; + if (treatment.getBoluscalc() != null) { + WizardInfoDialog wizardDialog = new WizardInfoDialog(); + wizardDialog.setData(treatment.getBoluscalc()); + wizardDialog.show(manager, "WizardInfoDialog"); + } + break; } } } @@ -189,6 +209,9 @@ public class TreatmentsBolusFragment extends SubscriberFragment implements View. refreshFromNS = (Button) view.findViewById(R.id.treatments_reshreshfromnightscout); refreshFromNS.setOnClickListener(this); + deleteFutureTreatments = (Button) view.findViewById(R.id.treatments_delete_future_treatments); + deleteFutureTreatments.setOnClickListener(this); + boolean nsUploadOnly = SP.getBoolean(R.string.key_ns_upload_only, false); if (nsUploadOnly) refreshFromNS.setVisibility(View.GONE); @@ -201,17 +224,37 @@ public class TreatmentsBolusFragment extends SubscriberFragment implements View. @Override public void onClick(View view) { + AlertDialog.Builder builder; switch (view.getId()) { case R.id.treatments_reshreshfromnightscout: - AlertDialog.Builder builder = new AlertDialog.Builder(this.getContext()); + builder = new AlertDialog.Builder(this.getContext()); builder.setTitle(MainApp.gs(R.string.confirmation)); builder.setMessage(MainApp.gs(R.string.refresheventsfromnightscout) + "?"); - builder.setPositiveButton(MainApp.gs(R.string.ok), new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - TreatmentsPlugin.getPlugin().getService().resetTreatments(); - Intent restartNSClient = new Intent(Intents.ACTION_RESTART); - MainApp.instance().getApplicationContext().sendBroadcast(restartNSClient); + builder.setPositiveButton(MainApp.gs(R.string.ok), (dialog, id) -> { + TreatmentsPlugin.getPlugin().getService().resetTreatments(); + Intent restartNSClient = new Intent(Intents.ACTION_RESTART); + MainApp.instance().getApplicationContext().sendBroadcast(restartNSClient); + }); + builder.setNegativeButton(MainApp.gs(R.string.cancel), null); + builder.show(); + break; + case R.id.treatments_delete_future_treatments: + builder = new AlertDialog.Builder(this.getContext()); + builder.setTitle(MainApp.gs(R.string.confirmation)); + builder.setMessage(MainApp.gs(R.string.deletefuturetreatments) + "?"); + builder.setPositiveButton(MainApp.gs(R.string.ok), (dialog, id) -> { + final List futureTreatments = TreatmentsPlugin.getPlugin().getService() + .getTreatmentDataFromTime(now() + 1000, true); + for (Treatment treatment : futureTreatments) { + final String _id = treatment._id; + if (NSUpload.isIdValid(_id)) { + NSUpload.removeCareportalEntryFromNS(_id); + } else { + UploadQueue.removeID("dbAdd", _id); + } + TreatmentsPlugin.getPlugin().getService().delete(treatment); } + updateGUI(); }); builder.setNegativeButton(MainApp.gs(R.string.cancel), null); builder.show(); @@ -233,14 +276,16 @@ public class TreatmentsBolusFragment extends SubscriberFragment implements View. protected void updateGUI() { Activity activity = getActivity(); if (activity != null) - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - recyclerView.swapAdapter(new RecyclerViewAdapter(TreatmentsPlugin.getPlugin().getTreatmentsFromHistory()), false); - if (TreatmentsPlugin.getPlugin().getLastCalculationTreatments() != null) { - iobTotal.setText(DecimalFormatter.to2Decimal(TreatmentsPlugin.getPlugin().getLastCalculationTreatments().iob) + " U"); - activityTotal.setText(DecimalFormatter.to3Decimal(TreatmentsPlugin.getPlugin().getLastCalculationTreatments().activity) + " U"); - } + activity.runOnUiThread(() -> { + recyclerView.swapAdapter(new RecyclerViewAdapter(TreatmentsPlugin.getPlugin().getTreatmentsFromHistory()), false); + if (TreatmentsPlugin.getPlugin().getLastCalculationTreatments() != null) { + iobTotal.setText(DecimalFormatter.to2Decimal(TreatmentsPlugin.getPlugin().getLastCalculationTreatments().iob) + " " + MainApp.gs(R.string.insulin_unit_shortname)); + activityTotal.setText(DecimalFormatter.to3Decimal(TreatmentsPlugin.getPlugin().getLastCalculationTreatments().activity) + " " + MainApp.gs(R.string.insulin_unit_shortname)); + } + if (!TreatmentsPlugin.getPlugin().getService().getTreatmentDataFromTime(now() + 1000, true).isEmpty()) { + deleteFutureTreatments.setVisibility(View.VISIBLE); + } else { + deleteFutureTreatments.setVisibility(View.GONE); } }); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsCareportalFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsCareportalFragment.java index 97c3a05274..56709963f7 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsCareportalFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsCareportalFragment.java @@ -22,13 +22,13 @@ import java.util.List; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.Services.Intents; +import info.nightscout.androidaps.services.Intents; import info.nightscout.androidaps.db.CareportalEvent; import info.nightscout.androidaps.events.EventCareportalEventChange; import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.NSClientInternal.UploadQueue; import info.nightscout.utils.DateUtil; -import info.nightscout.utils.NSUpload; +import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; import info.nightscout.utils.SP; import info.nightscout.utils.Translator; @@ -107,16 +107,14 @@ public class TreatmentsCareportalFragment extends SubscriberFragment implements AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setTitle(MainApp.gs(R.string.confirmation)); builder.setMessage(MainApp.gs(R.string.removerecord) + "\n" + DateUtil.dateAndTimeString(careportalEvent.date)); - builder.setPositiveButton(MainApp.gs(R.string.ok), new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - final String _id = careportalEvent._id; - if (NSUpload.isIdValid(_id)) { - NSUpload.removeCareportalEntryFromNS(_id); - } else { - UploadQueue.removeID("dbAdd", _id); - } - MainApp.getDbHelper().delete(careportalEvent); + builder.setPositiveButton(MainApp.gs(R.string.ok), (dialog, id) -> { + final String _id = careportalEvent._id; + if (NSUpload.isIdValid(_id)) { + NSUpload.removeCareportalEntryFromNS(_id); + } else { + UploadQueue.removeID("dbAdd", _id); } + MainApp.getDbHelper().delete(careportalEvent); }); builder.setNegativeButton(MainApp.gs(R.string.cancel), null); builder.show(); @@ -136,12 +134,14 @@ public class TreatmentsCareportalFragment extends SubscriberFragment implements llm = new LinearLayoutManager(view.getContext()); recyclerView.setLayoutManager(llm); - RecyclerViewAdapter adapter = new RecyclerViewAdapter(MainApp.getDbHelper().getCareportalEventsFromTime(false)); + RecyclerViewAdapter adapter = new RecyclerViewAdapter(MainApp.getDbHelper().getCareportalEvents(false)); recyclerView.setAdapter(adapter); refreshFromNS = (Button) view.findViewById(R.id.careportal_refreshfromnightscout); refreshFromNS.setOnClickListener(this); + view.findViewById(R.id.careportal_removeandroidapsstartedevents).setOnClickListener(this); + context = getContext(); boolean nsUploadOnly = SP.getBoolean(R.string.key_ns_upload_only, false); @@ -169,6 +169,16 @@ public class TreatmentsCareportalFragment extends SubscriberFragment implements builder.setNegativeButton(MainApp.gs(R.string.cancel), null); builder.show(); break; + case R.id.careportal_removeandroidapsstartedevents: + builder = new AlertDialog.Builder(context); + builder.setTitle(MainApp.gs(R.string.confirmation)); + builder.setMessage(MainApp.gs(R.string.careportal_removestartedevents)); + builder.setPositiveButton(MainApp.gs(R.string.ok), (dialog, id) -> { + removeAndroidAPSStatedEvents(); + }); + builder.setNegativeButton(MainApp.gs(R.string.cancel), null); + builder.show(); + break; } } @@ -185,8 +195,24 @@ public class TreatmentsCareportalFragment extends SubscriberFragment implements activity.runOnUiThread(new Runnable() { @Override public void run() { - recyclerView.swapAdapter(new RecyclerViewAdapter(MainApp.getDbHelper().getCareportalEventsFromTime(false)), false); + recyclerView.swapAdapter(new RecyclerViewAdapter(MainApp.getDbHelper().getCareportalEvents(false)), false); } }); } + + private void removeAndroidAPSStatedEvents() { + List events = MainApp.getDbHelper().getCareportalEvents(false); + for (int i = 0; i < events.size(); i++) { + CareportalEvent careportalEvent = events.get(i); + if (careportalEvent.json.contains(MainApp.gs(R.string.androidaps_start))) { + final String _id = careportalEvent._id; + if (NSUpload.isIdValid(_id)) { + NSUpload.removeCareportalEntryFromNS(_id); + } else { + UploadQueue.removeID("dbAdd", _id); + } + MainApp.getDbHelper().delete(careportalEvent); + } + } + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsExtendedBolusesFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsExtendedBolusesFragment.java index 05e18bfdc3..037a1a0023 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsExtendedBolusesFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsExtendedBolusesFragment.java @@ -18,9 +18,6 @@ import android.widget.TextView; import com.crashlytics.android.answers.CustomEvent; import com.squareup.otto.Subscribe; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.Intervals; @@ -35,12 +32,10 @@ import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.FabricPrivacy; -import info.nightscout.utils.NSUpload; +import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; public class TreatmentsExtendedBolusesFragment extends SubscriberFragment { - private static Logger log = LoggerFactory.getLogger(TreatmentsExtendedBolusesFragment.class); - RecyclerView recyclerView; LinearLayoutManager llm; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsProfileSwitchFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsProfileSwitchFragment.java index 307f9c8ee6..0edc704eb6 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsProfileSwitchFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsProfileSwitchFragment.java @@ -20,11 +20,16 @@ import android.widget.TextView; import com.squareup.otto.Subscribe; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.util.List; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.Services.Intents; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; +import info.nightscout.androidaps.services.Intents; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.db.ProfileSwitch; import info.nightscout.androidaps.db.Source; @@ -33,7 +38,7 @@ import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.NSClientInternal.UploadQueue; import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; -import info.nightscout.utils.NSUpload; +import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; import info.nightscout.utils.SP; /** @@ -41,6 +46,7 @@ import info.nightscout.utils.SP; */ public class TreatmentsProfileSwitchFragment extends SubscriberFragment implements View.OnClickListener { + private Logger log = LoggerFactory.getLogger(L.UI); RecyclerView recyclerView; LinearLayoutManager llm; @@ -64,7 +70,7 @@ public class TreatmentsProfileSwitchFragment extends SubscriberFragment implemen @Override public void onBindViewHolder(ProfileSwitchViewHolder holder, int position) { - Profile profile = MainApp.getConfigBuilder().getProfile(); + Profile profile = ProfileFunctions.getInstance().getProfile(); if (profile == null) return; ProfileSwitch profileSwitch = profileSwitchList.get(position); holder.ph.setVisibility(profileSwitch.source == Source.PUMP ? View.VISIBLE : View.GONE); @@ -128,6 +134,10 @@ public class TreatmentsProfileSwitchFragment extends SubscriberFragment implemen @Override public void onClick(View v) { final ProfileSwitch profileSwitch = (ProfileSwitch) v.getTag(); + if (profileSwitch == null) { + log.error("profileSwitch == null"); + return; + } switch (v.getId()) { case R.id.profileswitch_remove: AlertDialog.Builder builder = new AlertDialog.Builder(context); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsTempTargetFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsTempTargetFragment.java index df67349839..d60dfc9e4c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsTempTargetFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsTempTargetFragment.java @@ -21,7 +21,8 @@ import com.squareup.otto.Subscribe; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.Services.Intents; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; +import info.nightscout.androidaps.services.Intents; import info.nightscout.androidaps.data.Intervals; import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.TempTarget; @@ -31,7 +32,7 @@ import info.nightscout.androidaps.plugins.NSClientInternal.UploadQueue; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; -import info.nightscout.utils.NSUpload; +import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; import info.nightscout.utils.SP; /** @@ -65,7 +66,7 @@ public class TreatmentsTempTargetFragment extends SubscriberFragment implements @Override public void onBindViewHolder(TempTargetsViewHolder holder, int position) { - String units = MainApp.getConfigBuilder().getProfileUnits(); + String units = ProfileFunctions.getInstance().getProfileUnits(); TempTarget tempTarget = tempTargetList.getReversed(position); holder.ph.setVisibility(tempTarget.source == Source.PUMP ? View.VISIBLE : View.GONE); holder.ns.setVisibility(NSUpload.isIdValid(tempTarget._id) ? View.VISIBLE : View.GONE); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsTemporaryBasalsFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsTemporaryBasalsFragment.java index 957c5c02f1..3185bd81ac 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsTemporaryBasalsFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsTemporaryBasalsFragment.java @@ -28,12 +28,13 @@ import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.events.EventNewBG; import info.nightscout.androidaps.events.EventTempBasalChange; import info.nightscout.androidaps.plugins.Common.SubscriberFragment; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.NSClientInternal.UploadQueue; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.FabricPrivacy; -import info.nightscout.utils.NSUpload; +import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; public class TreatmentsTemporaryBasalsFragment extends SubscriberFragment { @@ -84,7 +85,7 @@ public class TreatmentsTemporaryBasalsFragment extends SubscriberFragment { } holder.duration.setText(DecimalFormatter.to0Decimal(tempBasal.durationInMinutes, " min")); if (tempBasal.isAbsolute) { - Profile profile = MainApp.getConfigBuilder().getProfile(tempBasal.date); + Profile profile = ProfileFunctions.getInstance().getProfile(tempBasal.date); if (profile != null) { holder.absolute.setText(DecimalFormatter.to0Decimal(tempBasal.tempBasalConvertedToAbsolute(tempBasal.date, profile), " U/h")); holder.percent.setText(""); @@ -99,7 +100,7 @@ public class TreatmentsTemporaryBasalsFragment extends SubscriberFragment { holder.realDuration.setText(DecimalFormatter.to0Decimal(tempBasal.getRealDuration(), " min")); long now = DateUtil.now(); IobTotal iob = new IobTotal(now); - Profile profile = MainApp.getConfigBuilder().getProfile(now); + Profile profile = ProfileFunctions.getInstance().getProfile(now); if (profile != null) iob = tempBasal.iobCalc(now, profile); holder.iob.setText(DecimalFormatter.to2Decimal(iob.basaliob, " U")); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Wear/ActionStringHandler.java b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/ActionStringHandler.java index 7cebe4a72d..5245921922 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Wear/ActionStringHandler.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/ActionStringHandler.java @@ -1,5 +1,7 @@ package info.nightscout.androidaps.plugins.Wear; +import android.app.NotificationManager; +import android.content.Context; import android.os.HandlerThread; import android.support.annotation.NonNull; @@ -32,6 +34,7 @@ import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.plugins.Actions.dialogs.FillDialog; import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialog; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.IobCobCalculator.CobInfo; import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin; import info.nightscout.androidaps.plugins.Loop.APSResult; @@ -134,7 +137,7 @@ public class ActionStringHandler { ///////////////////////////////////////////////////////// TEMPTARGET boolean isMGDL = Boolean.parseBoolean(act[1]); - Profile profile = MainApp.getConfigBuilder().getProfile(); + Profile profile = ProfileFunctions.getInstance().getProfile(); if (profile == null) { sendError("No profile found!"); return; @@ -203,7 +206,7 @@ public class ActionStringHandler { boolean useTrend = SP.getBoolean(R.string.key_wearwizard_trend, false); int percentage = Integer.parseInt(act[2]); - Profile profile = MainApp.getConfigBuilder().getProfile(); + Profile profile = ProfileFunctions.getInstance().getProfile(); if (profile == null) { sendError("No profile found!"); return; @@ -292,7 +295,7 @@ public class ActionStringHandler { } } else if ("tddstats".equals(act[0])) { - Object activePump = MainApp.getConfigBuilder().getActivePump(); + Object activePump = ConfigBuilderPlugin.getPlugin().getActivePump(); if (activePump != null) { // check if DB up to date List dummies = new LinkedList(); @@ -304,13 +307,13 @@ public class ActionStringHandler { rMessage = "OLD DATA - "; //if pump is not busy: try to fetch data - final PumpInterface pump = MainApp.getConfigBuilder().getActivePump(); + final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); if (pump.isBusy()) { rMessage += MainApp.gs(R.string.pumpbusy); } else { rMessage += "trying to fetch data from pump."; - ConfigBuilderPlugin.getCommandQueue().loadTDDs(new Callback() { + ConfigBuilderPlugin.getPlugin().getCommandQueue().loadTDDs(new Callback() { @Override public void run() { List dummies = new LinkedList(); @@ -352,6 +355,23 @@ public class ActionStringHandler { } rAction += "ecarbs " + carbsAfterConstraints + " " + starttimestamp + " " + duration; + } else if ("changeRequest".equals(act[0])) { + ////////////////////////////////////////////// CHANGE REQUEST + rTitle = MainApp.gs(R.string.openloop_newsuggestion); + rAction = "changeRequest"; + final LoopPlugin.LastRun finalLastRun = LoopPlugin.lastRun; + rMessage += finalLastRun.constraintsProcessed; + + WearPlugin.getPlugin().requestChangeConfirmation(rTitle, rMessage, rAction); + lastSentTimestamp = System.currentTimeMillis(); + lastConfirmActionString = rAction; + return; + } else if ("cancelChangeRequest".equals(act[0])) { + ////////////////////////////////////////////// CANCEL CHANGE REQUEST NOTIFICATION + rAction = "cancelChangeRequest"; + + WearPlugin.getPlugin().requestNotificationCancel(rAction); + return; } else return; @@ -363,7 +383,7 @@ public class ActionStringHandler { private static String generateTDDMessage(List historyList, List dummies) { - Profile profile = MainApp.getConfigBuilder().getProfile(); + Profile profile = ProfileFunctions.getInstance().getProfile(); if (profile == null) { return "No profile loaded :("; @@ -378,7 +398,7 @@ public class ActionStringHandler { double refTDD = profile.baseBasalSum() * 2; - PumpInterface pump = MainApp.getConfigBuilder().getActivePump(); + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); if (df.format(new Date(historyList.get(0).date)).equals(df.format(new Date()))) { double tdd = historyList.get(0).getTotal(); historyList.remove(0); @@ -427,7 +447,7 @@ public class ActionStringHandler { } public static boolean isOldData(List historyList) { - Object activePump = MainApp.getConfigBuilder().getActivePump(); + Object activePump = ConfigBuilderPlugin.getPlugin().getActivePump(); PumpInterface dana = MainApp.getSpecificPlugin(DanaRPlugin.class); PumpInterface danaRS = MainApp.getSpecificPlugin(DanaRSPlugin.class); PumpInterface danaV2 = MainApp.getSpecificPlugin(DanaRv2Plugin.class); @@ -478,7 +498,7 @@ public class ActionStringHandler { @NonNull private static String getPumpStatus() { - return ConfigBuilderPlugin.getActivePump().shortStatus(false); + return ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(false); } @NonNull @@ -492,7 +512,7 @@ public class ActionStringHandler { } else { ret += "OPEN LOOP\n"; } - final APSInterface aps = ConfigBuilderPlugin.getActiveAPS(); + final APSInterface aps = ConfigBuilderPlugin.getPlugin().getActiveAPS(); ret += "APS: " + ((aps == null) ? "NO APS SELECTED!" : ((PluginBase) aps).getName()); if (LoopPlugin.lastRun != null) { if (LoopPlugin.lastRun.lastAPSRun != null) @@ -517,7 +537,7 @@ public class ActionStringHandler { if (!Config.APS) { return "Targets only apply in APS mode!"; } - Profile profile = MainApp.getConfigBuilder().getProfile(); + Profile profile = ProfileFunctions.getInstance().getProfile(); if (profile == null) { return "No profile set :("; } @@ -541,12 +561,12 @@ public class ActionStringHandler { if (!Config.APS) { return "Only apply in APS mode!"; } - Profile profile = MainApp.getConfigBuilder().getProfile(); + Profile profile = ProfileFunctions.getInstance().getProfile(); if (profile == null) { return "No profile set :("; } - APSInterface usedAPS = ConfigBuilderPlugin.getActiveAPS(); + APSInterface usedAPS = ConfigBuilderPlugin.getPlugin().getActiveAPS(); if (usedAPS == null) { return "No active APS :(!"; } @@ -562,7 +582,7 @@ public class ActionStringHandler { ret += MainApp.gs(R.string.canceltemp) + "\n"; } else { ret += MainApp.gs(R.string.rate) + ": " + DecimalFormatter.to2Decimal(result.rate) + " U/h " + - "(" + DecimalFormatter.to2Decimal(result.rate / ConfigBuilderPlugin.getActivePump().getBaseBasalRate() * 100) + "%)\n" + + "(" + DecimalFormatter.to2Decimal(result.rate / ConfigBuilderPlugin.getPlugin().getActivePump().getBaseBasalRate() * 100) + "%)\n" + MainApp.gs(R.string.duration) + ": " + DecimalFormatter.to0Decimal(result.duration) + " min\n"; } ret += "\n" + MainApp.gs(R.string.reason) + ": " + result.reason; @@ -625,6 +645,11 @@ public class ActionStringHandler { doECarbs(carbs, starttime, duration); } else if ("dismissoverviewnotification".equals(act[0])) { MainApp.bus().post(new EventDismissNotification(SafeParse.stringToInt(act[1]))); + } else if ("changeRequest".equals(act[0])) { + LoopPlugin.getPlugin().acceptChangeRequest(); + NotificationManager notificationManager = + (NotificationManager) MainApp.instance().getSystemService(Context.NOTIFICATION_SERVICE); + notificationManager.cancel(Constants.notificationID); } lastBolusWizard = null; } @@ -651,7 +676,7 @@ public class ActionStringHandler { if (timeshift < 0 || timeshift > 23) { msg += String.format(MainApp.gs(R.string.valueoutofrange), "Profile-Timeshift") + "\n"; } - final Profile profile = MainApp.getConfigBuilder().getProfile(); + final Profile profile = ProfileFunctions.getInstance().getProfile(); if (profile == null) { msg += MainApp.gs(R.string.notloadedplugins) + "\n"; @@ -690,7 +715,7 @@ public class ActionStringHandler { detailedBolusInfo.insulin = amount; detailedBolusInfo.isValid = false; detailedBolusInfo.source = Source.USER; - ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() { + ConfigBuilderPlugin.getPlugin().getCommandQueue().bolus(detailedBolusInfo, new Callback() { @Override public void run() { if (!result.success) { @@ -707,8 +732,8 @@ public class ActionStringHandler { detailedBolusInfo.insulin = amount; detailedBolusInfo.carbs = carbs; detailedBolusInfo.source = Source.USER; - if (detailedBolusInfo.insulin > 0 || ConfigBuilderPlugin.getActivePump().getPumpDescription().storesCarbInfo) { - ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() { + if (detailedBolusInfo.insulin > 0 || ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().storesCarbInfo) { + ConfigBuilderPlugin.getPlugin().getCommandQueue().bolus(detailedBolusInfo, new Callback() { @Override public void run() { if (!result.success) { @@ -719,7 +744,7 @@ public class ActionStringHandler { } }); } else { - TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo); + TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Wear/WearPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/WearPlugin.java index 7282ac0763..72b2397213 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Wear/WearPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/WearPlugin.java @@ -56,6 +56,7 @@ public class WearPlugin extends PluginBase { .pluginName(R.string.wear) .shortName(R.string.wear_shortname) .preferencesId(R.xml.pref_wear) + .description(R.string.description_wear) ); this.ctx = ctx; } @@ -99,6 +100,12 @@ public class WearPlugin extends PluginBase { ctx.startService(new Intent(ctx, WatchUpdaterService.class).setAction(WatchUpdaterService.ACTION_OPEN_SETTINGS)); } + void requestNotificationCancel(String actionstring) { + Intent intent = new Intent(ctx, WatchUpdaterService.class).setAction(WatchUpdaterService.ACTION_CANCEL_NOTIFICATION); + intent.putExtra("actionstring", actionstring); + ctx.startService(intent); + } + @Subscribe public void onStatusEvent(final EventPreferenceChange ev) { @@ -191,6 +198,15 @@ public class WearPlugin extends PluginBase { ctx.startService(intent); } + public void requestChangeConfirmation(String title, String message, String actionstring) { + + Intent intent = new Intent(ctx, WatchUpdaterService.class).setAction(WatchUpdaterService.ACTION_SEND_CHANGECONFIRMATIONREQUEST); + intent.putExtra("title", title); + intent.putExtra("message", message); + intent.putExtra("actionstring", actionstring); + ctx.startService(intent); + } + public static void registerWatchUpdaterService(WatchUpdaterService wus) { watchUS = wus; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Wear/wearintegration/WatchUpdaterService.java b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/wearintegration/WatchUpdaterService.java index 696b8b0b57..8007e03164 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Wear/wearintegration/WatchUpdaterService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/wearintegration/WatchUpdaterService.java @@ -37,6 +37,7 @@ import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.db.BgReading; import info.nightscout.androidaps.db.DatabaseHelper; import info.nightscout.androidaps.db.TemporaryBasal; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.IobCobCalculator.CobInfo; import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin; import info.nightscout.androidaps.plugins.Treatments.Treatment; @@ -63,7 +64,8 @@ public class WatchUpdaterService extends WearableListenerService implements public static final String ACTION_SEND_BASALS = WatchUpdaterService.class.getName().concat(".SendBasals"); public static final String ACTION_SEND_BOLUSPROGRESS = WatchUpdaterService.class.getName().concat(".BolusProgress"); public static final String ACTION_SEND_ACTIONCONFIRMATIONREQUEST = WatchUpdaterService.class.getName().concat(".ActionConfirmationRequest"); - + public static final String ACTION_SEND_CHANGECONFIRMATIONREQUEST = WatchUpdaterService.class.getName().concat(".ChangeConfirmationRequest"); + public static final String ACTION_CANCEL_NOTIFICATION = WatchUpdaterService.class.getName().concat(".CancelNotification"); private GoogleApiClient googleApiClient; public static final String WEARABLE_DATA_PATH = "/nightscout_watch_data"; @@ -78,6 +80,8 @@ public class WatchUpdaterService extends WearableListenerService implements public static final String BASAL_DATA_PATH = "/nightscout_watch_basal"; public static final String BOLUS_PROGRESS_PATH = "/nightscout_watch_bolusprogress"; public static final String ACTION_CONFIRMATION_REQUEST_PATH = "/nightscout_watch_actionconfirmationrequest"; + public static final String ACTION_CHANGECONFIRMATION_REQUEST_PATH = "/nightscout_watch_changeconfirmationrequest"; + public static final String ACTION_CANCELNOTIFICATION_REQUEST_PATH = "/nightscout_watch_cancelnotificationrequest"; boolean wear_integration = false; @@ -153,6 +157,14 @@ public class WatchUpdaterService extends WearableListenerService implements String message = intent.getStringExtra("message"); String actionstring = intent.getStringExtra("actionstring"); sendActionConfirmationRequest(title, message, actionstring); + } else if (ACTION_SEND_CHANGECONFIRMATIONREQUEST.equals(action)) { + String title = intent.getStringExtra("title"); + String message = intent.getStringExtra("message"); + String actionstring = intent.getStringExtra("actionstring"); + sendChangeConfirmationRequest(title, message, actionstring); + } else if (ACTION_CANCEL_NOTIFICATION.equals(action)) { + String actionstring = intent.getStringExtra("actionstring"); + sendCancelNotificationRequest(actionstring); } else { sendData(); } @@ -197,7 +209,7 @@ public class WatchUpdaterService extends WearableListenerService implements } private void cancelBolus() { - ConfigBuilderPlugin.getActivePump().stopBolusDelivering(); + ConfigBuilderPlugin.getPlugin().getActivePump().stopBolusDelivering(); } private void sendData() { @@ -223,7 +235,7 @@ public class WatchUpdaterService extends WearableListenerService implements } private DataMap dataMapSingleBG(BgReading lastBG, GlucoseStatus glucoseStatus) { - String units = MainApp.getConfigBuilder().getProfileUnits(); + String units = ProfileFunctions.getInstance().getProfileUnits(); Double lowLine = SafeParse.stringToDouble(mPrefs.getString("low_mark", "0")); Double highLine = SafeParse.stringToDouble(mPrefs.getString("high_mark", "0")); @@ -363,7 +375,7 @@ public class WatchUpdaterService extends WearableListenerService implements ArrayList predictions = new ArrayList<>(); - Profile profile = MainApp.getConfigBuilder().getProfile(); + Profile profile = ProfileFunctions.getInstance().getProfile(); if (profile == null) { return; @@ -383,7 +395,7 @@ public class WatchUpdaterService extends WearableListenerService implements if (tb1 != null) { tb_before = beginBasalValue; - Profile profileTB = MainApp.getConfigBuilder().getProfile(runningTime); + Profile profileTB = ProfileFunctions.getInstance().getProfile(runningTime); if (profileTB != null) { tb_amount = tb1.tempBasalConvertedToAbsolute(runningTime, profileTB); tb_start = runningTime; @@ -392,7 +404,7 @@ public class WatchUpdaterService extends WearableListenerService implements for (; runningTime < now; runningTime += 5 * 60 * 1000) { - Profile profileTB = MainApp.getConfigBuilder().getProfile(runningTime); + Profile profileTB = ProfileFunctions.getInstance().getProfile(runningTime); //basal rate endBasalValue = profile.getBasal(runningTime); if (endBasalValue != beginBasalValue) { @@ -444,7 +456,7 @@ public class WatchUpdaterService extends WearableListenerService implements temps.add(tempDatamap(tb_start, tb_before, now - 1 * 60 * 1000, endBasalValue, tb_amount)); } else { //express currently running temp by painting it a bit into the future - Profile profileNow = MainApp.getConfigBuilder().getProfile(now); + Profile profileNow = ProfileFunctions.getInstance().getProfile(now); double currentAmount = tb2.tempBasalConvertedToAbsolute(now, profileNow); if (currentAmount != tb_amount) { temps.add(tempDatamap(tb_start, tb_before, now, tb_amount, tb_amount)); @@ -457,7 +469,7 @@ public class WatchUpdaterService extends WearableListenerService implements tb2 = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(now); //use "now" to express current situation if (tb2 != null) { //onset at the end - Profile profileTB = MainApp.getConfigBuilder().getProfile(runningTime); + Profile profileTB = ProfileFunctions.getInstance().getProfile(runningTime); double currentAmount = tb2.tempBasalConvertedToAbsolute(runningTime, profileTB); temps.add(tempDatamap(now - 1 * 60 * 1000, endBasalValue, runningTime + 5 * 60 * 1000, currentAmount, currentAmount)); } @@ -577,10 +589,46 @@ public class WatchUpdaterService extends WearableListenerService implements } } + private void sendChangeConfirmationRequest(String title, String message, String actionstring) { + if (googleApiClient.isConnected()) { + PutDataMapRequest dataMapRequest = PutDataMapRequest.create(ACTION_CHANGECONFIRMATION_REQUEST_PATH); + //unique content + dataMapRequest.getDataMap().putLong("timestamp", System.currentTimeMillis()); + dataMapRequest.getDataMap().putString("changeConfirmationRequest", "changeConfirmationRequest"); + dataMapRequest.getDataMap().putString("title", title); + dataMapRequest.getDataMap().putString("message", message); + dataMapRequest.getDataMap().putString("actionstring", actionstring); + + log.debug("Requesting confirmation from wear: " + actionstring); + + PutDataRequest putDataRequest = dataMapRequest.asPutDataRequest(); + Wearable.DataApi.putDataItem(googleApiClient, putDataRequest); + } else { + Log.e("changeConfirmRequest", "No connection to wearable available!"); + } + } + + private void sendCancelNotificationRequest(String actionstring) { + if (googleApiClient.isConnected()) { + PutDataMapRequest dataMapRequest = PutDataMapRequest.create(ACTION_CANCELNOTIFICATION_REQUEST_PATH); + //unique content + dataMapRequest.getDataMap().putLong("timestamp", System.currentTimeMillis()); + dataMapRequest.getDataMap().putString("cancelNotificationRequest", "cancelNotificationRequest"); + dataMapRequest.getDataMap().putString("actionstring", actionstring); + + log.debug("Canceling notification on wear: " + actionstring); + + PutDataRequest putDataRequest = dataMapRequest.asPutDataRequest(); + Wearable.DataApi.putDataItem(googleApiClient, putDataRequest); + } else { + Log.e("cancelNotificationRequest", "No connection to wearable available!"); + } + } + private void sendStatus() { if (googleApiClient.isConnected()) { - Profile profile = MainApp.getConfigBuilder().getProfile(); + Profile profile = ProfileFunctions.getInstance().getProfile(); String status = MainApp.gs(R.string.noprofile); String iobSum, iobDetail, cobString, currentBasal, bgiString; iobSum = iobDetail = cobString = currentBasal = bgiString = ""; @@ -699,7 +747,7 @@ public class WatchUpdaterService extends WearableListenerService implements String basalStringResult; - Profile profile = MainApp.getConfigBuilder().getProfile(); + Profile profile = ProfileFunctions.getInstance().getProfile(); if (profile == null) return ""; @@ -738,11 +786,14 @@ public class WatchUpdaterService extends WearableListenerService implements public static int getBatteryLevel(Context context) { Intent batteryIntent = context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); - int level = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); - int scale = batteryIntent.getIntExtra(BatteryManager.EXTRA_SCALE, -1); - if (level == -1 || scale == -1) { - return 50; + if (batteryIntent != null) { + int level = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); + int scale = batteryIntent.getIntExtra(BatteryManager.EXTRA_SCALE, -1); + if (level == -1 || scale == -1) { + return 50; + } + return (int) (((float) level / (float) scale) * 100.0f); } - return (int) (((float) level / (float) scale) * 100.0f); + return 50; } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/XDripStatusline/StatuslinePlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/XDripStatusline/StatuslinePlugin.java index 03c6c48a1a..9c4ec1551a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/XDripStatusline/StatuslinePlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/XDripStatusline/StatuslinePlugin.java @@ -9,11 +9,14 @@ import android.support.annotation.NonNull; import com.squareup.otto.Subscribe; +import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.db.TemporaryBasal; +import info.nightscout.androidaps.events.EventAppInitialized; +import info.nightscout.androidaps.events.EventConfigBuilderChange; import info.nightscout.androidaps.events.EventExtendedBolusChange; import info.nightscout.androidaps.events.EventNewBG; import info.nightscout.androidaps.events.EventPreferenceChange; @@ -25,6 +28,7 @@ import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.TreatmentsInterface; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.IobCobCalculator.CobInfo; import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin; import info.nightscout.androidaps.plugins.Loop.LoopPlugin; @@ -70,6 +74,7 @@ public class StatuslinePlugin extends PluginBase { .shortName(R.string.xdripstatus_shortname) .neverVisible(true) .preferencesId(R.xml.pref_xdripstatus) + .description(R.string.description_xdrip_status_line) ); this.ctx = ctx; this.mPrefs = PreferenceManager.getDefaultSharedPreferences(ctx); @@ -78,7 +83,6 @@ public class StatuslinePlugin extends PluginBase { @Override protected void onStart() { MainApp.bus().register(this); - sendStatus(); super.onStart(); } @@ -92,7 +96,7 @@ public class StatuslinePlugin extends PluginBase { private void sendStatus() { String status = ""; // sent once on disable - Profile profile = MainApp.getConfigBuilder().getProfile(); + Profile profile = ProfileFunctions.getInstance().getProfile(); if (isEnabled(PluginType.GENERAL) && profile != null) { status = buildStatusString(profile); @@ -110,6 +114,10 @@ public class StatuslinePlugin extends PluginBase { @NonNull private String buildStatusString(Profile profile) { String status = ""; + + if (ConfigBuilderPlugin.getPlugin().getActivePump() == null) + return ""; + LoopPlugin loopPlugin = LoopPlugin.getPlugin(); if (!loopPlugin.isEnabled(PluginType.LOOP)) { @@ -180,6 +188,16 @@ public class StatuslinePlugin extends PluginBase { sendStatus(); } + @Subscribe + public void onStatusEvent(final EventAppInitialized ev) { + sendStatus(); + } + + @Subscribe + public void onStatusEvent(final EventConfigBuilderChange ev) { + sendStatus(); + } + @Subscribe public void onStatusEvent(final EventRefreshOverview ev) { //Filter events where loop is (de)activated diff --git a/app/src/main/java/info/nightscout/androidaps/queue/CommandQueue.java b/app/src/main/java/info/nightscout/androidaps/queue/CommandQueue.java index cc28eb28a0..69979508fe 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/CommandQueue.java +++ b/app/src/main/java/info/nightscout/androidaps/queue/CommandQueue.java @@ -20,12 +20,16 @@ import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.events.EventBolusRequested; import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.Overview.Dialogs.BolusProgressDialog; import info.nightscout.androidaps.plugins.Overview.Dialogs.BolusProgressHelperActivity; +import info.nightscout.androidaps.plugins.Overview.events.EventDismissBolusprogressIfRunning; import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.Overview.notifications.Notification; +import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.androidaps.queue.commands.Command; import info.nightscout.androidaps.queue.commands.CommandBolus; import info.nightscout.androidaps.queue.commands.CommandCancelExtendedBolus; @@ -37,6 +41,7 @@ import info.nightscout.androidaps.queue.commands.CommandLoadTDDs; import info.nightscout.androidaps.queue.commands.CommandReadStatus; import info.nightscout.androidaps.queue.commands.CommandSMBBolus; import info.nightscout.androidaps.queue.commands.CommandSetProfile; +import info.nightscout.androidaps.queue.commands.CommandSetUserSettings; import info.nightscout.androidaps.queue.commands.CommandTempBasalAbsolute; import info.nightscout.androidaps.queue.commands.CommandTempBasalPercent; @@ -73,10 +78,10 @@ import info.nightscout.androidaps.queue.commands.CommandTempBasalPercent; */ public class CommandQueue { - private static Logger log = LoggerFactory.getLogger(CommandQueue.class); + private Logger log = LoggerFactory.getLogger(L.PUMPQUEUE); private final LinkedList queue = new LinkedList<>(); - protected Command performing; + Command performing; private QueueThread thread = null; @@ -91,7 +96,7 @@ public class CommandQueue { } private synchronized void removeAll(Command.CommandType type) { - for (int i = 0; i < queue.size(); i++) { + for (int i = queue.size() - 1; i >= 0; i--) { if (queue.get(i).commandType == type) { queue.remove(i); } @@ -107,12 +112,14 @@ public class CommandQueue { private synchronized void inject(Command command) { // inject as a first command - log.debug("QUEUE: Adding as first: " + command.getClass().getSimpleName() + " - " + command.status()); + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("Adding as first: " + command.getClass().getSimpleName() + " - " + command.status()); queue.addFirst(command); } private synchronized void add(Command command) { - log.debug("QUEUE: Adding: " + command.getClass().getSimpleName() + " - " + command.status()); + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("Adding: " + command.getClass().getSimpleName() + " - " + command.status()); queue.add(command); } @@ -145,25 +152,30 @@ public class CommandQueue { // start thread again if not already running protected synchronized void notifyAboutNewCommand() { while (thread != null && thread.getState() != Thread.State.TERMINATED && thread.waitingForDisconnect) { - log.debug("QUEUE: Waiting for previous thread finish"); + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("Waiting for previous thread finish"); SystemClock.sleep(500); } if (thread == null || thread.getState() == Thread.State.TERMINATED) { thread = new QueueThread(this); thread.start(); - log.debug("QUEUE: Starting new thread"); + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("Starting new thread"); } else { - log.debug("QUEUE: Thread is already running"); + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("Thread is already running"); } } - public static void independentConnect(String reason, Callback callback) { + public void independentConnect(String reason, Callback callback) { + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("Starting new queue"); CommandQueue tempCommandQueue = new CommandQueue(); tempCommandQueue.readStatus(reason, callback); } - public synchronized boolean bolusInQueue(){ - if(isRunning(Command.CommandType.BOLUS)) return true; + public synchronized boolean bolusInQueue() { + if (isRunning(Command.CommandType.BOLUS)) return true; for (int i = 0; i < queue.size(); i++) { if (queue.get(i).commandType == Command.CommandType.BOLUS) { return true; @@ -176,7 +188,21 @@ public class CommandQueue { public synchronized boolean bolus(DetailedBolusInfo detailedBolusInfo, Callback callback) { Command.CommandType type = detailedBolusInfo.isSMB ? Command.CommandType.SMB_BOLUS : Command.CommandType.BOLUS; - if(type.equals(Command.CommandType.BOLUS) && detailedBolusInfo.carbs > 0 && detailedBolusInfo.insulin == 0){ + if (type == Command.CommandType.SMB_BOLUS) { + if (isRunning(Command.CommandType.BOLUS) || bolusInQueue()) { + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("Rejecting SMB since a bolus is queue/running"); + return false; + } + if (detailedBolusInfo.lastKnownBolusTime < TreatmentsPlugin.getPlugin().getLastBolusTime()) { + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("Rejecting bolus, another bolus was issued since request time"); + return false; + } + } + + + if (type.equals(Command.CommandType.BOLUS) && detailedBolusInfo.carbs > 0 && detailedBolusInfo.insulin == 0) { type = Command.CommandType.CARBS_ONLY_TREATMENT; //Carbs only can be added in parallel as they can be "in the future". } else { @@ -199,7 +225,7 @@ public class CommandQueue { add(new CommandSMBBolus(detailedBolusInfo, callback)); } else { add(new CommandBolus(detailedBolusInfo, callback, type)); - if(type.equals(Command.CommandType.BOLUS)) { + if (type.equals(Command.CommandType.BOLUS)) { // Bring up bolus progress dialog (start here, so the dialog is shown when the bolus is requested, // not when the Bolus command is starting. The command closes the dialog upon completion). showBolusProgressDialog(detailedBolusInfo.insulin, detailedBolusInfo.context); @@ -214,9 +240,12 @@ public class CommandQueue { } public synchronized void cancelAllBoluses() { + if (!isRunning(Command.CommandType.BOLUS)) { + MainApp.bus().post(new EventDismissBolusprogressIfRunning(new PumpEnactResult().success(true).enacted(false))); + } removeAll(Command.CommandType.BOLUS); removeAll(Command.CommandType.SMB_BOLUS); - ConfigBuilderPlugin.getActivePump().stopBolusDelivering(); + ConfigBuilderPlugin.getPlugin().getActivePump().stopBolusDelivering(); } // returns true if command is queued @@ -269,7 +298,7 @@ public class CommandQueue { return false; } - Double rateAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(insulin)).value(); + Double rateAfterConstraints = MainApp.getConstraintChecker().applyExtendedBolusConstraints(new Constraint<>(insulin)).value(); // remove all unfinished removeAll(Command.CommandType.EXTENDEDBOLUS); @@ -323,7 +352,8 @@ public class CommandQueue { // returns true if command is queued public boolean setProfile(Profile profile, Callback callback) { if (isThisProfileSet(profile)) { - log.debug("QUEUE: Correct profile already set"); + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("Correct profile already set"); if (callback != null) callback.result(new PumpEnactResult().success(true).enacted(false)).run(); return false; @@ -339,7 +369,7 @@ public class CommandQueue { // Compare with pump limits Profile.BasalValue[] basalValues = profile.getBasalValues(); - PumpInterface pump = ConfigBuilderPlugin.getActivePump(); + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); for (Profile.BasalValue basalValue : basalValues) { if (basalValue.value < pump.getPumpDescription().basalMinimumRate) { @@ -367,7 +397,8 @@ public class CommandQueue { // returns true if command is queued public boolean readStatus(String reason, Callback callback) { if (isLastScheduled(Command.CommandType.READSTATUS)) { - log.debug("QUEUE: READSTATUS " + reason + " ignored as duplicated"); + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("READSTATUS " + reason + " ignored as duplicated"); if (callback != null) callback.result(executingNowError()).run(); return false; @@ -403,6 +434,25 @@ public class CommandQueue { return true; } + // returns true if command is queued + public boolean setUserOptions(Callback callback) { + if (isRunning(Command.CommandType.SETUSERSETTINGS)) { + if (callback != null) + callback.result(executingNowError()).run(); + return false; + } + + // remove all unfinished + removeAll(Command.CommandType.SETUSERSETTINGS); + + // add new command to queue + add(new CommandSetUserSettings(callback)); + + notifyAboutNewCommand(); + + return true; + } + // returns true if command is queued public boolean loadTDDs(Callback callback) { if (isRunning(Command.CommandType.LOADHISTORY)) { @@ -458,13 +508,15 @@ public class CommandQueue { } public boolean isThisProfileSet(Profile profile) { - PumpInterface activePump = ConfigBuilderPlugin.getActivePump(); - Profile current = MainApp.getConfigBuilder().getProfile(); + PumpInterface activePump = ConfigBuilderPlugin.getPlugin().getActivePump(); + Profile current = ProfileFunctions.getInstance().getProfile(); if (activePump != null && current != null) { boolean result = activePump.isThisProfileSet(profile); if (!result) { - log.debug("Current profile: " + current.getData().toString()); - log.debug("New profile: " + profile.getData().toString()); + if (L.isEnabled(L.PUMPQUEUE)) { + log.debug("Current profile: " + current.toString()); + log.debug("New profile: " + profile.toString()); + } } return result; } else return true; diff --git a/app/src/main/java/info/nightscout/androidaps/queue/QueueThread.java b/app/src/main/java/info/nightscout/androidaps/queue/QueueThread.java index a5ad59ca0b..7c95498db4 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/QueueThread.java +++ b/app/src/main/java/info/nightscout/androidaps/queue/QueueThread.java @@ -2,6 +2,7 @@ package info.nightscout.androidaps.queue; import android.bluetooth.BluetoothAdapter; import android.content.Context; +import android.content.ContextWrapper; import android.os.PowerManager; import android.os.SystemClock; @@ -11,13 +12,11 @@ import org.slf4j.LoggerFactory; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.events.EventPumpStatusChanged; import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.Overview.events.EventDismissBolusprogressIfRunning; -import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; -import info.nightscout.androidaps.plugins.Overview.notifications.Notification; import info.nightscout.androidaps.queue.events.EventQueueChanged; import info.nightscout.utils.SP; @@ -26,7 +25,7 @@ import info.nightscout.utils.SP; */ public class QueueThread extends Thread { - private static Logger log = LoggerFactory.getLogger(QueueThread.class); + private Logger log = LoggerFactory.getLogger(L.PUMPQUEUE); private CommandQueue queue; @@ -36,12 +35,15 @@ public class QueueThread extends Thread { private PowerManager.WakeLock mWakeLock; - public QueueThread(CommandQueue queue) { + QueueThread(CommandQueue queue) { super(); this.queue = queue; - PowerManager powerManager = (PowerManager) MainApp.instance().getApplicationContext().getSystemService(Context.POWER_SERVICE); - mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "QueueThread"); + Context context = MainApp.instance().getApplicationContext(); + if (context != null) { + PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); + mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "QueueThread"); + } } @Override @@ -52,9 +54,10 @@ public class QueueThread extends Thread { try { while (true) { - PumpInterface pump = ConfigBuilderPlugin.getActivePump(); + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); if (pump == null) { - log.debug("QUEUE: pump == null"); + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("pump == null"); MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.pumpNotInitialized))); SystemClock.sleep(1000); continue; @@ -64,15 +67,17 @@ public class QueueThread extends Thread { if (!pump.isConnected() && secondsElapsed > Constants.PUMP_MAX_CONNECTION_TIME_IN_SECONDS) { MainApp.bus().post(new EventDismissBolusprogressIfRunning(null)); MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.connectiontimedout))); - log.debug("QUEUE: timed out"); + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("timed out"); pump.stopConnecting(); //BLUETOOTH-WATCHDOG boolean watchdog = SP.getBoolean(R.string.key_btwatchdog, false); long last_watchdog = SP.getLong(R.string.key_btwatchdog_lastbark, 0l); watchdog = watchdog && System.currentTimeMillis() - last_watchdog > (Constants.MIN_WATCHDOG_INTERVAL_IN_SECONDS * 1000); - if(watchdog) { - log.debug("BT watchdog - toggeling the phonest bluetooth"); + if (watchdog) { + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("BT watchdog - toggeling the phonest bluetooth"); //write time SP.putLong(R.string.key_btwatchdog_lastbark, System.currentTimeMillis()); //toggle BT @@ -91,7 +96,8 @@ public class QueueThread extends Thread { pump.connect("watchdog"); } else { queue.clear(); - log.debug("QUEUE: no connection possible"); + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("no connection possible"); MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.DISCONNECTING)); pump.disconnect("Queue empty"); MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.DISCONNECTED)); @@ -99,16 +105,25 @@ public class QueueThread extends Thread { } } + if (pump.isHandshakeInProgress()) { + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("handshaking " + secondsElapsed); + MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.HANDSHAKING, (int) secondsElapsed)); + SystemClock.sleep(100); + continue; + } + if (pump.isConnecting()) { - log.debug("QUEUE: connecting " + secondsElapsed); + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("connecting " + secondsElapsed); MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.CONNECTING, (int) secondsElapsed)); SystemClock.sleep(1000); continue; } - if (!pump.isConnected()) { - log.debug("QUEUE: connect"); + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("connect"); MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.CONNECTING, (int) secondsElapsed)); pump.connect("Connection needed"); SystemClock.sleep(1000); @@ -118,12 +133,14 @@ public class QueueThread extends Thread { if (queue.performing() == null) { if (!connectLogged) { connectLogged = true; - log.debug("QUEUE: connection time " + secondsElapsed + "s"); + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("connection time " + secondsElapsed + "s"); } // Pickup 1st command and set performing variable if (queue.size() > 0) { queue.pickup(); - log.debug("QUEUE: performing " + queue.performing().status()); + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("performing " + queue.performing().status()); MainApp.bus().post(new EventQueueChanged()); queue.performing().execute(); queue.resetPerforming(); @@ -138,22 +155,25 @@ public class QueueThread extends Thread { long secondsFromLastCommand = (System.currentTimeMillis() - lastCommandTime) / 1000; if (secondsFromLastCommand >= 5) { waitingForDisconnect = true; - log.debug("QUEUE: queue empty. disconnect"); + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("queue empty. disconnect"); MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.DISCONNECTING)); pump.disconnect("Queue empty"); MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.DISCONNECTED)); - log.debug("QUEUE: disconnected"); + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("disconnected"); return; } else { - log.debug("QUEUE: waiting for disconnect"); + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("waiting for disconnect"); SystemClock.sleep(1000); } } } } finally { mWakeLock.release(); + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("thread end"); } } - - } diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/Command.java b/app/src/main/java/info/nightscout/androidaps/queue/commands/Command.java index b865fac86e..7207f5b8d1 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/commands/Command.java +++ b/app/src/main/java/info/nightscout/androidaps/queue/commands/Command.java @@ -1,14 +1,20 @@ package info.nightscout.androidaps.queue.commands; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.PumpEnactResult; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.queue.Callback; /** * Created by mike on 09.11.2017. */ public abstract class Command { + private Logger log = LoggerFactory.getLogger(L.PUMPQUEUE); + public enum CommandType { BOLUS, SMB_BOLUS, @@ -18,7 +24,8 @@ public abstract class Command { BASALPROFILE, READSTATUS, LOADHISTORY, // TDDs and so far only Dana specific - LOADEVENTS // so far only Dana specific + LOADEVENTS, // so far only Dana specific + SETUSERSETTINGS // so far only Dana specific } public CommandType commandType; @@ -32,6 +39,8 @@ public abstract class Command { PumpEnactResult result = new PumpEnactResult(); result.success = false; result.comment = MainApp.gs(R.string.connectiontimedout); + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("Result cancel"); if (callback != null) callback.result(result).run(); } diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandBolus.java b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandBolus.java index 2be3831ace..c239502187 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandBolus.java +++ b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandBolus.java @@ -1,8 +1,12 @@ package info.nightscout.androidaps.queue.commands; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.data.PumpEnactResult; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.Overview.Dialogs.BolusProgressDialog; import info.nightscout.androidaps.plugins.Overview.events.EventDismissBolusprogressIfRunning; @@ -14,7 +18,9 @@ import info.nightscout.utils.DecimalFormatter; */ public class CommandBolus extends Command { - DetailedBolusInfo detailedBolusInfo; + private Logger log = LoggerFactory.getLogger(L.PUMPQUEUE); + + private DetailedBolusInfo detailedBolusInfo; public CommandBolus(DetailedBolusInfo detailedBolusInfo, Callback callback, CommandType type) { commandType = type; @@ -24,10 +30,12 @@ public class CommandBolus extends Command { @Override public void execute() { - PumpEnactResult r = ConfigBuilderPlugin.getActivePump().deliverTreatment(detailedBolusInfo); + PumpEnactResult r = ConfigBuilderPlugin.getPlugin().getActivePump().deliverTreatment(detailedBolusInfo); BolusProgressDialog.bolusEnded = true; MainApp.bus().post(new EventDismissBolusprogressIfRunning(r)); + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("Result success: " + r.success + " enacted: " + r.enacted); if (callback != null) callback.result(r).run(); diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandCancelExtendedBolus.java b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandCancelExtendedBolus.java index 536c2d876c..8dca488890 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandCancelExtendedBolus.java +++ b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandCancelExtendedBolus.java @@ -3,9 +3,8 @@ package info.nightscout.androidaps.queue.commands; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; -import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.data.PumpEnactResult; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.queue.Callback; @@ -14,7 +13,7 @@ import info.nightscout.androidaps.queue.Callback; */ public class CommandCancelExtendedBolus extends Command { - private static Logger log = LoggerFactory.getLogger(CommandCancelExtendedBolus.class); + private Logger log = LoggerFactory.getLogger(L.PUMPQUEUE); public CommandCancelExtendedBolus(Callback callback) { commandType = CommandType.EXTENDEDBOLUS; @@ -23,9 +22,9 @@ public class CommandCancelExtendedBolus extends Command { @Override public void execute() { - PumpEnactResult r = ConfigBuilderPlugin.getActivePump().cancelExtendedBolus(); - if (Config.logCongigBuilderActions) - log.debug("cancelExtendedBolus success: " + r.success + " enacted: " + r.enacted); + PumpEnactResult r = ConfigBuilderPlugin.getPlugin().getActivePump().cancelExtendedBolus(); + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("Result success: " + r.success + " enacted: " + r.enacted); if (callback != null) callback.result(r).run(); } diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandCancelTempBasal.java b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandCancelTempBasal.java index d2496c871a..241ae015fb 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandCancelTempBasal.java +++ b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandCancelTempBasal.java @@ -1,7 +1,10 @@ package info.nightscout.androidaps.queue.commands; -import info.nightscout.androidaps.MainApp; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import info.nightscout.androidaps.data.PumpEnactResult; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.queue.Callback; @@ -10,7 +13,9 @@ import info.nightscout.androidaps.queue.Callback; */ public class CommandCancelTempBasal extends Command { - boolean enforceNew; + private Logger log = LoggerFactory.getLogger(L.PUMPQUEUE); + + private boolean enforceNew; public CommandCancelTempBasal(boolean enforceNew, Callback callback) { commandType = CommandType.TEMPBASAL; @@ -20,7 +25,9 @@ public class CommandCancelTempBasal extends Command { @Override public void execute() { - PumpEnactResult r = ConfigBuilderPlugin.getActivePump().cancelTempBasal(enforceNew); + PumpEnactResult r = ConfigBuilderPlugin.getPlugin().getActivePump().cancelTempBasal(enforceNew); + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("Result success: " + r.success + " enacted: " + r.enacted); if (callback != null) callback.result(r).run(); } diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandExtendedBolus.java b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandExtendedBolus.java index 0641d9139d..ea513bbb6c 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandExtendedBolus.java +++ b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandExtendedBolus.java @@ -3,9 +3,8 @@ package info.nightscout.androidaps.queue.commands; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; -import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.data.PumpEnactResult; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.queue.Callback; @@ -14,7 +13,7 @@ import info.nightscout.androidaps.queue.Callback; */ public class CommandExtendedBolus extends Command { - private static Logger log = LoggerFactory.getLogger(CommandExtendedBolus.class); + private Logger log = LoggerFactory.getLogger(L.PUMPQUEUE); private double insulin; private int durationInMinutes; @@ -28,9 +27,9 @@ public class CommandExtendedBolus extends Command { @Override public void execute() { - PumpEnactResult r = ConfigBuilderPlugin.getActivePump().setExtendedBolus(insulin, durationInMinutes); - if (Config.logCongigBuilderActions) - log.debug("setExtendedBolus rate: " + insulin + " durationInMinutes: " + durationInMinutes + " success: " + r.success + " enacted: " + r.enacted); + PumpEnactResult r = ConfigBuilderPlugin.getPlugin().getActivePump().setExtendedBolus(insulin, durationInMinutes); + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("Result rate: " + insulin + " durationInMinutes: " + durationInMinutes + " success: " + r.success + " enacted: " + r.enacted); if (callback != null) callback.result(r).run(); } diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandLoadEvents.java b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandLoadEvents.java index 2d6bc5b5fc..0742075035 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandLoadEvents.java +++ b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandLoadEvents.java @@ -1,8 +1,12 @@ package info.nightscout.androidaps.queue.commands; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.interfaces.DanaRInterface; import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.queue.Callback; @@ -11,6 +15,8 @@ import info.nightscout.androidaps.queue.Callback; */ public class CommandLoadEvents extends Command { + private Logger log = LoggerFactory.getLogger(L.PUMPQUEUE); + public CommandLoadEvents(Callback callback) { commandType = CommandType.LOADEVENTS; this.callback = callback; @@ -18,10 +24,12 @@ public class CommandLoadEvents extends Command { @Override public void execute() { - PumpInterface pump = ConfigBuilderPlugin.getActivePump(); + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); if (pump instanceof DanaRInterface) { DanaRInterface danaPump = (DanaRInterface) pump; PumpEnactResult r = danaPump.loadEvents(); + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("Result success: " + r.success + " enacted: " + r.enacted); if (callback != null) callback.result(r).run(); } diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandLoadHistory.java b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandLoadHistory.java index 16e9a18048..01ec6e1f16 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandLoadHistory.java +++ b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandLoadHistory.java @@ -1,18 +1,23 @@ package info.nightscout.androidaps.queue.commands; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.interfaces.DanaRInterface; import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.queue.Callback; -import info.nightscout.androidaps.queue.commands.Command; /** * Created by mike on 10.11.2017. */ public class CommandLoadHistory extends Command { - byte type; + private Logger log = LoggerFactory.getLogger(L.PUMPQUEUE); + + private byte type; public CommandLoadHistory(byte type, Callback callback) { commandType = CommandType.LOADHISTORY; @@ -22,10 +27,12 @@ public class CommandLoadHistory extends Command { @Override public void execute() { - PumpInterface pump = ConfigBuilderPlugin.getActivePump(); + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); if (pump instanceof DanaRInterface) { DanaRInterface danaPump = (DanaRInterface) pump; PumpEnactResult r = danaPump.loadHistory(type); + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("Result success: " + r.success + " enacted: " + r.enacted); if (callback != null) callback.result(r).run(); } diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandLoadTDDs.java b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandLoadTDDs.java index 363781a379..c072766310 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandLoadTDDs.java +++ b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandLoadTDDs.java @@ -1,7 +1,11 @@ package info.nightscout.androidaps.queue.commands; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.queue.Callback; @@ -10,6 +14,8 @@ import info.nightscout.androidaps.queue.Callback; */ public class CommandLoadTDDs extends Command { + private Logger log = LoggerFactory.getLogger(L.PUMPQUEUE); + public CommandLoadTDDs(Callback callback) { commandType = CommandType.LOADHISTORY; //belongs to the history group of commands @@ -18,11 +24,13 @@ public class CommandLoadTDDs extends Command { @Override public void execute() { - PumpInterface pump = ConfigBuilderPlugin.getActivePump(); + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); PumpEnactResult r = pump.loadTDDs(); + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("Result success: " + r.success + " enacted: " + r.enacted); if (callback != null) callback.result(r).run(); - } + } @Override public String status() { diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandReadStatus.java b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandReadStatus.java index 44c778c5f7..7e5bded5ee 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandReadStatus.java +++ b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandReadStatus.java @@ -1,15 +1,24 @@ package info.nightscout.androidaps.queue.commands; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import info.nightscout.androidaps.data.PumpEnactResult; +import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.queue.Callback; import info.nightscout.utils.LocalAlertUtils; +import info.nightscout.utils.T; /** * Created by mike on 09.11.2017. */ public class CommandReadStatus extends Command { - String reason; + private Logger log = LoggerFactory.getLogger(L.PUMPQUEUE); + + private String reason; public CommandReadStatus(String reason, Callback callback) { commandType = CommandType.READSTATUS; @@ -19,10 +28,19 @@ public class CommandReadStatus extends Command { @Override public void execute() { - ConfigBuilderPlugin.getActivePump().getPumpStatus(); + ConfigBuilderPlugin.getPlugin().getActivePump().getPumpStatus(); LocalAlertUtils.notifyPumpStatusRead(); + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("CommandReadStatus executed. Reason: " + reason); + final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); + PumpEnactResult result = new PumpEnactResult().success(false); + if (pump != null) { + long lastConnection = pump.lastDataTime(); + if (lastConnection > System.currentTimeMillis() - T.mins(1).msecs()) + result.success(true); + } if (callback != null) - callback.result(null).run(); + callback.result(result).run(); } @Override diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandSMBBolus.java b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandSMBBolus.java index 46336f7d4b..1bd958866e 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandSMBBolus.java +++ b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandSMBBolus.java @@ -3,12 +3,10 @@ package info.nightscout.androidaps.queue.commands; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.data.PumpEnactResult; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; -import info.nightscout.androidaps.plugins.Overview.Dialogs.BolusProgressDialog; -import info.nightscout.androidaps.plugins.Overview.events.EventDismissBolusprogressIfRunning; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.androidaps.queue.Callback; import info.nightscout.utils.DateUtil; @@ -20,8 +18,9 @@ import info.nightscout.utils.T; */ public class CommandSMBBolus extends Command { - private static Logger log = LoggerFactory.getLogger(CommandSMBBolus.class); - DetailedBolusInfo detailedBolusInfo; + private Logger log = LoggerFactory.getLogger(L.PUMPQUEUE); + + private DetailedBolusInfo detailedBolusInfo; public CommandSMBBolus(DetailedBolusInfo detailedBolusInfo, Callback callback) { commandType = CommandType.SMB_BOLUS; @@ -34,20 +33,25 @@ public class CommandSMBBolus extends Command { PumpEnactResult r; long lastBolusTime = TreatmentsPlugin.getPlugin().getLastBolusTime(); if (lastBolusTime != 0 && lastBolusTime + T.mins(3).msecs() > DateUtil.now()) { - log.debug("SMB requsted but still in 3 min interval"); + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("SMB requsted but still in 3 min interval"); r = new PumpEnactResult().enacted(false).success(false).comment("SMB requsted but still in 3 min interval"); - } else if (detailedBolusInfo.deliverAt != 0 && detailedBolusInfo.deliverAt + T.mins(1).msecs() > System.currentTimeMillis()) - r = ConfigBuilderPlugin.getActivePump().deliverTreatment(detailedBolusInfo); - else { + } else if (detailedBolusInfo.deliverAt != 0 && detailedBolusInfo.deliverAt + T.mins(1).msecs() > System.currentTimeMillis()) { + r = ConfigBuilderPlugin.getPlugin().getActivePump().deliverTreatment(detailedBolusInfo); + } else { r = new PumpEnactResult().enacted(false).success(false).comment("SMB request too old"); - log.debug("SMB bolus canceled. delivetAt=" + detailedBolusInfo.deliverAt + " now=" + System.currentTimeMillis()); + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("SMB bolus canceled. delivetAt: " + DateUtil.dateAndTimeString(detailedBolusInfo.deliverAt)); } + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("Result success: " + r.success + " enacted: " + r.enacted); + if (callback != null) callback.result(r).run(); } public String status() { - return "SMBBOLUS " + DecimalFormatter.to1Decimal(detailedBolusInfo.insulin) + "U"; + return "SMBBOLUS " + DecimalFormatter.to2Decimal(detailedBolusInfo.insulin) + "U"; } } diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandSetProfile.java b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandSetProfile.java index 03764dee0b..a9bf7258e3 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandSetProfile.java +++ b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandSetProfile.java @@ -10,6 +10,7 @@ import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.db.ProfileSwitch; import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.interfaces.PluginType; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.SmsCommunicator.SmsCommunicatorPlugin; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; @@ -20,7 +21,8 @@ import info.nightscout.androidaps.queue.Callback; */ public class CommandSetProfile extends Command { - private static Logger log = LoggerFactory.getLogger(CommandSetProfile.class); + private Logger log = LoggerFactory.getLogger(L.PUMPQUEUE); + private Profile profile; public CommandSetProfile(Profile profile, Callback callback) { @@ -31,20 +33,23 @@ public class CommandSetProfile extends Command { @Override public void execute() { - if (ConfigBuilderPlugin.getCommandQueue().isThisProfileSet(profile)) { - log.debug("QUEUE: Correct profile already set"); + if (ConfigBuilderPlugin.getPlugin().getCommandQueue().isThisProfileSet(profile)) { + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("Correct profile already set. profile: " + profile.toString()); if (callback != null) callback.result(new PumpEnactResult().success(true).enacted(false)).run(); return; } - PumpEnactResult r = ConfigBuilderPlugin.getActivePump().setNewBasalProfile(profile); + PumpEnactResult r = ConfigBuilderPlugin.getPlugin().getActivePump().setNewBasalProfile(profile); + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("Result success: " + r.success + " enacted: " + r.enacted + " profile: " + profile.toString()); if (callback != null) callback.result(r).run(); // Send SMS notification if ProfileSwitch is comming from NS ProfileSwitch profileSwitch = TreatmentsPlugin.getPlugin().getProfileSwitchFromHistory(System.currentTimeMillis()); - if (r.enacted && profileSwitch.source == Source.NIGHTSCOUT) { + if (profileSwitch != null && r.enacted && profileSwitch.source == Source.NIGHTSCOUT) { SmsCommunicatorPlugin smsCommunicatorPlugin = MainApp.getSpecificPlugin(SmsCommunicatorPlugin.class); if (smsCommunicatorPlugin != null && smsCommunicatorPlugin.isEnabled(PluginType.GENERAL)) { smsCommunicatorPlugin.sendNotificationToAllNumbers(MainApp.gs(R.string.profile_set_ok)); diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandSetUserSettings.java b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandSetUserSettings.java new file mode 100644 index 0000000000..c1bf69ce01 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandSetUserSettings.java @@ -0,0 +1,42 @@ +package info.nightscout.androidaps.queue.commands; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import info.nightscout.androidaps.data.PumpEnactResult; +import info.nightscout.androidaps.interfaces.DanaRInterface; +import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.queue.Callback; + +/** + * Created by mike on 10.11.2017. + */ + +public class CommandSetUserSettings extends Command { + private Logger log = LoggerFactory.getLogger(L.PUMPQUEUE); + + public CommandSetUserSettings(Callback callback) { + commandType = CommandType.SETUSERSETTINGS; + this.callback = callback; + } + + @Override + public void execute() { + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); + if (pump instanceof DanaRInterface) { + DanaRInterface danaPump = (DanaRInterface) pump; + PumpEnactResult r = danaPump.setUserOptions(); + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("Result success: " + r.success + " enacted: " + r.enacted); + if (callback != null) + callback.result(r).run(); + } + } + + @Override + public String status() { + return "SETUSERSETTINGS"; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandTempBasalAbsolute.java b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandTempBasalAbsolute.java index 35c2435558..9e75fd0713 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandTempBasalAbsolute.java +++ b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandTempBasalAbsolute.java @@ -3,10 +3,9 @@ package info.nightscout.androidaps.queue.commands; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; -import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.PumpEnactResult; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.queue.Callback; @@ -15,12 +14,12 @@ import info.nightscout.androidaps.queue.Callback; */ public class CommandTempBasalAbsolute extends Command { - private static Logger log = LoggerFactory.getLogger(CommandTempBasalAbsolute.class); + private Logger log = LoggerFactory.getLogger(L.PUMPQUEUE); - int durationInMinutes; - double absoluteRate; - boolean enforceNew; - Profile profile; + private int durationInMinutes; + private double absoluteRate; + private boolean enforceNew; + private Profile profile; public CommandTempBasalAbsolute(double absoluteRate, int durationInMinutes, boolean enforceNew, Profile profile, Callback callback) { commandType = CommandType.TEMPBASAL; @@ -33,9 +32,9 @@ public class CommandTempBasalAbsolute extends Command { @Override public void execute() { - PumpEnactResult r = ConfigBuilderPlugin.getActivePump().setTempBasalAbsolute(absoluteRate, durationInMinutes, profile, enforceNew); - if (Config.logCongigBuilderActions) - log.debug("setTempBasalAbsolute rate: " + absoluteRate + " durationInMinutes: " + durationInMinutes + " success: " + r.success + " enacted: " + r.enacted); + PumpEnactResult r = ConfigBuilderPlugin.getPlugin().getActivePump().setTempBasalAbsolute(absoluteRate, durationInMinutes, profile, enforceNew); + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("Result rate: " + absoluteRate + " durationInMinutes: " + durationInMinutes + " success: " + r.success + " enacted: " + r.enacted); if (callback != null) callback.result(r).run(); } diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandTempBasalPercent.java b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandTempBasalPercent.java index bbb421e128..2bc44e269e 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandTempBasalPercent.java +++ b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandTempBasalPercent.java @@ -3,9 +3,9 @@ package info.nightscout.androidaps.queue.commands; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.PumpEnactResult; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.queue.Callback; @@ -14,12 +14,12 @@ import info.nightscout.androidaps.queue.Callback; */ public class CommandTempBasalPercent extends Command { - private static Logger log = LoggerFactory.getLogger(CommandTempBasalPercent.class); + private Logger log = LoggerFactory.getLogger(L.PUMPQUEUE); - int durationInMinutes; - int percent; - boolean enforceNew; - Profile profile; + private int durationInMinutes; + private int percent; + private boolean enforceNew; + private Profile profile; public CommandTempBasalPercent(int percent, int durationInMinutes, boolean enforceNew, Profile profile, Callback callback) { commandType = CommandType.TEMPBASAL; @@ -32,9 +32,9 @@ public class CommandTempBasalPercent extends Command { @Override public void execute() { - PumpEnactResult r = ConfigBuilderPlugin.getActivePump().setTempBasalPercent(percent, durationInMinutes, profile, enforceNew); - if (Config.logCongigBuilderActions) - log.debug("setTempBasalPercent percent: " + percent + " durationInMinutes: " + durationInMinutes + " success: " + r.success + " enacted: " + r.enacted); + PumpEnactResult r = ConfigBuilderPlugin.getPlugin().getActivePump().setTempBasalPercent(percent, durationInMinutes, profile, enforceNew); + if (L.isEnabled(L.PUMPQUEUE)) + log.debug("Result percent: " + percent + " durationInMinutes: " + durationInMinutes + " success: " + r.success + " enacted: " + r.enacted); if (callback != null) callback.result(r).run(); } diff --git a/app/src/main/java/info/nightscout/androidaps/receivers/ChargingStateReceiver.java b/app/src/main/java/info/nightscout/androidaps/receivers/ChargingStateReceiver.java index 3dbec90b4f..b10c2e99e5 100644 --- a/app/src/main/java/info/nightscout/androidaps/receivers/ChargingStateReceiver.java +++ b/app/src/main/java/info/nightscout/androidaps/receivers/ChargingStateReceiver.java @@ -21,6 +21,9 @@ public class ChargingStateReceiver extends BroadcastReceiver { public EventChargingState grabChargingState(Context context) { BatteryManager bm = (BatteryManager) context.getSystemService(Context.BATTERY_SERVICE); + if (bm == null) + return new EventChargingState(false); + int status = bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_STATUS); boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING || status == BatteryManager.BATTERY_STATUS_FULL; diff --git a/app/src/main/java/info/nightscout/androidaps/receivers/DataReceiver.java b/app/src/main/java/info/nightscout/androidaps/receivers/DataReceiver.java index aa767bb154..087cd3a5f5 100644 --- a/app/src/main/java/info/nightscout/androidaps/receivers/DataReceiver.java +++ b/app/src/main/java/info/nightscout/androidaps/receivers/DataReceiver.java @@ -7,15 +7,15 @@ import android.support.v4.content.WakefulBroadcastReceiver; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Services.DataService; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.services.DataService; public class DataReceiver extends WakefulBroadcastReceiver { - private static Logger log = LoggerFactory.getLogger(DataReceiver.class); + private static Logger log = LoggerFactory.getLogger(L.DATASERVICE); @Override public void onReceive(Context context, Intent intent) { - if (Config.logFunctionCalls) + if (L.isEnabled(L.DATASERVICE)) log.debug("onReceive " + intent); startWakefulService(context, new Intent(context, DataService.class) .setAction(intent.getAction()) diff --git a/app/src/main/java/info/nightscout/androidaps/receivers/KeepAliveReceiver.java b/app/src/main/java/info/nightscout/androidaps/receivers/KeepAliveReceiver.java index af46321901..cc36f21a59 100644 --- a/app/src/main/java/info/nightscout/androidaps/receivers/KeepAliveReceiver.java +++ b/app/src/main/java/info/nightscout/androidaps/receivers/KeepAliveReceiver.java @@ -1,9 +1,5 @@ package info.nightscout.androidaps.receivers; -/** - * Created by mike on 07.07.2016. - */ - import android.app.AlarmManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; @@ -11,23 +7,34 @@ import android.content.Context; import android.content.Intent; import android.os.PowerManager; +import com.crashlytics.android.answers.CustomEvent; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Date; - import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.events.EventProfileSwitchChange; import info.nightscout.androidaps.interfaces.PumpInterface; -import info.nightscout.androidaps.data.Profile; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.queue.commands.Command; +import info.nightscout.utils.DateUtil; +import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.LocalAlertUtils; +import info.nightscout.utils.T; + +/** + * Created by mike on 07.07.2016. + */ public class KeepAliveReceiver extends BroadcastReceiver { - private static Logger log = LoggerFactory.getLogger(KeepAliveReceiver.class); - public static final long STATUS_UPDATE_FREQUENCY = 15 * 60 * 1000L; + private static Logger log = LoggerFactory.getLogger(L.CORE); + public static final long STATUS_UPDATE_FREQUENCY = T.mins(15).msecs(); + private static long lastReadStatus = 0; + private static long lastRun = 0; public static void cancelAlarm(Context context) { Intent intent = new Intent(context, KeepAliveReceiver.class); @@ -45,29 +52,44 @@ public class KeepAliveReceiver extends BroadcastReceiver { LocalAlertUtils.shortenSnoozeInterval(); LocalAlertUtils.checkStaleBGAlert(); checkPump(); + FabricPrivacy.uploadDailyStats(); - log.debug("KeepAlive received"); + if (L.isEnabled(L.CORE)) + log.debug("KeepAlive received"); wl.release(); } private void checkPump() { - final PumpInterface pump = ConfigBuilderPlugin.getActivePump(); - final Profile profile = MainApp.getConfigBuilder().getProfile(); + final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); + final Profile profile = ProfileFunctions.getInstance().getProfile(); if (pump != null && profile != null) { - Date lastConnection = pump.lastDataTime(); - boolean isStatusOutdated = lastConnection.getTime() + STATUS_UPDATE_FREQUENCY < System.currentTimeMillis(); + long lastConnection = pump.lastDataTime(); + boolean isStatusOutdated = lastConnection + STATUS_UPDATE_FREQUENCY < System.currentTimeMillis(); boolean isBasalOutdated = Math.abs(profile.getBasal() - pump.getBaseBasalRate()) > pump.getPumpDescription().basalStep; - LocalAlertUtils.checkPumpUnreachableAlarm(lastConnection, isStatusOutdated); + if (L.isEnabled(L.CORE)) + log.debug("Last connection: " + DateUtil.dateAndTimeString(lastConnection)); + // sometimes keepalive broadcast stops + // as as workaround test if readStatus was requested before an alarm is generated + if (lastReadStatus != 0 && lastReadStatus > System.currentTimeMillis() - T.mins(5).msecs()) { + LocalAlertUtils.checkPumpUnreachableAlarm(lastConnection, isStatusOutdated); + } - if (!pump.isThisProfileSet(profile) && !ConfigBuilderPlugin.getCommandQueue().isRunning(Command.CommandType.BASALPROFILE)) { + if (!pump.isThisProfileSet(profile) && !ConfigBuilderPlugin.getPlugin().getCommandQueue().isRunning(Command.CommandType.BASALPROFILE)) { MainApp.bus().post(new EventProfileSwitchChange()); } else if (isStatusOutdated && !pump.isBusy()) { - ConfigBuilderPlugin.getCommandQueue().readStatus("KeepAlive. Status outdated.", null); + lastReadStatus = System.currentTimeMillis(); + ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("KeepAlive. Status outdated.", null); } else if (isBasalOutdated && !pump.isBusy()) { - ConfigBuilderPlugin.getCommandQueue().readStatus("KeepAlive. Basal outdated.", null); + lastReadStatus = System.currentTimeMillis(); + ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("KeepAlive. Basal outdated.", null); } } + if (lastRun != 0 && System.currentTimeMillis() - lastRun > T.mins(10).msecs()) { + log.error("KeepAlive fail"); + FabricPrivacy.getInstance().logCustom(new CustomEvent("KeepAliveFail")); + } + lastRun = System.currentTimeMillis(); } //called by MainApp at first app start diff --git a/app/src/main/java/info/nightscout/androidaps/receivers/NSAlarmReceiver.java b/app/src/main/java/info/nightscout/androidaps/receivers/NSAlarmReceiver.java index 95bb5e17b3..d167bb9510 100644 --- a/app/src/main/java/info/nightscout/androidaps/receivers/NSAlarmReceiver.java +++ b/app/src/main/java/info/nightscout/androidaps/receivers/NSAlarmReceiver.java @@ -11,14 +11,15 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.Services.Intents; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.NSClientInternal.data.NSAlarm; -import info.nightscout.androidaps.plugins.Overview.notifications.Notification; import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; +import info.nightscout.androidaps.plugins.Overview.notifications.Notification; +import info.nightscout.androidaps.services.Intents; public class NSAlarmReceiver extends BroadcastReceiver { - private static Logger log = LoggerFactory.getLogger(NSAlarmReceiver.class); + private static Logger log = LoggerFactory.getLogger(L.CORE); @Override public void onReceive(Context context, Intent intent) { diff --git a/app/src/main/java/info/nightscout/androidaps/receivers/NetworkChangeReceiver.java b/app/src/main/java/info/nightscout/androidaps/receivers/NetworkChangeReceiver.java index a8bd49f430..9a3108e98c 100644 --- a/app/src/main/java/info/nightscout/androidaps/receivers/NetworkChangeReceiver.java +++ b/app/src/main/java/info/nightscout/androidaps/receivers/NetworkChangeReceiver.java @@ -15,10 +15,11 @@ import org.slf4j.LoggerFactory; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.events.EventNetworkChange; +import info.nightscout.androidaps.logging.L; public class NetworkChangeReceiver extends BroadcastReceiver { - private static Logger log = LoggerFactory.getLogger(NetworkChangeReceiver.class); + private static Logger log = LoggerFactory.getLogger(L.CORE); @Override public void onReceive(final Context context, final Intent intent) { @@ -44,17 +45,20 @@ public class NetworkChangeReceiver extends BroadcastReceiver { if (wifiInfo.getSupplicantState() == SupplicantState.COMPLETED) { event.ssid = wifiInfo.getSSID(); } - log.debug("NETCHANGE: Wifi connected. SSID: " + event.ssid); + if (L.isEnabled(L.CORE)) + log.debug("NETCHANGE: Wifi connected. SSID: " + event.ssid); } } if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) { event.mobileConnected = true; event.roaming = activeNetwork.isRoaming(); - log.debug("NETCHANGE: Mobile connected. Roaming: " + event.roaming); + if (L.isEnabled(L.CORE)) + log.debug("NETCHANGE: Mobile connected. Roaming: " + event.roaming); } } else { - log.debug("NETCHANGE: Disconnected."); + if (L.isEnabled(L.CORE)) + log.debug("NETCHANGE: Disconnected."); } return event; diff --git a/app/src/main/java/info/nightscout/androidaps/Services/AlarmSoundService.java b/app/src/main/java/info/nightscout/androidaps/services/AlarmSoundService.java similarity index 81% rename from app/src/main/java/info/nightscout/androidaps/Services/AlarmSoundService.java rename to app/src/main/java/info/nightscout/androidaps/services/AlarmSoundService.java index f453b04d36..e95cd7c479 100644 --- a/app/src/main/java/info/nightscout/androidaps/Services/AlarmSoundService.java +++ b/app/src/main/java/info/nightscout/androidaps/services/AlarmSoundService.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.Services; +package info.nightscout.androidaps.services; import android.app.Service; import android.content.Context; @@ -15,9 +15,10 @@ import java.io.IOException; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.logging.L; public class AlarmSoundService extends Service { - private static Logger log = LoggerFactory.getLogger(AlarmSoundService.class); + private static Logger log = LoggerFactory.getLogger(L.CORE); MediaPlayer player; int resourceId = R.raw.error; @@ -34,13 +35,15 @@ public class AlarmSoundService extends Service { @Override public void onCreate() { super.onCreate(); - log.debug("onCreate"); + if (L.isEnabled(L.CORE)) + log.debug("onCreate"); } public int onStartCommand(Intent intent, int flags, int startId) { if (player != null && player.isPlaying()) player.stop(); - log.debug("onStartCommand"); + if (L.isEnabled(L.CORE)) + log.debug("onStartCommand"); if (intent != null && intent.hasExtra("soundid")) resourceId = intent.getIntExtra("soundid", R.raw.error); @@ -55,7 +58,7 @@ public class AlarmSoundService extends Service { log.error("Unhandled exception", e); } player.setLooping(true); // Set looping - AudioManager manager = (AudioManager)this.getSystemService(Context.AUDIO_SERVICE); + AudioManager manager = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE); if (manager == null || !manager.isMusicActive()) { player.setVolume(100, 100); } @@ -74,5 +77,7 @@ public class AlarmSoundService extends Service { public void onDestroy() { player.stop(); player.release(); + if (L.isEnabled(L.CORE)) + log.debug("onDestroy"); } } diff --git a/app/src/main/java/info/nightscout/androidaps/services/DataService.java b/app/src/main/java/info/nightscout/androidaps/services/DataService.java new file mode 100644 index 0000000000..cfc564770d --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/services/DataService.java @@ -0,0 +1,264 @@ +package info.nightscout.androidaps.services; + +import android.app.IntentService; +import android.content.Intent; +import android.os.Bundle; +import android.provider.Telephony; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.db.CareportalEvent; +import info.nightscout.androidaps.events.EventNsFood; +import info.nightscout.androidaps.events.EventNsTreatment; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.NSClientInternal.data.NSDeviceStatus; +import info.nightscout.androidaps.plugins.NSClientInternal.data.NSMbg; +import info.nightscout.androidaps.plugins.NSClientInternal.data.NSSettingsStatus; +import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; +import info.nightscout.androidaps.plugins.Overview.notifications.Notification; +import info.nightscout.androidaps.plugins.ProfileNS.NSProfilePlugin; +import info.nightscout.androidaps.plugins.PumpDanaR.activities.DanaRNSHistorySync; +import info.nightscout.androidaps.plugins.SmsCommunicator.SmsCommunicatorPlugin; +import info.nightscout.androidaps.plugins.Source.SourceDexcomG5Plugin; +import info.nightscout.androidaps.plugins.Source.SourceGlimpPlugin; +import info.nightscout.androidaps.plugins.Source.SourceMM640gPlugin; +import info.nightscout.androidaps.plugins.Source.SourceNSClientPlugin; +import info.nightscout.androidaps.plugins.Source.SourcePoctechPlugin; +import info.nightscout.androidaps.plugins.Source.SourceXdripPlugin; +import info.nightscout.androidaps.receivers.DataReceiver; +import info.nightscout.androidaps.logging.BundleLogger; +import info.nightscout.utils.JsonHelper; +import info.nightscout.utils.SP; + + +public class DataService extends IntentService { + private Logger log = LoggerFactory.getLogger(L.DATASERVICE); + + public DataService() { + super("DataService"); + registerBus(); + } + + @Override + protected void onHandleIntent(final Intent intent) { + if (L.isEnabled(L.DATASERVICE)) { + log.debug("onHandleIntent " + intent); + log.debug("onHandleIntent " + BundleLogger.log(intent.getExtras())); + } + + boolean acceptNSData = !SP.getBoolean(R.string.key_ns_upload_only, false); + Bundle bundles = intent.getExtras(); + if (bundles != null && bundles.containsKey("islocal")) { + acceptNSData = acceptNSData || bundles.getBoolean("islocal"); + } + + + final String action = intent.getAction(); + if (Intents.ACTION_NEW_BG_ESTIMATE.equals(action)) { + SourceXdripPlugin.getPlugin().handleNewData(intent); + } else if (Intents.NS_EMULATOR.equals(action)) { + SourceMM640gPlugin.getPlugin().handleNewData(intent); + } else if (Intents.GLIMP_BG.equals(action)) { + SourceGlimpPlugin.getPlugin().handleNewData(intent); + } else if (Intents.DEXCOMG5_BG.equals(action)) { + SourceDexcomG5Plugin.getPlugin().handleNewData(intent); + } else if (Intents.POCTECH_BG.equals(action)) { + SourcePoctechPlugin.getPlugin().handleNewData(intent); + } else if (Intents.ACTION_NEW_SGV.equals(action)) { + SourceNSClientPlugin.getPlugin().handleNewData(intent); + } else if (Intents.ACTION_NEW_PROFILE.equals(action)) { + // always handle Profile if NSProfile is enabled without looking at nsUploadOnly + NSProfilePlugin.getPlugin().handleNewData(intent); + } else if (Intents.ACTION_NEW_DEVICESTATUS.equals(action)) { + NSDeviceStatus.getInstance().handleNewData(intent); + } else if (Intents.ACTION_NEW_STATUS.equals(action)) { + NSSettingsStatus.getInstance().handleNewData(intent); + } else if (Intents.ACTION_NEW_FOOD.equals(action)) { + EventNsFood evt = new EventNsFood(EventNsFood.ADD, bundles); + MainApp.bus().post(evt); + } else if (Intents.ACTION_CHANGED_FOOD.equals(action)) { + EventNsFood evt = new EventNsFood(EventNsFood.UPDATE, bundles); + MainApp.bus().post(evt); + } else if (Intents.ACTION_REMOVED_FOOD.equals(action)) { + EventNsFood evt = new EventNsFood(EventNsFood.REMOVE, bundles); + MainApp.bus().post(evt); + } else if (acceptNSData && + (Intents.ACTION_NEW_TREATMENT.equals(action) || + Intents.ACTION_CHANGED_TREATMENT.equals(action) || + Intents.ACTION_REMOVED_TREATMENT.equals(action) || + Intents.ACTION_NEW_CAL.equals(action) || + Intents.ACTION_NEW_MBG.equals(action)) + ) { + handleNewDataFromNSClient(intent); + } else if (Telephony.Sms.Intents.SMS_RECEIVED_ACTION.equals(action)) { + SmsCommunicatorPlugin.getPlugin().handleNewData(intent); + } + + if (L.isEnabled(L.DATASERVICE)) + log.debug("onHandleIntent exit " + intent); + DataReceiver.completeWakefulIntent(intent); + } + + @Override + public void onDestroy() { + super.onDestroy(); + MainApp.bus().unregister(this); + } + + private void registerBus() { + try { + MainApp.bus().unregister(this); + } catch (RuntimeException x) { + // Ignore + } + MainApp.bus().register(this); + } + + private void handleNewDataFromNSClient(Intent intent) { + Bundle bundles = intent.getExtras(); + if (bundles == null) return; + if (L.isEnabled(L.DATASERVICE)) + log.debug("Got intent: " + intent.getAction()); + + + if (intent.getAction().equals(Intents.ACTION_NEW_TREATMENT) || intent.getAction().equals(Intents.ACTION_CHANGED_TREATMENT)) { + try { + if (bundles.containsKey("treatment")) { + JSONObject json = new JSONObject(bundles.getString("treatment")); + handleTreatmentFromNS(json, intent); + } + if (bundles.containsKey("treatments")) { + String trstring = bundles.getString("treatments"); + JSONArray jsonArray = new JSONArray(trstring); + for (int i = 0; i < jsonArray.length(); i++) { + JSONObject json = jsonArray.getJSONObject(i); + handleTreatmentFromNS(json, intent); + } + } + } catch (JSONException e) { + log.error("Unhandled exception", e); + } + } + + if (intent.getAction().equals(Intents.ACTION_REMOVED_TREATMENT)) { + try { + if (bundles.containsKey("treatment")) { + String trstring = bundles.getString("treatment"); + JSONObject json = new JSONObject(trstring); + handleRemovedTreatmentFromNS(json); + } + + if (bundles.containsKey("treatments")) { + String trstring = bundles.getString("treatments"); + JSONArray jsonArray = new JSONArray(trstring); + for (int i = 0; i < jsonArray.length(); i++) { + JSONObject json = jsonArray.getJSONObject(i); + handleRemovedTreatmentFromNS(json); + } + } + } catch (JSONException e) { + log.error("Unhandled exception", e); + } + } + + if (intent.getAction().equals(Intents.ACTION_NEW_MBG)) { + try { + if (bundles.containsKey("mbg")) { + String mbgstring = bundles.getString("mbg"); + JSONObject mbgJson = new JSONObject(mbgstring); + storeMbg(mbgJson); + } + + if (bundles.containsKey("mbgs")) { + String sgvstring = bundles.getString("mbgs"); + JSONArray jsonArray = new JSONArray(sgvstring); + for (int i = 0; i < jsonArray.length(); i++) { + JSONObject mbgJson = jsonArray.getJSONObject(i); + storeMbg(mbgJson); + } + } + } catch (Exception e) { + log.error("Unhandled exception", e); + } + } + } + + private void handleRemovedTreatmentFromNS(JSONObject json) { + // new DB model + EventNsTreatment evtTreatment = new EventNsTreatment(EventNsTreatment.REMOVE, json); + MainApp.bus().post(evtTreatment); + // old DB model + String _id = JsonHelper.safeGetString(json, "_id"); + MainApp.getDbHelper().deleteTempTargetById(_id); + MainApp.getDbHelper().deleteTempBasalById(_id); + MainApp.getDbHelper().deleteExtendedBolusById(_id); + MainApp.getDbHelper().deleteCareportalEventById(_id); + MainApp.getDbHelper().deleteProfileSwitchById(_id); + } + + private void handleTreatmentFromNS(JSONObject json, Intent intent) { + // new DB model + int mode = Intents.ACTION_NEW_TREATMENT.equals(intent.getAction()) ? EventNsTreatment.ADD : EventNsTreatment.UPDATE; + double insulin = JsonHelper.safeGetDouble(json, "insulin"); + double carbs = JsonHelper.safeGetDouble(json, "carbs"); + String eventType = JsonHelper.safeGetString(json, "eventType"); + if (eventType == null) { + log.debug("Wrong treatment. Ignoring : " + json.toString()); + return; + } + if (insulin > 0 || carbs > 0) { + EventNsTreatment evtTreatment = new EventNsTreatment(mode, json); + MainApp.bus().post(evtTreatment); + } else if (json.has(DanaRNSHistorySync.DANARSIGNATURE)) { + // old DB model + MainApp.getDbHelper().updateDanaRHistoryRecordId(json); + } else if (eventType.equals(CareportalEvent.TEMPORARYTARGET)) { + MainApp.getDbHelper().createTemptargetFromJsonIfNotExists(json); + } else if (eventType.equals(CareportalEvent.TEMPBASAL)) { + MainApp.getDbHelper().createTempBasalFromJsonIfNotExists(json); + } else if (eventType.equals(CareportalEvent.COMBOBOLUS)) { + MainApp.getDbHelper().createExtendedBolusFromJsonIfNotExists(json); + } else if (eventType.equals(CareportalEvent.PROFILESWITCH)) { + MainApp.getDbHelper().createProfileSwitchFromJsonIfNotExists(json); + } else if (eventType.equals(CareportalEvent.SITECHANGE) || + eventType.equals(CareportalEvent.INSULINCHANGE) || + eventType.equals(CareportalEvent.SENSORCHANGE) || + eventType.equals(CareportalEvent.BGCHECK) || + eventType.equals(CareportalEvent.NOTE) || + eventType.equals(CareportalEvent.NONE) || + eventType.equals(CareportalEvent.ANNOUNCEMENT) || + eventType.equals(CareportalEvent.QUESTION) || + eventType.equals(CareportalEvent.EXERCISE) || + eventType.equals(CareportalEvent.OPENAPSOFFLINE) || + eventType.equals(CareportalEvent.PUMPBATTERYCHANGE)) { + MainApp.getDbHelper().createCareportalEventFromJsonIfNotExists(json); + } + + if (eventType.equals(CareportalEvent.ANNOUNCEMENT)) { + long date = JsonHelper.safeGetLong(json, "mills"); + long now = System.currentTimeMillis(); + String enteredBy = JsonHelper.safeGetString(json, "enteredBy", ""); + String notes = JsonHelper.safeGetString(json, "notes", ""); + if (date > now - 15 * 60 * 1000L && !notes.isEmpty() + && !enteredBy.equals(SP.getString("careportal_enteredby", "AndroidAPS"))) { + Notification announcement = new Notification(Notification.NSANNOUNCEMENT, notes, Notification.ANNOUNCEMENT, 60); + MainApp.bus().post(new EventNewNotification(announcement)); + } + } + } + + private void storeMbg(JSONObject mbgJson) { + NSMbg nsMbg = new NSMbg(mbgJson); + CareportalEvent careportalEvent = new CareportalEvent(nsMbg); + MainApp.getDbHelper().createOrUpdate(careportalEvent); + if (L.isEnabled(L.DATASERVICE)) + log.debug("Adding/Updating new MBG: " + careportalEvent.toString()); + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/Services/Intents.java b/app/src/main/java/info/nightscout/androidaps/services/Intents.java similarity index 96% rename from app/src/main/java/info/nightscout/androidaps/Services/Intents.java rename to app/src/main/java/info/nightscout/androidaps/services/Intents.java index 744530c8f2..6d3daf1ea9 100644 --- a/app/src/main/java/info/nightscout/androidaps/Services/Intents.java +++ b/app/src/main/java/info/nightscout/androidaps/services/Intents.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.Services; +package info.nightscout.androidaps.services; public interface Intents { // NSClient -> App @@ -49,4 +49,6 @@ public interface Intents { String GLIMP_BG = "it.ct.glicemia.ACTION_GLUCOSE_MEASURED"; String DEXCOMG5_BG = "com.dexcom.cgm.DATA"; + + String POCTECH_BG = "com.china.poctech.data"; } diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/SWDefinition.java b/app/src/main/java/info/nightscout/androidaps/setupwizard/SWDefinition.java index dbdb22782a..c1421d7f0c 100644 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/SWDefinition.java +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/SWDefinition.java @@ -1,13 +1,8 @@ package info.nightscout.androidaps.setupwizard; import android.Manifest; -import android.content.ActivityNotFoundException; -import android.content.Context; import android.content.Intent; -import android.net.Uri; import android.os.Build; -import android.os.PowerManager; -import android.provider.Settings; import android.support.v7.app.AppCompatActivity; import com.squareup.otto.Subscribe; @@ -18,9 +13,10 @@ import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.List; +import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.PreferencesActivity; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.activities.PreferencesActivity; import info.nightscout.androidaps.events.EventConfigBuilderChange; import info.nightscout.androidaps.events.EventPumpStatusChanged; import info.nightscout.androidaps.interfaces.PluginBase; @@ -30,9 +26,11 @@ import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialo import info.nightscout.androidaps.plugins.Careportal.OptionsToShow; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderFragment; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesFragment; import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin; import info.nightscout.androidaps.plugins.Loop.LoopPlugin; +import info.nightscout.androidaps.plugins.Maintenance.ImportExportPrefs; import info.nightscout.androidaps.plugins.NSClientInternal.NSClientPlugin; import info.nightscout.androidaps.plugins.NSClientInternal.events.EventNSClientStatus; import info.nightscout.androidaps.plugins.ProfileLocal.LocalProfileFragment; @@ -43,33 +41,28 @@ import info.nightscout.androidaps.plugins.ProfileSimple.SimpleProfileFragment; import info.nightscout.androidaps.plugins.ProfileSimple.SimpleProfilePlugin; import info.nightscout.androidaps.setupwizard.elements.SWBreak; import info.nightscout.androidaps.setupwizard.elements.SWButton; +import info.nightscout.androidaps.setupwizard.elements.SWEditString; +import info.nightscout.androidaps.setupwizard.elements.SWEditUrl; import info.nightscout.androidaps.setupwizard.elements.SWFragment; import info.nightscout.androidaps.setupwizard.elements.SWHtmlLink; import info.nightscout.androidaps.setupwizard.elements.SWInfotext; import info.nightscout.androidaps.setupwizard.elements.SWPlugin; import info.nightscout.androidaps.setupwizard.elements.SWRadioButton; -import info.nightscout.androidaps.setupwizard.elements.SWEditString; -import info.nightscout.androidaps.setupwizard.elements.SWEditUrl; import info.nightscout.androidaps.setupwizard.events.EventSWLabel; import info.nightscout.androidaps.setupwizard.events.EventSWUpdate; import info.nightscout.utils.AndroidPermission; -import info.nightscout.utils.ImportExportPrefs; import info.nightscout.utils.LocaleHelper; import info.nightscout.utils.PasswordProtection; import info.nightscout.utils.SP; -import info.nightscout.utils.ToastUtils; public class SWDefinition { private static Logger log = LoggerFactory.getLogger(SWDefinition.class); - private String packageName; - private AppCompatActivity activity; private List screens = new ArrayList<>(); public void setActivity(AppCompatActivity activity) { this.activity = activity; - packageName = activity.getPackageName(); } public AppCompatActivity getActivity() { @@ -85,20 +78,19 @@ public class SWDefinition { return this; } - SWDefinition() { + if (Config.APS || Config.PUMPCONTROL) + SWDefinitionFull(); + else if (Config.NSCLIENT) + SWDefinitionNSClient(); + } + + private void SWDefinitionFull() { // List all the screens here add(new SWScreen(R.string.nav_setupwizard) .add(new SWInfotext() .label(R.string.welcometosetupwizard)) - .add(new SWButton() - .text(R.string.nav_import) - .action(() -> ImportExportPrefs.importSharedPreferences(getActivity())) - .visibility(ImportExportPrefs.file::exists)) - .add(new SWInfotext() - .label(R.string.backupismissing) - .visibility(() -> !ImportExportPrefs.file.exists())) - ) + ) .add(new SWScreen(R.string.language) .skippable(false) .add(new SWRadioButton() @@ -162,6 +154,15 @@ public class SWDefinition { .visibility(() -> Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !AndroidPermission.checkForPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE)) .validator(() -> !(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !AndroidPermission.checkForPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE))) ) + .add(new SWScreen(R.string.nav_import) + .add(new SWInfotext() + .label(R.string.storedsettingsfound)) + .add(new SWBreak()) + .add(new SWButton() + .text(R.string.nav_import) + .action(() -> ImportExportPrefs.importSharedPreferences(getActivity()))) + .visibility(() -> ImportExportPrefs.file.exists() && !(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !AndroidPermission.checkForPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE))) + ) .add(new SWScreen(R.string.nsclientinternal_title) .skippable(true) .add(new SWInfotext() @@ -180,11 +181,13 @@ public class SWDefinition { .visibility(() -> !NSClientPlugin.getPlugin().isEnabled(PluginType.GENERAL))) .add(new SWEditUrl() .preferenceId(R.string.key_nsclientinternal_url) + .updateDelay(5) .label(R.string.nsclientinternal_url_title) .comment(R.string.nsclientinternal_url_dialogmessage)) .add(new SWEditString() .validator(text -> text.length() >= 12) .preferenceId(R.string.key_nsclientinternal_api_secret) + .updateDelay(5) .label(R.string.nsclientinternal_secret_dialogtitle) .comment(R.string.nsclientinternal_secret_dialogmessage)) .add(new SWBreak()) @@ -216,53 +219,45 @@ public class SWDefinition { ) .add(new SWScreen(R.string.configbuilder_insulin) .skippable(false) - .add(new SWInfotext() - .label(MainApp.gs(R.string.rapid_acting_oref) + ": " + MainApp.gs(R.string.fastactinginsulincomment))) - .add(new SWInfotext() - .label(MainApp.gs(R.string.ultrarapid_oref) + ": " + MainApp.gs(R.string.ultrafastactinginsulincomment))) - .add(new SWInfotext() - .label(MainApp.gs(R.string.free_peak_oref) + ": " + MainApp.gs(R.string.free_peak_oref_description))) + .add(new SWPlugin() + .option(PluginType.INSULIN, R.string.configbuilder_insulin_description) + .makeVisible(false) + .label(R.string.configbuilder_insulin)) .add(new SWBreak()) .add(new SWInfotext() .label(R.string.diawarning)) .add(new SWBreak()) - .add(new SWPlugin() - .option(PluginType.INSULIN) - .label(R.string.configbuilder_insulin)) - .add(new SWBreak()) .add(new SWButton() .text(R.string.insulinsourcesetup) .action(() -> { - final PluginBase plugin = (PluginBase) MainApp.getConfigBuilder().getActiveInsulin(); + final PluginBase plugin = (PluginBase) ConfigBuilderPlugin.getPlugin().getActiveInsulin(); PasswordProtection.QueryPassword(activity, R.string.settings_password, "settings_password", () -> { Intent i = new Intent(activity, PreferencesActivity.class); i.putExtra("id", plugin.getPreferencesId()); activity.startActivity(i); }, null); }) - .visibility(() -> MainApp.getConfigBuilder().getActiveInsulin()!= null && ((PluginBase) MainApp.getConfigBuilder().getActiveInsulin()).getPreferencesId() > 0)) - .validator(() -> MainApp.getConfigBuilder().getActiveInsulin() != null) + .visibility(() -> ConfigBuilderPlugin.getPlugin().getActiveInsulin()!= null && ((PluginBase) ConfigBuilderPlugin.getPlugin().getActiveInsulin()).getPreferencesId() > 0)) + .validator(() -> ConfigBuilderPlugin.getPlugin().getActiveInsulin() != null) ) .add(new SWScreen(R.string.configbuilder_bgsource) .skippable(false) - .add(new SWInfotext() - .label(R.string.setupwizard_bgsource_description)) .add(new SWPlugin() - .option(PluginType.BGSOURCE) + .option(PluginType.BGSOURCE, R.string.configbuilder_bgsource_description) .label(R.string.configbuilder_bgsource)) .add(new SWBreak()) .add(new SWButton() .text(R.string.bgsourcesetup) .action(() -> { - final PluginBase plugin = (PluginBase) MainApp.getConfigBuilder().getActiveBgSource(); + final PluginBase plugin = (PluginBase) ConfigBuilderPlugin.getPlugin().getActiveBgSource(); PasswordProtection.QueryPassword(activity, R.string.settings_password, "settings_password", () -> { Intent i = new Intent(activity, PreferencesActivity.class); i.putExtra("id", plugin.getPreferencesId()); activity.startActivity(i); }, null); }) - .visibility(() -> MainApp.getConfigBuilder().getActiveBgSource()!= null && ((PluginBase) MainApp.getConfigBuilder().getActiveBgSource()).getPreferencesId() > 0)) - .validator(() -> MainApp.getConfigBuilder().getActiveBgSource() != null) + .visibility(() -> ConfigBuilderPlugin.getPlugin().getActiveBgSource()!= null && ((PluginBase) ConfigBuilderPlugin.getPlugin().getActiveBgSource()).getPreferencesId() > 0)) + .validator(() -> ConfigBuilderPlugin.getPlugin().getActiveBgSource() != null) ) .add(new SWScreen(R.string.configbuilder_profile) .skippable(false) @@ -270,9 +265,9 @@ public class SWDefinition { .label(R.string.setupwizard_profile_description)) .add(new SWBreak()) .add(new SWPlugin() - .option(PluginType.PROFILE) + .option(PluginType.PROFILE, R.string.configbuilder_profile_description) .label(R.string.configbuilder_profile)) - .validator(() -> MainApp.getConfigBuilder().getActiveProfileInterface() != null) + .validator(() -> ConfigBuilderPlugin.getPlugin().getActiveProfileInterface() != null) ) .add(new SWScreen(R.string.nsprofile) .skippable(false) @@ -310,29 +305,30 @@ public class SWDefinition { newDialog.setOptions(profileswitch, R.string.careportal_profileswitch); newDialog.show(getActivity().getSupportFragmentManager(), "NewNSTreatmentDialog"); })) - .validator(() -> MainApp.getConfigBuilder().getProfile() != null) - .visibility(() -> MainApp.getConfigBuilder().getProfile() == null) + .validator(() -> ProfileFunctions.getInstance().getProfile() != null) + .visibility(() -> ProfileFunctions.getInstance().getProfile() == null) ) .add(new SWScreen(R.string.configbuilder_pump) .skippable(false) .add(new SWPlugin() - .option(PluginType.PUMP) + .option(PluginType.PUMP, R.string.configbuilder_pump_description) .label(R.string.configbuilder_pump)) + .add(new SWBreak()) .add(new SWButton() .text(R.string.pumpsetup) .action(() -> { - final PluginBase plugin = (PluginBase) MainApp.getConfigBuilder().getActivePump(); + final PluginBase plugin = (PluginBase) ConfigBuilderPlugin.getPlugin().getActivePump(); PasswordProtection.QueryPassword(activity, R.string.settings_password, "settings_password", () -> { Intent i = new Intent(activity, PreferencesActivity.class); i.putExtra("id", plugin.getPreferencesId()); activity.startActivity(i); }, null); }) - .visibility(() -> ((PluginBase) MainApp.getConfigBuilder().getActivePump()).getPreferencesId() > 0)) + .visibility(() -> ((PluginBase) ConfigBuilderPlugin.getPlugin().getActivePump()).getPreferencesId() > 0)) .add(new SWButton() .text(R.string.readstatus) - .action(() -> ConfigBuilderPlugin.getCommandQueue().readStatus("Clicked connect to pump", null)) - .visibility(() -> MainApp.getConfigBuilder().getActivePump() != null)) + .action(() -> ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("Clicked connect to pump", null)) + .visibility(() -> ConfigBuilderPlugin.getPlugin().getActivePump() != null)) .add(new SWEventListener(this) .listener(new Object() { @Subscribe @@ -341,7 +337,7 @@ public class SWDefinition { } }) ) - .validator(() -> MainApp.getConfigBuilder().getActivePump() != null && MainApp.getConfigBuilder().getActivePump().isInitialized()) + .validator(() -> ConfigBuilderPlugin.getPlugin().getActivePump() != null && ConfigBuilderPlugin.getPlugin().getActivePump().isInitialized()) ) .add(new SWScreen(R.string.configbuilder_aps) .skippable(false) @@ -352,20 +348,29 @@ public class SWDefinition { .label("https://openaps.readthedocs.io/en/latest/")) .add(new SWBreak()) .add(new SWPlugin() - .option(PluginType.APS) + .option(PluginType.APS, R.string.configbuilder_aps_description) .label(R.string.configbuilder_aps)) .add(new SWButton() .text(R.string.apssetup) .action(() -> { - final PluginBase plugin = (PluginBase) MainApp.getConfigBuilder().getActiveAPS(); + final PluginBase plugin = (PluginBase) ConfigBuilderPlugin.getPlugin().getActiveAPS(); PasswordProtection.QueryPassword(activity, R.string.settings_password, "settings_password", () -> { Intent i = new Intent(activity, PreferencesActivity.class); i.putExtra("id", plugin.getPreferencesId()); activity.startActivity(i); }, null); }) - .visibility(() -> MainApp.getConfigBuilder().getActiveAPS() != null && ((PluginBase) MainApp.getConfigBuilder().getActiveAPS()).getPreferencesId() > 0)) - .validator(() -> MainApp.getConfigBuilder().getActiveAPS() != null) + .visibility(() -> ConfigBuilderPlugin.getPlugin().getActiveAPS() != null && ((PluginBase) ConfigBuilderPlugin.getPlugin().getActiveAPS()).getPreferencesId() > 0)) + .validator(() -> ConfigBuilderPlugin.getPlugin().getActiveAPS() != null) + .visibility(() -> Config.APS) + ) + .add(new SWScreen(R.string.apsmode_title) + .skippable(false) + .add(new SWRadioButton() + .option(R.array.aps_modeArray, R.array.aps_modeValues) + .preferenceId(R.string.key_aps_mode).label(R.string.apsmode_title) + .comment(R.string.setupwizard_preferred_aps_mode)) + .validator(() -> SP.contains(R.string.key_aps_mode)) ) .add(new SWScreen(R.string.configbuilder_loop) .skippable(false) @@ -384,7 +389,7 @@ public class SWDefinition { }) .visibility(() -> !LoopPlugin.getPlugin().isEnabled(PluginType.LOOP))) .validator(() -> LoopPlugin.getPlugin().isEnabled(PluginType.LOOP)) - .visibility(() -> !LoopPlugin.getPlugin().isEnabled(PluginType.LOOP)) + .visibility(() -> !LoopPlugin.getPlugin().isEnabled(PluginType.LOOP) && Config.APS) ) .add(new SWScreen(R.string.configbuilder_sensitivity) .skippable(false) @@ -394,21 +399,21 @@ public class SWDefinition { .label(R.string.setupwizard_sensitivity_url)) .add(new SWBreak()) .add(new SWPlugin() - .option(PluginType.SENSITIVITY) + .option(PluginType.SENSITIVITY, R.string.configbuilder_sensitivity_description) .label(R.string.configbuilder_sensitivity)) .add(new SWBreak()) .add(new SWButton() .text(R.string.sensitivitysetup) .action(() -> { - final PluginBase plugin = (PluginBase) MainApp.getConfigBuilder().getActiveSensitivity(); + final PluginBase plugin = (PluginBase) ConfigBuilderPlugin.getPlugin().getActiveSensitivity(); PasswordProtection.QueryPassword(activity, R.string.settings_password, "settings_password", () -> { Intent i = new Intent(activity, PreferencesActivity.class); i.putExtra("id", plugin.getPreferencesId()); activity.startActivity(i); }, null); }) - .visibility(() -> MainApp.getConfigBuilder().getActiveSensitivity() != null && ((PluginBase) MainApp.getConfigBuilder().getActiveSensitivity()).getPreferencesId() > 0)) - .validator(() -> MainApp.getConfigBuilder().getActiveSensitivity() != null) + .visibility(() -> ConfigBuilderPlugin.getPlugin().getActiveSensitivity() != null && ((PluginBase) ConfigBuilderPlugin.getPlugin().getActiveSensitivity()).getPreferencesId() > 0)) + .validator(() -> ConfigBuilderPlugin.getPlugin().getActiveSensitivity() != null) ) .add(new SWScreen(R.string.objectives) .skippable(false) @@ -426,18 +431,207 @@ public class SWDefinition { }) .visibility(() -> !ObjectivesPlugin.getPlugin().isFragmentVisible())) .validator(() -> ObjectivesPlugin.getPlugin().isEnabled(PluginType.CONSTRAINTS)) - .visibility(() -> !ObjectivesPlugin.getPlugin().isFragmentVisible()) + .visibility(() -> !ObjectivesPlugin.getPlugin().isFragmentVisible() && Config.APS) ) .add(new SWScreen(R.string.objectives) - .skippable(false) - .add(new SWInfotext() - .label(R.string.startobjective)) - .add(new SWBreak()) - .add(new SWFragment(this) - .add(new ObjectivesFragment())) - .validator(() -> ObjectivesPlugin.getPlugin().objectives.get(0).isStarted()) - .visibility(() -> !ObjectivesPlugin.getPlugin().objectives.get(0).isStarted()) + .skippable(false) + .add(new SWInfotext() + .label(R.string.startobjective)) + .add(new SWBreak()) + .add(new SWFragment(this) + .add(new ObjectivesFragment())) + .validator(() -> ObjectivesPlugin.getPlugin().objectives.get(0).isStarted()) + .visibility(() -> !ObjectivesPlugin.getPlugin().objectives.get(0).isStarted() && Config.APS) + ) + ; + } + + private void SWDefinitionNSClient() { + // List all the screens here + add(new SWScreen(R.string.nav_setupwizard) + .add(new SWInfotext() + .label(R.string.welcometosetupwizard)) + ) + .add(new SWScreen(R.string.language) + .skippable(false) + .add(new SWRadioButton() + .option(R.array.languagesArray, R.array.languagesValues) + .preferenceId(R.string.key_language).label(R.string.language) + .comment(R.string.setupwizard_language_prompt)) + .validator(() -> { + String lang = SP.getString("language", "en"); + LocaleHelper.setLocale(MainApp.instance().getApplicationContext(), lang); + return SP.contains(R.string.key_language); + }) + ) + .add(new SWScreen(R.string.end_user_license_agreement) + .skippable(false) + .add(new SWInfotext() + .label(R.string.end_user_license_agreement_text)) + .add(new SWBreak()) + .add(new SWButton() + .text(R.string.end_user_license_agreement_i_understand) + .visibility(() -> !SP.getBoolean(R.string.key_i_understand, false)) + .action(() -> { + SP.putBoolean(R.string.key_i_understand, true); + MainApp.bus().post(new EventSWUpdate(false)); + })) + .visibility(() -> !SP.getBoolean(R.string.key_i_understand, false)) + .validator(() -> SP.getBoolean(R.string.key_i_understand, false)) + ) + .add(new SWScreen(R.string.permission) + .skippable(false) + .add(new SWInfotext() + .label(String.format(MainApp.gs(R.string.needwhitelisting), MainApp.gs(R.string.app_name)))) + .add(new SWBreak()) + .add(new SWButton() + .text(R.string.askforpermission) + .visibility(() -> Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !AndroidPermission.checkForPermission(getActivity(), Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)) + .action(() -> AndroidPermission.askForPermission(getActivity(), Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, AndroidPermission.CASE_BATTERY))) + .visibility(() -> Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !AndroidPermission.checkForPermission(getActivity(), Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)) + .validator(() -> !(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !AndroidPermission.checkForPermission(getActivity(), Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS))) + ) + .add(new SWScreen(R.string.permission) + .skippable(false) + .add(new SWInfotext() + .label(MainApp.gs(R.string.needstoragepermission))) + .add(new SWBreak()) + .add(new SWButton() + .text(R.string.askforpermission) + .visibility(() -> Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !AndroidPermission.checkForPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE)) + .action(() -> AndroidPermission.askForPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE, AndroidPermission.CASE_STORAGE))) + .visibility(() -> Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !AndroidPermission.checkForPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE)) + .validator(() -> !(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !AndroidPermission.checkForPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE))) + ) + .add(new SWScreen(R.string.nav_import) + .add(new SWInfotext() + .label(R.string.storedsettingsfound)) + .add(new SWBreak()) + .add(new SWButton() + .text(R.string.nav_import) + .action(() -> ImportExportPrefs.importSharedPreferences(getActivity()))) + .visibility(() -> ImportExportPrefs.file.exists() && !(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !AndroidPermission.checkForPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE))) + ) + .add(new SWScreen(R.string.nsclientinternal_title) + .skippable(true) + .add(new SWInfotext() + .label(R.string.nsclientinfotext)) + .add(new SWBreak()) + .add(new SWButton() + .text(R.string.enable_nsclient) + .action(() -> { + NSClientPlugin.getPlugin().setPluginEnabled(PluginType.GENERAL, true); + NSClientPlugin.getPlugin().setFragmentVisible(PluginType.GENERAL, true); + ConfigBuilderFragment.processOnEnabledCategoryChanged(NSClientPlugin.getPlugin(), PluginType.GENERAL); + ConfigBuilderPlugin.getPlugin().storeSettings("SetupWizard"); + MainApp.bus().post(new EventConfigBuilderChange()); + MainApp.bus().post(new EventSWUpdate(true)); + }) + .visibility(() -> !NSClientPlugin.getPlugin().isEnabled(PluginType.GENERAL))) + .add(new SWEditUrl() + .preferenceId(R.string.key_nsclientinternal_url) + .updateDelay(5) + .label(R.string.nsclientinternal_url_title) + .comment(R.string.nsclientinternal_url_dialogmessage)) + .add(new SWEditString() + .validator(text -> text.length() >= 12) + .updateDelay(5) + .preferenceId(R.string.key_nsclientinternal_api_secret) + .label(R.string.nsclientinternal_secret_dialogtitle) + .comment(R.string.nsclientinternal_secret_dialogmessage)) + .add(new SWBreak()) + .add(new SWEventListener(this) + .label(R.string.status) + .initialStatus(NSClientPlugin.getPlugin().status) + .listener(new Object() { + @Subscribe + public void onEventNSClientStatus(EventNSClientStatus event) { + MainApp.bus().post(new EventSWLabel(event.status)); + } + }) ) + .add(new SWBreak()) + .validator(() -> NSClientPlugin.getPlugin().nsClientService != null && NSClientPlugin.getPlugin().nsClientService.isConnected && NSClientPlugin.getPlugin().nsClientService.hasWriteAuth) + .visibility(() -> !(NSClientPlugin.getPlugin().nsClientService != null && NSClientPlugin.getPlugin().nsClientService.isConnected && NSClientPlugin.getPlugin().nsClientService.hasWriteAuth)) + ) + .add(new SWScreen(R.string.configbuilder_bgsource) + .skippable(false) + .add(new SWPlugin() + .option(PluginType.BGSOURCE, R.string.configbuilder_bgsource_description) + .label(R.string.configbuilder_bgsource)) + .add(new SWBreak()) + .add(new SWButton() + .text(R.string.bgsourcesetup) + .action(() -> { + final PluginBase plugin = (PluginBase) ConfigBuilderPlugin.getPlugin().getActiveBgSource(); + PasswordProtection.QueryPassword(activity, R.string.settings_password, "settings_password", () -> { + Intent i = new Intent(activity, PreferencesActivity.class); + i.putExtra("id", plugin.getPreferencesId()); + activity.startActivity(i); + }, null); + }) + .visibility(() -> ConfigBuilderPlugin.getPlugin().getActiveBgSource()!= null && ((PluginBase) ConfigBuilderPlugin.getPlugin().getActiveBgSource()).getPreferencesId() > 0)) + .validator(() -> ConfigBuilderPlugin.getPlugin().getActiveBgSource() != null) + ) + .add(new SWScreen(R.string.patientage) + .skippable(false) + .add(new SWInfotext() + .label(R.string.patientage_summary)) + .add(new SWBreak()) + .add(new SWRadioButton() + .option(R.array.ageArray, R.array.ageValues) + .preferenceId(R.string.key_age) + .label(R.string.patientage) + .comment(R.string.patientage_summary)) + .validator(() -> SP.contains(R.string.key_age)) + ) + .add(new SWScreen(R.string.configbuilder_insulin) + .skippable(false) + .add(new SWPlugin() + .option(PluginType.INSULIN, R.string.configbuilder_insulin_description) + .makeVisible(false) + .label(R.string.configbuilder_insulin)) + .add(new SWBreak()) + .add(new SWInfotext() + .label(R.string.diawarning)) + .add(new SWBreak()) + .add(new SWButton() + .text(R.string.insulinsourcesetup) + .action(() -> { + final PluginBase plugin = (PluginBase) ConfigBuilderPlugin.getPlugin().getActiveInsulin(); + PasswordProtection.QueryPassword(activity, R.string.settings_password, "settings_password", () -> { + Intent i = new Intent(activity, PreferencesActivity.class); + i.putExtra("id", plugin.getPreferencesId()); + activity.startActivity(i); + }, null); + }) + .visibility(() -> ConfigBuilderPlugin.getPlugin().getActiveInsulin()!= null && ((PluginBase) ConfigBuilderPlugin.getPlugin().getActiveInsulin()).getPreferencesId() > 0)) + .validator(() -> ConfigBuilderPlugin.getPlugin().getActiveInsulin() != null) + ) + .add(new SWScreen(R.string.configbuilder_sensitivity) + .skippable(false) + .add(new SWInfotext() + .label(R.string.setupwizard_sensitivity_description)) + .add(new SWHtmlLink() + .label(R.string.setupwizard_sensitivity_url)) + .add(new SWBreak()) + .add(new SWPlugin() + .option(PluginType.SENSITIVITY, R.string.configbuilder_sensitivity_description) + .label(R.string.configbuilder_sensitivity)) + .add(new SWBreak()) + .add(new SWButton() + .text(R.string.sensitivitysetup) + .action(() -> { + final PluginBase plugin = (PluginBase) ConfigBuilderPlugin.getPlugin().getActiveSensitivity(); + PasswordProtection.QueryPassword(activity, R.string.settings_password, "settings_password", () -> { + Intent i = new Intent(activity, PreferencesActivity.class); + i.putExtra("id", plugin.getPreferencesId()); + activity.startActivity(i); + }, null); + }) + .visibility(() -> ConfigBuilderPlugin.getPlugin().getActiveSensitivity() != null && ((PluginBase) ConfigBuilderPlugin.getPlugin().getActiveSensitivity()).getPreferencesId() > 0)) + .validator(() -> ConfigBuilderPlugin.getPlugin().getActiveSensitivity() != null) + ) ; } diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/SWEventListener.java b/app/src/main/java/info/nightscout/androidaps/setupwizard/SWEventListener.java index 40979a3efd..487a80d91c 100644 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/SWEventListener.java +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/SWEventListener.java @@ -46,11 +46,11 @@ public class SWEventListener extends SWItem { } @Override - public void generateDialog(View view, LinearLayout layout) { - Context context = view.getContext(); + public void generateDialog(LinearLayout layout) { + Context context = layout.getContext(); textView = new TextView(context); - textView.setId(view.generateViewId()); + textView.setId(layout.generateViewId()); textView.setText((textLabel != 0 ? MainApp.gs(textLabel) : "") + " " + status); layout.addView(textView); if (listener != null) diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/SetupWizardActivity.java b/app/src/main/java/info/nightscout/androidaps/setupwizard/SetupWizardActivity.java index 523970d6df..5102e36ac6 100644 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/SetupWizardActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/SetupWizardActivity.java @@ -129,7 +129,7 @@ public class SetupWizardActivity extends AppCompatActivity { LinearLayout layout = SWItem.generateLayout(this.findViewById(R.id.sw_content_fields)); for (int i = 0; i < currentScreen.items.size(); i++) { SWItem currentItem = currentScreen.items.get(i); - currentItem.generateDialog(this.findViewById(R.id.sw_content_fields), layout); + currentItem.generateDialog(layout); } scrollView.smoothScrollTo(0,0); } diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWBreak.java b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWBreak.java index f513cccf4e..c6a9cf3f86 100644 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWBreak.java +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWBreak.java @@ -27,8 +27,8 @@ public class SWBreak extends SWItem { } @Override - public void generateDialog(View view, LinearLayout layout) { - Context context = view.getContext(); + public void generateDialog(LinearLayout layout) { + Context context = layout.getContext(); l = new TextView(context); l.setId(View.generateViewId()); diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWButton.java b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWButton.java index 4f22720091..afa28c1803 100644 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWButton.java +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWButton.java @@ -39,8 +39,8 @@ public class SWButton extends SWItem { } @Override - public void generateDialog(View view, LinearLayout layout) { - Context context = view.getContext(); + public void generateDialog(LinearLayout layout) { + Context context = layout.getContext(); button = new Button(context); button.setText(buttonText); @@ -50,7 +50,7 @@ public class SWButton extends SWItem { }); processVisibility(); layout.addView(button); - super.generateDialog(view, layout); + super.generateDialog(layout); } @Override diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWCheckbox.java b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWCheckbox.java index 816fb79a97..ed96b37944 100644 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWCheckbox.java +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWCheckbox.java @@ -40,8 +40,8 @@ public class SWCheckbox extends SWItem { } @Override - public void generateDialog(View view, LinearLayout layout) { - Context context = view.getContext(); + public void generateDialog(LinearLayout layout) { + Context context = layout.getContext(); // Get if there is already value in SP Boolean previousValue; previousValue = SP.getBoolean(preferenceId, false); @@ -68,7 +68,7 @@ public class SWCheckbox extends SWItem { } }); layout.addView(checkBox); - super.generateDialog(view, layout); + super.generateDialog(layout); } public void save(boolean value){ SP.putBoolean(preferenceID, value); diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWEditString.java b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWEditString.java index b464ae6316..1f32e6622d 100644 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWEditString.java +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWEditString.java @@ -21,34 +21,35 @@ public class SWEditString extends SWItem { private static Logger log = LoggerFactory.getLogger(SWEditString.class); private SWTextValidator validator = null; + private int updateDelay = 0; public SWEditString() { super(Type.STRING); } @Override - public void generateDialog(View view, LinearLayout layout) { - Context context = view.getContext(); + public void generateDialog(LinearLayout layout) { + Context context = layout.getContext(); TextView l = new TextView(context); - l.setId(view.generateViewId()); + l.setId(layout.generateViewId()); l.setText(label); l.setTypeface(l.getTypeface(), Typeface.BOLD); layout.addView(l); TextView c = new TextView(context); - c.setId(view.generateViewId()); + c.setId(layout.generateViewId()); c.setText(comment); c.setTypeface(c.getTypeface(), Typeface.ITALIC); layout.addView(c); EditText editText = new EditText(context); - editText.setId(view.generateViewId()); + editText.setId(layout.generateViewId()); editText.setInputType(InputType.TYPE_CLASS_TEXT); editText.setMaxLines(1); editText.setText(SP.getString(preferenceId, "")); layout.addView(editText); - super.generateDialog(view, layout); + super.generateDialog(layout); editText.addTextChangedListener(new TextWatcher() { @Override @@ -58,7 +59,7 @@ public class SWEditString extends SWItem { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { if (validator != null && validator.isValid(s.toString())) - save(s.toString()); + save(s.toString(), updateDelay); } @Override @@ -76,4 +77,9 @@ public class SWEditString extends SWItem { this.validator = validator; return this; } + + public SWEditString updateDelay(int updateDelay) { + this.updateDelay = updateDelay; + return this; + } } diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWEditUrl.java b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWEditUrl.java index 6039577bff..254723e4e1 100644 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWEditUrl.java +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWEditUrl.java @@ -22,13 +22,15 @@ import info.nightscout.utils.SP; public class SWEditUrl extends SWItem { private static Logger log = LoggerFactory.getLogger(SWEditUrl.class); + private int updateDelay = 0; + public SWEditUrl() { super(Type.URL); } @Override - public void generateDialog(View view, LinearLayout layout) { - Context context = view.getContext(); + public void generateDialog(LinearLayout layout) { + Context context = layout.getContext(); TextView l = new TextView(context); l.setId(View.generateViewId()); @@ -48,7 +50,7 @@ public class SWEditUrl extends SWItem { editText.setMaxLines(1); editText.setText(SP.getString(preferenceId, "")); layout.addView(editText); - super.generateDialog(view, layout); + super.generateDialog(layout); editText.addTextChangedListener(new TextWatcher() { @Override @@ -58,7 +60,7 @@ public class SWEditUrl extends SWItem { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { if (Patterns.WEB_URL.matcher(s).matches()) - save(s.toString()); + save(s.toString(), updateDelay); else MainApp.bus().post(new EventSWLabel(MainApp.gs(R.string.error_url_not_valid))); } @@ -74,4 +76,9 @@ public class SWEditUrl extends SWItem { return this; } + public SWEditUrl updateDelay(int updateDelay) { + this.updateDelay = updateDelay; + return this; + } + } diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWFragment.java b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWFragment.java index 9e470fa687..a061f57eb6 100644 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWFragment.java @@ -27,7 +27,7 @@ public class SWFragment extends SWItem { } @Override - public void generateDialog(View view, LinearLayout layout) { + public void generateDialog(LinearLayout layout) { definition.getActivity().getSupportFragmentManager().beginTransaction().add(layout.getId(), fragment, fragment.getTag()).commit(); } diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWHtmlLink.java b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWHtmlLink.java index 1ee27be6ae..fd4ffdd524 100644 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWHtmlLink.java +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWHtmlLink.java @@ -39,8 +39,8 @@ public class SWHtmlLink extends SWItem { } @Override - public void generateDialog(View view, LinearLayout layout) { - Context context = view.getContext(); + public void generateDialog(LinearLayout layout) { + Context context = layout.getContext(); l = new TextView(context); l.setId(View.generateViewId()); diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWInfotext.java b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWInfotext.java index f98fbee82f..91e5c2da2d 100644 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWInfotext.java +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWInfotext.java @@ -38,8 +38,8 @@ public class SWInfotext extends SWItem { } @Override - public void generateDialog(View view, LinearLayout layout) { - Context context = view.getContext(); + public void generateDialog(LinearLayout layout) { + Context context = layout.getContext(); l = new TextView(context); l.setId(View.generateViewId()); diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWItem.java b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWItem.java index c82d4f5683..d9cfe3710d 100644 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWItem.java +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWItem.java @@ -6,14 +6,23 @@ import android.widget.LinearLayout; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.events.EventPreferenceChange; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.setupwizard.events.EventSWUpdate; import info.nightscout.utils.SP; public class SWItem { private static Logger log = LoggerFactory.getLogger(SWItem.class); + private static final ScheduledExecutorService eventWorker = Executors.newSingleThreadScheduledExecutor(); + private static ScheduledFuture scheduledEventPost = null; + public enum Type { NONE, TEXT, @@ -66,10 +75,9 @@ public class SWItem { return this; } - public void save(String value) { + public void save(String value, int updateDelay) { SP.putString(preferenceId, value); - MainApp.bus().post(new EventPreferenceChange(preferenceId)); - MainApp.bus().post(new EventSWUpdate()); + scheduleChange(updateDelay); } public static LinearLayout generateLayout(View view) { @@ -78,9 +86,27 @@ public class SWItem { return layout; } - public void generateDialog(View view, LinearLayout layout) { + public void generateDialog(LinearLayout layout) { } public void processVisibility() { } + + private void scheduleChange(int updateDelay) { + class PostRunnable implements Runnable { + public void run() { + if (L.isEnabled(L.CORE)) + log.debug("Firing EventPreferenceChange"); + MainApp.bus().post(new EventPreferenceChange(preferenceId)); + MainApp.bus().post(new EventSWUpdate()); + scheduledEventPost = null; + } + } + // cancel waiting task to prevent sending multiple posts + if (scheduledEventPost != null) + scheduledEventPost.cancel(false); + Runnable task = new PostRunnable(); + final int sec = updateDelay; + scheduledEventPost = eventWorker.schedule(task, sec, TimeUnit.SECONDS); + } } diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWPlugin.java b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWPlugin.java index b9519bc9b5..80f60eb678 100644 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWPlugin.java @@ -2,9 +2,11 @@ package info.nightscout.androidaps.setupwizard.elements; import android.content.Context; import android.view.View; +import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.RadioButton; import android.widget.RadioGroup; +import android.widget.TextView; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -24,19 +26,29 @@ public class SWPlugin extends SWItem { private PluginType pType; private RadioGroup radioGroup; + private int pluginDescription; + + private boolean makeVisible = true; public SWPlugin() { super(Type.PLUGIN); } - public SWPlugin option(PluginType pType) { + public SWPlugin option(PluginType pType, int pluginDescription) { this.pType = pType; + this.pluginDescription = pluginDescription; + return this; + } + + public SWPlugin makeVisible(boolean makeVisible) { + this.makeVisible = makeVisible; return this; } @Override - public void generateDialog(View view, LinearLayout layout) { - Context context = view.getContext(); + public void generateDialog(LinearLayout layout) { + + Context context = layout.getContext(); radioGroup = new RadioGroup(context); radioGroup.clearCheck(); @@ -45,6 +57,13 @@ public class SWPlugin extends SWItem { radioGroup.setOrientation(LinearLayout.VERTICAL); radioGroup.setVisibility(View.VISIBLE); + TextView pdesc = new TextView(context); + pdesc.setText(pluginDescription); + LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); + params.setMargins(0, 0, 0, 40); + pdesc.setLayoutParams(params); + layout.addView(pdesc); + for (int i = 0; i < pluginsInCategory.size(); i++) { RadioButton rdbtn = new RadioButton(context); PluginBase p = pluginsInCategory.get(i); @@ -54,19 +73,25 @@ public class SWPlugin extends SWItem { rdbtn.setChecked(true); rdbtn.setTag(p); radioGroup.addView(rdbtn); + params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); + params.setMargins(80, 0, 0, 0); + TextView desc = new TextView(context); + desc.setText(p.getDescription()); + desc.setLayoutParams(params); + radioGroup.addView(desc); } radioGroup.setOnCheckedChangeListener((group, checkedId) -> { RadioButton rb = group.findViewById(checkedId); - PluginBase plugin1 = (PluginBase) rb.getTag(); - plugin1.setPluginEnabled(pType, rb.isChecked()); - plugin1.setFragmentVisible(pType, rb.isChecked()); - ConfigBuilderFragment.processOnEnabledCategoryChanged(plugin1, pType); + PluginBase plugin = (PluginBase) rb.getTag(); + plugin.setPluginEnabled(pType, rb.isChecked()); + plugin.setFragmentVisible(pType, rb.isChecked() && makeVisible); + ConfigBuilderFragment.processOnEnabledCategoryChanged(plugin, pType); ConfigBuilderPlugin.getPlugin().storeSettings("SetupWizard"); MainApp.bus().post(new EventConfigBuilderChange()); MainApp.bus().post(new EventSWUpdate()); }); layout.addView(radioGroup); - super.generateDialog(view, layout); + super.generateDialog(layout); } } diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWRadioButton.java b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWRadioButton.java index e034e86ba8..cf7dbd55fe 100644 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWRadioButton.java +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/elements/SWRadioButton.java @@ -2,9 +2,11 @@ package info.nightscout.androidaps.setupwizard.elements; import android.content.Context; import android.view.View; +import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.RadioButton; import android.widget.RadioGroup; +import android.widget.TextView; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,8 +40,16 @@ public class SWRadioButton extends SWItem { } @Override - public void generateDialog(View view, LinearLayout layout) { - Context context = view.getContext(); + public void generateDialog(LinearLayout layout) { + Context context = layout.getContext(); + + TextView pdesc = new TextView(context); + pdesc.setText(getComment()); + LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); + params.setMargins(0, 0, 0, 40); + pdesc.setLayoutParams(params); + layout.addView(pdesc); + // Get if there is already value in SP String previousValue = SP.getString(preferenceId, "none"); radioGroup = new RadioGroup(context); @@ -59,10 +69,11 @@ public class SWRadioButton extends SWItem { radioGroup.setOnCheckedChangeListener((group, checkedId) -> { int i = (int) group.findViewById(checkedId).getTag(); - save(values()[i]); + save(values()[i], 0); }); layout.addView(radioGroup); - super.generateDialog(view, layout); + + super.generateDialog(layout); } public SWRadioButton preferenceId(int preferenceId) { diff --git a/app/src/main/java/info/nightscout/androidaps/tabs/SlidingTabLayout.java b/app/src/main/java/info/nightscout/androidaps/tabs/SlidingTabLayout.java deleted file mode 100644 index 80424a04f7..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/tabs/SlidingTabLayout.java +++ /dev/null @@ -1,322 +0,0 @@ -package info.nightscout.androidaps.tabs;/* - * Copyright 2014 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import android.content.Context; -import android.graphics.Typeface; -import android.support.v4.view.PagerAdapter; -import android.support.v4.view.ViewPager; -import android.util.AttributeSet; -import android.util.SparseArray; -import android.util.TypedValue; -import android.view.Gravity; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.HorizontalScrollView; -import android.widget.LinearLayout; -import android.widget.TextView; - -import info.nightscout.androidaps.R; - -/** - * To be used with ViewPager to provide a tab indicator component which give constant feedback as to - * the user's scroll progress. - *

- * To use the component, simply add it to your view hierarchy. Then in your - * {@link android.app.Activity} or {@link android.support.v4.app.Fragment} call - * {@link #setViewPager(ViewPager)} providing it the ViewPager this layout is being used for. - *

- * The colors can be customized in two ways. The first and simplest is to provide an array of colors - * via {@link #setSelectedIndicatorColors(int...)}. The - * alternative is via the {@link TabColorizer} interface which provides you complete control over - * which color is used for any individual position. - *

- * The views used as tabs can be customized by calling {@link #setCustomTabView(int, int)}, - * providing the layout ID of your custom layout. - */ -public class SlidingTabLayout extends HorizontalScrollView { - /** - * Allows complete control over the colors drawn in the tab layout. Set with - * {@link #setCustomTabColorizer(TabColorizer)}. - */ - public interface TabColorizer { - - /** - * @return return the color of the indicator used when {@code position} is selected. - */ - int getIndicatorColor(int position); - - } - - private static final int TITLE_OFFSET_DIPS = 24; - private static final int TAB_VIEW_PADDING_DIPS = 9; - private static final int TAB_VIEW_TEXT_SIZE_SP = 12; - - private int mTitleOffset; - - private int mTabViewLayoutId; - private int mTabViewTextViewId; - private boolean mDistributeEvenly; - - private ViewPager mViewPager; - private SparseArray mContentDescriptions = new SparseArray(); - private ViewPager.OnPageChangeListener mViewPagerPageChangeListener; - - private final SlidingTabStrip mTabStrip; - - public SlidingTabLayout(Context context) { - this(context, null); - } - - public SlidingTabLayout(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public SlidingTabLayout(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - - // Disable the Scroll Bar - setHorizontalScrollBarEnabled(false); - // Make sure that the Tab Strips fills this View - setFillViewport(true); - - mTitleOffset = (int) (TITLE_OFFSET_DIPS * getResources().getDisplayMetrics().density); - - mTabStrip = new SlidingTabStrip(context); - addView(mTabStrip, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); - setBackgroundColor(context.getResources().getColor(R.color.tabBgColor)); - } - - /** - * Set the custom {@link TabColorizer} to be used. - * - * If you only require simple custmisation then you can use - * {@link #setSelectedIndicatorColors(int...)} to achieve - * similar effects. - */ - public void setCustomTabColorizer(TabColorizer tabColorizer) { - mTabStrip.setCustomTabColorizer(tabColorizer); - } - - public void setDistributeEvenly(boolean distributeEvenly) { - mDistributeEvenly = distributeEvenly; - } - - /** - * Sets the colors to be used for indicating the selected tab. These colors are treated as a - * circular array. Providing one color will mean that all tabs are indicated with the same color. - */ - public void setSelectedIndicatorColors(int... colors) { - mTabStrip.setSelectedIndicatorColors(colors); - } - - /** - * Set the {@link ViewPager.OnPageChangeListener}. When using {@link SlidingTabLayout} you are - * required to set any {@link ViewPager.OnPageChangeListener} through this method. This is so - * that the layout can update it's scroll position correctly. - * - * @see ViewPager#setOnPageChangeListener(ViewPager.OnPageChangeListener) - */ - public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) { - mViewPagerPageChangeListener = listener; - } - - /** - * Set the custom layout to be inflated for the tab views. - * - * @param layoutResId Layout id to be inflated - * @param textViewId id of the {@link TextView} in the inflated view - */ - public void setCustomTabView(int layoutResId, int textViewId) { - mTabViewLayoutId = layoutResId; - mTabViewTextViewId = textViewId; - } - - /** - * Sets the associated view pager. Note that the assumption here is that the pager content - * (number of tabs and tab titles) does not change after this call has been made. - */ - public void setViewPager(ViewPager viewPager) { - mTabStrip.removeAllViews(); - - mViewPager = viewPager; - if (viewPager != null) { - viewPager.setOnPageChangeListener(new InternalViewPagerListener()); - populateTabStrip(); - } - } - - /** - * Create a default view to be used for tabs. This is called if a custom tab view is not set via - * {@link #setCustomTabView(int, int)}. - */ - protected TextView createDefaultTabView(Context context) { - TextView textView = new TextView(context); - textView.setGravity(Gravity.CENTER); - textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, TAB_VIEW_TEXT_SIZE_SP); - textView.setTypeface(Typeface.DEFAULT_BOLD); - textView.setLayoutParams(new LinearLayout.LayoutParams( - ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); - - TypedValue outValue = new TypedValue(); - getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground, - outValue, true); - textView.setBackgroundResource(outValue.resourceId); - textView.setAllCaps(true); - - int padding = (int) (TAB_VIEW_PADDING_DIPS * getResources().getDisplayMetrics().density); - textView.setPadding(padding, padding, padding, padding); - - return textView; - } - - private void populateTabStrip() { - final PagerAdapter adapter = mViewPager.getAdapter(); - final View.OnClickListener tabClickListener = new TabClickListener(); - - for (int i = 0; i < adapter.getCount(); i++) { - View tabView = null; - TextView tabTitleView = null; - - if (mTabViewLayoutId != 0) { - // If there is a custom tab view layout id set, try and inflate it - tabView = LayoutInflater.from(getContext()).inflate(mTabViewLayoutId, mTabStrip, - false); - tabTitleView = (TextView) tabView.findViewById(mTabViewTextViewId); - } - - if (tabView == null) { - tabView = createDefaultTabView(getContext()); - } - - if (tabTitleView == null && TextView.class.isInstance(tabView)) { - tabTitleView = (TextView) tabView; - } - - if (mDistributeEvenly) { - LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) tabView.getLayoutParams(); - lp.width = 0; - lp.weight = 1; - } - - tabTitleView.setText(adapter.getPageTitle(i)); - tabView.setOnClickListener(tabClickListener); - String desc = mContentDescriptions.get(i, null); - if (desc != null) { - tabView.setContentDescription(desc); - } - - mTabStrip.addView(tabView); - if (i == mViewPager.getCurrentItem()) { - tabView.setSelected(true); - } - } - } - - public void setContentDescription(int i, String desc) { - mContentDescriptions.put(i, desc); - } - - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - - if (mViewPager != null) { - scrollToTab(mViewPager.getCurrentItem(), 0); - } - } - - private void scrollToTab(int tabIndex, int positionOffset) { - final int tabStripChildCount = mTabStrip.getChildCount(); - if (tabStripChildCount == 0 || tabIndex < 0 || tabIndex >= tabStripChildCount) { - return; - } - - View selectedChild = mTabStrip.getChildAt(tabIndex); - if (selectedChild != null) { - int targetScrollX = selectedChild.getLeft() + positionOffset; - - if (tabIndex > 0 || positionOffset > 0) { - // If we're not at the first child and are mid-scroll, make sure we obey the offset - targetScrollX -= mTitleOffset; - } - - scrollTo(targetScrollX, 0); - } - } - - private class InternalViewPagerListener implements ViewPager.OnPageChangeListener { - private int mScrollState; - - @Override - public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { - int tabStripChildCount = mTabStrip.getChildCount(); - if ((tabStripChildCount == 0) || (position < 0) || (position >= tabStripChildCount)) { - return; - } - - mTabStrip.onViewPagerPageChanged(position, positionOffset); - - View selectedTitle = mTabStrip.getChildAt(position); - int extraOffset = (selectedTitle != null) - ? (int) (positionOffset * selectedTitle.getWidth()) - : 0; - scrollToTab(position, extraOffset); - - if (mViewPagerPageChangeListener != null) { - mViewPagerPageChangeListener.onPageScrolled(position, positionOffset, - positionOffsetPixels); - } - } - - @Override - public void onPageScrollStateChanged(int state) { - mScrollState = state; - - if (mViewPagerPageChangeListener != null) { - mViewPagerPageChangeListener.onPageScrollStateChanged(state); - } - } - - @Override - public void onPageSelected(int position) { - if (mScrollState == ViewPager.SCROLL_STATE_IDLE) { - mTabStrip.onViewPagerPageChanged(position, 0f); - scrollToTab(position, 0); - } - for (int i = 0; i < mTabStrip.getChildCount(); i++) { - mTabStrip.getChildAt(i).setSelected(position == i); - } - if (mViewPagerPageChangeListener != null) { - mViewPagerPageChangeListener.onPageSelected(position); - } - } - - } - - private class TabClickListener implements View.OnClickListener { - @Override - public void onClick(View v) { - for (int i = 0; i < mTabStrip.getChildCount(); i++) { - if (v == mTabStrip.getChildAt(i)) { - mViewPager.setCurrentItem(i); - return; - } - } - } - } - -} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/tabs/SlidingTabStrip.java b/app/src/main/java/info/nightscout/androidaps/tabs/SlidingTabStrip.java deleted file mode 100644 index 6c8e034477..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/tabs/SlidingTabStrip.java +++ /dev/null @@ -1,165 +0,0 @@ -package info.nightscout.androidaps.tabs;/* - * Copyright 2014 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.util.AttributeSet; -import android.util.TypedValue; -import android.view.View; -import android.widget.LinearLayout; - -import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.R; - -class SlidingTabStrip extends LinearLayout { - - private static final int DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS = 0; - private static final byte DEFAULT_BOTTOM_BORDER_COLOR_ALPHA = 0x26; - private static final int SELECTED_INDICATOR_THICKNESS_DIPS = 3; - - private final int mBottomBorderThickness; - private final Paint mBottomBorderPaint; - - private final int mSelectedIndicatorThickness; - private final Paint mSelectedIndicatorPaint; - - private int mSelectedPosition; - private float mSelectionOffset; - - private SlidingTabLayout.TabColorizer mCustomTabColorizer; - private final SimpleTabColorizer mDefaultTabColorizer; - - SlidingTabStrip(Context context) { - this(context, null); - } - - SlidingTabStrip(Context context, AttributeSet attrs) { - super(context, attrs); - setWillNotDraw(false); - - final float density = getResources().getDisplayMetrics().density; - - TypedValue outValue = new TypedValue(); - context.getTheme().resolveAttribute(android.R.attr.colorForeground, outValue, true); - final int themeForegroundColor = outValue.data; - - int defaultBottomBorderColor = setColorAlpha(themeForegroundColor, - DEFAULT_BOTTOM_BORDER_COLOR_ALPHA); - - mDefaultTabColorizer = new SimpleTabColorizer(); - mDefaultTabColorizer.setIndicatorColors(MainApp.gc(R.color.tabBgColorSelected)); - - mBottomBorderThickness = (int) (DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS * density); - mBottomBorderPaint = new Paint(); - mBottomBorderPaint.setColor(defaultBottomBorderColor); - - mSelectedIndicatorThickness = (int) (SELECTED_INDICATOR_THICKNESS_DIPS * density); - mSelectedIndicatorPaint = new Paint(); - } - - void setCustomTabColorizer(SlidingTabLayout.TabColorizer customTabColorizer) { - mCustomTabColorizer = customTabColorizer; - invalidate(); - } - - void setSelectedIndicatorColors(int... colors) { - // Make sure that the custom colorizer is removed - mCustomTabColorizer = null; - mDefaultTabColorizer.setIndicatorColors(colors); - invalidate(); - } - - void onViewPagerPageChanged(int position, float positionOffset) { - mSelectedPosition = position; - mSelectionOffset = positionOffset; - invalidate(); - } - - @Override - protected void onDraw(Canvas canvas) { - final int height = getHeight(); - final int childCount = getChildCount(); - final SlidingTabLayout.TabColorizer tabColorizer = mCustomTabColorizer != null - ? mCustomTabColorizer - : mDefaultTabColorizer; - - // Thick colored underline below the current selection - if (childCount > 0) { - View selectedTitle = getChildAt(mSelectedPosition); - int left = selectedTitle.getLeft(); - int right = selectedTitle.getRight(); - int color = tabColorizer.getIndicatorColor(mSelectedPosition); - - if (mSelectionOffset > 0f && mSelectedPosition < (getChildCount() - 1)) { - int nextColor = tabColorizer.getIndicatorColor(mSelectedPosition + 1); - if (color != nextColor) { - color = blendColors(nextColor, color, mSelectionOffset); - } - - // Draw the selection partway between the tabs - View nextTitle = getChildAt(mSelectedPosition + 1); - left = (int) (mSelectionOffset * nextTitle.getLeft() + - (1.0f - mSelectionOffset) * left); - right = (int) (mSelectionOffset * nextTitle.getRight() + - (1.0f - mSelectionOffset) * right); - } - - mSelectedIndicatorPaint.setColor(color); - - canvas.drawRect(left, height - mSelectedIndicatorThickness, right, - height, mSelectedIndicatorPaint); - } - - // Thin underline along the entire bottom edge - canvas.drawRect(0, height - mBottomBorderThickness, getWidth(), height, mBottomBorderPaint); - } - - /** - * Set the alpha value of the {@code color} to be the given {@code alpha} value. - */ - private static int setColorAlpha(int color, byte alpha) { - return Color.argb(alpha, Color.red(color), Color.green(color), Color.blue(color)); - } - - /** - * Blend {@code color1} and {@code color2} using the given ratio. - * - * @param ratio of which to blend. 1.0 will return {@code color1}, 0.5 will give an even blend, - * 0.0 will return {@code color2}. - */ - private static int blendColors(int color1, int color2, float ratio) { - final float inverseRation = 1f - ratio; - float r = (Color.red(color1) * ratio) + (Color.red(color2) * inverseRation); - float g = (Color.green(color1) * ratio) + (Color.green(color2) * inverseRation); - float b = (Color.blue(color1) * ratio) + (Color.blue(color2) * inverseRation); - return Color.rgb((int) r, (int) g, (int) b); - } - - private static class SimpleTabColorizer implements SlidingTabLayout.TabColorizer { - private int[] mIndicatorColors; - - @Override - public final int getIndicatorColor(int position) { - return mIndicatorColors[position % mIndicatorColors.length]; - } - - void setIndicatorColors(int... colors) { - mIndicatorColors = colors; - } - } -} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/tabs/TabPageAdapter.java b/app/src/main/java/info/nightscout/androidaps/tabs/TabPageAdapter.java index 8397da97aa..88f7d48d32 100644 --- a/app/src/main/java/info/nightscout/androidaps/tabs/TabPageAdapter.java +++ b/app/src/main/java/info/nightscout/androidaps/tabs/TabPageAdapter.java @@ -1,12 +1,10 @@ package info.nightscout.androidaps.tabs; import android.content.Context; -import android.content.SharedPreferences; -import android.preference.PreferenceManager; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; -import android.support.v4.app.FragmentStatePagerAdapter; +import android.support.v4.app.FragmentPagerAdapter; import android.view.ViewGroup; import org.slf4j.Logger; @@ -14,18 +12,21 @@ import org.slf4j.LoggerFactory; import java.util.ArrayList; +import info.nightscout.androidaps.R; import info.nightscout.androidaps.interfaces.PluginBase; +import info.nightscout.androidaps.logging.L; +import info.nightscout.utils.SP; /** * Created by mike on 30.05.2016. */ -public class TabPageAdapter extends FragmentStatePagerAdapter { +public class TabPageAdapter extends FragmentPagerAdapter { ArrayList visibleFragmentList = new ArrayList<>(); Context context; - private static Logger log = LoggerFactory.getLogger(TabPageAdapter.class); + private static Logger log = LoggerFactory.getLogger(L.CORE); public TabPageAdapter(FragmentManager fm, Context context) { super(fm); @@ -39,21 +40,24 @@ public class TabPageAdapter extends FragmentStatePagerAdapter { return Fragment.instantiate(context, visibleFragmentList.get(position).pluginDescription.getFragmentClass()); } + public PluginBase getPluginAt(int position) { + return visibleFragmentList.get(position); + } + @Override public void finishUpdate(ViewGroup container) { - try{ + try { super.finishUpdate(container); - } catch (NullPointerException nullPointerException){ + } catch (NullPointerException nullPointerException) { System.out.println("Catch the NullPointerException in FragmentStatePagerAdapter.finishUpdate"); - } catch (IllegalStateException e){ - log.error(e.getMessage()); + } catch (IllegalStateException e) { + log.error("Unhandled exception", e); } } @Override public CharSequence getPageTitle(int position) { - SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); - if(preferences.getBoolean("short_tabtitles", false)){ + if (SP.getBoolean(R.string.key_short_tabtitles, false)) { return visibleFragmentList.get(position).getNameShort(); } return visibleFragmentList.get(position).getName(); @@ -72,5 +76,8 @@ public class TabPageAdapter extends FragmentStatePagerAdapter { } } - + @Override + public long getItemId(int position) { + return System.identityHashCode(visibleFragmentList.get(position)); + } } diff --git a/app/src/main/java/info/nightscout/utils/AndroidPermission.java b/app/src/main/java/info/nightscout/utils/AndroidPermission.java index ca3cac82f1..6759bf5c96 100644 --- a/app/src/main/java/info/nightscout/utils/AndroidPermission.java +++ b/app/src/main/java/info/nightscout/utils/AndroidPermission.java @@ -44,7 +44,7 @@ public class AndroidPermission { } public static synchronized void notifyForSMSPermissions(Activity activity) { - if (SP.getBoolean(R.string.smscommunicator_remotecommandsallowed, false)) { + if (SP.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)) { if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) { if (!checkForPermission(activity, Manifest.permission.RECEIVE_SMS)) { NotificationWithAction notification = new NotificationWithAction(Notification.PERMISSION_SMS, MainApp.gs(R.string.smscommunicator_missingsmspermission), Notification.URGENT); diff --git a/app/src/main/java/info/nightscout/utils/BolusWizard.java b/app/src/main/java/info/nightscout/utils/BolusWizard.java index 3563a8a55d..d20827ce9e 100644 --- a/app/src/main/java/info/nightscout/utils/BolusWizard.java +++ b/app/src/main/java/info/nightscout/utils/BolusWizard.java @@ -1,10 +1,14 @@ package info.nightscout.utils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import info.nightscout.androidaps.data.GlucoseStatus; import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.db.TempTarget; import info.nightscout.androidaps.interfaces.TreatmentsInterface; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; @@ -13,35 +17,38 @@ import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; */ public class BolusWizard { + private Logger log = LoggerFactory.getLogger(L.CORE); // Inputs private Profile specificProfile = null; private TempTarget tempTarget; public Integer carbs = 0; private Double bg = 0d; + private Double cob = 0d; private Double correction; + private Double percentageCorrection; private Boolean includeBolusIOB = true; private Boolean includeBasalIOB = true; public Boolean superBolus = false; private Boolean trend = false; // Intermediate - public Double sens = 0d; - public Double ic = 0d; + public double sens = 0d; + public double ic = 0d; public GlucoseStatus glucoseStatus; - public Double targetBGLow = 0d; - public Double targetBGHigh = 0d; - public Double bgDiff = 0d; + public double targetBGLow = 0d; + public double targetBGHigh = 0d; + public double bgDiff = 0d; - public Double insulinFromBG = 0d; - public Double insulinFromCarbs = 0d; - public Double insulingFromBolusIOB = 0d; - public Double insulingFromBasalsIOB = 0d; - public Double insulinFromCorrection = 0d; - public Double insulinFromSuperBolus = 0d; - public Double insulinFromCOB = 0d; - public Double insulinFromTrend = 0d; + public double insulinFromBG = 0d; + public double insulinFromCarbs = 0d; + public double insulingFromBolusIOB = 0d; + public double insulingFromBasalsIOB = 0d; + public double insulinFromCorrection = 0d; + public double insulinFromSuperBolus = 0d; + public double insulinFromCOB = 0d; + public double insulinFromTrend = 0d; // Result public Double calculatedTotalInsulin = 0d; @@ -57,7 +64,9 @@ public class BolusWizard { this.tempTarget = tempTarget; this.carbs = carbs; this.bg = bg; + this.cob = cob; this.correction = correction; + this.percentageCorrection = percentageCorrection; this.includeBolusIOB = includeBolusIOB; this.includeBasalIOB = includeBasalIOB; this.superBolus = superBolus; @@ -109,7 +118,7 @@ public class BolusWizard { if (superBolus) { insulinFromSuperBolus = specificProfile.getBasal(); long timeAfter1h = System.currentTimeMillis(); - timeAfter1h += 60L * 60 * 1000; + timeAfter1h += T.hours(1).msecs(); insulinFromSuperBolus += specificProfile.getBasal(timeAfter1h); } @@ -127,9 +136,48 @@ public class BolusWizard { calculatedTotalInsulin = 0d; } - double bolusStep = ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep; + double bolusStep = ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().bolusStep; calculatedTotalInsulin = Round.roundTo(calculatedTotalInsulin, bolusStep); + log.debug(log()); + return calculatedTotalInsulin; } + + public String log() { + StringBuilder sb = new StringBuilder(); + + sb.append("TempTarget=").append(tempTarget != null ? tempTarget.toString() : "null").append("; "); + sb.append("Carbs=").append(carbs != null ? carbs : null).append("; "); + sb.append("Bg=").append(bg).append("; "); + sb.append("Cob=").append(cob).append("; "); + sb.append("Correction=").append(correction).append("; "); + sb.append("PercentageCorrection=").append(percentageCorrection).append("; "); + sb.append("IncludeBolusIOB=").append(includeBolusIOB).append("; "); + sb.append("IncludeBasalIOB=").append(includeBasalIOB).append("; "); + sb.append("Superbolus=").append(superBolus).append("; "); + sb.append("Trend=").append(trend).append("; "); + sb.append("Profile=").append(specificProfile != null && specificProfile.getData() != null ? specificProfile.getData().toString() : "null").append("; "); + sb.append("\n"); + + sb.append("targetBGLow=").append(targetBGLow).append("; "); + sb.append("targetBGHigh=").append(targetBGHigh).append("; "); + sb.append("bgDiff=").append(bgDiff).append("; "); + sb.append("insulinFromBG=").append(insulinFromBG).append("; "); + sb.append("insulinFromCarbs=").append(insulinFromCarbs).append("; "); + sb.append("insulingFromBolusIOB=").append(insulingFromBolusIOB).append("; "); + sb.append("insulingFromBasalsIOB=").append(insulingFromBasalsIOB).append("; "); + sb.append("insulinFromCorrection=").append(insulinFromCorrection).append("; "); + sb.append("insulinFromSuperBolus=").append(insulinFromSuperBolus).append("; "); + sb.append("insulinFromCOB=").append(insulinFromCOB).append("; "); + sb.append("insulinFromTrend=").append(insulinFromTrend).append("; "); + sb.append("\n"); + + + sb.append("calculatedTotalInsulin=").append(calculatedTotalInsulin).append("; "); + sb.append("totalBeforePercentageAdjustment=").append(totalBeforePercentageAdjustment).append("; "); + sb.append("carbsEquivalent=").append(carbsEquivalent).append("; "); + + return sb.toString(); + } } diff --git a/app/src/main/java/info/nightscout/utils/DateUtil.java b/app/src/main/java/info/nightscout/utils/DateUtil.java index 441449e8ee..c5d5eed51c 100644 --- a/app/src/main/java/info/nightscout/utils/DateUtil.java +++ b/app/src/main/java/info/nightscout/utils/DateUtil.java @@ -97,27 +97,27 @@ public class DateUtil { } public static String dateString(Date date) { - //return DateUtils.formatDateTime(MainApp.instance(), date.getTime(), DateUtils.FORMAT_SHOW_DATE); this provide month name not number DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT); return df.format(date); } public static String dateString(long mills) { - //return DateUtils.formatDateTime(MainApp.instance(), mills, DateUtils.FORMAT_SHOW_DATE); this provide month name not number DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT); return df.format(mills); } public static String timeString(Date date) { - //return DateUtils.formatDateTime(MainApp.instance(), date.getTime(), DateUtils.FORMAT_SHOW_TIME); return new DateTime(date).toString(DateTimeFormat.shortTime()); } public static String timeString(long mills) { - //return DateUtils.formatDateTime(MainApp.instance(), mills, DateUtils.FORMAT_SHOW_TIME); return new DateTime(mills).toString(DateTimeFormat.shortTime()); } + public static String timeFullString(long mills) { + return new DateTime(mills).toString(DateTimeFormat.fullTime()); + } + public static String dateAndTimeString(Date date) { return dateString(date) + " " + timeString(date); } @@ -130,11 +130,20 @@ public class DateUtil { return dateString(mills) + " " + timeString(mills); } + public static String dateAndTimeFullString(long mills) { + return dateString(mills) + " " + timeFullString(mills); + } + public static String minAgo(long time) { int mins = (int) ((now() - time) / 1000 / 60); return MainApp.gs(R.string.minago, mins); } + public static String minAgoShort(long time) { + Integer mins = (int) ((time - now()) / 1000 / 60); + return (mins > 0 ? "+" : "") + mins.toString(); + } + public static String hourAgo(long time) { double hours = (now() - time) / 1000d / 60 / 60; return MainApp.gs(R.string.hoursago, hours); @@ -174,5 +183,4 @@ public class DateUtil { public static long roundDateToSec(long date) { return date - date % 1000; } - } diff --git a/app/src/main/java/info/nightscout/utils/DecimalFormatter.java b/app/src/main/java/info/nightscout/utils/DecimalFormatter.java index 0f7164b690..620e636843 100644 --- a/app/src/main/java/info/nightscout/utils/DecimalFormatter.java +++ b/app/src/main/java/info/nightscout/utils/DecimalFormatter.java @@ -46,13 +46,13 @@ public class DecimalFormatter { } public static String toPumpSupportedBolus(double value) { - return ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep <= 0.05 + return ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().bolusStep <= 0.051 ? to2Decimal(value) : to1Decimal(value); } public static DecimalFormat pumpSupportedBolusFormat() { - return ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep <= 0.05 + return ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().bolusStep <= 0.051 ? new DecimalFormat("0.00") : new DecimalFormat("0.0"); } diff --git a/app/src/main/java/info/nightscout/utils/FabricPrivacy.java b/app/src/main/java/info/nightscout/utils/FabricPrivacy.java index bd117ed5c3..572cd4dab4 100644 --- a/app/src/main/java/info/nightscout/utils/FabricPrivacy.java +++ b/app/src/main/java/info/nightscout/utils/FabricPrivacy.java @@ -4,13 +4,20 @@ import com.crashlytics.android.Crashlytics; import com.crashlytics.android.answers.Answers; import com.crashlytics.android.answers.CustomEvent; +import info.nightscout.androidaps.BuildConfig; +import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.interfaces.PluginBase; + +import java.util.Date; + /** * Created by jamorham on 21/02/2018. - * + *

* Some users do not wish to be tracked, Fabric Answers and Crashlytics do not provide an easy way * to disable them and make calls from a potentially invalid singleton reference. This wrapper * emulates the methods but ignores the request if the instance is null or invalid. - * */ public class FabricPrivacy { @@ -80,4 +87,54 @@ public class FabricPrivacy { } } + public static void uploadDailyStats() { + if (!fabricEnabled()) return; + + long lastUploadDay = SP.getLong(MainApp.gs(R.string.key_plugin_stats_report_timestamp), 0L); + + Date date = new Date(); + date.setHours(0); + date.setMinutes(0); + date.setSeconds(0); + long today = date.getTime() - date.getTime() % 1000; + + if (today > lastUploadDay) { + uploadAppUsageType(); + uploadPluginStats(); + + SP.putLong(MainApp.gs(R.string.key_plugin_stats_report_timestamp), today); + } + } + + private static void uploadPluginStats() { + CustomEvent pluginStats = new CustomEvent("PluginStats"); + pluginStats.putCustomAttribute("version", BuildConfig.VERSION); + pluginStats.putCustomAttribute("HEAD", BuildConfig.HEAD); + pluginStats.putCustomAttribute("language", SP.getString(R.string.key_language,"default")); + for (PluginBase plugin : MainApp.getPluginsList()) { + if (plugin.isEnabled(plugin.getType()) && !plugin.pluginDescription.alwaysEnabled) { + // Fabric allows no more than 20 attributes attached to an event. By reporting disabled plugins as + // well, we would exceed that threshold, so only report what is enabled + // TODO >2.0: consider reworking this to upload an event per enabled plugin instead. + pluginStats.putCustomAttribute(plugin.getClass().getSimpleName(), "enabled"); + } + } + + getInstance().logCustom(pluginStats); + } + + private static void uploadAppUsageType() { + CustomEvent type = new CustomEvent("AppUsageType"); + if (Config.NSCLIENT) + type.putCustomAttribute("type", "NSClient"); + else if (Config.PUMPCONTROL) + type.putCustomAttribute("type", "PumpControl"); + else if (MainApp.getConstraintChecker().isClosedLoopAllowed().value()) + type.putCustomAttribute("type", "ClosedLoop"); + else + type.putCustomAttribute("type", "OpenLoop"); + + getInstance().logCustom(type); + } + } diff --git a/app/src/main/java/info/nightscout/utils/HardLimits.java b/app/src/main/java/info/nightscout/utils/HardLimits.java index 8e1a05db0d..1a36561b62 100644 --- a/app/src/main/java/info/nightscout/utils/HardLimits.java +++ b/app/src/main/java/info/nightscout/utils/HardLimits.java @@ -5,6 +5,7 @@ import org.slf4j.LoggerFactory; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; /** * Created by mike on 22.02.2017. diff --git a/app/src/main/java/info/nightscout/utils/ImportExportPrefs.java b/app/src/main/java/info/nightscout/utils/ImportExportPrefs.java deleted file mode 100644 index 22175e0281..0000000000 --- a/app/src/main/java/info/nightscout/utils/ImportExportPrefs.java +++ /dev/null @@ -1,140 +0,0 @@ -package info.nightscout.utils; - -import android.Manifest; -import android.app.Activity; -import android.app.AlertDialog; -import android.content.DialogInterface; -import android.content.SharedPreferences; -import android.content.pm.PackageManager; -import android.os.Environment; -import android.preference.PreferenceManager; -import android.support.v4.app.ActivityCompat; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.io.PrintWriter; -import java.util.Map; - -import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.R; -import info.nightscout.androidaps.events.EventAppExit; - -/** - * Created by mike on 03.07.2016. - */ - -public class ImportExportPrefs { - private static Logger log = LoggerFactory.getLogger(ImportExportPrefs.class); - static File path = new File(Environment.getExternalStorageDirectory().toString()); - static public final File file = new File(path, MainApp.gs(R.string.app_name) + "Preferences"); - - private static final int REQUEST_EXTERNAL_STORAGE = 1; - private static String[] PERMISSIONS_STORAGE = { - Manifest.permission.READ_EXTERNAL_STORAGE, - Manifest.permission.WRITE_EXTERNAL_STORAGE - }; - - public static void verifyStoragePermissions(Activity activity) { - // Check if we have write permission - int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE); - - - if (permission != PackageManager.PERMISSION_GRANTED) { - // We don't have permission so prompt the user - ActivityCompat.requestPermissions( - activity, - PERMISSIONS_STORAGE, - REQUEST_EXTERNAL_STORAGE - ); - } - } - - public static void exportSharedPreferences(final Activity c) { - - new AlertDialog.Builder(c) - .setMessage(MainApp.gs(R.string.export_to) + " " + file + " ?") - .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c); - try { - FileWriter fw = new FileWriter(file); - PrintWriter pw = new PrintWriter(fw); - Map prefsMap = prefs.getAll(); - for (Map.Entry entry : prefsMap.entrySet()) { - pw.println(entry.getKey() + "::" + entry.getValue().toString()); - } - pw.close(); - fw.close(); - ToastUtils.showToastInUiThread(c, MainApp.gs(R.string.exported)); - } catch (FileNotFoundException e) { - ToastUtils.showToastInUiThread(c, MainApp.gs(R.string.filenotfound) + " " + file); - log.error("Unhandled exception", e); - } catch (IOException e) { - log.error("Unhandled exception", e); - } - } - }) - .setNegativeButton(android.R.string.cancel, null) - .show(); - } - - public static void importSharedPreferences(final Activity c) { - new AlertDialog.Builder(c) - .setMessage(MainApp.gs(R.string.import_from) + " " + file + " ?") - .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c); - SharedPreferences.Editor editor = prefs.edit(); - String line; - String[] lineParts; - try { - editor.clear(); - editor.commit(); - - BufferedReader reader = new BufferedReader(new FileReader(file)); - while ((line = reader.readLine()) != null) { - lineParts = line.split("::"); - if (lineParts.length == 2) { - if (lineParts[1].equals("true") || lineParts[1].equals("false")) { - editor.putBoolean(lineParts[0], Boolean.parseBoolean(lineParts[1])); - } else { - editor.putString(lineParts[0], lineParts[1]); - } - } - } - reader.close(); - editor.commit(); - OKDialog.show(c, MainApp.gs(R.string.setting_imported), MainApp.gs(R.string.restartingapp), new Runnable() { - @Override - public void run() { - log.debug("Exiting"); - MainApp.instance().stopKeepAliveService(); - MainApp.bus().post(new EventAppExit()); - MainApp.closeDbHelper(); - c.finish(); - System.runFinalization(); - System.exit(0); - } - }); - } catch (FileNotFoundException e) { - ToastUtils.showToastInUiThread(c, MainApp.gs(R.string.filenotfound) + " " + file); - log.error("Unhandled exception", e); - } catch (IOException e) { - log.error("Unhandled exception", e); - } - } - }) - .setNegativeButton(android.R.string.cancel, null) - .show(); - } - -} diff --git a/app/src/main/java/info/nightscout/utils/JsonHelper.java b/app/src/main/java/info/nightscout/utils/JsonHelper.java index 503d0bf395..e082ed99f7 100644 --- a/app/src/main/java/info/nightscout/utils/JsonHelper.java +++ b/app/src/main/java/info/nightscout/utils/JsonHelper.java @@ -22,7 +22,7 @@ public class JsonHelper { public static Object safeGetObject(JSONObject json, String fieldName, Object defaultValue) { Object result = defaultValue; - if (json.has(fieldName)) { + if (json != null && json.has(fieldName)) { try { result = json.get(fieldName); } catch (JSONException ignored) { @@ -36,7 +36,7 @@ public class JsonHelper { public static String safeGetString(JSONObject json, String fieldName) { String result = null; - if (json.has(fieldName)) { + if (json != null && json.has(fieldName)) { try { result = json.getString(fieldName); } catch (JSONException ignored) { @@ -49,7 +49,7 @@ public class JsonHelper { public static String safeGetString(JSONObject json, String fieldName, String defaultValue) { String result = defaultValue; - if (json.has(fieldName)) { + if (json != null && json.has(fieldName)) { try { result = json.getString(fieldName); } catch (JSONException ignored) { @@ -62,7 +62,7 @@ public class JsonHelper { public static double safeGetDouble(JSONObject json, String fieldName) { double result = 0d; - if (json.has(fieldName)) { + if (json != null && json.has(fieldName)) { try { result = json.getDouble(fieldName); } catch (JSONException ignored) { @@ -75,7 +75,7 @@ public class JsonHelper { public static int safeGetInt(JSONObject json, String fieldName) { int result = 0; - if (json.has(fieldName)) { + if (json != null && json.has(fieldName)) { try { result = json.getInt(fieldName); } catch (JSONException ignored) { @@ -88,7 +88,7 @@ public class JsonHelper { public static long safeGetLong(JSONObject json, String fieldName) { long result = 0; - if (json.has(fieldName)) { + if (json != null && json.has(fieldName)) { try { result = json.getLong(fieldName); } catch (JSONException e) { @@ -101,7 +101,7 @@ public class JsonHelper { public static boolean safeGetBoolean(JSONObject json, String fieldName) { boolean result = false; - if (json.has(fieldName)) { + if (json != null && json.has(fieldName)) { try { result = json.getBoolean(fieldName); } catch (JSONException e) { diff --git a/app/src/main/java/info/nightscout/utils/LocalAlertUtils.java b/app/src/main/java/info/nightscout/utils/LocalAlertUtils.java index 5556cae935..89c422ec53 100644 --- a/app/src/main/java/info/nightscout/utils/LocalAlertUtils.java +++ b/app/src/main/java/info/nightscout/utils/LocalAlertUtils.java @@ -3,8 +3,6 @@ package info.nightscout.utils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Date; - import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; @@ -13,7 +11,9 @@ import info.nightscout.androidaps.db.BgReading; import info.nightscout.androidaps.db.DatabaseHelper; import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.Loop.LoopPlugin; +import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.Overview.notifications.Notification; @@ -33,8 +33,8 @@ public class LocalAlertUtils { return T.mins(SP.getInt(MainApp.gs(R.string.key_pump_unreachable_threshold), 30)).msecs(); } - public static void checkPumpUnreachableAlarm(Date lastConnection, boolean isStatusOutdated) { - boolean alarmTimeoutExpired = lastConnection.getTime() + pumpUnreachableThreshold() < System.currentTimeMillis(); + public static void checkPumpUnreachableAlarm(long lastConnection, boolean isStatusOutdated) { + boolean alarmTimeoutExpired = lastConnection + pumpUnreachableThreshold() < System.currentTimeMillis(); boolean nextAlarmOccurrenceReached = SP.getLong("nextPumpDisconnectedAlarm", 0L) < System.currentTimeMillis(); if (Config.APS && SP.getBoolean(MainApp.gs(R.string.key_enable_pump_unreachable_alert), true) @@ -78,11 +78,11 @@ public class LocalAlertUtils { public static void notifyPumpStatusRead() { //TODO: persist the actual time the pump is read and simplify the whole logic when to alarm - final PumpInterface pump = ConfigBuilderPlugin.getActivePump(); - final Profile profile = MainApp.getConfigBuilder().getProfile(); + final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); + final Profile profile = ProfileFunctions.getInstance().getProfile(); if (pump != null && profile != null) { - Date lastConnection = pump.lastDataTime(); - long earliestAlarmTime = lastConnection.getTime() + pumpUnreachableThreshold(); + long lastConnection = pump.lastDataTime(); + long earliestAlarmTime = lastConnection + pumpUnreachableThreshold(); if (SP.getLong("nextPumpDisconnectedAlarm", 0l) < earliestAlarmTime) { SP.putLong("nextPumpDisconnectedAlarm", earliestAlarmTime); } diff --git a/app/src/main/java/info/nightscout/utils/LogDialog.java b/app/src/main/java/info/nightscout/utils/LogDialog.java deleted file mode 100644 index 7e2468774e..0000000000 --- a/app/src/main/java/info/nightscout/utils/LogDialog.java +++ /dev/null @@ -1,67 +0,0 @@ -package info.nightscout.utils; - -import android.app.AlertDialog; -import android.content.ClipData; -import android.content.Context; -import android.content.DialogInterface; -import android.content.ClipboardManager; -import android.widget.TextView; - - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; - -import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.R; - -/** - * Created by mike on 09.02.2017. - */ - -public class LogDialog { - - public static void showLogcat(Context context) { - String logCat = "no logs"; - final String processId = Integer.toString(android.os.Process.myPid()); - try { - Process process = Runtime.getRuntime().exec("logcat -d " + MainApp.gs(R.string.app_name) + ":D"); - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream())); - StringBuilder log = new StringBuilder(); - String line; - - while ((line = bufferedReader.readLine()) != null) { - if (line.contains(processId)) log.append(line + "\n"); - } - logCat = log.toString(); - - } catch (IOException e) { - logCat = e.getLocalizedMessage(); - } finally { - showAlertText(logCat, context); - } - } - - public static void showAlertText(final String msg, final Context context) { - try { - AlertDialog alertDialog = new AlertDialog.Builder(context) - .setMessage(msg) - .setPositiveButton(MainApp.gs(R.string.copy_to_clipboard), new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); - clipboard.setPrimaryClip(ClipData.newPlainText(null, msg)); - ToastUtils.showToastInUiThread(context, MainApp.gs(R.string.copied_to_clipboard)); - } - }) - .setNegativeButton(android.R.string.cancel, null) - .show(); - - if (msg.length() > 100) { - TextView textView = (TextView) alertDialog.findViewById(android.R.id.message); - textView.setTextSize(10); - } - } catch (Exception e) { - // crashing on screen rotation - } - } -} diff --git a/app/src/main/java/info/nightscout/utils/MidnightTime.java b/app/src/main/java/info/nightscout/utils/MidnightTime.java new file mode 100644 index 0000000000..523fe13826 --- /dev/null +++ b/app/src/main/java/info/nightscout/utils/MidnightTime.java @@ -0,0 +1,43 @@ +package info.nightscout.utils; + +import android.util.LongSparseArray; + +import java.util.Calendar; + +public class MidnightTime { + private static LongSparseArray times = new LongSparseArray(); + + private static long hits = 0; + private static long misses = 0; + + public static long calc() { + Calendar c = Calendar.getInstance(); + c.set(Calendar.HOUR_OF_DAY, 0); + c.set(Calendar.MINUTE, 0); + c.set(Calendar.SECOND, 0); + c.set(Calendar.MILLISECOND, 0); + return c.getTimeInMillis(); + } + + public static long calc(long time) { + Long m = (Long) times.get(time); + if (m != null) { + ++hits; + return m; + } + Calendar c = Calendar.getInstance(); + c.setTimeInMillis(time); + c.set(Calendar.HOUR_OF_DAY, 0); + c.set(Calendar.MINUTE, 0); + c.set(Calendar.SECOND, 0); + c.set(Calendar.MILLISECOND, 0); + m = c.getTimeInMillis(); + times.append(time, m); + ++misses; + return m; + } + + public static String log() { + return "Hits: " + hits + " misses: " + misses + " stored: " + times.size(); + } +} diff --git a/app/src/main/java/info/nightscout/utils/OKDialog.java b/app/src/main/java/info/nightscout/utils/OKDialog.java index 5185049678..0e9d95a22c 100644 --- a/app/src/main/java/info/nightscout/utils/OKDialog.java +++ b/app/src/main/java/info/nightscout/utils/OKDialog.java @@ -1,7 +1,9 @@ package info.nightscout.utils; import android.app.Activity; +import android.content.Context; import android.content.DialogInterface; +import android.os.Handler; import android.os.SystemClock; import android.support.v7.app.AlertDialog; import android.support.v7.view.ContextThemeWrapper; @@ -20,9 +22,9 @@ import info.nightscout.androidaps.R; public class OKDialog { private static Logger log = LoggerFactory.getLogger(OKDialog.class); - public static void show(final Activity activity, String title, String message, final Runnable runnable) { + public static void show(final Context context, String title, String message, final Runnable runnable) { try { - AlertDialog.Builder builder = new AlertDialog.Builder(new ContextThemeWrapper(activity, R.style.AppTheme)); + AlertDialog.Builder builder = new AlertDialog.Builder(new ContextThemeWrapper(context, R.style.AppTheme)); builder.setTitle(title); builder.setMessage(message); builder.setPositiveButton(MainApp.gs(R.string.ok), new DialogInterface.OnClickListener() { @@ -30,7 +32,7 @@ public class OKDialog { dialog.dismiss(); if (runnable != null) { SystemClock.sleep(100); - activity.runOnUiThread(runnable); + runOnUiThread(runnable); } } }); @@ -41,6 +43,11 @@ public class OKDialog { } } + public static boolean runOnUiThread(Runnable theRunnable) { + final Handler mainHandler = new Handler(MainApp.instance().getApplicationContext().getMainLooper()); + return mainHandler.post(theRunnable); + } + public static void show(final Activity activity, String title, Spanned message, final Runnable runnable) { try { AlertDialog.Builder builder = new AlertDialog.Builder(new ContextThemeWrapper(activity, R.style.AppTheme)); diff --git a/app/src/main/java/info/nightscout/utils/PercentageSplitter.java b/app/src/main/java/info/nightscout/utils/PercentageSplitter.java index 53e50466b5..40dfdf2455 100644 --- a/app/src/main/java/info/nightscout/utils/PercentageSplitter.java +++ b/app/src/main/java/info/nightscout/utils/PercentageSplitter.java @@ -8,14 +8,23 @@ import java.util.regex.Pattern; */ public class PercentageSplitter { + // "Profile name (200%,2h)" + private static final Pattern percentagePattern = Pattern.compile("(.+)\\(\\d+%,\\d+h\\)"); + // "Profile name (200%)" + private static final Pattern percentageShiftPattern = Pattern.compile("(.+)\\(\\d+%\\)"); + + /** Removes the suffix for percentage and timeshift from a profile name. */ public static String pureName(String name) { - String newName = name; - String s = "(.*)\\((\\d+)\\%\\)"; - Pattern r = Pattern.compile(s); - Matcher m = r.matcher(name); - if (m.find()) { - newName = m.group(1); + Matcher percentageMatch = percentagePattern.matcher(name); + if (percentageMatch.find()) { + return percentageMatch.group(1).trim(); } - return newName; + + Matcher percentageShiftMatch = percentageShiftPattern.matcher(name); + if (percentageShiftMatch.find()) { + return percentageShiftMatch.group(1).trim(); + } + + return name; } } diff --git a/app/src/main/java/info/nightscout/utils/Profiler.java b/app/src/main/java/info/nightscout/utils/Profiler.java index 0410ad6ff8..140adc6366 100644 --- a/app/src/main/java/info/nightscout/utils/Profiler.java +++ b/app/src/main/java/info/nightscout/utils/Profiler.java @@ -2,8 +2,6 @@ package info.nightscout.utils; import org.slf4j.Logger; -import java.util.Date; - /** * Created by mike on 29.01.2017. */ @@ -11,8 +9,8 @@ import java.util.Date; public class Profiler { public Profiler(){} - static public void log(Logger log, String function, Date start) { - long msec = System.currentTimeMillis() - start.getTime(); + static public void log(Logger log, String function, long start) { + long msec = System.currentTimeMillis() - start; log.debug(">>> " + function + " <<< executed in " + msec + " miliseconds"); } } diff --git a/app/src/main/java/info/nightscout/utils/SafeParse.java b/app/src/main/java/info/nightscout/utils/SafeParse.java index ff749f732b..7d6d890b0e 100644 --- a/app/src/main/java/info/nightscout/utils/SafeParse.java +++ b/app/src/main/java/info/nightscout/utils/SafeParse.java @@ -11,6 +11,7 @@ public class SafeParse { public static Double stringToDouble(String input) { Double result = 0d; input = input.replace(",", "."); + input = input.replace("−", "-"); if (input.equals("")) return 0d; try { @@ -24,6 +25,7 @@ public class SafeParse { public static Integer stringToInt(String input) { Integer result = 0; input = input.replace(",", "."); + input = input.replace("−", "-"); if (input.equals("")) return 0; try { @@ -37,6 +39,7 @@ public class SafeParse { public static Long stringToLong(String input) { Long result = 0L; input = input.replace(",", "."); + input = input.replace("−", "-"); if (input.equals("")) return 0L; try { diff --git a/app/src/main/java/info/nightscout/utils/StringUtils.java b/app/src/main/java/info/nightscout/utils/StringUtils.java new file mode 100644 index 0000000000..de16f7964e --- /dev/null +++ b/app/src/main/java/info/nightscout/utils/StringUtils.java @@ -0,0 +1,20 @@ +package info.nightscout.utils; + +/** + * class contains useful String functions + */ +public class StringUtils { + + private StringUtils() { + // this constructor is private, since this class should not get instantiated + } + + public static String removeSurroundingQuotes(String string) { + if (string.length() >= 2 && string.charAt(0) == '"' + && string.charAt(string.length() - 1) == '"') { + string = string.substring(1, string.length() - 1); + } + + return string; + } +} diff --git a/app/src/main/java/info/nightscout/utils/VersionChecker.java b/app/src/main/java/info/nightscout/utils/VersionChecker.java new file mode 100644 index 0000000000..00bfc50395 --- /dev/null +++ b/app/src/main/java/info/nightscout/utils/VersionChecker.java @@ -0,0 +1,101 @@ +package info.nightscout.utils; + +import android.net.ConnectivityManager; +import android.net.NetworkInfo; + +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.DefaultHttpClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import info.nightscout.androidaps.BuildConfig; +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; +import info.nightscout.androidaps.plugins.Overview.notifications.Notification; + +import static android.content.Context.CONNECTIVITY_SERVICE; + +public class VersionChecker { + private static Logger log = LoggerFactory.getLogger(L.CORE); + + public static void check() { + if (isConnected()) + new Thread(() -> { + HttpClient client = new DefaultHttpClient(); + HttpGet request = new HttpGet("https://raw.githubusercontent.com/MilosKozak/AndroidAPS/master/app/build.gradle"); + HttpResponse response; + + try { + response = client.execute(request); + InputStream inputStream = response.getEntity().getContent(); + + if (inputStream != null) { + String result = findLine(inputStream); + if (result != null) { + result = result.replace("version", "").replace("\"", "").replace("\\s+", "").trim(); + int compare = result.compareTo(BuildConfig.VERSION_NAME.replace("\"", "")); + if (compare == 0) { + log.debug("Version equal to master"); + return; + } else if (compare > 0) { + log.debug("Version outdated. Found " + result); + Notification notification = new Notification(Notification.NEWVERSIONDETECTED, String.format(MainApp.gs(R.string.versionavailable), result), Notification.LOW); + MainApp.bus().post(new EventNewNotification(notification)); + return; + } else { + log.debug("Version newer than master. Are you developer?"); + return; + } + } + } + + log.debug("Github master version not found"); + + } catch (IOException e) { + e.printStackTrace(); + log.debug("Github master version check error"); + } + }).start(); + else + log.debug("Github master version no checked. No connectivity"); + } + + // convert inputstream to String + private static String findLine(InputStream inputStream) throws IOException { + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); + String line; + String regex = "(.*)version(.*)\"(\\d+)\\.(\\d+)\"(.*)"; + Pattern p = Pattern.compile(regex); + + while ((line = bufferedReader.readLine()) != null) { + Matcher m = p.matcher(line); + if (m.matches()) { + log.debug("+++ " + line); + return line; + } else { + log.debug("--- " + line); + } + } + inputStream.close(); + return null; + } + + // check network connection + public static boolean isConnected() { + ConnectivityManager connMgr = (ConnectivityManager) MainApp.instance().getApplicationContext().getSystemService(CONNECTIVITY_SERVICE); + NetworkInfo networkInfo = connMgr.getActiveNetworkInfo(); + return networkInfo != null && networkInfo.isConnected(); + } + +} diff --git a/app/src/main/java/info/nightscout/utils/XdripCalibrations.java b/app/src/main/java/info/nightscout/utils/XdripCalibrations.java index 66ec6bd3df..18c066b1da 100644 --- a/app/src/main/java/info/nightscout/utils/XdripCalibrations.java +++ b/app/src/main/java/info/nightscout/utils/XdripCalibrations.java @@ -10,14 +10,13 @@ import android.support.v7.app.AlertDialog; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Date; import java.util.List; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.Services.Intents; -import info.nightscout.androidaps.data.Profile; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; +import info.nightscout.androidaps.services.Intents; /** * Created by mike on 10.02.2017. @@ -47,7 +46,7 @@ public class XdripCalibrations { Context context = MainApp.instance().getApplicationContext(); Bundle bundle = new Bundle(); bundle.putDouble("glucose_number", bg); - bundle.putString("units", MainApp.getConfigBuilder().getProfileUnits().equals(Constants.MGDL) ? "mgdl" : "mmol"); + bundle.putString("units", ProfileFunctions.getInstance().getProfileUnits().equals(Constants.MGDL) ? "mgdl" : "mmol"); bundle.putLong("timestamp", System.currentTimeMillis()); Intent intent = new Intent(Intents.ACTION_REMOTE_CALIBRATION); intent.putExtras(bundle); diff --git a/app/src/main/res/drawable-hdpi-v11/ic_notification.png b/app/src/main/res/drawable-hdpi-v11/ic_notification.png deleted file mode 100644 index 1e28cbeb7a..0000000000 Binary files a/app/src/main/res/drawable-hdpi-v11/ic_notification.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi-v9/ic_notification.png b/app/src/main/res/drawable-hdpi-v9/ic_notification.png deleted file mode 100644 index ad1bcf514f..0000000000 Binary files a/app/src/main/res/drawable-hdpi-v9/ic_notification.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/ic_notification.png b/app/src/main/res/drawable-hdpi/ic_notification.png index bb8248c78f..453ed7b382 100644 Binary files a/app/src/main/res/drawable-hdpi/ic_notification.png and b/app/src/main/res/drawable-hdpi/ic_notification.png differ diff --git a/app/src/main/res/drawable-hdpi/ic_visibility.png b/app/src/main/res/drawable-hdpi/ic_visibility.png new file mode 100644 index 0000000000..a014628e30 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_visibility.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_danar_useropthdpi.png b/app/src/main/res/drawable-hdpi/icon_danar_useropthdpi.png new file mode 100644 index 0000000000..ee3ab7725e Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_danar_useropthdpi.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_local_activatehdpi.png b/app/src/main/res/drawable-hdpi/icon_local_activatehdpi.png new file mode 100644 index 0000000000..4ef567ffb6 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_local_activatehdpi.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_local_resethdpi.png b/app/src/main/res/drawable-hdpi/icon_local_resethdpi.png new file mode 100644 index 0000000000..7d38cf0b50 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_local_resethdpi.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_local_savehdpi.png b/app/src/main/res/drawable-hdpi/icon_local_savehdpi.png new file mode 100644 index 0000000000..e5c1d5cedc Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_local_savehdpi.png differ diff --git a/app/src/main/res/drawable-hdpi/nsclient_smallicon.png b/app/src/main/res/drawable-hdpi/nsclient_smallicon.png new file mode 100644 index 0000000000..e6d52996a6 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/nsclient_smallicon.png differ diff --git a/app/src/main/res/drawable-mdpi-v11/ic_notification.png b/app/src/main/res/drawable-mdpi-v11/ic_notification.png deleted file mode 100644 index fbed7675b1..0000000000 Binary files a/app/src/main/res/drawable-mdpi-v11/ic_notification.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi-v9/ic_notification.png b/app/src/main/res/drawable-mdpi-v9/ic_notification.png deleted file mode 100644 index 3be3f1383f..0000000000 Binary files a/app/src/main/res/drawable-mdpi-v9/ic_notification.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_notification.png b/app/src/main/res/drawable-mdpi/ic_notification.png index c19b973e2a..c483ada178 100644 Binary files a/app/src/main/res/drawable-mdpi/ic_notification.png and b/app/src/main/res/drawable-mdpi/ic_notification.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_visibility.png b/app/src/main/res/drawable-mdpi/ic_visibility.png new file mode 100644 index 0000000000..d5a9dc9ca4 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_visibility.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_danar_useroptmdpi.png b/app/src/main/res/drawable-mdpi/icon_danar_useroptmdpi.png new file mode 100644 index 0000000000..1fadcd446b Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_danar_useroptmdpi.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_local_activatemdpi.png b/app/src/main/res/drawable-mdpi/icon_local_activatemdpi.png new file mode 100644 index 0000000000..b39c72b407 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_local_activatemdpi.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_local_resetmdpi.png b/app/src/main/res/drawable-mdpi/icon_local_resetmdpi.png new file mode 100644 index 0000000000..ad2e0eaf6d Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_local_resetmdpi.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_local_savemdpi.png b/app/src/main/res/drawable-mdpi/icon_local_savemdpi.png new file mode 100644 index 0000000000..843beed523 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_local_savemdpi.png differ diff --git a/app/src/main/res/drawable-mdpi/nsclient_smallicon.png b/app/src/main/res/drawable-mdpi/nsclient_smallicon.png new file mode 100644 index 0000000000..0e55ac39eb Binary files /dev/null and b/app/src/main/res/drawable-mdpi/nsclient_smallicon.png differ diff --git a/app/src/main/res/drawable-xhdpi-v11/ic_notification.png b/app/src/main/res/drawable-xhdpi-v11/ic_notification.png deleted file mode 100644 index 0427fc6b02..0000000000 Binary files a/app/src/main/res/drawable-xhdpi-v11/ic_notification.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi-v9/ic_notification.png b/app/src/main/res/drawable-xhdpi-v9/ic_notification.png deleted file mode 100644 index b779bd4090..0000000000 Binary files a/app/src/main/res/drawable-xhdpi-v9/ic_notification.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/ic_notification.png b/app/src/main/res/drawable-xhdpi/ic_notification.png index 9eb0dcf193..56c4049e84 100644 Binary files a/app/src/main/res/drawable-xhdpi/ic_notification.png and b/app/src/main/res/drawable-xhdpi/ic_notification.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_visibility.png b/app/src/main/res/drawable-xhdpi/ic_visibility.png new file mode 100644 index 0000000000..1e16fb934f Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_visibility.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_danar_useroptxhdpi.png b/app/src/main/res/drawable-xhdpi/icon_danar_useroptxhdpi.png new file mode 100644 index 0000000000..126122a570 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_danar_useroptxhdpi.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_local_activatexhdpi.png b/app/src/main/res/drawable-xhdpi/icon_local_activatexhdpi.png new file mode 100644 index 0000000000..75e9af38ed Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_local_activatexhdpi.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_local_resetxhdpi.png b/app/src/main/res/drawable-xhdpi/icon_local_resetxhdpi.png new file mode 100644 index 0000000000..2813cb448d Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_local_resetxhdpi.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_local_savexhdpi.png b/app/src/main/res/drawable-xhdpi/icon_local_savexhdpi.png new file mode 100644 index 0000000000..0cf81430cc Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_local_savexhdpi.png differ diff --git a/app/src/main/res/drawable-xhdpi/nsclient_smallicon.png b/app/src/main/res/drawable-xhdpi/nsclient_smallicon.png new file mode 100644 index 0000000000..0ec8b219b6 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/nsclient_smallicon.png differ diff --git a/app/src/main/res/drawable-xxhdpi-v11/ic_notification.png b/app/src/main/res/drawable-xxhdpi-v11/ic_notification.png deleted file mode 100644 index 8a586cce76..0000000000 Binary files a/app/src/main/res/drawable-xxhdpi-v11/ic_notification.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi-v9/ic_notification.png b/app/src/main/res/drawable-xxhdpi-v9/ic_notification.png deleted file mode 100644 index b3cd107f78..0000000000 Binary files a/app/src/main/res/drawable-xxhdpi-v9/ic_notification.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_notification.png b/app/src/main/res/drawable-xxhdpi/ic_notification.png index 9da9b83a84..6ef4df1823 100644 Binary files a/app/src/main/res/drawable-xxhdpi/ic_notification.png and b/app/src/main/res/drawable-xxhdpi/ic_notification.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_visibility.png b/app/src/main/res/drawable-xxhdpi/ic_visibility.png new file mode 100644 index 0000000000..dbc192368f Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_visibility.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_danar_useroptxxhdpi.png b/app/src/main/res/drawable-xxhdpi/icon_danar_useroptxxhdpi.png new file mode 100644 index 0000000000..b2a8eb9313 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_danar_useroptxxhdpi.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_local_activatexxhdpi.png b/app/src/main/res/drawable-xxhdpi/icon_local_activatexxhdpi.png new file mode 100644 index 0000000000..600e6ee61c Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_local_activatexxhdpi.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_local_resetxxhdpi.png b/app/src/main/res/drawable-xxhdpi/icon_local_resetxxhdpi.png new file mode 100644 index 0000000000..dc9d659dd7 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_local_resetxxhdpi.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_local_savexxhdpi.png b/app/src/main/res/drawable-xxhdpi/icon_local_savexxhdpi.png new file mode 100644 index 0000000000..20448e4bf9 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_local_savexxhdpi.png differ diff --git a/app/src/main/res/drawable-xxhdpi/nsclient_smallicon.png b/app/src/main/res/drawable-xxhdpi/nsclient_smallicon.png new file mode 100644 index 0000000000..ce7eb909ff Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/nsclient_smallicon.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_visibility.png b/app/src/main/res/drawable-xxxhdpi/ic_visibility.png new file mode 100644 index 0000000000..882eacdee5 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_visibility.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_danar_useroptxxxhdpi.png b/app/src/main/res/drawable-xxxhdpi/icon_danar_useroptxxxhdpi.png new file mode 100644 index 0000000000..52f952ced4 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_danar_useroptxxxhdpi.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_local_activatexxxhdpi.png b/app/src/main/res/drawable-xxxhdpi/icon_local_activatexxxhdpi.png new file mode 100644 index 0000000000..2de9ce9d4d Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_local_activatexxxhdpi.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_local_resetxxxhdpi.png b/app/src/main/res/drawable-xxxhdpi/icon_local_resetxxxhdpi.png new file mode 100644 index 0000000000..ec54479149 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_local_resetxxxhdpi.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_local_savexxxhdpi.png b/app/src/main/res/drawable-xxxhdpi/icon_local_savexxxhdpi.png new file mode 100644 index 0000000000..f2ecc45ac0 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_local_savexxxhdpi.png differ diff --git a/app/src/main/res/drawable/ic_notification.png b/app/src/main/res/drawable/ic_notification.png new file mode 100644 index 0000000000..453ed7b382 Binary files /dev/null and b/app/src/main/res/drawable/ic_notification.png differ diff --git a/app/src/main/res/drawable/icon_danar_useropt.png b/app/src/main/res/drawable/icon_danar_useropt.png new file mode 100644 index 0000000000..1fadcd446b Binary files /dev/null and b/app/src/main/res/drawable/icon_danar_useropt.png differ diff --git a/app/src/main/res/drawable/notif_icon.png b/app/src/main/res/drawable/notif_icon.png index 1b89799dc6..480d0eaf77 100644 Binary files a/app/src/main/res/drawable/notif_icon.png and b/app/src/main/res/drawable/notif_icon.png differ diff --git a/app/src/main/res/drawable/visibility_black_16x16.png b/app/src/main/res/drawable/visibility_black_16x16.png deleted file mode 100644 index d24867dcdf..0000000000 Binary files a/app/src/main/res/drawable/visibility_black_16x16.png and /dev/null differ diff --git a/app/src/main/res/layout/activity_agreement.xml b/app/src/main/res/layout/activity_agreement.xml index e5f5c8ddf1..9a17432930 100644 --- a/app/src/main/res/layout/activity_agreement.xml +++ b/app/src/main/res/layout/activity_agreement.xml @@ -4,7 +4,7 @@ android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizo android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" -tools:context="info.nightscout.androidaps.AgreementActivity"> +tools:context="info.nightscout.androidaps.activities.AgreementActivity"> + tools:context="info.nightscout.androidaps.activities.HistoryBrowseActivity"> - -