From ea1e78b16921fea12e0ceaf5ceccb01ed4a46c2b Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Sat, 13 Oct 2018 16:50:47 +0200 Subject: [PATCH 01/39] prepare new classes --- .../info/nightscout/androidaps/logging/L.java | 2 + .../plugins/SmsCommunicator/AuthRequest.java | 54 +++++++++++++++ .../plugins/SmsCommunicator/Sms.java | 51 +++++++++++++++ .../plugins/SmsCommunicator/SmsAction.java | 16 +++++ .../SmsCommunicatorFragment.java | 65 +++++++------------ .../SmsCommunicatorPlugin.java | 59 ++++------------- 6 files changed, 158 insertions(+), 89 deletions(-) create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/AuthRequest.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/Sms.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/SmsAction.java diff --git a/app/src/main/java/info/nightscout/androidaps/logging/L.java b/app/src/main/java/info/nightscout/androidaps/logging/L.java index c44d2516c2..d47ba313af 100644 --- a/app/src/main/java/info/nightscout/androidaps/logging/L.java +++ b/app/src/main/java/info/nightscout/androidaps/logging/L.java @@ -95,6 +95,7 @@ public class L { public static final String PROFILE = "PROFILE"; public static final String CONFIGBUILDER = "CONFIGBUILDER"; public static final String UI = "UI"; + public static final String SMS = "SMS"; private static void initialize() { logElements = new ArrayList<>(); @@ -117,6 +118,7 @@ public class L { logElements.add(new LogElement(PUMPBTCOMM, false)); logElements.add(new LogElement(PUMPCOMM, true)); logElements.add(new LogElement(PUMPQUEUE, true)); + logElements.add(new LogElement(SMS, true)); logElements.add(new LogElement(UI, true)); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/AuthRequest.java b/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/AuthRequest.java new file mode 100644 index 0000000000..c5dde0f644 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/AuthRequest.java @@ -0,0 +1,54 @@ +package info.nightscout.androidaps.plugins.SmsCommunicator; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import info.nightscout.androidaps.Constants; +import info.nightscout.androidaps.logging.L; +import info.nightscout.utils.DateUtil; + +class AuthRequest { + private static Logger log = LoggerFactory.getLogger(L.SMS); + + private Sms requester; + private String confirmCode; + private Runnable action; + + private long date; + + private boolean processed; + + AuthRequest(SmsCommunicatorPlugin plugin, Sms requester, String requestText, String confirmCode, SmsAction action) { + this.requester = requester; + this.confirmCode = confirmCode; + this.action = action; + + this.date = DateUtil.now(); + + plugin.sendSMS(new Sms(requester.phoneNumber, requestText)); + } + + void action(String codeReceived) { + if (processed) { + if (L.isEnabled(L.SMS)) + log.debug("Already processed"); + return; + } + if (!confirmCode.equals(codeReceived)) { + if (L.isEnabled(L.SMS)) + log.debug("Wrong code"); + return; + } + if (DateUtil.now() - date < Constants.SMS_CONFIRM_TIMEOUT) { + processed = true; + if (L.isEnabled(L.SMS)) + log.debug("Processing confirmed SMS: " + requester.text); + if (action != null) + action.run(); + return; + } + if (L.isEnabled(L.SMS)) + log.debug("Timed out SMS: " + requester.text); + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/Sms.java b/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/Sms.java new file mode 100644 index 0000000000..a2e56c833d --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/Sms.java @@ -0,0 +1,51 @@ +package info.nightscout.androidaps.plugins.SmsCommunicator; + +import android.telephony.SmsMessage; + +class Sms { + String phoneNumber; + String confirmCode; // move + String text; + long date; //move + boolean received = false; + boolean sent = false; + boolean processed = false; + + double bolusRequested = 0d; + double tempBasal = 0d; + double calibrationRequested = 0d; + int duration = 0; + + Sms(SmsMessage message) { + phoneNumber = message.getOriginatingAddress(); + text = message.getMessageBody(); + date = message.getTimestampMillis(); + received = true; + } + + Sms(String phoneNumber, String text) { + this.phoneNumber = phoneNumber; + this.text = text; + sent = true; + } + + Sms(String phoneNumber, String text, long date) { + this.phoneNumber = phoneNumber; + this.text = text; + this.date = date; + sent = true; + } + + Sms(String phoneNumber, String text, long date, String confirmCode) { + this.phoneNumber = phoneNumber; + this.text = text; + this.date = date; + this.confirmCode = confirmCode; + sent = true; + } + + public String toString() { + return "SMS from " + phoneNumber + ": " + text; + } +} + diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/SmsAction.java b/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/SmsAction.java new file mode 100644 index 0000000000..6b0daf9f2d --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/SmsAction.java @@ -0,0 +1,16 @@ +package info.nightscout.androidaps.plugins.SmsCommunicator; + +abstract class SmsAction implements Runnable { + Double d; + Integer i; + + SmsAction() {} + + SmsAction(Double d) { + this.d = d; + } + + SmsAction(Integer i) { + this.i = i; + } +} 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 3f218063ef..0289437124 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 @@ -3,7 +3,6 @@ package info.nightscout.androidaps.plugins.SmsCommunicator; import android.app.Activity; import android.os.Bundle; -import android.support.v4.app.Fragment; import android.text.Html; import android.view.LayoutInflater; import android.view.View; @@ -12,9 +11,6 @@ import android.widget.TextView; import com.squareup.otto.Subscribe; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.util.Collections; import java.util.Comparator; @@ -22,14 +18,8 @@ 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; -import info.nightscout.utils.FabricPrivacy; -/** - * A simple {@link Fragment} subclass. - */ public class SmsCommunicatorFragment extends SubscriberFragment { - private static Logger log = LoggerFactory.getLogger(SmsCommunicatorFragment.class); - TextView logView; public SmsCommunicatorFragment() { @@ -39,18 +29,11 @@ public class SmsCommunicatorFragment extends SubscriberFragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - try { - View view = inflater.inflate(R.layout.smscommunicator_fragment, container, false); + View view = inflater.inflate(R.layout.smscommunicator_fragment, container, false); - logView = (TextView) view.findViewById(R.id.smscommunicator_log); + logView = (TextView) view.findViewById(R.id.smscommunicator_log); - updateGUI(); - return view; - } catch (Exception e) { - FabricPrivacy.logException(e); - } - - return null; + return view; } @Subscribe @@ -58,35 +41,31 @@ public class SmsCommunicatorFragment extends SubscriberFragment { updateGUI(); } - @Override protected void updateGUI() { Activity activity = getActivity(); if (activity != null) - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - class CustomComparator implements Comparator { - public int compare(SmsCommunicatorPlugin.Sms object1, SmsCommunicatorPlugin.Sms object2) { - return (int) (object1.date - object2.date); - } + activity.runOnUiThread(() -> { + class CustomComparator implements Comparator { + public int compare(Sms object1, Sms object2) { + return (int) (object1.date - object2.date); } - Collections.sort(SmsCommunicatorPlugin.getPlugin().messages, new CustomComparator()); - int messagesToShow = 40; - - int start = Math.max(0, SmsCommunicatorPlugin.getPlugin().messages.size() - messagesToShow); - - String logText = ""; - for (int x = start; x < SmsCommunicatorPlugin.getPlugin().messages.size(); x++) { - SmsCommunicatorPlugin.Sms sms = SmsCommunicatorPlugin.getPlugin().messages.get(x); - if (sms.received) { - logText += DateUtil.timeString(sms.date) + " <<< " + (sms.processed ? "● " : "○ ") + sms.phoneNumber + " " + sms.text + "
"; - } else if (sms.sent) { - logText += DateUtil.timeString(sms.date) + " >>> " + (sms.processed ? "● " : "○ ") + sms.phoneNumber + " " + sms.text + "
"; - } - } - logView.setText(Html.fromHtml(logText)); } + Collections.sort(SmsCommunicatorPlugin.getPlugin().messages, new CustomComparator()); + int messagesToShow = 40; + + int start = Math.max(0, SmsCommunicatorPlugin.getPlugin().messages.size() - messagesToShow); + + String logText = ""; + for (int x = start; x < SmsCommunicatorPlugin.getPlugin().messages.size(); x++) { + Sms sms = SmsCommunicatorPlugin.getPlugin().messages.get(x); + if (sms.received) { + logText += DateUtil.timeString(sms.date) + " <<< " + (sms.processed ? "● " : "○ ") + sms.phoneNumber + " " + sms.text + "
"; + } else if (sms.sent) { + logText += DateUtil.timeString(sms.date) + " >>> " + (sms.processed ? "● " : "○ ") + sms.phoneNumber + " " + sms.text + "
"; + } + } + logView.setText(Html.fromHtml(logText)); }); } } 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 1d36eea817..c18f678235 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 @@ -21,8 +21,6 @@ import java.util.List; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; -import info.nightscout.androidaps.services.Intents; import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.data.GlucoseStatus; import info.nightscout.androidaps.data.IobTotal; @@ -37,16 +35,19 @@ import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.Loop.LoopPlugin; +import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.Overview.notifications.Notification; import info.nightscout.androidaps.plugins.SmsCommunicator.events.EventSmsCommunicatorUpdateGui; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.androidaps.queue.Callback; +import info.nightscout.androidaps.services.Intents; import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.FabricPrivacy; -import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; import info.nightscout.utils.SP; import info.nightscout.utils.SafeParse; import info.nightscout.utils.T; @@ -56,7 +57,7 @@ import info.nightscout.utils.XdripCalibrations; * Created by mike on 05.08.2016. */ public class SmsCommunicatorPlugin extends PluginBase { - private static Logger log = LoggerFactory.getLogger(SmsCommunicatorPlugin.class); + private static Logger log = LoggerFactory.getLogger(L.SMS); private static SmsCommunicatorPlugin smsCommunicatorPlugin; @@ -70,46 +71,7 @@ public class SmsCommunicatorPlugin extends PluginBase { private List allowedNumbers = new ArrayList<>(); - class Sms { - String phoneNumber; - String text; - long date; - boolean received = false; - boolean sent = false; - boolean processed = false; - - String confirmCode; - double bolusRequested = 0d; - double tempBasal = 0d; - double calibrationRequested = 0d; - int duration = 0; - - Sms(SmsMessage message) { - phoneNumber = message.getOriginatingAddress(); - text = message.getMessageBody(); - date = message.getTimestampMillis(); - received = true; - } - - Sms(String phoneNumber, String text, long date) { - this.phoneNumber = phoneNumber; - this.text = text; - this.date = date; - sent = true; - } - - Sms(String phoneNumber, String text, long date, String confirmCode) { - this.phoneNumber = phoneNumber; - this.text = text; - this.date = date; - this.confirmCode = confirmCode; - sent = true; - } - - public String toString() { - return "SMS from " + phoneNumber + ": " + text; - } - } + private AuthRequest messageToConfirm = null; private Sms cancelTempBasalWaitingForConfirmation = null; private Sms tempBasalWaitingForConfirmation = null; @@ -443,6 +405,10 @@ public class SmsCommunicatorPlugin extends PluginBase { } break; default: // expect passCode here + if (messageToConfirm != null) { + messageToConfirm.action(splited[0]); + messageToConfirm = null; + } if (bolusWaitingForConfirmation != null && !bolusWaitingForConfirmation.processed && bolusWaitingForConfirmation.confirmCode.equals(splited[0]) && System.currentTimeMillis() - bolusWaitingForConfirmation.date < Constants.SMS_CONFIRM_TIMEOUT) { bolusWaitingForConfirmation.processed = true; @@ -561,12 +527,13 @@ public class SmsCommunicatorPlugin extends PluginBase { } } - private void sendSMS(Sms sms) { + 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); try { - log.debug("Sending SMS to " + sms.phoneNumber + ": " + sms.text); + if (L.isEnabled(L.SMS)) + log.debug("Sending SMS to " + sms.phoneNumber + ": " + sms.text); smsManager.sendTextMessage(sms.phoneNumber, null, sms.text, null, null); messages.add(sms); } catch (IllegalArgumentException e) { From 903504d72dedeb688641623c935b6cba399ad85d Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Sun, 14 Oct 2018 10:55:11 +0200 Subject: [PATCH 02/39] SMSPlugin refactor & cleanup --- .../plugins/SmsCommunicator/Sms.java | 26 +- .../plugins/SmsCommunicator/SmsAction.java | 12 +- .../SmsCommunicatorPlugin.java | 293 ++++++++---------- 3 files changed, 143 insertions(+), 188 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/Sms.java b/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/Sms.java index a2e56c833d..ec77f03923 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/Sms.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/Sms.java @@ -2,20 +2,16 @@ package info.nightscout.androidaps.plugins.SmsCommunicator; import android.telephony.SmsMessage; +import info.nightscout.utils.DateUtil; + class Sms { String phoneNumber; - String confirmCode; // move String text; - long date; //move + long date; boolean received = false; boolean sent = false; boolean processed = false; - double bolusRequested = 0d; - double tempBasal = 0d; - double calibrationRequested = 0d; - int duration = 0; - Sms(SmsMessage message) { phoneNumber = message.getOriginatingAddress(); text = message.getMessageBody(); @@ -26,21 +22,7 @@ class Sms { Sms(String phoneNumber, String text) { this.phoneNumber = phoneNumber; this.text = text; - sent = true; - } - - Sms(String phoneNumber, String text, long date) { - this.phoneNumber = phoneNumber; - this.text = text; - this.date = date; - sent = true; - } - - Sms(String phoneNumber, String text, long date, String confirmCode) { - this.phoneNumber = phoneNumber; - this.text = text; - this.date = date; - this.confirmCode = confirmCode; + this.date = DateUtil.now(); sent = true; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/SmsAction.java b/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/SmsAction.java index 6b0daf9f2d..6e991c8370 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/SmsAction.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/SmsAction.java @@ -1,16 +1,16 @@ package info.nightscout.androidaps.plugins.SmsCommunicator; abstract class SmsAction implements Runnable { - Double d; - Integer i; + Double aDouble; + Integer anInteger; SmsAction() {} - SmsAction(Double d) { - this.d = d; + SmsAction(Double aDouble) { + this.aDouble = aDouble; } - SmsAction(Integer i) { - this.i = i; + SmsAction(Integer anInteger) { + this.anInteger = anInteger; } } 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 6c9c662098..64f7e01d0c 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 @@ -73,11 +73,6 @@ public class SmsCommunicatorPlugin extends PluginBase { private AuthRequest messageToConfirm = null; - 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<>(); @@ -158,9 +153,6 @@ public class SmsCommunicatorPlugin extends PluginBase { log.debug(receivedSms.toString()); String[] splited = receivedSms.text.split("\\s+"); - Double amount; - Double tempBasal; - int duration = 0; String passCode; boolean remoteCommandsAllowed = SP.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false); @@ -192,9 +184,8 @@ public class SmsCommunicatorPlugin extends PluginBase { + MainApp.gs(R.string.sms_bolus) + " " + DecimalFormatter.to2Decimal(bolusIob.iob) + "U " + MainApp.gs(R.string.sms_basal) + " " + DecimalFormatter.to2Decimal(basalIob.basaliob) + "U)"; - sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); receivedSms.processed = true; - FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Bg")); break; case "LOOP": if (splited.length > 1) @@ -210,7 +201,7 @@ public class SmsCommunicatorPlugin extends PluginBase { MainApp.bus().post(new EventRefreshOverview("SMS_LOOP_STOP")); String reply = MainApp.gs(R.string.smscommunicator_loophasbeendisabled) + " " + MainApp.gs(result.success ? R.string.smscommunicator_tempbasalcanceled : R.string.smscommunicator_tempbasalcancelfailed); - sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); } }); } @@ -223,7 +214,7 @@ public class SmsCommunicatorPlugin extends PluginBase { if (loopPlugin != null && !loopPlugin.isEnabled(PluginType.LOOP)) { loopPlugin.setPluginEnabled(PluginType.LOOP, true); reply = MainApp.gs(R.string.smscommunicator_loophasbeenenabled); - sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); MainApp.bus().post(new EventRefreshOverview("SMS_LOOP_START")); } receivedSms.processed = true; @@ -240,7 +231,7 @@ public class SmsCommunicatorPlugin extends PluginBase { } else { reply = MainApp.gs(R.string.smscommunicator_loopisdisabled); } - sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); } receivedSms.processed = true; FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Loop_Status")); @@ -250,28 +241,48 @@ public class SmsCommunicatorPlugin extends PluginBase { MainApp.bus().post(new EventRefreshOverview("SMS_LOOP_RESUME")); NSUpload.uploadOpenAPSOffline(0); reply = MainApp.gs(R.string.smscommunicator_loopresumed); - sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); + sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Loop_Resume")); break; case "SUSPEND": + int duration = 0; if (splited.length >= 3) duration = SafeParse.stringToInt(splited[2]); duration = Math.max(0, duration); duration = Math.min(180, duration); if (duration == 0) { reply = MainApp.gs(R.string.smscommunicator_wrongduration); - sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); } else if (remoteCommandsAllowed) { passCode = generatePasscode(); reply = String.format(MainApp.gs(R.string.smscommunicator_suspendreplywithcode), duration, passCode); receivedSms.processed = true; - resetWaitingMessages(); - sendSMS(suspendWaitingForConfirmation = new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis(), passCode)); - suspendWaitingForConfirmation.duration = duration; - FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Loop_Suspend")); + messageToConfirm = new AuthRequest(this, receivedSms, reply, passCode, new SmsAction(duration) { + @Override + public void run() { + ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(true, new Callback() { + @Override + public void run() { + if (result.success) { + LoopPlugin.getPlugin().suspendTo(System.currentTimeMillis() + anInteger * 60L * 1000); + NSUpload.uploadOpenAPSOffline(anInteger * 60); + MainApp.bus().post(new EventRefreshOverview("SMS_LOOP_SUSPENDED")); + String reply = MainApp.gs(R.string.smscommunicator_loopsuspended) + " " + + MainApp.gs(result.success ? R.string.smscommunicator_tempbasalcanceled : R.string.smscommunicator_tempbasalcancelfailed); + sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); + } else { + String reply = MainApp.gs(R.string.smscommunicator_tempbasalcancelfailed); + reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); + } + } + }); + + } + }); } else { reply = MainApp.gs(R.string.smscommunicator_remotecommandnotallowed); - sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); } break; } @@ -285,7 +296,7 @@ public class SmsCommunicatorPlugin extends PluginBase { MainApp.instance().getApplicationContext().sendBroadcast(restartNSClient); List q = MainApp.instance().getApplicationContext().getPackageManager().queryBroadcastReceivers(restartNSClient, 0); reply = "TERATMENTS REFRESH " + q.size() + " receivers"; - sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); receivedSms.processed = true; FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Treatments_Refresh")); break; @@ -299,7 +310,7 @@ public class SmsCommunicatorPlugin extends PluginBase { MainApp.instance().getApplicationContext().sendBroadcast(restartNSClient); List q = MainApp.instance().getApplicationContext().getPackageManager().queryBroadcastReceivers(restartNSClient, 0); reply = "NSCLIENT RESTART " + q.size() + " receivers"; - sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); receivedSms.processed = true; FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Nsclient_Restart")); break; @@ -314,11 +325,11 @@ public class SmsCommunicatorPlugin extends PluginBase { if (result.success) { if (pump != null) { String reply = pump.shortStatus(true); - sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); + sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); } } else { String reply = MainApp.gs(R.string.readstatusfailed); - sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); } } }); @@ -332,32 +343,65 @@ public class SmsCommunicatorPlugin extends PluginBase { passCode = generatePasscode(); reply = String.format(MainApp.gs(R.string.smscommunicator_basalstopreplywithcode), passCode); receivedSms.processed = true; - resetWaitingMessages(); - sendSMS(cancelTempBasalWaitingForConfirmation = new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis(), passCode)); - FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Basal")); + messageToConfirm = new AuthRequest(this, receivedSms, reply, passCode, new SmsAction() { + @Override + public void run() { + ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(true, new Callback() { + @Override + public void run() { + if (result.success) { + String reply = MainApp.gs(R.string.smscommunicator_tempbasalcanceled); + reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); + sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); + } else { + String reply = MainApp.gs(R.string.smscommunicator_tempbasalcancelfailed); + reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); + } + } + }); + } + }); } else { reply = MainApp.gs(R.string.smscommunicator_remotebasalnotallowed); - sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); } } else { - tempBasal = SafeParse.stringToDouble(splited[1]); + Double tempBasal = SafeParse.stringToDouble(splited[1]); Profile profile = ProfileFunctions.getInstance().getProfile(); if (profile == null) { reply = MainApp.gs(R.string.noprofile); - sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); } else { tempBasal = MainApp.getConstraintChecker().applyBasalConstraints(new Constraint<>(tempBasal), profile).value(); if (remoteCommandsAllowed) { passCode = generatePasscode(); reply = String.format(MainApp.gs(R.string.smscommunicator_basalreplywithcode), tempBasal, passCode); receivedSms.processed = true; - resetWaitingMessages(); - sendSMS(tempBasalWaitingForConfirmation = new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis(), passCode)); - tempBasalWaitingForConfirmation.tempBasal = tempBasal; - FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Basal")); + messageToConfirm = new AuthRequest(this, receivedSms, reply, passCode, new SmsAction(tempBasal) { + @Override + public void run() { + Profile profile = ProfileFunctions.getInstance().getProfile(); + if (profile != null) + ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalAbsolute(aDouble, 30, true, profile, new Callback() { + @Override + public void run() { + if (result.success) { + String reply = String.format(MainApp.gs(R.string.smscommunicator_tempbasalset), result.absolute, result.duration); + reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); + sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); + } else { + String reply = MainApp.gs(R.string.smscommunicator_tempbasalfailed); + reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); + } + } + }); + } + }); } else { reply = MainApp.gs(R.string.smscommunicator_remotebasalnotallowed); - sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); } } } @@ -366,41 +410,74 @@ public class SmsCommunicatorPlugin extends PluginBase { case "BOLUS": if (System.currentTimeMillis() - lastRemoteBolusTime.getTime() < Constants.remoteBolusMinDistance) { reply = MainApp.gs(R.string.smscommunicator_remotebolusnotallowed); - sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); } else if (ConfigBuilderPlugin.getPlugin().getActivePump().isSuspended()) { reply = MainApp.gs(R.string.pumpsuspended); - sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); } else if (splited.length > 1) { - amount = SafeParse.stringToDouble(splited[1]); - amount = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(amount)).value(); - if (amount > 0d && remoteCommandsAllowed) { + Double bolus = SafeParse.stringToDouble(splited[1]); + bolus = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(bolus)).value(); + if (bolus > 0d && remoteCommandsAllowed) { passCode = generatePasscode(); - reply = String.format(MainApp.gs(R.string.smscommunicator_bolusreplywithcode), amount, passCode); + reply = String.format(MainApp.gs(R.string.smscommunicator_bolusreplywithcode), bolus, passCode); receivedSms.processed = true; - resetWaitingMessages(); - sendSMS(bolusWaitingForConfirmation = new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis(), passCode)); - bolusWaitingForConfirmation.bolusRequested = amount; - FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Bolus")); + messageToConfirm = new AuthRequest(this, receivedSms, reply, passCode, new SmsAction(bolus) { + @Override + public void run() { + DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo(); + detailedBolusInfo.insulin = aDouble; + detailedBolusInfo.source = Source.USER; + ConfigBuilderPlugin.getPlugin().getCommandQueue().bolus(detailedBolusInfo, new Callback() { + @Override + public void run() { + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); + if (result.success) { + SystemClock.sleep(T.secs(15).msecs()); // wait some time to get history + String reply = String.format(MainApp.gs(R.string.smscommunicator_bolusdelivered), result.bolusDelivered); + if (pump != null) + reply += "\n" + pump.shortStatus(true); + lastRemoteBolusTime = new Date(); + sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); + } else { + SystemClock.sleep(T.secs(60).msecs()); // wait some time to get history + String reply = MainApp.gs(R.string.smscommunicator_bolusfailed); + if (pump != null) + reply += "\n" + pump.shortStatus(true); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); + } + } + }); + } + }); } else { reply = MainApp.gs(R.string.smscommunicator_remotebolusnotallowed); - sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); } } break; case "CAL": if (splited.length > 1) { - amount = SafeParse.stringToDouble(splited[1]); - if (amount > 0d && remoteCommandsAllowed) { + Double cal = SafeParse.stringToDouble(splited[1]); + if (cal > 0d && remoteCommandsAllowed) { passCode = generatePasscode(); - reply = String.format(MainApp.gs(R.string.smscommunicator_calibrationreplywithcode), amount, passCode); + reply = String.format(MainApp.gs(R.string.smscommunicator_calibrationreplywithcode), cal, passCode); receivedSms.processed = true; - resetWaitingMessages(); - sendSMS(calibrationWaitingForConfirmation = new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis(), passCode)); - calibrationWaitingForConfirmation.calibrationRequested = amount; - FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Cal")); + messageToConfirm = new AuthRequest(this, receivedSms, reply, passCode, new SmsAction() { + @Override + public void run() { + boolean result = XdripCalibrations.sendIntent(aDouble); + if (result) { + String reply = MainApp.gs(R.string.smscommunicator_calibrationsent); + sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); + } else { + String reply = MainApp.gs(R.string.smscommunicator_calibrationfailed); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); + } + } + }); } else { reply = MainApp.gs(R.string.smscommunicator_remotecalibrationnotallowed); - sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); } } break; @@ -408,105 +485,9 @@ public class SmsCommunicatorPlugin extends PluginBase { if (messageToConfirm != null) { messageToConfirm.action(splited[0]); messageToConfirm = null; - } - if (bolusWaitingForConfirmation != null && !bolusWaitingForConfirmation.processed && - bolusWaitingForConfirmation.confirmCode.equals(splited[0]) && System.currentTimeMillis() - bolusWaitingForConfirmation.date < Constants.SMS_CONFIRM_TIMEOUT) { - bolusWaitingForConfirmation.processed = true; - DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo(); - detailedBolusInfo.insulin = bolusWaitingForConfirmation.bolusRequested; - detailedBolusInfo.source = Source.USER; - ConfigBuilderPlugin.getPlugin().getCommandQueue().bolus(detailedBolusInfo, new Callback() { - @Override - public void run() { - PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); - if (result.success) { - SystemClock.sleep(T.secs(15).msecs()); // wait some time to get history - String reply = String.format(MainApp.gs(R.string.smscommunicator_bolusdelivered), result.bolusDelivered); - if (pump != null) - reply += "\n" + pump.shortStatus(true); - lastRemoteBolusTime = new Date(); - sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); - } else { - SystemClock.sleep(T.secs(60).msecs()); // wait some time to get history - String reply = MainApp.gs(R.string.smscommunicator_bolusfailed); - if (pump != null) - reply += "\n" + pump.shortStatus(true); - sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); - } - } - }); - } else if (tempBasalWaitingForConfirmation != null && !tempBasalWaitingForConfirmation.processed && - tempBasalWaitingForConfirmation.confirmCode.equals(splited[0]) && System.currentTimeMillis() - tempBasalWaitingForConfirmation.date < Constants.SMS_CONFIRM_TIMEOUT) { - tempBasalWaitingForConfirmation.processed = true; - Profile profile = ProfileFunctions.getInstance().getProfile(); - if (profile != null) - ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalAbsolute(tempBasalWaitingForConfirmation.tempBasal, 30, true, profile, new Callback() { - @Override - public void run() { - if (result.success) { - String reply = String.format(MainApp.gs(R.string.smscommunicator_tempbasalset), result.absolute, result.duration); - reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); - sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); - } else { - String reply = MainApp.gs(R.string.smscommunicator_tempbasalfailed); - reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); - sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); - } - } - }); - } else if (cancelTempBasalWaitingForConfirmation != null && !cancelTempBasalWaitingForConfirmation.processed && - cancelTempBasalWaitingForConfirmation.confirmCode.equals(splited[0]) && System.currentTimeMillis() - cancelTempBasalWaitingForConfirmation.date < Constants.SMS_CONFIRM_TIMEOUT) { - cancelTempBasalWaitingForConfirmation.processed = true; - ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(true, new Callback() { - @Override - public void run() { - if (result.success) { - String reply = MainApp.gs(R.string.smscommunicator_tempbasalcanceled); - reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); - sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); - } else { - String reply = MainApp.gs(R.string.smscommunicator_tempbasalcancelfailed); - reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); - sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); - } - } - }); - } else if (calibrationWaitingForConfirmation != null && !calibrationWaitingForConfirmation.processed && - calibrationWaitingForConfirmation.confirmCode.equals(splited[0]) && System.currentTimeMillis() - calibrationWaitingForConfirmation.date < Constants.SMS_CONFIRM_TIMEOUT) { - calibrationWaitingForConfirmation.processed = true; - boolean result = XdripCalibrations.sendIntent(calibrationWaitingForConfirmation.calibrationRequested); - if (result) { - reply = MainApp.gs(R.string.smscommunicator_calibrationsent); - sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); - } else { - reply = MainApp.gs(R.string.smscommunicator_calibrationfailed); - sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); - } - } else if (suspendWaitingForConfirmation != null && !suspendWaitingForConfirmation.processed && - suspendWaitingForConfirmation.confirmCode.equals(splited[0]) && System.currentTimeMillis() - suspendWaitingForConfirmation.date < Constants.SMS_CONFIRM_TIMEOUT) { - suspendWaitingForConfirmation.processed = true; - final int dur = suspendWaitingForConfirmation.duration; - ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(true, new Callback() { - @Override - public void run() { - if (result.success) { - LoopPlugin.getPlugin().suspendTo(System.currentTimeMillis() + dur * 60L * 1000); - NSUpload.uploadOpenAPSOffline(dur * 60); - MainApp.bus().post(new EventRefreshOverview("SMS_LOOP_SUSPENDED")); - String reply = MainApp.gs(R.string.smscommunicator_loopsuspended) + " " + - MainApp.gs(result.success ? R.string.smscommunicator_tempbasalcanceled : R.string.smscommunicator_tempbasalcancelfailed); - sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); - } else { - String reply = MainApp.gs(R.string.smscommunicator_tempbasalcancelfailed); - reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); - sendSMS(new Sms(receivedSms.phoneNumber, reply, System.currentTimeMillis())); - } - } - }); } else { - sendSMS(new Sms(receivedSms.phoneNumber, MainApp.gs(R.string.smscommunicator_unknowncommand), System.currentTimeMillis())); + sendSMS(new Sms(receivedSms.phoneNumber, MainApp.gs(R.string.smscommunicator_unknowncommand))); } - resetWaitingMessages(); break; } } @@ -516,7 +497,7 @@ public class SmsCommunicatorPlugin extends PluginBase { public void sendNotificationToAllNumbers(String text) { for (int i = 0; i < allowedNumbers.size(); i++) { - Sms sms = new Sms(allowedNumbers.get(i), text, System.currentTimeMillis()); + Sms sms = new Sms(allowedNumbers.get(i), text); sendSMS(sms); } } @@ -556,14 +537,6 @@ public class SmsCommunicatorPlugin extends PluginBase { return passCode; } - private void resetWaitingMessages() { - tempBasalWaitingForConfirmation = null; - cancelTempBasalWaitingForConfirmation = null; - bolusWaitingForConfirmation = null; - calibrationWaitingForConfirmation = null; - suspendWaitingForConfirmation = null; - } - private static String stripAccents(String s) { s = Normalizer.normalize(s, Normalizer.Form.NFD); s = s.replaceAll("[\\p{InCombiningDiacriticalMarks}]", ""); From cc25520770001974ee0c6749b64b8203b39f51b7 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Sun, 14 Oct 2018 11:58:19 +0200 Subject: [PATCH 03/39] ignore SMS starting # --- .../plugins/SmsCommunicator/SmsCommunicatorPlugin.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 64f7e01d0c..0fc392fc8a 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 @@ -482,7 +482,9 @@ public class SmsCommunicatorPlugin extends PluginBase { } break; default: // expect passCode here - if (messageToConfirm != null) { + if (splited[0].startsWith("#")) { + // user text .... ignore + } else if (messageToConfirm != null) { messageToConfirm.action(splited[0]); messageToConfirm = null; } else { From 26cb25893ecb8acb37f66b4c7b81dfaa82a501d5 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Sun, 14 Oct 2018 12:01:14 +0200 Subject: [PATCH 04/39] remove fabric logging for SMS --- .../plugins/SmsCommunicator/SmsCommunicatorPlugin.java | 9 --------- 1 file changed, 9 deletions(-) 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 0fc392fc8a..a6fde68028 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 @@ -7,7 +7,6 @@ import android.os.SystemClock; import android.telephony.SmsManager; import android.telephony.SmsMessage; -import com.crashlytics.android.answers.CustomEvent; import com.squareup.otto.Subscribe; import org.slf4j.Logger; @@ -47,7 +46,6 @@ import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.androidaps.queue.Callback; import info.nightscout.androidaps.services.Intents; import info.nightscout.utils.DecimalFormatter; -import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.SP; import info.nightscout.utils.SafeParse; import info.nightscout.utils.T; @@ -206,7 +204,6 @@ public class SmsCommunicatorPlugin extends PluginBase { }); } receivedSms.processed = true; - FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Loop_Stop")); break; case "ENABLE": case "START": @@ -218,7 +215,6 @@ public class SmsCommunicatorPlugin extends PluginBase { MainApp.bus().post(new EventRefreshOverview("SMS_LOOP_START")); } receivedSms.processed = true; - FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Loop_Start")); break; case "STATUS": loopPlugin = MainApp.getSpecificPlugin(LoopPlugin.class); @@ -234,7 +230,6 @@ public class SmsCommunicatorPlugin extends PluginBase { sendSMS(new Sms(receivedSms.phoneNumber, reply)); } receivedSms.processed = true; - FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Loop_Status")); break; case "RESUME": LoopPlugin.getPlugin().suspendTo(0); @@ -242,7 +237,6 @@ public class SmsCommunicatorPlugin extends PluginBase { NSUpload.uploadOpenAPSOffline(0); reply = MainApp.gs(R.string.smscommunicator_loopresumed); sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); - FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Loop_Resume")); break; case "SUSPEND": int duration = 0; @@ -298,7 +292,6 @@ public class SmsCommunicatorPlugin extends PluginBase { reply = "TERATMENTS REFRESH " + q.size() + " receivers"; sendSMS(new Sms(receivedSms.phoneNumber, reply)); receivedSms.processed = true; - FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Treatments_Refresh")); break; } break; @@ -312,7 +305,6 @@ public class SmsCommunicatorPlugin extends PluginBase { reply = "NSCLIENT RESTART " + q.size() + " receivers"; sendSMS(new Sms(receivedSms.phoneNumber, reply)); receivedSms.processed = true; - FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Nsclient_Restart")); break; } break; @@ -334,7 +326,6 @@ public class SmsCommunicatorPlugin extends PluginBase { } }); receivedSms.processed = true; - FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Pump")); break; case "BASAL": if (splited.length > 1) { From 791d5dbd1bc3d66c595ce8ab5bed91232d535d3a Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Fri, 8 Mar 2019 19:42:48 +0100 Subject: [PATCH 05/39] add missing files after merge --- .../androidaps/plugins/general/smsCommunicator/AuthRequest.java | 2 +- .../androidaps/plugins/general/smsCommunicator/Sms.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequest.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequest.java index 525c7837bf..07744c7c7b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequest.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequest.java @@ -5,7 +5,7 @@ import org.slf4j.LoggerFactory; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.logging.L; -import info.nightscout.utils.DateUtil; +import info.nightscout.androidaps.utils.DateUtil; class AuthRequest { private static Logger log = LoggerFactory.getLogger(L.SMS); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/Sms.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/Sms.java index 1402d8d0ca..14a26e8fd3 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/Sms.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/Sms.java @@ -2,7 +2,7 @@ package info.nightscout.androidaps.plugins.general.smsCommunicator; import android.telephony.SmsMessage; -import info.nightscout.utils.DateUtil; +import info.nightscout.androidaps.utils.DateUtil; class Sms { String phoneNumber; From 6ea49f17bcf62e50f8b352b1a4b3b5f38ce79d8b Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Fri, 8 Mar 2019 21:08:21 +0100 Subject: [PATCH 06/39] SMS Plugin add missing fragment refresh --- .../plugins/general/smsCommunicator/SmsCommunicatorPlugin.java | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java index 3c7864d757..c158ae6c57 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java @@ -518,6 +518,7 @@ public class SmsCommunicatorPlugin extends PluginBase { Notification notification = new Notification(Notification.MISSING_SMS_PERMISSION, MainApp.gs(R.string.smscommunicator_missingsmspermission), Notification.NORMAL); MainApp.bus().post(new EventNewNotification(notification)); } + MainApp.bus().post(new EventSmsCommunicatorUpdateGui()); } private String generatePasscode() { From 1eea170ead1564d4ddfd70fc2e5ec598f02e03c7 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Fri, 8 Mar 2019 22:07:20 +0100 Subject: [PATCH 07/39] SMS Plugin correct response for % TBR --- .../general/smsCommunicator/SmsCommunicatorPlugin.java | 6 +++++- app/src/main/res/values/strings.xml | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java index c158ae6c57..c6453b25f1 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java @@ -378,7 +378,11 @@ public class SmsCommunicatorPlugin extends PluginBase { @Override public void run() { if (result.success) { - String reply = String.format(MainApp.gs(R.string.smscommunicator_tempbasalset), result.absolute, result.duration); + String reply; + if (result.isPercent) + reply = String.format(MainApp.gs(R.string.smscommunicator_tempbasalset_percent), result.percent, result.duration); + else + reply = String.format(MainApp.gs(R.string.smscommunicator_tempbasalset), result.absolute, result.duration); reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); } else { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index be0e0e2c5d..b97adda5c7 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -371,6 +371,7 @@ To start basal %1$.2fU/h reply with code %2$s To suspend loop for %1$d minutes reply with code %2$s Temp basal %1$.2fU/h for %2$d min started successfully + Temp basal %1$d %% for %2$d min started successfully Temp basal start failed To stop temp basal reply with code %s Temp basal canceled From 9e2cb7d047be7adb292c96e3ef886b73667771d8 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Fri, 8 Mar 2019 23:01:33 +0100 Subject: [PATCH 08/39] allow any non letter for SMS to ignore command --- .../plugins/general/smsCommunicator/SmsCommunicatorPlugin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java index c6453b25f1..7727a083a6 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java @@ -477,7 +477,7 @@ public class SmsCommunicatorPlugin extends PluginBase { } break; default: // expect passCode here - if (splited[0].startsWith("#")) { + if (!Character.isLetter(splited[0].charAt(0))) { // user text .... ignore } else if (messageToConfirm != null) { messageToConfirm.action(splited[0]); From 95da55724efb83442c9766f8b42d8f52bcca2110 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Fri, 8 Mar 2019 23:30:25 +0100 Subject: [PATCH 09/39] SMS Plugin show ignored too --- .../androidaps/plugins/general/smsCommunicator/Sms.java | 1 + .../general/smsCommunicator/SmsCommunicatorFragment.java | 4 +++- .../general/smsCommunicator/SmsCommunicatorPlugin.java | 3 +++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/Sms.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/Sms.java index 14a26e8fd3..470770f134 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/Sms.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/Sms.java @@ -11,6 +11,7 @@ class Sms { boolean received = false; boolean sent = false; boolean processed = false; + boolean ignored = false; Sms(SmsMessage message) { phoneNumber = message.getOriginatingAddress(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorFragment.java index 1104bfcf3e..d1c4adf5fe 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorFragment.java @@ -59,7 +59,9 @@ public class SmsCommunicatorFragment extends SubscriberFragment { String logText = ""; for (int x = start; x < SmsCommunicatorPlugin.getPlugin().messages.size(); x++) { Sms sms = SmsCommunicatorPlugin.getPlugin().messages.get(x); - if (sms.received) { + if (sms.ignored) { + logText += DateUtil.timeString(sms.date) + " <<< " + "░ " + sms.phoneNumber + " " + sms.text + "
"; + } else if (sms.received) { logText += DateUtil.timeString(sms.date) + " <<< " + (sms.processed ? "● " : "○ ") + sms.phoneNumber + " " + sms.text + "
"; } else if (sms.sent) { logText += DateUtil.timeString(sms.date) + " >>> " + (sms.processed ? "● " : "○ ") + sms.phoneNumber + " " + sms.text + "
"; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java index 7727a083a6..daf07f9e2f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java @@ -142,6 +142,9 @@ public class SmsCommunicatorPlugin extends PluginBase { } if (!isAllowedNumber(receivedSms.phoneNumber)) { log.debug("Ignoring SMS from: " + receivedSms.phoneNumber + ". Sender not allowed"); + receivedSms.ignored = true; + messages.add(receivedSms); + MainApp.bus().post(new EventSmsCommunicatorUpdateGui()); return; } From 56f977df3c3c331b5d1a2abf36fbb97ce7393375 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Fri, 8 Mar 2019 23:48:41 +0100 Subject: [PATCH 10/39] SMS Plugin allow basal in % --- .../SmsCommunicatorPlugin.java | 46 +++++++++++++++++++ app/src/main/res/values/strings.xml | 2 + 2 files changed, 48 insertions(+) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java index daf07f9e2f..0b3f66ea97 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java @@ -9,6 +9,7 @@ import android.telephony.SmsMessage; import com.squareup.otto.Subscribe; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -360,6 +361,51 @@ public class SmsCommunicatorPlugin extends PluginBase { reply = MainApp.gs(R.string.smscommunicator_remotebasalnotallowed); sendSMS(new Sms(receivedSms.phoneNumber, reply)); } + } else if (splited[1].endsWith("%")) { + int tempBasalPct = SafeParse.stringToInt(StringUtils.removeEnd(splited[1],"%")); + Profile profile = ProfileFunctions.getInstance().getProfile(); + if (profile == null) { + reply = MainApp.gs(R.string.noprofile); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); + } else if (tempBasalPct == 0 && !splited[1].equals("0%")) { + reply = MainApp.gs(R.string.wrongformat); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); + } else { + tempBasalPct = MainApp.getConstraintChecker().applyBasalPercentConstraints(new Constraint<>(tempBasalPct), profile).value(); + if (remoteCommandsAllowed) { + passCode = generatePasscode(); + reply = String.format(MainApp.gs(R.string.smscommunicator_basalpctreplywithcode), tempBasalPct, passCode); + receivedSms.processed = true; + messageToConfirm = new AuthRequest(this, receivedSms, reply, passCode, new SmsAction(tempBasalPct) { + @Override + public void run() { + Profile profile = ProfileFunctions.getInstance().getProfile(); + if (profile != null) + ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalPercent(anInteger, 30, true, profile, new Callback() { + @Override + public void run() { + if (result.success) { + String reply; + if (result.isPercent) + reply = String.format(MainApp.gs(R.string.smscommunicator_tempbasalset_percent), result.percent, result.duration); + else + reply = String.format(MainApp.gs(R.string.smscommunicator_tempbasalset), result.absolute, result.duration); + reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); + sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); + } else { + String reply = MainApp.gs(R.string.smscommunicator_tempbasalfailed); + reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); + } + } + }); + } + }); + } else { + reply = MainApp.gs(R.string.smscommunicator_remotebasalnotallowed); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); + } + } } else { Double tempBasal = SafeParse.stringToDouble(splited[1]); Profile profile = ProfileFunctions.getInstance().getProfile(); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b97adda5c7..2974ee86d3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -369,6 +369,7 @@ Remote basal setting is not allowed Remote command is not allowed To start basal %1$.2fU/h reply with code %2$s + To start basal %1$d%% reply with code %2$s To suspend loop for %1$d minutes reply with code %2$s Temp basal %1$.2fU/h for %2$d min started successfully Temp basal %1$d %% for %2$d min started successfully @@ -1315,6 +1316,7 @@ Dayligh Saving time change in less than 3 hours - Closed loop diabled internal storage constraint Free at least %1$d MB from internal storage! Loop disabled! + Wrong format %1$d day %1$d days From 79b6bc6c4323d8f395059f1f0443fb76e2b8de6f Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Fri, 8 Mar 2019 23:56:35 +0100 Subject: [PATCH 11/39] SMS Plugin allow duration in basal command --- .../plugins/general/smsCommunicator/SmsAction.java | 11 +++++++++++ .../smsCommunicator/SmsCommunicatorPlugin.java | 14 ++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsAction.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsAction.java index 14f03776df..d6ea031fa7 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsAction.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsAction.java @@ -3,6 +3,7 @@ package info.nightscout.androidaps.plugins.general.smsCommunicator; abstract class SmsAction implements Runnable { Double aDouble; Integer anInteger; + Integer secondInteger; SmsAction() {} @@ -10,7 +11,17 @@ abstract class SmsAction implements Runnable { this.aDouble = aDouble; } + SmsAction(Double aDouble, Integer secondInteger) { + this.aDouble = aDouble; + this.secondInteger = secondInteger; + } + SmsAction(Integer anInteger) { this.anInteger = anInteger; } + + SmsAction(Integer anInteger, Integer secondInteger) { + this.anInteger = anInteger; + this.secondInteger = secondInteger; + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java index 0b3f66ea97..6ff70602fc 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java @@ -363,6 +363,9 @@ public class SmsCommunicatorPlugin extends PluginBase { } } else if (splited[1].endsWith("%")) { int tempBasalPct = SafeParse.stringToInt(StringUtils.removeEnd(splited[1],"%")); + int duration = 30; + if (splited.length > 2) + duration = SafeParse.stringToInt(splited[2]); Profile profile = ProfileFunctions.getInstance().getProfile(); if (profile == null) { reply = MainApp.gs(R.string.noprofile); @@ -376,12 +379,12 @@ public class SmsCommunicatorPlugin extends PluginBase { passCode = generatePasscode(); reply = String.format(MainApp.gs(R.string.smscommunicator_basalpctreplywithcode), tempBasalPct, passCode); receivedSms.processed = true; - messageToConfirm = new AuthRequest(this, receivedSms, reply, passCode, new SmsAction(tempBasalPct) { + messageToConfirm = new AuthRequest(this, receivedSms, reply, passCode, new SmsAction(tempBasalPct, duration) { @Override public void run() { Profile profile = ProfileFunctions.getInstance().getProfile(); if (profile != null) - ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalPercent(anInteger, 30, true, profile, new Callback() { + ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalPercent(anInteger, secondInteger, true, profile, new Callback() { @Override public void run() { if (result.success) { @@ -408,6 +411,9 @@ public class SmsCommunicatorPlugin extends PluginBase { } } else { Double tempBasal = SafeParse.stringToDouble(splited[1]); + int duration = 30; + if (splited.length > 2) + duration = SafeParse.stringToInt(splited[2]); Profile profile = ProfileFunctions.getInstance().getProfile(); if (profile == null) { reply = MainApp.gs(R.string.noprofile); @@ -418,12 +424,12 @@ public class SmsCommunicatorPlugin extends PluginBase { passCode = generatePasscode(); reply = String.format(MainApp.gs(R.string.smscommunicator_basalreplywithcode), tempBasal, passCode); receivedSms.processed = true; - messageToConfirm = new AuthRequest(this, receivedSms, reply, passCode, new SmsAction(tempBasal) { + messageToConfirm = new AuthRequest(this, receivedSms, reply, passCode, new SmsAction(tempBasal, duration) { @Override public void run() { Profile profile = ProfileFunctions.getInstance().getProfile(); if (profile != null) - ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalAbsolute(aDouble, 30, true, profile, new Callback() { + ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalAbsolute(aDouble, secondInteger, true, profile, new Callback() { @Override public void run() { if (result.success) { From 53721d5d2c96f7fa5b47c99368c1f20217aa344a Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Sat, 9 Mar 2019 09:52:58 +0100 Subject: [PATCH 12/39] SMS Plugin extended bolus support --- .../SmsCommunicatorPlugin.java | 83 +++++++++++++++++-- app/src/main/res/values/strings.xml | 9 +- 2 files changed, 82 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java index 6ff70602fc..19b62132f3 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java @@ -358,11 +358,11 @@ public class SmsCommunicatorPlugin extends PluginBase { } }); } else { - reply = MainApp.gs(R.string.smscommunicator_remotebasalnotallowed); + reply = MainApp.gs(R.string.smscommunicator_remotecommandnotallowed); sendSMS(new Sms(receivedSms.phoneNumber, reply)); } } else if (splited[1].endsWith("%")) { - int tempBasalPct = SafeParse.stringToInt(StringUtils.removeEnd(splited[1],"%")); + int tempBasalPct = SafeParse.stringToInt(StringUtils.removeEnd(splited[1], "%")); int duration = 30; if (splited.length > 2) duration = SafeParse.stringToInt(splited[2]); @@ -405,7 +405,7 @@ public class SmsCommunicatorPlugin extends PluginBase { } }); } else { - reply = MainApp.gs(R.string.smscommunicator_remotebasalnotallowed); + reply = MainApp.gs(R.string.smscommunicator_remotecommandnotallowed); sendSMS(new Sms(receivedSms.phoneNumber, reply)); } } @@ -450,7 +450,76 @@ public class SmsCommunicatorPlugin extends PluginBase { } }); } else { - reply = MainApp.gs(R.string.smscommunicator_remotebasalnotallowed); + reply = MainApp.gs(R.string.smscommunicator_remotecommandnotallowed); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); + } + } + } + } + break; + case "EXTENDED": + if (splited.length > 1) { + if (splited[1].toUpperCase().equals("CANCEL") || splited[1].toUpperCase().equals("STOP")) { + if (remoteCommandsAllowed) { + passCode = generatePasscode(); + reply = String.format(MainApp.gs(R.string.smscommunicator_extendedstopreplywithcode), passCode); + receivedSms.processed = true; + messageToConfirm = new AuthRequest(this, receivedSms, reply, passCode, new SmsAction() { + @Override + public void run() { + ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelExtended(new Callback() { + @Override + public void run() { + if (result.success) { + String reply = MainApp.gs(R.string.smscommunicator_extendedcanceled); + reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); + sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); + } else { + String reply = MainApp.gs(R.string.smscommunicator_extendedcancelfailed); + reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); + } + } + }); + } + }); + } else { + reply = MainApp.gs(R.string.smscommunicator_remotecommandnotallowed); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); + } + } else { + if (splited.length < 3) { + reply = MainApp.gs(R.string.wrongformat); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); + } else { + Double extended = SafeParse.stringToDouble(splited[1]); + int duration = SafeParse.stringToInt(splited[2]); + extended = MainApp.getConstraintChecker().applyExtendedBolusConstraints(new Constraint<>(extended)).value(); + if (remoteCommandsAllowed) { + passCode = generatePasscode(); + reply = String.format(MainApp.gs(R.string.smscommunicator_extendedreplywithcode), extended, duration, passCode); + receivedSms.processed = true; + messageToConfirm = new AuthRequest(this, receivedSms, reply, passCode, new SmsAction(extended, duration) { + @Override + public void run() { + ConfigBuilderPlugin.getPlugin().getCommandQueue().extendedBolus(aDouble, secondInteger, new Callback() { + @Override + public void run() { + if (result.success) { + String reply = String.format(MainApp.gs(R.string.smscommunicator_extendedset), aDouble, duration); + reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); + sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); + } else { + String reply = MainApp.gs(R.string.smscommunicator_extendedfailed); + reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); + } + } + }); + } + }); + } else { + reply = MainApp.gs(R.string.smscommunicator_remotecommandnotallowed); sendSMS(new Sms(receivedSms.phoneNumber, reply)); } } @@ -459,7 +528,7 @@ public class SmsCommunicatorPlugin extends PluginBase { break; case "BOLUS": if (System.currentTimeMillis() - lastRemoteBolusTime.getTime() < Constants.remoteBolusMinDistance) { - reply = MainApp.gs(R.string.smscommunicator_remotebolusnotallowed); + reply = MainApp.gs(R.string.smscommunicator_remotecommandnotallowed); sendSMS(new Sms(receivedSms.phoneNumber, reply)); } else if (ConfigBuilderPlugin.getPlugin().getActivePump().isSuspended()) { reply = MainApp.gs(R.string.pumpsuspended); @@ -500,7 +569,7 @@ public class SmsCommunicatorPlugin extends PluginBase { } }); } else { - reply = MainApp.gs(R.string.smscommunicator_remotebolusnotallowed); + reply = MainApp.gs(R.string.smscommunicator_remotecommandnotallowed); sendSMS(new Sms(receivedSms.phoneNumber, reply)); } } @@ -526,7 +595,7 @@ public class SmsCommunicatorPlugin extends PluginBase { } }); } else { - reply = MainApp.gs(R.string.smscommunicator_remotecalibrationnotallowed); + reply = MainApp.gs(R.string.smscommunicator_remotecommandnotallowed); sendSMS(new Sms(receivedSms.phoneNumber, reply)); } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2974ee86d3..0acebd1ae6 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -298,7 +298,6 @@ Bolus %.2fU delivered successfully Delivering %.2fU Allow remote commands via SMS - Remote bolus not allowed Finger Sensor Manual @@ -366,17 +365,22 @@ Loop is enabled %1$.2f limited to %2$.2f Value %s is out of hard limits - Remote basal setting is not allowed Remote command is not allowed To start basal %1$.2fU/h reply with code %2$s + To start extended bolus %1$.2fU for %2$d min reply with code %3$s To start basal %1$d%% reply with code %2$s To suspend loop for %1$d minutes reply with code %2$s Temp basal %1$.2fU/h for %2$d min started successfully + Extended bolus %1$.2fU for %2$d min started successfully Temp basal %1$d %% for %2$d min started successfully Temp basal start failed + Extended bolus start failed To stop temp basal reply with code %s + To stop extended bolus reply with code %s Temp basal canceled + Extended bolus canceled Canceling temp basal failed + Canceling extended bolus failed Uknown command or wrong reply QuickWizard @@ -510,7 +514,6 @@ Send calibration %.1f to xDrip? xDrip+ not installed Calibration sent to xDrip - Remote calibration not allowed Calibration sent. Receiving must be enabled in xDrip. xDrip is not receiving calibrations Pump suspended From f30f4cbee2615a938be33aaae90f42178a3a638f Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Sat, 9 Mar 2019 18:46:22 +0100 Subject: [PATCH 13/39] SMS code cleanup --- .../general/smsCommunicator/AuthRequest.java | 4 + .../plugins/general/smsCommunicator/Sms.java | 8 + .../SmsCommunicatorPlugin.java | 884 +++++++++--------- app/src/main/res/values/strings.xml | 2 + 4 files changed, 466 insertions(+), 432 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequest.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequest.java index 07744c7c7b..42da28a458 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequest.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequest.java @@ -4,6 +4,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import info.nightscout.androidaps.Constants; +import info.nightscout.androidaps.R; import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.utils.DateUtil; @@ -17,11 +18,13 @@ class AuthRequest { private long date; private boolean processed; + private SmsCommunicatorPlugin plugin; AuthRequest(SmsCommunicatorPlugin plugin, Sms requester, String requestText, String confirmCode, SmsAction action) { this.requester = requester; this.confirmCode = confirmCode; this.action = action; + this.plugin = plugin; this.date = DateUtil.now(); @@ -37,6 +40,7 @@ class AuthRequest { if (!confirmCode.equals(codeReceived)) { if (L.isEnabled(L.SMS)) log.debug("Wrong code"); + plugin.sendSMS(new Sms(requester.phoneNumber, R.string.sms_wrongcode)); return; } if (DateUtil.now() - date < Constants.SMS_CONFIRM_TIMEOUT) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/Sms.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/Sms.java index 470770f134..2eedfa0a51 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/Sms.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/Sms.java @@ -2,6 +2,7 @@ package info.nightscout.androidaps.plugins.general.smsCommunicator; import android.telephony.SmsMessage; +import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.utils.DateUtil; class Sms { @@ -27,6 +28,13 @@ class Sms { sent = true; } + Sms(String phoneNumber, int textId) { + this.phoneNumber = phoneNumber; + this.text = MainApp.gs(textId); + this.date = DateUtil.now(); + sent = true; + } + public String toString() { return "SMS from " + phoneNumber + ": " + text; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java index 19b62132f3..9c4063c38d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java @@ -46,6 +46,7 @@ import info.nightscout.androidaps.plugins.general.smsCommunicator.events.EventSm import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin; import info.nightscout.androidaps.queue.Callback; import info.nightscout.androidaps.services.Intents; +import info.nightscout.androidaps.utils.DateUtil; import info.nightscout.androidaps.utils.DecimalFormatter; import info.nightscout.androidaps.utils.SP; import info.nightscout.androidaps.utils.SafeParse; @@ -149,466 +150,85 @@ public class SmsCommunicatorPlugin extends PluginBase { return; } - String reply = ""; - messages.add(receivedSms); log.debug(receivedSms.toString()); - String[] splited = receivedSms.text.split("\\s+"); - String passCode; + String[] splitted = receivedSms.text.split("\\s+"); boolean remoteCommandsAllowed = SP.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false); - if (splited.length > 0) { - switch (splited[0].toUpperCase()) { + if (splitted.length > 0) { + switch (splitted[0].toUpperCase()) { case "BG": - BgReading actualBG = DatabaseHelper.actualBg(); - BgReading lastBG = DatabaseHelper.lastBg(); - - String units = ProfileFunctions.getInstance().getProfileUnits(); - - if (actualBG != null) { - reply = MainApp.gs(R.string.sms_actualbg) + " " + actualBG.valueToUnitsToString(units) + ", "; - } else if (lastBG != null) { - Long agoMsec = System.currentTimeMillis() - lastBG.date; - int agoMin = (int) (agoMsec / 60d / 1000d); - reply = MainApp.gs(R.string.sms_lastbg) + " " + lastBG.valueToUnitsToString(units) + " " + String.format(MainApp.gs(R.string.sms_minago), agoMin) + ", "; - } - GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData(); - if (glucoseStatus != null) - reply += MainApp.gs(R.string.sms_delta) + " " + Profile.toUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units) + " " + units + ", "; - - TreatmentsPlugin.getPlugin().updateTotalIOBTreatments(); - IobTotal bolusIob = TreatmentsPlugin.getPlugin().getLastCalculationTreatments().round(); - TreatmentsPlugin.getPlugin().updateTotalIOBTempBasals(); - IobTotal basalIob = TreatmentsPlugin.getPlugin().getLastCalculationTempBasals().round(); - - reply += MainApp.gs(R.string.sms_iob) + " " + DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U (" - + MainApp.gs(R.string.sms_bolus) + " " + DecimalFormatter.to2Decimal(bolusIob.iob) + "U " - + MainApp.gs(R.string.sms_basal) + " " + DecimalFormatter.to2Decimal(basalIob.basaliob) + "U)"; - - sendSMS(new Sms(receivedSms.phoneNumber, reply)); - receivedSms.processed = true; + processBG(splitted, receivedSms); break; case "LOOP": - if (splited.length > 1) - switch (splited[1].toUpperCase()) { - case "DISABLE": - case "STOP": - LoopPlugin loopPlugin = MainApp.getSpecificPlugin(LoopPlugin.class); - if (loopPlugin != null && loopPlugin.isEnabled(PluginType.LOOP)) { - loopPlugin.setPluginEnabled(PluginType.LOOP, false); - ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(true, new Callback() { - @Override - public void run() { - MainApp.bus().post(new EventRefreshOverview("SMS_LOOP_STOP")); - String reply = MainApp.gs(R.string.smscommunicator_loophasbeendisabled) + " " + - MainApp.gs(result.success ? R.string.smscommunicator_tempbasalcanceled : R.string.smscommunicator_tempbasalcancelfailed); - sendSMS(new Sms(receivedSms.phoneNumber, reply)); - } - }); - } - receivedSms.processed = true; - break; - case "ENABLE": - case "START": - loopPlugin = MainApp.getSpecificPlugin(LoopPlugin.class); - if (loopPlugin != null && !loopPlugin.isEnabled(PluginType.LOOP)) { - loopPlugin.setPluginEnabled(PluginType.LOOP, true); - reply = MainApp.gs(R.string.smscommunicator_loophasbeenenabled); - sendSMS(new Sms(receivedSms.phoneNumber, reply)); - MainApp.bus().post(new EventRefreshOverview("SMS_LOOP_START")); - } - receivedSms.processed = true; - break; - case "STATUS": - loopPlugin = MainApp.getSpecificPlugin(LoopPlugin.class); - if (loopPlugin != null) { - if (loopPlugin.isEnabled(PluginType.LOOP)) { - if (loopPlugin.isSuspended()) - reply = String.format(MainApp.gs(R.string.loopsuspendedfor), loopPlugin.minutesToEndOfSuspend()); - else - reply = MainApp.gs(R.string.smscommunicator_loopisenabled); - } else { - reply = MainApp.gs(R.string.smscommunicator_loopisdisabled); - } - sendSMS(new Sms(receivedSms.phoneNumber, reply)); - } - receivedSms.processed = true; - break; - case "RESUME": - LoopPlugin.getPlugin().suspendTo(0); - MainApp.bus().post(new EventRefreshOverview("SMS_LOOP_RESUME")); - NSUpload.uploadOpenAPSOffline(0); - reply = MainApp.gs(R.string.smscommunicator_loopresumed); - sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); - break; - case "SUSPEND": - int duration = 0; - if (splited.length >= 3) - duration = SafeParse.stringToInt(splited[2]); - duration = Math.max(0, duration); - duration = Math.min(180, duration); - if (duration == 0) { - reply = MainApp.gs(R.string.smscommunicator_wrongduration); - sendSMS(new Sms(receivedSms.phoneNumber, reply)); - } else if (remoteCommandsAllowed) { - passCode = generatePasscode(); - reply = String.format(MainApp.gs(R.string.smscommunicator_suspendreplywithcode), duration, passCode); - receivedSms.processed = true; - messageToConfirm = new AuthRequest(this, receivedSms, reply, passCode, new SmsAction(duration) { - @Override - public void run() { - ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(true, new Callback() { - @Override - public void run() { - if (result.success) { - LoopPlugin.getPlugin().suspendTo(System.currentTimeMillis() + anInteger * 60L * 1000); - NSUpload.uploadOpenAPSOffline(anInteger * 60); - MainApp.bus().post(new EventRefreshOverview("SMS_LOOP_SUSPENDED")); - String reply = MainApp.gs(R.string.smscommunicator_loopsuspended) + " " + - MainApp.gs(result.success ? R.string.smscommunicator_tempbasalcanceled : R.string.smscommunicator_tempbasalcancelfailed); - sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); - } else { - String reply = MainApp.gs(R.string.smscommunicator_tempbasalcancelfailed); - reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); - sendSMS(new Sms(receivedSms.phoneNumber, reply)); - } - } - }); - - } - }); - } else { - reply = MainApp.gs(R.string.smscommunicator_remotecommandnotallowed); - sendSMS(new Sms(receivedSms.phoneNumber, reply)); - } - break; - } + if (!remoteCommandsAllowed) + sendSMS(new Sms(receivedSms.phoneNumber, R.string.smscommunicator_remotecommandnotallowed)); + else if (splitted.length == 2) + processLOOP(splitted, receivedSms); + else + sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat)); break; case "TREATMENTS": - if (splited.length > 1) - switch (splited[1].toUpperCase()) { - case "REFRESH": - Intent restartNSClient = new Intent(Intents.ACTION_RESTART); - TreatmentsPlugin.getPlugin().getService().resetTreatments(); - MainApp.instance().getApplicationContext().sendBroadcast(restartNSClient); - List q = MainApp.instance().getApplicationContext().getPackageManager().queryBroadcastReceivers(restartNSClient, 0); - reply = "TERATMENTS REFRESH " + q.size() + " receivers"; - sendSMS(new Sms(receivedSms.phoneNumber, reply)); - receivedSms.processed = true; - break; - } + if (splitted.length == 2) + processTREATMENTS(splitted, receivedSms); + else + sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat)); break; case "NSCLIENT": - if (splited.length > 1) - switch (splited[1].toUpperCase()) { - case "RESTART": - Intent restartNSClient = new Intent(Intents.ACTION_RESTART); - MainApp.instance().getApplicationContext().sendBroadcast(restartNSClient); - List q = MainApp.instance().getApplicationContext().getPackageManager().queryBroadcastReceivers(restartNSClient, 0); - reply = "NSCLIENT RESTART " + q.size() + " receivers"; - sendSMS(new Sms(receivedSms.phoneNumber, reply)); - receivedSms.processed = true; - break; - } + if (splitted.length == 2) + processNSCLIENT(splitted, receivedSms); + else + sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat)); break; case "PUMP": - case "DANAR": - ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("SMS", new Callback() { - @Override - public void run() { - PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); - if (result.success) { - if (pump != null) { - String reply = pump.shortStatus(true); - sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); - } - } else { - String reply = MainApp.gs(R.string.readstatusfailed); - sendSMS(new Sms(receivedSms.phoneNumber, reply)); - } - } - }); - receivedSms.processed = true; + processPUMP(splitted, receivedSms); break; case "BASAL": - if (splited.length > 1) { - if (splited[1].toUpperCase().equals("CANCEL") || splited[1].toUpperCase().equals("STOP")) { - if (remoteCommandsAllowed) { - passCode = generatePasscode(); - reply = String.format(MainApp.gs(R.string.smscommunicator_basalstopreplywithcode), passCode); - receivedSms.processed = true; - messageToConfirm = new AuthRequest(this, receivedSms, reply, passCode, new SmsAction() { - @Override - public void run() { - ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(true, new Callback() { - @Override - public void run() { - if (result.success) { - String reply = MainApp.gs(R.string.smscommunicator_tempbasalcanceled); - reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); - sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); - } else { - String reply = MainApp.gs(R.string.smscommunicator_tempbasalcancelfailed); - reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); - sendSMS(new Sms(receivedSms.phoneNumber, reply)); - } - } - }); - } - }); - } else { - reply = MainApp.gs(R.string.smscommunicator_remotecommandnotallowed); - sendSMS(new Sms(receivedSms.phoneNumber, reply)); - } - } else if (splited[1].endsWith("%")) { - int tempBasalPct = SafeParse.stringToInt(StringUtils.removeEnd(splited[1], "%")); - int duration = 30; - if (splited.length > 2) - duration = SafeParse.stringToInt(splited[2]); - Profile profile = ProfileFunctions.getInstance().getProfile(); - if (profile == null) { - reply = MainApp.gs(R.string.noprofile); - sendSMS(new Sms(receivedSms.phoneNumber, reply)); - } else if (tempBasalPct == 0 && !splited[1].equals("0%")) { - reply = MainApp.gs(R.string.wrongformat); - sendSMS(new Sms(receivedSms.phoneNumber, reply)); - } else { - tempBasalPct = MainApp.getConstraintChecker().applyBasalPercentConstraints(new Constraint<>(tempBasalPct), profile).value(); - if (remoteCommandsAllowed) { - passCode = generatePasscode(); - reply = String.format(MainApp.gs(R.string.smscommunicator_basalpctreplywithcode), tempBasalPct, passCode); - receivedSms.processed = true; - messageToConfirm = new AuthRequest(this, receivedSms, reply, passCode, new SmsAction(tempBasalPct, duration) { - @Override - public void run() { - Profile profile = ProfileFunctions.getInstance().getProfile(); - if (profile != null) - ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalPercent(anInteger, secondInteger, true, profile, new Callback() { - @Override - public void run() { - if (result.success) { - String reply; - if (result.isPercent) - reply = String.format(MainApp.gs(R.string.smscommunicator_tempbasalset_percent), result.percent, result.duration); - else - reply = String.format(MainApp.gs(R.string.smscommunicator_tempbasalset), result.absolute, result.duration); - reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); - sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); - } else { - String reply = MainApp.gs(R.string.smscommunicator_tempbasalfailed); - reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); - sendSMS(new Sms(receivedSms.phoneNumber, reply)); - } - } - }); - } - }); - } else { - reply = MainApp.gs(R.string.smscommunicator_remotecommandnotallowed); - sendSMS(new Sms(receivedSms.phoneNumber, reply)); - } - } - } else { - Double tempBasal = SafeParse.stringToDouble(splited[1]); - int duration = 30; - if (splited.length > 2) - duration = SafeParse.stringToInt(splited[2]); - Profile profile = ProfileFunctions.getInstance().getProfile(); - if (profile == null) { - reply = MainApp.gs(R.string.noprofile); - sendSMS(new Sms(receivedSms.phoneNumber, reply)); - } else { - tempBasal = MainApp.getConstraintChecker().applyBasalConstraints(new Constraint<>(tempBasal), profile).value(); - if (remoteCommandsAllowed) { - passCode = generatePasscode(); - reply = String.format(MainApp.gs(R.string.smscommunicator_basalreplywithcode), tempBasal, passCode); - receivedSms.processed = true; - messageToConfirm = new AuthRequest(this, receivedSms, reply, passCode, new SmsAction(tempBasal, duration) { - @Override - public void run() { - Profile profile = ProfileFunctions.getInstance().getProfile(); - if (profile != null) - ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalAbsolute(aDouble, secondInteger, true, profile, new Callback() { - @Override - public void run() { - if (result.success) { - String reply; - if (result.isPercent) - reply = String.format(MainApp.gs(R.string.smscommunicator_tempbasalset_percent), result.percent, result.duration); - else - reply = String.format(MainApp.gs(R.string.smscommunicator_tempbasalset), result.absolute, result.duration); - reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); - sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); - } else { - String reply = MainApp.gs(R.string.smscommunicator_tempbasalfailed); - reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); - sendSMS(new Sms(receivedSms.phoneNumber, reply)); - } - } - }); - } - }); - } else { - reply = MainApp.gs(R.string.smscommunicator_remotecommandnotallowed); - sendSMS(new Sms(receivedSms.phoneNumber, reply)); - } - } - } - } + if (!remoteCommandsAllowed) + sendSMS(new Sms(receivedSms.phoneNumber, R.string.smscommunicator_remotecommandnotallowed)); + else if (splitted.length == 2 || splitted.length == 3) + processBASAL(splitted, receivedSms); + else + sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat)); break; case "EXTENDED": - if (splited.length > 1) { - if (splited[1].toUpperCase().equals("CANCEL") || splited[1].toUpperCase().equals("STOP")) { - if (remoteCommandsAllowed) { - passCode = generatePasscode(); - reply = String.format(MainApp.gs(R.string.smscommunicator_extendedstopreplywithcode), passCode); - receivedSms.processed = true; - messageToConfirm = new AuthRequest(this, receivedSms, reply, passCode, new SmsAction() { - @Override - public void run() { - ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelExtended(new Callback() { - @Override - public void run() { - if (result.success) { - String reply = MainApp.gs(R.string.smscommunicator_extendedcanceled); - reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); - sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); - } else { - String reply = MainApp.gs(R.string.smscommunicator_extendedcancelfailed); - reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); - sendSMS(new Sms(receivedSms.phoneNumber, reply)); - } - } - }); - } - }); - } else { - reply = MainApp.gs(R.string.smscommunicator_remotecommandnotallowed); - sendSMS(new Sms(receivedSms.phoneNumber, reply)); - } - } else { - if (splited.length < 3) { - reply = MainApp.gs(R.string.wrongformat); - sendSMS(new Sms(receivedSms.phoneNumber, reply)); - } else { - Double extended = SafeParse.stringToDouble(splited[1]); - int duration = SafeParse.stringToInt(splited[2]); - extended = MainApp.getConstraintChecker().applyExtendedBolusConstraints(new Constraint<>(extended)).value(); - if (remoteCommandsAllowed) { - passCode = generatePasscode(); - reply = String.format(MainApp.gs(R.string.smscommunicator_extendedreplywithcode), extended, duration, passCode); - receivedSms.processed = true; - messageToConfirm = new AuthRequest(this, receivedSms, reply, passCode, new SmsAction(extended, duration) { - @Override - public void run() { - ConfigBuilderPlugin.getPlugin().getCommandQueue().extendedBolus(aDouble, secondInteger, new Callback() { - @Override - public void run() { - if (result.success) { - String reply = String.format(MainApp.gs(R.string.smscommunicator_extendedset), aDouble, duration); - reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); - sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); - } else { - String reply = MainApp.gs(R.string.smscommunicator_extendedfailed); - reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); - sendSMS(new Sms(receivedSms.phoneNumber, reply)); - } - } - }); - } - }); - } else { - reply = MainApp.gs(R.string.smscommunicator_remotecommandnotallowed); - sendSMS(new Sms(receivedSms.phoneNumber, reply)); - } - } - } - } + if (!remoteCommandsAllowed) + sendSMS(new Sms(receivedSms.phoneNumber, R.string.smscommunicator_remotecommandnotallowed)); + else if (splitted.length == 3) + processEXTENDED(splitted, receivedSms); + else + sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat)); break; case "BOLUS": - if (System.currentTimeMillis() - lastRemoteBolusTime.getTime() < Constants.remoteBolusMinDistance) { - reply = MainApp.gs(R.string.smscommunicator_remotecommandnotallowed); - sendSMS(new Sms(receivedSms.phoneNumber, reply)); - } else if (ConfigBuilderPlugin.getPlugin().getActivePump().isSuspended()) { - reply = MainApp.gs(R.string.pumpsuspended); - sendSMS(new Sms(receivedSms.phoneNumber, reply)); - } else if (splited.length > 1) { - Double bolus = SafeParse.stringToDouble(splited[1]); - bolus = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(bolus)).value(); - if (bolus > 0d && remoteCommandsAllowed) { - passCode = generatePasscode(); - reply = String.format(MainApp.gs(R.string.smscommunicator_bolusreplywithcode), bolus, passCode); - receivedSms.processed = true; - messageToConfirm = new AuthRequest(this, receivedSms, reply, passCode, new SmsAction(bolus) { - @Override - public void run() { - DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo(); - detailedBolusInfo.insulin = aDouble; - detailedBolusInfo.source = Source.USER; - ConfigBuilderPlugin.getPlugin().getCommandQueue().bolus(detailedBolusInfo, new Callback() { - @Override - public void run() { - PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); - if (result.success) { - SystemClock.sleep(T.secs(15).msecs()); // wait some time to get history - String reply = String.format(MainApp.gs(R.string.smscommunicator_bolusdelivered), result.bolusDelivered); - if (pump != null) - reply += "\n" + pump.shortStatus(true); - lastRemoteBolusTime = new Date(); - sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); - } else { - SystemClock.sleep(T.secs(60).msecs()); // wait some time to get history - String reply = MainApp.gs(R.string.smscommunicator_bolusfailed); - if (pump != null) - reply += "\n" + pump.shortStatus(true); - sendSMS(new Sms(receivedSms.phoneNumber, reply)); - } - } - }); - } - }); - } else { - reply = MainApp.gs(R.string.smscommunicator_remotecommandnotallowed); - sendSMS(new Sms(receivedSms.phoneNumber, reply)); - } - } + if (!remoteCommandsAllowed) + sendSMS(new Sms(receivedSms.phoneNumber, R.string.smscommunicator_remotecommandnotallowed)); + else if (DateUtil.now() - lastRemoteBolusTime.getTime() < Constants.remoteBolusMinDistance) + sendSMS(new Sms(receivedSms.phoneNumber, R.string.smscommunicator_remotebolusnotallowed)); + else if (ConfigBuilderPlugin.getPlugin().getActivePump().isSuspended()) + sendSMS(new Sms(receivedSms.phoneNumber, R.string.pumpsuspended)); + else if (splitted.length == 2) + processBOLUS(splitted, receivedSms); + else + sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat)); break; case "CAL": - if (splited.length > 1) { - Double cal = SafeParse.stringToDouble(splited[1]); - if (cal > 0d && remoteCommandsAllowed) { - passCode = generatePasscode(); - reply = String.format(MainApp.gs(R.string.smscommunicator_calibrationreplywithcode), cal, passCode); - receivedSms.processed = true; - messageToConfirm = new AuthRequest(this, receivedSms, reply, passCode, new SmsAction() { - @Override - public void run() { - boolean result = XdripCalibrations.sendIntent(aDouble); - if (result) { - String reply = MainApp.gs(R.string.smscommunicator_calibrationsent); - sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); - } else { - String reply = MainApp.gs(R.string.smscommunicator_calibrationfailed); - sendSMS(new Sms(receivedSms.phoneNumber, reply)); - } - } - }); - } else { - reply = MainApp.gs(R.string.smscommunicator_remotecommandnotallowed); - sendSMS(new Sms(receivedSms.phoneNumber, reply)); - } - } + if (!remoteCommandsAllowed) + sendSMS(new Sms(receivedSms.phoneNumber, R.string.smscommunicator_remotecommandnotallowed)); + else if (splitted.length == 2) + processCAL(splitted, receivedSms); + else + sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat)); break; default: // expect passCode here - if (!Character.isLetter(splited[0].charAt(0))) { + //noinspection StatementWithEmptyBody + if (!Character.isLetter(splitted[0].charAt(0))) { // user text .... ignore } else if (messageToConfirm != null) { - messageToConfirm.action(splited[0]); + messageToConfirm.action(splitted[0]); messageToConfirm = null; - } else { + } else sendSMS(new Sms(receivedSms.phoneNumber, MainApp.gs(R.string.smscommunicator_unknowncommand))); - } break; } } @@ -616,6 +236,406 @@ public class SmsCommunicatorPlugin extends PluginBase { MainApp.bus().post(new EventSmsCommunicatorUpdateGui()); } + @SuppressWarnings("unused") + private void processBG(String[] splitted, Sms receivedSms) { + BgReading actualBG = DatabaseHelper.actualBg(); + BgReading lastBG = DatabaseHelper.lastBg(); + + String reply = ""; + + String units = ProfileFunctions.getInstance().getProfileUnits(); + + if (actualBG != null) { + reply = MainApp.gs(R.string.sms_actualbg) + " " + actualBG.valueToUnitsToString(units) + ", "; + } else if (lastBG != null) { + Long agoMsec = System.currentTimeMillis() - lastBG.date; + int agoMin = (int) (agoMsec / 60d / 1000d); + reply = MainApp.gs(R.string.sms_lastbg) + " " + lastBG.valueToUnitsToString(units) + " " + String.format(MainApp.gs(R.string.sms_minago), agoMin) + ", "; + } + GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData(); + if (glucoseStatus != null) + reply += MainApp.gs(R.string.sms_delta) + " " + Profile.toUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units) + " " + units + ", "; + + TreatmentsPlugin.getPlugin().updateTotalIOBTreatments(); + IobTotal bolusIob = TreatmentsPlugin.getPlugin().getLastCalculationTreatments().round(); + TreatmentsPlugin.getPlugin().updateTotalIOBTempBasals(); + IobTotal basalIob = TreatmentsPlugin.getPlugin().getLastCalculationTempBasals().round(); + + reply += MainApp.gs(R.string.sms_iob) + " " + DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U (" + + MainApp.gs(R.string.sms_bolus) + " " + DecimalFormatter.to2Decimal(bolusIob.iob) + "U " + + MainApp.gs(R.string.sms_basal) + " " + DecimalFormatter.to2Decimal(basalIob.basaliob) + "U)"; + + sendSMS(new Sms(receivedSms.phoneNumber, reply)); + receivedSms.processed = true; + } + + private void processLOOP(String[] splitted, Sms receivedSms) { + String reply; + switch (splitted[1].toUpperCase()) { + case "DISABLE": + case "STOP": + LoopPlugin loopPlugin = MainApp.getSpecificPlugin(LoopPlugin.class); + if (loopPlugin != null && loopPlugin.isEnabled(PluginType.LOOP)) { + loopPlugin.setPluginEnabled(PluginType.LOOP, false); + ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(true, new Callback() { + @Override + public void run() { + MainApp.bus().post(new EventRefreshOverview("SMS_LOOP_STOP")); + String reply = MainApp.gs(R.string.smscommunicator_loophasbeendisabled) + " " + + MainApp.gs(result.success ? R.string.smscommunicator_tempbasalcanceled : R.string.smscommunicator_tempbasalcancelfailed); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); + } + }); + } + receivedSms.processed = true; + break; + case "ENABLE": + case "START": + loopPlugin = MainApp.getSpecificPlugin(LoopPlugin.class); + if (loopPlugin != null && !loopPlugin.isEnabled(PluginType.LOOP)) { + loopPlugin.setPluginEnabled(PluginType.LOOP, true); + sendSMS(new Sms(receivedSms.phoneNumber, R.string.smscommunicator_loophasbeenenabled)); + MainApp.bus().post(new EventRefreshOverview("SMS_LOOP_START")); + } + receivedSms.processed = true; + break; + case "STATUS": + loopPlugin = MainApp.getSpecificPlugin(LoopPlugin.class); + if (loopPlugin != null) { + if (loopPlugin.isEnabled(PluginType.LOOP)) { + if (loopPlugin.isSuspended()) + reply = String.format(MainApp.gs(R.string.loopsuspendedfor), loopPlugin.minutesToEndOfSuspend()); + else + reply = MainApp.gs(R.string.smscommunicator_loopisenabled); + } else { + reply = MainApp.gs(R.string.smscommunicator_loopisdisabled); + } + sendSMS(new Sms(receivedSms.phoneNumber, reply)); + } + receivedSms.processed = true; + break; + case "RESUME": + LoopPlugin.getPlugin().suspendTo(0); + MainApp.bus().post(new EventRefreshOverview("SMS_LOOP_RESUME")); + NSUpload.uploadOpenAPSOffline(0); + reply = MainApp.gs(R.string.smscommunicator_loopresumed); + sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); + break; + case "SUSPEND": + int duration = 0; + if (splitted.length >= 3) + duration = SafeParse.stringToInt(splitted[2]); + duration = Math.max(0, duration); + duration = Math.min(180, duration); + if (duration == 0) { + reply = MainApp.gs(R.string.smscommunicator_wrongduration); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); + } else { + String passCode = generatePasscode(); + reply = String.format(MainApp.gs(R.string.smscommunicator_suspendreplywithcode), duration, passCode); + receivedSms.processed = true; + messageToConfirm = new AuthRequest(this, receivedSms, reply, passCode, new SmsAction(duration) { + @Override + public void run() { + ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(true, new Callback() { + @Override + public void run() { + if (result.success) { + LoopPlugin.getPlugin().suspendTo(System.currentTimeMillis() + anInteger * 60L * 1000); + NSUpload.uploadOpenAPSOffline(anInteger * 60); + MainApp.bus().post(new EventRefreshOverview("SMS_LOOP_SUSPENDED")); + String reply = MainApp.gs(R.string.smscommunicator_loopsuspended) + " " + + MainApp.gs(result.success ? R.string.smscommunicator_tempbasalcanceled : R.string.smscommunicator_tempbasalcancelfailed); + sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); + } else { + String reply = MainApp.gs(R.string.smscommunicator_tempbasalcancelfailed); + reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); + } + } + }); + + } + }); + } + default: + sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat)); + break; + } + } + + private void processTREATMENTS(String[] splitted, Sms receivedSms) { + if (splitted[1].toUpperCase().equals("REFRESH")) { + Intent restartNSClient = new Intent(Intents.ACTION_RESTART); + TreatmentsPlugin.getPlugin().getService().resetTreatments(); + MainApp.instance().getApplicationContext().sendBroadcast(restartNSClient); + List q = MainApp.instance().getApplicationContext().getPackageManager().queryBroadcastReceivers(restartNSClient, 0); + String reply = "TREATMENTS REFRESH " + q.size() + " receivers"; + sendSMS(new Sms(receivedSms.phoneNumber, reply)); + receivedSms.processed = true; + } else + sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat)); + } + + private void processNSCLIENT(String[] splitted, Sms receivedSms) { + if (splitted[2].toUpperCase().equals("RESTART")) { + Intent restartNSClient = new Intent(Intents.ACTION_RESTART); + MainApp.instance().getApplicationContext().sendBroadcast(restartNSClient); + List q = MainApp.instance().getApplicationContext().getPackageManager().queryBroadcastReceivers(restartNSClient, 0); + String reply = "NSCLIENT RESTART " + q.size() + " receivers"; + sendSMS(new Sms(receivedSms.phoneNumber, reply)); + receivedSms.processed = true; + } else + sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat)); + } + + @SuppressWarnings("unused") + private void processPUMP(String[] splitted, Sms receivedSms) { + ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("SMS", new Callback() { + @Override + public void run() { + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); + if (result.success) { + if (pump != null) { + String reply = pump.shortStatus(true); + sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); + } + } else { + String reply = MainApp.gs(R.string.readstatusfailed); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); + } + } + }); + receivedSms.processed = true; + } + + private void processBASAL(String[] splitted, Sms receivedSms) { + if (splitted[1].toUpperCase().equals("CANCEL") || splitted[1].toUpperCase().equals("STOP")) { + String passCode = generatePasscode(); + String reply = String.format(MainApp.gs(R.string.smscommunicator_basalstopreplywithcode), passCode); + receivedSms.processed = true; + messageToConfirm = new AuthRequest(this, receivedSms, reply, passCode, new SmsAction() { + @Override + public void run() { + ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(true, new Callback() { + @Override + public void run() { + if (result.success) { + String reply = MainApp.gs(R.string.smscommunicator_tempbasalcanceled); + reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); + sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); + } else { + String reply = MainApp.gs(R.string.smscommunicator_tempbasalcancelfailed); + reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); + } + } + }); + } + }); + } else if (splitted[1].endsWith("%")) { + int tempBasalPct = SafeParse.stringToInt(StringUtils.removeEnd(splitted[1], "%")); + int duration = 30; + if (splitted.length > 2) + duration = SafeParse.stringToInt(splitted[2]); + final Profile profile = ProfileFunctions.getInstance().getProfile(); + + if (profile == null) + sendSMS(new Sms(receivedSms.phoneNumber, R.string.noprofile)); + else if (tempBasalPct == 0 && !splitted[1].equals("0%")) + sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat)); + else if (duration == 0) + sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat)); + else { + tempBasalPct = MainApp.getConstraintChecker().applyBasalPercentConstraints(new Constraint<>(tempBasalPct), profile).value(); + String passCode = generatePasscode(); + String reply = String.format(MainApp.gs(R.string.smscommunicator_basalpctreplywithcode), tempBasalPct, passCode); + receivedSms.processed = true; + messageToConfirm = new AuthRequest(this, receivedSms, reply, passCode, new SmsAction(tempBasalPct, duration) { + @Override + public void run() { + ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalPercent(anInteger, secondInteger, true, profile, new Callback() { + @Override + public void run() { + if (result.success) { + String reply; + if (result.isPercent) + reply = String.format(MainApp.gs(R.string.smscommunicator_tempbasalset_percent), result.percent, result.duration); + else + reply = String.format(MainApp.gs(R.string.smscommunicator_tempbasalset), result.absolute, result.duration); + reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); + sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); + } else { + String reply = MainApp.gs(R.string.smscommunicator_tempbasalfailed); + reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); + } + } + }); + } + }); + } + } else { + Double tempBasal = SafeParse.stringToDouble(splitted[1]); + int duration = 30; + if (splitted.length > 2) + duration = SafeParse.stringToInt(splitted[2]); + final Profile profile = ProfileFunctions.getInstance().getProfile(); + if (profile == null) + sendSMS(new Sms(receivedSms.phoneNumber, R.string.noprofile)); + else if (tempBasal == 0 && !splitted[1].equals("0")) + sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat)); + else if (duration == 0) + sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat)); + else { + tempBasal = MainApp.getConstraintChecker().applyBasalConstraints(new Constraint<>(tempBasal), profile).value(); + String passCode = generatePasscode(); + String reply = String.format(MainApp.gs(R.string.smscommunicator_basalreplywithcode), tempBasal, passCode); + receivedSms.processed = true; + messageToConfirm = new AuthRequest(this, receivedSms, reply, passCode, new SmsAction(tempBasal, duration) { + @Override + public void run() { + ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalAbsolute(aDouble, secondInteger, true, profile, new Callback() { + @Override + public void run() { + if (result.success) { + String reply; + if (result.isPercent) + reply = String.format(MainApp.gs(R.string.smscommunicator_tempbasalset_percent), result.percent, result.duration); + else + reply = String.format(MainApp.gs(R.string.smscommunicator_tempbasalset), result.absolute, result.duration); + reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); + sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); + } else { + String reply = MainApp.gs(R.string.smscommunicator_tempbasalfailed); + reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); + } + } + }); + } + }); + } + } + } + + private void processEXTENDED(String[] splitted, Sms receivedSms) { + if (splitted[1].toUpperCase().equals("CANCEL") || splitted[1].toUpperCase().equals("STOP")) { + String passCode = generatePasscode(); + String reply = String.format(MainApp.gs(R.string.smscommunicator_extendedstopreplywithcode), passCode); + receivedSms.processed = true; + messageToConfirm = new AuthRequest(this, receivedSms, reply, passCode, new SmsAction() { + @Override + public void run() { + ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelExtended(new Callback() { + @Override + public void run() { + if (result.success) { + String reply = MainApp.gs(R.string.smscommunicator_extendedcanceled); + reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); + sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); + } else { + String reply = MainApp.gs(R.string.smscommunicator_extendedcancelfailed); + reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); + } + } + }); + } + }); + } else { + Double extended = SafeParse.stringToDouble(splitted[1]); + int duration = SafeParse.stringToInt(splitted[2]); + extended = MainApp.getConstraintChecker().applyExtendedBolusConstraints(new Constraint<>(extended)).value(); + if (extended == 0 || duration == 0) + sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat)); + else { + String passCode = generatePasscode(); + String reply = String.format(MainApp.gs(R.string.smscommunicator_extendedreplywithcode), extended, duration, passCode); + receivedSms.processed = true; + messageToConfirm = new AuthRequest(this, receivedSms, reply, passCode, new SmsAction(extended, duration) { + @Override + public void run() { + ConfigBuilderPlugin.getPlugin().getCommandQueue().extendedBolus(aDouble, secondInteger, new Callback() { + @Override + public void run() { + if (result.success) { + String reply = String.format(MainApp.gs(R.string.smscommunicator_extendedset), aDouble, duration); + reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); + sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); + } else { + String reply = MainApp.gs(R.string.smscommunicator_extendedfailed); + reply += "\n" + ConfigBuilderPlugin.getPlugin().getActivePump().shortStatus(true); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); + } + } + }); + } + }); + } + } + } + + + private void processBOLUS(String[] splitted, Sms receivedSms) { + Double bolus = SafeParse.stringToDouble(splitted[1]); + bolus = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(bolus)).value(); + if (bolus > 0d) { + String passCode = generatePasscode(); + String reply = String.format(MainApp.gs(R.string.smscommunicator_bolusreplywithcode), bolus, passCode); + receivedSms.processed = true; + messageToConfirm = new AuthRequest(this, receivedSms, reply, passCode, new SmsAction(bolus) { + @Override + public void run() { + DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo(); + detailedBolusInfo.insulin = aDouble; + detailedBolusInfo.source = Source.USER; + ConfigBuilderPlugin.getPlugin().getCommandQueue().bolus(detailedBolusInfo, new Callback() { + @Override + public void run() { + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); + if (result.success) { + SystemClock.sleep(T.secs(15).msecs()); // wait some time to get history + String reply = String.format(MainApp.gs(R.string.smscommunicator_bolusdelivered), result.bolusDelivered); + if (pump != null) + reply += "\n" + pump.shortStatus(true); + lastRemoteBolusTime = new Date(); + sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); + } else { + SystemClock.sleep(T.secs(60).msecs()); // wait some time to get history + String reply = MainApp.gs(R.string.smscommunicator_bolusfailed); + if (pump != null) + reply += "\n" + pump.shortStatus(true); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); + } + } + }); + } + }); + } else + sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat)); + } + + private void processCAL(String[] splitted, Sms receivedSms) { + Double cal = SafeParse.stringToDouble(splitted[1]); + if (cal > 0d) { + String passCode = generatePasscode(); + String reply = String.format(MainApp.gs(R.string.smscommunicator_calibrationreplywithcode), cal, passCode); + receivedSms.processed = true; + messageToConfirm = new AuthRequest(this, receivedSms, reply, passCode, new SmsAction() { + @Override + public void run() { + boolean result = XdripCalibrations.sendIntent(aDouble); + if (result) + sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, R.string.smscommunicator_calibrationsent)); + else + sendSMS(new Sms(receivedSms.phoneNumber, R.string.smscommunicator_calibrationfailed)); + } + }); + } else + sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat)); + } + public void sendNotificationToAllNumbers(String text) { for (int i = 0; i < allowedNumbers.size(); i++) { Sms sms = new Sms(allowedNumbers.get(i), text); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0acebd1ae6..7576c277be 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -366,6 +366,7 @@ %1$.2f limited to %2$.2f Value %s is out of hard limits Remote command is not allowed + Remote bolus not available. Try again later. To start basal %1$.2fU/h reply with code %2$s To start extended bolus %1$.2fU for %2$d min reply with code %3$s To start basal %1$d%% reply with code %2$s @@ -1320,6 +1321,7 @@ internal storage constraint Free at least %1$d MB from internal storage! Loop disabled! Wrong format + Wrong code. Command cancelled. %1$d day %1$d days From c7c3506b53bfc140cea76e5887863bcbd524f5e4 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Sun, 10 Mar 2019 07:59:14 +0100 Subject: [PATCH 14/39] SMS PROFILE command --- .../configBuilder/ProfileFunctions.java | 41 ++++++++++ .../Dialogs/NewNSTreatmentDialog.java | 44 +---------- .../general/smsCommunicator/SmsAction.java | 6 ++ .../SmsCommunicatorPlugin.java | 76 +++++++++++++++++++ .../general/wear/ActionStringHandler.java | 2 +- .../plugins/profile/ns/NSProfileFragment.java | 3 +- app/src/main/res/values/strings.xml | 3 + 7 files changed, 130 insertions(+), 45 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ProfileFunctions.java b/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ProfileFunctions.java index c87432a9ab..6b9b353979 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ProfileFunctions.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ProfileFunctions.java @@ -16,6 +16,7 @@ import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.ProfileStore; import info.nightscout.androidaps.db.ProfileSwitch; +import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.events.EventNewBasalProfile; import info.nightscout.androidaps.events.EventProfileSwitchChange; import info.nightscout.androidaps.interfaces.ProfileInterface; @@ -139,4 +140,44 @@ public class ProfileFunctions { return null; } + public static ProfileSwitch prepareProfileSwitch(final ProfileStore profileStore, final String profileName, final int duration, final int percentage, final int timeshift, long date) { + ProfileSwitch profileSwitch = new ProfileSwitch(); + profileSwitch.date = date; + profileSwitch.source = Source.USER; + profileSwitch.profileName = profileName; + profileSwitch.profileJson = profileStore.getSpecificProfile(profileName).getData().toString(); + profileSwitch.profilePlugin = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getClass().getName(); + profileSwitch.durationInMinutes = duration; + profileSwitch.isCPP = percentage != 100 || timeshift != 0; + profileSwitch.timeshift = timeshift; + profileSwitch.percentage = percentage; + return profileSwitch; + } + + public static void doProfileSwitch(final ProfileStore profileStore, final String profileName, final int duration, final int percentage, final int timeshift) { + ProfileSwitch profileSwitch = prepareProfileSwitch(profileStore, profileName, duration, percentage, timeshift, System.currentTimeMillis()); + TreatmentsPlugin.getPlugin().addToHistoryProfileSwitch(profileSwitch); + FabricPrivacy.getInstance().logCustom(new CustomEvent("ProfileSwitch")); + } + + public static void doProfileSwitch(final int duration, final int percentage, final int timeshift) { + ProfileSwitch profileSwitch = TreatmentsPlugin.getPlugin().getProfileSwitchFromHistory(System.currentTimeMillis()); + if (profileSwitch != null) { + profileSwitch = new ProfileSwitch(); + profileSwitch.date = System.currentTimeMillis(); + profileSwitch.source = Source.USER; + profileSwitch.profileName = getInstance().getProfileName(System.currentTimeMillis(), false); + profileSwitch.profileJson = getInstance().getProfile().getData().toString(); + profileSwitch.profilePlugin = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getClass().getName(); + profileSwitch.durationInMinutes = duration; + profileSwitch.isCPP = percentage != 100 || timeshift != 0; + profileSwitch.timeshift = timeshift; + profileSwitch.percentage = percentage; + TreatmentsPlugin.getPlugin().addToHistoryProfileSwitch(profileSwitch); + FabricPrivacy.getInstance().logCustom(new CustomEvent("ProfileSwitch")); + } else { + log.error("No profile switch existing"); + } + } + } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/careportal/Dialogs/NewNSTreatmentDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/careportal/Dialogs/NewNSTreatmentDialog.java index 1e38a0131a..e4eccd18d9 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/careportal/Dialogs/NewNSTreatmentDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/careportal/Dialogs/NewNSTreatmentDialog.java @@ -722,7 +722,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick public void createNSTreatment(JSONObject data) { if (options.executeProfileSwitch) { if (data.has("profile")) { - doProfileSwitch(profileStore, JsonHelper.safeGetString(data, "profile"), JsonHelper.safeGetInt(data, "duration"), JsonHelper.safeGetInt(data, "percentage"), JsonHelper.safeGetInt(data, "timeshift")); + ProfileFunctions.doProfileSwitch(profileStore, JsonHelper.safeGetString(data, "profile"), JsonHelper.safeGetInt(data, "duration"), JsonHelper.safeGetInt(data, "percentage"), JsonHelper.safeGetInt(data, "timeshift")); } } else if (options.executeTempTarget) { final int duration = JsonHelper.safeGetInt(data, "duration"); @@ -746,7 +746,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick } } else { if (JsonHelper.safeGetString(data, "eventType").equals(CareportalEvent.PROFILESWITCH)) { - ProfileSwitch profileSwitch = prepareProfileSwitch( + ProfileSwitch profileSwitch = ProfileFunctions.prepareProfileSwitch( profileStore, JsonHelper.safeGetString(data, "profile"), JsonHelper.safeGetInt(data, "duration"), @@ -762,46 +762,6 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick } } - public static ProfileSwitch prepareProfileSwitch(final ProfileStore profileStore, final String profileName, final int duration, final int percentage, final int timeshift, long date) { - ProfileSwitch profileSwitch = new ProfileSwitch(); - profileSwitch.date = date; - profileSwitch.source = Source.USER; - profileSwitch.profileName = profileName; - profileSwitch.profileJson = profileStore.getSpecificProfile(profileName).getData().toString(); - profileSwitch.profilePlugin = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getClass().getName(); - profileSwitch.durationInMinutes = duration; - profileSwitch.isCPP = percentage != 100 || timeshift != 0; - profileSwitch.timeshift = timeshift; - profileSwitch.percentage = percentage; - return profileSwitch; - } - - public static void doProfileSwitch(final ProfileStore profileStore, final String profileName, final int duration, final int percentage, final int timeshift) { - ProfileSwitch profileSwitch = prepareProfileSwitch(profileStore, profileName, duration, percentage, timeshift, System.currentTimeMillis()); - TreatmentsPlugin.getPlugin().addToHistoryProfileSwitch(profileSwitch); - FabricPrivacy.getInstance().logCustom(new CustomEvent("ProfileSwitch")); - } - - public static void doProfileSwitch(final int duration, final int percentage, final int timeshift) { - ProfileSwitch profileSwitch = TreatmentsPlugin.getPlugin().getProfileSwitchFromHistory(System.currentTimeMillis()); - if (profileSwitch != null) { - profileSwitch = new ProfileSwitch(); - profileSwitch.date = System.currentTimeMillis(); - profileSwitch.source = Source.USER; - profileSwitch.profileName = ProfileFunctions.getInstance().getProfileName(System.currentTimeMillis(), false); - profileSwitch.profileJson = ProfileFunctions.getInstance().getProfile().getData().toString(); - profileSwitch.profilePlugin = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getClass().getName(); - profileSwitch.durationInMinutes = duration; - profileSwitch.isCPP = percentage != 100 || timeshift != 0; - profileSwitch.timeshift = timeshift; - profileSwitch.percentage = percentage; - TreatmentsPlugin.getPlugin().addToHistoryProfileSwitch(profileSwitch); - FabricPrivacy.getInstance().logCustom(new CustomEvent("ProfileSwitch")); - } else { - log.error("No profile switch existing"); - } - } - @Override public void onSaveInstanceState(Bundle savedInstanceState) { savedInstanceState.putString("notesEdit", notesEdit.getText().toString()); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsAction.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsAction.java index d6ea031fa7..6b5d5b8747 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsAction.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsAction.java @@ -4,6 +4,7 @@ abstract class SmsAction implements Runnable { Double aDouble; Integer anInteger; Integer secondInteger; + String aString; SmsAction() {} @@ -16,6 +17,11 @@ abstract class SmsAction implements Runnable { this.secondInteger = secondInteger; } + SmsAction(String aString, Integer secondInteger) { + this.aString = aString; + this.secondInteger = secondInteger; + } + SmsAction(Integer anInteger) { this.anInteger = anInteger; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java index 9c4063c38d..d58e2aaacf 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java @@ -25,6 +25,7 @@ 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.ProfileStore; import info.nightscout.androidaps.db.BgReading; import info.nightscout.androidaps.db.DatabaseHelper; import info.nightscout.androidaps.db.Source; @@ -34,6 +35,7 @@ import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginType; +import info.nightscout.androidaps.interfaces.ProfileInterface; import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin; @@ -184,6 +186,14 @@ public class SmsCommunicatorPlugin extends PluginBase { case "PUMP": processPUMP(splitted, receivedSms); break; + case "PROFILE": + if (!remoteCommandsAllowed) + sendSMS(new Sms(receivedSms.phoneNumber, R.string.smscommunicator_remotecommandnotallowed)); + else if (splitted.length == 2 || splitted.length == 3) + processPROFILE(splitted, receivedSms); + else + sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat)); + break; case "BASAL": if (!remoteCommandsAllowed) sendSMS(new Sms(receivedSms.phoneNumber, R.string.smscommunicator_remotecommandnotallowed)); @@ -409,6 +419,72 @@ public class SmsCommunicatorPlugin extends PluginBase { receivedSms.processed = true; } + private void processPROFILE(String[] splitted, Sms receivedSms) { + // load profiles + ProfileInterface anInterface = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface(); + if (anInterface == null) { + sendSMS(new Sms(receivedSms.phoneNumber, R.string.notconfigured)); + receivedSms.processed = true; + return; + } + ProfileStore store = anInterface.getProfile(); + if (store == null) { + sendSMS(new Sms(receivedSms.phoneNumber, R.string.notconfigured)); + receivedSms.processed = true; + return; + } + final ArrayList list = store.getProfileList(); + + if (splitted[1].toUpperCase().equals("STATUS")) { + sendSMS(new Sms(receivedSms.phoneNumber, ProfileFunctions.getInstance().getProfileName())); + } else if (splitted[1].toUpperCase().equals("LIST")) { + if (list.isEmpty()) + sendSMS(new Sms(receivedSms.phoneNumber, R.string.invalidprofile)); + else { + String reply = ""; + for (int i = 0; i < list.size(); i++) { + if (i > 0) + reply += "\n"; + reply += (i + 1) + ". "; + reply += list.get(i); + } + sendSMS(new Sms(receivedSms.phoneNumber, reply)); + } + } else { + + int pindex = SafeParse.stringToInt(splitted[1]); + int percentage = 100; + if (splitted.length > 2) + percentage = SafeParse.stringToInt(splitted[2]); + + if (pindex > list.size()) + sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat)); + else if (percentage == 0) + sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat)); + else if (pindex == 0) + sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat)); + else { + final Profile profile = store.getSpecificProfile((String) list.get(pindex - 1)); + if (profile == null) + sendSMS(new Sms(receivedSms.phoneNumber, R.string.noprofile)); + else { + String passCode = generatePasscode(); + String reply = String.format(MainApp.gs(R.string.smscommunicator_profilereplywithcode), list.get(pindex - 1), percentage, passCode); + receivedSms.processed = true; + int finalPercentage = percentage; + messageToConfirm = new AuthRequest(this, receivedSms, reply, passCode, new SmsAction((String) list.get(pindex - 1), finalPercentage) { + @Override + public void run() { + ProfileFunctions.doProfileSwitch(store, (String) list.get(pindex - 1), 0, finalPercentage, 0); + sendSMS(new Sms(receivedSms.phoneNumber, R.string.profileswitchcreated)); + } + }); + } + } + } + receivedSms.processed = true; + } + private void processBASAL(String[] splitted, Sms receivedSms) { if (splitted[1].toUpperCase().equals("CANCEL") || splitted[1].toUpperCase().equals("STOP")) { String passCode = generatePasscode(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/ActionStringHandler.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/ActionStringHandler.java index aef742b49b..b92410d67f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/ActionStringHandler.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/ActionStringHandler.java @@ -693,7 +693,7 @@ public class ActionStringHandler { //send profile to pumpe new NewNSTreatmentDialog(); //init - NewNSTreatmentDialog.doProfileSwitch(0, percentage, timeshift); + ProfileFunctions.doProfileSwitch(0, percentage, timeshift); } private static void generateTempTarget(int duration, double low, double high) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/profile/ns/NSProfileFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/profile/ns/NSProfileFragment.java index 913f6a1d12..66b895839d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/profile/ns/NSProfileFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/profile/ns/NSProfileFragment.java @@ -22,7 +22,6 @@ import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.ProfileStore; -import info.nightscout.androidaps.plugins.general.careportal.Dialogs.NewNSTreatmentDialog; import info.nightscout.androidaps.plugins.common.SubscriberFragment; import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.profile.ns.events.EventNSProfileUpdateGUI; @@ -157,7 +156,7 @@ public class NSProfileFragment extends SubscriberFragment { Profile profile = store.getSpecificProfile(name); if (profile != null) { OKDialog.showConfirmation(getActivity(), MainApp.gs(R.string.activate_profile) + ": " + name + " ?", () -> - NewNSTreatmentDialog.doProfileSwitch(store, name, 0, 100, 0) + ProfileFunctions.doProfileSwitch(store, name, 0, 100, 0) ); } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7576c277be..0ddc68865a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -368,6 +368,7 @@ Remote command is not allowed Remote bolus not available. Try again later. To start basal %1$.2fU/h reply with code %2$s + To switch profile to %1$s %2$d%% reply with code %3$s To start extended bolus %1$.2fU for %2$d min reply with code %3$s To start basal %1$d%% reply with code %2$s To suspend loop for %1$d minutes reply with code %2$s @@ -1322,6 +1323,8 @@ Free at least %1$d MB from internal storage! Loop disabled! Wrong format Wrong code. Command cancelled. + Not configured + Profile switch created %1$d day %1$d days From b9ea583d3de2fb1e75902dec033817d6fb3ed3b5 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Mon, 11 Mar 2019 18:29:43 +0100 Subject: [PATCH 15/39] SMS read status after bolus --- .../SmsCommunicatorPlugin.java | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java index d58e2aaacf..ca1a1669b0 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java @@ -669,21 +669,26 @@ public class SmsCommunicatorPlugin extends PluginBase { ConfigBuilderPlugin.getPlugin().getCommandQueue().bolus(detailedBolusInfo, new Callback() { @Override public void run() { - PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); - if (result.success) { - SystemClock.sleep(T.secs(15).msecs()); // wait some time to get history - String reply = String.format(MainApp.gs(R.string.smscommunicator_bolusdelivered), result.bolusDelivered); - if (pump != null) - reply += "\n" + pump.shortStatus(true); - lastRemoteBolusTime = new Date(); - sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); - } else { - SystemClock.sleep(T.secs(60).msecs()); // wait some time to get history - String reply = MainApp.gs(R.string.smscommunicator_bolusfailed); - if (pump != null) - reply += "\n" + pump.shortStatus(true); - sendSMS(new Sms(receivedSms.phoneNumber, reply)); - } + final boolean resultSuccess = result.success; + final double resultBolusDelivered = result.bolusDelivered; + ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("SMS", new Callback() { + @Override + public void run() { + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); + if (resultSuccess) { + String reply = String.format(MainApp.gs(R.string.smscommunicator_bolusdelivered), resultBolusDelivered); + if (pump != null) + reply += "\n" + pump.shortStatus(true); + lastRemoteBolusTime = new Date(); + sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); + } else { + String reply = MainApp.gs(R.string.smscommunicator_bolusfailed); + if (pump != null) + reply += "\n" + pump.shortStatus(true); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); + } + } + }); } }); } From e1a82cc78eb6621342046c3e532e7f8dd2cc5faf Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Mon, 11 Mar 2019 18:33:43 +0100 Subject: [PATCH 16/39] SMS eleminate I and l from passcode --- .../plugins/general/smsCommunicator/SmsCommunicatorPlugin.java | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java index ca1a1669b0..b4ff04baa0 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java @@ -757,6 +757,7 @@ public class SmsCommunicatorPlugin extends PluginBase { passCode += Character.toString((char) (startChar2 + Math.random() * ('z' - 'a' + 1))); int startChar3 = Math.random() > 0.5 ? 'a' : 'A'; passCode += Character.toString((char) (startChar3 + Math.random() * ('z' - 'a' + 1))); + passCode.replace('l','k').replace('I', 'J'); return passCode; } From a32508a7adf317cb91ac9b62e0e28be707173267 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Tue, 12 Mar 2019 18:41:20 +0100 Subject: [PATCH 17/39] move test to correct package --- .../iobCobCalculatorPlugin}/IobCobCalculatorPluginTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename app/src/test/java/info/nightscout/androidaps/plugins/{IobCobCalculatorPlugin => iob/iobCobCalculatorPlugin}/IobCobCalculatorPluginTest.java (99%) diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/IobCobCalculatorPlugin/IobCobCalculatorPluginTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/iob/iobCobCalculatorPlugin/IobCobCalculatorPluginTest.java similarity index 99% rename from app/src/test/java/info/nightscout/androidaps/plugins/IobCobCalculatorPlugin/IobCobCalculatorPluginTest.java rename to app/src/test/java/info/nightscout/androidaps/plugins/iob/iobCobCalculatorPlugin/IobCobCalculatorPluginTest.java index 8cb7f2e4ad..4cd57f93ad 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/IobCobCalculatorPlugin/IobCobCalculatorPluginTest.java +++ b/app/src/test/java/info/nightscout/androidaps/plugins/iob/iobCobCalculatorPlugin/IobCobCalculatorPluginTest.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.IobCobCalculatorPlugin; +package info.nightscout.androidaps.plugins.iob.iobCobCalculatorPlugin; import android.content.Context; From a8a1bb793fba9680432ed531d49d6a5defe574c4 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Tue, 12 Mar 2019 18:58:26 +0100 Subject: [PATCH 18/39] SmsTest --- .../general/smsCommunicator/SmsTest.java | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsTest.java diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsTest.java new file mode 100644 index 0000000000..5f7af11a67 --- /dev/null +++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsTest.java @@ -0,0 +1,53 @@ +package info.nightscout.androidaps.plugins.general.smsCommunicator; + +import android.telephony.SmsMessage; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import info.AAPSMocker; +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; + +import static org.powermock.api.mockito.PowerMockito.mock; +import static org.powermock.api.mockito.PowerMockito.when; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({SmsMessage.class, MainApp.class}) + +public class SmsTest { + + @Test + public void doTests() { + SmsMessage smsMessage = mock(SmsMessage.class); + when(smsMessage.getOriginatingAddress()).thenReturn("aNumber"); + when(smsMessage.getMessageBody()).thenReturn("aBody"); + + Sms sms = new Sms(smsMessage); + Assert.assertEquals(sms.phoneNumber, "aNumber"); + Assert.assertEquals(sms.text, "aBody"); + Assert.assertTrue(sms.received); + + sms = new Sms("aNumber", "aBody"); + Assert.assertEquals(sms.phoneNumber, "aNumber"); + Assert.assertEquals(sms.text, "aBody"); + Assert.assertTrue(sms.sent); + + sms = new Sms("aNumber", R.string.insulin_unit_shortname); + Assert.assertEquals(sms.phoneNumber, "aNumber"); + Assert.assertEquals(sms.text, MainApp.gs(R.string.insulin_unit_shortname)); + Assert.assertTrue(sms.sent); + + Assert.assertEquals(sms.toString(), "SMS from aNumber: U"); + } + + @Before + public void prepareTests() { + AAPSMocker.mockMainApp(); + AAPSMocker.mockStrings(); + } +} From b7305f156f7548c16cdc1351426bf9353429df91 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Tue, 12 Mar 2019 19:14:15 +0100 Subject: [PATCH 19/39] SmsActionTest --- .../smsCommunicator/SmsActionTest.java | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsActionTest.java diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsActionTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsActionTest.java new file mode 100644 index 0000000000..f4d61e56eb --- /dev/null +++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsActionTest.java @@ -0,0 +1,90 @@ +package info.nightscout.androidaps.plugins.general.smsCommunicator; + +import android.telephony.SmsMessage; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import info.AAPSMocker; +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; + +import static org.powermock.api.mockito.PowerMockito.mock; +import static org.powermock.api.mockito.PowerMockito.when; + +@RunWith(PowerMockRunner.class) + +public class SmsActionTest { + String result = ""; + + @Test + public void doTests() { + + SmsAction smsAction = new SmsAction() { + @Override + public void run() { + result = "A"; + } + }; + smsAction.run(); + Assert.assertEquals(result, "A"); + + smsAction = new SmsAction(1d) { + @Override + public void run() { + result = "B"; + } + }; + smsAction.run(); + Assert.assertEquals(result, "B"); + Assert.assertEquals(smsAction.aDouble, 1d, 0.000001d); + + smsAction = new SmsAction(1d, 2) { + @Override + public void run() { + result = "C"; + } + }; + smsAction.run(); + Assert.assertEquals(result, "C"); + Assert.assertEquals(smsAction.aDouble, 1d, 0.000001d); + Assert.assertEquals(smsAction.secondInteger.intValue(), 2); + + smsAction = new SmsAction("aString", 3) { + @Override + public void run() { + result = "D"; + } + }; + smsAction.run(); + Assert.assertEquals(result, "D"); + Assert.assertEquals(smsAction.aString, "aString"); + Assert.assertEquals(smsAction.secondInteger.intValue(), 3); + + smsAction = new SmsAction(4) { + @Override + public void run() { + result = "E"; + } + }; + smsAction.run(); + Assert.assertEquals(result, "E"); + Assert.assertEquals(smsAction.anInteger.intValue(), 4); + + smsAction = new SmsAction(5, 6) { + @Override + public void run() { + result = "F"; + } + }; + smsAction.run(); + Assert.assertEquals(result, "F"); + Assert.assertEquals(smsAction.anInteger.intValue(), 5); + Assert.assertEquals(smsAction.secondInteger.intValue(), 6); + } + +} From bb22b00245401e57b77a9db069bc84db85d55503 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Tue, 12 Mar 2019 19:55:47 +0100 Subject: [PATCH 20/39] AuthRequestTest --- .../general/smsCommunicator/AuthRequest.java | 1 + app/src/test/java/info/AAPSMocker.java | 1 + .../smsCommunicator/AuthRequestTest.java | 90 +++++++++++++++++++ 3 files changed, 92 insertions(+) create mode 100644 app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequestTest.java diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequest.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequest.java index 42da28a458..7fa497650f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequest.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequest.java @@ -38,6 +38,7 @@ class AuthRequest { return; } if (!confirmCode.equals(codeReceived)) { + processed = true; if (L.isEnabled(L.SMS)) log.debug("Wrong code"); plugin.sendSMS(new Sms(requester.phoneNumber, R.string.sms_wrongcode)); diff --git a/app/src/test/java/info/AAPSMocker.java b/app/src/test/java/info/AAPSMocker.java index f1ec982f9b..fcf35d48f4 100644 --- a/app/src/test/java/info/AAPSMocker.java +++ b/app/src/test/java/info/AAPSMocker.java @@ -104,6 +104,7 @@ public class AAPSMocker { when(MainApp.gs(R.string.profile_per_unit)).thenReturn("/U"); when(MainApp.gs(R.string.profile_carbs_per_unit)).thenReturn("g/U"); when(MainApp.gs(R.string.profile_ins_units_per_hout)).thenReturn("U/h"); + when(MainApp.gs(R.string.sms_wrongcode)).thenReturn("Wrong code. Command cancelled."); } public static MainApp mockMainApp() { diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequestTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequestTest.java new file mode 100644 index 0000000000..f5d2b6b56d --- /dev/null +++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequestTest.java @@ -0,0 +1,90 @@ +package info.nightscout.androidaps.plugins.general.smsCommunicator; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.stubbing.Answer; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.Date; + +import info.AAPSMocker; +import info.nightscout.androidaps.Constants; +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.utils.DateUtil; +import info.nightscout.androidaps.utils.SP; +import info.nightscout.androidaps.utils.T; + +import static org.mockito.ArgumentMatchers.any; +import static org.powermock.api.mockito.PowerMockito.doAnswer; +import static org.powermock.api.mockito.PowerMockito.mock; +import static org.powermock.api.mockito.PowerMockito.mockStatic; +import static org.powermock.api.mockito.PowerMockito.when; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({SmsCommunicatorPlugin.class, L.class, SP.class, MainApp.class, DateUtil.class}) + +public class AuthRequestTest { + SmsCommunicatorPlugin smsCommunicatorPlugin; + Sms sentSms; + boolean actionCalled = false; + + @Test + public void doTests() { + Sms requester = new Sms("aNumber", "aText"); + SmsAction action = new SmsAction() { + @Override + public void run() { + actionCalled = true; + } + }; + + // Check if SMS requesting code is sent + AuthRequest authRequest = new AuthRequest(smsCommunicatorPlugin, requester, "Request text", "ABC", action); + + Assert.assertEquals(sentSms.phoneNumber, "aNumber"); + Assert.assertEquals(sentSms.text, "Request text"); + + // wrong reply + actionCalled = false; + authRequest.action("EFG"); + Assert.assertEquals(sentSms.phoneNumber, "aNumber"); + Assert.assertEquals(sentSms.text, "Wrong code. Command cancelled."); + Assert.assertFalse(actionCalled); + + // correct reply + authRequest = new AuthRequest(smsCommunicatorPlugin, requester, "Request text", "ABC", action); + actionCalled = false; + authRequest.action("ABC"); + Assert.assertTrue(actionCalled); + + // test timed out message + long now = 10000; + when(DateUtil.now()).thenReturn(now); + authRequest = new AuthRequest(smsCommunicatorPlugin, requester, "Request text", "ABC", action); + actionCalled = false; + when(DateUtil.now()).thenReturn(now + T.mins(Constants.SMS_CONFIRM_TIMEOUT).msecs() + 1); + authRequest.action("ABC"); + Assert.assertFalse(actionCalled); + } + + @Before + public void prepareTests() { + smsCommunicatorPlugin = mock(SmsCommunicatorPlugin.class); + doAnswer((Answer) invocation -> { + sentSms = invocation.getArgument(0); + return null; + }).when(smsCommunicatorPlugin).sendSMS(any(Sms.class)); + + AAPSMocker.mockMainApp(); + AAPSMocker.mockApplicationContext(); + AAPSMocker.mockSP(); + AAPSMocker.mockL(); + AAPSMocker.mockStrings(); + + mockStatic(DateUtil.class); + } +} From 3ebd7dcdb82c77c64f95f38355529080e58e32f9 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Tue, 12 Mar 2019 20:03:41 +0100 Subject: [PATCH 21/39] AuthRequestTest 2 --- .../plugins/general/smsCommunicator/AuthRequestTest.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequestTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequestTest.java index f5d2b6b56d..dd41f9873a 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequestTest.java +++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequestTest.java @@ -60,6 +60,10 @@ public class AuthRequestTest { actionCalled = false; authRequest.action("ABC"); Assert.assertTrue(actionCalled); + // second time action should not be called + actionCalled = false; + authRequest.action("ABC"); + Assert.assertFalse(actionCalled); // test timed out message long now = 10000; From b24217491bc3c6981422d02fa865f54592079789 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Tue, 12 Mar 2019 22:58:04 +0100 Subject: [PATCH 22/39] SmsCommunicatorPluginTest 1 --- .../SmsCommunicatorPlugin.java | 12 +- app/src/test/java/info/AAPSMocker.java | 27 ++++- .../SmsCommunicatorPluginTest.java | 103 ++++++++++++++++++ 3 files changed, 130 insertions(+), 12 deletions(-) create mode 100644 app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java index b4ff04baa0..8f6b437d06 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java @@ -3,7 +3,6 @@ package info.nightscout.androidaps.plugins.general.smsCommunicator; import android.content.Intent; import android.content.pm.ResolveInfo; import android.os.Bundle; -import android.os.SystemClock; import android.telephony.SmsManager; import android.telephony.SmsMessage; @@ -52,7 +51,6 @@ import info.nightscout.androidaps.utils.DateUtil; import info.nightscout.androidaps.utils.DecimalFormatter; import info.nightscout.androidaps.utils.SP; import info.nightscout.androidaps.utils.SafeParse; -import info.nightscout.androidaps.utils.T; import info.nightscout.androidaps.utils.XdripCalibrations; /** @@ -71,7 +69,7 @@ public class SmsCommunicatorPlugin extends PluginBase { return smsCommunicatorPlugin; } - private List allowedNumbers = new ArrayList<>(); + List allowedNumbers = new ArrayList<>(); private AuthRequest messageToConfirm = null; @@ -79,7 +77,7 @@ public class SmsCommunicatorPlugin extends PluginBase { ArrayList messages = new ArrayList<>(); - private SmsCommunicatorPlugin() { + SmsCommunicatorPlugin() { super(new PluginDescription() .mainType(PluginType.GENERAL) .fragmentClass(SmsCommunicatorFragment.class.getName()) @@ -118,7 +116,7 @@ public class SmsCommunicatorPlugin extends PluginBase { } } - private boolean isAllowedNumber(String number) { + boolean isAllowedNumber(String number) { for (String num : allowedNumbers) { if (num.equals(number)) return true; } @@ -139,7 +137,7 @@ public class SmsCommunicatorPlugin extends PluginBase { } } - private void processSms(final Sms receivedSms) { + void processSms(final Sms receivedSms) { if (!isEnabled(PluginType.GENERAL)) { log.debug("Ignoring SMS. Plugin disabled."); return; @@ -757,7 +755,7 @@ public class SmsCommunicatorPlugin extends PluginBase { passCode += Character.toString((char) (startChar2 + Math.random() * ('z' - 'a' + 1))); int startChar3 = Math.random() > 0.5 ? 'a' : 'A'; passCode += Character.toString((char) (startChar3 + Math.random() * ('z' - 'a' + 1))); - passCode.replace('l','k').replace('I', 'J'); + passCode.replace('l', 'k').replace('I', 'J'); return passCode; } diff --git a/app/src/test/java/info/AAPSMocker.java b/app/src/test/java/info/AAPSMocker.java index fcf35d48f4..5fbc267cd5 100644 --- a/app/src/test/java/info/AAPSMocker.java +++ b/app/src/test/java/info/AAPSMocker.java @@ -17,6 +17,7 @@ import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.ConstraintChecker; +import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.ProfileStore; import info.nightscout.androidaps.db.DatabaseHelper; @@ -24,11 +25,12 @@ import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.general.nsclient.NSUpload; +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin; +import info.nightscout.androidaps.plugins.pump.danaR.DanaRPlugin; +import info.nightscout.androidaps.plugins.pump.danaRKorean.DanaRKoreanPlugin; import info.nightscout.androidaps.plugins.pump.danaRv2.DanaRv2Plugin; import info.nightscout.androidaps.plugins.treatments.TreatmentService; import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin; -import info.nightscout.androidaps.plugins.pump.danaR.DanaRPlugin; -import info.nightscout.androidaps.plugins.pump.danaRKorean.DanaRKoreanPlugin; import info.nightscout.androidaps.queue.CommandQueue; import info.nightscout.androidaps.utils.SP; @@ -105,6 +107,9 @@ public class AAPSMocker { when(MainApp.gs(R.string.profile_carbs_per_unit)).thenReturn("g/U"); when(MainApp.gs(R.string.profile_ins_units_per_hout)).thenReturn("U/h"); when(MainApp.gs(R.string.sms_wrongcode)).thenReturn("Wrong code. Command cancelled."); + when(MainApp.gs(R.string.sms_iob)).thenReturn("IOB:"); + when(MainApp.gs(R.string.sms_lastbg)).thenReturn("Last BG:"); + when(MainApp.gs(R.string.sms_minago)).thenReturn("%1$dmin ago"); } public static MainApp mockMainApp() { @@ -144,7 +149,7 @@ public class AAPSMocker { when(L.isEnabled(any())).thenReturn(true); } - public static void mockNSUpload(){ + public static void mockNSUpload() { PowerMockito.mockStatic(NSUpload.class); } @@ -170,12 +175,17 @@ public class AAPSMocker { PowerMockito.mockStatic(TreatmentsPlugin.class); TreatmentsPlugin treatmentsPlugin = PowerMockito.mock(TreatmentsPlugin.class); when(TreatmentsPlugin.getPlugin()).thenReturn(treatmentsPlugin); + when(treatmentsPlugin.getLastCalculationTreatments()).thenReturn(new IobTotal(0)); + when(treatmentsPlugin.getLastCalculationTempBasals()).thenReturn(new IobTotal(0)); return treatmentsPlugin; } - public static void mockTreatmentService() throws Exception { + public static void mockTreatmentService() { TreatmentService treatmentService = PowerMockito.mock(TreatmentService.class); - PowerMockito.whenNew(TreatmentService.class).withNoArguments().thenReturn(treatmentService); + try { + PowerMockito.whenNew(TreatmentService.class).withNoArguments().thenReturn(treatmentService); + } catch (Exception e) { + } } public static DanaRPlugin mockDanaRPlugin() { @@ -222,6 +232,13 @@ public class AAPSMocker { PowerMockito.when(ProfileFunctions.getInstance()).thenReturn(profileFunctions); profile = getValidProfile(); PowerMockito.when(ProfileFunctions.getInstance().getProfile()).thenReturn(profile); + PowerMockito.when(ProfileFunctions.getInstance().getProfileUnits()).thenReturn(Constants.MGDL); + } + + public static void mockIobCobCalculatorPlugin() { + PowerMockito.mockStatic(IobCobCalculatorPlugin.class); + IobCobCalculatorPlugin iobCobCalculatorPlugin = PowerMockito.mock(IobCobCalculatorPlugin.class); + PowerMockito.when(IobCobCalculatorPlugin.getPlugin()).thenReturn(iobCobCalculatorPlugin); } private static MockedBus bus = new MockedBus(); diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java new file mode 100644 index 0000000000..eb1445c074 --- /dev/null +++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java @@ -0,0 +1,103 @@ +package info.nightscout.androidaps.plugins.general.smsCommunicator; + +import android.telephony.SmsManager; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.ArrayList; +import java.util.List; + +import info.AAPSMocker; +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.db.BgReading; +import info.nightscout.androidaps.interfaces.PluginType; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin; +import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin; +import info.nightscout.androidaps.utils.DateUtil; +import info.nightscout.androidaps.utils.SP; + +import static org.powermock.api.mockito.PowerMockito.mock; +import static org.powermock.api.mockito.PowerMockito.mockStatic; +import static org.powermock.api.mockito.PowerMockito.when; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({SmsCommunicatorPlugin.class, L.class, SP.class, MainApp.class, DateUtil.class, ProfileFunctions.class, TreatmentsPlugin.class, SmsManager.class, IobCobCalculatorPlugin.class}) + +public class SmsCommunicatorPluginTest { + + SmsCommunicatorPlugin smsCommunicatorPlugin; + String sentNumber; + String sentText; + + @Test + public void processSettingsTest() { + // called from constructor + Assert.assertEquals(smsCommunicatorPlugin.allowedNumbers.get(0), "1234"); + Assert.assertEquals(smsCommunicatorPlugin.allowedNumbers.get(1), "5678"); + Assert.assertEquals(smsCommunicatorPlugin.allowedNumbers.size(), 2); + } + + @Test + public void isAllowedNumberTest() { + Assert.assertTrue(smsCommunicatorPlugin.isAllowedNumber("5678")); + Assert.assertFalse(smsCommunicatorPlugin.isAllowedNumber("56")); + } + + @Test + public void processSmsTest() { + Sms sms; + + // SMS from not allowed number should be ignored + sms = new Sms("12", "aText"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertTrue(sms.ignored); + Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "aText"); + + //BG + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "BG"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertFalse(sms.ignored); + Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "BG"); + Assert.assertTrue(smsCommunicatorPlugin.messages.get(1).text.contains("IOB:")); + Assert.assertTrue(smsCommunicatorPlugin.messages.get(1).text.contains("Last BG: 100")); + } + + @Before + public void prepareTests() { + AAPSMocker.mockMainApp(); + AAPSMocker.mockApplicationContext(); + AAPSMocker.mockSP(); + AAPSMocker.mockL(); + AAPSMocker.mockStrings(); + AAPSMocker.mockBus(); + AAPSMocker.mockProfileFunctions(); + AAPSMocker.mockTreatmentPlugin(); + AAPSMocker.mockIobCobCalculatorPlugin(); + + BgReading reading = new BgReading(); + reading.value = 100; + List bgList = new ArrayList<>(); + bgList.add(reading); + PowerMockito.when(IobCobCalculatorPlugin.getPlugin().getBgReadings()).thenReturn(bgList); + + mockStatic(DateUtil.class); + mockStatic(SmsManager.class); + SmsManager smsManager = mock(SmsManager.class); + when(SmsManager.getDefault()).thenReturn(smsManager); + + when(SP.getString(R.string.key_smscommunicator_allowednumbers, "")).thenReturn("1234;5678"); + smsCommunicatorPlugin = new SmsCommunicatorPlugin(); + smsCommunicatorPlugin.setPluginEnabled(PluginType.GENERAL, true); + } + +} From a212ba715688e20516bc6ef5007fd9aa5be2a8fe Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Tue, 12 Mar 2019 23:30:31 +0100 Subject: [PATCH 23/39] SmsCommunicatorPluginTest 2 --- .../general/smsCommunicator/SmsCommunicatorPluginTest.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java index eb1445c074..200b956946 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java +++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java @@ -30,13 +30,11 @@ import static org.powermock.api.mockito.PowerMockito.mockStatic; import static org.powermock.api.mockito.PowerMockito.when; @RunWith(PowerMockRunner.class) -@PrepareForTest({SmsCommunicatorPlugin.class, L.class, SP.class, MainApp.class, DateUtil.class, ProfileFunctions.class, TreatmentsPlugin.class, SmsManager.class, IobCobCalculatorPlugin.class}) +@PrepareForTest({L.class, SP.class, MainApp.class, DateUtil.class, ProfileFunctions.class, TreatmentsPlugin.class, SmsManager.class, IobCobCalculatorPlugin.class}) public class SmsCommunicatorPluginTest { SmsCommunicatorPlugin smsCommunicatorPlugin; - String sentNumber; - String sentText; @Test public void processSettingsTest() { From bb5cec95eafb1aae176b159844a11082a4a0ba28 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Wed, 13 Mar 2019 14:33:28 +0100 Subject: [PATCH 24/39] SmsCommunicatorPluginTest 3 --- .../androidaps/data/ConstraintChecker.java | 15 ++++++ .../interfaces/ConstraintsInterface.java | 4 ++ .../aps/openAPSSMB/OpenAPSSMBPlugin.java | 8 +++- app/src/test/java/info/AAPSMocker.java | 4 ++ .../interfaces/ConstraintsCheckerTest.java | 10 ++++ .../SmsCommunicatorPluginTest.java | 46 ++++++++++++++++++- 6 files changed, 85 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/data/ConstraintChecker.java b/app/src/main/java/info/nightscout/androidaps/data/ConstraintChecker.java index ceb85c6967..68664033d0 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/ConstraintChecker.java +++ b/app/src/main/java/info/nightscout/androidaps/data/ConstraintChecker.java @@ -50,6 +50,10 @@ public class ConstraintChecker implements ConstraintsInterface { return isAdvancedFilteringEnabled(new Constraint<>(true)); } + public Constraint isSuperBolusEnabled() { + return isSuperBolusEnabled(new Constraint<>(true)); + } + public Constraint getMaxBasalAllowed(Profile profile) { return applyBasalConstraints(new Constraint<>(Constants.REALLYHIGHBASALRATE), profile); } @@ -157,6 +161,17 @@ public class ConstraintChecker implements ConstraintsInterface { return value; } + @Override + public Constraint isSuperBolusEnabled(Constraint value) { + ArrayList constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); + for (PluginBase p : constraintsPlugins) { + ConstraintsInterface constraint = (ConstraintsInterface) p; + if (!p.isEnabled(PluginType.CONSTRAINTS)) continue; + constraint.isSuperBolusEnabled(value); + } + return value; + } + @Override public Constraint applyBasalConstraints(Constraint absoluteRate, Profile profile) { ArrayList constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); diff --git a/app/src/main/java/info/nightscout/androidaps/interfaces/ConstraintsInterface.java b/app/src/main/java/info/nightscout/androidaps/interfaces/ConstraintsInterface.java index 5ac8cc83f7..f1c79dd5cb 100644 --- a/app/src/main/java/info/nightscout/androidaps/interfaces/ConstraintsInterface.java +++ b/app/src/main/java/info/nightscout/androidaps/interfaces/ConstraintsInterface.java @@ -35,6 +35,10 @@ public interface ConstraintsInterface { return value; } + default Constraint isSuperBolusEnabled(Constraint value) { + return value; + } + default Constraint applyBasalConstraints(Constraint absoluteRate, Profile profile) { return absoluteRate; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/OpenAPSSMBPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/OpenAPSSMBPlugin.java index f1232e39c3..f1367bcc8e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/OpenAPSSMBPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/OpenAPSSMBPlugin.java @@ -13,6 +13,7 @@ import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.db.TempTarget; import info.nightscout.androidaps.interfaces.APSInterface; import info.nightscout.androidaps.interfaces.Constraint; +import info.nightscout.androidaps.interfaces.ConstraintsInterface; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginType; @@ -38,7 +39,7 @@ import info.nightscout.androidaps.utils.ToastUtils; /** * Created by mike on 05.08.2016. */ -public class OpenAPSSMBPlugin extends PluginBase implements APSInterface { +public class OpenAPSSMBPlugin extends PluginBase implements APSInterface, ConstraintsInterface { private static Logger log = LoggerFactory.getLogger(L.APS); private static OpenAPSSMBPlugin openAPSSMBPlugin; @@ -266,4 +267,9 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface { return newvalue; } + public Constraint isSuperBolusEnabled(Constraint value) { + value.set(false); + return value; + } + } diff --git a/app/src/test/java/info/AAPSMocker.java b/app/src/test/java/info/AAPSMocker.java index 5fbc267cd5..e04576cdbc 100644 --- a/app/src/test/java/info/AAPSMocker.java +++ b/app/src/test/java/info/AAPSMocker.java @@ -110,6 +110,10 @@ public class AAPSMocker { when(MainApp.gs(R.string.sms_iob)).thenReturn("IOB:"); when(MainApp.gs(R.string.sms_lastbg)).thenReturn("Last BG:"); when(MainApp.gs(R.string.sms_minago)).thenReturn("%1$dmin ago"); + when(MainApp.gs(R.string.smscommunicator_remotecommandnotallowed)).thenReturn("Remote command is not allowed"); + when(MainApp.gs(R.string.loopsuspendedfor)).thenReturn("Suspended (%1$d m)"); + when(MainApp.gs(R.string.smscommunicator_loopisdisabled)).thenReturn("Loop is disabled"); + when(MainApp.gs(R.string.smscommunicator_loopisenabled)).thenReturn("Loop is enabled"); } public static MainApp mockMainApp() { diff --git a/app/src/test/java/info/nightscout/androidaps/interfaces/ConstraintsCheckerTest.java b/app/src/test/java/info/nightscout/androidaps/interfaces/ConstraintsCheckerTest.java index 113cff31f8..d391d847f1 100644 --- a/app/src/test/java/info/nightscout/androidaps/interfaces/ConstraintsCheckerTest.java +++ b/app/src/test/java/info/nightscout/androidaps/interfaces/ConstraintsCheckerTest.java @@ -54,6 +54,7 @@ public class ConstraintsCheckerTest { DanaRPlugin danaRPlugin; DanaRSPlugin danaRSPlugin; LocalInsightPlugin insightPlugin; + OpenAPSSMBPlugin openAPSSMBPlugin; boolean notificationSent = false; @@ -119,6 +120,13 @@ public class ConstraintsCheckerTest { Assert.assertEquals(Boolean.FALSE, c.value()); } + @Test + public void isSuperBolusEnabledTest() throws Exception { + + Constraint c = constraintChecker.isSuperBolusEnabled(); + Assert.assertEquals(Boolean.FALSE, c.value()); // SMB should limit + } + @Test public void isSMBModeEnabledTest() throws Exception { objectivesPlugin.objectives.get(7).setStartedOn(null); @@ -288,6 +296,7 @@ public class ConstraintsCheckerTest { danaRPlugin = DanaRPlugin.getPlugin(); danaRSPlugin = DanaRSPlugin.getPlugin(); insightPlugin = LocalInsightPlugin.getPlugin(); + openAPSSMBPlugin = OpenAPSSMBPlugin.getPlugin(); ArrayList constraintsPluginsList = new ArrayList<>(); constraintsPluginsList.add(safetyPlugin); constraintsPluginsList.add(objectivesPlugin); @@ -295,6 +304,7 @@ public class ConstraintsCheckerTest { constraintsPluginsList.add(danaRPlugin); constraintsPluginsList.add(danaRSPlugin); constraintsPluginsList.add(insightPlugin); + constraintsPluginsList.add(openAPSSMBPlugin); when(mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class)).thenReturn(constraintsPluginsList); } diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java index 200b956946..7f11a57e2c 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java +++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java @@ -19,6 +19,7 @@ import info.nightscout.androidaps.R; import info.nightscout.androidaps.db.BgReading; import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin; import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin; import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin; @@ -35,6 +36,7 @@ import static org.powermock.api.mockito.PowerMockito.when; public class SmsCommunicatorPluginTest { SmsCommunicatorPlugin smsCommunicatorPlugin; + LoopPlugin loopPlugin; @Test public void processSettingsTest() { @@ -60,14 +62,53 @@ public class SmsCommunicatorPluginTest { Assert.assertTrue(sms.ignored); Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "aText"); + // test remote control disabled + when(SP.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)).thenReturn(false); + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "LOOP STATUS"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertFalse(sms.ignored); + Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "LOOP STATUS"); + Assert.assertTrue(smsCommunicatorPlugin.messages.get(1).text.contains("Remote command is not allowed")); + + // enable remote control for next tests + when(SP.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)).thenReturn(true); + //BG smsCommunicatorPlugin.messages = new ArrayList<>(); sms = new Sms("1234", "BG"); smsCommunicatorPlugin.processSms(sms); - Assert.assertFalse(sms.ignored); Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "BG"); Assert.assertTrue(smsCommunicatorPlugin.messages.get(1).text.contains("IOB:")); Assert.assertTrue(smsCommunicatorPlugin.messages.get(1).text.contains("Last BG: 100")); + + //LOOP STATUS : disabled + when(loopPlugin.isEnabled(PluginType.LOOP)).thenReturn(false); + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "LOOP STATUS"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "LOOP STATUS"); + Assert.assertEquals(smsCommunicatorPlugin.messages.get(1).text, "Loop is disabled"); + + //LOOP STATUS : suspended + when(loopPlugin.minutesToEndOfSuspend()).thenReturn(10); + when(loopPlugin.isEnabled(PluginType.LOOP)).thenReturn(true); + when(loopPlugin.isSuspended()).thenReturn(true); + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "LOOP STATUS"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "LOOP STATUS"); + Assert.assertEquals(smsCommunicatorPlugin.messages.get(1).text, "Suspended (10 m)"); + + //LOOP STATUS : enabled + when(loopPlugin.isEnabled(PluginType.LOOP)).thenReturn(true); + when(loopPlugin.isSuspended()).thenReturn(false); + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "LOOP STATUS"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertFalse(sms.ignored); + Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "LOOP STATUS"); + Assert.assertEquals(smsCommunicatorPlugin.messages.get(1).text, "Loop is enabled"); } @Before @@ -96,6 +137,9 @@ public class SmsCommunicatorPluginTest { when(SP.getString(R.string.key_smscommunicator_allowednumbers, "")).thenReturn("1234;5678"); smsCommunicatorPlugin = new SmsCommunicatorPlugin(); smsCommunicatorPlugin.setPluginEnabled(PluginType.GENERAL, true); + + loopPlugin = mock(LoopPlugin.class); + when(MainApp.getSpecificPlugin(LoopPlugin.class)).thenReturn(loopPlugin); } } From 826497c9f6fbe07f4a548a8429813a361d671338 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Wed, 13 Mar 2019 18:50:37 +0100 Subject: [PATCH 25/39] Fix superbolus test & allow APS plugin to be constraint --- .../java/info/nightscout/androidaps/interfaces/PluginBase.java | 2 ++ .../androidaps/interfaces/ConstraintsCheckerTest.java | 1 + 2 files changed, 3 insertions(+) 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 b92b8a8f87..01be296539 100644 --- a/app/src/main/java/info/nightscout/androidaps/interfaces/PluginBase.java +++ b/app/src/main/java/info/nightscout/androidaps/interfaces/PluginBase.java @@ -93,6 +93,8 @@ public abstract class PluginBase { return state == State.ENABLED && specialEnableCondition(); if (type == PluginType.CONSTRAINTS && pluginDescription.mainType == PluginType.PUMP && isEnabled(PluginType.PUMP)) return true; + if (type == PluginType.CONSTRAINTS && pluginDescription.mainType == PluginType.APS && isEnabled(PluginType.APS)) + return true; if (type == PluginType.PROFILE && pluginDescription.mainType == PluginType.PUMP) return isProfileInterfaceEnabled; return false; diff --git a/app/src/test/java/info/nightscout/androidaps/interfaces/ConstraintsCheckerTest.java b/app/src/test/java/info/nightscout/androidaps/interfaces/ConstraintsCheckerTest.java index d391d847f1..ee03ef73d7 100644 --- a/app/src/test/java/info/nightscout/androidaps/interfaces/ConstraintsCheckerTest.java +++ b/app/src/test/java/info/nightscout/androidaps/interfaces/ConstraintsCheckerTest.java @@ -122,6 +122,7 @@ public class ConstraintsCheckerTest { @Test public void isSuperBolusEnabledTest() throws Exception { + OpenAPSSMBPlugin.getPlugin().setPluginEnabled(PluginType.APS, true); Constraint c = constraintChecker.isSuperBolusEnabled(); Assert.assertEquals(Boolean.FALSE, c.value()); // SMB should limit From 4c0554f61aa3a665d7fa5d39cfd61c6114a50303 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Wed, 13 Mar 2019 19:35:48 +0100 Subject: [PATCH 26/39] SmsCommunicatorPluginTest 4 --- .../SmsCommunicatorPlugin.java | 16 +- app/src/test/java/info/AAPSMocker.java | 16 +- .../SmsCommunicatorPluginTest.java | 158 ++++++++++++++++-- 3 files changed, 172 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java index 8f6b437d06..a1adb1598f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java @@ -164,7 +164,7 @@ public class SmsCommunicatorPlugin extends PluginBase { case "LOOP": if (!remoteCommandsAllowed) sendSMS(new Sms(receivedSms.phoneNumber, R.string.smscommunicator_remotecommandnotallowed)); - else if (splitted.length == 2) + else if (splitted.length == 2 || splitted.length == 3) processLOOP(splitted, receivedSms); else sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat)); @@ -236,7 +236,7 @@ public class SmsCommunicatorPlugin extends PluginBase { messageToConfirm.action(splitted[0]); messageToConfirm = null; } else - sendSMS(new Sms(receivedSms.phoneNumber, MainApp.gs(R.string.smscommunicator_unknowncommand))); + sendSMS(new Sms(receivedSms.phoneNumber, R.string.smscommunicator_unknowncommand)); break; } } @@ -294,6 +294,8 @@ public class SmsCommunicatorPlugin extends PluginBase { sendSMS(new Sms(receivedSms.phoneNumber, reply)); } }); + } else { + sendSMS(new Sms(receivedSms.phoneNumber, R.string.smscommunicator_loopisdisabled)); } receivedSms.processed = true; break; @@ -304,6 +306,8 @@ public class SmsCommunicatorPlugin extends PluginBase { loopPlugin.setPluginEnabled(PluginType.LOOP, true); sendSMS(new Sms(receivedSms.phoneNumber, R.string.smscommunicator_loophasbeenenabled)); MainApp.bus().post(new EventRefreshOverview("SMS_LOOP_START")); + } else { + sendSMS(new Sms(receivedSms.phoneNumber, R.string.smscommunicator_loopisenabled)); } receivedSms.processed = true; break; @@ -326,18 +330,16 @@ public class SmsCommunicatorPlugin extends PluginBase { LoopPlugin.getPlugin().suspendTo(0); MainApp.bus().post(new EventRefreshOverview("SMS_LOOP_RESUME")); NSUpload.uploadOpenAPSOffline(0); - reply = MainApp.gs(R.string.smscommunicator_loopresumed); - sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); + sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, R.string.smscommunicator_loopresumed)); break; case "SUSPEND": int duration = 0; - if (splitted.length >= 3) + if (splitted.length == 3) duration = SafeParse.stringToInt(splitted[2]); duration = Math.max(0, duration); duration = Math.min(180, duration); if (duration == 0) { - reply = MainApp.gs(R.string.smscommunicator_wrongduration); - sendSMS(new Sms(receivedSms.phoneNumber, reply)); + sendSMS(new Sms(receivedSms.phoneNumber, R.string.smscommunicator_wrongduration)); } else { String passCode = generatePasscode(); reply = String.format(MainApp.gs(R.string.smscommunicator_suspendreplywithcode), duration, passCode); diff --git a/app/src/test/java/info/AAPSMocker.java b/app/src/test/java/info/AAPSMocker.java index e04576cdbc..27a2d2d6b4 100644 --- a/app/src/test/java/info/AAPSMocker.java +++ b/app/src/test/java/info/AAPSMocker.java @@ -9,6 +9,7 @@ import com.squareup.otto.Bus; import org.json.JSONException; import org.json.JSONObject; import org.junit.Assert; +import org.mockito.stubbing.Answer; import org.powermock.api.mockito.PowerMockito; import java.util.Locale; @@ -31,6 +32,7 @@ import info.nightscout.androidaps.plugins.pump.danaRKorean.DanaRKoreanPlugin; import info.nightscout.androidaps.plugins.pump.danaRv2.DanaRv2Plugin; import info.nightscout.androidaps.plugins.treatments.TreatmentService; import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin; +import info.nightscout.androidaps.queue.Callback; import info.nightscout.androidaps.queue.CommandQueue; import info.nightscout.androidaps.utils.SP; @@ -38,6 +40,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -53,6 +56,8 @@ public class AAPSMocker { public static Intent intentSent = null; + public static CommandQueue queue; + public static void mockStrings() { Locale.setDefault(new Locale("en", "US")); @@ -114,6 +119,15 @@ public class AAPSMocker { when(MainApp.gs(R.string.loopsuspendedfor)).thenReturn("Suspended (%1$d m)"); when(MainApp.gs(R.string.smscommunicator_loopisdisabled)).thenReturn("Loop is disabled"); when(MainApp.gs(R.string.smscommunicator_loopisenabled)).thenReturn("Loop is enabled"); + when(MainApp.gs(R.string.wrongformat)).thenReturn("Wrong format"); + when(MainApp.gs(R.string.smscommunicator_loophasbeendisabled)).thenReturn("Loop has been disabled"); + when(MainApp.gs(R.string.smscommunicator_loophasbeenenabled)).thenReturn("Loop has been enabled"); + when(MainApp.gs(R.string.smscommunicator_tempbasalcanceled)).thenReturn("Temp basal canceled"); + when(MainApp.gs(R.string.smscommunicator_loopresumed)).thenReturn("Loop resumed"); + when(MainApp.gs(R.string.smscommunicator_wrongduration)).thenReturn("Wrong duration"); + when(MainApp.gs(R.string.smscommunicator_suspendreplywithcode)).thenReturn("To suspend loop for %1$d minutes reply with code %2$s"); + when(MainApp.gs(R.string.smscommunicator_loopsuspended)).thenReturn("Loop suspended"); + when(MainApp.gs(R.string.smscommunicator_unknowncommand)).thenReturn("Uknown command or wrong reply"); } public static MainApp mockMainApp() { @@ -171,7 +185,7 @@ public class AAPSMocker { } public static void mockCommandQueue() { - CommandQueue queue = mock(CommandQueue.class); + queue = mock(CommandQueue.class); when(ConfigBuilderPlugin.getPlugin().getCommandQueue()).thenReturn(queue); } diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java index 7f11a57e2c..6a96acfb6d 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java +++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java @@ -6,6 +6,8 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.mockito.stubbing.Answer; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; @@ -16,28 +18,42 @@ import java.util.List; import info.AAPSMocker; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.db.BgReading; import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin; +import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; +import info.nightscout.androidaps.plugins.general.nsclient.NSUpload; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin; import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin; +import info.nightscout.androidaps.queue.Callback; +import info.nightscout.androidaps.queue.CommandQueue; import info.nightscout.androidaps.utils.DateUtil; import info.nightscout.androidaps.utils.SP; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.powermock.api.mockito.PowerMockito.doAnswer; import static org.powermock.api.mockito.PowerMockito.mock; import static org.powermock.api.mockito.PowerMockito.mockStatic; import static org.powermock.api.mockito.PowerMockito.when; @RunWith(PowerMockRunner.class) -@PrepareForTest({L.class, SP.class, MainApp.class, DateUtil.class, ProfileFunctions.class, TreatmentsPlugin.class, SmsManager.class, IobCobCalculatorPlugin.class}) +@PrepareForTest({ + L.class, SP.class, MainApp.class, DateUtil.class, ProfileFunctions.class, + TreatmentsPlugin.class, SmsManager.class, IobCobCalculatorPlugin.class, + CommandQueue.class, ConfigBuilderPlugin.class, NSUpload.class +}) public class SmsCommunicatorPluginTest { SmsCommunicatorPlugin smsCommunicatorPlugin; LoopPlugin loopPlugin; + boolean hasBeenRun = false; + @Test public void processSettingsTest() { // called from constructor @@ -62,17 +78,12 @@ public class SmsCommunicatorPluginTest { Assert.assertTrue(sms.ignored); Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "aText"); - // test remote control disabled - when(SP.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)).thenReturn(false); + //UNKNOWN smsCommunicatorPlugin.messages = new ArrayList<>(); - sms = new Sms("1234", "LOOP STATUS"); + sms = new Sms("1234", "UNKNOWN"); smsCommunicatorPlugin.processSms(sms); - Assert.assertFalse(sms.ignored); - Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "LOOP STATUS"); - Assert.assertTrue(smsCommunicatorPlugin.messages.get(1).text.contains("Remote command is not allowed")); - - // enable remote control for next tests - when(SP.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)).thenReturn(true); + Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "UNKNOWN"); + Assert.assertEquals(smsCommunicatorPlugin.messages.get(1).text, "Uknown command or wrong reply"); //BG smsCommunicatorPlugin.messages = new ArrayList<>(); @@ -82,6 +93,16 @@ public class SmsCommunicatorPluginTest { Assert.assertTrue(smsCommunicatorPlugin.messages.get(1).text.contains("IOB:")); Assert.assertTrue(smsCommunicatorPlugin.messages.get(1).text.contains("Last BG: 100")); + // LOOP : test remote control disabled + when(SP.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)).thenReturn(false); + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "LOOP STATUS"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertFalse(sms.ignored); + Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "LOOP STATUS"); + Assert.assertTrue(smsCommunicatorPlugin.messages.get(1).text.contains("Remote command is not allowed")); + when(SP.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)).thenReturn(true); + //LOOP STATUS : disabled when(loopPlugin.isEnabled(PluginType.LOOP)).thenReturn(false); smsCommunicatorPlugin.messages = new ArrayList<>(); @@ -109,6 +130,112 @@ public class SmsCommunicatorPluginTest { Assert.assertFalse(sms.ignored); Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "LOOP STATUS"); Assert.assertEquals(smsCommunicatorPlugin.messages.get(1).text, "Loop is enabled"); + + //LOOP : wrong format + when(loopPlugin.isEnabled(PluginType.LOOP)).thenReturn(true); + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "LOOP"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertFalse(sms.ignored); + Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "LOOP"); + Assert.assertEquals(smsCommunicatorPlugin.messages.get(1).text, "Wrong format"); + + //LOOP DISABLE : already disabled + when(loopPlugin.isEnabled(PluginType.LOOP)).thenReturn(false); + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "LOOP DISABLE"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertFalse(sms.ignored); + Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "LOOP DISABLE"); + Assert.assertEquals(smsCommunicatorPlugin.messages.get(1).text, "Loop is disabled"); + + //LOOP DISABLE : from enabled + hasBeenRun = false; + when(loopPlugin.isEnabled(PluginType.LOOP)).thenReturn(true); + doAnswer((Answer) invocation -> { + hasBeenRun = true; + return null; + }).when(loopPlugin).setPluginEnabled(PluginType.LOOP, false); + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "LOOP DISABLE"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertFalse(sms.ignored); + Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "LOOP DISABLE"); + Assert.assertEquals(smsCommunicatorPlugin.messages.get(1).text, "Loop has been disabled Temp basal canceled"); + Assert.assertTrue(hasBeenRun); + + //LOOP ENABLE : already enabled + when(loopPlugin.isEnabled(PluginType.LOOP)).thenReturn(true); + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "LOOP ENABLE"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertFalse(sms.ignored); + Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "LOOP ENABLE"); + Assert.assertEquals(smsCommunicatorPlugin.messages.get(1).text, "Loop is enabled"); + + //LOOP ENABLE : from disabled + hasBeenRun = false; + when(loopPlugin.isEnabled(PluginType.LOOP)).thenReturn(false); + doAnswer((Answer) invocation -> { + hasBeenRun = true; + return null; + }).when(loopPlugin).setPluginEnabled(PluginType.LOOP, true); + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "LOOP ENABLE"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertFalse(sms.ignored); + Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "LOOP ENABLE"); + Assert.assertEquals(smsCommunicatorPlugin.messages.get(1).text, "Loop has been enabled"); + Assert.assertTrue(hasBeenRun); + + //LOOP RESUME : already enabled + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "LOOP RESUME"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertFalse(sms.ignored); + Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "LOOP RESUME"); + Assert.assertEquals(smsCommunicatorPlugin.messages.get(1).text, "Loop resumed"); + + //LOOP SUSPEND 1 2: wrong format + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "LOOP SUSPEND 1 2"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertFalse(sms.ignored); + Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "LOOP SUSPEND 1 2"); + Assert.assertEquals(smsCommunicatorPlugin.messages.get(1).text, "Wrong format"); + + //LOOP SUSPEND 0 : wrong duration + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "LOOP SUSPEND 0"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertFalse(sms.ignored); + Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "LOOP SUSPEND 0"); + Assert.assertEquals(smsCommunicatorPlugin.messages.get(1).text, "Wrong duration"); + + //LOOP SUSPEND 100 : suspend for 100 min + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "LOOP SUSPEND 100"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertFalse(sms.ignored); + Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "LOOP SUSPEND 100"); + Assert.assertTrue(smsCommunicatorPlugin.messages.get(1).text.contains("To suspend loop for 100 minutes reply with code ")); + + //LOOP SUSPEND 200 : limit to 180 min + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "LOOP SUSPEND 200"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertFalse(sms.ignored); + Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "LOOP SUSPEND 200"); + Assert.assertTrue(smsCommunicatorPlugin.messages.get(1).text.contains("To suspend loop for 180 minutes reply with code ")); + + //LOOP BLABLA + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "LOOP BLABLA"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertFalse(sms.ignored); + Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "LOOP BLABLA"); + Assert.assertEquals(smsCommunicatorPlugin.messages.get(1).text, "Wrong format"); + } @Before @@ -122,6 +249,9 @@ public class SmsCommunicatorPluginTest { AAPSMocker.mockProfileFunctions(); AAPSMocker.mockTreatmentPlugin(); AAPSMocker.mockIobCobCalculatorPlugin(); + AAPSMocker.mockConfigBuilder(); + AAPSMocker.mockCommandQueue(); + AAPSMocker.mockNSUpload(); BgReading reading = new BgReading(); reading.value = 100; @@ -140,6 +270,14 @@ public class SmsCommunicatorPluginTest { loopPlugin = mock(LoopPlugin.class); when(MainApp.getSpecificPlugin(LoopPlugin.class)).thenReturn(loopPlugin); + + Mockito.doAnswer((Answer) invocation -> { + Callback callback = invocation.getArgument(1); + callback.result = new PumpEnactResult().success(true); + callback.run(); + return null; + }).when(AAPSMocker.queue).cancelTempBasal(anyBoolean(), any(Callback.class)); + } } From 74391eefdc7e2d6261740fb3db2300c6daf7bf84 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Wed, 13 Mar 2019 21:10:52 +0100 Subject: [PATCH 27/39] SmsCommunicatorPluginTest 5 --- .../general/smsCommunicator/AuthRequest.java | 2 +- .../SmsCommunicatorPlugin.java | 7 +- app/src/test/java/info/AAPSMocker.java | 7 + .../SmsCommunicatorPluginTest.java | 147 +++++++++++++----- 4 files changed, 123 insertions(+), 40 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequest.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequest.java index 7fa497650f..ad17f4ff42 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequest.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequest.java @@ -12,7 +12,7 @@ class AuthRequest { private static Logger log = LoggerFactory.getLogger(L.SMS); private Sms requester; - private String confirmCode; + String confirmCode; private Runnable action; private long date; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java index a1adb1598f..5159b73946 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java @@ -71,7 +71,7 @@ public class SmsCommunicatorPlugin extends PluginBase { List allowedNumbers = new ArrayList<>(); - private AuthRequest messageToConfirm = null; + AuthRequest messageToConfirm = null; private Date lastRemoteBolusTime = new Date(0); @@ -339,7 +339,9 @@ public class SmsCommunicatorPlugin extends PluginBase { duration = Math.max(0, duration); duration = Math.min(180, duration); if (duration == 0) { + receivedSms.processed = true; sendSMS(new Sms(receivedSms.phoneNumber, R.string.smscommunicator_wrongduration)); + return; } else { String passCode = generatePasscode(); reply = String.format(MainApp.gs(R.string.smscommunicator_suspendreplywithcode), duration, passCode); @@ -368,6 +370,7 @@ public class SmsCommunicatorPlugin extends PluginBase { } }); } + break; default: sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat)); break; @@ -388,7 +391,7 @@ public class SmsCommunicatorPlugin extends PluginBase { } private void processNSCLIENT(String[] splitted, Sms receivedSms) { - if (splitted[2].toUpperCase().equals("RESTART")) { + if (splitted[1].toUpperCase().equals("RESTART")) { Intent restartNSClient = new Intent(Intents.ACTION_RESTART); MainApp.instance().getApplicationContext().sendBroadcast(restartNSClient); List q = MainApp.instance().getApplicationContext().getPackageManager().queryBroadcastReceivers(restartNSClient, 0); diff --git a/app/src/test/java/info/AAPSMocker.java b/app/src/test/java/info/AAPSMocker.java index 27a2d2d6b4..906dc53ca5 100644 --- a/app/src/test/java/info/AAPSMocker.java +++ b/app/src/test/java/info/AAPSMocker.java @@ -2,6 +2,7 @@ package info; import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; import android.content.res.Resources; import com.squareup.otto.Bus; @@ -176,6 +177,8 @@ public class AAPSMocker { Resources mResources = mock(Resources.class); when(MainApp.instance().getApplicationContext()).thenReturn(mockedContext); when(mockedContext.getResources()).thenReturn(mResources); + PackageManager packageManager = mock(PackageManager.class); + when(mockedContext.getPackageManager()).thenReturn(packageManager); } public static DatabaseHelper mockDatabaseHelper() { @@ -195,6 +198,9 @@ public class AAPSMocker { when(TreatmentsPlugin.getPlugin()).thenReturn(treatmentsPlugin); when(treatmentsPlugin.getLastCalculationTreatments()).thenReturn(new IobTotal(0)); when(treatmentsPlugin.getLastCalculationTempBasals()).thenReturn(new IobTotal(0)); + + TreatmentService treatmentService = PowerMockito.mock(TreatmentService.class); + when(treatmentsPlugin.getService()).thenReturn(treatmentService); return treatmentsPlugin; } @@ -204,6 +210,7 @@ public class AAPSMocker { PowerMockito.whenNew(TreatmentService.class).withNoArguments().thenReturn(treatmentService); } catch (Exception e) { } + } public static DanaRPlugin mockDanaRPlugin() { diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java index 6a96acfb6d..99a4e6c30a 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java +++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java @@ -57,9 +57,9 @@ public class SmsCommunicatorPluginTest { @Test public void processSettingsTest() { // called from constructor - Assert.assertEquals(smsCommunicatorPlugin.allowedNumbers.get(0), "1234"); - Assert.assertEquals(smsCommunicatorPlugin.allowedNumbers.get(1), "5678"); - Assert.assertEquals(smsCommunicatorPlugin.allowedNumbers.size(), 2); + Assert.assertEquals("1234", smsCommunicatorPlugin.allowedNumbers.get(0)); + Assert.assertEquals("5678", smsCommunicatorPlugin.allowedNumbers.get(1)); + Assert.assertEquals(2, smsCommunicatorPlugin.allowedNumbers.size()); } @Test @@ -76,20 +76,20 @@ public class SmsCommunicatorPluginTest { sms = new Sms("12", "aText"); smsCommunicatorPlugin.processSms(sms); Assert.assertTrue(sms.ignored); - Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "aText"); + Assert.assertEquals("aText", smsCommunicatorPlugin.messages.get(0).text); //UNKNOWN smsCommunicatorPlugin.messages = new ArrayList<>(); sms = new Sms("1234", "UNKNOWN"); smsCommunicatorPlugin.processSms(sms); - Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "UNKNOWN"); - Assert.assertEquals(smsCommunicatorPlugin.messages.get(1).text, "Uknown command or wrong reply"); + Assert.assertEquals("UNKNOWN", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Uknown command or wrong reply", smsCommunicatorPlugin.messages.get(1).text); //BG smsCommunicatorPlugin.messages = new ArrayList<>(); sms = new Sms("1234", "BG"); smsCommunicatorPlugin.processSms(sms); - Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "BG"); + Assert.assertEquals("BG", smsCommunicatorPlugin.messages.get(0).text); Assert.assertTrue(smsCommunicatorPlugin.messages.get(1).text.contains("IOB:")); Assert.assertTrue(smsCommunicatorPlugin.messages.get(1).text.contains("Last BG: 100")); @@ -99,7 +99,7 @@ public class SmsCommunicatorPluginTest { sms = new Sms("1234", "LOOP STATUS"); smsCommunicatorPlugin.processSms(sms); Assert.assertFalse(sms.ignored); - Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "LOOP STATUS"); + Assert.assertEquals("LOOP STATUS", smsCommunicatorPlugin.messages.get(0).text); Assert.assertTrue(smsCommunicatorPlugin.messages.get(1).text.contains("Remote command is not allowed")); when(SP.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)).thenReturn(true); @@ -108,8 +108,8 @@ public class SmsCommunicatorPluginTest { smsCommunicatorPlugin.messages = new ArrayList<>(); sms = new Sms("1234", "LOOP STATUS"); smsCommunicatorPlugin.processSms(sms); - Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "LOOP STATUS"); - Assert.assertEquals(smsCommunicatorPlugin.messages.get(1).text, "Loop is disabled"); + Assert.assertEquals("LOOP STATUS", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Loop is disabled", smsCommunicatorPlugin.messages.get(1).text); //LOOP STATUS : suspended when(loopPlugin.minutesToEndOfSuspend()).thenReturn(10); @@ -118,8 +118,8 @@ public class SmsCommunicatorPluginTest { smsCommunicatorPlugin.messages = new ArrayList<>(); sms = new Sms("1234", "LOOP STATUS"); smsCommunicatorPlugin.processSms(sms); - Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "LOOP STATUS"); - Assert.assertEquals(smsCommunicatorPlugin.messages.get(1).text, "Suspended (10 m)"); + Assert.assertEquals("LOOP STATUS", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Suspended (10 m)", smsCommunicatorPlugin.messages.get(1).text); //LOOP STATUS : enabled when(loopPlugin.isEnabled(PluginType.LOOP)).thenReturn(true); @@ -128,8 +128,8 @@ public class SmsCommunicatorPluginTest { sms = new Sms("1234", "LOOP STATUS"); smsCommunicatorPlugin.processSms(sms); Assert.assertFalse(sms.ignored); - Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "LOOP STATUS"); - Assert.assertEquals(smsCommunicatorPlugin.messages.get(1).text, "Loop is enabled"); + Assert.assertEquals("LOOP STATUS", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Loop is enabled", smsCommunicatorPlugin.messages.get(1).text); //LOOP : wrong format when(loopPlugin.isEnabled(PluginType.LOOP)).thenReturn(true); @@ -137,8 +137,8 @@ public class SmsCommunicatorPluginTest { sms = new Sms("1234", "LOOP"); smsCommunicatorPlugin.processSms(sms); Assert.assertFalse(sms.ignored); - Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "LOOP"); - Assert.assertEquals(smsCommunicatorPlugin.messages.get(1).text, "Wrong format"); + Assert.assertEquals("LOOP", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Wrong format", smsCommunicatorPlugin.messages.get(1).text); //LOOP DISABLE : already disabled when(loopPlugin.isEnabled(PluginType.LOOP)).thenReturn(false); @@ -146,8 +146,8 @@ public class SmsCommunicatorPluginTest { sms = new Sms("1234", "LOOP DISABLE"); smsCommunicatorPlugin.processSms(sms); Assert.assertFalse(sms.ignored); - Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "LOOP DISABLE"); - Assert.assertEquals(smsCommunicatorPlugin.messages.get(1).text, "Loop is disabled"); + Assert.assertEquals("LOOP DISABLE", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Loop is disabled", smsCommunicatorPlugin.messages.get(1).text); //LOOP DISABLE : from enabled hasBeenRun = false; @@ -160,8 +160,8 @@ public class SmsCommunicatorPluginTest { sms = new Sms("1234", "LOOP DISABLE"); smsCommunicatorPlugin.processSms(sms); Assert.assertFalse(sms.ignored); - Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "LOOP DISABLE"); - Assert.assertEquals(smsCommunicatorPlugin.messages.get(1).text, "Loop has been disabled Temp basal canceled"); + Assert.assertEquals("LOOP DISABLE", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Loop has been disabled Temp basal canceled", smsCommunicatorPlugin.messages.get(1).text); Assert.assertTrue(hasBeenRun); //LOOP ENABLE : already enabled @@ -170,8 +170,8 @@ public class SmsCommunicatorPluginTest { sms = new Sms("1234", "LOOP ENABLE"); smsCommunicatorPlugin.processSms(sms); Assert.assertFalse(sms.ignored); - Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "LOOP ENABLE"); - Assert.assertEquals(smsCommunicatorPlugin.messages.get(1).text, "Loop is enabled"); + Assert.assertEquals("LOOP ENABLE", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Loop is enabled", smsCommunicatorPlugin.messages.get(1).text); //LOOP ENABLE : from disabled hasBeenRun = false; @@ -184,8 +184,8 @@ public class SmsCommunicatorPluginTest { sms = new Sms("1234", "LOOP ENABLE"); smsCommunicatorPlugin.processSms(sms); Assert.assertFalse(sms.ignored); - Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "LOOP ENABLE"); - Assert.assertEquals(smsCommunicatorPlugin.messages.get(1).text, "Loop has been enabled"); + Assert.assertEquals("LOOP ENABLE", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Loop has been enabled", smsCommunicatorPlugin.messages.get(1).text); Assert.assertTrue(hasBeenRun); //LOOP RESUME : already enabled @@ -193,48 +193,120 @@ public class SmsCommunicatorPluginTest { sms = new Sms("1234", "LOOP RESUME"); smsCommunicatorPlugin.processSms(sms); Assert.assertFalse(sms.ignored); - Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "LOOP RESUME"); - Assert.assertEquals(smsCommunicatorPlugin.messages.get(1).text, "Loop resumed"); + Assert.assertEquals("LOOP RESUME", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Loop resumed", smsCommunicatorPlugin.messages.get(1).text); //LOOP SUSPEND 1 2: wrong format smsCommunicatorPlugin.messages = new ArrayList<>(); sms = new Sms("1234", "LOOP SUSPEND 1 2"); smsCommunicatorPlugin.processSms(sms); Assert.assertFalse(sms.ignored); - Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "LOOP SUSPEND 1 2"); - Assert.assertEquals(smsCommunicatorPlugin.messages.get(1).text, "Wrong format"); + Assert.assertEquals("LOOP SUSPEND 1 2", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Wrong format", smsCommunicatorPlugin.messages.get(1).text); //LOOP SUSPEND 0 : wrong duration smsCommunicatorPlugin.messages = new ArrayList<>(); sms = new Sms("1234", "LOOP SUSPEND 0"); smsCommunicatorPlugin.processSms(sms); Assert.assertFalse(sms.ignored); - Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "LOOP SUSPEND 0"); - Assert.assertEquals(smsCommunicatorPlugin.messages.get(1).text, "Wrong duration"); + Assert.assertEquals("LOOP SUSPEND 0", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Wrong duration", smsCommunicatorPlugin.messages.get(1).text); - //LOOP SUSPEND 100 : suspend for 100 min + //LOOP SUSPEND 100 : suspend for 100 min + correct answer smsCommunicatorPlugin.messages = new ArrayList<>(); sms = new Sms("1234", "LOOP SUSPEND 100"); smsCommunicatorPlugin.processSms(sms); Assert.assertFalse(sms.ignored); - Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "LOOP SUSPEND 100"); + Assert.assertEquals("LOOP SUSPEND 100", smsCommunicatorPlugin.messages.get(0).text); Assert.assertTrue(smsCommunicatorPlugin.messages.get(1).text.contains("To suspend loop for 100 minutes reply with code ")); + String passCode = smsCommunicatorPlugin.messageToConfirm.confirmCode; + smsCommunicatorPlugin.processSms(new Sms("1234", passCode)); + Assert.assertEquals(passCode, smsCommunicatorPlugin.messages.get(2).text); + Assert.assertEquals("Loop suspended Temp basal canceled", smsCommunicatorPlugin.messages.get(3).text); - //LOOP SUSPEND 200 : limit to 180 min + //LOOP SUSPEND 200 : limit to 180 min + wrong answer smsCommunicatorPlugin.messages = new ArrayList<>(); sms = new Sms("1234", "LOOP SUSPEND 200"); smsCommunicatorPlugin.processSms(sms); Assert.assertFalse(sms.ignored); - Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "LOOP SUSPEND 200"); + Assert.assertEquals("LOOP SUSPEND 200", smsCommunicatorPlugin.messages.get(0).text); Assert.assertTrue(smsCommunicatorPlugin.messages.get(1).text.contains("To suspend loop for 180 minutes reply with code ")); + passCode = smsCommunicatorPlugin.messageToConfirm.confirmCode; + smsCommunicatorPlugin.processSms(new Sms("1234", "XXXX")); + Assert.assertEquals("XXXX", smsCommunicatorPlugin.messages.get(2).text); + Assert.assertEquals("Wrong code. Command cancelled.", smsCommunicatorPlugin.messages.get(3).text); + //then correct code should not work + smsCommunicatorPlugin.processSms(new Sms("1234", passCode)); + Assert.assertEquals(passCode, smsCommunicatorPlugin.messages.get(4).text); + Assert.assertEquals("Uknown command or wrong reply", smsCommunicatorPlugin.messages.get(5).text); //LOOP BLABLA smsCommunicatorPlugin.messages = new ArrayList<>(); sms = new Sms("1234", "LOOP BLABLA"); smsCommunicatorPlugin.processSms(sms); Assert.assertFalse(sms.ignored); - Assert.assertEquals(smsCommunicatorPlugin.messages.get(0).text, "LOOP BLABLA"); - Assert.assertEquals(smsCommunicatorPlugin.messages.get(1).text, "Wrong format"); + Assert.assertEquals("LOOP BLABLA", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Wrong format", smsCommunicatorPlugin.messages.get(1).text); + + //TREATMENTS REFRESH + when(loopPlugin.isEnabled(PluginType.LOOP)).thenReturn(true); + when(loopPlugin.isSuspended()).thenReturn(false); + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "TREATMENTS REFRESH"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertFalse(sms.ignored); + Assert.assertEquals("TREATMENTS REFRESH", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertTrue(smsCommunicatorPlugin.messages.get(1).text.contains("TREATMENTS REFRESH")); + + //TREATMENTS BLA BLA + when(loopPlugin.isEnabled(PluginType.LOOP)).thenReturn(true); + when(loopPlugin.isSuspended()).thenReturn(false); + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "TREATMENTS BLA BLA"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertFalse(sms.ignored); + Assert.assertEquals("TREATMENTS BLA BLA", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Wrong format", smsCommunicatorPlugin.messages.get(1).text); + + //TREATMENTS BLABLA + when(loopPlugin.isEnabled(PluginType.LOOP)).thenReturn(true); + when(loopPlugin.isSuspended()).thenReturn(false); + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "TREATMENTS BLABLA"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertFalse(sms.ignored); + Assert.assertEquals("TREATMENTS BLABLA", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Wrong format", smsCommunicatorPlugin.messages.get(1).text); + + //NSCLIENT RESTART + when(loopPlugin.isEnabled(PluginType.LOOP)).thenReturn(true); + when(loopPlugin.isSuspended()).thenReturn(false); + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "NSCLIENT RESTART"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertFalse(sms.ignored); + Assert.assertEquals("NSCLIENT RESTART", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertTrue(smsCommunicatorPlugin.messages.get(1).text.contains("NSCLIENT RESTART")); + + //NSCLIENT BLA BLA + when(loopPlugin.isEnabled(PluginType.LOOP)).thenReturn(true); + when(loopPlugin.isSuspended()).thenReturn(false); + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "NSCLIENT BLA BLA"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertFalse(sms.ignored); + Assert.assertEquals("NSCLIENT BLA BLA", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Wrong format", smsCommunicatorPlugin.messages.get(1).text); + + //NSCLIENT BLABLA + when(loopPlugin.isEnabled(PluginType.LOOP)).thenReturn(true); + when(loopPlugin.isSuspended()).thenReturn(false); + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "NSCLIENT BLABLA"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertFalse(sms.ignored); + Assert.assertEquals("NSCLIENT BLABLA", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Wrong format", smsCommunicatorPlugin.messages.get(1).text); } @@ -248,6 +320,7 @@ public class SmsCommunicatorPluginTest { AAPSMocker.mockBus(); AAPSMocker.mockProfileFunctions(); AAPSMocker.mockTreatmentPlugin(); + AAPSMocker.mockTreatmentService(); AAPSMocker.mockIobCobCalculatorPlugin(); AAPSMocker.mockConfigBuilder(); AAPSMocker.mockCommandQueue(); @@ -265,7 +338,7 @@ public class SmsCommunicatorPluginTest { when(SmsManager.getDefault()).thenReturn(smsManager); when(SP.getString(R.string.key_smscommunicator_allowednumbers, "")).thenReturn("1234;5678"); - smsCommunicatorPlugin = new SmsCommunicatorPlugin(); + smsCommunicatorPlugin = SmsCommunicatorPlugin.getPlugin(); smsCommunicatorPlugin.setPluginEnabled(PluginType.GENERAL, true); loopPlugin = mock(LoopPlugin.class); From 546f99f4714bc4508738cc285474ac1d6577baad Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Wed, 13 Mar 2019 23:30:41 +0100 Subject: [PATCH 28/39] SmsCommunicatorPluginTest 6 --- .../smsCommunicator/SmsCommunicatorPlugin.java | 2 +- .../SmsCommunicatorPluginTest.java | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java index 5159b73946..121a4d5ad7 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java @@ -411,7 +411,7 @@ public class SmsCommunicatorPlugin extends PluginBase { if (result.success) { if (pump != null) { String reply = pump.shortStatus(true); - sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); + sendSMS(new Sms(receivedSms.phoneNumber, reply)); } } else { String reply = MainApp.gs(R.string.readstatusfailed); diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java index 99a4e6c30a..e8ab991d2a 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java +++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java @@ -27,6 +27,7 @@ import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.general.nsclient.NSUpload; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin; +import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin; import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin; import info.nightscout.androidaps.queue.Callback; import info.nightscout.androidaps.queue.CommandQueue; @@ -35,6 +36,7 @@ import info.nightscout.androidaps.utils.SP; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyString; import static org.powermock.api.mockito.PowerMockito.doAnswer; import static org.powermock.api.mockito.PowerMockito.mock; import static org.powermock.api.mockito.PowerMockito.mockStatic; @@ -308,6 +310,13 @@ public class SmsCommunicatorPluginTest { Assert.assertEquals("NSCLIENT BLABLA", smsCommunicatorPlugin.messages.get(0).text); Assert.assertEquals("Wrong format", smsCommunicatorPlugin.messages.get(1).text); + //PUMP + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "PUMP"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals("PUMP", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Virtual Pump", smsCommunicatorPlugin.messages.get(1).text); + } @Before @@ -351,6 +360,15 @@ public class SmsCommunicatorPluginTest { return null; }).when(AAPSMocker.queue).cancelTempBasal(anyBoolean(), any(Callback.class)); + Mockito.doAnswer((Answer) invocation -> { + Callback callback = invocation.getArgument(1); + callback.result = new PumpEnactResult().success(true); + callback.run(); + return null; + }).when(AAPSMocker.queue).readStatus(anyString(), any(Callback.class)); + + VirtualPumpPlugin virtualPumpPlugin = VirtualPumpPlugin.getPlugin(); + when(ConfigBuilderPlugin.getPlugin().getActivePump()).thenReturn(virtualPumpPlugin); } } From 98eb3a1d7307eb52cb7b3986149cc9e01d6254a3 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Wed, 20 Mar 2019 22:12:25 +0100 Subject: [PATCH 29/39] SmsCommunicatorPluginTest 7 --- app/src/test/java/info/AAPSMocker.java | 4 + .../SmsCommunicatorPluginTest.java | 99 ++++++++++++++++++- 2 files changed, 102 insertions(+), 1 deletion(-) diff --git a/app/src/test/java/info/AAPSMocker.java b/app/src/test/java/info/AAPSMocker.java index 906dc53ca5..9bbd7d7b86 100644 --- a/app/src/test/java/info/AAPSMocker.java +++ b/app/src/test/java/info/AAPSMocker.java @@ -129,6 +129,9 @@ public class AAPSMocker { when(MainApp.gs(R.string.smscommunicator_suspendreplywithcode)).thenReturn("To suspend loop for %1$d minutes reply with code %2$s"); when(MainApp.gs(R.string.smscommunicator_loopsuspended)).thenReturn("Loop suspended"); when(MainApp.gs(R.string.smscommunicator_unknowncommand)).thenReturn("Uknown command or wrong reply"); + when(MainApp.gs(R.string.notconfigured)).thenReturn("Not configured"); + when(MainApp.gs(R.string.smscommunicator_profilereplywithcode)).thenReturn("To switch profile to %1$s %2$d%% reply with code %3$s"); + when(MainApp.gs(R.string.profileswitchcreated)).thenReturn("Profile switch created"); } public static MainApp mockMainApp() { @@ -258,6 +261,7 @@ public class AAPSMocker { profile = getValidProfile(); PowerMockito.when(ProfileFunctions.getInstance().getProfile()).thenReturn(profile); PowerMockito.when(ProfileFunctions.getInstance().getProfileUnits()).thenReturn(Constants.MGDL); + PowerMockito.when(ProfileFunctions.getInstance().getProfileName()).thenReturn(TESTPROFILENAME); } public static void mockIobCobCalculatorPlugin() { diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java index e8ab991d2a..a781e3944f 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java +++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java @@ -21,12 +21,14 @@ import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.db.BgReading; import info.nightscout.androidaps.interfaces.PluginType; +import info.nightscout.androidaps.interfaces.ProfileInterface; import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin; import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.general.nsclient.NSUpload; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin; +import info.nightscout.androidaps.plugins.profile.simple.SimpleProfilePlugin; import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin; import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin; import info.nightscout.androidaps.queue.Callback; @@ -46,7 +48,8 @@ import static org.powermock.api.mockito.PowerMockito.when; @PrepareForTest({ L.class, SP.class, MainApp.class, DateUtil.class, ProfileFunctions.class, TreatmentsPlugin.class, SmsManager.class, IobCobCalculatorPlugin.class, - CommandQueue.class, ConfigBuilderPlugin.class, NSUpload.class + CommandQueue.class, ConfigBuilderPlugin.class, NSUpload.class, ProfileInterface.class, + SimpleProfilePlugin.class }) public class SmsCommunicatorPluginTest { @@ -319,6 +322,100 @@ public class SmsCommunicatorPluginTest { } + @Test + public void processProfileTest() { + Sms sms; + + //PROFILE + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "PROFILE"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals("PROFILE", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Remote command is not allowed", smsCommunicatorPlugin.messages.get(1).text); + + when(SP.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)).thenReturn(true); + + //PROFILE + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "PROFILE"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals("PROFILE", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Wrong format", smsCommunicatorPlugin.messages.get(1).text); + + //PROFILE LIST (no profile interface) + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "PROFILE LIST"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals("PROFILE LIST", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Not configured", smsCommunicatorPlugin.messages.get(1).text); + + ProfileInterface profileInterface = mock(SimpleProfilePlugin.class); + when(ConfigBuilderPlugin.getPlugin().getActiveProfileInterface()).thenReturn(profileInterface); + + //PROFILE LIST (no profile defined) + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "PROFILE LIST"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals("PROFILE LIST", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Not configured", smsCommunicatorPlugin.messages.get(1).text); + + when(profileInterface.getProfile()).thenReturn(AAPSMocker.getValidProfileStore()); + + //PROFILE STATUS + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "PROFILE STATUS"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals("PROFILE STATUS", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals(AAPSMocker.TESTPROFILENAME, smsCommunicatorPlugin.messages.get(1).text); + + //PROFILE LIST + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "PROFILE LIST"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals("PROFILE LIST", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("1. " + AAPSMocker.TESTPROFILENAME, smsCommunicatorPlugin.messages.get(1).text); + + //PROFILE 2 (non existing) + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "PROFILE 2"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals("PROFILE 2", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Wrong format", smsCommunicatorPlugin.messages.get(1).text); + + //PROFILE 1 0(wrong percentage) + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "PROFILE 1 0"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals("PROFILE 1 0", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Wrong format", smsCommunicatorPlugin.messages.get(1).text); + + //PROFILE 0(wrong index) + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "PROFILE 0"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals("PROFILE 0", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Wrong format", smsCommunicatorPlugin.messages.get(1).text); + + //PROFILE 1(OK) + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "PROFILE 1"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals("PROFILE 1", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertTrue(smsCommunicatorPlugin.messages.get(1).text.contains("To switch profile to someProfile 100% reply with code")); + + //PROFILE 1 90(OK) + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "PROFILE 1 90"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals("PROFILE 1 90", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertTrue(smsCommunicatorPlugin.messages.get(1).text.contains("To switch profile to someProfile 90% reply with code")); + String passCode = smsCommunicatorPlugin.messageToConfirm.confirmCode; + smsCommunicatorPlugin.processSms(new Sms("1234", passCode)); + Assert.assertEquals(passCode, smsCommunicatorPlugin.messages.get(2).text); + Assert.assertEquals("Profile switch created", smsCommunicatorPlugin.messages.get(3).text); + + } + @Before public void prepareTests() { AAPSMocker.mockMainApp(); From a37d04a8d912675d95384840f9dfef1ce7862c54 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Wed, 20 Mar 2019 22:49:35 +0100 Subject: [PATCH 30/39] SmsCommunicatorPluginTest 8 --- app/src/main/res/values/strings.xml | 6 +- app/src/test/java/info/AAPSMocker.java | 5 + .../SmsCommunicatorPluginTest.java | 108 +++++++++++++++++- 3 files changed, 114 insertions(+), 5 deletions(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0ddc68865a..def8df3adb 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -374,11 +374,11 @@ To suspend loop for %1$d minutes reply with code %2$s Temp basal %1$.2fU/h for %2$d min started successfully Extended bolus %1$.2fU for %2$d min started successfully - Temp basal %1$d %% for %2$d min started successfully + Temp basal %1$d%% for %2$d min started successfully Temp basal start failed Extended bolus start failed - To stop temp basal reply with code %s - To stop extended bolus reply with code %s + To stop temp basal reply with code %1$s + To stop extended bolus reply with code %1$s Temp basal canceled Extended bolus canceled Canceling temp basal failed diff --git a/app/src/test/java/info/AAPSMocker.java b/app/src/test/java/info/AAPSMocker.java index 9bbd7d7b86..e17cb522b7 100644 --- a/app/src/test/java/info/AAPSMocker.java +++ b/app/src/test/java/info/AAPSMocker.java @@ -132,6 +132,11 @@ public class AAPSMocker { when(MainApp.gs(R.string.notconfigured)).thenReturn("Not configured"); when(MainApp.gs(R.string.smscommunicator_profilereplywithcode)).thenReturn("To switch profile to %1$s %2$d%% reply with code %3$s"); when(MainApp.gs(R.string.profileswitchcreated)).thenReturn("Profile switch created"); + when(MainApp.gs(R.string.smscommunicator_basalstopreplywithcode)).thenReturn("To stop temp basal reply with code %1$s"); + when(MainApp.gs(R.string.smscommunicator_basalpctreplywithcode)).thenReturn("To start basal %1$d%% reply with code %2$s"); + when(MainApp.gs(R.string.smscommunicator_tempbasalset_percent)).thenReturn("Temp basal %1$d%% for %2$d min started successfully"); + when(MainApp.gs(R.string.smscommunicator_basalreplywithcode)).thenReturn("To start basal %1$.2fU/h reply with code %2$s"); + when(MainApp.gs(R.string.smscommunicator_tempbasalset)).thenReturn("Temp basal %1$.2fU/h for %2$d min started successfully"); } public static MainApp mockMainApp() { diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java index a781e3944f..d5e4e048b2 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java +++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java @@ -20,6 +20,7 @@ import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.db.BgReading; +import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.ProfileInterface; import info.nightscout.androidaps.logging.L; @@ -38,6 +39,8 @@ import info.nightscout.androidaps.utils.SP; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyDouble; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.powermock.api.mockito.PowerMockito.doAnswer; import static org.powermock.api.mockito.PowerMockito.mock; @@ -413,6 +416,92 @@ public class SmsCommunicatorPluginTest { smsCommunicatorPlugin.processSms(new Sms("1234", passCode)); Assert.assertEquals(passCode, smsCommunicatorPlugin.messages.get(2).text); Assert.assertEquals("Profile switch created", smsCommunicatorPlugin.messages.get(3).text); + } + + @Test + public void processBasalTest() { + Sms sms; + + //BASAL + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "BASAL"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals("BASAL", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Remote command is not allowed", smsCommunicatorPlugin.messages.get(1).text); + + when(SP.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)).thenReturn(true); + + //BASAL + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "BASAL"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals("BASAL", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Wrong format", smsCommunicatorPlugin.messages.get(1).text); + + //BASAL CANCEL + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "BASAL CANCEL"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals("BASAL CANCEL", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertTrue(smsCommunicatorPlugin.messages.get(1).text.contains("To stop temp basal reply with code")); + String passCode = smsCommunicatorPlugin.messageToConfirm.confirmCode; + smsCommunicatorPlugin.processSms(new Sms("1234", passCode)); + Assert.assertEquals(passCode, smsCommunicatorPlugin.messages.get(2).text); + Assert.assertEquals("Temp basal canceled\nVirtual Pump", smsCommunicatorPlugin.messages.get(3).text); + + //BASAL a% + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "BASAL a%"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals("BASAL a%", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Wrong format", smsCommunicatorPlugin.messages.get(1).text); + + //BASAL 10% 0 + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "BASAL 10% 0"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals("BASAL 10% 0", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Wrong format", smsCommunicatorPlugin.messages.get(1).text); + + when(MainApp.getConstraintChecker().applyBasalPercentConstraints(any(), any())).thenReturn(new Constraint<>(20)); + + //BASAL 20% 20 + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "BASAL 20% 20"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals("BASAL 20% 20", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertTrue(smsCommunicatorPlugin.messages.get(1).text.contains("To start basal 20% reply with code")); + passCode = smsCommunicatorPlugin.messageToConfirm.confirmCode; + smsCommunicatorPlugin.processSms(new Sms("1234", passCode)); + Assert.assertEquals(passCode, smsCommunicatorPlugin.messages.get(2).text); + Assert.assertEquals("Temp basal 20% for 20 min started successfully\nVirtual Pump", smsCommunicatorPlugin.messages.get(3).text); + + //BASAL a + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "BASAL a"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals("BASAL a", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Wrong format", smsCommunicatorPlugin.messages.get(1).text); + + //BASAL 1 0 + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "BASAL 1 0"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals("BASAL 1 0", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Wrong format", smsCommunicatorPlugin.messages.get(1).text); + + when(MainApp.getConstraintChecker().applyBasalConstraints(any(), any())).thenReturn(new Constraint<>(1d)); + + //BASAL 1 20 + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "BASAL 1 20"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals("BASAL 1 20", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertTrue(smsCommunicatorPlugin.messages.get(1).text.contains("To start basal 1.00U/h reply with code")); + passCode = smsCommunicatorPlugin.messageToConfirm.confirmCode; + smsCommunicatorPlugin.processSms(new Sms("1234", passCode)); + Assert.assertEquals(passCode, smsCommunicatorPlugin.messages.get(2).text); + Assert.assertEquals("Temp basal 1.00U/h for 20 min started successfully\nVirtual Pump", smsCommunicatorPlugin.messages.get(3).text); } @@ -431,6 +520,7 @@ public class SmsCommunicatorPluginTest { AAPSMocker.mockConfigBuilder(); AAPSMocker.mockCommandQueue(); AAPSMocker.mockNSUpload(); + AAPSMocker.mockConstraintsChecker(); BgReading reading = new BgReading(); reading.value = 100; @@ -450,20 +540,34 @@ public class SmsCommunicatorPluginTest { loopPlugin = mock(LoopPlugin.class); when(MainApp.getSpecificPlugin(LoopPlugin.class)).thenReturn(loopPlugin); - Mockito.doAnswer((Answer) invocation -> { + Mockito.doAnswer(invocation -> { Callback callback = invocation.getArgument(1); callback.result = new PumpEnactResult().success(true); callback.run(); return null; }).when(AAPSMocker.queue).cancelTempBasal(anyBoolean(), any(Callback.class)); - Mockito.doAnswer((Answer) invocation -> { + Mockito.doAnswer(invocation -> { Callback callback = invocation.getArgument(1); callback.result = new PumpEnactResult().success(true); callback.run(); return null; }).when(AAPSMocker.queue).readStatus(anyString(), any(Callback.class)); + Mockito.doAnswer(invocation -> { + Callback callback = invocation.getArgument(4); + callback.result = new PumpEnactResult().success(true).isPercent(true).percent(invocation.getArgument(0)).duration(invocation.getArgument(1)); + callback.run(); + return null; + }).when(AAPSMocker.queue).tempBasalPercent(anyInt(), anyInt(), anyBoolean(), any(), any(Callback.class)); + + Mockito.doAnswer(invocation -> { + Callback callback = invocation.getArgument(4); + callback.result = new PumpEnactResult().success(true).isPercent(false).absolute(invocation.getArgument(0)).duration(invocation.getArgument(1)); + callback.run(); + return null; + }).when(AAPSMocker.queue).tempBasalAbsolute(anyDouble(), anyInt(), anyBoolean(), any(), any(Callback.class)); + VirtualPumpPlugin virtualPumpPlugin = VirtualPumpPlugin.getPlugin(); when(ConfigBuilderPlugin.getPlugin().getActivePump()).thenReturn(virtualPumpPlugin); } From 30bfa1ca1f377d4fe900b55855c4f18f9e21f382 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Wed, 20 Mar 2019 23:12:07 +0100 Subject: [PATCH 31/39] SmsCommunicatorPluginTest 9 --- .../SmsCommunicatorPlugin.java | 4 +- app/src/test/java/info/AAPSMocker.java | 4 + .../SmsCommunicatorPluginTest.java | 74 +++++++++++++++++++ 3 files changed, 81 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java index 121a4d5ad7..e1c097c112 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java @@ -203,7 +203,7 @@ public class SmsCommunicatorPlugin extends PluginBase { case "EXTENDED": if (!remoteCommandsAllowed) sendSMS(new Sms(receivedSms.phoneNumber, R.string.smscommunicator_remotecommandnotallowed)); - else if (splitted.length == 3) + else if (splitted.length == 2 || splitted.length == 3) processEXTENDED(splitted, receivedSms); else sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat)); @@ -622,6 +622,8 @@ public class SmsCommunicatorPlugin extends PluginBase { }); } }); + } else if (splitted.length != 3) { + sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat)); } else { Double extended = SafeParse.stringToDouble(splitted[1]); int duration = SafeParse.stringToInt(splitted[2]); diff --git a/app/src/test/java/info/AAPSMocker.java b/app/src/test/java/info/AAPSMocker.java index e17cb522b7..d6bf6940a3 100644 --- a/app/src/test/java/info/AAPSMocker.java +++ b/app/src/test/java/info/AAPSMocker.java @@ -137,6 +137,10 @@ public class AAPSMocker { when(MainApp.gs(R.string.smscommunicator_tempbasalset_percent)).thenReturn("Temp basal %1$d%% for %2$d min started successfully"); when(MainApp.gs(R.string.smscommunicator_basalreplywithcode)).thenReturn("To start basal %1$.2fU/h reply with code %2$s"); when(MainApp.gs(R.string.smscommunicator_tempbasalset)).thenReturn("Temp basal %1$.2fU/h for %2$d min started successfully"); + when(MainApp.gs(R.string.smscommunicator_extendedstopreplywithcode)).thenReturn("To stop extended bolus reply with code %1$s"); + when(MainApp.gs(R.string.smscommunicator_extendedcanceled)).thenReturn("Extended bolus canceled"); + when(MainApp.gs(R.string.smscommunicator_extendedreplywithcode)).thenReturn("To start extended bolus %1$.2fU for %2$d min reply with code %3$s"); + when(MainApp.gs(R.string.smscommunicator_extendedset)).thenReturn("Extended bolus %1$.2fU for %2$d min started successfully"); } public static MainApp mockMainApp() { diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java index d5e4e048b2..b88dd1e94b 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java +++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java @@ -505,6 +505,66 @@ public class SmsCommunicatorPluginTest { } + @Test + public void processExtendedTest() { + Sms sms; + + //EXTENDED + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "EXTENDED"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals("EXTENDED", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Remote command is not allowed", smsCommunicatorPlugin.messages.get(1).text); + + when(SP.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)).thenReturn(true); + + //EXTENDED + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "EXTENDED"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals("EXTENDED", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Wrong format", smsCommunicatorPlugin.messages.get(1).text); + + //EXTENDED CANCEL + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "EXTENDED CANCEL"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals("EXTENDED CANCEL", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertTrue(smsCommunicatorPlugin.messages.get(1).text.contains("To stop extended bolus reply with code")); + String passCode = smsCommunicatorPlugin.messageToConfirm.confirmCode; + smsCommunicatorPlugin.processSms(new Sms("1234", passCode)); + Assert.assertEquals(passCode, smsCommunicatorPlugin.messages.get(2).text); + Assert.assertEquals("Extended bolus canceled\nVirtual Pump", smsCommunicatorPlugin.messages.get(3).text); + + //EXTENDED a% + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "EXTENDED a%"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals("EXTENDED a%", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Wrong format", smsCommunicatorPlugin.messages.get(1).text); + + when(MainApp.getConstraintChecker().applyExtendedBolusConstraints(any())).thenReturn(new Constraint<>(1d)); + + //EXTENDED 1 0 + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "EXTENDED 1 0"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals("EXTENDED 1 0", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Wrong format", smsCommunicatorPlugin.messages.get(1).text); + + //EXTENDED 1 20 + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "EXTENDED 1 20"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals("EXTENDED 1 20", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertTrue(smsCommunicatorPlugin.messages.get(1).text.contains("To start extended bolus 1.00U for 20 min reply with code")); + passCode = smsCommunicatorPlugin.messageToConfirm.confirmCode; + smsCommunicatorPlugin.processSms(new Sms("1234", passCode)); + Assert.assertEquals(passCode, smsCommunicatorPlugin.messages.get(2).text); + Assert.assertEquals("Extended bolus 1.00U for 20 min started successfully\nVirtual Pump", smsCommunicatorPlugin.messages.get(3).text); + + } + @Before public void prepareTests() { AAPSMocker.mockMainApp(); @@ -547,6 +607,13 @@ public class SmsCommunicatorPluginTest { return null; }).when(AAPSMocker.queue).cancelTempBasal(anyBoolean(), any(Callback.class)); + Mockito.doAnswer(invocation -> { + Callback callback = invocation.getArgument(0); + callback.result = new PumpEnactResult().success(true); + callback.run(); + return null; + }).when(AAPSMocker.queue).cancelExtended(any(Callback.class)); + Mockito.doAnswer(invocation -> { Callback callback = invocation.getArgument(1); callback.result = new PumpEnactResult().success(true); @@ -568,6 +635,13 @@ public class SmsCommunicatorPluginTest { return null; }).when(AAPSMocker.queue).tempBasalAbsolute(anyDouble(), anyInt(), anyBoolean(), any(), any(Callback.class)); + Mockito.doAnswer(invocation -> { + Callback callback = invocation.getArgument(2); + callback.result = new PumpEnactResult().success(true).isPercent(false).absolute(invocation.getArgument(0)).duration(invocation.getArgument(1)); + callback.run(); + return null; + }).when(AAPSMocker.queue).extendedBolus(anyDouble(), anyInt(), any(Callback.class)); + VirtualPumpPlugin virtualPumpPlugin = VirtualPumpPlugin.getPlugin(); when(ConfigBuilderPlugin.getPlugin().getActivePump()).thenReturn(virtualPumpPlugin); } From a9992503f6b0fe8c06e5247b9d6216d20eeb383e Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Thu, 21 Mar 2019 21:00:42 +0100 Subject: [PATCH 32/39] SmsCommunicatorPluginTest 10 --- .../SmsCommunicatorPlugin.java | 9 +- app/src/main/res/values/strings.xml | 8 +- app/src/test/java/info/AAPSMocker.java | 6 + .../SmsCommunicatorPluginTest.java | 136 +++++++++++++++++- 4 files changed, 146 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java index e1c097c112..b58022c2e9 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java @@ -14,7 +14,6 @@ import org.slf4j.LoggerFactory; import java.text.Normalizer; import java.util.ArrayList; -import java.util.Date; import java.util.List; import info.nightscout.androidaps.Constants; @@ -73,7 +72,7 @@ public class SmsCommunicatorPlugin extends PluginBase { AuthRequest messageToConfirm = null; - private Date lastRemoteBolusTime = new Date(0); + long lastRemoteBolusTime = 0; ArrayList messages = new ArrayList<>(); @@ -211,9 +210,9 @@ public class SmsCommunicatorPlugin extends PluginBase { case "BOLUS": if (!remoteCommandsAllowed) sendSMS(new Sms(receivedSms.phoneNumber, R.string.smscommunicator_remotecommandnotallowed)); - else if (DateUtil.now() - lastRemoteBolusTime.getTime() < Constants.remoteBolusMinDistance) + else if (splitted.length == 2 && DateUtil.now() - lastRemoteBolusTime < Constants.remoteBolusMinDistance) sendSMS(new Sms(receivedSms.phoneNumber, R.string.smscommunicator_remotebolusnotallowed)); - else if (ConfigBuilderPlugin.getPlugin().getActivePump().isSuspended()) + else if (splitted.length == 2 && ConfigBuilderPlugin.getPlugin().getActivePump().isSuspended()) sendSMS(new Sms(receivedSms.phoneNumber, R.string.pumpsuspended)); else if (splitted.length == 2) processBOLUS(splitted, receivedSms); @@ -684,7 +683,7 @@ public class SmsCommunicatorPlugin extends PluginBase { String reply = String.format(MainApp.gs(R.string.smscommunicator_bolusdelivered), resultBolusDelivered); if (pump != null) reply += "\n" + pump.shortStatus(true); - lastRemoteBolusTime = new Date(); + lastRemoteBolusTime = DateUtil.now(); sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); } else { String reply = MainApp.gs(R.string.smscommunicator_bolusfailed); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index def8df3adb..2af1c4caed 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -293,10 +293,10 @@ To deliver bolus %1$.2fU reply with code %2$s To send calibration %1$.2f reply with code %2$s Bolus failed - Bolus %.2fU delivered successfully - Going to deliver %.2fU - Bolus %.2fU delivered successfully - Delivering %.2fU + Bolus %1$.2fU delivered successfully + Going to deliver %1$.2fU + Bolus %1$.2fU delivered successfully + Delivering %1$.2fU Allow remote commands via SMS Finger Sensor diff --git a/app/src/test/java/info/AAPSMocker.java b/app/src/test/java/info/AAPSMocker.java index d6bf6940a3..689ce08c03 100644 --- a/app/src/test/java/info/AAPSMocker.java +++ b/app/src/test/java/info/AAPSMocker.java @@ -141,6 +141,12 @@ public class AAPSMocker { when(MainApp.gs(R.string.smscommunicator_extendedcanceled)).thenReturn("Extended bolus canceled"); when(MainApp.gs(R.string.smscommunicator_extendedreplywithcode)).thenReturn("To start extended bolus %1$.2fU for %2$d min reply with code %3$s"); when(MainApp.gs(R.string.smscommunicator_extendedset)).thenReturn("Extended bolus %1$.2fU for %2$d min started successfully"); + when(MainApp.gs(R.string.smscommunicator_bolusreplywithcode)).thenReturn("To deliver bolus %1$.2fU reply with code %2$s"); + when(MainApp.gs(R.string.smscommunicator_bolusdelivered)).thenReturn("Bolus %1$.2fU delivered successfully"); + when(MainApp.gs(R.string.smscommunicator_remotebolusnotallowed)).thenReturn("Remote bolus not available. Try again later."); + when(MainApp.gs(R.string.smscommunicator_calibrationreplywithcode)).thenReturn("To send calibration %1$.2f reply with code %2$s"); + when(MainApp.gs(R.string.smscommunicator_calibrationsent)).thenReturn("Calibration sent. Receiving must be enabled in xDrip."); + when(MainApp.gs(R.string.pumpsuspended)).thenReturn("Pump suspended"); } public static MainApp mockMainApp() { diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java index b88dd1e94b..d8bf191926 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java +++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java @@ -16,13 +16,16 @@ import java.util.ArrayList; import java.util.List; import info.AAPSMocker; +import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.db.BgReading; import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.ProfileInterface; +import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin; import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; @@ -36,6 +39,7 @@ import info.nightscout.androidaps.queue.Callback; import info.nightscout.androidaps.queue.CommandQueue; import info.nightscout.androidaps.utils.DateUtil; import info.nightscout.androidaps.utils.SP; +import info.nightscout.androidaps.utils.XdripCalibrations; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; @@ -52,15 +56,15 @@ import static org.powermock.api.mockito.PowerMockito.when; L.class, SP.class, MainApp.class, DateUtil.class, ProfileFunctions.class, TreatmentsPlugin.class, SmsManager.class, IobCobCalculatorPlugin.class, CommandQueue.class, ConfigBuilderPlugin.class, NSUpload.class, ProfileInterface.class, - SimpleProfilePlugin.class + SimpleProfilePlugin.class, XdripCalibrations.class, VirtualPumpPlugin.class }) public class SmsCommunicatorPluginTest { - SmsCommunicatorPlugin smsCommunicatorPlugin; - LoopPlugin loopPlugin; + private SmsCommunicatorPlugin smsCommunicatorPlugin; + private LoopPlugin loopPlugin; - boolean hasBeenRun = false; + private boolean hasBeenRun = false; @Test public void processSettingsTest() { @@ -81,6 +85,7 @@ public class SmsCommunicatorPluginTest { Sms sms; // SMS from not allowed number should be ignored + smsCommunicatorPlugin.messages = new ArrayList<>(); sms = new Sms("12", "aText"); smsCommunicatorPlugin.processSms(sms); Assert.assertTrue(sms.ignored); @@ -562,7 +567,122 @@ public class SmsCommunicatorPluginTest { smsCommunicatorPlugin.processSms(new Sms("1234", passCode)); Assert.assertEquals(passCode, smsCommunicatorPlugin.messages.get(2).text); Assert.assertEquals("Extended bolus 1.00U for 20 min started successfully\nVirtual Pump", smsCommunicatorPlugin.messages.get(3).text); + } + @Test + public void processBolusTest() { + Sms sms; + + //BOLUS + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "BOLUS"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals("BOLUS", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Remote command is not allowed", smsCommunicatorPlugin.messages.get(1).text); + + when(SP.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)).thenReturn(true); + + //BOLUS + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "BOLUS"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals("BOLUS", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Wrong format", smsCommunicatorPlugin.messages.get(1).text); + + when(MainApp.getConstraintChecker().applyBolusConstraints(any())).thenReturn(new Constraint<>(1d)); + + when(DateUtil.now()).thenReturn(1000L); + //BOLUS 1 + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "BOLUS 1"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals("BOLUS 1", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Remote bolus not available. Try again later.", smsCommunicatorPlugin.messages.get(1).text); + + when(MainApp.getConstraintChecker().applyBolusConstraints(any())).thenReturn(new Constraint<>(0d)); + + when(DateUtil.now()).thenReturn(Constants.remoteBolusMinDistance + 1002L); + + //BOLUS 0 + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "BOLUS 0"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals("BOLUS 0", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Wrong format", smsCommunicatorPlugin.messages.get(1).text); + + //BOLUS a + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "BOLUS a"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals("BOLUS a", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Wrong format", smsCommunicatorPlugin.messages.get(1).text); + + when(MainApp.getConstraintChecker().applyExtendedBolusConstraints(any())).thenReturn(new Constraint<>(1d)); + + when(MainApp.getConstraintChecker().applyBolusConstraints(any())).thenReturn(new Constraint<>(1d)); + + //BOLUS 1 + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "BOLUS 1"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals("BOLUS 1", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertTrue(smsCommunicatorPlugin.messages.get(1).text.contains("To deliver bolus 1.00U reply with code")); + String passCode = smsCommunicatorPlugin.messageToConfirm.confirmCode; + smsCommunicatorPlugin.processSms(new Sms("1234", passCode)); + Assert.assertEquals(passCode, smsCommunicatorPlugin.messages.get(2).text); + Assert.assertEquals("Bolus 1.00U delivered successfully\nVirtual Pump", smsCommunicatorPlugin.messages.get(3).text); + + //BOLUS 1 (Suspended pump) + smsCommunicatorPlugin.lastRemoteBolusTime = 0; + PumpInterface pump = mock(VirtualPumpPlugin.class); + when(ConfigBuilderPlugin.getPlugin().getActivePump()).thenReturn(pump); + when(pump.isSuspended()).thenReturn(true); + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "BOLUS 1"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals("BOLUS 1", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Pump suspended", smsCommunicatorPlugin.messages.get(1).text); + when(pump.isSuspended()).thenReturn(false); + } + + @Test + public void processCalTest() { + Sms sms; + + //CAL + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "CAL"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals("CAL", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Remote command is not allowed", smsCommunicatorPlugin.messages.get(1).text); + + when(SP.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)).thenReturn(true); + + //CAL + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "CAL"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals("CAL", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Wrong format", smsCommunicatorPlugin.messages.get(1).text); + + //CAL 0 + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "CAL 0"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals("CAL 0", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("Wrong format", smsCommunicatorPlugin.messages.get(1).text); + + when(XdripCalibrations.sendIntent(any())).thenReturn(true); + //CAL 1 + smsCommunicatorPlugin.messages = new ArrayList<>(); + sms = new Sms("1234", "CAL 1"); + smsCommunicatorPlugin.processSms(sms); + Assert.assertEquals("CAL 1", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertTrue(smsCommunicatorPlugin.messages.get(1).text.contains("To send calibration 1.00 reply with code")); + String passCode = smsCommunicatorPlugin.messageToConfirm.confirmCode; + smsCommunicatorPlugin.processSms(new Sms("1234", passCode)); + Assert.assertEquals(passCode, smsCommunicatorPlugin.messages.get(2).text); + Assert.assertEquals("Calibration sent. Receiving must be enabled in xDrip.", smsCommunicatorPlugin.messages.get(3).text); } @Before @@ -588,6 +708,7 @@ public class SmsCommunicatorPluginTest { bgList.add(reading); PowerMockito.when(IobCobCalculatorPlugin.getPlugin().getBgReadings()).thenReturn(bgList); + mockStatic(XdripCalibrations.class); mockStatic(DateUtil.class); mockStatic(SmsManager.class); SmsManager smsManager = mock(SmsManager.class); @@ -621,6 +742,13 @@ public class SmsCommunicatorPluginTest { return null; }).when(AAPSMocker.queue).readStatus(anyString(), any(Callback.class)); + Mockito.doAnswer(invocation -> { + Callback callback = invocation.getArgument(1); + callback.result = new PumpEnactResult().success(true).bolusDelivered(1); + callback.run(); + return null; + }).when(AAPSMocker.queue).bolus(any(DetailedBolusInfo.class), any(Callback.class)); + Mockito.doAnswer(invocation -> { Callback callback = invocation.getArgument(4); callback.result = new PumpEnactResult().success(true).isPercent(true).percent(invocation.getArgument(0)).duration(invocation.getArgument(1)); From beb50bad4411553f79f9bdb009e62c124d083d14 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Thu, 21 Mar 2019 21:03:34 +0100 Subject: [PATCH 33/39] SmsCommunicatorPluginTest 11 --- .../smsCommunicator/SmsCommunicatorPluginTest.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java index d8bf191926..02ffd42d02 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java +++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java @@ -685,6 +685,14 @@ public class SmsCommunicatorPluginTest { Assert.assertEquals("Calibration sent. Receiving must be enabled in xDrip.", smsCommunicatorPlugin.messages.get(3).text); } + @Test + public void sendNotificationToAllNumbers() { + smsCommunicatorPlugin.messages = new ArrayList<>(); + smsCommunicatorPlugin.sendNotificationToAllNumbers("abc"); + Assert.assertEquals("abc", smsCommunicatorPlugin.messages.get(0).text); + Assert.assertEquals("abc", smsCommunicatorPlugin.messages.get(1).text); + } + @Before public void prepareTests() { AAPSMocker.mockMainApp(); From 9e05ea8c8e3f93e289efdecb5b28a26f043e6a19 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Thu, 21 Mar 2019 21:29:09 +0100 Subject: [PATCH 34/39] ConstraintTest --- .../androidaps/interfaces/ConstraintTest.java | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/app/src/test/java/info/nightscout/androidaps/interfaces/ConstraintTest.java b/app/src/test/java/info/nightscout/androidaps/interfaces/ConstraintTest.java index 4b2d209661..3dbe770bfc 100644 --- a/app/src/test/java/info/nightscout/androidaps/interfaces/ConstraintTest.java +++ b/app/src/test/java/info/nightscout/androidaps/interfaces/ConstraintTest.java @@ -2,6 +2,7 @@ package info.nightscout.androidaps.interfaces; import junit.framework.Assert; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.core.classloader.annotations.PrepareForTest; @@ -9,6 +10,7 @@ import org.powermock.modules.junit4.PowerMockRunner; import info.AAPSMocker; import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.utils.SP; /** @@ -16,15 +18,11 @@ import info.nightscout.androidaps.utils.SP; */ @RunWith(PowerMockRunner.class) -@PrepareForTest({MainApp.class, SP.class}) +@PrepareForTest({MainApp.class, SP.class, L.class}) public class ConstraintTest { @Test public void doTests() { - AAPSMocker.mockMainApp(); - AAPSMocker.mockApplicationContext(); - AAPSMocker.mockSP(); - Constraint b = new Constraint<>(true); Assert.assertEquals(Boolean.TRUE, b.value()); Assert.assertEquals("", b.getReasons()); @@ -56,5 +54,18 @@ public class ConstraintTest { Assert.assertEquals("ConstraintTest: Set 5d\nConstraintTest: Set 6d\nConstraintTest: Set 4d", d.getReasons()); Assert.assertEquals("ConstraintTest: Set 4d", d.getMostLimitedReasons()); Assert.assertEquals(10d, d.originalValue()); + d.setIfDifferent(7d, "Set 7d", this); + Assert.assertEquals(7d, d.value()); + Assert.assertEquals("ConstraintTest: Set 5d\nConstraintTest: Set 6d\nConstraintTest: Set 4d\nConstraintTest: Set 7d", d.getReasons()); + Assert.assertEquals("ConstraintTest: Set 4d\nConstraintTest: Set 7d", d.getMostLimitedReasons()); + Assert.assertEquals(10d, d.originalValue()); + } + + @Before + public void prepareMock() { + AAPSMocker.mockMainApp(); + AAPSMocker.mockApplicationContext(); + AAPSMocker.mockSP(); + AAPSMocker.mockL(); } } From fcc4a4edd3e0d3e0315d989992dac9431d2ab747 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Thu, 21 Mar 2019 21:54:46 +0100 Subject: [PATCH 35/39] SmsCommunicatorPluginTest 12 --- .../general/smsCommunicator/SmsCommunicatorPlugin.java | 4 ++-- app/src/main/res/values/strings.xml | 6 +++--- app/src/test/java/info/AAPSMocker.java | 6 +++--- .../general/smsCommunicator/SmsCommunicatorPluginTest.java | 6 +++--- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java index b58022c2e9..604d1e856c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java @@ -527,7 +527,7 @@ public class SmsCommunicatorPlugin extends PluginBase { else { tempBasalPct = MainApp.getConstraintChecker().applyBasalPercentConstraints(new Constraint<>(tempBasalPct), profile).value(); String passCode = generatePasscode(); - String reply = String.format(MainApp.gs(R.string.smscommunicator_basalpctreplywithcode), tempBasalPct, passCode); + String reply = String.format(MainApp.gs(R.string.smscommunicator_basalpctreplywithcode), tempBasalPct, duration, passCode); receivedSms.processed = true; messageToConfirm = new AuthRequest(this, receivedSms, reply, passCode, new SmsAction(tempBasalPct, duration) { @Override @@ -568,7 +568,7 @@ public class SmsCommunicatorPlugin extends PluginBase { else { tempBasal = MainApp.getConstraintChecker().applyBasalConstraints(new Constraint<>(tempBasal), profile).value(); String passCode = generatePasscode(); - String reply = String.format(MainApp.gs(R.string.smscommunicator_basalreplywithcode), tempBasal, passCode); + String reply = String.format(MainApp.gs(R.string.smscommunicator_basalreplywithcode), tempBasal, duration, passCode); receivedSms.processed = true; messageToConfirm = new AuthRequest(this, receivedSms, reply, passCode, new SmsAction(tempBasal, duration) { @Override diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2af1c4caed..87243e486f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -367,14 +367,14 @@ Value %s is out of hard limits Remote command is not allowed Remote bolus not available. Try again later. - To start basal %1$.2fU/h reply with code %2$s + To start basal %1$.2fU/h for %2$d min reply with code %3$s To switch profile to %1$s %2$d%% reply with code %3$s To start extended bolus %1$.2fU for %2$d min reply with code %3$s - To start basal %1$d%% reply with code %2$s + To start basal %1$d%% for %2$d min reply with code %3$s To suspend loop for %1$d minutes reply with code %2$s Temp basal %1$.2fU/h for %2$d min started successfully Extended bolus %1$.2fU for %2$d min started successfully - Temp basal %1$d%% for %2$d min started successfully + Temp basal %1$d%% for %2$d min started successfully Temp basal start failed Extended bolus start failed To stop temp basal reply with code %1$s diff --git a/app/src/test/java/info/AAPSMocker.java b/app/src/test/java/info/AAPSMocker.java index 689ce08c03..dcbb3263c1 100644 --- a/app/src/test/java/info/AAPSMocker.java +++ b/app/src/test/java/info/AAPSMocker.java @@ -133,9 +133,9 @@ public class AAPSMocker { when(MainApp.gs(R.string.smscommunicator_profilereplywithcode)).thenReturn("To switch profile to %1$s %2$d%% reply with code %3$s"); when(MainApp.gs(R.string.profileswitchcreated)).thenReturn("Profile switch created"); when(MainApp.gs(R.string.smscommunicator_basalstopreplywithcode)).thenReturn("To stop temp basal reply with code %1$s"); - when(MainApp.gs(R.string.smscommunicator_basalpctreplywithcode)).thenReturn("To start basal %1$d%% reply with code %2$s"); - when(MainApp.gs(R.string.smscommunicator_tempbasalset_percent)).thenReturn("Temp basal %1$d%% for %2$d min started successfully"); - when(MainApp.gs(R.string.smscommunicator_basalreplywithcode)).thenReturn("To start basal %1$.2fU/h reply with code %2$s"); + when(MainApp.gs(R.string.smscommunicator_basalpctreplywithcode)).thenReturn("To start basal %1$d%% for %2$d min reply with code %3$s"); + when(MainApp.gs(R.string.smscommunicator_tempbasalset_percent)).thenReturn("Temp basal %1$d%% for %2$d min started successfully"); + when(MainApp.gs(R.string.smscommunicator_basalreplywithcode)).thenReturn("To start basal %1$.2fU/h for %2$d min reply with code %3$s"); when(MainApp.gs(R.string.smscommunicator_tempbasalset)).thenReturn("Temp basal %1$.2fU/h for %2$d min started successfully"); when(MainApp.gs(R.string.smscommunicator_extendedstopreplywithcode)).thenReturn("To stop extended bolus reply with code %1$s"); when(MainApp.gs(R.string.smscommunicator_extendedcanceled)).thenReturn("Extended bolus canceled"); diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java index 02ffd42d02..f570e20f97 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java +++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java @@ -475,11 +475,11 @@ public class SmsCommunicatorPluginTest { sms = new Sms("1234", "BASAL 20% 20"); smsCommunicatorPlugin.processSms(sms); Assert.assertEquals("BASAL 20% 20", smsCommunicatorPlugin.messages.get(0).text); - Assert.assertTrue(smsCommunicatorPlugin.messages.get(1).text.contains("To start basal 20% reply with code")); + Assert.assertTrue(smsCommunicatorPlugin.messages.get(1).text.contains("To start basal 20% for 20 min reply with code")); passCode = smsCommunicatorPlugin.messageToConfirm.confirmCode; smsCommunicatorPlugin.processSms(new Sms("1234", passCode)); Assert.assertEquals(passCode, smsCommunicatorPlugin.messages.get(2).text); - Assert.assertEquals("Temp basal 20% for 20 min started successfully\nVirtual Pump", smsCommunicatorPlugin.messages.get(3).text); + Assert.assertEquals("Temp basal 20% for 20 min started successfully\nVirtual Pump", smsCommunicatorPlugin.messages.get(3).text); //BASAL a smsCommunicatorPlugin.messages = new ArrayList<>(); @@ -502,7 +502,7 @@ public class SmsCommunicatorPluginTest { sms = new Sms("1234", "BASAL 1 20"); smsCommunicatorPlugin.processSms(sms); Assert.assertEquals("BASAL 1 20", smsCommunicatorPlugin.messages.get(0).text); - Assert.assertTrue(smsCommunicatorPlugin.messages.get(1).text.contains("To start basal 1.00U/h reply with code")); + Assert.assertTrue(smsCommunicatorPlugin.messages.get(1).text.contains("To start basal 1.00U/h for 20 min reply with code")); passCode = smsCommunicatorPlugin.messageToConfirm.confirmCode; smsCommunicatorPlugin.processSms(new Sms("1234", passCode)); Assert.assertEquals(passCode, smsCommunicatorPlugin.messages.get(2).text); From 52482d112d6355d01f3d0a12621c4f06bfbfeeea Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Thu, 21 Mar 2019 22:31:44 +0100 Subject: [PATCH 36/39] typo --- app/src/main/res/values/strings.xml | 2 +- app/src/test/java/info/AAPSMocker.java | 2 +- .../general/smsCommunicator/SmsCommunicatorPluginTest.java | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ca44a72f82..cb8329872e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -384,7 +384,7 @@ Extended bolus canceled Canceling temp basal failed Canceling extended bolus failed - Uknown command or wrong reply + Unknown command or wrong reply QuickWizard QuickWizard settings diff --git a/app/src/test/java/info/AAPSMocker.java b/app/src/test/java/info/AAPSMocker.java index dcbb3263c1..24542f12e9 100644 --- a/app/src/test/java/info/AAPSMocker.java +++ b/app/src/test/java/info/AAPSMocker.java @@ -128,7 +128,7 @@ public class AAPSMocker { when(MainApp.gs(R.string.smscommunicator_wrongduration)).thenReturn("Wrong duration"); when(MainApp.gs(R.string.smscommunicator_suspendreplywithcode)).thenReturn("To suspend loop for %1$d minutes reply with code %2$s"); when(MainApp.gs(R.string.smscommunicator_loopsuspended)).thenReturn("Loop suspended"); - when(MainApp.gs(R.string.smscommunicator_unknowncommand)).thenReturn("Uknown command or wrong reply"); + when(MainApp.gs(R.string.smscommunicator_unknowncommand)).thenReturn("Unknown command or wrong reply"); when(MainApp.gs(R.string.notconfigured)).thenReturn("Not configured"); when(MainApp.gs(R.string.smscommunicator_profilereplywithcode)).thenReturn("To switch profile to %1$s %2$d%% reply with code %3$s"); when(MainApp.gs(R.string.profileswitchcreated)).thenReturn("Profile switch created"); diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java index f570e20f97..aecc98de24 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java +++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java @@ -96,7 +96,7 @@ public class SmsCommunicatorPluginTest { sms = new Sms("1234", "UNKNOWN"); smsCommunicatorPlugin.processSms(sms); Assert.assertEquals("UNKNOWN", smsCommunicatorPlugin.messages.get(0).text); - Assert.assertEquals("Uknown command or wrong reply", smsCommunicatorPlugin.messages.get(1).text); + Assert.assertEquals("Unknown command or wrong reply", smsCommunicatorPlugin.messages.get(1).text); //BG smsCommunicatorPlugin.messages = new ArrayList<>(); @@ -251,7 +251,7 @@ public class SmsCommunicatorPluginTest { //then correct code should not work smsCommunicatorPlugin.processSms(new Sms("1234", passCode)); Assert.assertEquals(passCode, smsCommunicatorPlugin.messages.get(4).text); - Assert.assertEquals("Uknown command or wrong reply", smsCommunicatorPlugin.messages.get(5).text); + Assert.assertEquals("Unknown command or wrong reply", smsCommunicatorPlugin.messages.get(5).text); //LOOP BLABLA smsCommunicatorPlugin.messages = new ArrayList<>(); From ca3c6b409393c6a8b8e3ff1aad54fb54ae175459 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Fri, 22 Mar 2019 22:18:51 +0100 Subject: [PATCH 37/39] SmsCommunicator detect commands --- .../general/smsCommunicator/AuthRequest.java | 2 +- .../SmsCommunicatorPlugin.java | 26 +++++++++++++++---- .../SmsCommunicatorPluginTest.java | 26 +++++++++++++++---- 3 files changed, 43 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequest.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequest.java index ad17f4ff42..4b05072eb1 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequest.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/AuthRequest.java @@ -11,7 +11,7 @@ import info.nightscout.androidaps.utils.DateUtil; class AuthRequest { private static Logger log = LoggerFactory.getLogger(L.SMS); - private Sms requester; + Sms requester; String confirmCode; private Runnable action; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java index 604d1e856c..58791c6a6f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java @@ -115,6 +115,25 @@ public class SmsCommunicatorPlugin extends PluginBase { } } + boolean isCommand(String command, String number) { + switch(command.toUpperCase()) { + case "BG": + case "LOOP": + case "TREATMENTS": + case "NSCLIENT": + case "PUMP": + case "BASAL": + case "BOLUS": + case "EXTENDED": + case "CAL": + case "PROFILE": + return true; + } + if (messageToConfirm != null && messageToConfirm.requester.phoneNumber.equals(number)) + return true; + return false; + } + boolean isAllowedNumber(String number) { for (String num : allowedNumbers) { if (num.equals(number)) return true; @@ -155,7 +174,7 @@ public class SmsCommunicatorPlugin extends PluginBase { String[] splitted = receivedSms.text.split("\\s+"); boolean remoteCommandsAllowed = SP.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false); - if (splitted.length > 0) { + if (splitted.length > 0 && isCommand(splitted[0].toUpperCase(), receivedSms.phoneNumber)) { switch (splitted[0].toUpperCase()) { case "BG": processBG(splitted, receivedSms); @@ -228,10 +247,7 @@ public class SmsCommunicatorPlugin extends PluginBase { sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat)); break; default: // expect passCode here - //noinspection StatementWithEmptyBody - if (!Character.isLetter(splitted[0].charAt(0))) { - // user text .... ignore - } else if (messageToConfirm != null) { + if (messageToConfirm != null && messageToConfirm.requester.phoneNumber.equals(receivedSms.phoneNumber)) { messageToConfirm.action(splitted[0]); messageToConfirm = null; } else diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java index aecc98de24..80c7e0a44f 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java +++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java @@ -74,6 +74,21 @@ public class SmsCommunicatorPluginTest { Assert.assertEquals(2, smsCommunicatorPlugin.allowedNumbers.size()); } + @Test + public void isCommandTest() { + Assert.assertTrue(smsCommunicatorPlugin.isCommand("BOLUS", "")); + smsCommunicatorPlugin.messageToConfirm = null; + Assert.assertFalse(smsCommunicatorPlugin.isCommand("BLB", "")); + smsCommunicatorPlugin.messageToConfirm = new AuthRequest(smsCommunicatorPlugin, new Sms("1234", "ddd"), "RequestText", "ccode", new SmsAction() { + @Override + public void run() { + } + }); + Assert.assertTrue(smsCommunicatorPlugin.isCommand("BLB", "1234")); + Assert.assertFalse(smsCommunicatorPlugin.isCommand("BLB", "2345")); + smsCommunicatorPlugin.messageToConfirm = null; + } + @Test public void isAllowedNumberTest() { Assert.assertTrue(smsCommunicatorPlugin.isAllowedNumber("5678")); @@ -96,7 +111,6 @@ public class SmsCommunicatorPluginTest { sms = new Sms("1234", "UNKNOWN"); smsCommunicatorPlugin.processSms(sms); Assert.assertEquals("UNKNOWN", smsCommunicatorPlugin.messages.get(0).text); - Assert.assertEquals("Unknown command or wrong reply", smsCommunicatorPlugin.messages.get(1).text); //BG smsCommunicatorPlugin.messages = new ArrayList<>(); @@ -245,13 +259,15 @@ public class SmsCommunicatorPluginTest { Assert.assertEquals("LOOP SUSPEND 200", smsCommunicatorPlugin.messages.get(0).text); Assert.assertTrue(smsCommunicatorPlugin.messages.get(1).text.contains("To suspend loop for 180 minutes reply with code ")); passCode = smsCommunicatorPlugin.messageToConfirm.confirmCode; + // ignore from other number + smsCommunicatorPlugin.processSms(new Sms("5678", passCode)); smsCommunicatorPlugin.processSms(new Sms("1234", "XXXX")); - Assert.assertEquals("XXXX", smsCommunicatorPlugin.messages.get(2).text); - Assert.assertEquals("Wrong code. Command cancelled.", smsCommunicatorPlugin.messages.get(3).text); + Assert.assertEquals("XXXX", smsCommunicatorPlugin.messages.get(3).text); + Assert.assertEquals("Wrong code. Command cancelled.", smsCommunicatorPlugin.messages.get(4).text); //then correct code should not work smsCommunicatorPlugin.processSms(new Sms("1234", passCode)); - Assert.assertEquals(passCode, smsCommunicatorPlugin.messages.get(4).text); - Assert.assertEquals("Unknown command or wrong reply", smsCommunicatorPlugin.messages.get(5).text); + Assert.assertEquals(passCode, smsCommunicatorPlugin.messages.get(5).text); + Assert.assertEquals(6, smsCommunicatorPlugin.messages.size()); // processed as common message //LOOP BLABLA smsCommunicatorPlugin.messages = new ArrayList<>(); From fdbb76cb925f54ff3b3613de89e25e09950170aa Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Fri, 22 Mar 2019 22:45:41 +0100 Subject: [PATCH 38/39] SmsCommunicator show COB --- .../general/smsCommunicator/SmsCommunicatorPlugin.java | 8 +++++++- app/src/test/java/info/AAPSMocker.java | 3 +++ .../smsCommunicator/SmsCommunicatorPluginTest.java | 3 +++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java index 58791c6a6f..5363ce29a3 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java @@ -43,6 +43,8 @@ import info.nightscout.androidaps.plugins.general.nsclient.NSUpload; import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.general.overview.notifications.Notification; import info.nightscout.androidaps.plugins.general.smsCommunicator.events.EventSmsCommunicatorUpdateGui; +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.CobInfo; +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin; import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin; import info.nightscout.androidaps.queue.Callback; import info.nightscout.androidaps.services.Intents; @@ -284,9 +286,13 @@ public class SmsCommunicatorPlugin extends PluginBase { TreatmentsPlugin.getPlugin().updateTotalIOBTempBasals(); IobTotal basalIob = TreatmentsPlugin.getPlugin().getLastCalculationTempBasals().round(); + String cobText = MainApp.gs(R.string.value_unavailable_short); + CobInfo cobInfo = IobCobCalculatorPlugin.getPlugin().getCobInfo(false, "SMS COB"); + reply += MainApp.gs(R.string.sms_iob) + " " + DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U (" + MainApp.gs(R.string.sms_bolus) + " " + DecimalFormatter.to2Decimal(bolusIob.iob) + "U " - + MainApp.gs(R.string.sms_basal) + " " + DecimalFormatter.to2Decimal(basalIob.basaliob) + "U)"; + + MainApp.gs(R.string.sms_basal) + " " + DecimalFormatter.to2Decimal(basalIob.basaliob) + "U)" + + MainApp.gs(R.string.cob) + ": " + cobInfo.generateCOBString(); sendSMS(new Sms(receivedSms.phoneNumber, reply)); receivedSms.processed = true; diff --git a/app/src/test/java/info/AAPSMocker.java b/app/src/test/java/info/AAPSMocker.java index 24542f12e9..7d4884bb96 100644 --- a/app/src/test/java/info/AAPSMocker.java +++ b/app/src/test/java/info/AAPSMocker.java @@ -27,6 +27,7 @@ import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.general.nsclient.NSUpload; +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.CobInfo; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin; import info.nightscout.androidaps.plugins.pump.danaR.DanaRPlugin; import info.nightscout.androidaps.plugins.pump.danaRKorean.DanaRKoreanPlugin; @@ -147,6 +148,8 @@ public class AAPSMocker { when(MainApp.gs(R.string.smscommunicator_calibrationreplywithcode)).thenReturn("To send calibration %1$.2f reply with code %2$s"); when(MainApp.gs(R.string.smscommunicator_calibrationsent)).thenReturn("Calibration sent. Receiving must be enabled in xDrip."); when(MainApp.gs(R.string.pumpsuspended)).thenReturn("Pump suspended"); + when(MainApp.gs(R.string.cob)).thenReturn("COB"); + when(MainApp.gs(R.string.value_unavailable_short)).thenReturn("n/a"); } public static MainApp mockMainApp() { diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java index 80c7e0a44f..abc29216b0 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java +++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.java @@ -31,6 +31,7 @@ import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin; import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.general.nsclient.NSUpload; +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.CobInfo; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin; import info.nightscout.androidaps.plugins.profile.simple.SimpleProfilePlugin; import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin; @@ -119,6 +120,7 @@ public class SmsCommunicatorPluginTest { Assert.assertEquals("BG", smsCommunicatorPlugin.messages.get(0).text); Assert.assertTrue(smsCommunicatorPlugin.messages.get(1).text.contains("IOB:")); Assert.assertTrue(smsCommunicatorPlugin.messages.get(1).text.contains("Last BG: 100")); + Assert.assertTrue(smsCommunicatorPlugin.messages.get(1).text.contains("COB: 10(2)g")); // LOOP : test remote control disabled when(SP.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)).thenReturn(false); @@ -731,6 +733,7 @@ public class SmsCommunicatorPluginTest { List bgList = new ArrayList<>(); bgList.add(reading); PowerMockito.when(IobCobCalculatorPlugin.getPlugin().getBgReadings()).thenReturn(bgList); + PowerMockito.when(IobCobCalculatorPlugin.getPlugin().getCobInfo(false, "SMS COB")).thenReturn(new CobInfo(10d, 2d)); mockStatic(XdripCalibrations.class); mockStatic(DateUtil.class); From a060af8b0e09d189c0cc264748e6c3eee0178625 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Fri, 22 Mar 2019 22:53:16 +0100 Subject: [PATCH 39/39] SmsCommunicator separator --- .../plugins/general/smsCommunicator/SmsCommunicatorPlugin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java index 5363ce29a3..e4ec65df11 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java @@ -291,7 +291,7 @@ public class SmsCommunicatorPlugin extends PluginBase { reply += MainApp.gs(R.string.sms_iob) + " " + DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U (" + MainApp.gs(R.string.sms_bolus) + " " + DecimalFormatter.to2Decimal(bolusIob.iob) + "U " - + MainApp.gs(R.string.sms_basal) + " " + DecimalFormatter.to2Decimal(basalIob.basaliob) + "U)" + + MainApp.gs(R.string.sms_basal) + " " + DecimalFormatter.to2Decimal(basalIob.basaliob) + "U), " + MainApp.gs(R.string.cob) + ": " + cobInfo.generateCOBString(); sendSMS(new Sms(receivedSms.phoneNumber, reply));