diff --git a/app/build.gradle b/app/build.gradle index d656fa97d9..c12c150513 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -44,7 +44,7 @@ android { minSdkVersion 21 targetSdkVersion 23 versionCode 1500 - version "1.5" + version "1.5g" buildConfigField "String", "VERSION", '"' + version + '"' buildConfigField "String", "BUILDVERSION", generateGitBuild() } @@ -173,6 +173,9 @@ dependencies { androidTestCompile 'com.google.dexmaker:dexmaker:1.2' androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2' compile(name: 'android-edittext-validator-v1.3.4-mod', ext: 'aar') + compile ('com.google.android:flexbox:0.3.0') { + exclude group: 'com.android.support' + } compile('io.socket:socket.io-client:0.8.3') { // excluding org.json which is provided by Android exclude group: 'org.json', module: 'json' @@ -180,4 +183,4 @@ dependencies { compile 'com.google.code.gson:gson:2.7' compile 'com.google.guava:guava:20.0' -} \ No newline at end of file +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c4f9bcfe04..7d792556b7 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -17,6 +17,7 @@ + @@ -41,14 +42,11 @@ android:name=".plugins.Overview.Dialogs.BolusProgressHelperActivity" android:theme="@style/Theme.AppCompat.Translucent" /> - - - - + + - @@ -58,17 +56,6 @@ android:enabled="true" android:exported="true"> - - - - - - - - - - - @@ -79,7 +66,6 @@ - @@ -117,7 +103,6 @@ android:exported="false" /> + + - - \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/Config.java b/app/src/main/java/info/nightscout/androidaps/Config.java index 31031333d3..e6c06583c9 100644 --- a/app/src/main/java/info/nightscout/androidaps/Config.java +++ b/app/src/main/java/info/nightscout/androidaps/Config.java @@ -4,6 +4,8 @@ package info.nightscout.androidaps; * Created by mike on 07.06.2016. */ public class Config { + public static int SUPPORTEDNSVERSION = 1000; // 0.10.00 + // MAIN FUCTIONALITY public static final boolean APS = BuildConfig.APS; // PLUGINS @@ -29,19 +31,16 @@ public class Config { public static final boolean detailedLog = true; public static final boolean logFunctionCalls = true; - public static final boolean logIncommingBG = 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 logConstraintsChanges = true; - public static final boolean logTempBasalsCut = true; public static final boolean logNSUpload = true; public static final boolean logPumpActions = true; - public static final boolean logSMSComm = true; public static final boolean logCongigBuilderActions = true; - public static final boolean logAutosensData = false; + public static final boolean logAutosensData = true; // DanaR specific public static final boolean logDanaBTComm = true; diff --git a/app/src/main/java/info/nightscout/androidaps/Constants.java b/app/src/main/java/info/nightscout/androidaps/Constants.java index 51f27d84a2..e361e4cc8c 100644 --- a/app/src/main/java/info/nightscout/androidaps/Constants.java +++ b/app/src/main/java/info/nightscout/androidaps/Constants.java @@ -33,14 +33,6 @@ public class Constants { public static final int CPP_MIN_PERCENTAGE = 50; public static final int CPP_MAX_PERCENTAGE = 200; - // Defaults for settings - public static final Double MAX_BG_DEFAULT_MGDL = 180d; - public static final Double MAX_BG_DEFAULT_MMOL = 10d; - public static final Double MIN_BG_DEFAULT_MGDL = 100d; - public static final Double MIN_BG_DEFAULT_MMOL = 5d; - public static final Double TARGET_BG_DEFAULT_MGDL = 150d; - public static final Double TARGET_BG_DEFAULT_MMOL = 7d; - // Very Hard Limits Ranges // First value is the Lowest and second value is the Highest a Limit can define public static final int[] VERY_HARD_LIMIT_MIN_BG = {72,180}; diff --git a/app/src/main/java/info/nightscout/androidaps/MainActivity.java b/app/src/main/java/info/nightscout/androidaps/MainActivity.java index c9445ed1f8..528cbd21bd 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/MainActivity.java @@ -23,6 +23,7 @@ import android.view.MenuInflater; 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; @@ -34,10 +35,14 @@ import com.squareup.otto.Subscribe; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import info.nightscout.androidaps.Services.AlarmSoundService; +import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.events.EventAppExit; import info.nightscout.androidaps.events.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.Overview.events.EventSetWakeLock; import info.nightscout.androidaps.tabs.SlidingTabLayout; import info.nightscout.androidaps.tabs.TabPageAdapter; import info.nightscout.utils.ImportExportPrefs; @@ -58,6 +63,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe ImageButton menuButton; + protected PowerManager.WakeLock mWakeLock; @Override protected void onCreate(Bundle savedInstanceState) { @@ -74,13 +80,28 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe Manifest.permission.WRITE_EXTERNAL_STORAGE}, CASE_STORAGE); } askForBatteryOptimizationPermission(); + checkUpgradeToProfileTarget(); if (Config.logFunctionCalls) log.debug("onCreate"); + onStatusEvent(new EventSetWakeLock(SP.getBoolean("lockscreen", false))); + registerBus(); setUpTabs(false); } + @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"); + mWakeLock.acquire(); + } else { + if (mWakeLock != null) + mWakeLock.release(); + } + } + @Subscribe public void onStatusEvent(final EventRefreshGui ev) { String lang = SP.getString("language", "en"); @@ -90,10 +111,15 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe public void run() { recreate(); try { // activity may be destroyed - setUpTabs(ev.isSwitchToLast()); + setUpTabs(true); } catch (IllegalStateException e) { e.printStackTrace(); } + 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); } }); } @@ -130,6 +156,29 @@ 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(); + String oldRange = SP.getDouble("openapsma_min_bg", 0d) + " - " + SP.getDouble("openapsma_max_bg", 0d); + String newRange = ""; + if (profile != null) { + newRange = profile.getTargetLow() + " - " + profile.getTargetHigh(); + } + String message = "Target range is changed in current version.\n\nIt's not taken from preferences but from profile.\n\n!!! REVIEW YOUR SETTINGS !!!"; + message += "\n\nOld settings: " + oldRange; + message += "\nProfile settings: " + newRange; + OKDialog.show(this, "Target range change", message, new Runnable() { + @Override + public void run() { + SP.remove("openapsma_min_bg"); + SP.remove("openapsma_max_bg"); + SP.remove("openapsma_target_bg"); + } + }); + } + } + //check for sms permission if enable in prefernces @Subscribe public void onStatusEvent(final EventPreferenceChange ev) { @@ -154,6 +203,13 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe askForSMSPermissions(); } + @Override + public void onDestroy() { + if (mWakeLock != null) + mWakeLock.release(); + super.onDestroy(); + } + private void askForBatteryOptimizationPermission() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { final String packageName = getPackageName(); @@ -162,7 +218,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe if (!pm.isIgnoringBatteryOptimizations(packageName)) { log.debug("Requesting ignore battery optimization"); - OKDialog.show(getParent(), getString(R.string.pleaseallowpermission), String.format(getString(R.string.needwhitelisting), getString(R.string.app_name)), new Runnable() { + OKDialog.show(this, getString(R.string.pleaseallowpermission), String.format(getString(R.string.needwhitelisting), getString(R.string.app_name)), new Runnable() { @Override public void run() { @@ -299,7 +355,9 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe builder.setIcon(R.mipmap.yellowowl); else builder.setIcon(R.mipmap.blueowl); - builder.setMessage("Build: " + BuildConfig.BUILDVERSION); + String message = "Build: " + BuildConfig.BUILDVERSION + "\n"; + message += MainApp.sResources.getString(R.string.configbuilder_nightscoutversion_label) + " " + ConfigBuilderPlugin.nightscoutVersionName; + builder.setMessage(message); builder.setPositiveButton(MainApp.sResources.getString(R.string.ok), null); AlertDialog alertDialog = builder.create(); alertDialog.show(); diff --git a/app/src/main/java/info/nightscout/androidaps/MainApp.java b/app/src/main/java/info/nightscout/androidaps/MainApp.java index 1e49b03d73..817b0adafb 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainApp.java +++ b/app/src/main/java/info/nightscout/androidaps/MainApp.java @@ -2,8 +2,10 @@ package info.nightscout.androidaps; import android.app.Application; import android.content.Intent; +import android.content.IntentFilter; import android.content.res.Resources; import android.support.annotation.Nullable; +import android.support.v4.content.LocalBroadcastManager; import com.crashlytics.android.Crashlytics; import com.crashlytics.android.answers.Answers; @@ -17,6 +19,7 @@ import org.slf4j.LoggerFactory; import java.util.ArrayList; +import info.nightscout.androidaps.Services.Intents; import info.nightscout.androidaps.db.DatabaseHelper; import info.nightscout.androidaps.interfaces.InsulinInterface; import info.nightscout.androidaps.interfaces.PluginBase; @@ -26,12 +29,13 @@ import info.nightscout.androidaps.plugins.Careportal.CareportalFragment; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderFragment; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesFragment; -import info.nightscout.androidaps.plugins.ConstraintsSafety.SafetyFragment; +import info.nightscout.androidaps.plugins.ConstraintsSafety.SafetyPlugin; import info.nightscout.androidaps.plugins.InsulinFastacting.InsulinFastactingFragment; import info.nightscout.androidaps.plugins.InsulinFastactingProlonged.InsulinFastactingProlongedFragment; -import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorFragment; +import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin; import info.nightscout.androidaps.plugins.Loop.LoopFragment; import info.nightscout.androidaps.plugins.NSClientInternal.NSClientInternalFragment; +import info.nightscout.androidaps.plugins.NSClientInternal.receivers.AckAlarmReceiver; import info.nightscout.androidaps.plugins.OpenAPSAMA.OpenAPSAMAFragment; import info.nightscout.androidaps.plugins.OpenAPSMA.OpenAPSMAFragment; import info.nightscout.androidaps.plugins.Overview.OverviewFragment; @@ -46,18 +50,22 @@ import info.nightscout.androidaps.plugins.PumpDanaRKorean.DanaRKoreanFragment; import info.nightscout.androidaps.plugins.PumpDanaRKorean.services.DanaRKoreanExecutionService; import info.nightscout.androidaps.plugins.PumpDanaRv2.DanaRv2Fragment; import info.nightscout.androidaps.plugins.PumpDanaRv2.services.DanaRv2ExecutionService; -import info.nightscout.androidaps.plugins.PumpMDI.MDIFragment; -import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpFragment; +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.SmsCommunicator.SmsCommunicatorFragment; -import info.nightscout.androidaps.plugins.SourceGlimp.SourceGlimpFragment; -import info.nightscout.androidaps.plugins.SourceMM640g.SourceMM640gFragment; -import info.nightscout.androidaps.plugins.SourceNSClient.SourceNSClientFragment; -import info.nightscout.androidaps.plugins.SourceXdrip.SourceXdripFragment; +import info.nightscout.androidaps.plugins.SourceGlimp.SourceGlimpPlugin; +import info.nightscout.androidaps.plugins.SourceMM640g.SourceMM640gPlugin; +import info.nightscout.androidaps.plugins.SourceNSClient.SourceNSClientPlugin; +import info.nightscout.androidaps.plugins.SourceXdrip.SourceXdripPlugin; import info.nightscout.androidaps.plugins.Treatments.TreatmentsFragment; import info.nightscout.androidaps.plugins.Wear.WearFragment; -import info.nightscout.androidaps.plugins.XDripStatusline.StatuslineFragment; +import info.nightscout.androidaps.plugins.XDripStatusline.StatuslinePlugin; +import info.nightscout.androidaps.receivers.DataReceiver; import info.nightscout.androidaps.receivers.KeepAliveReceiver; +import info.nightscout.androidaps.receivers.NSAlarmReceiver; import info.nightscout.utils.NSUpload; import io.fabric.sdk.android.Fabric; @@ -75,6 +83,11 @@ public class MainApp extends Application { private static ArrayList pluginsList = null; + private static DataReceiver dataReceiver = new DataReceiver(); + private static NSAlarmReceiver alarmReciever = new NSAlarmReceiver(); + private static AckAlarmReceiver ackAlarmReciever = new AckAlarmReceiver(); + private LocalBroadcastManager lbm; + @Override public void onCreate() { super.onCreate(); @@ -90,19 +103,24 @@ public class MainApp extends Application { sInstance = this; sResources = getResources(); + registerLocalBroadcastReceiver(); + if (pluginsList == null) { pluginsList = new ArrayList<>(); // Register all tabs in app here pluginsList.add(OverviewFragment.getPlugin()); - pluginsList.add(IobCobCalculatorFragment.getPlugin()); + pluginsList.add(IobCobCalculatorPlugin.getPlugin()); if (Config.ACTION) pluginsList.add(ActionsFragment.getPlugin()); pluginsList.add(InsulinFastactingFragment.getPlugin()); pluginsList.add(InsulinFastactingProlongedFragment.getPlugin()); + pluginsList.add(SensitivityOref0Plugin.getPlugin()); + pluginsList.add(SensitivityAAPSPlugin.getPlugin()); + pluginsList.add(SensitivityWeightedAveragePlugin.getPlugin()); if (Config.DANAR) pluginsList.add(DanaRFragment.getPlugin()); if (Config.DANAR) pluginsList.add(DanaRKoreanFragment.getPlugin()); if (Config.DANARv2) pluginsList.add(DanaRv2Fragment.getPlugin()); pluginsList.add(CareportalFragment.getPlugin()); - if (Config.MDI) pluginsList.add(MDIFragment.getPlugin()); + if (Config.MDI) pluginsList.add(MDIPlugin.getPlugin()); if (Config.VIRTUALPUMP) pluginsList.add(VirtualPumpPlugin.getInstance()); if (Config.LOOPENABLED) pluginsList.add(LoopFragment.getPlugin()); if (Config.OPENAPSENABLED) pluginsList.add(OpenAPSMAFragment.getPlugin()); @@ -113,19 +131,19 @@ public class MainApp extends Application { if (Config.OTHERPROFILES) pluginsList.add(CircadianPercentageProfileFragment.getPlugin()); pluginsList.add(TreatmentsFragment.getPlugin()); - if (Config.SAFETY) pluginsList.add(SafetyFragment.getPlugin()); + if (Config.SAFETY) pluginsList.add(SafetyPlugin.getPlugin()); if (Config.APS) pluginsList.add(ObjectivesFragment.getPlugin()); if (!Config.NSCLIENT) - pluginsList.add(SourceXdripFragment.getPlugin()); - pluginsList.add(SourceNSClientFragment.getPlugin()); + pluginsList.add(SourceXdripPlugin.getPlugin()); + pluginsList.add(SourceNSClientPlugin.getPlugin()); if (!Config.NSCLIENT) - pluginsList.add(SourceMM640gFragment.getPlugin()); + pluginsList.add(SourceMM640gPlugin.getPlugin()); if (!Config.NSCLIENT) - pluginsList.add(SourceGlimpFragment.getPlugin()); + pluginsList.add(SourceGlimpPlugin.getPlugin()); if (Config.SMSCOMMUNICATORENABLED) pluginsList.add(SmsCommunicatorFragment.getPlugin()); if (Config.WEAR) pluginsList.add(WearFragment.getPlugin(this)); - pluginsList.add(StatuslineFragment.getPlugin(this)); + pluginsList.add(StatuslinePlugin.getPlugin(this)); pluginsList.add(new PersistentNotificationPlugin(this)); pluginsList.add(NSClientInternalFragment.getPlugin()); @@ -150,6 +168,29 @@ public class MainApp extends Application { } }); t.start(); + + } + + private void registerLocalBroadcastReceiver() { + lbm = LocalBroadcastManager.getInstance(this); + lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_NEW_TREATMENT)); + lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_CHANGED_TREATMENT)); + lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_REMOVED_TREATMENT)); + lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_NEW_SGV)); + lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_NEW_PROFILE)); + lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_NEW_STATUS)); + lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_NEW_MBG)); + lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_NEW_DEVICESTATUS)); + lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_NEW_CAL)); + + //register alarms + lbm.registerReceiver(alarmReciever, new IntentFilter(Intents.ACTION_ALARM)); + lbm.registerReceiver(alarmReciever, new IntentFilter(Intents.ACTION_ANNOUNCEMENT)); + lbm.registerReceiver(alarmReciever, new IntentFilter(Intents.ACTION_CLEAR_ALARM)); + lbm.registerReceiver(alarmReciever, new IntentFilter(Intents.ACTION_URGENT_ALARM)); + + //register ack alarm + lbm.registerReceiver(ackAlarmReciever, new IntentFilter(Intents.ACTION_ACK_ALARM)); } private void startKeepAliveService() { diff --git a/app/src/main/java/info/nightscout/androidaps/PreferencesActivity.java b/app/src/main/java/info/nightscout/androidaps/PreferencesActivity.java index d3d52298aa..c5d8769639 100644 --- a/app/src/main/java/info/nightscout/androidaps/PreferencesActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/PreferencesActivity.java @@ -21,9 +21,14 @@ import info.nightscout.androidaps.plugins.NSClientInternal.NSClientInternalPlugi import info.nightscout.androidaps.plugins.OpenAPSAMA.OpenAPSAMAPlugin; import info.nightscout.androidaps.plugins.PumpDanaRv2.DanaRv2Plugin; 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.Wear.WearPlugin; import info.nightscout.androidaps.plugins.XDripStatusline.StatuslinePlugin; import info.nightscout.utils.LocaleHelper; +import info.nightscout.utils.OKDialog; +import info.nightscout.utils.SP; public class PreferencesActivity extends PreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener { MyPreferenceFragment myPreferenceFragment; @@ -43,10 +48,13 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre String lang = sharedPreferences.getString("language", "en"); LocaleHelper.setLocale(getApplicationContext(), lang); recreate(); - MainApp.bus().post(new EventRefreshGui(true)); + MainApp.bus().post(new EventRefreshGui()); } if (key.equals("short_tabtitles")) { - MainApp.bus().post(new EventRefreshGui(true)); + MainApp.bus().post(new EventRefreshGui()); + } + if (key.equals("openapsama_useautosens") && SP.getBoolean("openapsama_useautosens", false)) { + OKDialog.show(this, MainApp.sResources.getString(R.string.configbuilder_sensitivity), MainApp.sResources.getString(R.string.sensitivity_warning), null); } updatePrefSummary(myPreferenceFragment.getPreference(key)); } @@ -88,8 +96,8 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre super.onCreate(savedInstanceState); if (Config.ALLPREFERENCES) { addPreferencesFromResource(R.xml.pref_password); - addPreferencesFromResource(R.xml.pref_age); } + addPreferencesFromResource(R.xml.pref_age); addPreferencesFromResource(R.xml.pref_language); if (Config.ALLPREFERENCES) { addPreferencesFromResource(R.xml.pref_quickwizard); @@ -105,6 +113,11 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre if (MainApp.getSpecificPlugin(OpenAPSAMAPlugin.class) != null && MainApp.getSpecificPlugin(OpenAPSAMAPlugin.class).isEnabled(PluginBase.APS)) addPreferencesFromResource(R.xml.pref_openapsama); } + if (MainApp.getSpecificPlugin(SensitivityAAPSPlugin.class) != null && MainApp.getSpecificPlugin(SensitivityAAPSPlugin.class).isEnabled(PluginBase.SENSITIVITY) + || MainApp.getSpecificPlugin(SensitivityWeightedAveragePlugin.class) != null && MainApp.getSpecificPlugin(SensitivityWeightedAveragePlugin.class).isEnabled(PluginBase.SENSITIVITY)) + addPreferencesFromResource(R.xml.pref_absorption_aaps); + if (MainApp.getSpecificPlugin(SensitivityOref0Plugin.class) != null && MainApp.getSpecificPlugin(SensitivityOref0Plugin.class).isEnabled(PluginBase.SENSITIVITY)) + addPreferencesFromResource(R.xml.pref_absorption_oref0); if (Config.ALLPREFERENCES) { addPreferencesFromResource(R.xml.pref_profile); } @@ -134,8 +147,8 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre addPreferencesFromResource(R.xml.pref_smscommunicator); if (Config.ALLPREFERENCES) { addPreferencesFromResource(R.xml.pref_others); - addPreferencesFromResource(R.xml.pref_advanced); } + addPreferencesFromResource(R.xml.pref_advanced); if (Config.WEAR) { WearPlugin wearPlugin = (WearPlugin) MainApp.getSpecificPlugin(WearPlugin.class); diff --git a/app/src/main/java/info/nightscout/androidaps/Services/AlarmSoundService.java b/app/src/main/java/info/nightscout/androidaps/Services/AlarmSoundService.java new file mode 100644 index 0000000000..41587e79b9 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/Services/AlarmSoundService.java @@ -0,0 +1,73 @@ +package info.nightscout.androidaps.Services; + +import android.app.Service; +import android.content.Intent; +import android.content.res.AssetFileDescriptor; +import android.media.MediaPlayer; +import android.os.IBinder; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; + +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; + +public class AlarmSoundService extends Service { + private static Logger log = LoggerFactory.getLogger(AlarmSoundService.class); + + MediaPlayer player; + int resourceId = R.raw.error; + + public AlarmSoundService() { + } + + @Override + public IBinder onBind(Intent intent) { + // TODO: Return the communication channel to the service. + throw new UnsupportedOperationException("Not yet implemented"); + } + + @Override + public void onCreate() { + super.onCreate(); + log.debug("onCreate"); + } + + public int onStartCommand(Intent intent, int flags, int startId) { + if (player != null && player.isPlaying()) + player.stop(); + log.debug("onStartCommand"); + if (intent != null && intent.hasExtra("soundid")) + resourceId = intent.getIntExtra("soundid", R.raw.error); + + player = new MediaPlayer(); + AssetFileDescriptor afd = MainApp.sResources.openRawResourceFd(resourceId); + if (afd == null) + return START_STICKY; + try { + player.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength()); + afd.close(); + } catch (IOException e) { + e.printStackTrace(); + } + player.setLooping(true); // Set looping + player.setVolume(100, 100); + + try { + player.prepare(); + player.start(); + } catch (IOException e) { + e.printStackTrace(); + } + + return START_STICKY; + } + + @Override + public void onDestroy() { + player.stop(); + player.release(); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/Services/DataService.java b/app/src/main/java/info/nightscout/androidaps/Services/DataService.java index def268bd35..3b04c30d94 100644 --- a/app/src/main/java/info/nightscout/androidaps/Services/DataService.java +++ b/app/src/main/java/info/nightscout/androidaps/Services/DataService.java @@ -2,6 +2,7 @@ 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; @@ -11,10 +12,7 @@ import org.json.JSONObject; import org.slf4j.Logger; 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.db.BgReading; @@ -25,18 +23,20 @@ import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin import info.nightscout.androidaps.plugins.NSClientInternal.data.NSMbg; import info.nightscout.androidaps.plugins.NSClientInternal.data.NSSgv; import info.nightscout.androidaps.data.ProfileStore; +import info.nightscout.androidaps.plugins.NSClientInternal.data.NSSettingsStatus; import info.nightscout.androidaps.plugins.Overview.Notification; 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.ProfileNS.NSProfilePlugin; -import info.nightscout.androidaps.plugins.PumpDanaR.History.DanaRNSHistorySync; +import info.nightscout.androidaps.plugins.PumpDanaR.activities.DanaRNSHistorySync; import info.nightscout.androidaps.plugins.SmsCommunicator.events.EventNewSMS; import info.nightscout.androidaps.plugins.SourceGlimp.SourceGlimpPlugin; import info.nightscout.androidaps.plugins.SourceMM640g.SourceMM640gPlugin; import info.nightscout.androidaps.plugins.SourceNSClient.SourceNSClientPlugin; import info.nightscout.androidaps.plugins.SourceXdrip.SourceXdripPlugin; import info.nightscout.androidaps.receivers.DataReceiver; +import info.nightscout.androidaps.plugins.NSClientInternal.data.NSDeviceStatus; import info.nightscout.utils.SP; @@ -229,19 +229,27 @@ public class DataService extends IntentService { if (intent.getAction().equals(Intents.ACTION_NEW_STATUS)) { - if (Config.logIncommingData) - log.debug("Received status: " + bundles); 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); - if (ConfigBuilderPlugin.nsClientVersionCode < 121) { - Notification notification = new Notification(Notification.OLD_NSCLIENT, MainApp.sResources.getString(R.string.unsupportedclientver), Notification.URGENT); + try { + if (ConfigBuilderPlugin.nsClientVersionCode < MainApp.instance().getPackageManager().getPackageInfo(MainApp.instance().getPackageName(), 0).versionCode) { + Notification notification = new Notification(Notification.OLD_NSCLIENT, MainApp.sResources.getString(R.string.unsupportedclientver), Notification.URGENT); + MainApp.bus().post(new EventNewNotification(notification)); + } else { + MainApp.bus().post(new EventDismissNotification(Notification.OLD_NSCLIENT)); + } + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + if (ConfigBuilderPlugin.nightscoutVersionCode < Config.SUPPORTEDNSVERSION) { + Notification notification = new Notification(Notification.OLD_NS, MainApp.sResources.getString(R.string.unsupportednsversion), Notification.URGENT); MainApp.bus().post(new EventNewNotification(notification)); } else { - MainApp.bus().post(new EventDismissNotification(Notification.OLD_NSCLIENT)); + MainApp.bus().post(new EventDismissNotification(Notification.OLD_NS)); } } else { Notification notification = new Notification(Notification.OLD_NSCLIENT, MainApp.sResources.getString(R.string.unsupportedclientver), Notification.URGENT); @@ -250,18 +258,15 @@ public class DataService extends IntentService { if (bundles.containsKey("status")) { try { JSONObject statusJson = new JSONObject(bundles.getString("status")); - if (statusJson.has("settings")) { - JSONObject settings = statusJson.getJSONObject("settings"); - if (settings.has("thresholds")) { - JSONObject thresholds = settings.getJSONObject("thresholds"); - if (thresholds.has("bgTargetTop")) { - OverviewPlugin.bgTargetHigh = thresholds.getDouble("bgTargetTop"); - } - if (thresholds.has("bgTargetBottom")) { - OverviewPlugin.bgTargetLow = thresholds.getDouble("bgTargetBottom"); - } - } - } + 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) { e.printStackTrace(); } @@ -270,8 +275,8 @@ public class DataService extends IntentService { if (intent.getAction().equals(Intents.ACTION_NEW_DEVICESTATUS)) { try { if (bundles.containsKey("devicestatus")) { - String devicestatusesstring = bundles.getString("devicestatus"); JSONObject devicestatusJson = new JSONObject(bundles.getString("devicestatus")); + NSDeviceStatus.getInstance().setData(devicestatusJson); if (devicestatusJson.has("pump")) { // Objectives 0 ObjectivesPlugin.pumpStatusIsAvailableInNS = true; @@ -281,8 +286,9 @@ public class DataService extends IntentService { if (bundles.containsKey("devicestatuses")) { String devicestatusesstring = bundles.getString("devicestatuses"); JSONArray jsonArray = new JSONArray(devicestatusesstring); - if (jsonArray.length() > 0) { - JSONObject devicestatusJson = jsonArray.getJSONObject(0); + 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; @@ -500,11 +506,11 @@ public class DataService extends IntentService { MainApp.getDbHelper().createCareportalEventFromJsonIfNotExists(trJson); } - if (trJson.getString("eventType").equals(CareportalEvent.ANNOUNCEMENT)) { + if (trJson.has("eventType") && trJson.getString("eventType").equals(CareportalEvent.ANNOUNCEMENT)) { long date = trJson.getLong("mills"); - long now = new Date().getTime(); + long now = System.currentTimeMillis(); if (date > now - 15 * 60 * 1000L && trJson.has("notes")) { - Notification announcement = new Notification(Notification.ANNOUNCEMENT, trJson.getString("notes"), Notification.URGENT); + Notification announcement = new Notification(Notification.NSANNOUNCEMENT, trJson.getString("notes"), Notification.ANNOUNCEMENT, 60); MainApp.bus().post(new EventNewNotification(announcement)); } } diff --git a/app/src/main/java/info/nightscout/androidaps/Services/Intents.java b/app/src/main/java/info/nightscout/androidaps/Services/Intents.java index 1b7b0875e5..77ef5139ae 100644 --- a/app/src/main/java/info/nightscout/androidaps/Services/Intents.java +++ b/app/src/main/java/info/nightscout/androidaps/Services/Intents.java @@ -12,12 +12,17 @@ public interface Intents { String ACTION_NEW_CAL = "info.nightscout.client.NEW_CAL"; String ACTION_NEW_STATUS = "info.nightscout.client.NEW_STATUS"; String ACTION_QUEUE_STATUS = "info.nightscout.client.QUEUE_STATUS"; + String ACTION_ANNOUNCEMENT = "info.nightscout.client.ANNOUNCEMENT"; + String ACTION_ALARM = "info.nightscout.client.ALARM"; + String ACTION_URGENT_ALARM = "info.nightscout.client.URGENT_ALARM"; + String ACTION_CLEAR_ALARM = "info.nightscout.client.CLEAR_ALARM"; // App -> NSClient String ACTION_DATABASE = "info.nightscout.client.DBACCESS"; String ACTION_RESTART = "info.nightscout.client.RESTART"; String ACTION_RESEND = "info.nightscout.client.RESEND"; + String ACTION_ACK_ALARM = "info.nightscout.client.ACK_ALARM"; // xDrip -> App String RECEIVER_PERMISSION = "com.eveningoutpost.dexdrip.permissions.RECEIVE_BG_ESTIMATE"; 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 f560ad0282..00a04df4c4 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/DetailedBolusInfo.java +++ b/app/src/main/java/info/nightscout/androidaps/data/DetailedBolusInfo.java @@ -16,7 +16,7 @@ import info.nightscout.androidaps.interfaces.InsulinInterface; */ public class DetailedBolusInfo { - public long date = new Date().getTime(); + public long date = System.currentTimeMillis(); public InsulinInterface insulinInterface = MainApp.getConfigBuilder().getActiveInsulin(); public String eventType = CareportalEvent.MEALBOLUS; public double insulin = 0; @@ -28,5 +28,6 @@ public class DetailedBolusInfo { public JSONObject boluscalc = null; // additional bolus wizard info public Context context = null; // context for progress dialog public boolean addToTreatments = true; - public long pumpId = 0; // id of record if comming from pump history (not a newly created treatment) + public long pumpId = 0; // id of record if comming from pump history (not a newly created treatment) + public boolean isSMB = false; // is a Super-MicroBolus } diff --git a/app/src/main/java/info/nightscout/androidaps/data/GlucoseStatus.java b/app/src/main/java/info/nightscout/androidaps/data/GlucoseStatus.java index 68d4936460..1623028a82 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/GlucoseStatus.java +++ b/app/src/main/java/info/nightscout/androidaps/data/GlucoseStatus.java @@ -67,11 +67,11 @@ public class GlucoseStatus { @Nullable public static GlucoseStatus getGlucoseStatusData() { // load 45min - long fromtime = (long) (new Date().getTime() - 60 * 1000L * 45); + long fromtime = (long) (System.currentTimeMillis() - 60 * 1000L * 45); List data = MainApp.getDbHelper().getBgreadingsDataFromTime(fromtime, false); int sizeRecords = data.size(); - if (sizeRecords < 1 || data.get(0).date < new Date().getTime() - 7 * 60 * 1000L) { + if (sizeRecords < 1 || data.get(0).date < System.currentTimeMillis() - 7 * 60 * 1000L) { return null; } diff --git a/app/src/main/java/info/nightscout/androidaps/data/Intervals.java b/app/src/main/java/info/nightscout/androidaps/data/Intervals.java new file mode 100644 index 0000000000..108b4060e0 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/data/Intervals.java @@ -0,0 +1,90 @@ +package info.nightscout.androidaps.data; + +import android.support.annotation.Nullable; +import android.support.v4.util.LongSparseArray; + +import java.util.ArrayList; +import java.util.List; + +import info.nightscout.androidaps.interfaces.Interval; + +/** + * Created by mike on 09.05.2017. + */ + +// Zero duration means end of interval + +public abstract class Intervals { + + LongSparseArray rawData = new LongSparseArray(); // oldest at index 0 + + public synchronized Intervals reset() { + rawData = new LongSparseArray(); + return this; + } + + protected abstract void merge(); + + /** + * The List must be sorted by `T.start()` in ascending order + * + * */ + public synchronized void add(List list) { + for (T interval : list) { + rawData.put(interval.start(), interval); + } + merge(); + } + + + + public synchronized List getList() { + List list = new ArrayList<>(); + for (int i = 0; i < rawData.size(); i++) + list.add(rawData.valueAt(i)); + return list; + } + + public synchronized List getReversedList() { + List list = new ArrayList<>(); + for (int i = rawData.size() -1; i>=0; i--) + list.add(rawData.valueAt(i)); + return list; + } + + protected synchronized int binarySearch(long value) { + int lo = 0; + int hi = rawData.size() - 1; + + while (lo <= hi) { + final int mid = (lo + hi) >>> 1; + final Interval midVal = rawData.valueAt(mid); + + if (midVal.before(value)) { + lo = mid + 1; + } else if (midVal.after(value)) { + hi = mid - 1; + } else if (midVal.match(value)) { + return mid; // value found + } + } + return ~lo; // value not present + } + + public abstract T getValueByInterval(long time); + + public synchronized int size() { + return rawData.size(); + } + + public synchronized T get(int index) { + return rawData.valueAt(index); + } + + public synchronized T getReversed(int index) { + return rawData.valueAt(size() - 1 - index); + } + + + +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/data/IobTotal.java b/app/src/main/java/info/nightscout/androidaps/data/IobTotal.java index 5c89a7bec7..cd5df466f0 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/IobTotal.java +++ b/app/src/main/java/info/nightscout/androidaps/data/IobTotal.java @@ -9,17 +9,17 @@ import info.nightscout.utils.DateUtil; import info.nightscout.utils.Round; public class IobTotal { - public Double iob; - public Double activity; - public Double bolussnooze; - public Double basaliob; - public Double netbasalinsulin; - public Double hightempinsulin; + public double iob; + public double activity; + public double bolussnooze; + public double basaliob; + public double netbasalinsulin; + public double hightempinsulin; - public Double netInsulin = 0d; // for calculations from temp basals only - public Double netRatio = 0d; // net ratio at start of temp basal + public double netInsulin = 0d; // for calculations from temp basals only + public double netRatio = 0d; // net ratio at start of temp basal - public Double extendedBolusInsulin = 0d; // total insulin for extended bolus + public double extendedBolusInsulin = 0d; // total insulin for extended bolus long time; diff --git a/app/src/main/java/info/nightscout/androidaps/data/NonOverlappingIntervals.java b/app/src/main/java/info/nightscout/androidaps/data/NonOverlappingIntervals.java new file mode 100644 index 0000000000..385eeb9594 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/data/NonOverlappingIntervals.java @@ -0,0 +1,30 @@ +package info.nightscout.androidaps.data; + + +import android.support.annotation.Nullable; + +import info.nightscout.androidaps.interfaces.Interval; + +/** + * Created by adrian on 15/07/17. + */ + +public class NonOverlappingIntervals extends Intervals { + + protected synchronized void merge() { + for (int index = 0; index < rawData.size() - 1; index++) { + Interval i = rawData.valueAt(index); + long startOfNewer = rawData.valueAt(index + 1).start(); + if (i.originalEnd() > startOfNewer) { + i.cutEndTo(startOfNewer); + } + } + } + + @Nullable + public synchronized T getValueByInterval(long time) { + int index = binarySearch(time); + if (index >= 0) return rawData.valueAt(index); + return null; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/data/OverlappingIntervals.java b/app/src/main/java/info/nightscout/androidaps/data/OverlappingIntervals.java index cc03936766..608fa8d328 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/OverlappingIntervals.java +++ b/app/src/main/java/info/nightscout/androidaps/data/OverlappingIntervals.java @@ -1,99 +1,43 @@ package info.nightscout.androidaps.data; -import android.support.annotation.Nullable; -import android.support.v4.util.LongSparseArray; -import java.util.ArrayList; -import java.util.List; +import android.support.annotation.Nullable; import info.nightscout.androidaps.interfaces.Interval; /** - * Created by mike on 09.05.2017. + * Created by adrian on 15/07/17. */ -// Zero duration means end of interval +public class OverlappingIntervals extends Intervals { -public class OverlappingIntervals { + protected synchronized void merge() { + boolean needToCut = false; + long cutTime = 0; - private LongSparseArray rawData = new LongSparseArray<>(); // oldest at index 0 - - public OverlappingIntervals reset() { - rawData = new LongSparseArray<>(); - return this; - } - - public void add(T newInterval) { - rawData.put(newInterval.start(), newInterval); - merge(); - } - - public void add(List list) { - for (T interval : list) { - rawData.put(interval.start(), interval); - } - merge(); - } - - private void merge() { - for (int index = 0; index < rawData.size() - 1; index++) { - Interval i = rawData.valueAt(index); - long startOfNewer = rawData.valueAt(index + 1).start(); - if (i.originalEnd() > startOfNewer) { - i.cutEndTo(startOfNewer); + for (int index = rawData.size()-1; index > 0; index--) { //begin with newest + Interval cur = rawData.valueAt(index); + if (cur.isEndingEvent()){ + needToCut = true; + cutTime = cur.start(); + } else { + //event that is no EndingEvent might need to be stopped by an ending event + if(needToCut&&cur.end() > cutTime){ + cur.cutEndTo(cutTime); + } } } } @Nullable - public Interval getValueByInterval(long time) { - int index = binarySearch(time); - if (index >= 0) return rawData.valueAt(index); + public synchronized T getValueByInterval(long time) { + for (int index = rawData.size()-1; index > 0; index--) { //begin with newest + T cur = rawData.valueAt(index); + if (cur.match(time)){ + return cur; + } + } return null; } - public List getList() { - List list = new ArrayList<>(); - for (int i = 0; i < rawData.size(); i++) - list.add(rawData.valueAt(i)); - return list; - } - - public List getReversedList() { - List list = new ArrayList<>(); - for (int i = rawData.size() -1; i>=0; i--) - list.add(rawData.valueAt(i)); - return list; - } - - private int binarySearch(long value) { - int lo = 0; - int hi = rawData.size() - 1; - - while (lo <= hi) { - final int mid = (lo + hi) >>> 1; - final Interval midVal = rawData.valueAt(mid); - - if (midVal.before(value)) { - lo = mid + 1; - } else if (midVal.after(value)) { - hi = mid - 1; - } else if (midVal.match(value)) { - return mid; // value found - } - } - return ~lo; // value not present - } - - public int size() { - return rawData.size(); - } - - public T get(int index) { - return rawData.valueAt(index); - } - - public T getReversed(int index) { - return rawData.valueAt(size() - 1 - index); - } -} \ No newline at end of file +} 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 dd68eff35f..dc49d95455 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/Profile.java +++ b/app/src/main/java/info/nightscout/androidaps/data/Profile.java @@ -1,5 +1,7 @@ package info.nightscout.androidaps.data; +import android.support.v4.util.LongSparseArray; + import com.crashlytics.android.Crashlytics; import org.json.JSONArray; @@ -30,8 +32,11 @@ public class Profile { double dia = Constants.defaultDIA; TimeZone timeZone = TimeZone.getDefault(); JSONArray isf; + private LongSparseArray isf_v = null; // oldest at index 0 JSONArray ic; + private LongSparseArray ic_v = null; // oldest at index 0 JSONArray basal; + private LongSparseArray basal_v = null; // oldest at index 0 JSONArray targetLow; JSONArray targetHigh; @@ -112,7 +117,7 @@ public class Profile { public String log() { String ret = "\n"; for (Integer hour = 0; hour < 24; hour++) { - double value = getBasal(hour * 60 * 60); + double value = getBasal((Integer) (hour * 60 * 60)); ret += "NS basal value for " + hour + ":00 is " + value + "\n"; } ret += "NS units: " + getUnits(); @@ -120,10 +125,16 @@ public class Profile { } public JSONObject getData() { + if (!json.has("units")) + try { + json.put("units", units); + } catch (JSONException e) { + e.printStackTrace(); + } return json; } - public Double getDia() { + public double getDia() { return dia; } @@ -136,6 +147,21 @@ public class Profile { return timeZone; } + private LongSparseArray convertToSparseArray(JSONArray array) { + LongSparseArray sparse = new LongSparseArray<>(); + for (Integer index = 0; index < array.length(); index++) { + try { + JSONObject o = array.getJSONObject(index); + long tas = o.getLong("timeAsSeconds"); + Double value = o.getDouble("value"); + sparse.put(tas, value); + } catch (JSONException e) { + e.printStackTrace(); + } + } + return sparse; + } + private Double getValueToTime(JSONArray array, Integer timeAsSeconds) { Double lastValue = null; @@ -156,6 +182,21 @@ public class Profile { return lastValue; } + private Double getValueToTime(LongSparseArray array, long timeAsSeconds) { + Double lastValue = null; + + for (Integer index = 0; index < array.size(); index++) { + long tas = array.keyAt(index); + double value = array.valueAt(index); + if (lastValue == null) lastValue = value; + if (timeAsSeconds < tas) { + break; + } + lastValue = value; + } + return lastValue; + } + private String getValuesList(JSONArray array, JSONArray array2, DecimalFormat format, String units) { String retValue = ""; @@ -180,7 +221,7 @@ public class Profile { } public Double getIsf() { - return getIsf(secondsFromMidnight(new Date().getTime())); + return getIsf(secondsFromMidnight(System.currentTimeMillis())); } public Double getIsf(long time) { @@ -188,7 +229,9 @@ public class Profile { } public Double getIsf(Integer timeAsSeconds) { - return getValueToTime(isf, timeAsSeconds); + if (isf_v == null) + isf_v = convertToSparseArray(isf); + return getValueToTime(isf_v, timeAsSeconds); } public String getIsfList() { @@ -196,7 +239,7 @@ public class Profile { } public Double getIc() { - return getIc(secondsFromMidnight(new Date().getTime())); + return getIc(secondsFromMidnight(System.currentTimeMillis())); } public Double getIc(long time) { @@ -204,15 +247,17 @@ public class Profile { } public Double getIc(Integer timeAsSeconds) { - return getValueToTime(ic, timeAsSeconds); + if (ic_v == null) + ic_v = convertToSparseArray(ic); + return getValueToTime(ic_v, timeAsSeconds); } public String getIcList() { - return getValuesList(ic, null, new DecimalFormat("0.0"), getUnits() + "/U"); + return getValuesList(ic, null, new DecimalFormat("0.0"), " g/U"); } public Double getBasal() { - return getBasal(secondsFromMidnight(new Date().getTime())); + return getBasal(secondsFromMidnight(System.currentTimeMillis())); } public Double getBasal(long time) { @@ -220,7 +265,9 @@ public class Profile { } public Double getBasal(Integer timeAsSeconds) { - return getValueToTime(basal, timeAsSeconds); + if (basal_v == null) + basal_v = convertToSparseArray(basal); + return getValueToTime(basal_v, timeAsSeconds); } public String getBasalList() { @@ -255,7 +302,7 @@ public class Profile { } public Double getTargetLow() { - return getTargetLow(secondsFromMidnight(new Date().getTime())); + return getTargetLow(secondsFromMidnight(System.currentTimeMillis())); } public Double getTargetLow(long time) { @@ -267,7 +314,7 @@ public class Profile { } public Double getTargetHigh() { - return getTargetHigh(secondsFromMidnight(new Date().getTime())); + return getTargetHigh(secondsFromMidnight(System.currentTimeMillis())); } public Double getTargetHigh(long time) { @@ -285,7 +332,7 @@ public class Profile { public double getMaxDailyBasal() { Double max = 0d; for (Integer hour = 0; hour < 24; hour++) { - double value = getBasal(hour * 60 * 60); + double value = getBasal((Integer)(hour * 60 * 60)); if (value > max) max = value; } return max; diff --git a/app/src/main/java/info/nightscout/androidaps/data/ProfileIntervals.java b/app/src/main/java/info/nightscout/androidaps/data/ProfileIntervals.java index ef255ed901..3633f1079e 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/ProfileIntervals.java +++ b/app/src/main/java/info/nightscout/androidaps/data/ProfileIntervals.java @@ -19,24 +19,24 @@ public class ProfileIntervals { private LongSparseArray rawData = new LongSparseArray<>(); // oldest at index 0 - public ProfileIntervals reset() { + public synchronized ProfileIntervals reset() { rawData = new LongSparseArray<>(); return this; } - public void add(T newInterval) { + public synchronized void add(T newInterval) { rawData.put(newInterval.start(), newInterval); merge(); } - public void add(List list) { + public synchronized void add(List list) { for (T interval : list) { rawData.put(interval.start(), interval); } merge(); } - private void merge() { + private synchronized void merge() { for (int index = 0; index < rawData.size() - 1; index++) { Interval i = rawData.valueAt(index); long startOfNewer = rawData.valueAt(index + 1).start(); @@ -47,27 +47,27 @@ public class ProfileIntervals { } @Nullable - public Interval getValueToTime(long time) { + public synchronized Interval getValueToTime(long time) { int index = binarySearch(time); if (index >= 0) return rawData.valueAt(index); return null; } - public List getList() { + public synchronized List getList() { List list = new ArrayList<>(); for (int i = 0; i < rawData.size(); i++) list.add(rawData.valueAt(i)); return list; } - public List getReversedList() { + public synchronized List getReversedList() { List list = new ArrayList<>(); for (int i = rawData.size() -1; i>=0; i--) list.add(rawData.valueAt(i)); return list; } - private int binarySearch(long value) { + private synchronized int binarySearch(long value) { if (rawData.size() == 0) return -1; int lo = 0; @@ -95,15 +95,15 @@ public class ProfileIntervals { return -1; // value not present } - public int size() { + public synchronized int size() { return rawData.size(); } - public T get(int index) { + public synchronized T get(int index) { return rawData.valueAt(index); } - public T getReversed(int index) { + public synchronized T getReversed(int index) { return rawData.valueAt(size() - 1 - index); } } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/data/ProfileStore.java b/app/src/main/java/info/nightscout/androidaps/data/ProfileStore.java index 466351076b..3e2217454f 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/ProfileStore.java +++ b/app/src/main/java/info/nightscout/androidaps/data/ProfileStore.java @@ -1,6 +1,7 @@ package info.nightscout.androidaps.data; import android.support.annotation.Nullable; +import android.support.v4.util.ArrayMap; import org.json.JSONException; import org.json.JSONObject; @@ -10,6 +11,8 @@ import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.Iterator; +import info.nightscout.androidaps.Constants; + /** * Created by mike on 01.06.2017. */ @@ -17,9 +20,13 @@ import java.util.Iterator; public class ProfileStore { private static Logger log = LoggerFactory.getLogger(ProfileStore.class); private JSONObject json = null; + private String units = Constants.MGDL; + + ArrayMap cachedObjects = new ArrayMap<>(); public ProfileStore(JSONObject json) { this.json = json; + getDefaultProfile(); // initialize units } public JSONObject getData() { @@ -33,10 +40,14 @@ public class ProfileStore { String defaultProfileName = json.getString("defaultProfile"); JSONObject store = json.getJSONObject("store"); if (store.has(defaultProfileName)) { - String units = null; - if (store.has("units")) - units = store.getString("units"); - profile = new Profile(store.getJSONObject(defaultProfileName), units); + profile = cachedObjects.get(defaultProfileName); + if (profile == null) { + if (store.has("units")) + units = store.getString("units"); + profile = new Profile(store.getJSONObject(defaultProfileName), units); + units = profile.getUnits(); + cachedObjects.put(defaultProfileName, profile); + } } } catch (JSONException e) { e.printStackTrace(); @@ -59,16 +70,24 @@ public class ProfileStore { return defaultProfileName; } + public String getUnits() { + return units; + } + @Nullable public Profile getSpecificProfile(String profileName) { Profile profile = null; try { JSONObject store = json.getJSONObject("store"); if (store.has(profileName)) { - String units = null; - if (json.has("units")) - units = json.getString("units"); - profile = new Profile(store.getJSONObject(profileName), units); + profile = cachedObjects.get(profileName); + if (profile == null) { + if (store.has("units")) + units = store.getString("units"); + profile = new Profile(store.getJSONObject(profileName), units); + units = profile.getUnits(); + cachedObjects.put(profileName, profile); + } } } catch (JSONException e) { e.printStackTrace(); 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 fa5cd00c54..cbe1850958 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/BgReading.java +++ b/app/src/main/java/info/nightscout/androidaps/db/BgReading.java @@ -69,7 +69,9 @@ public class BgReading implements DataPointWithLabelInterface { public String directionToSymbol() { String symbol = ""; - if (direction.compareTo("DoubleDown") == 0) { + if (direction == null) { + symbol = "??"; + } else if (direction.compareTo("DoubleDown") == 0) { symbol = "\u21ca"; } else if (direction.compareTo("SingleDown") == 0) { symbol = "\u2193"; @@ -158,7 +160,7 @@ public class BgReading implements DataPointWithLabelInterface { @Override public double getY() { - String units = MainApp.getConfigBuilder().getProfile().getUnits(); + String units = MainApp.getConfigBuilder().getProfileUnits(); return valueToUnits(units); } @@ -190,7 +192,7 @@ public class BgReading implements DataPointWithLabelInterface { @Override public int getColor() { - String units = MainApp.getConfigBuilder().getProfile().getUnits(); + String units = MainApp.getConfigBuilder().getProfileUnits(); Double lowLine = SP.getDouble("low_mark", 0d); Double highLine = SP.getDouble("high_mark", 0d); if (lowLine < 1) { 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 3d67abc597..f65da51176 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/CareportalEvent.java +++ b/app/src/main/java/info/nightscout/androidaps/db/CareportalEvent.java @@ -24,6 +24,7 @@ import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.Profile; 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; @@ -81,16 +82,19 @@ public class CareportalEvent implements DataPointWithLabelInterface { } public long getMillisecondsFromStart() { - return new Date().getTime() - date; + return System.currentTimeMillis() - date; } public long getHoursFromStart() { - return (new Date().getTime() - date) / (60 * 1000); + return (System.currentTimeMillis() - date) / (60 * 1000); } public String age() { - Map diff = computeDiff(date, new Date().getTime()); - return diff.get(TimeUnit.DAYS) + " " + MainApp.sResources.getString(R.string.days) + " " + diff.get(TimeUnit.HOURS) + " " + MainApp.sResources.getString(R.string.hours); + Map diff = computeDiff(date, System.currentTimeMillis()); + if (OverviewFragment.shorttextmode) + return diff.get(TimeUnit.DAYS) +"d" + diff.get(TimeUnit.HOURS) + "h"; + else + return diff.get(TimeUnit.DAYS) + " " + MainApp.sResources.getString(R.string.days) + " " + diff.get(TimeUnit.HOURS) + " " + MainApp.sResources.getString(R.string.hours); } public String log() { @@ -105,17 +109,17 @@ public class CareportalEvent implements DataPointWithLabelInterface { } //Map:{DAYS=1, HOURS=3, MINUTES=46, SECONDS=40, MILLISECONDS=0, MICROSECONDS=0, NANOSECONDS=0} - public static Map computeDiff(long date1, long date2) { + public static Map computeDiff(long date1, long date2) { long diffInMillies = date2 - date1; List units = new ArrayList(EnumSet.allOf(TimeUnit.class)); Collections.reverse(units); - Map result = new LinkedHashMap(); + Map result = new LinkedHashMap(); long milliesRest = diffInMillies; - for ( TimeUnit unit : units ) { - long diff = unit.convert(milliesRest,TimeUnit.MILLISECONDS); + for (TimeUnit unit : units) { + long diff = unit.convert(milliesRest, TimeUnit.MILLISECONDS); long diffInMilliesForUnit = unit.toMillis(diff); milliesRest = milliesRest - diffInMilliesForUnit; - result.put(unit,diff); + result.put(unit, diff); } return result; } @@ -131,7 +135,7 @@ public class CareportalEvent implements DataPointWithLabelInterface { @Override public double getY() { - Profile profile = MainApp.getConfigBuilder().getProfile(); + String units = MainApp.getConfigBuilder().getProfileUnits(); if (eventType.equals(MBG)) { double mbg = 0d; try { @@ -140,13 +144,10 @@ public class CareportalEvent implements DataPointWithLabelInterface { } catch (JSONException e) { e.printStackTrace(); } - if (profile != null) - return profile.fromMgdlToUnits(mbg, profile.getUnits()); - return 0d; + return Profile.fromMgdlToUnits(mbg, units); } double glucose = 0d; - String units = Constants.MGDL; try { JSONObject object = new JSONObject(json); if (object.has("glucose")) { @@ -156,7 +157,7 @@ public class CareportalEvent implements DataPointWithLabelInterface { } catch (JSONException e) { e.printStackTrace(); } - if (profile != null && glucose != 0d) { + if (glucose != 0d) { double mmol = 0d; double mgdl = 0; if (units.equals(Constants.MGDL)) { @@ -167,7 +168,7 @@ public class CareportalEvent implements DataPointWithLabelInterface { mmol = glucose; mgdl = glucose * Constants.MMOLL_TO_MGDL; } - return profile.toUnits(mgdl, mmol, profile.getUnits()); + return Profile.toUnits(mgdl, mmol, units); } return yValue; @@ -230,7 +231,7 @@ public class CareportalEvent implements DataPointWithLabelInterface { @Override public int getColor() { if (eventType.equals(ANNOUNCEMENT)) - return 0xFFFF8C00; + return MainApp.sResources.getColor(R.color.notificationAnnouncement); if (eventType.equals(MBG)) return Color.RED; if (eventType.equals(BGCHECK)) 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 cd216ef8e0..9734456cc9 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java +++ b/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java @@ -21,7 +21,6 @@ import org.slf4j.LoggerFactory; import java.sql.SQLException; import java.util.ArrayList; -import java.util.Date; import java.util.List; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; @@ -36,14 +35,16 @@ import info.nightscout.androidaps.events.EventCareportalEventChange; import info.nightscout.androidaps.events.EventExtendedBolusChange; import info.nightscout.androidaps.events.EventNewBG; import info.nightscout.androidaps.events.EventProfileSwitchChange; -import info.nightscout.androidaps.events.EventRefreshGui; +import info.nightscout.androidaps.events.EventRefreshOverview; +import info.nightscout.androidaps.events.EventReloadProfileSwitchData; 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.events.EventTreatmentChange; import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventNewHistoryData; -import info.nightscout.androidaps.plugins.PumpDanaR.History.DanaRNSHistorySync; +import info.nightscout.androidaps.plugins.PumpDanaR.activities.DanaRNSHistorySync; +import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin; public class DatabaseHelper extends OrmLiteSqliteOpenHelper { private static Logger log = LoggerFactory.getLogger(DatabaseHelper.class); @@ -59,7 +60,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { public static final String DATABASE_CAREPORTALEVENTS = "CareportalEvents"; public static final String DATABASE_PROFILESWITCHES = "ProfileSwitches"; - private static final int DATABASE_VERSION = 7; + private static final int DATABASE_VERSION = 8; private static Long earliestDataChange = null; @@ -112,17 +113,23 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { @Override public void onUpgrade(SQLiteDatabase database, ConnectionSource connectionSource, int oldVersion, int newVersion) { try { - log.info(DatabaseHelper.class.getName(), "onUpgrade"); - TableUtils.dropTable(connectionSource, TempTarget.class, true); - TableUtils.dropTable(connectionSource, Treatment.class, true); - TableUtils.dropTable(connectionSource, BgReading.class, true); - TableUtils.dropTable(connectionSource, DanaRHistoryRecord.class, true); - TableUtils.dropTable(connectionSource, DbRequest.class, true); - TableUtils.dropTable(connectionSource, TemporaryBasal.class, true); - TableUtils.dropTable(connectionSource, ExtendedBolus.class, true); - TableUtils.dropTable(connectionSource, CareportalEvent.class, true); - TableUtils.dropTable(connectionSource, ProfileSwitch.class, true); - onCreate(database, connectionSource); + if (oldVersion == 7 && newVersion == 8) { + log.debug("Upgrading database from v7 to v8"); + TableUtils.dropTable(connectionSource, Treatment.class, true); + TableUtils.createTableIfNotExists(connectionSource, Treatment.class); + } else { + log.info(DatabaseHelper.class.getName(), "onUpgrade"); + TableUtils.dropTable(connectionSource, TempTarget.class, true); + TableUtils.dropTable(connectionSource, Treatment.class, true); + TableUtils.dropTable(connectionSource, BgReading.class, true); + TableUtils.dropTable(connectionSource, DanaRHistoryRecord.class, true); + TableUtils.dropTable(connectionSource, DbRequest.class, true); + TableUtils.dropTable(connectionSource, TemporaryBasal.class, true); + TableUtils.dropTable(connectionSource, ExtendedBolus.class, true); + TableUtils.dropTable(connectionSource, CareportalEvent.class, true); + TableUtils.dropTable(connectionSource, ProfileSwitch.class, true); + onCreate(database, connectionSource); + } } catch (SQLException e) { log.error("Can't drop databases", e); throw new RuntimeException(e); @@ -140,35 +147,35 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { public void cleanUpDatabases() { // TODO: call it somewhere log.debug("Before BgReadings size: " + DatabaseUtils.queryNumEntries(getReadableDatabase(), DATABASE_BGREADINGS)); - getWritableDatabase().delete(DATABASE_BGREADINGS, "date" + " < '" + (new Date().getTime() - Constants.hoursToKeepInDatabase * 60 * 60 * 1000L) + "'", null); + getWritableDatabase().delete(DATABASE_BGREADINGS, "date" + " < '" + (System.currentTimeMillis() - Constants.hoursToKeepInDatabase * 60 * 60 * 1000L) + "'", null); log.debug("After BgReadings size: " + DatabaseUtils.queryNumEntries(getReadableDatabase(), DATABASE_BGREADINGS)); log.debug("Before TempTargets size: " + DatabaseUtils.queryNumEntries(getReadableDatabase(), DATABASE_TEMPTARGETS)); - getWritableDatabase().delete(DATABASE_TEMPTARGETS, "date" + " < '" + (new Date().getTime() - Constants.hoursToKeepInDatabase * 60 * 60 * 1000L) + "'", null); + getWritableDatabase().delete(DATABASE_TEMPTARGETS, "date" + " < '" + (System.currentTimeMillis() - Constants.hoursToKeepInDatabase * 60 * 60 * 1000L) + "'", null); log.debug("After TempTargets size: " + DatabaseUtils.queryNumEntries(getReadableDatabase(), DATABASE_TEMPTARGETS)); log.debug("Before Treatments size: " + DatabaseUtils.queryNumEntries(getReadableDatabase(), DATABASE_TREATMENTS)); - getWritableDatabase().delete(DATABASE_TREATMENTS, "date" + " < '" + (new Date().getTime() - Constants.hoursToKeepInDatabase * 60 * 60 * 1000L) + "'", null); + getWritableDatabase().delete(DATABASE_TREATMENTS, "date" + " < '" + (System.currentTimeMillis() - Constants.hoursToKeepInDatabase * 60 * 60 * 1000L) + "'", null); log.debug("After Treatments size: " + DatabaseUtils.queryNumEntries(getReadableDatabase(), DATABASE_TREATMENTS)); log.debug("Before History size: " + DatabaseUtils.queryNumEntries(getReadableDatabase(), DATABASE_DANARHISTORY)); - getWritableDatabase().delete(DATABASE_DANARHISTORY, "recordDate" + " < '" + (new Date().getTime() - Constants.daysToKeepHistoryInDatabase * 24 * 60 * 60 * 1000L) + "'", null); + getWritableDatabase().delete(DATABASE_DANARHISTORY, "recordDate" + " < '" + (System.currentTimeMillis() - Constants.daysToKeepHistoryInDatabase * 24 * 60 * 60 * 1000L) + "'", null); log.debug("After History size: " + DatabaseUtils.queryNumEntries(getReadableDatabase(), DATABASE_DANARHISTORY)); log.debug("Before TemporaryBasals size: " + DatabaseUtils.queryNumEntries(getReadableDatabase(), DATABASE_TEMPORARYBASALS)); - getWritableDatabase().delete(DATABASE_TEMPORARYBASALS, "recordDate" + " < '" + (new Date().getTime() - Constants.daysToKeepHistoryInDatabase * 24 * 60 * 60 * 1000L) + "'", null); + getWritableDatabase().delete(DATABASE_TEMPORARYBASALS, "recordDate" + " < '" + (System.currentTimeMillis() - Constants.daysToKeepHistoryInDatabase * 24 * 60 * 60 * 1000L) + "'", null); log.debug("After TemporaryBasals size: " + DatabaseUtils.queryNumEntries(getReadableDatabase(), DATABASE_TEMPORARYBASALS)); log.debug("Before ExtendedBoluses size: " + DatabaseUtils.queryNumEntries(getReadableDatabase(), DATABASE_EXTENDEDBOLUSES)); - getWritableDatabase().delete(DATABASE_EXTENDEDBOLUSES, "recordDate" + " < '" + (new Date().getTime() - Constants.daysToKeepHistoryInDatabase * 24 * 60 * 60 * 1000L) + "'", null); + getWritableDatabase().delete(DATABASE_EXTENDEDBOLUSES, "recordDate" + " < '" + (System.currentTimeMillis() - Constants.daysToKeepHistoryInDatabase * 24 * 60 * 60 * 1000L) + "'", null); log.debug("After ExtendedBoluses size: " + DatabaseUtils.queryNumEntries(getReadableDatabase(), DATABASE_EXTENDEDBOLUSES)); log.debug("Before CareportalEvent size: " + DatabaseUtils.queryNumEntries(getReadableDatabase(), DATABASE_CAREPORTALEVENTS)); - getWritableDatabase().delete(DATABASE_CAREPORTALEVENTS, "recordDate" + " < '" + (new Date().getTime() - Constants.daysToKeepHistoryInDatabase * 24 * 60 * 60 * 1000L) + "'", null); + getWritableDatabase().delete(DATABASE_CAREPORTALEVENTS, "recordDate" + " < '" + (System.currentTimeMillis() - Constants.daysToKeepHistoryInDatabase * 24 * 60 * 60 * 1000L) + "'", null); log.debug("After CareportalEvent size: " + DatabaseUtils.queryNumEntries(getReadableDatabase(), DATABASE_CAREPORTALEVENTS)); log.debug("Before ProfileSwitch size: " + DatabaseUtils.queryNumEntries(getReadableDatabase(), DATABASE_PROFILESWITCHES)); - getWritableDatabase().delete(DATABASE_PROFILESWITCHES, "recordDate" + " < '" + (new Date().getTime() - Constants.daysToKeepHistoryInDatabase * 24 * 60 * 60 * 1000L) + "'", null); + getWritableDatabase().delete(DATABASE_PROFILESWITCHES, "recordDate" + " < '" + (System.currentTimeMillis() - Constants.daysToKeepHistoryInDatabase * 24 * 60 * 60 * 1000L) + "'", null); log.debug("After ProfileSwitch size: " + DatabaseUtils.queryNumEntries(getReadableDatabase(), DATABASE_PROFILESWITCHES)); } @@ -202,6 +209,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { } catch (SQLException e) { e.printStackTrace(); } + VirtualPumpPlugin.setFakingStatus(true); scheduleBgChange(); // trigger refresh scheduleTemporaryBasalChange(); scheduleTreatmentChange(); @@ -213,7 +221,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { new java.util.TimerTask() { @Override public void run() { - MainApp.bus().post(new EventRefreshGui(false)); + MainApp.bus().post(new EventRefreshOverview("resetDatabases")); } }, 3000 @@ -249,6 +257,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { } catch (SQLException e) { e.printStackTrace(); } + VirtualPumpPlugin.setFakingStatus(false); scheduleTemporaryBasalChange(); } @@ -402,7 +411,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { if (lastBg == null) return null; - if (lastBg.date > new Date().getTime() - 9 * 60 * 1000) + if (lastBg.date > System.currentTimeMillis() - 9 * 60 * 1000) return lastBg; return null; @@ -680,6 +689,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { treatment.insulin = trJson.has("insulin") ? trJson.getDouble("insulin") : 0d; treatment.pumpId = trJson.has("pumpId") ? trJson.getLong("pumpId") : 0; treatment._id = trJson.getString("_id"); + if (trJson.has("isSMB")) + treatment.isSMB = trJson.getBoolean("isSMB"); if (trJson.has("eventType")) { treatment.mealBolus = !trJson.get("eventType").equals("Correction Bolus"); double carbs = treatment.carbs; @@ -815,8 +826,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { public void createTemptargetFromJsonIfNotExists(JSONObject trJson) { try { - Profile profile = MainApp.getConfigBuilder().getProfile(); - String units = profile.getUnits(); + String units = MainApp.getConfigBuilder().getProfileUnits(); TempTarget tempTarget = new TempTarget(); tempTarget.date = trJson.getLong("mills"); tempTarget.durationInMinutes = trJson.getInt("duration"); @@ -940,6 +950,10 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { if (tempBasal.source == Source.NIGHTSCOUT) { old = getDaoTemporaryBasal().queryForId(tempBasal.date); if (old != null) { + if (!old.isAbsolute && tempBasal.isAbsolute) { // converted to absolute by "ns_sync_use_absolute" + // so far ignore, do not convert back because it may not be accurate + return false; + } if (!old.isEqual(tempBasal)) { long oldDate = old.date; getDaoTemporaryBasal().delete(old); // need to delete/create because date may change too @@ -1068,6 +1082,11 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { extendedBolus.durationInMinutes = trJson.getInt("duration"); extendedBolus.insulin = trJson.getDouble("originalExtendedAmount"); extendedBolus._id = trJson.getString("_id"); + if (!VirtualPumpPlugin.getFakingStatus()) { + VirtualPumpPlugin.setFakingStatus(true); + updateEarliestDataChange(0); + scheduleTemporaryBasalChange(); + } createOrUpdate(extendedBolus); } else if (trJson.has("isFakedTempBasal")) { // extended bolus end uploaded as temp basal end ExtendedBolus extendedBolus = new ExtendedBolus(); @@ -1077,6 +1096,11 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { extendedBolus.durationInMinutes = 0; extendedBolus.insulin = 0; extendedBolus._id = trJson.getString("_id"); + if (!VirtualPumpPlugin.getFakingStatus()) { + VirtualPumpPlugin.setFakingStatus(true); + updateEarliestDataChange(0); + scheduleTemporaryBasalChange(); + } createOrUpdate(extendedBolus); } else { TemporaryBasal tempBasal = new TemporaryBasal(); @@ -1153,7 +1177,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { getDaoExtendedBolus().create(extendedBolus); log.debug("EXTENDEDBOLUS: New record from: " + Source.getString(extendedBolus.source) + " " + extendedBolus.toString()); updateEarliestDataChange(extendedBolus.date); - scheduleTreatmentChange(); + scheduleExtendedBolusChange(); return true; } if (extendedBolus.source == Source.NIGHTSCOUT) { @@ -1167,7 +1191,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { log.debug("EXTENDEDBOLUS: Updating record by date from: " + Source.getString(extendedBolus.source) + " " + old.toString()); updateEarliestDataChange(oldDate); updateEarliestDataChange(old.date); - scheduleTreatmentChange(); + scheduleExtendedBolusChange(); return true; } return false; @@ -1189,7 +1213,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { log.debug("EXTENDEDBOLUS: Updating record by _id from: " + Source.getString(extendedBolus.source) + " " + old.toString()); updateEarliestDataChange(oldDate); updateEarliestDataChange(old.date); - scheduleTreatmentChange(); + scheduleExtendedBolusChange(); return true; } } @@ -1197,14 +1221,14 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { getDaoExtendedBolus().create(extendedBolus); log.debug("EXTENDEDBOLUS: New record from: " + Source.getString(extendedBolus.source) + " " + extendedBolus.toString()); updateEarliestDataChange(extendedBolus.date); - scheduleTreatmentChange(); + scheduleExtendedBolusChange(); return true; } if (extendedBolus.source == Source.USER) { getDaoExtendedBolus().create(extendedBolus); log.debug("EXTENDEDBOLUS: New record from: " + Source.getString(extendedBolus.source) + " " + extendedBolus.toString()); updateEarliestDataChange(extendedBolus.date); - scheduleTreatmentChange(); + scheduleExtendedBolusChange(); return true; } } catch (SQLException e) { @@ -1248,6 +1272,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { scheduleExtendedBolusChange(); } } + public ExtendedBolus findExtendedBolusById(String _id) { try { QueryBuilder queryBuilder = null; @@ -1504,7 +1529,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { old.copyFrom(profileSwitch); getDaoProfileSwitch().create(old); log.debug("PROFILESWITCH: Updating record by date from: " + Source.getString(profileSwitch.source) + " " + old.toString()); - scheduleTemporaryTargetChange(); + scheduleProfileSwitchChange(); return true; } return false; @@ -1523,20 +1548,20 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { old.copyFrom(profileSwitch); getDaoProfileSwitch().create(old); log.debug("PROFILESWITCH: Updating record by _id from: " + Source.getString(profileSwitch.source) + " " + old.toString()); - scheduleTemporaryTargetChange(); + scheduleProfileSwitchChange(); return true; } } } getDaoProfileSwitch().create(profileSwitch); log.debug("PROFILESWITCH: New record from: " + Source.getString(profileSwitch.source) + " " + profileSwitch.toString()); - scheduleTemporaryTargetChange(); + scheduleProfileSwitchChange(); return true; } if (profileSwitch.source == Source.USER) { getDaoProfileSwitch().create(profileSwitch); log.debug("PROFILESWITCH: New record from: " + Source.getString(profileSwitch.source) + " " + profileSwitch.toString()); - scheduleTemporaryTargetChange(); + scheduleProfileSwitchChange(); return true; } } catch (SQLException e) { @@ -1558,6 +1583,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { class PostRunnable implements Runnable { public void run() { log.debug("Firing EventProfileSwitchChange"); + MainApp.bus().post(new EventReloadProfileSwitchData()); MainApp.bus().post(new EventProfileSwitchChange()); scheduledProfileSwitchEventPost = 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 d422a94211..32a9eca24c 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/ExtendedBolus.java +++ b/app/src/main/java/info/nightscout/androidaps/db/ExtendedBolus.java @@ -139,7 +139,7 @@ public class ExtendedBolus implements Interval, DataPointWithLabelInterface { @Override public boolean isInProgress() { - return match(new Date().getTime()); + return match(System.currentTimeMillis()); } @Override @@ -171,31 +171,27 @@ public class ExtendedBolus implements Interval, DataPointWithLabelInterface { public IobTotal iobCalc(long time) { IobTotal result = new IobTotal(time); - Profile profile = MainApp.getConfigBuilder().getProfile(time); InsulinInterface insulinInterface = ConfigBuilderPlugin.getActiveInsulin(); - if (profile == null) - return result; - int realDuration = getDurationToTime(time); if (realDuration > 0) { - Double dia_ago = time - profile.getDia() * 60 * 60 * 1000; + double dia_ago = time - dia * 60 * 60 * 1000; int aboutFiveMinIntervals = (int) Math.ceil(realDuration / 5d); double spacing = realDuration / aboutFiveMinIntervals; - for (Long j = 0L; j < aboutFiveMinIntervals; j++) { + for (long j = 0L; j < aboutFiveMinIntervals; j++) { // find middle of the interval - Long calcdate = (long) (date + j * spacing * 60 * 1000 + 0.5d * spacing * 60 * 1000); + long calcdate = (long) (date + j * spacing * 60 * 1000 + 0.5d * spacing * 60 * 1000); if (calcdate > dia_ago && calcdate <= time) { double tempBolusSize = absoluteRate() * spacing / 60d; - Treatment tempBolusPart = new Treatment(insulinInterface); + Treatment tempBolusPart = new Treatment(insulinInterface, dia); tempBolusPart.insulin = tempBolusSize; tempBolusPart.date = calcdate; - Iob aIOB = insulinInterface.iobCalcForTreatment(tempBolusPart, time, profile.getDia()); + Iob aIOB = insulinInterface.iobCalcForTreatment(tempBolusPart, time, dia); result.iob += aIOB.iobContrib; result.activity += aIOB.activityContrib; result.extendedBolusInsulin += tempBolusPart.insulin; @@ -206,7 +202,7 @@ public class ExtendedBolus implements Interval, DataPointWithLabelInterface { } public int getRealDuration() { - return getDurationToTime(new Date().getTime()); + return getDurationToTime(System.currentTimeMillis()); } private int getDurationToTime(long time) { @@ -216,7 +212,7 @@ public class ExtendedBolus implements Interval, DataPointWithLabelInterface { } public int getPlannedRemainingMinutes() { - float remainingMin = (end() - new Date().getTime()) / 1000f / 60; + float remainingMin = (end() - System.currentTimeMillis()) / 1000f / 60; return (remainingMin < 0) ? 0 : Math.round(remainingMin); } 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 448f6cdd51..fb99934382 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/ProfileSwitch.java +++ b/app/src/main/java/info/nightscout/androidaps/db/ProfileSwitch.java @@ -5,12 +5,15 @@ import android.graphics.Color; import com.j256.ormlite.field.DatabaseField; import com.j256.ormlite.table.DatabaseTable; +import org.json.JSONException; +import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Date; import java.util.Objects; +import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.interfaces.Interval; import info.nightscout.androidaps.plugins.Overview.graphExtensions.DataPointWithLabelInterface; import info.nightscout.androidaps.plugins.Overview.graphExtensions.PointsWithLabelGraphSeries; @@ -50,6 +53,18 @@ public class ProfileSwitch implements Interval, DataPointWithLabelInterface { @DatabaseField public int durationInMinutes = 0; + private Profile profile = null; + + public Profile getProfileObject() { + if (profile == null) + try { + profile = new Profile(new JSONObject(profileJson)); + } catch (JSONException e) { + e.printStackTrace(); + } + return profile; + } + public boolean isEqual(ProfileSwitch other) { if (date != other.date) { return false; @@ -133,7 +148,7 @@ public class ProfileSwitch implements Interval, DataPointWithLabelInterface { @Override public boolean isInProgress() { - return match(new Date().getTime()); + return match(System.currentTimeMillis()); } @Override @@ -187,7 +202,7 @@ public class ProfileSwitch implements Interval, DataPointWithLabelInterface { return Color.CYAN; } - public String log() { + public String toString() { return "ProfileSwitch{" + "date=" + date + "date=" + DateUtil.dateAndTimeString(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 7afe994437..3bbdcbc06c 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/TempTarget.java +++ b/app/src/main/java/info/nightscout/androidaps/db/TempTarget.java @@ -51,7 +51,7 @@ public class TempTarget implements Interval { return false; if (high != other.high) return false; - if (reason != other.reason) + if (!Objects.equals(reason, other.reason)) return false; if (!Objects.equals(_id, other._id)) return false; @@ -115,7 +115,7 @@ public class TempTarget implements Interval { @Override public boolean isInProgress() { - return match(new Date().getTime()); + return match(System.currentTimeMillis()); } @Override 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 4bf668411d..751e679699 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/TemporaryBasal.java +++ b/app/src/main/java/info/nightscout/androidaps/db/TemporaryBasal.java @@ -10,6 +10,7 @@ import java.util.Date; import java.util.Objects; import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.Iob; import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.Profile; @@ -18,6 +19,7 @@ import info.nightscout.androidaps.interfaces.Interval; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; +import info.nightscout.utils.SP; /** * Created by mike on 21.05.2017. @@ -45,11 +47,16 @@ public class TemporaryBasal implements Interval { public int durationInMinutes = 0; // duration == 0 means end of temp basal @DatabaseField public boolean isAbsolute = false; + + public boolean isFakeExtended = false; + @DatabaseField public int percentRate = 0; @DatabaseField public double absoluteRate = 0d; + public double netExtendedRate = 0d; + public TemporaryBasal() { } @@ -65,6 +72,8 @@ public class TemporaryBasal implements Interval { this._id = extendedBolus._id; this.durationInMinutes = extendedBolus.durationInMinutes; this.isAbsolute = true; + this.isFakeExtended = true; + this.netExtendedRate = extendedBolus.absoluteRate(); this.absoluteRate = basal + extendedBolus.absoluteRate(); } @@ -94,6 +103,10 @@ public class TemporaryBasal implements Interval { return false; if (absoluteRate != other.absoluteRate) return false; + if (netExtendedRate != other.netExtendedRate) + return false; + if (isFakeExtended != other.isFakeExtended) + return false; if (pumpId != other.pumpId) return false; if (!Objects.equals(_id, other._id)) @@ -109,6 +122,8 @@ public class TemporaryBasal implements Interval { percentRate = t.percentRate; absoluteRate = t.absoluteRate; pumpId = t.pumpId; + isFakeExtended = t.isFakeExtended; + netExtendedRate = t.netExtendedRate; } // -------- Interval interface --------- @@ -159,7 +174,7 @@ public class TemporaryBasal implements Interval { @Override public boolean isInProgress() { - return match(new Date().getTime()); + return match(System.currentTimeMillis()); } @Override @@ -170,23 +185,29 @@ public class TemporaryBasal implements Interval { // -------- Interval interface end --------- public IobTotal iobCalc(long time) { + + if(isFakeExtended){ + log.error("iobCalc should only be called on Extended boluses separately"); + return new IobTotal(time); + } + IobTotal result = new IobTotal(time); Profile profile = MainApp.getConfigBuilder().getProfile(time); InsulinInterface insulinInterface = ConfigBuilderPlugin.getActiveInsulin(); int realDuration = getDurationToTime(time); - Double netBasalAmount = 0d; + double netBasalAmount = 0d; if (realDuration > 0) { - Double netBasalRate = 0d; - - Double dia_ago = time - profile.getDia() * 60 * 60 * 1000; + double netBasalRate = 0d; + double dia = profile.getDia(); + double dia_ago = time - dia * 60 * 60 * 1000; int aboutFiveMinIntervals = (int) Math.ceil(realDuration / 5d); double tempBolusSpacing = realDuration / aboutFiveMinIntervals; - for (Long j = 0L; j < aboutFiveMinIntervals; j++) { + for (long j = 0L; j < aboutFiveMinIntervals; j++) { // find middle of the interval - Long calcdate = (long) (date + j * tempBolusSpacing * 60 * 1000 + 0.5d * tempBolusSpacing * 60 * 1000); + long calcdate = (long) (date + j * tempBolusSpacing * 60 * 1000 + 0.5d * tempBolusSpacing * 60 * 1000); Double basalRate = profile.getBasal(calcdate); @@ -202,11 +223,11 @@ public class TemporaryBasal implements Interval { double tempBolusSize = netBasalRate * tempBolusSpacing / 60d; netBasalAmount += tempBolusSize; - Treatment tempBolusPart = new Treatment(insulinInterface); + Treatment tempBolusPart = new Treatment(insulinInterface, dia); tempBolusPart.insulin = tempBolusSize; tempBolusPart.date = calcdate; - Iob aIOB = insulinInterface.iobCalcForTreatment(tempBolusPart, time, profile.getDia()); + Iob aIOB = insulinInterface.iobCalcForTreatment(tempBolusPart, time, dia); result.basaliob += aIOB.iobContrib; result.activity += aIOB.activityContrib; result.netbasalinsulin += tempBolusPart.insulin; @@ -222,7 +243,7 @@ public class TemporaryBasal implements Interval { } public int getRealDuration() { - return getDurationToTime(new Date().getTime()); + return getDurationToTime(System.currentTimeMillis()); } private int getDurationToTime(long time) { @@ -232,13 +253,16 @@ public class TemporaryBasal implements Interval { } public int getPlannedRemainingMinutes() { - float remainingMin = (end() - new Date().getTime()) / 1000f / 60; + float remainingMin = (end() - System.currentTimeMillis()) / 1000f / 60; return (remainingMin < 0) ? 0 : Math.round(remainingMin); } public double tempBasalConvertedToAbsolute(long time) { - if (isAbsolute) return absoluteRate; - else { + if(isFakeExtended){ + return MainApp.getConfigBuilder().getProfile(time).getBasal(time) + netExtendedRate; + } else if (isAbsolute) { + return absoluteRate; + } else { return MainApp.getConfigBuilder().getProfile(time).getBasal(time) * percentRate / 100; } } @@ -254,35 +278,97 @@ public class TemporaryBasal implements Interval { ", absoluteRate=" + absoluteRate + ", durationInMinutes=" + durationInMinutes + ", isAbsolute=" + isAbsolute + + ", isFakeExtended=" + isFakeExtended + + ", netExtendedRate=" + netExtendedRate + '}'; } public String toStringFull() { - if (isAbsolute) { + if(isFakeExtended){ + + Profile profile = MainApp.getConfigBuilder().getProfile(); + Double currentBasalRate = profile.getBasal(); + 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) { return DecimalFormatter.to2Decimal(absoluteRate) + "U/h @" + DateUtil.timeString(date) + - " " + getRealDuration() + "/" + durationInMinutes + "min"; + " " + getRealDuration() + "/" + durationInMinutes + "'"; } else { // percent return percentRate + "% @" + DateUtil.timeString(date) + - " " + getRealDuration() + "/" + durationInMinutes + "min"; + " " + getRealDuration() + "/" + durationInMinutes + "'"; } } public String toStringShort() { - if (isAbsolute) { - return DecimalFormatter.to2Decimal(absoluteRate) + "U/h "; + if (isAbsolute || isFakeExtended) { + + double rate = 0d; + if (isFakeExtended) { + Profile profile = MainApp.getConfigBuilder().getProfile(); + Double currentBasalRate = profile.getBasal(); + 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) { + double basal = profile.getBasal(); + if(basal != 0){ + return Math.round(rate*100d/basal) + "% "; + } + } + } + return DecimalFormatter.to2Decimal(rate) + "U/h "; } else { // percent return percentRate + "% "; } } - public String toStringMedium() { - if (isAbsolute) { - return DecimalFormatter.to2Decimal(absoluteRate) + "U/h (" - + getRealDuration() + "/" + durationInMinutes + ") "; + private String getCalcuatedPercentageIfNeeded(){ + if (isAbsolute || isFakeExtended) { + + double rate = 0d; + if (isFakeExtended) { + Profile profile = MainApp.getConfigBuilder().getProfile(); + Double currentBasalRate = profile.getBasal(); + 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) { + double basal = profile.getBasal(); + if(basal != 0){ + return Math.round(rate*100d/basal) + "% "; + } + } + } + } + return ""; + } + + public String toStringVeryShort() { + if (isAbsolute || isFakeExtended) { + + double rate = 0d; + if (isFakeExtended) { + Profile profile = MainApp.getConfigBuilder().getProfile(); + Double currentBasalRate = profile.getBasal(); + rate = (currentBasalRate == null)?0d:(currentBasalRate+netExtendedRate); + } else if (isAbsolute){ + rate = absoluteRate; + } + return DecimalFormatter.to2Decimal(rate) + "U/h "; } else { // percent - return percentRate + "% (" + getRealDuration() + "/" + durationInMinutes + ") "; + return percentRate + "% "; } } diff --git a/app/src/main/java/info/nightscout/androidaps/db/Treatment.java b/app/src/main/java/info/nightscout/androidaps/db/Treatment.java index e386a195b8..722b534c7d 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/Treatment.java +++ b/app/src/main/java/info/nightscout/androidaps/db/Treatment.java @@ -47,6 +47,8 @@ public class Treatment implements DataPointWithLabelInterface { public double carbs = 0d; @DatabaseField public boolean mealBolus = true; // true for meal bolus , false for correction bolus + @DatabaseField + public boolean isSMB = false; @DatabaseField public int insulinInterfaceID = InsulinInterface.FASTACTINGINSULIN; @@ -65,8 +67,13 @@ public class Treatment implements DataPointWithLabelInterface { dia = insulin.getDia(); } + public Treatment(InsulinInterface insulin, double dia) { + insulinInterfaceID = insulin.getId(); + this.dia = dia; + } + public long getMillisecondsFromStart() { - return new Date().getTime() - date; + return System.currentTimeMillis() - date; } public String toString() { @@ -74,6 +81,7 @@ public class Treatment implements DataPointWithLabelInterface { "date= " + date + ", date= " + DateUtil.dateAndTimeString(date) + ", isValid= " + isValid + + ", isSMB= " + isSMB + ", _id= " + _id + ", pumpId= " + pumpId + ", insulin= " + insulin + @@ -105,6 +113,8 @@ public class Treatment implements DataPointWithLabelInterface { return false; if (pumpId != other.pumpId) return false; + if (isSMB != other.isSMB) + return false; if (!Objects.equals(_id, other._id)) return false; return true; @@ -117,6 +127,7 @@ public class Treatment implements DataPointWithLabelInterface { carbs = t.carbs; mealBolus = t.mealBolus; pumpId = t.pumpId; + isSMB = t.isSMB; } // ----------------- DataPointInterface -------------------- diff --git a/app/src/main/java/info/nightscout/androidaps/events/EventRefreshGui.java b/app/src/main/java/info/nightscout/androidaps/events/EventRefreshGui.java index cb57c361fc..f20dfb9329 100644 --- a/app/src/main/java/info/nightscout/androidaps/events/EventRefreshGui.java +++ b/app/src/main/java/info/nightscout/androidaps/events/EventRefreshGui.java @@ -4,15 +4,4 @@ package info.nightscout.androidaps.events; * Created by mike on 13.06.2016. */ public class EventRefreshGui { - - public boolean isSwitchToLast() { - return switchToLast; - } - - private final boolean switchToLast; - - public EventRefreshGui(boolean switchToLast){ - this.switchToLast = switchToLast; - } - } diff --git a/app/src/main/java/info/nightscout/androidaps/events/EventRefreshOverview.java b/app/src/main/java/info/nightscout/androidaps/events/EventRefreshOverview.java new file mode 100644 index 0000000000..bf14f5f585 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/events/EventRefreshOverview.java @@ -0,0 +1,13 @@ +package info.nightscout.androidaps.events; + +/** + * Created by mike on 16.06.2017. + */ + +public class EventRefreshOverview { + public String from; + + public EventRefreshOverview(String from) { + this.from = from; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/events/EventReloadProfileSwitchData.java b/app/src/main/java/info/nightscout/androidaps/events/EventReloadProfileSwitchData.java new file mode 100644 index 0000000000..20073a7cf0 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/events/EventReloadProfileSwitchData.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.events; + +/** + * Created by mike on 12.06.2017. + */ + +public class EventReloadProfileSwitchData { +} diff --git a/app/src/main/java/info/nightscout/androidaps/interfaces/DanaRInterface.java b/app/src/main/java/info/nightscout/androidaps/interfaces/DanaRInterface.java new file mode 100644 index 0000000000..abd1d8e304 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/interfaces/DanaRInterface.java @@ -0,0 +1,9 @@ +package info.nightscout.androidaps.interfaces; + +/** + * Created by mike on 12.06.2017. + */ + +public interface DanaRInterface { + boolean loadHistory(byte type); +} 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 ba4faf4ba6..bf5e66f2a1 100644 --- a/app/src/main/java/info/nightscout/androidaps/interfaces/PluginBase.java +++ b/app/src/main/java/info/nightscout/androidaps/interfaces/PluginBase.java @@ -8,7 +8,7 @@ import java.util.Date; public interface PluginBase { int GENERAL = 1; int TREATMENT = 2; - //int TEMPBASAL = 3; + int SENSITIVITY = 3; int PROFILE = 4; int APS = 5; int PUMP = 6; diff --git a/app/src/main/java/info/nightscout/androidaps/interfaces/ProfileInterface.java b/app/src/main/java/info/nightscout/androidaps/interfaces/ProfileInterface.java index 64fffa3e57..e3b368fe86 100644 --- a/app/src/main/java/info/nightscout/androidaps/interfaces/ProfileInterface.java +++ b/app/src/main/java/info/nightscout/androidaps/interfaces/ProfileInterface.java @@ -10,5 +10,6 @@ import info.nightscout.androidaps.data.ProfileStore; public interface ProfileInterface { @Nullable ProfileStore getProfile(); + String getUnits(); String getProfileName(); } 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 dbbdec2ce1..bb78ea1d0a 100644 --- a/app/src/main/java/info/nightscout/androidaps/interfaces/PumpInterface.java +++ b/app/src/main/java/info/nightscout/androidaps/interfaces/PumpInterface.java @@ -34,7 +34,9 @@ public interface PumpInterface { PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes); PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes); PumpEnactResult setExtendedBolus(Double insulin, Integer durationInMinutes); - PumpEnactResult cancelTempBasal(); + //some pumps might set a very short temp close to 100% as canecelling a temp can be noisy + //when the cancel request is requested by the user, the pump should always do a real cancel + PumpEnactResult cancelTempBasal(boolean userRequested); PumpEnactResult cancelExtendedBolus(); // Status to be passed to NS diff --git a/app/src/main/java/info/nightscout/androidaps/interfaces/SensitivityInterface.java b/app/src/main/java/info/nightscout/androidaps/interfaces/SensitivityInterface.java new file mode 100644 index 0000000000..deb649c21f --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/interfaces/SensitivityInterface.java @@ -0,0 +1,11 @@ +package info.nightscout.androidaps.interfaces; + +import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensResult; + +/** + * Created by mike on 24.06.2017. + */ + +public interface SensitivityInterface { + AutosensResult detectSensitivity(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 d9e3742c70..5e8b4e52e8 100644 --- a/app/src/main/java/info/nightscout/androidaps/interfaces/TreatmentsInterface.java +++ b/app/src/main/java/info/nightscout/androidaps/interfaces/TreatmentsInterface.java @@ -10,7 +10,7 @@ import info.nightscout.androidaps.db.ProfileSwitch; import info.nightscout.androidaps.db.TempTarget; import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.db.Treatment; -import info.nightscout.androidaps.data.OverlappingIntervals; +import info.nightscout.androidaps.data.Intervals; import info.nightscout.androidaps.data.ProfileIntervals; /** @@ -42,18 +42,18 @@ public interface TreatmentsInterface { TemporaryBasal getTempBasalFromHistory(long time); double getTempBasalAbsoluteRateHistory(); double getTempBasalRemainingMinutesFromHistory(); - OverlappingIntervals getTemporaryBasalsFromHistory(); + Intervals getTemporaryBasalsFromHistory(); boolean isInHistoryExtendedBoluslInProgress(); ExtendedBolus getExtendedBolusFromHistory(long time); - OverlappingIntervals getExtendedBolusesFromHistory(); + Intervals getExtendedBolusesFromHistory(); boolean addToHistoryExtendedBolus(ExtendedBolus extendedBolus); boolean addToHistoryTreatment(DetailedBolusInfo detailedBolusInfo); TempTarget getTempTargetFromHistory(long time); - OverlappingIntervals getTempTargetsFromHistory(); + Intervals getTempTargetsFromHistory(); ProfileSwitch getProfileSwitchFromHistory(long time); ProfileIntervals getProfileSwitchesFromHistory(); 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 77e5b40250..c6b278955f 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 @@ -16,28 +16,28 @@ import com.crashlytics.android.answers.Answers; import com.crashlytics.android.answers.CustomEvent; import com.squareup.otto.Subscribe; -import java.util.Date; - import info.nightscout.androidaps.Config; 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.events.EventExtendedBolusChange; import info.nightscout.androidaps.events.EventInitializationChanged; -import info.nightscout.androidaps.events.EventRefreshGui; +import info.nightscout.androidaps.events.EventRefreshOverview; import info.nightscout.androidaps.events.EventTempBasalChange; import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.plugins.Actions.dialogs.FillDialog; import info.nightscout.androidaps.plugins.Actions.dialogs.NewExtendedBolusDialog; import info.nightscout.androidaps.plugins.Actions.dialogs.NewTempBasalDialog; +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.PumpDanaRv2.DanaRv2Plugin; +import info.nightscout.androidaps.plugins.Common.SubscriberFragment; /** * A simple {@link Fragment} subclass. */ -public class ActionsFragment extends Fragment implements View.OnClickListener { +public class ActionsFragment extends SubscriberFragment implements View.OnClickListener { static ActionsPlugin actionsPlugin = new ActionsPlugin(); @@ -50,6 +50,7 @@ public class ActionsFragment extends Fragment implements View.OnClickListener { Button extendedBolus; Button extendedBolusCancel; Button tempBasal; + Button tempBasalCancel; Button fill; private static Handler sHandler; @@ -75,6 +76,7 @@ public class ActionsFragment extends Fragment implements View.OnClickListener { extendedBolus = (Button) view.findViewById(R.id.actions_extendedbolus); extendedBolusCancel = (Button) view.findViewById(R.id.actions_extendedbolus_cancel); tempBasal = (Button) view.findViewById(R.id.actions_settempbasal); + tempBasalCancel = (Button) view.findViewById(R.id.actions_canceltempbasal); fill = (Button) view.findViewById(R.id.actions_fill); profileSwitch.setOnClickListener(this); @@ -82,77 +84,93 @@ public class ActionsFragment extends Fragment implements View.OnClickListener { extendedBolus.setOnClickListener(this); extendedBolusCancel.setOnClickListener(this); tempBasal.setOnClickListener(this); + tempBasalCancel.setOnClickListener(this); fill.setOnClickListener(this); - updateGUIIfVisible(); + updateGUI(); return view; } - @Override - public void onPause() { - super.onPause(); - MainApp.bus().unregister(this); - } - - @Override - public void onResume() { - super.onResume(); - MainApp.bus().register(this); - } - @Subscribe public void onStatusEvent(final EventInitializationChanged ev) { - updateGUIIfVisible(); + updateGUI(); } @Subscribe - public void onStatusEvent(final EventRefreshGui ev) { - updateGUIIfVisible(); + public void onStatusEvent(final EventRefreshOverview ev) { + updateGUI(); } @Subscribe public void onStatusEvent(final EventExtendedBolusChange ev) { - updateGUIIfVisible(); + updateGUI(); } @Subscribe public void onStatusEvent(final EventTempBasalChange ev) { - updateGUIIfVisible(); + updateGUI(); } - void updateGUIIfVisible() { + @Override + protected void updateGUI() { Activity activity = getActivity(); if (activity != null) activity.runOnUiThread(new Runnable() { @Override public void run() { - if (MainApp.getConfigBuilder().getActiveProfileInterface().getProfile() == null) + if (MainApp.getConfigBuilder().getActiveProfileInterface().getProfile() == null) { + tempTarget.setVisibility(View.GONE); + profileSwitch.setVisibility(View.GONE); + extendedBolus.setVisibility(View.GONE); + extendedBolusCancel.setVisibility(View.GONE); + tempBasal.setVisibility(View.GONE); + tempBasalCancel.setVisibility(View.GONE); + fill.setVisibility(View.GONE); return; + } boolean allowProfileSwitch = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile().getProfileList().size() > 1; if (!MainApp.getConfigBuilder().getPumpDescription().isSetBasalProfileCapable || !MainApp.getConfigBuilder().isInitialized() || MainApp.getConfigBuilder().isSuspended() || !allowProfileSwitch) profileSwitch.setVisibility(View.GONE); else profileSwitch.setVisibility(View.VISIBLE); - if (!MainApp.getConfigBuilder().getPumpDescription().isExtendedBolusCapable || !MainApp.getConfigBuilder().isInitialized() || MainApp.getConfigBuilder().isSuspended() || MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress() || MainApp.getConfigBuilder().isFakingTempsByExtendedBoluses()) + + + if (!MainApp.getConfigBuilder().getPumpDescription().isExtendedBolusCapable || !MainApp.getConfigBuilder().isInitialized() || MainApp.getConfigBuilder().isSuspended() || MainApp.getConfigBuilder().isFakingTempsByExtendedBoluses()) { extendedBolus.setVisibility(View.GONE); - else { - extendedBolus.setVisibility(View.VISIBLE); - } - if (!MainApp.getConfigBuilder().getPumpDescription().isExtendedBolusCapable || !MainApp.getConfigBuilder().isInitialized() || MainApp.getConfigBuilder().isSuspended() || !MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress() || MainApp.getConfigBuilder().isFakingTempsByExtendedBoluses()) extendedBolusCancel.setVisibility(View.GONE); - else { - extendedBolusCancel.setVisibility(View.VISIBLE); - ExtendedBolus running = MainApp.getConfigBuilder().getExtendedBolusFromHistory(new Date().getTime()); - extendedBolusCancel.setText(MainApp.instance().getString(R.string.cancel) + " " + running.toString()); + } else { + if (MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) { + extendedBolus.setVisibility(View.GONE); + extendedBolusCancel.setVisibility(View.VISIBLE); + ExtendedBolus running = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()); + extendedBolusCancel.setText(MainApp.instance().getString(R.string.cancel) + " " + running.toString()); + } else { + extendedBolus.setVisibility(View.VISIBLE); + extendedBolusCancel.setVisibility(View.GONE); + } } - if (!MainApp.getConfigBuilder().getPumpDescription().isTempBasalCapable || !MainApp.getConfigBuilder().isInitialized() || MainApp.getConfigBuilder().isSuspended() || MainApp.getConfigBuilder().isTempBasalInProgress()) + + + if (!MainApp.getConfigBuilder().getPumpDescription().isTempBasalCapable || !MainApp.getConfigBuilder().isInitialized() || MainApp.getConfigBuilder().isSuspended()) { tempBasal.setVisibility(View.GONE); - else - tempBasal.setVisibility(View.VISIBLE); + tempBasalCancel.setVisibility(View.GONE); + } else { + if (MainApp.getConfigBuilder().isTempBasalInProgress()) { + tempBasal.setVisibility(View.GONE); + tempBasalCancel.setVisibility(View.VISIBLE); + final TemporaryBasal activeTemp = MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis()); + tempBasalCancel.setText(MainApp.instance().getString(R.string.cancel) + "\n" + activeTemp.toStringShort()); + } else { + tempBasal.setVisibility(View.VISIBLE); + tempBasalCancel.setVisibility(View.GONE); + } + } + if (!MainApp.getConfigBuilder().getPumpDescription().isRefillingCapable || !MainApp.getConfigBuilder().isInitialized() || MainApp.getConfigBuilder().isSuspended()) fill.setVisibility(View.GONE); else fill.setVisibility(View.VISIBLE); + if (!Config.APS) tempTarget.setVisibility(View.GONE); else @@ -169,16 +187,16 @@ public class ActionsFragment extends Fragment implements View.OnClickListener { switch (view.getId()) { case R.id.actions_profileswitch: NewNSTreatmentDialog newDialog = new NewNSTreatmentDialog(); - final OptionsToShow profileswitch = new OptionsToShow(R.id.careportal_profileswitch, R.string.careportal_profileswitch, true, false, false, false, false, false, false, true, false, false); + final OptionsToShow profileswitch = CareportalFragment.profileswitch; profileswitch.executeProfileSwitch = true; - newDialog.setOptions(profileswitch); + newDialog.setOptions(profileswitch, R.string.careportal_profileswitch); newDialog.show(manager, "NewNSTreatmentDialog"); break; case R.id.actions_temptarget: NewNSTreatmentDialog newTTDialog = new NewNSTreatmentDialog(); - final OptionsToShow temptarget = new OptionsToShow(R.id.careportal_temporarytarget, R.string.careportal_temporarytarget, false, false, false, false, true, false, false, false, false, true); + final OptionsToShow temptarget = CareportalFragment.temptarget; temptarget.executeTempTarget = true; - newTTDialog.setOptions(temptarget); + newTTDialog.setOptions(temptarget, R.string.careportal_temporarytarget); newTTDialog.show(manager, "NewNSTreatmentDialog"); break; case R.id.actions_extendedbolus: @@ -196,6 +214,17 @@ public class ActionsFragment extends Fragment implements View.OnClickListener { }); } break; + case R.id.actions_canceltempbasal: + if (MainApp.getConfigBuilder().isInHistoryRealTempBasalInProgress()) { + sHandler.post(new Runnable() { + @Override + public void run() { + pump.cancelTempBasal(true); + Answers.getInstance().logCustom(new CustomEvent("CancelTemp")); + } + }); + } + break; case R.id.actions_settempbasal: NewTempBasalDialog newTempDialog = new NewTempBasalDialog(); newTempDialog.show(manager, "NewTempDialog"); 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 51effccb86..0a379a904d 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 @@ -27,6 +27,7 @@ import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.interfaces.PumpDescription; import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.data.Profile; +import info.nightscout.utils.NumberPicker; import info.nightscout.utils.PlusMinusEditText; import info.nightscout.utils.SafeParse; @@ -35,14 +36,14 @@ public class NewTempBasalDialog extends DialogFragment implements View.OnClickLi RadioButton percentRadio; RadioButton absoluteRadio; RadioGroup basalTypeRadioGroup; - RelativeLayout typeSelectorLayout; + LinearLayout typeSelectorLayout; LinearLayout percentLayout; LinearLayout absoluteLayout; - PlusMinusEditText basalPercent; - PlusMinusEditText basalAbsolute; - PlusMinusEditText duration; + NumberPicker basalPercent; + NumberPicker basalAbsolute; + NumberPicker duration; Handler mHandler; public static HandlerThread mHandlerThread; @@ -65,22 +66,24 @@ public class NewTempBasalDialog extends DialogFragment implements View.OnClickLi percentRadio = (RadioButton) view.findViewById(R.id.overview_newtempbasal_percent_radio); basalTypeRadioGroup = (RadioGroup) view.findViewById(R.id.overview_newtempbasal_radiogroup); absoluteRadio = (RadioButton) view.findViewById(R.id.overview_newtempbasal_absolute_radio); - typeSelectorLayout = (RelativeLayout) view.findViewById(R.id.overview_newtempbasal_typeselector_layout); + typeSelectorLayout = (LinearLayout) view.findViewById(R.id.overview_newtempbasal_typeselector_layout); PumpDescription pumpDescription = MainApp.getConfigBuilder().getPumpDescription(); - basalPercent = new PlusMinusEditText(view, R.id.overview_newtempbasal_basalpercentinput, R.id.overview_newtempbasal_basalpercent_plus, R.id.overview_newtempbasal_basalpercent_minus, - 100d, 0d, (double) pumpDescription.maxTempPercent, (double) pumpDescription.tempPercentStep, new DecimalFormat("0"), true); + 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(); - Double currentBasal = profile.getBasal(); - basalAbsolute = new PlusMinusEditText(view, R.id.overview_newtempbasal_basalabsoluteinput, R.id.overview_newtempbasal_basalabsolute_plus, R.id.overview_newtempbasal_basalabsolute_minus, - currentBasal, 0d, pumpDescription.maxTempAbsolute, pumpDescription.tempAbsoluteStep, new DecimalFormat("0.00"), true); + 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); - double tempDurationStep = MainApp.getConfigBuilder().getPumpDescription().tempDurationStep; - double tempMaxDuration = MainApp.getConfigBuilder().getPumpDescription().tempMaxDuration; - duration = new PlusMinusEditText(view, R.id.overview_newtempbasal_duration, R.id.overview_newtempbasal_duration_plus, R.id.overview_newtempbasal_duration_minus, - tempDurationStep, tempDurationStep, tempMaxDuration, tempDurationStep, new DecimalFormat("0"), false); + double tempDurationStep = pumpDescription.tempDurationStep; + double tempMaxDuration = pumpDescription.tempMaxDuration; + duration = (NumberPicker) view.findViewById(R.id.overview_newtempbasal_duration); + duration.setParams(tempDurationStep, tempDurationStep, tempMaxDuration, tempDurationStep, new DecimalFormat("0"), false); if ((pumpDescription.tempBasalStyle & PumpDescription.PERCENT) == PumpDescription.PERCENT && (pumpDescription.tempBasalStyle & PumpDescription.ABSOLUTE) == PumpDescription.ABSOLUTE) { // Both allowed @@ -107,13 +110,6 @@ public class NewTempBasalDialog extends DialogFragment implements View.OnClickLi return view; } - @Override - public void onResume() { - super.onResume(); - if (getDialog() != null) - getDialog().getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); - } - @Override public void onClick(View view) { switch (view.getId()) { 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 c016f5ec61..6ddda8cd68 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 @@ -5,6 +5,7 @@ import android.app.Activity; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; +import android.text.Layout; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -12,13 +13,16 @@ import android.widget.TextView; import com.squareup.otto.Subscribe; +import info.nightscout.androidaps.BuildConfig; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; 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.Overview.OverviewFragment; -public class CareportalFragment extends Fragment implements View.OnClickListener { +public class CareportalFragment extends SubscriberFragment implements View.OnClickListener { static CareportalPlugin careportalPlugin; @@ -27,6 +31,8 @@ public class CareportalFragment extends Fragment implements View.OnClickListener TextView sage; TextView pbage; + View statsLayout; + static public CareportalPlugin getPlugin() { if (careportalPlugin == null) { careportalPlugin = new CareportalPlugin(); @@ -35,26 +41,26 @@ public class CareportalFragment extends Fragment implements View.OnClickListener } // bg,insulin,carbs,prebolus,duration,percent,absolute,profile,split,temptarget - static final OptionsToShow bgcheck = new OptionsToShow(R.id.careportal_bgcheck, R.string.careportal_bgcheck, true, true, true, false, false, false, false, false, false, false); - static final OptionsToShow snackbolus = new OptionsToShow(R.id.careportal_snackbolus, R.string.careportal_snackbolus, true, true, true, true, false, false, false, false, false, false); - static final OptionsToShow mealbolus = new OptionsToShow(R.id.careportal_mealbolus, R.string.careportal_mealbolus, true, true, true, true, false, false, false, false, false, false); - static final OptionsToShow correctionbolus = new OptionsToShow(R.id.careportal_correctionbolus, R.string.careportal_correctionbolus, true, true, true, true, false, false, false, false, false, false); - static final OptionsToShow carbcorrection = new OptionsToShow(R.id.careportal_carbscorrection, R.string.careportal_carbscorrection, true, false, true, false, false, false, false, false, false, false); - static final OptionsToShow combobolus = new OptionsToShow(R.id.careportal_combobolus, R.string.careportal_combobolus, true, true, true, true, true, false, false, false, true, false); - static final OptionsToShow announcement = new OptionsToShow(R.id.careportal_announcement, R.string.careportal_announcement, true, false, false, false, false, false, false, false, false, false); - static final OptionsToShow note = new OptionsToShow(R.id.careportal_note, R.string.careportal_note, true, false, false, false, true, false, false, false, false, false); - static final OptionsToShow question = new OptionsToShow(R.id.careportal_question, R.string.careportal_question, true, false, false, false, false, false, false, false, false, false); - static final OptionsToShow exercise = new OptionsToShow(R.id.careportal_exercise, R.string.careportal_exercise, false, false, false, false, true, false, false, false, false, false); - static final OptionsToShow sitechange = new OptionsToShow(R.id.careportal_pumpsitechange, R.string.careportal_pumpsitechange, true, true, false, false, false, false, false, false, false, false); - static final OptionsToShow sensorstart = new OptionsToShow(R.id.careportal_cgmsensorstart, R.string.careportal_cgmsensorstart, true, false, false, false, false, false, false, false, false, false); - static final OptionsToShow sensorchange = new OptionsToShow(R.id.careportal_cgmsensorinsert, R.string.careportal_cgmsensorinsert, true, false, false, false, false, false, false, false, false, false); - static final OptionsToShow insulinchange = new OptionsToShow(R.id.careportal_insulincartridgechange, R.string.careportal_insulincartridgechange, true, false, false, false, false, false, false, false, false, false); - static final OptionsToShow pumpbatterychange = new OptionsToShow(R.id.careportal_pumpbatterychange, R.string.careportal_pumpbatterychange, true, false, false, false, false, false, false, false, false, false); - static final OptionsToShow tempbasalstart = new OptionsToShow(R.id.careportal_tempbasalstart, R.string.careportal_tempbasalstart, true, false, false, false, true, true, true, false, false, false); - static final OptionsToShow tempbasalend = new OptionsToShow(R.id.careportal_tempbasalend, R.string.careportal_tempbasalend, true, false, false, false, false, false, false, false, false, false); - static final OptionsToShow profileswitch = new OptionsToShow(R.id.careportal_profileswitch, R.string.careportal_profileswitch, true, false, false, false, true, false, false, true, false, false); - static final OptionsToShow openapsoffline = new OptionsToShow(R.id.careportal_openapsoffline, R.string.careportal_openapsoffline, false, false, false, false, true, false, false, false, false, false); - static final OptionsToShow temptarget = new OptionsToShow(R.id.careportal_temporarytarget, R.string.careportal_temporarytarget, false, false, false, false, true, false, false, false, false, true); + public static final OptionsToShow bgcheck = new OptionsToShow(R.id.careportal_bgcheck, R.string.careportal_bgcheck, true, true, true, false, false, false, false, false, false, false); + public static final OptionsToShow snackbolus = new OptionsToShow(R.id.careportal_snackbolus, R.string.careportal_snackbolus, true, true, true, true, false, false, false, false, false, false); + public static final OptionsToShow mealbolus = new OptionsToShow(R.id.careportal_mealbolus, R.string.careportal_mealbolus, true, true, true, true, false, false, false, false, false, false); + public static final OptionsToShow correctionbolus = new OptionsToShow(R.id.careportal_correctionbolus, R.string.careportal_correctionbolus, true, true, true, true, false, false, false, false, false, false); + public static final OptionsToShow carbcorrection = new OptionsToShow(R.id.careportal_carbscorrection, R.string.careportal_carbscorrection, true, false, true, false, false, false, false, false, false, false); + public static final OptionsToShow combobolus = new OptionsToShow(R.id.careportal_combobolus, R.string.careportal_combobolus, true, true, true, true, true, false, false, false, true, false); + public static final OptionsToShow announcement = new OptionsToShow(R.id.careportal_announcement, R.string.careportal_announcement, true, false, false, false, false, false, false, false, false, false); + public static final OptionsToShow note = new OptionsToShow(R.id.careportal_note, R.string.careportal_note, true, false, false, false, true, false, false, false, false, false); + public static final OptionsToShow question = new OptionsToShow(R.id.careportal_question, R.string.careportal_question, true, false, false, false, false, false, false, false, false, false); + public static final OptionsToShow exercise = new OptionsToShow(R.id.careportal_exercise, R.string.careportal_exercise, false, false, false, false, true, false, false, false, false, false); + public static final OptionsToShow sitechange = new OptionsToShow(R.id.careportal_pumpsitechange, R.string.careportal_pumpsitechange, true, true, false, false, false, false, false, false, false, false); + public static final OptionsToShow sensorstart = new OptionsToShow(R.id.careportal_cgmsensorstart, R.string.careportal_cgmsensorstart, true, false, false, false, false, false, false, false, false, false); + public static final OptionsToShow sensorchange = new OptionsToShow(R.id.careportal_cgmsensorinsert, R.string.careportal_cgmsensorinsert, true, false, false, false, false, false, false, false, false, false); + public static final OptionsToShow insulinchange = new OptionsToShow(R.id.careportal_insulincartridgechange, R.string.careportal_insulincartridgechange, true, false, false, false, false, false, false, false, false, false); + public static final OptionsToShow pumpbatterychange = new OptionsToShow(R.id.careportal_pumpbatterychange, R.string.careportal_pumpbatterychange, true, false, false, false, false, false, false, false, false, false); + public static final OptionsToShow tempbasalstart = new OptionsToShow(R.id.careportal_tempbasalstart, R.string.careportal_tempbasalstart, true, false, false, false, true, true, true, false, false, false); + public static final OptionsToShow tempbasalend = new OptionsToShow(R.id.careportal_tempbasalend, R.string.careportal_tempbasalend, true, false, false, false, false, false, false, false, false, false); + public static final OptionsToShow profileswitch = new OptionsToShow(R.id.careportal_profileswitch, R.string.careportal_profileswitch, true, false, false, false, true, false, false, true, false, false); + public static final OptionsToShow openapsoffline = new OptionsToShow(R.id.careportal_openapsoffline, R.string.careportal_openapsoffline, false, false, false, false, true, false, false, false, false, false); + public static final OptionsToShow temptarget = new OptionsToShow(R.id.careportal_temporarytarget, R.string.careportal_temporarytarget, false, false, false, false, true, false, false, false, false, true); @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, @@ -87,6 +93,11 @@ public class CareportalFragment extends Fragment implements View.OnClickListener sage = (TextView) view.findViewById(R.id.careportal_sensorage); pbage = (TextView) view.findViewById(R.id.careportal_pbage); + statsLayout = (View) view.findViewById(R.id.careportal_stats); + + if (BuildConfig.NSCLIENTOLNY) + statsLayout.setVisibility(View.GONE); // visible on overview + updateGUI(); return view; } @@ -100,64 +111,66 @@ public class CareportalFragment extends Fragment implements View.OnClickListener NewNSTreatmentDialog newDialog = new NewNSTreatmentDialog(); switch (id) { case R.id.careportal_bgcheck: - newDialog.setOptions(bgcheck); + newDialog.setOptions(bgcheck, R.string.careportal_bgcheck); break; case R.id.careportal_announcement: - newDialog.setOptions(announcement); + newDialog.setOptions(announcement, R.string.careportal_announcement); break; case R.id.careportal_cgmsensorinsert: - newDialog.setOptions(sensorchange); + newDialog.setOptions(sensorchange, R.string.careportal_cgmsensorinsert); break; case R.id.careportal_cgmsensorstart: - newDialog.setOptions(sensorstart); + newDialog.setOptions(sensorstart, R.string.careportal_cgmsensorstart); break; case R.id.careportal_combobolus: - newDialog.setOptions(combobolus); + newDialog.setOptions(combobolus, R.string.careportal_combobolus); break; case R.id.careportal_correctionbolus: - newDialog.setOptions(correctionbolus); + newDialog.setOptions(correctionbolus, R.string.careportal_correctionbolus); break; case R.id.careportal_carbscorrection: - newDialog.setOptions(carbcorrection); + newDialog.setOptions(carbcorrection, R.string.careportal_carbscorrection); break; case R.id.careportal_exercise: - newDialog.setOptions(exercise); + newDialog.setOptions(exercise, R.string.careportal_exercise); break; case R.id.careportal_insulincartridgechange: - newDialog.setOptions(insulinchange); + newDialog.setOptions(insulinchange, R.string.careportal_insulincartridgechange); break; case R.id.careportal_pumpbatterychange: - newDialog.setOptions(pumpbatterychange); + newDialog.setOptions(pumpbatterychange, R.string.careportal_pumpbatterychange); break; case R.id.careportal_mealbolus: - newDialog.setOptions(mealbolus); + newDialog.setOptions(mealbolus, R.string.careportal_mealbolus); break; case R.id.careportal_note: - newDialog.setOptions(note); + newDialog.setOptions(note, R.string.careportal_note); break; case R.id.careportal_profileswitch: - newDialog.setOptions(profileswitch); + profileswitch.executeProfileSwitch = false; + newDialog.setOptions(profileswitch, R.string.careportal_profileswitch); break; case R.id.careportal_pumpsitechange: - newDialog.setOptions(sitechange); + newDialog.setOptions(sitechange, R.string.careportal_pumpsitechange); break; case R.id.careportal_question: - newDialog.setOptions(question); + newDialog.setOptions(question, R.string.careportal_question); break; case R.id.careportal_snackbolus: - newDialog.setOptions(snackbolus); + newDialog.setOptions(snackbolus, R.string.careportal_snackbolus); break; case R.id.careportal_tempbasalstart: - newDialog.setOptions(tempbasalstart); + newDialog.setOptions(tempbasalstart, R.string.careportal_tempbasalstart); break; case R.id.careportal_tempbasalend: - newDialog.setOptions(tempbasalend); + newDialog.setOptions(tempbasalend, R.string.careportal_tempbasalend); break; case R.id.careportal_openapsoffline: - newDialog.setOptions(openapsoffline); + newDialog.setOptions(openapsoffline, R.string.careportal_openapsoffline); break; case R.id.careportal_temporarytarget: - newDialog.setOptions(temptarget); + temptarget.executeTempTarget = false; + newDialog.setOptions(temptarget, R.string.careportal_temporarytarget); break; default: newDialog = null; @@ -166,24 +179,13 @@ public class CareportalFragment extends Fragment implements View.OnClickListener newDialog.show(manager, "NewNSTreatmentDialog"); } - @Override - public void onPause() { - super.onPause(); - MainApp.bus().unregister(this); - } - - @Override - public void onResume() { - super.onResume(); - MainApp.bus().register(this); - } - @Subscribe public void onStatusEvent(final EventCareportalEventChange c) { updateGUI(); } - void updateGUI() { + @Override + protected void updateGUI() { Activity activity = getActivity(); updateAge(activity, sage, iage, cage, pbage); } @@ -195,21 +197,22 @@ public class CareportalFragment extends Fragment implements View.OnClickListener @Override public void run() { CareportalEvent careportalEvent; + String notavailable = OverviewFragment.shorttextmode ? "-" : MainApp.sResources.getString(R.string.notavailable); if (sage != null) { careportalEvent = MainApp.getDbHelper().getLastCareportalEvent(CareportalEvent.SENSORCHANGE); - sage.setText(careportalEvent != null ? careportalEvent.age() : MainApp.sResources.getString(R.string.notavailable)); + sage.setText(careportalEvent != null ? careportalEvent.age() : notavailable); } if (iage != null) { careportalEvent = MainApp.getDbHelper().getLastCareportalEvent(CareportalEvent.INSULINCHANGE); - iage.setText(careportalEvent != null ? careportalEvent.age() : MainApp.sResources.getString(R.string.notavailable)); + iage.setText(careportalEvent != null ? careportalEvent.age() : notavailable); } if (cage != null) { careportalEvent = MainApp.getDbHelper().getLastCareportalEvent(CareportalEvent.SITECHANGE); - cage.setText(careportalEvent != null ? careportalEvent.age() : MainApp.sResources.getString(R.string.notavailable)); + cage.setText(careportalEvent != null ? careportalEvent.age() : notavailable); } if (pbage != null) { careportalEvent = MainApp.getDbHelper().getLastCareportalEvent(CareportalEvent.PUMPBATTERYCHANGE); - pbage.setText(careportalEvent != null ? careportalEvent.age() : MainApp.sResources.getString(R.string.notavailable)); + pbage.setText(careportalEvent != null ? careportalEvent.age() : notavailable); } } } 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 f1e5f09ebd..b10ab5dab8 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 @@ -15,12 +15,10 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; -import android.widget.Button; import android.widget.CompoundButton; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.RadioButton; -import android.widget.RelativeLayout; import android.widget.Spinner; import android.widget.TextView; @@ -44,6 +42,8 @@ import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.GlucoseStatus; +import info.nightscout.androidaps.data.Profile; +import info.nightscout.androidaps.data.ProfileStore; import info.nightscout.androidaps.db.CareportalEvent; import info.nightscout.androidaps.db.ProfileSwitch; import info.nightscout.androidaps.db.Source; @@ -52,12 +52,10 @@ import info.nightscout.androidaps.events.EventNewBasalProfile; import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.plugins.Careportal.OptionsToShow; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; -import info.nightscout.androidaps.data.Profile; -import info.nightscout.androidaps.data.ProfileStore; import info.nightscout.androidaps.plugins.ProfileCircadianPercentage.CircadianPercentageProfilePlugin; import info.nightscout.utils.DateUtil; import info.nightscout.utils.NSUpload; -import info.nightscout.utils.PlusMinusEditText; +import info.nightscout.utils.NumberPicker; import info.nightscout.utils.SP; import info.nightscout.utils.SafeParse; import info.nightscout.utils.Translator; @@ -68,53 +66,44 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick private Activity context; private static OptionsToShow options; + private static String event; Profile profile; ProfileStore profileStore; String units; - RelativeLayout layoutBg; + TextView eventTypeText; + LinearLayout layoutBg; LinearLayout layoutBgSource; - RelativeLayout layoutInsulin; - RelativeLayout layoutCarbs; - RelativeLayout layoutSplit; - RelativeLayout layoutDuration; - RelativeLayout layoutPercent; - RelativeLayout layoutAbsolute; - RelativeLayout layoutCarbTime; - RelativeLayout layoutProfile; + LinearLayout layoutInsulin; + LinearLayout layoutCarbs; + LinearLayout layoutSplit; + LinearLayout layoutDuration; + LinearLayout layoutPercent; + LinearLayout layoutAbsolute; + LinearLayout layoutCarbTime; + LinearLayout layoutProfile; LinearLayout layoutTempTarget; - Button dateButton; - Button timeButton; - Button okButton; - Button cancelButton; + TextView dateButton; + TextView timeButton; TextView bgUnitsView; RadioButton meterRadioButton; RadioButton sensorRadioButton; RadioButton otherRadioButton; EditText notesEdit; - EditText bgInputEdit; - EditText insulinEdit; - EditText carbsEdit; - EditText percentEdit; - EditText absoluteEdit; - EditText durationeEdit; - EditText carbTimeEdit; - EditText splitEdit; Spinner profileSpinner; - EditText low; - EditText high; Spinner reasonSpinner; - PlusMinusEditText editBg; - PlusMinusEditText editCarbs; - PlusMinusEditText editInsulin; - PlusMinusEditText editSplit; - PlusMinusEditText editDuration; - PlusMinusEditText editPercent; - PlusMinusEditText editAbsolute; - PlusMinusEditText editCarbTime; + NumberPicker editBg; + NumberPicker editCarbs; + NumberPicker editInsulin; + NumberPicker editSplit; + NumberPicker editDuration; + NumberPicker editPercent; + NumberPicker editAbsolute; + NumberPicker editCarbTime; + NumberPicker editTemptarget; Date eventTime; @@ -122,8 +111,9 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick private static HandlerThread sHandlerThread; - public void setOptions(OptionsToShow options) { + public void setOptions(OptionsToShow options, int event) { this.options = options; + this.event = MainApp.sResources.getString(event); } public NewNSTreatmentDialog() { @@ -141,6 +131,12 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick super.onAttach(activity); } + @Override + public void onDetach() { + super.onDetach(); + this.context = null; + } + @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { @@ -148,91 +144,46 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick setStyle(DialogFragment.STYLE_NORMAL, getTheme()); View view = inflater.inflate(R.layout.careportal_newnstreatment_dialog, container, false); - layoutBg = (RelativeLayout) view.findViewById(R.id.careportal_newnstreatment_bg_layout); + layoutBg = (LinearLayout) view.findViewById(R.id.careportal_newnstreatment_bg_layout); layoutBgSource = (LinearLayout) view.findViewById(R.id.careportal_newnstreatment_bgsource_layout); - layoutInsulin = (RelativeLayout) view.findViewById(R.id.careportal_newnstreatment_insulin_layout); - layoutCarbs = (RelativeLayout) view.findViewById(R.id.careportal_newnstreatment_carbs_layout); - layoutSplit = (RelativeLayout) view.findViewById(R.id.careportal_newnstreatment_split_layout); - layoutDuration = (RelativeLayout) view.findViewById(R.id.careportal_newnstreatment_duration_layout); - layoutPercent = (RelativeLayout) view.findViewById(R.id.careportal_newnstreatment_percent_layout); - layoutAbsolute = (RelativeLayout) view.findViewById(R.id.careportal_newnstreatment_absolute_layout); - layoutCarbTime = (RelativeLayout) view.findViewById(R.id.careportal_newnstreatment_carbtime_layout); - layoutProfile = (RelativeLayout) view.findViewById(R.id.careportal_newnstreatment_profile_layout); + layoutInsulin = (LinearLayout) view.findViewById(R.id.careportal_newnstreatment_insulin_layout); + layoutCarbs = (LinearLayout) view.findViewById(R.id.careportal_newnstreatment_carbs_layout); + layoutSplit = (LinearLayout) view.findViewById(R.id.careportal_newnstreatment_split_layout); + layoutDuration = (LinearLayout) view.findViewById(R.id.careportal_newnstreatment_duration_layout); + layoutPercent = (LinearLayout) view.findViewById(R.id.careportal_newnstreatment_percent_layout); + layoutAbsolute = (LinearLayout) view.findViewById(R.id.careportal_newnstreatment_absolute_layout); + layoutCarbTime = (LinearLayout) view.findViewById(R.id.careportal_newnstreatment_carbtime_layout); + layoutProfile = (LinearLayout) view.findViewById(R.id.careportal_newnstreatment_profile_layout); layoutTempTarget = (LinearLayout) view.findViewById(R.id.careportal_newnstreatment_temptarget_layout); + eventTypeText = (TextView) view.findViewById(R.id.careportal_newnstreatment_eventtype); + eventTypeText.setText(event); bgUnitsView = (TextView) view.findViewById(R.id.careportal_newnstreatment_bgunits); meterRadioButton = (RadioButton) view.findViewById(R.id.careportal_newnstreatment_meter); sensorRadioButton = (RadioButton) view.findViewById(R.id.careportal_newnstreatment_sensor); otherRadioButton = (RadioButton) view.findViewById(R.id.careportal_newnstreatment_other); profileSpinner = (Spinner) view.findViewById(R.id.careportal_newnstreatment_profile); - bgInputEdit = (EditText) view.findViewById(R.id.careportal_newnstreatment_bginput); - insulinEdit = (EditText) view.findViewById(R.id.careportal_newnstreatment_insulininput); - carbsEdit = (EditText) view.findViewById(R.id.careportal_newnstreatment_carbsinput); - percentEdit = (EditText) view.findViewById(R.id.careportal_newnstreatment_percentinput); - percentEdit.addTextChangedListener(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) { - layoutPercent.setVisibility(View.VISIBLE); - layoutAbsolute.setVisibility(View.GONE); - } - }); - absoluteEdit = (EditText) view.findViewById(R.id.careportal_newnstreatment_absoluteinput); - absoluteEdit.addTextChangedListener(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) { - layoutPercent.setVisibility(View.GONE); - layoutAbsolute.setVisibility(View.VISIBLE); - } - }); - durationeEdit = (EditText) view.findViewById(R.id.careportal_newnstreatment_durationinput); - carbTimeEdit = (EditText) view.findViewById(R.id.careportal_newnstreatment_carbtimeinput); notesEdit = (EditText) view.findViewById(R.id.careportal_newnstreatment_notes); - splitEdit = (EditText) view.findViewById(R.id.careportal_newnstreatment_splitinput); reasonSpinner = (Spinner) view.findViewById(R.id.careportal_newnstreatment_temptarget_reason); - low = (EditText) view.findViewById(R.id.careportal_temptarget_low); - high = (EditText) view.findViewById(R.id.careportal_temptarget_high); eventTime = new Date(); - dateButton = (Button) view.findViewById(R.id.careportal_newnstreatment_eventdate); - timeButton = (Button) view.findViewById(R.id.careportal_newnstreatment_eventtime); + dateButton = (TextView) view.findViewById(R.id.careportal_newnstreatment_eventdate); + timeButton = (TextView) view.findViewById(R.id.careportal_newnstreatment_eventtime); dateButton.setText(DateUtil.dateString(eventTime)); timeButton.setText(DateUtil.timeString(eventTime)); dateButton.setOnClickListener(this); timeButton.setOnClickListener(this); - okButton = (Button) view.findViewById(R.id.ok); - okButton.setOnClickListener(this); - cancelButton = (Button) view.findViewById(R.id.cancel); - cancelButton.setOnClickListener(this); + view.findViewById(R.id.ok).setOnClickListener(this); + view.findViewById(R.id.cancel).setOnClickListener(this); // profile profile = MainApp.getConfigBuilder().getProfile(); - profileStore = MainApp.getConfigBuilder().getActiveProfileInterface().getProfile(); + profileStore = ConfigBuilderPlugin.getActiveProfileInterface().getProfile(); ArrayList profileList; - units = Constants.MGDL; - units = profile.getUnits(); + units = profile != null ? profile.getUnits() : Constants.MGDL; profileList = profileStore.getProfileList(); ArrayAdapter adapter = new ArrayAdapter(getContext(), R.layout.spinner_centered, profileList); @@ -255,25 +206,20 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick // bg bgUnitsView.setText(units); - // Set BG if not old -// BgReading lastBg = MainApp.getDbHelper().lastBg(); -// Double lastBgValue = 0d; -// if (lastBg != null) { -// lastBgValue = lastBg.valueToUnits(units); -// sensorRadioButton.setChecked(true); -// } else { -// meterRadioButton.setChecked(true); -// } - Double bg = Profile.fromMgdlToUnits(GlucoseStatus.getGlucoseStatusData() != null ? GlucoseStatus.getGlucoseStatusData().glucose : 0d, profile != null ? profile.getUnits() : Constants.MGDL); - if (profile == null) - editBg = new PlusMinusEditText(view, R.id.careportal_newnstreatment_bginput, R.id.careportal_newnstreatment_bg_plus, R.id.careportal_newnstreatment_bg_minus, bg, 0d, 500d, 0.1d, new DecimalFormat("0.0"), false); - else if (profile.getUnits().equals(Constants.MMOL)) - editBg = new PlusMinusEditText(view, R.id.careportal_newnstreatment_bginput, R.id.careportal_newnstreatment_bg_plus, R.id.careportal_newnstreatment_bg_minus, bg, 0d, 30d, 0.1d, new DecimalFormat("0.0"), false); - else - editBg = new PlusMinusEditText(view, R.id.careportal_newnstreatment_bginput, R.id.careportal_newnstreatment_bg_plus, R.id.careportal_newnstreatment_bg_minus, bg, 0d, 500d, 1d, new DecimalFormat("0"), false); - bgInputEdit.addTextChangedListener(new TextWatcher() { - + 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); + editTemptarget.setParams(bg, 0d, 500d, 0.1d, new DecimalFormat("0.0"), false); + } else if (profile.getUnits().equals(Constants.MMOL)) { + editBg.setParams(bg, 0d, 30d, 0.1d, new DecimalFormat("0.0"), false); + editTemptarget.setParams(bg, 0d, 30d, 0.1d, new DecimalFormat("0.0"), false); + } else { + editBg.setParams(bg, 0d, 500d, 1d, new DecimalFormat("0"), false); + editTemptarget.setParams(bg, 0d, 500d, 1d, new DecimalFormat("0"), false); + } + editBg.addTextChangedListener(new TextWatcher() { public void afterTextChanged(Editable s) { } @@ -284,6 +230,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick if (sensorRadioButton.isChecked()) meterRadioButton.setChecked(true); } }); + sensorRadioButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { @@ -293,21 +240,63 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick }); Integer maxCarbs = MainApp.getConfigBuilder().applyCarbsConstraints(Constants.carbsOnlyForCheckLimit); - editCarbs = new PlusMinusEditText(view, R.id.careportal_newnstreatment_carbsinput, R.id.careportal_newnstreatment_carbs_plus, R.id.careportal_newnstreatment_carbs_minus, 0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false); + editCarbs = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_carbsinput); + editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false); Double maxInsulin = MainApp.getConfigBuilder().applyBolusConstraints(Constants.bolusOnlyForCheckLimit); - editInsulin = new PlusMinusEditText(view, R.id.careportal_newnstreatment_insulininput, R.id.careportal_newnstreatment_insulin_plus, R.id.careportal_newnstreatment_insulin_minus, 0d, 0d, maxInsulin, 0.05d, new DecimalFormat("0.00"), false); + editInsulin = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_insulininput); + editInsulin.setParams(0d, 0d, maxInsulin, 0.05d, new DecimalFormat("0.00"), false); - editSplit = new PlusMinusEditText(view, R.id.careportal_newnstreatment_splitinput, R.id.careportal_newnstreatment_split_plus, R.id.careportal_newnstreatment_split_minus, 100d, 0d, 100d, 5d, new DecimalFormat("0"), true); - editDuration = new PlusMinusEditText(view, R.id.careportal_newnstreatment_durationinput, R.id.careportal_newnstreatment_duration_plus, R.id.careportal_newnstreatment_duration_minus, 0d, 0d, 24 * 60d, 10d, new DecimalFormat("0"), false); + editSplit = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_splitinput); + editSplit.setParams(100d, 0d, 100d, 5d, new DecimalFormat("0"), true); + editDuration = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_durationinput); + editDuration.setParams(0d, 0d, 24 * 60d, 10d, new DecimalFormat("0"), false); Integer maxPercent = MainApp.getConfigBuilder().applyBasalConstraints(Constants.basalPercentOnlyForCheckLimit); - editPercent = new PlusMinusEditText(view, R.id.careportal_newnstreatment_percentinput, R.id.careportal_newnstreatment_percent_plus, R.id.careportal_newnstreatment_percent_minus, 0d, 0d, (double) maxPercent, 5d, new DecimalFormat("0"), true); + editPercent = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_percentinput); + editPercent.setParams(0d, 0d, (double) maxPercent, 5d, new DecimalFormat("0"), true); + editPercent.addTextChangedListener(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) { + layoutPercent.setVisibility(View.VISIBLE); + layoutAbsolute.setVisibility(View.GONE); + } + }); Double maxAbsolute = MainApp.getConfigBuilder().applyBasalConstraints(Constants.basalAbsoluteOnlyForCheckLimit); - editAbsolute = new PlusMinusEditText(view, R.id.careportal_newnstreatment_absoluteinput, R.id.careportal_newnstreatment_absolute_plus, R.id.careportal_newnstreatment_absolute_minus, 0d, 0d, maxAbsolute, 0.05d, new DecimalFormat("0.00"), true); + editAbsolute = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_absoluteinput); + editAbsolute.setParams(0d, 0d, maxAbsolute, 0.05d, new DecimalFormat("0.00"), true); + editAbsolute.addTextChangedListener(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) { + layoutPercent.setVisibility(View.GONE); + layoutAbsolute.setVisibility(View.VISIBLE); + } + }); + + editCarbTime = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_carbtimeinput); + editCarbTime.setParams(0d, -60d, 60d, 5d, new DecimalFormat("0"), false); - editCarbTime = new PlusMinusEditText(view, R.id.careportal_newnstreatment_carbtimeinput, R.id.careportal_newnstreatment_carbtime_plus, R.id.careportal_newnstreatment_carbtime_minus, 0d, -60d, 60d, 5d, new DecimalFormat("0"), false); showOrHide(layoutBg, options.bg); showOrHide(layoutBgSource, options.bg); @@ -324,13 +313,6 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick return view; } - @Override - public void onResume() { - super.onResume(); - if (getDialog() != null) - getDialog().getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); - } - @Override public void onClick(View view) { Calendar calendar = Calendar.getInstance(); @@ -348,7 +330,6 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick dpd.show(context.getFragmentManager(), "Datepickerdialog"); break; case R.id.careportal_newnstreatment_eventtime: - android.text.format.DateFormat df = new android.text.format.DateFormat(); TimePickerDialog tpd = TimePickerDialog.newInstance( this, calendar.get(Calendar.HOUR_OF_DAY), @@ -412,8 +393,8 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick data.put("eventType", "Sensor Start"); break; case R.id.careportal_combobolus: - data.put("splitNow", SafeParse.stringToDouble(splitEdit.getText().toString())); - data.put("splitExt", 100 - SafeParse.stringToDouble(splitEdit.getText().toString())); + data.put("splitNow", SafeParse.stringToDouble(editSplit.getText())); + data.put("splitExt", 100 - SafeParse.stringToDouble(editSplit.getText())); data.put("eventType", CareportalEvent.COMBOBOLUS); break; case R.id.careportal_correctionbolus: @@ -463,42 +444,42 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick data.put("eventType", CareportalEvent.TEMPORARYTARGET); if (!reasonSpinner.getSelectedItem().toString().equals("")) data.put("reason", reasonSpinner.getSelectedItem().toString()); - if (SafeParse.stringToDouble(low.getText().toString()) != 0d) - data.put("targetBottom", SafeParse.stringToDouble(low.getText().toString())); - if (SafeParse.stringToDouble(high.getText().toString()) != 0d) - data.put("targetTop", SafeParse.stringToDouble(high.getText().toString())); + if (SafeParse.stringToDouble(editTemptarget.getText()) != 0d) { + data.put("targetBottom", SafeParse.stringToDouble(editTemptarget.getText())); + data.put("targetTop", SafeParse.stringToDouble(editTemptarget.getText())); + } allowZeroDuration = true; break; } - if (SafeParse.stringToDouble(bgInputEdit.getText().toString()) != 0d) { - data.put("glucose", SafeParse.stringToDouble(bgInputEdit.getText().toString())); + if (SafeParse.stringToDouble(editBg.getText()) != 0d) { + data.put("glucose", SafeParse.stringToDouble(editBg.getText())); if (meterRadioButton.isChecked()) data.put("glucoseType", "Finger"); if (sensorRadioButton.isChecked()) data.put("glucoseType", "Sensor"); if (otherRadioButton.isChecked()) data.put("glucoseType", "Manual"); } - if (SafeParse.stringToDouble(carbsEdit.getText().toString()) != 0d) - data.put("carbs", SafeParse.stringToDouble(carbsEdit.getText().toString())); - if (SafeParse.stringToDouble(insulinEdit.getText().toString()) != 0d) - data.put("insulin", SafeParse.stringToDouble(insulinEdit.getText().toString())); - if (allowZeroDuration || SafeParse.stringToDouble(durationeEdit.getText().toString()) != 0d) - data.put("duration", SafeParse.stringToDouble(durationeEdit.getText().toString())); + if (SafeParse.stringToDouble(editCarbs.getText()) != 0d) + data.put("carbs", SafeParse.stringToDouble(editCarbs.getText())); + if (SafeParse.stringToDouble(editInsulin.getText()) != 0d) + data.put("insulin", SafeParse.stringToDouble(editInsulin.getText())); + if (allowZeroDuration || SafeParse.stringToDouble(editDuration.getText()) != 0d) + data.put("duration", SafeParse.stringToDouble(editDuration.getText())); if (layoutPercent.getVisibility() != View.GONE) - data.put("percent", SafeParse.stringToDouble(percentEdit.getText().toString())); + data.put("percent", SafeParse.stringToDouble(editPercent.getText())); if (layoutAbsolute.getVisibility() != View.GONE) - data.put("absolute", SafeParse.stringToDouble(absoluteEdit.getText().toString())); + data.put("absolute", SafeParse.stringToDouble(editAbsolute.getText())); if (options.profile && profileSpinner.getSelectedItem() != null) data.put("profile", profileSpinner.getSelectedItem().toString()); - if (SafeParse.stringToDouble(carbTimeEdit.getText().toString()) != 0d) - data.put("preBolus", SafeParse.stringToDouble(carbTimeEdit.getText().toString())); + if (SafeParse.stringToDouble(editCarbTime.getText()) != 0d) + data.put("preBolus", SafeParse.stringToDouble(editCarbTime.getText())); if (!notesEdit.getText().toString().equals("")) data.put("notes", notesEdit.getText().toString()); data.put("units", units); if (!enteredBy.equals("")) data.put("enteredBy", enteredBy); if (options.eventType == R.id.careportal_combobolus) { - Double enteredInsulin = SafeParse.stringToDouble(insulinEdit.getText().toString()); + Double enteredInsulin = SafeParse.stringToDouble(editInsulin.getText()); data.put("enteredinsulin", enteredInsulin); - data.put("insulin", enteredInsulin * SafeParse.stringToDouble(splitEdit.getText().toString()) / 100); - data.put("relative", enteredInsulin * (100 - SafeParse.stringToDouble(splitEdit.getText().toString())) / 100 / SafeParse.stringToDouble(durationeEdit.getText().toString()) * 60); + data.put("insulin", enteredInsulin * SafeParse.stringToDouble(editInsulin.getText()) / 100); + data.put("relative", enteredInsulin * (100 - SafeParse.stringToDouble(editSplit.getText())) / 100 / SafeParse.stringToDouble(editDuration.getText()) * 60); } } catch (JSONException e) { e.printStackTrace(); @@ -612,40 +593,11 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick public void onClick(DialogInterface dialog, int id) { if (options.executeProfileSwitch) { if (data.has("profile")) { - sHandler.post(new Runnable() { - @Override - public void run() { - try { - String profileName = data.getString("profile"); - ProfileSwitch profileSwitch = new ProfileSwitch(); - profileSwitch.date = new Date().getTime(); - profileSwitch.source = Source.PUMP; - profileSwitch.profileName = profileName; - profileSwitch.profileJson = profileStore.getSpecificProfile(profileName).toString(); - profileSwitch.profilePlugin = MainApp.getConfigBuilder().getActiveProfileInterface().getClass().getName(); - profileSwitch.durationInMinutes = data.getInt("duration"); - if (ConfigBuilderPlugin.getActiveProfileInterface() instanceof CircadianPercentageProfilePlugin) { - CircadianPercentageProfilePlugin cpp = (CircadianPercentageProfilePlugin) MainApp.getConfigBuilder().getActiveProfileInterface(); - profileSwitch.isCPP = true; - profileSwitch.timeshift = cpp.timeshift; - profileSwitch.percentage = cpp.percentage; - } - MainApp.getConfigBuilder().addToHistoryProfileSwitch(profileSwitch); - - PumpInterface pump = MainApp.getConfigBuilder(); - if (pump != null) { - pump.setNewBasalProfile(profileStore.getSpecificProfile(profileName)); - log.debug("Setting new profile: " + profile); - MainApp.bus().post(new EventNewBasalProfile()); - } else { - log.error("No active pump selected"); - } - Answers.getInstance().logCustom(new CustomEvent("ProfileSwitch")); - } catch (JSONException e) { - e.printStackTrace(); - } - } - }); + try { + doProfileSwitch(profileStore, data.getString("profile"), data.getInt("duration")); + } catch (JSONException e) { + e.printStackTrace(); + } } } else if (options.executeTempTarget) { try { @@ -689,4 +641,35 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick builder.show(); } + public static void doProfileSwitch(final ProfileStore profileStore, final String profileName, final int duration) { + sHandler.post(new Runnable() { + @Override + public void run() { + ProfileSwitch profileSwitch = new ProfileSwitch(); + profileSwitch.date = System.currentTimeMillis(); + profileSwitch.source = Source.USER; + profileSwitch.profileName = profileName; + profileSwitch.profileJson = profileStore.getSpecificProfile(profileName).getData().toString(); + profileSwitch.profilePlugin = ConfigBuilderPlugin.getActiveProfileInterface().getClass().getName(); + profileSwitch.durationInMinutes = duration; + if (ConfigBuilderPlugin.getActiveProfileInterface() instanceof CircadianPercentageProfilePlugin) { + CircadianPercentageProfilePlugin cpp = (CircadianPercentageProfilePlugin) ConfigBuilderPlugin.getActiveProfileInterface(); + profileSwitch.isCPP = true; + profileSwitch.timeshift = cpp.timeshift; + profileSwitch.percentage = cpp.percentage; + } + MainApp.getConfigBuilder().addToHistoryProfileSwitch(profileSwitch); + + PumpInterface pump = MainApp.getConfigBuilder(); + if (pump != null) { + pump.setNewBasalProfile(profileStore.getSpecificProfile(profileName)); + MainApp.bus().post(new EventNewBasalProfile()); + } else { + log.error("No active pump selected"); + } + Answers.getInstance().logCustom(new CustomEvent("ProfileSwitch")); + } + }); + } + } 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 new file mode 100644 index 0000000000..74abc837fe --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Common/SubscriberFragment.java @@ -0,0 +1,22 @@ +package info.nightscout.androidaps.plugins.Common; + +import android.support.v4.app.Fragment; + +import info.nightscout.androidaps.MainApp; + +abstract public class SubscriberFragment extends Fragment { + @Override + public void onPause() { + super.onPause(); + MainApp.bus().unregister(this); + } + + @Override + public void onResume() { + super.onResume(); + MainApp.bus().register(this); + updateGUI(); + } + + protected abstract void updateGUI(); +} 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 2445f262df..be9341b860 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 @@ -34,9 +34,11 @@ import info.nightscout.androidaps.interfaces.InsulinInterface; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.ProfileInterface; import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.interfaces.SensitivityInterface; import info.nightscout.androidaps.plugins.InsulinFastacting.InsulinFastactingPlugin; import info.nightscout.androidaps.plugins.ProfileNS.NSProfilePlugin; import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin; +import info.nightscout.androidaps.plugins.SensitivityOref0.SensitivityOref0Plugin; import info.nightscout.utils.PasswordProtection; @@ -49,6 +51,7 @@ public class ConfigBuilderFragment extends Fragment { } ListView insulinListView; + ListView sensitivityListView; ListView bgsourceListView; TextView bgsourceLabel; ListView pumpListView; @@ -64,13 +67,12 @@ public class ConfigBuilderFragment extends Fragment { ListView constraintsListView; TextView constraintsLabel; ListView generalListView; - TextView nsclientVerView; - TextView nightscoutVerView; LinearLayout mainLayout; Button unlock; PluginCustomAdapter insulinDataAdapter = null; + PluginCustomAdapter sensivityDataAdapter = null; PluginCustomAdapter bgsourceDataAdapter = null; PluginCustomAdapter pumpDataAdapter = null; PluginCustomAdapter loopDataAdapter = null; @@ -96,6 +98,7 @@ public class ConfigBuilderFragment extends Fragment { smallWidth = screen_width < Constants.SMALL_WIDTH; insulinListView = (ListView) view.findViewById(R.id.configbuilder_insulinlistview); + sensitivityListView = (ListView) view.findViewById(R.id.configbuilder_sensitivitylistview); bgsourceListView = (ListView) view.findViewById(R.id.configbuilder_bgsourcelistview); bgsourceLabel = (TextView) view.findViewById(R.id.configbuilder_bgsourcelabel); pumpListView = (ListView) view.findViewById(R.id.configbuilder_pumplistview); @@ -111,17 +114,10 @@ public class ConfigBuilderFragment extends Fragment { constraintsListView = (ListView) view.findViewById(R.id.configbuilder_constraintslistview); constraintsLabel = (TextView) view.findViewById(R.id.configbuilder_constraintslabel); generalListView = (ListView) view.findViewById(R.id.configbuilder_generallistview); - nsclientVerView = (TextView) view.findViewById(R.id.configbuilder_nsclientversion); - nightscoutVerView = (TextView) view.findViewById(R.id.configbuilder_nightscoutversion); mainLayout = (LinearLayout) view.findViewById(R.id.configbuilder_mainlayout); unlock = (Button) view.findViewById(R.id.configbuilder_unlock); - nsclientVerView.setText(ConfigBuilderPlugin.nsClientVersionName); - nightscoutVerView.setText(ConfigBuilderPlugin.nightscoutVersionName); - if (ConfigBuilderPlugin.nsClientVersionCode < 117) nsclientVerView.setTextColor(Color.RED); - if (ConfigBuilderPlugin.nightscoutVersionCode < 900) - nightscoutVerView.setTextColor(Color.RED); setViews(); if (PasswordProtection.isLocked("settings_password")) { @@ -168,7 +164,7 @@ public class ConfigBuilderFragment extends Fragment { if (MainApp.getSpecificPluginsVisibleInList(PluginBase.TREATMENT).size() == 0) treatmentsLabel.setVisibility(View.GONE); setListViewHeightBasedOnChildren(treatmentsListView); - profileDataAdapter = new PluginCustomAdapter(getContext(), smallWidth?R.layout.configbuilder_smallitem :R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInListByInterface(ProfileInterface.class, PluginBase.BGSOURCE), PluginBase.PROFILE); + profileDataAdapter = new PluginCustomAdapter(getContext(), smallWidth?R.layout.configbuilder_smallitem :R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInListByInterface(ProfileInterface.class, PluginBase.PROFILE), PluginBase.PROFILE); profileListView.setAdapter(profileDataAdapter); if (MainApp.getSpecificPluginsVisibleInList(PluginBase.PROFILE).size() == 0) profileLabel.setVisibility(View.GONE); @@ -178,7 +174,10 @@ public class ConfigBuilderFragment extends Fragment { setListViewHeightBasedOnChildren(apsListView); if (MainApp.getSpecificPluginsVisibleInList(PluginBase.APS).size() == 0) apsLabel.setVisibility(View.GONE); - constraintsDataAdapter = new PluginCustomAdapter(getContext(), smallWidth?R.layout.configbuilder_smallitem :R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInListByInterface(ConstraintsInterface.class, PluginBase.BGSOURCE), PluginBase.CONSTRAINTS); + sensivityDataAdapter = new PluginCustomAdapter(getContext(), smallWidth?R.layout.configbuilder_smallitem :R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInListByInterface(SensitivityInterface.class, PluginBase.SENSITIVITY), PluginBase.SENSITIVITY); + sensitivityListView.setAdapter(sensivityDataAdapter); + setListViewHeightBasedOnChildren(sensitivityListView); + constraintsDataAdapter = new PluginCustomAdapter(getContext(), smallWidth?R.layout.configbuilder_smallitem :R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInListByInterface(ConstraintsInterface.class, PluginBase.CONSTRAINTS), PluginBase.CONSTRAINTS); constraintsListView.setAdapter(constraintsDataAdapter); setListViewHeightBasedOnChildren(constraintsListView); if (MainApp.getSpecificPluginsVisibleInList(PluginBase.CONSTRAINTS).size() == 0) @@ -234,7 +233,7 @@ public class ConfigBuilderFragment extends Fragment { plugin.setFragmentVisible(type, cb.isChecked()); onEnabledCategoryChanged(plugin, type); configBuilderPlugin.storeSettings(); - MainApp.bus().post(new EventRefreshGui(true)); + MainApp.bus().post(new EventRefreshGui()); MainApp.bus().post(new EventConfigBuilderChange()); getPlugin().logPluginStatus(); Answers.getInstance().logCustom(new CustomEvent("ConfigurationChange")); @@ -247,7 +246,7 @@ public class ConfigBuilderFragment extends Fragment { PluginBase plugin = (PluginBase) cb.getTag(); plugin.setFragmentVisible(type, cb.isChecked()); configBuilderPlugin.storeSettings(); - MainApp.bus().post(new EventRefreshGui(true)); + MainApp.bus().post(new EventRefreshGui()); getPlugin().logPluginStatus(); } }); @@ -277,7 +276,7 @@ public class ConfigBuilderFragment extends Fragment { } // Hide enabled control and force enabled plugin if there is only one plugin available - if (type == PluginBase.INSULIN || type == PluginBase.PUMP || type == PluginBase.TREATMENT || type == PluginBase.PROFILE) + if (type == PluginBase.INSULIN || type == PluginBase.PUMP || type == PluginBase.TREATMENT || type == PluginBase.PROFILE || type == PluginBase.SENSITIVITY) if (pluginList.size() < 2) { holder.checkboxEnabled.setEnabled(false); plugin.setFragmentEnabled(type, true); @@ -326,6 +325,9 @@ public class ConfigBuilderFragment extends Fragment { case PluginBase.INSULIN: pluginsInCategory = MainApp.getSpecificPluginsListByInterface(InsulinInterface.class); break; + case PluginBase.SENSITIVITY: + pluginsInCategory = MainApp.getSpecificPluginsListByInterface(SensitivityInterface.class); + break; case PluginBase.APS: pluginsInCategory = MainApp.getSpecificPluginsListByInterface(APSInterface.class); break; @@ -356,6 +358,8 @@ public class ConfigBuilderFragment extends Fragment { MainApp.getSpecificPlugin(VirtualPumpPlugin.class).setFragmentEnabled(type, true); else if (type == PluginBase.INSULIN) MainApp.getSpecificPlugin(InsulinFastactingPlugin.class).setFragmentEnabled(type, true); + else if (type == PluginBase.SENSITIVITY) + MainApp.getSpecificPlugin(SensitivityOref0Plugin.class).setFragmentEnabled(type, true); else if (type == PluginBase.PROFILE) MainApp.getSpecificPlugin(NSProfilePlugin.class).setFragmentEnabled(type, true); else 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 b476577d06..e65e5b8445 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,6 +1,7 @@ package info.nightscout.androidaps.plugins.ConfigBuilder; import android.content.Context; +import android.content.Intent; import android.content.SharedPreferences; import android.os.PowerManager; import android.preference.PreferenceManager; @@ -22,7 +23,7 @@ import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.MealData; -import info.nightscout.androidaps.data.OverlappingIntervals; +import info.nightscout.androidaps.data.Intervals; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.ProfileIntervals; import info.nightscout.androidaps.data.PumpEnactResult; @@ -40,16 +41,19 @@ import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.ProfileInterface; import info.nightscout.androidaps.interfaces.PumpDescription; import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.interfaces.SensitivityInterface; import info.nightscout.androidaps.interfaces.TreatmentsInterface; import info.nightscout.androidaps.plugins.Loop.APSResult; import info.nightscout.androidaps.plugins.Loop.LoopPlugin; import info.nightscout.androidaps.plugins.Overview.Dialogs.BolusProgressDialog; +import info.nightscout.androidaps.plugins.Overview.Dialogs.BolusProgressHelperActivity; import info.nightscout.androidaps.plugins.Overview.Notification; 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.PumpVirtual.VirtualPumpPlugin; import info.nightscout.utils.NSUpload; +import info.nightscout.utils.SP; /** * Created by mike on 05.08.2016. @@ -64,6 +68,7 @@ public class ConfigBuilderPlugin implements PluginBase, PumpInterface, Constrain private static APSInterface activeAPS; private static LoopPlugin activeLoop; private static InsulinInterface activeInsulin; + private static SensitivityInterface activeSensitivity; static public String nightscoutVersionName = ""; static public Integer nightscoutVersionCode = 0; @@ -78,7 +83,6 @@ public class ConfigBuilderPlugin implements PluginBase, PumpInterface, Constrain MainApp.bus().register(this); PowerManager powerManager = (PowerManager) MainApp.instance().getApplicationContext().getSystemService(Context.POWER_SERVICE); mWakeLock = powerManager.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "ConfigBuilderPlugin"); - ; } @Override @@ -208,11 +212,20 @@ public class ConfigBuilderPlugin implements PluginBase, PumpInterface, Constrain return activeLoop; } + public static PumpInterface getActivePump() { + return activePump; + } + + public static SensitivityInterface getActiveSensitivity() { + return activeSensitivity; + } + void logPluginStatus() { for (PluginBase p : pluginList) { log.debug(p.getName() + ":" + (p.isEnabled(1) ? " GENERAL" : "") + (p.isEnabled(2) ? " TREATMENT" : "") + + (p.isEnabled(3) ? " SENSITIVITY" : "") + (p.isEnabled(4) ? " PROFILE" : "") + (p.isEnabled(5) ? " APS" : "") + (p.isEnabled(6) ? " PUMP" : "") + @@ -251,6 +264,17 @@ public class ConfigBuilderPlugin implements PluginBase, PumpInterface, Constrain } } + // PluginBase.SENSITIVITY + pluginsInCategory = MainApp.getSpecificPluginsListByInterface(SensitivityInterface.class); + activeSensitivity = (SensitivityInterface) getTheOneEnabledInArray(pluginsInCategory, PluginBase.SENSITIVITY); + if (Config.logConfigBuilder) + log.debug("Selected sensitivity interface: " + ((PluginBase) activeSensitivity).getName()); + for (PluginBase p : pluginsInCategory) { + if (!p.getName().equals(((PluginBase) activeSensitivity).getName())) { + p.setFragmentVisible(PluginBase.SENSITIVITY, false); + } + } + // PluginBase.PROFILE pluginsInCategory = MainApp.getSpecificPluginsListByInterface(ProfileInterface.class); activeProfile = (ProfileInterface) getTheOneEnabledInArray(pluginsInCategory, PluginBase.PROFILE); @@ -406,43 +430,6 @@ public class ConfigBuilderPlugin implements PluginBase, PumpInterface, Constrain return 0d; } - /* - public PumpEnactResult deliverTreatmentFromBolusWizard(InsulinInterface insulinType, Context context, Double insulin, Integer carbs, Double glucose, String glucoseType, int carbTime, JSONObject boluscalc) { - mWakeLock.acquire(); - PumpEnactResult result; - insulin = applyBolusConstraints(insulin); - carbs = applyCarbsConstraints(carbs); - - BolusProgressDialog bolusProgressDialog = null; - if (context != null) { - bolusProgressDialog = new BolusProgressDialog(); - bolusProgressDialog.setInsulin(insulin); - bolusProgressDialog.show(((AppCompatActivity) context).getSupportFragmentManager(), "BolusProgress"); - } - - MainApp.bus().post(new EventBolusRequested(insulin)); - - result = activePump.deliverTreatment(insulinType, insulin, carbs, context); - - BolusProgressDialog.bolusEnded = true; - - MainApp.bus().post(new EventDismissBolusprogressIfRunning(result)); - - if (result.success) { - Treatment t = new Treatment(insulinType); - t.insulin = result.bolusDelivered; - if (carbTime == 0) - t.carbs = (double) result.carbsDelivered; // with different carbTime record will come back from nightscout - t.date = new Date().getTime(); - t.mealBolus = result.carbsDelivered > 0; - addToHistoryTreatment(t); - t.carbs = (double) result.carbsDelivered; - NSUpload.uploadBolusWizardRecord(t, glucose, glucoseType, carbTime, boluscalc); - } - mWakeLock.release(); - return result; - } - */ @Override public PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo) { mWakeLock.acquire(); @@ -455,8 +442,15 @@ public class ConfigBuilderPlugin implements PluginBase, PumpInterface, Constrain bolusProgressDialog = new BolusProgressDialog(); bolusProgressDialog.setInsulin(detailedBolusInfo.insulin); bolusProgressDialog.show(((AppCompatActivity) detailedBolusInfo.context).getSupportFragmentManager(), "BolusProgress"); + } else { + Intent i = new Intent(); + i.putExtra("insulin", detailedBolusInfo.insulin); + i.setClass(MainApp.instance(), BolusProgressHelperActivity.class); + i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + MainApp.instance().startActivity(i); } + MainApp.bus().post(new EventBolusRequested(detailedBolusInfo.insulin)); result = activePump.deliverTreatment(detailedBolusInfo); @@ -468,56 +462,6 @@ public class ConfigBuilderPlugin implements PluginBase, PumpInterface, Constrain return result; } - /* - @Override - public PumpEnactResult deliverTreatment(InsulinInterface insulinType, Double insulin, Integer carbs, Context context) { - return deliverTreatment(insulinType, insulin, carbs, context, true); - } - - public PumpEnactResult deliverTreatment(InsulinInterface insulinType, Double insulin, Integer carbs, Context context, boolean createTreatment) { - mWakeLock.acquire(); - PumpEnactResult result; - insulin = applyBolusConstraints(insulin); - carbs = applyCarbsConstraints(carbs); - - BolusProgressDialog bolusProgressDialog = null; - if (context != null) { - bolusProgressDialog = new BolusProgressDialog(); - bolusProgressDialog.setInsulin(insulin); - bolusProgressDialog.show(((AppCompatActivity) context).getSupportFragmentManager(), "BolusProgress"); - } else { - Intent i = new Intent(); - i.putExtra("insulin", insulin.doubleValue()); - i.setClass(MainApp.instance(), BolusProgressHelperActivity.class); - i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - MainApp.instance().startActivity(i); - } - - MainApp.bus().post(new EventBolusRequested(insulin)); - - result = activePump.deliverTreatment(insulinType, insulin, carbs, context); - - BolusProgressDialog.bolusEnded = true; - - MainApp.bus().post(new EventDismissBolusprogressIfRunning(result)); - - if (Config.logCongigBuilderActions) - log.debug("deliverTreatment insulin: " + insulin + " carbs: " + carbs + " success: " + result.success + " enacted: " + result.enacted + " bolusDelivered: " + result.bolusDelivered); - - if (result.success && createTreatment) { - Treatment t = new Treatment(insulinType); - t.insulin = result.bolusDelivered; - t.carbs = (double) result.carbsDelivered; - t.date = new Date().getTime(); - t.mealBolus = t.carbs > 0; - addToHistoryTreatment(t); - NSUpload.uploadTreatment(t); - } - mWakeLock.release(); - return result; - } - - */ @Override public void stopBolusDelivering() { activePump.stopBolusDelivering(); @@ -565,8 +509,8 @@ public class ConfigBuilderPlugin implements PluginBase, PumpInterface, Constrain } @Override - public PumpEnactResult cancelTempBasal() { - PumpEnactResult result = activePump.cancelTempBasal(); + public PumpEnactResult cancelTempBasal(boolean userRequested) { + PumpEnactResult result = activePump.cancelTempBasal(userRequested); if (Config.logCongigBuilderActions) log.debug("cancelTempBasal success: " + result.success + " enacted: " + result.enacted); return result; @@ -615,7 +559,7 @@ public class ConfigBuilderPlugin implements PluginBase, PumpInterface, Constrain if (isTempBasalInProgress()) { if (Config.logCongigBuilderActions) log.debug("applyAPSRequest: cancelTempBasal()"); - result = cancelTempBasal(); + result = cancelTempBasal(false); } else { result = new PumpEnactResult(); result.absolute = request.rate; @@ -629,7 +573,7 @@ public class ConfigBuilderPlugin implements PluginBase, PumpInterface, Constrain } else if (isTempBasalInProgress() && Math.abs(request.rate - getTempBasalAbsoluteRateHistory()) < 0.05) { result = new PumpEnactResult(); result.absolute = getTempBasalAbsoluteRateHistory(); - result.duration = getTempBasalFromHistory(new Date().getTime()).getPlannedRemainingMinutes(); + result.duration = getTempBasalFromHistory(System.currentTimeMillis()).getPlannedRemainingMinutes(); result.enacted = false; result.comment = "Temp basal set correctly"; result.success = true; @@ -684,8 +628,6 @@ public class ConfigBuilderPlugin implements PluginBase, PumpInterface, Constrain @Override public boolean isFakingTempsByExtendedBoluses() { - if (Config.NSCLIENT) - return false; return activePump.isFakingTempsByExtendedBoluses(); } @@ -884,7 +826,7 @@ public class ConfigBuilderPlugin implements PluginBase, PumpInterface, Constrain } @Override - public OverlappingIntervals getTemporaryBasalsFromHistory() { + public Intervals getTemporaryBasalsFromHistory() { return activeTreatments.getTemporaryBasalsFromHistory(); } @@ -931,7 +873,7 @@ public class ConfigBuilderPlugin implements PluginBase, PumpInterface, Constrain } @Override - public OverlappingIntervals getExtendedBolusesFromHistory() { + public Intervals getExtendedBolusesFromHistory() { return activeTreatments.getExtendedBolusesFromHistory(); } @@ -953,7 +895,7 @@ public class ConfigBuilderPlugin implements PluginBase, PumpInterface, Constrain } @Override - public OverlappingIntervals getTempTargetsFromHistory() { + public Intervals getTempTargetsFromHistory() { return activeTreatments.getTempTargetsFromHistory(); } @@ -980,7 +922,7 @@ public class ConfigBuilderPlugin implements PluginBase, PumpInterface, Constrain } public String getProfileName() { - return getProfileName(new Date().getTime()); + return getProfileName(System.currentTimeMillis()); } public String getProfileName(long time) { @@ -1003,28 +945,33 @@ public class ConfigBuilderPlugin implements PluginBase, PumpInterface, Constrain } public Profile getProfile() { - return getProfile(new Date().getTime()); + return getProfile(System.currentTimeMillis()); + } + + public String getProfileUnits() { + return activeProfile.getUnits(); } public Profile getProfile(long time) { - //log.debug("Profile for: " + new Date(time).toLocaleString() + " : " + getProfileName(time)); - ProfileSwitch profileSwitch = getProfileSwitchFromHistory(time); - if (profileSwitch != null) { - if (profileSwitch.profileJson != null) { - try { - return new Profile(new JSONObject(profileSwitch.profileJson)); - } catch (JSONException e) { - e.printStackTrace(); - } - } else { - Profile profile = activeProfile.getProfile().getSpecificProfile(profileSwitch.profileName); - if (profile != null) - return profile; - } - } - // Unable to determine profile, failover to default - if (activeProfile.getProfile() == null) + if (activeTreatments == null) return null; //app not initialized + //log.debug("Profile for: " + new Date(time).toLocaleString() + " : " + getProfileName(time)); + boolean ignoreProfileSwitchEvents = SP.getBoolean(R.string.key_do_not_track_profile_switch, false); + if (!ignoreProfileSwitchEvents) { + ProfileSwitch profileSwitch = getProfileSwitchFromHistory(time); + if (profileSwitch != null) { + if (profileSwitch.profileJson != null) { + return profileSwitch.getProfileObject(); + } else if (activeProfile.getProfile() != null) { + Profile profile = activeProfile.getProfile().getSpecificProfile(profileSwitch.profileName); + if (profile != null) + return profile; + } + } + // Unable to determine profile, failover to default + if (activeProfile.getProfile() == null) + return null; //app not initialized + } Profile defaultProfile = activeProfile.getProfile().getDefaultProfile(); if (defaultProfile != null) return defaultProfile; 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 new file mode 100644 index 0000000000..c717d62edb --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/DetailedBolusInfoStorage.java @@ -0,0 +1,41 @@ +package info.nightscout.androidaps.plugins.ConfigBuilder; + +import android.support.annotation.Nullable; + +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; + +/** + * Created by mike on 08.08.2017. + */ + +public class DetailedBolusInfoStorage { + private static Logger log = LoggerFactory.getLogger(DetailedBolusInfoStorage.class); + private static List store = new ArrayList<>(); + + public static void add(DetailedBolusInfo detailedBolusInfo) { + log.debug("Bolus info stored: " + new Date(detailedBolusInfo.date).toLocaleString()); + store.add(detailedBolusInfo); + } + + @Nullable + public static DetailedBolusInfo findDetailedBolusInfo(long bolustime) { + DetailedBolusInfo found = null; + for (int i = 0; i < store.size(); i++) { + long infoTime = store.get(0).date; + log.debug("Existing info: " + new Date(infoTime).toLocaleString()); + if (bolustime > infoTime - 60 * 1000 && bolustime < infoTime + 60 * 1000) { + found = store.get(i); + store.remove(i); + break; + } + } + return found; + } +} 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 3334267057..906bf243ff 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 @@ -91,7 +91,7 @@ public class ObjectivesFragment extends Fragment { } }); - Long now = new Date().getTime(); + Long now = System.currentTimeMillis(); if (position > 0 && objectives.get(position - 1).accomplished.getTime() == 0) { // Phase 0: previous not completed holder.startedLayout.setVisibility(View.GONE); 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 b6f4e57acd..e04efb70cb 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 @@ -10,6 +10,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; +import info.nightscout.androidaps.BuildConfig; import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; @@ -67,8 +68,7 @@ public class ObjectivesPlugin implements PluginBase, ConstraintsInterface { @Override public boolean isVisibleInTabs(int type) { - LoopPlugin loopPlugin = (LoopPlugin) MainApp.getSpecificPlugin(LoopPlugin.class); - return type == CONSTRAINTS && fragmentVisible && loopPlugin != null && loopPlugin.isVisibleInTabs(LOOP); + return type == CONSTRAINTS && fragmentVisible && !BuildConfig.NSCLIENTOLNY; } @Override diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsSafety/SafetyFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsSafety/SafetyFragment.java deleted file mode 100644 index 07583e7622..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsSafety/SafetyFragment.java +++ /dev/null @@ -1,17 +0,0 @@ -package info.nightscout.androidaps.plugins.ConstraintsSafety; - - -import android.support.v4.app.Fragment; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class SafetyFragment extends Fragment { - private static Logger log = LoggerFactory.getLogger(SafetyFragment.class); - - private static SafetyPlugin safetyPlugin = new SafetyPlugin(); - - public static SafetyPlugin getPlugin() { - return safetyPlugin; - } -} 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 213bba47fa..c685cd472d 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 @@ -21,9 +21,17 @@ import info.nightscout.utils.SP; public class SafetyPlugin implements PluginBase, ConstraintsInterface { private static Logger log = LoggerFactory.getLogger(SafetyPlugin.class); + static SafetyPlugin plugin = null; + + public static SafetyPlugin getPlugin() { + if (plugin == null) + plugin = new SafetyPlugin(); + return plugin; + } + @Override public String getFragmentClass() { - return SafetyFragment.class.getName(); + return null; } @Override diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/InsulinFastacting/ActivityGraph.java b/app/src/main/java/info/nightscout/androidaps/plugins/InsulinFastacting/ActivityGraph.java index 2f98e45272..a2181a3a15 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/InsulinFastacting/ActivityGraph.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/InsulinFastacting/ActivityGraph.java @@ -38,7 +38,7 @@ public class ActivityGraph extends GraphView { double dia = insulin.getDia(); int hours = (int) Math.floor(dia + 1); - Treatment t = new Treatment(insulin); + Treatment t = new Treatment(insulin, dia); t.date = 0; t.insulin = 1d; @@ -63,6 +63,7 @@ public class ActivityGraph extends GraphView { getViewport().setMaxX(hours * 60); getGridLabelRenderer().setNumHorizontalLabels(hours + 1); getGridLabelRenderer().setHorizontalAxisTitle("[min]"); + getGridLabelRenderer().setVerticalLabelsColor(activitySeries.getColor()); DataPoint[] iobDataPoints = new DataPoint[iobArray.size()]; iobDataPoints = iobArray.toArray(iobDataPoints); @@ -72,5 +73,6 @@ public class ActivityGraph extends GraphView { iobSeries.setBackgroundColor(Color.argb(70, 255, 0, 255)); getSecondScale().setMinY(0); getSecondScale().setMaxY(1); + getGridLabelRenderer().setVerticalLabelsSecondScaleColor(Color.MAGENTA); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/InsulinFastacting/InsulinFastactingFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/InsulinFastacting/InsulinFastactingFragment.java index a99e016621..84741656f5 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/InsulinFastacting/InsulinFastactingFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/InsulinFastacting/InsulinFastactingFragment.java @@ -35,12 +35,22 @@ public class InsulinFastactingFragment extends Fragment { insulinDia = (TextView) view.findViewById(R.id.insulin_dia); insulinGraph = (ActivityGraph) view.findViewById(R.id.insuling_graph); - insulinName.setText(insulinFastactingPlugin.getFriendlyName()); - insulinComment.setText(insulinFastactingPlugin.getComment()); - insulinDia.setText(MainApp.sResources.getText(R.string.dia) + " " + new Double(insulinFastactingPlugin.getDia()).toString() + "h"); - insulinGraph.show(insulinFastactingPlugin); + updateGUI(); return view; } + @Override + public void onResume() { + super.onResume(); + updateGUI(); + } + + private void updateGUI() { + insulinName.setText(insulinFastactingPlugin.getFriendlyName()); + insulinComment.setText(insulinFastactingPlugin.getComment()); + insulinDia.setText(MainApp.sResources.getText(R.string.dia) + " " + new Double(insulinFastactingPlugin.getDia()).toString() + "h"); + insulinGraph.show(insulinFastactingPlugin); + } + } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/InsulinFastacting/InsulinFastactingPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/InsulinFastacting/InsulinFastactingPlugin.java index c98295ad35..e055e3d3ed 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/InsulinFastacting/InsulinFastactingPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/InsulinFastacting/InsulinFastactingPlugin.java @@ -1,5 +1,6 @@ package info.nightscout.androidaps.plugins.InsulinFastacting; +import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.Iob; @@ -89,7 +90,7 @@ public class InsulinFastactingPlugin implements PluginBase, InsulinInterface { @Override public double getDia() { - return MainApp.getConfigBuilder().getProfile().getDia(); + return MainApp.getConfigBuilder().getProfile() != null ? MainApp.getConfigBuilder().getProfile().getDia() : Constants.defaultDIA; } @Override diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/InsulinFastactingProlonged/InsulinFastactingProlongedFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/InsulinFastactingProlonged/InsulinFastactingProlongedFragment.java index acc915b001..e1d0143934 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/InsulinFastactingProlonged/InsulinFastactingProlongedFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/InsulinFastactingProlonged/InsulinFastactingProlongedFragment.java @@ -36,12 +36,22 @@ public class InsulinFastactingProlongedFragment extends Fragment { insulinDia = (TextView) view.findViewById(R.id.insulin_dia); insulinGraph = (ActivityGraph) view.findViewById(R.id.insuling_graph); - insulinName.setText(insulinFastactingProlongedPlugin.getFriendlyName()); - insulinComment.setText(insulinFastactingProlongedPlugin.getComment()); - insulinDia.setText(MainApp.sResources.getText(R.string.dia) + " " + new Double(insulinFastactingProlongedPlugin.getDia()).toString() + "h"); - insulinGraph.show(insulinFastactingProlongedPlugin); + updateGUI(); return view; } + @Override + public void onResume() { + super.onResume(); + updateGUI(); + } + + private void updateGUI() { + insulinName.setText(insulinFastactingProlongedPlugin.getFriendlyName()); + insulinComment.setText(insulinFastactingProlongedPlugin.getComment()); + insulinDia.setText(MainApp.sResources.getText(R.string.dia) + " " + new Double(insulinFastactingProlongedPlugin.getDia()).toString() + "h"); + insulinGraph.show(insulinFastactingProlongedPlugin); + } + } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/InsulinFastactingProlonged/InsulinFastactingProlongedPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/InsulinFastactingProlonged/InsulinFastactingProlongedPlugin.java index ed5fc0485c..3c5df052df 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/InsulinFastactingProlonged/InsulinFastactingProlongedPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/InsulinFastactingProlonged/InsulinFastactingProlongedPlugin.java @@ -1,5 +1,6 @@ package info.nightscout.androidaps.plugins.InsulinFastactingProlonged; +import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.Iob; @@ -89,7 +90,7 @@ public class InsulinFastactingProlongedPlugin implements PluginBase, InsulinInte @Override public double getDia() { - return MainApp.getConfigBuilder().getProfile().getDia(); + return MainApp.getConfigBuilder().getProfile() != null ? MainApp.getConfigBuilder().getProfile().getDia() : Constants.defaultDIA; } @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 427ca5d531..9939bd44d1 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 @@ -1,28 +1,95 @@ package info.nightscout.androidaps.plugins.IobCobCalculator; +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.Profile; +import info.nightscout.androidaps.db.Treatment; +import info.nightscout.androidaps.interfaces.PluginBase; +import info.nightscout.androidaps.plugins.SensitivityAAPS.SensitivityAAPSPlugin; +import info.nightscout.utils.SP; /** * Created by mike on 25.04.2017. */ public class AutosensData { - long time = 0L; + private static Logger log = LoggerFactory.getLogger(AutosensData.class); + + static class CarbsInPast { + long time = 0L; + double carbs = 0d; + double min5minCarbImpact = 0d; + double remaining = 0d; + + public CarbsInPast(Treatment t) { + time = t.date; + carbs = t.carbs; + remaining = t.carbs; + if (MainApp.getSpecificPlugin(SensitivityAAPSPlugin.class) != null && MainApp.getSpecificPlugin(SensitivityAAPSPlugin.class).isEnabled(PluginBase.SENSITIVITY)) { + double maxAbsorptionHours = SP.getDouble(R.string.key_absorption_maxtime, 4d); + Profile profile = MainApp.getConfigBuilder().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); + } else { + min5minCarbImpact = SP.getDouble("openapsama_min_5m_carbimpact", 3.0); + } + } + } + + public long time = 0L; public String pastSensitivity = ""; public double deviation = 0d; - boolean calculateWithDeviation = false; + boolean nonCarbsDeviation = false; + public boolean nonEqualDeviation = false; + List activeCarbsList = new ArrayList<>(); double absorbed = 0d; public double carbsFromBolus = 0d; public double cob = 0; public double bgi = 0d; public double delta = 0d; + public double autosensRatio = 1d; + public String log(long time) { - return "AutosensData: " + new Date(time).toLocaleString() + " " + pastSensitivity + " Delta=" + delta + " Bgi=" + bgi + " Deviation=" + deviation + " Absorbed=" + absorbed + " CarbsFromBolus=" + carbsFromBolus + " COB=" + cob; + return "AutosensData: " + new Date(time).toLocaleString() + " " + pastSensitivity + " Delta=" + delta + " Bgi=" + bgi + " Deviation=" + deviation + " Absorbed=" + absorbed + " CarbsFromBolus=" + carbsFromBolus + " COB=" + cob + " autosensRatio=" + autosensRatio; } public int minOld() { - return (int) ((new Date().getTime() - time) / 1000 / 60); + return (int) ((System.currentTimeMillis() - time) / 1000 / 60); + } + + // remove carbs older than 4h + public void removeOldCarbs(long toTime) { + for (int i = 0; i < activeCarbsList.size(); i++) { + CarbsInPast c = activeCarbsList.get(i); + if (c.time + 4 * 60 * 60 * 1000L < toTime) { + activeCarbsList.remove(i--); + if (c.remaining > 0) + cob -= c.remaining; + log.debug("Removing carbs at "+ new Date(toTime).toLocaleString() + " + after 4h :" + new Date(c.time).toLocaleString()); + } + } + } + + public void substractAbosorbedCarbs() { + double ac = absorbed; + for (int i = 0; i < activeCarbsList.size() && ac > 0; i++) { + CarbsInPast c = activeCarbsList.get(i); + if (c.remaining > 0) { + double sub = Math.min(ac, c.remaining); + c.remaining -= sub; + ac -= sub; + } + } } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobCalculatorFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobCalculatorFragment.java deleted file mode 100644 index db1db95998..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobCalculatorFragment.java +++ /dev/null @@ -1,16 +0,0 @@ -package info.nightscout.androidaps.plugins.IobCobCalculator; - -import android.support.v4.app.Fragment; - -/** - * Created by adrian on 17/11/16. - */ - -public class IobCobCalculatorFragment extends Fragment { - - private static IobCobCalculatorPlugin iobCobCalculatorPlugin = new IobCobCalculatorPlugin(); - - public static IobCobCalculatorPlugin getPlugin() { - return iobCobCalculatorPlugin; - } -} 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 417322a6b4..445eda93cd 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,27 +12,27 @@ 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.Config; 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.TemporaryBasal; import info.nightscout.androidaps.db.Treatment; +import info.nightscout.androidaps.events.EventConfigBuilderChange; import info.nightscout.androidaps.events.EventNewBG; import info.nightscout.androidaps.events.EventNewBasalProfile; +import info.nightscout.androidaps.events.EventPreferenceChange; import info.nightscout.androidaps.interfaces.PluginBase; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.IobCobCalculator.events.BasalData; import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished; import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventNewHistoryData; -import info.nightscout.utils.Round; -import info.nightscout.utils.SP; -import info.nightscout.utils.SafeParse; /** * Created by mike on 24.04.2017. @@ -53,7 +53,23 @@ public class IobCobCalculatorPlugin implements PluginBase { private static Handler sHandler = null; private static HandlerThread sHandlerThread = null; - private static Object dataLock = new Object(); + private static final Object dataLock = new Object(); + + private static IobCobCalculatorPlugin plugin = null; + + public static IobCobCalculatorPlugin getPlugin() { + if (plugin == null) + plugin = new IobCobCalculatorPlugin(); + return plugin; + } + + public static LongSparseArray getAutosensDataTable() { + return autosensDataTable; + } + + public static List getBucketedData() { + return bucketed_data; + } @Override public int getType() { @@ -62,7 +78,7 @@ public class IobCobCalculatorPlugin implements PluginBase { @Override public String getFragmentClass() { - return IobCobCalculatorFragment.class.getName(); + return null; } @Override @@ -110,7 +126,7 @@ public class IobCobCalculatorPlugin implements PluginBase { } - public IobCobCalculatorPlugin() { + IobCobCalculatorPlugin() { MainApp.bus().register(this); if (sHandlerThread == null) { sHandlerThread = new HandlerThread(IobCobCalculatorPlugin.class.getSimpleName()); @@ -158,13 +174,102 @@ public class IobCobCalculatorPlugin implements PluginBase { //log.debug("Locking loadBgData"); synchronized (dataLock) { onNewProfile(null); - bgReadings = MainApp.getDbHelper().getBgreadingsDataFromTime((long) (new Date().getTime() - 60 * 60 * 1000L * (24 + dia)), false); + bgReadings = MainApp.getDbHelper().getBgreadingsDataFromTime((long) (System.currentTimeMillis() - 60 * 60 * 1000L * (24 + dia)), false); log.debug("BG data loaded. Size: " + bgReadings.size()); } //log.debug("Releasing loadBgData"); } - public void createBucketedData() { + private boolean isAbout5minData() { + synchronized (dataLock) { + if (bgReadings == null || bgReadings.size() < 3) { + return true; + } + long totalDiff = 0; + for (int i = 1; i < bgReadings.size(); ++i) { + long bgTime = bgReadings.get(i).date; + long lastbgTime = bgReadings.get(i - 1).date; + long diff = lastbgTime - bgTime; + totalDiff += diff; + if (diff > 30 * 1000 && diff < 270 * 1000) { // 0:30 - 4:30 + log.debug("Interval detection: values: " + bgReadings.size() + " diff: " + (diff / 1000) + "sec is5minData: " + false); + return false; + } + } + 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); + return is5mindata; + } + } + + private void createBucketedData() { + if (isAbout5minData()) + createBucketedData5min(); + else + createBucketedDataRecalculated(); + } + + @Nullable + private 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) continue; + lastFound = bgReadings.get(i); + if (bgReadings.get(i).date < time) break; + } + return lastFound; + } + + @Nullable + private 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) continue; + lastFound = bgReadings.get(i); + if (bgReadings.get(i).date > time) break; + } + return lastFound; + } + + private void createBucketedDataRecalculated() { + synchronized (dataLock) { + if (bgReadings == null || bgReadings.size() < 3) { + bucketed_data = null; + return; + } + + bucketed_data = new ArrayList<>(); + long currentTime = bgReadings.get(0).date + 5 * 60 * 1000 - bgReadings.get(0).date % (5 * 60 * 1000) - 5 * 60 * 1000L; + //log.debug("First reading: " + new Date(currentTime).toLocaleString()); + + while (true) { + // test if current value is older than current time + BgReading newer = findNewer(currentTime); + BgReading older = findOlder(currentTime); + if (newer == null || older == null) + break; + + 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; + + } + } + } + + + public void createBucketedData5min() { //log.debug("Locking createBucketedData"); synchronized (dataLock) { if (bgReadings == null || bgReadings.size() < 3) { @@ -230,10 +335,14 @@ public class IobCobCalculatorPlugin implements PluginBase { //log.debug("Releasing createBucketedData"); } - public void calculateSensitivityData() { + private void calculateSensitivityData() { if (MainApp.getConfigBuilder() == null) return; // app still initializing + if (MainApp.getConfigBuilder().getProfile() == null) + return; // app still initializing //log.debug("Locking calculateSensitivityData"); + long oldestTimeWithData = oldestDataAvailable(); + synchronized (dataLock) { if (bucketed_data == null || bucketed_data.size() < 3) { @@ -261,6 +370,10 @@ public class IobCobCalculatorPlugin implements PluginBase { AutosensData autosensData = new AutosensData(); autosensData.time = bgTime; + if (previous != null) + autosensData.activeCarbsList = new ArrayList<>(previous.activeCarbsList); + else + autosensData.activeCarbsList = new ArrayList<>(); //console.error(bgTime , bucketed_data[i].glucose); double bg; @@ -273,7 +386,7 @@ public class IobCobCalculatorPlugin implements PluginBase { } delta = (bg - bucketed_data.get(i + 1).value); - IobTotal iob = calulateFromTreatmentsAndTemps(bgTime); + IobTotal iob = calculateFromTreatmentsAndTemps(bgTime); double bgi = -iob.activity * sens * 5; double deviation = delta - bgi; @@ -281,17 +394,28 @@ public class IobCobCalculatorPlugin implements PluginBase { List recentTreatments = MainApp.getConfigBuilder().getTreatments5MinBackFromHistory(bgTime); for (int ir = 0; ir < recentTreatments.size(); ir++) { autosensData.carbsFromBolus += recentTreatments.get(ir).carbs; + autosensData.activeCarbsList.add(new AutosensData.CarbsInPast(recentTreatments.get(ir))); } + // if we are absorbing carbs if (previous != null && previous.cob > 0) { + // calculate sum of min carb impact from all active treatments + double totalMinCarbsImpact = 0d; + for (int ii = 0; ii < autosensData.activeCarbsList.size(); ++ii) { + AutosensData.CarbsInPast c = autosensData.activeCarbsList.get(ii); + totalMinCarbsImpact += c.min5minCarbImpact; + } + // figure out how many carbs that represents - // but always assume at least 3mg/dL/5m (default) absorption - double ci = Math.max(deviation, SP.getDouble("openapsama_min_5m_carbimpact", 3.0)); + // but always assume at least 3mg/dL/5m (default) absorption per active treatment + double ci = Math.max(deviation, totalMinCarbsImpact); 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.substractAbosorbedCarbs(); } + autosensData.removeOldCarbs(bgTime); autosensData.cob += autosensData.carbsFromBolus; autosensData.deviation = deviation; autosensData.bgi = bgi; @@ -301,12 +425,15 @@ public class IobCobCalculatorPlugin implements PluginBase { if (autosensData.cob <= 0) { if (Math.abs(deviation) < Constants.DEVIATION_TO_BE_EQUAL) { autosensData.pastSensitivity += "="; + autosensData.nonEqualDeviation = true; } else if (deviation > 0) { autosensData.pastSensitivity += "+"; + autosensData.nonEqualDeviation = true; } else { autosensData.pastSensitivity += "-"; + autosensData.nonEqualDeviation = true; } - autosensData.calculateWithDeviation = true; + autosensData.nonCarbsDeviation = true; } else { autosensData.pastSensitivity += "C"; } @@ -314,6 +441,7 @@ public class IobCobCalculatorPlugin implements PluginBase { previous = autosensData; autosensDataTable.put(bgTime, autosensData); + autosensData.autosensRatio = detectSensitivity(oldestTimeWithData, bgTime).ratio; if (Config.logAutosensData) log.debug(autosensData.log(bgTime)); } @@ -322,29 +450,41 @@ public class IobCobCalculatorPlugin implements PluginBase { //log.debug("Releasing calculateSensitivityData"); } - public static IobTotal calulateFromTreatmentsAndTemps(long time) { - long now = new Date().getTime(); + public static long oldestDataAvailable() { + long now = System.currentTimeMillis(); + + long oldestDataAvailable = MainApp.getConfigBuilder().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()); + return getBGDataFrom; + } + + public static IobTotal calculateFromTreatmentsAndTempsSynchronized(long time) { + synchronized (dataLock) { + return calculateFromTreatmentsAndTemps(time); + } + } + + public static IobTotal calculateFromTreatmentsAndTemps(long time) { + long now = System.currentTimeMillis(); time = roundUpTime(time); if (time < now && iobTable.get(time) != null) { - //log.debug(">>> Cache hit"); + //og.debug(">>> calculateFromTreatmentsAndTemps Cache hit " + new Date(time).toLocaleString()); return iobTable.get(time); } else { - //log.debug(">>> Cache miss " + new Date(time).toLocaleString()); + //log.debug(">>> calculateFromTreatmentsAndTemps Cache miss " + new Date(time).toLocaleString()); } IobTotal bolusIob = MainApp.getConfigBuilder().getCalculationToTimeTreatments(time).round(); IobTotal basalIob = MainApp.getConfigBuilder().getCalculationToTimeTempBasals(time).round(); -/* - if (basalIob.basaliob > 0) { - log.debug(new Date(time).toLocaleString() + " basaliob: " + basalIob.basaliob ); - } -*/ + IobTotal iobTotal = IobTotal.combine(bolusIob, basalIob).round(); - if (time < new Date().getTime()) { + if (time < System.currentTimeMillis()) { iobTable.put(time, iobTotal); } return iobTotal; } + @Nullable private static Long findPreviousTimeFromBucketedData(long time) { if (bucketed_data == null) return null; @@ -356,7 +496,7 @@ public class IobCobCalculatorPlugin implements PluginBase { } public static BasalData getBasalData(long time) { - long now = new Date().getTime(); + long now = System.currentTimeMillis(); time = roundUpTime(time); BasalData retval = basalDataTable.get(time); if (retval == null) { @@ -373,36 +513,40 @@ public class IobCobCalculatorPlugin implements PluginBase { if (time < now) { basalDataTable.append(time, retval); } - //log.debug(">>> Cache miss " + new Date(time).toLocaleString()); + //log.debug(">>> getBasalData Cache miss " + new Date(time).toLocaleString()); } else { - //log.debug(">>> Cache hit " + new Date(time).toLocaleString()); + //log.debug(">>> getBasalData Cache hit " + new Date(time).toLocaleString()); } return retval; } + @Nullable public static AutosensData getAutosensData(long time) { - long now = new Date().getTime(); - if (time > now) - return null; - Long previous = findPreviousTimeFromBucketedData(time); - if (previous == null) - return null; - time = roundUpTime(previous); - AutosensData data = autosensDataTable.get(time); - if (data != null) { - //log.debug(">>> Cache hit " + data.log(time)); - return data; - } else { - //log.debug(">>> Cache miss " + new Date(time).toLocaleString()); - return null; + synchronized (dataLock) { + long now = System.currentTimeMillis(); + if (time > now) + return null; + Long previous = findPreviousTimeFromBucketedData(time); + if (previous == null) + return null; + time = roundUpTime(previous); + AutosensData data = autosensDataTable.get(time); + if (data != null) { + //log.debug(">>> getAutosensData Cache hit " + data.log(time)); + return data; + } else { + //log.debug(">>> getAutosensData Cache miss " + new Date(time).toLocaleString()); + return null; + } } } + @Nullable public static AutosensData getLastAutosensData() { if (autosensDataTable.size() < 1) return null; AutosensData data = autosensDataTable.valueAt(autosensDataTable.size() - 1); - if (data.time < new Date().getTime() - 5 * 60 * 1000) { + if (data.time < System.currentTimeMillis() - 5 * 60 * 1000) { return null; } else { return data; @@ -412,117 +556,29 @@ public class IobCobCalculatorPlugin implements PluginBase { public static IobTotal[] calculateIobArrayInDia() { Profile profile = MainApp.getConfigBuilder().getProfile(); // predict IOB out to DIA plus 30m - long time = new Date().getTime(); + long time = System.currentTimeMillis(); + time = roundUpTime(time); int len = (int) ((profile.getDia() * 60 + 30) / 5); IobTotal[] array = new IobTotal[len]; int pos = 0; for (int i = 0; i < len; i++) { long t = time + i * 5 * 60000; - IobTotal iob = calulateFromTreatmentsAndTemps(t); + IobTotal iob = calculateFromTreatmentsAndTempsSynchronized(t); array[pos] = iob; pos++; } return array; } - public static AutosensResult detectSensitivity(long fromTime) { - //log.debug("Locking detectSensitivity"); + public static AutosensResult detectSensitivityWithLock(long fromTime, long toTime) { synchronized (dataLock) { - if (autosensDataTable == null || autosensDataTable.size() < 4) { - log.debug("No autosens data available"); - return new AutosensResult(); - } - - AutosensData current = getLastAutosensData(); - if (current == null) { - log.debug("No current autosens data available"); - return new AutosensResult(); - } - - - 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.calculateWithDeviation) - deviationsArray.add(autosensData.deviation); - - 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++; - } - - Double[] deviations = new Double[deviationsArray.size()]; - deviations = deviationsArray.toArray(deviations); - - Profile profile = MainApp.getConfigBuilder().getProfile(); - - double sens = profile.getIsf(); - - double ratio = 1; - String ratioLimit = ""; - String sensResult = ""; - - log.debug("Records: " + index + " " + pastSensitivity); - Arrays.sort(deviations); - - for (double i = 0.9; i > 0.1; i = i - 0.02) { - if (percentile(deviations, (i + 0.02)) >= 0 && percentile(deviations, i) < 0) { - log.debug(Math.round(100 * i) + "% of non-meal deviations negative (target 45%-50%)"); - } - } - double pSensitive = percentile(deviations, 0.50); - double pResistant = percentile(deviations, 0.45); - - 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"; - } - log.debug(sensResult); - ratio = 1 + (basalOff / profile.getMaxDailyBasal()); - - double rawRatio = ratio; - ratio = Math.max(ratio, SafeParse.stringToDouble(SP.getString("openapsama_autosens_min", "0.7"))); - ratio = Math.min(ratio, SafeParse.stringToDouble(SP.getString("openapsama_autosens_max", "1.2"))); - - if (ratio != rawRatio) { - ratioLimit = "Ratio limited from " + rawRatio + " to " + ratio; - log.debug(ratioLimit); - } - - double newisf = Math.round(Profile.toMgdl(sens, profile.getUnits()) / ratio); - if (ratio != 1) { - log.debug("ISF adjusted from " + Profile.toMgdl(sens, profile.getUnits()) + " to " + newisf); - } - - 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; + return detectSensitivity(fromTime, toTime); } - //log.debug("Releasing detectSensitivity"); } + private static AutosensResult detectSensitivity(long fromTime, long toTime) { + return ConfigBuilderPlugin.getActiveSensitivity().detectSensitivity(fromTime, toTime); + } public static JSONArray convertToJSONArray(IobTotal[] iobArray) { JSONArray array = new JSONArray(); @@ -549,6 +605,8 @@ public class IobCobCalculatorPlugin implements PluginBase { if (MainApp.getConfigBuilder() == null) return; // app still initializing Profile profile = MainApp.getConfigBuilder().getProfile(); + if (profile == null) + return; // app still initializing dia = profile.getDia(); if (ev == null) { // on init no need of reset return; @@ -566,6 +624,41 @@ public class IobCobCalculatorPlugin implements PluginBase { }); } + @Subscribe + public void onStatusEvent(EventPreferenceChange ev) { + if (ev.isChanged(R.string.key_openapsama_autosens_period) || + ev.isChanged(R.string.key_age) || + ev.isChanged(R.string.key_absorption_maxtime) + ) { + synchronized (dataLock) { + log.debug("Invalidating cached data because of preference change. IOB: " + iobTable.size() + " Autosens: " + autosensDataTable.size() + " records"); + iobTable = new LongSparseArray<>(); + autosensDataTable = new LongSparseArray<>(); + } + sHandler.post(new Runnable() { + @Override + public void run() { + calculateSensitivityData(); + } + }); + } + } + + @Subscribe + public void onStatusEvent(EventConfigBuilderChange ev) { + synchronized (dataLock) { + log.debug("Invalidating cached data because of configuration change. IOB: " + iobTable.size() + " Autosens: " + autosensDataTable.size() + " records"); + iobTable = new LongSparseArray<>(); + autosensDataTable = new LongSparseArray<>(); + } + sHandler.post(new Runnable() { + @Override + public void run() { + calculateSensitivityData(); + } + }); + } + // When historical data is changed (comming from NS etc) finished calculations after this date must be invalidated @Subscribe public void onNewHistoryData(EventNewHistoryData ev) { @@ -575,6 +668,7 @@ public class IobCobCalculatorPlugin implements PluginBase { log.debug("Invalidating cached data to: " + new Date(time).toLocaleString()); for (int index = iobTable.size() - 1; index >= 0; index--) { if (iobTable.keyAt(index) > time) { + if (Config.logAutosensData) if (Config.logAutosensData) log.debug("Removing from iobTable: " + new Date(iobTable.keyAt(index)).toLocaleString()); iobTable.removeAt(index); 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 de295d8a6e..2fb143517b 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 @@ -3,7 +3,6 @@ package info.nightscout.androidaps.plugins.Loop; 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,10 +18,11 @@ 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.Loop.events.EventLoopSetLastRunGui; import info.nightscout.androidaps.plugins.Loop.events.EventLoopUpdateGui; -public class LoopFragment extends Fragment implements View.OnClickListener { +public class LoopFragment extends SubscriberFragment implements View.OnClickListener { private static Logger log = LoggerFactory.getLogger(LoopFragment.class); private static LoopPlugin loopPlugin; @@ -61,18 +61,6 @@ public class LoopFragment extends Fragment implements View.OnClickListener { return view; } - @Override - public void onPause() { - super.onPause(); - MainApp.bus().unregister(this); - } - - @Override - public void onResume() { - super.onResume(); - MainApp.bus().register(this); - } - @Override public void onClick(View view) { switch (view.getId()) { @@ -110,7 +98,8 @@ public class LoopFragment extends Fragment implements View.OnClickListener { } - void updateGUI() { + @Override + protected void updateGUI() { Activity activity = getActivity(); if (activity != null) activity.runOnUiThread(new Runnable() { 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 6fa9e6d677..d3f59de5ad 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 @@ -167,7 +167,7 @@ public class LoopPlugin implements PluginBase { if (loopSuspendedTill == 0) return 0; - long now = new Date().getTime(); + long now = System.currentTimeMillis(); long msecDiff = loopSuspendedTill - now; if (loopSuspendedTill <= now) { // time exceeded @@ -182,7 +182,7 @@ public class LoopPlugin implements PluginBase { if (loopSuspendedTill == 0) return false; - long now = new Date().getTime(); + long now = System.currentTimeMillis(); if (loopSuspendedTill <= now) { // time exceeded suspendTo(0L); @@ -196,7 +196,7 @@ public class LoopPlugin implements PluginBase { if (loopSuspendedTill == 0) return false; - long now = new Date().getTime(); + long now = System.currentTimeMillis(); if (loopSuspendedTill <= now) { // time exceeded suspendTo(0L); @@ -209,7 +209,7 @@ public class LoopPlugin implements PluginBase { public void invoke(String initiator, boolean allowNotification) { try { if (Config.logFunctionCalls) - log.debug("invoke"); + log.debug("invoke from " + initiator); ConstraintsInterface constraintsInterface = MainApp.getConfigBuilder(); if (!constraintsInterface.isLoopEnabled()) { log.debug(MainApp.sResources.getString(R.string.loopdisabled)); @@ -234,6 +234,12 @@ public class LoopPlugin implements PluginBase { return; } + if (configBuilder.getProfile() == null) { + log.debug(MainApp.sResources.getString(R.string.noprofileselected)); + MainApp.bus().post(new EventLoopSetLastRunGui(MainApp.sResources.getString(R.string.noprofileselected))); + return; + } + // Check if pump info is loaded if (configBuilder.getBaseBasalRate() < 0.01d) return; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientInternalFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientInternalFragment.java index c3e8c777c6..164e9902df 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientInternalFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientInternalFragment.java @@ -28,12 +28,13 @@ import org.slf4j.LoggerFactory; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.events.EventPreferenceChange; +import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.NSClientInternal.events.EventNSClientNewLog; import info.nightscout.androidaps.plugins.NSClientInternal.events.EventNSClientRestart; import info.nightscout.androidaps.plugins.NSClientInternal.events.EventNSClientUpdateGUI; import info.nightscout.utils.SP; -public class NSClientInternalFragment extends Fragment implements View.OnClickListener, CompoundButton.OnCheckedChangeListener { +public class NSClientInternalFragment extends SubscriberFragment implements View.OnClickListener, CompoundButton.OnCheckedChangeListener { private static Logger log = LoggerFactory.getLogger(NSClientInternalFragment.class); static NSClientInternalPlugin nsClientInternalPlugin; @@ -58,8 +59,6 @@ public class NSClientInternalFragment extends Fragment implements View.OnClickLi private CheckBox autoscrollCheckbox; private CheckBox pausedCheckbox; - String status = ""; - @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { @@ -119,7 +118,7 @@ public class NSClientInternalFragment extends Fragment implements View.OnClickLi builder.setMessage("Clear queue? All data in queue will be lost!"); builder.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { - getPlugin().queue().clearQueue(); + UploadQueue.clearQueue(); updateGUI(); Answers.getInstance().logCustom(new CustomEvent("NSClientClearQueue")); } @@ -152,36 +151,25 @@ public class NSClientInternalFragment extends Fragment implements View.OnClickLi } } - @Override - public void onPause() { - super.onPause(); - MainApp.bus().unregister(this); - } - - @Override - public void onResume() { - super.onResume(); - MainApp.bus().register(this); - updateGUI(); - } - @Subscribe public void onStatusEvent(final EventNSClientUpdateGUI ev) { updateGUI(); } - private void updateGUI() { + @Override + protected void updateGUI() { Activity activity = getActivity(); if (activity != null) activity.runOnUiThread(new Runnable() { @Override public void run() { - logTextView.setText(getPlugin().textLog); + NSClientInternalPlugin.updateLog(); + logTextView.setText(NSClientInternalPlugin.textLog); if (getPlugin().autoscroll) { logScrollview.fullScroll(ScrollView.FOCUS_DOWN); } urlTextView.setText(getPlugin().url()); - Spanned queuetext = Html.fromHtml(MainApp.sResources.getString(R.string.queue) + " " + getPlugin().queue().size() + ""); + Spanned queuetext = Html.fromHtml(MainApp.sResources.getString(R.string.queue) + " " + UploadQueue.size() + ""); queueTextView.setText(queuetext); statusTextView.setText(getPlugin().status); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientInternalPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientInternalPlugin.java index a37d5442ca..b33d1cb2c3 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientInternalPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientInternalPlugin.java @@ -9,14 +9,12 @@ import android.os.HandlerThread; import android.os.IBinder; import android.text.Html; import android.text.Spanned; -import android.text.TextUtils; import com.squareup.otto.Subscribe; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; @@ -36,29 +34,28 @@ import info.nightscout.utils.ToastUtils; public class NSClientInternalPlugin implements PluginBase { private static Logger log = LoggerFactory.getLogger(NSClientInternalPlugin.class); - boolean fragmentEnabled = true; - boolean fragmentVisible = true; + private boolean fragmentEnabled = true; + private boolean fragmentVisible = true; static public Handler handler; - static private HandlerThread handlerThread; - public List listLog = new ArrayList(); - public Spanned textLog = Html.fromHtml(""); + private static List listLog = new ArrayList<>(); + static Spanned textLog = Html.fromHtml(""); public boolean paused = false; - public boolean autoscroll = true; + boolean autoscroll = true; public String status = ""; public NSClientService nsClientService = null; - public NSClientInternalPlugin() { + NSClientInternalPlugin() { MainApp.bus().register(this); paused = SP.getBoolean(R.string.key_nsclientinternal_paused, false); autoscroll = SP.getBoolean(R.string.key_nsclientinternal_autoscroll, true); if (handler == null) { - handlerThread = new HandlerThread(NSClientInternalPlugin.class.getSimpleName() + "Handler"); + HandlerThread handlerThread = new HandlerThread(NSClientInternalPlugin.class.getSimpleName() + "Handler"); handlerThread.start(); handler = new Handler(handlerThread.getLooper()); } @@ -129,7 +126,7 @@ public class NSClientInternalPlugin implements PluginBase { if (type == GENERAL) this.fragmentVisible = fragmentVisible; } - ServiceConnection mConnection = new ServiceConnection() { + private ServiceConnection mConnection = new ServiceConnection() { public void onServiceDisconnected(ComponentName name) { log.debug("Service is disconnected"); @@ -162,45 +159,44 @@ public class NSClientInternalPlugin implements PluginBase { MainApp.bus().post(new EventNSClientUpdateGUI()); } - public void clearLog() { + synchronized void clearLog() { handler.post(new Runnable() { @Override public void run() { - listLog = new ArrayList(); - updateLog(); + listLog = new ArrayList<>(); + MainApp.bus().post(new EventNSClientUpdateGUI()); } }); } - private void addToLog(final EventNSClientNewLog ev) { + private synchronized void addToLog(final EventNSClientNewLog ev) { handler.post(new Runnable() { @Override public void run() { - SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss"); listLog.add(ev); // remove the first line if log is too large if (listLog.size() >= Constants.MAX_LOG_LINES) { listLog.remove(0); } - updateLog(); + MainApp.bus().post(new EventNSClientUpdateGUI()); } }); } - private void updateLog() { + static synchronized void updateLog() { try { - Spanned newTextLog = Html.fromHtml(""); - for (EventNSClientNewLog log : listLog) { - newTextLog = (Spanned) TextUtils.concat(newTextLog, log.toHtml()); + StringBuilder newTextLog = new StringBuilder(); + List temporaryList = new ArrayList<>(listLog); + for (EventNSClientNewLog log : temporaryList) { + newTextLog.append(log.toPreparedHtml()); } - textLog = newTextLog; - MainApp.bus().post(new EventNSClientUpdateGUI()); + textLog = Html.fromHtml(newTextLog.toString()); } catch (OutOfMemoryError e) { ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), "Out of memory!\nStop using this phone !!!", R.raw.error); } } - public void resend(String reason) { + void resend(String reason) { if (nsClientService != null) nsClientService.resend(reason); } 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 new file mode 100644 index 0000000000..216fa3d19a --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastAckAlarm.java @@ -0,0 +1,50 @@ +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.plugins.NSClientInternal.data.NSAlarm; +import info.nightscout.utils.SP; + +/** + * Created by mike on 11.06.2017. + */ + +public class BroadcastAckAlarm { + private static Logger log = LoggerFactory.getLogger(BroadcastAckAlarm.class); + + public static void handleClearAlarm(NSAlarm originalAlarm, Context context, long silenceTimeInMsec) { + + Bundle bundle = new Bundle(); + bundle.putInt("level", originalAlarm.getLevel()); + bundle.putString("group", originalAlarm.getGroup()); + bundle.putLong("silenceTime", silenceTimeInMsec); + Intent intent = new Intent(Intents.ACTION_ACK_ALARM); + 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.putInt("level", originalAlarm.getLevel()); + bundle.putString("group", originalAlarm.getGroup()); + bundle.putLong("silenceTime", silenceTimeInMsec); + intent = new Intent(Intents.ACTION_ACK_ALARM); + 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/BroadcastAlarm.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastAlarm.java new file mode 100644 index 0000000000..0fee6600bd --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastAlarm.java @@ -0,0 +1,43 @@ +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.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()); + Intent intent = new Intent(Intents.ACTION_ALARM); + 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("data", alarm.toString()); + intent = new Intent(Intents.ACTION_ALARM); + 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/BroadcastAnnouncement.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastAnnouncement.java new file mode 100644 index 0000000000..9b133c2551 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastAnnouncement.java @@ -0,0 +1,44 @@ +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.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()); + Intent intent = new Intent(Intents.ACTION_ANNOUNCEMENT); + 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("data", announcement.toString()); + intent = new Intent(Intents.ACTION_ANNOUNCEMENT); + 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/BroadcastCals.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastCals.java index 58a24e825c..7580a00088 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 @@ -4,6 +4,7 @@ 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; @@ -11,7 +12,10 @@ 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.utils.SP; /** * Created by mike on 26.06.2016. @@ -19,16 +23,24 @@ import info.nightscout.androidaps.Services.Intents; public class BroadcastCals { private static Logger log = LoggerFactory.getLogger(BroadcastCals.class); - public void handleNewCal(JSONArray cals, Context context, boolean isDelta) { + public static void handleNewCal(JSONArray cals, Context context, boolean isDelta) { + Bundle bundle = new Bundle(); bundle.putString("cals", cals.toString()); bundle.putBoolean("delta", isDelta); Intent intent = new Intent(Intents.ACTION_NEW_CAL); intent.putExtras(bundle); intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - context.sendBroadcast(intent); - List x = context.getPackageManager().queryBroadcastReceivers(intent, 0); + LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); - log.debug("CAL " + x.size() + " receivers"); + if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) { + bundle = new Bundle(); + bundle.putString("cals", cals.toString()); + bundle.putBoolean("delta", isDelta); + intent = new Intent(Intents.ACTION_NEW_CAL); + 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/BroadcastClearAlarm.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastClearAlarm.java new file mode 100644 index 0000000000..23406837a7 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastClearAlarm.java @@ -0,0 +1,43 @@ +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.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()); + Intent intent = new Intent(Intents.ACTION_CLEAR_ALARM); + 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("data", clearalarm.toString()); + intent = new Intent(Intents.ACTION_CLEAR_ALARM); + 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/BroadcastDeviceStatus.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastDeviceStatus.java index 64fd72b36a..a912fc5d3c 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 @@ -4,6 +4,7 @@ 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; @@ -12,34 +13,58 @@ 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.utils.SP; public class BroadcastDeviceStatus { private static Logger log = LoggerFactory.getLogger(BroadcastDeviceStatus.class); - public void handleNewDeviceStatus(JSONObject status, Context context, boolean isDelta) { + 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); - context.sendBroadcast(intent); - List x = context.getPackageManager().queryBroadcastReceivers(intent, 0); + LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); - log.debug("DEVICESTATUS " + x.size() + " receivers"); + 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 void handleNewDeviceStatus(JSONArray statuses, Context context, boolean isDelta) { - Bundle bundle = new Bundle(); - bundle.putString("devicestatuses", statuses.toString()); - bundle.putBoolean("delta", isDelta); - Intent intent = new Intent(Intents.ACTION_NEW_DEVICESTATUS); - intent.putExtras(bundle); - intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - context.sendBroadcast(intent); - List x = context.getPackageManager().queryBroadcastReceivers(intent, 0); + public static void handleNewDeviceStatus(JSONArray statuses, Context context, boolean isDelta) { - log.debug("DEVICESTATUS " + x.size() + " receivers"); + List splitted = BroadcastTreatment.splitArray(statuses); + for (JSONArray part: splitted) { + Bundle bundle = new Bundle(); + bundle.putString("devicestatuses", part.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)) { + splitted = BroadcastTreatment.splitArray(statuses); + for (JSONArray part : splitted) { + Bundle bundle = new Bundle(); + bundle.putString("devicestatuses", part.toString()); + bundle.putBoolean("delta", isDelta); + Intent intent = new Intent(Intents.ACTION_NEW_DEVICESTATUS); + 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/BroadcastMbgs.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastMbgs.java index 33669e1852..a715747791 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 @@ -4,6 +4,7 @@ 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; @@ -11,7 +12,10 @@ 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.utils.SP; /** * Created by mike on 26.06.2016. @@ -19,16 +23,24 @@ import info.nightscout.androidaps.Services.Intents; public class BroadcastMbgs { private static Logger log = LoggerFactory.getLogger(BroadcastMbgs.class); - public void handleNewMbg(JSONArray mbgs, Context context, boolean isDelta) { + public static void handleNewMbg(JSONArray mbgs, Context context, boolean isDelta) { + Bundle bundle = new Bundle(); bundle.putString("mbgs", mbgs.toString()); bundle.putBoolean("delta", isDelta); Intent intent = new Intent(Intents.ACTION_NEW_MBG); intent.putExtras(bundle); intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - context.sendBroadcast(intent); - List x = context.getPackageManager().queryBroadcastReceivers(intent, 0); + LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); - log.debug("MBG " + x.size() + " receivers"); + if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) { + bundle = new Bundle(); + bundle.putString("mbgs", mbgs.toString()); + bundle.putBoolean("delta", isDelta); + intent = new Intent(Intents.ACTION_NEW_MBG); + 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/BroadcastProfile.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastProfile.java index 641a4e6a77..3802b09657 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 @@ -4,14 +4,18 @@ 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.data.ProfileStore; +import info.nightscout.utils.SP; /** @@ -20,17 +24,25 @@ import info.nightscout.androidaps.data.ProfileStore; public class BroadcastProfile { private static Logger log = LoggerFactory.getLogger(BroadcastProfile.class); - public void handleNewTreatment(ProfileStore profile, Context context, boolean isDelta) { + public static void handleNewTreatment(ProfileStore profile, Context context, boolean isDelta) { + Bundle bundle = new Bundle(); bundle.putString("profile", profile.getData().toString()); bundle.putBoolean("delta", isDelta); Intent intent = new Intent(Intents.ACTION_NEW_PROFILE); intent.putExtras(bundle); intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - context.sendBroadcast(intent); - List x = context.getPackageManager().queryBroadcastReceivers(intent, 0); + LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); - log.debug("PROFILE " + x.size() + " receivers"); + if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) { + bundle = new Bundle(); + bundle.putString("profile", profile.getData().toString()); + bundle.putBoolean("delta", isDelta); + intent = new Intent(Intents.ACTION_NEW_PROFILE); + 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/BroadcastQueueStatus.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastQueueStatus.java index ed2b01a27c..abc49be18a 100644 --- 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 @@ -5,13 +5,18 @@ 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 void handleNewStatus(int size, Context context) { + 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"); 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 81a2621a77..d4193f3cb7 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 @@ -4,6 +4,7 @@ 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; @@ -12,7 +13,10 @@ 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.utils.SP; /** * Created by mike on 22.02.2016. @@ -20,30 +24,45 @@ import info.nightscout.androidaps.Services.Intents; public class BroadcastSgvs { private static Logger log = LoggerFactory.getLogger(BroadcastSgvs.class); - public void handleNewSgv(JSONObject sgv, Context context, boolean isDelta) { + 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); - context.sendBroadcast(intent); - List x = context.getPackageManager().queryBroadcastReceivers(intent, 0); + LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); - log.debug("SGV " + x.size() + " receivers"); + 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 void handleNewSgv(JSONArray sgvs, Context context, boolean isDelta) { + public static void handleNewSgv(JSONArray sgvs, Context context, boolean isDelta) { Bundle bundle = new Bundle(); bundle.putString("sgvs", sgvs.toString()); bundle.putBoolean("delta", isDelta); Intent intent = new Intent(Intents.ACTION_NEW_SGV); intent.putExtras(bundle); intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - context.sendBroadcast(intent); - List x = context.getPackageManager().queryBroadcastReceivers(intent, 0); + LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); - log.debug("SGV " + x.size() + " receivers"); + if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) { + bundle = new Bundle(); + bundle.putString("sgvs", sgvs.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); + } } } 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 b99950c89b..7c6862cb14 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 @@ -5,6 +5,7 @@ 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; @@ -12,9 +13,11 @@ 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.plugins.NSClientInternal.data.NSStatus; +import info.nightscout.androidaps.plugins.NSClientInternal.data.NSSettingsStatus; import info.nightscout.androidaps.plugins.NSClientInternal.services.NSClientService; +import info.nightscout.utils.SP; /** * Created by mike on 24.02.2016. @@ -22,14 +25,15 @@ import info.nightscout.androidaps.plugins.NSClientInternal.services.NSClientServ public class BroadcastStatus { private static Logger log = LoggerFactory.getLogger(BroadcastStatus.class); - public void handleNewStatus(NSStatus status, Context context, boolean isDelta) { + public static void handleNewStatus(NSSettingsStatus status, Context context, 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) { e.printStackTrace(); - }; + } bundle.putString("nightscoutversionname", NSClientService.nightscoutVersionName); bundle.putInt("nightscoutversioncode", NSClientService.nightscoutVersionCode); bundle.putString("status", status.getData().toString()); @@ -37,9 +41,24 @@ public class BroadcastStatus { Intent intent = new Intent(Intents.ACTION_NEW_STATUS); intent.putExtras(bundle); intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - context.sendBroadcast(intent); - List x = context.getPackageManager().queryBroadcastReceivers(intent, 0); + LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); - log.debug("STATUS: " + x.size() + " receivers"); + 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) { + e.printStackTrace(); + } + 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); + } } } 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 9d1abe43e3..0d998a2bcd 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 @@ -4,6 +4,8 @@ import android.content.Context; import android.content.Intent; import android.content.pm.ResolveInfo; import android.os.Bundle; +import android.os.TransactionTooLargeException; +import android.support.v4.content.LocalBroadcastManager; import org.json.JSONArray; import org.json.JSONException; @@ -11,10 +13,15 @@ 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.utils.SP; +import info.nightscout.utils.ToastUtils; /** * Created by mike on 20.02.2016. @@ -22,86 +29,173 @@ import info.nightscout.androidaps.plugins.NSClientInternal.data.NSTreatment; public class BroadcastTreatment { private static Logger log = LoggerFactory.getLogger(BroadcastTreatment.class); - public void handleNewTreatment(NSTreatment treatment, Context context, boolean isDelta) { + public static void handleNewTreatment(NSTreatment treatment, Context context, boolean isDelta) { + Bundle bundle = new Bundle(); bundle.putString("treatment", treatment.getData().toString()); bundle.putBoolean("delta", isDelta); Intent intent = new Intent(Intents.ACTION_NEW_TREATMENT); intent.putExtras(bundle); intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - context.sendBroadcast(intent); - List x = context.getPackageManager().queryBroadcastReceivers(intent, 0); + LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); - log.debug("TREAT_ADD " + treatment.getEventType() + " " + x.size() + " receivers"); + if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) { + bundle = new Bundle(); + bundle.putString("treatment", treatment.getData().toString()); + bundle.putBoolean("delta", isDelta); + intent = new Intent(Intents.ACTION_NEW_TREATMENT); + intent.putExtras(bundle); + intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); + context.sendBroadcast(intent); + } } - public void handleNewTreatment(JSONArray treatments, Context context, boolean isDelta) { - Bundle bundle = new Bundle(); - bundle.putString("treatments", treatments.toString()); - bundle.putBoolean("delta", isDelta); - Intent intent = new Intent(Intents.ACTION_NEW_TREATMENT); - intent.putExtras(bundle); - intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - context.sendBroadcast(intent); - List x = context.getPackageManager().queryBroadcastReceivers(intent, 0); + public static void handleNewTreatment(JSONArray treatments, Context context, boolean isDelta) { - log.debug("TREAT_ADD " + treatments.length() + " " + x.size() + " receivers"); + List splitted = splitArray(treatments); + for (JSONArray part: splitted) { + Bundle bundle = new Bundle(); + bundle.putString("treatments", part.toString()); + bundle.putBoolean("delta", isDelta); + Intent intent = new Intent(Intents.ACTION_NEW_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)){ + splitted = splitArray(treatments); + for (JSONArray part: splitted) { + Bundle bundle = new Bundle(); + bundle.putString("treatments", part.toString()); + bundle.putBoolean("delta", isDelta); + Intent intent = new Intent(Intents.ACTION_NEW_TREATMENT); + intent.putExtras(bundle); + intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); + context.sendBroadcast(intent); + } + } } public void handleChangedTreatment(JSONObject treatment, Context context, 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); - context.sendBroadcast(intent); - List x = context.getPackageManager().queryBroadcastReceivers(intent, 0); + LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); - try { - log.debug("TREAT_CHANGE " + treatment.getString("_id") + " " + x.size() + " receivers"); - } catch (JSONException e) {} + + 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); + context.sendBroadcast(intent); + } } - public void handleChangedTreatment(JSONArray treatments, Context context, boolean isDelta) { - Bundle bundle = new Bundle(); - bundle.putString("treatments", treatments.toString()); - bundle.putBoolean("delta", isDelta); - Intent intent = new Intent(Intents.ACTION_CHANGED_TREATMENT); - intent.putExtras(bundle); - intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - context.sendBroadcast(intent); - List x = context.getPackageManager().queryBroadcastReceivers(intent, 0); + public static void handleChangedTreatment(JSONArray treatments, Context context, boolean isDelta) { - log.debug("TREAT_CHANGE " + treatments.length() + " " + x.size() + " receivers"); + List splitted = splitArray(treatments); + for (JSONArray part : splitted) { + Bundle bundle = new Bundle(); + bundle.putString("treatments", part.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)) { + splitted = splitArray(treatments); + for (JSONArray part : splitted) { + Bundle bundle = new Bundle(); + bundle.putString("treatments", part.toString()); + bundle.putBoolean("delta", isDelta); + Intent intent = new Intent(Intents.ACTION_CHANGED_TREATMENT); + intent.putExtras(bundle); + intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); + context.sendBroadcast(intent); + } + } } - public void handleRemovedTreatment(JSONObject treatment, Context context, boolean isDelta) { + public static void handleRemovedTreatment(JSONObject treatment, Context context, 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); - context.sendBroadcast(intent); - List x = context.getPackageManager().queryBroadcastReceivers(intent, 0); + LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); - try { - log.debug("TREAT_REMOVE " + treatment.getString("_id") + " " + x.size() + " receivers"); - } catch (JSONException e) {} + + 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); + context.sendBroadcast(intent); + } } - public void handleRemovedTreatment(JSONArray treatments, Context context, boolean isDelta) { + public static void handleRemovedTreatment(JSONArray treatments, Context context, boolean isDelta) { + Bundle bundle = new Bundle(); bundle.putString("treatments", treatments.toString()); bundle.putBoolean("delta", isDelta); Intent intent = new Intent(Intents.ACTION_REMOVED_TREATMENT); intent.putExtras(bundle); intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); - context.sendBroadcast(intent); - List x = context.getPackageManager().queryBroadcastReceivers(intent, 0); + LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent); - log.debug("TREAT_REMOVE " + treatments.length() + " treatments " + x.size() + " receivers"); + + if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) { + bundle = new Bundle(); + bundle.putString("treatments", treatments.toString()); + bundle.putBoolean("delta", isDelta); + intent = new Intent(Intents.ACTION_REMOVED_TREATMENT); + intent.putExtras(bundle); + intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); + context.sendBroadcast(intent); + } } + + public static List splitArray(JSONArray array) { + List ret = new ArrayList<>(); + try { + int size = array.length(); + int count = 0; + JSONArray newarr = null; + for (int i = 0; i < size; i++) { + if (count == 0) { + if (newarr != null) { + ret.add(newarr); + } + newarr = new JSONArray(); + count = 200; + } + newarr.put(array.get(i)); + --count; + } + if (newarr != null && newarr.length() > 0) { + ret.add(newarr); + } + } catch (JSONException e) { + e.printStackTrace(); + ret = new ArrayList<>(); + ret.add(array); + } + return ret; + } } 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 new file mode 100644 index 0000000000..c332be03af --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/broadcasts/BroadcastUrgentAlarm.java @@ -0,0 +1,43 @@ +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.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()); + Intent intent = new Intent(Intents.ACTION_URGENT_ALARM); + 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("data", urgentalarm.toString()); + intent = new Intent(Intents.ACTION_URGENT_ALARM); + 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/data/AlarmAck.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/AlarmAck.java new file mode 100644 index 0000000000..109331b34b --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/AlarmAck.java @@ -0,0 +1,11 @@ +package info.nightscout.androidaps.plugins.NSClientInternal.data; + +/** + * Created by mike on 11.06.2017. + */ + +public class AlarmAck { + public Integer level = null; + public String group = null; + public Long silenceTime = null; +} 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 new file mode 100644 index 0000000000..f7a7f79303 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/NSAlarm.java @@ -0,0 +1,64 @@ +package info.nightscout.androidaps.plugins.NSClientInternal.data; + +import org.json.JSONException; +import org.json.JSONObject; + +/** + * Created by mike on 11.06.2017. + */ + +public class NSAlarm { + JSONObject data; + + public NSAlarm(JSONObject data) { + this.data = data; + } + + public int getLevel() { + int retval = 0; + if (data.has("level")) { + try { + retval = data.getInt("level"); + } catch (JSONException e) { + e.printStackTrace(); + } + } + return retval; + } + + public String getGroup() { + String retval = "N/A"; + if (data.has("group")) { + try { + retval = data.getString("group"); + } catch (JSONException e) { + e.printStackTrace(); + } + } + return retval; + } + + public String getTile() { + String retval = "N/A"; + if (data.has("title")) { + try { + retval = data.getString("title"); + } catch (JSONException e) { + e.printStackTrace(); + } + } + return retval; + } + + public String getMessage() { + String retval = "N/A"; + if (data.has("message")) { + try { + retval = data.getString("message"); + } catch (JSONException e) { + e.printStackTrace(); + } + } + return retval; + } +} 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 new file mode 100644 index 0000000000..8ce3fc87e2 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/NSDeviceStatus.java @@ -0,0 +1,387 @@ +package info.nightscout.androidaps.plugins.NSClientInternal.data; + +import android.text.Html; +import android.text.Spanned; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import info.nightscout.androidaps.R; +import info.nightscout.utils.DateUtil; +import info.nightscout.utils.Round; +import info.nightscout.utils.SP; + +/** + * Created by mike on 25.06.2017. + */ + +/* +{ + "_id": "594fdcec327b83c81b6b8c0f", + "device": "openaps://Sony D5803", + "pump": { + "battery": { + "percent": 100 + }, + "status": { + "status": "normal", + "timestamp": "2017-06-25T15:50:14Z" + }, + "extended": { + "Version": "1.5-ac98852-2017.06.25", + "PumpIOB": 1.13, + "LastBolus": "25. 6. 2017 17:25:00", + "LastBolusAmount": 0.3, + "BaseBasalRate": 0.4, + "ActiveProfile": "2016 +30%" + }, + "reservoir": 109, + "clock": "2017-06-25T15:55:10Z" + }, + "openaps": { + "suggested": { + "temp": "absolute", + "bg": 115.9, + "tick": "+5", + "eventualBG": 105, + "snoozeBG": 105, + "predBGs": { + "IOB": [116, 114, 112, 110, 109, 107, 106, 105, 105, 104, 104, 104, 104, 104, 104, 104, 104, 105, 105, 105, 105, 105, 106, 106, 106, 106, 106, 107] + }, + "COB": 0, + "IOB": -0.035, + "reason": "COB: 0, Dev: -18, BGI: 0.43, ISF: 216, Target: 99; Eventual BG 105 > 99 but Min. Delta -2.60 < Exp. Delta 0.1; setting current basal of 0.4 as temp. Suggested rate is same as profile rate, no temp basal is active, doing nothing", + "timestamp": "2017-06-25T15:55:10Z" + }, + "iob": { + "iob": -0.035, + "basaliob": -0.035, + "activity": -0.0004, + "time": "2017-06-25T15:55:10Z" + } + }, + "uploaderBattery": 93, + "created_at": "2017-06-25T15:55:10Z", + "NSCLIENT_ID": 1498406118857 +} + */ +public class NSDeviceStatus { + + private static NSDeviceStatus instance = null; + + public static NSDeviceStatus getInstance() { + if (instance == null) + instance = new NSDeviceStatus(); + return instance; + } + + private JSONObject data = null; + + public NSDeviceStatus() { + } + + public NSDeviceStatus setData(JSONObject obj) { + this.data = obj; + updatePumpData(obj); + updateOpenApsData(obj); + updateUploaderData(obj); + return this; + } + + public String getDevice() { + try { + if (data.has("device")) { + String device = data.getString("device"); + if (device.startsWith("openaps://")) { + device = device.substring(10); + return device; + } + } + } catch (JSONException e) { + e.printStackTrace(); + } + return ""; + } + + public static class Levels { + static int URGENT = 2; + static int WARN = 1; + static int INFO = 0; + int LOW = -1; + int LOWEST = -2; + static int NONE = -3; + } + + // ***** PUMP DATA ****** + + static DeviceStatusPumpData deviceStatusPumpData = null; + + public Spanned getExtendedPumpStatus() { + if (deviceStatusPumpData.extended != null) + return deviceStatusPumpData.extended; + return Html.fromHtml(""); + } + + public Spanned getPumpStatus() { + //String[] ALL_STATUS_FIELDS = {"reservoir", "battery", "clock", "status", "device"}; + + if (deviceStatusPumpData == null) + return Html.fromHtml(""); + + StringBuilder string = new StringBuilder(); + // test warning level + int level = Levels.INFO; + long now = System.currentTimeMillis(); + if (deviceStatusPumpData.clock + NSSettingsStatus.getInstance().extendedPumpSettings("urgentClock") * 60 * 1000L < now) + level = Levels.URGENT; + else if (deviceStatusPumpData.reservoir < NSSettingsStatus.getInstance().extendedPumpSettings("urgentRes")) + level = Levels.URGENT; + else if (deviceStatusPumpData.isPercent && deviceStatusPumpData.percent < NSSettingsStatus.getInstance().extendedPumpSettings("urgentBattP")) + level = Levels.URGENT; + else if (!deviceStatusPumpData.isPercent && deviceStatusPumpData.voltage < NSSettingsStatus.getInstance().extendedPumpSettings("urgentBattV")) + level = Levels.URGENT; + else if (deviceStatusPumpData.clock + NSSettingsStatus.getInstance().extendedPumpSettings("warnClock") < now) + level = Levels.WARN; + else if (deviceStatusPumpData.reservoir < NSSettingsStatus.getInstance().extendedPumpSettings("warnRes")) + level = Levels.WARN; + else if (deviceStatusPumpData.isPercent && deviceStatusPumpData.percent < NSSettingsStatus.getInstance().extendedPumpSettings("warnBattP")) + level = Levels.WARN; + else if (!deviceStatusPumpData.isPercent && deviceStatusPumpData.voltage < NSSettingsStatus.getInstance().extendedPumpSettings("warnBattV")) + level = Levels.WARN; + + string.append(""); + if (level == Levels.WARN) string.append("yellow\">"); + if (level == Levels.URGENT) string.append("red\">"); + + String fields = NSSettingsStatus.getInstance().pumpExtentendedSettingsFields(); + + if (fields.contains("reservoir")) { + string.append((int) deviceStatusPumpData.reservoir).append("U "); + } + + if (fields.contains("battery") && deviceStatusPumpData.isPercent) { + string.append(deviceStatusPumpData.percent).append("% "); + } + if (fields.contains("battery") && !deviceStatusPumpData.isPercent) { + string.append(Round.roundTo(deviceStatusPumpData.voltage, 0.001d)).append(" "); + } + + if (fields.contains("clock")) { + string.append(DateUtil.minAgo(deviceStatusPumpData.clock)).append(" "); + } + + if (fields.contains("status")) { + string.append(deviceStatusPumpData.status).append(" "); + } + + if (fields.contains("device")) { + string.append(getDevice()).append(" "); + } + + + string.append(""); // color + + return Html.fromHtml(string.toString()); + } + + static class DeviceStatusPumpData { + long clock = 0L; + boolean isPercent = false; + int percent = 0; + double voltage = 0; + + String status = "N/A"; + double reservoir = 0d; + + Spanned extended = null; + } + + public void updatePumpData(JSONObject object) { + try { + JSONObject pump = data != null && data.has("pump") ? data.getJSONObject("pump") : new JSONObject(); + + long clock = 0L; + if (pump.has("clock")) + clock = DateUtil.fromISODateString(pump.getString("clock")).getTime(); + // check if this is new data + if (clock == 0 || deviceStatusPumpData != null && clock < deviceStatusPumpData.clock) + return; + // create new status and process data + deviceStatusPumpData = new DeviceStatusPumpData(); + deviceStatusPumpData.clock = clock; + if (pump.has("status") && pump.getJSONObject("status").has("status")) + deviceStatusPumpData.status = pump.getJSONObject("status").getString("status"); + if (pump.has("reservoir")) + deviceStatusPumpData.reservoir = pump.getDouble("reservoir"); + if (pump.has("battery") && pump.getJSONObject("battery").has("percent")) { + deviceStatusPumpData.isPercent = true; + deviceStatusPumpData.percent = pump.getJSONObject("battery").getInt("percent"); + } else if (pump.has("battery") && pump.getJSONObject("battery").has("voltage")) { + deviceStatusPumpData.isPercent = false; + deviceStatusPumpData.voltage = pump.getJSONObject("battery").getDouble("voltage"); + } + if (pump.has("extended")) { + JSONObject extendedJson = pump.getJSONObject("extended"); + StringBuilder exteneded = new StringBuilder(); + Iterator keys = extendedJson.keys(); + while (keys.hasNext()) { + String key = (String) keys.next(); + String value = extendedJson.getString(key); + exteneded.append("").append(key).append(": ").append(value).append("
"); + } + deviceStatusPumpData.extended = Html.fromHtml(exteneded.toString()); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + + // ********* OpenAPS data *********** + + static DeviceStatusOpenAPSData deviceStatusOpenAPSData = new DeviceStatusOpenAPSData(); + + static class DeviceStatusOpenAPSData { + long clockSuggested = 0L; + long clockEnacted = 0L; + + JSONObject suggested = null; + JSONObject enacted = null; + } + + public void updateOpenApsData(JSONObject object) { + try { + JSONObject openaps = object.has("openaps") ? object.getJSONObject("openaps") : new JSONObject(); + JSONObject suggested = openaps.has("suggested") ? openaps.getJSONObject("suggested") : new JSONObject(); + JSONObject enacted = openaps.has("enacted") ? openaps.getJSONObject("enacted") : new JSONObject(); + + long clock = 0L; + if (suggested.has("timestamp")) + clock = DateUtil.fromISODateString(suggested.getString("timestamp")).getTime(); + // check if this is new data + if (clock != 0 && clock > deviceStatusOpenAPSData.clockSuggested) { + deviceStatusOpenAPSData.suggested = suggested; + deviceStatusOpenAPSData.clockSuggested = clock; + } + + clock = 0L; + if (enacted.has("timestamp")) + clock = DateUtil.fromISODateString(enacted.getString("timestamp")).getTime(); + // check if this is new data + if (clock != 0 && clock > deviceStatusOpenAPSData.clockEnacted) { + deviceStatusOpenAPSData.enacted = enacted; + deviceStatusOpenAPSData.clockEnacted = clock; + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + public Spanned getOpenApsStatus() { + StringBuilder string = new StringBuilder(); + // test warning level + int level = Levels.INFO; + long now = System.currentTimeMillis(); + if (deviceStatusOpenAPSData.clockSuggested != 0 && deviceStatusOpenAPSData.clockSuggested + SP.getInt(R.string.key_nsalarm_urgent_staledatavalue, 16) * 60 * 1000L < now) + level = Levels.URGENT; + else if (deviceStatusOpenAPSData.clockSuggested != 0 && deviceStatusOpenAPSData.clockSuggested + SP.getInt(R.string.key_nsalarm_staledatavalue, 16) * 60 * 1000L < now) + level = Levels.WARN; + + string.append(""); + if (level == Levels.WARN) string.append("yellow\">"); + if (level == Levels.URGENT) string.append("red\">"); + + if (deviceStatusOpenAPSData.clockSuggested != 0) { + string.append(DateUtil.minAgo(deviceStatusOpenAPSData.clockSuggested)).append(" "); + } + string.append(""); // color + + return Html.fromHtml(string.toString()); + } + + public Spanned getExtendedOpenApsStatus() { + StringBuilder string = new StringBuilder(); + + try { + if (deviceStatusOpenAPSData.enacted != null && deviceStatusOpenAPSData.clockEnacted != deviceStatusOpenAPSData.clockSuggested) + string.append("").append(DateUtil.minAgo(deviceStatusOpenAPSData.clockEnacted)).append(" ").append(deviceStatusOpenAPSData.enacted.getString("reason")).append("
"); + if (deviceStatusOpenAPSData.suggested != null) + string.append("").append(DateUtil.minAgo(deviceStatusOpenAPSData.clockSuggested)).append(" ").append(deviceStatusOpenAPSData.suggested.getString("reason")).append("
"); + return Html.fromHtml(string.toString()); + } catch (JSONException e) { + e.printStackTrace(); + } + return Html.fromHtml(""); + } + + // ********* Uploader data *********** + + public static HashMap uploaders = new HashMap<>(); + + static class Uploader { + long clock = 0L; + int battery = 0; + } + + public void updateUploaderData(JSONObject object) { + try { + + long clock = 0L; + if (object.has("created_at")) + clock = DateUtil.fromISODateString(object.getString("created_at")).getTime(); + String device = getDevice(); + Integer battery = null; + if (object.has("uploaderBattery")) + battery = object.getInt("uploaderBattery"); + else if (object.has("uploader")) { + if (object.getJSONObject("uploader").has("battery")) + battery = object.getJSONObject("uploader").getInt("battery"); + } + Uploader uploader = uploaders.get(device); + // check if this is new data + if (clock != 0 && (uploader != null && clock > uploader.clock || uploader == null)) { + if (uploader == null) + uploader = new Uploader(); + uploader.battery = battery; + uploader.clock = clock; + uploaders.put(device, uploader); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + public String getUploaderStatus() { + 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; + } + + return minBattery + "%"; + } + + public Spanned getExtendedUploaderStatus() { + StringBuilder string = new StringBuilder(); + + Iterator iter = uploaders.entrySet().iterator(); + while(iter.hasNext()) { + Map.Entry pair = (Map.Entry) iter.next(); + Uploader uploader = (Uploader) pair.getValue(); + String device = (String) pair.getKey(); + string.append("").append(device).append(": ").append(uploader.battery).append("%
"); + } + + return Html.fromHtml(string.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 new file mode 100644 index 0000000000..4980b342e9 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/NSSettingsStatus.java @@ -0,0 +1,343 @@ +package info.nightscout.androidaps.plugins.NSClientInternal.data; + +import android.support.annotation.Nullable; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.Date; + +/* + { + "status": "ok", + "name": "Nightscout", + "version": "0.10.0-dev-20170423", + "versionNum": 1000, + "serverTime": "2017-06-12T07:46:56.006Z", + "apiEnabled": true, + "careportalEnabled": true, + "boluscalcEnabled": true, + "head": "96ee154", + "settings": { + "units": "mmol", + "timeFormat": 24, + "nightMode": false, + "editMode": true, + "showRawbg": "always", + "customTitle": "Bara's CGM", + "theme": "colors", + "alarmUrgentHigh": true, + "alarmUrgentHighMins": [30, 60, 90, 120], + "alarmHigh": true, + "alarmHighMins": [30, 60, 90, 120], + "alarmLow": true, + "alarmLowMins": [15, 30, 45, 60], + "alarmUrgentLow": true, + "alarmUrgentLowMins": [15, 30, 45], + "alarmUrgentMins": [30, 60, 90, 120], + "alarmWarnMins": [30, 60, 90, 120], + "alarmTimeagoWarn": true, + "alarmTimeagoWarnMins": 15, + "alarmTimeagoUrgent": true, + "alarmTimeagoUrgentMins": 30, + "language": "cs", + "scaleY": "linear", + "showPlugins": "careportal boluscalc food bwp cage sage iage iob cob basal ar2 delta direction upbat rawbg", + "showForecast": "ar2", + "focusHours": 3, + "heartbeat": 60, + "baseURL": "http:\/\/barascgm.sysop.cz:82", + "authDefaultRoles": "readable", + "thresholds": { + "bgHigh": 252, + "bgTargetTop": 180, + "bgTargetBottom": 72, + "bgLow": 71 + }, + "DEFAULT_FEATURES": ["bgnow", "delta", "direction", "timeago", "devicestatus", "upbat", "errorcodes", "profile"], + "alarmTypes": ["predict"], + "enable": ["careportal", "boluscalc", "food", "bwp", "cage", "sage", "iage", "iob", "cob", "basal", "ar2", "rawbg", "pushover", "bgi", "pump", "openaps", "pushover", "treatmentnotify", "bgnow", "delta", "direction", "timeago", "devicestatus", "upbat", "profile", "ar2"] + }, + "extendedSettings": { + "pump": { + "fields": "reservoir battery clock", + "urgentBattP": 26, + "warnBattP": 51 + }, + "openaps": { + "enableAlerts": true + }, + "cage": { + "alerts": true, + "display": "days", + "urgent": 96, + "warn": 72 + }, + "sage": { + "alerts": true, + "urgent": 336, + "warn": 168 + }, + "iage": { + "alerts": true, + "urgent": 150, + "warn": 120 + }, + "basal": { + "render": "default" + }, + "profile": { + "history": true, + "multiple": true + }, + "devicestatus": { + "advanced": true + } + }, + "activeProfile": "2016 +30%" + } + */ +public class NSSettingsStatus { + private static NSSettingsStatus instance = null; + + public static NSSettingsStatus getInstance() { + if (instance == null) + instance = new NSSettingsStatus(); + return instance; + } + + private JSONObject data = null; + + public NSSettingsStatus() { + } + + public NSSettingsStatus setData(JSONObject obj) { + this.data = obj; + return this; + } + + public String getName() { + return getStringOrNull("name"); + } + + public String getVersion() { + return getStringOrNull("version"); + } + + public Integer getVersionNum() { + return getIntegerOrNull("versionNum"); + } + + public Date getServerTime() { + return getDateOrNull("versionNum"); + } + + public boolean getApiEnabled() { + return getBooleanOrNull("apiEnabled"); + } + + public boolean getCareportalEnabled() { + return getBooleanOrNull("careportalEnabled"); + } + + public boolean getBoluscalcEnabled() { + return getBooleanOrNull("boluscalcEnabled"); + } + + public String getHead() { + return getStringOrNull("head"); + } + + public String getSettings() { + return getStringOrNull("settings"); + } + + public JSONObject getExtendedSettings() { + try { + String extended = getStringOrNull("extendedSettings"); + if (extended != null) + return new JSONObject(extended); + + } catch (JSONException e) { + e.printStackTrace(); + } + return null; + + } + + public String getActiveProfile() { + return getStringOrNull("activeProfile"); + } + + // "bgHigh": 252, + // "bgTargetTop": 180, + // "bgTargetBottom": 72, + // "bgLow": 71 + @Nullable + public Double getThreshold(String what) { + try { + if (data == null) + return null; + String settings = getSettings(); + if (settings != null) { + JSONObject settingsO = new JSONObject(settings); + if (settingsO.has("thresholds")) { + JSONObject tObject = settingsO.getJSONObject("thresholds"); + if (tObject.has(what)) { + Double result = tObject.getDouble(what); + return result; + } + } + } + } catch (JSONException e) { + e.printStackTrace(); + } + return null; + } + + private String getStringOrNull(String key) { + String ret = null; + if (data.has(key)) { + try { + ret = data.getString(key); + } catch (JSONException e) { + e.printStackTrace(); + } + } + return ret; + } + + private Integer getIntegerOrNull(String key) { + Integer ret = null; + if (data.has(key)) { + try { + ret = data.getInt(key); + } catch (JSONException e) { + e.printStackTrace(); + } + } + return ret; + } + + private Long getLongOrNull(String key) { + Long ret = null; + if (data.has(key)) { + try { + ret = data.getLong(key); + } catch (JSONException e) { + e.printStackTrace(); + } + } + return ret; + } + + private Date getDateOrNull(String key) { + Date ret = null; + if (data.has(key)) { + try { + ret = new Date(data.getString(key)); + } catch (JSONException e) { + e.printStackTrace(); + } + } + return ret; + } + + private boolean getBooleanOrNull(String key) { + boolean ret = false; + if (data.has(key)) { + try { + ret = data.getBoolean(key); + } catch (JSONException e) { + e.printStackTrace(); + } + } + return ret; + } + + // ***** PUMP STATUS ****** + + public JSONObject getData() { + return data; + } + + /* + , warnClock: sbx.extendedSettings.warnClock || 30 + , urgentClock: sbx.extendedSettings.urgentClock || 60 + , warnRes: sbx.extendedSettings.warnRes || 10 + , urgentRes: sbx.extendedSettings.urgentRes || 5 + , warnBattV: sbx.extendedSettings.warnBattV || 1.35 + , urgentBattV: sbx.extendedSettings.urgentBattV || 1.3 + , warnBattP: sbx.extendedSettings.warnBattP || 30 + , urgentBattP: sbx.extendedSettings.urgentBattP || 20 + , enableAlerts: sbx.extendedSettings.enableAlerts || false + + */ + + public double extendedPumpSettings(String setting) { + try { + JSONObject pump = extentendedPumpSettings(); + switch (setting) { + case "warnClock": + return pump != null && pump.has(setting) ? pump.getDouble(setting) : 30; + case "urgentClock": + return pump != null && pump.has(setting) ? pump.getDouble(setting) : 30; + case "warnRes": + return pump != null && pump.has(setting) ? pump.getDouble(setting) : 30; + case "urgentRes": + return pump != null && pump.has(setting) ? pump.getDouble(setting) : 30; + case "warnBattV": + return pump != null && pump.has(setting) ? pump.getDouble(setting) : 30; + case "urgentBattV": + return pump != null && pump.has(setting) ? pump.getDouble(setting) : 30; + case "warnBattP": + return pump != null && pump.has(setting) ? pump.getDouble(setting) : 30; + case "urgentBattP": + return pump != null && pump.has(setting) ? pump.getDouble(setting) : 30; + } + } catch (JSONException e) { + e.printStackTrace(); + } + return 0d; + } + + @Nullable + public JSONObject extentendedPumpSettings() { + try { + JSONObject extended = getExtendedSettings(); + if (extended.has("pump")) { + JSONObject pump = extended.getJSONObject("pump"); + return pump; + } + } catch (JSONException e) { + e.printStackTrace(); + } + return null; + } + + public boolean pumpExtentendedSettingsEnabledAlerts() { + try { + JSONObject pump = extentendedPumpSettings(); + if (pump != null && pump.has("enableAlerts")) { + return pump.getBoolean("enableAlerts"); + } + } catch (JSONException e) { + e.printStackTrace(); + } + return false; + } + + public String pumpExtentendedSettingsFields() { + try { + JSONObject pump = extentendedPumpSettings(); + if (pump != null && pump.has("fields")) { + return pump.getString("fields"); + } + } catch (JSONException e) { + e.printStackTrace(); + } + return ""; + } + + +} 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 c8666f4306..78ddc7a8f7 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 @@ -24,7 +24,7 @@ public class NSSgv { } } return ret; - }; + } private Integer getIntegerOrNull(String key) { Integer ret = null; @@ -36,7 +36,7 @@ public class NSSgv { } } return ret; - }; + } private Long getLongOrNull(String key) { Long ret = null; @@ -48,7 +48,7 @@ public class NSSgv { } } return ret; - }; + } public JSONObject getData () { return data; } public Integer getMgdl () { return getIntegerOrNull("mgdl"); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/NSStatus.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/NSStatus.java deleted file mode 100644 index fe20e90b1d..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/data/NSStatus.java +++ /dev/null @@ -1,105 +0,0 @@ -package info.nightscout.androidaps.plugins.NSClientInternal.data; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.Date; - -/** - { - status: 'ok' - , name: env.name - , version: env.version - , versionNum: versionNum (for ver 1.2.3 contains 10203) - , serverTime: new Date().toISOString() - , apiEnabled: apiEnabled - , careportalEnabled: apiEnabled && env.settings.enable.indexOf('careportal') > -1 - , boluscalcEnabled: apiEnabled && env.settings.enable.indexOf('boluscalc') > -1 - , head: env.head - , settings: env.settings - , extendedSettings: ctx.plugins && ctx.plugins.extendedClientSettings ? ctx.plugins.extendedClientSettings(env.extendedSettings) : {} - , activeProfile ..... calculated from treatments or missing - } - */ -public class NSStatus { - private JSONObject data; - - public NSStatus(JSONObject obj) { - this.data = obj; - } - - public String getName () { return getStringOrNull("name"); } - public String getVersion () { return getStringOrNull("version"); } - public Integer getVersionNum () { return getIntegerOrNull("versionNum"); } - public Date getServerTime () { return getDateOrNull("versionNum"); } - public boolean getApiEnabled () { return getBooleanOrNull("apiEnabled"); } - public boolean getCareportalEnabled () { return getBooleanOrNull("careportalEnabled"); } - public boolean getBoluscalcEnabled () { return getBooleanOrNull("boluscalcEnabled"); } - public String getHead () { return getStringOrNull("head"); } - public String getSettings () { return getStringOrNull("settings"); } - public String getExtendedSettings () { return getStringOrNull("extendedSettings"); } - public String getActiveProfile () { return getStringOrNull("activeProfile"); } - - private String getStringOrNull(String key) { - String ret = null; - if (data.has(key)) { - try { - ret = data.getString(key); - } catch (JSONException e) { - e.printStackTrace(); - } - } - return ret; - }; - - private Integer getIntegerOrNull(String key) { - Integer ret = null; - if (data.has(key)) { - try { - ret = data.getInt(key); - } catch (JSONException e) { - e.printStackTrace(); - } - } - return ret; - }; - - private Long getLongOrNull(String key) { - Long ret = null; - if (data.has(key)) { - try { - ret = data.getLong(key); - } catch (JSONException e) { - e.printStackTrace(); - } - } - return ret; - }; - - private Date getDateOrNull(String key) { - Date ret = null; - if (data.has(key)) { - try { - ret = new Date(data.getString(key)); - } catch (JSONException e) { - e.printStackTrace(); - } - } - return ret; - }; - - private boolean getBooleanOrNull(String key) { - boolean ret = false; - if (data.has(key)) { - try { - ret = data.getBoolean(key); - } catch (JSONException e) { - e.printStackTrace(); - } - } - return ret; - }; - - public JSONObject getData () { return 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 7430caf600..1b48f27e2f 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 @@ -25,7 +25,7 @@ public class NSTreatment { } } return ret; - }; + } private Double getDoubleOrNull(String key) { Double ret = null; @@ -37,7 +37,7 @@ public class NSTreatment { } } return ret; - }; + } private Integer getIntegerOrNull(String key) { Integer ret = null; @@ -49,7 +49,7 @@ public class NSTreatment { } } return ret; - }; + } private Long getLongOrNull(String key) { Long ret = null; @@ -61,7 +61,7 @@ public class NSTreatment { } } return ret; - }; + } private Date getDateOrNull(String key) { Date ret = null; @@ -73,7 +73,7 @@ public class NSTreatment { } } return ret; - }; + } public String getAction() { return action; } public JSONObject getData() { return data; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/events/EventNSClientNewLog.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/events/EventNSClientNewLog.java index 7f576fde7e..7caafbd28a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/events/EventNSClientNewLog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/events/EventNSClientNewLog.java @@ -22,9 +22,16 @@ public class EventNSClientNewLog { this.logText = logText; } - public Spanned toHtml() { - SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss"); - Spanned line = Html.fromHtml(timeFormat.format(date) + " " + action + " " + logText + "
"); - return line; + SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss"); + + public StringBuilder toPreparedHtml() { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append(timeFormat.format(date)); + stringBuilder.append(" "); + stringBuilder.append(action); + stringBuilder.append(" "); + stringBuilder.append(logText); + stringBuilder.append("
"); + return stringBuilder; } } 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 new file mode 100644 index 0000000000..413d37d55d --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/receivers/AckAlarmReceiver.java @@ -0,0 +1,64 @@ +package info.nightscout.androidaps.plugins.NSClientInternal.receivers; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.os.PowerManager; + +import org.json.JSONException; +import org.json.JSONObject; +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.db.DbRequest; +import info.nightscout.androidaps.interfaces.PluginBase; +import info.nightscout.androidaps.plugins.NSClientInternal.NSClientInternalPlugin; +import info.nightscout.androidaps.plugins.NSClientInternal.UploadQueue; +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); + + + @Override + public void onReceive(Context context, Intent intent) { + PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); + PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, + AckAlarmReceiver.class.getSimpleName()); + NSClientInternalPlugin nsClientInternalPlugin = (NSClientInternalPlugin) MainApp.getSpecificPlugin(NSClientInternalPlugin.class); + if (!nsClientInternalPlugin.isEnabled(PluginBase.GENERAL)) { + return; + } + if (SP.getBoolean(R.string.key_ns_noupload, false)) { + log.debug("Upload disabled. Message dropped"); + return; + } + wakeLock.acquire(); + try { + Bundle bundles = intent.getExtras(); + if (bundles == null) return; + if (!bundles.containsKey("level")) return; + if (!bundles.containsKey("group")) return; + if (!bundles.containsKey("silenceTime")) return; + + AlarmAck ack = new AlarmAck(); + ack.level = bundles.getInt("level"); + ack.group = bundles.getString("group"); + ack.silenceTime = bundles.getLong("silenceTime"); + + NSClientService nsClientService = nsClientInternalPlugin.nsClientService; + if (nsClientService != null) + nsClientService.sendAlarmAck(ack); + + } finally { + wakeLock.release(); + } + } +} 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 91fca44d12..d8ed48dba5 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 @@ -19,6 +19,8 @@ import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.plugins.NSClientInternal.NSClientInternalPlugin; import info.nightscout.androidaps.plugins.NSClientInternal.UploadQueue; import info.nightscout.androidaps.db.DbRequest; +import info.nightscout.androidaps.plugins.NSClientInternal.data.AlarmAck; +import info.nightscout.androidaps.plugins.NSClientInternal.services.NSClientService; import info.nightscout.utils.SP; public class DBAccessReceiver extends BroadcastReceiver { @@ -29,7 +31,7 @@ public class DBAccessReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, - "sendQueue"); + DBAccessReceiver.class.getSimpleName()); NSClientInternalPlugin nsClientInternalPlugin = (NSClientInternalPlugin) MainApp.getSpecificPlugin(NSClientInternalPlugin.class); if (!nsClientInternalPlugin.isEnabled(PluginBase.GENERAL)) { return; @@ -61,7 +63,7 @@ public class DBAccessReceiver extends BroadcastReceiver { data = new JSONObject(); } // mark by id - Long nsclientid = new Date().getTime(); + Long nsclientid = System.currentTimeMillis(); try { data.put("NSCLIENT_ID", nsclientid); } catch (JSONException e) { 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 901b29ad16..21f863fe10 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 @@ -38,16 +38,20 @@ import info.nightscout.androidaps.plugins.NSClientInternal.UploadQueue; import info.nightscout.androidaps.plugins.NSClientInternal.acks.NSAddAck; import info.nightscout.androidaps.plugins.NSClientInternal.acks.NSAuthAck; import info.nightscout.androidaps.plugins.NSClientInternal.acks.NSUpdateAck; +import info.nightscout.androidaps.plugins.NSClientInternal.broadcasts.BroadcastAlarm; +import info.nightscout.androidaps.plugins.NSClientInternal.broadcasts.BroadcastAnnouncement; import info.nightscout.androidaps.plugins.NSClientInternal.broadcasts.BroadcastCals; +import info.nightscout.androidaps.plugins.NSClientInternal.broadcasts.BroadcastClearAlarm; import info.nightscout.androidaps.plugins.NSClientInternal.broadcasts.BroadcastDeviceStatus; import info.nightscout.androidaps.plugins.NSClientInternal.broadcasts.BroadcastMbgs; import info.nightscout.androidaps.plugins.NSClientInternal.broadcasts.BroadcastProfile; import info.nightscout.androidaps.plugins.NSClientInternal.broadcasts.BroadcastSgvs; import info.nightscout.androidaps.plugins.NSClientInternal.broadcasts.BroadcastStatus; import info.nightscout.androidaps.plugins.NSClientInternal.broadcasts.BroadcastTreatment; -import info.nightscout.androidaps.plugins.NSClientInternal.data.NSCal; +import info.nightscout.androidaps.plugins.NSClientInternal.broadcasts.BroadcastUrgentAlarm; +import info.nightscout.androidaps.plugins.NSClientInternal.data.AlarmAck; import info.nightscout.androidaps.plugins.NSClientInternal.data.NSSgv; -import info.nightscout.androidaps.plugins.NSClientInternal.data.NSStatus; +import info.nightscout.androidaps.plugins.NSClientInternal.data.NSSettingsStatus; import info.nightscout.androidaps.plugins.NSClientInternal.data.NSTreatment; import info.nightscout.androidaps.plugins.NSClientInternal.events.EventNSClientNewLog; import info.nightscout.androidaps.plugins.NSClientInternal.events.EventNSClientRestart; @@ -152,6 +156,7 @@ public class NSClientService extends Service { ev.isChanged(R.string.key_nsclientinternal_api_secret) || ev.isChanged(R.string.key_nsclientinternal_paused) ) { + latestDateInReceivedData = 0; destroy(); initialize(); } @@ -160,6 +165,7 @@ public class NSClientService extends Service { @Subscribe public void onStatusEvent(EventConfigBuilderChange ev) { if (nsEnabled != MainApp.getSpecificPlugin(NSClientInternalPlugin.class).isEnabled(PluginBase.GENERAL)) { + latestDateInReceivedData = 0; destroy(); initialize(); } @@ -201,6 +207,10 @@ public class NSClientService extends Service { MainApp.bus().post(new EventNSClientNewLog("NSCLIENT", "do connect")); mSocket.connect(); mSocket.on("dataUpdate", onDataUpdate); + mSocket.on("announcement", onAnnouncement); + mSocket.on("alarm", onAlarm); + mSocket.on("urgent_alarm", onUrgentAlarm); + mSocket.on("clear_alarm", onClearAlarm); } catch (URISyntaxException | RuntimeException e) { MainApp.bus().post(new EventNSClientNewLog("NSCLIENT", "Wrong URL syntax")); MainApp.bus().post(new EventNSClientStatus("Wrong URL syntax")); @@ -297,6 +307,99 @@ public class NSClientService extends Service { } }; + private Emitter.Listener onAnnouncement = new Emitter.Listener() { +/* +{ +"level":0, +"title":"Announcement", +"message":"test", +"plugin":{"name":"treatmentnotify","label":"Treatment Notifications","pluginType":"notification","enabled":true}, +"group":"Announcement", +"isAnnouncement":true, +"key":"9ac46ad9a1dcda79dd87dae418fce0e7955c68da" +} + */ + @Override + public void call(final Object... args) { + JSONObject data = (JSONObject) args[0]; + if (Config.detailedLog) + try { + MainApp.bus().post(new EventNSClientNewLog("ANNOUNCEMENT", data.has("message") ? data.getString("message") : "received")); + } catch (JSONException e) { + e.printStackTrace(); + } + BroadcastAnnouncement.handleAnnouncement(data, getApplicationContext()); + log.debug(data.toString()); + } + }; + + private Emitter.Listener onAlarm = new Emitter.Listener() { +/* +{ +"level":1, +"title":"Warning HIGH", +"message":"BG Now: 5 -0.2 → mmol\/L\nRaw BG: 4.8 mmol\/L Čistý\nBG 15m: 4.8 mmol\/L\nIOB: -0.02U\nCOB: 0g", +"eventName":"high", +"plugin":{"name":"simplealarms","label":"Simple Alarms","pluginType":"notification","enabled":true}, +"pushoverSound":"climb", +"debug":{"lastSGV":5,"thresholds":{"bgHigh":180,"bgTargetTop":75,"bgTargetBottom":72,"bgLow":70}}, +"group":"default", +"key":"simplealarms_1" +} + */ + @Override + public void call(final Object... args) { + if (Config.detailedLog) + MainApp.bus().post(new EventNSClientNewLog("ALARM", "received")); + JSONObject data = (JSONObject) args[0]; + BroadcastAlarm.handleAlarm(data, getApplicationContext()); + log.debug(data.toString()); + } + }; + + private Emitter.Listener onUrgentAlarm = new Emitter.Listener() { +/* +{ +"level":2, +"title":"Urgent HIGH", +"message":"BG Now: 5.2 -0.1 → mmol\/L\nRaw BG: 5 mmol\/L Čistý\nBG 15m: 5 mmol\/L\nIOB: 0.00U\nCOB: 0g", +"eventName":"high", +"plugin":{"name":"simplealarms","label":"Simple Alarms","pluginType":"notification","enabled":true}, +"pushoverSound":"persistent", +"debug":{"lastSGV":5.2,"thresholds":{"bgHigh":80,"bgTargetTop":75,"bgTargetBottom":72,"bgLow":70}}, +"group":"default", +"key":"simplealarms_2" +} + */ + @Override + public void call(final Object... args) { + JSONObject data = (JSONObject) args[0]; + if (Config.detailedLog) + MainApp.bus().post(new EventNSClientNewLog("URGENTALARM", "received")); + BroadcastUrgentAlarm.handleUrgentAlarm(data, getApplicationContext()); + log.debug(data.toString()); + } + }; + + private Emitter.Listener onClearAlarm = new Emitter.Listener() { +/* +{ +"clear":true, +"title":"All Clear", +"message":"default - Urgent was ack'd", +"group":"default" +} + */ + @Override + public void call(final Object... args) { + if (Config.detailedLog) + MainApp.bus().post(new EventNSClientNewLog("CLEARALARM", "received")); + JSONObject data = (JSONObject) args[0]; + BroadcastClearAlarm.handleClearAlarm(data, getApplicationContext()); + log.debug(data.toString()); + } + }; + private Emitter.Listener onDataUpdate = new Emitter.Listener() { @Override public void call(final Object... args) { @@ -329,19 +432,17 @@ public class NSClientService extends Service { if (data.has("status")) { JSONObject status = data.getJSONObject("status"); - NSStatus nsStatus = new NSStatus(status); + NSSettingsStatus nsSettingsStatus = NSSettingsStatus.getInstance().setData(status); if (!status.has("versionNum")) { - if (status.getInt("versionNum") < 900) { + if (status.getInt("versionNum") < Config.SUPPORTEDNSVERSION) { MainApp.bus().post(new EventNSClientNewLog("ERROR", "Unsupported Nightscout version !!!!")); } } else { - nightscoutVersionName = status.getString("version"); - nightscoutVersionCode = status.getInt("versionNum"); + nightscoutVersionName = nsSettingsStatus.getVersion(); + nightscoutVersionCode = nsSettingsStatus.getVersionNum(); } - - BroadcastStatus bs = new BroadcastStatus(); - bs.handleNewStatus(nsStatus, MainApp.instance().getApplicationContext(), isDelta); + BroadcastStatus.handleNewStatus(nsSettingsStatus, MainApp.instance().getApplicationContext(), isDelta); /* Other received data to 2016/02/10 { @@ -365,17 +466,15 @@ public class NSClientService extends Service { // If new profile received or change detected broadcast it if (broadcastProfile && profileStore != null) { - BroadcastProfile bp = new BroadcastProfile(); - bp.handleNewTreatment(profileStore, MainApp.instance().getApplicationContext(), isDelta); + BroadcastProfile.handleNewTreatment(profileStore, MainApp.instance().getApplicationContext(), isDelta); MainApp.bus().post(new EventNSClientNewLog("PROFILE", "broadcasting")); } if (data.has("treatments")) { - JSONArray treatments = (JSONArray) data.getJSONArray("treatments"); + JSONArray treatments = data.getJSONArray("treatments"); JSONArray removedTreatments = new JSONArray(); JSONArray updatedTreatments = new JSONArray(); JSONArray addedTreatments = new JSONArray(); - BroadcastTreatment bt = new BroadcastTreatment(); if (treatments.length() > 0) MainApp.bus().post(new EventNSClientNewLog("DATA", "received " + treatments.length() + " treatments")); for (Integer index = 0; index < treatments.length(); index++) { @@ -385,7 +484,7 @@ public class NSClientService extends Service { // remove from upload queue if Ack is failing UploadQueue.removeID(jsonTreatment); //Find latest date in treatment - if (treatment.getMills() != null && treatment.getMills() < new Date().getTime()) + if (treatment.getMills() != null && treatment.getMills() < System.currentTimeMillis()) if (treatment.getMills() > latestDateInReceivedData) latestDateInReceivedData = treatment.getMills(); @@ -394,23 +493,22 @@ public class NSClientService extends Service { } else if (treatment.getAction().equals("update")) { updatedTreatments.put(jsonTreatment); } else if (treatment.getAction().equals("remove")) { - if (treatment.getMills() != null && treatment.getMills() > new Date().getTime() - 24 * 60 * 60 * 1000L) // handle 1 day old deletions only + if (treatment.getMills() != null && treatment.getMills() > System.currentTimeMillis() - 24 * 60 * 60 * 1000L) // handle 1 day old deletions only removedTreatments.put(jsonTreatment); } } if (removedTreatments.length() > 0) { - bt.handleRemovedTreatment(removedTreatments, MainApp.instance().getApplicationContext(), isDelta); + BroadcastTreatment.handleRemovedTreatment(removedTreatments, MainApp.instance().getApplicationContext(), isDelta); } if (updatedTreatments.length() > 0) { - bt.handleChangedTreatment(updatedTreatments, MainApp.instance().getApplicationContext(), isDelta); + BroadcastTreatment.handleChangedTreatment(updatedTreatments, MainApp.instance().getApplicationContext(), isDelta); } if (addedTreatments.length() > 0) { - bt.handleNewTreatment(addedTreatments, MainApp.instance().getApplicationContext(), isDelta); + BroadcastTreatment.handleNewTreatment(addedTreatments, MainApp.instance().getApplicationContext(), isDelta); } } if (data.has("devicestatus")) { - BroadcastDeviceStatus bds = new BroadcastDeviceStatus(); - JSONArray devicestatuses = (JSONArray) data.getJSONArray("devicestatus"); + JSONArray devicestatuses = data.getJSONArray("devicestatus"); if (devicestatuses.length() > 0) { MainApp.bus().post(new EventNSClientNewLog("DATA", "received " + devicestatuses.length() + " devicestatuses")); for (Integer index = 0; index < devicestatuses.length(); index++) { @@ -418,13 +516,11 @@ public class NSClientService extends Service { // remove from upload queue if Ack is failing UploadQueue.removeID(jsonStatus); } - // send only last record - bds.handleNewDeviceStatus(devicestatuses.getJSONObject(devicestatuses.length() - 1), MainApp.instance().getApplicationContext(), isDelta); + BroadcastDeviceStatus.handleNewDeviceStatus(devicestatuses, MainApp.instance().getApplicationContext(), isDelta); } } if (data.has("mbgs")) { - BroadcastMbgs bmbg = new BroadcastMbgs(); - JSONArray mbgs = (JSONArray) data.getJSONArray("mbgs"); + JSONArray mbgs = data.getJSONArray("mbgs"); if (mbgs.length() > 0) MainApp.bus().post(new EventNSClientNewLog("DATA", "received " + mbgs.length() + " mbgs")); for (Integer index = 0; index < mbgs.length(); index++) { @@ -432,11 +528,10 @@ public class NSClientService extends Service { // remove from upload queue if Ack is failing UploadQueue.removeID(jsonMbg); } - bmbg.handleNewMbg(mbgs, MainApp.instance().getApplicationContext(), isDelta); + BroadcastMbgs.handleNewMbg(mbgs, MainApp.instance().getApplicationContext(), isDelta); } if (data.has("cals")) { - BroadcastCals bc = new BroadcastCals(); - JSONArray cals = (JSONArray) data.getJSONArray("cals"); + JSONArray cals = data.getJSONArray("cals"); if (cals.length() > 0) MainApp.bus().post(new EventNSClientNewLog("DATA", "received " + cals.length() + " cals")); // Retreive actual calibration @@ -444,11 +539,10 @@ public class NSClientService extends Service { // remove from upload queue if Ack is failing UploadQueue.removeID(cals.optJSONObject(index)); } - bc.handleNewCal(cals, MainApp.instance().getApplicationContext(), isDelta); + BroadcastCals.handleNewCal(cals, MainApp.instance().getApplicationContext(), isDelta); } if (data.has("sgvs")) { - BroadcastSgvs bs = new BroadcastSgvs(); - JSONArray sgvs = (JSONArray) data.getJSONArray("sgvs"); + JSONArray sgvs = data.getJSONArray("sgvs"); if (sgvs.length() > 0) MainApp.bus().post(new EventNSClientNewLog("DATA", "received " + sgvs.length() + " sgvs")); for (Integer index = 0; index < sgvs.length(); index++) { @@ -459,11 +553,11 @@ public class NSClientService extends Service { // remove from upload queue if Ack is failing UploadQueue.removeID(jsonSgv); //Find latest date in sgv - if (sgv.getMills() != null && sgv.getMills() < new Date().getTime()) + if (sgv.getMills() != null && sgv.getMills() < System.currentTimeMillis()) if (sgv.getMills() > latestDateInReceivedData) latestDateInReceivedData = sgv.getMills(); } - bs.handleNewSgv(sgvs, MainApp.instance().getApplicationContext(), isDelta); + BroadcastSgvs.handleNewSgv(sgvs, MainApp.instance().getApplicationContext(), isDelta); } MainApp.bus().post(new EventNSClientNewLog("LAST", DateUtil.dateAndTimeString(latestDateInReceivedData))); } catch (JSONException e) { @@ -543,6 +637,12 @@ public class NSClientService extends Service { } } + public void sendAlarmAck(AlarmAck alarmAck) { + if (!isConnected || !hasWriteAuth) return; + mSocket.emit("ack", alarmAck.level, alarmAck.group, alarmAck.silenceTime); + MainApp.bus().post(new EventNSClientNewLog("ALARMACK ", alarmAck.level + " " + alarmAck.group + " " + alarmAck.silenceTime)); + } + @Subscribe public void onStatusEvent(NSAddAck ack) { if (ack.nsClientID != null) { @@ -575,11 +675,11 @@ public class NSClientService extends Service { public void run() { if (mSocket == null || !mSocket.connected()) return; - if (lastResendTime > new Date().getTime() - 10 * 1000L) { - log.debug("Skipping resend by lastResendTime: " + ((new Date().getTime() - lastResendTime) / 1000L) + " sec"); + if (lastResendTime > System.currentTimeMillis() - 10 * 1000L) { + log.debug("Skipping resend by lastResendTime: " + ((System.currentTimeMillis() - lastResendTime) / 1000L) + " sec"); return; } - lastResendTime = new Date().getTime(); + lastResendTime = System.currentTimeMillis(); MainApp.bus().post(new EventNSClientNewLog("QUEUE", "Resend started: " + reason)); 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 044374bc86..6e1070eac3 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 @@ -232,7 +232,7 @@ public class DetermineBasalAdapterAMAJS { mCurrentTemp.add("rate", MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory()); // as we have non default temps longer than 30 mintues - TemporaryBasal tempBasal = MainApp.getConfigBuilder().getTempBasalFromHistory(new Date().getTime()); + TemporaryBasal tempBasal = MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis()); if (tempBasal != null) { mCurrentTemp.add("minutesrunning", tempBasal.getRealDuration()); } 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 c086ff2cd5..c2a55ff894 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 @@ -43,7 +43,7 @@ public class DetermineBasalResultAMA extends APSResult { } if (result.contains("duration")) { duration = result.getInteger("duration"); - changeRequested = changeRequested; + //changeRequested as above } else { duration = -1; changeRequested = false; 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 c480ebfe3c..419a55f057 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 @@ -20,11 +20,12 @@ 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.JSONFormatter; -public class OpenAPSAMAFragment extends Fragment implements View.OnClickListener { +public class OpenAPSAMAFragment extends SubscriberFragment implements View.OnClickListener { private static Logger log = LoggerFactory.getLogger(OpenAPSAMAFragment.class); private static OpenAPSAMAPlugin openAPSAMAPlugin; @@ -81,18 +82,6 @@ public class OpenAPSAMAFragment extends Fragment implements View.OnClickListener } - @Override - public void onPause() { - super.onPause(); - MainApp.bus().unregister(this); - } - - @Override - public void onResume() { - super.onResume(); - MainApp.bus().register(this); - } - @Subscribe public void onStatusEvent(final EventOpenAPSUpdateGui ev) { updateGUI(); @@ -103,7 +92,8 @@ public class OpenAPSAMAFragment extends Fragment implements View.OnClickListener updateResultGUI(ev.text); } - void updateGUI() { + @Override + protected void updateGUI() { Activity activity = getActivity(); if (activity != null) activity.runOnUiThread(new Runnable() { 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 c39e9a78d3..53bcfcf1ec 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 @@ -135,6 +135,13 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface { Profile profile = MainApp.getConfigBuilder().getProfile(); PumpInterface pump = MainApp.getConfigBuilder(); + if (profile == null) { + MainApp.bus().post(new EventOpenAPSUpdateResultGui(MainApp.instance().getString(R.string.noprofileselected))); + if (Config.logAPSResult) + log.debug(MainApp.instance().getString(R.string.noprofileselected)); + return; + } + if (!isEnabled(PluginBase.APS)) { MainApp.bus().post(new EventOpenAPSUpdateResultGui(MainApp.instance().getString(R.string.openapsma_disabled))); if (Config.logAPSResult) @@ -151,22 +158,11 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface { String units = profile.getUnits(); - Double maxBgDefault = Constants.MAX_BG_DEFAULT_MGDL; - Double minBgDefault = Constants.MIN_BG_DEFAULT_MGDL; - Double targetBgDefault = Constants.TARGET_BG_DEFAULT_MGDL; - if (!units.equals(Constants.MGDL)) { - maxBgDefault = Constants.MAX_BG_DEFAULT_MMOL; - minBgDefault = Constants.MIN_BG_DEFAULT_MMOL; - targetBgDefault = Constants.TARGET_BG_DEFAULT_MMOL; - } - - Date now = new Date(); - double maxIob = SP.getDouble("openapsma_max_iob", 1.5d); double maxBasal = SP.getDouble("openapsma_max_basal", 1d); - double minBg = Profile.toMgdl(SP.getDouble("openapsma_min_bg", minBgDefault), units); - double maxBg = Profile.toMgdl(SP.getDouble("openapsma_max_bg", maxBgDefault), units); - double targetBg = Profile.toMgdl(SP.getDouble("openapsma_target_bg", targetBgDefault), units); + double minBg = Profile.toMgdl(profile.getTargetLow(), units); + double maxBg = Profile.toMgdl(profile.getTargetHigh(), units); + double targetBg = (minBg + maxBg) / 2; minBg = Round.roundTo(minBg, 0.1d); maxBg = Round.roundTo(maxBg, 0.1d); @@ -187,7 +183,7 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface { targetBg = verifyHardLimits(targetBg, "targetBg", Constants.VERY_HARD_LIMIT_TARGET_BG[0], Constants.VERY_HARD_LIMIT_TARGET_BG[1]); boolean isTempTarget = false; - TempTarget tempTarget = MainApp.getConfigBuilder().getTempTargetFromHistory(new Date().getTime()); + TempTarget tempTarget = MainApp.getConfigBuilder().getTempTargetFromHistory(System.currentTimeMillis()); if (tempTarget != null) { isTempTarget = true; minBg = verifyHardLimits(tempTarget.low, "minBg", Constants.VERY_HARD_LIMIT_TEMP_MIN_BG[0], Constants.VERY_HARD_LIMIT_TEMP_MIN_BG[1]); @@ -207,14 +203,9 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface { if (!checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.1, 10)) return; if (!checkOnlyHardLimits(pump.getBaseBasalRate(), "current_basal", 0.01, 5)) return; - long oldestDataAvailable = MainApp.getConfigBuilder().oldestDataAvailable(); - long getBGDataFrom = Math.max(oldestDataAvailable, (long) (new Date().getTime() - 60 * 60 * 1000L * (24 + profile.getDia()))); - log.debug("Limiting data to oldest available temps: " + new Date(oldestDataAvailable).toString()); - startPart = new Date(); if (MainApp.getConfigBuilder().isAMAModeEnabled()) { - //lastAutosensResult = Autosens.detectSensitivityandCarbAbsorption(getBGDataFrom, null); - lastAutosensResult = IobCobCalculatorPlugin.detectSensitivity(getBGDataFrom); + lastAutosensResult = IobCobCalculatorPlugin.detectSensitivityWithLock(IobCobCalculatorPlugin.oldestDataAvailable(), System.currentTimeMillis()); } else { lastAutosensResult = new AutosensResult(); } @@ -246,6 +237,8 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface { determineBasalAdapterAMAJS.release(); + Date now = new Date(); + try { determineBasalResultAMA.json.put("timestamp", DateUtil.toISOString(now)); } catch (JSONException e) { 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 cb0e67249f..a0cd1a75b0 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 @@ -41,7 +41,7 @@ public class DetermineBasalResultMA extends APSResult { } if (result.contains("duration")) { duration = result.getInteger("duration"); - changeRequested = changeRequested; + //changeRequested as above } else { duration = -1; changeRequested = false; 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 16249dffc3..90bfc301b1 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 @@ -18,11 +18,12 @@ 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.JSONFormatter; -public class OpenAPSMAFragment extends Fragment implements View.OnClickListener { +public class OpenAPSMAFragment extends SubscriberFragment implements View.OnClickListener { private static Logger log = LoggerFactory.getLogger(OpenAPSMAFragment.class); private static OpenAPSMAPlugin openAPSMAPlugin; @@ -75,18 +76,6 @@ public class OpenAPSMAFragment extends Fragment implements View.OnClickListener } - @Override - public void onPause() { - super.onPause(); - MainApp.bus().unregister(this); - } - - @Override - public void onResume() { - super.onResume(); - MainApp.bus().register(this); - } - @Subscribe public void onStatusEvent(final EventOpenAPSUpdateGui ev) { updateGUI(); @@ -97,7 +86,8 @@ public class OpenAPSMAFragment extends Fragment implements View.OnClickListener updateResultGUI(ev.text); } - void updateGUI() { + @Override + protected void updateGUI() { Activity activity = getActivity(); if (activity != null) activity.runOnUiThread(new Runnable() { @@ -123,7 +113,7 @@ public class OpenAPSMAFragment extends Fragment implements View.OnClickListener }); } - void updateResultGUI(final String text) { + private void updateResultGUI(final String text) { Activity activity = getActivity(); if (activity != null) activity.runOnUiThread(new Runnable() { 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 11ea2de109..95f1235161 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 @@ -133,6 +133,13 @@ public class OpenAPSMAPlugin implements PluginBase, APSInterface { Profile profile = MainApp.getConfigBuilder().getProfile(); PumpInterface pump = MainApp.getConfigBuilder(); + if (profile == null) { + MainApp.bus().post(new EventOpenAPSUpdateResultGui(MainApp.instance().getString(R.string.noprofileselected))); + if (Config.logAPSResult) + log.debug(MainApp.instance().getString(R.string.noprofileselected)); + return; + } + if (!isEnabled(PluginBase.APS)) { MainApp.bus().post(new EventOpenAPSUpdateResultGui(MainApp.instance().getString(R.string.openapsma_disabled))); if (Config.logAPSResult) @@ -149,22 +156,13 @@ public class OpenAPSMAPlugin implements PluginBase, APSInterface { String units = profile.getUnits(); - Double maxBgDefault = Constants.MAX_BG_DEFAULT_MGDL; - Double minBgDefault = Constants.MIN_BG_DEFAULT_MGDL; - Double targetBgDefault = Constants.TARGET_BG_DEFAULT_MGDL; - if (!units.equals(Constants.MGDL)) { - maxBgDefault = Constants.MAX_BG_DEFAULT_MMOL; - minBgDefault = Constants.MIN_BG_DEFAULT_MMOL; - targetBgDefault = Constants.TARGET_BG_DEFAULT_MMOL; - } - Date now = new Date(); double maxIob = SP.getDouble("openapsma_max_iob", 1.5d); double maxBasal = SafeParse.stringToDouble(SP.getString("openapsma_max_basal", "1")); - double minBg = Profile.toMgdl(SP.getDouble("openapsma_min_bg", minBgDefault), units); - double maxBg = Profile.toMgdl(SP.getDouble("openapsma_max_bg", maxBgDefault), units); - double targetBg = Profile.toMgdl(SP.getDouble("openapsma_target_bg", targetBgDefault), units); + double minBg = Profile.toMgdl(profile.getTargetLow(), units); + double maxBg = Profile.toMgdl(profile.getTargetHigh(), units); + double targetBg = (minBg + maxBg) / 2; minBg = Round.roundTo(minBg, 0.1d); maxBg = Round.roundTo(maxBg, 0.1d); @@ -186,7 +184,7 @@ public class OpenAPSMAPlugin implements PluginBase, APSInterface { maxBg = verifyHardLimits(maxBg, "maxBg", Constants.VERY_HARD_LIMIT_MAX_BG[0], Constants.VERY_HARD_LIMIT_MAX_BG[1]); targetBg = verifyHardLimits(targetBg, "targetBg", Constants.VERY_HARD_LIMIT_TARGET_BG[0], Constants.VERY_HARD_LIMIT_TARGET_BG[1]); - TempTarget tempTarget = MainApp.getConfigBuilder().getTempTargetFromHistory(new Date().getTime()); + TempTarget tempTarget = MainApp.getConfigBuilder().getTempTargetFromHistory(System.currentTimeMillis()); if (tempTarget != null) { minBg = verifyHardLimits(tempTarget.low, "minBg", Constants.VERY_HARD_LIMIT_TEMP_MIN_BG[0], Constants.VERY_HARD_LIMIT_TEMP_MIN_BG[1]); maxBg = verifyHardLimits(tempTarget.high, "maxBg", Constants.VERY_HARD_LIMIT_TEMP_MAX_BG[0], Constants.VERY_HARD_LIMIT_TEMP_MAX_BG[1]); 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 d1b25fff3a..fdc58e92f4 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 @@ -9,7 +9,6 @@ import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; -import android.widget.Button; import android.widget.TextView; import com.crashlytics.android.answers.Answers; @@ -25,17 +24,15 @@ import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.GlucoseStatus; import info.nightscout.androidaps.data.Profile; -import info.nightscout.utils.PlusMinusEditText; +import info.nightscout.utils.NumberPicker; import info.nightscout.utils.SafeParse; import info.nightscout.utils.XdripCalibrations; public class CalibrationDialog extends DialogFragment implements View.OnClickListener { private static Logger log = LoggerFactory.getLogger(CalibrationDialog.class); - Button okButton; - PlusMinusEditText bgText; + NumberPicker bgNumber; TextView unitsView; - TextView bgView; Context context; @@ -49,6 +46,12 @@ public class CalibrationDialog extends DialogFragment implements View.OnClickLis this.context = context; } + @Override + public void onDetach() { + super.onDetach(); + this.context = null; + } + @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { @@ -57,24 +60,21 @@ public class CalibrationDialog extends DialogFragment implements View.OnClickLis getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE); getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); - okButton = (Button) view.findViewById(R.id.overview_calibration_okbutton); - okButton.setOnClickListener(this); + view.findViewById(R.id.ok).setOnClickListener(this); + view.findViewById(R.id.cancel).setOnClickListener(this); - Profile profile = MainApp.getConfigBuilder().getProfile(); - Double bg = profile != null ? Profile.fromMgdlToUnits(GlucoseStatus.getGlucoseStatusData() != null ? GlucoseStatus.getGlucoseStatusData().glucose : 0d, profile.getUnits()) : 0d; + String units = MainApp.getConfigBuilder().getProfileUnits(); + Double bg = Profile.fromMgdlToUnits(GlucoseStatus.getGlucoseStatusData() != null ? GlucoseStatus.getGlucoseStatusData().glucose : 0d, units); - String units = Constants.MGDL; - if (profile != null) - units = profile.getUnits(); + bgNumber = (NumberPicker) view.findViewById(R.id.overview_calibration_bg); if (units.equals(Constants.MMOL)) - bgText = new PlusMinusEditText(view, R.id.overview_calibration_bg, R.id.overview_calibration_bg_plus, R.id.overview_calibration_bg_minus, bg, 0d, 30d, 0.1d, new DecimalFormat("0.0"), false); + bgNumber.setParams(bg, 0d, 30d, 0.1d, new DecimalFormat("0.0"), false); else - bgText = new PlusMinusEditText(view, R.id.overview_calibration_bg, R.id.overview_calibration_bg_plus, R.id.overview_calibration_bg_minus, bg, 0d, 500d, 1d, new DecimalFormat("0"), false); + bgNumber.setParams(bg, 0d, 500d, 1d, new DecimalFormat("0"), false); unitsView = (TextView) view.findViewById(R.id.overview_calibration_units); unitsView.setText(units); - bgView = (TextView) view.findViewById(R.id.overview_calibration_bg); return view; } @@ -82,13 +82,15 @@ public class CalibrationDialog extends DialogFragment implements View.OnClickLis @Override public void onClick(View view) { switch (view.getId()) { - case R.id.overview_calibration_okbutton: - final Double bg = SafeParse.stringToDouble(this.bgView.getText().toString()); - ; + case R.id.ok: + final Double bg = SafeParse.stringToDouble(bgNumber.getText()); XdripCalibrations.confirmAndSendCalibration(bg, context); dismiss(); Answers.getInstance().logCustom(new CustomEvent("Calibration")); break; + case R.id.cancel: + dismiss(); + break; } } } 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 9b6b7a0f45..0eb8d93720 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 @@ -29,13 +29,14 @@ import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.db.CareportalEvent; import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.utils.NumberPicker; import info.nightscout.utils.PlusMinusEditText; import info.nightscout.utils.SafeParse; public class NewTreatmentDialog extends DialogFragment implements OnClickListener { - PlusMinusEditText editCarbs; - PlusMinusEditText editInsulin; + NumberPicker editCarbs; + NumberPicker editInsulin; Handler mHandler; public static HandlerThread mHandlerThread; @@ -49,7 +50,7 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.overview_newtreatment_dialog, null, false); + View view = inflater.inflate(R.layout.overview_newtreatment_dialog, container, false); view.findViewById(R.id.ok).setOnClickListener(this); view.findViewById(R.id.cancel).setOnClickListener(this); @@ -60,19 +61,15 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene Integer maxCarbs = MainApp.getConfigBuilder().applyCarbsConstraints(Constants.carbsOnlyForCheckLimit); Double maxInsulin = MainApp.getConfigBuilder().applyBolusConstraints(Constants.bolusOnlyForCheckLimit); - editCarbs = new PlusMinusEditText(view, R.id.treatments_newtreatment_carbsamount, R.id.treatments_newtreatment_carbsamount_plus, R.id.treatments_newtreatment_carbsamount_minus, 0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false); - editInsulin = new PlusMinusEditText(view, R.id.treatments_newtreatment_insulinamount, R.id.treatments_newtreatment_insulinamount_plus, R.id.treatments_newtreatment_insulinamount_minus, 0d, 0d, maxInsulin, MainApp.getConfigBuilder().getPumpDescription().bolusStep, new DecimalFormat("0.00"), false); + editCarbs = (NumberPicker) view.findViewById(R.id.treatments_newtreatment_carbsamount); + editInsulin = (NumberPicker) view.findViewById(R.id.treatments_newtreatment_insulinamount); + + editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false); + editInsulin.setParams(0d, 0d, maxInsulin, MainApp.getConfigBuilder().getPumpDescription().bolusStep, new DecimalFormat("0.00"), false); return view; } - @Override - public void onResume() { - super.onResume(); - if (getDialog() != null) - getDialog().getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); - } - @Override public void onClick(View view) { switch (view.getId()) { 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 5ba5f3a6f3..c68bbb19d7 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 @@ -21,7 +21,6 @@ import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; -import android.widget.EditText; import android.widget.LinearLayout; import android.widget.Spinner; import android.widget.TextView; @@ -44,24 +43,24 @@ import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.data.IobTotal; +import info.nightscout.androidaps.data.Profile; +import info.nightscout.androidaps.data.ProfileStore; import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.db.BgReading; import info.nightscout.androidaps.db.CareportalEvent; import info.nightscout.androidaps.db.DatabaseHelper; import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.events.EventNewBG; -import info.nightscout.androidaps.events.EventRefreshGui; +import info.nightscout.androidaps.events.EventRefreshOverview; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.Loop.LoopPlugin; -import info.nightscout.androidaps.data.Profile; -import info.nightscout.androidaps.data.ProfileStore; import info.nightscout.androidaps.plugins.OpenAPSAMA.OpenAPSAMAPlugin; import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateGui; import info.nightscout.utils.BolusWizard; import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; +import info.nightscout.utils.NumberPicker; import info.nightscout.utils.OKDialog; -import info.nightscout.utils.PlusMinusEditText; import info.nightscout.utils.SP; import info.nightscout.utils.SafeParse; import info.nightscout.utils.ToastUtils; @@ -69,10 +68,7 @@ import info.nightscout.utils.ToastUtils; public class WizardDialog extends DialogFragment implements OnClickListener, CompoundButton.OnCheckedChangeListener, Spinner.OnItemSelectedListener { private static Logger log = LoggerFactory.getLogger(WizardDialog.class); - Button wizardDialogDeliverButton; - TextView correctionInput; - TextView carbsInput; - TextView bgInput; + Button okButton; TextView bg; TextView bgInsulin; TextView bgUnits; @@ -85,8 +81,6 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com CheckBox basalIobCheckbox; TextView correctionInsulin; TextView total; - TextView totalInsulin; - EditText carbTimeEdit; Spinner profileSpinner; CheckBox superbolusCheckbox; TextView superbolus; @@ -99,10 +93,10 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com TextView cob; TextView cobInsulin; - PlusMinusEditText editBg; - PlusMinusEditText editCarbs; - PlusMinusEditText editCorr; - PlusMinusEditText editCarbTime; + NumberPicker editBg; + NumberPicker editCarbs; + NumberPicker editCorr; + NumberPicker editCarbTime; Integer calculatedCarbs = 0; Double calculatedTotalInsulin = 0d; @@ -127,11 +121,15 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com this.context = context; } + @Override + public void onDetach() { + super.onDetach(); + this.context = null; + } + @Override public void onResume() { - super.onResume(); - if (getDialog() != null) - getDialog().getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); + super.onPause(); MainApp.bus().register(this); } @@ -148,7 +146,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com activity.runOnUiThread(new Runnable() { @Override public void run() { - if (ConfigBuilderPlugin.getActiveAPS() instanceof OpenAPSAMAPlugin && ConfigBuilderPlugin.getActiveAPS().getLastAPSResult() != null && ConfigBuilderPlugin.getActiveAPS().getLastAPSRun().after(new Date(new Date().getTime() - 11 * 60 * 1000L))) { + if (ConfigBuilderPlugin.getActiveAPS() instanceof OpenAPSAMAPlugin && ConfigBuilderPlugin.getActiveAPS().getLastAPSResult() != null && ConfigBuilderPlugin.getActiveAPS().getLastAPSRun().after(new Date(System.currentTimeMillis() - 11 * 60 * 1000L))) { cobLayout.setVisibility(View.VISIBLE); cobAvailable = true; } else { @@ -195,8 +193,9 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE); getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); - wizardDialogDeliverButton = (Button) view.findViewById(R.id.treatments_wizard_deliverButton); - wizardDialogDeliverButton.setOnClickListener(this); + okButton = (Button) view.findViewById(R.id.ok); + okButton.setOnClickListener(this); + view.findViewById(R.id.cancel).setOnClickListener(this); bg = (TextView) view.findViewById(R.id.treatments_wizard_bg); bgInsulin = (TextView) view.findViewById(R.id.treatments_wizard_bginsulin); @@ -207,8 +206,6 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com basalIobInsulin = (TextView) view.findViewById(R.id.treatments_wizard_basaliobinsulin); correctionInsulin = (TextView) view.findViewById(R.id.treatments_wizard_correctioninsulin); total = (TextView) view.findViewById(R.id.treatments_wizard_total); - totalInsulin = (TextView) view.findViewById(R.id.treatments_wizard_totalinsulin); - carbTimeEdit = (EditText) view.findViewById(R.id.treatments_wizard_carbtimeinput); superbolus = (TextView) view.findViewById(R.id.treatments_wizard_sb); superbolusInsulin = (TextView) view.findViewById(R.id.treatments_wizard_sbinsulin); @@ -216,9 +213,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com bgTrendInsulin = (TextView) view.findViewById(R.id.treatments_wizard_bgtrendinsulin); cobLayout = (LinearLayout) view.findViewById(R.id.treatments_wizard_cob_layout); cob = (TextView) view.findViewById(R.id.treatments_wizard_cob); - ; cobInsulin = (TextView) view.findViewById(R.id.treatments_wizard_cobinsulin); - ; bgCheckbox = (CheckBox) view.findViewById(R.id.treatments_wizard_bgcheckbox); bolusIobCheckbox = (CheckBox) view.findViewById(R.id.treatments_wizard_bolusiobcheckbox); @@ -236,22 +231,20 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com profileSpinner = (Spinner) view.findViewById(R.id.treatments_wizard_profile); profileSpinner.setOnItemSelectedListener(this); - correctionInput = (TextView) view.findViewById(R.id.treatments_wizard_correctioninput); - carbsInput = (TextView) view.findViewById(R.id.treatments_wizard_carbsinput); - bgInput = (TextView) view.findViewById(R.id.treatments_wizard_bginput); - correctionInput.addTextChangedListener(textWatcher); - carbsInput.addTextChangedListener(textWatcher); - bgInput.addTextChangedListener(textWatcher); + editCarbTime = (NumberPicker) view.findViewById(R.id.treatments_wizard_carbtimeinput); + editCorr = (NumberPicker) view.findViewById(R.id.treatments_wizard_correctioninput); + editCarbs = (NumberPicker) view.findViewById(R.id.treatments_wizard_carbsinput); + editBg = (NumberPicker) view.findViewById(R.id.treatments_wizard_bginput); superbolusCheckbox.setVisibility(SP.getBoolean(R.string.key_usesuperbolus, false) ? View.VISIBLE : View.GONE); Integer maxCarbs = MainApp.getConfigBuilder().applyCarbsConstraints(Constants.carbsOnlyForCheckLimit); Double maxCorrection = MainApp.getConfigBuilder().applyBolusConstraints(Constants.bolusOnlyForCheckLimit); - editBg = new PlusMinusEditText(view, R.id.treatments_wizard_bginput, R.id.treatments_wizard_bginput_plus, R.id.treatments_wizard_bginput_minus, 0d, 0d, 500d, 0.1d, new DecimalFormat("0.0"), false); - editCarbs = new PlusMinusEditText(view, R.id.treatments_wizard_carbsinput, R.id.treatments_wizard_carbsinput_plus, R.id.treatments_wizard_carbsinput_minus, 0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false); - editCorr = new PlusMinusEditText(view, R.id.treatments_wizard_correctioninput, R.id.treatments_wizard_correctioninput_plus, R.id.treatments_wizard_correctioninput_minus, 0d, -maxCorrection, maxCorrection, 0.05d, new DecimalFormat("0.00"), false); - editCarbTime = new PlusMinusEditText(view, R.id.treatments_wizard_carbtimeinput, R.id.treatments_wizard_carbtime_plus, R.id.treatments_wizard_carbtime_minus, 0d, -60d, 60d, 5d, new DecimalFormat("0"), false); + 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); + editCorr.setParams(0d, -maxCorrection, maxCorrection, 0.05d, new DecimalFormat("0.00"), false, textWatcher); + editCarbTime.setParams(0d, -60d, 60d, 5d, new DecimalFormat("0"), false); initDialog(); return view; @@ -265,19 +258,19 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com @Override public void onItemSelected(AdapterView parent, View view, int position, long id) { calculateInsulin(); - wizardDialogDeliverButton.setVisibility(View.VISIBLE); + okButton.setVisibility(View.VISIBLE); } @Override public void onNothingSelected(AdapterView parent) { ToastUtils.showToastInUiThread(context, MainApp.sResources.getString(R.string.noprofileselected)); - wizardDialogDeliverButton.setVisibility(View.GONE); + okButton.setVisibility(View.GONE); } @Override public void onClick(View view) { switch (view.getId()) { - case R.id.treatments_wizard_deliverButton: + case R.id.ok: if (calculatedTotalInsulin > 0d || calculatedCarbs > 0d) { DecimalFormat formatNumber2decimalplaces = new DecimalFormat("0.00"); String confirmMessage = getString(R.string.entertreatmentquestion); @@ -299,8 +292,8 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com final Double finalInsulinAfterConstraints = insulinAfterConstraints; final Integer finalCarbsAfterConstraints = carbsAfterConstraints; - final Double bg = SafeParse.stringToDouble(bgInput.getText().toString()); - final int carbTime = SafeParse.stringToInt(carbTimeEdit.getText().toString()); + final Double bg = SafeParse.stringToDouble(editBg.getText()); + final int carbTime = SafeParse.stringToInt(editCarbTime.getText()); final boolean useSuperBolus = superbolusCheckbox.isChecked(); AlertDialog.Builder builder = new AlertDialog.Builder(context); @@ -317,9 +310,10 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com if (useSuperBolus) { final LoopPlugin activeloop = MainApp.getConfigBuilder().getActiveLoop(); if (activeloop != null) { - activeloop.superBolusTo(new Date().getTime() + 2 * 60L * 60 * 1000); - MainApp.bus().post(new EventRefreshGui(false)); + activeloop.superBolusTo(System.currentTimeMillis() + 2 * 60L * 60 * 1000); + MainApp.bus().post(new EventRefreshOverview("WizardDialog")); } + pump.cancelTempBasal(true); result = pump.setTempBasalAbsolute(0d, 120); if (!result.success) { OKDialog.show(getActivity(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror), result.comment, null); @@ -350,6 +344,9 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com dismiss(); } break; + case R.id.cancel: + dismiss(); + break; } } @@ -396,17 +393,17 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com bg.setText(lastBg.valueToUnitsToString(units) + " ISF: " + DecimalFormatter.to1Decimal(sens)); bgInsulin.setText(DecimalFormatter.to2Decimal(bgDiff / sens) + "U"); - bgInput.removeTextChangedListener(textWatcher); + editBg.removeTextChangedListener(textWatcher); //bgInput.setText(lastBg.valueToUnitsToString(units)); editBg.setValue(lastBg.valueToUnits(units)); - bgInput.addTextChangedListener(textWatcher); + editBg.addTextChangedListener(textWatcher); } else { bg.setText(""); bgInsulin.setText(""); - bgInput.removeTextChangedListener(textWatcher); + editBg.removeTextChangedListener(textWatcher); //bgInput.setText(""); editBg.setValue(0d); - bgInput.addTextChangedListener(textWatcher); + editBg.addTextChangedListener(textWatcher); } // IOB calculation @@ -418,17 +415,15 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com bolusIobInsulin.setText(DecimalFormatter.to2Decimal(-bolusIob.iob) + "U"); basalIobInsulin.setText(DecimalFormatter.to2Decimal(-basalIob.basaliob) + "U"); - totalInsulin.setText(""); - wizardDialogDeliverButton.setVisibility(Button.INVISIBLE); - // COB only if AMA is selected - if (ConfigBuilderPlugin.getActiveAPS() instanceof OpenAPSAMAPlugin && ConfigBuilderPlugin.getActiveAPS().getLastAPSResult() != null && ConfigBuilderPlugin.getActiveAPS().getLastAPSRun().after(new Date(new Date().getTime() - 11 * 60 * 1000L))) { + if (ConfigBuilderPlugin.getActiveAPS() instanceof OpenAPSAMAPlugin && ConfigBuilderPlugin.getActiveAPS().getLastAPSResult() != null && ConfigBuilderPlugin.getActiveAPS().getLastAPSRun().after(new Date(System.currentTimeMillis() - 11 * 60 * 1000L))) { cobLayout.setVisibility(View.VISIBLE); cobAvailable = true; } else { cobLayout.setVisibility(View.GONE); cobAvailable = false; } + calculateInsulin(); } private void calculateInsulin() { @@ -439,23 +434,23 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com Profile specificProfile = profile.getSpecificProfile(selectedAlternativeProfile); // Entered values - Double c_bg = SafeParse.stringToDouble(bgInput.getText().toString()); - Integer c_carbs = SafeParse.stringToInt(carbsInput.getText().toString()); - Double c_correction = SafeParse.stringToDouble(correctionInput.getText().toString()); + Double c_bg = SafeParse.stringToDouble(editBg.getText()); + Integer c_carbs = SafeParse.stringToInt(editCarbs.getText()); + Double c_correction = SafeParse.stringToDouble(editCorr.getText()); Double corrAfterConstraint = MainApp.getConfigBuilder().applyBolusConstraints(c_correction); if (c_correction - corrAfterConstraint != 0) { // c_correction != corrAfterConstraint doesn't work - correctionInput.removeTextChangedListener(textWatcher); - correctionInput.setText(""); - correctionInput.addTextChangedListener(textWatcher); + editCorr.removeTextChangedListener(textWatcher); + editCorr.setValue(0d); + editCorr.addTextChangedListener(textWatcher); //wizardDialogDeliverButton.setVisibility(Button.GONE); ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), getString(R.string.bolusconstraintapplied)); return; } Integer carbsAfterConstraint = MainApp.getConfigBuilder().applyCarbsConstraints(c_carbs); if (c_carbs - carbsAfterConstraint != 0) { - carbsInput.removeTextChangedListener(textWatcher); - carbsInput.setText(""); - carbsInput.addTextChangedListener(textWatcher); + editCarbs.removeTextChangedListener(textWatcher); + editCarbs.setValue(0d); + editCarbs.addTextChangedListener(textWatcher); //wizardDialogDeliverButton.setVisibility(Button.GONE); ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), getString(R.string.carbsconstraintapplied)); return; @@ -466,7 +461,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com // COB Double c_cob = 0d; if (cobAvailable && cobCheckbox.isChecked()) { - if (ConfigBuilderPlugin.getActiveAPS().getLastAPSResult() != null && ConfigBuilderPlugin.getActiveAPS().getLastAPSRun().after(new Date(new Date().getTime() - 11 * 60 * 1000L))) { + if (ConfigBuilderPlugin.getActiveAPS().getLastAPSResult() != null && ConfigBuilderPlugin.getActiveAPS().getLastAPSRun().after(new Date(System.currentTimeMillis() - 11 * 60 * 1000L))) { try { c_cob = SafeParse.stringToDouble(ConfigBuilderPlugin.getActiveAPS().getLastAPSResult().json().getString("COB")); } catch (JSONException e) { @@ -489,14 +484,6 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com correctionInsulin.setText(DecimalFormatter.to2Decimal(wizard.insulinFromCorrection) + "U"); calculatedTotalInsulin = wizard.calculatedTotalInsulin; - if (calculatedTotalInsulin <= 0) { - total.setText(getString(R.string.missing) + " " + DecimalFormatter.to0Decimal(wizard.carbsEquivalent) + "g"); - totalInsulin.setText(""); - } else { - total.setText(""); - totalInsulin.setText(DecimalFormatter.to2Decimal(calculatedTotalInsulin) + "U"); - } - calculatedCarbs = carbsAfterConstraint; // Superbolus @@ -531,10 +518,11 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com if (calculatedTotalInsulin > 0d || calculatedCarbs > 0d) { String insulinText = calculatedTotalInsulin > 0d ? (DecimalFormatter.to2Decimal(calculatedTotalInsulin) + "U") : ""; String carbsText = calculatedCarbs > 0d ? (DecimalFormatter.to0Decimal(calculatedCarbs) + "g") : ""; - wizardDialogDeliverButton.setText(getString(R.string.send) + " " + insulinText + " " + carbsText); - wizardDialogDeliverButton.setVisibility(Button.VISIBLE); + total.setText(getString(R.string.result) + ": " + insulinText + " " + carbsText); + okButton.setVisibility(View.VISIBLE); } else { - wizardDialogDeliverButton.setVisibility(Button.INVISIBLE); + total.setText(getString(R.string.missing) + " " + DecimalFormatter.to0Decimal(wizard.carbsEquivalent) + "g"); + okButton.setVisibility(View.INVISIBLE); } boluscalcJSON = new JSONObject(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Notification.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Notification.java index c9a80dbaef..6b15a9e17d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Notification.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Notification.java @@ -2,6 +2,13 @@ package info.nightscout.androidaps.plugins.Overview; import java.util.Date; +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.db.BgReading; +import info.nightscout.androidaps.plugins.NSClientInternal.data.NSAlarm; +import info.nightscout.androidaps.plugins.NSClientInternal.data.NSSettingsStatus; +import info.nightscout.utils.SP; + /** * Created by mike on 03.12.2016. */ @@ -11,6 +18,7 @@ public class Notification { public static final int NORMAL = 1; public static final int LOW = 2; public static final int INFO = 3; + public static final int ANNOUNCEMENT = 4; public static final int PROFILE_SET_FAILED = 0; public static final int PROFILE_SET_OK = 1; @@ -21,15 +29,18 @@ public class Notification { public static final int FAILED_UDPATE_PROFILE = 6; public static final int BASAL_VALUE_BELOW_MINIMUM = 7; public static final int OLD_NSCLIENT = 8; - public static final int INVALID_PHONE_NUMBER = 9; - public static final int APPROACHING_DAILY_LIMIT = 10; - public static final int NSCLIENT_NO_WRITE_PERMISSION = 11; - public static final int MISSING_SMS_PERMISSION = 12; - public static final int ISF_MISSING = 13; - public static final int IC_MISSING = 14; - public static final int BASAL_MISSING = 15; - public static final int TARGET_MISSING = 16; - public static final int ANNOUNCEMENT = 17; + public static final int OLD_NS = 9; + public static final int INVALID_PHONE_NUMBER = 10; + 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 ISF_MISSING = 14; + public static final int IC_MISSING = 15; + public static final int BASAL_MISSING = 16; + public static final int TARGET_MISSING = 17; + public static final int NSANNOUNCEMENT = 18; + public static final int NSALARM = 19; + public static final int NSURGENTALARM = 20; public int id; public Date date; @@ -37,6 +48,9 @@ public class Notification { public int level; public Date validTo = new Date(0); + public NSAlarm nsAlarm = null; + public Integer soundId = null; + public Notification() { } @@ -53,7 +67,7 @@ public class Notification { this.date = new Date(); this.text = text; this.level = level; - this.validTo = new Date(new Date().getTime() + validMinutes * 60 * 1000L); + this.validTo = new Date(System.currentTimeMillis() + validMinutes * 60 * 1000L); } public Notification(int id, String text, int level) { @@ -63,4 +77,68 @@ public class Notification { this.level = level; this.validTo = new Date(0); } + + public Notification(NSAlarm nsAlarm) { + this.date = new Date(); + this.validTo = new Date(0); + this.nsAlarm = nsAlarm; + switch (nsAlarm.getLevel()) { + case 0: + this.id = NSANNOUNCEMENT; + this.level = ANNOUNCEMENT; + this.text = nsAlarm.getMessage(); + this.validTo = new Date(System.currentTimeMillis() + 60 * 60 * 1000L); + break; + case 1: + this.id = NSALARM; + this.level = NORMAL; + this.text = nsAlarm.getTile(); + if (isAlarmForLow() && SP.getBoolean(R.string.key_nsalarm_low, false) || isAlarmForHigh() && SP.getBoolean(R.string.key_nsalarm_high, false)) + this.soundId = R.raw.alarm; + break; + case 2: + this.id = NSURGENTALARM; + this.level = URGENT; + this.text = nsAlarm.getTile(); + if (isAlarmForLow() && SP.getBoolean(R.string.key_nsalarm_urgent_low, false) || isAlarmForHigh() && SP.getBoolean(R.string.key_nsalarm_urgent_high, false)) + this.soundId = R.raw.urgentalarm; + break; + } + } + + public boolean isEnabled() { + if (nsAlarm == null) + return true; + if (level == ANNOUNCEMENT) + return true; + if (level == NORMAL && isAlarmForLow() && SP.getBoolean(R.string.key_nsalarm_low, false) || isAlarmForHigh() && SP.getBoolean(R.string.key_nsalarm_high, false)) + return true; + if (level == URGENT && isAlarmForLow() && SP.getBoolean(R.string.key_nsalarm_urgent_low, false) || isAlarmForHigh() && SP.getBoolean(R.string.key_nsalarm_urgent_high, false)) + return true; + return false; + } + + boolean isAlarmForLow() { + BgReading bgReading = MainApp.getDbHelper().lastBg(); + if (bgReading == null) + return false; + Double threshold = NSSettingsStatus.getInstance().getThreshold("bgTargetTop"); + if (threshold == null) + return false; + if (bgReading.value <= threshold) + return true; + return false; + } + + boolean isAlarmForHigh() { + BgReading bgReading = MainApp.getDbHelper().lastBg(); + if (bgReading == null) + return false; + Double threshold = NSSettingsStatus.getInstance().getThreshold("bgTargetBottom"); + if (threshold == null) + return false; + if (bgReading.value >= threshold) + return true; + return false; + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/NotificationStore.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/NotificationStore.java index b4cb02e914..45393f3659 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/NotificationStore.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/NotificationStore.java @@ -1,5 +1,7 @@ package info.nightscout.androidaps.plugins.Overview; +import android.content.Intent; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -9,6 +11,11 @@ import java.util.Comparator; import java.util.Date; import java.util.List; +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.Services.AlarmSoundService; +import info.nightscout.androidaps.plugins.Wear.WearPlugin; + /** * Created by mike on 03.12.2016. @@ -41,23 +48,39 @@ public class NotificationStore { return; } } + if (n.soundId != null) { + Intent alarm = new Intent(MainApp.instance().getApplicationContext(), AlarmSoundService.class); + alarm.putExtra("soundid", n.soundId); + MainApp.instance().startService(alarm); + } store.add(n); + + WearPlugin wearPlugin = (WearPlugin) MainApp.getSpecificPlugin(WearPlugin.class); + if(wearPlugin!= null && wearPlugin.isEnabled()) { + wearPlugin.overviewNotification(n.id, "OverviewNotification:\n" + n.text); + } + Collections.sort(store, new NotificationComparator()); } - public void remove(int id) { + public boolean remove(int id) { for (int i = 0; i < store.size(); i++) { if (get(i).id == id) { + if (get(i).soundId != null) { + Intent alarm = new Intent(MainApp.instance().getApplicationContext(), AlarmSoundService.class); + MainApp.instance().stopService(alarm); + } store.remove(i); - return; + return true; } } + return false; } public void removeExpired() { for (int i = 0; i < store.size(); i++) { Notification n = get(i); - if (n.validTo.getTime() != 0 && n.validTo.getTime() < new Date().getTime()) { + if (n.validTo.getTime() != 0 && n.validTo.getTime() < System.currentTimeMillis()) { store.remove(i); i--; } 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 7d81f307a2..2738491634 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 @@ -60,6 +60,7 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; +import info.nightscout.androidaps.BuildConfig; import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; @@ -83,7 +84,7 @@ import info.nightscout.androidaps.events.EventExtendedBolusChange; import info.nightscout.androidaps.events.EventInitializationChanged; import info.nightscout.androidaps.events.EventPreferenceChange; import info.nightscout.androidaps.events.EventPumpStatusChanged; -import info.nightscout.androidaps.events.EventRefreshGui; +import info.nightscout.androidaps.events.EventRefreshOverview; import info.nightscout.androidaps.events.EventTempBasalChange; import info.nightscout.androidaps.events.EventTempTargetChange; import info.nightscout.androidaps.events.EventTreatmentChange; @@ -100,13 +101,15 @@ import info.nightscout.androidaps.plugins.IobCobCalculator.events.BasalData; import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished; import info.nightscout.androidaps.plugins.Loop.LoopPlugin; import info.nightscout.androidaps.plugins.Loop.events.EventNewOpenLoopNotification; +import info.nightscout.androidaps.plugins.NSClientInternal.broadcasts.BroadcastAckAlarm; +import info.nightscout.androidaps.plugins.NSClientInternal.data.NSDeviceStatus; import info.nightscout.androidaps.plugins.OpenAPSAMA.DetermineBasalResultAMA; import info.nightscout.androidaps.plugins.OpenAPSAMA.OpenAPSAMAPlugin; import info.nightscout.androidaps.plugins.Overview.Dialogs.CalibrationDialog; import info.nightscout.androidaps.plugins.Overview.Dialogs.NewTreatmentDialog; import info.nightscout.androidaps.plugins.Overview.Dialogs.WizardDialog; import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification; -import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; +import info.nightscout.androidaps.plugins.Overview.events.EventSetWakeLock; import info.nightscout.androidaps.plugins.Overview.graphExtensions.AreaGraphSeries; import info.nightscout.androidaps.plugins.Overview.graphExtensions.DataPointWithLabelInterface; import info.nightscout.androidaps.plugins.Overview.graphExtensions.DoubleDataPoint; @@ -118,6 +121,7 @@ import info.nightscout.utils.BolusWizard; import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.NSUpload; +import info.nightscout.utils.OKDialog; import info.nightscout.utils.Profiler; import info.nightscout.utils.Round; import info.nightscout.utils.SP; @@ -147,6 +151,9 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, TextView apsModeView; TextView tempTargetView; TextView pumpStatusView; + TextView pumpDeviceStatusView; + TextView openapsDeviceStatusView; + TextView uploaderDeviceStatusView; LinearLayout loopStatusLayout; LinearLayout pumpStatusLayout; GraphView bgGraph; @@ -157,28 +164,29 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, TextView sage; TextView pbage; - TextView updating; - CheckBox showPredictionView; CheckBox showBasalsView; CheckBox showIobView; CheckBox showCobView; CheckBox showDeviationsView; + CheckBox showRatiosView; RecyclerView notificationsView; LinearLayoutManager llm; LinearLayout acceptTempLayout; - Button cancelTempButton; Button treatmentButton; Button wizardButton; Button calibrationButton; Button acceptTempButton; Button quickWizardButton; + CheckBox lockScreen; + boolean smallWidth; boolean smallHeight; + public static boolean shorttextmode = false; private int rangeToDisplay = 6; // for graph @@ -211,12 +219,16 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, 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; - if (MainApp.sResources.getBoolean(R.bool.isTablet)) { - view = inflater.inflate(R.layout.overview_fragment_tablet, container, false); - } else if (smallHeight) { + if (MainApp.sResources.getBoolean(R.bool.isTablet) && BuildConfig.NSCLIENTOLNY) { + view = inflater.inflate(R.layout.overview_fragment_nsclient_tablet, container, false); + } else if (BuildConfig.NSCLIENTOLNY) { + 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); @@ -235,6 +247,9 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, 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); loopStatusLayout = (LinearLayout) view.findViewById(R.id.overview_looplayout); pumpStatusLayout = (LinearLayout) view.findViewById(R.id.overview_pumpstatuslayout); @@ -250,23 +265,21 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, sage = (TextView) view.findViewById(R.id.careportal_sensorage); pbage = (TextView) view.findViewById(R.id.careportal_pbage); - updating = (TextView) view.findViewById(R.id.overview_updating); - bgGraph = (GraphView) view.findViewById(R.id.overview_bggraph); iobGraph = (GraphView) view.findViewById(R.id.overview_iobgraph); - cancelTempButton = (Button) view.findViewById(R.id.overview_canceltempbutton); - cancelTempButton.setOnClickListener(this); treatmentButton = (Button) view.findViewById(R.id.overview_treatmentbutton); treatmentButton.setOnClickListener(this); wizardButton = (Button) view.findViewById(R.id.overview_wizardbutton); wizardButton.setOnClickListener(this); acceptTempButton = (Button) view.findViewById(R.id.overview_accepttempbutton); - acceptTempButton.setOnClickListener(this); + if (acceptTempButton != null) + acceptTempButton.setOnClickListener(this); quickWizardButton = (Button) view.findViewById(R.id.overview_quickwizardbutton); quickWizardButton.setOnClickListener(this); calibrationButton = (Button) view.findViewById(R.id.overview_calibrationbutton); - calibrationButton.setOnClickListener(this); + if (calibrationButton != null) + calibrationButton.setOnClickListener(this); acceptTempLayout = (LinearLayout) view.findViewById(R.id.overview_accepttemplayout); @@ -275,36 +288,25 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, showIobView = (CheckBox) view.findViewById(R.id.overview_showiob); showCobView = (CheckBox) view.findViewById(R.id.overview_showcob); showDeviationsView = (CheckBox) view.findViewById(R.id.overview_showdeviations); + showRatiosView = (CheckBox) view.findViewById(R.id.overview_showratios); showPredictionView.setChecked(SP.getBoolean("showprediction", false)); showBasalsView.setChecked(SP.getBoolean("showbasals", true)); showIobView.setChecked(SP.getBoolean("showiob", false)); showCobView.setChecked(SP.getBoolean("showcob", false)); showDeviationsView.setChecked(SP.getBoolean("showdeviations", false)); + showRatiosView.setChecked(SP.getBoolean("showratios", false)); showPredictionView.setOnCheckedChangeListener(this); showBasalsView.setOnCheckedChangeListener(this); showIobView.setOnCheckedChangeListener(this); showCobView.setOnCheckedChangeListener(this); showDeviationsView.setOnCheckedChangeListener(this); + showRatiosView.setOnCheckedChangeListener(this); notificationsView = (RecyclerView) view.findViewById(R.id.overview_notifications); notificationsView.setHasFixedSize(true); llm = new LinearLayoutManager(view.getContext()); notificationsView.setLayoutManager(llm); -/* - final LinearLayout graphs = (LinearLayout)view.findViewById(R.id.overview_graphs_layout); - ViewTreeObserver observer = graphs.getViewTreeObserver(); - observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { - @Override - public void onGlobalLayout() { - log.debug("Height: " + graphs.getHeight()); - graphs.getViewTreeObserver().removeGlobalOnLayoutListener( - this); - int heightNeeded = Math.max(320, graphs.getHeight() - 200); - if (heightNeeded != bgGraph.getHeight()) - bgGraph.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, heightNeeded)); - } - }); -*/ + bgGraph.getGridLabelRenderer().setGridColor(MainApp.sResources.getColor(R.color.graphgrid)); bgGraph.getGridLabelRenderer().reloadStyles(); iobGraph.getGridLabelRenderer().setGridColor(MainApp.sResources.getColor(R.color.graphgrid)); @@ -314,16 +316,31 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, iobGraph.getGridLabelRenderer().setLabelVerticalWidth(50); 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; } }); + 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; } @@ -358,34 +375,29 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { switch (buttonView.getId()) { case R.id.overview_showprediction: - SP.putBoolean("showprediction", showPredictionView.isChecked()); - updateGUI("onPredictionCheckedChanged"); - break; case R.id.overview_showbasals: - SP.putBoolean("showbasals", showBasalsView.isChecked()); - updateGUI("onBasalsCheckedChanged"); - break; case R.id.overview_showiob: - SP.putBoolean("showiob", showIobView.isChecked()); - updateGUI("onIobCheckedChanged"); break; case R.id.overview_showcob: showDeviationsView.setOnCheckedChangeListener(null); showDeviationsView.setChecked(false); showDeviationsView.setOnCheckedChangeListener(this); - SP.putBoolean("showcob", showCobView.isChecked()); - SP.putBoolean("showdeviations", showDeviationsView.isChecked()); - updateGUI("onCobCheckedChanged"); break; case R.id.overview_showdeviations: showCobView.setOnCheckedChangeListener(null); showCobView.setChecked(false); showCobView.setOnCheckedChangeListener(this); - SP.putBoolean("showcob", showCobView.isChecked()); - SP.putBoolean("showdeviations", showDeviationsView.isChecked()); - updateGUI("onDeviationsCheckedChanged"); + break; + case R.id.overview_showratios: break; } + SP.putBoolean("showiob", showIobView.isChecked()); + SP.putBoolean("showprediction", showPredictionView.isChecked()); + SP.putBoolean("showbasals", showBasalsView.isChecked()); + SP.putBoolean("showcob", showCobView.isChecked()); + SP.putBoolean("showdeviations", showDeviationsView.isChecked()); + SP.putBoolean("showratios", showRatiosView.isChecked()); + scheduleUpdateGUI("onGraphCheckboxesCheckedChanged"); } @Override @@ -399,7 +411,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, sHandler.post(new Runnable() { @Override public void run() { - PumpEnactResult result = MainApp.getConfigBuilder().cancelTempBasal(); + PumpEnactResult result = MainApp.getConfigBuilder().cancelTempBasal(true); if (!result.success) { ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror)); } @@ -420,7 +432,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, sHandler.post(new Runnable() { @Override public void run() { - PumpEnactResult result = MainApp.getConfigBuilder().cancelTempBasal(); + PumpEnactResult result = MainApp.getConfigBuilder().cancelTempBasal(true); if (!result.success) { ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror)); } @@ -429,12 +441,12 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, NSUpload.uploadOpenAPSOffline(0); return true; } else if (item.getTitle().equals(MainApp.sResources.getString(R.string.suspendloopfor1h))) { - activeloop.suspendTo(new Date().getTime() + 60L * 60 * 1000); + activeloop.suspendTo(System.currentTimeMillis() + 60L * 60 * 1000); updateGUI("suspendmenu"); sHandler.post(new Runnable() { @Override public void run() { - PumpEnactResult result = MainApp.getConfigBuilder().cancelTempBasal(); + PumpEnactResult result = MainApp.getConfigBuilder().cancelTempBasal(true); if (!result.success) { ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror)); } @@ -443,12 +455,12 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, NSUpload.uploadOpenAPSOffline(60); return true; } else if (item.getTitle().equals(MainApp.sResources.getString(R.string.suspendloopfor2h))) { - activeloop.suspendTo(new Date().getTime() + 2 * 60L * 60 * 1000); + activeloop.suspendTo(System.currentTimeMillis() + 2 * 60L * 60 * 1000); updateGUI("suspendmenu"); sHandler.post(new Runnable() { @Override public void run() { - PumpEnactResult result = MainApp.getConfigBuilder().cancelTempBasal(); + PumpEnactResult result = MainApp.getConfigBuilder().cancelTempBasal(true); if (!result.success) { ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror)); } @@ -457,12 +469,12 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, NSUpload.uploadOpenAPSOffline(120); return true; } else if (item.getTitle().equals(MainApp.sResources.getString(R.string.suspendloopfor3h))) { - activeloop.suspendTo(new Date().getTime() + 3 * 60L * 60 * 1000); + activeloop.suspendTo(System.currentTimeMillis() + 3 * 60L * 60 * 1000); updateGUI("suspendmenu"); sHandler.post(new Runnable() { @Override public void run() { - PumpEnactResult result = MainApp.getConfigBuilder().cancelTempBasal(); + PumpEnactResult result = MainApp.getConfigBuilder().cancelTempBasal(true); if (!result.success) { ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror)); } @@ -471,12 +483,12 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, NSUpload.uploadOpenAPSOffline(180); return true; } else if (item.getTitle().equals(MainApp.sResources.getString(R.string.suspendloopfor10h))) { - activeloop.suspendTo(new Date().getTime() + 10 * 60L * 60 * 1000); + activeloop.suspendTo(System.currentTimeMillis() + 10 * 60L * 60 * 1000); updateGUI("suspendmenu"); sHandler.post(new Runnable() { @Override public void run() { - PumpEnactResult result = MainApp.getConfigBuilder().cancelTempBasal(); + PumpEnactResult result = MainApp.getConfigBuilder().cancelTempBasal(true); if (!result.success) { ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror)); } @@ -485,11 +497,12 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, NSUpload.uploadOpenAPSOffline(600); return true; } else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor30m))) { - activeloop.suspendTo(new Date().getTime() + 30L * 60 * 1000); + activeloop.suspendTo(System.currentTimeMillis() + 30L * 60 * 1000); updateGUI("suspendmenu"); sHandler.post(new Runnable() { @Override public void run() { + MainApp.getConfigBuilder().cancelTempBasal(true); PumpEnactResult result = MainApp.getConfigBuilder().setTempBasalAbsolute(0d, 30); if (!result.success) { ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror)); @@ -499,11 +512,12 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, NSUpload.uploadOpenAPSOffline(30); return true; } else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor1h))) { - activeloop.suspendTo(new Date().getTime() + 1 * 60L * 60 * 1000); + activeloop.suspendTo(System.currentTimeMillis() + 1 * 60L * 60 * 1000); updateGUI("suspendmenu"); sHandler.post(new Runnable() { @Override public void run() { + MainApp.getConfigBuilder().cancelTempBasal(true); PumpEnactResult result = MainApp.getConfigBuilder().setTempBasalAbsolute(0d, 60); if (!result.success) { ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror)); @@ -513,11 +527,12 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, NSUpload.uploadOpenAPSOffline(60); return true; } else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor2h))) { - activeloop.suspendTo(new Date().getTime() + 2 * 60L * 60 * 1000); + activeloop.suspendTo(System.currentTimeMillis() + 2 * 60L * 60 * 1000); updateGUI("suspendmenu"); sHandler.post(new Runnable() { @Override public void run() { + MainApp.getConfigBuilder().cancelTempBasal(true); PumpEnactResult result = MainApp.getConfigBuilder().setTempBasalAbsolute(0d, 2 * 60); if (!result.success) { ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror)); @@ -527,11 +542,12 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, NSUpload.uploadOpenAPSOffline(120); return true; } else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor3h))) { - activeloop.suspendTo(new Date().getTime() + 3 * 60L * 60 * 1000); + activeloop.suspendTo(System.currentTimeMillis() + 3 * 60L * 60 * 1000); updateGUI("suspendmenu"); sHandler.post(new Runnable() { @Override public void run() { + MainApp.getConfigBuilder().cancelTempBasal(true); PumpEnactResult result = MainApp.getConfigBuilder().setTempBasalAbsolute(0d, 3 * 60); if (!result.success) { ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror)); @@ -567,18 +583,6 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, NewTreatmentDialog treatmentDialogFragment = new NewTreatmentDialog(); treatmentDialogFragment.show(manager, "TreatmentDialog"); break; - case R.id.overview_canceltempbutton: - final PumpInterface pump = MainApp.getConfigBuilder(); - if (MainApp.getConfigBuilder().isTempBasalInProgress()) { - sHandler.post(new Runnable() { - @Override - public void run() { - pump.cancelTempBasal(); - Answers.getInstance().logCustom(new CustomEvent("CancelTemp")); - } - }); - } - break; case R.id.overview_pumpstatus: if (MainApp.getConfigBuilder().isSuspended() || !MainApp.getConfigBuilder().isInitialized()) sHandler.post(new Runnable() { @@ -758,8 +762,8 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, } @Subscribe - public void onStatusEvent(final EventRefreshGui ev) { - scheduleUpdateGUI("EventRefreshGui"); + public void onStatusEvent(final EventRefreshOverview ev) { + scheduleUpdateGUI(ev.from); } @Subscribe @@ -809,16 +813,6 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, scheduleUpdateGUI("EventTempTargetChange"); } - @Subscribe - public void onStatusEvent(final EventNewNotification n) { - updateNotifications(); - } - - @Subscribe - public void onStatusEvent(final EventDismissNotification n) { - updateNotifications(); - } - @Subscribe public void onStatusEvent(final EventPumpStatusChanged s) { Activity activity = getActivity(); @@ -837,7 +831,8 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, activity.runOnUiThread(new Runnable() { @Override public void run() { - acceptTempLayout.setVisibility(View.GONE); + if (acceptTempLayout != null) + acceptTempLayout.setVisibility(View.GONE); } }); } @@ -878,7 +873,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, if (scheduledUpdate != null) scheduledUpdate.cancel(false); Runnable task = new UpdateRunnable(); - final int msec = 2000; + final int msec = 500; scheduledUpdate = worker.schedule(task, msec, TimeUnit.MILLISECONDS); } @@ -893,15 +888,10 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, if (timeView != null) { //must not exists timeView.setText(DateUtil.timeString(new Date())); } - if (updating != null) - updating.setVisibility(View.VISIBLE); - if (MainApp.getConfigBuilder().getProfile() == null) {// app not initialized yet pumpStatusView.setText(R.string.noprofileset); pumpStatusLayout.setVisibility(View.VISIBLE); loopStatusLayout.setVisibility(View.GONE); - if (updating != null) - updating.setVisibility(View.GONE); return; } pumpStatusLayout.setVisibility(View.GONE); @@ -915,6 +905,14 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, PumpInterface pump = MainApp.getConfigBuilder(); Profile profile = MainApp.getConfigBuilder().getProfile(); + String units = profile.getUnits(); + + if (units == null) { + pumpStatusView.setText(R.string.noprofileset); + pumpStatusLayout.setVisibility(View.VISIBLE); + loopStatusLayout.setVisibility(View.GONE); + return; + } // open loop mode final LoopPlugin.LastRun finalLastRun = LoopPlugin.lastRun; @@ -951,25 +949,24 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, } // temp target - TempTarget tempTarget = MainApp.getConfigBuilder().getTempTargetFromHistory(new Date().getTime()); + TempTarget tempTarget = MainApp.getConfigBuilder().getTempTargetFromHistory(System.currentTimeMillis()); if (tempTarget != null) { tempTargetView.setTextColor(Color.BLACK); tempTargetView.setBackgroundColor(MainApp.sResources.getColor(R.color.tempTargetBackground)); tempTargetView.setVisibility(View.VISIBLE); if (tempTarget.low == tempTarget.high) - tempTargetView.setText(Profile.toUnitsString(tempTarget.low, Profile.fromMgdlToUnits(tempTarget.low, profile.getUnits()), profile.getUnits())); + tempTargetView.setText(Profile.toUnitsString(tempTarget.low, Profile.fromMgdlToUnits(tempTarget.low, units), units)); else - tempTargetView.setText(Profile.toUnitsString(tempTarget.low, Profile.fromMgdlToUnits(tempTarget.low, profile.getUnits()), profile.getUnits()) + " - " + Profile.toUnitsString(tempTarget.high, Profile.fromMgdlToUnits(tempTarget.high, profile.getUnits()), profile.getUnits())); + tempTargetView.setText(Profile.toUnitsString(tempTarget.low, Profile.fromMgdlToUnits(tempTarget.low, units), units) + " - " + Profile.toUnitsString(tempTarget.high, Profile.fromMgdlToUnits(tempTarget.high, units), units)); } else { - Double maxBgDefault = Constants.MAX_BG_DEFAULT_MGDL; - Double minBgDefault = Constants.MIN_BG_DEFAULT_MGDL; - if (!profile.getUnits().equals(Constants.MGDL)) { - maxBgDefault = Constants.MAX_BG_DEFAULT_MMOL; - minBgDefault = Constants.MIN_BG_DEFAULT_MMOL; - } tempTargetView.setTextColor(Color.WHITE); tempTargetView.setBackgroundColor(MainApp.sResources.getColor(R.color.tempTargetDisabledBackground)); - tempTargetView.setText(SP.getDouble("openapsma_min_bg", minBgDefault) + " - " + SP.getDouble("openapsma_max_bg", maxBgDefault)); + double low = MainApp.getConfigBuilder().getProfile().getTargetLow(); + double high = MainApp.getConfigBuilder().getProfile().getTargetHigh(); + if (low == high) + tempTargetView.setText("" + low); + else + tempTargetView.setText(low + " - " + high); tempTargetView.setVisibility(View.VISIBLE); } if (Config.NSCLIENT && tempTarget == null) { @@ -977,51 +974,91 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, } // **** Temp button **** - boolean showAcceptButton = !MainApp.getConfigBuilder().isClosedModeEnabled(); // Open mode needed - showAcceptButton = showAcceptButton && finalLastRun != null && finalLastRun.lastAPSRun != null; // aps result must exist - showAcceptButton = showAcceptButton && (finalLastRun.lastOpenModeAccept == null || finalLastRun.lastOpenModeAccept.getTime() < finalLastRun.lastAPSRun.getTime()); // never accepted or before last result - showAcceptButton = showAcceptButton && finalLastRun.constraintsProcessed.changeRequested; // change is requested + if (acceptTempLayout != null) { + boolean showAcceptButton = !MainApp.getConfigBuilder().isClosedModeEnabled(); // Open mode needed + showAcceptButton = showAcceptButton && finalLastRun != null && finalLastRun.lastAPSRun != null; // aps result must exist + showAcceptButton = showAcceptButton && (finalLastRun.lastOpenModeAccept == null || finalLastRun.lastOpenModeAccept.getTime() < finalLastRun.lastAPSRun.getTime()); // never accepted or before last result + showAcceptButton = showAcceptButton && finalLastRun.constraintsProcessed.changeRequested; // change is requested - if (showAcceptButton && pump.isInitialized() && !pump.isSuspended() && ConfigBuilderPlugin.getActiveLoop() != null) { - acceptTempLayout.setVisibility(View.VISIBLE); - acceptTempButton.setText(getContext().getString(R.string.setbasalquestion) + "\n" + finalLastRun.constraintsProcessed); - } else { - acceptTempLayout.setVisibility(View.GONE); + if (showAcceptButton && pump.isInitialized() && !pump.isSuspended() && ConfigBuilderPlugin.getActiveLoop() != null) { + acceptTempLayout.setVisibility(View.VISIBLE); + acceptTempButton.setText(getContext().getString(R.string.setbasalquestion) + "\n" + finalLastRun.constraintsProcessed); + } else { + acceptTempLayout.setVisibility(View.GONE); + } } // **** Calibration button **** - if (MainApp.getSpecificPlugin(SourceXdripPlugin.class) != null && MainApp.getSpecificPlugin(SourceXdripPlugin.class).isEnabled(PluginBase.BGSOURCE) && profile != null && DatabaseHelper.actualBg() != null) { - calibrationButton.setVisibility(View.VISIBLE); - } else { - calibrationButton.setVisibility(View.GONE); - } - - TemporaryBasal activeTemp = MainApp.getConfigBuilder().getTempBasalFromHistory(new Date().getTime()); - if (activeTemp != null) { - cancelTempButton.setVisibility(View.VISIBLE); - cancelTempButton.setText(MainApp.instance().getString(R.string.cancel) + "\n" + activeTemp.toStringShort()); - } else { - cancelTempButton.setVisibility(View.GONE); + if (calibrationButton != null) { + if (MainApp.getSpecificPlugin(SourceXdripPlugin.class) != null && MainApp.getSpecificPlugin(SourceXdripPlugin.class).isEnabled(PluginBase.BGSOURCE) && profile != null && DatabaseHelper.actualBg() != null) { + calibrationButton.setVisibility(View.VISIBLE); + } else { + calibrationButton.setVisibility(View.GONE); + } } + final TemporaryBasal activeTemp = MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis()); String basalText = ""; + if (shorttextmode) { + if (activeTemp != null) { + basalText = "T: " + activeTemp.toStringVeryShort(); + } else { + basalText = DecimalFormatter.to2Decimal(MainApp.getConfigBuilder().getProfile().getBasal()) + "U/h"; + } + baseBasalView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + String fullText = MainApp.sResources.getString(R.string.virtualpump_basebasalrate_label) + ": " + DecimalFormatter.to2Decimal(MainApp.getConfigBuilder().getProfile().getBasal()) + "U/h\n"; + if (activeTemp != null) { + fullText += MainApp.sResources.getString(R.string.virtualpump_tempbasal_label) + ": " + activeTemp.toStringFull(); + } + OKDialog.show(getActivity(), MainApp.sResources.getString(R.string.basal), fullText, null); + } + }); + + } else { + if (activeTemp != null) { + basalText = activeTemp.toStringFull() + " "; + } + if (Config.NSCLIENT) + basalText += "(" + DecimalFormatter.to2Decimal(MainApp.getConfigBuilder().getProfile().getBasal()) + " U/h)"; + else if (pump.getPumpDescription().isTempBasalCapable) { + basalText += "(" + DecimalFormatter.to2Decimal(pump.getBaseBasalRate()) + "U/h)"; + } + } if (activeTemp != null) { - basalText = activeTemp.toStringFull() + " "; - } - if (Config.NSCLIENT) - basalText += "( " + DecimalFormatter.to2Decimal(MainApp.getConfigBuilder().getProfile().getBasal()) + " U/h )"; - else if (pump.getPumpDescription().isTempBasalCapable) { - basalText += "( " + DecimalFormatter.to2Decimal(pump.getBaseBasalRate()) + " U/h )"; + baseBasalView.setTextColor(MainApp.sResources.getColor(R.color.basal)); + } else { + baseBasalView.setTextColor(Color.WHITE); + } + baseBasalView.setText(basalText); - ExtendedBolus extendedBolus = MainApp.getConfigBuilder().getExtendedBolusFromHistory(new Date().getTime()); + final ExtendedBolus extendedBolus = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()); String extendedBolusText = ""; - if (extendedBolus != null) { + if (extendedBolus != null && !pump.isFakingTempsByExtendedBoluses()) { extendedBolusText = extendedBolus.toString(); } - if (extendedBolusView != null) // must not exists in all layouts - extendedBolusView.setText(extendedBolusText); + if (extendedBolusView != null) { // must not exists in all layouts + if (shorttextmode) { + if (extendedBolus != null && !pump.isFakingTempsByExtendedBoluses()) { + extendedBolusText = DecimalFormatter.to2Decimal(extendedBolus.absoluteRate()) + "U/h"; + } else { + extendedBolusText = ""; + } + extendedBolusView.setText(extendedBolusText); + extendedBolusView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + OKDialog.show(getActivity(), MainApp.sResources.getString(R.string.extendedbolus), extendedBolus.toString(), null); + } + }); + + } else { + extendedBolusView.setText(extendedBolusText); + } + } activeProfileView.setText(MainApp.getConfigBuilder().getProfileName()); activeProfileView.setBackgroundColor(Color.GRAY); @@ -1031,9 +1068,9 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, public boolean onLongClick(View view) { view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); NewNSTreatmentDialog newDialog = new NewNSTreatmentDialog(); - final OptionsToShow profileswitch = new OptionsToShow(R.id.careportal_profileswitch, R.string.careportal_profileswitch, true, false, false, false, false, false, false, true, false, false); + final OptionsToShow profileswitch = CareportalFragment.profileswitch; profileswitch.executeProfileSwitch = true; - newDialog.setOptions(profileswitch); + newDialog.setOptions(profileswitch, R.string.careportal_profileswitch); newDialog.show(getFragmentManager(), "NewNSTreatmentDialog"); return true; } @@ -1046,9 +1083,9 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, public boolean onLongClick(View view) { view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); NewNSTreatmentDialog newTTDialog = new NewNSTreatmentDialog(); - final OptionsToShow temptarget = new OptionsToShow(R.id.careportal_temporarytarget, R.string.careportal_temporarytarget, false, false, false, false, true, false, false, false, false, true); + final OptionsToShow temptarget = CareportalFragment.temptarget; temptarget.executeTempTarget = true; - newTTDialog.setOptions(temptarget); + newTTDialog.setOptions(temptarget, R.string.careportal_temporarytarget); newTTDialog.show(getFragmentManager(), "NewNSTreatmentDialog"); return true; } @@ -1061,7 +1098,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, quickWizardButton.setVisibility(View.VISIBLE); String text = quickWizardEntry.buttonText() + "\n" + DecimalFormatter.to0Decimal(quickWizardEntry.carbs()) + "g"; BolusWizard wizard = new BolusWizard(); - wizard.doCalc(profile, quickWizardEntry.carbs(), 0d, lastBG.valueToUnits(profile.getUnits()), 0d, true, true, false, false); + wizard.doCalc(profile, quickWizardEntry.carbs(), 0d, lastBG.valueToUnits(units), 0d, true, true, false, false); text += " " + DecimalFormatter.to2Decimal(wizard.calculatedTotalInsulin) + "U"; quickWizardButton.setText(text); if (wizard.calculatedTotalInsulin <= 0) @@ -1078,8 +1115,6 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, treatmentButton.setVisibility(View.GONE); } - String units = profile.getUnits(); - Double lowLine = SP.getDouble("low_mark", 0d); Double highLine = SP.getDouble("high_mark", 0d); if (lowLine < 1) { @@ -1096,22 +1131,22 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, color = MainApp.sResources.getColor(R.color.low); else if (lastBG.valueToUnits(units) > highLine) color = MainApp.sResources.getColor(R.color.high); - bgView.setText(lastBG.valueToUnitsToString(profile.getUnits())); + bgView.setText(lastBG.valueToUnitsToString(units)); arrowView.setText(lastBG.directionToSymbol()); bgView.setTextColor(color); arrowView.setTextColor(color); GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData(); if (glucoseStatus != null) { deltaView.setText("Δ " + Profile.toUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units) + " " + units); - 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)); + 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.sResources.getString(R.string.notavailable)); - avgdeltaView.setText(""); + if (avgdeltaView != null) + avgdeltaView.setText(""); } } else { - if (updating != null) - updating.setVisibility(View.GONE); return; } Integer flag = bgView.getPaintFlags(); @@ -1121,27 +1156,46 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, flag &= ~Paint.STRIKE_THRU_TEXT_FLAG; bgView.setPaintFlags(flag); - Long agoMsec = new Date().getTime() - lastBG.date; + Long agoMsec = System.currentTimeMillis() - lastBG.date; int agoMin = (int) (agoMsec / 60d / 1000d); timeAgoView.setText(String.format(MainApp.sResources.getString(R.string.minago), agoMin)); // iob MainApp.getConfigBuilder().updateTotalIOBTreatments(); MainApp.getConfigBuilder().updateTotalIOBTempBasals(); - IobTotal bolusIob = MainApp.getConfigBuilder().getLastCalculationTreatments().round(); - IobTotal basalIob = MainApp.getConfigBuilder().getLastCalculationTempBasals().round(); + final IobTotal bolusIob = MainApp.getConfigBuilder().getLastCalculationTreatments().round(); + final IobTotal basalIob = MainApp.getConfigBuilder().getLastCalculationTempBasals().round(); - String iobtext = getString(R.string.treatments_iob_label_string) + " " + DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U (" - + getString(R.string.bolus) + ": " + DecimalFormatter.to2Decimal(bolusIob.iob) + "U " - + getString(R.string.basal) + ": " + DecimalFormatter.to2Decimal(basalIob.basaliob) + "U)"; - iobView.setText(iobtext); + if (shorttextmode) { + String iobtext = DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U"; + iobView.setText(iobtext); + iobView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + String iobtext = DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U\n" + + getString(R.string.bolus) + ": " + DecimalFormatter.to2Decimal(bolusIob.iob) + "U\n" + + getString(R.string.basal) + ": " + DecimalFormatter.to2Decimal(basalIob.basaliob) + "U\n"; + OKDialog.show(getActivity(), MainApp.sResources.getString(R.string.iob), iobtext, null); + } + }); + } else if (MainApp.sResources.getBoolean(R.bool.isTablet)) { + String iobtext = DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U (" + + getString(R.string.bolus) + ": " + DecimalFormatter.to2Decimal(bolusIob.iob) + "U " + + getString(R.string.basal) + ": " + DecimalFormatter.to2Decimal(basalIob.basaliob) + "U)"; + iobView.setText(iobtext); + } else { + String iobtext = DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U (" + + DecimalFormatter.to2Decimal(bolusIob.iob) + "/" + + DecimalFormatter.to2Decimal(basalIob.basaliob) + ")"; + iobView.setText(iobtext); + } // cob if (cobView != null) { // view must not exists String cobText = ""; - AutosensData autosensData = IobCobCalculatorPlugin.getAutosensData(new Date().getTime()); + AutosensData autosensData = IobCobCalculatorPlugin.getAutosensData(System.currentTimeMillis()); if (autosensData != null) - cobText = (int) autosensData.cob + " g " + String.format(MainApp.sResources.getString(R.string.minago), autosensData.minOld()); + cobText = (int) autosensData.cob + " g"; cobView.setText(cobText); } @@ -1154,12 +1208,45 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, getActivity().findViewById(R.id.overview_showprediction_label).setVisibility(View.GONE); } + // pump status from ns + if (pumpDeviceStatusView != null) { + pumpDeviceStatusView.setText(NSDeviceStatus.getInstance().getPumpStatus()); + pumpDeviceStatusView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + OKDialog.show(getActivity(), MainApp.sResources.getString(R.string.pump), NSDeviceStatus.getInstance().getExtendedPumpStatus(), null); + } + }); + } + + // OpenAPS status from ns + if (openapsDeviceStatusView != null) { + openapsDeviceStatusView.setText(NSDeviceStatus.getInstance().getOpenApsStatus()); + openapsDeviceStatusView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + OKDialog.show(getActivity(), MainApp.sResources.getString(R.string.openaps), NSDeviceStatus.getInstance().getExtendedOpenApsStatus(), null); + } + }); + } + + // Uploader status from ns + if (uploaderDeviceStatusView != null) { + uploaderDeviceStatusView.setText(NSDeviceStatus.getInstance().getUploaderStatus()); + uploaderDeviceStatusView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + OKDialog.show(getActivity(), MainApp.sResources.getString(R.string.uploader), NSDeviceStatus.getInstance().getExtendedUploaderStatus(), null); + } + }); + } + // ****** GRAPH ******* //log.debug("updateGUI checkpoint 1"); // allign to hours Calendar calendar = Calendar.getInstance(); - calendar.setTimeInMillis(new Date().getTime()); + calendar.setTimeInMillis(System.currentTimeMillis()); calendar.set(Calendar.MILLISECOND, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MINUTE, 0); @@ -1170,16 +1257,16 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, long fromTime; long endTime; if (showPrediction) { - int predHours = (int) (Math.ceil(((DetermineBasalResultAMA) finalLastRun.constraintsProcessed).getLatestPredictionsTime() - new Date().getTime()) / (60 * 60 * 1000)); + 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() + 60000; // little bit more to avoid wrong rounding + 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 { hoursToFetch = rangeToDisplay; - toTime = calendar.getTimeInMillis() + 600000; // little bit more to avoid wrong rounding + toTime = calendar.getTimeInMillis() + 100000; // little bit more to avoid wrong rounding - Graphview specific fromTime = toTime - hoursToFetch * 60 * 60 * 1000L; endTime = toTime; } @@ -1194,7 +1281,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, // **** TEMP BASALS graph **** Double maxBasalValueFound = 0d; - long now = new Date().getTime(); + long now = System.currentTimeMillis(); if (pump.getPumpDescription().isTempBasalCapable && showBasalsView.isChecked()) { List baseBasalArray = new ArrayList<>(); List tempBasalArray = new ArrayList<>(); @@ -1204,7 +1291,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, double lastAbsoluteLineBasal = 0; double lastBaseBasal = 0; double lastTempBasal = 0; - for (long time = fromTime; time < now; time += 60 * 1000L) { + for (long time = fromTime; time < now; time += 60 * 1000L) { BasalData basalData = IobCobCalculatorPlugin.getBasalData(time); double baseBasalValue = basalData.basal; double absoluteLineValue = baseBasalValue; @@ -1300,20 +1387,23 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, FixedLineGraphSeries iobSeries; FixedLineGraphSeries cobSeries; BarGraphSeries devSeries; + LineGraphSeries ratioSeries; Double maxIobValueFound = 0d; Double maxCobValueFound = 0d; Double maxDevValueFound = 0d; + Double maxRatioValueFound = 0d; - if (showIobView.isChecked() || showCobView.isChecked() || showDeviationsView.isChecked()) { + if (showIobView.isChecked() || showCobView.isChecked() || showDeviationsView.isChecked() || showRatiosView.isChecked()) { //Date start = new Date(); List iobArray = new ArrayList<>(); List cobArray = new ArrayList<>(); List devArray = new ArrayList<>(); + List ratioArray = new ArrayList<>(); double lastIob = 0; int lastCob = 0; for (long time = fromTime; time <= now; time += 5 * 60 * 1000L) { if (showIobView.isChecked()) { - double iob = IobCobCalculatorPlugin.calulateFromTreatmentsAndTemps(time).iob; + double iob = IobCobCalculatorPlugin.calculateFromTreatmentsAndTempsSynchronized(time).iob; if (Math.abs(lastIob - iob) > 0.02) { if (Math.abs(lastIob - iob) > 0.2) iobArray.add(new DataPoint(time, lastIob)); @@ -1322,7 +1412,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, lastIob = iob; } } - if (showCobView.isChecked() || showDeviationsView.isChecked()) { + if (showCobView.isChecked() || showDeviationsView.isChecked() || showRatiosView.isChecked()) { AutosensData autosensData = IobCobCalculatorPlugin.getAutosensData(time); if (autosensData != null && showCobView.isChecked()) { int cob = (int) autosensData.cob; @@ -1342,6 +1432,10 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, devArray.add(new DeviationDataPoint(time, autosensData.deviation, color)); maxDevValueFound = Math.max(maxDevValueFound, Math.abs(autosensData.deviation)); } + if (autosensData != null && showRatiosView.isChecked()) { + ratioArray.add(new DataPoint(time, autosensData.autosensRatio)); + maxRatioValueFound = Math.max(maxRatioValueFound, Math.abs(autosensData.autosensRatio)); + } } } //Profiler.log(log, "IOB processed", start); @@ -1354,18 +1448,49 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, iobSeries.setThickness(3); - if (showIobView.isChecked() && (showCobView.isChecked() || showDeviationsView.isChecked())) { - List cobArrayRescaled = new ArrayList<>(); - List devArrayRescaled = new ArrayList<>(); - for (int ci = 0; ci < cobArray.size(); ci++) { - cobArrayRescaled.add(new DataPoint(cobArray.get(ci).getX(), cobArray.get(ci).getY() * maxIobValueFound / maxCobValueFound / 2)); - } - for (int ci = 0; ci < devArray.size(); ci++) { - devArrayRescaled.add(new DeviationDataPoint(devArray.get(ci).getX(), devArray.get(ci).getY() * maxIobValueFound / maxDevValueFound, devArray.get(ci).color)); - } - cobArray = cobArrayRescaled; - devArray = devArrayRescaled; + Double maxByScale = null; + int graphsToShow = 0; + if (showIobView.isChecked()) { + if (maxByScale == null) maxByScale = maxIobValueFound; + graphsToShow++; } + if (showCobView.isChecked()) { + if (maxByScale == null) maxByScale = maxCobValueFound; + graphsToShow++; + } + if (showDeviationsView.isChecked()) { + if (maxByScale == null) maxByScale = maxDevValueFound; + graphsToShow++; + } + if (showRatiosView.isChecked()) { + if (maxByScale == null) maxByScale = maxRatioValueFound; + graphsToShow++; + } + + if (graphsToShow > 1) { + if (!maxByScale.equals(maxCobValueFound)) { + List cobArrayRescaled = new ArrayList<>(); + for (int ci = 0; ci < cobArray.size(); ci++) { + cobArrayRescaled.add(new DataPoint(cobArray.get(ci).getX(), cobArray.get(ci).getY() * maxByScale / maxCobValueFound / 2)); + } + cobArray = cobArrayRescaled; + } + if (!maxByScale.equals(maxDevValueFound)) { + List devArrayRescaled = new ArrayList<>(); + for (int ci = 0; ci < devArray.size(); ci++) { + devArrayRescaled.add(new DeviationDataPoint(devArray.get(ci).getX(), devArray.get(ci).getY() * maxByScale / maxDevValueFound, devArray.get(ci).color)); + } + devArray = devArrayRescaled; + } + if (!maxByScale.equals(maxRatioValueFound)) { + List ratioArrayRescaled = new ArrayList<>(); + for (int ci = 0; ci < ratioArray.size(); ci++) { + ratioArrayRescaled.add(new DataPoint(ratioArray.get(ci).getX(), (ratioArray.get(ci).getY() - 1) * maxByScale / maxRatioValueFound)); + } + ratioArray = ratioArrayRescaled; + } + } + // COB DataPoint[] cobData = new DataPoint[cobArray.size()]; cobData = cobArray.toArray(cobData); @@ -1385,13 +1510,17 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, return data.color; } }); - //devSeries.setBackgroundColor(0xB0FFFFFF & MainApp.sResources.getColor(R.color.cob)); //50% - //devSeries.setColor(MainApp.sResources.getColor(R.color.cob)); - //devSeries.setThickness(3); + + // RATIOS + DataPoint[] ratioData = new DataPoint[ratioArray.size()]; + ratioData = ratioArray.toArray(ratioData); + ratioSeries = new LineGraphSeries<>(ratioData); + ratioSeries.setColor(MainApp.sResources.getColor(R.color.ratio)); + ratioSeries.setThickness(3); iobGraph.getSeries().clear(); - if (showIobView.isChecked()) { + if (showIobView.isChecked() && iobData.length > 0) { addSeriesWithoutInvalidate(iobSeries, iobGraph); } if (showCobView.isChecked() && cobData.length > 0) { @@ -1400,6 +1529,9 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, if (showDeviationsView.isChecked() && devData.length > 0) { addSeriesWithoutInvalidate(devSeries, iobGraph); } + if (showRatiosView.isChecked() && ratioData.length > 0) { + addSeriesWithoutInvalidate(ratioSeries, iobGraph); + } iobGraph.setVisibility(View.VISIBLE); } else { iobGraph.setVisibility(View.GONE); @@ -1440,8 +1572,6 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, List bgListArray = new ArrayList<>(); if (bgReadingsArray.size() == 0) { - if (updating != null) - updating.setVisibility(View.GONE); return; } @@ -1461,7 +1591,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, maxBgValue = Profile.fromMgdlToUnits(maxBgValue, units); maxBgValue = units.equals(Constants.MGDL) ? Round.roundTo(maxBgValue, 40d) + 80 : Round.roundTo(maxBgValue, 2d) + 4; if (highLine > maxBgValue) maxBgValue = highLine; - Integer numOfHorizLines = units.equals(Constants.MGDL) ? (int) (maxBgValue / 40 + 1) : (int) (maxBgValue / 2 + 1); + Integer numOfVertLines = units.equals(Constants.MGDL) ? (int) (maxBgValue / 40 + 1) : (int) (maxBgValue / 2 + 1); DataPointWithLabelInterface[] bg = new DataPointWithLabelInterface[bgListArray.size()]; bg = bgListArray.toArray(bg); @@ -1529,7 +1659,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, bgGraph.getViewport().setMaxY(maxBgValue); bgGraph.getViewport().setMinY(0); bgGraph.getViewport().setYAxisBoundsManual(true); - bgGraph.getGridLabelRenderer().setNumVerticalLabels(numOfHorizLines); + bgGraph.getGridLabelRenderer().setNumVerticalLabels(numOfVertLines); // set second scale if (pump.getPumpDescription().isTempBasalCapable && showBasalsView.isChecked()) { @@ -1578,18 +1708,16 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, bgGraph.onDataChanged(false, false); iobGraph.onDataChanged(false, false); - if (updating != null) - updating.setVisibility(View.GONE); Profiler.log(log, from, updateGUIStart); } public double getNearestBg(long date, List bgReadingsArray) { double bg = 0; - Profile profile = MainApp.getConfigBuilder().getProfile(); + String units = MainApp.getConfigBuilder().getProfileUnits(); for (int r = bgReadingsArray.size() - 1; r >= 0; r--) { BgReading reading = bgReadingsArray.get(r); if (reading.date > date) continue; - bg = Profile.fromMgdlToUnits(reading.value, profile.getUnits()); + bg = Profile.fromMgdlToUnits(reading.value, units); break; } return bg; @@ -1602,7 +1730,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, //Notifications - public static class RecyclerViewAdapter extends RecyclerView.Adapter { + static class RecyclerViewAdapter extends RecyclerView.Adapter { List notificationsList; @@ -1613,8 +1741,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, @Override public NotificationsViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.overview_notification_item, viewGroup, false); - NotificationsViewHolder notificationsViewHolder = new NotificationsViewHolder(v); - return notificationsViewHolder; + return new NotificationsViewHolder(v); } @Override @@ -1631,6 +1758,8 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, holder.cv.setBackgroundColor(ContextCompat.getColor(MainApp.instance(), R.color.notificationLow)); else if (notification.level == Notification.INFO) holder.cv.setBackgroundColor(ContextCompat.getColor(MainApp.instance(), R.color.notificationInfo)); + else if (notification.level == Notification.ANNOUNCEMENT) + holder.cv.setBackgroundColor(ContextCompat.getColor(MainApp.instance(), R.color.notificationAnnouncement)); } @Override @@ -1643,7 +1772,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, super.onAttachedToRecyclerView(recyclerView); } - public static class NotificationsViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { + static class NotificationsViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { CardView cv; TextView time; TextView text; @@ -1664,6 +1793,9 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, switch (v.getId()) { case R.id.notification_dismiss: MainApp.bus().post(new EventDismissNotification(notification.id)); + if (notification.nsAlarm != null) { + BroadcastAckAlarm.handleClearAlarm(notification.nsAlarm, MainApp.instance().getApplicationContext(), 60 * 60 * 1000L); + } break; } } 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 b513d68dac..30148f94c2 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 @@ -7,6 +7,7 @@ import org.json.JSONException; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.events.EventRefreshOverview; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; @@ -17,8 +18,8 @@ import info.nightscout.utils.SP; */ public class OverviewPlugin implements PluginBase { - public static Double bgTargetLow = 80d; - public static Double bgTargetHigh = 180d; + public static double bgTargetLow = 80d; + public static double bgTargetHigh = 180d; public QuickWizard quickWizard = new QuickWizard(); @@ -99,11 +100,13 @@ public class OverviewPlugin implements PluginBase { @Subscribe public void onStatusEvent(final EventNewNotification n) { notificationStore.add(n.notification); + MainApp.bus().post(new EventRefreshOverview("EventNewNotification")); } @Subscribe public void onStatusEvent(final EventDismissNotification n) { - notificationStore.remove(n.id); + if (notificationStore.remove(n.id)) + MainApp.bus().post(new EventRefreshOverview("EventDismissNotification")); } } 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 new file mode 100644 index 0000000000..519341172d --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/events/EventSetWakeLock.java @@ -0,0 +1,13 @@ +package info.nightscout.androidaps.plugins.Overview.events; + +/** + * Created by mike on 02.07.2017. + */ + +public class EventSetWakeLock { + public boolean lock = false; + + public EventSetWakeLock(boolean val) { + lock = val; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphExtensions/TimeAsXAxisLabelFormatter.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphExtensions/TimeAsXAxisLabelFormatter.java index c8ba40369d..881e472a1d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphExtensions/TimeAsXAxisLabelFormatter.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphExtensions/TimeAsXAxisLabelFormatter.java @@ -23,10 +23,8 @@ public class TimeAsXAxisLabelFormatter extends DefaultLabelFormatter { public String formatLabel(double value, boolean isValueX) { if (isValueX) { // format as date - Calendar calendar = Calendar.getInstance(); - calendar.setTimeInMillis((long) value); DateFormat dateFormat = new SimpleDateFormat(mFormat); - return dateFormat.format(calendar.getTimeInMillis()); + return dateFormat.format((long) value); } else { return super.formatLabel(value, isValueX); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Persistentnotification/PersistentNotificationFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Persistentnotification/PersistentNotificationFragment.java deleted file mode 100644 index 78e7791c2d..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Persistentnotification/PersistentNotificationFragment.java +++ /dev/null @@ -1,12 +0,0 @@ -package info.nightscout.androidaps.plugins.Persistentnotification; - -import android.support.v4.app.Fragment; - -/** - * Created by adrian on 23/12/16. - */ - -public class PersistentNotificationFragment extends Fragment { - - -} 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 7e7f2ab7a2..68d1ed487a 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 @@ -11,8 +11,6 @@ import android.support.v7.app.NotificationCompat; import com.squareup.otto.Subscribe; -import java.util.Date; - import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainActivity; import info.nightscout.androidaps.MainApp; @@ -27,12 +25,11 @@ import info.nightscout.androidaps.events.EventInitializationChanged; import info.nightscout.androidaps.events.EventNewBG; import info.nightscout.androidaps.events.EventNewBasalProfile; import info.nightscout.androidaps.events.EventPreferenceChange; -import info.nightscout.androidaps.events.EventRefreshGui; +import info.nightscout.androidaps.events.EventRefreshOverview; import info.nightscout.androidaps.events.EventTempBasalChange; import info.nightscout.androidaps.events.EventTreatmentChange; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PumpInterface; -import info.nightscout.androidaps.data.Profile; import info.nightscout.utils.DecimalFormatter; /** @@ -57,7 +54,7 @@ public class PersistentNotificationPlugin implements PluginBase { @Override public String getFragmentClass() { - return PersistentNotificationFragment.class.getName(); + return null; } @Override @@ -118,17 +115,20 @@ public class PersistentNotificationPlugin implements PluginBase { String line1 = ctx.getString(R.string.noprofile); - Profile profile = MainApp.getConfigBuilder().getProfile(); + + if (MainApp.getConfigBuilder().getActiveProfileInterface() == null || MainApp.getConfigBuilder().getProfile() == null) + return; + String units = MainApp.getConfigBuilder().getProfileUnits(); BgReading lastBG = DatabaseHelper.lastBg(); GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData(); - if (profile != null && lastBG != null) { - line1 = lastBG.valueToUnitsToString(profile.getUnits()); + if (lastBG != null) { + line1 = lastBG.valueToUnitsToString(units); if (glucoseStatus != null) { - line1 += " Δ" + deltastring(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, profile.getUnits()) - + " avgΔ" + deltastring(glucoseStatus.avgdelta, glucoseStatus.avgdelta * Constants.MGDL_TO_MMOLL, profile.getUnits()); + line1 += " Δ" + deltastring(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units) + + " avgΔ" + deltastring(glucoseStatus.avgdelta, glucoseStatus.avgdelta * Constants.MGDL_TO_MMOLL, units); } else { line1 += " " + ctx.getString(R.string.old_data) + @@ -139,7 +139,7 @@ public class PersistentNotificationPlugin implements PluginBase { PumpInterface pump = MainApp.getConfigBuilder(); if (MainApp.getConfigBuilder().isTempBasalInProgress()) { - TemporaryBasal activeTemp = MainApp.getConfigBuilder().getTempBasalFromHistory(new Date().getTime()); + TemporaryBasal activeTemp = MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis()); line1 += " " + activeTemp.toStringShort(); } @@ -258,7 +258,7 @@ public class PersistentNotificationPlugin implements PluginBase { } @Subscribe - public void onStatusEvent(final EventRefreshGui ev) { + public void onStatusEvent(final EventRefreshOverview ev) { updateNotification(); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileCircadianPercentage/CircadianPercentageProfileFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileCircadianPercentage/CircadianPercentageProfileFragment.java index 7ae97a17b5..c42f1d0c64 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileCircadianPercentage/CircadianPercentageProfileFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileCircadianPercentage/CircadianPercentageProfileFragment.java @@ -33,13 +33,17 @@ import org.slf4j.LoggerFactory; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.events.EventInitializationChanged; +import info.nightscout.androidaps.events.EventNewBasalProfile; +import info.nightscout.androidaps.events.EventProfileSwitchChange; import info.nightscout.androidaps.interfaces.PumpInterface; +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.utils.DecimalFormatter; import info.nightscout.utils.SafeParse; -public class CircadianPercentageProfileFragment extends Fragment { +public class CircadianPercentageProfileFragment extends SubscriberFragment { private static Logger log = LoggerFactory.getLogger(CircadianPercentageProfileFragment.class); private static CircadianPercentageProfilePlugin circadianPercentageProfilePlugin = new CircadianPercentageProfilePlugin(); @@ -74,6 +78,50 @@ public class CircadianPercentageProfileFragment extends Fragment { static Boolean percentageViewHint = true; static Boolean timeshiftViewHint = true; + TextWatcher textWatch = new TextWatcher() { + + @Override + public void afterTextChanged(Editable s) { + } + + @Override + public void beforeTextChanged(CharSequence s, int start, + int count, int after) { + } + + @Override + public void onTextChanged(CharSequence s, int start, + int before, int count) { + + if (percentageView.testValidity()) { + if (SafeParse.stringToInt(percentageView.getText().toString()) == 0) { + circadianPercentageProfilePlugin.percentage = 100; + } else { + circadianPercentageProfilePlugin.percentage = SafeParse.stringToInt(percentageView.getText().toString()); + } + updateProfileInfo(); + } + if (timeshiftView.testValidity()) { + circadianPercentageProfilePlugin.timeshift = SafeParse.stringToInt(timeshiftView.getText().toString()); + updateProfileInfo(); + } + if (diaView.testValidity()) { + circadianPercentageProfilePlugin.dia = SafeParse.stringToDouble(diaView.getText().toString()); + updateProfileInfo(); + } + if (targethighView.testValidity()) { + circadianPercentageProfilePlugin.targetLow = SafeParse.stringToDouble(targetlowView.getText().toString()); + updateProfileInfo(); + } + if (targetlowView.testValidity()) { + circadianPercentageProfilePlugin.targetHigh = SafeParse.stringToDouble(targethighView.getText().toString()); + updateProfileInfo(); + } + circadianPercentageProfilePlugin.storeSettings(); + updateProfileInfo(); + } + }; + @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { @@ -105,16 +153,6 @@ public class CircadianPercentageProfileFragment extends Fragment { layout.findViewById(R.id.circadianpercentageprofile_baseprofilebasal_layout).setVisibility(View.GONE); } - - mgdlView.setChecked(circadianPercentageProfilePlugin.mgdl); - mmolView.setChecked(circadianPercentageProfilePlugin.mmol); - diaView.setText(circadianPercentageProfilePlugin.dia.toString()); - targetlowView.setText(circadianPercentageProfilePlugin.targetLow.toString()); - targethighView.setText(circadianPercentageProfilePlugin.targetHigh.toString()); - percentageView.setText("" + circadianPercentageProfilePlugin.percentage); - timeshiftView.setText("" + circadianPercentageProfilePlugin.timeshift); - updateProfileInfo(); - mgdlView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -140,9 +178,9 @@ public class CircadianPercentageProfileFragment extends Fragment { @Override public void onClick(View view) { NewNSTreatmentDialog newDialog = new NewNSTreatmentDialog(); - final OptionsToShow profileswitch = new OptionsToShow(R.id.careportal_profileswitch, R.string.careportal_profileswitch, true, false, false, false, false, false, false, true, false, false); + final OptionsToShow profileswitch = CareportalFragment.profileswitch; profileswitch.executeProfileSwitch = true; - newDialog.setOptions(profileswitch); + newDialog.setOptions(profileswitch, R.string.careportal_profileswitch); newDialog.show(getFragmentManager(), "NewNSTreatmentDialog"); } }); @@ -265,49 +303,6 @@ public class CircadianPercentageProfileFragment extends Fragment { } }); - TextWatcher textWatch = new TextWatcher() { - - @Override - public void afterTextChanged(Editable s) { - } - - @Override - public void beforeTextChanged(CharSequence s, int start, - int count, int after) { - } - - @Override - public void onTextChanged(CharSequence s, int start, - int before, int count) { - - if (percentageView.testValidity()) { - if (SafeParse.stringToInt(percentageView.getText().toString()) == 0) { - circadianPercentageProfilePlugin.percentage = 100; - } else { - circadianPercentageProfilePlugin.percentage = SafeParse.stringToInt(percentageView.getText().toString()); - } - updateProfileInfo(); - } - if (timeshiftView.testValidity()) { - circadianPercentageProfilePlugin.timeshift = SafeParse.stringToInt(timeshiftView.getText().toString()); - updateProfileInfo(); - } - if (diaView.testValidity()) { - circadianPercentageProfilePlugin.dia = SafeParse.stringToDouble(diaView.getText().toString()); - updateProfileInfo(); - } - if (targethighView.testValidity()) { - circadianPercentageProfilePlugin.targetLow = SafeParse.stringToDouble(targetlowView.getText().toString()); - updateProfileInfo(); - } - if (targetlowView.testValidity()) { - circadianPercentageProfilePlugin.targetHigh = SafeParse.stringToDouble(targethighView.getText().toString()); - updateProfileInfo(); - } - circadianPercentageProfilePlugin.storeSettings(); - updateProfileInfo(); - } - }; diaView.addTextChangedListener(textWatch); targetlowView.addTextChangedListener(textWatch); @@ -315,11 +310,39 @@ public class CircadianPercentageProfileFragment extends Fragment { percentageView.addTextChangedListener(textWatch); timeshiftView.addTextChangedListener(textWatch); - onStatusEvent(null); + updateGUI(); + + onStatusEvent(new EventInitializationChanged()); return layout; } + public void updateGUI() { + updateProfileInfo(); + + diaView.removeTextChangedListener(textWatch); + targetlowView.removeTextChangedListener(textWatch); + targethighView.removeTextChangedListener(textWatch); + percentageView.removeTextChangedListener(textWatch); + timeshiftView.removeTextChangedListener(textWatch); + + mgdlView.setChecked(circadianPercentageProfilePlugin.mgdl); + mmolView.setChecked(circadianPercentageProfilePlugin.mmol); + diaView.setText(circadianPercentageProfilePlugin.dia.toString()); + targetlowView.setText(circadianPercentageProfilePlugin.targetLow.toString()); + targethighView.setText(circadianPercentageProfilePlugin.targetHigh.toString()); + percentageView.setText("" + circadianPercentageProfilePlugin.percentage); + timeshiftView.setText("" + circadianPercentageProfilePlugin.timeshift); + + + diaView.addTextChangedListener(textWatch); + targetlowView.addTextChangedListener(textWatch); + targethighView.addTextChangedListener(textWatch); + percentageView.addTextChangedListener(textWatch); + timeshiftView.addTextChangedListener(textWatch); + + } + private void customSnackbar(View view, final String Msg, Object snackbarCaller) { if(mSnackBar!= null) mSnackBar.dismiss(); @@ -410,7 +433,6 @@ public class CircadianPercentageProfileFragment extends Fragment { if (i == 0) { copyprevbutton.setVisibility(View.INVISIBLE); - ; } else { final int j = i; //needs to be final to be passed to inner class. copyprevbutton.setOnClickListener(new View.OnClickListener() { @@ -461,15 +483,13 @@ public class CircadianPercentageProfileFragment extends Fragment { } basalEditDialog = null; - MainApp.bus().unregister(this); fl.requestFocusFromTouch(); } @Override public void onResume() { super.onResume(); - MainApp.bus().register(this); - onStatusEvent(null); + onStatusEvent(new EventInitializationChanged()); fl.requestFocusFromTouch(); } @@ -488,4 +508,17 @@ public class CircadianPercentageProfileFragment extends Fragment { } }); } + + @Subscribe + public void onStatusEvent(final EventProfileSwitchChange e) { + Activity activity = getActivity(); + if (activity != null) + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + updateGUI(); + } + }); + } + } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileCircadianPercentage/CircadianPercentageProfilePlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileCircadianPercentage/CircadianPercentageProfilePlugin.java index 0fe6c30c78..768cdf90e7 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileCircadianPercentage/CircadianPercentageProfilePlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileCircadianPercentage/CircadianPercentageProfilePlugin.java @@ -9,13 +9,18 @@ import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.text.DecimalFormat; + import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.ProfileInterface; import info.nightscout.androidaps.data.ProfileStore; +import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialog; import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.NSUpload; import info.nightscout.utils.SP; @@ -157,6 +162,55 @@ public class CircadianPercentageProfilePlugin implements PluginBase, ProfileInte createConvertedProfile(); } + public String externallySetParameters(int timeshift, int percentage) { + + String msg = ""; + + if (!fragmentEnabled){ + msg+= "NO CPP!" + "\n"; + } + + //check for validity + if (percentage < Constants.CPP_MIN_PERCENTAGE || percentage > Constants.CPP_MAX_PERCENTAGE) { + msg+= String.format(MainApp.sResources.getString(R.string.openapsma_valueoutofrange), "Profile-Percentage") + "\n"; + } + if (timeshift < 0 || timeshift > 23) { + msg+= String.format(MainApp.sResources.getString(R.string.openapsma_valueoutofrange), "Profile-Timeshift") + "\n"; + } + if(!SP.getBoolean("syncprofiletopump", false)){ + msg+= MainApp.sResources.getString(R.string.syncprofiletopump_title) + " " + MainApp.sResources.getString(R.string.cpp_sync_setting_missing) + "\n"; + } + final PumpInterface pump = MainApp.getConfigBuilder(); + final Profile profile = MainApp.getConfigBuilder().getProfile(); + + if (pump == null || profile == null || profile.getBasal() == null){ + msg+= MainApp.sResources.getString(R.string.cpp_notloadedplugins) + "\n"; + } + if(!"".equals(msg)) { + msg += MainApp.sResources.getString(R.string.cpp_valuesnotstored); + return msg; + } + + //store profile + this.timeshift= timeshift; + this.percentage = percentage; + storeSettings(); + + + //send profile to pumpe + new NewNSTreatmentDialog(); //init + NewNSTreatmentDialog.doProfileSwitch(this.getProfile(), this.getProfileName(), 0); + + //return formatted string + /*msg += "%: " + this.percentage + " h: +" + this.timeshift; + msg += "\n"; + msg += "\nBasal:\n" + basalString() + "\n"; + msg += "\nISF:\n" + isfString() + "\n"; + msg += "\nIC:\n" + isfString() + "\n";*/ + + return msg; + } + private void createConvertedProfile() { JSONObject json = new JSONObject(); JSONObject store = new JSONObject(); @@ -179,26 +233,23 @@ public class CircadianPercentageProfilePlugin implements PluginBase, ProfileInte int offset = -(timeshift % 24) + 24; JSONArray icArray = new JSONArray(); - for (int i = 0; i < 24; i++) { - icArray.put(new JSONObject().put("timeAsSeconds", i * 60 * 60).put("value", baseic[(offset + i) % 24] * 100d / percentage)); - } - profile.put("carbratio", icArray); - JSONArray isfArray = new JSONArray(); - for (int i = 0; i < 24; i++) { - isfArray.put(new JSONObject().put("timeAsSeconds", i * 60 * 60).put("value", baseisf[(offset + i) % 24] * 100d / percentage)); - } - profile.put("sens", isfArray); - JSONArray basalArray = new JSONArray(); for (int i = 0; i < 24; i++) { - basalArray.put(new JSONObject().put("timeAsSeconds", i * 60 * 60).put("value", basebasal[(offset + i) % 24] * percentage / 100d)); + String time; + DecimalFormat df = new DecimalFormat("00"); + time = df.format(i) + ":00"; + icArray.put(new JSONObject().put("time", time).put("timeAsSeconds", i * 60 * 60).put("value", baseic[(offset + i) % 24] * 100d / percentage)); + isfArray.put(new JSONObject().put("time", time).put("timeAsSeconds", i * 60 * 60).put("value", baseisf[(offset + i) % 24] * 100d / percentage)); + basalArray.put(new JSONObject().put("time", time).put("timeAsSeconds", i * 60 * 60).put("value", basebasal[(offset + i) % 24] * percentage / 100d)); } + profile.put("carbratio", icArray); + profile.put("sens", isfArray); profile.put("basal", basalArray); - profile.put("target_low", new JSONArray().put(new JSONObject().put("timeAsSeconds", 0).put("value", targetLow))); - profile.put("target_high", new JSONArray().put(new JSONObject().put("timeAsSeconds", 0).put("value", targetHigh))); + profile.put("target_low", new JSONArray().put(new JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", targetLow))); + profile.put("target_high", new JSONArray().put(new JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", targetHigh))); profile.put("units", mgdl ? Constants.MGDL : Constants.MMOL); store.put(profileName, profile); } catch (JSONException e) { @@ -214,6 +265,11 @@ public class CircadianPercentageProfilePlugin implements PluginBase, ProfileInte return convertedProfile; } + @Override + public String getUnits() { + return mgdl ? Constants.MGDL : Constants.MMOL; + } + @Override public String getProfileName() { performLimitCheck(); @@ -300,4 +356,11 @@ public class CircadianPercentageProfilePlugin implements PluginBase, ProfileInte return sb.toString(); } + public int getPercentage() { + return percentage; + } + + public int getTimeshift() { + return timeshift; + } } 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 86a983ae17..7161a1d9de 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 @@ -24,12 +24,14 @@ import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.events.EventInitializationChanged; import info.nightscout.androidaps.interfaces.PumpInterface; +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.utils.SafeParse; import info.nightscout.utils.TimeListEdit; -public class LocalProfileFragment extends Fragment { +public class LocalProfileFragment extends SubscriberFragment { private static Logger log = LoggerFactory.getLogger(LocalProfileFragment.class); private static LocalProfilePlugin localProfilePlugin = new LocalProfilePlugin(); @@ -72,7 +74,7 @@ public class LocalProfileFragment extends Fragment { layout.findViewById(R.id.localprofile_basal).setVisibility(View.GONE); } - onStatusEvent(null); + updateGUI(); mgdlView.setChecked(localProfilePlugin.mgdl); mmolView.setChecked(localProfilePlugin.mmol); @@ -101,9 +103,9 @@ public class LocalProfileFragment extends Fragment { @Override public void onClick(View view) { NewNSTreatmentDialog newDialog = new NewNSTreatmentDialog(); - final OptionsToShow profileswitch = new OptionsToShow(R.id.careportal_profileswitch, R.string.careportal_profileswitch, true, false, false, false, false, false, false, true, false, false); + final OptionsToShow profileswitch = CareportalFragment.profileswitch; profileswitch.executeProfileSwitch = true; - newDialog.setOptions(profileswitch); + newDialog.setOptions(profileswitch, R.string.careportal_profileswitch); newDialog.show(getFragmentManager(), "NewNSTreatmentDialog"); } }); @@ -129,26 +131,18 @@ public class LocalProfileFragment extends Fragment { diaView.addTextChangedListener(textWatch); - onStatusEvent(null); + updateGUI(); return layout; } - @Override - public void onPause() { - super.onPause(); - MainApp.bus().unregister(this); - } - - @Override - public void onResume() { - super.onResume(); - MainApp.bus().register(this); - onStatusEvent(null); - } - @Subscribe public void onStatusEvent(final EventInitializationChanged e) { + updateGUI(); + } + + @Override + protected void updateGUI() { Activity activity = getActivity(); if (activity != null) activity.runOnUiThread(new Runnable() { 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 d22361981c..8aca0a8dbc 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 @@ -30,7 +30,7 @@ public class LocalProfilePlugin implements PluginBase, ProfileInterface { private static ProfileStore convertedProfile = null; private static String convertedProfileName = null; - final private String DEFAULTARRAY = "[{\"timeAsSeconds\":0,\"value\":0}]"; + final private String DEFAULTARRAY = "[{\"time\":\"00:00\",\"timeAsSeconds\":0,\"value\":0}]"; boolean mgdl; boolean mmol; @@ -240,6 +240,11 @@ public class LocalProfilePlugin implements PluginBase, ProfileInterface { return convertedProfile; } + @Override + public String getUnits() { + return mgdl ? Constants.MGDL : Constants.MMOL; + } + @Override public String getProfileName() { return convertedProfileName; 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 f765fe6ed1..c8b5b2c5db 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 @@ -13,10 +13,11 @@ import com.squareup.otto.Subscribe; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.Profile; +import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.ProfileNS.events.EventNSProfileUpdateGUI; import info.nightscout.utils.DecimalFormatter; -public class NSProfileFragment extends Fragment { +public class NSProfileFragment extends SubscriberFragment { private static NSProfilePlugin nsProfilePlugin = new NSProfilePlugin(); public static NSProfilePlugin getPlugin() { @@ -50,18 +51,6 @@ public class NSProfileFragment extends Fragment { return layout; } - @Override - public void onPause() { - super.onPause(); - MainApp.bus().unregister(this); - } - - @Override - public void onResume() { - super.onResume(); - MainApp.bus().register(this); - } - @Subscribe public void onStatusEvent(final EventNSProfileUpdateGUI ev) { Activity activity = getActivity(); @@ -74,7 +63,8 @@ public class NSProfileFragment extends Fragment { }); } - private void updateGUI() { + @Override + protected void updateGUI() { if (MainApp.getConfigBuilder().getProfile() == null) { noProfile.setVisibility(View.VISIBLE); return; 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 b310993584..32d3f625d3 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 @@ -11,6 +11,7 @@ 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.Services.Intents; @@ -153,6 +154,11 @@ public class NSProfilePlugin implements PluginBase, ProfileInterface { return profile; } + @Override + public String getUnits() { + return profile != null ? profile.getUnits() : Constants.MGDL; + } + @Override public String getProfileName() { return profile.getDefaultProfileName(); 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 b183b28a0b..a4e3a8eecf 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 @@ -22,11 +22,13 @@ import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.events.EventInitializationChanged; import info.nightscout.androidaps.interfaces.PumpInterface; +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.utils.SafeParse; -public class SimpleProfileFragment extends Fragment { +public class SimpleProfileFragment extends SubscriberFragment { private static Logger log = LoggerFactory.getLogger(SimpleProfileFragment.class); private static SimpleProfilePlugin simpleProfilePlugin = new SimpleProfilePlugin(); @@ -65,7 +67,7 @@ public class SimpleProfileFragment extends Fragment { layout.findViewById(R.id.simpleprofile_basalrate_label).setVisibility(View.GONE); } - onStatusEvent(null); + updateGUI(); mgdlView.setChecked(simpleProfilePlugin.mgdl); mmolView.setChecked(simpleProfilePlugin.mmol); @@ -99,9 +101,9 @@ public class SimpleProfileFragment extends Fragment { @Override public void onClick(View view) { NewNSTreatmentDialog newDialog = new NewNSTreatmentDialog(); - final OptionsToShow profileswitch = new OptionsToShow(R.id.careportal_profileswitch, R.string.careportal_profileswitch, true, false, false, false, false, false, false, true, false, false); + final OptionsToShow profileswitch = CareportalFragment.profileswitch; profileswitch.executeProfileSwitch = true; - newDialog.setOptions(profileswitch); + newDialog.setOptions(profileswitch, R.string.careportal_profileswitch); newDialog.show(getFragmentManager(), "NewNSTreatmentDialog"); } }); @@ -137,26 +139,18 @@ public class SimpleProfileFragment extends Fragment { targetlowView.addTextChangedListener(textWatch); targethighView.addTextChangedListener(textWatch); - onStatusEvent(null); + updateGUI(); return layout; } - @Override - public void onPause() { - super.onPause(); - MainApp.bus().unregister(this); - } - - @Override - public void onResume() { - super.onResume(); - MainApp.bus().register(this); - onStatusEvent(null); - } - @Subscribe public void onStatusEvent(final EventInitializationChanged e) { + updateGUI(); + } + + @Override + protected void updateGUI() { Activity activity = getActivity(); if (activity != null) activity.runOnUiThread(new Runnable() { 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 40a53d0707..e02f4918c2 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 @@ -183,11 +183,11 @@ public class SimpleProfilePlugin implements PluginBase, ProfileInterface { json.put("defaultProfile", "SimpleProfile"); json.put("store", store); profile.put("dia", dia); - profile.put("carbratio", new JSONArray().put(new JSONObject().put("timeAsSeconds", 0).put("value", ic))); - profile.put("sens", new JSONArray().put(new JSONObject().put("timeAsSeconds", 0).put("value", isf))); - profile.put("basal", new JSONArray().put(new JSONObject().put("timeAsSeconds", 0).put("value", basal))); - profile.put("target_low", new JSONArray().put(new JSONObject().put("timeAsSeconds", 0).put("value", targetLow))); - profile.put("target_high", new JSONArray().put(new JSONObject().put("timeAsSeconds", 0).put("value", targetHigh))); + profile.put("carbratio", new JSONArray().put(new JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", ic))); + profile.put("sens", new JSONArray().put(new JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", isf))); + profile.put("basal", new JSONArray().put(new JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", basal))); + profile.put("target_low", new JSONArray().put(new JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", targetLow))); + profile.put("target_high", new JSONArray().put(new JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", targetHigh))); profile.put("units", mgdl ? Constants.MGDL : Constants.MMOL); store.put("SimpleProfile", profile); } catch (JSONException e) { @@ -201,6 +201,11 @@ public class SimpleProfilePlugin implements PluginBase, ProfileInterface { return convertedProfile; } + @Override + public String getUnits() { + return mgdl ? Constants.MGDL : Constants.MMOL; + } + @Override public String getProfileName() { return "SimpleProfile"; 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 20c8843a31..87c635cbef 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 @@ -27,15 +27,16 @@ import info.nightscout.androidaps.R; import info.nightscout.androidaps.events.EventExtendedBolusChange; import info.nightscout.androidaps.events.EventPumpStatusChanged; import info.nightscout.androidaps.events.EventTempBasalChange; +import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.PumpDanaR.Dialogs.ProfileViewDialog; -import info.nightscout.androidaps.plugins.PumpDanaR.History.DanaRHistoryActivity; -import info.nightscout.androidaps.plugins.PumpDanaR.History.DanaRStatsActivity; +import info.nightscout.androidaps.plugins.PumpDanaR.activities.DanaRHistoryActivity; +import info.nightscout.androidaps.plugins.PumpDanaR.activities.DanaRStatsActivity; import info.nightscout.androidaps.plugins.PumpDanaR.events.EventDanaRNewStatus; import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.SetWarnColor; -public class DanaRFragment extends Fragment { +public class DanaRFragment extends SubscriberFragment { private static Logger log = LoggerFactory.getLogger(DanaRFragment.class); private static DanaRPlugin danaRPlugin; @@ -156,18 +157,6 @@ public class DanaRFragment extends Fragment { return view; } - @Override - public void onPause() { - super.onPause(); - MainApp.bus().unregister(this); - } - - @Override - public void onResume() { - super.onResume(); - MainApp.bus().register(this); - } - @Subscribe public void onStatusEvent(final EventPumpStatusChanged c) { Activity activity = getActivity(); @@ -204,7 +193,8 @@ public class DanaRFragment extends Fragment { } // GUI functions - private void updateGUI() { + @Override + protected void updateGUI() { Activity activity = getActivity(); if (activity != null && basaBasalRateView != null) activity.runOnUiThread(new Runnable() { @@ -213,13 +203,13 @@ public class DanaRFragment extends Fragment { public void run() { DanaRPump pump = DanaRPump.getInstance(); if (pump.lastConnection.getTime() != 0) { - Long agoMsec = new Date().getTime() - pump.lastConnection.getTime(); + Long agoMsec = System.currentTimeMillis() - pump.lastConnection.getTime(); int agoMin = (int) (agoMsec / 60d / 1000d); lastConnectionView.setText(DateUtil.timeString(pump.lastConnection) + " (" + String.format(MainApp.sResources.getString(R.string.minago), agoMin) + ")"); SetWarnColor.setColor(lastConnectionView, agoMin, 16d, 31d); } if (pump.lastBolusTime.getTime() != 0) { - Long agoMsec = new Date().getTime() - pump.lastBolusTime.getTime(); + Long agoMsec = System.currentTimeMillis() - pump.lastBolusTime.getTime(); double agoHours = agoMsec / 60d / 60d / 1000d; if (agoHours < 6) // max 6h back lastBolusView.setText(DateUtil.timeString(pump.lastBolusTime) + " (" + DecimalFormatter.to1Decimal(agoHours) + " " + MainApp.sResources.getString(R.string.hoursago) + ") " + DecimalFormatter.to2Decimal(DanaRPump.getInstance().lastBolusAmount) + " U"); @@ -230,12 +220,12 @@ public class DanaRFragment extends Fragment { SetWarnColor.setColor(dailyUnitsView, pump.dailyTotalUnits, pump.maxDailyTotalUnits * 0.75d, pump.maxDailyTotalUnits * 0.9d); basaBasalRateView.setText("( " + (pump.activeProfile + 1) + " ) " + DecimalFormatter.to2Decimal(getPlugin().getBaseBasalRate()) + " U/h"); if (MainApp.getConfigBuilder().isInHistoryRealTempBasalInProgress()) { - tempBasalView.setText(MainApp.getConfigBuilder().getRealTempBasalFromHistory(new Date().getTime()).toStringFull()); + tempBasalView.setText(MainApp.getConfigBuilder().getRealTempBasalFromHistory(System.currentTimeMillis()).toStringFull()); } else { tempBasalView.setText(""); } if (MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) { - extendedBolusView.setText(MainApp.getConfigBuilder().getExtendedBolusFromHistory(new Date().getTime()).toString()); + extendedBolusView.setText(MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()).toString()); } else { extendedBolusView.setText(""); } 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 6d337048d7..aaae495c58 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 @@ -30,6 +30,7 @@ import info.nightscout.androidaps.db.Treatment; import info.nightscout.androidaps.events.EventAppExit; import info.nightscout.androidaps.events.EventPreferenceChange; import info.nightscout.androidaps.interfaces.ConstraintsInterface; +import info.nightscout.androidaps.interfaces.DanaRInterface; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.ProfileInterface; import info.nightscout.androidaps.interfaces.PumpDescription; @@ -50,7 +51,7 @@ import info.nightscout.utils.SP; /** * Created by mike on 05.08.2016. */ -public class DanaRPlugin implements PluginBase, PumpInterface, ConstraintsInterface, ProfileInterface { +public class DanaRPlugin implements PluginBase, PumpInterface, DanaRInterface, ConstraintsInterface, ProfileInterface { private static Logger log = LoggerFactory.getLogger(DanaRPlugin.class); @Override @@ -82,7 +83,7 @@ public class DanaRPlugin implements PluginBase, PumpInterface, ConstraintsInterf pumpDescription.bolusStep = 0.1d; pumpDescription.isExtendedBolusCapable = true; - pumpDescription.extendedBolusStep = 0.1d; + pumpDescription.extendedBolusStep = 0.05d; pumpDescription.extendedBolusDurationStep = 30; pumpDescription.extendedBolusMaxDuration = 8 * 60; @@ -265,7 +266,7 @@ public class DanaRPlugin implements PluginBase, PumpInterface, ConstraintsInterf int basalIncrement = pump.basal48Enable ? 30 * 60 : 60 * 60; for (int h = 0; h < basalValues; h++) { Double pumpValue = pump.pumpProfiles[pump.activeProfile][h]; - Double profileValue = profile.getBasal(h * basalIncrement); + Double profileValue = profile.getBasal((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); @@ -308,7 +309,7 @@ public class DanaRPlugin implements PluginBase, PumpInterface, ConstraintsInterf if (Config.logPumpActions) log.debug("deliverTreatment: OK. Asked: " + detailedBolusInfo.insulin + " Delivered: " + result.bolusDelivered); detailedBolusInfo.insulin = t.insulin; - detailedBolusInfo.date = new Date().getTime(); + detailedBolusInfo.date = System.currentTimeMillis(); MainApp.getConfigBuilder().addToHistoryTreatment(detailedBolusInfo); return result; } else { @@ -335,7 +336,7 @@ public class DanaRPlugin implements PluginBase, PumpInterface, ConstraintsInterf @Override public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes) { // Recheck pump status if older than 30 min - if (pump.lastConnection.getTime() + 30 * 60 * 1000L < new Date().getTime()) { + if (pump.lastConnection.getTime() + 30 * 60 * 1000L < System.currentTimeMillis()) { doConnect("setTempBasalAbsolute old data"); } @@ -379,6 +380,9 @@ public class DanaRPlugin implements PluginBase, PumpInterface, ConstraintsInterf if (percentRate > getPumpDescription().maxTempPercent) { percentRate = getPumpDescription().maxTempPercent; } + if (Config.logPumpActions) + log.debug("setTempBasalAbsolute: Calculated percent rate: " + percentRate); + // If extended in progress if (MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress() && useExtendedBoluses) { if (Config.logPumpActions) @@ -392,7 +396,10 @@ public class DanaRPlugin implements PluginBase, PumpInterface, ConstraintsInterf // Check if some temp is already in progress if (MainApp.getConfigBuilder().isInHistoryRealTempBasalInProgress()) { // Correct basal already set ? - if (MainApp.getConfigBuilder().getRealTempBasalFromHistory(new Date().getTime()).percentRate == percentRate) { + TemporaryBasal running = MainApp.getConfigBuilder().getRealTempBasalFromHistory(System.currentTimeMillis()); + if (Config.logPumpActions) + log.debug("setTempBasalAbsolute: currently running: " + running.toString()); + if (running.percentRate == percentRate) { result.success = true; result.percent = percentRate; result.absolute = MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory(); @@ -403,15 +410,6 @@ public class DanaRPlugin implements PluginBase, PumpInterface, ConstraintsInterf if (Config.logPumpActions) log.debug("setTempBasalAbsolute: Correct temp basal already set (doLowTemp || doHighTemp)"); return result; - } else { - if (Config.logPumpActions) - log.debug("setTempBasalAbsolute: Stopping temp basal (doLowTemp || doHighTemp)"); - result = cancelRealTempBasal(); - // Check for proper result - if (!result.success) { - log.error("setTempBasalAbsolute: Failed to stop previous temp basal (doLowTemp || doHighTemp)"); - return result; - } } } // Convert duration from minutes to hours @@ -438,7 +436,7 @@ public class DanaRPlugin implements PluginBase, PumpInterface, ConstraintsInterf Double extendedRateToSet = absoluteRate - getBaseBasalRate(); extendedRateToSet = configBuilderPlugin.applyBasalConstraints(extendedRateToSet); // needs to be rounded to 0.1 - extendedRateToSet = Round.roundTo(extendedRateToSet, 0.1d); + extendedRateToSet = Round.roundTo(extendedRateToSet, pumpDescription.extendedBolusStep * 2); // *2 because of halfhours // What is current rate of extended bolusing in u/h? if (Config.logPumpActions) { @@ -503,6 +501,7 @@ public class DanaRPlugin implements PluginBase, PumpInterface, ConstraintsInterf result.comment = MainApp.instance().getString(R.string.virtualpump_resultok); result.duration = pump.tempBasalRemainingMin; result.percent = pump.tempBasalPercent; + result.absolute = MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory(); result.isPercent = true; if (Config.logPumpActions) log.debug("setTempBasalPercent: Correct value already set"); @@ -517,6 +516,7 @@ public class DanaRPlugin implements PluginBase, PumpInterface, ConstraintsInterf result.isTempCancel = false; result.duration = pump.tempBasalRemainingMin; result.percent = pump.tempBasalPercent; + result.absolute = MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory(); result.isPercent = true; if (Config.logPumpActions) log.debug("setTempBasalPercent: OK"); @@ -534,7 +534,8 @@ public class DanaRPlugin implements PluginBase, PumpInterface, ConstraintsInterf ConfigBuilderPlugin configBuilderPlugin = MainApp.getConfigBuilder(); insulin = configBuilderPlugin.applyBolusConstraints(insulin); // needs to be rounded - insulin = Round.roundTo(insulin, getPumpDescription().extendedBolusStep); + int durationInHalfHours = Math.max(durationInMinutes / 30, 1); + insulin = Round.roundTo(insulin, getPumpDescription().extendedBolusStep * (1 + durationInHalfHours % 1)); PumpEnactResult result = new PumpEnactResult(); if (pump.isExtendedInProgress && Math.abs(pump.extendedBolusAmount - insulin) < getPumpDescription().extendedBolusStep) { @@ -549,7 +550,6 @@ public class DanaRPlugin implements PluginBase, PumpInterface, ConstraintsInterf log.debug("setExtendedBolus: Correct extended bolus already set. Current: " + pump.extendedBolusAmount + " Asked: " + insulin); return result; } - int durationInHalfHours = Math.max(durationInMinutes / 30, 1); boolean connectionOK = sExecutionService.extendedBolus(insulin, durationInHalfHours); if (connectionOK && pump.isExtendedInProgress && Math.abs(pump.extendedBolusAmount - insulin) < getPumpDescription().extendedBolusStep) { result.enacted = true; @@ -572,7 +572,7 @@ public class DanaRPlugin implements PluginBase, PumpInterface, ConstraintsInterf } @Override - public PumpEnactResult cancelTempBasal() { + public PumpEnactResult cancelTempBasal(boolean userRequested) { if (MainApp.getConfigBuilder().isInHistoryRealTempBasalInProgress()) return cancelRealTempBasal(); if (MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress() && useExtendedBoluses) { @@ -650,7 +650,7 @@ public class DanaRPlugin implements PluginBase, PumpInterface, ConstraintsInterf @Override public JSONObject getJSONStatus() { - if (pump.lastConnection.getTime() + 5 * 60 * 1000L < new Date().getTime()) { + if (pump.lastConnection.getTime() + 5 * 60 * 1000L < System.currentTimeMillis()) { return null; } JSONObject pumpjson = new JSONObject(); @@ -667,13 +667,13 @@ public class DanaRPlugin implements PluginBase, PumpInterface, ConstraintsInterf extended.put("LastBolus", pump.lastBolusTime.toLocaleString()); extended.put("LastBolusAmount", pump.lastBolusAmount); } - TemporaryBasal tb = MainApp.getConfigBuilder().getRealTempBasalFromHistory(new Date().getTime()); + TemporaryBasal tb = MainApp.getConfigBuilder().getRealTempBasalFromHistory(System.currentTimeMillis()); if (tb != null) { - extended.put("TempBasalAbsoluteRate", tb.tempBasalConvertedToAbsolute(new Date().getTime())); + extended.put("TempBasalAbsoluteRate", tb.tempBasalConvertedToAbsolute(System.currentTimeMillis())); extended.put("TempBasalStart", DateUtil.dateAndTimeString(tb.date)); extended.put("TempBasalRemaining", tb.getPlannedRemainingMinutes()); } - ExtendedBolus eb = MainApp.getConfigBuilder().getExtendedBolusFromHistory(new Date().getTime()); + ExtendedBolus eb = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()); if (eb != null) { extended.put("ExtendedBolusAbsoluteRate", eb.absoluteRate()); extended.put("ExtendedBolusStart", DateUtil.dateAndTimeString(eb.date)); @@ -706,6 +706,15 @@ public class DanaRPlugin implements PluginBase, PumpInterface, ConstraintsInterf return pumpDescription; } + /** + * DanaR interface + */ + + @Override + public boolean loadHistory(byte type) { + return sExecutionService.loadHistory(type); + } + /** * Constraint interface */ @@ -788,6 +797,11 @@ public class DanaRPlugin implements PluginBase, PumpInterface, ConstraintsInterf return pump.createConvertedProfile(); } + @Override + public String getUnits() { + return pump.getUnits(); + } + @Override public String getProfileName() { return pump.createConvertedProfileName(); @@ -797,7 +811,7 @@ public class DanaRPlugin implements PluginBase, PumpInterface, ConstraintsInterf public String shortStatus(boolean veryShort) { String ret = ""; if (pump.lastConnection.getTime() != 0) { - Long agoMsec = new Date().getTime() - pump.lastConnection.getTime(); + Long agoMsec = System.currentTimeMillis() - pump.lastConnection.getTime(); int agoMin = (int) (agoMsec / 60d / 1000d); ret += "LastConn: " + agoMin + " minago\n"; } @@ -805,10 +819,10 @@ public class DanaRPlugin implements PluginBase, PumpInterface, ConstraintsInterf ret += "LastBolus: " + DecimalFormatter.to2Decimal(pump.lastBolusAmount) + "U @" + android.text.format.DateFormat.format("HH:mm", pump.lastBolusTime) + "\n"; } if (MainApp.getConfigBuilder().isInHistoryRealTempBasalInProgress()) { - ret += "Temp: " + MainApp.getConfigBuilder().getRealTempBasalFromHistory(new Date().getTime()).toStringFull() + "\n"; + ret += "Temp: " + MainApp.getConfigBuilder().getRealTempBasalFromHistory(System.currentTimeMillis()).toStringFull() + "\n"; } if (MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) { - ret += "Extended: " + MainApp.getConfigBuilder().getExtendedBolusFromHistory(new Date().getTime()).toString() + "\n"; + ret += "Extended: " + MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()).toString() + "\n"; } if (!veryShort) { ret += "TDD: " + DecimalFormatter.to0Decimal(pump.dailyTotalUnits) + " / " + pump.maxDailyTotalUnits + " U\n"; 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 af36e4059f..55fdc7ad04 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 @@ -132,6 +132,10 @@ public class DanaRPump { public double maxBolus; public double maxBasal; + public String getUnits() { + return units == UNITS_MGDL ? Constants.MGDL : Constants.MMOL; + } + public ProfileStore createConvertedProfile() { JSONObject json = new JSONObject(); JSONObject store = new JSONObject(); 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 9f05a7569a..4015b8856b 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 @@ -17,8 +17,10 @@ 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.interfaces.ProfileInterface; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPlugin; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; import info.nightscout.androidaps.plugins.PumpDanaRKorean.DanaRKoreanPlugin; @@ -103,14 +105,20 @@ public class ProfileViewDialog extends DialogFragment { // } else { // noProfile.setVisibility(View.GONE); // } - Profile profile = MainApp.getConfigBuilder().getProfile(); - units.setText(profile.getUnits()); - dia.setText(DecimalFormatter.to2Decimal(profile.getDia()) + " h"); - activeProfile.setText(MainApp.getConfigBuilder().getProfileName()); - ic.setText(profile.getIcList()); - isf.setText(profile.getIsfList()); - basal.setText(profile.getBasalList()); - target.setText(profile.getTargetList()); + ProfileStore store = ((ProfileInterface)MainApp.getConfigBuilder().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()); + ic.setText(profile.getIcList()); + isf.setText(profile.getIsfList()); + basal.setText(profile.getBasalList()); + target.setText(profile.getTargetList()); + } else { + noProfile.setVisibility(View.VISIBLE); + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/History/DanaRHistoryActivity.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/activities/DanaRHistoryActivity.java similarity index 91% rename from app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/History/DanaRHistoryActivity.java rename to app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/activities/DanaRHistoryActivity.java index 0116498233..5fc022bcc6 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/History/DanaRHistoryActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/activities/DanaRHistoryActivity.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.PumpDanaR.History; +package info.nightscout.androidaps.plugins.PumpDanaR.activities; import android.app.Activity; import android.content.ComponentName; @@ -35,9 +35,13 @@ import info.nightscout.androidaps.R; import info.nightscout.androidaps.db.DanaRHistoryRecord; import info.nightscout.androidaps.events.EventPumpStatusChanged; import info.nightscout.androidaps.data.Profile; +import info.nightscout.androidaps.interfaces.DanaRInterface; +import info.nightscout.androidaps.interfaces.PluginBase; +import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.plugins.PumpDanaR.services.DanaRExecutionService; 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.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.ToastUtils; @@ -46,7 +50,6 @@ public class DanaRHistoryActivity extends Activity { private static Logger log = LoggerFactory.getLogger(DanaRHistoryActivity.class); private boolean mBounded; - private static DanaRExecutionService mExecutionService; private Handler mHandler; private static HandlerThread mHandlerThread; @@ -86,13 +89,6 @@ public class DanaRHistoryActivity extends Activity { } - @Override - public void onStart() { - super.onStart(); - Intent intent = new Intent(this, DanaRExecutionService.class); - bindService(intent, mConnection, Context.BIND_AUTO_CREATE); - } - @Override protected void onResume() { super.onResume(); @@ -105,31 +101,6 @@ public class DanaRHistoryActivity extends Activity { MainApp.bus().unregister(this); } - @Override - public void onStop() { - super.onStop(); - if (mBounded) { - unbindService(mConnection); - mBounded = false; - } - } - - ServiceConnection mConnection = new ServiceConnection() { - - public void onServiceDisconnected(ComponentName name) { - log.debug("Service is disconnected"); - mBounded = false; - mExecutionService = null; - } - - public void onServiceConnected(ComponentName name, IBinder service) { - log.debug("Service is connected"); - mBounded = true; - DanaRExecutionService.LocalBinder mLocalBinder = (DanaRExecutionService.LocalBinder) service; - mExecutionService = mLocalBinder.getServiceInstance(); - } - }; - @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -150,6 +121,8 @@ public class DanaRHistoryActivity extends Activity { statusView.setVisibility(View.GONE); + boolean isKorean = MainApp.getSpecificPlugin(DanaRKoreanPlugin.class).isEnabled(PluginBase.PUMP); + // Types ArrayList typeList = new ArrayList<>(); @@ -158,10 +131,12 @@ public class DanaRHistoryActivity extends Activity { typeList.add(new TypeList(RecordTypes.RECORD_TYPE_BOLUS, getString(R.string.danar_history_bolus))); typeList.add(new TypeList(RecordTypes.RECORD_TYPE_CARBO, getString(R.string.danar_history_carbohydrates))); typeList.add(new TypeList(RecordTypes.RECORD_TYPE_DAILY, getString(R.string.danar_history_dailyinsulin))); - typeList.add(new TypeList(RecordTypes.RECORD_TYPE_ERROR, getString(R.string.danar_history_errors))); typeList.add(new TypeList(RecordTypes.RECORD_TYPE_GLUCOSE, getString(R.string.danar_history_glucose))); - typeList.add(new TypeList(RecordTypes.RECORD_TYPE_REFILL, getString(R.string.danar_history_refill))); - typeList.add(new TypeList(RecordTypes.RECORD_TYPE_SUSPEND, getString(R.string.danar_history_syspend))); + if (!isKorean) { + typeList.add(new TypeList(RecordTypes.RECORD_TYPE_ERROR, getString(R.string.danar_history_errors))); + typeList.add(new TypeList(RecordTypes.RECORD_TYPE_REFILL, getString(R.string.danar_history_refill))); + typeList.add(new TypeList(RecordTypes.RECORD_TYPE_SUSPEND, getString(R.string.danar_history_syspend))); + } ArrayAdapter spinnerAdapter = new ArrayAdapter<>(this, R.layout.spinner_centered, typeList); historyTypeSpinner.setAdapter(spinnerAdapter); @@ -169,7 +144,8 @@ public class DanaRHistoryActivity extends Activity { reloadButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - if (mExecutionService.isConnected() || mExecutionService.isConnecting()) { + final PumpInterface pump = MainApp.getConfigBuilder().getActivePump(); + if (pump.isBusy()) { ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), getString(R.string.pumpbusy)); return; } @@ -186,7 +162,7 @@ public class DanaRHistoryActivity extends Activity { } }); clearCardView(); - mExecutionService.loadHistory(selected.type); + ((DanaRInterface)pump).loadHistory(selected.type); loadDataFromDB(selected.type); runOnUiThread(new Runnable() { @Override diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/History/DanaRNSHistorySync.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/activities/DanaRNSHistorySync.java similarity index 89% rename from app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/History/DanaRNSHistorySync.java rename to app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/activities/DanaRNSHistorySync.java index 72ecf91f0f..0668a74c1d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/History/DanaRNSHistorySync.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/activities/DanaRNSHistorySync.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.PumpDanaR.History; +package info.nightscout.androidaps.plugins.PumpDanaR.activities; import org.json.JSONException; import org.json.JSONObject; @@ -46,12 +46,6 @@ public class DanaRNSHistorySync { public void sync(int what) { try { - ConfigBuilderPlugin ConfigBuilderPlugin = MainApp.getConfigBuilder(); - Profile profile = MainApp.getConfigBuilder().getProfile(); - if (profile == null) { - ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.noprofile)); - return; - } Calendar cal = Calendar.getInstance(); long records = historyRecords.size(); long processing = 0; @@ -74,7 +68,7 @@ public class DanaRNSHistorySync { nsrec.put("eventType", "Meal Bolus"); nsrec.put("insulin", record.recordValue); nsrec.put("created_at", DateUtil.toISOString(record.recordDate)); - nsrec.put("enteredBy", MainApp.sResources.getString(R.string.app_name)); + nsrec.put("enteredBy", "openaps://" + MainApp.sResources.getString(R.string.app_name)); NSUpload.uploadCareportalEntryToNS(nsrec); uploaded++; ev.message += MainApp.sResources.getString(R.string.danar_sbolus); @@ -92,7 +86,7 @@ public class DanaRNSHistorySync { cal.setTimeInMillis(record.recordDate); cal.add(Calendar.MINUTE, -1 * record.recordDuration); nsrec.put("created_at", DateUtil.toISOString(cal.getTime())); - nsrec.put("enteredBy", MainApp.sResources.getString(R.string.app_name)); + nsrec.put("enteredBy", "openaps://" + MainApp.sResources.getString(R.string.app_name)); NSUpload.uploadCareportalEntryToNS(nsrec); uploaded++; ev.message += MainApp.sResources.getString(R.string.danar_ebolus); @@ -108,7 +102,7 @@ public class DanaRNSHistorySync { nsrec.put("splitNow", 100); nsrec.put("splitExt", 0); nsrec.put("created_at", DateUtil.toISOString(record.recordDate)); - nsrec.put("enteredBy", MainApp.sResources.getString(R.string.app_name)); + nsrec.put("enteredBy", "openaps://" + MainApp.sResources.getString(R.string.app_name)); NSUpload.uploadCareportalEntryToNS(nsrec); uploaded++; ev.message += MainApp.sResources.getString(R.string.danar_dsbolus); @@ -124,7 +118,7 @@ public class DanaRNSHistorySync { cal.setTimeInMillis(record.recordDate); cal.add(Calendar.MINUTE, -1 * record.recordDuration); nsrec.put("created_at", DateUtil.toISOString(cal.getTime())); - nsrec.put("enteredBy", MainApp.sResources.getString(R.string.app_name)); + nsrec.put("enteredBy", "openaps://" + MainApp.sResources.getString(R.string.app_name)); NSUpload.uploadCareportalEntryToNS(nsrec); uploaded++; ev.message += MainApp.sResources.getString(R.string.danar_debolus); @@ -141,7 +135,7 @@ public class DanaRNSHistorySync { nsrec.put("eventType", "Note"); nsrec.put("notes", "Error"); nsrec.put("created_at", DateUtil.toISOString(record.recordDate)); - nsrec.put("enteredBy", MainApp.sResources.getString(R.string.app_name)); + nsrec.put("enteredBy", "openaps://" + MainApp.sResources.getString(R.string.app_name)); NSUpload.uploadCareportalEntryToNS(nsrec); uploaded++; ev.message += MainApp.sResources.getString(R.string.danar_error); @@ -153,7 +147,7 @@ public class DanaRNSHistorySync { nsrec.put("eventType", "Insulin Change"); nsrec.put("notes", "Refill " + record.recordValue + "U"); nsrec.put("created_at", DateUtil.toISOString(record.recordDate)); - nsrec.put("enteredBy", MainApp.sResources.getString(R.string.app_name)); + nsrec.put("enteredBy", "openaps://" + MainApp.sResources.getString(R.string.app_name)); NSUpload.uploadCareportalEntryToNS(nsrec); uploaded++; ev.message += MainApp.sResources.getString(R.string.danar_refill); @@ -166,7 +160,7 @@ public class DanaRNSHistorySync { nsrec.put("absolute", record.recordValue); nsrec.put("duration", 60); nsrec.put("created_at", DateUtil.toISOString(record.recordDate)); - nsrec.put("enteredBy", MainApp.sResources.getString(R.string.app_name)); + nsrec.put("enteredBy", "openaps://" + MainApp.sResources.getString(R.string.app_name)); NSUpload.uploadCareportalEntryToNS(nsrec); uploaded++; ev.message += MainApp.sResources.getString(R.string.danar_basalhour); @@ -179,10 +173,10 @@ public class DanaRNSHistorySync { 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, profile.getUnits())); + nsrec.put("glucose", Profile.fromMgdlToUnits(record.recordValue, MainApp.getConfigBuilder().getProfileUnits())); nsrec.put("glucoseType", "Finger"); nsrec.put("created_at", DateUtil.toISOString(record.recordDate)); - nsrec.put("enteredBy", MainApp.sResources.getString(R.string.app_name)); + nsrec.put("enteredBy", "openaps://" + MainApp.sResources.getString(R.string.app_name)); NSUpload.uploadCareportalEntryToNS(nsrec); uploaded++; ev.message += MainApp.sResources.getString(R.string.danar_glucose); @@ -194,7 +188,7 @@ public class DanaRNSHistorySync { nsrec.put("eventType", "Meal Bolus"); nsrec.put("carbs", record.recordValue); nsrec.put("created_at", DateUtil.toISOString(record.recordDate)); - nsrec.put("enteredBy", MainApp.sResources.getString(R.string.app_name)); + nsrec.put("enteredBy", "openaps://" + MainApp.sResources.getString(R.string.app_name)); NSUpload.uploadCareportalEntryToNS(nsrec); uploaded++; ev.message += MainApp.sResources.getString(R.string.danar_carbohydrate); @@ -206,7 +200,7 @@ public class DanaRNSHistorySync { nsrec.put("eventType", "Note"); nsrec.put("notes", "Alarm: " + record.recordAlarm); nsrec.put("created_at", DateUtil.toISOString(record.recordDate)); - nsrec.put("enteredBy", MainApp.sResources.getString(R.string.app_name)); + nsrec.put("enteredBy", "openaps://" + MainApp.sResources.getString(R.string.app_name)); NSUpload.uploadCareportalEntryToNS(nsrec); uploaded++; ev.message += MainApp.sResources.getString(R.string.danar_alarm); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/History/DanaRStatsActivity.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/activities/DanaRStatsActivity.java similarity index 91% rename from app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/History/DanaRStatsActivity.java rename to app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/activities/DanaRStatsActivity.java index 6a360b9c26..fbe828a25f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/History/DanaRStatsActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/activities/DanaRStatsActivity.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.PumpDanaR.History; +package info.nightscout.androidaps.plugins.PumpDanaR.activities; import android.app.Activity; import android.content.ComponentName; @@ -35,14 +35,18 @@ import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; +import java.util.Comparator; 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.db.DanaRHistoryRecord; import info.nightscout.androidaps.events.EventPumpStatusChanged; +import info.nightscout.androidaps.interfaces.DanaRInterface; import info.nightscout.androidaps.interfaces.ProfileInterface; +import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.ProfileCircadianPercentage.CircadianPercentageProfilePlugin; import info.nightscout.androidaps.plugins.PumpDanaR.comm.RecordTypes; @@ -57,7 +61,6 @@ public class DanaRStatsActivity extends Activity { private static Logger log = LoggerFactory.getLogger(DanaRStatsActivity.class); private boolean mBounded; - private static DanaRExecutionService mExecutionService; private Handler mHandler; private static HandlerThread mHandlerThread; @@ -72,6 +75,7 @@ public class DanaRStatsActivity extends Activity { DecimalFormat decimalFormat; List historyList = new ArrayList<>(); + List dummies; public DanaRStatsActivity() { super(); @@ -80,13 +84,6 @@ public class DanaRStatsActivity extends Activity { this.mHandler = new Handler(mHandlerThread.getLooper()); } - @Override - public void onStart() { - super.onStart(); - Intent intent = new Intent(this, DanaRExecutionService.class); - bindService(intent, mConnection, Context.BIND_AUTO_CREATE); - } - @Override protected void onResume() { super.onResume(); @@ -99,15 +96,6 @@ public class DanaRStatsActivity extends Activity { MainApp.bus().unregister(this); } - @Override - public void onStop() { - super.onStop(); - if (mBounded) { - unbindService(mConnection); - mBounded = false; - } - } - @Override public boolean dispatchTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { @@ -123,22 +111,6 @@ public class DanaRStatsActivity extends Activity { return super.dispatchTouchEvent(event); } - ServiceConnection mConnection = new ServiceConnection() { - - public void onServiceDisconnected(ComponentName name) { - log.debug("Service is disconnected"); - mBounded = false; - mExecutionService = null; - } - - public void onServiceConnected(ComponentName name, IBinder service) { - log.debug("Service is connected"); - mBounded = true; - DanaRExecutionService.LocalBinder mLocalBinder = (DanaRExecutionService.LocalBinder) service; - mExecutionService = mLocalBinder.getServiceInstance(); - } - }; - @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -269,7 +241,8 @@ public class DanaRStatsActivity extends Activity { reloadButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - if (mExecutionService.isConnected() || mExecutionService.isConnecting()) { + final PumpInterface pump = MainApp.getConfigBuilder().getActivePump(); + if (pump.isBusy()) { ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), getString(R.string.pumpbusy)); return; } @@ -285,7 +258,7 @@ public class DanaRStatsActivity extends Activity { statsMessage.setText(getString(R.string.danar_stats_warning_Message)); } }); - mExecutionService.loadHistory(RecordTypes.RECORD_TYPE_DAILY); + ((DanaRInterface)pump).loadHistory(RecordTypes.RECORD_TYPE_DAILY); loadDataFromDB(RecordTypes.RECORD_TYPE_DAILY); runOnUiThread(new Runnable() { @Override @@ -332,6 +305,34 @@ public class DanaRStatsActivity extends Activity { private void loadDataFromDB(byte type) { historyList = MainApp.getDbHelper().getDanaRHistoryRecordsByType(type); + //only use newest 10 + historyList = historyList.subList(0, Math.min(10, historyList.size())); + + //fill single gaps + dummies = new LinkedList(); + DateFormat df = new SimpleDateFormat("dd.MM."); + for(int i = 0; i < historyList.size()-1; i++){ + DanaRHistoryRecord elem1 = historyList.get(i); + DanaRHistoryRecord elem2 = historyList.get(i+1); + + if (!df.format(new Date(elem1.recordDate)).equals(df.format(new Date(elem2.recordDate + 25*60*60*1000)))){ + DanaRHistoryRecord dummy = new DanaRHistoryRecord(); + dummy.recordDate = elem1.recordDate - 24*60*60*1000; + dummy.recordDailyBasal = elem1.recordDailyBasal/2; + dummy.recordDailyBolus = elem1.recordDailyBolus/2; + dummies.add(dummy); + elem1.recordDailyBasal /= 2; + elem1.recordDailyBolus /= 2; + } + } + historyList.addAll(dummies); + Collections.sort(historyList, new Comparator() { + @Override + public int compare(DanaRHistoryRecord lhs, DanaRHistoryRecord rhs) { + return (int) (rhs.recordDate-lhs.recordDate); + } + }); + runOnUiThread(new Runnable() { @Override public void run() { @@ -362,6 +363,9 @@ public class DanaRStatsActivity extends Activity { // Create the table row TableRow tr = new TableRow(DanaRStatsActivity.this); if (i % 2 != 0) tr.setBackgroundColor(Color.DKGRAY); + if(dummies.contains(record)){ + tr.setBackgroundColor(Color.argb(125, 255, 0, 0)); + } tr.setId(100 + i); tr.setLayoutParams(new TableLayout.LayoutParams( TableLayout.LayoutParams.MATCH_PARENT, 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 fd18407e5c..b200ccc5c1 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 @@ -30,13 +30,13 @@ public class MsgBolusProgress extends MessageBase { this(); this.amount = amount; this.t = t; - lastReceive = new Date().getTime(); + lastReceive = System.currentTimeMillis(); } @Override public void handleMessage(byte[] bytes) { progress = intFromBuff(bytes, 0, 2); - lastReceive = new Date().getTime(); + lastReceive = System.currentTimeMillis(); Double done = (amount * 100 - progress) / 100d; t.insulin = done; EventOverviewBolusProgress bolusingEvent = EventOverviewBolusProgress.getInstance(); 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 a27cfe07bf..dfd5788ec9 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 @@ -8,7 +8,7 @@ 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.events.EventRefreshOverview; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPlugin; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; @@ -41,7 +41,7 @@ public class MsgInitConnStatusTime extends MessageBase { } MainApp.getConfigBuilder().storeSettings(); - MainApp.bus().post(new EventRefreshGui(false)); + MainApp.bus().post(new EventRefreshOverview("MsgInitConnStatusTime")); return; } 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 9d9ccde307..256ccc18da 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 @@ -61,16 +61,16 @@ public class MsgStatusBolusExtended extends MessageBase { @NonNull private Date getDateFromSecAgo(int tempBasalAgoSecs) { - return new Date((long) (Math.ceil(new Date().getTime() / 1000d) - tempBasalAgoSecs) * 1000); + return new Date((long) (Math.ceil(System.currentTimeMillis() / 1000d) - tempBasalAgoSecs) * 1000); } public static void updateExtendedBolusInDB() { TreatmentsInterface treatmentsInterface = MainApp.getConfigBuilder(); DanaRPump pump = DanaRPump.getInstance(); - long now = new Date().getTime(); + long now = System.currentTimeMillis(); if (treatmentsInterface.isInHistoryExtendedBoluslInProgress()) { - ExtendedBolus extendedBolus = treatmentsInterface.getExtendedBolusFromHistory(new Date().getTime()); + ExtendedBolus extendedBolus = treatmentsInterface.getExtendedBolusFromHistory(System.currentTimeMillis()); if (pump.isExtendedInProgress) { if (extendedBolus.absoluteRate() != pump.extendedBolusAbsoluteRate) { // Close current extended 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 bcfd56a8fe..725bed1220 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 @@ -55,16 +55,16 @@ public class MsgStatusTempBasal extends MessageBase { @NonNull private Date getDateFromTempBasalSecAgo(int tempBasalAgoSecs) { - return new Date((long) (Math.ceil(new Date().getTime() / 1000d) - tempBasalAgoSecs) * 1000); + return new Date((long) (Math.ceil(System.currentTimeMillis() / 1000d) - tempBasalAgoSecs) * 1000); } public static void updateTempBasalInDB() { TreatmentsInterface treatmentsInterface = MainApp.getConfigBuilder(); DanaRPump danaRPump = DanaRPump.getInstance(); - long now = new Date().getTime(); + long now = System.currentTimeMillis(); if (treatmentsInterface.isInHistoryRealTempBasalInProgress()) { - TemporaryBasal tempBasal = treatmentsInterface.getRealTempBasalFromHistory(new Date().getTime()); + TemporaryBasal tempBasal = treatmentsInterface.getRealTempBasalFromHistory(System.currentTimeMillis()); if (danaRPump.isTempBasalInProgress) { if (tempBasal.percentRate != danaRPump.tempBasalPercent) { // Close current temp basal 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 957819aaf9..e4e32e39c3 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 @@ -200,9 +200,9 @@ public class DanaRExecutionService extends Service { getBTSocketForSelectedPump(); if (mRfcommSocket == null || mBTDevice == null) return; // Device not found - long startTime = new Date().getTime(); - while (!isConnected() && startTime + maxConnectionTime >= new Date().getTime()) { - long secondsElapsed = (new Date().getTime() - startTime) / 1000L; + long startTime = System.currentTimeMillis(); + while (!isConnected() && startTime + maxConnectionTime >= System.currentTimeMillis()) { + long secondsElapsed = (System.currentTimeMillis() - startTime) / 1000L; MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.CONNECTING, (int) secondsElapsed)); if (Config.logDanaBTComm) log.debug("connect waiting " + secondsElapsed + "sec from: " + from); @@ -229,7 +229,7 @@ public class DanaRExecutionService extends Service { if (!MainApp.getSpecificPlugin(DanaRPlugin.class).isEnabled(PluginBase.PUMP)) return; getBTSocketForSelectedPump(); - startTime = new Date().getTime(); + startTime = System.currentTimeMillis(); } } } @@ -353,6 +353,11 @@ public class DanaRExecutionService extends Service { public boolean tempBasal(int percent, int durationInHours) { connect("tempBasal"); if (!isConnected()) return false; + if (danaRPump.isTempBasalInProgress) { + MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.stoppingtempbasal))); + mSerialIOThread.sendMessage(new MsgSetTempBasalStop()); + waitMsec(500); + } MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.settingtempbasal))); mSerialIOThread.sendMessage(new MsgSetTempBasalStart(percent, durationInHours)); mSerialIOThread.sendMessage(new MsgStatusTempBasal()); @@ -399,12 +404,12 @@ public class DanaRExecutionService extends Service { if (!isConnected()) return false; if (carbs > 0) { - mSerialIOThread.sendMessage(new MsgSetCarbsEntry(new Date().getTime(), carbs)); + mSerialIOThread.sendMessage(new MsgSetCarbsEntry(System.currentTimeMillis(), carbs)); } MsgBolusProgress progress = new MsgBolusProgress(amount, t); // initialize static variables MainApp.bus().post(new EventDanaRBolusStart()); - long startTime = new Date().getTime(); + long startTime = System.currentTimeMillis(); if (!stop.stopped) { mSerialIOThread.sendMessage(start); @@ -414,7 +419,7 @@ public class DanaRExecutionService extends Service { } while (!stop.stopped && !start.failed) { waitMsec(100); - if ((new Date().getTime() - progress.lastReceive) > 5 * 1000L) { // if i didn't receive status for more than 5 sec expecting broken comm + if ((System.currentTimeMillis() - progress.lastReceive) > 5 * 1000L) { // if i didn't receive status for more than 5 sec expecting broken comm stop.stopped = true; stop.forced = true; log.debug("Communication stopped"); @@ -425,7 +430,7 @@ public class DanaRExecutionService extends Service { // try to find real amount if bolusing was interrupted or comm failed if (t.insulin != amount) { disconnect("bolusingInterrupted"); - long now = new Date().getTime(); + long now = System.currentTimeMillis(); long estimatedBolusEnd = (long) (startTime + amount / 5d * 60 * 1000); // std delivery rate 5 U/min waitMsec(Math.max(5000, estimatedBolusEnd - now + 3000)); connect("bolusingInterrupted"); @@ -461,7 +466,7 @@ public class DanaRExecutionService extends Service { public boolean carbsEntry(int amount) { connect("carbsEntry"); if (!isConnected()) return false; - MsgSetCarbsEntry msg = new MsgSetCarbsEntry(new Date().getTime(), amount); + MsgSetCarbsEntry msg = new MsgSetCarbsEntry(System.currentTimeMillis(), amount); mSerialIOThread.sendMessage(msg); return true; } @@ -531,7 +536,7 @@ public class DanaRExecutionService extends Service { 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.getBasal(hour * 60 * 60))/100d + 0.00001; + double value = Math.round(100d * nsProfile.getBasal((Integer) (hour * 60 * 60)))/100d + 0.00001; if (Config.logDanaMessageDetail) log.debug("NS basal value for " + hour + ":00 is " + value); record[hour] = value; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/DanaRKoreanFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/DanaRKoreanFragment.java index 5a3a5a4f36..50ec8883c6 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/DanaRKoreanFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/DanaRKoreanFragment.java @@ -27,16 +27,17 @@ import info.nightscout.androidaps.R; import info.nightscout.androidaps.events.EventExtendedBolusChange; import info.nightscout.androidaps.events.EventPumpStatusChanged; import info.nightscout.androidaps.events.EventTempBasalChange; +import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; import info.nightscout.androidaps.plugins.PumpDanaR.Dialogs.ProfileViewDialog; +import info.nightscout.androidaps.plugins.PumpDanaR.activities.DanaRHistoryActivity; +import info.nightscout.androidaps.plugins.PumpDanaR.activities.DanaRStatsActivity; import info.nightscout.androidaps.plugins.PumpDanaR.events.EventDanaRNewStatus; -import info.nightscout.androidaps.plugins.PumpDanaRKorean.History.DanaRHistoryActivity; -import info.nightscout.androidaps.plugins.PumpDanaRKorean.History.DanaRStatsActivity; import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.SetWarnColor; -public class DanaRKoreanFragment extends Fragment { +public class DanaRKoreanFragment extends SubscriberFragment { private static Logger log = LoggerFactory.getLogger(DanaRKoreanFragment.class); private static DanaRKoreanPlugin danaRKoreanPlugin = new DanaRKoreanPlugin(); @@ -154,18 +155,6 @@ public class DanaRKoreanFragment extends Fragment { return view; } - @Override - public void onPause() { - super.onPause(); - MainApp.bus().unregister(this); - } - - @Override - public void onResume() { - super.onResume(); - MainApp.bus().register(this); - } - @Subscribe public void onStatusEvent(final EventPumpStatusChanged c) { Activity activity = getActivity(); @@ -202,7 +191,8 @@ public class DanaRKoreanFragment extends Fragment { } // GUI functions - private void updateGUI() { + @Override + protected void updateGUI() { Activity activity = getActivity(); if (activity != null && basaBasalRateView != null) @@ -212,13 +202,13 @@ public class DanaRKoreanFragment extends Fragment { public void run() { DanaRPump pump = DanaRPump.getInstance(); if (pump.lastConnection.getTime() != 0) { - Long agoMsec = new Date().getTime() - pump.lastConnection.getTime(); + Long agoMsec = System.currentTimeMillis() - pump.lastConnection.getTime(); int agoMin = (int) (agoMsec / 60d / 1000d); lastConnectionView.setText(DateUtil.timeString(pump.lastConnection) + " (" + String.format(MainApp.sResources.getString(R.string.minago), agoMin) + ")"); SetWarnColor.setColor(lastConnectionView, agoMin, 16d, 31d); } // if (pump.lastBolusTime.getTime() != 0) { -// Long agoMsec = new Date().getTime() - pump.lastBolusTime.getTime(); +// Long agoMsec = System.currentTimeMillis() - pump.lastBolusTime.getTime(); // double agoHours = agoMsec / 60d / 60d / 1000d; // if (agoHours < 6) // max 6h back // lastBolusView.setText(formatTime.format(pump.lastBolusTime) + " (" + DecimalFormatter.to1Decimal(agoHours) + " " + getString(R.string.hoursago) + ") " + DecimalFormatter.to2Decimal(pump.lastBolusAmount) + " U"); @@ -229,12 +219,12 @@ public class DanaRKoreanFragment extends Fragment { SetWarnColor.setColor(dailyUnitsView, pump.dailyTotalUnits, pump.maxDailyTotalUnits * 0.75d, pump.maxDailyTotalUnits * 0.9d); basaBasalRateView.setText("( " + (pump.activeProfile + 1) + " ) " + DecimalFormatter.to2Decimal(danaRKoreanPlugin.getBaseBasalRate()) + " U/h"); if (MainApp.getConfigBuilder().isInHistoryRealTempBasalInProgress()) { - tempBasalView.setText(MainApp.getConfigBuilder().getRealTempBasalFromHistory(new Date().getTime()).toStringFull()); + tempBasalView.setText(MainApp.getConfigBuilder().getRealTempBasalFromHistory(System.currentTimeMillis()).toStringFull()); } else { tempBasalView.setText(""); } if (MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) { - extendedBolusView.setText(MainApp.getConfigBuilder().getExtendedBolusFromHistory(new Date().getTime()).toString()); + extendedBolusView.setText(MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()).toString()); } else { extendedBolusView.setText(""); } 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 45330dc6d7..e3b6bf3598 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 @@ -30,6 +30,7 @@ import info.nightscout.androidaps.db.Treatment; import info.nightscout.androidaps.events.EventAppExit; import info.nightscout.androidaps.events.EventPreferenceChange; import info.nightscout.androidaps.interfaces.ConstraintsInterface; +import info.nightscout.androidaps.interfaces.DanaRInterface; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.ProfileInterface; import info.nightscout.androidaps.interfaces.PumpDescription; @@ -51,7 +52,7 @@ import info.nightscout.utils.SP; /** * Created by mike on 05.08.2016. */ -public class DanaRKoreanPlugin implements PluginBase, PumpInterface, ConstraintsInterface, ProfileInterface { +public class DanaRKoreanPlugin implements PluginBase, PumpInterface, DanaRInterface, ConstraintsInterface, ProfileInterface { private static Logger log = LoggerFactory.getLogger(DanaRKoreanPlugin.class); @Override @@ -85,7 +86,7 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, Constraints pumpDescription.bolusStep = 0.1d; pumpDescription.isExtendedBolusCapable = true; - pumpDescription.extendedBolusStep = 0.1d; + pumpDescription.extendedBolusStep = 0.05d; pumpDescription.extendedBolusDurationStep = 30; pumpDescription.extendedBolusMaxDuration = 8 * 60; @@ -268,7 +269,7 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, Constraints int basalIncrement = pump.basal48Enable ? 30 * 60 : 60 * 60; for (int h = 0; h < basalValues; h++) { Double pumpValue = pump.pumpProfiles[pump.activeProfile][h]; - Double profileValue = profile.getBasal(h * basalIncrement); + Double profileValue = profile.getBasal((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); @@ -312,7 +313,7 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, Constraints if (Config.logPumpActions) log.debug("deliverTreatment: OK. Asked: " + detailedBolusInfo.insulin + " Delivered: " + result.bolusDelivered); detailedBolusInfo.insulin = t.insulin; - detailedBolusInfo.date = new Date().getTime(); + detailedBolusInfo.date = System.currentTimeMillis(); MainApp.getConfigBuilder().addToHistoryTreatment(detailedBolusInfo); return result; } else { @@ -339,7 +340,7 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, Constraints @Override public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes) { // Recheck pump status if older than 30 min - if (pump.lastConnection.getTime() + 30 * 60 * 1000L < new Date().getTime()) { + if (pump.lastConnection.getTime() + 30 * 60 * 1000L < System.currentTimeMillis()) { doConnect("setTempBasalAbsolute old data"); } @@ -396,7 +397,7 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, Constraints // Check if some temp is already in progress if (MainApp.getConfigBuilder().isInHistoryRealTempBasalInProgress()) { // Correct basal already set ? - if (MainApp.getConfigBuilder().getRealTempBasalFromHistory(new Date().getTime()).percentRate == percentRate) { + if (MainApp.getConfigBuilder().getRealTempBasalFromHistory(System.currentTimeMillis()).percentRate == percentRate) { result.success = true; result.percent = percentRate; result.absolute = MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory(); @@ -407,15 +408,6 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, Constraints if (Config.logPumpActions) log.debug("setTempBasalAbsolute: Correct temp basal already set (doLowTemp || doHighTemp)"); return result; - } else { - if (Config.logPumpActions) - log.debug("setTempBasalAbsolute: Stopping temp basal (doLowTemp || doHighTemp)"); - result = cancelRealTempBasal(); - // Check for proper result - if (!result.success) { - log.error("setTempBasalAbsolute: Failed to stop previous temp basal (doLowTemp || doHighTemp)"); - return result; - } } } // Convert duration from minutes to hours @@ -442,7 +434,7 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, Constraints Double extendedRateToSet = absoluteRate - getBaseBasalRate(); extendedRateToSet = configBuilderPlugin.applyBasalConstraints(extendedRateToSet); // needs to be rounded to 0.1 - extendedRateToSet = Round.roundTo(extendedRateToSet, 0.1d); + extendedRateToSet = Round.roundTo(extendedRateToSet, pumpDescription.extendedBolusStep * 2); // *2 because of 30 min // What is current rate of extended bolusing in u/h? if (Config.logPumpActions) { @@ -507,6 +499,7 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, Constraints result.comment = MainApp.instance().getString(R.string.virtualpump_resultok); result.duration = pump.tempBasalRemainingMin; result.percent = pump.tempBasalPercent; + result.absolute = MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory(); result.isPercent = true; if (Config.logPumpActions) log.debug("setTempBasalPercent: Correct value already set"); @@ -521,6 +514,7 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, Constraints result.isTempCancel = false; result.duration = pump.tempBasalRemainingMin; result.percent = pump.tempBasalPercent; + result.absolute = MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory(); result.isPercent = true; if (Config.logPumpActions) log.debug("setTempBasalPercent: OK"); @@ -538,7 +532,8 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, Constraints ConfigBuilderPlugin configBuilderPlugin = MainApp.getConfigBuilder(); insulin = configBuilderPlugin.applyBolusConstraints(insulin); // needs to be rounded - insulin = Round.roundTo(insulin, getPumpDescription().extendedBolusStep); + int durationInHalfHours = Math.max(durationInMinutes / 30, 1); + insulin = Round.roundTo(insulin, getPumpDescription().extendedBolusStep * (1 + durationInHalfHours % 1)); PumpEnactResult result = new PumpEnactResult(); if (pump.isExtendedInProgress && Math.abs(pump.extendedBolusAmount - insulin) < getPumpDescription().extendedBolusStep) { @@ -553,7 +548,6 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, Constraints log.debug("setExtendedBolus: Correct extended bolus already set. Current: " + pump.extendedBolusAmount + " Asked: " + insulin); return result; } - int durationInHalfHours = Math.max(durationInMinutes / 30, 1); boolean connectionOK = sExecutionService.extendedBolus(insulin, durationInHalfHours); if (connectionOK && pump.isExtendedInProgress && Math.abs(pump.extendedBolusAmount - insulin) < getPumpDescription().extendedBolusStep) { result.enacted = true; @@ -576,7 +570,7 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, Constraints } @Override - public PumpEnactResult cancelTempBasal() { + public PumpEnactResult cancelTempBasal(boolean userRequested) { if (MainApp.getConfigBuilder().isInHistoryRealTempBasalInProgress()) return cancelRealTempBasal(); if (MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress() && useExtendedBoluses) { @@ -654,7 +648,7 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, Constraints @Override public JSONObject getJSONStatus() { - if (pump.lastConnection.getTime() + 5 * 60 * 1000L < new Date().getTime()) { + if (pump.lastConnection.getTime() + 5 * 60 * 1000L < System.currentTimeMillis()) { return null; } JSONObject pumpjson = new JSONObject(); @@ -671,13 +665,13 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, Constraints extended.put("LastBolus", pump.lastBolusTime.toLocaleString()); extended.put("LastBolusAmount", pump.lastBolusAmount); } - TemporaryBasal tb = MainApp.getConfigBuilder().getRealTempBasalFromHistory(new Date().getTime()); + TemporaryBasal tb = MainApp.getConfigBuilder().getRealTempBasalFromHistory(System.currentTimeMillis()); if (tb != null) { - extended.put("TempBasalAbsoluteRate", tb.tempBasalConvertedToAbsolute(new Date().getTime())); + extended.put("TempBasalAbsoluteRate", tb.tempBasalConvertedToAbsolute(System.currentTimeMillis())); extended.put("TempBasalStart", DateUtil.dateAndTimeString(tb.date)); extended.put("TempBasalRemaining", tb.getPlannedRemainingMinutes()); } - ExtendedBolus eb = MainApp.getConfigBuilder().getExtendedBolusFromHistory(new Date().getTime()); + ExtendedBolus eb = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()); if (eb != null) { extended.put("ExtendedBolusAbsoluteRate", eb.absoluteRate()); extended.put("ExtendedBolusStart", DateUtil.dateAndTimeString(eb.date)); @@ -710,6 +704,15 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, Constraints return pumpDescription; } + /** + * DanaR interface + */ + + @Override + public boolean loadHistory(byte type) { + return sExecutionService.loadHistory(type); + } + /** * Constraint interface */ @@ -792,6 +795,11 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, Constraints return pump.createConvertedProfile(); } + @Override + public String getUnits() { + return pump.getUnits(); + } + @Override public String getProfileName() { return pump.createConvertedProfileName(); @@ -801,7 +809,7 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, Constraints public String shortStatus(boolean veryShort) { String ret = ""; if (pump.lastConnection.getTime() != 0) { - Long agoMsec = new Date().getTime() - pump.lastConnection.getTime(); + Long agoMsec = System.currentTimeMillis() - pump.lastConnection.getTime(); int agoMin = (int) (agoMsec / 60d / 1000d); ret += "LastConn: " + agoMin + " minago\n"; } @@ -809,10 +817,10 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, Constraints ret += "LastBolus: " + DecimalFormatter.to2Decimal(pump.lastBolusAmount) + "U @" + android.text.format.DateFormat.format("HH:mm", pump.lastBolusTime) + "\n"; } if (MainApp.getConfigBuilder().isInHistoryRealTempBasalInProgress()) { - ret += "Temp: " + MainApp.getConfigBuilder().getRealTempBasalFromHistory(new Date().getTime()).toStringFull() + "\n"; + ret += "Temp: " + MainApp.getConfigBuilder().getRealTempBasalFromHistory(System.currentTimeMillis()).toStringFull() + "\n"; } if (MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) { - ret += "Extended: " + MainApp.getConfigBuilder().getExtendedBolusFromHistory(new Date().getTime()).toString() + "\n"; + ret += "Extended: " + MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()).toString() + "\n"; } if (!veryShort) { ret += "TDD: " + DecimalFormatter.to0Decimal(pump.dailyTotalUnits) + " / " + pump.maxDailyTotalUnits + " U\n"; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/History/DanaRHistoryActivity.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/History/DanaRHistoryActivity.java deleted file mode 100644 index d9802c016c..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/History/DanaRHistoryActivity.java +++ /dev/null @@ -1,430 +0,0 @@ -package info.nightscout.androidaps.plugins.PumpDanaRKorean.History; - -import android.app.Activity; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.ServiceConnection; -import android.os.Bundle; -import android.os.Handler; -import android.os.HandlerThread; -import android.os.IBinder; -import android.support.v7.widget.CardView; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.ArrayAdapter; -import android.widget.Button; -import android.widget.Spinner; -import android.widget.TextView; - -import com.squareup.otto.Subscribe; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.List; - -import info.nightscout.androidaps.Constants; -import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.R; -import info.nightscout.androidaps.db.DanaRHistoryRecord; -import info.nightscout.androidaps.events.EventPumpStatusChanged; -import info.nightscout.androidaps.data.Profile; -import info.nightscout.androidaps.plugins.PumpDanaR.History.DanaRNSHistorySync; -import info.nightscout.androidaps.plugins.PumpDanaR.comm.RecordTypes; -import info.nightscout.androidaps.plugins.PumpDanaR.events.EventDanaRSyncStatus; -import info.nightscout.androidaps.plugins.PumpDanaRKorean.services.DanaRKoreanExecutionService; -import info.nightscout.utils.DateUtil; -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 DanaRKoreanExecutionService mExecutionService; - - private Handler mHandler; - private static HandlerThread mHandlerThread; - - static Profile profile = null; - - Spinner historyTypeSpinner; - TextView statusView; - Button reloadButton; - Button syncButton; - RecyclerView recyclerView; - LinearLayoutManager llm; - - static byte showingType = RecordTypes.RECORD_TYPE_ALARM; - List historyList = new ArrayList<>(); - - public static class TypeList { - public byte type; - String name; - - public TypeList(byte type, String name) { - this.type = type; - this.name = name; - } - - @Override - public String toString() { - return name; - } - } - - public DanaRHistoryActivity() { - super(); - mHandlerThread = new HandlerThread(DanaRHistoryActivity.class.getSimpleName()); - mHandlerThread.start(); - this.mHandler = new Handler(mHandlerThread.getLooper()); - } - - - @Override - public void onStart() { - super.onStart(); - Intent intent = new Intent(this, DanaRKoreanExecutionService.class); - bindService(intent, mConnection, Context.BIND_AUTO_CREATE); - } - - @Override - protected void onResume() { - super.onResume(); - MainApp.bus().register(this); - } - - @Override - protected void onPause() { - super.onPause(); - MainApp.bus().unregister(this); - } - - @Override - public void onStop() { - super.onStop(); - if (mBounded) { - unbindService(mConnection); - mBounded = false; - } - } - - ServiceConnection mConnection = new ServiceConnection() { - - public void onServiceDisconnected(ComponentName name) { - log.debug("Service is disconnected"); - mBounded = false; - mExecutionService = null; - } - - public void onServiceConnected(ComponentName name, IBinder service) { - log.debug("Service is connected"); - mBounded = true; - DanaRKoreanExecutionService.LocalBinder mLocalBinder = (DanaRKoreanExecutionService.LocalBinder) service; - mExecutionService = mLocalBinder.getServiceInstance(); - } - }; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.danar_historyactivity); - - historyTypeSpinner = (Spinner) findViewById(R.id.danar_historytype); - statusView = (TextView) findViewById(R.id.danar_historystatus); - reloadButton = (Button) findViewById(R.id.danar_historyreload); - syncButton = (Button) findViewById(R.id.danar_historysync); - recyclerView = (RecyclerView) findViewById(R.id.danar_history_recyclerview); - - recyclerView.setHasFixedSize(true); - llm = new LinearLayoutManager(this); - recyclerView.setLayoutManager(llm); - - RecyclerViewAdapter adapter = new RecyclerViewAdapter(historyList); - recyclerView.setAdapter(adapter); - - statusView.setVisibility(View.GONE); - - // Types - - ArrayList typeList = new ArrayList<>(); - typeList.add(new TypeList(RecordTypes.RECORD_TYPE_ALARM, getString(R.string.danar_history_alarm))); - typeList.add(new TypeList(RecordTypes.RECORD_TYPE_BASALHOUR, getString(R.string.danar_history_basalhours))); - typeList.add(new TypeList(RecordTypes.RECORD_TYPE_BOLUS, getString(R.string.danar_history_bolus))); - typeList.add(new TypeList(RecordTypes.RECORD_TYPE_CARBO, getString(R.string.danar_history_carbohydrates))); - typeList.add(new TypeList(RecordTypes.RECORD_TYPE_DAILY, getString(R.string.danar_history_dailyinsulin))); - typeList.add(new TypeList(RecordTypes.RECORD_TYPE_GLUCOSE, getString(R.string.danar_history_glucose))); - - ArrayAdapter spinnerAdapter = new ArrayAdapter<>(this, - R.layout.spinner_centered, typeList); - historyTypeSpinner.setAdapter(spinnerAdapter); - - reloadButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (mExecutionService.isConnected() || mExecutionService.isConnecting()) { - ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), getString(R.string.pumpbusy)); - return; - } - mHandler.post(new Runnable() { - @Override - public void run() { - TypeList selected = (TypeList) historyTypeSpinner.getSelectedItem(); - runOnUiThread(new Runnable() { - @Override - public void run() { - reloadButton.setVisibility(View.GONE); - syncButton.setVisibility(View.GONE); - statusView.setVisibility(View.VISIBLE); - } - }); - clearCardView(); - mExecutionService.loadHistory(selected.type); - loadDataFromDB(selected.type); - runOnUiThread(new Runnable() { - @Override - public void run() { - 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 - public void onItemSelected(AdapterView parent, View view, int position, long id) { - TypeList selected = (TypeList) historyTypeSpinner.getSelectedItem(); - loadDataFromDB(selected.type); - showingType = selected.type; - } - - @Override - public void onNothingSelected(AdapterView parent) { - clearCardView(); - } - }); - profile = MainApp.getConfigBuilder().getProfile(); - if (profile == null) { - ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.noprofile)); - finish(); - } - } - - public static class RecyclerViewAdapter extends RecyclerView.Adapter { - - List historyList; - - RecyclerViewAdapter(List historyList) { - this.historyList = historyList; - } - - @Override - public HistoryViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { - View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.danar_history_item, viewGroup, false); - return new HistoryViewHolder(v); - } - - @Override - public void onBindViewHolder(HistoryViewHolder holder, int position) { - DanaRHistoryRecord record = historyList.get(position); - holder.time.setText(DateUtil.dateAndTimeString(record.recordDate)); - holder.value.setText(DecimalFormatter.to2Decimal(record.recordValue)); - holder.stringvalue.setText(record.stringRecordValue); - holder.bolustype.setText(record.bolusType); - holder.duration.setText(DecimalFormatter.to0Decimal(record.recordDuration)); - holder.alarm.setText(record.recordAlarm); - switch (showingType) { - case RecordTypes.RECORD_TYPE_ALARM: - holder.time.setVisibility(View.VISIBLE); - holder.value.setVisibility(View.VISIBLE); - holder.stringvalue.setVisibility(View.GONE); - holder.bolustype.setVisibility(View.GONE); - holder.duration.setVisibility(View.GONE); - holder.dailybasal.setVisibility(View.GONE); - holder.dailybolus.setVisibility(View.GONE); - holder.dailytotal.setVisibility(View.GONE); - holder.alarm.setVisibility(View.VISIBLE); - break; - case RecordTypes.RECORD_TYPE_BOLUS: - holder.time.setVisibility(View.VISIBLE); - holder.value.setVisibility(View.VISIBLE); - holder.stringvalue.setVisibility(View.GONE); - holder.bolustype.setVisibility(View.VISIBLE); - holder.duration.setVisibility(View.VISIBLE); - holder.dailybasal.setVisibility(View.GONE); - holder.dailybolus.setVisibility(View.GONE); - holder.dailytotal.setVisibility(View.GONE); - holder.alarm.setVisibility(View.GONE); - break; - case RecordTypes.RECORD_TYPE_DAILY: - holder.dailybasal.setText(DecimalFormatter.to2Decimal(record.recordDailyBasal) + "U"); - holder.dailybolus.setText(DecimalFormatter.to2Decimal(record.recordDailyBolus) + "U"); - holder.dailytotal.setText(DecimalFormatter.to2Decimal(record.recordDailyBolus + record.recordDailyBasal) + "U"); - holder.time.setText(DateUtil.dateString(record.recordDate)); - holder.time.setVisibility(View.VISIBLE); - holder.value.setVisibility(View.GONE); - holder.stringvalue.setVisibility(View.GONE); - holder.bolustype.setVisibility(View.GONE); - holder.duration.setVisibility(View.GONE); - holder.dailybasal.setVisibility(View.VISIBLE); - holder.dailybolus.setVisibility(View.VISIBLE); - holder.dailytotal.setVisibility(View.VISIBLE); - holder.alarm.setVisibility(View.GONE); - break; - case RecordTypes.RECORD_TYPE_GLUCOSE: - holder.value.setText(Profile.toUnitsString(record.recordValue, record.recordValue * Constants.MGDL_TO_MMOLL, profile.getUnits())); - // rest is the same - case RecordTypes.RECORD_TYPE_CARBO: - case RecordTypes.RECORD_TYPE_BASALHOUR: - case RecordTypes.RECORD_TYPE_ERROR: - case RecordTypes.RECORD_TYPE_PRIME: - case RecordTypes.RECORD_TYPE_REFILL: - case RecordTypes.RECORD_TYPE_TB: - holder.time.setVisibility(View.VISIBLE); - holder.value.setVisibility(View.VISIBLE); - holder.stringvalue.setVisibility(View.GONE); - holder.bolustype.setVisibility(View.GONE); - holder.duration.setVisibility(View.GONE); - holder.dailybasal.setVisibility(View.GONE); - holder.dailybolus.setVisibility(View.GONE); - holder.dailytotal.setVisibility(View.GONE); - holder.alarm.setVisibility(View.GONE); - break; - case RecordTypes.RECORD_TYPE_SUSPEND: - holder.time.setVisibility(View.VISIBLE); - holder.value.setVisibility(View.GONE); - holder.stringvalue.setVisibility(View.VISIBLE); - holder.bolustype.setVisibility(View.GONE); - holder.duration.setVisibility(View.GONE); - holder.dailybasal.setVisibility(View.GONE); - holder.dailybolus.setVisibility(View.GONE); - holder.dailytotal.setVisibility(View.GONE); - holder.alarm.setVisibility(View.GONE); - break; - } - } - - @Override - public int getItemCount() { - return historyList.size(); - } - - @Override - public void onAttachedToRecyclerView(RecyclerView recyclerView) { - super.onAttachedToRecyclerView(recyclerView); - } - - public static class HistoryViewHolder extends RecyclerView.ViewHolder { - CardView cv; - TextView time; - TextView value; - TextView bolustype; - TextView stringvalue; - TextView duration; - TextView dailybasal; - TextView dailybolus; - TextView dailytotal; - TextView alarm; - - HistoryViewHolder(View itemView) { - super(itemView); - cv = (CardView) itemView.findViewById(R.id.danar_history_cardview); - time = (TextView) itemView.findViewById(R.id.danar_history_time); - value = (TextView) itemView.findViewById(R.id.danar_history_value); - bolustype = (TextView) itemView.findViewById(R.id.danar_history_bolustype); - stringvalue = (TextView) itemView.findViewById(R.id.danar_history_stringvalue); - duration = (TextView) itemView.findViewById(R.id.danar_history_duration); - dailybasal = (TextView) itemView.findViewById(R.id.danar_history_dailybasal); - dailybolus = (TextView) itemView.findViewById(R.id.danar_history_dailybolus); - dailytotal = (TextView) itemView.findViewById(R.id.danar_history_dailytotal); - alarm = (TextView) itemView.findViewById(R.id.danar_history_alarm); - } - } - } - - private void loadDataFromDB(byte type) { - historyList = MainApp.getDbHelper().getDanaRHistoryRecordsByType(type); - - runOnUiThread(new Runnable() { - @Override - public void run() { - 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); - } - }); - } - - @Subscribe - public void onStatusEvent(final EventDanaRSyncStatus s) { - log.debug("EventDanaRSyncStatus: " + s.message); - runOnUiThread( - new Runnable() { - @Override - public void run() { - statusView.setText(s.message); - } - }); - } - - @Subscribe - public void onStatusEvent(final EventPumpStatusChanged c) { - runOnUiThread( - new Runnable() { - @Override - public void run() { - statusView.setText(c.textStatus()); - } - } - ); - } - - -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/History/DanaRStatsActivity.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/History/DanaRStatsActivity.java deleted file mode 100644 index dc014b5eaa..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/History/DanaRStatsActivity.java +++ /dev/null @@ -1,539 +0,0 @@ -package info.nightscout.androidaps.plugins.PumpDanaRKorean.History; - -import android.app.Activity; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.ServiceConnection; -import android.graphics.Color; -import android.graphics.Rect; -import android.os.Bundle; -import android.os.Handler; -import android.os.HandlerThread; -import android.os.IBinder; -import android.support.v7.widget.LinearLayoutManager; -import android.text.TextUtils; -import android.view.KeyEvent; -import android.view.MotionEvent; -import android.view.View; -import android.view.WindowManager; -import android.view.inputmethod.EditorInfo; -import android.view.inputmethod.InputMethodManager; -import android.widget.Button; -import android.widget.EditText; -import android.widget.TableLayout; -import android.widget.TableRow; -import android.widget.TextView; - -import com.squareup.otto.Subscribe; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.text.DateFormat; -import java.text.DecimalFormat; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.List; - -import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.R; -import info.nightscout.androidaps.db.DanaRHistoryRecord; -import info.nightscout.androidaps.events.EventPumpStatusChanged; -import info.nightscout.androidaps.interfaces.ProfileInterface; -import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; -import info.nightscout.androidaps.plugins.ProfileCircadianPercentage.CircadianPercentageProfilePlugin; -import info.nightscout.androidaps.plugins.PumpDanaR.comm.RecordTypes; -import info.nightscout.androidaps.plugins.PumpDanaR.events.EventDanaRSyncStatus; -import info.nightscout.androidaps.plugins.PumpDanaRKorean.services.DanaRKoreanExecutionService; -import info.nightscout.utils.DecimalFormatter; -import info.nightscout.utils.SP; -import info.nightscout.utils.SafeParse; -import info.nightscout.utils.ToastUtils; - -public class DanaRStatsActivity extends Activity { - private static Logger log = LoggerFactory.getLogger(DanaRStatsActivity.class); - - private boolean mBounded; - private static DanaRKoreanExecutionService mExecutionService; - - private Handler mHandler; - private static HandlerThread mHandlerThread; - - TextView statusView, statsMessage, totalBaseBasal2; - EditText totalBaseBasal; - Button reloadButton; - LinearLayoutManager llm; - TableLayout tl, ctl, etl; - String TBB; - double magicNumber; - DecimalFormat decimalFormat; - - List historyList = new ArrayList<>(); - - public DanaRStatsActivity() { - super(); - mHandlerThread = new HandlerThread(DanaRStatsActivity.class.getSimpleName()); - mHandlerThread.start(); - this.mHandler = new Handler(mHandlerThread.getLooper()); - } - - @Override - public void onStart() { - super.onStart(); - Intent intent = new Intent(this, DanaRKoreanExecutionService.class); - bindService(intent, mConnection, Context.BIND_AUTO_CREATE); - } - - @Override - protected void onResume() { - super.onResume(); - MainApp.bus().register(this); - } - - @Override - protected void onPause() { - super.onPause(); - MainApp.bus().unregister(this); - } - - @Override - public void onStop() { - super.onStop(); - if (mBounded) { - unbindService(mConnection); - mBounded = false; - } - } - - @Override - public boolean dispatchTouchEvent(MotionEvent event) { - if (event.getAction() == MotionEvent.ACTION_DOWN) { - View myView = getCurrentFocus(); - if (myView instanceof EditText) { - Rect rect = new Rect(); - myView.getGlobalVisibleRect(rect); - if (!rect.contains((int) event.getRawX(), (int) event.getRawY())) { - myView.clearFocus(); - } - } - } - return super.dispatchTouchEvent(event); - } - - ServiceConnection mConnection = new ServiceConnection() { - - public void onServiceDisconnected(ComponentName name) { - log.debug("Service is disconnected"); - mBounded = false; - mExecutionService = null; - } - - public void onServiceConnected(ComponentName name, IBinder service) { - log.debug("Service is connected"); - mBounded = true; - DanaRKoreanExecutionService.LocalBinder mLocalBinder = (DanaRKoreanExecutionService.LocalBinder) service; - mExecutionService = mLocalBinder.getServiceInstance(); - } - }; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.danar_statsactivity); - getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN); - statusView = (TextView) findViewById(R.id.danar_stats_connection_status); - reloadButton = (Button) findViewById(R.id.danar_statsreload); - totalBaseBasal = (EditText) findViewById(R.id.danar_stats_editTotalBaseBasal); - totalBaseBasal2 = (TextView) findViewById(R.id.danar_stats_editTotalBaseBasal2); - statsMessage = (TextView) findViewById(R.id.danar_stats_Message); - - statusView.setVisibility(View.GONE); - statsMessage.setVisibility(View.GONE); - - totalBaseBasal2.setEnabled(false); - totalBaseBasal2.setClickable(false); - totalBaseBasal2.setFocusable(false); - totalBaseBasal2.setInputType(0); - - decimalFormat = new DecimalFormat("0.000"); - llm = new LinearLayoutManager(this); - - TBB = SP.getString("TBB", "10.00"); - totalBaseBasal.setText(TBB); - - ProfileInterface pi = ConfigBuilderPlugin.getActiveProfileInterface(); - if (pi != null && pi instanceof CircadianPercentageProfilePlugin) { - double cppTBB = ((CircadianPercentageProfilePlugin) pi).baseBasalSum(); - totalBaseBasal.setText(decimalFormat.format(cppTBB)); - SP.putString("TBB", totalBaseBasal.getText().toString()); - TBB = SP.getString("TBB", ""); - } - - // stats table - tl = (TableLayout) findViewById(R.id.main_table); - TableRow tr_head = new TableRow(this); - tr_head.setBackgroundColor(Color.DKGRAY); - tr_head.setLayoutParams(new TableLayout.LayoutParams( - TableLayout.LayoutParams.MATCH_PARENT, - TableLayout.LayoutParams.WRAP_CONTENT)); - - TextView label_date = new TextView(this); - label_date.setText(getString(R.string.danar_stats_date)); - label_date.setTextColor(Color.WHITE); - tr_head.addView(label_date); - - TextView label_basalrate = new TextView(this); - label_basalrate.setText(getString(R.string.danar_stats_basalrate)); - label_basalrate.setTextColor(Color.WHITE); - tr_head.addView(label_basalrate); - - TextView label_bolus = new TextView(this); - label_bolus.setText(getString(R.string.danar_stats_bolus)); - label_bolus.setTextColor(Color.WHITE); - tr_head.addView(label_bolus); - - TextView label_tdd = new TextView(this); - label_tdd.setText(getString(R.string.danar_stats_tdd)); - label_tdd.setTextColor(Color.WHITE); - tr_head.addView(label_tdd); - - TextView label_ratio = new TextView(this); - label_ratio.setText(getString(R.string.danar_stats_ratio)); - label_ratio.setTextColor(Color.WHITE); - tr_head.addView(label_ratio); - - // add stats headers to tables - tl.addView(tr_head, new TableLayout.LayoutParams( - TableLayout.LayoutParams.MATCH_PARENT, - TableLayout.LayoutParams.WRAP_CONTENT)); - - // cumulative table - ctl = (TableLayout) findViewById(R.id.cumulative_table); - TableRow ctr_head = new TableRow(this); - ctr_head.setBackgroundColor(Color.DKGRAY); - ctr_head.setLayoutParams(new TableLayout.LayoutParams( - TableLayout.LayoutParams.MATCH_PARENT, - TableLayout.LayoutParams.WRAP_CONTENT)); - - TextView label_cum_amount_days = new TextView(this); - label_cum_amount_days.setText(getString(R.string.danar_stats_amount_days)); - label_cum_amount_days.setTextColor(Color.WHITE); - ctr_head.addView(label_cum_amount_days); - - TextView label_cum_tdd = new TextView(this); - label_cum_tdd.setText(getString(R.string.danar_stats_tdd)); - label_cum_tdd.setTextColor(Color.WHITE); - ctr_head.addView(label_cum_tdd); - - TextView label_cum_ratio = new TextView(this); - label_cum_ratio.setText(getString(R.string.danar_stats_ratio)); - label_cum_ratio.setTextColor(Color.WHITE); - ctr_head.addView(label_cum_ratio); - - // add cummulative headers to tables - ctl.addView(ctr_head, new TableLayout.LayoutParams( - TableLayout.LayoutParams.MATCH_PARENT, - TableLayout.LayoutParams.WRAP_CONTENT)); - - // expontial table - etl = (TableLayout) findViewById(R.id.expweight_table); - TableRow etr_head = new TableRow(this); - etr_head.setBackgroundColor(Color.DKGRAY); - etr_head.setLayoutParams(new TableLayout.LayoutParams( - TableLayout.LayoutParams.MATCH_PARENT, - TableLayout.LayoutParams.WRAP_CONTENT)); - - TextView label_exp_weight = new TextView(this); - label_exp_weight.setText(getString(R.string.danar_stats_weight)); - label_exp_weight.setTextColor(Color.WHITE); - etr_head.addView(label_exp_weight); - - TextView label_exp_tdd = new TextView(this); - label_exp_tdd.setText(getString(R.string.danar_stats_tdd)); - label_exp_tdd.setTextColor(Color.WHITE); - etr_head.addView(label_exp_tdd); - - TextView label_exp_ratio = new TextView(this); - label_exp_ratio.setText(getString(R.string.danar_stats_ratio)); - label_exp_ratio.setTextColor(Color.WHITE); - etr_head.addView(label_exp_ratio); - - // add expontial headers to tables - etl.addView(etr_head, new TableLayout.LayoutParams( - TableLayout.LayoutParams.MATCH_PARENT, - TableLayout.LayoutParams.WRAP_CONTENT)); - - reloadButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (mExecutionService.isConnected() || mExecutionService.isConnecting()) { - ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), getString(R.string.pumpbusy)); - return; - } - mHandler.post(new Runnable() { - @Override - public void run() { - runOnUiThread(new Runnable() { - @Override - public void run() { - reloadButton.setVisibility(View.GONE); - statusView.setVisibility(View.VISIBLE); - statsMessage.setVisibility(View.VISIBLE); - statsMessage.setText(getString(R.string.danar_stats_warning_Message)); - } - }); - mExecutionService.loadHistory(RecordTypes.RECORD_TYPE_DAILY); - loadDataFromDB(RecordTypes.RECORD_TYPE_DAILY); - runOnUiThread(new Runnable() { - @Override - public void run() { - reloadButton.setVisibility(View.VISIBLE); - statusView.setVisibility(View.GONE); - statsMessage.setVisibility(View.GONE); - } - }); - } - }); - } - }); - - totalBaseBasal.setOnEditorActionListener(new TextView.OnEditorActionListener() { - @Override - public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { - if (actionId == EditorInfo.IME_ACTION_DONE) { - totalBaseBasal.clearFocus(); - return true; - } - return false; - } - }); - - totalBaseBasal.setOnFocusChangeListener(new View.OnFocusChangeListener() { - @Override - public void onFocusChange(View v, boolean hasFocus) { - if (hasFocus) { - totalBaseBasal.getText().clear(); - } else { - SP.putString("TBB", totalBaseBasal.getText().toString()); - TBB = SP.getString("TBB", ""); - loadDataFromDB(RecordTypes.RECORD_TYPE_DAILY); - InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE); - imm.hideSoftInputFromWindow(totalBaseBasal.getWindowToken(), 0); - } - } - }); - - loadDataFromDB(RecordTypes.RECORD_TYPE_DAILY); - } - - private void loadDataFromDB(byte type) { - historyList = MainApp.getDbHelper().getDanaRHistoryRecordsByType(type); - - runOnUiThread(new Runnable() { - @Override - public void run() { - cleanTable(tl); - cleanTable(ctl); - cleanTable(etl); - DateFormat df = new SimpleDateFormat("dd.MM."); - - if (TextUtils.isEmpty(TBB)) { - totalBaseBasal.setError("Please Enter Total Base Basal"); - return; - } else { - magicNumber = SafeParse.stringToDouble(TBB); - } - - magicNumber *= 2; - totalBaseBasal2.setText(decimalFormat.format(magicNumber)); - - int i = 0; - double sum = 0d; - double weighted03 = 0d; - double weighted05 = 0d; - double weighted07 = 0d; - - for (DanaRHistoryRecord record : historyList) { - double tdd = record.recordDailyBolus + record.recordDailyBasal; - - // Create the table row - TableRow tr = new TableRow(DanaRStatsActivity.this); - if (i % 2 != 0) tr.setBackgroundColor(Color.DKGRAY); - tr.setId(100 + i); - tr.setLayoutParams(new TableLayout.LayoutParams( - TableLayout.LayoutParams.MATCH_PARENT, - TableLayout.LayoutParams.WRAP_CONTENT)); - - // Here create the TextView dynamically - TextView labelDATE = new TextView(DanaRStatsActivity.this); - labelDATE.setId(200 + i); - labelDATE.setText(df.format(new Date(record.recordDate))); - labelDATE.setTextColor(Color.WHITE); - tr.addView(labelDATE); - - TextView labelBASAL = new TextView(DanaRStatsActivity.this); - labelBASAL.setId(300 + i); - labelBASAL.setText(DecimalFormatter.to2Decimal(record.recordDailyBasal) + " U"); - labelBASAL.setTextColor(Color.WHITE); - tr.addView(labelBASAL); - - TextView labelBOLUS = new TextView(DanaRStatsActivity.this); - labelBOLUS.setId(400 + i); - labelBOLUS.setText(DecimalFormatter.to2Decimal(record.recordDailyBolus) + " U"); - labelBOLUS.setTextColor(Color.WHITE); - tr.addView(labelBOLUS); - - TextView labelTDD = new TextView(DanaRStatsActivity.this); - labelTDD.setId(500 + i); - labelTDD.setText(DecimalFormatter.to2Decimal(tdd) + " U"); - labelTDD.setTextColor(Color.WHITE); - tr.addView(labelTDD); - - TextView labelRATIO = new TextView(DanaRStatsActivity.this); - labelRATIO.setId(600 + i); - labelRATIO.setText(Math.round(100 * tdd / magicNumber) + " %"); - labelRATIO.setTextColor(Color.WHITE); - tr.addView(labelRATIO); - - // add stats rows to tables - tl.addView(tr, new TableLayout.LayoutParams( - TableLayout.LayoutParams.MATCH_PARENT, - TableLayout.LayoutParams.WRAP_CONTENT)); - - sum = sum + tdd; - i++; - - // Create the cumtable row - TableRow ctr = new TableRow(DanaRStatsActivity.this); - if (i % 2 == 0) ctr.setBackgroundColor(Color.DKGRAY); - ctr.setId(700 + i); - ctr.setLayoutParams(new TableLayout.LayoutParams( - TableLayout.LayoutParams.MATCH_PARENT, - TableLayout.LayoutParams.WRAP_CONTENT)); - - // Here create the TextView dynamically - TextView labelDAYS = new TextView(DanaRStatsActivity.this); - labelDAYS.setId(800 + i); - labelDAYS.setText("" + i); - labelDAYS.setTextColor(Color.WHITE); - ctr.addView(labelDAYS); - - TextView labelCUMTDD = new TextView(DanaRStatsActivity.this); - labelCUMTDD.setId(900 + i); - labelCUMTDD.setText(DecimalFormatter.to2Decimal(sum / i) + " U"); - labelCUMTDD.setTextColor(Color.WHITE); - ctr.addView(labelCUMTDD); - - TextView labelCUMRATIO = new TextView(DanaRStatsActivity.this); - labelCUMRATIO.setId(1000 + i); - labelCUMRATIO.setText(Math.round(100 * sum / i / magicNumber) + " %"); - labelCUMRATIO.setTextColor(Color.WHITE); - ctr.addView(labelCUMRATIO); - - // add cummulative rows to tables - ctl.addView(ctr, new TableLayout.LayoutParams( - TableLayout.LayoutParams.MATCH_PARENT, - TableLayout.LayoutParams.WRAP_CONTENT)); - } - - if (historyList.size() < 3 || !(df.format(new Date(historyList.get(0).recordDate)).equals(df.format(new Date(System.currentTimeMillis() - 1000 * 60 * 60 * 24))))) { - statsMessage.setVisibility(View.VISIBLE); - statsMessage.setText(getString(R.string.danar_stats_olddata_Message)); - - } else { - tl.setBackgroundColor(Color.TRANSPARENT); - } - - Collections.reverse(historyList); - - i = 0; - - for (DanaRHistoryRecord record : historyList) { - double tdd = record.recordDailyBolus + record.recordDailyBasal; - if (i == 0) { - weighted03 = tdd; - weighted05 = tdd; - weighted07 = tdd; - - } else { - weighted07 = (weighted07 * 0.3 + tdd * 0.7); - weighted05 = (weighted05 * 0.5 + tdd * 0.5); - weighted03 = (weighted03 * 0.7 + tdd * 0.3); - } - i++; - } - - // Create the exptable row - TableRow etr = new TableRow(DanaRStatsActivity.this); - if (i % 2 != 0) etr.setBackgroundColor(Color.DKGRAY); - etr.setId(1100 + i); - etr.setLayoutParams(new TableLayout.LayoutParams( - TableLayout.LayoutParams.MATCH_PARENT, - TableLayout.LayoutParams.WRAP_CONTENT)); - - // Here create the TextView dynamically - TextView labelWEIGHT = new TextView(DanaRStatsActivity.this); - labelWEIGHT.setId(1200 + i); - labelWEIGHT.setText("0.3\n" + "0.5\n" + "0.7"); - labelWEIGHT.setTextColor(Color.WHITE); - etr.addView(labelWEIGHT); - - TextView labelEXPTDD = new TextView(DanaRStatsActivity.this); - labelEXPTDD.setId(1300 + i); - labelEXPTDD.setText(DecimalFormatter.to2Decimal(weighted03) - + " U\n" + DecimalFormatter.to2Decimal(weighted05) - + " U\n" + DecimalFormatter.to2Decimal(weighted07) + " U"); - labelEXPTDD.setTextColor(Color.WHITE); - etr.addView(labelEXPTDD); - - TextView labelEXPRATIO = new TextView(DanaRStatsActivity.this); - labelEXPRATIO.setId(1400 + i); - labelEXPRATIO.setText(Math.round(100 * weighted03 / magicNumber) + " %\n" - + Math.round(100 * weighted05 / magicNumber) + " %\n" - + Math.round(100 * weighted07 / magicNumber) + " %"); - labelEXPRATIO.setTextColor(Color.WHITE); - etr.addView(labelEXPRATIO); - - // add exponentail rows to tables - etl.addView(etr, new TableLayout.LayoutParams( - TableLayout.LayoutParams.MATCH_PARENT, - TableLayout.LayoutParams.WRAP_CONTENT)); - } - }); - } - - private void cleanTable(TableLayout table) { - int childCount = table.getChildCount(); - // Remove all rows except the first one - if (childCount > 1) { - table.removeViews(1, childCount - 1); - } - } - - @Subscribe - public void onStatusEvent(final EventDanaRSyncStatus s) { - log.debug("EventDanaRSyncStatus: " + s.message); - runOnUiThread( - new Runnable() { - @Override - public void run() { - statusView.setText(s.message); - } - }); - } - - @Subscribe - public void onStatusEvent(final EventPumpStatusChanged c) { - runOnUiThread( - new Runnable() { - @Override - public void run() { - statusView.setText(c.textStatus()); - } - } - ); - } -} \ No newline at end of file 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 0a73555b52..f54b8edb30 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 @@ -8,7 +8,7 @@ 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.events.EventRefreshOverview; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPlugin; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; @@ -43,7 +43,7 @@ public class MsgInitConnStatusTime_k extends MessageBase { } MainApp.getConfigBuilder().storeSettings(); - MainApp.bus().post(new EventRefreshGui(false)); + MainApp.bus().post(new EventRefreshOverview("MsgInitConnStatusTime_k")); return; } 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 3bf1aa2e5f..1fdcf26917 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 @@ -20,7 +20,7 @@ public class MsgStatus_k extends MessageBase { pump.isExtendedInProgress = intFromBuff(bytes, 3, 1) == 1; pump.extendedBolusMinutes = intFromBuff(bytes, 4, 2); pump.extendedBolusAmount = intFromBuff(bytes, 6, 2) / 100d; - Double lastBolusAmount = intFromBuff(bytes, 13, 2) / 100d; + double lastBolusAmount = intFromBuff(bytes, 13, 2) / 100d; // if (lastBolusAmount != 0d) { // pump.lastBolusTime = dateTimeFromBuff(bytes, 8); // pump.lastBolusAmount = lastBolusAmount; 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 89976c6778..d803c17bda 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 @@ -196,9 +196,9 @@ public class DanaRKoreanExecutionService extends Service { getBTSocketForSelectedPump(); if (mRfcommSocket == null || mBTDevice == null) return; // Device not found - long startTime = new Date().getTime(); - while (!isConnected() && startTime + maxConnectionTime >= new Date().getTime()) { - long secondsElapsed = (new Date().getTime() - startTime) / 1000L; + long startTime = System.currentTimeMillis(); + while (!isConnected() && startTime + maxConnectionTime >= System.currentTimeMillis()) { + long secondsElapsed = (System.currentTimeMillis() - startTime) / 1000L; MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.CONNECTING, (int) secondsElapsed)); if (Config.logDanaBTComm) log.debug("connect waiting " + secondsElapsed + "sec from: " + from); @@ -225,7 +225,7 @@ public class DanaRKoreanExecutionService extends Service { if (!MainApp.getSpecificPlugin(DanaRKoreanPlugin.class).isEnabled(PluginBase.PUMP)) return; getBTSocketForSelectedPump(); - startTime = new Date().getTime(); + startTime = System.currentTimeMillis(); } } } @@ -347,6 +347,11 @@ public class DanaRKoreanExecutionService extends Service { public boolean tempBasal(int percent, int durationInHours) { connect("tempBasal"); if (!isConnected()) return false; + if (danaRPump.isTempBasalInProgress) { + MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.stoppingtempbasal))); + mSerialIOThread.sendMessage(new MsgSetTempBasalStop()); + waitMsec(500); + } MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.settingtempbasal))); mSerialIOThread.sendMessage(new MsgSetTempBasalStart(percent, durationInHours)); mSerialIOThread.sendMessage(new MsgStatusTempBasal()); @@ -393,7 +398,7 @@ public class DanaRKoreanExecutionService extends Service { if (!isConnected()) return false; if (carbs > 0) { - mSerialIOThread.sendMessage(new MsgSetCarbsEntry(new Date().getTime(), carbs)); + mSerialIOThread.sendMessage(new MsgSetCarbsEntry(System.currentTimeMillis(), carbs)); } MsgBolusProgress progress = new MsgBolusProgress(amount, t); // initialize static variables @@ -407,7 +412,7 @@ public class DanaRKoreanExecutionService extends Service { } while (!stop.stopped && !start.failed) { waitMsec(100); - if ((new Date().getTime() - progress.lastReceive) > 5 * 1000L) { // if i didn't receive status for more than 5 sec expecting broken comm + if ((System.currentTimeMillis() - progress.lastReceive) > 5 * 1000L) { // if i didn't receive status for more than 5 sec expecting broken comm stop.stopped = true; stop.forced = true; log.debug("Communication stopped"); @@ -438,7 +443,7 @@ public class DanaRKoreanExecutionService extends Service { public boolean carbsEntry(int amount) { connect("carbsEntry"); if (!isConnected()) return false; - MsgSetCarbsEntry msg = new MsgSetCarbsEntry(new Date().getTime(), amount); + MsgSetCarbsEntry msg = new MsgSetCarbsEntry(System.currentTimeMillis(), amount); mSerialIOThread.sendMessage(msg); return true; } @@ -504,7 +509,7 @@ public class DanaRKoreanExecutionService extends Service { private double[] buildDanaRProfileRecord(Profile nsProfile) { double[] record = new double[24]; for (Integer hour = 0; hour < 24; hour++) { - double value = Math.round(100d * nsProfile.getBasal(hour * 60 * 60))/100d + 0.00001; + double value = Math.round(100d * nsProfile.getBasal((Integer) (hour * 60 * 60)))/100d + 0.00001; if (Config.logDanaMessageDetail) log.debug("NS basal value for " + hour + ":00 is " + value); record[hour] = value; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/DanaRv2Fragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/DanaRv2Fragment.java index a0480685ad..85d9f4b5f2 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/DanaRv2Fragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/DanaRv2Fragment.java @@ -27,16 +27,17 @@ import info.nightscout.androidaps.R; import info.nightscout.androidaps.events.EventExtendedBolusChange; import info.nightscout.androidaps.events.EventPumpStatusChanged; import info.nightscout.androidaps.events.EventTempBasalChange; +import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; import info.nightscout.androidaps.plugins.PumpDanaR.Dialogs.ProfileViewDialog; +import info.nightscout.androidaps.plugins.PumpDanaR.activities.DanaRHistoryActivity; +import info.nightscout.androidaps.plugins.PumpDanaR.activities.DanaRStatsActivity; import info.nightscout.androidaps.plugins.PumpDanaR.events.EventDanaRNewStatus; -import info.nightscout.androidaps.plugins.PumpDanaRv2.History.DanaRHistoryActivity; -import info.nightscout.androidaps.plugins.PumpDanaRv2.History.DanaRStatsActivity; import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.SetWarnColor; -public class DanaRv2Fragment extends Fragment { +public class DanaRv2Fragment extends SubscriberFragment { private static Logger log = LoggerFactory.getLogger(DanaRv2Fragment.class); private static DanaRv2Plugin danaRPlugin; @@ -65,6 +66,8 @@ public class DanaRv2Fragment extends Fragment { TextView reservoirView; TextView iobView; TextView firmwareView; + TextView basalStepView; + TextView bolusStepView; Button viewProfileButton; Button historyButton; Button statsButton; @@ -111,6 +114,8 @@ public class DanaRv2Fragment extends Fragment { viewProfileButton = (Button) view.findViewById(R.id.danar_viewprofile); historyButton = (Button) view.findViewById(R.id.danar_history); statsButton = (Button) view.findViewById(R.id.danar_stats); + basalStepView = (TextView) view.findViewById(R.id.danar_basalstep); + bolusStepView = (TextView) view.findViewById(R.id.danar_bolusstep); viewProfileButton.setOnClickListener(new View.OnClickListener() { @@ -153,18 +158,6 @@ public class DanaRv2Fragment extends Fragment { return view; } - @Override - public void onPause() { - super.onPause(); - MainApp.bus().unregister(this); - } - - @Override - public void onResume() { - super.onResume(); - MainApp.bus().register(this); - } - @Subscribe public void onStatusEvent(final EventPumpStatusChanged c) { Activity activity = getActivity(); @@ -201,7 +194,8 @@ public class DanaRv2Fragment extends Fragment { } // GUI functions - private void updateGUI() { + @Override + protected void updateGUI() { Activity activity = getActivity(); if (activity != null && basaBasalRateView != null) activity.runOnUiThread(new Runnable() { @@ -210,13 +204,13 @@ public class DanaRv2Fragment extends Fragment { public void run() { DanaRPump pump = DanaRPump.getInstance(); if (pump.lastConnection.getTime() != 0) { - Long agoMsec = new Date().getTime() - pump.lastConnection.getTime(); + Long agoMsec = System.currentTimeMillis() - pump.lastConnection.getTime(); int agoMin = (int) (agoMsec / 60d / 1000d); lastConnectionView.setText(DateUtil.timeString(pump.lastConnection) + " (" + String.format(MainApp.sResources.getString(R.string.minago), agoMin) + ")"); SetWarnColor.setColor(lastConnectionView, agoMin, 16d, 31d); } if (pump.lastBolusTime.getTime() != 0) { - Long agoMsec = new Date().getTime() - pump.lastBolusTime.getTime(); + Long agoMsec = System.currentTimeMillis() - pump.lastBolusTime.getTime(); double agoHours = agoMsec / 60d / 60d / 1000d; if (agoHours < 6) // max 6h back lastBolusView.setText(DateUtil.timeString(pump.lastBolusTime) + " (" + DecimalFormatter.to1Decimal(agoHours) + " " + MainApp.sResources.getString(R.string.hoursago) + ") " + DecimalFormatter.to2Decimal(DanaRPump.getInstance().lastBolusAmount) + " U"); @@ -227,12 +221,12 @@ public class DanaRv2Fragment extends Fragment { SetWarnColor.setColor(dailyUnitsView, pump.dailyTotalUnits, pump.maxDailyTotalUnits * 0.75d, pump.maxDailyTotalUnits * 0.9d); basaBasalRateView.setText("( " + (pump.activeProfile + 1) + " ) " + DecimalFormatter.to2Decimal(getPlugin().getBaseBasalRate()) + " U/h"); if (MainApp.getConfigBuilder().isTempBasalInProgress()) { - tempBasalView.setText(MainApp.getConfigBuilder().getTempBasalFromHistory(new Date().getTime()).toStringFull()); + tempBasalView.setText(MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis()).toStringFull()); } else { tempBasalView.setText(""); } if (MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) { - extendedBolusView.setText(MainApp.getConfigBuilder().getExtendedBolusFromHistory(new Date().getTime()).toString()); + extendedBolusView.setText(MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()).toString()); } else { extendedBolusView.setText(""); } @@ -246,6 +240,8 @@ public class DanaRv2Fragment extends Fragment { } else { firmwareView.setText("OLD"); } + basalStepView.setText("" + pump.basalStep); + bolusStepView.setText("" + pump.bolusStep); } }); 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 cf2cad1527..8c2b2d327b 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 @@ -31,6 +31,7 @@ import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.db.Treatment; import info.nightscout.androidaps.events.EventAppExit; import info.nightscout.androidaps.interfaces.ConstraintsInterface; +import info.nightscout.androidaps.interfaces.DanaRInterface; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.ProfileInterface; import info.nightscout.androidaps.interfaces.PumpDescription; @@ -38,6 +39,7 @@ import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.ProfileStore; +import info.nightscout.androidaps.plugins.ConfigBuilder.DetailedBolusInfoStorage; import info.nightscout.androidaps.plugins.Overview.Notification; import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; @@ -51,7 +53,7 @@ import info.nightscout.utils.Round; /** * Created by mike on 05.08.2016. */ -public class DanaRv2Plugin implements PluginBase, PumpInterface, ConstraintsInterface, ProfileInterface { +public class DanaRv2Plugin implements PluginBase, PumpInterface, DanaRInterface, ConstraintsInterface, ProfileInterface { private static Logger log = LoggerFactory.getLogger(DanaRv2Plugin.class); @Override @@ -253,7 +255,7 @@ public class DanaRv2Plugin implements PluginBase, PumpInterface, ConstraintsInte int basalIncrement = pump.basal48Enable ? 30 * 60 : 60 * 60; for (int h = 0; h < basalValues; h++) { Double pumpValue = pump.pumpProfiles[pump.activeProfile][h]; - Double profileValue = profile.getBasal(h * basalIncrement); + Double profileValue = profile.getBasal((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); @@ -285,10 +287,11 @@ public class DanaRv2Plugin implements PluginBase, PumpInterface, ConstraintsInte ConfigBuilderPlugin configBuilderPlugin = MainApp.getConfigBuilder(); detailedBolusInfo.insulin = configBuilderPlugin.applyBolusConstraints(detailedBolusInfo.insulin); if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) { + DetailedBolusInfoStorage.add(detailedBolusInfo); // will be picked up on reading history Treatment t = new Treatment(detailedBolusInfo.insulinInterface); boolean connectionOK = false; if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) - connectionOK = sExecutionService.bolus(detailedBolusInfo.insulin, (int) detailedBolusInfo.carbs, new Date().getTime() + detailedBolusInfo.carbTime * 60 * 1000 + 1000, t); // +1000 to make the record different + connectionOK = sExecutionService.bolus(detailedBolusInfo.insulin, (int) detailedBolusInfo.carbs, System.currentTimeMillis() + detailedBolusInfo.carbTime * 60 * 1000 + 1000, t); // +1000 to make the record different PumpEnactResult result = new PumpEnactResult(); result.success = connectionOK; result.bolusDelivered = t.insulin; @@ -296,6 +299,7 @@ public class DanaRv2Plugin implements PluginBase, PumpInterface, ConstraintsInte result.comment = MainApp.instance().getString(R.string.virtualpump_resultok); if (Config.logPumpActions) log.debug("deliverTreatment: OK. Asked: " + detailedBolusInfo.insulin + " Delivered: " + result.bolusDelivered); + // remove carbs because it's get from history seprately return result; } else { PumpEnactResult result = new PumpEnactResult(); @@ -321,7 +325,7 @@ public class DanaRv2Plugin implements PluginBase, PumpInterface, ConstraintsInte @Override public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes) { // Recheck pump status if older than 30 min - if (pump.lastConnection.getTime() + 30 * 60 * 1000L < new Date().getTime()) { + if (pump.lastConnection.getTime() + 30 * 60 * 1000L < System.currentTimeMillis()) { doConnect("setTempBasalAbsolute old data"); } @@ -339,7 +343,7 @@ public class DanaRv2Plugin implements PluginBase, PumpInterface, ConstraintsInte if (MainApp.getConfigBuilder().isTempBasalInProgress()) { if (Config.logPumpActions) log.debug("setTempBasalAbsolute: Stopping temp basal (doTempOff)"); - return cancelTempBasal(); + return cancelTempBasal(false); } result.success = true; result.enacted = false; @@ -360,7 +364,7 @@ public class DanaRv2Plugin implements PluginBase, PumpInterface, ConstraintsInte // Check if some temp is already in progress if (MainApp.getConfigBuilder().isTempBasalInProgress()) { // Correct basal already set ? - if (MainApp.getConfigBuilder().getTempBasalFromHistory(new Date().getTime()).percentRate == percentRate) { + if (MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis()).percentRate == percentRate) { result.success = true; result.percent = percentRate; result.absolute = MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory(); @@ -414,6 +418,7 @@ public class DanaRv2Plugin implements PluginBase, PumpInterface, ConstraintsInte result.comment = MainApp.instance().getString(R.string.virtualpump_resultok); result.duration = pump.tempBasalRemainingMin; result.percent = pump.tempBasalPercent; + result.absolute = MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory(); result.isPercent = true; if (Config.logPumpActions) log.debug("setTempBasalPercent: Correct value already set"); @@ -428,6 +433,7 @@ public class DanaRv2Plugin implements PluginBase, PumpInterface, ConstraintsInte result.isTempCancel = false; result.duration = pump.tempBasalRemainingMin; result.percent = pump.tempBasalPercent; + result.absolute = MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory(); result.isPercent = true; if (Config.logPumpActions) log.debug("setTempBasalPercent: OK"); @@ -467,8 +473,8 @@ public class DanaRv2Plugin implements PluginBase, PumpInterface, ConstraintsInte ConfigBuilderPlugin configBuilderPlugin = MainApp.getConfigBuilder(); insulin = configBuilderPlugin.applyBolusConstraints(insulin); // needs to be rounded - insulin = Round.roundTo(insulin, getPumpDescription().extendedBolusStep); - + int durationInHalfHours = Math.max(durationInMinutes / 30, 1); + insulin = Round.roundTo(insulin, getPumpDescription().extendedBolusStep * (1 + durationInHalfHours % 1)); PumpEnactResult result = new PumpEnactResult(); if (pump.isExtendedInProgress && Math.abs(pump.extendedBolusAmount - insulin) < getPumpDescription().extendedBolusStep) { result.enacted = false; @@ -482,7 +488,6 @@ public class DanaRv2Plugin implements PluginBase, PumpInterface, ConstraintsInte log.debug("setExtendedBolus: Correct extended bolus already set. Current: " + pump.extendedBolusAmount + " Asked: " + insulin); return result; } - int durationInHalfHours = Math.max(durationInMinutes / 30, 1); boolean connectionOK = sExecutionService.extendedBolus(insulin, durationInHalfHours); if (connectionOK && pump.isExtendedInProgress && Math.abs(pump.extendedBolusAmount - insulin) < getPumpDescription().extendedBolusStep) { result.enacted = true; @@ -505,7 +510,7 @@ public class DanaRv2Plugin implements PluginBase, PumpInterface, ConstraintsInte } @Override - public PumpEnactResult cancelTempBasal() { + public PumpEnactResult cancelTempBasal(boolean userRequested) { PumpEnactResult result = new PumpEnactResult(); if (pump.isTempBasalInProgress) { sExecutionService.tempBasalStop(); @@ -568,7 +573,7 @@ public class DanaRv2Plugin implements PluginBase, PumpInterface, ConstraintsInte @Override public JSONObject getJSONStatus() { - if (pump.lastConnection.getTime() + 5 * 60 * 1000L < new Date().getTime()) { + if (pump.lastConnection.getTime() + 5 * 60 * 1000L < System.currentTimeMillis()) { return null; } JSONObject pumpjson = new JSONObject(); @@ -585,13 +590,13 @@ public class DanaRv2Plugin implements PluginBase, PumpInterface, ConstraintsInte extended.put("LastBolus", pump.lastBolusTime.toLocaleString()); extended.put("LastBolusAmount", pump.lastBolusAmount); } - TemporaryBasal tb = MainApp.getConfigBuilder().getTempBasalFromHistory(new Date().getTime()); + TemporaryBasal tb = MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis()); if (tb != null) { - extended.put("TempBasalAbsoluteRate", tb.tempBasalConvertedToAbsolute(new Date().getTime())); + extended.put("TempBasalAbsoluteRate", tb.tempBasalConvertedToAbsolute(System.currentTimeMillis())); extended.put("TempBasalStart", DateUtil.dateAndTimeString(tb.date)); extended.put("TempBasalRemaining", tb.getPlannedRemainingMinutes()); } - ExtendedBolus eb = MainApp.getConfigBuilder().getExtendedBolusFromHistory(new Date().getTime()); + ExtendedBolus eb = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()); if (eb != null) { extended.put("ExtendedBolusAbsoluteRate", eb.absoluteRate()); extended.put("ExtendedBolusStart", DateUtil.dateAndTimeString(eb.date)); @@ -624,6 +629,15 @@ public class DanaRv2Plugin implements PluginBase, PumpInterface, ConstraintsInte return pumpDescription; } + /** + * DanaR interface + */ + + @Override + public boolean loadHistory(byte type) { + return sExecutionService.loadHistory(type); + } + /** * Constraint interface */ @@ -706,6 +720,11 @@ public class DanaRv2Plugin implements PluginBase, PumpInterface, ConstraintsInte return pump.createConvertedProfile(); } + @Override + public String getUnits() { + return pump.getUnits(); + } + @Override public String getProfileName() { return pump.createConvertedProfileName(); @@ -715,7 +734,7 @@ public class DanaRv2Plugin implements PluginBase, PumpInterface, ConstraintsInte public String shortStatus(boolean veryShort) { String ret = ""; if (pump.lastConnection.getTime() != 0) { - Long agoMsec = new Date().getTime() - pump.lastConnection.getTime(); + Long agoMsec = System.currentTimeMillis() - pump.lastConnection.getTime(); int agoMin = (int) (agoMsec / 60d / 1000d); ret += "LastConn: " + agoMin + " minago\n"; } @@ -723,10 +742,10 @@ public class DanaRv2Plugin implements PluginBase, PumpInterface, ConstraintsInte ret += "LastBolus: " + DecimalFormatter.to2Decimal(pump.lastBolusAmount) + "U @" + android.text.format.DateFormat.format("HH:mm", pump.lastBolusTime) + "\n"; } if (MainApp.getConfigBuilder().isTempBasalInProgress()) { - ret += "Temp: " + MainApp.getConfigBuilder().getTempBasalFromHistory(new Date().getTime()).toStringFull() + "\n"; + ret += "Temp: " + MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis()).toStringFull() + "\n"; } if (MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) { - ret += "Extended: " + MainApp.getConfigBuilder().getExtendedBolusFromHistory(new Date().getTime()).toString() + "\n"; + ret += "Extended: " + MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()).toString() + "\n"; } if (!veryShort) { ret += "TDD: " + DecimalFormatter.to0Decimal(pump.dailyTotalUnits) + " / " + pump.maxDailyTotalUnits + " U\n"; @@ -736,6 +755,7 @@ public class DanaRv2Plugin implements PluginBase, PumpInterface, ConstraintsInte ret += "Batt: " + pump.batteryRemaining + "\n"; return ret; } + // TODO: daily total constraint } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/History/DanaRHistoryActivity.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/History/DanaRHistoryActivity.java deleted file mode 100644 index 1391b753f8..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/History/DanaRHistoryActivity.java +++ /dev/null @@ -1,431 +0,0 @@ -package info.nightscout.androidaps.plugins.PumpDanaRv2.History; - -import android.app.Activity; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.ServiceConnection; -import android.os.Bundle; -import android.os.Handler; -import android.os.HandlerThread; -import android.os.IBinder; -import android.support.v7.widget.CardView; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.ArrayAdapter; -import android.widget.Button; -import android.widget.Spinner; -import android.widget.TextView; - -import com.squareup.otto.Subscribe; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.List; - -import info.nightscout.androidaps.Constants; -import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.R; -import info.nightscout.androidaps.db.DanaRHistoryRecord; -import info.nightscout.androidaps.events.EventPumpStatusChanged; -import info.nightscout.androidaps.data.Profile; -import info.nightscout.androidaps.plugins.PumpDanaR.History.DanaRNSHistorySync; -import info.nightscout.androidaps.plugins.PumpDanaR.comm.RecordTypes; -import info.nightscout.androidaps.plugins.PumpDanaR.events.EventDanaRSyncStatus; -import info.nightscout.androidaps.plugins.PumpDanaRv2.services.DanaRv2ExecutionService; -import info.nightscout.utils.DateUtil; -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 DanaRv2ExecutionService mExecutionService; - - private Handler mHandler; - private static HandlerThread mHandlerThread; - - static Profile profile = null; - - Spinner historyTypeSpinner; - TextView statusView; - Button reloadButton; - Button syncButton; - RecyclerView recyclerView; - LinearLayoutManager llm; - - static byte showingType = RecordTypes.RECORD_TYPE_ALARM; - List historyList = new ArrayList<>(); - - public static class TypeList { - public byte type; - String name; - - public TypeList(byte type, String name) { - this.type = type; - this.name = name; - } - - @Override - public String toString() { - return name; - } - } - - public DanaRHistoryActivity() { - super(); - mHandlerThread = new HandlerThread(DanaRHistoryActivity.class.getSimpleName()); - mHandlerThread.start(); - this.mHandler = new Handler(mHandlerThread.getLooper()); - } - - - @Override - public void onStart() { - super.onStart(); - Intent intent = new Intent(this, DanaRv2ExecutionService.class); - bindService(intent, mConnection, Context.BIND_AUTO_CREATE); - } - - @Override - protected void onResume() { - super.onResume(); - MainApp.bus().register(this); - } - - @Override - protected void onPause() { - super.onPause(); - MainApp.bus().unregister(this); - } - - @Override - public void onStop() { - super.onStop(); - if (mBounded) { - unbindService(mConnection); - mBounded = false; - } - } - - ServiceConnection mConnection = new ServiceConnection() { - - public void onServiceDisconnected(ComponentName name) { - log.debug("Service is disconnected"); - mBounded = false; - mExecutionService = null; - } - - public void onServiceConnected(ComponentName name, IBinder service) { - log.debug("Service is connected"); - mBounded = true; - DanaRv2ExecutionService.LocalBinder mLocalBinder = (DanaRv2ExecutionService.LocalBinder) service; - mExecutionService = mLocalBinder.getServiceInstance(); - } - }; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.danar_historyactivity); - - historyTypeSpinner = (Spinner) findViewById(R.id.danar_historytype); - statusView = (TextView) findViewById(R.id.danar_historystatus); - reloadButton = (Button) findViewById(R.id.danar_historyreload); - syncButton = (Button) findViewById(R.id.danar_historysync); - recyclerView = (RecyclerView) findViewById(R.id.danar_history_recyclerview); - - recyclerView.setHasFixedSize(true); - llm = new LinearLayoutManager(this); - recyclerView.setLayoutManager(llm); - - RecyclerViewAdapter adapter = new RecyclerViewAdapter(historyList); - recyclerView.setAdapter(adapter); - - statusView.setVisibility(View.GONE); - - // Types - - ArrayList typeList = new ArrayList<>(); - typeList.add(new TypeList(RecordTypes.RECORD_TYPE_ALARM, getString(R.string.danar_history_alarm))); - typeList.add(new TypeList(RecordTypes.RECORD_TYPE_BASALHOUR, getString(R.string.danar_history_basalhours))); - typeList.add(new TypeList(RecordTypes.RECORD_TYPE_BOLUS, getString(R.string.danar_history_bolus))); - typeList.add(new TypeList(RecordTypes.RECORD_TYPE_CARBO, getString(R.string.danar_history_carbohydrates))); - typeList.add(new TypeList(RecordTypes.RECORD_TYPE_DAILY, getString(R.string.danar_history_dailyinsulin))); - typeList.add(new TypeList(RecordTypes.RECORD_TYPE_GLUCOSE, getString(R.string.danar_history_glucose))); - - ArrayAdapter spinnerAdapter = new ArrayAdapter<>(this, - android.R.layout.simple_spinner_item, typeList); - spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - historyTypeSpinner.setAdapter(spinnerAdapter); - - reloadButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (mExecutionService.isConnected() || mExecutionService.isConnecting()) { - ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), getString(R.string.pumpbusy)); - return; - } - mHandler.post(new Runnable() { - @Override - public void run() { - TypeList selected = (TypeList) historyTypeSpinner.getSelectedItem(); - runOnUiThread(new Runnable() { - @Override - public void run() { - reloadButton.setVisibility(View.GONE); - syncButton.setVisibility(View.GONE); - statusView.setVisibility(View.VISIBLE); - } - }); - clearCardView(); - mExecutionService.loadHistory(selected.type); - loadDataFromDB(selected.type); - runOnUiThread(new Runnable() { - @Override - public void run() { - 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 - public void onItemSelected(AdapterView parent, View view, int position, long id) { - TypeList selected = (TypeList) historyTypeSpinner.getSelectedItem(); - loadDataFromDB(selected.type); - showingType = selected.type; - } - - @Override - public void onNothingSelected(AdapterView parent) { - clearCardView(); - } - }); - profile = MainApp.getConfigBuilder().getProfile(); - if (profile == null) { - ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.noprofile)); - finish(); - } - } - - public static class RecyclerViewAdapter extends RecyclerView.Adapter { - - List historyList; - - RecyclerViewAdapter(List historyList) { - this.historyList = historyList; - } - - @Override - public HistoryViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { - View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.danar_history_item, viewGroup, false); - return new HistoryViewHolder(v); - } - - @Override - public void onBindViewHolder(HistoryViewHolder holder, int position) { - DanaRHistoryRecord record = historyList.get(position); - holder.time.setText(DateUtil.dateAndTimeString(record.recordDate)); - holder.value.setText(DecimalFormatter.to2Decimal(record.recordValue)); - holder.stringvalue.setText(record.stringRecordValue); - holder.bolustype.setText(record.bolusType); - holder.duration.setText(DecimalFormatter.to0Decimal(record.recordDuration)); - holder.alarm.setText(record.recordAlarm); - switch (showingType) { - case RecordTypes.RECORD_TYPE_ALARM: - holder.time.setVisibility(View.VISIBLE); - holder.value.setVisibility(View.VISIBLE); - holder.stringvalue.setVisibility(View.GONE); - holder.bolustype.setVisibility(View.GONE); - holder.duration.setVisibility(View.GONE); - holder.dailybasal.setVisibility(View.GONE); - holder.dailybolus.setVisibility(View.GONE); - holder.dailytotal.setVisibility(View.GONE); - holder.alarm.setVisibility(View.VISIBLE); - break; - case RecordTypes.RECORD_TYPE_BOLUS: - holder.time.setVisibility(View.VISIBLE); - holder.value.setVisibility(View.VISIBLE); - holder.stringvalue.setVisibility(View.GONE); - holder.bolustype.setVisibility(View.VISIBLE); - holder.duration.setVisibility(View.VISIBLE); - holder.dailybasal.setVisibility(View.GONE); - holder.dailybolus.setVisibility(View.GONE); - holder.dailytotal.setVisibility(View.GONE); - holder.alarm.setVisibility(View.GONE); - break; - case RecordTypes.RECORD_TYPE_DAILY: - holder.dailybasal.setText(DecimalFormatter.to2Decimal(record.recordDailyBasal) + "U"); - holder.dailybolus.setText(DecimalFormatter.to2Decimal(record.recordDailyBolus) + "U"); - holder.dailytotal.setText(DecimalFormatter.to2Decimal(record.recordDailyBolus + record.recordDailyBasal) + "U"); - holder.time.setText(DateUtil.dateString(record.recordDate)); - holder.time.setVisibility(View.VISIBLE); - holder.value.setVisibility(View.GONE); - holder.stringvalue.setVisibility(View.GONE); - holder.bolustype.setVisibility(View.GONE); - holder.duration.setVisibility(View.GONE); - holder.dailybasal.setVisibility(View.VISIBLE); - holder.dailybolus.setVisibility(View.VISIBLE); - holder.dailytotal.setVisibility(View.VISIBLE); - holder.alarm.setVisibility(View.GONE); - break; - case RecordTypes.RECORD_TYPE_GLUCOSE: - holder.value.setText(Profile.toUnitsString(record.recordValue, record.recordValue * Constants.MGDL_TO_MMOLL, profile.getUnits())); - // rest is the same - case RecordTypes.RECORD_TYPE_CARBO: - case RecordTypes.RECORD_TYPE_BASALHOUR: - case RecordTypes.RECORD_TYPE_ERROR: - case RecordTypes.RECORD_TYPE_PRIME: - case RecordTypes.RECORD_TYPE_REFILL: - case RecordTypes.RECORD_TYPE_TB: - holder.time.setVisibility(View.VISIBLE); - holder.value.setVisibility(View.VISIBLE); - holder.stringvalue.setVisibility(View.GONE); - holder.bolustype.setVisibility(View.GONE); - holder.duration.setVisibility(View.GONE); - holder.dailybasal.setVisibility(View.GONE); - holder.dailybolus.setVisibility(View.GONE); - holder.dailytotal.setVisibility(View.GONE); - holder.alarm.setVisibility(View.GONE); - break; - case RecordTypes.RECORD_TYPE_SUSPEND: - holder.time.setVisibility(View.VISIBLE); - holder.value.setVisibility(View.GONE); - holder.stringvalue.setVisibility(View.VISIBLE); - holder.bolustype.setVisibility(View.GONE); - holder.duration.setVisibility(View.GONE); - holder.dailybasal.setVisibility(View.GONE); - holder.dailybolus.setVisibility(View.GONE); - holder.dailytotal.setVisibility(View.GONE); - holder.alarm.setVisibility(View.GONE); - break; - } - } - - @Override - public int getItemCount() { - return historyList.size(); - } - - @Override - public void onAttachedToRecyclerView(RecyclerView recyclerView) { - super.onAttachedToRecyclerView(recyclerView); - } - - public static class HistoryViewHolder extends RecyclerView.ViewHolder { - CardView cv; - TextView time; - TextView value; - TextView bolustype; - TextView stringvalue; - TextView duration; - TextView dailybasal; - TextView dailybolus; - TextView dailytotal; - TextView alarm; - - HistoryViewHolder(View itemView) { - super(itemView); - cv = (CardView) itemView.findViewById(R.id.danar_history_cardview); - time = (TextView) itemView.findViewById(R.id.danar_history_time); - value = (TextView) itemView.findViewById(R.id.danar_history_value); - bolustype = (TextView) itemView.findViewById(R.id.danar_history_bolustype); - stringvalue = (TextView) itemView.findViewById(R.id.danar_history_stringvalue); - duration = (TextView) itemView.findViewById(R.id.danar_history_duration); - dailybasal = (TextView) itemView.findViewById(R.id.danar_history_dailybasal); - dailybolus = (TextView) itemView.findViewById(R.id.danar_history_dailybolus); - dailytotal = (TextView) itemView.findViewById(R.id.danar_history_dailytotal); - alarm = (TextView) itemView.findViewById(R.id.danar_history_alarm); - } - } - } - - private void loadDataFromDB(byte type) { - historyList = MainApp.getDbHelper().getDanaRHistoryRecordsByType(type); - - runOnUiThread(new Runnable() { - @Override - public void run() { - 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); - } - }); - } - - @Subscribe - public void onStatusEvent(final EventDanaRSyncStatus s) { - log.debug("EventDanaRSyncStatus: " + s.message); - runOnUiThread( - new Runnable() { - @Override - public void run() { - statusView.setText(s.message); - } - }); - } - - @Subscribe - public void onStatusEvent(final EventPumpStatusChanged c) { - runOnUiThread( - new Runnable() { - @Override - public void run() { - statusView.setText(c.textStatus()); - } - } - ); - } - - -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/History/DanaRStatsActivity.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/History/DanaRStatsActivity.java deleted file mode 100644 index d366c42df7..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/History/DanaRStatsActivity.java +++ /dev/null @@ -1,546 +0,0 @@ -package info.nightscout.androidaps.plugins.PumpDanaRv2.History; - -import android.app.Activity; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.ServiceConnection; -import android.content.SharedPreferences; -import android.graphics.Color; -import android.graphics.Rect; -import android.os.Bundle; -import android.os.Handler; -import android.os.HandlerThread; -import android.os.IBinder; -import android.preference.PreferenceManager; -import android.support.v7.widget.LinearLayoutManager; -import android.text.TextUtils; -import android.view.KeyEvent; -import android.view.MotionEvent; -import android.view.View; -import android.view.WindowManager; -import android.view.inputmethod.EditorInfo; -import android.view.inputmethod.InputMethodManager; -import android.widget.Button; -import android.widget.EditText; -import android.widget.TableLayout; -import android.widget.TableRow; -import android.widget.TextView; - -import com.j256.ormlite.dao.Dao; -import com.j256.ormlite.stmt.PreparedQuery; -import com.j256.ormlite.stmt.QueryBuilder; -import com.j256.ormlite.stmt.Where; -import com.squareup.otto.Subscribe; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.sql.SQLException; -import java.text.DateFormat; -import java.text.DecimalFormat; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.List; - -import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.R; -import info.nightscout.androidaps.db.DanaRHistoryRecord; -import info.nightscout.androidaps.events.EventPumpStatusChanged; -import info.nightscout.androidaps.interfaces.ProfileInterface; -import info.nightscout.androidaps.plugins.ProfileCircadianPercentage.CircadianPercentageProfilePlugin; -import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; -import info.nightscout.androidaps.plugins.PumpDanaR.comm.RecordTypes; -import info.nightscout.androidaps.plugins.PumpDanaR.events.EventDanaRSyncStatus; -import info.nightscout.androidaps.plugins.PumpDanaRv2.services.DanaRv2ExecutionService; -import info.nightscout.utils.DecimalFormatter; -import info.nightscout.utils.SP; -import info.nightscout.utils.SafeParse; -import info.nightscout.utils.ToastUtils; - -public class DanaRStatsActivity extends Activity { - private static Logger log = LoggerFactory.getLogger(DanaRStatsActivity.class); - - private boolean mBounded; - private static DanaRv2ExecutionService mExecutionService; - - private Handler mHandler; - private static HandlerThread mHandlerThread; - - TextView statusView, statsMessage, totalBaseBasal2; - EditText totalBaseBasal; - Button reloadButton; - LinearLayoutManager llm; - TableLayout tl, ctl, etl; - String TBB; - double magicNumber; - DecimalFormat decimalFormat; - - List historyList = new ArrayList<>(); - - public DanaRStatsActivity() { - super(); - mHandlerThread = new HandlerThread(DanaRStatsActivity.class.getSimpleName()); - mHandlerThread.start(); - this.mHandler = new Handler(mHandlerThread.getLooper()); - } - - @Override - public void onStart() { - super.onStart(); - Intent intent = new Intent(this, DanaRv2ExecutionService.class); - bindService(intent, mConnection, Context.BIND_AUTO_CREATE); - } - - @Override - protected void onResume() { - super.onResume(); - MainApp.bus().register(this); - } - - @Override - protected void onPause() { - super.onPause(); - MainApp.bus().unregister(this); - } - - @Override - public void onStop() { - super.onStop(); - if (mBounded) { - unbindService(mConnection); - mBounded = false; - } - } - - @Override - public boolean dispatchTouchEvent(MotionEvent event) { - if (event.getAction() == MotionEvent.ACTION_DOWN) { - View myView = getCurrentFocus(); - if (myView instanceof EditText) { - Rect rect = new Rect(); - myView.getGlobalVisibleRect(rect); - if (!rect.contains((int) event.getRawX(), (int) event.getRawY())) { - myView.clearFocus(); - } - } - } - return super.dispatchTouchEvent(event); - } - - ServiceConnection mConnection = new ServiceConnection() { - - public void onServiceDisconnected(ComponentName name) { - log.debug("Service is disconnected"); - mBounded = false; - mExecutionService = null; - } - - public void onServiceConnected(ComponentName name, IBinder service) { - log.debug("Service is connected"); - mBounded = true; - DanaRv2ExecutionService.LocalBinder mLocalBinder = (DanaRv2ExecutionService.LocalBinder) service; - mExecutionService = mLocalBinder.getServiceInstance(); - } - }; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.danar_statsactivity); - getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN); - statusView = (TextView) findViewById(R.id.danar_stats_connection_status); - reloadButton = (Button) findViewById(R.id.danar_statsreload); - totalBaseBasal = (EditText) findViewById(R.id.danar_stats_editTotalBaseBasal); - totalBaseBasal2 = (TextView) findViewById(R.id.danar_stats_editTotalBaseBasal2); - statsMessage = (TextView) findViewById(R.id.danar_stats_Message); - - statusView.setVisibility(View.GONE); - statsMessage.setVisibility(View.GONE); - - totalBaseBasal2.setEnabled(false); - totalBaseBasal2.setClickable(false); - totalBaseBasal2.setFocusable(false); - totalBaseBasal2.setInputType(0); - - decimalFormat = new DecimalFormat("0.000"); - llm = new LinearLayoutManager(this); - - TBB = SP.getString("TBB", "10.00"); - totalBaseBasal.setText(TBB); - - ProfileInterface pi = ConfigBuilderPlugin.getActiveProfileInterface(); - if (pi != null && pi instanceof CircadianPercentageProfilePlugin) { - double cppTBB = ((CircadianPercentageProfilePlugin) pi).baseBasalSum(); - totalBaseBasal.setText(decimalFormat.format(cppTBB)); - SP.putString("TBB", totalBaseBasal.getText().toString()); - TBB = SP.getString("TBB", ""); - } - - // stats table - tl = (TableLayout) findViewById(R.id.main_table); - TableRow tr_head = new TableRow(this); - tr_head.setBackgroundColor(Color.DKGRAY); - tr_head.setLayoutParams(new TableLayout.LayoutParams( - TableLayout.LayoutParams.MATCH_PARENT, - TableLayout.LayoutParams.WRAP_CONTENT)); - - TextView label_date = new TextView(this); - label_date.setText(getString(R.string.danar_stats_date)); - label_date.setTextColor(Color.WHITE); - tr_head.addView(label_date); - - TextView label_basalrate = new TextView(this); - label_basalrate.setText(getString(R.string.danar_stats_basalrate)); - label_basalrate.setTextColor(Color.WHITE); - tr_head.addView(label_basalrate); - - TextView label_bolus = new TextView(this); - label_bolus.setText(getString(R.string.danar_stats_bolus)); - label_bolus.setTextColor(Color.WHITE); - tr_head.addView(label_bolus); - - TextView label_tdd = new TextView(this); - label_tdd.setText(getString(R.string.danar_stats_tdd)); - label_tdd.setTextColor(Color.WHITE); - tr_head.addView(label_tdd); - - TextView label_ratio = new TextView(this); - label_ratio.setText(getString(R.string.danar_stats_ratio)); - label_ratio.setTextColor(Color.WHITE); - tr_head.addView(label_ratio); - - // add stats headers to tables - tl.addView(tr_head, new TableLayout.LayoutParams( - TableLayout.LayoutParams.MATCH_PARENT, - TableLayout.LayoutParams.WRAP_CONTENT)); - - // cumulative table - ctl = (TableLayout) findViewById(R.id.cumulative_table); - TableRow ctr_head = new TableRow(this); - ctr_head.setBackgroundColor(Color.DKGRAY); - ctr_head.setLayoutParams(new TableLayout.LayoutParams( - TableLayout.LayoutParams.MATCH_PARENT, - TableLayout.LayoutParams.WRAP_CONTENT)); - - TextView label_cum_amount_days = new TextView(this); - label_cum_amount_days.setText(getString(R.string.danar_stats_amount_days)); - label_cum_amount_days.setTextColor(Color.WHITE); - ctr_head.addView(label_cum_amount_days); - - TextView label_cum_tdd = new TextView(this); - label_cum_tdd.setText(getString(R.string.danar_stats_tdd)); - label_cum_tdd.setTextColor(Color.WHITE); - ctr_head.addView(label_cum_tdd); - - TextView label_cum_ratio = new TextView(this); - label_cum_ratio.setText(getString(R.string.danar_stats_ratio)); - label_cum_ratio.setTextColor(Color.WHITE); - ctr_head.addView(label_cum_ratio); - - // add cummulative headers to tables - ctl.addView(ctr_head, new TableLayout.LayoutParams( - TableLayout.LayoutParams.MATCH_PARENT, - TableLayout.LayoutParams.WRAP_CONTENT)); - - // expontial table - etl = (TableLayout) findViewById(R.id.expweight_table); - TableRow etr_head = new TableRow(this); - etr_head.setBackgroundColor(Color.DKGRAY); - etr_head.setLayoutParams(new TableLayout.LayoutParams( - TableLayout.LayoutParams.MATCH_PARENT, - TableLayout.LayoutParams.WRAP_CONTENT)); - - TextView label_exp_weight = new TextView(this); - label_exp_weight.setText(getString(R.string.danar_stats_weight)); - label_exp_weight.setTextColor(Color.WHITE); - etr_head.addView(label_exp_weight); - - TextView label_exp_tdd = new TextView(this); - label_exp_tdd.setText(getString(R.string.danar_stats_tdd)); - label_exp_tdd.setTextColor(Color.WHITE); - etr_head.addView(label_exp_tdd); - - TextView label_exp_ratio = new TextView(this); - label_exp_ratio.setText(getString(R.string.danar_stats_ratio)); - label_exp_ratio.setTextColor(Color.WHITE); - etr_head.addView(label_exp_ratio); - - // add expontial headers to tables - etl.addView(etr_head, new TableLayout.LayoutParams( - TableLayout.LayoutParams.MATCH_PARENT, - TableLayout.LayoutParams.WRAP_CONTENT)); - - reloadButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (mExecutionService.isConnected() || mExecutionService.isConnecting()) { - ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), getString(R.string.pumpbusy)); - return; - } - mHandler.post(new Runnable() { - @Override - public void run() { - runOnUiThread(new Runnable() { - @Override - public void run() { - reloadButton.setVisibility(View.GONE); - statusView.setVisibility(View.VISIBLE); - statsMessage.setVisibility(View.VISIBLE); - statsMessage.setText(getString(R.string.danar_stats_warning_Message)); - } - }); - mExecutionService.loadHistory(RecordTypes.RECORD_TYPE_DAILY); - loadDataFromDB(RecordTypes.RECORD_TYPE_DAILY); - runOnUiThread(new Runnable() { - @Override - public void run() { - reloadButton.setVisibility(View.VISIBLE); - statusView.setVisibility(View.GONE); - statsMessage.setVisibility(View.GONE); - } - }); - } - }); - } - }); - - totalBaseBasal.setOnEditorActionListener(new TextView.OnEditorActionListener() { - @Override - public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { - if (actionId == EditorInfo.IME_ACTION_DONE) { - totalBaseBasal.clearFocus(); - return true; - } - return false; - } - }); - - totalBaseBasal.setOnFocusChangeListener(new View.OnFocusChangeListener() { - @Override - public void onFocusChange(View v, boolean hasFocus) { - if (hasFocus) { - totalBaseBasal.getText().clear(); - } else { - SP.putString("TBB", totalBaseBasal.getText().toString()); - TBB = SP.getString("TBB", ""); - loadDataFromDB(RecordTypes.RECORD_TYPE_DAILY); - InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE); - imm.hideSoftInputFromWindow(totalBaseBasal.getWindowToken(), 0); - } - } - }); - - loadDataFromDB(RecordTypes.RECORD_TYPE_DAILY); - } - - private void loadDataFromDB(byte type) { - historyList = MainApp.getDbHelper().getDanaRHistoryRecordsByType(type); - - runOnUiThread(new Runnable() { - @Override - public void run() { - cleanTable(tl); - cleanTable(ctl); - cleanTable(etl); - DateFormat df = new SimpleDateFormat("dd.MM."); - - if (TextUtils.isEmpty(TBB)) { - totalBaseBasal.setError("Please Enter Total Base Basal"); - return; - } else { - magicNumber = SafeParse.stringToDouble(TBB); - } - - magicNumber *= 2; - totalBaseBasal2.setText(decimalFormat.format(magicNumber)); - - int i = 0; - double sum = 0d; - double weighted03 = 0d; - double weighted05 = 0d; - double weighted07 = 0d; - - for (DanaRHistoryRecord record : historyList) { - double tdd = record.recordDailyBolus + record.recordDailyBasal; - - // Create the table row - TableRow tr = new TableRow(DanaRStatsActivity.this); - if (i % 2 != 0) tr.setBackgroundColor(Color.DKGRAY); - tr.setId(100 + i); - tr.setLayoutParams(new TableLayout.LayoutParams( - TableLayout.LayoutParams.MATCH_PARENT, - TableLayout.LayoutParams.WRAP_CONTENT)); - - // Here create the TextView dynamically - TextView labelDATE = new TextView(DanaRStatsActivity.this); - labelDATE.setId(200 + i); - labelDATE.setText(df.format(new Date(record.recordDate))); - labelDATE.setTextColor(Color.WHITE); - tr.addView(labelDATE); - - TextView labelBASAL = new TextView(DanaRStatsActivity.this); - labelBASAL.setId(300 + i); - labelBASAL.setText(DecimalFormatter.to2Decimal(record.recordDailyBasal) + " U"); - labelBASAL.setTextColor(Color.WHITE); - tr.addView(labelBASAL); - - TextView labelBOLUS = new TextView(DanaRStatsActivity.this); - labelBOLUS.setId(400 + i); - labelBOLUS.setText(DecimalFormatter.to2Decimal(record.recordDailyBolus) + " U"); - labelBOLUS.setTextColor(Color.WHITE); - tr.addView(labelBOLUS); - - TextView labelTDD = new TextView(DanaRStatsActivity.this); - labelTDD.setId(500 + i); - labelTDD.setText(DecimalFormatter.to2Decimal(tdd) + " U"); - labelTDD.setTextColor(Color.WHITE); - tr.addView(labelTDD); - - TextView labelRATIO = new TextView(DanaRStatsActivity.this); - labelRATIO.setId(600 + i); - labelRATIO.setText(Math.round(100 * tdd / magicNumber) + " %"); - labelRATIO.setTextColor(Color.WHITE); - tr.addView(labelRATIO); - - // add stats rows to tables - tl.addView(tr, new TableLayout.LayoutParams( - TableLayout.LayoutParams.MATCH_PARENT, - TableLayout.LayoutParams.WRAP_CONTENT)); - - sum = sum + tdd; - i++; - - // Create the cumtable row - TableRow ctr = new TableRow(DanaRStatsActivity.this); - if (i % 2 == 0) ctr.setBackgroundColor(Color.DKGRAY); - ctr.setId(700 + i); - ctr.setLayoutParams(new TableLayout.LayoutParams( - TableLayout.LayoutParams.MATCH_PARENT, - TableLayout.LayoutParams.WRAP_CONTENT)); - - // Here create the TextView dynamically - TextView labelDAYS = new TextView(DanaRStatsActivity.this); - labelDAYS.setId(800 + i); - labelDAYS.setText("" + i); - labelDAYS.setTextColor(Color.WHITE); - ctr.addView(labelDAYS); - - TextView labelCUMTDD = new TextView(DanaRStatsActivity.this); - labelCUMTDD.setId(900 + i); - labelCUMTDD.setText(DecimalFormatter.to2Decimal(sum / i) + " U"); - labelCUMTDD.setTextColor(Color.WHITE); - ctr.addView(labelCUMTDD); - - TextView labelCUMRATIO = new TextView(DanaRStatsActivity.this); - labelCUMRATIO.setId(1000 + i); - labelCUMRATIO.setText(Math.round(100 * sum / i / magicNumber) + " %"); - labelCUMRATIO.setTextColor(Color.WHITE); - ctr.addView(labelCUMRATIO); - - // add cummulative rows to tables - ctl.addView(ctr, new TableLayout.LayoutParams( - TableLayout.LayoutParams.MATCH_PARENT, - TableLayout.LayoutParams.WRAP_CONTENT)); - } - - if (historyList.size() < 3 || !(df.format(new Date(historyList.get(0).recordDate)).equals(df.format(new Date(System.currentTimeMillis() - 1000 * 60 * 60 * 24))))) { - statsMessage.setVisibility(View.VISIBLE); - statsMessage.setText(getString(R.string.danar_stats_olddata_Message)); - - } else { - tl.setBackgroundColor(Color.TRANSPARENT); - } - - Collections.reverse(historyList); - - i = 0; - - for (DanaRHistoryRecord record : historyList) { - double tdd = record.recordDailyBolus + record.recordDailyBasal; - if (i == 0) { - weighted03 = tdd; - weighted05 = tdd; - weighted07 = tdd; - - } else { - weighted07 = (weighted07 * 0.3 + tdd * 0.7); - weighted05 = (weighted05 * 0.5 + tdd * 0.5); - weighted03 = (weighted03 * 0.7 + tdd * 0.3); - } - i++; - } - - // Create the exptable row - TableRow etr = new TableRow(DanaRStatsActivity.this); - if (i % 2 != 0) etr.setBackgroundColor(Color.DKGRAY); - etr.setId(1100 + i); - etr.setLayoutParams(new TableLayout.LayoutParams( - TableLayout.LayoutParams.MATCH_PARENT, - TableLayout.LayoutParams.WRAP_CONTENT)); - - // Here create the TextView dynamically - TextView labelWEIGHT = new TextView(DanaRStatsActivity.this); - labelWEIGHT.setId(1200 + i); - labelWEIGHT.setText("0.3\n" + "0.5\n" + "0.7"); - labelWEIGHT.setTextColor(Color.WHITE); - etr.addView(labelWEIGHT); - - TextView labelEXPTDD = new TextView(DanaRStatsActivity.this); - labelEXPTDD.setId(1300 + i); - labelEXPTDD.setText(DecimalFormatter.to2Decimal(weighted03) - + " U\n" + DecimalFormatter.to2Decimal(weighted05) - + " U\n" + DecimalFormatter.to2Decimal(weighted07) + " U"); - labelEXPTDD.setTextColor(Color.WHITE); - etr.addView(labelEXPTDD); - - TextView labelEXPRATIO = new TextView(DanaRStatsActivity.this); - labelEXPRATIO.setId(1400 + i); - labelEXPRATIO.setText(Math.round(100 * weighted03 / magicNumber) + " %\n" - + Math.round(100 * weighted05 / magicNumber) + " %\n" - + Math.round(100 * weighted07 / magicNumber) + " %"); - labelEXPRATIO.setTextColor(Color.WHITE); - etr.addView(labelEXPRATIO); - - // add exponentail rows to tables - etl.addView(etr, new TableLayout.LayoutParams( - TableLayout.LayoutParams.MATCH_PARENT, - TableLayout.LayoutParams.WRAP_CONTENT)); - } - }); - } - - private void cleanTable(TableLayout table) { - int childCount = table.getChildCount(); - // Remove all rows except the first one - if (childCount > 1) { - table.removeViews(1, childCount - 1); - } - } - - @Subscribe - public void onStatusEvent(final EventDanaRSyncStatus s) { - log.debug("EventDanaRSyncStatus: " + s.message); - runOnUiThread( - new Runnable() { - @Override - public void run() { - statusView.setText(s.message); - } - }); - } - - @Subscribe - public void onStatusEvent(final EventPumpStatusChanged c) { - runOnUiThread( - new Runnable() { - @Override - public void run() { - statusView.setText(c.textStatus()); - } - } - ); - } -} \ No newline at end of file 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 801cfb80cc..d7b37a4b0f 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 @@ -6,7 +6,7 @@ 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.events.EventRefreshOverview; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPlugin; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; @@ -57,7 +57,7 @@ public class MsgCheckValue_v2 extends MessageBase { } MainApp.getConfigBuilder().storeSettings(); - MainApp.bus().post(new EventRefreshGui(false)); + MainApp.bus().post(new EventRefreshOverview("MsgCheckValue_v2")); return; } if (Config.logDanaMessageDetail) { 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 fa3cff5c39..5c1b20a9ea 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 @@ -11,6 +11,7 @@ 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.plugins.ConfigBuilder.DetailedBolusInfoStorage; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase; @@ -62,7 +63,15 @@ public class MsgHistoryEvents_v2 extends MessageBase { extendedBolus.source = Source.PUMP; extendedBolus.pumpId = datetime.getTime(); - DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo(); + DetailedBolusInfo detailedBolusInfo = DetailedBolusInfoStorage.findDetailedBolusInfo(datetime.getTime()); + if (detailedBolusInfo == null) { + log.debug("DetailedBolusInfo not found for " + datetime.toLocaleString()); + detailedBolusInfo = new DetailedBolusInfo(); + } else { + log.debug("DetailedBolusInfo found for " + datetime.toLocaleString() + ": " + new Date(detailedBolusInfo.date).toLocaleString()); + detailedBolusInfo.carbTime = 0; + detailedBolusInfo.carbs = 0; + } detailedBolusInfo.date = datetime.getTime(); detailedBolusInfo.source = Source.PUMP; detailedBolusInfo.pumpId = datetime.getTime(); @@ -122,7 +131,7 @@ public class MsgHistoryEvents_v2 extends MessageBase { log.debug("EVENT PRIME (" + recordCode + ") " + datetime.toLocaleString() + " Amount: " + param1 / 100d + "U"); break; case DanaRPump.PROFILECHANGE: - log.debug("EVENT PROFILECHANGE (" + recordCode + ") " + datetime.toLocaleString() + " No: " + param1 + "U CurrentRate: " + param2 + "U/h"); + log.debug("EVENT PROFILECHANGE (" + recordCode + ") " + datetime.toLocaleString() + " No: " + param1 + " CurrentRate: " + (param2 / 100d) + "U/h"); break; case DanaRPump.CARBS: log.debug("EVENT CARBS (" + recordCode + ") " + datetime.toLocaleString() + " Carbs: " + param1 + "g"); 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 5f4ccf960f..f695f6a792 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 @@ -59,7 +59,7 @@ public class MsgStatusBolusExtended_v2 extends MessageBase { @NonNull private Date getDateFromSecAgo(int tempBasalAgoSecs) { - return new Date((long) (Math.ceil(new Date().getTime() / 1000d) - tempBasalAgoSecs) * 1000); + return new Date((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 5cc8068f4d..256fa4cd8a 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 @@ -53,7 +53,7 @@ public class MsgStatusTempBasal_v2 extends MessageBase { @NonNull private Date getDateFromTempBasalSecAgo(int tempBasalAgoSecs) { - return new Date((long) (Math.ceil(new Date().getTime() / 1000d) - tempBasalAgoSecs) * 1000); + return new Date((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 57e3607504..6527eeebaf 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 @@ -171,9 +171,9 @@ public class DanaRv2ExecutionService extends Service { getBTSocketForSelectedPump(); if (mRfcommSocket == null || mBTDevice == null) return; // Device not found - long startTime = new Date().getTime(); - while (!isConnected() && startTime + maxConnectionTime >= new Date().getTime()) { - long secondsElapsed = (new Date().getTime() - startTime) / 1000L; + long startTime = System.currentTimeMillis(); + while (!isConnected() && startTime + maxConnectionTime >= System.currentTimeMillis()) { + long secondsElapsed = (System.currentTimeMillis() - startTime) / 1000L; MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.CONNECTING, (int) secondsElapsed)); if (Config.logDanaBTComm) log.debug("connect waiting " + secondsElapsed + "sec from: " + from); @@ -200,7 +200,7 @@ public class DanaRv2ExecutionService extends Service { if (!MainApp.getSpecificPlugin(DanaRv2Plugin.class).isEnabled(PluginBase.PUMP)) return; getBTSocketForSelectedPump(); - startTime = new Date().getTime(); + startTime = System.currentTimeMillis(); } } } @@ -415,7 +415,7 @@ public class DanaRv2ExecutionService extends Service { } while (!stop.stopped && !start.failed) { waitMsec(100); - if ((new Date().getTime() - progress.lastReceive) > 5 * 1000L) { // if i didn't receive status for more than 5 sec expecting broken comm + if ((System.currentTimeMillis() - progress.lastReceive) > 5 * 1000L) { // if i didn't receive status for more than 5 sec expecting broken comm stop.stopped = true; stop.forced = true; log.debug("Communication stopped"); @@ -502,6 +502,7 @@ public class DanaRv2ExecutionService extends Service { public boolean loadEvents() { if (!isConnected()) return false; + waitMsec(300); MsgHistoryEvents_v2 msg; if (lastHistoryFetched == 0) { msg = new MsgHistoryEvents_v2(); @@ -537,7 +538,7 @@ public class DanaRv2ExecutionService extends Service { private double[] buildDanaRProfileRecord(Profile nsProfile) { double[] record = new double[24]; for (Integer hour = 0; hour < 24; hour++) { - double value = Math.round(100d * nsProfile.getBasal(hour * 60 * 60))/100d + 0.00001; + double value = Math.round(100d * nsProfile.getBasal((Integer) (hour * 60 * 60)))/100d + 0.00001; if (Config.logDanaMessageDetail) log.debug("NS basal value for " + hour + ":00 is " + value); record[hour] = value; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMDI/MDIFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMDI/MDIFragment.java deleted file mode 100644 index f6221d627e..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMDI/MDIFragment.java +++ /dev/null @@ -1,12 +0,0 @@ -package info.nightscout.androidaps.plugins.PumpMDI; - - -import android.support.v4.app.Fragment; - -public class MDIFragment extends Fragment { - private static MDIPlugin mdiPlugin = new MDIPlugin(); - - public static MDIPlugin getPlugin() { - return mdiPlugin; - } -} 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 b0c55ba036..ddd05a2e0b 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 @@ -12,11 +12,11 @@ import info.nightscout.androidaps.Config; 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.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PumpDescription; import info.nightscout.androidaps.interfaces.PumpInterface; -import info.nightscout.androidaps.data.Profile; import info.nightscout.utils.DateUtil; /** @@ -30,6 +30,14 @@ public class MDIPlugin implements PluginBase, PumpInterface { PumpDescription pumpDescription = new PumpDescription(); + static MDIPlugin plugin = null; + + public static MDIPlugin getPlugin() { + if (plugin == null) + plugin = new MDIPlugin(); + return plugin; + } + public MDIPlugin() { pumpDescription.isBolusCapable = true; pumpDescription.bolusStep = 0.5d; @@ -42,7 +50,7 @@ public class MDIPlugin implements PluginBase, PumpInterface { @Override public String getFragmentClass() { - return MDIFragment.class.getName(); + return null; } @Override @@ -188,7 +196,7 @@ public class MDIPlugin implements PluginBase, PumpInterface { } @Override - public PumpEnactResult cancelTempBasal() { + public PumpEnactResult cancelTempBasal(boolean userRequested) { PumpEnactResult result = new PumpEnactResult(); result.success = false; result.comment = MainApp.instance().getString(R.string.pumperror); 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 c2a0b6780b..b479183b80 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 @@ -5,7 +5,6 @@ import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.support.annotation.Nullable; -import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -16,13 +15,12 @@ import com.squareup.otto.Subscribe; 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.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.PumpVirtual.events.EventVirtualPumpUpdateGui; -public class VirtualPumpFragment extends Fragment { +public class VirtualPumpFragment extends SubscriberFragment { private static Logger log = LoggerFactory.getLogger(VirtualPumpFragment.class); TextView basaBasalRateView; @@ -59,47 +57,35 @@ public class VirtualPumpFragment extends Fragment { batteryView = (TextView) view.findViewById(R.id.virtualpump_battery); reservoirView = (TextView) view.findViewById(R.id.virtualpump_reservoir); - updateGUI(); return view; } - @Override - public void onPause() { - super.onPause(); - MainApp.bus().unregister(this); - } - - @Override - public void onResume() { - super.onResume(); - MainApp.bus().register(this); - } - @Subscribe public void onStatusEvent(final EventVirtualPumpUpdateGui ev) { updateGUI(); } - public void updateGUI() { + @Override + protected void updateGUI() { Activity activity = getActivity(); if (activity != null && basaBasalRateView != null) activity.runOnUiThread(new Runnable() { @Override public void run() { - - basaBasalRateView.setText(VirtualPumpPlugin.getInstance().getBaseBasalRate() + "U"); + VirtualPumpPlugin virtualPump = VirtualPumpPlugin.getInstance(); + basaBasalRateView.setText(virtualPump.getBaseBasalRate() + "U"); if (MainApp.getConfigBuilder().isTempBasalInProgress()) { - tempBasalView.setText(MainApp.getConfigBuilder().getTempBasalFromHistory(new Date().getTime()).toStringFull()); + tempBasalView.setText(MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis()).toStringFull()); } else { tempBasalView.setText(""); } if (MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) { - extendedBolusView.setText(MainApp.getConfigBuilder().getExtendedBolusFromHistory(new Date().getTime()).toString()); + extendedBolusView.setText(MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()).toString()); } else { extendedBolusView.setText(""); } - batteryView.setText(VirtualPumpPlugin.getInstance().batteryPercent + "%"); - reservoirView.setText(VirtualPumpPlugin.getInstance().reservoirInUnits + "U"); + batteryView.setText(virtualPump.batteryPercent + "%"); + reservoirView.setText(virtualPump.reservoirInUnits + "U"); } }); } 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 39dfcf7873..7337859c47 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 @@ -28,6 +28,7 @@ import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProg import info.nightscout.androidaps.plugins.PumpVirtual.events.EventVirtualPumpUpdateGui; import info.nightscout.utils.DateUtil; import info.nightscout.utils.NSUpload; +import info.nightscout.utils.SP; /** * Created by mike on 05.08.2016. @@ -45,10 +46,26 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface { boolean fragmentEnabled = true; boolean fragmentVisible = true; + private static boolean fromNSAreCommingFakedExtendedBoluses = false; + PumpDescription pumpDescription = new PumpDescription(); + static void loadFakingStatus() { + fromNSAreCommingFakedExtendedBoluses = SP.getBoolean("fromNSAreCommingFakedExtendedBoluses", false); + } + + public static void setFakingStatus(boolean newStatus) { + fromNSAreCommingFakedExtendedBoluses = newStatus; + SP.putBoolean("fromNSAreCommingFakedExtendedBoluses", fromNSAreCommingFakedExtendedBoluses); + } + + public static boolean getFakingStatus() { + return fromNSAreCommingFakedExtendedBoluses; + } + static VirtualPumpPlugin instance = null; public static VirtualPumpPlugin getInstance() { + loadFakingStatus(); if (instance == null) instance = new VirtualPumpPlugin(); return instance; @@ -143,7 +160,7 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface { @Override public boolean isFakingTempsByExtendedBoluses() { - return false; + return Config.NSCLIENT && fromNSAreCommingFakedExtendedBoluses; } @Override @@ -180,13 +197,18 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface { @Override public void refreshDataFromPump(String reason) { - NSUpload.uploadDeviceStatus(); + if (!BuildConfig.NSCLIENTOLNY) + NSUpload.uploadDeviceStatus(); lastDataTime = new Date(); } @Override public double getBaseBasalRate() { - return MainApp.getConfigBuilder().getProfile().getBasal(); + Profile profile = MainApp.getConfigBuilder().getProfile(); + if (profile != null) + return profile.getBasal(); + else + return 0d; } @Override @@ -239,7 +261,7 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface { public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes) { TreatmentsInterface treatmentsInterface = MainApp.getConfigBuilder(); TemporaryBasal tempBasal = new TemporaryBasal(); - tempBasal.date = new Date().getTime(); + tempBasal.date = System.currentTimeMillis(); tempBasal.isAbsolute = true; tempBasal.absoluteRate = absoluteRate; tempBasal.durationInMinutes = durationInMinutes; @@ -264,12 +286,12 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface { TreatmentsInterface treatmentsInterface = MainApp.getConfigBuilder(); PumpEnactResult result = new PumpEnactResult(); if (MainApp.getConfigBuilder().isTempBasalInProgress()) { - result = cancelTempBasal(); + result = cancelTempBasal(false); if (!result.success) return result; } TemporaryBasal tempBasal = new TemporaryBasal(); - tempBasal.date = new Date().getTime(); + tempBasal.date = System.currentTimeMillis(); tempBasal.isAbsolute = false; tempBasal.percentRate = percent; tempBasal.durationInMinutes = durationInMinutes; @@ -296,7 +318,7 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface { if (!result.success) return result; ExtendedBolus extendedBolus = new ExtendedBolus(); - extendedBolus.date = new Date().getTime(); + extendedBolus.date = System.currentTimeMillis(); extendedBolus.insulin = insulin; extendedBolus.durationInMinutes = durationInMinutes; extendedBolus.source = Source.USER; @@ -315,7 +337,7 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface { } @Override - public PumpEnactResult cancelTempBasal() { + public PumpEnactResult cancelTempBasal(boolean userRequested) { TreatmentsInterface treatmentsInterface = MainApp.getConfigBuilder(); PumpEnactResult result = new PumpEnactResult(); result.success = true; @@ -323,7 +345,7 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface { result.comment = MainApp.instance().getString(R.string.virtualpump_resultok); if (treatmentsInterface.isTempBasalInProgress()) { result.enacted = true; - TemporaryBasal tempStop = new TemporaryBasal(new Date().getTime()); + TemporaryBasal tempStop = new TemporaryBasal(System.currentTimeMillis()); tempStop.source = Source.USER; treatmentsInterface.addToHistoryTempBasal(tempStop); //tempBasal = null; @@ -340,7 +362,7 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface { TreatmentsInterface treatmentsInterface = MainApp.getConfigBuilder(); PumpEnactResult result = new PumpEnactResult(); if (treatmentsInterface.isInHistoryExtendedBoluslInProgress()) { - ExtendedBolus exStop = new ExtendedBolus(new Date().getTime()); + ExtendedBolus exStop = new ExtendedBolus(System.currentTimeMillis()); exStop.source = Source.USER; treatmentsInterface.addToHistoryExtendedBolus(exStop); } @@ -373,13 +395,13 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface { extended.put("ActiveProfile", MainApp.getConfigBuilder().getProfileName()); } catch (Exception e) { } - TemporaryBasal tb = MainApp.getConfigBuilder().getTempBasalFromHistory(new Date().getTime()); + TemporaryBasal tb = MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis()); if (tb != null) { - extended.put("TempBasalAbsoluteRate", tb.tempBasalConvertedToAbsolute(new Date().getTime())); + extended.put("TempBasalAbsoluteRate", tb.tempBasalConvertedToAbsolute(System.currentTimeMillis())); extended.put("TempBasalStart", DateUtil.dateAndTimeString(tb.date)); extended.put("TempBasalRemaining", tb.getPlannedRemainingMinutes()); } - ExtendedBolus eb = MainApp.getConfigBuilder().getExtendedBolusFromHistory(new Date().getTime()); + ExtendedBolus eb = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()); if (eb != null) { extended.put("ExtendedBolusAbsoluteRate", eb.absoluteRate()); extended.put("ExtendedBolusStart", DateUtil.dateAndTimeString(eb.date)); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/SensitivityAAPS/SensitivityAAPSPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/SensitivityAAPS/SensitivityAAPSPlugin.java new file mode 100644 index 0000000000..9f0dc9a21f --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/SensitivityAAPS/SensitivityAAPSPlugin.java @@ -0,0 +1,200 @@ +package info.nightscout.androidaps.plugins.SensitivityAAPS; + +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.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.data.Profile; +import info.nightscout.androidaps.interfaces.PluginBase; +import info.nightscout.androidaps.interfaces.SensitivityInterface; +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; + +/** + * Created by mike on 24.06.2017. + */ + +public class SensitivityAAPSPlugin implements PluginBase, SensitivityInterface{ + private static Logger log = LoggerFactory.getLogger(SensitivityAAPSPlugin.class); + + private static boolean fragmentEnabled = true; + private static boolean fragmentVisible = false; + + static SensitivityAAPSPlugin plugin = null; + + public static SensitivityAAPSPlugin getPlugin() { + if (plugin == null) + plugin = new SensitivityAAPSPlugin(); + return plugin; + } + + @Override + public int getType() { + return SENSITIVITY; + } + + @Override + public String getFragmentClass() { + return null; + } + + @Override + public String getName() { + return MainApp.sResources.getString(R.string.sensitivityaaps); + } + + @Override + public String getNameShort() { + return MainApp.sResources.getString(R.string.sensitivity_shortname); + } + + @Override + public boolean isEnabled(int type) { + return type == SENSITIVITY && fragmentEnabled; + } + + @Override + public boolean isVisibleInTabs(int type) { + return type == SENSITIVITY && fragmentVisible; + } + + @Override + public boolean canBeHidden(int type) { + return true; + } + + @Override + public boolean hasFragment() { + return false; + } + + @Override + public boolean showInList(int type) { + return true; + } + + @Override + public void setFragmentEnabled(int type, boolean fragmentEnabled) { + if (type == SENSITIVITY) this.fragmentEnabled = fragmentEnabled; + } + + @Override + public void setFragmentVisible(int type, boolean fragmentVisible) { + if (type == SENSITIVITY) this.fragmentVisible = fragmentVisible; + } + + + @Override + public AutosensResult detectSensitivity(long fromTime, long toTime) { + LongSparseArray autosensDataTable = IobCobCalculatorPlugin.getAutosensDataTable(); + + String age = SP.getString(R.string.key_age, ""); + int defaultHours = 24; + if (age.equals(MainApp.sResources.getString(R.string.key_adult))) defaultHours = 24; + if (age.equals(MainApp.sResources.getString(R.string.key_teenage))) defaultHours = 4; + if (age.equals(MainApp.sResources.getString(R.string.key_child))) defaultHours = 4; + int hoursForDetection = SP.getInt(R.string.key_openapsama_autosens_period, defaultHours); + + if (autosensDataTable == null || autosensDataTable.size() < 4) { + log.debug("No autosens data available"); + return new AutosensResult(); + } + + AutosensData current = IobCobCalculatorPlugin.getAutosensData(toTime); + if (current == null) { + log.debug("No autosens data available"); + return new AutosensResult(); + } + + + 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; + } + + if (autosensData.time > toTime - hoursForDetection * 60 * 60 * 1000L) + deviationsArray.add(autosensData.nonEqualDeviation ? autosensData.deviation : 0d); + if (deviationsArray.size() > hoursForDetection * 60 / 5) + 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++; + } + + Double[] deviations = new Double[deviationsArray.size()]; + deviations = deviationsArray.toArray(deviations); + + Profile profile = MainApp.getConfigBuilder().getProfile(); + + double sens = profile.getIsf(); + + String ratioLimit = ""; + String sensResult = ""; + + log.debug("Records: " + index + " " + pastSensitivity); + Arrays.sort(deviations); + + double percentile = IobCobCalculatorPlugin.percentile(deviations, 0.50); + double basalOff = percentile * (60 / 5) / Profile.toMgdl(sens, profile.getUnits()); + double ratio = 1 + (basalOff / profile.getMaxDailyBasal()); + + if (percentile < 0) { // sensitive + sensResult = "Excess insulin sensitivity detected"; + } else if (percentile > 0) { // resistant + sensResult = "Excess insulin resistance detected"; + } else { + sensResult = "Sensitivity normal"; + } + + log.debug(sensResult); + + double rawRatio = ratio; + ratio = Math.max(ratio, SafeParse.stringToDouble(SP.getString("openapsama_autosens_min", "0.7"))); + ratio = Math.min(ratio, SafeParse.stringToDouble(SP.getString("openapsama_autosens_max", "1.2"))); + + if (ratio != rawRatio) { + ratioLimit = "Ratio limited from " + rawRatio + " to " + ratio; + log.debug(ratioLimit); + } + + log.debug("Sensitivity to: " + new Date(toTime).toLocaleString() + " percentile: " + percentile + " ratio: " + ratio); + 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/SensitivityOref0/SensitivityOref0Plugin.java new file mode 100644 index 0000000000..4face65ced --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/SensitivityOref0/SensitivityOref0Plugin.java @@ -0,0 +1,210 @@ +package info.nightscout.androidaps.plugins.SensitivityOref0; + +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.List; + +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.interfaces.SensitivityInterface; +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; + +/** + * Created by mike on 24.06.2017. + */ + +public class SensitivityOref0Plugin implements PluginBase, SensitivityInterface { + private static Logger log = LoggerFactory.getLogger(IobCobCalculatorPlugin.class); + + private static boolean fragmentEnabled = true; + private static boolean fragmentVisible = false; + + static SensitivityOref0Plugin plugin = null; + + public static SensitivityOref0Plugin getPlugin() { + if (plugin == null) + plugin = new SensitivityOref0Plugin(); + return plugin; + } + + @Override + public int getType() { + return SENSITIVITY; + } + + @Override + public String getFragmentClass() { + return null; + } + + @Override + public String getName() { + return MainApp.sResources.getString(R.string.sensitivityoref0); + } + + @Override + public String getNameShort() { + return MainApp.sResources.getString(R.string.sensitivity_shortname); + } + + @Override + public boolean isEnabled(int type) { + return type == SENSITIVITY && fragmentEnabled; + } + + @Override + public boolean isVisibleInTabs(int type) { + return type == SENSITIVITY && fragmentVisible; + } + + @Override + public boolean canBeHidden(int type) { + return true; + } + + @Override + public boolean hasFragment() { + return false; + } + + @Override + public boolean showInList(int type) { + return true; + } + + @Override + public void setFragmentEnabled(int type, boolean fragmentEnabled) { + if (type == SENSITIVITY) this.fragmentEnabled = fragmentEnabled; + } + + @Override + public void setFragmentVisible(int type, boolean fragmentVisible) { + if (type == SENSITIVITY) this.fragmentVisible = fragmentVisible; + } + + + @Override + public AutosensResult detectSensitivity(long fromTime, long toTime) { + LongSparseArray autosensDataTable = IobCobCalculatorPlugin.getAutosensDataTable(); + + String age = SP.getString(R.string.key_age, ""); + int defaultHours = 24; + if (age.equals(MainApp.sResources.getString(R.string.key_adult))) defaultHours = 24; + if (age.equals(MainApp.sResources.getString(R.string.key_teenage))) defaultHours = 24; + if (age.equals(MainApp.sResources.getString(R.string.key_child))) defaultHours = 24; + int hoursForDetection = SP.getInt(R.string.key_openapsama_autosens_period, defaultHours); + + long now = System.currentTimeMillis(); + + if (autosensDataTable == null || autosensDataTable.size() < 4) { + log.debug("No autosens data available"); + return new AutosensResult(); + } + + AutosensData current = IobCobCalculatorPlugin.getLastAutosensData(); + if (current == null) { + log.debug("No current autosens data available"); + return new AutosensResult(); + } + + + 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; + } + + if (autosensData.time > toTime - hoursForDetection * 60 * 60 * 1000L) + deviationsArray.add(autosensData.nonEqualDeviation ? autosensData.deviation : 0d); + if (deviationsArray.size() > hoursForDetection * 60 / 5) + 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++; + } + + Double[] deviations = new Double[deviationsArray.size()]; + deviations = deviationsArray.toArray(deviations); + + Profile profile = MainApp.getConfigBuilder().getProfile(); + + double sens = profile.getIsf(); + + double ratio = 1; + String ratioLimit = ""; + String sensResult = ""; + + 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) { + log.debug(Math.round(100 * i) + "% of non-meal deviations negative (target 45%-50%)"); + } + } + double pSensitive = IobCobCalculatorPlugin.percentile(deviations, 0.50); + double pResistant = IobCobCalculatorPlugin.percentile(deviations, 0.45); + + 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"; + } + log.debug(sensResult); + ratio = 1 + (basalOff / profile.getMaxDailyBasal()); + + double rawRatio = ratio; + ratio = Math.max(ratio, SafeParse.stringToDouble(SP.getString("openapsama_autosens_min", "0.7"))); + ratio = Math.min(ratio, SafeParse.stringToDouble(SP.getString("openapsama_autosens_max", "1.2"))); + + if (ratio != rawRatio) { + ratioLimit = "Ratio limited from " + rawRatio + " to " + ratio; + log.debug(ratioLimit); + } + + double newisf = Math.round(Profile.toMgdl(sens, profile.getUnits()) / ratio); + if (ratio != 1) { + log.debug("ISF adjusted from " + Profile.toMgdl(sens, profile.getUnits()) + " to " + newisf); + } + + 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/SensitivityWeightedAverage/SensitivityWeightedAveragePlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/SensitivityWeightedAverage/SensitivityWeightedAveragePlugin.java new file mode 100644 index 0000000000..b957e21bda --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/SensitivityWeightedAverage/SensitivityWeightedAveragePlugin.java @@ -0,0 +1,217 @@ +package info.nightscout.androidaps.plugins.SensitivityWeightedAverage; + +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.interfaces.PluginBase; +import info.nightscout.androidaps.interfaces.SensitivityInterface; +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; + +/** + * Created by mike on 24.06.2017. + */ + +public class SensitivityWeightedAveragePlugin implements PluginBase, SensitivityInterface { + private static Logger log = LoggerFactory.getLogger(SensitivityWeightedAveragePlugin.class); + + private static boolean fragmentEnabled = true; + private static boolean fragmentVisible = false; + + static SensitivityWeightedAveragePlugin plugin = null; + + public static SensitivityWeightedAveragePlugin getPlugin() { + if (plugin == null) + plugin = new SensitivityWeightedAveragePlugin(); + return plugin; + } + + @Override + public int getType() { + return SENSITIVITY; + } + + @Override + public String getFragmentClass() { + return null; + } + + @Override + public String getName() { + return MainApp.sResources.getString(R.string.sensitivityweightedaverage); + } + + @Override + public String getNameShort() { + return MainApp.sResources.getString(R.string.sensitivity_shortname); + } + + @Override + public boolean isEnabled(int type) { + return type == SENSITIVITY && fragmentEnabled; + } + + @Override + public boolean isVisibleInTabs(int type) { + return type == SENSITIVITY && fragmentVisible; + } + + @Override + public boolean canBeHidden(int type) { + return true; + } + + @Override + public boolean hasFragment() { + return false; + } + + @Override + public boolean showInList(int type) { + return true; + } + + @Override + public void setFragmentEnabled(int type, boolean fragmentEnabled) { + if (type == SENSITIVITY) this.fragmentEnabled = fragmentEnabled; + } + + @Override + public void setFragmentVisible(int type, boolean fragmentVisible) { + if (type == SENSITIVITY) this.fragmentVisible = fragmentVisible; + } + + + @Override + public AutosensResult detectSensitivity(long fromTime, long toTime) { + LongSparseArray autosensDataTable = IobCobCalculatorPlugin.getAutosensDataTable(); + + String age = SP.getString(R.string.key_age, ""); + int defaultHours = 24; + if (age.equals(MainApp.sResources.getString(R.string.key_adult))) defaultHours = 24; + if (age.equals(MainApp.sResources.getString(R.string.key_teenage))) defaultHours = 4; + if (age.equals(MainApp.sResources.getString(R.string.key_child))) defaultHours = 4; + int hoursForDetection = SP.getInt(R.string.key_openapsama_autosens_period, defaultHours); + + if (autosensDataTable == null || autosensDataTable.size() < 4) { + log.debug("No autosens data available"); + return new AutosensResult(); + } + + AutosensData current = IobCobCalculatorPlugin.getAutosensData(toTime); + if (current == null) { + log.debug("No autosens data available"); + return new AutosensResult(); + } + + + String pastSensitivity = ""; + int index = 0; + LongSparseArray data = new LongSparseArray<>(); + + while (index < autosensDataTable.size()) { + AutosensData autosensData = autosensDataTable.valueAt(index); + + if (autosensData.time < fromTime) { + index++; + continue; + } + + if (autosensData.time > toTime) { + index++; + continue; + } + + if (autosensData.time < toTime - hoursForDetection * 60 * 60 * 1000L) { + index++; + continue; + } + + //data.append(autosensData.time); + long reverseWeight = (toTime - autosensData.time) / (5 * 60 * 1000L); + data.append(reverseWeight, autosensData.nonEqualDeviation ? autosensData.deviation : 0d); + //weights += reverseWeight; + //weightedsum += reverseWeight * (autosensData.nonEqualDeviation ? autosensData.deviation : 0d); + + + 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++; + } + + if (data.size() == 0) { + return new AutosensResult(); + } + + double weightedsum = 0; + double weights = 0; + + long hightestWeight = data.keyAt(data.size() - 1); + for (int i = 0; i < data.size(); i++) { + long reversedWeigth = data.keyAt(i); + double value = data.valueAt(i); + double weight = (hightestWeight - reversedWeigth) / 2; + weights += weight; + weightedsum += weight * value; + } + + Profile profile = MainApp.getConfigBuilder().getProfile(); + + double sens = profile.getIsf(); + + String ratioLimit = ""; + String sensResult = ""; + + log.debug("Records: " + index + " " + pastSensitivity); + + double average = weightedsum / weights; + double basalOff = average * (60 / 5) / Profile.toMgdl(sens, profile.getUnits()); + double ratio = 1 + (basalOff / profile.getMaxDailyBasal()); + + if (average < 0) { // sensitive + sensResult = "Excess insulin sensitivity detected"; + } else if (average > 0) { // resistant + sensResult = "Excess insulin resistance detected"; + } else { + sensResult = "Sensitivity normal"; + } + + log.debug(sensResult); + + double rawRatio = ratio; + ratio = Math.max(ratio, SafeParse.stringToDouble(SP.getString("openapsama_autosens_min", "0.7"))); + ratio = Math.min(ratio, SafeParse.stringToDouble(SP.getString("openapsama_autosens_max", "1.2"))); + + if (ratio != rawRatio) { + ratioLimit = "Ratio limited from " + rawRatio + " to " + ratio; + log.debug(ratioLimit); + } + + log.debug("Sensitivity to: " + new Date(toTime).toLocaleString() + " weightedaverage: " + average + " ratio: " + ratio); + + 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 83973e83ff..09a635bf86 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 @@ -20,13 +20,14 @@ import java.util.Comparator; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.SmsCommunicator.events.EventSmsCommunicatorUpdateGui; import info.nightscout.utils.DateUtil; /** * A simple {@link Fragment} subclass. */ -public class SmsCommunicatorFragment extends Fragment { +public class SmsCommunicatorFragment extends SubscriberFragment { private static Logger log = LoggerFactory.getLogger(SmsCommunicatorFragment.class); private static SmsCommunicatorPlugin smsCommunicatorPlugin; @@ -56,25 +57,14 @@ public class SmsCommunicatorFragment extends Fragment { return view; } - @Override - public void onPause() { - super.onPause(); - MainApp.bus().unregister(this); - } - - @Override - public void onResume() { - super.onResume(); - MainApp.bus().register(this); - } - @Subscribe public void onStatusEvent(final EventSmsCommunicatorUpdateGui ev) { updateGUI(); } - private void updateGUI() { + @Override + protected void updateGUI() { Activity activity = getActivity(); if (activity != null) activity.runOnUiThread(new Runnable() { 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 4e81aa49d9..8e5e3bde46 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 @@ -24,21 +24,21 @@ import info.nightscout.androidaps.Services.Intents; import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.data.GlucoseStatus; import info.nightscout.androidaps.data.IobTotal; +import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.db.BgReading; import info.nightscout.androidaps.db.DatabaseHelper; import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.events.EventPreferenceChange; -import info.nightscout.androidaps.events.EventRefreshGui; +import info.nightscout.androidaps.events.EventRefreshOverview; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; -import info.nightscout.androidaps.data.Profile; -import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPlugin; -import info.nightscout.androidaps.plugins.PumpDanaRKorean.DanaRKoreanPlugin; import info.nightscout.androidaps.plugins.Loop.LoopPlugin; import info.nightscout.androidaps.plugins.Overview.Notification; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; +import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPlugin; +import info.nightscout.androidaps.plugins.PumpDanaRKorean.DanaRKoreanPlugin; import info.nightscout.androidaps.plugins.SmsCommunicator.events.EventNewSMS; import info.nightscout.androidaps.plugins.SmsCommunicator.events.EventSmsCommunicatorUpdateGui; import info.nightscout.utils.DecimalFormatter; @@ -238,13 +238,12 @@ public class SmsCommunicatorPlugin implements PluginBase { BgReading actualBG = DatabaseHelper.actualBg(); BgReading lastBG = DatabaseHelper.lastBg(); - Profile profile = MainApp.getConfigBuilder().getProfile(); - String units = profile.getUnits(); + String units = MainApp.getConfigBuilder().getProfileUnits(); if (actualBG != null) { reply = MainApp.sResources.getString(R.string.sms_actualbg) + " " + actualBG.valueToUnitsToString(units) + ", "; } else if (lastBG != null) { - Long agoMsec = new Date().getTime() - lastBG.date; + Long agoMsec = System.currentTimeMillis() - lastBG.date; int agoMin = (int) (agoMsec / 60d / 1000d); reply = MainApp.sResources.getString(R.string.sms_lastbg) + " " + lastBG.valueToUnitsToString(units) + " " + String.format(MainApp.sResources.getString(R.string.sms_minago), agoMin) + ", "; } @@ -273,8 +272,8 @@ public class SmsCommunicatorPlugin implements PluginBase { LoopPlugin loopPlugin = (LoopPlugin) MainApp.getSpecificPlugin(LoopPlugin.class); if (loopPlugin != null && loopPlugin.isEnabled(PluginBase.LOOP)) { loopPlugin.setFragmentEnabled(PluginBase.LOOP, false); - PumpEnactResult result = MainApp.getConfigBuilder().cancelTempBasal(); - MainApp.bus().post(new EventRefreshGui(false)); + PumpEnactResult result = MainApp.getConfigBuilder().cancelTempBasal(true); + MainApp.bus().post(new EventRefreshOverview("SMS_LOOP_STOP")); reply = MainApp.sResources.getString(R.string.smscommunicator_loophasbeendisabled)+ " " + MainApp.sResources.getString(result.success?R.string.smscommunicator_tempbasalcanceled:R.string.smscommunicator_tempbasalcancelfailed); sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); @@ -289,6 +288,7 @@ public class SmsCommunicatorPlugin implements PluginBase { loopPlugin.setFragmentEnabled(PluginBase.LOOP, true); reply = MainApp.sResources.getString(R.string.smscommunicator_loophasbeenenabled); sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); + MainApp.bus().post(new EventRefreshOverview("SMS_LOOP_START")); } receivedSms.processed = true; Answers.getInstance().logCustom(new CustomEvent("SMS_Loop_Start")); @@ -312,7 +312,7 @@ public class SmsCommunicatorPlugin implements PluginBase { case "RESUME": final LoopPlugin activeloop = ConfigBuilderPlugin.getActiveLoop(); activeloop.suspendTo(0); - MainApp.bus().post(new EventRefreshGui(false)); + MainApp.bus().post(new EventRefreshOverview("SMS_LOOP_RESUME")); NSUpload.uploadOpenAPSOffline(0); reply = MainApp.sResources.getString(R.string.smscommunicator_loopresumed); sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply, new Date())); @@ -417,7 +417,7 @@ public class SmsCommunicatorPlugin implements PluginBase { } break; case "BOLUS": - if (new Date().getTime() - lastRemoteBolusTime.getTime() < Constants.remoteBolusMinDistance) { + if (System.currentTimeMillis() - lastRemoteBolusTime.getTime() < Constants.remoteBolusMinDistance) { reply = MainApp.sResources.getString(R.string.smscommunicator_remotebolusnotallowed); sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); } else if (MainApp.getConfigBuilder().isSuspended()) { @@ -459,7 +459,7 @@ public class SmsCommunicatorPlugin implements PluginBase { break; default: // expect passCode here if (bolusWaitingForConfirmation != null && !bolusWaitingForConfirmation.processed && - bolusWaitingForConfirmation.confirmCode.equals(splited[0]) && new Date().getTime() - bolusWaitingForConfirmation.date.getTime() < CONFIRM_TIMEOUT) { + bolusWaitingForConfirmation.confirmCode.equals(splited[0]) && System.currentTimeMillis() - bolusWaitingForConfirmation.date.getTime() < CONFIRM_TIMEOUT) { bolusWaitingForConfirmation.processed = true; PumpInterface pumpInterface = MainApp.getConfigBuilder(); if (pumpInterface != null) { @@ -482,7 +482,7 @@ public class SmsCommunicatorPlugin implements PluginBase { } } } else if (tempBasalWaitingForConfirmation != null && !tempBasalWaitingForConfirmation.processed && - tempBasalWaitingForConfirmation.confirmCode.equals(splited[0]) && new Date().getTime() - tempBasalWaitingForConfirmation.date.getTime() < CONFIRM_TIMEOUT) { + tempBasalWaitingForConfirmation.confirmCode.equals(splited[0]) && System.currentTimeMillis() - tempBasalWaitingForConfirmation.date.getTime() < CONFIRM_TIMEOUT) { tempBasalWaitingForConfirmation.processed = true; PumpInterface pumpInterface = MainApp.getConfigBuilder(); if (pumpInterface != null) { @@ -501,12 +501,12 @@ public class SmsCommunicatorPlugin implements PluginBase { } } } else if (cancelTempBasalWaitingForConfirmation != null && !cancelTempBasalWaitingForConfirmation.processed && - cancelTempBasalWaitingForConfirmation.confirmCode.equals(splited[0]) && new Date().getTime() - cancelTempBasalWaitingForConfirmation.date.getTime() < CONFIRM_TIMEOUT) { + cancelTempBasalWaitingForConfirmation.confirmCode.equals(splited[0]) && System.currentTimeMillis() - cancelTempBasalWaitingForConfirmation.date.getTime() < CONFIRM_TIMEOUT) { cancelTempBasalWaitingForConfirmation.processed = true; PumpInterface pumpInterface = MainApp.getConfigBuilder(); if (pumpInterface != null) { danaRPlugin = (DanaRPlugin) MainApp.getSpecificPlugin(DanaRPlugin.class); - PumpEnactResult result = pumpInterface.cancelTempBasal(); + PumpEnactResult result = pumpInterface.cancelTempBasal(true); if (result.success) { reply = MainApp.sResources.getString(R.string.smscommunicator_tempbasalcanceled); if (danaRPlugin != null) @@ -520,7 +520,7 @@ public class SmsCommunicatorPlugin implements PluginBase { } } } else if (calibrationWaitingForConfirmation != null && !calibrationWaitingForConfirmation.processed && - calibrationWaitingForConfirmation.confirmCode.equals(splited[0]) && new Date().getTime() - calibrationWaitingForConfirmation.date.getTime() < CONFIRM_TIMEOUT) { + calibrationWaitingForConfirmation.confirmCode.equals(splited[0]) && System.currentTimeMillis() - calibrationWaitingForConfirmation.date.getTime() < CONFIRM_TIMEOUT) { calibrationWaitingForConfirmation.processed = true; boolean result = XdripCalibrations.sendIntent(calibrationWaitingForConfirmation.calibrationRequested); if (result) { @@ -531,13 +531,13 @@ public class SmsCommunicatorPlugin implements PluginBase { sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); } } else if (suspendWaitingForConfirmation != null && !suspendWaitingForConfirmation.processed && - suspendWaitingForConfirmation.confirmCode.equals(splited[0]) && new Date().getTime() - suspendWaitingForConfirmation.date.getTime() < CONFIRM_TIMEOUT) { + suspendWaitingForConfirmation.confirmCode.equals(splited[0]) && System.currentTimeMillis() - suspendWaitingForConfirmation.date.getTime() < CONFIRM_TIMEOUT) { suspendWaitingForConfirmation.processed = true; final LoopPlugin activeloop = ConfigBuilderPlugin.getActiveLoop(); - activeloop.suspendTo(new Date().getTime() + suspendWaitingForConfirmation.duration * 60L * 1000); - PumpEnactResult result = MainApp.getConfigBuilder().cancelTempBasal(); + activeloop.suspendTo(System.currentTimeMillis() + suspendWaitingForConfirmation.duration * 60L * 1000); + PumpEnactResult result = MainApp.getConfigBuilder().cancelTempBasal(true); NSUpload.uploadOpenAPSOffline(suspendWaitingForConfirmation.duration * 60); - MainApp.bus().post(new EventRefreshGui(false)); + MainApp.bus().post(new EventRefreshOverview("SMS_LOOP_SUSPENDED")); reply = MainApp.sResources.getString(R.string.smscommunicator_loopsuspended) + " " + MainApp.sResources.getString(result.success?R.string.smscommunicator_tempbasalcanceled:R.string.smscommunicator_tempbasalcancelfailed); sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply, new Date())); 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 similarity index 100% rename from app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/Events/EventNewSMS.java rename to app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/events/EventNewSMS.java diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/SourceGlimp/SourceGlimpFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/SourceGlimp/SourceGlimpFragment.java deleted file mode 100644 index 63ab27deee..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/SourceGlimp/SourceGlimpFragment.java +++ /dev/null @@ -1,14 +0,0 @@ -package info.nightscout.androidaps.plugins.SourceGlimp; - - -import android.support.v4.app.Fragment; - -public class SourceGlimpFragment extends Fragment { - - private static SourceGlimpPlugin sourceGlimpPlugin = new SourceGlimpPlugin(); - - public static SourceGlimpPlugin getPlugin() { - return sourceGlimpPlugin; - } - -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/SourceGlimp/SourceGlimpPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/SourceGlimp/SourceGlimpPlugin.java index 3c1248c4de..0f914feddc 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/SourceGlimp/SourceGlimpPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/SourceGlimp/SourceGlimpPlugin.java @@ -4,7 +4,6 @@ import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.interfaces.BgSourceInterface; import info.nightscout.androidaps.interfaces.PluginBase; -import info.nightscout.androidaps.plugins.SourceMM640g.SourceMM640gFragment; /** * Created by mike on 05.08.2016. @@ -12,9 +11,17 @@ import info.nightscout.androidaps.plugins.SourceMM640g.SourceMM640gFragment; public class SourceGlimpPlugin implements PluginBase, BgSourceInterface { boolean fragmentEnabled = false; + static SourceGlimpPlugin plugin = null; + + public static SourceGlimpPlugin getPlugin() { + if (plugin == null) + plugin = new SourceGlimpPlugin(); + return plugin; + } + @Override public String getFragmentClass() { - return SourceGlimpFragment.class.getName(); + return null; } @Override diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/SourceMM640g/SourceMM640gFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/SourceMM640g/SourceMM640gFragment.java deleted file mode 100644 index 28bfabf813..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/SourceMM640g/SourceMM640gFragment.java +++ /dev/null @@ -1,14 +0,0 @@ -package info.nightscout.androidaps.plugins.SourceMM640g; - - -import android.support.v4.app.Fragment; - -public class SourceMM640gFragment extends Fragment { - - private static SourceMM640gPlugin sourceMM640gPlugin = new SourceMM640gPlugin(); - - public static SourceMM640gPlugin getPlugin() { - return sourceMM640gPlugin; - } - -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/SourceMM640g/SourceMM640gPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/SourceMM640g/SourceMM640gPlugin.java index df8111b5cd..6276b97f25 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/SourceMM640g/SourceMM640gPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/SourceMM640g/SourceMM640gPlugin.java @@ -4,7 +4,6 @@ import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.interfaces.BgSourceInterface; import info.nightscout.androidaps.interfaces.PluginBase; -import info.nightscout.androidaps.plugins.SourceNSClient.SourceNSClientFragment; /** * Created by mike on 05.08.2016. @@ -12,9 +11,17 @@ import info.nightscout.androidaps.plugins.SourceNSClient.SourceNSClientFragment; public class SourceMM640gPlugin implements PluginBase, BgSourceInterface { boolean fragmentEnabled = false; + static SourceMM640gPlugin plugin = null; + + public static SourceMM640gPlugin getPlugin() { + if (plugin == null) + plugin = new SourceMM640gPlugin(); + return plugin; + } + @Override public String getFragmentClass() { - return SourceMM640gFragment.class.getName(); + return null; } @Override diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/SourceNSClient/SourceNSClientFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/SourceNSClient/SourceNSClientFragment.java deleted file mode 100644 index b2eddc09fc..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/SourceNSClient/SourceNSClientFragment.java +++ /dev/null @@ -1,14 +0,0 @@ -package info.nightscout.androidaps.plugins.SourceNSClient; - - -import android.support.v4.app.Fragment; - -public class SourceNSClientFragment extends Fragment { - - private static SourceNSClientPlugin sourceNSClientPlugin = new SourceNSClientPlugin(); - - public static SourceNSClientPlugin getPlugin() { - return sourceNSClientPlugin; - } - -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/SourceNSClient/SourceNSClientPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/SourceNSClient/SourceNSClientPlugin.java index 62ae6b93da..a10d0d1d1e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/SourceNSClient/SourceNSClientPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/SourceNSClient/SourceNSClientPlugin.java @@ -12,9 +12,17 @@ import info.nightscout.androidaps.interfaces.PluginBase; public class SourceNSClientPlugin implements PluginBase, BgSourceInterface { boolean fragmentEnabled = true; + static SourceNSClientPlugin plugin = null; + + public static SourceNSClientPlugin getPlugin() { + if (plugin == null) + plugin = new SourceNSClientPlugin(); + return plugin; + } + @Override public String getFragmentClass() { - return SourceNSClientFragment.class.getName(); + return null; } @Override diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/SourceXdrip/SourceXdripFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/SourceXdrip/SourceXdripFragment.java deleted file mode 100644 index c9be1298d2..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/SourceXdrip/SourceXdripFragment.java +++ /dev/null @@ -1,13 +0,0 @@ -package info.nightscout.androidaps.plugins.SourceXdrip; - - -import android.support.v4.app.Fragment; - -public class SourceXdripFragment extends Fragment { - - private static SourceXdripPlugin sourceXdripPlugin = new SourceXdripPlugin(); - - public static SourceXdripPlugin getPlugin() { - return sourceXdripPlugin; - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/SourceXdrip/SourceXdripPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/SourceXdrip/SourceXdripPlugin.java index b32040a2e8..6d214dc028 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/SourceXdrip/SourceXdripPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/SourceXdrip/SourceXdripPlugin.java @@ -4,16 +4,23 @@ import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.interfaces.BgSourceInterface; import info.nightscout.androidaps.interfaces.PluginBase; -import info.nightscout.androidaps.plugins.SourceNSClient.SourceNSClientFragment; /** * Created by mike on 05.08.2016. */ public class SourceXdripPlugin implements PluginBase, BgSourceInterface { + static SourceXdripPlugin plugin = null; + + public static SourceXdripPlugin getPlugin() { + if (plugin == null) + plugin = new SourceXdripPlugin(); + return plugin; + } + @Override public String getFragmentClass() { - return SourceNSClientFragment.class.getName(); + return null; } private static boolean fragmentEnabled = false; 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 50bb0c7892..8a999cbcd6 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 @@ -8,7 +8,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; -import java.util.Date; import java.util.List; import info.nightscout.androidaps.Config; @@ -19,16 +18,17 @@ import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.data.Iob; import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.MealData; +import info.nightscout.androidaps.data.Intervals; +import info.nightscout.androidaps.data.NonOverlappingIntervals; import info.nightscout.androidaps.data.OverlappingIntervals; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.ProfileIntervals; import info.nightscout.androidaps.db.ExtendedBolus; import info.nightscout.androidaps.db.ProfileSwitch; -import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.TempTarget; import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.db.Treatment; -import info.nightscout.androidaps.events.EventProfileSwitchChange; +import info.nightscout.androidaps.events.EventReloadProfileSwitchData; import info.nightscout.androidaps.events.EventReloadTempBasalData; import info.nightscout.androidaps.events.EventReloadTreatmentData; import info.nightscout.androidaps.events.EventTempTargetChange; @@ -49,9 +49,9 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { public static IobTotal lastTempBasalsCalculation; public static List treatments; - private static OverlappingIntervals tempBasals = new OverlappingIntervals<>(); - private static OverlappingIntervals extendedBoluses = new OverlappingIntervals<>(); - private static OverlappingIntervals tempTargets = new OverlappingIntervals<>(); + private static Intervals tempBasals = new NonOverlappingIntervals(); + private static Intervals extendedBoluses = new NonOverlappingIntervals(); + private static Intervals tempTargets = new OverlappingIntervals(); private static ProfileIntervals profiles = new ProfileIntervals<>(); private static boolean fragmentEnabled = true; @@ -130,7 +130,7 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { public static void initializeTreatmentData() { // Treatments double dia = MainApp.getConfigBuilder() == null ? Constants.defaultDIA : MainApp.getConfigBuilder().getProfile().getDia(); - long fromMills = (long) (new Date().getTime() - 60 * 60 * 1000L * (24 + dia)); + long fromMills = (long) (System.currentTimeMillis() - 60 * 60 * 1000L * (24 + dia)); treatments = MainApp.getDbHelper().getTreatmentDataFromTime(fromMills, false); } @@ -138,7 +138,7 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { public static void initializeTempBasalData() { // Treatments double dia = MainApp.getConfigBuilder() == null ? Constants.defaultDIA : MainApp.getConfigBuilder().getProfile().getDia(); - long fromMills = (long) (new Date().getTime() - 60 * 60 * 1000L * (24 + dia)); + long fromMills = (long) (System.currentTimeMillis() - 60 * 60 * 1000L * (24 + dia)); tempBasals.reset().add(MainApp.getDbHelper().getTemporaryBasalsDataFromTime(fromMills, false)); @@ -147,14 +147,14 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { public static void initializeExtendedBolusData() { // Treatments double dia = MainApp.getConfigBuilder() == null ? Constants.defaultDIA : MainApp.getConfigBuilder().getProfile().getDia(); - long fromMills = (long) (new Date().getTime() - 60 * 60 * 1000L * (24 + dia)); + long fromMills = (long) (System.currentTimeMillis() - 60 * 60 * 1000L * (24 + dia)); extendedBoluses.reset().add(MainApp.getDbHelper().getExtendedBolusDataFromTime(fromMills, false)); } public void initializeTempTargetData() { - long fromMills = new Date().getTime() - 60 * 60 * 1000L * 24; + long fromMills = System.currentTimeMillis() - 60 * 60 * 1000L * 24; tempTargets.reset().add(MainApp.getDbHelper().getTemptargetsDataFromTime(fromMills, false)); } @@ -175,7 +175,7 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { if (profile == null) return total; - Double dia = profile.getDia(); + double dia = profile.getDia(); for (Integer pos = 0; pos < treatments.size(); pos++) { Treatment t = treatments.get(pos); @@ -183,23 +183,25 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { Iob tIOB = t.iobCalc(time, dia); total.iob += tIOB.iobContrib; total.activity += tIOB.activityContrib; - Iob bIOB = t.iobCalc(time, dia / SP.getInt("openapsama_bolussnooze_dia_divisor", 2)); + Iob bIOB = t.iobCalc(time, dia / SP.getDouble("openapsama_bolussnooze_dia_divisor", 2.0)); total.bolussnooze += bIOB.iobContrib; } if (!MainApp.getConfigBuilder().isFakingTempsByExtendedBoluses()) - for (Integer pos = 0; pos < extendedBoluses.size(); pos++) { - ExtendedBolus e = extendedBoluses.get(pos); - if (e.date > time) continue; - IobTotal calc = e.iobCalc(time); - total.plus(calc); + synchronized (extendedBoluses) { + for (Integer pos = 0; pos < extendedBoluses.size(); pos++) { + ExtendedBolus e = extendedBoluses.get(pos); + if (e.date > time) continue; + IobTotal calc = e.iobCalc(time); + total.plus(calc); + } } return total; } @Override public void updateTotalIOBTreatments() { - IobTotal total = getCalculationToTimeTreatments(new Date().getTime()); + IobTotal total = getCalculationToTimeTreatments(System.currentTimeMillis()); lastTreatmentCalculation = total; } @@ -211,7 +213,7 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { Profile profile = MainApp.getConfigBuilder().getProfile(); if (profile == null) return result; - long now = new Date().getTime(); + long now = System.currentTimeMillis(); long dia_ago = now - (new Double(1.5d * profile.getDia() * 60 * 60 * 1000l)).longValue(); for (Treatment treatment : treatments) { @@ -243,7 +245,7 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { List in5minback = new ArrayList<>(); for (Integer pos = 0; pos < treatments.size(); pos++) { Treatment t = treatments.get(pos); - if (t.date <= time && t.date > time - 5 * 60 * 1000) + if (t.date <= time && t.date > time - 5 * 60 * 1000 && t.carbs > 0) in5minback.add(t); } return in5minback; @@ -251,7 +253,7 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { @Override public boolean isInHistoryRealTempBasalInProgress() { - return getRealTempBasalFromHistory(new Date().getTime()) != null; + return getRealTempBasalFromHistory(System.currentTimeMillis()) != null; } @Override @@ -261,12 +263,12 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { @Override public boolean isTempBasalInProgress() { - return getTempBasalFromHistory(new Date().getTime()) != null; + return getTempBasalFromHistory(System.currentTimeMillis()) != null; } @Override public boolean isInHistoryExtendedBoluslInProgress() { - return getExtendedBolusFromHistory(new Date().getTime()) != null; //TODO: crosscheck here + return getExtendedBolusFromHistory(System.currentTimeMillis()) != null; //TODO: crosscheck here } @Subscribe @@ -292,20 +294,24 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { @Override public IobTotal getCalculationToTimeTempBasals(long time) { IobTotal total = new IobTotal(time); - for (Integer pos = 0; pos < tempBasals.size(); pos++) { - TemporaryBasal t = tempBasals.get(pos); - if (t.date > time) continue; - IobTotal calc = t.iobCalc(time); - //log.debug("BasalIOB " + new Date(time) + " >>> " + calc.basaliob); - total.plus(calc); + synchronized (tempBasals) { + for (Integer pos = 0; pos < tempBasals.size(); pos++) { + TemporaryBasal t = tempBasals.get(pos); + if (t.date > time) continue; + IobTotal calc = t.iobCalc(time); + //log.debug("BasalIOB " + new Date(time) + " >>> " + calc.basaliob); + total.plus(calc); + } } if (MainApp.getConfigBuilder().isFakingTempsByExtendedBoluses()) { IobTotal totalExt = new IobTotal(time); - for (Integer pos = 0; pos < extendedBoluses.size(); pos++) { - ExtendedBolus e = extendedBoluses.get(pos); - if (e.date > time) continue; - IobTotal calc = e.iobCalc(time); - totalExt.plus(calc); + synchronized (extendedBoluses) { + for (Integer pos = 0; pos < extendedBoluses.size(); pos++) { + ExtendedBolus e = extendedBoluses.get(pos); + if (e.date > time) continue; + IobTotal calc = e.iobCalc(time); + totalExt.plus(calc); + } } // Convert to basal iob totalExt.basaliob = totalExt.iob; @@ -319,7 +325,7 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { @Override public void updateTotalIOBTempBasals() { - IobTotal total = getCalculationToTimeTempBasals(new Date().getTime()); + IobTotal total = getCalculationToTimeTempBasals(System.currentTimeMillis()); lastTempBasalsCalculation = total; } @@ -348,7 +354,7 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { } @Override - public OverlappingIntervals getExtendedBolusesFromHistory() { + public Intervals getExtendedBolusesFromHistory() { return extendedBoluses; } @@ -356,13 +362,17 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { public double getTempBasalAbsoluteRateHistory() { PumpInterface pump = MainApp.getConfigBuilder(); - TemporaryBasal tb = getTempBasalFromHistory(new Date().getTime()); + TemporaryBasal tb = getTempBasalFromHistory(System.currentTimeMillis()); if (tb != null) { - if (tb.isAbsolute) { + if (tb.isFakeExtended){ + double baseRate = pump.getBaseBasalRate(); + double tempRate = baseRate + tb.netExtendedRate; + return tempRate; + } else if (tb.isAbsolute) { return tb.absoluteRate; } else { - Double baseRate = pump.getBaseBasalRate(); - Double tempRate = baseRate * (tb.percentRate / 100d); + double baseRate = pump.getBaseBasalRate(); + double tempRate = baseRate * (tb.percentRate / 100d); return tempRate; } } @@ -372,12 +382,12 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { @Override public double getTempBasalRemainingMinutesFromHistory() { if (isTempBasalInProgress()) - return getTempBasalFromHistory(new Date().getTime()).getPlannedRemainingMinutes(); + return getTempBasalFromHistory(System.currentTimeMillis()).getPlannedRemainingMinutes(); return 0; } @Override - public OverlappingIntervals getTemporaryBasalsFromHistory() { + public Intervals getTemporaryBasalsFromHistory() { return tempBasals; } @@ -415,13 +425,19 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { @Override public long oldestDataAvailable() { - long oldestTime = new Date().getTime(); - if (tempBasals.size() > 0) - oldestTime = Math.min(oldestTime, tempBasals.get(0).date); - if (extendedBoluses.size() > 0) - oldestTime = Math.min(oldestTime, extendedBoluses.get(0).date); - if (treatments.size() > 0) - oldestTime = Math.min(oldestTime, treatments.get(treatments.size() - 1).date); + long oldestTime = System.currentTimeMillis(); + synchronized (tempBasals) { + if (tempBasals.size() > 0) + oldestTime = Math.min(oldestTime, tempBasals.get(0).date); + } + synchronized (extendedBoluses) { + if (extendedBoluses.size() > 0) + oldestTime = Math.min(oldestTime, extendedBoluses.get(0).date); + } + synchronized (treatments) { + if (treatments.size() > 0) + oldestTime = Math.min(oldestTime, treatments.get(treatments.size() - 1).date); + } oldestTime -= 15 * 60 * 1000L; // allow 15 min before return oldestTime; } @@ -439,13 +455,13 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { } @Override - public OverlappingIntervals getTempTargetsFromHistory() { + public Intervals getTempTargetsFromHistory() { return tempTargets; } // Profile Switch @Subscribe - public void onStatusEvent(final EventProfileSwitchChange ev) { + public void onStatusEvent(final EventReloadProfileSwitchData ev) { initializeProfileSwitchData(); } 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 5f6ff02950..0e7d94cd88 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 @@ -37,13 +37,14 @@ import info.nightscout.androidaps.db.Treatment; import info.nightscout.androidaps.events.EventNewBG; import info.nightscout.androidaps.events.EventTreatmentChange; import info.nightscout.androidaps.data.Profile; +import info.nightscout.androidaps.plugins.Common.SubscriberFragment; 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.utils.SP; -public class TreatmentsBolusFragment extends Fragment implements View.OnClickListener { +public class TreatmentsBolusFragment extends SubscriberFragment implements View.OnClickListener { private static Logger log = LoggerFactory.getLogger(TreatmentsBolusFragment.class); RecyclerView recyclerView; @@ -78,7 +79,7 @@ public class TreatmentsBolusFragment extends Fragment implements View.OnClickLis holder.date.setText(DateUtil.dateAndTimeString(t.date)); holder.insulin.setText(DecimalFormatter.to2Decimal(t.insulin) + " U"); holder.carbs.setText(DecimalFormatter.to0Decimal(t.carbs) + " g"); - Iob iob = t.iobCalc(new Date().getTime(), profile.getDia()); + 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.mealBolus ? MainApp.sResources.getString(R.string.mealbolus) : MainApp.sResources.getString(R.string.correctionbous)); @@ -205,19 +206,6 @@ public class TreatmentsBolusFragment extends Fragment implements View.OnClickLis } } - @Override - public void onPause() { - super.onPause(); - MainApp.bus().unregister(this); - } - - @Override - public void onResume() { - super.onResume(); - MainApp.bus().register(this); - updateGUI(); - } - @Subscribe public void onStatusEvent(final EventTreatmentChange ev) { updateGUI(); @@ -228,7 +216,8 @@ public class TreatmentsBolusFragment extends Fragment implements View.OnClickLis updateGUI(); } - public void updateGUI() { + @Override + protected void updateGUI() { Activity activity = getActivity(); if (activity != null) activity.runOnUiThread(new Runnable() { 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 fcd691cf68..eb3bd49d89 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 @@ -23,8 +23,6 @@ import com.squareup.otto.Subscribe; 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.IobTotal; @@ -32,13 +30,14 @@ import info.nightscout.androidaps.db.ExtendedBolus; import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.events.EventExtendedBolusChange; import info.nightscout.androidaps.events.EventNewBG; +import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.NSUpload; -import info.nightscout.androidaps.data.OverlappingIntervals; +import info.nightscout.androidaps.data.Intervals; -public class TreatmentsExtendedBolusesFragment extends Fragment { +public class TreatmentsExtendedBolusesFragment extends SubscriberFragment { private static Logger log = LoggerFactory.getLogger(TreatmentsExtendedBolusesFragment.class); RecyclerView recyclerView; @@ -48,9 +47,9 @@ public class TreatmentsExtendedBolusesFragment extends Fragment { public class RecyclerViewAdapter extends RecyclerView.Adapter { - OverlappingIntervals extendedBolusList; + Intervals extendedBolusList; - RecyclerViewAdapter(OverlappingIntervals extendedBolusList) { + RecyclerViewAdapter(Intervals extendedBolusList) { this.extendedBolusList = extendedBolusList; } @@ -82,7 +81,7 @@ public class TreatmentsExtendedBolusesFragment extends Fragment { holder.duration.setText(DecimalFormatter.to0Decimal(extendedBolus.durationInMinutes) + " min"); holder.insulin.setText(DecimalFormatter.to2Decimal(extendedBolus.insulin) + " U"); holder.realDuration.setText(DecimalFormatter.to0Decimal(extendedBolus.getRealDuration()) + " min"); - IobTotal iob = extendedBolus.iobCalc(new Date().getTime()); + IobTotal iob = extendedBolus.iobCalc(System.currentTimeMillis()); holder.iob.setText(DecimalFormatter.to2Decimal(iob.iob) + " U"); holder.insulinSoFar.setText(DecimalFormatter.to2Decimal(extendedBolus.insulinSoFar()) + " U"); holder.ratio.setText(DecimalFormatter.to2Decimal(extendedBolus.absoluteRate()) + " U/h"); @@ -90,7 +89,7 @@ public class TreatmentsExtendedBolusesFragment extends Fragment { holder.date.setTextColor(ContextCompat.getColor(MainApp.instance(), R.color.colorActive)); else holder.date.setTextColor(holder.insulin.getCurrentTextColor()); - if (extendedBolus.iobCalc(new Date().getTime()).iob != 0) + if (extendedBolus.iobCalc(System.currentTimeMillis()).iob != 0) holder.iob.setTextColor(ContextCompat.getColor(MainApp.instance(), R.color.colorActive)); else holder.iob.setTextColor(holder.insulin.getCurrentTextColor()); @@ -183,18 +182,6 @@ public class TreatmentsExtendedBolusesFragment extends Fragment { return view; } - @Override - public void onPause() { - super.onPause(); - MainApp.bus().unregister(this); - } - - @Override - public void onResume() { - super.onResume(); - MainApp.bus().register(this); - } - @Subscribe public void onStatusEvent(final EventExtendedBolusChange ev) { updateGUI(); @@ -205,7 +192,8 @@ public class TreatmentsExtendedBolusesFragment extends Fragment { updateGUI(); } - public void updateGUI() { + @Override + protected void updateGUI() { Activity activity = getActivity(); if (activity != null && recyclerView != null) activity.runOnUiThread(new Runnable() { 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 344abd8346..e5c1134787 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 @@ -30,6 +30,7 @@ import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.TempTarget; import info.nightscout.androidaps.events.EventProfileSwitchChange; import info.nightscout.androidaps.events.EventTempTargetChange; +import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.NSUpload; @@ -40,7 +41,7 @@ import info.nightscout.utils.SP; * Created by mike on 13/01/17. */ -public class TreatmentsProfileSwitchFragment extends Fragment implements View.OnClickListener { +public class TreatmentsProfileSwitchFragment extends SubscriberFragment implements View.OnClickListener { RecyclerView recyclerView; LinearLayoutManager llm; @@ -180,24 +181,13 @@ public class TreatmentsProfileSwitchFragment extends Fragment implements View.On } } - @Override - public void onPause() { - super.onPause(); - MainApp.bus().unregister(this); - } - - @Override - public void onResume() { - super.onResume(); - MainApp.bus().register(this); - } - @Subscribe public void onStatusEvent(final EventProfileSwitchChange ev) { updateGUI(); } - void updateGUI() { + @Override + protected void updateGUI() { Activity activity = getActivity(); if (activity != null) activity.runOnUiThread(new Runnable() { 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 9b2603ef4f..008c82e612 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 @@ -26,18 +26,18 @@ import info.nightscout.androidaps.Services.Intents; import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.TempTarget; import info.nightscout.androidaps.events.EventTempTargetChange; -import info.nightscout.androidaps.data.Profile; +import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.NSUpload; -import info.nightscout.androidaps.data.OverlappingIntervals; +import info.nightscout.androidaps.data.Intervals; import info.nightscout.utils.SP; /** * Created by mike on 13/01/17. */ -public class TreatmentsTempTargetFragment extends Fragment implements View.OnClickListener { +public class TreatmentsTempTargetFragment extends SubscriberFragment implements View.OnClickListener { RecyclerView recyclerView; LinearLayoutManager llm; @@ -47,10 +47,12 @@ public class TreatmentsTempTargetFragment extends Fragment implements View.OnCli public class RecyclerViewAdapter extends RecyclerView.Adapter { - OverlappingIntervals tempTargetList; + Intervals tempTargetList; + TempTarget currentlyActiveTarget; - RecyclerViewAdapter(OverlappingIntervals TempTargetList) { + RecyclerViewAdapter(Intervals TempTargetList) { this.tempTargetList = TempTargetList; + currentlyActiveTarget = tempTargetList.getValueByInterval(System.currentTimeMillis()); } @Override @@ -62,16 +64,15 @@ public class TreatmentsTempTargetFragment extends Fragment implements View.OnCli @Override public void onBindViewHolder(TempTargetsViewHolder holder, int position) { - Profile profile = MainApp.getConfigBuilder().getProfile(); - if (profile == null) return; + String units = MainApp.getConfigBuilder().getProfileUnits(); TempTarget tempTarget = tempTargetList.getReversed(position); holder.ph.setVisibility(tempTarget.source == Source.PUMP ? View.VISIBLE : View.GONE); holder.ns.setVisibility(tempTarget._id != null ? View.VISIBLE : View.GONE); if (!tempTarget.isEndingEvent()) { holder.date.setText(DateUtil.dateAndTimeString(tempTarget.date) + " - " + DateUtil.timeString(tempTarget.originalEnd())); holder.duration.setText(DecimalFormatter.to0Decimal(tempTarget.durationInMinutes) + " min"); - holder.low.setText(tempTarget.lowValueToUnitsToString(profile.getUnits())); - holder.high.setText(tempTarget.highValueToUnitsToString(profile.getUnits())); + holder.low.setText(tempTarget.lowValueToUnitsToString(units)); + holder.high.setText(tempTarget.highValueToUnitsToString(units)); holder.reason.setText(tempTarget.reason); } else { holder.date.setText(DateUtil.dateAndTimeString(tempTarget.date)); @@ -82,10 +83,18 @@ public class TreatmentsTempTargetFragment extends Fragment implements View.OnCli holder.reasonLabel.setText(""); holder.reasonColon.setText(""); } - if (tempTarget.isInProgress()) - holder.date.setTextColor(ContextCompat.getColor(MainApp.instance(), R.color.colorActive)); - else + if (tempTarget.isInProgress()) { + if(tempTarget == currentlyActiveTarget){ + // active as newest + holder.date.setTextColor(ContextCompat.getColor(MainApp.instance(), R.color.colorInProgress)); + } else { + // other's that might become active again after the latest (overlapping) is over + holder.date.setTextColor(ContextCompat.getColor(MainApp.instance(), R.color.colorActive)); + } + } + else { holder.date.setTextColor(holder.reasonColon.getCurrentTextColor()); + } holder.remove.setTag(tempTarget); } @@ -202,24 +211,13 @@ public class TreatmentsTempTargetFragment extends Fragment implements View.OnCli } - @Override - public void onPause() { - super.onPause(); - MainApp.bus().unregister(this); - } - - @Override - public void onResume() { - super.onResume(); - MainApp.bus().register(this); - } - @Subscribe public void onStatusEvent(final EventTempTargetChange ev) { updateGUI(); } - void updateGUI() { + @Override + protected void updateGUI() { Activity activity = getActivity(); if (activity != null) activity.runOnUiThread(new Runnable() { 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 61c93abd96..9127bf1e7a 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 @@ -23,8 +23,6 @@ import com.squareup.otto.Subscribe; 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.IobTotal; @@ -32,13 +30,14 @@ import info.nightscout.androidaps.db.Source; 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.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.NSUpload; -import info.nightscout.androidaps.data.OverlappingIntervals; +import info.nightscout.androidaps.data.Intervals; -public class TreatmentsTemporaryBasalsFragment extends Fragment { +public class TreatmentsTemporaryBasalsFragment extends SubscriberFragment { private static Logger log = LoggerFactory.getLogger(TreatmentsTemporaryBasalsFragment.class); RecyclerView recyclerView; @@ -50,9 +49,9 @@ public class TreatmentsTemporaryBasalsFragment extends Fragment { public class RecyclerViewAdapter extends RecyclerView.Adapter { - OverlappingIntervals tempBasalList; + Intervals tempBasalList; - RecyclerViewAdapter(OverlappingIntervals tempBasalList) { + RecyclerViewAdapter(Intervals tempBasalList) { this.tempBasalList = tempBasalList; } @@ -93,7 +92,7 @@ public class TreatmentsTemporaryBasalsFragment extends Fragment { holder.percent.setText(DecimalFormatter.to0Decimal(tempBasal.percentRate) + "%"); } holder.realDuration.setText(DecimalFormatter.to0Decimal(tempBasal.getRealDuration()) + " min"); - IobTotal iob = tempBasal.iobCalc(new Date().getTime()); + IobTotal iob = tempBasal.iobCalc(System.currentTimeMillis()); holder.iob.setText(DecimalFormatter.to2Decimal(iob.basaliob) + " U"); holder.netInsulin.setText(DecimalFormatter.to2Decimal(iob.netInsulin) + " U"); holder.netRatio.setText(DecimalFormatter.to2Decimal(iob.netRatio) + " U/h"); @@ -103,7 +102,7 @@ public class TreatmentsTemporaryBasalsFragment extends Fragment { holder.date.setTextColor(ContextCompat.getColor(MainApp.instance(), R.color.colorActive)); else holder.date.setTextColor(holder.netRatio.getCurrentTextColor()); - if (tempBasal.iobCalc(new Date().getTime()).basaliob != 0) + if (tempBasal.iobCalc(System.currentTimeMillis()).basaliob != 0) holder.iob.setTextColor(ContextCompat.getColor(MainApp.instance(), R.color.colorActive)); else holder.iob.setTextColor(holder.netRatio.getCurrentTextColor()); @@ -202,18 +201,6 @@ public class TreatmentsTemporaryBasalsFragment extends Fragment { return view; } - @Override - public void onPause() { - super.onPause(); - MainApp.bus().unregister(this); - } - - @Override - public void onResume() { - super.onResume(); - MainApp.bus().register(this); - } - @Subscribe public void onStatusEvent(final EventTempBasalChange ev) { updateGUI(); @@ -224,7 +211,8 @@ public class TreatmentsTemporaryBasalsFragment extends Fragment { updateGUI(); } - public void updateGUI() { + @Override + protected void updateGUI() { Activity activity = getActivity(); if (activity != null) activity.runOnUiThread(new Runnable() { 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 8fc7e9f868..2db941e1c5 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 @@ -4,8 +4,14 @@ import android.os.Handler; import android.os.HandlerThread; import android.support.annotation.NonNull; +import java.text.DateFormat; import java.text.DecimalFormat; +import java.text.SimpleDateFormat; +import java.util.Collections; +import java.util.Comparator; import java.util.Date; +import java.util.LinkedList; +import java.util.List; import info.nightscout.androidaps.BuildConfig; import info.nightscout.androidaps.Config; @@ -15,14 +21,25 @@ import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.db.BgReading; +import info.nightscout.androidaps.db.DanaRHistoryRecord; import info.nightscout.androidaps.db.DatabaseHelper; import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.TempTarget; import info.nightscout.androidaps.interfaces.APSInterface; +import info.nightscout.androidaps.interfaces.DanaRInterface; import info.nightscout.androidaps.interfaces.PluginBase; +import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.plugins.Actions.dialogs.FillDialog; +import info.nightscout.androidaps.plugins.Loop.APSResult; import info.nightscout.androidaps.plugins.Loop.LoopPlugin; import info.nightscout.androidaps.data.Profile; +import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification; +import info.nightscout.androidaps.plugins.ProfileCircadianPercentage.CircadianPercentageProfilePlugin; +import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPlugin; +import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; +import info.nightscout.androidaps.plugins.PumpDanaR.comm.RecordTypes; +import info.nightscout.androidaps.plugins.PumpDanaRKorean.DanaRKoreanPlugin; +import info.nightscout.androidaps.plugins.PumpDanaRv2.DanaRv2Plugin; import info.nightscout.utils.BolusWizard; import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; @@ -154,11 +171,9 @@ public class ActionStringHandler { rMessage = getPumpStatus(); } else if ("loop".equals(act[1])) { rTitle += " LOOP"; - rMessage = getLoopStatus(); - - } else if ("targets".equals(act[1])) { - rTitle += " TARGETS"; - rMessage = getTargetsStatus(); + rMessage = "TARGETS:\n" + getTargetsStatus(); + rMessage += "\n\n" + getLoopStatus(); + rMessage += "\n\nOAPS RESULT:\n" + getOAPSResultStatus(); } } else if ("wizard".equals(act[0])) { @@ -174,6 +189,7 @@ public class ActionStringHandler { boolean useBG = Boolean.parseBoolean(act[2]); boolean useBolusIOB = Boolean.parseBoolean(act[3]); boolean useBasalIOB = Boolean.parseBoolean(act[4]); + int percentage = Integer.parseInt(act[5]); Profile profile = MainApp.getConfigBuilder().getProfile(); if (profile == null) { @@ -188,7 +204,7 @@ public class ActionStringHandler { } DecimalFormat format = new DecimalFormat("0.00"); BolusWizard bolusWizard = new BolusWizard(); - bolusWizard.doCalc(profile, carbsAfterConstraints, 0d, useBG ? bgReading.valueToUnits(profile.getUnits()) : 0d, 0d, useBolusIOB, useBasalIOB, false, false); + bolusWizard.doCalc(profile, carbsAfterConstraints, 0d, useBG ? bgReading.valueToUnits(profile.getUnits()) : 0d, 0d, percentage, useBolusIOB, useBasalIOB, false, false); Double insulinAfterConstraints = MainApp.getConfigBuilder().applyBolusConstraints(bolusWizard.calculatedTotalInsulin); if (insulinAfterConstraints - bolusWizard.calculatedTotalInsulin != 0) { @@ -218,10 +234,96 @@ public class ActionStringHandler { rMessage += "\nBolus IOB: " + format.format(bolusWizard.insulingFromBolusIOB) + "U"; if (useBasalIOB) rMessage += "\nBasal IOB: " + format.format(bolusWizard.insulingFromBasalsIOB) + "U"; + if(percentage != 100){ + rMessage += "\nPercentage: " +format.format(bolusWizard.totalBeforePercentageAdjustment) + "U * " + percentage + "% -> ~" + format.format(bolusWizard.calculatedTotalInsulin) + "U"; + } lastBolusWizard = bolusWizard; - } else return; + } else if("opencpp".equals(act[0])){ + Object activeProfile = MainApp.getConfigBuilder().getActiveProfileInterface(); + CircadianPercentageProfilePlugin cpp = (CircadianPercentageProfilePlugin) MainApp.getSpecificPlugin(CircadianPercentageProfilePlugin.class); + + if(cpp == null || activeProfile==null || cpp != activeProfile){ + sendError("CPP not activated!"); + return; + } else { + // read CPP values + rTitle = "opencpp"; + rMessage = "opencpp"; + rAction = "opencpp" + " " + cpp.getPercentage() + " " + cpp.getTimeshift(); + } + + } else if("cppset".equals(act[0])){ + Object activeProfile = MainApp.getConfigBuilder().getActiveProfileInterface(); + CircadianPercentageProfilePlugin cpp = (CircadianPercentageProfilePlugin) MainApp.getSpecificPlugin(CircadianPercentageProfilePlugin.class); + + if(cpp == null || activeProfile==null || cpp != activeProfile){ + sendError("CPP not activated!"); + return; + } else { + // read CPP values + rMessage = "CPP:" + "\n\n"+ + "Timeshift: " + act[1] + "\n" + + "Percentage: " + act[2] + "%"; + rAction = actionstring; + } + + } else if("tddstats".equals(act[0])){ + Object activePump = MainApp.getConfigBuilder().getActivePump(); + PumpInterface dana = (PumpInterface) MainApp.getSpecificPlugin(DanaRPlugin.class); + PumpInterface danaV2 = (PumpInterface) MainApp.getSpecificPlugin(DanaRv2Plugin.class); + PumpInterface danaKorean = (PumpInterface) MainApp.getSpecificPlugin(DanaRKoreanPlugin.class); + + + if((dana == null || dana != activePump) && + (danaV2 == null || danaV2 != activePump) && + (danaKorean == null || danaKorean != activePump) + ){ + sendError("Pump does not support TDDs!"); + return; + } else { + // check if DB up to date + List dummies = new LinkedList(); + List historyList = getTDDList(dummies); + + if(isOldData(historyList)){ + rTitle = "TDD"; + rAction = "statusmessage"; + rMessage = "OLD DATA - "; + + //if pump is not busy: try to fetch data + final PumpInterface pump = MainApp.getConfigBuilder().getActivePump(); + if (pump.isBusy()) { + rMessage += MainApp.instance().getString(R.string.pumpbusy); + } else { + rMessage += "trying to fetch data from pump."; + Handler handler = new Handler(handlerThread.getLooper()); + handler.post(new Runnable() { + @Override + public void run() { + ((DanaRInterface)pump).loadHistory(RecordTypes.RECORD_TYPE_DAILY); + List dummies = new LinkedList(); + List historyList = getTDDList(dummies); + if(isOldData(historyList)){ + sendStatusmessage("TDD", "TDD: Still old data! Cannot load from pump."); + } else { + sendStatusmessage("TDD", generateTDDMessage(historyList, dummies)); + } + } + }); + } + } else { + // if up to date: prepare, send (check if CPP is activated -> add CPP stats) + rTitle = "TDD"; + rAction = "statusmessage"; + rMessage = generateTDDMessage(historyList, dummies); + } + } + + } + else return; + // send result WearFragment.getPlugin(MainApp.instance()).requestActionConfirmation(rTitle, rMessage, rAction); @@ -229,6 +331,98 @@ public class ActionStringHandler { lastConfirmActionString = rAction; } + private static String generateTDDMessage(List historyList, List dummies) { + + DateFormat df = new SimpleDateFormat("dd.MM."); + String message = ""; + + CircadianPercentageProfilePlugin cpp = (CircadianPercentageProfilePlugin) MainApp.getSpecificPlugin(CircadianPercentageProfilePlugin.class); + boolean isCPP = (cpp!= null && cpp.isEnabled(PluginBase.PROFILE)); + double refTDD = 100; + if(isCPP) refTDD = cpp.baseBasalSum()*2; + + int i = 0; + double sum = 0d; + double weighted03 = 0d; + double weighted05 = 0d; + double weighted07 = 0d; + + Collections.reverse(historyList); + for (DanaRHistoryRecord record : historyList) { + double tdd = record.recordDailyBolus + record.recordDailyBasal; + if (i == 0) { + weighted03 = tdd; + weighted05 = tdd; + weighted07 = tdd; + + } else { + weighted07 = (weighted07 * 0.3 + tdd * 0.7); + weighted05 = (weighted05 * 0.5 + tdd * 0.5); + weighted03 = (weighted03 * 0.7 + tdd * 0.3); + } + i++; + } + message += "weighted:\n"; + message += "0.3: " + DecimalFormatter.to2Decimal(weighted03) + "U " + (isCPP?(DecimalFormatter.to0Decimal(100*weighted03/refTDD) + "%"):"") + "\n"; + message += "0.5: " + DecimalFormatter.to2Decimal(weighted05) + "U " + (isCPP?(DecimalFormatter.to0Decimal(100*weighted05/refTDD) + "%"):"") + "\n"; + message += "0.7: " + DecimalFormatter.to2Decimal(weighted07) + "U " + (isCPP?(DecimalFormatter.to0Decimal(100*weighted07/refTDD) + "%"):"") + "\n"; + message += "\n"; + + PumpInterface pump = MainApp.getConfigBuilder().getActivePump(); + if (pump != null && pump instanceof DanaRPlugin) { + double tdd = DanaRPump.getInstance().dailyTotalUnits; + message += "Today: " + DecimalFormatter.to2Decimal(tdd) + "U " + (isCPP?(DecimalFormatter.to0Decimal(100*tdd/refTDD) + "%"):"") + "\n"; + message += "\n"; + } + + //add TDDs: + Collections.reverse(historyList); + for (DanaRHistoryRecord record : historyList) { + double tdd = record.recordDailyBolus + record.recordDailyBasal; + message += df.format(new Date(record.recordDate)) + " " + DecimalFormatter.to2Decimal(tdd) +"U " + (isCPP?(DecimalFormatter.to0Decimal(100*tdd/refTDD) + "%"):"") + (dummies.contains(record)?"x":"") +"\n"; + } + return message; + } + + public static boolean isOldData(List historyList) { + DateFormat df = new SimpleDateFormat("dd.MM."); + return (historyList.size() < 3 || !(df.format(new Date(historyList.get(0).recordDate)).equals(df.format(new Date(System.currentTimeMillis() - 1000 * 60 * 60 * 24))))); + } + + @NonNull + public static List getTDDList(List returnDummies) { + List historyList = MainApp.getDbHelper().getDanaRHistoryRecordsByType(RecordTypes.RECORD_TYPE_DAILY); + + //only use newest 10 + historyList = historyList.subList(0, Math.min(10, historyList.size())); + + //fill single gaps + List dummies = (returnDummies!=null)?returnDummies:(new LinkedList()); + DateFormat df = new SimpleDateFormat("dd.MM."); + for(int i = 0; i < historyList.size()-1; i++){ + DanaRHistoryRecord elem1 = historyList.get(i); + DanaRHistoryRecord elem2 = historyList.get(i+1); + + if (!df.format(new Date(elem1.recordDate)).equals(df.format(new Date(elem2.recordDate + 25*60*60*1000)))){ + DanaRHistoryRecord dummy = new DanaRHistoryRecord(); + dummy.recordDate = elem1.recordDate - 24*60*60*1000; + dummy.recordDailyBasal = elem1.recordDailyBasal/2; + dummy.recordDailyBolus = elem1.recordDailyBolus/2; + dummies.add(dummy); + elem1.recordDailyBasal /= 2; + elem1.recordDailyBolus /= 2; + } + } + historyList.addAll(dummies); + Collections.sort(historyList, new Comparator() { + @Override + public int compare(DanaRHistoryRecord lhs, DanaRHistoryRecord rhs) { + return (int) (rhs.recordDate-lhs.recordDate); + } + }); + return historyList; + } + @NonNull private static String getPumpStatus() { return MainApp.getConfigBuilder().shortStatus(false); @@ -276,25 +470,50 @@ public class ActionStringHandler { } //Check for Temp-Target: - TempTarget tempTarget = MainApp.getConfigBuilder().getTempTargetFromHistory(new Date().getTime()); + TempTarget tempTarget = MainApp.getConfigBuilder().getTempTargetFromHistory(System.currentTimeMillis()); if (tempTarget != null) { ret += "Temp Target: " + Profile.toUnitsString(tempTarget.low, Profile.fromMgdlToUnits(tempTarget.low, profile.getUnits()), profile.getUnits()) + " - " + Profile.toUnitsString(tempTarget.high, Profile.fromMgdlToUnits(tempTarget.high, profile.getUnits()), profile.getUnits()); ret += "\nuntil: " + DateUtil.timeString(tempTarget.originalEnd()); ret += "\n\n"; } - //Default Range/Target - Double maxBgDefault = Constants.MAX_BG_DEFAULT_MGDL; - Double minBgDefault = Constants.MIN_BG_DEFAULT_MGDL; - Double targetBgDefault = Constants.TARGET_BG_DEFAULT_MGDL; - if (!profile.getUnits().equals(Constants.MGDL)) { - maxBgDefault = Constants.MAX_BG_DEFAULT_MMOL; - minBgDefault = Constants.MIN_BG_DEFAULT_MMOL; - targetBgDefault = Constants.TARGET_BG_DEFAULT_MMOL; - } ret += "DEFAULT RANGE: "; - ret += SP.getDouble("openapsma_min_bg", minBgDefault) + " - " + SP.getDouble("openapsma_max_bg", maxBgDefault); - ret += " target: " + SP.getDouble("openapsma_target_bg", targetBgDefault); + ret += profile.getTargetLow() + " - " + profile.getTargetHigh(); + ret += " target: " + (profile.getTargetLow() + profile.getTargetHigh()) / 2; + return ret; + } + + private static String getOAPSResultStatus() { + String ret = ""; + if (!Config.APS) { + return "Only apply in APS mode!"; + } + Profile profile = MainApp.getConfigBuilder().getProfile(); + if (profile == null) { + return "No profile set :("; + } + + APSInterface usedAPS = MainApp.getConfigBuilder().getActiveAPS(); + if (usedAPS == null) { + return "No active APS :(!"; + } + + APSResult result = usedAPS.getLastAPSResult(); + if (result == null) { + return "Last result not available!"; + } + + if (!result.changeRequested) { + ret += MainApp.sResources.getString(R.string.nochangerequested) + "\n"; + } else if (result.rate == 0 && result.duration == 0) { + ret += MainApp.sResources.getString(R.string.canceltemp)+ "\n"; + } else { + ret += MainApp.sResources.getString(R.string.rate) + ": " + DecimalFormatter.to2Decimal(result.rate) + " U/h " + + "(" + DecimalFormatter.to2Decimal(result.rate / MainApp.getConfigBuilder().getBaseBasalRate() * 100) + "%)\n" + + MainApp.sResources.getString(R.string.duration) + ": " + DecimalFormatter.to0Decimal(result.duration) + " min\n"; + } + ret += "\n" + MainApp.sResources.getString(R.string.reason) + ": " + result.reason; + return ret; } @@ -341,13 +560,37 @@ public class ActionStringHandler { double insulin = SafeParse.stringToDouble(act[1]); int carbs = SafeParse.stringToInt(act[2]); doBolus(insulin, carbs); + } else if ("cppset".equals(act[0])) { + int timeshift = SafeParse.stringToInt(act[1]); + int percentage = SafeParse.stringToInt(act[2]); + setCPP(percentage, timeshift); + } else if ("dismissoverviewnotification".equals(act[0])){ + MainApp.bus().post(new EventDismissNotification(SafeParse.stringToInt(act[1]))); } lastBolusWizard = null; } + private static void setCPP(int percentage, int timeshift) { + Object activeProfile = MainApp.getConfigBuilder().getActiveProfileInterface(); + CircadianPercentageProfilePlugin cpp = (CircadianPercentageProfilePlugin) MainApp.getSpecificPlugin(CircadianPercentageProfilePlugin.class); + + if(cpp == null || activeProfile==null || cpp != activeProfile){ + sendError("CPP not activated!"); + return; + } + String msg = cpp.externallySetParameters(timeshift, percentage); + if(msg != null && !"".equals(msg)){ + String rTitle = "STATUS"; + String rAction = "statusmessage"; + WearFragment.getPlugin(MainApp.instance()).requestActionConfirmation(rTitle, msg, rAction); + lastSentTimestamp = System.currentTimeMillis(); + lastConfirmActionString = rAction; + } + } + private static void generateTempTarget(int duration, double low, double high) { TempTarget tempTarget = new TempTarget(); - tempTarget.date = new Date().getTime(); + tempTarget.date = System.currentTimeMillis(); tempTarget.durationInMinutes = duration; tempTarget.reason = "WearPlugin"; tempTarget.source = Source.USER; @@ -410,4 +653,19 @@ public class ActionStringHandler { lastConfirmActionString = null; lastBolusWizard = null; } + + private synchronized static void sendStatusmessage(String title, String message) { + WearFragment.getPlugin(MainApp.instance()).requestActionConfirmation(title, message, "statusmessage"); + lastSentTimestamp = System.currentTimeMillis(); + lastConfirmActionString = null; + lastBolusWizard = null; + } + + public synchronized static void expectNotificationAction(String message, int id) { + String actionstring = "dismissoverviewnotification " + id; + WearFragment.getPlugin(MainApp.instance()).requestActionConfirmation("DISMISS", message, actionstring); + lastSentTimestamp = System.currentTimeMillis(); + lastConfirmActionString = actionstring; + lastBolusWizard = null; + } } 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 0c8932278e..c115819f0d 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 @@ -13,16 +13,15 @@ import info.nightscout.androidaps.events.EventExtendedBolusChange; import info.nightscout.androidaps.events.EventNewBG; import info.nightscout.androidaps.events.EventNewBasalProfile; import info.nightscout.androidaps.events.EventPreferenceChange; -import info.nightscout.androidaps.events.EventRefreshGui; +import info.nightscout.androidaps.events.EventRefreshOverview; import info.nightscout.androidaps.events.EventTempBasalChange; import info.nightscout.androidaps.events.EventTreatmentChange; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.plugins.Loop.LoopPlugin; -import info.nightscout.androidaps.plugins.Loop.events.EventNewOpenLoopNotification; import info.nightscout.androidaps.plugins.Overview.events.EventDismissBolusprogressIfRunning; import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress; import info.nightscout.androidaps.plugins.Wear.wearintegration.WatchUpdaterService; -import info.nightscout.utils.ToastUtils; +import info.nightscout.utils.SP; /** * Created by adrian on 17/11/16. @@ -166,7 +165,7 @@ public class WearPlugin implements PluginBase { } @Subscribe - public void onStatusEvent(final EventRefreshGui ev) { + public void onStatusEvent(final EventRefreshOverview ev) { LoopPlugin activeloop = MainApp.getConfigBuilder().getActiveLoop(); if (activeloop == null) return; @@ -230,5 +229,10 @@ public class WearPlugin implements PluginBase { watchUS = null; } + public void overviewNotification(int id, String message) { + if(SP.getBoolean("wear_overview_notification", false)){ + ActionStringHandler.expectNotificationAction(message, id); + } + } } 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 d58742d32a..93a85686b3 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 @@ -19,6 +19,9 @@ import com.google.android.gms.wearable.PutDataRequest; import com.google.android.gms.wearable.Wearable; import com.google.android.gms.wearable.WearableListenerService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -37,6 +40,7 @@ import info.nightscout.androidaps.interfaces.TreatmentsInterface; import info.nightscout.androidaps.plugins.Loop.LoopPlugin; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.plugins.Overview.OverviewPlugin; +import info.nightscout.androidaps.plugins.ProfileCircadianPercentage.CircadianPercentageProfilePlugin; import info.nightscout.androidaps.plugins.Wear.ActionStringHandler; import info.nightscout.androidaps.plugins.Wear.WearPlugin; import info.nightscout.utils.DecimalFormatter; @@ -72,6 +76,9 @@ public class WatchUpdaterService extends WearableListenerService implements SharedPreferences mPrefs; private static boolean lastLoopStatus; + private static Logger log = LoggerFactory.getLogger(CircadianPercentageProfilePlugin.class); + + @Override public void onCreate() { mPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); @@ -169,13 +176,13 @@ public class WatchUpdaterService extends WearableListenerService implements if (event != null && event.getPath().equals(WEARABLE_INITIATE_ACTIONSTRING_PATH)) { String actionstring = new String(event.getData()); - ToastUtils.showToastInUiThread(this, "Wear: " + actionstring); + log.debug("Wear: " + actionstring); ActionStringHandler.handleInitiate(actionstring); } if (event != null && event.getPath().equals(WEARABLE_CONFIRM_ACTIONSTRING_PATH)) { String actionstring = new String(event.getData()); - ToastUtils.showToastInUiThread(this, "Wear Confirm: " + actionstring); + log.debug("Wear Confirm: " + actionstring); ActionStringHandler.handleConfirmation(actionstring); } } @@ -209,14 +216,13 @@ public class WatchUpdaterService extends WearableListenerService implements } private DataMap dataMapSingleBG(BgReading lastBG, GlucoseStatus glucoseStatus) { - Profile profile = MainApp.getConfigBuilder().getProfile(); - if (profile == null) return null; + String units = MainApp.getConfigBuilder().getProfileUnits(); Double lowLine = SafeParse.stringToDouble(mPrefs.getString("low_mark", "0")); Double highLine = SafeParse.stringToDouble(mPrefs.getString("high_mark", "0")); //convert to mg/dl - if (!profile.getUnits().equals(Constants.MGDL)) { + if (!units.equals(Constants.MGDL)) { lowLine *= Constants.MMOLL_TO_MGDL; highLine *= Constants.MMOLL_TO_MGDL; @@ -239,7 +245,7 @@ public class WatchUpdaterService extends WearableListenerService implements DataMap dataMap = new DataMap(); int battery = getBatteryLevel(getApplicationContext()); - dataMap.putString("sgvString", lastBG.valueToUnitsToString(profile.getUnits())); + dataMap.putString("sgvString", lastBG.valueToUnitsToString(units)); dataMap.putDouble("timestamp", lastBG.date); if (glucoseStatus == null) { dataMap.putString("slopeArrow", ""); @@ -247,8 +253,8 @@ public class WatchUpdaterService extends WearableListenerService implements dataMap.putString("avgDelta", ""); } else { dataMap.putString("slopeArrow", slopeArrow(glucoseStatus.delta)); - dataMap.putString("delta", deltastring(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, profile.getUnits())); - dataMap.putString("avgDelta", deltastring(glucoseStatus.avgdelta, glucoseStatus.avgdelta * Constants.MGDL_TO_MMOLL, profile.getUnits())); + dataMap.putString("delta", deltastring(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units)); + dataMap.putString("avgDelta", deltastring(glucoseStatus.avgdelta, glucoseStatus.avgdelta * Constants.MGDL_TO_MMOLL, units)); } dataMap.putString("battery", "" + battery); dataMap.putLong("sgvLevel", sgvLevel); @@ -498,7 +504,7 @@ public class WatchUpdaterService extends WearableListenerService implements dataMapRequest.getDataMap().putString("message", message); dataMapRequest.getDataMap().putString("actionstring", actionstring); - ToastUtils.showToastInUiThread(this, "Requesting confirmation from wear: " + actionstring); + log.debug("Requesting confirmation from wear: " + actionstring); PutDataRequest putDataRequest = dataMapRequest.asPutDataRequest(); Wearable.DataApi.putDataItem(googleApiClient, putDataRequest); @@ -526,7 +532,12 @@ public class WatchUpdaterService extends WearableListenerService implements @NonNull private String generateStatusString() { String status = ""; - boolean shortString = true; + + Profile profile = MainApp.getConfigBuilder().getProfile(); + if (profile == null) { + status = MainApp.sResources.getString(R.string.noprofile); + return status; + } LoopPlugin activeloop = MainApp.getConfigBuilder().getActiveLoop(); @@ -541,12 +552,9 @@ public class WatchUpdaterService extends WearableListenerService implements TreatmentsInterface treatmentsInterface = MainApp.getConfigBuilder(); if (treatmentsInterface.isTempBasalInProgress()) { - TemporaryBasal activeTemp = treatmentsInterface.getTempBasalFromHistory(new Date().getTime()); - if (shortString) { - status += activeTemp.toStringShort(); - } else { - status += activeTemp.toStringMedium(); - } + TemporaryBasal activeTemp = treatmentsInterface.getTempBasalFromHistory(System.currentTimeMillis()); + status += activeTemp.toStringShort(); + } //IOB @@ -554,14 +562,13 @@ public class WatchUpdaterService extends WearableListenerService implements IobTotal bolusIob = treatmentsInterface.getLastCalculationTreatments().round(); treatmentsInterface.updateTotalIOBTempBasals(); IobTotal basalIob = treatmentsInterface.getLastCalculationTempBasals().round(); - status += (shortString ? "" : (getString(R.string.treatments_iob_label_string) + " ")) + DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob); + status += DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob); if (mPrefs.getBoolean("wear_detailediob", true)) { status += "(" + DecimalFormatter.to2Decimal(bolusIob.iob) + "|" + DecimalFormatter.to2Decimal(basalIob.basaliob) + ")"; } - Profile profile = MainApp.getConfigBuilder().getProfile(); if (!mPrefs.getBoolean("wear_showbgi", false)) { return status; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/XDripStatusline/StatuslineFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/XDripStatusline/StatuslineFragment.java deleted file mode 100644 index ba2cbc0783..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/XDripStatusline/StatuslineFragment.java +++ /dev/null @@ -1,29 +0,0 @@ -package info.nightscout.androidaps.plugins.XDripStatusline; - -import android.content.Context; -import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import info.nightscout.androidaps.R; - -/** - * Created by adrian on 17/11/16. - */ - -public class StatuslineFragment extends Fragment { - - private static StatuslinePlugin statuslinePlugin; - - public static StatuslinePlugin getPlugin(Context ctx) { - - if (statuslinePlugin == null) { - statuslinePlugin = new StatuslinePlugin(ctx); - } - - return statuslinePlugin; - } - -} 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 35b82d185c..45b5867886 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,23 +9,21 @@ import android.support.annotation.NonNull; import com.squareup.otto.Subscribe; -import java.util.Date; - 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.EventExtendedBolusChange; import info.nightscout.androidaps.events.EventNewBG; import info.nightscout.androidaps.events.EventPreferenceChange; -import info.nightscout.androidaps.events.EventRefreshGui; +import info.nightscout.androidaps.events.EventRefreshOverview; import info.nightscout.androidaps.events.EventTempBasalChange; import info.nightscout.androidaps.events.EventTreatmentChange; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.TreatmentsInterface; import info.nightscout.androidaps.plugins.Loop.LoopPlugin; -import info.nightscout.androidaps.data.Profile; import info.nightscout.utils.DecimalFormatter; /** @@ -46,6 +44,17 @@ public class StatuslinePlugin implements PluginBase { private final Context ctx; SharedPreferences mPrefs; + private static StatuslinePlugin statuslinePlugin; + + public static StatuslinePlugin getPlugin(Context ctx) { + + if (statuslinePlugin == null) { + statuslinePlugin = new StatuslinePlugin(ctx); + } + + return statuslinePlugin; + } + StatuslinePlugin(Context ctx) { this.ctx = ctx; this.mPrefs = PreferenceManager.getDefaultSharedPreferences(ctx); @@ -58,7 +67,7 @@ public class StatuslinePlugin implements PluginBase { @Override public String getFragmentClass() { - return StatuslineFragment.class.getName(); + return null; } @Override @@ -151,8 +160,6 @@ public class StatuslinePlugin implements PluginBase { @NonNull private String buildStatusString() { String status = ""; - boolean shortString = true; // make setting? - LoopPlugin activeloop = MainApp.getConfigBuilder().getActiveLoop(); if (activeloop != null && !activeloop.isEnabled(PluginBase.LOOP)) { @@ -166,12 +173,9 @@ public class StatuslinePlugin implements PluginBase { TreatmentsInterface treatmentsInterface = MainApp.getConfigBuilder(); if (treatmentsInterface.isTempBasalInProgress()) { - TemporaryBasal activeTemp = treatmentsInterface.getTempBasalFromHistory(new Date().getTime()); - if (shortString) { - status += activeTemp.toStringShort(); - } else { - status += activeTemp.toStringMedium(); - } + TemporaryBasal activeTemp = treatmentsInterface.getTempBasalFromHistory(System.currentTimeMillis()); + status += activeTemp.toStringShort(); + } //IOB @@ -179,7 +183,7 @@ public class StatuslinePlugin implements PluginBase { IobTotal bolusIob = treatmentsInterface.getLastCalculationTreatments().round(); treatmentsInterface.updateTotalIOBTempBasals(); IobTotal basalIob = treatmentsInterface.getLastCalculationTempBasals().round(); - status += (shortString ? "" : (ctx.getString(R.string.treatments_iob_label_string) + " ")) + DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob); + status += DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob); if (mPrefs.getBoolean("xdripstatus_detailediob", true)) { @@ -227,7 +231,7 @@ public class StatuslinePlugin implements PluginBase { } @Subscribe - public void onStatusEvent(final EventRefreshGui ev) { + public void onStatusEvent(final EventRefreshOverview ev) { //Filter events where loop is (de)activated 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 6b48804926..e3c77d0122 100644 --- a/app/src/main/java/info/nightscout/androidaps/receivers/KeepAliveReceiver.java +++ b/app/src/main/java/info/nightscout/androidaps/receivers/KeepAliveReceiver.java @@ -40,7 +40,7 @@ public class KeepAliveReceiver extends BroadcastReceiver { boolean isStatusOutdated = false; Date lastConnection = pump.lastDataTime(); - if (lastConnection.getTime() + 30 * 60 * 1000L < new Date().getTime()) + if (lastConnection.getTime() + 30 * 60 * 1000L < System.currentTimeMillis()) isStatusOutdated = true; if (Math.abs(profile.getBasal() - pump.getBaseBasalRate()) > pump.getPumpDescription().basalStep) isBasalOutdated = true; diff --git a/app/src/main/java/info/nightscout/androidaps/receivers/NSAlarmReceiver.java b/app/src/main/java/info/nightscout/androidaps/receivers/NSAlarmReceiver.java new file mode 100644 index 0000000000..bff2e6695a --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/receivers/NSAlarmReceiver.java @@ -0,0 +1,48 @@ +package info.nightscout.androidaps.receivers; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; + +import org.json.JSONException; +import org.json.JSONObject; + +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.Services.Intents; +import info.nightscout.androidaps.plugins.NSClientInternal.data.NSAlarm; +import info.nightscout.androidaps.plugins.Overview.Notification; +import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification; +import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; + +public class NSAlarmReceiver extends BroadcastReceiver { + + @Override + public void onReceive(Context context, Intent intent) { + if (intent == null) + return; + Bundle bundle = intent.getExtras(); + String data = bundle.getString("data"); + JSONObject json = null; + try { + json = new JSONObject(data); + } catch (JSONException e) { + e.printStackTrace(); + return; + } + NSAlarm nsAlarm = new NSAlarm(json); + switch (intent.getAction()) { + case Intents.ACTION_ANNOUNCEMENT: + case Intents.ACTION_ALARM: + case Intents.ACTION_URGENT_ALARM: + Notification notification = new Notification(nsAlarm); + if (notification.isEnabled()) + MainApp.bus().post(new EventNewNotification(notification)); + break; + case Intents.ACTION_CLEAR_ALARM: + MainApp.bus().post(new EventDismissNotification(Notification.NSALARM)); + MainApp.bus().post(new EventDismissNotification(Notification.NSURGENTALARM)); + break; + } + } +} 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 b6eaf73ce4..8dff2aec93 100644 --- a/app/src/main/java/info/nightscout/androidaps/tabs/TabPageAdapter.java +++ b/app/src/main/java/info/nightscout/androidaps/tabs/TabPageAdapter.java @@ -59,7 +59,7 @@ public class TabPageAdapter extends FragmentStatePagerAdapter { } public void registerNewFragment(PluginBase plugin) { - if (plugin.isVisibleInTabs(plugin.getType())) { + if (plugin.hasFragment() && plugin.isVisibleInTabs(plugin.getType())) { visibleFragmentList.add(plugin); notifyDataSetChanged(); } diff --git a/app/src/main/java/info/nightscout/utils/BolusWizard.java b/app/src/main/java/info/nightscout/utils/BolusWizard.java index ea34c7c8f9..f4eb4907ef 100644 --- a/app/src/main/java/info/nightscout/utils/BolusWizard.java +++ b/app/src/main/java/info/nightscout/utils/BolusWizard.java @@ -47,9 +47,14 @@ public class BolusWizard { // Result public Double calculatedTotalInsulin = 0d; + public Double totalBeforePercentageAdjustment = 0d; public Double carbsEquivalent = 0d; public Double doCalc(Profile specificProfile, Integer carbs, Double cob, Double bg, Double correction, Boolean includeBolusIOB, Boolean includeBasalIOB, Boolean superBolus, Boolean trend) { + return doCalc(specificProfile, carbs, cob, bg, correction, 100d, includeBolusIOB, includeBasalIOB, superBolus, trend); + } + + public Double doCalc(Profile specificProfile, Integer carbs, Double cob, Double bg, Double correction, double percentageCorrection, Boolean includeBolusIOB, Boolean includeBasalIOB, Boolean superBolus, Boolean trend) { this.specificProfile = specificProfile; this.carbs = carbs; this.bg = bg; @@ -97,20 +102,27 @@ public class BolusWizard { // Insulin from superbolus for 2h. Get basal rate now and after 1h if (superBolus) { insulinFromSuperBolus = specificProfile.getBasal(); - long timeAfter1h = new Date().getTime(); + long timeAfter1h = System.currentTimeMillis(); timeAfter1h += 60L * 60 * 1000; - insulinFromSuperBolus += specificProfile.getBasal(Profile.secondsFromMidnight(new Date(timeAfter1h))); + insulinFromSuperBolus += specificProfile.getBasal(timeAfter1h); } // Total - calculatedTotalInsulin = insulinFromBG + insulinFromTrend + insulinFromCarbs + insulingFromBolusIOB + insulingFromBasalsIOB + insulinFromCorrection + insulinFromSuperBolus + insulinFromCOB; + calculatedTotalInsulin = totalBeforePercentageAdjustment = insulinFromBG + insulinFromTrend + insulinFromCarbs + insulingFromBolusIOB + insulingFromBasalsIOB + insulinFromCorrection + insulinFromSuperBolus + insulinFromCOB; + + //percentage + if(totalBeforePercentageAdjustment > 0){ + calculatedTotalInsulin = totalBeforePercentageAdjustment*percentageCorrection/100d; + } + if (calculatedTotalInsulin < 0) { carbsEquivalent = -calculatedTotalInsulin * ic; calculatedTotalInsulin = 0d; } - calculatedTotalInsulin = Round.roundTo(calculatedTotalInsulin, 0.05d); + double bolusStep = MainApp.getConfigBuilder().getPumpDescription().bolusStep; + calculatedTotalInsulin = Round.roundTo(calculatedTotalInsulin, bolusStep); return calculatedTotalInsulin; } diff --git a/app/src/main/java/info/nightscout/utils/DateUtil.java b/app/src/main/java/info/nightscout/utils/DateUtil.java index c4efa45f93..b058450512 100644 --- a/app/src/main/java/info/nightscout/utils/DateUtil.java +++ b/app/src/main/java/info/nightscout/utils/DateUtil.java @@ -3,6 +3,7 @@ package info.nightscout.utils; import android.text.format.DateUtils; import java.text.DateFormat; +import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; @@ -12,6 +13,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; /** * The Class DateUtil. A simple wrapper around SimpleDateFormat to ease the handling of iso date string <-> date obj @@ -23,6 +25,7 @@ public class DateUtil { * The date format in iso. */ public static String FORMAT_DATE_ISO = "yyyy-MM-dd'T'HH:mm:ss'Z'"; + public static String FORMAT_DATE_ISO_MSEC = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"; /** * Takes in an ISO date string of the following format: @@ -35,8 +38,15 @@ public class DateUtil { public static Date fromISODateString(String isoDateString) throws Exception { SimpleDateFormat f = new SimpleDateFormat(FORMAT_DATE_ISO); + Date date; f.setTimeZone(TimeZone.getTimeZone("UTC")); - Date date = f.parse(isoDateString); + try { + date = f.parse(isoDateString); + } catch (ParseException e) { + f = new SimpleDateFormat(FORMAT_DATE_ISO_MSEC); + f.setTimeZone(TimeZone.getTimeZone("UTC")); + date = f.parse(isoDateString); + } return date; } @@ -111,4 +121,10 @@ public class DateUtil { public static String dateAndTimeString(long mills) { return dateString(mills) + " " + timeString(mills); } + + public static String minAgo(long time) { + int mins = (int) ((System.currentTimeMillis() - time) / 1000 / 60); + return String.format(MainApp.sResources.getString(R.string.minago), mins); + } + } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/utils/NSUpload.java b/app/src/main/java/info/nightscout/utils/NSUpload.java index 86d15dc9b7..09ecbc9370 100644 --- a/app/src/main/java/info/nightscout/utils/NSUpload.java +++ b/app/src/main/java/info/nightscout/utils/NSUpload.java @@ -3,6 +3,7 @@ package info.nightscout.utils; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; +import android.os.Build; import android.os.Bundle; import android.preference.PreferenceManager; @@ -47,8 +48,7 @@ public class NSUpload { if (temporaryBasal.pumpId != 0) data.put("pumpId", temporaryBasal.pumpId); data.put("created_at", DateUtil.toISOString(temporaryBasal.date)); - data.put("enteredBy", MainApp.instance().getString(R.string.app_name)); - data.put("notes", MainApp.sResources.getString(R.string.androidaps_tempbasalstartnote) + " " + temporaryBasal.absoluteRate + "u/h " + temporaryBasal.durationInMinutes + " min"); // ECOR + data.put("enteredBy", "openaps://" + MainApp.instance().getString(R.string.app_name)); if (originalExtendedAmount != null) data.put("originalExtendedAmount", originalExtendedAmount); // for back synchronization Bundle bundle = new Bundle(); @@ -86,8 +86,7 @@ public class NSUpload { if (temporaryBasal.pumpId != 0) data.put("pumpId", temporaryBasal.pumpId); data.put("created_at", DateUtil.toISOString(temporaryBasal.date)); - data.put("enteredBy", MainApp.instance().getString(R.string.app_name)); - data.put("notes", MainApp.sResources.getString(R.string.androidaps_tempbasalstartnote) + " " + temporaryBasal.percentRate + "% " + temporaryBasal.durationInMinutes + " min"); // ECOR + data.put("enteredBy", "openaps://" + MainApp.instance().getString(R.string.app_name)); Bundle bundle = new Bundle(); bundle.putString("action", "dbAdd"); bundle.putString("collection", "treatments"); @@ -109,8 +108,7 @@ public class NSUpload { JSONObject data = new JSONObject(); data.put("eventType", CareportalEvent.TEMPBASAL); data.put("created_at", DateUtil.toISOString(time)); - data.put("enteredBy", MainApp.instance().getString(R.string.app_name)); - data.put("notes", MainApp.sResources.getString(R.string.androidaps_tempbasalendnote)); // ECOR + data.put("enteredBy", "openaps://" + MainApp.instance().getString(R.string.app_name)); if (isFakedTempBasal) data.put("isFakedTempBasal", isFakedTempBasal); if (pumpId != 0) @@ -142,7 +140,7 @@ public class NSUpload { if (extendedBolus.pumpId != 0) data.put("pumpId", extendedBolus.pumpId); data.put("created_at", DateUtil.toISOString(extendedBolus.date)); - data.put("enteredBy", MainApp.instance().getString(R.string.app_name)); + data.put("enteredBy", "openaps://" + MainApp.instance().getString(R.string.app_name)); Bundle bundle = new Bundle(); bundle.putString("action", "dbAdd"); bundle.putString("collection", "treatments"); @@ -168,7 +166,7 @@ public class NSUpload { data.put("enteredinsulin", 0); data.put("relative", 0); data.put("created_at", DateUtil.toISOString(time)); - data.put("enteredBy", MainApp.instance().getString(R.string.app_name)); + data.put("enteredBy", "openaps://" + MainApp.instance().getString(R.string.app_name)); if (pumpId != 0) data.put("pumpId", pumpId); Bundle bundle = new Bundle(); @@ -189,7 +187,7 @@ public class NSUpload { DeviceStatus deviceStatus = new DeviceStatus(); try { LoopPlugin.LastRun lastRun = LoopPlugin.lastRun; - if (lastRun != null && lastRun.lastAPSRun.getTime() > new Date().getTime() - 300 * 1000L) { + if (lastRun != null && lastRun.lastAPSRun.getTime() > System.currentTimeMillis() - 300 * 1000L) { // do not send if result is older than 1 min APSResult apsResult = lastRun.request; apsResult.json().put("timestamp", DateUtil.toISOString(lastRun.lastAPSRun)); @@ -221,7 +219,7 @@ public class NSUpload { } else { log.debug("OpenAPS data too old to upload"); } - deviceStatus.device = "openaps://" + MainApp.getConfigBuilder().deviceID(); + deviceStatus.device = "openaps://" + Build.MANUFACTURER + " " + Build.MODEL; JSONObject pumpstatus = MainApp.getConfigBuilder().getJSONStatus(); if (pumpstatus != null) { deviceStatus.pump = pumpstatus; @@ -254,6 +252,7 @@ public class NSUpload { if (detailedBolusInfo.carbs != 0d) data.put("carbs", (int) detailedBolusInfo.carbs); data.put("created_at", DateUtil.toISOString(detailedBolusInfo.date)); data.put("date", detailedBolusInfo.date); + data.put("isSMB", detailedBolusInfo.isSMB); if (detailedBolusInfo.pumpId != 0) data.put("pumpId", detailedBolusInfo.pumpId); if (detailedBolusInfo.glucose != 0d) @@ -301,7 +300,7 @@ public class NSUpload { if (data.has("enteredBy")) prebolus.put("enteredBy", data.get("enteredBy")); if (data.has("notes")) prebolus.put("notes", data.get("notes")); long mills = DateUtil.fromISODateString(data.getString("created_at")).getTime(); - Date preBolusDate = new Date(mills + data.getInt("preBolus") * 60000L); + Date preBolusDate = new Date(mills + data.getInt("preBolus") * 60000L + 1000L); prebolus.put("created_at", DateUtil.toISOString(preBolusDate)); uploadCareportalEntryToNS(prebolus); } @@ -346,7 +345,7 @@ public class NSUpload { data.put("eventType", "OpenAPS Offline"); data.put("duration", durationInMinutes); data.put("created_at", DateUtil.toISOString(new Date())); - data.put("enteredBy", MainApp.instance().getString(R.string.app_name)); + data.put("enteredBy", "openaps://" + MainApp.instance().getString(R.string.app_name)); Bundle bundle = new Bundle(); bundle.putString("action", "dbAdd"); bundle.putString("collection", "treatments"); diff --git a/app/src/main/java/info/nightscout/utils/NumberPicker.java b/app/src/main/java/info/nightscout/utils/NumberPicker.java new file mode 100644 index 0000000000..ce960cbe7a --- /dev/null +++ b/app/src/main/java/info/nightscout/utils/NumberPicker.java @@ -0,0 +1,248 @@ +package info.nightscout.utils; + +import android.content.Context; +import android.os.Handler; +import android.os.Message; +import android.text.TextWatcher; +import android.util.AttributeSet; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.LinearLayout; +import android.widget.TextView; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.text.NumberFormat; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; + +/** + * Created by mike on 28.06.2016. + */ +public class NumberPicker extends LinearLayout implements View.OnKeyListener, + View.OnTouchListener, View.OnClickListener { + private static Logger log = LoggerFactory.getLogger(NumberPicker.class); + + TextView editText; + Button minusButton; + Button plusButton; + + Double value; + Double minValue = 0d; + Double maxValue = 1d; + Double step = 1d; + NumberFormat formater; + boolean allowZero = false; + + private Handler mHandler; + private ScheduledExecutorService mUpdater; + + private class UpdateCounterTask implements Runnable { + private boolean mInc; + private int repeated = 0; + private int multiplier = 1; + + private final int doubleLimit = 5; + + public UpdateCounterTask(boolean inc) { + mInc = inc; + } + + public void run() { + Message msg = new Message(); + if (repeated % doubleLimit == 0) multiplier *= 2; + repeated++; + msg.arg1 = multiplier; + msg.arg2 = repeated; + if (mInc) { + msg.what = MSG_INC; + } else { + msg.what = MSG_DEC; + } + mHandler.sendMessage(msg); + } + } + + private static final int MSG_INC = 0; + private static final int MSG_DEC = 1; + + public NumberPicker(Context context) { + super(context, null); + } + + public NumberPicker(Context context, AttributeSet attrs) { + super(context, attrs); + + this.initialize(context, attrs); + } + + public NumberPicker(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + private void initialize(Context context, AttributeSet attrs) { + // set layout view + LayoutInflater.from(context).inflate(R.layout.number_picker_layout, this, true); + + // init ui components + this.minusButton = (Button) findViewById(R.id.decrement); + this.plusButton = (Button) findViewById(R.id.increment); + this.editText = (EditText) findViewById(R.id.display); + + mHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_INC: + inc(msg.arg1); + return; + case MSG_DEC: + dec(msg.arg1); + return; + } + super.handleMessage(msg); + } + }; + + minusButton.setOnTouchListener(this); + minusButton.setOnKeyListener(this); + minusButton.setOnClickListener(this); + plusButton.setOnTouchListener(this); + plusButton.setOnKeyListener(this); + plusButton.setOnClickListener(this); + } + + public void removeTextChangedListener(TextWatcher textWatcher) { + editText.removeTextChangedListener(textWatcher); + } + + public void addTextChangedListener(TextWatcher textWatcher) { + editText.addTextChangedListener(textWatcher); + } + + public void setParams(Double initValue, Double minValue, Double maxValue, Double step, NumberFormat formater, boolean allowZero, TextWatcher textWatcher) { + setParams(initValue, minValue, maxValue, step, formater, allowZero); + editText.addTextChangedListener(textWatcher); + } + + public void setParams(Double initValue, Double minValue, Double maxValue, Double step, NumberFormat formater, boolean allowZero) { + this.value = initValue; + this.minValue = minValue; + this.maxValue = maxValue; + this.step = step; + this.formater = formater; + this.allowZero = allowZero; + + updateEditText(); + } + + public void setValue(Double value) { + this.value = value; + updateEditText(); + } + + public Double getValue() { + return value; + } + + public String getText() { + return editText.getText().toString(); + } + + public void setStep(Double step) { + this.step = step; + } + + private void inc(int multiplier) { + value += step * multiplier; + if (value > maxValue) { + value = maxValue; + ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.youareonallowedlimit)); + stopUpdating(); + } + updateEditText(); + } + + private void dec( int multiplier) { + value -= step * multiplier; + if (value < minValue) { + value = minValue; + ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.youareonallowedlimit)); + stopUpdating(); + } + updateEditText(); + } + + private void updateEditText() { + if (value == 0d && !allowZero) + editText.setText(""); + else + editText.setText(formater.format(value)); + } + + private void startUpdating(boolean inc) { + if (mUpdater != null) { + log.debug("Another executor is still active"); + return; + } + mUpdater = Executors.newSingleThreadScheduledExecutor(); + mUpdater.scheduleAtFixedRate(new UpdateCounterTask(inc), 200, 200, + TimeUnit.MILLISECONDS); + } + + private void stopUpdating() { + if (mUpdater != null) { + mUpdater.shutdownNow(); + mUpdater = null; + } + } + + @Override + public void onClick(View v) { + if (mUpdater == null) { + if (v == plusButton) { + inc(1); + } else { + dec(1); + } + } + } + + @Override + public boolean onKey(View v, int keyCode, KeyEvent event) { + boolean isKeyOfInterest = keyCode == KeyEvent.KEYCODE_DPAD_CENTER || keyCode == KeyEvent.KEYCODE_ENTER; + boolean isReleased = event.getAction() == KeyEvent.ACTION_UP; + boolean isPressed = event.getAction() == KeyEvent.ACTION_DOWN + && event.getAction() != KeyEvent.ACTION_MULTIPLE; + + if (isKeyOfInterest && isReleased) { + stopUpdating(); + } else if (isKeyOfInterest && isPressed) { + startUpdating(v == plusButton); + } + return false; + } + + @Override + public boolean onTouch(View v, MotionEvent event) { + boolean isReleased = event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL; + boolean isPressed = event.getAction() == MotionEvent.ACTION_DOWN; + + if (isReleased) { + stopUpdating(); + } else if (isPressed) { + startUpdating(v == plusButton); + } + return false; + } + +} diff --git a/app/src/main/java/info/nightscout/utils/OKDialog.java b/app/src/main/java/info/nightscout/utils/OKDialog.java index 19fbe7c62a..72e0ddd8d2 100644 --- a/app/src/main/java/info/nightscout/utils/OKDialog.java +++ b/app/src/main/java/info/nightscout/utils/OKDialog.java @@ -4,6 +4,7 @@ import android.app.Activity; import android.content.DialogInterface; import android.support.v7.app.AlertDialog; import android.support.v7.view.ContextThemeWrapper; +import android.text.Spanned; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -41,4 +42,28 @@ public class OKDialog { log.debug("show_dialog exception: " + e); } } + + 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)); + builder.setTitle(title); + builder.setMessage(message); + builder.setPositiveButton(MainApp.sResources.getString(R.string.ok), new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + if (runnable != null) { + try { + Thread.sleep(100); + } catch (InterruptedException e) { + } + activity.runOnUiThread(runnable); + } + } + }); + + builder.create().show(); + } catch (Exception e) { + log.debug("show_dialog exception: " + e); + } + } } diff --git a/app/src/main/java/info/nightscout/utils/Profiler.java b/app/src/main/java/info/nightscout/utils/Profiler.java index 99093b238f..0410ad6ff8 100644 --- a/app/src/main/java/info/nightscout/utils/Profiler.java +++ b/app/src/main/java/info/nightscout/utils/Profiler.java @@ -12,7 +12,7 @@ public class Profiler { public Profiler(){} static public void log(Logger log, String function, Date start) { - long msec = new Date().getTime() - start.getTime(); + long msec = System.currentTimeMillis() - start.getTime(); log.debug(">>> " + function + " <<< executed in " + msec + " miliseconds"); } } diff --git a/app/src/main/java/info/nightscout/utils/Round.java b/app/src/main/java/info/nightscout/utils/Round.java index f1fe3e0df6..26a4d5abce 100644 --- a/app/src/main/java/info/nightscout/utils/Round.java +++ b/app/src/main/java/info/nightscout/utils/Round.java @@ -4,7 +4,7 @@ package info.nightscout.utils; * Created by mike on 20.06.2016. */ public class Round { - public static Double roundTo(Double x, Double step) { + public static Double roundTo(double x, Double step) { if (x != 0d) { return Math.round(x / step) * step; } diff --git a/app/src/main/java/info/nightscout/utils/SP.java b/app/src/main/java/info/nightscout/utils/SP.java index 4733c42d04..36ab3b05e7 100644 --- a/app/src/main/java/info/nightscout/utils/SP.java +++ b/app/src/main/java/info/nightscout/utils/SP.java @@ -49,11 +49,19 @@ public class SP { } static public int getInt(int resourceID, Integer defaultValue) { - return SafeParse.stringToInt(sharedPreferences.getString(MainApp.sResources.getString(resourceID), defaultValue.toString())); + try { + return sharedPreferences.getInt(MainApp.sResources.getString(resourceID), defaultValue); + } catch (Exception e) { + return SafeParse.stringToInt(sharedPreferences.getString(MainApp.sResources.getString(resourceID), defaultValue.toString())); + } } static public int getInt(String key, Integer defaultValue) { - return SafeParse.stringToInt(sharedPreferences.getString(key, defaultValue.toString())); + try { + return sharedPreferences.getInt(key, defaultValue); + } catch (Exception e) { + return SafeParse.stringToInt(sharedPreferences.getString(key, defaultValue.toString())); + } } static public long getLong(int resourceID, Long defaultValue) { @@ -80,18 +88,30 @@ public class SP { editor.apply(); } - static public void removeBoolean(int resourceID) { - SharedPreferences.Editor editor = sharedPreferences.edit(); - editor.remove(MainApp.sResources.getString(resourceID)); - editor.apply(); - } - static public void putLong(String key, long value) { SharedPreferences.Editor editor = sharedPreferences.edit(); editor.putLong(key, value); editor.apply(); } + static public void putLong(int resourceID, long value) { + SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.putLong(MainApp.sResources.getString(resourceID), value); + editor.apply(); + } + + static public void putInt(String key, int value) { + SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.putInt(key, value); + editor.apply(); + } + + static public void putInt(int resourceID, int value) { + SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.putInt(MainApp.sResources.getString(resourceID), value); + editor.apply(); + } + static public void putString(int resourceID, String value) { SharedPreferences.Editor editor = sharedPreferences.edit(); editor.putString(MainApp.sResources.getString(resourceID), value); @@ -104,9 +124,15 @@ public class SP { editor.apply(); } - static public void removeString(int resourceID) { + static public void remove(int resourceID) { SharedPreferences.Editor editor = sharedPreferences.edit(); editor.remove(MainApp.sResources.getString(resourceID)); editor.apply(); } + + static public void remove(String key) { + SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.remove(key); + editor.apply(); + } } diff --git a/app/src/main/java/info/nightscout/utils/SafeParse.java b/app/src/main/java/info/nightscout/utils/SafeParse.java index 8697daeebd..ff749f732b 100644 --- a/app/src/main/java/info/nightscout/utils/SafeParse.java +++ b/app/src/main/java/info/nightscout/utils/SafeParse.java @@ -11,6 +11,8 @@ public class SafeParse { public static Double stringToDouble(String input) { Double result = 0d; input = input.replace(",", "."); + if (input.equals("")) + return 0d; try { result = Double.parseDouble(input); } catch (Exception e) { @@ -22,6 +24,8 @@ public class SafeParse { public static Integer stringToInt(String input) { Integer result = 0; input = input.replace(",", "."); + if (input.equals("")) + return 0; try { result = Integer.parseInt(input); } catch (Exception e) { @@ -33,6 +37,8 @@ public class SafeParse { public static Long stringToLong(String input) { Long result = 0L; input = input.replace(",", "."); + if (input.equals("")) + return 0L; try { result = Long.parseLong(input); } catch (Exception e) { diff --git a/app/src/main/java/info/nightscout/utils/TimeListEdit.java b/app/src/main/java/info/nightscout/utils/TimeListEdit.java index ce1f604060..2ad591b1ef 100644 --- a/app/src/main/java/info/nightscout/utils/TimeListEdit.java +++ b/app/src/main/java/info/nightscout/utils/TimeListEdit.java @@ -25,6 +25,7 @@ import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.text.DecimalFormat; import java.text.NumberFormat; import java.util.ArrayList; @@ -285,12 +286,19 @@ public class TimeListEdit { public void editItem(int index, int timeAsSeconds, double value1, double value2) { try { + String time; + int hour = timeAsSeconds / 60 / 60; + DecimalFormat df = new DecimalFormat("00"); + time = df.format(hour) + ":00"; + JSONObject newObject1 = new JSONObject(); + newObject1.put("time", time); newObject1.put("timeAsSeconds", timeAsSeconds); newObject1.put("value", value1); data1.put(index, newObject1); if (data2 != null) { JSONObject newObject2 = new JSONObject(); + newObject1.put("time", time); newObject2.put("timeAsSeconds", timeAsSeconds); newObject2.put("value", value2); data2.put(index, newObject2); diff --git a/app/src/main/java/info/nightscout/utils/XdripCalibrations.java b/app/src/main/java/info/nightscout/utils/XdripCalibrations.java index 2bc60d3693..662b7a0c8f 100644 --- a/app/src/main/java/info/nightscout/utils/XdripCalibrations.java +++ b/app/src/main/java/info/nightscout/utils/XdripCalibrations.java @@ -44,13 +44,11 @@ public class XdripCalibrations { } public static boolean sendIntent(Double bg) { - final Profile profile = MainApp.getConfigBuilder().getProfile(); - Context context = MainApp.instance().getApplicationContext(); Bundle bundle = new Bundle(); bundle.putDouble("glucose_number", bg); - bundle.putString("units", profile.getUnits().equals(Constants.MGDL) ? "mgdl" : "mmol"); - bundle.putLong("timestamp", new Date().getTime()); + bundle.putString("units", MainApp.getConfigBuilder().getProfileUnits().equals(Constants.MGDL) ? "mgdl" : "mmol"); + bundle.putLong("timestamp", System.currentTimeMillis()); Intent intent = new Intent(Intents.ACTION_REMOTE_CALIBRATION); intent.putExtras(bundle); intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); diff --git a/app/src/main/res/drawable-hdpi/background_darkgray.xml b/app/src/main/res/drawable-hdpi/background_darkgray.xml new file mode 100644 index 0000000000..4d5138556b --- /dev/null +++ b/app/src/main/res/drawable-hdpi/background_darkgray.xml @@ -0,0 +1,9 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-hdpi/border_gray.xml b/app/src/main/res/drawable-hdpi/border_gray.xml new file mode 100644 index 0000000000..c2792233ee --- /dev/null +++ b/app/src/main/res/drawable-hdpi/border_gray.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable-hdpi/icon_actions_cancelextbolus.png b/app/src/main/res/drawable-hdpi/icon_actions_cancelextbolus.png new file mode 100644 index 0000000000..95761084a9 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_actions_cancelextbolus.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_actions_profileswitch.png b/app/src/main/res/drawable-hdpi/icon_actions_profileswitch.png new file mode 100644 index 0000000000..4b36a0cc23 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_actions_profileswitch.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_actions_refill.png b/app/src/main/res/drawable-hdpi/icon_actions_refill.png new file mode 100644 index 0000000000..ace25d1558 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_actions_refill.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_actions_startextbolus.png b/app/src/main/res/drawable-hdpi/icon_actions_startextbolus.png new file mode 100644 index 0000000000..a67d52838c Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_actions_startextbolus.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_actions_starttempbasal.png b/app/src/main/res/drawable-hdpi/icon_actions_starttempbasal.png new file mode 100644 index 0000000000..8772df62a4 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_actions_starttempbasal.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_actions_temptarget.png b/app/src/main/res/drawable-hdpi/icon_actions_temptarget.png new file mode 100644 index 0000000000..f839a6894b Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_actions_temptarget.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_bolus.png b/app/src/main/res/drawable-hdpi/icon_bolus.png new file mode 100644 index 0000000000..b212194219 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_bolus.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_calculator.png b/app/src/main/res/drawable-hdpi/icon_calculator.png new file mode 100644 index 0000000000..2eb2a3b96c Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_calculator.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_calibration.png b/app/src/main/res/drawable-hdpi/icon_calibration.png new file mode 100644 index 0000000000..605635f41d Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_calibration.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_cancelbasal.png b/app/src/main/res/drawable-hdpi/icon_cancelbasal.png new file mode 100644 index 0000000000..91803a3f3c Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_cancelbasal.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_cp_aaps_offline.png b/app/src/main/res/drawable-hdpi/icon_cp_aaps_offline.png new file mode 100644 index 0000000000..0fe1cd628b Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_cp_aaps_offline.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_cp_age_battery.png b/app/src/main/res/drawable-hdpi/icon_cp_age_battery.png new file mode 100644 index 0000000000..abc626901a Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_cp_age_battery.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_cp_age_canula.png b/app/src/main/res/drawable-hdpi/icon_cp_age_canula.png new file mode 100644 index 0000000000..ecccc39426 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_cp_age_canula.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_cp_age_insulin.png b/app/src/main/res/drawable-hdpi/icon_cp_age_insulin.png new file mode 100644 index 0000000000..ab4d345881 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_cp_age_insulin.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_cp_age_sensor.png b/app/src/main/res/drawable-hdpi/icon_cp_age_sensor.png new file mode 100644 index 0000000000..30d5d02de0 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_cp_age_sensor.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_cp_announcement.png b/app/src/main/res/drawable-hdpi/icon_cp_announcement.png new file mode 100644 index 0000000000..23c9a9847d Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_cp_announcement.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_cp_basal_end.png b/app/src/main/res/drawable-hdpi/icon_cp_basal_end.png new file mode 100644 index 0000000000..b9cdf5cc1f Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_cp_basal_end.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_cp_basal_start.png b/app/src/main/res/drawable-hdpi/icon_cp_basal_start.png new file mode 100644 index 0000000000..d79ca15f86 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_cp_basal_start.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_cp_bgcheck.png b/app/src/main/res/drawable-hdpi/icon_cp_bgcheck.png new file mode 100644 index 0000000000..56569a264a Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_cp_bgcheck.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_cp_bolus_carbs.png b/app/src/main/res/drawable-hdpi/icon_cp_bolus_carbs.png new file mode 100644 index 0000000000..ed6be099aa Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_cp_bolus_carbs.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_cp_bolus_combo.png b/app/src/main/res/drawable-hdpi/icon_cp_bolus_combo.png new file mode 100644 index 0000000000..98c076905c Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_cp_bolus_combo.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_cp_bolus_correction.png b/app/src/main/res/drawable-hdpi/icon_cp_bolus_correction.png new file mode 100644 index 0000000000..8ad7864406 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_cp_bolus_correction.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_cp_bolus_meal.png b/app/src/main/res/drawable-hdpi/icon_cp_bolus_meal.png new file mode 100644 index 0000000000..97dd4e2ed8 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_cp_bolus_meal.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_cp_bolus_snack.png b/app/src/main/res/drawable-hdpi/icon_cp_bolus_snack.png new file mode 100644 index 0000000000..710bf6e0da Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_cp_bolus_snack.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_cp_cgm_insert.png b/app/src/main/res/drawable-hdpi/icon_cp_cgm_insert.png new file mode 100644 index 0000000000..699be54792 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_cp_cgm_insert.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_cp_cgm_profile.png b/app/src/main/res/drawable-hdpi/icon_cp_cgm_profile.png new file mode 100644 index 0000000000..8887e60f27 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_cp_cgm_profile.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_cp_cgm_start.png b/app/src/main/res/drawable-hdpi/icon_cp_cgm_start.png new file mode 100644 index 0000000000..e917402c48 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_cp_cgm_start.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_cp_cgm_target.png b/app/src/main/res/drawable-hdpi/icon_cp_cgm_target.png new file mode 100644 index 0000000000..2cf826dad1 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_cp_cgm_target.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_cp_exercise.png b/app/src/main/res/drawable-hdpi/icon_cp_exercise.png new file mode 100644 index 0000000000..e9aee1ac8a Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_cp_exercise.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_cp_note.png b/app/src/main/res/drawable-hdpi/icon_cp_note.png new file mode 100644 index 0000000000..b6b752e150 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_cp_note.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_cp_pump_battery.png b/app/src/main/res/drawable-hdpi/icon_cp_pump_battery.png new file mode 100644 index 0000000000..b4a4f2923a Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_cp_pump_battery.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_cp_pump_canula.png b/app/src/main/res/drawable-hdpi/icon_cp_pump_canula.png new file mode 100644 index 0000000000..e75d9ed81d Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_cp_pump_canula.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_cp_pump_cartridge.png b/app/src/main/res/drawable-hdpi/icon_cp_pump_cartridge.png new file mode 100644 index 0000000000..f780c23e37 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_cp_pump_cartridge.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_cp_question.png b/app/src/main/res/drawable-hdpi/icon_cp_question.png new file mode 100644 index 0000000000..65102f2abf Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_cp_question.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_home_loop.png b/app/src/main/res/drawable-hdpi/icon_home_loop.png new file mode 100644 index 0000000000..b0f9f6ea29 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_home_loop.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_home_profile.png b/app/src/main/res/drawable-hdpi/icon_home_profile.png new file mode 100644 index 0000000000..b288171332 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_home_profile.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_home_target.png b/app/src/main/res/drawable-hdpi/icon_home_target.png new file mode 100644 index 0000000000..0b2f2b166a Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_home_target.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_quickwizard.png b/app/src/main/res/drawable-hdpi/icon_quickwizard.png new file mode 100644 index 0000000000..67a020c05e Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_quickwizard.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_actions_cancelextbolus.png b/app/src/main/res/drawable-mdpi/icon_actions_cancelextbolus.png new file mode 100644 index 0000000000..4ad378e374 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_actions_cancelextbolus.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_actions_profileswitch.png b/app/src/main/res/drawable-mdpi/icon_actions_profileswitch.png new file mode 100644 index 0000000000..eeae6ccfdb Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_actions_profileswitch.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_actions_refill.png b/app/src/main/res/drawable-mdpi/icon_actions_refill.png new file mode 100644 index 0000000000..737cca8b00 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_actions_refill.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_actions_startextbolus.png b/app/src/main/res/drawable-mdpi/icon_actions_startextbolus.png new file mode 100644 index 0000000000..338df773c2 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_actions_startextbolus.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_actions_starttempbasal.png b/app/src/main/res/drawable-mdpi/icon_actions_starttempbasal.png new file mode 100644 index 0000000000..18fbd8c111 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_actions_starttempbasal.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_actions_temptarget.png b/app/src/main/res/drawable-mdpi/icon_actions_temptarget.png new file mode 100644 index 0000000000..39170bab37 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_actions_temptarget.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_bolus.png b/app/src/main/res/drawable-mdpi/icon_bolus.png new file mode 100644 index 0000000000..c083219b45 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_bolus.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_calculator.png b/app/src/main/res/drawable-mdpi/icon_calculator.png new file mode 100644 index 0000000000..056722a440 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_calculator.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_calibration.png b/app/src/main/res/drawable-mdpi/icon_calibration.png new file mode 100644 index 0000000000..0929d3690d Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_calibration.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_cancelbasal.png b/app/src/main/res/drawable-mdpi/icon_cancelbasal.png new file mode 100644 index 0000000000..c48a20792d Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_cancelbasal.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_cp_aaps_offline.png b/app/src/main/res/drawable-mdpi/icon_cp_aaps_offline.png new file mode 100644 index 0000000000..dc50653883 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_cp_aaps_offline.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_cp_age_battery.png b/app/src/main/res/drawable-mdpi/icon_cp_age_battery.png new file mode 100644 index 0000000000..6c7fc56139 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_cp_age_battery.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_cp_age_canula.png b/app/src/main/res/drawable-mdpi/icon_cp_age_canula.png new file mode 100644 index 0000000000..303ad946cd Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_cp_age_canula.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_cp_age_insulin.png b/app/src/main/res/drawable-mdpi/icon_cp_age_insulin.png new file mode 100644 index 0000000000..5cd8598faa Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_cp_age_insulin.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_cp_age_sensor.png b/app/src/main/res/drawable-mdpi/icon_cp_age_sensor.png new file mode 100644 index 0000000000..d312b6c572 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_cp_age_sensor.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_cp_announcement.png b/app/src/main/res/drawable-mdpi/icon_cp_announcement.png new file mode 100644 index 0000000000..6e1338ac24 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_cp_announcement.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_cp_basal_end.png b/app/src/main/res/drawable-mdpi/icon_cp_basal_end.png new file mode 100644 index 0000000000..be8474f002 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_cp_basal_end.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_cp_basal_start.png b/app/src/main/res/drawable-mdpi/icon_cp_basal_start.png new file mode 100644 index 0000000000..34cd31f14b Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_cp_basal_start.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_cp_bgcheck.png b/app/src/main/res/drawable-mdpi/icon_cp_bgcheck.png new file mode 100644 index 0000000000..0cb14c2f57 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_cp_bgcheck.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_cp_bolus_carbs.png b/app/src/main/res/drawable-mdpi/icon_cp_bolus_carbs.png new file mode 100644 index 0000000000..561703fb06 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_cp_bolus_carbs.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_cp_bolus_combo.png b/app/src/main/res/drawable-mdpi/icon_cp_bolus_combo.png new file mode 100644 index 0000000000..ce4d8fb9d3 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_cp_bolus_combo.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_cp_bolus_correction.png b/app/src/main/res/drawable-mdpi/icon_cp_bolus_correction.png new file mode 100644 index 0000000000..582472dc92 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_cp_bolus_correction.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_cp_bolus_meal.png b/app/src/main/res/drawable-mdpi/icon_cp_bolus_meal.png new file mode 100644 index 0000000000..54b51e126e Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_cp_bolus_meal.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_cp_bolus_snack.png b/app/src/main/res/drawable-mdpi/icon_cp_bolus_snack.png new file mode 100644 index 0000000000..b2ba41c27d Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_cp_bolus_snack.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_cp_cgm_insert.png b/app/src/main/res/drawable-mdpi/icon_cp_cgm_insert.png new file mode 100644 index 0000000000..67c0fb1ba2 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_cp_cgm_insert.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_cp_cgm_profile.png b/app/src/main/res/drawable-mdpi/icon_cp_cgm_profile.png new file mode 100644 index 0000000000..e0f0a15cc8 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_cp_cgm_profile.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_cp_cgm_start.png b/app/src/main/res/drawable-mdpi/icon_cp_cgm_start.png new file mode 100644 index 0000000000..14a44bc852 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_cp_cgm_start.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_cp_cgm_target.png b/app/src/main/res/drawable-mdpi/icon_cp_cgm_target.png new file mode 100644 index 0000000000..86ce00442c Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_cp_cgm_target.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_cp_exercise.png b/app/src/main/res/drawable-mdpi/icon_cp_exercise.png new file mode 100644 index 0000000000..1c92c0ebb5 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_cp_exercise.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_cp_note.png b/app/src/main/res/drawable-mdpi/icon_cp_note.png new file mode 100644 index 0000000000..7c8663a4fe Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_cp_note.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_cp_pump_battery.png b/app/src/main/res/drawable-mdpi/icon_cp_pump_battery.png new file mode 100644 index 0000000000..f4dab169a8 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_cp_pump_battery.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_cp_pump_canula.png b/app/src/main/res/drawable-mdpi/icon_cp_pump_canula.png new file mode 100644 index 0000000000..ee512c5fef Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_cp_pump_canula.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_cp_pump_cartridge.png b/app/src/main/res/drawable-mdpi/icon_cp_pump_cartridge.png new file mode 100644 index 0000000000..70a90c596f Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_cp_pump_cartridge.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_cp_question.png b/app/src/main/res/drawable-mdpi/icon_cp_question.png new file mode 100644 index 0000000000..5d430d9164 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_cp_question.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_home_loop.png b/app/src/main/res/drawable-mdpi/icon_home_loop.png new file mode 100644 index 0000000000..5240cc85db Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_home_loop.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_home_profile.png b/app/src/main/res/drawable-mdpi/icon_home_profile.png new file mode 100644 index 0000000000..f689df10c6 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_home_profile.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_home_target.png b/app/src/main/res/drawable-mdpi/icon_home_target.png new file mode 100644 index 0000000000..9fc7086e9d Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_home_target.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_quickwizard.png b/app/src/main/res/drawable-mdpi/icon_quickwizard.png new file mode 100644 index 0000000000..d65347f235 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_quickwizard.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_actions_cancelextbolus.png b/app/src/main/res/drawable-xhdpi/icon_actions_cancelextbolus.png new file mode 100644 index 0000000000..8c4ee82d1e Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_actions_cancelextbolus.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_actions_profileswitch.png b/app/src/main/res/drawable-xhdpi/icon_actions_profileswitch.png new file mode 100644 index 0000000000..57864f6ed5 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_actions_profileswitch.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_actions_refill.png b/app/src/main/res/drawable-xhdpi/icon_actions_refill.png new file mode 100644 index 0000000000..ace20f3bfe Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_actions_refill.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_actions_startextbolus.png b/app/src/main/res/drawable-xhdpi/icon_actions_startextbolus.png new file mode 100644 index 0000000000..0e59f6ec36 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_actions_startextbolus.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_actions_starttempbasal.png b/app/src/main/res/drawable-xhdpi/icon_actions_starttempbasal.png new file mode 100644 index 0000000000..1deb6f3ca8 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_actions_starttempbasal.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_actions_temptarget.png b/app/src/main/res/drawable-xhdpi/icon_actions_temptarget.png new file mode 100644 index 0000000000..c484837e53 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_actions_temptarget.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_bolus.png b/app/src/main/res/drawable-xhdpi/icon_bolus.png new file mode 100644 index 0000000000..a472289d6b Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_bolus.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_calculator.png b/app/src/main/res/drawable-xhdpi/icon_calculator.png new file mode 100644 index 0000000000..9352f7b2a7 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_calculator.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_calibration.png b/app/src/main/res/drawable-xhdpi/icon_calibration.png new file mode 100644 index 0000000000..98a24e4c78 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_calibration.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_cancelbasal.png b/app/src/main/res/drawable-xhdpi/icon_cancelbasal.png new file mode 100644 index 0000000000..a6eb55c6cb Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_cancelbasal.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_cp_aaps_offline.png b/app/src/main/res/drawable-xhdpi/icon_cp_aaps_offline.png new file mode 100644 index 0000000000..4239e40ba7 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_cp_aaps_offline.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_cp_age_battery.png b/app/src/main/res/drawable-xhdpi/icon_cp_age_battery.png new file mode 100644 index 0000000000..3d75b9dc7a Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_cp_age_battery.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_cp_age_canula.png b/app/src/main/res/drawable-xhdpi/icon_cp_age_canula.png new file mode 100644 index 0000000000..8629a7998d Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_cp_age_canula.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_cp_age_insulin.png b/app/src/main/res/drawable-xhdpi/icon_cp_age_insulin.png new file mode 100644 index 0000000000..2e88ec9ad4 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_cp_age_insulin.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_cp_age_sensor.png b/app/src/main/res/drawable-xhdpi/icon_cp_age_sensor.png new file mode 100644 index 0000000000..a3577da118 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_cp_age_sensor.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_cp_announcement.png b/app/src/main/res/drawable-xhdpi/icon_cp_announcement.png new file mode 100644 index 0000000000..472b51d775 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_cp_announcement.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_cp_basal_end.png b/app/src/main/res/drawable-xhdpi/icon_cp_basal_end.png new file mode 100644 index 0000000000..c92af22df3 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_cp_basal_end.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_cp_basal_start.png b/app/src/main/res/drawable-xhdpi/icon_cp_basal_start.png new file mode 100644 index 0000000000..5e694ba89c Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_cp_basal_start.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_cp_bgcheck.png b/app/src/main/res/drawable-xhdpi/icon_cp_bgcheck.png new file mode 100644 index 0000000000..030099f910 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_cp_bgcheck.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_cp_bolus_carbs.png b/app/src/main/res/drawable-xhdpi/icon_cp_bolus_carbs.png new file mode 100644 index 0000000000..64815bc8f0 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_cp_bolus_carbs.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_cp_bolus_combo.png b/app/src/main/res/drawable-xhdpi/icon_cp_bolus_combo.png new file mode 100644 index 0000000000..908f33ccd8 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_cp_bolus_combo.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_cp_bolus_correction.png b/app/src/main/res/drawable-xhdpi/icon_cp_bolus_correction.png new file mode 100644 index 0000000000..0fe89d5f8b Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_cp_bolus_correction.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_cp_bolus_meal.png b/app/src/main/res/drawable-xhdpi/icon_cp_bolus_meal.png new file mode 100644 index 0000000000..52ef734adf Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_cp_bolus_meal.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_cp_bolus_snack.png b/app/src/main/res/drawable-xhdpi/icon_cp_bolus_snack.png new file mode 100644 index 0000000000..8d2e9690fc Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_cp_bolus_snack.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_cp_cgm_insert.png b/app/src/main/res/drawable-xhdpi/icon_cp_cgm_insert.png new file mode 100644 index 0000000000..af93321e3a Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_cp_cgm_insert.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_cp_cgm_profile.png b/app/src/main/res/drawable-xhdpi/icon_cp_cgm_profile.png new file mode 100644 index 0000000000..e4c50f2667 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_cp_cgm_profile.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_cp_cgm_start.png b/app/src/main/res/drawable-xhdpi/icon_cp_cgm_start.png new file mode 100644 index 0000000000..ce23d1cf54 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_cp_cgm_start.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_cp_cgm_target.png b/app/src/main/res/drawable-xhdpi/icon_cp_cgm_target.png new file mode 100644 index 0000000000..fbd5880490 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_cp_cgm_target.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_cp_exercise.png b/app/src/main/res/drawable-xhdpi/icon_cp_exercise.png new file mode 100644 index 0000000000..90cc102c07 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_cp_exercise.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_cp_note.png b/app/src/main/res/drawable-xhdpi/icon_cp_note.png new file mode 100644 index 0000000000..cf821a9d1f Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_cp_note.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_cp_pump_battery.png b/app/src/main/res/drawable-xhdpi/icon_cp_pump_battery.png new file mode 100644 index 0000000000..15af2af396 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_cp_pump_battery.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_cp_pump_canula.png b/app/src/main/res/drawable-xhdpi/icon_cp_pump_canula.png new file mode 100644 index 0000000000..84ae19c4a3 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_cp_pump_canula.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_cp_pump_cartridge.png b/app/src/main/res/drawable-xhdpi/icon_cp_pump_cartridge.png new file mode 100644 index 0000000000..d40a8540e6 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_cp_pump_cartridge.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_cp_question.png b/app/src/main/res/drawable-xhdpi/icon_cp_question.png new file mode 100644 index 0000000000..43df04ef81 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_cp_question.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_home_loop.png b/app/src/main/res/drawable-xhdpi/icon_home_loop.png new file mode 100644 index 0000000000..09ebbed57f Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_home_loop.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_home_profile.png b/app/src/main/res/drawable-xhdpi/icon_home_profile.png new file mode 100644 index 0000000000..95c0ca4502 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_home_profile.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_home_target.png b/app/src/main/res/drawable-xhdpi/icon_home_target.png new file mode 100644 index 0000000000..545ff5db79 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_home_target.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_quickwizard.png b/app/src/main/res/drawable-xhdpi/icon_quickwizard.png new file mode 100644 index 0000000000..b937f1448f Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_quickwizard.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_actions_cancelextbolus.png b/app/src/main/res/drawable-xxhdpi/icon_actions_cancelextbolus.png new file mode 100644 index 0000000000..d223d16d8f Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_actions_cancelextbolus.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_actions_profileswitch.png b/app/src/main/res/drawable-xxhdpi/icon_actions_profileswitch.png new file mode 100644 index 0000000000..29e28afe02 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_actions_profileswitch.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_actions_refill.png b/app/src/main/res/drawable-xxhdpi/icon_actions_refill.png new file mode 100644 index 0000000000..45cc5d3e1a Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_actions_refill.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_actions_startextbolus.png b/app/src/main/res/drawable-xxhdpi/icon_actions_startextbolus.png new file mode 100644 index 0000000000..e33b5e0a64 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_actions_startextbolus.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_actions_starttempbasal.png b/app/src/main/res/drawable-xxhdpi/icon_actions_starttempbasal.png new file mode 100644 index 0000000000..9e4aca67e2 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_actions_starttempbasal.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_actions_temptarget.png b/app/src/main/res/drawable-xxhdpi/icon_actions_temptarget.png new file mode 100644 index 0000000000..4fa88421ae Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_actions_temptarget.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_bolus.png b/app/src/main/res/drawable-xxhdpi/icon_bolus.png new file mode 100644 index 0000000000..efa063d54d Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_bolus.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_calculator.png b/app/src/main/res/drawable-xxhdpi/icon_calculator.png new file mode 100644 index 0000000000..18ab99e92b Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_calculator.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_calibration.png b/app/src/main/res/drawable-xxhdpi/icon_calibration.png new file mode 100644 index 0000000000..3fd492a623 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_calibration.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_cancelbasal.png b/app/src/main/res/drawable-xxhdpi/icon_cancelbasal.png new file mode 100644 index 0000000000..2bb5d6df09 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_cancelbasal.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_cp_aaps_offline.png b/app/src/main/res/drawable-xxhdpi/icon_cp_aaps_offline.png new file mode 100644 index 0000000000..1b4603bafc Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_cp_aaps_offline.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_cp_age_battery.png b/app/src/main/res/drawable-xxhdpi/icon_cp_age_battery.png new file mode 100644 index 0000000000..d32a7791e1 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_cp_age_battery.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_cp_age_canula.png b/app/src/main/res/drawable-xxhdpi/icon_cp_age_canula.png new file mode 100644 index 0000000000..715682129b Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_cp_age_canula.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_cp_age_insulin.png b/app/src/main/res/drawable-xxhdpi/icon_cp_age_insulin.png new file mode 100644 index 0000000000..79a21cea45 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_cp_age_insulin.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_cp_age_sensor.png b/app/src/main/res/drawable-xxhdpi/icon_cp_age_sensor.png new file mode 100644 index 0000000000..bb269c3af9 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_cp_age_sensor.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_cp_announcement.png b/app/src/main/res/drawable-xxhdpi/icon_cp_announcement.png new file mode 100644 index 0000000000..e287fa15d4 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_cp_announcement.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_cp_basal_end.png b/app/src/main/res/drawable-xxhdpi/icon_cp_basal_end.png new file mode 100644 index 0000000000..08acae3012 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_cp_basal_end.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_cp_basal_start.png b/app/src/main/res/drawable-xxhdpi/icon_cp_basal_start.png new file mode 100644 index 0000000000..1b6d970b95 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_cp_basal_start.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_cp_bgcheck.png b/app/src/main/res/drawable-xxhdpi/icon_cp_bgcheck.png new file mode 100644 index 0000000000..4e68c25d70 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_cp_bgcheck.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_cp_bolus_carbs.png b/app/src/main/res/drawable-xxhdpi/icon_cp_bolus_carbs.png new file mode 100644 index 0000000000..a110276120 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_cp_bolus_carbs.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_cp_bolus_combo.png b/app/src/main/res/drawable-xxhdpi/icon_cp_bolus_combo.png new file mode 100644 index 0000000000..c91b515001 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_cp_bolus_combo.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_cp_bolus_correction.png b/app/src/main/res/drawable-xxhdpi/icon_cp_bolus_correction.png new file mode 100644 index 0000000000..d0c7a40613 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_cp_bolus_correction.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_cp_bolus_meal.png b/app/src/main/res/drawable-xxhdpi/icon_cp_bolus_meal.png new file mode 100644 index 0000000000..e13a420bad Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_cp_bolus_meal.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_cp_bolus_snack.png b/app/src/main/res/drawable-xxhdpi/icon_cp_bolus_snack.png new file mode 100644 index 0000000000..6a9fb42088 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_cp_bolus_snack.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_cp_cgm_insert.png b/app/src/main/res/drawable-xxhdpi/icon_cp_cgm_insert.png new file mode 100644 index 0000000000..f1a791b702 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_cp_cgm_insert.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_cp_cgm_profile.png b/app/src/main/res/drawable-xxhdpi/icon_cp_cgm_profile.png new file mode 100644 index 0000000000..d40cba3c46 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_cp_cgm_profile.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_cp_cgm_start.png b/app/src/main/res/drawable-xxhdpi/icon_cp_cgm_start.png new file mode 100644 index 0000000000..47d5de66a1 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_cp_cgm_start.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_cp_cgm_target.png b/app/src/main/res/drawable-xxhdpi/icon_cp_cgm_target.png new file mode 100644 index 0000000000..13fc303aa2 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_cp_cgm_target.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_cp_exercise.png b/app/src/main/res/drawable-xxhdpi/icon_cp_exercise.png new file mode 100644 index 0000000000..4fb54d3703 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_cp_exercise.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_cp_note.png b/app/src/main/res/drawable-xxhdpi/icon_cp_note.png new file mode 100644 index 0000000000..c1881112b7 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_cp_note.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_cp_pump_battery.png b/app/src/main/res/drawable-xxhdpi/icon_cp_pump_battery.png new file mode 100644 index 0000000000..1a6d44bba0 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_cp_pump_battery.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_cp_pump_canula.png b/app/src/main/res/drawable-xxhdpi/icon_cp_pump_canula.png new file mode 100644 index 0000000000..6021f928ed Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_cp_pump_canula.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_cp_pump_cartridge.png b/app/src/main/res/drawable-xxhdpi/icon_cp_pump_cartridge.png new file mode 100644 index 0000000000..c7a8897a52 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_cp_pump_cartridge.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_cp_question.png b/app/src/main/res/drawable-xxhdpi/icon_cp_question.png new file mode 100644 index 0000000000..09455d09fd Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_cp_question.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_home_loop.png b/app/src/main/res/drawable-xxhdpi/icon_home_loop.png new file mode 100644 index 0000000000..c33f090311 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_home_loop.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_home_profile.png b/app/src/main/res/drawable-xxhdpi/icon_home_profile.png new file mode 100644 index 0000000000..00c4de023a Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_home_profile.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_home_target.png b/app/src/main/res/drawable-xxhdpi/icon_home_target.png new file mode 100644 index 0000000000..70fd9ebc27 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_home_target.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_quickwizard.png b/app/src/main/res/drawable-xxhdpi/icon_quickwizard.png new file mode 100644 index 0000000000..9f2c9c9350 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_quickwizard.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_actions_cancelextbolus.png b/app/src/main/res/drawable-xxxhdpi/icon_actions_cancelextbolus.png new file mode 100644 index 0000000000..f5b57a9bc9 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_actions_cancelextbolus.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_actions_profileswitch.png b/app/src/main/res/drawable-xxxhdpi/icon_actions_profileswitch.png new file mode 100644 index 0000000000..d5631ef3ae Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_actions_profileswitch.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_actions_refill.png b/app/src/main/res/drawable-xxxhdpi/icon_actions_refill.png new file mode 100644 index 0000000000..be3a5db708 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_actions_refill.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_actions_startextbolus.png b/app/src/main/res/drawable-xxxhdpi/icon_actions_startextbolus.png new file mode 100644 index 0000000000..89b44ea201 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_actions_startextbolus.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_actions_starttempbasal.png b/app/src/main/res/drawable-xxxhdpi/icon_actions_starttempbasal.png new file mode 100644 index 0000000000..7be2e32dfe Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_actions_starttempbasal.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_actions_temptarget.png b/app/src/main/res/drawable-xxxhdpi/icon_actions_temptarget.png new file mode 100644 index 0000000000..955a19f3bc Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_actions_temptarget.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_bolus.png b/app/src/main/res/drawable-xxxhdpi/icon_bolus.png new file mode 100644 index 0000000000..b4c4fb8559 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_bolus.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_calculator.png b/app/src/main/res/drawable-xxxhdpi/icon_calculator.png new file mode 100644 index 0000000000..90c8fab919 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_calculator.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_calibration.png b/app/src/main/res/drawable-xxxhdpi/icon_calibration.png new file mode 100644 index 0000000000..82eb93205e Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_calibration.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_cancelbasal.png b/app/src/main/res/drawable-xxxhdpi/icon_cancelbasal.png new file mode 100644 index 0000000000..cd66d14c4f Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_cancelbasal.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_cp_aaps_offline.png b/app/src/main/res/drawable-xxxhdpi/icon_cp_aaps_offline.png new file mode 100644 index 0000000000..3da8775fb4 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_cp_aaps_offline.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_cp_age_battery.png b/app/src/main/res/drawable-xxxhdpi/icon_cp_age_battery.png new file mode 100644 index 0000000000..dd21ad490c Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_cp_age_battery.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_cp_age_canula.png b/app/src/main/res/drawable-xxxhdpi/icon_cp_age_canula.png new file mode 100644 index 0000000000..6a3585b72f Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_cp_age_canula.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_cp_age_insulin.png b/app/src/main/res/drawable-xxxhdpi/icon_cp_age_insulin.png new file mode 100644 index 0000000000..3b50b616fc Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_cp_age_insulin.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_cp_age_sensor.png b/app/src/main/res/drawable-xxxhdpi/icon_cp_age_sensor.png new file mode 100644 index 0000000000..2dd35e6e9e Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_cp_age_sensor.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_cp_announcement.png b/app/src/main/res/drawable-xxxhdpi/icon_cp_announcement.png new file mode 100644 index 0000000000..256631f49b Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_cp_announcement.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_cp_basal_end.png b/app/src/main/res/drawable-xxxhdpi/icon_cp_basal_end.png new file mode 100644 index 0000000000..a57ceb3b8a Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_cp_basal_end.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_cp_basal_start.png b/app/src/main/res/drawable-xxxhdpi/icon_cp_basal_start.png new file mode 100644 index 0000000000..d36b0b711c Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_cp_basal_start.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_cp_bgcheck.png b/app/src/main/res/drawable-xxxhdpi/icon_cp_bgcheck.png new file mode 100644 index 0000000000..fa72b549a9 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_cp_bgcheck.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_cp_bolus_carbs.png b/app/src/main/res/drawable-xxxhdpi/icon_cp_bolus_carbs.png new file mode 100644 index 0000000000..4dab75558b Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_cp_bolus_carbs.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_cp_bolus_combo.png b/app/src/main/res/drawable-xxxhdpi/icon_cp_bolus_combo.png new file mode 100644 index 0000000000..1418ea4994 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_cp_bolus_combo.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_cp_bolus_correction.png b/app/src/main/res/drawable-xxxhdpi/icon_cp_bolus_correction.png new file mode 100644 index 0000000000..ccc3d0e39c Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_cp_bolus_correction.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_cp_bolus_meal.png b/app/src/main/res/drawable-xxxhdpi/icon_cp_bolus_meal.png new file mode 100644 index 0000000000..aa7bdf7fe3 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_cp_bolus_meal.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_cp_bolus_snack.png b/app/src/main/res/drawable-xxxhdpi/icon_cp_bolus_snack.png new file mode 100644 index 0000000000..1f9ab1697d Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_cp_bolus_snack.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_cp_cgm_insert.png b/app/src/main/res/drawable-xxxhdpi/icon_cp_cgm_insert.png new file mode 100644 index 0000000000..2d7e6b4542 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_cp_cgm_insert.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_cp_cgm_profile.png b/app/src/main/res/drawable-xxxhdpi/icon_cp_cgm_profile.png new file mode 100644 index 0000000000..e8b4668b86 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_cp_cgm_profile.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_cp_cgm_start.png b/app/src/main/res/drawable-xxxhdpi/icon_cp_cgm_start.png new file mode 100644 index 0000000000..e8d0e6773e Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_cp_cgm_start.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_cp_cgm_target.png b/app/src/main/res/drawable-xxxhdpi/icon_cp_cgm_target.png new file mode 100644 index 0000000000..2bdaf7d73d Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_cp_cgm_target.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_cp_exercise.png b/app/src/main/res/drawable-xxxhdpi/icon_cp_exercise.png new file mode 100644 index 0000000000..c16560e8de Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_cp_exercise.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_cp_note.png b/app/src/main/res/drawable-xxxhdpi/icon_cp_note.png new file mode 100644 index 0000000000..dd1e04b419 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_cp_note.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_cp_pump_battery.png b/app/src/main/res/drawable-xxxhdpi/icon_cp_pump_battery.png new file mode 100644 index 0000000000..f1d306de12 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_cp_pump_battery.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_cp_pump_canula.png b/app/src/main/res/drawable-xxxhdpi/icon_cp_pump_canula.png new file mode 100644 index 0000000000..465111a6ba Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_cp_pump_canula.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_cp_pump_cartridge.png b/app/src/main/res/drawable-xxxhdpi/icon_cp_pump_cartridge.png new file mode 100644 index 0000000000..afffd90482 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_cp_pump_cartridge.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_cp_question.png b/app/src/main/res/drawable-xxxhdpi/icon_cp_question.png new file mode 100644 index 0000000000..b2e19c1575 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_cp_question.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_home_loop.png b/app/src/main/res/drawable-xxxhdpi/icon_home_loop.png new file mode 100644 index 0000000000..a59d73e2b4 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_home_loop.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_home_profile.png b/app/src/main/res/drawable-xxxhdpi/icon_home_profile.png new file mode 100644 index 0000000000..80234a0f75 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_home_profile.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_home_target.png b/app/src/main/res/drawable-xxxhdpi/icon_home_target.png new file mode 100644 index 0000000000..c1a4d99087 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_home_target.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_quickwizard.png b/app/src/main/res/drawable-xxxhdpi/icon_quickwizard.png new file mode 100644 index 0000000000..314b8a98de Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_quickwizard.png differ diff --git a/app/src/main/res/drawable/icon_actions_cancelextbolus.png b/app/src/main/res/drawable/icon_actions_cancelextbolus.png new file mode 100644 index 0000000000..4ad378e374 Binary files /dev/null and b/app/src/main/res/drawable/icon_actions_cancelextbolus.png differ diff --git a/app/src/main/res/drawable/icon_actions_profileswitch.png b/app/src/main/res/drawable/icon_actions_profileswitch.png new file mode 100644 index 0000000000..eeae6ccfdb Binary files /dev/null and b/app/src/main/res/drawable/icon_actions_profileswitch.png differ diff --git a/app/src/main/res/drawable/icon_actions_refill.png b/app/src/main/res/drawable/icon_actions_refill.png new file mode 100644 index 0000000000..737cca8b00 Binary files /dev/null and b/app/src/main/res/drawable/icon_actions_refill.png differ diff --git a/app/src/main/res/drawable/icon_actions_startextbolus.png b/app/src/main/res/drawable/icon_actions_startextbolus.png new file mode 100644 index 0000000000..338df773c2 Binary files /dev/null and b/app/src/main/res/drawable/icon_actions_startextbolus.png differ diff --git a/app/src/main/res/drawable/icon_actions_starttempbasal.png b/app/src/main/res/drawable/icon_actions_starttempbasal.png new file mode 100644 index 0000000000..18fbd8c111 Binary files /dev/null and b/app/src/main/res/drawable/icon_actions_starttempbasal.png differ diff --git a/app/src/main/res/drawable/icon_actions_temptarget.png b/app/src/main/res/drawable/icon_actions_temptarget.png new file mode 100644 index 0000000000..39170bab37 Binary files /dev/null and b/app/src/main/res/drawable/icon_actions_temptarget.png differ diff --git a/app/src/main/res/drawable/icon_bolus.png b/app/src/main/res/drawable/icon_bolus.png index e0d0204a22..c083219b45 100644 Binary files a/app/src/main/res/drawable/icon_bolus.png and b/app/src/main/res/drawable/icon_bolus.png differ diff --git a/app/src/main/res/drawable/icon_calculator.png b/app/src/main/res/drawable/icon_calculator.png index b327e69327..056722a440 100644 Binary files a/app/src/main/res/drawable/icon_calculator.png and b/app/src/main/res/drawable/icon_calculator.png differ diff --git a/app/src/main/res/drawable/icon_calibration.png b/app/src/main/res/drawable/icon_calibration.png index 8a6db6f8d1..0929d3690d 100644 Binary files a/app/src/main/res/drawable/icon_calibration.png and b/app/src/main/res/drawable/icon_calibration.png differ diff --git a/app/src/main/res/drawable/icon_cancelbasal.png b/app/src/main/res/drawable/icon_cancelbasal.png index 55a39b40e5..c48a20792d 100644 Binary files a/app/src/main/res/drawable/icon_cancelbasal.png and b/app/src/main/res/drawable/icon_cancelbasal.png differ diff --git a/app/src/main/res/drawable/icon_cp_aaps_offline.png b/app/src/main/res/drawable/icon_cp_aaps_offline.png new file mode 100644 index 0000000000..dc50653883 Binary files /dev/null and b/app/src/main/res/drawable/icon_cp_aaps_offline.png differ diff --git a/app/src/main/res/drawable/icon_cp_age_battery.png b/app/src/main/res/drawable/icon_cp_age_battery.png new file mode 100644 index 0000000000..6c7fc56139 Binary files /dev/null and b/app/src/main/res/drawable/icon_cp_age_battery.png differ diff --git a/app/src/main/res/drawable/icon_cp_age_canula.png b/app/src/main/res/drawable/icon_cp_age_canula.png new file mode 100644 index 0000000000..303ad946cd Binary files /dev/null and b/app/src/main/res/drawable/icon_cp_age_canula.png differ diff --git a/app/src/main/res/drawable/icon_cp_age_insulin.png b/app/src/main/res/drawable/icon_cp_age_insulin.png new file mode 100644 index 0000000000..5cd8598faa Binary files /dev/null and b/app/src/main/res/drawable/icon_cp_age_insulin.png differ diff --git a/app/src/main/res/drawable/icon_cp_age_sensor.png b/app/src/main/res/drawable/icon_cp_age_sensor.png new file mode 100644 index 0000000000..d312b6c572 Binary files /dev/null and b/app/src/main/res/drawable/icon_cp_age_sensor.png differ diff --git a/app/src/main/res/drawable/icon_cp_announcement.png b/app/src/main/res/drawable/icon_cp_announcement.png new file mode 100644 index 0000000000..6e1338ac24 Binary files /dev/null and b/app/src/main/res/drawable/icon_cp_announcement.png differ diff --git a/app/src/main/res/drawable/icon_cp_basal_end.png b/app/src/main/res/drawable/icon_cp_basal_end.png new file mode 100644 index 0000000000..be8474f002 Binary files /dev/null and b/app/src/main/res/drawable/icon_cp_basal_end.png differ diff --git a/app/src/main/res/drawable/icon_cp_basal_start.png b/app/src/main/res/drawable/icon_cp_basal_start.png new file mode 100644 index 0000000000..34cd31f14b Binary files /dev/null and b/app/src/main/res/drawable/icon_cp_basal_start.png differ diff --git a/app/src/main/res/drawable/icon_cp_bgcheck.png b/app/src/main/res/drawable/icon_cp_bgcheck.png new file mode 100644 index 0000000000..0cb14c2f57 Binary files /dev/null and b/app/src/main/res/drawable/icon_cp_bgcheck.png differ diff --git a/app/src/main/res/drawable/icon_cp_bolus_carbs.png b/app/src/main/res/drawable/icon_cp_bolus_carbs.png new file mode 100644 index 0000000000..561703fb06 Binary files /dev/null and b/app/src/main/res/drawable/icon_cp_bolus_carbs.png differ diff --git a/app/src/main/res/drawable/icon_cp_bolus_combo.png b/app/src/main/res/drawable/icon_cp_bolus_combo.png new file mode 100644 index 0000000000..ce4d8fb9d3 Binary files /dev/null and b/app/src/main/res/drawable/icon_cp_bolus_combo.png differ diff --git a/app/src/main/res/drawable/icon_cp_bolus_correction.png b/app/src/main/res/drawable/icon_cp_bolus_correction.png new file mode 100644 index 0000000000..582472dc92 Binary files /dev/null and b/app/src/main/res/drawable/icon_cp_bolus_correction.png differ diff --git a/app/src/main/res/drawable/icon_cp_bolus_meal.png b/app/src/main/res/drawable/icon_cp_bolus_meal.png new file mode 100644 index 0000000000..54b51e126e Binary files /dev/null and b/app/src/main/res/drawable/icon_cp_bolus_meal.png differ diff --git a/app/src/main/res/drawable/icon_cp_bolus_snack.png b/app/src/main/res/drawable/icon_cp_bolus_snack.png new file mode 100644 index 0000000000..b2ba41c27d Binary files /dev/null and b/app/src/main/res/drawable/icon_cp_bolus_snack.png differ diff --git a/app/src/main/res/drawable/icon_cp_cgm_insert.png b/app/src/main/res/drawable/icon_cp_cgm_insert.png new file mode 100644 index 0000000000..67c0fb1ba2 Binary files /dev/null and b/app/src/main/res/drawable/icon_cp_cgm_insert.png differ diff --git a/app/src/main/res/drawable/icon_cp_cgm_profile.png b/app/src/main/res/drawable/icon_cp_cgm_profile.png new file mode 100644 index 0000000000..e0f0a15cc8 Binary files /dev/null and b/app/src/main/res/drawable/icon_cp_cgm_profile.png differ diff --git a/app/src/main/res/drawable/icon_cp_cgm_start.png b/app/src/main/res/drawable/icon_cp_cgm_start.png new file mode 100644 index 0000000000..14a44bc852 Binary files /dev/null and b/app/src/main/res/drawable/icon_cp_cgm_start.png differ diff --git a/app/src/main/res/drawable/icon_cp_cgm_target.png b/app/src/main/res/drawable/icon_cp_cgm_target.png new file mode 100644 index 0000000000..86ce00442c Binary files /dev/null and b/app/src/main/res/drawable/icon_cp_cgm_target.png differ diff --git a/app/src/main/res/drawable/icon_cp_exercise.png b/app/src/main/res/drawable/icon_cp_exercise.png new file mode 100644 index 0000000000..1c92c0ebb5 Binary files /dev/null and b/app/src/main/res/drawable/icon_cp_exercise.png differ diff --git a/app/src/main/res/drawable/icon_cp_note.png b/app/src/main/res/drawable/icon_cp_note.png new file mode 100644 index 0000000000..7c8663a4fe Binary files /dev/null and b/app/src/main/res/drawable/icon_cp_note.png differ diff --git a/app/src/main/res/drawable/icon_cp_pump_battery.png b/app/src/main/res/drawable/icon_cp_pump_battery.png new file mode 100644 index 0000000000..f4dab169a8 Binary files /dev/null and b/app/src/main/res/drawable/icon_cp_pump_battery.png differ diff --git a/app/src/main/res/drawable/icon_cp_pump_canula.png b/app/src/main/res/drawable/icon_cp_pump_canula.png new file mode 100644 index 0000000000..ee512c5fef Binary files /dev/null and b/app/src/main/res/drawable/icon_cp_pump_canula.png differ diff --git a/app/src/main/res/drawable/icon_cp_pump_cartridge.png b/app/src/main/res/drawable/icon_cp_pump_cartridge.png new file mode 100644 index 0000000000..70a90c596f Binary files /dev/null and b/app/src/main/res/drawable/icon_cp_pump_cartridge.png differ diff --git a/app/src/main/res/drawable/icon_cp_question.png b/app/src/main/res/drawable/icon_cp_question.png new file mode 100644 index 0000000000..5d430d9164 Binary files /dev/null and b/app/src/main/res/drawable/icon_cp_question.png differ diff --git a/app/src/main/res/drawable/icon_home_loop.png b/app/src/main/res/drawable/icon_home_loop.png new file mode 100644 index 0000000000..5240cc85db Binary files /dev/null and b/app/src/main/res/drawable/icon_home_loop.png differ diff --git a/app/src/main/res/drawable/icon_home_profile.png b/app/src/main/res/drawable/icon_home_profile.png new file mode 100644 index 0000000000..f689df10c6 Binary files /dev/null and b/app/src/main/res/drawable/icon_home_profile.png differ diff --git a/app/src/main/res/drawable/icon_home_target.png b/app/src/main/res/drawable/icon_home_target.png new file mode 100644 index 0000000000..9fc7086e9d Binary files /dev/null and b/app/src/main/res/drawable/icon_home_target.png differ diff --git a/app/src/main/res/drawable/icon_quickwizard.png b/app/src/main/res/drawable/icon_quickwizard.png index 0487ee2ac1..d65347f235 100644 Binary files a/app/src/main/res/drawable/icon_quickwizard.png and b/app/src/main/res/drawable/icon_quickwizard.png differ diff --git a/app/src/main/res/layout/actions_fragment.xml b/app/src/main/res/layout/actions_fragment.xml index 5a0faa4099..bc8f416770 100644 --- a/app/src/main/res/layout/actions_fragment.xml +++ b/app/src/main/res/layout/actions_fragment.xml @@ -23,8 +23,8 @@ android:layout_marginRight="10dp" android:layout_marginTop="3dp" android:layout_weight="0.5" - android:text="@string/careportal_profileswitch" - android:textColor="@color/colorProfileSwitchButton" /> + android:drawableTop="@drawable/icon_actions_profileswitch" + android:text="@string/careportal_profileswitch" />