diff --git a/app/build.gradle b/app/build.gradle index 1463745658..4ddab3d323 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -44,7 +44,7 @@ android { minSdkVersion 21 targetSdkVersion 23 versionCode 1400 - version "1.42" + version "1.43" buildConfigField "String", "VERSION", '"' + version + '"' buildConfigField "String", "BUILDVERSION", generateGitBuild() } 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 0863c8e72d..b9bc74f526 100644 --- a/app/src/main/java/info/nightscout/androidaps/Services/DataService.java +++ b/app/src/main/java/info/nightscout/androidaps/Services/DataService.java @@ -54,6 +54,7 @@ import info.nightscout.androidaps.plugins.TempTargetRange.events.EventTempTarget import info.nightscout.androidaps.receivers.DataReceiver; import info.nightscout.androidaps.plugins.NSClientInternal.data.NSProfile; import info.nightscout.androidaps.plugins.NSClientInternal.data.NSSgv; +import info.nightscout.utils.SP; public class DataService extends IntentService { @@ -98,8 +99,7 @@ public class DataService extends IntentService { boolean isNSProfile = ConfigBuilderPlugin.getActiveProfile().getClass().equals(NSProfilePlugin.class); - SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); - boolean nsUploadOnly = SP.getBoolean("ns_upload_only", false); + boolean nsUploadOnly = SP.getBoolean(R.string.key_ns_upload_only, false); if (intent != null) { final String action = intent.getAction(); @@ -356,7 +356,7 @@ public class DataService extends IntentService { String activeProfile = bundles.getString("activeprofile"); String profile = bundles.getString("profile"); NSProfile nsProfile = new NSProfile(new JSONObject(profile), activeProfile); - MainApp.bus().post(new EventNewBasalProfile(nsProfile)); + MainApp.bus().post(new EventNewBasalProfile(nsProfile, "NSClient")); PumpInterface pump = MainApp.getConfigBuilder(); if (pump != null) { 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 b3cd0ace70..17c01bd9ff 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java +++ b/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java @@ -421,6 +421,16 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { return new ArrayList(); } + public void delete(TempBasal tempBasal) { + try { + getDaoTempBasals().delete(tempBasal); + latestTreatmentChange = tempBasal.getTimeIndex(); + } catch (SQLException e) { + e.printStackTrace(); + } + scheduleTreatmentChange(); + } + public List getTemptargetsDataFromTime(long mills, boolean ascending) { try { Dao daoTempTargets = getDaoTempTargets(); diff --git a/app/src/main/java/info/nightscout/androidaps/events/EventNewBasalProfile.java b/app/src/main/java/info/nightscout/androidaps/events/EventNewBasalProfile.java index 3e270e8a1b..b3750f59c8 100644 --- a/app/src/main/java/info/nightscout/androidaps/events/EventNewBasalProfile.java +++ b/app/src/main/java/info/nightscout/androidaps/events/EventNewBasalProfile.java @@ -7,8 +7,10 @@ import info.nightscout.androidaps.plugins.NSClientInternal.data.NSProfile; */ public class EventNewBasalProfile { public NSProfile newNSProfile = null; + public String from = ""; - public EventNewBasalProfile(NSProfile newProfile) { + public EventNewBasalProfile(NSProfile newProfile, String from) { newNSProfile = newProfile; + this.from = from; } } 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 34641f5ebb..f0cf085e16 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 @@ -618,7 +618,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick if (pump != null) { pump.setNewBasalProfile(nsProfile); log.debug("Setting new profile: " + profile); - MainApp.bus().post(new EventNewBasalProfile(nsProfile)); + MainApp.bus().post(new EventNewBasalProfile(nsProfile, "NewNSTreatmentDialog")); } else { log.error("No active pump selected"); } 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 84135e5e85..eaea986d19 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 @@ -928,6 +928,28 @@ public class ConfigBuilderPlugin implements PluginBase, PumpInterface, Constrain } } + public static void uploadOpenAPSOffline(double durationInMinutes) { + try { + Context context = MainApp.instance().getApplicationContext(); + JSONObject data = new JSONObject(); + 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)); + Bundle bundle = new Bundle(); + bundle.putString("action", "dbAdd"); + bundle.putString("collection", "treatments"); + bundle.putString("data", data.toString()); + Intent intent = new Intent(Intents.ACTION_DATABASE); + intent.putExtras(bundle); + intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); + context.sendBroadcast(intent); + DbLogger.dbAdd(intent, data.toString(), ConfigBuilderPlugin.class); + } catch (JSONException e) { + e.printStackTrace(); + } + } + public void uploadTempBasalStartPercent(Integer percent, double durationInMinutes) { try { SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext()); 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 0e9e4512ae..b28927d3ba 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 @@ -156,7 +156,7 @@ public class IobCobCalculatorPlugin implements PluginBase { private void loadBgData() { //log.debug("Locking loadBgData"); synchronized (dataLock) { - onNewProfile(new EventNewBasalProfile(null)); + onNewProfile(new EventNewBasalProfile(null, "IobCobCalculator init")); bgReadings = MainApp.getDbHelper().getBgreadingsDataFromTime((long) (new Date().getTime() - 60 * 60 * 1000L * (24 + dia)), false); log.debug("BG data loaded. Size: " + bgReadings.size()); } @@ -545,6 +545,20 @@ public class IobCobCalculatorPlugin implements PluginBase { if (profile != null) { dia = profile.getDia(); } + if (ev.newNSProfile == null) { // on init no need of reset + return; + } + synchronized (dataLock) { + log.debug("Invalidating cached data because of new profile from " + ev.from + ". 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 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 44c6587fb1..91fca44d12 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 @@ -14,10 +14,12 @@ import org.slf4j.LoggerFactory; import java.util.Date; import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; 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.utils.SP; public class DBAccessReceiver extends BroadcastReceiver { private static Logger log = LoggerFactory.getLogger(DBAccessReceiver.class); @@ -32,6 +34,10 @@ public class DBAccessReceiver extends BroadcastReceiver { 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(); 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 96a49a23b3..05b8d272a1 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 @@ -352,18 +352,20 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, @Override public boolean onContextItemSelected(MenuItem item) { - final LoopPlugin activeloop = MainApp.getConfigBuilder().getActiveLoop(); + final LoopPlugin activeloop = ConfigBuilderPlugin.getActiveLoop(); if (item.getTitle().equals(MainApp.sResources.getString(R.string.disableloop))) { activeloop.setFragmentEnabled(PluginBase.LOOP, false); activeloop.setFragmentVisible(PluginBase.LOOP, false); MainApp.getConfigBuilder().storeSettings(); scheduleUpdateGUI("suspendmenu"); + ConfigBuilderPlugin.uploadOpenAPSOffline(60); // upload 60 min, we don;t know real duration return true; } else if (item.getTitle().equals(MainApp.sResources.getString(R.string.enableloop))) { activeloop.setFragmentEnabled(PluginBase.LOOP, true); activeloop.setFragmentVisible(PluginBase.LOOP, true); MainApp.getConfigBuilder().storeSettings(); scheduleUpdateGUI("suspendmenu"); + ConfigBuilderPlugin.uploadOpenAPSOffline(0); return true; } else if (item.getTitle().equals(MainApp.sResources.getString(R.string.resume))) { activeloop.suspendTo(0L); @@ -377,22 +379,27 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, } } }); + ConfigBuilderPlugin.uploadOpenAPSOffline(0); return true; } else if (item.getTitle().equals(MainApp.sResources.getString(R.string.suspendloopfor1h))) { activeloop.suspendTo(new Date().getTime() + 60L * 60 * 1000); scheduleUpdateGUI("suspendmenu"); + ConfigBuilderPlugin.uploadOpenAPSOffline(60); return true; } else if (item.getTitle().equals(MainApp.sResources.getString(R.string.suspendloopfor2h))) { activeloop.suspendTo(new Date().getTime() + 2 * 60L * 60 * 1000); scheduleUpdateGUI("suspendmenu"); + ConfigBuilderPlugin.uploadOpenAPSOffline(120); return true; } else if (item.getTitle().equals(MainApp.sResources.getString(R.string.suspendloopfor3h))) { activeloop.suspendTo(new Date().getTime() + 3 * 60L * 60 * 1000); scheduleUpdateGUI("suspendmenu"); + ConfigBuilderPlugin.uploadOpenAPSOffline(180); return true; } else if (item.getTitle().equals(MainApp.sResources.getString(R.string.suspendloopfor10h))) { activeloop.suspendTo(new Date().getTime() + 10 * 60L * 60 * 1000); scheduleUpdateGUI("suspendmenu"); + ConfigBuilderPlugin.uploadOpenAPSOffline(600); return true; } else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor30m))) { activeloop.suspendTo(new Date().getTime() + 30L * 60 * 1000); @@ -406,6 +413,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, } } }); + ConfigBuilderPlugin.uploadOpenAPSOffline(30); return true; } else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor1h))) { activeloop.suspendTo(new Date().getTime() + 1 * 60L * 60 * 1000); @@ -419,6 +427,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, } } }); + ConfigBuilderPlugin.uploadOpenAPSOffline(60); return true; } else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor2h))) { activeloop.suspendTo(new Date().getTime() + 2 * 60L * 60 * 1000); @@ -432,6 +441,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, } } }); + ConfigBuilderPlugin.uploadOpenAPSOffline(120); return true; } else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor3h))) { activeloop.suspendTo(new Date().getTime() + 3 * 60L * 60 * 1000); @@ -445,6 +455,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, } } }); + ConfigBuilderPlugin.uploadOpenAPSOffline(180); return true; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/Services/ExecutionService.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/Services/ExecutionService.java index 54aae17687..ffd16fefdf 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/Services/ExecutionService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/Services/ExecutionService.java @@ -391,7 +391,7 @@ public class ExecutionService extends Service { return true; } - public boolean bolus(Double amount, int carbs, Treatment t) { + public boolean bolus(double amount, int carbs, Treatment t) { bolusingTreatment = t; MsgBolusStart start = new MsgBolusStart(amount); MsgBolusStop stop = new MsgBolusStop(amount, t); @@ -405,6 +405,7 @@ public class ExecutionService extends Service { } MsgBolusProgress progress = new MsgBolusProgress(amount, t); // initialize static variables MainApp.bus().post(new EventDanaRBolusStart()); + long startTime = new Date().getTime(); if (!stop.stopped) { mSerialIOThread.sendMessage(start); @@ -422,7 +423,23 @@ public class ExecutionService extends Service { } waitMsec(300); bolusingTreatment = null; - getPumpStatus(); + // try to find real amount if bolusing was interrupted or comm failed + if (t.insulin != amount) { + disconnect("bolusingInterrupted"); + long now = new Date().getTime(); + long estimatedBolusEnd = (long) (startTime + amount / 5d * 60 * 1000); // std delivery rate 5 U/min + waitMsec(Math.max(5000, estimatedBolusEnd - now + 3000)); + connect("bolusingInterrupted"); + getPumpStatus(); + if (danaRPump.lastBolusTime.getTime() > now - 60 * 1000L) { // last bolus max 1 min old + t.insulin = danaRPump.lastBolusAmount; + log.debug("Used bolus amount from history: " + danaRPump.lastBolusAmount); + } else { + log.debug("Bolus amount in history too old: " + danaRPump.lastBolusTime.toLocaleString()); + } + } else { + getPumpStatus(); + } return true; } 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 1a7501ba1a..2eeb5c0857 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 @@ -29,6 +29,7 @@ import info.nightscout.androidaps.events.EventPreferenceChange; import info.nightscout.androidaps.events.EventRefreshGui; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPlugin; import info.nightscout.androidaps.plugins.PumpDanaRKorean.DanaRKoreanPlugin; import info.nightscout.androidaps.plugins.Loop.LoopPlugin; @@ -42,6 +43,8 @@ import info.nightscout.utils.SP; import info.nightscout.utils.SafeParse; import info.nightscout.utils.XdripCalibrations; +import static info.nightscout.androidaps.R.string.profile; + /** * Created by mike on 05.08.2016. */ @@ -51,11 +54,11 @@ public class SmsCommunicatorPlugin implements PluginBase { private static boolean fragmentEnabled = false; private static boolean fragmentVisible = true; - final long CONFIRM_TIMEOUT = 5 * 60 * 1000L; + private final long CONFIRM_TIMEOUT = 5 * 60 * 1000L; - List allowedNumbers = new ArrayList(); + private List allowedNumbers = new ArrayList(); - public class Sms { + class Sms { String phoneNumber; String text; Date date; @@ -69,21 +72,21 @@ public class SmsCommunicatorPlugin implements PluginBase { double calibrationRequested = 0d; int duration = 0; - public Sms(SmsMessage message) { + Sms(SmsMessage message) { phoneNumber = message.getOriginatingAddress(); text = message.getMessageBody(); date = new Date(message.getTimestampMillis()); received = true; } - public Sms(String phoneNumber, String text, Date date) { + Sms(String phoneNumber, String text, Date date) { this.phoneNumber = phoneNumber; this.text = text; this.date = date; sent = true; } - public Sms(String phoneNumber, String text, Date date, String confirmCode) { + Sms(String phoneNumber, String text, Date date, String confirmCode) { this.phoneNumber = phoneNumber; this.text = text; this.date = date; @@ -96,12 +99,12 @@ public class SmsCommunicatorPlugin implements PluginBase { } } - Sms cancelTempBasalWaitingForConfirmation = null; - Sms tempBasalWaitingForConfirmation = null; - Sms bolusWaitingForConfirmation = null; - Sms calibrationWaitingForConfirmation = null; - Sms suspendWaitingForConfirmation = null; - Date lastRemoteBolusTime = new Date(0); + private Sms cancelTempBasalWaitingForConfirmation = null; + private Sms tempBasalWaitingForConfirmation = null; + private Sms bolusWaitingForConfirmation = null; + private Sms calibrationWaitingForConfirmation = null; + private Sms suspendWaitingForConfirmation = null; + private Date lastRemoteBolusTime = new Date(0); ArrayList messages = new ArrayList<>(); @@ -187,7 +190,7 @@ public class SmsCommunicatorPlugin implements PluginBase { } } - boolean isAllowedNumber(String number) { + private boolean isAllowedNumber(String number) { for (String num : allowedNumbers) { if (num.equals(number)) return true; } @@ -199,8 +202,8 @@ public class SmsCommunicatorPlugin implements PluginBase { Object[] pdus = (Object[]) ev.bundle.get("pdus"); // For every SMS message received - for (int i = 0; i < pdus.length; i++) { - SmsMessage message = SmsMessage.createFromPdu((byte[]) pdus[i]); + for (Object pdu : pdus) { + SmsMessage message = SmsMessage.createFromPdu((byte[]) pdu); processSms(new Sms(message)); } } @@ -233,25 +236,30 @@ public class SmsCommunicatorPlugin implements PluginBase { BgReading actualBG = GlucoseStatus.actualBg(); BgReading lastBG = GlucoseStatus.lastBg(); - NSProfile profile = MainApp.getConfigBuilder().getActiveProfile().getProfile(); - String units = profile.getUnits(); + if (ConfigBuilderPlugin.getActiveProfile() == null || ConfigBuilderPlugin.getActiveProfile().getProfile() == null) { + reply = MainApp.sResources.getString(R.string.noprofile); + sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); + return; + } - Long agoMsec = new Date().getTime() - lastBG.timeIndex; - int agoMin = (int) (agoMsec / 60d / 1000d); + NSProfile profile = ConfigBuilderPlugin.getActiveProfile().getProfile(); + String units = profile.getUnits(); if (actualBG != null) { reply = MainApp.sResources.getString(R.string.sms_actualbg) + " " + actualBG.valueToUnitsToString(units) + ", "; } else if (lastBG != null) { + Long agoMsec = new Date().getTime() - lastBG.timeIndex; + 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) + ", "; } GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData(); if (glucoseStatus != null) reply += MainApp.sResources.getString(R.string.sms_delta) + " " + NSProfile.toUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units) + " " + units + ", "; - MainApp.getConfigBuilder().getActiveTreatments().updateTotalIOB(); - IobTotal bolusIob = MainApp.getConfigBuilder().getActiveTreatments().getLastCalculation().round(); - MainApp.getConfigBuilder().getActiveTempBasals().updateTotalIOB(); - IobTotal basalIob = MainApp.getConfigBuilder().getActiveTempBasals().getLastCalculation().round(); + ConfigBuilderPlugin.getActiveTreatments().updateTotalIOB(); + IobTotal bolusIob = ConfigBuilderPlugin.getActiveTreatments().getLastCalculation().round(); + ConfigBuilderPlugin.getActiveTempBasals().updateTotalIOB(); + IobTotal basalIob = ConfigBuilderPlugin.getActiveTempBasals().getLastCalculation().round(); reply += MainApp.sResources.getString(R.string.sms_iob) + " " + DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U (" + MainApp.sResources.getString(R.string.sms_bolus) + " " + DecimalFormatter.to2Decimal(bolusIob.iob) + "U " @@ -303,10 +311,11 @@ public class SmsCommunicatorPlugin implements PluginBase { Answers.getInstance().logCustom(new CustomEvent("SMS_Loop_Status")); break; case "RESUME": - final LoopPlugin activeloop = MainApp.getConfigBuilder().getActiveLoop(); + final LoopPlugin activeloop = ConfigBuilderPlugin.getActiveLoop(); activeloop.suspendTo(0); MainApp.bus().post(new EventRefreshGui(false)); - reply = String.format(MainApp.sResources.getString(R.string.smscommunicator_loopresumed)); + ConfigBuilderPlugin.uploadOpenAPSOffline(0); + reply = MainApp.sResources.getString(R.string.smscommunicator_loopresumed); sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply, new Date())); Answers.getInstance().logCustom(new CustomEvent("SMS_Loop_Resume")); break; @@ -453,7 +462,7 @@ public class SmsCommunicatorPlugin implements PluginBase { PumpInterface pumpInterface = MainApp.getConfigBuilder(); if (pumpInterface != null) { danaRPlugin = (DanaRPlugin) MainApp.getSpecificPlugin(DanaRPlugin.class); - PumpEnactResult result = pumpInterface.deliverTreatment(MainApp.getConfigBuilder().getActiveInsulin(), bolusWaitingForConfirmation.bolusRequested, 0, null); + PumpEnactResult result = pumpInterface.deliverTreatment(ConfigBuilderPlugin.getActiveInsulin(), bolusWaitingForConfirmation.bolusRequested, 0, null); if (result.success) { reply = String.format(MainApp.sResources.getString(R.string.smscommunicator_bolusdelivered), result.bolusDelivered); if (danaRPlugin != null) @@ -494,7 +503,7 @@ public class SmsCommunicatorPlugin implements PluginBase { danaRPlugin = (DanaRPlugin) MainApp.getSpecificPlugin(DanaRPlugin.class); PumpEnactResult result = pumpInterface.cancelTempBasal(); if (result.success) { - reply = String.format(MainApp.sResources.getString(R.string.smscommunicator_tempbasalcanceled)); + reply = MainApp.sResources.getString(R.string.smscommunicator_tempbasalcanceled); if (danaRPlugin != null) reply += "\n" + danaRPlugin.shortStatus(true); sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply, new Date())); @@ -510,7 +519,7 @@ public class SmsCommunicatorPlugin implements PluginBase { calibrationWaitingForConfirmation.processed = true; boolean result = XdripCalibrations.sendIntent(calibrationWaitingForConfirmation.calibrationRequested); if (result) { - reply = String.format(MainApp.sResources.getString(R.string.smscommunicator_calibrationsent)); + reply = MainApp.sResources.getString(R.string.smscommunicator_calibrationsent); sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply, new Date())); } else { reply = MainApp.sResources.getString(R.string.smscommunicator_calibrationfailed); @@ -519,10 +528,11 @@ public class SmsCommunicatorPlugin implements PluginBase { } else if (suspendWaitingForConfirmation != null && !suspendWaitingForConfirmation.processed && suspendWaitingForConfirmation.confirmCode.equals(splited[0]) && new Date().getTime() - suspendWaitingForConfirmation.date.getTime() < CONFIRM_TIMEOUT) { suspendWaitingForConfirmation.processed = true; - final LoopPlugin activeloop = MainApp.getConfigBuilder().getActiveLoop(); + final LoopPlugin activeloop = ConfigBuilderPlugin.getActiveLoop(); activeloop.suspendTo(new Date().getTime() + suspendWaitingForConfirmation.duration * 60L * 1000); + ConfigBuilderPlugin.uploadOpenAPSOffline(suspendWaitingForConfirmation.duration * 60); MainApp.bus().post(new EventRefreshGui(false)); - reply = String.format(MainApp.sResources.getString(R.string.smscommunicator_loopsuspended)); + reply = MainApp.sResources.getString(R.string.smscommunicator_loopsuspended); sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply, new Date())); } else { sendSMS(new Sms(receivedSms.phoneNumber, MainApp.sResources.getString(R.string.smscommunicator_unknowncommand), new Date())); @@ -542,14 +552,14 @@ public class SmsCommunicatorPlugin implements PluginBase { } } - public void sendSMSToAllNumbers(Sms sms) { + private void sendSMSToAllNumbers(Sms sms) { for (String number : allowedNumbers) { sms.phoneNumber = number; sendSMS(sms); } } - public void sendSMS(Sms sms) { + private void sendSMS(Sms sms) { SmsManager smsManager = SmsManager.getDefault(); sms.text = stripAccents(sms.text); if (sms.text.length() > 140) sms.text = sms.text.substring(0, 139); @@ -584,7 +594,7 @@ public class SmsCommunicatorPlugin implements PluginBase { suspendWaitingForConfirmation = null; } - public static String stripAccents(String s) { + private static String stripAccents(String s) { s = Normalizer.normalize(s, Normalizer.Form.NFD); s = s.replaceAll("[\\p{InCombiningDiacriticalMarks}]", ""); return s; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/TempBasals/TempBasalsFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/TempBasals/TempBasalsFragment.java index fee0d278e8..1bd43719de 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/TempBasals/TempBasalsFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/TempBasals/TempBasalsFragment.java @@ -1,9 +1,13 @@ package info.nightscout.androidaps.plugins.TempBasals; import android.app.Activity; +import android.content.Context; +import android.content.DialogInterface; +import android.graphics.Paint; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.content.ContextCompat; +import android.support.v7.app.AlertDialog; import android.support.v7.widget.CardView; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; @@ -13,6 +17,8 @@ import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.TextView; +import com.crashlytics.android.answers.Answers; +import com.crashlytics.android.answers.CustomEvent; import com.squareup.otto.Subscribe; import org.slf4j.Logger; @@ -44,7 +50,9 @@ public class TempBasalsFragment extends Fragment { TextView tempBasalTotalView; - public static class RecyclerViewAdapter extends RecyclerView.Adapter { + Context context; + + public class RecyclerViewAdapter extends RecyclerView.Adapter { List tempBasalList; @@ -55,8 +63,7 @@ public class TempBasalsFragment extends Fragment { @Override public TempBasalsViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.tempbasals_item, viewGroup, false); - TempBasalsViewHolder tempBasalsViewHolder = new TempBasalsViewHolder(v); - return tempBasalsViewHolder; + return new TempBasalsViewHolder(v); } @Override @@ -89,6 +96,7 @@ public class TempBasalsFragment extends Fragment { holder.dateLinearLayout.setBackgroundColor(ContextCompat.getColor(MainApp.instance(), R.color.colorAffectingIOB)); else holder.dateLinearLayout.setBackgroundColor(ContextCompat.getColor(MainApp.instance(), R.color.cardColorBackground)); + holder.remove.setTag(tempBasal); } @Override @@ -101,7 +109,7 @@ public class TempBasalsFragment extends Fragment { super.onAttachedToRecyclerView(recyclerView); } - public static class TempBasalsViewHolder extends RecyclerView.ViewHolder { + public class TempBasalsViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { CardView cv; TextView date; TextView duration; @@ -113,6 +121,7 @@ public class TempBasalsFragment extends Fragment { TextView iob; TextView extendedFlag; LinearLayout dateLinearLayout; + TextView remove; TempBasalsViewHolder(View itemView) { super(itemView); @@ -127,6 +136,36 @@ public class TempBasalsFragment extends Fragment { iob = (TextView) itemView.findViewById(R.id.tempbasals_iob); extendedFlag = (TextView) itemView.findViewById(R.id.tempbasals_extendedflag); dateLinearLayout = (LinearLayout) itemView.findViewById(R.id.tempbasals_datelinearlayout); + remove = (TextView) itemView.findViewById(R.id.tempbasals_remove); + remove.setOnClickListener(this); + remove.setPaintFlags(remove.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG); + } + + @Override + public void onClick(View v) { + final TempBasal tempBasal = (TempBasal) v.getTag(); + switch (v.getId()) { + case R.id.tempbasals_remove: + AlertDialog.Builder builder = new AlertDialog.Builder(context); + builder.setTitle(MainApp.sResources.getString(R.string.confirmation)); + builder.setMessage(MainApp.sResources.getString(R.string.removerecord) + "\n" + DateUtil.dateAndTimeString(tempBasal.timeStart)); + builder.setPositiveButton(MainApp.sResources.getString(R.string.ok), new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + // TODO: handle this in NS too + //final String _id = tempBasal._id; + //if (_id != null && !_id.equals("")) { + // MainApp.getConfigBuilder().removeCareportalEntryFromNS(_id); + //} + MainApp.getDbHelper().delete(tempBasal); + tempBasalsPlugin.initializeData(); + updateGUI(); + Answers.getInstance().logCustom(new CustomEvent("RemoveTempBasal")); + } + }); + builder.setNegativeButton(MainApp.sResources.getString(R.string.cancel), null); + builder.show(); + break; + } } } } @@ -145,6 +184,9 @@ public class TempBasalsFragment extends Fragment { recyclerView.setAdapter(adapter); tempBasalTotalView = (TextView) view.findViewById(R.id.tempbasals_totaltempiob); + + context = getContext(); + updateGUI(); return view; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/TempBasals/TempBasalsPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/TempBasals/TempBasalsPlugin.java index d398ddfad6..51c5a2c0a1 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/TempBasals/TempBasalsPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/TempBasals/TempBasalsPlugin.java @@ -112,7 +112,7 @@ public class TempBasalsPlugin implements PluginBase, TempBasalsInterface { return PluginBase.TEMPBASAL; } - private void initializeData() { + public void initializeData() { double dia = 3; if (MainApp.getConfigBuilder().getActiveProfile() != null && MainApp.getConfigBuilder().getActiveProfile().getProfile() != null) dia = MainApp.getConfigBuilder().getActiveProfile().getProfile().getDia(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/TempTargetRange/TempTargetRangeFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/TempTargetRange/TempTargetRangeFragment.java index 13cae1aad0..9222a9a819 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/TempTargetRange/TempTargetRangeFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/TempTargetRange/TempTargetRangeFragment.java @@ -36,6 +36,7 @@ import info.nightscout.androidaps.plugins.NSClientInternal.data.NSProfile; import info.nightscout.androidaps.plugins.TempTargetRange.events.EventTempTargetRangeChange; import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; +import info.nightscout.utils.SP; import info.nightscout.utils.ToastUtils; /** @@ -194,8 +195,7 @@ public class TempTargetRangeFragment extends Fragment implements View.OnClickLis public void onClick(View view) { switch (view.getId()) { case R.id.temptargetrange_refreshfromnightscout: - SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(getContext()); - boolean nsUploadOnly = SP.getBoolean("ns_upload_only", false); + boolean nsUploadOnly = SP.getBoolean(R.string.key_ns_upload_only, false); if (nsUploadOnly) { ToastUtils.showToastInUiThread(getContext(), this.getContext().getString(R.string.ns_upload_only_enabled)); } else { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsFragment.java index 704d71e61b..e4442dde0f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsFragment.java @@ -38,9 +38,11 @@ import info.nightscout.androidaps.data.Iob; import info.nightscout.androidaps.db.Treatment; import info.nightscout.androidaps.events.EventTreatmentChange; import info.nightscout.androidaps.interfaces.InsulinInterface; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.NSClientInternal.data.NSProfile; import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; +import info.nightscout.utils.SP; import info.nightscout.utils.ToastUtils; public class TreatmentsFragment extends Fragment implements View.OnClickListener { @@ -72,16 +74,15 @@ public class TreatmentsFragment extends Fragment implements View.OnClickListener @Override public TreatmentsViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.treatments_item, viewGroup, false); - TreatmentsViewHolder treatmentsViewHolder = new TreatmentsViewHolder(v); - return treatmentsViewHolder; + return new TreatmentsViewHolder(v); } @Override public void onBindViewHolder(TreatmentsViewHolder holder, int position) { - if (MainApp.getConfigBuilder() == null || MainApp.getConfigBuilder().getActiveProfile() == null) // app not initialized yet + if (MainApp.getConfigBuilder() == null || ConfigBuilderPlugin.getActiveProfile() == null) // app not initialized yet return; - NSProfile profile = MainApp.getConfigBuilder().getActiveProfile().getProfile(); - InsulinInterface insulinInterface = MainApp.getConfigBuilder().getActiveInsulin(); + NSProfile profile = ConfigBuilderPlugin.getActiveProfile().getProfile(); + InsulinInterface insulinInterface = ConfigBuilderPlugin.getActiveInsulin(); if (profile == null || insulinInterface == null) return; holder.date.setText(DateUtil.dateAndTimeString(treatments.get(position).created_at)); @@ -137,7 +138,6 @@ public class TreatmentsFragment extends Fragment implements View.OnClickListener @Override public void onClick(View v) { final Treatment treatment = (Treatment) v.getTag(); - final Context finalContext = context; switch (v.getId()) { case R.id.treatments_remove: AlertDialog.Builder builder = new AlertDialog.Builder(context); @@ -152,7 +152,7 @@ public class TreatmentsFragment extends Fragment implements View.OnClickListener MainApp.getDbHelper().delete(treatment); treatmentsPlugin.initializeData(); updateGUI(); - Answers.getInstance().logCustom(new CustomEvent("RefreshTreatments")); + Answers.getInstance().logCustom(new CustomEvent("RemoveTreatment")); } }); builder.setNegativeButton(MainApp.sResources.getString(R.string.cancel), null); @@ -192,8 +192,7 @@ public class TreatmentsFragment extends Fragment implements View.OnClickListener public void onClick(View view) { switch (view.getId()) { case R.id.treatments_reshreshfromnightscout: - SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(getContext()); - boolean nsUploadOnly = SP.getBoolean("ns_upload_only", false); + boolean nsUploadOnly = SP.getBoolean(R.string.key_ns_upload_only, false); if (nsUploadOnly) { ToastUtils.showToastInUiThread(getContext(), this.getContext().getString(R.string.ns_upload_only_enabled)); } else { 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 d7265bfa3c..3bac27c168 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 @@ -45,10 +45,6 @@ public class StatuslinePlugin implements PluginBase { StatuslinePlugin(Context ctx) { this.ctx = ctx; this.mPrefs = PreferenceManager.getDefaultSharedPreferences(ctx); - - if (fragmentEnabled) { - MainApp.bus().register(this); - } } @Override @@ -108,11 +104,15 @@ public class StatuslinePlugin implements PluginBase { this.fragmentEnabled = fragmentEnabled; if (fragmentEnabled) { - MainApp.bus().register(this); + try { + MainApp.bus().register(this); + } catch (Exception e) {} sendStatus(); } else{ - MainApp.bus().unregister(this); + try { + MainApp.bus().unregister(this); + } catch (Exception e) {} sendStatus(); } } diff --git a/app/src/main/res/layout/careportal_fragment.xml b/app/src/main/res/layout/careportal_fragment.xml index b0beb569f3..f72dc7070e 100644 --- a/app/src/main/res/layout/careportal_fragment.xml +++ b/app/src/main/res/layout/careportal_fragment.xml @@ -19,6 +19,7 @@