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 a881464e82..f800d9d531 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,17 +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; @@ -157,14 +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(); - } else if ("oapsresult".equals(act[1])) { - rTitle += " OAPS RESULT"; - rMessage = getOAPSResultStatus(); + rMessage = "TARGETS:\n" + getTargetsStatus(); + rMessage += "\n\n" + getLoopStatus(); + rMessage += "\n\nOAPS RESULT:\n" + getOAPSResultStatus();; } } else if ("wizard".equals(act[0])) { @@ -256,6 +265,58 @@ public class ActionStringHandler { 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; @@ -266,6 +327,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); @@ -506,6 +659,13 @@ public class ActionStringHandler { 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); diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/TempTargetActivity.java b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/TempTargetActivity.java index 2981066bfb..4b04a72cdc 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/TempTargetActivity.java +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/TempTargetActivity.java @@ -50,7 +50,7 @@ public class TempTargetActivity extends ViewSelectorActivity { SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); isMGDL = sp.getBoolean("units_mgdl", true); - isSingleTarget = sp.getBoolean("singletarget", false); + isSingleTarget = sp.getBoolean("singletarget", true); } diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/menus/FillMenuActivity.java b/wear/src/main/java/info/nightscout/androidaps/interaction/menus/FillMenuActivity.java index da8daa80cb..a4d1a3d181 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/menus/FillMenuActivity.java +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/menus/FillMenuActivity.java @@ -14,7 +14,7 @@ public class FillMenuActivity extends MenuListActivity { @Override protected String[] getElements() { - return new String[] { + return new String[]{ "Preset 1", "Preset 2", "Preset 3", @@ -23,23 +23,17 @@ public class FillMenuActivity extends MenuListActivity { } @Override - protected void doAction(int position) { - switch (position) { - case 0: - ListenerService.initiateAction(this, "fillpreset 1"); - break; - case 1: - ListenerService.initiateAction(this, "fillpreset 2"); - break; - case 2: - ListenerService.initiateAction(this, "fillpreset 3"); - break; - case 3: - Intent intent = new Intent(this, FillActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - this.startActivity(intent); - break; + protected void doAction(String action) { + if ("Preset 1".equals(action)) { + ListenerService.initiateAction(this, "fillpreset 1"); + } else if ("Preset 2".equals(action)) { + ListenerService.initiateAction(this, "fillpreset 2"); + } else if ("Preset 3".equals(action)) { + ListenerService.initiateAction(this, "fillpreset 3"); + } else if ("Free amount".equals(action)) { + Intent intent = new Intent(this, FillActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + this.startActivity(intent); } - } } diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/menus/MainMenuActivity.java b/wear/src/main/java/info/nightscout/androidaps/interaction/menus/MainMenuActivity.java index aeea844f42..2d8b29d10a 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/menus/MainMenuActivity.java +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/menus/MainMenuActivity.java @@ -5,6 +5,8 @@ import android.content.SharedPreferences; import android.os.Bundle; import android.preference.PreferenceManager; +import java.util.Vector; + import info.nightscout.androidaps.BuildConfig; import info.nightscout.androidaps.data.ListenerService; import info.nightscout.androidaps.interaction.AAPSPreferences; @@ -39,74 +41,50 @@ public class MainMenuActivity extends MenuListActivity { boolean showPrimeFill = sp.getBoolean("primefill", false); - return new String[] { - "TempT", - "Bolus", - "Wizard", - "Settings", - "Re-Sync", - "Status", - showPrimeFill?"Prime/Fill":""}; + boolean showWizard = sp.getBoolean("showWizard", true); + + Vector menuitems = new Vector(); + menuitems.add("TempT"); + menuitems.add("Bolus"); + if(showWizard) menuitems.add("Wizard"); + menuitems.add("Settings"); + menuitems.add("Status"); + if (showPrimeFill) menuitems.add("Prime/Fill"); + + return menuitems.toArray(new String[menuitems.size()]); } @Override - protected void doAction(int position) { + protected void doAction(String action) { Intent intent; - if(!BuildConfig.WEAR_CONTROL) { - switch (position) { - case 0: - intent = new Intent(this, AAPSPreferences.class); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - this.startActivity(intent); - break; - case 1: - ListenerService.requestData(this); - break; - } - return; + if ("Settings".equals(action)) { + intent = new Intent(this, AAPSPreferences.class); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + this.startActivity(intent); + } else if ("Re-Sync".equals(action)) { + ListenerService.requestData(this); + } else if ("TempT".equals(action)) { + intent = new Intent(this, TempTargetActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + this.startActivity(intent); + } else if ("Bolus".equals(action)) { + intent = new Intent(this, BolusActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + this.startActivity(intent); + } else if ("Wizard".equals(action)) { + intent = new Intent(this, WizardActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + this.startActivity(intent); + } else if ("Status".equals(action)) { + intent = new Intent(this, StatusMenuActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + this.startActivity(intent); + } else if ("Prime/Fill".equals(action)) { + intent = new Intent(this, FillMenuActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + this.startActivity(intent); } - - - switch (position) { - case 0: - intent = new Intent(this, TempTargetActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - this.startActivity(intent); - break; - case 1: - intent = new Intent(this, BolusActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - this.startActivity(intent); - break; - case 2: - intent = new Intent(this, WizardActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - this.startActivity(intent); - break; - case 3: - intent = new Intent(this, AAPSPreferences.class); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - this.startActivity(intent); - break; - case 4: - ListenerService.requestData(this); - break; - case 5: - intent = new Intent(this, StatusMenuActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - this.startActivity(intent); - break; - case 6: - boolean showPrimeFill = sp.getBoolean("primefill", false); - if(showPrimeFill) { - intent = new Intent(this, FillMenuActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - this.startActivity(intent); - } - break; - } - } } diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/menus/MainMenuRestrictedActivity.java b/wear/src/main/java/info/nightscout/androidaps/interaction/menus/MainMenuRestrictedActivity.java deleted file mode 100644 index 779e9611d2..0000000000 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/menus/MainMenuRestrictedActivity.java +++ /dev/null @@ -1,53 +0,0 @@ -package info.nightscout.androidaps.interaction.menus; - -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.Bundle; -import android.preference.PreferenceManager; - -import info.nightscout.androidaps.data.ListenerService; -import info.nightscout.androidaps.interaction.AAPSPreferences; -import info.nightscout.androidaps.interaction.actions.BolusActivity; -import info.nightscout.androidaps.interaction.actions.TempTargetActivity; -import info.nightscout.androidaps.interaction.actions.WizardActivity; -import info.nightscout.androidaps.interaction.utils.MenuListActivity; - -/** - * Created by adrian on 09/02/17. - */ - -public class MainMenuRestrictedActivity extends MenuListActivity { - - SharedPreferences sp; - - @Override - protected void onCreate(Bundle savedInstanceState) { - sp = PreferenceManager.getDefaultSharedPreferences(this); - super.onCreate(savedInstanceState); - ListenerService.requestData(this); - } - - @Override - protected String[] getElements() { - return new String[] { - "Settings", - "Re-Sync"}; - } - - @Override - protected void doAction(int position) { - - Intent intent; - switch (position) { - case 0: - intent = new Intent(this, AAPSPreferences.class); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - this.startActivity(intent); - break; - case 1: - ListenerService.requestData(this); - break; - } - - } -} diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/menus/StatusMenuActivity.java b/wear/src/main/java/info/nightscout/androidaps/interaction/menus/StatusMenuActivity.java index a57bd17c8f..f17bc23e46 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/menus/StatusMenuActivity.java +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/menus/StatusMenuActivity.java @@ -14,32 +14,22 @@ public class StatusMenuActivity extends MenuListActivity { return new String[] { "Pump", "Loop", - "Targets", "CPP", - "OAPS Result"}; + "TDD"}; + } @Override - protected void doAction(int position) { - switch (position) { - - case 0: - ListenerService.initiateAction(this, "status pump"); - break; - case 1: - ListenerService.initiateAction(this, "status loop"); - break; - case 2: - ListenerService.initiateAction(this, "status targets"); - break; - case 3: - ListenerService.initiateAction(this, "opencpp"); - break; - case 4: - ListenerService.initiateAction(this, "status oapsresult"); - break; + protected void doAction(String action) { + if ("Pump".equals(action)) { + ListenerService.initiateAction(this, "status pump"); + } else if ("Loop".equals(action)) { + ListenerService.initiateAction(this, "status loop"); + } else if ("CPP".equals(action)) { + ListenerService.initiateAction(this, "opencpp"); + } else if ("TDD".equals(action)) { + ListenerService.initiateAction(this, "tddstats"); } - } } diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/MenuListActivity.java b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/MenuListActivity.java index d151196091..9d6fd51126 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/MenuListActivity.java +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/MenuListActivity.java @@ -22,7 +22,7 @@ public abstract class MenuListActivity extends Activity protected abstract String[] getElements(); - protected abstract void doAction(int position); + protected abstract void doAction(String position); @Override protected void onPause(){ @@ -50,7 +50,7 @@ public abstract class MenuListActivity extends Activity // WearableListView click listener @Override public void onClick(WearableListView.ViewHolder v) { - Integer tag = (Integer) v.itemView.getTag(); + String tag = (String) v.itemView.getTag(); doAction(tag); //ActionsDefinitions.doAction(v.getAdapterPosition(), this); finish(); @@ -105,7 +105,7 @@ public abstract class MenuListActivity extends Activity // replace text contents view.setText(mDataset[position]); // replace list item's metadata - holder.itemView.setTag(position); + holder.itemView.setTag(mDataset[position]); } // Return the size of your dataset diff --git a/wear/src/main/res/xml/preferences.xml b/wear/src/main/res/xml/preferences.xml index 57050ef0f5..b9c6307cac 100644 --- a/wear/src/main/res/xml/preferences.xml +++ b/wear/src/main/res/xml/preferences.xml @@ -121,6 +121,13 @@ app:wear_iconOff="@drawable/settings_off" app:wear_iconOn="@drawable/settings_on"/> +