Merge branch 'dev' into feature/1806_remove_whitebar_wearos
Resolved Conflicts in: [...]/watchfaces/Home.java [...]/watchfaces/Home2.java [...]/watchfaces/LargeHome.java
|
@ -129,7 +129,14 @@ public class MainApp extends Application {
|
||||||
sConstraintsChecker = new ConstraintChecker();
|
sConstraintsChecker = new ConstraintChecker();
|
||||||
sDatabaseHelper = OpenHelperManager.getHelper(sInstance, DatabaseHelper.class);
|
sDatabaseHelper = OpenHelperManager.getHelper(sInstance, DatabaseHelper.class);
|
||||||
|
|
||||||
Thread.setDefaultUncaughtExceptionHandler((thread, ex) -> log.error("Uncaught exception crashing app", ex));
|
Thread.setDefaultUncaughtExceptionHandler((thread, ex) -> {
|
||||||
|
if (ex instanceof InternalError) {
|
||||||
|
// usually the app trying to spawn a thread while being killed
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
log.error("Uncaught exception crashing app", ex);
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (FabricPrivacy.fabricEnabled()) {
|
if (FabricPrivacy.fabricEnabled()) {
|
||||||
|
@ -204,7 +211,7 @@ public class MainApp extends Application {
|
||||||
pluginsList.add(SourcePoctechPlugin.getPlugin());
|
pluginsList.add(SourcePoctechPlugin.getPlugin());
|
||||||
pluginsList.add(SourceTomatoPlugin.getPlugin());
|
pluginsList.add(SourceTomatoPlugin.getPlugin());
|
||||||
pluginsList.add(SourceEversensePlugin.getPlugin());
|
pluginsList.add(SourceEversensePlugin.getPlugin());
|
||||||
if (!Config.NSCLIENT) pluginsList.add(SmsCommunicatorPlugin.getPlugin());
|
if (!Config.NSCLIENT) pluginsList.add(SmsCommunicatorPlugin.INSTANCE);
|
||||||
pluginsList.add(FoodPlugin.getPlugin());
|
pluginsList.add(FoodPlugin.getPlugin());
|
||||||
|
|
||||||
pluginsList.add(WearPlugin.initPlugin(this));
|
pluginsList.add(WearPlugin.initPlugin(this));
|
||||||
|
|
|
@ -9,27 +9,28 @@ import android.preference.PreferenceActivity;
|
||||||
import android.preference.PreferenceFragment;
|
import android.preference.PreferenceFragment;
|
||||||
import android.preference.PreferenceGroup;
|
import android.preference.PreferenceGroup;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.preference.PreferenceScreen;
|
|
||||||
import android.text.TextUtils;
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.Config;
|
import info.nightscout.androidaps.Config;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBus;
|
|
||||||
import info.nightscout.androidaps.events.EventPreferenceChange;
|
import info.nightscout.androidaps.events.EventPreferenceChange;
|
||||||
import info.nightscout.androidaps.events.EventRebuildTabs;
|
import info.nightscout.androidaps.events.EventRebuildTabs;
|
||||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||||
import info.nightscout.androidaps.interfaces.PluginType;
|
import info.nightscout.androidaps.interfaces.PluginType;
|
||||||
import info.nightscout.androidaps.plugins.general.careportal.CareportalPlugin;
|
|
||||||
import info.nightscout.androidaps.plugins.constraints.safety.SafetyPlugin;
|
|
||||||
import info.nightscout.androidaps.plugins.general.tidepool.TidepoolPlugin;
|
|
||||||
import info.nightscout.androidaps.plugins.general.tidepool.comm.TidepoolUploader;
|
|
||||||
import info.nightscout.androidaps.plugins.insulin.InsulinOrefFreePeakPlugin;
|
|
||||||
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin;
|
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin;
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin;
|
|
||||||
import info.nightscout.androidaps.plugins.aps.openAPSAMA.OpenAPSAMAPlugin;
|
import info.nightscout.androidaps.plugins.aps.openAPSAMA.OpenAPSAMAPlugin;
|
||||||
import info.nightscout.androidaps.plugins.aps.openAPSMA.OpenAPSMAPlugin;
|
import info.nightscout.androidaps.plugins.aps.openAPSMA.OpenAPSMAPlugin;
|
||||||
import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin;
|
import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.bus.RxBus;
|
||||||
|
import info.nightscout.androidaps.plugins.constraints.safety.SafetyPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.general.careportal.CareportalPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.general.tidepool.TidepoolPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.general.wear.WearPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.general.xdripStatusline.StatuslinePlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.insulin.InsulinOrefFreePeakPlugin;
|
||||||
import info.nightscout.androidaps.plugins.pump.combo.ComboPlugin;
|
import info.nightscout.androidaps.plugins.pump.combo.ComboPlugin;
|
||||||
import info.nightscout.androidaps.plugins.pump.danaR.DanaRPlugin;
|
import info.nightscout.androidaps.plugins.pump.danaR.DanaRPlugin;
|
||||||
import info.nightscout.androidaps.plugins.pump.danaRKorean.DanaRKoreanPlugin;
|
import info.nightscout.androidaps.plugins.pump.danaRKorean.DanaRKoreanPlugin;
|
||||||
|
@ -42,14 +43,9 @@ import info.nightscout.androidaps.plugins.sensitivity.SensitivityAAPSPlugin;
|
||||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref0Plugin;
|
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref0Plugin;
|
||||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin;
|
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin;
|
||||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityWeightedAveragePlugin;
|
import info.nightscout.androidaps.plugins.sensitivity.SensitivityWeightedAveragePlugin;
|
||||||
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin;
|
|
||||||
import info.nightscout.androidaps.plugins.general.wear.WearPlugin;
|
|
||||||
import info.nightscout.androidaps.plugins.general.xdripStatusline.StatuslinePlugin;
|
|
||||||
import info.nightscout.androidaps.plugins.source.SourceDexcomPlugin;
|
import info.nightscout.androidaps.plugins.source.SourceDexcomPlugin;
|
||||||
import info.nightscout.androidaps.utils.LocaleHelper;
|
|
||||||
import info.nightscout.androidaps.utils.OKDialog;
|
import info.nightscout.androidaps.utils.OKDialog;
|
||||||
import info.nightscout.androidaps.utils.SP;
|
import info.nightscout.androidaps.utils.SP;
|
||||||
import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin;
|
|
||||||
|
|
||||||
public class PreferencesActivity extends PreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
|
public class PreferencesActivity extends PreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
MyPreferenceFragment myPreferenceFragment;
|
MyPreferenceFragment myPreferenceFragment;
|
||||||
|
@ -80,7 +76,7 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
|
||||||
if (key.equals(MainApp.gs(R.string.key_openapsama_useautosens)) && SP.getBoolean(R.string.key_openapsama_useautosens, false)) {
|
if (key.equals(MainApp.gs(R.string.key_openapsama_useautosens)) && SP.getBoolean(R.string.key_openapsama_useautosens, false)) {
|
||||||
OKDialog.show(this, MainApp.gs(R.string.configbuilder_sensitivity), MainApp.gs(R.string.sensitivity_warning), null);
|
OKDialog.show(this, MainApp.gs(R.string.configbuilder_sensitivity), MainApp.gs(R.string.sensitivity_warning), null);
|
||||||
}
|
}
|
||||||
updatePrefSummary(myPreferenceFragment.getPreference(key));
|
updatePrefSummary(myPreferenceFragment.findPreference(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void updatePrefSummary(Preference pref) {
|
private static void updatePrefSummary(Preference pref) {
|
||||||
|
@ -92,13 +88,13 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
|
||||||
EditTextPreference editTextPref = (EditTextPreference) pref;
|
EditTextPreference editTextPref = (EditTextPreference) pref;
|
||||||
if (pref.getKey().contains("password") || pref.getKey().contains("secret")) {
|
if (pref.getKey().contains("password") || pref.getKey().contains("secret")) {
|
||||||
pref.setSummary("******");
|
pref.setSummary("******");
|
||||||
} else if (pref.getKey().equals(MainApp.gs(R.string.key_danars_name))) {
|
|
||||||
pref.setSummary(SP.getString(R.string.key_danars_name, ""));
|
|
||||||
} else if (editTextPref.getText() != null) {
|
} else if (editTextPref.getText() != null) {
|
||||||
((EditTextPreference) pref).setDialogMessage(editTextPref.getDialogMessage());
|
((EditTextPreference) pref).setDialogMessage(editTextPref.getDialogMessage());
|
||||||
pref.setSummary(editTextPref.getText());
|
pref.setSummary(editTextPref.getText());
|
||||||
} else if (pref.getKey().contains("smscommunicator_allowednumbers") && (editTextPref.getText() == null || TextUtils.isEmpty(editTextPref.getText().trim()))) {
|
} else {
|
||||||
pref.setSummary(MainApp.gs(R.string.smscommunicator_allowednumbers_summary));
|
for (PluginBase plugin : MainApp.getPluginsList()) {
|
||||||
|
plugin.updatePreferenceSummary(pref);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -188,7 +184,7 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
|
||||||
|
|
||||||
addPreferencesFromResourceIfEnabled(NSClientPlugin.getPlugin(), PluginType.GENERAL);
|
addPreferencesFromResourceIfEnabled(NSClientPlugin.getPlugin(), PluginType.GENERAL);
|
||||||
addPreferencesFromResourceIfEnabled(TidepoolPlugin.INSTANCE, PluginType.GENERAL);
|
addPreferencesFromResourceIfEnabled(TidepoolPlugin.INSTANCE, PluginType.GENERAL);
|
||||||
addPreferencesFromResourceIfEnabled(SmsCommunicatorPlugin.getPlugin(), PluginType.GENERAL);
|
addPreferencesFromResourceIfEnabled(SmsCommunicatorPlugin.INSTANCE, PluginType.GENERAL);
|
||||||
addPreferencesFromResourceIfEnabled(AutomationPlugin.INSTANCE, PluginType.GENERAL);
|
addPreferencesFromResourceIfEnabled(AutomationPlugin.INSTANCE, PluginType.GENERAL);
|
||||||
|
|
||||||
addPreferencesFromResource(R.xml.pref_others);
|
addPreferencesFromResource(R.xml.pref_others);
|
||||||
|
@ -198,26 +194,11 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
|
||||||
addPreferencesFromResourceIfEnabled(StatuslinePlugin.getPlugin(), PluginType.GENERAL);
|
addPreferencesFromResourceIfEnabled(StatuslinePlugin.getPlugin(), PluginType.GENERAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Config.NSCLIENT) {
|
|
||||||
PreferenceScreen scrnAdvancedSettings = (PreferenceScreen) findPreference(getString(R.string.key_advancedsettings));
|
|
||||||
if (scrnAdvancedSettings != null) {
|
|
||||||
scrnAdvancedSettings.removePreference(getPreference(getString(R.string.key_statuslights_res_warning)));
|
|
||||||
scrnAdvancedSettings.removePreference(getPreference(getString(R.string.key_statuslights_res_critical)));
|
|
||||||
scrnAdvancedSettings.removePreference(getPreference(getString(R.string.key_statuslights_bat_warning)));
|
|
||||||
scrnAdvancedSettings.removePreference(getPreference(getString(R.string.key_statuslights_bat_critical)));
|
|
||||||
scrnAdvancedSettings.removePreference(getPreference(getString(R.string.key_show_statuslights)));
|
|
||||||
scrnAdvancedSettings.removePreference(getPreference(getString(R.string.key_show_statuslights_extended)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
initSummary(getPreferenceScreen());
|
initSummary(getPreferenceScreen());
|
||||||
|
|
||||||
final Preference tidepoolTestLogin = findPreference(MainApp.gs(R.string.key_tidepool_test_login));
|
for (PluginBase plugin : MainApp.getPluginsList()) {
|
||||||
if (tidepoolTestLogin != null)
|
plugin.preprocessPreferences(this);
|
||||||
tidepoolTestLogin.setOnPreferenceClickListener(preference -> {
|
}
|
||||||
TidepoolUploader.INSTANCE.testLogin(getActivity());
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -225,9 +206,5 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
|
||||||
super.onSaveInstanceState(outState);
|
super.onSaveInstanceState(outState);
|
||||||
outState.putInt("id", id);
|
outState.putInt("id", id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Preference getPreference(String key) {
|
|
||||||
return findPreference(key);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,8 +100,8 @@ public class CareportalEvent implements DataPointWithLabelInterface, Interval {
|
||||||
String hours = " " + MainApp.gs(R.string.hours) + " ";
|
String hours = " " + MainApp.gs(R.string.hours) + " ";
|
||||||
|
|
||||||
if (useShortText) {
|
if (useShortText) {
|
||||||
days = "d";
|
days = MainApp.gs(R.string.shortday);
|
||||||
hours = "h";
|
hours = MainApp.gs(R.string.shorthour);
|
||||||
}
|
}
|
||||||
|
|
||||||
return diff.get(TimeUnit.DAYS) + days + diff.get(TimeUnit.HOURS) + hours;
|
return diff.get(TimeUnit.DAYS) + days + diff.get(TimeUnit.HOURS) + hours;
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
package info.nightscout.androidaps.interfaces;
|
package info.nightscout.androidaps.interfaces;
|
||||||
|
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
|
import android.preference.Preference;
|
||||||
|
import android.preference.PreferenceFragment;
|
||||||
|
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.fragment.app.FragmentActivity;
|
import androidx.fragment.app.FragmentActivity;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -215,4 +218,10 @@ public abstract class PluginBase {
|
||||||
|
|
||||||
protected void onStateChange(PluginType type, State oldState, State newState) {
|
protected void onStateChange(PluginType type, State oldState, State newState) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void preprocessPreferences(@NotNull final PreferenceFragment preferenceFragment) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updatePreferenceSummary(@NotNull final Preference pref) {
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -247,7 +247,7 @@ public class APSResult {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
@ -280,7 +280,7 @@ public class APSResult {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return latest;
|
return latest;
|
||||||
|
|
|
@ -164,7 +164,7 @@ public class OpenAPSAMAPlugin extends PluginBase implements APSInterface {
|
||||||
return;
|
return;
|
||||||
if (!HardLimits.checkOnlyHardLimits(Profile.toMgdl(profile.getIsf(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF))
|
if (!HardLimits.checkOnlyHardLimits(Profile.toMgdl(profile.getIsf(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF))
|
||||||
return;
|
return;
|
||||||
if (!HardLimits.checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.05, HardLimits.maxBasal()))
|
if (!HardLimits.checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.02, HardLimits.maxBasal()))
|
||||||
return;
|
return;
|
||||||
if (!HardLimits.checkOnlyHardLimits(pump.getBaseBasalRate(), "current_basal", 0.01, HardLimits.maxBasal()))
|
if (!HardLimits.checkOnlyHardLimits(pump.getBaseBasalRate(), "current_basal", 0.01, HardLimits.maxBasal()))
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -162,7 +162,7 @@ public class OpenAPSMAPlugin extends PluginBase implements APSInterface {
|
||||||
return;
|
return;
|
||||||
if (!checkOnlyHardLimits(Profile.toMgdl(profile.getIsf(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF))
|
if (!checkOnlyHardLimits(Profile.toMgdl(profile.getIsf(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF))
|
||||||
return;
|
return;
|
||||||
if (!checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.05, HardLimits.maxBasal()))
|
if (!checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.02, HardLimits.maxBasal()))
|
||||||
return;
|
return;
|
||||||
if (!checkOnlyHardLimits(pump.getBaseBasalRate(), "current_basal", 0.01, HardLimits.maxBasal()))
|
if (!checkOnlyHardLimits(pump.getBaseBasalRate(), "current_basal", 0.01, HardLimits.maxBasal()))
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -170,7 +170,7 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface, Constr
|
||||||
return;
|
return;
|
||||||
if (!checkOnlyHardLimits(Profile.toMgdl(profile.getIsf(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF))
|
if (!checkOnlyHardLimits(Profile.toMgdl(profile.getIsf(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF))
|
||||||
return;
|
return;
|
||||||
if (!checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.05, HardLimits.maxBasal()))
|
if (!checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.02, HardLimits.maxBasal()))
|
||||||
return;
|
return;
|
||||||
if (!checkOnlyHardLimits(pump.getBaseBasalRate(), "current_basal", 0.01, HardLimits.maxBasal()))
|
if (!checkOnlyHardLimits(pump.getBaseBasalRate(), "current_basal", 0.01, HardLimits.maxBasal()))
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -27,6 +27,7 @@ import info.nightscout.androidaps.plugins.bus.RxBus;
|
||||||
import info.nightscout.androidaps.plugins.general.overview.dialogs.ErrorHelperActivity;
|
import info.nightscout.androidaps.plugins.general.overview.dialogs.ErrorHelperActivity;
|
||||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
|
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.androidaps.queue.Callback;
|
import info.nightscout.androidaps.queue.Callback;
|
||||||
|
import info.nightscout.androidaps.utils.DateUtil;
|
||||||
import info.nightscout.androidaps.utils.FabricPrivacy;
|
import info.nightscout.androidaps.utils.FabricPrivacy;
|
||||||
import info.nightscout.androidaps.utils.SP;
|
import info.nightscout.androidaps.utils.SP;
|
||||||
import io.reactivex.disposables.CompositeDisposable;
|
import io.reactivex.disposables.CompositeDisposable;
|
||||||
|
@ -75,35 +76,42 @@ public class ProfileFunctions {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getProfileName() {
|
public String getProfileName() {
|
||||||
return getProfileName(System.currentTimeMillis());
|
return getProfileName(System.currentTimeMillis(), true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getProfileName(boolean customized) {
|
public String getProfileName(boolean customized) {
|
||||||
return getProfileName(System.currentTimeMillis(), customized);
|
return getProfileName(System.currentTimeMillis(), customized, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getProfileName(long time) {
|
public String getProfileNameWithDuration() {
|
||||||
return getProfileName(time, true);
|
return getProfileName(System.currentTimeMillis(), true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getProfileName(long time, boolean customized) {
|
public String getProfileName(long time, boolean customized, boolean showRemainingTime) {
|
||||||
|
String profileName = MainApp.gs(R.string.noprofileselected);
|
||||||
|
|
||||||
TreatmentsInterface activeTreatments = TreatmentsPlugin.getPlugin();
|
TreatmentsInterface activeTreatments = TreatmentsPlugin.getPlugin();
|
||||||
ProfileInterface activeProfile = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface();
|
ProfileInterface activeProfile = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface();
|
||||||
|
|
||||||
ProfileSwitch profileSwitch = activeTreatments.getProfileSwitchFromHistory(time);
|
ProfileSwitch profileSwitch = activeTreatments.getProfileSwitchFromHistory(time);
|
||||||
if (profileSwitch != null) {
|
if (profileSwitch != null) {
|
||||||
if (profileSwitch.profileJson != null) {
|
if (profileSwitch.profileJson != null) {
|
||||||
return customized ? profileSwitch.getCustomizedName() : profileSwitch.profileName;
|
profileName = customized ? profileSwitch.getCustomizedName() : profileSwitch.profileName;
|
||||||
} else {
|
} else {
|
||||||
ProfileStore profileStore = activeProfile.getProfile();
|
ProfileStore profileStore = activeProfile.getProfile();
|
||||||
if (profileStore != null) {
|
if (profileStore != null) {
|
||||||
Profile profile = profileStore.getSpecificProfile(profileSwitch.profileName);
|
Profile profile = profileStore.getSpecificProfile(profileSwitch.profileName);
|
||||||
if (profile != null)
|
if (profile != null)
|
||||||
return profileSwitch.profileName;
|
profileName = profileSwitch.profileName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (showRemainingTime && profileSwitch.durationInMinutes != 0) {
|
||||||
|
profileName += DateUtil.untilString(profileSwitch.originalEnd());
|
||||||
|
}
|
||||||
|
return profileName;
|
||||||
}
|
}
|
||||||
return MainApp.gs(R.string.noprofileselected);
|
return profileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isProfileValid(String from) {
|
public boolean isProfileValid(String from) {
|
||||||
|
@ -176,7 +184,7 @@ public class ProfileFunctions {
|
||||||
profileSwitch = new ProfileSwitch();
|
profileSwitch = new ProfileSwitch();
|
||||||
profileSwitch.date = System.currentTimeMillis();
|
profileSwitch.date = System.currentTimeMillis();
|
||||||
profileSwitch.source = Source.USER;
|
profileSwitch.source = Source.USER;
|
||||||
profileSwitch.profileName = getInstance().getProfileName(System.currentTimeMillis(), false);
|
profileSwitch.profileName = getInstance().getProfileName(System.currentTimeMillis(), false, false);
|
||||||
profileSwitch.profileJson = getInstance().getProfile().getData().toString();
|
profileSwitch.profileJson = getInstance().getProfile().getData().toString();
|
||||||
profileSwitch.profilePlugin = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getClass().getName();
|
profileSwitch.profilePlugin = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getClass().getName();
|
||||||
profileSwitch.durationInMinutes = duration;
|
profileSwitch.durationInMinutes = duration;
|
||||||
|
|
|
@ -22,7 +22,7 @@ import info.nightscout.androidaps.plugins.general.overview.notifications.Notific
|
||||||
|
|
||||||
public class DstHelperPlugin extends PluginBase implements ConstraintsInterface {
|
public class DstHelperPlugin extends PluginBase implements ConstraintsInterface {
|
||||||
public static final int DISABLE_TIMEFRAME_HOURS = -3;
|
public static final int DISABLE_TIMEFRAME_HOURS = -3;
|
||||||
public static final int WARN_PRIOR_TIMEFRAME_HOURS = 24;
|
public static final int WARN_PRIOR_TIMEFRAME_HOURS = 12;
|
||||||
private static Logger log = LoggerFactory.getLogger(L.CONSTRAINTS);
|
private static Logger log = LoggerFactory.getLogger(L.CONSTRAINTS);
|
||||||
|
|
||||||
static DstHelperPlugin plugin = null;
|
static DstHelperPlugin plugin = null;
|
||||||
|
|
|
@ -204,7 +204,7 @@ class ObjectivesFragment : Fragment() {
|
||||||
holder.accomplished.setTextColor(-0x3e3e3f)
|
holder.accomplished.setTextColor(-0x3e3e3f)
|
||||||
holder.verify.setOnClickListener {
|
holder.verify.setOnClickListener {
|
||||||
holder.verify.visibility = View.INVISIBLE
|
holder.verify.visibility = View.INVISIBLE
|
||||||
NetworkChangeReceiver.fetch()
|
NetworkChangeReceiver.grabNetworkStatus(context)
|
||||||
if (objectives_fake.isChecked) {
|
if (objectives_fake.isChecked) {
|
||||||
objective.accomplishedOn = DateUtil.now()
|
objective.accomplishedOn = DateUtil.now()
|
||||||
scrollToCurrentObjective()
|
scrollToCurrentObjective()
|
||||||
|
@ -236,7 +236,7 @@ class ObjectivesFragment : Fragment() {
|
||||||
}
|
}
|
||||||
holder.start.setOnClickListener {
|
holder.start.setOnClickListener {
|
||||||
holder.start.visibility = View.INVISIBLE
|
holder.start.visibility = View.INVISIBLE
|
||||||
NetworkChangeReceiver.fetch()
|
NetworkChangeReceiver.grabNetworkStatus(context)
|
||||||
if (objectives_fake.isChecked) {
|
if (objectives_fake.isChecked) {
|
||||||
objective.startedOn = DateUtil.now()
|
objective.startedOn = DateUtil.now()
|
||||||
scrollToCurrentObjective()
|
scrollToCurrentObjective()
|
||||||
|
|
|
@ -105,7 +105,7 @@ object ObjectivesPlugin : PluginBase(PluginDescription()
|
||||||
val requestCode = SP.getString(R.string.key_objectives_request_code, "")
|
val requestCode = SP.getString(R.string.key_objectives_request_code, "")
|
||||||
var url = SP.getString(R.string.key_nsclientinternal_url, "").toLowerCase()
|
var url = SP.getString(R.string.key_nsclientinternal_url, "").toLowerCase()
|
||||||
if (!url.endsWith("\"")) url = "$url/"
|
if (!url.endsWith("\"")) url = "$url/"
|
||||||
val hashNS = Hashing.sha1().hashString(url + BuildConfig.APPLICATION_ID + "/" + requestCode, Charsets.UTF_8).toString()
|
@Suppress("DEPRECATION") val hashNS = Hashing.sha1().hashString(url + BuildConfig.APPLICATION_ID + "/" + requestCode, Charsets.UTF_8).toString()
|
||||||
if (request.equals(hashNS.substring(0, 10), ignoreCase = true)) {
|
if (request.equals(hashNS.substring(0, 10), ignoreCase = true)) {
|
||||||
SP.putLong("Objectives_" + "openloop" + "_started", DateUtil.now())
|
SP.putLong("Objectives_" + "openloop" + "_started", DateUtil.now())
|
||||||
SP.putLong("Objectives_" + "openloop" + "_accomplished", DateUtil.now())
|
SP.putLong("Objectives_" + "openloop" + "_accomplished", DateUtil.now())
|
||||||
|
|
|
@ -10,8 +10,11 @@ import java.util.List;
|
||||||
import info.nightscout.androidaps.plugins.general.automation.actions.Action;
|
import info.nightscout.androidaps.plugins.general.automation.actions.Action;
|
||||||
import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger;
|
import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger;
|
||||||
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector;
|
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class AutomationEvent {
|
public class AutomationEvent {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(AutomationEvent.class);
|
||||||
|
|
||||||
private Trigger trigger = new TriggerConnector();
|
private Trigger trigger = new TriggerConnector();
|
||||||
private List<Action> actions = new ArrayList<>();
|
private List<Action> actions = new ArrayList<>();
|
||||||
|
@ -74,7 +77,7 @@ public class AutomationEvent {
|
||||||
}
|
}
|
||||||
o.put("actions", array);
|
o.put("actions", array);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return o.toString();
|
return o.toString();
|
||||||
}
|
}
|
||||||
|
@ -91,7 +94,7 @@ public class AutomationEvent {
|
||||||
actions.add(Action.instantiate(new JSONObject(array.getString(i))));
|
actions.add(Action.instantiate(new JSONObject(array.getString(i))));
|
||||||
}
|
}
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,8 @@ import javax.annotation.Nullable;
|
||||||
|
|
||||||
import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger;
|
import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger;
|
||||||
import info.nightscout.androidaps.queue.Callback;
|
import info.nightscout.androidaps.queue.Callback;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Action ideas:
|
Action ideas:
|
||||||
|
@ -44,6 +46,7 @@ import info.nightscout.androidaps.queue.Callback;
|
||||||
|
|
||||||
|
|
||||||
public abstract class Action {
|
public abstract class Action {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(Action.class);
|
||||||
|
|
||||||
public Trigger precondition = null;
|
public Trigger precondition = null;
|
||||||
|
|
||||||
|
@ -65,7 +68,7 @@ public abstract class Action {
|
||||||
try {
|
try {
|
||||||
o.put("type", this.getClass().getName());
|
o.put("type", this.getClass().getName());
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return o.toString();
|
return o.toString();
|
||||||
}
|
}
|
||||||
|
@ -84,7 +87,7 @@ public abstract class Action {
|
||||||
Class clazz = Class.forName(type);
|
Class clazz = Class.forName(type);
|
||||||
return ((Action) clazz.newInstance()).fromJSON(data != null ? data.toString() : "");
|
return ((Action) clazz.newInstance()).fromJSON(data != null ? data.toString() : "");
|
||||||
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | JSONException e) {
|
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -98,7 +101,7 @@ public abstract class Action {
|
||||||
fromJSON(data.toString());
|
fromJSON(data.toString());
|
||||||
}
|
}
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,12 @@ import info.nightscout.androidaps.plugins.general.automation.elements.LabelWithE
|
||||||
import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder;
|
import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder;
|
||||||
import info.nightscout.androidaps.queue.Callback;
|
import info.nightscout.androidaps.queue.Callback;
|
||||||
import info.nightscout.androidaps.utils.JsonHelper;
|
import info.nightscout.androidaps.utils.JsonHelper;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class ActionLoopSuspend extends Action {
|
public class ActionLoopSuspend extends Action {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(ActionLoopSuspend.class);
|
||||||
|
|
||||||
public InputDuration minutes = new InputDuration(0, InputDuration.TimeUnit.MINUTES);
|
public InputDuration minutes = new InputDuration(0, InputDuration.TimeUnit.MINUTES);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -59,7 +63,7 @@ public class ActionLoopSuspend extends Action {
|
||||||
o.put("type", this.getClass().getName());
|
o.put("type", this.getClass().getName());
|
||||||
o.put("data", data);
|
o.put("data", data);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return o.toString();
|
return o.toString();
|
||||||
}
|
}
|
||||||
|
@ -70,7 +74,7 @@ public class ActionLoopSuspend extends Action {
|
||||||
JSONObject o = new JSONObject(data);
|
JSONObject o = new JSONObject(data);
|
||||||
minutes.setMinutes(JsonHelper.safeGetInt(o, "minutes"));
|
minutes.setMinutes(JsonHelper.safeGetInt(o, "minutes"));
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,8 +20,12 @@ import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotifi
|
||||||
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
|
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
|
||||||
import info.nightscout.androidaps.queue.Callback;
|
import info.nightscout.androidaps.queue.Callback;
|
||||||
import info.nightscout.androidaps.utils.JsonHelper;
|
import info.nightscout.androidaps.utils.JsonHelper;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class ActionNotification extends Action {
|
public class ActionNotification extends Action {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(ActionNotification.class);
|
||||||
|
|
||||||
public InputString text = new InputString();
|
public InputString text = new InputString();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -59,7 +63,7 @@ public class ActionNotification extends Action {
|
||||||
o.put("type", this.getClass().getName());
|
o.put("type", this.getClass().getName());
|
||||||
o.put("data", data);
|
o.put("data", data);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return o.toString();
|
return o.toString();
|
||||||
}
|
}
|
||||||
|
@ -70,7 +74,7 @@ public class ActionNotification extends Action {
|
||||||
JSONObject o = new JSONObject(data);
|
JSONObject o = new JSONObject(data);
|
||||||
text.setValue(JsonHelper.safeGetString(o, "text"));
|
text.setValue(JsonHelper.safeGetString(o, "text"));
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,7 +92,7 @@ public class ActionProfileSwitch extends Action {
|
||||||
data.put("profileToSwitchTo", inputProfileName.getValue());
|
data.put("profileToSwitchTo", inputProfileName.getValue());
|
||||||
o.put("data", data);
|
o.put("data", data);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return o.toString();
|
return o.toString();
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,7 @@ public class ActionProfileSwitch extends Action {
|
||||||
profileName = JsonHelper.safeGetString(d, "profileToSwitchTo");
|
profileName = JsonHelper.safeGetString(d, "profileToSwitchTo");
|
||||||
inputProfileName.setValue(profileName);
|
inputProfileName.setValue(profileName);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,8 +19,12 @@ import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuil
|
||||||
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerProfilePercent;
|
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerProfilePercent;
|
||||||
import info.nightscout.androidaps.queue.Callback;
|
import info.nightscout.androidaps.queue.Callback;
|
||||||
import info.nightscout.androidaps.utils.JsonHelper;
|
import info.nightscout.androidaps.utils.JsonHelper;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class ActionProfileSwitchPercent extends Action {
|
public class ActionProfileSwitchPercent extends Action {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(ActionProfileSwitchPercent.class);
|
||||||
|
|
||||||
InputPercent pct = new InputPercent();
|
InputPercent pct = new InputPercent();
|
||||||
InputDuration duration = new InputDuration(0, InputDuration.TimeUnit.MINUTES);
|
InputDuration duration = new InputDuration(0, InputDuration.TimeUnit.MINUTES);
|
||||||
|
|
||||||
|
@ -71,7 +75,7 @@ public class ActionProfileSwitchPercent extends Action {
|
||||||
data.put("durationInMinutes", duration.getMinutes());
|
data.put("durationInMinutes", duration.getMinutes());
|
||||||
o.put("data", data);
|
o.put("data", data);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return o.toString();
|
return o.toString();
|
||||||
}
|
}
|
||||||
|
@ -83,7 +87,7 @@ public class ActionProfileSwitchPercent extends Action {
|
||||||
pct.setValue(JsonHelper.safeGetInt(d, "percentage"));
|
pct.setValue(JsonHelper.safeGetInt(d, "percentage"));
|
||||||
duration.setMinutes(JsonHelper.safeGetInt(d, "durationInMinutes"));
|
duration.setMinutes(JsonHelper.safeGetInt(d, "durationInMinutes"));
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import info.nightscout.androidaps.queue.Callback;
|
||||||
import info.nightscout.androidaps.utils.JsonHelper;
|
import info.nightscout.androidaps.utils.JsonHelper;
|
||||||
|
|
||||||
public class ActionSendSMS extends Action {
|
public class ActionSendSMS extends Action {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(ActionSendSMS.class);
|
||||||
|
|
||||||
public InputString text = new InputString();
|
public InputString text = new InputString();
|
||||||
|
|
||||||
|
@ -36,7 +37,7 @@ public class ActionSendSMS extends Action {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doAction(Callback callback) {
|
public void doAction(Callback callback) {
|
||||||
boolean result = SmsCommunicatorPlugin.getPlugin().sendNotificationToAllNumbers(text.getValue());
|
boolean result = SmsCommunicatorPlugin.INSTANCE.sendNotificationToAllNumbers(text.getValue());
|
||||||
if (callback != null)
|
if (callback != null)
|
||||||
callback.result(new PumpEnactResult().success(result).comment(result ? R.string.ok : R.string.danar_error)).run();
|
callback.result(new PumpEnactResult().success(result).comment(result ? R.string.ok : R.string.danar_error)).run();
|
||||||
|
|
||||||
|
@ -56,7 +57,7 @@ public class ActionSendSMS extends Action {
|
||||||
o.put("type", this.getClass().getName());
|
o.put("type", this.getClass().getName());
|
||||||
o.put("data", data);
|
o.put("data", data);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return o.toString();
|
return o.toString();
|
||||||
}
|
}
|
||||||
|
@ -67,7 +68,7 @@ public class ActionSendSMS extends Action {
|
||||||
JSONObject o = new JSONObject(data);
|
JSONObject o = new JSONObject(data);
|
||||||
text.setValue(JsonHelper.safeGetString(o, "text"));
|
text.setValue(JsonHelper.safeGetString(o, "text"));
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,8 +24,12 @@ import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.androidaps.queue.Callback;
|
import info.nightscout.androidaps.queue.Callback;
|
||||||
import info.nightscout.androidaps.utils.DateUtil;
|
import info.nightscout.androidaps.utils.DateUtil;
|
||||||
import info.nightscout.androidaps.utils.JsonHelper;
|
import info.nightscout.androidaps.utils.JsonHelper;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class ActionStartTempTarget extends Action {
|
public class ActionStartTempTarget extends Action {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(ActionStartTempTarget.class);
|
||||||
|
|
||||||
String reason = "";
|
String reason = "";
|
||||||
InputTempTarget value = new InputTempTarget();
|
InputTempTarget value = new InputTempTarget();
|
||||||
InputDuration duration = new InputDuration(0, InputDuration.TimeUnit.MINUTES);
|
InputDuration duration = new InputDuration(0, InputDuration.TimeUnit.MINUTES);
|
||||||
|
@ -93,7 +97,7 @@ public class ActionStartTempTarget extends Action {
|
||||||
data.put("durationInMinutes", duration.getMinutes());
|
data.put("durationInMinutes", duration.getMinutes());
|
||||||
o.put("data", data);
|
o.put("data", data);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return o.toString();
|
return o.toString();
|
||||||
}
|
}
|
||||||
|
@ -107,7 +111,7 @@ public class ActionStartTempTarget extends Action {
|
||||||
value.setValue(JsonHelper.safeGetDouble(d, "value"));
|
value.setValue(JsonHelper.safeGetDouble(d, "value"));
|
||||||
duration.setMinutes(JsonHelper.safeGetInt(d, "durationInMinutes"));
|
duration.setMinutes(JsonHelper.safeGetInt(d, "durationInMinutes"));
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,8 +14,12 @@ import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.androidaps.queue.Callback;
|
import info.nightscout.androidaps.queue.Callback;
|
||||||
import info.nightscout.androidaps.utils.DateUtil;
|
import info.nightscout.androidaps.utils.DateUtil;
|
||||||
import info.nightscout.androidaps.utils.JsonHelper;
|
import info.nightscout.androidaps.utils.JsonHelper;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class ActionStopTempTarget extends Action {
|
public class ActionStopTempTarget extends Action {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(ActionStopTempTarget.class);
|
||||||
|
|
||||||
String reason = "";
|
String reason = "";
|
||||||
private TempTarget tempTarget;
|
private TempTarget tempTarget;
|
||||||
|
|
||||||
|
@ -54,7 +58,7 @@ public class ActionStopTempTarget extends Action {
|
||||||
data.put("reason", reason);
|
data.put("reason", reason);
|
||||||
o.put("data", data);
|
o.put("data", data);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return o.toString();
|
return o.toString();
|
||||||
}
|
}
|
||||||
|
@ -65,7 +69,7 @@ public class ActionStopTempTarget extends Action {
|
||||||
JSONObject d = new JSONObject(data);
|
JSONObject d = new JSONObject(data);
|
||||||
reason = JsonHelper.safeGetString(d, "reason");
|
reason = JsonHelper.safeGetString(d, "reason");
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,10 +13,13 @@ import com.google.common.base.Optional;
|
||||||
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public abstract class Trigger {
|
public abstract class Trigger {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(Trigger.class);
|
||||||
|
|
||||||
TriggerConnector connector = null;
|
TriggerConnector connector = null;
|
||||||
long lastRun;
|
long lastRun;
|
||||||
|
@ -56,7 +59,7 @@ public abstract class Trigger {
|
||||||
try {
|
try {
|
||||||
return instantiate(new JSONObject(json));
|
return instantiate(new JSONObject(json));
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -69,7 +72,7 @@ public abstract class Trigger {
|
||||||
Class clazz = Class.forName(type);
|
Class clazz = Class.forName(type);
|
||||||
return ((Trigger) clazz.newInstance()).fromJSON(data.toString());
|
return ((Trigger) clazz.newInstance()).fromJSON(data.toString());
|
||||||
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | JSONException e) {
|
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,7 +89,7 @@ public class TriggerAutosensValue extends Trigger {
|
||||||
data.put("comparator", comparator.getValue().toString());
|
data.put("comparator", comparator.getValue().toString());
|
||||||
o.put("data", data);
|
o.put("data", data);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return o.toString();
|
return o.toString();
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,7 @@ public class TriggerAutosensValue extends Trigger {
|
||||||
lastRun = JsonHelper.safeGetLong(d, "lastRun");
|
lastRun = JsonHelper.safeGetLong(d, "lastRun");
|
||||||
comparator.setValue(Comparator.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")));
|
comparator.setValue(Comparator.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,7 +104,7 @@ public class TriggerBg extends Trigger {
|
||||||
data.put("units", bg.getUnits());
|
data.put("units", bg.getUnits());
|
||||||
o.put("data", data);
|
o.put("data", data);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return o.toString();
|
return o.toString();
|
||||||
}
|
}
|
||||||
|
@ -118,7 +118,7 @@ public class TriggerBg extends Trigger {
|
||||||
lastRun = JsonHelper.safeGetLong(d, "lastRun");
|
lastRun = JsonHelper.safeGetLong(d, "lastRun");
|
||||||
comparator.setValue(Comparator.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")));
|
comparator.setValue(Comparator.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,7 @@ public class TriggerBolusAgo extends Trigger {
|
||||||
data.put("comparator", comparator.getValue().toString());
|
data.put("comparator", comparator.getValue().toString());
|
||||||
o.put("data", data);
|
o.put("data", data);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return o.toString();
|
return o.toString();
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ public class TriggerBolusAgo extends Trigger {
|
||||||
lastRun = JsonHelper.safeGetLong(d, "lastRun");
|
lastRun = JsonHelper.safeGetLong(d, "lastRun");
|
||||||
comparator.setValue(Comparator.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")));
|
comparator.setValue(Comparator.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,7 @@ public class TriggerCOB extends Trigger {
|
||||||
data.put("comparator", comparator.getValue().toString());
|
data.put("comparator", comparator.getValue().toString());
|
||||||
o.put("data", data);
|
o.put("data", data);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return o.toString();
|
return o.toString();
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ public class TriggerCOB extends Trigger {
|
||||||
lastRun = JsonHelper.safeGetLong(d, "lastRun");
|
lastRun = JsonHelper.safeGetLong(d, "lastRun");
|
||||||
comparator.setValue(Comparator.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")));
|
comparator.setValue(Comparator.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,7 +162,7 @@ public class TriggerConnector extends Trigger {
|
||||||
data.put("triggerList", array);
|
data.put("triggerList", array);
|
||||||
o.put("data", data);
|
o.put("data", data);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return o.toString();
|
return o.toString();
|
||||||
}
|
}
|
||||||
|
@ -179,7 +179,7 @@ public class TriggerConnector extends Trigger {
|
||||||
add(newItem);
|
add(newItem);
|
||||||
}
|
}
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,7 +129,7 @@ public class TriggerDelta extends Trigger {
|
||||||
data.put("comparator", comparator.getValue().toString());
|
data.put("comparator", comparator.getValue().toString());
|
||||||
o.put("data", data);
|
o.put("data", data);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return o.toString();
|
return o.toString();
|
||||||
}
|
}
|
||||||
|
@ -144,7 +144,7 @@ public class TriggerDelta extends Trigger {
|
||||||
lastRun = JsonHelper.safeGetLong(d, "lastRun");
|
lastRun = JsonHelper.safeGetLong(d, "lastRun");
|
||||||
comparator.setValue(Comparator.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")));
|
comparator.setValue(Comparator.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,7 @@ public class TriggerIob extends Trigger {
|
||||||
data.put("comparator", comparator.getValue().toString());
|
data.put("comparator", comparator.getValue().toString());
|
||||||
o.put("data", data);
|
o.put("data", data);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return o.toString();
|
return o.toString();
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,7 @@ public class TriggerIob extends Trigger {
|
||||||
lastRun = JsonHelper.safeGetLong(d, "lastRun");
|
lastRun = JsonHelper.safeGetLong(d, "lastRun");
|
||||||
comparator.setValue(Comparator.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")));
|
comparator.setValue(Comparator.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,7 +93,7 @@ public class TriggerLocation extends Trigger {
|
||||||
data.put("lastRun", lastRun);
|
data.put("lastRun", lastRun);
|
||||||
o.put("data", data);
|
o.put("data", data);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return o.toString();
|
return o.toString();
|
||||||
}
|
}
|
||||||
|
@ -108,7 +108,7 @@ public class TriggerLocation extends Trigger {
|
||||||
name.setValue(JsonHelper.safeGetString(d, "name"));
|
name.setValue(JsonHelper.safeGetString(d, "name"));
|
||||||
lastRun = JsonHelper.safeGetLong(d, "lastRun");
|
lastRun = JsonHelper.safeGetLong(d, "lastRun");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,7 +88,7 @@ public class TriggerProfilePercent extends Trigger {
|
||||||
data.put("comparator", comparator.getValue().toString());
|
data.put("comparator", comparator.getValue().toString());
|
||||||
o.put("data", data);
|
o.put("data", data);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return o.toString();
|
return o.toString();
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,7 @@ public class TriggerProfilePercent extends Trigger {
|
||||||
lastRun = JsonHelper.safeGetLong(d, "lastRun");
|
lastRun = JsonHelper.safeGetLong(d, "lastRun");
|
||||||
comparator.setValue(Comparator.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")));
|
comparator.setValue(Comparator.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,7 @@ public class TriggerPumpLastConnection extends Trigger {
|
||||||
data.put("comparator", comparator.getValue().toString());
|
data.put("comparator", comparator.getValue().toString());
|
||||||
o.put("data", data);
|
o.put("data", data);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return o.toString();
|
return o.toString();
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,7 @@ public class TriggerPumpLastConnection extends Trigger {
|
||||||
lastRun = JsonHelper.safeGetLong(d, "lastRun");
|
lastRun = JsonHelper.safeGetLong(d, "lastRun");
|
||||||
comparator.setValue(Comparator.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")));
|
comparator.setValue(Comparator.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,7 +163,7 @@ public class TriggerRecurringTime extends Trigger {
|
||||||
object.put("type", TriggerRecurringTime.class.getName());
|
object.put("type", TriggerRecurringTime.class.getName());
|
||||||
object.put("data", data);
|
object.put("data", data);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return object.toString();
|
return object.toString();
|
||||||
}
|
}
|
||||||
|
@ -181,7 +181,7 @@ public class TriggerRecurringTime extends Trigger {
|
||||||
minute = JsonHelper.safeGetInt(o, "minute");
|
minute = JsonHelper.safeGetInt(o, "minute");
|
||||||
validTo = JsonHelper.safeGetLong(o, "validTo");
|
validTo = JsonHelper.safeGetLong(o, "validTo");
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,7 @@ public class TriggerTempTarget extends Trigger {
|
||||||
data.put("comparator", comparator.getValue().toString());
|
data.put("comparator", comparator.getValue().toString());
|
||||||
o.put("data", data);
|
o.put("data", data);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return o.toString();
|
return o.toString();
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ public class TriggerTempTarget extends Trigger {
|
||||||
lastRun = JsonHelper.safeGetLong(d, "lastRun");
|
lastRun = JsonHelper.safeGetLong(d, "lastRun");
|
||||||
comparator.setValue(ComparatorExists.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")));
|
comparator.setValue(ComparatorExists.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ public class TriggerTime extends Trigger {
|
||||||
object.put("type", TriggerTime.class.getName());
|
object.put("type", TriggerTime.class.getName());
|
||||||
object.put("data", data);
|
object.put("data", data);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return object.toString();
|
return object.toString();
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ public class TriggerTime extends Trigger {
|
||||||
lastRun = JsonHelper.safeGetLong(o, "lastRun");
|
lastRun = JsonHelper.safeGetLong(o, "lastRun");
|
||||||
runAt = JsonHelper.safeGetLong(o, "runAt");
|
runAt = JsonHelper.safeGetLong(o, "runAt");
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,7 +93,7 @@ public class TriggerTimeRange extends Trigger {
|
||||||
object.put("type", TriggerTimeRange.class.getName());
|
object.put("type", TriggerTimeRange.class.getName());
|
||||||
object.put("data", data);
|
object.put("data", data);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
log.debug(object.toString());
|
log.debug(object.toString());
|
||||||
return object.toString();
|
return object.toString();
|
||||||
|
@ -108,7 +108,7 @@ public class TriggerTimeRange extends Trigger {
|
||||||
start = JsonHelper.safeGetInt(o, "start");
|
start = JsonHelper.safeGetInt(o, "start");
|
||||||
end = JsonHelper.safeGetInt(o, "end");
|
end = JsonHelper.safeGetInt(o, "end");
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,7 +85,7 @@ public class TriggerWifiSsid extends Trigger {
|
||||||
data.put("comparator", comparator.getValue().toString());
|
data.put("comparator", comparator.getValue().toString());
|
||||||
o.put("data", data);
|
o.put("data", data);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return o.toString();
|
return o.toString();
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ public class TriggerWifiSsid extends Trigger {
|
||||||
lastRun = JsonHelper.safeGetLong(d, "lastRun");
|
lastRun = JsonHelper.safeGetLong(d, "lastRun");
|
||||||
comparator.setValue(Comparator.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")));
|
comparator.setValue(Comparator.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,9 +7,12 @@ import android.content.ServiceConnection;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.HandlerThread;
|
import android.os.HandlerThread;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.preference.PreferenceFragment;
|
||||||
|
import android.preference.PreferenceScreen;
|
||||||
import android.text.Html;
|
import android.text.Html;
|
||||||
import android.text.Spanned;
|
import android.text.Spanned;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -89,7 +92,7 @@ public class NSClientPlugin extends PluginBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
nsClientReceiverDelegate =
|
nsClientReceiverDelegate =
|
||||||
new NsClientReceiverDelegate(MainApp.instance().getApplicationContext());
|
new NsClientReceiverDelegate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isAllowed() {
|
public boolean isAllowed() {
|
||||||
|
@ -104,7 +107,7 @@ public class NSClientPlugin extends PluginBase {
|
||||||
context.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
|
context.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
|
||||||
super.onStart();
|
super.onStart();
|
||||||
|
|
||||||
nsClientReceiverDelegate.registerReceivers();
|
nsClientReceiverDelegate.grabReceiversState();
|
||||||
disposable.add(RxBus.INSTANCE
|
disposable.add(RxBus.INSTANCE
|
||||||
.toObservable(EventNSClientStatus.class)
|
.toObservable(EventNSClientStatus.class)
|
||||||
.observeOn(Schedulers.io())
|
.observeOn(Schedulers.io())
|
||||||
|
@ -129,7 +132,6 @@ public class NSClientPlugin extends PluginBase {
|
||||||
.subscribe(event -> {
|
.subscribe(event -> {
|
||||||
if (nsClientService != null) {
|
if (nsClientService != null) {
|
||||||
MainApp.instance().getApplicationContext().unbindService(mConnection);
|
MainApp.instance().getApplicationContext().unbindService(mConnection);
|
||||||
nsClientReceiverDelegate.unregisterReceivers();
|
|
||||||
}
|
}
|
||||||
}, FabricPrivacy::logException)
|
}, FabricPrivacy::logException)
|
||||||
);
|
);
|
||||||
|
@ -152,11 +154,27 @@ public class NSClientPlugin extends PluginBase {
|
||||||
@Override
|
@Override
|
||||||
protected void onStop() {
|
protected void onStop() {
|
||||||
MainApp.instance().getApplicationContext().unbindService(mConnection);
|
MainApp.instance().getApplicationContext().unbindService(mConnection);
|
||||||
nsClientReceiverDelegate.unregisterReceivers();
|
|
||||||
disposable.clear();
|
disposable.clear();
|
||||||
super.onStop();
|
super.onStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void preprocessPreferences(@NotNull PreferenceFragment preferenceFragment) {
|
||||||
|
super.preprocessPreferences(preferenceFragment);
|
||||||
|
|
||||||
|
if (Config.NSCLIENT) {
|
||||||
|
PreferenceScreen scrnAdvancedSettings = (PreferenceScreen) preferenceFragment.findPreference(MainApp.gs(R.string.key_advancedsettings));
|
||||||
|
if (scrnAdvancedSettings != null) {
|
||||||
|
scrnAdvancedSettings.removePreference(preferenceFragment.findPreference(MainApp.gs(R.string.key_statuslights_res_warning)));
|
||||||
|
scrnAdvancedSettings.removePreference(preferenceFragment.findPreference(MainApp.gs(R.string.key_statuslights_res_critical)));
|
||||||
|
scrnAdvancedSettings.removePreference(preferenceFragment.findPreference(MainApp.gs(R.string.key_statuslights_bat_warning)));
|
||||||
|
scrnAdvancedSettings.removePreference(preferenceFragment.findPreference(MainApp.gs(R.string.key_statuslights_bat_critical)));
|
||||||
|
scrnAdvancedSettings.removePreference(preferenceFragment.findPreference(MainApp.gs(R.string.key_show_statuslights)));
|
||||||
|
scrnAdvancedSettings.removePreference(preferenceFragment.findPreference(MainApp.gs(R.string.key_show_statuslights_extended)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private ServiceConnection mConnection = new ServiceConnection() {
|
private ServiceConnection mConnection = new ServiceConnection() {
|
||||||
|
|
||||||
public void onServiceDisconnected(ComponentName name) {
|
public void onServiceDisconnected(ComponentName name) {
|
||||||
|
|
|
@ -594,7 +594,7 @@ public class NSUpload {
|
||||||
|
|
||||||
|
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,44 +18,19 @@ import info.nightscout.androidaps.utils.SP;
|
||||||
|
|
||||||
class NsClientReceiverDelegate {
|
class NsClientReceiverDelegate {
|
||||||
|
|
||||||
private final Context context;
|
|
||||||
|
|
||||||
private NetworkChangeReceiver networkChangeReceiver = new NetworkChangeReceiver();
|
|
||||||
private ChargingStateReceiver chargingStateReceiver = new ChargingStateReceiver();
|
|
||||||
|
|
||||||
private boolean allowedChargingState = true;
|
private boolean allowedChargingState = true;
|
||||||
private boolean allowedNetworkState = true;
|
private boolean allowedNetworkState = true;
|
||||||
boolean allowed = true;
|
boolean allowed = true;
|
||||||
|
|
||||||
NsClientReceiverDelegate(Context context) {
|
void grabReceiversState() {
|
||||||
this.context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
void registerReceivers() {
|
|
||||||
Context context = MainApp.instance().getApplicationContext();
|
Context context = MainApp.instance().getApplicationContext();
|
||||||
// register NetworkChangeReceiver --> https://developer.android.com/training/monitoring-device-state/connectivity-monitoring.html
|
|
||||||
// Nougat is not providing Connectivity-Action anymore ;-(
|
|
||||||
context.registerReceiver(networkChangeReceiver,
|
|
||||||
new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
|
|
||||||
context.registerReceiver(networkChangeReceiver,
|
|
||||||
new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION));
|
|
||||||
|
|
||||||
EventNetworkChange event = networkChangeReceiver.grabNetworkStatus(context);
|
EventNetworkChange event = NetworkChangeReceiver.grabNetworkStatus(context);
|
||||||
if (event != null)
|
if (event != null) RxBus.INSTANCE.send(event);
|
||||||
RxBus.INSTANCE.send(event);
|
|
||||||
|
|
||||||
context.registerReceiver(chargingStateReceiver,
|
EventChargingState eventChargingState = ChargingStateReceiver.grabChargingState(context);
|
||||||
new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
|
if (eventChargingState != null) RxBus.INSTANCE.send(eventChargingState);
|
||||||
|
|
||||||
EventChargingState eventChargingState = chargingStateReceiver.grabChargingState(context);
|
|
||||||
if (eventChargingState != null)
|
|
||||||
RxBus.INSTANCE.send(eventChargingState);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void unregisterReceivers() {
|
|
||||||
context.unregisterReceiver(networkChangeReceiver);
|
|
||||||
context.unregisterReceiver(chargingStateReceiver);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void onStatusEvent(EventPreferenceChange ev) {
|
void onStatusEvent(EventPreferenceChange ev) {
|
||||||
|
@ -63,11 +38,11 @@ class NsClientReceiverDelegate {
|
||||||
ev.isChanged(R.string.key_ns_wifi_ssids) ||
|
ev.isChanged(R.string.key_ns_wifi_ssids) ||
|
||||||
ev.isChanged(R.string.key_ns_allowroaming)
|
ev.isChanged(R.string.key_ns_allowroaming)
|
||||||
) {
|
) {
|
||||||
EventNetworkChange event = networkChangeReceiver.grabNetworkStatus(MainApp.instance().getApplicationContext());
|
EventNetworkChange event = NetworkChangeReceiver.grabNetworkStatus(MainApp.instance().getApplicationContext());
|
||||||
if (event != null)
|
if (event != null)
|
||||||
RxBus.INSTANCE.send(event);
|
RxBus.INSTANCE.send(event);
|
||||||
} else if (ev.isChanged(R.string.key_ns_chargingonly)) {
|
} else if (ev.isChanged(R.string.key_ns_chargingonly)) {
|
||||||
EventChargingState event = chargingStateReceiver.grabChargingState(MainApp.instance().getApplicationContext());
|
EventChargingState event = ChargingStateReceiver.grabChargingState(MainApp.instance().getApplicationContext());
|
||||||
if (event != null)
|
if (event != null)
|
||||||
RxBus.INSTANCE.send(event);
|
RxBus.INSTANCE.send(event);
|
||||||
}
|
}
|
||||||
|
@ -91,7 +66,7 @@ class NsClientReceiverDelegate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void processStateChange() {
|
private void processStateChange() {
|
||||||
boolean newAllowedState = allowedChargingState && allowedNetworkState;
|
boolean newAllowedState = allowedChargingState && allowedNetworkState;
|
||||||
if (newAllowedState != allowed) {
|
if (newAllowedState != allowed) {
|
||||||
allowed = newAllowedState;
|
allowed = newAllowedState;
|
||||||
|
@ -101,7 +76,6 @@ class NsClientReceiverDelegate {
|
||||||
|
|
||||||
boolean calculateStatus(final EventChargingState ev) {
|
boolean calculateStatus(final EventChargingState ev) {
|
||||||
boolean chargingOnly = SP.getBoolean(R.string.key_ns_chargingonly, false);
|
boolean chargingOnly = SP.getBoolean(R.string.key_ns_chargingonly, false);
|
||||||
|
|
||||||
boolean newAllowedState = true;
|
boolean newAllowedState = true;
|
||||||
|
|
||||||
if (!ev.isCharging() && chargingOnly) {
|
if (!ev.isCharging() && chargingOnly) {
|
||||||
|
@ -129,8 +103,6 @@ class NsClientReceiverDelegate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return newAllowedState;
|
return newAllowedState;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1223,7 +1223,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
||||||
extendedBolusView.setVisibility(View.VISIBLE);
|
extendedBolusView.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
activeProfileView.setText(ProfileFunctions.getInstance().getProfileName());
|
activeProfileView.setText(ProfileFunctions.getInstance().getProfileNameWithDuration());
|
||||||
if (profile.getPercentage() != 100 || profile.getTimeshift() != 0) {
|
if (profile.getPercentage() != 100 || profile.getTimeshift() != 0) {
|
||||||
activeProfileView.setBackgroundColor(MainApp.gc(R.color.ribbonWarning));
|
activeProfileView.setBackgroundColor(MainApp.gc(R.color.ribbonWarning));
|
||||||
activeProfileView.setTextColor(MainApp.gc(R.color.ribbonTextWarning));
|
activeProfileView.setTextColor(MainApp.gc(R.color.ribbonTextWarning));
|
||||||
|
|
|
@ -114,6 +114,7 @@ class WizardDialog : DialogFragment() {
|
||||||
log.debug("guarding: ok already clicked")
|
log.debug("guarding: ok already clicked")
|
||||||
} else {
|
} else {
|
||||||
okClicked = true
|
okClicked = true
|
||||||
|
calculateInsulin()
|
||||||
parentContext?.let { context ->
|
parentContext?.let { context ->
|
||||||
wizard?.confirmAndExecute(context)
|
wizard?.confirmAndExecute(context)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,59 +0,0 @@
|
||||||
package info.nightscout.androidaps.plugins.general.smsCommunicator;
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
class AuthRequest {
|
|
||||||
private static Logger log = LoggerFactory.getLogger(L.SMS);
|
|
||||||
|
|
||||||
Sms requester;
|
|
||||||
String confirmCode;
|
|
||||||
private Runnable action;
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
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)) {
|
|
||||||
processed = true;
|
|
||||||
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) {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
package info.nightscout.androidaps.plugins.general.smsCommunicator
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.Constants
|
||||||
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.logging.L
|
||||||
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
|
||||||
|
class AuthRequest internal constructor(val plugin: SmsCommunicatorPlugin, var requester: Sms, requestText: String, var confirmCode: String, val action: SmsAction) {
|
||||||
|
private val log = LoggerFactory.getLogger(L.SMS)
|
||||||
|
|
||||||
|
private val date = DateUtil.now()
|
||||||
|
private var processed = false
|
||||||
|
|
||||||
|
init {
|
||||||
|
plugin.sendSMS(Sms(requester.phoneNumber, requestText))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun action(codeReceived: String) {
|
||||||
|
if (processed) {
|
||||||
|
if (L.isEnabled(L.SMS)) log.debug("Already processed")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (confirmCode != codeReceived) {
|
||||||
|
processed = true
|
||||||
|
if (L.isEnabled(L.SMS)) log.debug("Wrong code")
|
||||||
|
plugin.sendSMS(Sms(requester.phoneNumber, R.string.sms_wrongcode))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (DateUtil.now() - date < Constants.SMS_CONFIRM_TIMEOUT) {
|
||||||
|
processed = true
|
||||||
|
if (L.isEnabled(L.SMS)) log.debug("Processing confirmed SMS: " + requester.text)
|
||||||
|
action.run()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (L.isEnabled(L.SMS)) log.debug("Timed out SMS: " + requester.text)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,42 +0,0 @@
|
||||||
package info.nightscout.androidaps.plugins.general.smsCommunicator;
|
|
||||||
|
|
||||||
import android.telephony.SmsMessage;
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.MainApp;
|
|
||||||
import info.nightscout.androidaps.utils.DateUtil;
|
|
||||||
|
|
||||||
class Sms {
|
|
||||||
String phoneNumber;
|
|
||||||
String text;
|
|
||||||
long date;
|
|
||||||
boolean received = false;
|
|
||||||
boolean sent = false;
|
|
||||||
boolean processed = false;
|
|
||||||
boolean ignored = false;
|
|
||||||
|
|
||||||
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;
|
|
||||||
this.date = DateUtil.now();
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
package info.nightscout.androidaps.plugins.general.smsCommunicator
|
||||||
|
|
||||||
|
import android.telephony.SmsMessage
|
||||||
|
import info.nightscout.androidaps.MainApp
|
||||||
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
|
|
||||||
|
class Sms {
|
||||||
|
var phoneNumber: String
|
||||||
|
var text: String
|
||||||
|
var date: Long
|
||||||
|
var received = false
|
||||||
|
var sent = false
|
||||||
|
var processed = false
|
||||||
|
var ignored = false
|
||||||
|
|
||||||
|
internal constructor(message: SmsMessage) {
|
||||||
|
phoneNumber = message.originatingAddress ?: ""
|
||||||
|
text = message.messageBody
|
||||||
|
date = message.timestampMillis
|
||||||
|
received = true
|
||||||
|
}
|
||||||
|
|
||||||
|
internal constructor(phoneNumber: String, text: String) {
|
||||||
|
this.phoneNumber = phoneNumber
|
||||||
|
this.text = text
|
||||||
|
date = DateUtil.now()
|
||||||
|
sent = true
|
||||||
|
}
|
||||||
|
|
||||||
|
internal constructor(phoneNumber: String, textId: Int) {
|
||||||
|
this.phoneNumber = phoneNumber
|
||||||
|
text = MainApp.gs(textId)
|
||||||
|
date = DateUtil.now()
|
||||||
|
sent = true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return "SMS from $phoneNumber: $text"
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,33 +0,0 @@
|
||||||
package info.nightscout.androidaps.plugins.general.smsCommunicator;
|
|
||||||
|
|
||||||
abstract class SmsAction implements Runnable {
|
|
||||||
Double aDouble;
|
|
||||||
Integer anInteger;
|
|
||||||
Integer secondInteger;
|
|
||||||
String aString;
|
|
||||||
|
|
||||||
SmsAction() {}
|
|
||||||
|
|
||||||
SmsAction(Double aDouble) {
|
|
||||||
this.aDouble = aDouble;
|
|
||||||
}
|
|
||||||
|
|
||||||
SmsAction(Double aDouble, Integer secondInteger) {
|
|
||||||
this.aDouble = aDouble;
|
|
||||||
this.secondInteger = secondInteger;
|
|
||||||
}
|
|
||||||
|
|
||||||
SmsAction(String aString, Integer secondInteger) {
|
|
||||||
this.aString = aString;
|
|
||||||
this.secondInteger = secondInteger;
|
|
||||||
}
|
|
||||||
|
|
||||||
SmsAction(Integer anInteger) {
|
|
||||||
this.anInteger = anInteger;
|
|
||||||
}
|
|
||||||
|
|
||||||
SmsAction(Integer anInteger, Integer secondInteger) {
|
|
||||||
this.anInteger = anInteger;
|
|
||||||
this.secondInteger = secondInteger;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
package info.nightscout.androidaps.plugins.general.smsCommunicator
|
||||||
|
|
||||||
|
abstract class SmsAction : Runnable {
|
||||||
|
var aDouble: Double? = null
|
||||||
|
var anInteger: Int? = null
|
||||||
|
var secondInteger: Int? = null
|
||||||
|
var secondLong: Long? = null
|
||||||
|
var aString: String? = null
|
||||||
|
|
||||||
|
internal constructor()
|
||||||
|
internal constructor(aDouble: Double) {
|
||||||
|
this.aDouble = aDouble
|
||||||
|
}
|
||||||
|
|
||||||
|
internal constructor(aDouble: Double, secondInteger: Int) {
|
||||||
|
this.aDouble = aDouble
|
||||||
|
this.secondInteger = secondInteger
|
||||||
|
}
|
||||||
|
|
||||||
|
internal constructor(aString: String, secondInteger: Int) {
|
||||||
|
this.aString = aString
|
||||||
|
this.secondInteger = secondInteger
|
||||||
|
}
|
||||||
|
|
||||||
|
internal constructor(anInteger: Int) {
|
||||||
|
this.anInteger = anInteger
|
||||||
|
}
|
||||||
|
|
||||||
|
internal constructor(anInteger: Int, secondInteger: Int) {
|
||||||
|
this.anInteger = anInteger
|
||||||
|
this.secondInteger = secondInteger
|
||||||
|
}
|
||||||
|
|
||||||
|
internal constructor(anInteger: Int, secondLong: Long) {
|
||||||
|
this.anInteger = anInteger
|
||||||
|
this.secondLong = secondLong
|
||||||
|
}
|
||||||
|
|
||||||
|
fun aDouble(): Double {
|
||||||
|
return aDouble?.let {
|
||||||
|
aDouble
|
||||||
|
} ?: throw IllegalStateException()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun anInteger(): Int {
|
||||||
|
return anInteger?.let {
|
||||||
|
anInteger
|
||||||
|
} ?: throw IllegalStateException()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun secondInteger(): Int {
|
||||||
|
return secondInteger?.let {
|
||||||
|
secondInteger
|
||||||
|
} ?: throw IllegalStateException()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun secondLong(): Long {
|
||||||
|
return secondLong?.let {
|
||||||
|
secondLong
|
||||||
|
} ?: throw IllegalStateException()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun aString(): String {
|
||||||
|
return aString?.let {
|
||||||
|
aString
|
||||||
|
} ?: throw IllegalStateException()
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,83 +0,0 @@
|
||||||
package info.nightscout.androidaps.plugins.general.smsCommunicator;
|
|
||||||
|
|
||||||
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.text.Html;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Comparator;
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.R;
|
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBus;
|
|
||||||
import info.nightscout.androidaps.plugins.general.smsCommunicator.events.EventSmsCommunicatorUpdateGui;
|
|
||||||
import info.nightscout.androidaps.utils.DateUtil;
|
|
||||||
import info.nightscout.androidaps.utils.FabricPrivacy;
|
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
|
||||||
import io.reactivex.disposables.CompositeDisposable;
|
|
||||||
|
|
||||||
public class SmsCommunicatorFragment extends Fragment {
|
|
||||||
private CompositeDisposable disposable = new CompositeDisposable();
|
|
||||||
TextView logView;
|
|
||||||
|
|
||||||
public SmsCommunicatorFragment() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
|
||||||
Bundle savedInstanceState) {
|
|
||||||
View view = inflater.inflate(R.layout.smscommunicator_fragment, container, false);
|
|
||||||
|
|
||||||
logView = (TextView) view.findViewById(R.id.smscommunicator_log);
|
|
||||||
|
|
||||||
return view;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
disposable.add(RxBus.INSTANCE
|
|
||||||
.toObservable(EventSmsCommunicatorUpdateGui.class)
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(event -> updateGui(), FabricPrivacy::logException)
|
|
||||||
);
|
|
||||||
updateGui();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized void onPause() {
|
|
||||||
super.onPause();
|
|
||||||
disposable.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void updateGui() {
|
|
||||||
class CustomComparator implements Comparator<Sms> {
|
|
||||||
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++) {
|
|
||||||
Sms sms = SmsCommunicatorPlugin.getPlugin().messages.get(x);
|
|
||||||
if (sms.ignored) {
|
|
||||||
logText += DateUtil.timeString(sms.date) + " <<< " + "░ " + sms.phoneNumber + " <b>" + sms.text + "</b><br>";
|
|
||||||
} else if (sms.received) {
|
|
||||||
logText += DateUtil.timeString(sms.date) + " <<< " + (sms.processed ? "● " : "○ ") + sms.phoneNumber + " <b>" + sms.text + "</b><br>";
|
|
||||||
} else if (sms.sent) {
|
|
||||||
logText += DateUtil.timeString(sms.date) + " >>> " + (sms.processed ? "● " : "○ ") + sms.phoneNumber + " <b>" + sms.text + "</b><br>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
logView.setText(Html.fromHtml(logText));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
package info.nightscout.androidaps.plugins.general.smsCommunicator
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.plugins.bus.RxBus.toObservable
|
||||||
|
import info.nightscout.androidaps.plugins.general.smsCommunicator.events.EventSmsCommunicatorUpdateGui
|
||||||
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
|
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||||
|
import info.nightscout.androidaps.utils.HtmlHelper
|
||||||
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
|
import kotlinx.android.synthetic.main.smscommunicator_fragment.*
|
||||||
|
import java.util.*
|
||||||
|
import kotlin.math.max
|
||||||
|
|
||||||
|
class SmsCommunicatorFragment : Fragment() {
|
||||||
|
private val disposable = CompositeDisposable()
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?): View? {
|
||||||
|
return inflater.inflate(R.layout.smscommunicator_fragment, container, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
disposable.add(toObservable(EventSmsCommunicatorUpdateGui::class.java)
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe({ updateGui() }) { FabricPrivacy.logException(it) }
|
||||||
|
)
|
||||||
|
updateGui()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
|
override fun onPause() {
|
||||||
|
super.onPause()
|
||||||
|
disposable.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateGui() {
|
||||||
|
class CustomComparator : Comparator<Sms> {
|
||||||
|
override fun compare(object1: Sms, object2: Sms): Int {
|
||||||
|
return (object1.date - object2.date).toInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Collections.sort(SmsCommunicatorPlugin.messages, CustomComparator())
|
||||||
|
val messagesToShow = 40
|
||||||
|
val start = max(0, SmsCommunicatorPlugin.messages.size - messagesToShow)
|
||||||
|
var logText = ""
|
||||||
|
for (x in start until SmsCommunicatorPlugin.messages.size) {
|
||||||
|
val sms = SmsCommunicatorPlugin.messages[x]
|
||||||
|
when {
|
||||||
|
sms.ignored -> {
|
||||||
|
logText += DateUtil.timeString(sms.date) + " <<< " + "░ " + sms.phoneNumber + " <b>" + sms.text + "</b><br>"
|
||||||
|
}
|
||||||
|
sms.received -> {
|
||||||
|
logText += DateUtil.timeString(sms.date) + " <<< " + (if (sms.processed) "● " else "○ ") + sms.phoneNumber + " <b>" + sms.text + "</b><br>"
|
||||||
|
}
|
||||||
|
sms.sent -> {
|
||||||
|
logText += DateUtil.timeString(sms.date) + " >>> " + (if (sms.processed) "● " else "○ ") + sms.phoneNumber + " <b>" + sms.text + "</b><br>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
smscommunicator_log?.text = HtmlHelper.fromHtml(logText)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,812 +0,0 @@
|
||||||
package info.nightscout.androidaps.plugins.general.smsCommunicator;
|
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.telephony.SmsManager;
|
|
||||||
import android.telephony.SmsMessage;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.text.Normalizer;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.Constants;
|
|
||||||
import info.nightscout.androidaps.MainApp;
|
|
||||||
import info.nightscout.androidaps.R;
|
|
||||||
import info.nightscout.androidaps.data.DetailedBolusInfo;
|
|
||||||
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;
|
|
||||||
import info.nightscout.androidaps.events.EventPreferenceChange;
|
|
||||||
import info.nightscout.androidaps.events.EventRefreshOverview;
|
|
||||||
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;
|
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBus;
|
|
||||||
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.general.nsclient.events.EventNSClientRestart;
|
|
||||||
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.GlucoseStatus;
|
|
||||||
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.utils.DateUtil;
|
|
||||||
import info.nightscout.androidaps.utils.DecimalFormatter;
|
|
||||||
import info.nightscout.androidaps.utils.FabricPrivacy;
|
|
||||||
import info.nightscout.androidaps.utils.SP;
|
|
||||||
import info.nightscout.androidaps.utils.SafeParse;
|
|
||||||
import info.nightscout.androidaps.utils.XdripCalibrations;
|
|
||||||
import io.reactivex.disposables.CompositeDisposable;
|
|
||||||
import io.reactivex.schedulers.Schedulers;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by mike on 05.08.2016.
|
|
||||||
*/
|
|
||||||
public class SmsCommunicatorPlugin extends PluginBase {
|
|
||||||
private static Logger log = LoggerFactory.getLogger(L.SMS);
|
|
||||||
private CompositeDisposable disposable = new CompositeDisposable();
|
|
||||||
|
|
||||||
private static SmsCommunicatorPlugin smsCommunicatorPlugin;
|
|
||||||
|
|
||||||
public static SmsCommunicatorPlugin getPlugin() {
|
|
||||||
|
|
||||||
if (smsCommunicatorPlugin == null) {
|
|
||||||
smsCommunicatorPlugin = new SmsCommunicatorPlugin();
|
|
||||||
}
|
|
||||||
return smsCommunicatorPlugin;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<String> allowedNumbers = new ArrayList<>();
|
|
||||||
|
|
||||||
AuthRequest messageToConfirm = null;
|
|
||||||
|
|
||||||
long lastRemoteBolusTime = 0;
|
|
||||||
|
|
||||||
ArrayList<Sms> messages = new ArrayList<>();
|
|
||||||
|
|
||||||
SmsCommunicatorPlugin() {
|
|
||||||
super(new PluginDescription()
|
|
||||||
.mainType(PluginType.GENERAL)
|
|
||||||
.fragmentClass(SmsCommunicatorFragment.class.getName())
|
|
||||||
.pluginName(R.string.smscommunicator)
|
|
||||||
.shortName(R.string.smscommunicator_shortname)
|
|
||||||
.preferencesId(R.xml.pref_smscommunicator)
|
|
||||||
.description(R.string.description_sms_communicator)
|
|
||||||
);
|
|
||||||
processSettings(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onStart() {
|
|
||||||
super.onStart();
|
|
||||||
disposable.add(RxBus.INSTANCE
|
|
||||||
.toObservable(EventPreferenceChange.class)
|
|
||||||
.observeOn(Schedulers.io())
|
|
||||||
.subscribe(event -> {
|
|
||||||
processSettings(event);
|
|
||||||
}, FabricPrivacy::logException)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onStop() {
|
|
||||||
disposable.clear();
|
|
||||||
super.onStop();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void processSettings(final EventPreferenceChange ev) {
|
|
||||||
if (ev == null || ev.isChanged(R.string.key_smscommunicator_allowednumbers)) {
|
|
||||||
String settings = SP.getString(R.string.key_smscommunicator_allowednumbers, "");
|
|
||||||
|
|
||||||
allowedNumbers.clear();
|
|
||||||
String[] substrings = settings.split(";");
|
|
||||||
for (String number : substrings) {
|
|
||||||
String cleaned = number.replaceAll("\\s+", "");
|
|
||||||
allowedNumbers.add(cleaned);
|
|
||||||
log.debug("Found allowed number: " + cleaned);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void handleNewData(Intent intent) {
|
|
||||||
Bundle bundle = intent.getExtras();
|
|
||||||
if (bundle == null) return;
|
|
||||||
|
|
||||||
Object[] pdus = (Object[]) bundle.get("pdus");
|
|
||||||
if (pdus != null) {
|
|
||||||
// For every SMS message received
|
|
||||||
for (Object pdu : pdus) {
|
|
||||||
SmsMessage message = SmsMessage.createFromPdu((byte[]) pdu);
|
|
||||||
processSms(new Sms(message));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void processSms(final Sms receivedSms) {
|
|
||||||
if (!isEnabled(PluginType.GENERAL)) {
|
|
||||||
log.debug("Ignoring SMS. Plugin disabled.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!isAllowedNumber(receivedSms.phoneNumber)) {
|
|
||||||
log.debug("Ignoring SMS from: " + receivedSms.phoneNumber + ". Sender not allowed");
|
|
||||||
receivedSms.ignored = true;
|
|
||||||
messages.add(receivedSms);
|
|
||||||
RxBus.INSTANCE.send(new EventSmsCommunicatorUpdateGui());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
messages.add(receivedSms);
|
|
||||||
log.debug(receivedSms.toString());
|
|
||||||
|
|
||||||
String[] splitted = receivedSms.text.split("\\s+");
|
|
||||||
boolean remoteCommandsAllowed = SP.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false);
|
|
||||||
|
|
||||||
if (splitted.length > 0 && isCommand(splitted[0].toUpperCase(), receivedSms.phoneNumber)) {
|
|
||||||
switch (splitted[0].toUpperCase()) {
|
|
||||||
case "BG":
|
|
||||||
processBG(splitted, receivedSms);
|
|
||||||
break;
|
|
||||||
case "LOOP":
|
|
||||||
if (!remoteCommandsAllowed)
|
|
||||||
sendSMS(new Sms(receivedSms.phoneNumber, R.string.smscommunicator_remotecommandnotallowed));
|
|
||||||
else if (splitted.length == 2 || splitted.length == 3)
|
|
||||||
processLOOP(splitted, receivedSms);
|
|
||||||
else
|
|
||||||
sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat));
|
|
||||||
break;
|
|
||||||
case "TREATMENTS":
|
|
||||||
if (splitted.length == 2)
|
|
||||||
processTREATMENTS(splitted, receivedSms);
|
|
||||||
else
|
|
||||||
sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat));
|
|
||||||
break;
|
|
||||||
case "NSCLIENT":
|
|
||||||
if (splitted.length == 2)
|
|
||||||
processNSCLIENT(splitted, receivedSms);
|
|
||||||
else
|
|
||||||
sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat));
|
|
||||||
break;
|
|
||||||
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));
|
|
||||||
else if (splitted.length == 2 || splitted.length == 3)
|
|
||||||
processBASAL(splitted, receivedSms);
|
|
||||||
else
|
|
||||||
sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat));
|
|
||||||
break;
|
|
||||||
case "EXTENDED":
|
|
||||||
if (!remoteCommandsAllowed)
|
|
||||||
sendSMS(new Sms(receivedSms.phoneNumber, R.string.smscommunicator_remotecommandnotallowed));
|
|
||||||
else if (splitted.length == 2 || splitted.length == 3)
|
|
||||||
processEXTENDED(splitted, receivedSms);
|
|
||||||
else
|
|
||||||
sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat));
|
|
||||||
break;
|
|
||||||
case "BOLUS":
|
|
||||||
if (!remoteCommandsAllowed)
|
|
||||||
sendSMS(new Sms(receivedSms.phoneNumber, R.string.smscommunicator_remotecommandnotallowed));
|
|
||||||
else if (splitted.length == 2 && DateUtil.now() - lastRemoteBolusTime < Constants.remoteBolusMinDistance)
|
|
||||||
sendSMS(new Sms(receivedSms.phoneNumber, R.string.smscommunicator_remotebolusnotallowed));
|
|
||||||
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);
|
|
||||||
else
|
|
||||||
sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat));
|
|
||||||
break;
|
|
||||||
case "CAL":
|
|
||||||
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 (messageToConfirm != null && messageToConfirm.requester.phoneNumber.equals(receivedSms.phoneNumber)) {
|
|
||||||
messageToConfirm.action(splitted[0]);
|
|
||||||
messageToConfirm = null;
|
|
||||||
} else
|
|
||||||
sendSMS(new Sms(receivedSms.phoneNumber, R.string.smscommunicator_unknowncommand));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RxBus.INSTANCE.send(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();
|
|
||||||
|
|
||||||
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.cob) + ": " + cobInfo.generateCOBString();
|
|
||||||
|
|
||||||
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 = LoopPlugin.getPlugin();
|
|
||||||
if (loopPlugin.isEnabled(PluginType.LOOP)) {
|
|
||||||
loopPlugin.setPluginEnabled(PluginType.LOOP, false);
|
|
||||||
ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(true, new Callback() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
RxBus.INSTANCE.send(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));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
sendSMS(new Sms(receivedSms.phoneNumber, R.string.smscommunicator_loopisdisabled));
|
|
||||||
}
|
|
||||||
receivedSms.processed = true;
|
|
||||||
break;
|
|
||||||
case "ENABLE":
|
|
||||||
case "START":
|
|
||||||
loopPlugin = LoopPlugin.getPlugin();
|
|
||||||
if (!loopPlugin.isEnabled(PluginType.LOOP)) {
|
|
||||||
loopPlugin.setPluginEnabled(PluginType.LOOP, true);
|
|
||||||
sendSMS(new Sms(receivedSms.phoneNumber, R.string.smscommunicator_loophasbeenenabled));
|
|
||||||
RxBus.INSTANCE.send(new EventRefreshOverview("SMS_LOOP_START"));
|
|
||||||
} else {
|
|
||||||
sendSMS(new Sms(receivedSms.phoneNumber, R.string.smscommunicator_loopisenabled));
|
|
||||||
}
|
|
||||||
receivedSms.processed = true;
|
|
||||||
break;
|
|
||||||
case "STATUS":
|
|
||||||
loopPlugin = LoopPlugin.getPlugin();
|
|
||||||
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);
|
|
||||||
RxBus.INSTANCE.send(new EventRefreshOverview("SMS_LOOP_RESUME"));
|
|
||||||
NSUpload.uploadOpenAPSOffline(0);
|
|
||||||
sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, R.string.smscommunicator_loopresumed));
|
|
||||||
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) {
|
|
||||||
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);
|
|
||||||
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);
|
|
||||||
RxBus.INSTANCE.send(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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void processTREATMENTS(String[] splitted, Sms receivedSms) {
|
|
||||||
if (splitted[1].toUpperCase().equals("REFRESH")) {
|
|
||||||
TreatmentsPlugin.getPlugin().getService().resetTreatments();
|
|
||||||
RxBus.INSTANCE.send(new EventNSClientRestart());
|
|
||||||
sendSMS(new Sms(receivedSms.phoneNumber, "TREATMENTS REFRESH SENT"));
|
|
||||||
receivedSms.processed = true;
|
|
||||||
} else
|
|
||||||
sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void processNSCLIENT(String[] splitted, Sms receivedSms) {
|
|
||||||
if (splitted[1].toUpperCase().equals("RESTART")) {
|
|
||||||
RxBus.INSTANCE.send(new EventNSClientRestart());
|
|
||||||
sendSMS(new Sms(receivedSms.phoneNumber, "NSCLIENT RESTART SENT"));
|
|
||||||
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);
|
|
||||||
sendSMS(new Sms(receivedSms.phoneNumber, reply));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
String reply = MainApp.gs(R.string.readstatusfailed);
|
|
||||||
sendSMS(new Sms(receivedSms.phoneNumber, reply));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
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<CharSequence> 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();
|
|
||||||
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, duration, 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, duration, 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 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]);
|
|
||||||
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() {
|
|
||||||
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 = DateUtil.now();
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} 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(cal) {
|
|
||||||
@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 boolean sendNotificationToAllNumbers(String text) {
|
|
||||||
boolean result = true;
|
|
||||||
for (int i = 0; i < allowedNumbers.size(); i++) {
|
|
||||||
Sms sms = new Sms(allowedNumbers.get(i), text);
|
|
||||||
result = result && sendSMS(sms);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sendSMSToAllNumbers(Sms sms) {
|
|
||||||
for (String number : allowedNumbers) {
|
|
||||||
sms.phoneNumber = number;
|
|
||||||
sendSMS(sms);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean sendSMS(Sms sms) {
|
|
||||||
SmsManager smsManager = SmsManager.getDefault();
|
|
||||||
sms.text = stripAccents(sms.text);
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (L.isEnabled(L.SMS))
|
|
||||||
log.debug("Sending SMS to " + sms.phoneNumber + ": " + sms.text);
|
|
||||||
if (sms.text.getBytes().length <= 140)
|
|
||||||
smsManager.sendTextMessage(sms.phoneNumber, null, sms.text, null, null);
|
|
||||||
else {
|
|
||||||
ArrayList<String> parts = smsManager.divideMessage(sms.text);
|
|
||||||
smsManager.sendMultipartTextMessage(sms.phoneNumber, null, parts,
|
|
||||||
null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
messages.add(sms);
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
if (e.getMessage().equals("Invalid message body")) {
|
|
||||||
Notification notification = new Notification(Notification.INVALID_MESSAGE_BODY, MainApp.gs(R.string.smscommunicator_messagebody), Notification.NORMAL);
|
|
||||||
RxBus.INSTANCE.send(new EventNewNotification(notification));
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
Notification notification = new Notification(Notification.INVALID_PHONE_NUMBER, MainApp.gs(R.string.smscommunicator_invalidphonennumber), Notification.NORMAL);
|
|
||||||
RxBus.INSTANCE.send(new EventNewNotification(notification));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} catch (java.lang.SecurityException e) {
|
|
||||||
Notification notification = new Notification(Notification.MISSING_SMS_PERMISSION, MainApp.gs(R.string.smscommunicator_missingsmspermission), Notification.NORMAL);
|
|
||||||
RxBus.INSTANCE.send(new EventNewNotification(notification));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
RxBus.INSTANCE.send(new EventSmsCommunicatorUpdateGui());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String generatePasscode() {
|
|
||||||
int startChar1 = 'A'; // on iphone 1st char is uppercase :)
|
|
||||||
String passCode = Character.toString((char) (startChar1 + Math.random() * ('z' - 'a' + 1)));
|
|
||||||
int startChar2 = Math.random() > 0.5 ? 'a' : 'A';
|
|
||||||
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 = passCode.replace('l', 'k').replace('I', 'J');
|
|
||||||
return passCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String stripAccents(String s) {
|
|
||||||
s = Normalizer.normalize(s, Normalizer.Form.NFD);
|
|
||||||
s = s.replaceAll("[\\p{InCombiningDiacriticalMarks}]", "");
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,922 @@
|
||||||
|
package info.nightscout.androidaps.plugins.general.smsCommunicator
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.preference.EditTextPreference
|
||||||
|
import android.preference.Preference
|
||||||
|
import android.preference.Preference.OnPreferenceChangeListener
|
||||||
|
import android.preference.PreferenceFragment
|
||||||
|
import android.telephony.SmsManager
|
||||||
|
import android.telephony.SmsMessage
|
||||||
|
import android.text.TextUtils
|
||||||
|
import com.andreabaccega.widget.ValidatingEditTextPreference
|
||||||
|
import info.nightscout.androidaps.Constants
|
||||||
|
import info.nightscout.androidaps.MainApp
|
||||||
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.data.DetailedBolusInfo
|
||||||
|
import info.nightscout.androidaps.data.Profile
|
||||||
|
import info.nightscout.androidaps.db.DatabaseHelper
|
||||||
|
import info.nightscout.androidaps.db.Source
|
||||||
|
import info.nightscout.androidaps.db.TempTarget
|
||||||
|
import info.nightscout.androidaps.events.EventPreferenceChange
|
||||||
|
import info.nightscout.androidaps.events.EventRefreshOverview
|
||||||
|
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.logging.L
|
||||||
|
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
|
||||||
|
import info.nightscout.androidaps.plugins.bus.RxBus.send
|
||||||
|
import info.nightscout.androidaps.plugins.bus.RxBus.toObservable
|
||||||
|
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.general.nsclient.events.EventNSClientRestart
|
||||||
|
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.GlucoseStatus
|
||||||
|
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.utils.*
|
||||||
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
|
import io.reactivex.schedulers.Schedulers
|
||||||
|
import org.apache.commons.lang3.StringUtils
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
import java.text.Normalizer
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
object SmsCommunicatorPlugin : PluginBase(PluginDescription()
|
||||||
|
.mainType(PluginType.GENERAL)
|
||||||
|
.fragmentClass(SmsCommunicatorFragment::class.java.name)
|
||||||
|
.pluginName(R.string.smscommunicator)
|
||||||
|
.shortName(R.string.smscommunicator_shortname)
|
||||||
|
.preferencesId(R.xml.pref_smscommunicator)
|
||||||
|
.description(R.string.description_sms_communicator)
|
||||||
|
) {
|
||||||
|
private val log = LoggerFactory.getLogger(L.SMS)
|
||||||
|
private val disposable = CompositeDisposable()
|
||||||
|
var allowedNumbers: MutableList<String> = ArrayList()
|
||||||
|
var messageToConfirm: AuthRequest? = null
|
||||||
|
var lastRemoteBolusTime: Long = 0
|
||||||
|
var messages = ArrayList<Sms>()
|
||||||
|
|
||||||
|
val commands = mapOf(
|
||||||
|
"BG" to "BG",
|
||||||
|
"LOOP" to "LOOP STOP/DISABLE/START/ENABLE/RESUME/STATUS\nLOOP SUSPEND 20",
|
||||||
|
"TREATMENTS" to "TREATMENTS REFRESH",
|
||||||
|
"NSCLIENT" to "NSCLIENT RESTART",
|
||||||
|
"PUMP" to "PUMP",
|
||||||
|
"BASAL" to "BASAL STOP/CANCEL\nBASAL 0.3\nBASAL 0.3 20\nBASAL 30%\nBASAL 30% 20\n",
|
||||||
|
"BOLUS" to "BOLUS 1.2\nBOLUS 1.2 MEAL",
|
||||||
|
"EXTENDED" to "EXTENDED STOP/CANCEL\nEXTENDED 2 120",
|
||||||
|
"CAL" to "CAL 5.6",
|
||||||
|
"PROFILE" to "PROFILE STATUS/LIST\nPROFILE 1\nPROFILE 2 30",
|
||||||
|
"TARGET" to "TARGET MEAL/ACTIVITY/HYPO/STOP",
|
||||||
|
"SMS" to "SMS DISABLE/STOP",
|
||||||
|
"CARBS" to "CARBS 12\nCARBS 12 23:05\nCARBS 12 11:05PM",
|
||||||
|
"HELP" to "HELP\nHELP command"
|
||||||
|
)
|
||||||
|
|
||||||
|
init {
|
||||||
|
processSettings(null)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStart() {
|
||||||
|
super.onStart()
|
||||||
|
disposable.add(toObservable(EventPreferenceChange::class.java)
|
||||||
|
.observeOn(Schedulers.io())
|
||||||
|
.subscribe({ event: EventPreferenceChange? -> processSettings(event) }) { throwable: Throwable? -> FabricPrivacy.logException(throwable) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStop() {
|
||||||
|
disposable.clear()
|
||||||
|
super.onStop()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun preprocessPreferences(preferenceFragment: PreferenceFragment) {
|
||||||
|
super.preprocessPreferences(preferenceFragment)
|
||||||
|
val distance = preferenceFragment.findPreference(MainApp.gs(R.string.key_smscommunicator_remotebolusmindistance)) as ValidatingEditTextPreference?
|
||||||
|
?: return
|
||||||
|
val allowedNumbers = preferenceFragment.findPreference(MainApp.gs(R.string.key_smscommunicator_allowednumbers)) as EditTextPreference?
|
||||||
|
?: return
|
||||||
|
if (!areMoreNumbers(allowedNumbers.text)) {
|
||||||
|
distance.title = (MainApp.gs(R.string.smscommunicator_remotebolusmindistance)
|
||||||
|
+ ".\n"
|
||||||
|
+ MainApp.gs(R.string.smscommunicator_remotebolusmindistance_caveat))
|
||||||
|
distance.isEnabled = false
|
||||||
|
} else {
|
||||||
|
distance.title = MainApp.gs(R.string.smscommunicator_remotebolusmindistance)
|
||||||
|
distance.isEnabled = true
|
||||||
|
}
|
||||||
|
allowedNumbers.onPreferenceChangeListener = OnPreferenceChangeListener { _: Preference?, newValue: Any ->
|
||||||
|
if (!areMoreNumbers(newValue as String)) {
|
||||||
|
distance.text = (Constants.remoteBolusMinDistance / (60 * 1000L)).toString()
|
||||||
|
distance.title = (MainApp.gs(R.string.smscommunicator_remotebolusmindistance)
|
||||||
|
+ ".\n"
|
||||||
|
+ MainApp.gs(R.string.smscommunicator_remotebolusmindistance_caveat))
|
||||||
|
distance.isEnabled = false
|
||||||
|
} else {
|
||||||
|
distance.title = MainApp.gs(R.string.smscommunicator_remotebolusmindistance)
|
||||||
|
distance.isEnabled = true
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updatePreferenceSummary(pref: Preference) {
|
||||||
|
super.updatePreferenceSummary(pref)
|
||||||
|
if (pref is EditTextPreference) {
|
||||||
|
val editTextPref = pref
|
||||||
|
if (pref.getKey().contains("smscommunicator_allowednumbers") && (editTextPref.text == null || TextUtils.isEmpty(editTextPref.text.trim { it <= ' ' }))) {
|
||||||
|
pref.setSummary(MainApp.gs(R.string.smscommunicator_allowednumbers_summary))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun processSettings(ev: EventPreferenceChange?) {
|
||||||
|
if (ev == null || ev.isChanged(R.string.key_smscommunicator_allowednumbers)) {
|
||||||
|
val settings = SP.getString(R.string.key_smscommunicator_allowednumbers, "")
|
||||||
|
allowedNumbers.clear()
|
||||||
|
val substrings = settings.split(";").toTypedArray()
|
||||||
|
for (number in substrings) {
|
||||||
|
val cleaned = number.replace("\\s+".toRegex(), "")
|
||||||
|
allowedNumbers.add(cleaned)
|
||||||
|
log.debug("Found allowed number: $cleaned")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isCommand(command: String, number: String): Boolean {
|
||||||
|
var found = false
|
||||||
|
commands.forEach { (k, _) ->
|
||||||
|
if (k == command) found = true
|
||||||
|
}
|
||||||
|
return found || messageToConfirm?.requester?.phoneNumber == number
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isAllowedNumber(number: String): Boolean {
|
||||||
|
for (num in allowedNumbers) {
|
||||||
|
if (num == number) return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
fun handleNewData(intent: Intent) {
|
||||||
|
val bundle = intent.extras ?: return
|
||||||
|
val format = bundle.getString("format") ?: return
|
||||||
|
val pdus = bundle["pdus"] as Array<*>
|
||||||
|
for (pdu in pdus) {
|
||||||
|
val message = SmsMessage.createFromPdu(pdu as ByteArray, format)
|
||||||
|
processSms(Sms(message))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun processSms(receivedSms: Sms) {
|
||||||
|
if (!isEnabled(PluginType.GENERAL)) {
|
||||||
|
log.debug("Ignoring SMS. Plugin disabled.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!isAllowedNumber(receivedSms.phoneNumber)) {
|
||||||
|
log.debug("Ignoring SMS from: " + receivedSms.phoneNumber + ". Sender not allowed")
|
||||||
|
receivedSms.ignored = true
|
||||||
|
messages.add(receivedSms)
|
||||||
|
send(EventSmsCommunicatorUpdateGui())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val pump = ConfigBuilderPlugin.getPlugin().activePump ?: return
|
||||||
|
messages.add(receivedSms)
|
||||||
|
log.debug(receivedSms.toString())
|
||||||
|
val splitted = receivedSms.text.split(Regex("\\s+")).toTypedArray()
|
||||||
|
val remoteCommandsAllowed = SP.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)
|
||||||
|
if (splitted.isNotEmpty() && isCommand(splitted[0].toUpperCase(Locale.getDefault()), receivedSms.phoneNumber)) {
|
||||||
|
when (splitted[0].toUpperCase(Locale.getDefault())) {
|
||||||
|
"BG" ->
|
||||||
|
if (splitted.size == 1) processBG(receivedSms)
|
||||||
|
else sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
|
||||||
|
"LOOP" ->
|
||||||
|
if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, R.string.smscommunicator_remotecommandnotallowed))
|
||||||
|
else if (splitted.size == 2 || splitted.size == 3) processLOOP(splitted, receivedSms)
|
||||||
|
else sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
|
||||||
|
"TREATMENTS" ->
|
||||||
|
if (splitted.size == 2) processTREATMENTS(splitted, receivedSms)
|
||||||
|
else sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
|
||||||
|
"NSCLIENT" ->
|
||||||
|
if (splitted.size == 2) processNSCLIENT(splitted, receivedSms)
|
||||||
|
else sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
|
||||||
|
"PUMP" ->
|
||||||
|
if (splitted.size == 1) processPUMP(receivedSms)
|
||||||
|
else sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
|
||||||
|
"PROFILE" ->
|
||||||
|
if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, R.string.smscommunicator_remotecommandnotallowed))
|
||||||
|
else if (splitted.size == 2 || splitted.size == 3) processPROFILE(splitted, receivedSms)
|
||||||
|
else sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
|
||||||
|
"BASAL" ->
|
||||||
|
if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, R.string.smscommunicator_remotecommandnotallowed))
|
||||||
|
else if (splitted.size == 2 || splitted.size == 3) processBASAL(splitted, receivedSms)
|
||||||
|
else sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
|
||||||
|
"EXTENDED" ->
|
||||||
|
if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, R.string.smscommunicator_remotecommandnotallowed))
|
||||||
|
else if (splitted.size == 2 || splitted.size == 3) processEXTENDED(splitted, receivedSms)
|
||||||
|
else sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
|
||||||
|
"BOLUS" ->
|
||||||
|
if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, R.string.smscommunicator_remotecommandnotallowed))
|
||||||
|
else if (splitted.size == 2 && DateUtil.now() - lastRemoteBolusTime < Constants.remoteBolusMinDistance) sendSMS(Sms(receivedSms.phoneNumber, R.string.smscommunicator_remotebolusnotallowed))
|
||||||
|
else if (splitted.size == 2 && pump.isSuspended) sendSMS(Sms(receivedSms.phoneNumber, R.string.pumpsuspended))
|
||||||
|
else if (splitted.size == 2 || splitted.size == 3) processBOLUS(splitted, receivedSms)
|
||||||
|
else sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
|
||||||
|
"CARBS" ->
|
||||||
|
if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, R.string.smscommunicator_remotecommandnotallowed))
|
||||||
|
else if (splitted.size == 2 || splitted.size == 3) processCARBS(splitted, receivedSms)
|
||||||
|
else sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
|
||||||
|
"CAL" ->
|
||||||
|
if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, R.string.smscommunicator_remotecommandnotallowed))
|
||||||
|
else if (splitted.size == 2) processCAL(splitted, receivedSms)
|
||||||
|
else sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
|
||||||
|
"TARGET" ->
|
||||||
|
if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, R.string.smscommunicator_remotecommandnotallowed))
|
||||||
|
else if (splitted.size == 2) processTARGET(splitted, receivedSms)
|
||||||
|
else sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
|
||||||
|
"SMS" ->
|
||||||
|
if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, R.string.smscommunicator_remotecommandnotallowed))
|
||||||
|
else if (splitted.size == 2) processSMS(splitted, receivedSms)
|
||||||
|
else sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
|
||||||
|
"HELP" ->
|
||||||
|
if (splitted.size == 1 || splitted.size == 2) processHELP(splitted, receivedSms)
|
||||||
|
else sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
|
||||||
|
else ->
|
||||||
|
if (messageToConfirm?.requester?.phoneNumber == receivedSms.phoneNumber) {
|
||||||
|
messageToConfirm?.action(splitted[0])
|
||||||
|
messageToConfirm = null
|
||||||
|
} else sendSMS(Sms(receivedSms.phoneNumber, R.string.smscommunicator_unknowncommand))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
send(EventSmsCommunicatorUpdateGui())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun processBG(receivedSms: Sms) {
|
||||||
|
val actualBG = DatabaseHelper.actualBg()
|
||||||
|
val lastBG = DatabaseHelper.lastBg()
|
||||||
|
var reply = ""
|
||||||
|
val units = ProfileFunctions.getInstance().profileUnits
|
||||||
|
if (actualBG != null) {
|
||||||
|
reply = MainApp.gs(R.string.sms_actualbg) + " " + actualBG.valueToUnitsToString(units) + ", "
|
||||||
|
} else if (lastBG != null) {
|
||||||
|
val agoMsec = System.currentTimeMillis() - lastBG.date
|
||||||
|
val agoMin = (agoMsec / 60.0 / 1000.0).toInt()
|
||||||
|
reply = MainApp.gs(R.string.sms_lastbg) + " " + lastBG.valueToUnitsToString(units) + " " + String.format(MainApp.gs(R.string.sms_minago), agoMin) + ", "
|
||||||
|
}
|
||||||
|
val 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()
|
||||||
|
val bolusIob = TreatmentsPlugin.getPlugin().lastCalculationTreatments.round()
|
||||||
|
TreatmentsPlugin.getPlugin().updateTotalIOBTempBasals()
|
||||||
|
val basalIob = TreatmentsPlugin.getPlugin().lastCalculationTempBasals.round()
|
||||||
|
val 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.cob) + ": " + cobInfo.generateCOBString())
|
||||||
|
sendSMS(Sms(receivedSms.phoneNumber, reply))
|
||||||
|
receivedSms.processed = true
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun processLOOP(splitted: Array<String>, receivedSms: Sms) {
|
||||||
|
when (splitted[1].toUpperCase(Locale.getDefault())) {
|
||||||
|
"DISABLE", "STOP" -> {
|
||||||
|
val loopPlugin = LoopPlugin.getPlugin()
|
||||||
|
if (loopPlugin.isEnabled(PluginType.LOOP)) {
|
||||||
|
loopPlugin.setPluginEnabled(PluginType.LOOP, false)
|
||||||
|
ConfigBuilderPlugin.getPlugin().commandQueue.cancelTempBasal(true, object : Callback() {
|
||||||
|
override fun run() {
|
||||||
|
send(EventRefreshOverview("SMS_LOOP_STOP"))
|
||||||
|
val replyText = MainApp.gs(R.string.smscommunicator_loophasbeendisabled) + " " +
|
||||||
|
MainApp.gs(if (result.success) R.string.smscommunicator_tempbasalcanceled else R.string.smscommunicator_tempbasalcancelfailed)
|
||||||
|
sendSMS(Sms(receivedSms.phoneNumber, replyText))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else
|
||||||
|
sendSMS(Sms(receivedSms.phoneNumber, R.string.smscommunicator_loopisdisabled))
|
||||||
|
receivedSms.processed = true
|
||||||
|
}
|
||||||
|
"ENABLE", "START" -> {
|
||||||
|
val loopPlugin = LoopPlugin.getPlugin()
|
||||||
|
if (!loopPlugin.isEnabled(PluginType.LOOP)) {
|
||||||
|
loopPlugin.setPluginEnabled(PluginType.LOOP, true)
|
||||||
|
sendSMS(Sms(receivedSms.phoneNumber, R.string.smscommunicator_loophasbeenenabled))
|
||||||
|
send(EventRefreshOverview("SMS_LOOP_START"))
|
||||||
|
} else
|
||||||
|
sendSMS(Sms(receivedSms.phoneNumber, R.string.smscommunicator_loopisenabled))
|
||||||
|
receivedSms.processed = true
|
||||||
|
}
|
||||||
|
"STATUS" -> {
|
||||||
|
val loopPlugin = LoopPlugin.getPlugin()
|
||||||
|
val reply = if (loopPlugin.isEnabled(PluginType.LOOP)) {
|
||||||
|
if (loopPlugin.isSuspended()) String.format(MainApp.gs(R.string.loopsuspendedfor), loopPlugin.minutesToEndOfSuspend())
|
||||||
|
else MainApp.gs(R.string.smscommunicator_loopisenabled)
|
||||||
|
} else
|
||||||
|
MainApp.gs(R.string.smscommunicator_loopisdisabled)
|
||||||
|
sendSMS(Sms(receivedSms.phoneNumber, reply))
|
||||||
|
receivedSms.processed = true
|
||||||
|
}
|
||||||
|
"RESUME" -> {
|
||||||
|
LoopPlugin.getPlugin().suspendTo(0)
|
||||||
|
send(EventRefreshOverview("SMS_LOOP_RESUME"))
|
||||||
|
NSUpload.uploadOpenAPSOffline(0.0)
|
||||||
|
sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, R.string.smscommunicator_loopresumed))
|
||||||
|
}
|
||||||
|
"SUSPEND" -> {
|
||||||
|
var duration = 0
|
||||||
|
if (splitted.size == 3) duration = SafeParse.stringToInt(splitted[2])
|
||||||
|
duration = Math.max(0, duration)
|
||||||
|
duration = Math.min(180, duration)
|
||||||
|
if (duration == 0) {
|
||||||
|
receivedSms.processed = true
|
||||||
|
sendSMS(Sms(receivedSms.phoneNumber, R.string.smscommunicator_wrongduration))
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
val passCode = generatePasscode()
|
||||||
|
val reply = String.format(MainApp.gs(R.string.smscommunicator_suspendreplywithcode), duration, passCode)
|
||||||
|
receivedSms.processed = true
|
||||||
|
messageToConfirm = AuthRequest(this, receivedSms, reply, passCode, object : SmsAction(duration) {
|
||||||
|
override fun run() {
|
||||||
|
ConfigBuilderPlugin.getPlugin().commandQueue.cancelTempBasal(true, object : Callback() {
|
||||||
|
override fun run() {
|
||||||
|
if (result.success) {
|
||||||
|
LoopPlugin.getPlugin().suspendTo(System.currentTimeMillis() + anInteger() * 60L * 1000)
|
||||||
|
NSUpload.uploadOpenAPSOffline(anInteger() * 60.toDouble())
|
||||||
|
send(EventRefreshOverview("SMS_LOOP_SUSPENDED"))
|
||||||
|
val replyText = MainApp.gs(R.string.smscommunicator_loopsuspended) + " " +
|
||||||
|
MainApp.gs(if (result.success) R.string.smscommunicator_tempbasalcanceled else R.string.smscommunicator_tempbasalcancelfailed)
|
||||||
|
sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, replyText))
|
||||||
|
} else {
|
||||||
|
var replyText = MainApp.gs(R.string.smscommunicator_tempbasalcancelfailed)
|
||||||
|
replyText += "\n" + ConfigBuilderPlugin.getPlugin().activePump?.shortStatus(true)
|
||||||
|
sendSMS(Sms(receivedSms.phoneNumber, replyText))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun processTREATMENTS(splitted: Array<String>, receivedSms: Sms) {
|
||||||
|
if (splitted[1].toUpperCase(Locale.getDefault()) == "REFRESH") {
|
||||||
|
TreatmentsPlugin.getPlugin().service.resetTreatments()
|
||||||
|
send(EventNSClientRestart())
|
||||||
|
sendSMS(Sms(receivedSms.phoneNumber, "TREATMENTS REFRESH SENT"))
|
||||||
|
receivedSms.processed = true
|
||||||
|
} else
|
||||||
|
sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun processNSCLIENT(splitted: Array<String>, receivedSms: Sms) {
|
||||||
|
if (splitted[1].toUpperCase(Locale.getDefault()) == "RESTART") {
|
||||||
|
send(EventNSClientRestart())
|
||||||
|
sendSMS(Sms(receivedSms.phoneNumber, "NSCLIENT RESTART SENT"))
|
||||||
|
receivedSms.processed = true
|
||||||
|
} else
|
||||||
|
sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun processHELP(splitted: Array<String>, receivedSms: Sms) {
|
||||||
|
if (splitted.size == 1) {
|
||||||
|
sendSMS(Sms(receivedSms.phoneNumber, commands.keys.toString().replace("[", "").replace("]", "")))
|
||||||
|
receivedSms.processed = true
|
||||||
|
} else if (isCommand(splitted[1].toUpperCase(Locale.getDefault()), receivedSms.phoneNumber)) {
|
||||||
|
commands[splitted[1].toUpperCase(Locale.getDefault())]?.let {
|
||||||
|
sendSMS(Sms(receivedSms.phoneNumber, it))
|
||||||
|
receivedSms.processed = true
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun processPUMP(receivedSms: Sms) {
|
||||||
|
ConfigBuilderPlugin.getPlugin().commandQueue.readStatus("SMS", object : Callback() {
|
||||||
|
override fun run() {
|
||||||
|
val pump = ConfigBuilderPlugin.getPlugin().activePump
|
||||||
|
if (result.success) {
|
||||||
|
if (pump != null) {
|
||||||
|
val reply = pump.shortStatus(true)
|
||||||
|
sendSMS(Sms(receivedSms.phoneNumber, reply))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val reply = MainApp.gs(R.string.readstatusfailed)
|
||||||
|
sendSMS(Sms(receivedSms.phoneNumber, reply))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
receivedSms.processed = true
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun processPROFILE(splitted: Array<String>, receivedSms: Sms) { // load profiles
|
||||||
|
val anInterface = ConfigBuilderPlugin.getPlugin().activeProfileInterface
|
||||||
|
if (anInterface == null) {
|
||||||
|
sendSMS(Sms(receivedSms.phoneNumber, R.string.notconfigured))
|
||||||
|
receivedSms.processed = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val store = anInterface.profile
|
||||||
|
if (store == null) {
|
||||||
|
sendSMS(Sms(receivedSms.phoneNumber, R.string.notconfigured))
|
||||||
|
receivedSms.processed = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val list = store.profileList
|
||||||
|
if (splitted[1].toUpperCase(Locale.getDefault()) == "STATUS") {
|
||||||
|
sendSMS(Sms(receivedSms.phoneNumber, ProfileFunctions.getInstance().profileName))
|
||||||
|
} else if (splitted[1].toUpperCase(Locale.getDefault()) == "LIST") {
|
||||||
|
if (list.isEmpty()) sendSMS(Sms(receivedSms.phoneNumber, R.string.invalidprofile))
|
||||||
|
else {
|
||||||
|
var reply = ""
|
||||||
|
for (i in list.indices) {
|
||||||
|
if (i > 0) reply += "\n"
|
||||||
|
reply += (i + 1).toString() + ". "
|
||||||
|
reply += list[i]
|
||||||
|
}
|
||||||
|
sendSMS(Sms(receivedSms.phoneNumber, reply))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val pindex = SafeParse.stringToInt(splitted[1])
|
||||||
|
var percentage = 100
|
||||||
|
if (splitted.size > 2) percentage = SafeParse.stringToInt(splitted[2])
|
||||||
|
if (pindex > list.size) sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
|
||||||
|
else if (percentage == 0) sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
|
||||||
|
else if (pindex == 0) sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
|
||||||
|
else {
|
||||||
|
val profile = store.getSpecificProfile(list[pindex - 1] as String)
|
||||||
|
if (profile == null) sendSMS(Sms(receivedSms.phoneNumber, R.string.noprofile))
|
||||||
|
else {
|
||||||
|
val passCode = generatePasscode()
|
||||||
|
val reply = String.format(MainApp.gs(R.string.smscommunicator_profilereplywithcode), list[pindex - 1], percentage, passCode)
|
||||||
|
receivedSms.processed = true
|
||||||
|
val finalPercentage = percentage
|
||||||
|
messageToConfirm = AuthRequest(this, receivedSms, reply, passCode, object : SmsAction(list[pindex - 1] as String, finalPercentage) {
|
||||||
|
override fun run() {
|
||||||
|
ProfileFunctions.doProfileSwitch(store, list[pindex - 1] as String, 0, finalPercentage, 0)
|
||||||
|
sendSMS(Sms(receivedSms.phoneNumber, R.string.profileswitchcreated))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
receivedSms.processed = true
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun processBASAL(splitted: Array<String>, receivedSms: Sms) {
|
||||||
|
if (splitted[1].toUpperCase(Locale.getDefault()) == "CANCEL" || splitted[1].toUpperCase(Locale.getDefault()) == "STOP") {
|
||||||
|
val passCode = generatePasscode()
|
||||||
|
val reply = String.format(MainApp.gs(R.string.smscommunicator_basalstopreplywithcode), passCode)
|
||||||
|
receivedSms.processed = true
|
||||||
|
messageToConfirm = AuthRequest(this, receivedSms, reply, passCode, object : SmsAction() {
|
||||||
|
override fun run() {
|
||||||
|
ConfigBuilderPlugin.getPlugin().commandQueue.cancelTempBasal(true, object : Callback() {
|
||||||
|
override fun run() {
|
||||||
|
if (result.success) {
|
||||||
|
var replyText = MainApp.gs(R.string.smscommunicator_tempbasalcanceled)
|
||||||
|
replyText += "\n" + ConfigBuilderPlugin.getPlugin().activePump?.shortStatus(true)
|
||||||
|
sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, replyText))
|
||||||
|
} else {
|
||||||
|
var replyText = MainApp.gs(R.string.smscommunicator_tempbasalcancelfailed)
|
||||||
|
replyText += "\n" + ConfigBuilderPlugin.getPlugin().activePump?.shortStatus(true)
|
||||||
|
sendSMS(Sms(receivedSms.phoneNumber, replyText))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else if (splitted[1].endsWith("%")) {
|
||||||
|
var tempBasalPct = SafeParse.stringToInt(StringUtils.removeEnd(splitted[1], "%"))
|
||||||
|
var duration = 30
|
||||||
|
if (splitted.size > 2) duration = SafeParse.stringToInt(splitted[2])
|
||||||
|
val profile = ProfileFunctions.getInstance().profile
|
||||||
|
if (profile == null) sendSMS(Sms(receivedSms.phoneNumber, R.string.noprofile))
|
||||||
|
else if (tempBasalPct == 0 && splitted[1] != "0%") sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
|
||||||
|
else if (duration == 0) sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
|
||||||
|
else {
|
||||||
|
tempBasalPct = MainApp.getConstraintChecker().applyBasalPercentConstraints(Constraint(tempBasalPct), profile).value()
|
||||||
|
val passCode = generatePasscode()
|
||||||
|
val reply = String.format(MainApp.gs(R.string.smscommunicator_basalpctreplywithcode), tempBasalPct, duration, passCode)
|
||||||
|
receivedSms.processed = true
|
||||||
|
messageToConfirm = AuthRequest(this, receivedSms, reply, passCode, object : SmsAction(tempBasalPct, duration) {
|
||||||
|
override fun run() {
|
||||||
|
ConfigBuilderPlugin.getPlugin().commandQueue.tempBasalPercent(anInteger(), secondInteger(), true, profile, object : Callback() {
|
||||||
|
override fun run() {
|
||||||
|
if (result.success) {
|
||||||
|
var replyText: String
|
||||||
|
replyText = if (result.isPercent) String.format(MainApp.gs(R.string.smscommunicator_tempbasalset_percent), result.percent, result.duration) else String.format(MainApp.gs(R.string.smscommunicator_tempbasalset), result.absolute, result.duration)
|
||||||
|
replyText += "\n" + ConfigBuilderPlugin.getPlugin().activePump?.shortStatus(true)
|
||||||
|
sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, replyText))
|
||||||
|
} else {
|
||||||
|
var replyText = MainApp.gs(R.string.smscommunicator_tempbasalfailed)
|
||||||
|
replyText += "\n" + ConfigBuilderPlugin.getPlugin().activePump?.shortStatus(true)
|
||||||
|
sendSMS(Sms(receivedSms.phoneNumber, replyText))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var tempBasal = SafeParse.stringToDouble(splitted[1])
|
||||||
|
var duration = 30
|
||||||
|
if (splitted.size > 2) duration = SafeParse.stringToInt(splitted[2])
|
||||||
|
val profile = ProfileFunctions.getInstance().profile
|
||||||
|
if (profile == null) sendSMS(Sms(receivedSms.phoneNumber, R.string.noprofile))
|
||||||
|
else if (tempBasal == 0.0 && splitted[1] != "0") sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
|
||||||
|
else if (duration == 0) sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
|
||||||
|
else {
|
||||||
|
tempBasal = MainApp.getConstraintChecker().applyBasalConstraints(Constraint(tempBasal), profile).value()
|
||||||
|
val passCode = generatePasscode()
|
||||||
|
val reply = String.format(MainApp.gs(R.string.smscommunicator_basalreplywithcode), tempBasal, duration, passCode)
|
||||||
|
receivedSms.processed = true
|
||||||
|
messageToConfirm = AuthRequest(this, receivedSms, reply, passCode, object : SmsAction(tempBasal, duration) {
|
||||||
|
override fun run() {
|
||||||
|
ConfigBuilderPlugin.getPlugin().commandQueue.tempBasalAbsolute(aDouble(), secondInteger(), true, profile, object : Callback() {
|
||||||
|
override fun run() {
|
||||||
|
if (result.success) {
|
||||||
|
var replyText = if (result.isPercent) String.format(MainApp.gs(R.string.smscommunicator_tempbasalset_percent), result.percent, result.duration)
|
||||||
|
else String.format(MainApp.gs(R.string.smscommunicator_tempbasalset), result.absolute, result.duration)
|
||||||
|
replyText += "\n" + ConfigBuilderPlugin.getPlugin().activePump?.shortStatus(true)
|
||||||
|
sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, replyText))
|
||||||
|
} else {
|
||||||
|
var replyText = MainApp.gs(R.string.smscommunicator_tempbasalfailed)
|
||||||
|
replyText += "\n" + ConfigBuilderPlugin.getPlugin().activePump?.shortStatus(true)
|
||||||
|
sendSMS(Sms(receivedSms.phoneNumber, replyText))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun processEXTENDED(splitted: Array<String>, receivedSms: Sms) {
|
||||||
|
if (splitted[1].toUpperCase(Locale.getDefault()) == "CANCEL" || splitted[1].toUpperCase(Locale.getDefault()) == "STOP") {
|
||||||
|
val passCode = generatePasscode()
|
||||||
|
val reply = String.format(MainApp.gs(R.string.smscommunicator_extendedstopreplywithcode), passCode)
|
||||||
|
receivedSms.processed = true
|
||||||
|
messageToConfirm = AuthRequest(this, receivedSms, reply, passCode, object : SmsAction() {
|
||||||
|
override fun run() {
|
||||||
|
ConfigBuilderPlugin.getPlugin().commandQueue.cancelExtended(object : Callback() {
|
||||||
|
override fun run() {
|
||||||
|
if (result.success) {
|
||||||
|
var replyText = MainApp.gs(R.string.smscommunicator_extendedcanceled)
|
||||||
|
replyText += "\n" + ConfigBuilderPlugin.getPlugin().activePump?.shortStatus(true)
|
||||||
|
sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, replyText))
|
||||||
|
} else {
|
||||||
|
var replyText = MainApp.gs(R.string.smscommunicator_extendedcancelfailed)
|
||||||
|
replyText += "\n" + ConfigBuilderPlugin.getPlugin().activePump?.shortStatus(true)
|
||||||
|
sendSMS(Sms(receivedSms.phoneNumber, replyText))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else if (splitted.size != 3) {
|
||||||
|
sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
|
||||||
|
} else {
|
||||||
|
var extended = SafeParse.stringToDouble(splitted[1])
|
||||||
|
val duration = SafeParse.stringToInt(splitted[2])
|
||||||
|
extended = MainApp.getConstraintChecker().applyExtendedBolusConstraints(Constraint(extended)).value()
|
||||||
|
if (extended == 0.0 || duration == 0) sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
|
||||||
|
else {
|
||||||
|
val passCode = generatePasscode()
|
||||||
|
val reply = String.format(MainApp.gs(R.string.smscommunicator_extendedreplywithcode), extended, duration, passCode)
|
||||||
|
receivedSms.processed = true
|
||||||
|
messageToConfirm = AuthRequest(this, receivedSms, reply, passCode, object : SmsAction(extended, duration) {
|
||||||
|
override fun run() {
|
||||||
|
ConfigBuilderPlugin.getPlugin().commandQueue.extendedBolus(aDouble(), secondInteger(), object : Callback() {
|
||||||
|
override fun run() {
|
||||||
|
if (result.success) {
|
||||||
|
var replyText = String.format(MainApp.gs(R.string.smscommunicator_extendedset), aDouble, duration)
|
||||||
|
replyText += "\n" + ConfigBuilderPlugin.getPlugin().activePump?.shortStatus(true)
|
||||||
|
sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, replyText))
|
||||||
|
} else {
|
||||||
|
var replyText = MainApp.gs(R.string.smscommunicator_extendedfailed)
|
||||||
|
replyText += "\n" + ConfigBuilderPlugin.getPlugin().activePump?.shortStatus(true)
|
||||||
|
sendSMS(Sms(receivedSms.phoneNumber, replyText))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun processBOLUS(splitted: Array<String>, receivedSms: Sms) {
|
||||||
|
var bolus = SafeParse.stringToDouble(splitted[1])
|
||||||
|
val isMeal = splitted.size > 2 && splitted[2].equals("MEAL", ignoreCase = true)
|
||||||
|
bolus = MainApp.getConstraintChecker().applyBolusConstraints(Constraint(bolus)).value()
|
||||||
|
if (splitted.size == 3 && !isMeal) {
|
||||||
|
sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
|
||||||
|
} else if (bolus > 0.0) {
|
||||||
|
val passCode = generatePasscode()
|
||||||
|
val reply = if (isMeal)
|
||||||
|
String.format(MainApp.gs(R.string.smscommunicator_mealbolusreplywithcode), bolus, passCode)
|
||||||
|
else
|
||||||
|
String.format(MainApp.gs(R.string.smscommunicator_bolusreplywithcode), bolus, passCode)
|
||||||
|
receivedSms.processed = true
|
||||||
|
messageToConfirm = AuthRequest(this, receivedSms, reply, passCode, object : SmsAction(bolus) {
|
||||||
|
override fun run() {
|
||||||
|
val detailedBolusInfo = DetailedBolusInfo()
|
||||||
|
detailedBolusInfo.insulin = aDouble()
|
||||||
|
detailedBolusInfo.source = Source.USER
|
||||||
|
ConfigBuilderPlugin.getPlugin().commandQueue.bolus(detailedBolusInfo, object : Callback() {
|
||||||
|
override fun run() {
|
||||||
|
val resultSuccess = result.success
|
||||||
|
val resultBolusDelivered = result.bolusDelivered
|
||||||
|
ConfigBuilderPlugin.getPlugin().commandQueue.readStatus("SMS", object : Callback() {
|
||||||
|
override fun run() {
|
||||||
|
if (resultSuccess) {
|
||||||
|
var replyText = if (isMeal)
|
||||||
|
String.format(MainApp.gs(R.string.smscommunicator_mealbolusdelivered), resultBolusDelivered)
|
||||||
|
else
|
||||||
|
String.format(MainApp.gs(R.string.smscommunicator_bolusdelivered), resultBolusDelivered)
|
||||||
|
replyText += "\n" + ConfigBuilderPlugin.getPlugin().activePump?.shortStatus(true)
|
||||||
|
lastRemoteBolusTime = DateUtil.now()
|
||||||
|
if (isMeal) {
|
||||||
|
ProfileFunctions.getInstance().profile?.let { currentProfile ->
|
||||||
|
var eatingSoonTTDuration = SP.getInt(R.string.key_eatingsoon_duration, Constants.defaultEatingSoonTTDuration)
|
||||||
|
eatingSoonTTDuration =
|
||||||
|
if (eatingSoonTTDuration > 0) eatingSoonTTDuration
|
||||||
|
else Constants.defaultEatingSoonTTDuration
|
||||||
|
var eatingSoonTT = SP.getDouble(R.string.key_eatingsoon_target, if (currentProfile.units == Constants.MMOL) Constants.defaultEatingSoonTTmmol else Constants.defaultEatingSoonTTmgdl)
|
||||||
|
eatingSoonTT =
|
||||||
|
if (eatingSoonTT > 0) eatingSoonTT
|
||||||
|
else if (currentProfile.units == Constants.MMOL) Constants.defaultEatingSoonTTmmol
|
||||||
|
else Constants.defaultEatingSoonTTmgdl
|
||||||
|
val tempTarget = TempTarget()
|
||||||
|
.date(System.currentTimeMillis())
|
||||||
|
.duration(eatingSoonTTDuration)
|
||||||
|
.reason(MainApp.gs(R.string.eatingsoon))
|
||||||
|
.source(Source.USER)
|
||||||
|
.low(Profile.toMgdl(eatingSoonTT, currentProfile.units))
|
||||||
|
.high(Profile.toMgdl(eatingSoonTT, currentProfile.units))
|
||||||
|
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget)
|
||||||
|
val tt = if (currentProfile.units == Constants.MMOL) {
|
||||||
|
DecimalFormatter.to1Decimal(eatingSoonTT)
|
||||||
|
} else DecimalFormatter.to0Decimal(eatingSoonTT)
|
||||||
|
replyText += "\n" + String.format(MainApp.gs(R.string.smscommunicator_mealbolusdelivered_tt), tt, eatingSoonTTDuration)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, replyText))
|
||||||
|
} else {
|
||||||
|
var replyText = MainApp.gs(R.string.smscommunicator_bolusfailed)
|
||||||
|
replyText += "\n" + ConfigBuilderPlugin.getPlugin().activePump?.shortStatus(true)
|
||||||
|
sendSMS(Sms(receivedSms.phoneNumber, replyText))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun processCARBS(splitted: Array<String>, receivedSms: Sms) {
|
||||||
|
var grams = SafeParse.stringToInt(splitted[1])
|
||||||
|
var time = DateUtil.now()
|
||||||
|
if (splitted.size > 2) {
|
||||||
|
val seconds = DateUtil.toSeconds(splitted[2].toUpperCase(Locale.getDefault()))
|
||||||
|
val midnight = MidnightTime.calc()
|
||||||
|
if (seconds == 0 && (!splitted[2].startsWith("00:00") || !splitted[2].startsWith("12:00"))) {
|
||||||
|
sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
time = midnight + T.secs(seconds.toLong()).msecs()
|
||||||
|
}
|
||||||
|
grams = MainApp.getConstraintChecker().applyCarbsConstraints(Constraint(grams)).value()
|
||||||
|
if (grams == 0) sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
|
||||||
|
else {
|
||||||
|
val passCode = generatePasscode()
|
||||||
|
val reply = String.format(MainApp.gs(R.string.smscommunicator_carbsreplywithcode), grams, DateUtil.timeString(time), passCode)
|
||||||
|
receivedSms.processed = true
|
||||||
|
messageToConfirm = AuthRequest(this, receivedSms, reply, passCode, object : SmsAction(grams, time) {
|
||||||
|
override fun run() {
|
||||||
|
val detailedBolusInfo = DetailedBolusInfo()
|
||||||
|
detailedBolusInfo.carbs = anInteger().toDouble()
|
||||||
|
detailedBolusInfo.date = secondLong()
|
||||||
|
ConfigBuilderPlugin.getPlugin().commandQueue.bolus(detailedBolusInfo, object : Callback() {
|
||||||
|
override fun run() {
|
||||||
|
if (result.success) {
|
||||||
|
var replyText = String.format(MainApp.gs(R.string.smscommunicator_carbsset), anInteger)
|
||||||
|
replyText += "\n" + ConfigBuilderPlugin.getPlugin().activePump?.shortStatus(true)
|
||||||
|
sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, replyText))
|
||||||
|
} else {
|
||||||
|
var replyText = MainApp.gs(R.string.smscommunicator_carbsfailed)
|
||||||
|
replyText += "\n" + ConfigBuilderPlugin.getPlugin().activePump?.shortStatus(true)
|
||||||
|
sendSMS(Sms(receivedSms.phoneNumber, replyText))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun processTARGET(splitted: Array<String>, receivedSms: Sms) {
|
||||||
|
val isMeal = splitted[1].equals("MEAL", ignoreCase = true)
|
||||||
|
val isActivity = splitted[1].equals("ACTIVITY", ignoreCase = true)
|
||||||
|
val isHypo = splitted[1].equals("HYPO", ignoreCase = true)
|
||||||
|
val isStop = splitted[1].equals("STOP", ignoreCase = true) || splitted[1].equals("CANCEL", ignoreCase = true)
|
||||||
|
if (isMeal || isActivity || isHypo) {
|
||||||
|
val passCode = generatePasscode()
|
||||||
|
val reply = String.format(MainApp.gs(R.string.smscommunicator_temptargetwithcode), splitted[1].toUpperCase(Locale.getDefault()), passCode)
|
||||||
|
receivedSms.processed = true
|
||||||
|
messageToConfirm = AuthRequest(this, receivedSms, reply, passCode, object : SmsAction() {
|
||||||
|
override fun run() {
|
||||||
|
val currentProfile = ProfileFunctions.getInstance().profile
|
||||||
|
if (currentProfile != null) {
|
||||||
|
var keyDuration = 0
|
||||||
|
var defaultTargetDuration = 0
|
||||||
|
var keyTarget = 0
|
||||||
|
var defaultTargetMMOL = 0.0
|
||||||
|
var defaultTargetMGDL = 0.0
|
||||||
|
if (isMeal) {
|
||||||
|
keyDuration = R.string.key_eatingsoon_duration
|
||||||
|
defaultTargetDuration = Constants.defaultEatingSoonTTDuration
|
||||||
|
keyTarget = R.string.key_eatingsoon_target
|
||||||
|
defaultTargetMMOL = Constants.defaultEatingSoonTTmmol
|
||||||
|
defaultTargetMGDL = Constants.defaultEatingSoonTTmgdl
|
||||||
|
} else if (isActivity) {
|
||||||
|
keyDuration = R.string.key_activity_duration
|
||||||
|
defaultTargetDuration = Constants.defaultActivityTTDuration
|
||||||
|
keyTarget = R.string.key_activity_target
|
||||||
|
defaultTargetMMOL = Constants.defaultActivityTTmmol
|
||||||
|
defaultTargetMGDL = Constants.defaultActivityTTmgdl
|
||||||
|
} else if (isHypo) {
|
||||||
|
keyDuration = R.string.key_hypo_duration
|
||||||
|
defaultTargetDuration = Constants.defaultHypoTTDuration
|
||||||
|
keyTarget = R.string.key_hypo_target
|
||||||
|
defaultTargetMMOL = Constants.defaultHypoTTmmol
|
||||||
|
defaultTargetMGDL = Constants.defaultHypoTTmgdl
|
||||||
|
}
|
||||||
|
var ttDuration = SP.getInt(keyDuration, defaultTargetDuration)
|
||||||
|
ttDuration = if (ttDuration > 0) ttDuration else defaultTargetDuration
|
||||||
|
var tt = SP.getDouble(keyTarget, if (currentProfile.units == Constants.MMOL) defaultTargetMMOL else defaultTargetMGDL)
|
||||||
|
tt = if (tt > 0) tt else if (currentProfile.units == Constants.MMOL) defaultTargetMMOL else defaultTargetMGDL
|
||||||
|
val tempTarget = TempTarget()
|
||||||
|
.date(System.currentTimeMillis())
|
||||||
|
.duration(ttDuration)
|
||||||
|
.reason(MainApp.gs(R.string.eatingsoon))
|
||||||
|
.source(Source.USER)
|
||||||
|
.low(Profile.toMgdl(tt, currentProfile.units))
|
||||||
|
.high(Profile.toMgdl(tt, currentProfile.units))
|
||||||
|
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget)
|
||||||
|
val ttString = if (currentProfile.units == Constants.MMOL) DecimalFormatter.to1Decimal(tt) else DecimalFormatter.to0Decimal(tt)
|
||||||
|
val replyText = String.format(MainApp.gs(R.string.smscommunicator_tt_set), ttString, ttDuration)
|
||||||
|
sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, replyText))
|
||||||
|
} else {
|
||||||
|
sendSMS(Sms(receivedSms.phoneNumber, R.string.smscommunicator_unknowncommand))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else if (isStop) {
|
||||||
|
val passCode = generatePasscode()
|
||||||
|
val reply = String.format(MainApp.gs(R.string.smscommunicator_temptargetcancel), passCode)
|
||||||
|
receivedSms.processed = true
|
||||||
|
messageToConfirm = AuthRequest(this, receivedSms, reply, passCode, object : SmsAction() {
|
||||||
|
override fun run() {
|
||||||
|
val currentProfile = ProfileFunctions.getInstance().profile
|
||||||
|
if (currentProfile != null) {
|
||||||
|
val tempTarget = TempTarget()
|
||||||
|
.source(Source.USER)
|
||||||
|
.date(DateUtil.now())
|
||||||
|
.duration(0)
|
||||||
|
.low(0.0)
|
||||||
|
.high(0.0)
|
||||||
|
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget)
|
||||||
|
val replyText = String.format(MainApp.gs(R.string.smscommunicator_tt_canceled))
|
||||||
|
sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, replyText))
|
||||||
|
} else {
|
||||||
|
sendSMS(Sms(receivedSms.phoneNumber, R.string.smscommunicator_unknowncommand))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else
|
||||||
|
sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun processSMS(splitted: Array<String>, receivedSms: Sms) {
|
||||||
|
val isStop = (splitted[1].equals("STOP", ignoreCase = true)
|
||||||
|
|| splitted[1].equals("DISABLE", ignoreCase = true))
|
||||||
|
if (isStop) {
|
||||||
|
val passCode = generatePasscode()
|
||||||
|
val reply = String.format(MainApp.gs(R.string.smscommunicator_stopsmswithcode), passCode)
|
||||||
|
receivedSms.processed = true
|
||||||
|
messageToConfirm = AuthRequest(this, receivedSms, reply, passCode, object : SmsAction() {
|
||||||
|
override fun run() {
|
||||||
|
SP.putBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)
|
||||||
|
val replyText = String.format(MainApp.gs(R.string.smscommunicator_stoppedsms))
|
||||||
|
sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, replyText))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun processCAL(splitted: Array<String>, receivedSms: Sms) {
|
||||||
|
val cal = SafeParse.stringToDouble(splitted[1])
|
||||||
|
if (cal > 0.0) {
|
||||||
|
val passCode = generatePasscode()
|
||||||
|
val reply = String.format(MainApp.gs(R.string.smscommunicator_calibrationreplywithcode), cal, passCode)
|
||||||
|
receivedSms.processed = true
|
||||||
|
messageToConfirm = AuthRequest(this, receivedSms, reply, passCode, object : SmsAction(cal) {
|
||||||
|
override fun run() {
|
||||||
|
val result = XdripCalibrations.sendIntent(aDouble)
|
||||||
|
if (result) sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, R.string.smscommunicator_calibrationsent)) else sendSMS(Sms(receivedSms.phoneNumber, R.string.smscommunicator_calibrationfailed))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun sendNotificationToAllNumbers(text: String): Boolean {
|
||||||
|
var result = true
|
||||||
|
for (i in allowedNumbers.indices) {
|
||||||
|
val sms = Sms(allowedNumbers[i], text)
|
||||||
|
result = result && sendSMS(sms)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun sendSMSToAllNumbers(sms: Sms) {
|
||||||
|
for (number in allowedNumbers) {
|
||||||
|
sms.phoneNumber = number
|
||||||
|
sendSMS(sms)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun sendSMS(sms: Sms): Boolean {
|
||||||
|
val smsManager = SmsManager.getDefault()
|
||||||
|
sms.text = stripAccents(sms.text)
|
||||||
|
try {
|
||||||
|
if (L.isEnabled(L.SMS)) log.debug("Sending SMS to " + sms.phoneNumber + ": " + sms.text)
|
||||||
|
if (sms.text.toByteArray().size <= 140) smsManager.sendTextMessage(sms.phoneNumber, null, sms.text, null, null)
|
||||||
|
else {
|
||||||
|
val parts = smsManager.divideMessage(sms.text)
|
||||||
|
smsManager.sendMultipartTextMessage(sms.phoneNumber, null, parts,
|
||||||
|
null, null)
|
||||||
|
}
|
||||||
|
messages.add(sms)
|
||||||
|
} catch (e: IllegalArgumentException) {
|
||||||
|
return if (e.message == "Invalid message body") {
|
||||||
|
val notification = Notification(Notification.INVALID_MESSAGE_BODY, MainApp.gs(R.string.smscommunicator_messagebody), Notification.NORMAL)
|
||||||
|
send(EventNewNotification(notification))
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
val notification = Notification(Notification.INVALID_PHONE_NUMBER, MainApp.gs(R.string.smscommunicator_invalidphonennumber), Notification.NORMAL)
|
||||||
|
send(EventNewNotification(notification))
|
||||||
|
false
|
||||||
|
}
|
||||||
|
} catch (e: SecurityException) {
|
||||||
|
val notification = Notification(Notification.MISSING_SMS_PERMISSION, MainApp.gs(R.string.smscommunicator_missingsmspermission), Notification.NORMAL)
|
||||||
|
send(EventNewNotification(notification))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
send(EventSmsCommunicatorUpdateGui())
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generatePasscode(): String {
|
||||||
|
val startChar1 = 'A'.toInt() // on iphone 1st char is uppercase :)
|
||||||
|
var passCode = Character.toString((startChar1 + Math.random() * ('z' - 'a' + 1)).toChar())
|
||||||
|
val startChar2: Int = if (Math.random() > 0.5) 'a'.toInt() else 'A'.toInt()
|
||||||
|
passCode += Character.toString((startChar2 + Math.random() * ('z' - 'a' + 1)).toChar())
|
||||||
|
val startChar3: Int = if (Math.random() > 0.5) 'a'.toInt() else 'A'.toInt()
|
||||||
|
passCode += Character.toString((startChar3 + Math.random() * ('z' - 'a' + 1)).toChar())
|
||||||
|
passCode = passCode.replace('l', 'k').replace('I', 'J')
|
||||||
|
return passCode
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun stripAccents(str: String): String {
|
||||||
|
var s = str
|
||||||
|
s = Normalizer.normalize(s, Normalizer.Form.NFD)
|
||||||
|
s = s.replace("[\\p{InCombiningDiacriticalMarks}]".toRegex(), "")
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
fun areMoreNumbers(allowednumbers: String?): Boolean {
|
||||||
|
return allowednumbers?.let {
|
||||||
|
var countNumbers = 0
|
||||||
|
val substrings = it.split(";").toTypedArray()
|
||||||
|
for (number in substrings) {
|
||||||
|
var cleaned = number.replace(Regex("\\s+"), "")
|
||||||
|
if (cleaned.length < 4) continue
|
||||||
|
cleaned = cleaned.replace("+", "")
|
||||||
|
cleaned = cleaned.replace("-", "")
|
||||||
|
if (!cleaned.matches(Regex("[0-9]+"))) continue
|
||||||
|
countNumbers++
|
||||||
|
}
|
||||||
|
countNumbers > 1
|
||||||
|
} ?: false
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package info.nightscout.androidaps.plugins.general.tidepool
|
package info.nightscout.androidaps.plugins.general.tidepool
|
||||||
|
|
||||||
|
import android.preference.PreferenceFragment
|
||||||
import android.text.Spanned
|
import android.text.Spanned
|
||||||
import info.nightscout.androidaps.Constants
|
import info.nightscout.androidaps.Constants
|
||||||
import info.nightscout.androidaps.MainApp
|
import info.nightscout.androidaps.MainApp
|
||||||
|
@ -34,7 +35,6 @@ object TidepoolPlugin : PluginBase(PluginDescription()
|
||||||
.preferencesId(R.xml.pref_tidepool)
|
.preferencesId(R.xml.pref_tidepool)
|
||||||
.description(R.string.description_tidepool)
|
.description(R.string.description_tidepool)
|
||||||
) {
|
) {
|
||||||
|
|
||||||
private val log = LoggerFactory.getLogger(L.TIDEPOOL)
|
private val log = LoggerFactory.getLogger(L.TIDEPOOL)
|
||||||
private var disposable: CompositeDisposable = CompositeDisposable()
|
private var disposable: CompositeDisposable = CompositeDisposable()
|
||||||
|
|
||||||
|
@ -111,6 +111,16 @@ object TidepoolPlugin : PluginBase(PluginDescription()
|
||||||
super.onStop()
|
super.onStop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun preprocessPreferences(preferenceFragment: PreferenceFragment) {
|
||||||
|
super.preprocessPreferences(preferenceFragment)
|
||||||
|
|
||||||
|
val tidepoolTestLogin = preferenceFragment.findPreference(MainApp.gs(R.string.key_tidepool_test_login))
|
||||||
|
tidepoolTestLogin?.setOnPreferenceClickListener {
|
||||||
|
TidepoolUploader.testLogin(preferenceFragment.getActivity())
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun doUpload() =
|
private fun doUpload() =
|
||||||
when (TidepoolUploader.connectionStatus) {
|
when (TidepoolUploader.connectionStatus) {
|
||||||
TidepoolUploader.ConnectionStatus.FAILED -> {}
|
TidepoolUploader.ConnectionStatus.FAILED -> {}
|
||||||
|
|
|
@ -16,6 +16,7 @@ import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class Encoding4b6bLoop extends Encoding4b6bAbstract {
|
public class Encoding4b6bLoop extends Encoding4b6bAbstract {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(Encoding4b6bLoop.class);
|
||||||
|
|
||||||
public static final Logger LOG = LoggerFactory.getLogger(Encoding4b6bLoop.class);
|
public static final Logger LOG = LoggerFactory.getLogger(Encoding4b6bLoop.class);
|
||||||
public Map<Integer, Byte> codesRev = null;
|
public Map<Integer, Byte> codesRev = null;
|
||||||
|
@ -108,9 +109,8 @@ public class Encoding4b6bLoop extends Encoding4b6bAbstract {
|
||||||
int index2 = ((bitAccumulator >> (availBits - 12)) & 0b111111);
|
int index2 = ((bitAccumulator >> (availBits - 12)) & 0b111111);
|
||||||
hiNibble = codesRev.get((bitAccumulator >> (availBits - 6)));
|
hiNibble = codesRev.get((bitAccumulator >> (availBits - 6)));
|
||||||
loNibble = codesRev.get(((bitAccumulator >> (availBits - 12)) & 0b111111));
|
loNibble = codesRev.get(((bitAccumulator >> (availBits - 12)) & 0b111111));
|
||||||
} catch (Exception ex) {
|
} catch (Exception e) {
|
||||||
System.out.println("Exception: " + ex.getMessage());
|
log.error("Unhandled exception", e);
|
||||||
ex.printStackTrace();
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -383,7 +383,7 @@ public class DanaRExecutionService extends AbstractDanaRExecutionService {
|
||||||
try {
|
try {
|
||||||
o.wait();
|
o.wait();
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -5,10 +5,12 @@ import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.ServiceConnection;
|
import android.content.ServiceConnection;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.preference.Preference;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.fragment.app.FragmentActivity;
|
import androidx.fragment.app.FragmentActivity;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -110,6 +112,14 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updatePreferenceSummary(@NotNull Preference pref) {
|
||||||
|
super.updatePreferenceSummary(pref);
|
||||||
|
|
||||||
|
if (pref.getKey().equals(MainApp.gs(R.string.key_danars_name)))
|
||||||
|
pref.setSummary(SP.getString(R.string.key_danars_name, ""));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStart() {
|
protected void onStart() {
|
||||||
Context context = MainApp.instance().getApplicationContext();
|
Context context = MainApp.instance().getApplicationContext();
|
||||||
|
|
|
@ -4,11 +4,15 @@ import android.annotation.TargetApi;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
|
||||||
import com.cozmo.danar.util.BleCommandUtil;
|
import com.cozmo.danar.util.BleCommandUtil;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
public class DanaRS_Packet {
|
public class DanaRS_Packet {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(DanaRS_Packet.class);
|
||||||
|
|
||||||
protected static final int TYPE_START = 0;
|
protected static final int TYPE_START = 0;
|
||||||
protected static final int OPCODE_START = 1;
|
protected static final int OPCODE_START = 1;
|
||||||
protected static final int DATA_START = 2;
|
protected static final int DATA_START = 2;
|
||||||
|
@ -73,7 +77,7 @@ public class DanaRS_Packet {
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -551,7 +551,7 @@ public class BLEComm {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
startSignatureFound = false;
|
startSignatureFound = false;
|
||||||
packetIsValid = false;
|
packetIsValid = false;
|
||||||
|
@ -635,7 +635,7 @@ public class BLEComm {
|
||||||
message.wait(5000);
|
message.wait(5000);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
log.error("sendMessage InterruptedException", e);
|
log.error("sendMessage InterruptedException", e);
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1526,7 +1526,7 @@ public class LocalInsightPlugin extends PluginBase implements PumpInterface, Con
|
||||||
data.put("notes", note);
|
data.put("notes", note);
|
||||||
NSUpload.uploadCareportalEntryToNS(data);
|
NSUpload.uploadCareportalEntryToNS(data);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1554,7 +1554,7 @@ public class LocalInsightPlugin extends PluginBase implements PumpInterface, Con
|
||||||
data.put("eventType", event);
|
data.put("eventType", event);
|
||||||
NSUpload.uploadCareportalEntryToNS(data);
|
NSUpload.uploadCareportalEntryToNS(data);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,11 @@ package info.nightscout.androidaps.plugins.pump.insight.app_layer.history.histor
|
||||||
import info.nightscout.androidaps.plugins.pump.insight.ids.HistoryEventIDs;
|
import info.nightscout.androidaps.plugins.pump.insight.ids.HistoryEventIDs;
|
||||||
import info.nightscout.androidaps.plugins.pump.insight.utils.BOCUtil;
|
import info.nightscout.androidaps.plugins.pump.insight.utils.BOCUtil;
|
||||||
import info.nightscout.androidaps.plugins.pump.insight.utils.ByteBuf;
|
import info.nightscout.androidaps.plugins.pump.insight.utils.ByteBuf;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class HistoryEvent implements Comparable<HistoryEvent> {
|
public class HistoryEvent implements Comparable<HistoryEvent> {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(HistoryEvent.class);
|
||||||
|
|
||||||
private int eventYear;
|
private int eventYear;
|
||||||
private int eventMonth;
|
private int eventMonth;
|
||||||
|
@ -22,10 +25,8 @@ public class HistoryEvent implements Comparable<HistoryEvent> {
|
||||||
else {
|
else {
|
||||||
try {
|
try {
|
||||||
event = eventClass.newInstance();
|
event = eventClass.newInstance();
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException | InstantiationException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
} catch (InstantiationException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
event.parseHeader(byteBuf);
|
event.parseHeader(byteBuf);
|
||||||
|
|
|
@ -48,6 +48,7 @@ import info.nightscout.androidaps.plugins.general.overview.dialogs.ErrorHelperAc
|
||||||
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification;
|
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification;
|
||||||
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
|
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
|
||||||
import info.nightscout.androidaps.plugins.pump.common.PumpPluginAbstract;
|
import info.nightscout.androidaps.plugins.pump.common.PumpPluginAbstract;
|
||||||
|
import info.nightscout.androidaps.plugins.pump.common.bolusInfo.DetailedBolusInfoStorage;
|
||||||
import info.nightscout.androidaps.plugins.pump.common.defs.PumpDriverState;
|
import info.nightscout.androidaps.plugins.pump.common.defs.PumpDriverState;
|
||||||
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType;
|
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType;
|
||||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkConst;
|
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkConst;
|
||||||
|
@ -372,7 +373,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
||||||
refreshAnyStatusThatNeedsToBeRefreshed();
|
refreshAnyStatusThatNeedsToBeRefreshed();
|
||||||
}
|
}
|
||||||
|
|
||||||
RxBus.INSTANCE.send(new EventMedtronicPumpValuesChanged());
|
RxBus.INSTANCE.send(new EventMedtronicPumpValuesChanged());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -386,7 +387,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
||||||
|
|
||||||
RileyLinkServiceState rileyLinkServiceState = MedtronicUtil.getServiceState();
|
RileyLinkServiceState rileyLinkServiceState = MedtronicUtil.getServiceState();
|
||||||
|
|
||||||
if (rileyLinkServiceState==null) {
|
if (rileyLinkServiceState == null) {
|
||||||
LOG.error("RileyLink unreachable. RileyLinkServiceState is null.");
|
LOG.error("RileyLink unreachable. RileyLinkServiceState is null.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -744,13 +745,13 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
||||||
|
|
||||||
ClockDTO clock = MedtronicUtil.getPumpTime();
|
ClockDTO clock = MedtronicUtil.getPumpTime();
|
||||||
|
|
||||||
if (clock==null) { // retry
|
if (clock == null) { // retry
|
||||||
medtronicUIComm.executeCommand(MedtronicCommandType.GetRealTimeClock);
|
medtronicUIComm.executeCommand(MedtronicCommandType.GetRealTimeClock);
|
||||||
|
|
||||||
clock = MedtronicUtil.getPumpTime();
|
clock = MedtronicUtil.getPumpTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clock==null)
|
if (clock == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int timeDiff = Math.abs(clock.timeDifference);
|
int timeDiff = Math.abs(clock.timeDifference);
|
||||||
|
@ -866,6 +867,11 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
|
||||||
|
detailedBolusInfo.date = now;
|
||||||
|
detailedBolusInfo.deliverAt = now; // not sure about that one
|
||||||
|
|
||||||
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, true);
|
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, true);
|
||||||
|
|
||||||
// we subtract insulin, exact amount will be visible with next remainingInsulin update.
|
// we subtract insulin, exact amount will be visible with next remainingInsulin update.
|
||||||
|
@ -877,7 +883,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
||||||
|
|
||||||
// calculate time for bolus and set driver to busy for that time
|
// calculate time for bolus and set driver to busy for that time
|
||||||
int bolusTime = (int) (detailedBolusInfo.insulin * 42.0d);
|
int bolusTime = (int) (detailedBolusInfo.insulin * 42.0d);
|
||||||
long time = System.currentTimeMillis() + (bolusTime * 1000);
|
long time = now + (bolusTime * 1000);
|
||||||
|
|
||||||
this.busyTimestamps.add(time);
|
this.busyTimestamps.add(time);
|
||||||
setEnableCustomAction(MedtronicCustomActionType.ClearBolusBlock, true);
|
setEnableCustomAction(MedtronicCustomActionType.ClearBolusBlock, true);
|
||||||
|
@ -1065,10 +1071,10 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
||||||
@Override
|
@Override
|
||||||
public PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes, Profile profile,
|
public PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes, Profile profile,
|
||||||
boolean enforceNew) {
|
boolean enforceNew) {
|
||||||
if (percent==0) {
|
if (percent == 0) {
|
||||||
return setTempBasalAbsolute(0.0d, durationInMinutes, profile, enforceNew);
|
return setTempBasalAbsolute(0.0d, durationInMinutes, profile, enforceNew);
|
||||||
} else {
|
} else {
|
||||||
double absoluteValue = profile.getBasal() * (percent /100.0d);
|
double absoluteValue = profile.getBasal() * (percent / 100.0d);
|
||||||
getMDTPumpStatus();
|
getMDTPumpStatus();
|
||||||
absoluteValue = pumpStatusLocal.pumpType.determineCorrectBasalSize(absoluteValue);
|
absoluteValue = pumpStatusLocal.pumpType.determineCorrectBasalSize(absoluteValue);
|
||||||
LOG.warn("setTempBasalPercent [MedtronicPumpPlugin] - You are trying to use setTempBasalPercent with percent other then 0% (%d). This will start setTempBasalAbsolute, with calculated value (%.3f). Result might not be 100% correct.", percent, absoluteValue);
|
LOG.warn("setTempBasalPercent [MedtronicPumpPlugin] - You are trying to use setTempBasalPercent with percent other then 0% (%d). This will start setTempBasalAbsolute, with calculated value (%.3f). Result might not be 100% correct.", percent, absoluteValue);
|
||||||
|
|
|
@ -412,25 +412,18 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder<PumpHis
|
||||||
rate = body[1] * 0.025f;
|
rate = body[1] * 0.025f;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG.info("Basal Profile Start: offset={}, rate={}, index={}, body_raw={}", offset, rate, index,
|
//LOG.info("Basal Profile Start: offset={}, rate={}, index={}, body_raw={}", offset, rate, index, body);
|
||||||
body);
|
|
||||||
|
|
||||||
if (rate == null) {
|
if (rate == null) {
|
||||||
LOG.warn("Basal Profile Start (ERROR): offset={}, rate={}, index={}, body_raw={}", offset, rate, index,
|
LOG.warn("Basal Profile Start (ERROR): offset={}, rate={}, index={}, body_raw={}", offset, rate, index,
|
||||||
body);
|
body);
|
||||||
return RecordDecodeStatus.Error;
|
return RecordDecodeStatus.Error;
|
||||||
} else {
|
} else {
|
||||||
// writeData(PumpBaseType.Basal, PumpBasalType.ValueChange, getFormattedFloat(rate, 3),
|
|
||||||
// entry.getATechDate());
|
|
||||||
entry.addDecodedData("Value", getFormattedFloat(rate, 3));
|
entry.addDecodedData("Value", getFormattedFloat(rate, 3));
|
||||||
entry.setDisplayableValue(getFormattedFloat(rate, 3));
|
entry.setDisplayableValue(getFormattedFloat(rate, 3));
|
||||||
return RecordDecodeStatus.OK;
|
return RecordDecodeStatus.OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// profileIndex = asUINT8(data[1]);
|
|
||||||
// offset = asUINT8(data[7]) * 30 * 1000 * 60;
|
|
||||||
// rate = (double)(asUINT8(data[8])) / 40.0;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -10,12 +10,10 @@ import java.util.List;
|
||||||
import info.nightscout.androidaps.logging.L;
|
import info.nightscout.androidaps.logging.L;
|
||||||
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil;
|
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil;
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by andy on 9/23/18.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* History page contains data, sorted from newest to oldest (0=newest..n=oldest)
|
* History page contains data, sorted from newest to oldest (0=newest..n=oldest)
|
||||||
|
*
|
||||||
|
* Created by andy on 9/23/18.
|
||||||
*/
|
*/
|
||||||
public class PumpHistoryResult {
|
public class PumpHistoryResult {
|
||||||
|
|
||||||
|
@ -29,8 +27,6 @@ public class PumpHistoryResult {
|
||||||
public List<PumpHistoryEntry> validEntries;
|
public List<PumpHistoryEntry> validEntries;
|
||||||
|
|
||||||
|
|
||||||
// private Object validValues;
|
|
||||||
|
|
||||||
public PumpHistoryResult(PumpHistoryEntry searchEntry, Long targetDate) {
|
public PumpHistoryResult(PumpHistoryEntry searchEntry, Long targetDate) {
|
||||||
if (searchEntry != null) {
|
if (searchEntry != null) {
|
||||||
/*
|
/*
|
||||||
|
@ -109,9 +105,8 @@ public class PumpHistoryResult {
|
||||||
if (unprocessedEntry.isAfter(this.searchDate)) {
|
if (unprocessedEntry.isAfter(this.searchDate)) {
|
||||||
this.validEntries.add(unprocessedEntry);
|
this.validEntries.add(unprocessedEntry);
|
||||||
} else {
|
} else {
|
||||||
LOG.debug("PE. PumpHistoryResult. Not after.. Unprocessed Entry [year={},entry={}]",
|
// LOG.debug("PE. PumpHistoryResult. Not after.. Unprocessed Entry [year={},entry={}]",
|
||||||
DateTimeUtil.getYear(unprocessedEntry.atechDateTime), unprocessedEntry);
|
// DateTimeUtil.getYear(unprocessedEntry.atechDateTime), unprocessedEntry);
|
||||||
|
|
||||||
if (DateTimeUtil.getYear(unprocessedEntry.atechDateTime) > 2015)
|
if (DateTimeUtil.getYear(unprocessedEntry.atechDateTime) > 2015)
|
||||||
olderEntries++;
|
olderEntries++;
|
||||||
}
|
}
|
||||||
|
@ -131,14 +126,6 @@ public class PumpHistoryResult {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void clearOrPrepareList() {
|
|
||||||
if (this.validEntries == null)
|
|
||||||
this.validEntries = new ArrayList<>();
|
|
||||||
else
|
|
||||||
this.validEntries.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "PumpHistoryResult [unprocessed=" + (unprocessedEntries != null ? "" + unprocessedEntries.size() : "0") + //
|
return "PumpHistoryResult [unprocessed=" + (unprocessedEntries != null ? "" + unprocessedEntries.size() : "0") + //
|
||||||
", valid=" + (validEntries != null ? "" + validEntries.size() : "0") + //
|
", valid=" + (validEntries != null ? "" + validEntries.size() : "0") + //
|
||||||
|
|
|
@ -49,6 +49,7 @@ import info.nightscout.androidaps.plugins.pump.medtronic.driver.MedtronicPumpSta
|
||||||
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicConst;
|
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicConst;
|
||||||
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
|
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
|
||||||
import info.nightscout.androidaps.plugins.treatments.Treatment;
|
import info.nightscout.androidaps.plugins.treatments.Treatment;
|
||||||
|
import info.nightscout.androidaps.plugins.treatments.TreatmentService;
|
||||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
|
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.androidaps.utils.DateUtil;
|
import info.nightscout.androidaps.utils.DateUtil;
|
||||||
import info.nightscout.androidaps.utils.SP;
|
import info.nightscout.androidaps.utils.SP;
|
||||||
|
@ -67,7 +68,6 @@ import info.nightscout.androidaps.utils.SP;
|
||||||
// All things marked with "TODO: Fix db code" needs to be updated in new 2.5 database code
|
// All things marked with "TODO: Fix db code" needs to be updated in new 2.5 database code
|
||||||
|
|
||||||
public class MedtronicHistoryData {
|
public class MedtronicHistoryData {
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(L.PUMP);
|
private static final Logger LOG = LoggerFactory.getLogger(L.PUMP);
|
||||||
|
|
||||||
private List<PumpHistoryEntry> allHistory = null;
|
private List<PumpHistoryEntry> allHistory = null;
|
||||||
|
@ -77,6 +77,7 @@ public class MedtronicHistoryData {
|
||||||
private boolean isInit = false;
|
private boolean isInit = false;
|
||||||
|
|
||||||
private Gson gson;
|
private Gson gson;
|
||||||
|
private Gson gsonCore;
|
||||||
|
|
||||||
private DatabaseHelper databaseHelper = MainApp.getDbHelper();
|
private DatabaseHelper databaseHelper = MainApp.getDbHelper();
|
||||||
private ClockDTO pumpTime;
|
private ClockDTO pumpTime;
|
||||||
|
@ -94,10 +95,15 @@ public class MedtronicHistoryData {
|
||||||
public MedtronicHistoryData() {
|
public MedtronicHistoryData() {
|
||||||
this.allHistory = new ArrayList<>();
|
this.allHistory = new ArrayList<>();
|
||||||
this.gson = MedtronicUtil.gsonInstance;
|
this.gson = MedtronicUtil.gsonInstance;
|
||||||
|
this.gsonCore = MedtronicUtil.getGsonInstanceCore();
|
||||||
|
|
||||||
if (this.gson == null) {
|
if (this.gson == null) {
|
||||||
this.gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
|
this.gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.gsonCore == null) {
|
||||||
|
this.gsonCore = new GsonBuilder().create();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -523,7 +529,7 @@ public class MedtronicHistoryData {
|
||||||
data.put("eventType", event);
|
data.put("eventType", event);
|
||||||
NSUpload.uploadCareportalEntryToNS(data);
|
NSUpload.uploadCareportalEntryToNS(data);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
LOG.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -597,7 +603,7 @@ public class MedtronicHistoryData {
|
||||||
|
|
||||||
if (doubleBolusDebug)
|
if (doubleBolusDebug)
|
||||||
LOG.debug("DoubleBolusDebug: List (before filter): {}, FromDb={}", gson.toJson(entryList),
|
LOG.debug("DoubleBolusDebug: List (before filter): {}, FromDb={}", gson.toJson(entryList),
|
||||||
gson.toJson(entriesFromHistory));
|
gsonCore.toJson(entriesFromHistory));
|
||||||
|
|
||||||
filterOutAlreadyAddedEntries(entryList, entriesFromHistory);
|
filterOutAlreadyAddedEntries(entryList, entriesFromHistory);
|
||||||
|
|
||||||
|
@ -609,7 +615,7 @@ public class MedtronicHistoryData {
|
||||||
|
|
||||||
if (doubleBolusDebug)
|
if (doubleBolusDebug)
|
||||||
LOG.debug("DoubleBolusDebug: List (after filter): {}, FromDb={}", gson.toJson(entryList),
|
LOG.debug("DoubleBolusDebug: List (after filter): {}, FromDb={}", gson.toJson(entryList),
|
||||||
gson.toJson(entriesFromHistory));
|
gsonCore.toJson(entriesFromHistory));
|
||||||
|
|
||||||
if (isCollectionEmpty(entriesFromHistory)) {
|
if (isCollectionEmpty(entriesFromHistory)) {
|
||||||
for (PumpHistoryEntry treatment : entryList) {
|
for (PumpHistoryEntry treatment : entryList) {
|
||||||
|
@ -862,6 +868,7 @@ public class MedtronicHistoryData {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
List<DbObjectBase> removeTreatmentsFromHistory = new ArrayList<>();
|
List<DbObjectBase> removeTreatmentsFromHistory = new ArrayList<>();
|
||||||
|
List<PumpHistoryEntry> removeTreatmentsFromPH = new ArrayList<>();
|
||||||
|
|
||||||
for (DbObjectBase treatment : treatmentsFromHistory) {
|
for (DbObjectBase treatment : treatmentsFromHistory) {
|
||||||
|
|
||||||
|
@ -879,11 +886,17 @@ public class MedtronicHistoryData {
|
||||||
if (selectedBolus != null) {
|
if (selectedBolus != null) {
|
||||||
entryList.remove(selectedBolus);
|
entryList.remove(selectedBolus);
|
||||||
|
|
||||||
|
removeTreatmentsFromPH.add(selectedBolus);
|
||||||
removeTreatmentsFromHistory.add(treatment);
|
removeTreatmentsFromHistory.add(treatment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (doubleBolusDebug)
|
||||||
|
LOG.debug("DoubleBolusDebug: filterOutAlreadyAddedEntries: PumpHistory={}, Treatments={}",
|
||||||
|
gson.toJson(removeTreatmentsFromPH),
|
||||||
|
gsonCore.toJson(removeTreatmentsFromHistory));
|
||||||
|
|
||||||
treatmentsFromHistory.removeAll(removeTreatmentsFromHistory);
|
treatmentsFromHistory.removeAll(removeTreatmentsFromHistory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -947,36 +960,23 @@ public class MedtronicHistoryData {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
DetailedBolusInfo detailedBolusInfo = DetailedBolusInfoStorage.INSTANCE.findDetailedBolusInfo(treatment.date, bolusDTO.getDeliveredAmount());
|
if (doubleBolusDebug)
|
||||||
|
LOG.debug("DoubleBolusDebug: addBolus(OldTreatment={}): Bolus={}", treatment, bolusDTO);
|
||||||
|
|
||||||
|
treatment.source = Source.PUMP;
|
||||||
|
treatment.pumpId = bolus.getPumpId();
|
||||||
|
treatment.insulin = bolusDTO.getDeliveredAmount();
|
||||||
|
|
||||||
|
TreatmentService.UpdateReturn updateReturn = TreatmentsPlugin.getPlugin().getService().createOrUpdateMedtronic(treatment, false);
|
||||||
|
|
||||||
if (doubleBolusDebug)
|
if (doubleBolusDebug)
|
||||||
LOG.debug("DoubleBolusDebug: addBolus(tretament={}): Bolus={}, DetailedBolusInfo={}", treatment, bolusDTO, detailedBolusInfo);
|
LOG.debug("DoubleBolusDebug: addBolus(tretament!=null): NewTreatment={}, UpdateReturn={}", treatment, updateReturn);
|
||||||
|
|
||||||
if (detailedBolusInfo == null) {
|
|
||||||
detailedBolusInfo = new DetailedBolusInfo();
|
|
||||||
|
|
||||||
if (doubleBolusDebug)
|
|
||||||
LOG.debug("DoubleBolusDebug: detailedBolusInfoCouldNotBeRetrived !");
|
|
||||||
}
|
|
||||||
|
|
||||||
detailedBolusInfo.date = treatment.date;
|
|
||||||
detailedBolusInfo.source = Source.PUMP;
|
|
||||||
detailedBolusInfo.pumpId = bolus.getPumpId();
|
|
||||||
detailedBolusInfo.insulin = bolusDTO.getDeliveredAmount();
|
|
||||||
detailedBolusInfo.carbs = treatment.carbs;
|
|
||||||
|
|
||||||
addCarbsFromEstimate(detailedBolusInfo, bolus);
|
|
||||||
|
|
||||||
if (doubleBolusDebug)
|
|
||||||
LOG.debug("DoubleBolusDebug: addBolus(tretament!=null): DetailedBolusInfo(New)={}", detailedBolusInfo);
|
|
||||||
|
|
||||||
boolean newRecord = TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, false);
|
|
||||||
|
|
||||||
bolus.setLinkedObject(detailedBolusInfo);
|
|
||||||
|
|
||||||
if (isLogEnabled())
|
if (isLogEnabled())
|
||||||
LOG.debug("editBolus - [date={},pumpId={}, insulin={}, newRecord={}]", detailedBolusInfo.date,
|
LOG.debug("editBolus - [date={},pumpId={}, insulin={}, newRecord={}]", treatment.date,
|
||||||
detailedBolusInfo.pumpId, detailedBolusInfo.insulin, newRecord);
|
treatment.pumpId, treatment.insulin, updateReturn.toString());
|
||||||
|
|
||||||
|
bolus.setLinkedObject(treatment);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,8 +61,7 @@ public class MedtronicUtil extends RileyLinkUtil {
|
||||||
private static int doneBit = 1 << 7;
|
private static int doneBit = 1 << 7;
|
||||||
private static ClockDTO pumpTime;
|
private static ClockDTO pumpTime;
|
||||||
public static Gson gsonInstance = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
|
public static Gson gsonInstance = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
|
||||||
public static Gson gsonInstancePretty = new GsonBuilder().excludeFieldsWithoutExposeAnnotation()
|
public static Gson gsonInstanceCore = new GsonBuilder().create();
|
||||||
.setPrettyPrinting().create();
|
|
||||||
private static BatteryType batteryType = BatteryType.None;
|
private static BatteryType batteryType = BatteryType.None;
|
||||||
|
|
||||||
|
|
||||||
|
@ -70,8 +69,9 @@ public class MedtronicUtil extends RileyLinkUtil {
|
||||||
return gsonInstance;
|
return gsonInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Gson getGsonInstancePretty() {
|
|
||||||
return gsonInstancePretty;
|
public static Gson getGsonInstanceCore() {
|
||||||
|
return gsonInstanceCore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ import info.nightscout.androidaps.logging.L
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
|
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
|
||||||
import info.nightscout.androidaps.utils.DateUtil
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
import info.nightscout.androidaps.utils.SP
|
import info.nightscout.androidaps.utils.SP
|
||||||
|
import info.nightscout.androidaps.utils.T
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
|
|
||||||
|
@ -51,7 +52,7 @@ object SourceDexcomPlugin : PluginBase(PluginDescription()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun findDexcomPackageName(): String? {
|
fun findDexcomPackageName(): String? {
|
||||||
val packageManager = MainApp.instance().packageManager;
|
val packageManager = MainApp.instance().packageManager
|
||||||
for (packageInfo in packageManager.getInstalledPackages(0)) {
|
for (packageInfo in packageManager.getInstalledPackages(0)) {
|
||||||
if (PACKAGE_NAMES.contains(packageInfo.packageName)) return packageInfo.packageName
|
if (PACKAGE_NAMES.contains(packageInfo.packageName)) return packageInfo.packageName
|
||||||
}
|
}
|
||||||
|
@ -64,43 +65,53 @@ object SourceDexcomPlugin : PluginBase(PluginDescription()
|
||||||
val sensorType = intent.getStringExtra("sensorType") ?: ""
|
val sensorType = intent.getStringExtra("sensorType") ?: ""
|
||||||
val glucoseValues = intent.getBundleExtra("glucoseValues")
|
val glucoseValues = intent.getBundleExtra("glucoseValues")
|
||||||
for (i in 0 until glucoseValues.size()) {
|
for (i in 0 until glucoseValues.size()) {
|
||||||
val glucoseValue = glucoseValues.getBundle(i.toString())
|
glucoseValues.getBundle(i.toString())?.let { glucoseValue ->
|
||||||
val bgReading = BgReading()
|
val bgReading = BgReading()
|
||||||
bgReading.value = glucoseValue!!.getInt("glucoseValue").toDouble()
|
bgReading.value = glucoseValue.getInt("glucoseValue").toDouble()
|
||||||
bgReading.direction = glucoseValue.getString("trendArrow")
|
bgReading.direction = glucoseValue.getString("trendArrow")
|
||||||
bgReading.date = glucoseValue.getLong("timestamp") * 1000
|
bgReading.date = glucoseValue.getLong("timestamp") * 1000
|
||||||
bgReading.raw = 0.0
|
bgReading.raw = 0.0
|
||||||
if (MainApp.getDbHelper().createIfNotExists(bgReading, "Dexcom$sensorType")) {
|
if (MainApp.getDbHelper().createIfNotExists(bgReading, "Dexcom$sensorType")) {
|
||||||
if (SP.getBoolean(R.string.key_dexcomg5_nsupload, false)) {
|
if (SP.getBoolean(R.string.key_dexcomg5_nsupload, false)) {
|
||||||
NSUpload.uploadBg(bgReading, "AndroidAPS-Dexcom$sensorType")
|
NSUpload.uploadBg(bgReading, "AndroidAPS-Dexcom$sensorType")
|
||||||
}
|
}
|
||||||
if (SP.getBoolean(R.string.key_dexcomg5_xdripupload, false)) {
|
if (SP.getBoolean(R.string.key_dexcomg5_xdripupload, false)) {
|
||||||
NSUpload.sendToXdrip(bgReading)
|
NSUpload.sendToXdrip(bgReading)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val meters = intent.getBundleExtra("meters")
|
val meters = intent.getBundleExtra("meters")
|
||||||
for (i in 0 until meters.size()) {
|
for (i in 0 until meters.size()) {
|
||||||
val meter = meters.getBundle(i.toString())
|
val meter = meters.getBundle(i.toString())
|
||||||
val timestamp = meter!!.getLong("timestamp") * 1000
|
meter?.let {
|
||||||
if (MainApp.getDbHelper().getCareportalEventFromTimestamp(timestamp) != null) continue
|
val timestamp = it.getLong("timestamp") * 1000
|
||||||
val jsonObject = JSONObject()
|
val now = DateUtil.now()
|
||||||
jsonObject.put("enteredBy", "AndroidAPS-Dexcom$sensorType")
|
if (timestamp > now - T.months(1).msecs() && timestamp < now)
|
||||||
jsonObject.put("created_at", DateUtil.toISOString(timestamp))
|
if (MainApp.getDbHelper().getCareportalEventFromTimestamp(timestamp) == null) {
|
||||||
jsonObject.put("eventType", CareportalEvent.BGCHECK)
|
val jsonObject = JSONObject()
|
||||||
jsonObject.put("glucoseType", "Finger")
|
jsonObject.put("enteredBy", "AndroidAPS-Dexcom$sensorType")
|
||||||
jsonObject.put("glucose", meter.getInt("meterValue"))
|
jsonObject.put("created_at", DateUtil.toISOString(timestamp))
|
||||||
jsonObject.put("units", Constants.MGDL)
|
jsonObject.put("eventType", CareportalEvent.BGCHECK)
|
||||||
NSUpload.uploadCareportalEntryToNS(jsonObject)
|
jsonObject.put("glucoseType", "Finger")
|
||||||
|
jsonObject.put("glucose", meter.getInt("meterValue"))
|
||||||
|
jsonObject.put("units", Constants.MGDL)
|
||||||
|
NSUpload.uploadCareportalEntryToNS(jsonObject)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (SP.getBoolean(R.string.key_dexcom_lognssensorchange, false) && intent.hasExtra("sensorInsertionTime")) {
|
if (SP.getBoolean(R.string.key_dexcom_lognssensorchange, false) && intent.hasExtra("sensorInsertionTime")) {
|
||||||
val sensorInsertionTime = intent.extras!!.getLong("sensorInsertionTime") * 1000
|
intent.extras?.let {
|
||||||
if (MainApp.getDbHelper().getCareportalEventFromTimestamp(sensorInsertionTime) == null) {
|
val sensorInsertionTime = it.getLong("sensorInsertionTime") * 1000
|
||||||
val jsonObject = JSONObject()
|
val now = DateUtil.now()
|
||||||
jsonObject.put("enteredBy", "AndroidAPS-Dexcom$sensorType")
|
if (sensorInsertionTime > now - T.months(1).msecs() && sensorInsertionTime < now)
|
||||||
jsonObject.put("created_at", DateUtil.toISOString(sensorInsertionTime))
|
if (MainApp.getDbHelper().getCareportalEventFromTimestamp(sensorInsertionTime) == null) {
|
||||||
jsonObject.put("eventType", CareportalEvent.SENSORCHANGE)
|
val jsonObject = JSONObject()
|
||||||
NSUpload.uploadCareportalEntryToNS(jsonObject)
|
jsonObject.put("enteredBy", "AndroidAPS-Dexcom$sensorType")
|
||||||
|
jsonObject.put("created_at", DateUtil.toISOString(sensorInsertionTime))
|
||||||
|
jsonObject.put("eventType", CareportalEvent.SENSORCHANGE)
|
||||||
|
NSUpload.uploadCareportalEntryToNS(jsonObject)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
|
|
@ -133,7 +133,7 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> {
|
||||||
try {
|
try {
|
||||||
getDao().executeRaw("ALTER TABLE `" + Treatment.TABLE_TREATMENTS + "` ADD COLUMN boluscalc STRING;");
|
getDao().executeRaw("ALTER TABLE `" + Treatment.TABLE_TREATMENTS + "` ADD COLUMN boluscalc STRING;");
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (L.isEnabled(L.DATATREATMENTS))
|
if (L.isEnabled(L.DATATREATMENTS))
|
||||||
|
@ -147,7 +147,7 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> {
|
||||||
try {
|
try {
|
||||||
getDao().executeRaw("ALTER TABLE `" + Treatment.TABLE_TREATMENTS + "` DROP COLUMN boluscalc STRING;");
|
getDao().executeRaw("ALTER TABLE `" + Treatment.TABLE_TREATMENTS + "` DROP COLUMN boluscalc STRING;");
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
log.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -736,6 +736,14 @@ public class TreatmentService extends OrmLiteBaseService<DatabaseHelper> {
|
||||||
|
|
||||||
boolean newRecord;
|
boolean newRecord;
|
||||||
boolean success;
|
boolean success;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "UpdateReturn [" +
|
||||||
|
"newRecord=" + newRecord +
|
||||||
|
", success=" + success +
|
||||||
|
']';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -349,7 +349,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
||||||
long time = System.currentTimeMillis();
|
long time = System.currentTimeMillis();
|
||||||
synchronized (treatments) {
|
synchronized (treatments) {
|
||||||
if (MedtronicHistoryData.doubleBolusDebug)
|
if (MedtronicHistoryData.doubleBolusDebug)
|
||||||
log.debug("DoubleBolusDebug: AllTreatmentsInDb: {}", MedtronicUtil.getGsonInstance().toJson(treatments));
|
log.debug("DoubleBolusDebug: AllTreatmentsInDb: {}", MedtronicUtil.getGsonInstanceCore().toJson(treatments));
|
||||||
|
|
||||||
for (Treatment t : treatments) {
|
for (Treatment t : treatments) {
|
||||||
if (t.date <= time && t.date >= fromTimestamp)
|
if (t.date <= time && t.date >= fromTimestamp)
|
||||||
|
@ -357,7 +357,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MedtronicHistoryData.doubleBolusDebug)
|
if (MedtronicHistoryData.doubleBolusDebug)
|
||||||
log.debug("DoubleBolusDebug: FilteredTreatments: AfterTime={}, Items={}", fromTimestamp, MedtronicUtil.getGsonInstance().toJson(in5minback));
|
log.debug("DoubleBolusDebug: FilteredTreatments: AfterTime={}, Items={}", fromTimestamp, MedtronicUtil.getGsonInstanceCore().toJson(in5minback));
|
||||||
|
|
||||||
return in5minback;
|
return in5minback;
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ public class CommandSetProfile extends Command {
|
||||||
// Send SMS notification if ProfileSwitch is comming from NS
|
// Send SMS notification if ProfileSwitch is comming from NS
|
||||||
ProfileSwitch profileSwitch = TreatmentsPlugin.getPlugin().getProfileSwitchFromHistory(System.currentTimeMillis());
|
ProfileSwitch profileSwitch = TreatmentsPlugin.getPlugin().getProfileSwitchFromHistory(System.currentTimeMillis());
|
||||||
if (profileSwitch != null && r.enacted && profileSwitch.source == Source.NIGHTSCOUT) {
|
if (profileSwitch != null && r.enacted && profileSwitch.source == Source.NIGHTSCOUT) {
|
||||||
SmsCommunicatorPlugin smsCommunicatorPlugin = SmsCommunicatorPlugin.getPlugin();
|
SmsCommunicatorPlugin smsCommunicatorPlugin = SmsCommunicatorPlugin.INSTANCE;
|
||||||
if (smsCommunicatorPlugin.isEnabled(PluginType.GENERAL)) {
|
if (smsCommunicatorPlugin.isEnabled(PluginType.GENERAL)) {
|
||||||
smsCommunicatorPlugin.sendNotificationToAllNumbers(MainApp.gs(R.string.profile_set_ok));
|
smsCommunicatorPlugin.sendNotificationToAllNumbers(MainApp.gs(R.string.profile_set_ok));
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ public class ChargingStateReceiver extends BroadcastReceiver {
|
||||||
lastEvent = event;
|
lastEvent = event;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EventChargingState grabChargingState(Context context) {
|
public static EventChargingState grabChargingState(Context context) {
|
||||||
BatteryManager bm = (BatteryManager) context.getSystemService(Context.BATTERY_SERVICE);
|
BatteryManager bm = (BatteryManager) context.getSystemService(Context.BATTERY_SERVICE);
|
||||||
|
|
||||||
if (bm == null)
|
if (bm == null)
|
||||||
|
|
|
@ -26,11 +26,6 @@ public class NetworkChangeReceiver extends BroadcastReceiver {
|
||||||
|
|
||||||
public static final NetworkChangeReceiver instance = new NetworkChangeReceiver();
|
public static final NetworkChangeReceiver instance = new NetworkChangeReceiver();
|
||||||
|
|
||||||
// TODO: Split NSClient into network state component that can be used by several plugins and logic for plugin
|
|
||||||
public static void fetch() {
|
|
||||||
new NetworkChangeReceiver().grabNetworkStatus(MainApp.instance().getApplicationContext());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(final Context context, final Intent intent) {
|
public void onReceive(final Context context, final Intent intent) {
|
||||||
EventNetworkChange event = grabNetworkStatus(context);
|
EventNetworkChange event = grabNetworkStatus(context);
|
||||||
|
@ -39,7 +34,7 @@ public class NetworkChangeReceiver extends BroadcastReceiver {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public EventNetworkChange grabNetworkStatus(final Context context) {
|
public static EventNetworkChange grabNetworkStatus(final Context context) {
|
||||||
EventNetworkChange event = new EventNetworkChange();
|
EventNetworkChange event = new EventNetworkChange();
|
||||||
|
|
||||||
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||||
|
|
|
@ -103,7 +103,7 @@ public class DataService extends IntentService {
|
||||||
) {
|
) {
|
||||||
handleNewDataFromNSClient(intent);
|
handleNewDataFromNSClient(intent);
|
||||||
} else if (Telephony.Sms.Intents.SMS_RECEIVED_ACTION.equals(action)) {
|
} else if (Telephony.Sms.Intents.SMS_RECEIVED_ACTION.equals(action)) {
|
||||||
SmsCommunicatorPlugin.getPlugin().handleNewData(intent);
|
SmsCommunicatorPlugin.INSTANCE.handleNewData(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (L.isEnabled(L.DATASERVICE))
|
if (L.isEnabled(L.DATASERVICE))
|
||||||
|
|
|
@ -93,15 +93,15 @@ public class DateUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int toSeconds(String hh_colon_mm) {
|
public static int toSeconds(String hh_colon_mm) {
|
||||||
Pattern p = Pattern.compile("(\\d+):(\\d+)( a.m.| p.m.| AM | PM|)");
|
Pattern p = Pattern.compile("(\\d+):(\\d+)( a.m.| p.m.| AM| PM|AM|PM|)");
|
||||||
Matcher m = p.matcher(hh_colon_mm);
|
Matcher m = p.matcher(hh_colon_mm);
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
|
||||||
if (m.find()) {
|
if (m.find()) {
|
||||||
retval = SafeParse.stringToInt(m.group(1)) * 60 * 60 + SafeParse.stringToInt(m.group(2)) * 60;
|
retval = SafeParse.stringToInt(m.group(1)) * 60 * 60 + SafeParse.stringToInt(m.group(2)) * 60;
|
||||||
if ((m.group(3).equals(" a.m.") || m.group(3).equals(" AM")) && m.group(1).equals("12"))
|
if ((m.group(3).equals(" a.m.") || m.group(3).equals(" AM") || m.group(3).equals("AM")) && m.group(1).equals("12"))
|
||||||
retval -= 12 * 60 * 60;
|
retval -= 12 * 60 * 60;
|
||||||
if ((m.group(3).equals(" p.m.") || m.group(3).equals(" PM")) && !(m.group(1).equals("12")))
|
if ((m.group(3).equals(" p.m.") || m.group(3).equals(" PM") || m.group(3).equals("PM")) && !(m.group(1).equals("12")))
|
||||||
retval += 12 * 60 * 60;
|
retval += 12 * 60 * 60;
|
||||||
}
|
}
|
||||||
return retval;
|
return retval;
|
||||||
|
@ -185,7 +185,7 @@ public class DateUtil {
|
||||||
long remainingTimeMinutes = timeInMillis / (1000 * 60);
|
long remainingTimeMinutes = timeInMillis / (1000 * 60);
|
||||||
long remainingTimeHours = remainingTimeMinutes / 60;
|
long remainingTimeHours = remainingTimeMinutes / 60;
|
||||||
remainingTimeMinutes = remainingTimeMinutes % 60;
|
remainingTimeMinutes = remainingTimeMinutes % 60;
|
||||||
return "(" + ((remainingTimeHours > 0) ? (remainingTimeHours + "h ") : "") + remainingTimeMinutes + "')";
|
return "(" + ((remainingTimeHours > 0) ? (remainingTimeHours + MainApp.gs(R.string.shorthour) + " ") : "") + remainingTimeMinutes + "')";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String sinceString(long timestamp) {
|
public static String sinceString(long timestamp) {
|
||||||
|
|
|
@ -1,14 +1,23 @@
|
||||||
package info.nightscout.androidaps.utils;
|
package info.nightscout.androidaps.utils;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by mike on 20.06.2016.
|
* Created by mike on 20.06.2016.
|
||||||
*/
|
*/
|
||||||
public class Round {
|
public class Round {
|
||||||
public static Double roundTo(double x, Double step) {
|
public static Double roundTo(double x, Double step) {
|
||||||
if (x != 0d) {
|
if (x == 0d) {
|
||||||
return Math.round(x / step) * step;
|
return 0d;
|
||||||
}
|
}
|
||||||
return 0d;
|
|
||||||
|
//Double oldCalc = Math.round(x / step) * step;
|
||||||
|
Double newCalc = BigDecimal.valueOf(Math.round(x / step)).multiply(BigDecimal.valueOf(step)).doubleValue();
|
||||||
|
|
||||||
|
// just for the tests, forcing failures
|
||||||
|
//newCalc = oldCalc;
|
||||||
|
|
||||||
|
return newCalc;
|
||||||
}
|
}
|
||||||
public static Double floorTo(Double x, Double step) {
|
public static Double floorTo(Double x, Double step) {
|
||||||
if (x != 0d) {
|
if (x != 0d) {
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
<string name="objectives_useloop">Display content of Loop plugin</string>
|
<string name="objectives_useloop">Display content of Loop plugin</string>
|
||||||
<string name="objectives_usescale">Use scale function by long-pressing BG chart</string>
|
<string name="objectives_usescale">Use scale function by long-pressing BG chart</string>
|
||||||
<string name="objectives_button_enter">Enter</string>
|
<string name="objectives_button_enter">Enter</string>
|
||||||
<string name="enter_code_obtained_from_developers_to_bypass_the_rest_of_objectives">Enter code obtained from developers to bypass the rest of objectives</string>
|
<string name="enter_code_obtained_from_developers_to_bypass_the_rest_of_objectives">If you were OpenAPS user before and your NS has at least 3 months of looping data, you can send an email to objectives@androidaps.org with your NS address and request code to bypass the rest of objectives. Enter code obtained from developers</string>
|
||||||
<string name="codeaccepted">Code accepted</string>
|
<string name="codeaccepted">Code accepted</string>
|
||||||
<string name="codeinvalid">Code invalid</string>
|
<string name="codeinvalid">Code invalid</string>
|
||||||
<string name="objectives_exam_objective">Prove your knowledge</string>
|
<string name="objectives_exam_objective">Prove your knowledge</string>
|
||||||
|
|
|
@ -292,11 +292,24 @@
|
||||||
<string name="smscommunicator_allowednumbers">Allowed phone numbers</string>
|
<string name="smscommunicator_allowednumbers">Allowed phone numbers</string>
|
||||||
<string name="smscommunicator_allowednumbers_summary">+XXXXXXXXXX;+YYYYYYYYYY</string>
|
<string name="smscommunicator_allowednumbers_summary">+XXXXXXXXXX;+YYYYYYYYYY</string>
|
||||||
<string name="smscommunicator_bolusreplywithcode">To deliver bolus %1$.2fU reply with code %2$s</string>
|
<string name="smscommunicator_bolusreplywithcode">To deliver bolus %1$.2fU reply with code %2$s</string>
|
||||||
|
<string name="smscommunicator_mealbolusreplywithcode">To deliver meal bolus %1$.2fU reply with code %2$s</string>
|
||||||
|
<string name="smscommunicator_temptargetwithcode">To set the Temp Target %1$s reply with code %2$s</string>
|
||||||
|
<string name="smscommunicator_temptargetcancel">To cancel Temp Target reply with code %1$s</string>
|
||||||
|
<string name="smscommunicator_stopsmswithcode">To disable the SMS Remote Service reply with code %1$s.\n\nKeep in mind that you\'ll able to reactivate it directly from the AAPS master smartphone only.</string>
|
||||||
|
<string name="smscommunicator_stoppedsms">SMS Remote Service stopped. To reactivate it, use AAPS on master smartphone.</string>
|
||||||
<string name="smscommunicator_calibrationreplywithcode">To send calibration %1$.2f reply with code %2$s</string>
|
<string name="smscommunicator_calibrationreplywithcode">To send calibration %1$.2f reply with code %2$s</string>
|
||||||
<string name="smscommunicator_bolusfailed">Bolus failed</string>
|
<string name="smscommunicator_bolusfailed">Bolus failed</string>
|
||||||
|
<string name="key_smscommunicator_remotebolusmindistance" translatable="false">smscommunicator_remotebolusmindistance</string>
|
||||||
|
<string name="smscommunicator_remotebolusmindistance_summary">Minimum number of minutes that must elapse between one remote bolus and the next</string>
|
||||||
|
<string name="smscommunicator_remotebolusmindistance">How many minutes must elapse, at least, between one bolus and the next</string>
|
||||||
|
<string name="smscommunicator_remotebolusmindistance_caveat">For your safety, to edit this preference you need to add at least 2 phone numbers.</string>
|
||||||
<string name="bolusdelivered">Bolus %1$.2fU delivered successfully</string>
|
<string name="bolusdelivered">Bolus %1$.2fU delivered successfully</string>
|
||||||
<string name="bolusrequested">Going to deliver %1$.2fU</string>
|
<string name="bolusrequested">Going to deliver %1$.2fU</string>
|
||||||
<string name="smscommunicator_bolusdelivered">Bolus %1$.2fU delivered successfully</string>
|
<string name="smscommunicator_bolusdelivered">Bolus %1$.2fU delivered successfully</string>
|
||||||
|
<string name="smscommunicator_mealbolusdelivered">Meal Bolus %1$.2fU delivered successfully</string>
|
||||||
|
<string name="smscommunicator_mealbolusdelivered_tt">Target %1$s for %2$d minutes</string>
|
||||||
|
<string name="smscommunicator_tt_set">Target %1$s for %2$d minutes set successfully</string>
|
||||||
|
<string name="smscommunicator_tt_canceled">Temp Target canceled successfully</string>
|
||||||
<string name="bolusdelivering">Delivering %1$.2fU</string>
|
<string name="bolusdelivering">Delivering %1$.2fU</string>
|
||||||
<string name="smscommunicator_remotecommandsallowed">Allow remote commands via SMS</string>
|
<string name="smscommunicator_remotecommandsallowed">Allow remote commands via SMS</string>
|
||||||
<string name="glucosetype_finger">Finger</string>
|
<string name="glucosetype_finger">Finger</string>
|
||||||
|
@ -356,10 +369,13 @@
|
||||||
<string name="smscommunicator_basalreplywithcode">To start basal %1$.2fU/h for %2$d min reply with code %3$s</string>
|
<string name="smscommunicator_basalreplywithcode">To start basal %1$.2fU/h for %2$d min reply with code %3$s</string>
|
||||||
<string name="smscommunicator_profilereplywithcode">To switch profile to %1$s %2$d%% reply with code %3$s</string>
|
<string name="smscommunicator_profilereplywithcode">To switch profile to %1$s %2$d%% reply with code %3$s</string>
|
||||||
<string name="smscommunicator_extendedreplywithcode">To start extended bolus %1$.2fU for %2$d min reply with code %3$s</string>
|
<string name="smscommunicator_extendedreplywithcode">To start extended bolus %1$.2fU for %2$d min reply with code %3$s</string>
|
||||||
|
<string name="smscommunicator_carbsreplywithcode">To enter %1$dg at %2$s reply with code %3$s</string>
|
||||||
<string name="smscommunicator_basalpctreplywithcode">To start basal %1$d%% for %2$d min reply with code %3$s</string>
|
<string name="smscommunicator_basalpctreplywithcode">To start basal %1$d%% for %2$d min reply with code %3$s</string>
|
||||||
<string name="smscommunicator_suspendreplywithcode">To suspend loop for %1$d minutes reply with code %2$s</string>
|
<string name="smscommunicator_suspendreplywithcode">To suspend loop for %1$d minutes reply with code %2$s</string>
|
||||||
<string name="smscommunicator_tempbasalset">Temp basal %1$.2fU/h for %2$d min started successfully</string>
|
<string name="smscommunicator_tempbasalset">Temp basal %1$.2fU/h for %2$d min started successfully</string>
|
||||||
<string name="smscommunicator_extendedset">Extended bolus %1$.2fU for %2$d min started successfully</string>
|
<string name="smscommunicator_extendedset">Extended bolus %1$.2fU for %2$d min started successfully</string>
|
||||||
|
<string name="smscommunicator_carbsset">Carbs %1$dg entered successfully</string>
|
||||||
|
<string name="smscommunicator_carbsfailed">Entering %1$dg of carbs failed</string>
|
||||||
<string name="smscommunicator_tempbasalset_percent">Temp basal %1$d%% for %2$d min started successfully</string>
|
<string name="smscommunicator_tempbasalset_percent">Temp basal %1$d%% for %2$d min started successfully</string>
|
||||||
<string name="smscommunicator_tempbasalfailed">Temp basal start failed</string>
|
<string name="smscommunicator_tempbasalfailed">Temp basal start failed</string>
|
||||||
<string name="smscommunicator_extendedfailed">Extended bolus start failed</string>
|
<string name="smscommunicator_extendedfailed">Extended bolus start failed</string>
|
||||||
|
@ -778,6 +794,7 @@
|
||||||
<string name="shortgramm">g</string>
|
<string name="shortgramm">g</string>
|
||||||
<string name="shortminute">m</string>
|
<string name="shortminute">m</string>
|
||||||
<string name="shorthour">h</string>
|
<string name="shorthour">h</string>
|
||||||
|
<string name="shortday">d</string>
|
||||||
<string name="none"><![CDATA[<none>]]></string>
|
<string name="none"><![CDATA[<none>]]></string>
|
||||||
<string name="shortkilojoul">kJ</string>
|
<string name="shortkilojoul">kJ</string>
|
||||||
<string name="shortenergy">En</string>
|
<string name="shortenergy">En</string>
|
||||||
|
@ -814,7 +831,7 @@
|
||||||
<string name="bgsource_upload">BG upload settings</string>
|
<string name="bgsource_upload">BG upload settings</string>
|
||||||
<string name="wear_detailed_delta_title">Show detailed delta</string>
|
<string name="wear_detailed_delta_title">Show detailed delta</string>
|
||||||
<string name="wear_detailed_delta_summary">Show delta with one more decimal place</string>
|
<string name="wear_detailed_delta_summary">Show delta with one more decimal place</string>
|
||||||
<string name="smbmaxminutes" translatable="false">45 60 75 90 105 120</string>
|
<string name="smbmaxminutes">SMB max minutes</string>
|
||||||
<string name="smbmaxminutes_summary">Max minutes of basal to limit SMB to</string>
|
<string name="smbmaxminutes_summary">Max minutes of basal to limit SMB to</string>
|
||||||
<string name="unsupportedfirmware">Unsupported pump firmware</string>
|
<string name="unsupportedfirmware">Unsupported pump firmware</string>
|
||||||
<string name="dexcomg5_xdripupload_title">Send BG data to xDrip+</string>
|
<string name="dexcomg5_xdripupload_title">Send BG data to xDrip+</string>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:validate="http://schemas.android.com/apk/res-auto">
|
||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
android:key="smscommunicator"
|
android:key="smscommunicator"
|
||||||
android:title="@string/smscommunicator">
|
android:title="@string/smscommunicator">
|
||||||
|
@ -8,6 +9,16 @@
|
||||||
android:key="@string/key_smscommunicator_allowednumbers"
|
android:key="@string/key_smscommunicator_allowednumbers"
|
||||||
android:summary="@string/smscommunicator_allowednumbers_summary"
|
android:summary="@string/smscommunicator_allowednumbers_summary"
|
||||||
android:title="@string/smscommunicator_allowednumbers" />
|
android:title="@string/smscommunicator_allowednumbers" />
|
||||||
|
<com.andreabaccega.widget.ValidatingEditTextPreference
|
||||||
|
android:key="@string/key_smscommunicator_remotebolusmindistance"
|
||||||
|
android:defaultValue="15"
|
||||||
|
android:summary="@string/smscommunicator_remotebolusmindistance_summary"
|
||||||
|
android:title="@string/smscommunicator_remotebolusmindistance"
|
||||||
|
validate:minNumber="3"
|
||||||
|
validate:maxNumber="60"
|
||||||
|
validate:testType="numericRange"
|
||||||
|
android:singleLineTitle="false"
|
||||||
|
/>
|
||||||
<SwitchPreference
|
<SwitchPreference
|
||||||
android:defaultValue="false"
|
android:defaultValue="false"
|
||||||
android:key="@string/key_smscommunicator_remotecommandsallowed"
|
android:key="@string/key_smscommunicator_remotecommandsallowed"
|
||||||
|
|
|
@ -37,6 +37,7 @@ import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
import static org.mockito.ArgumentMatchers.anyLong;
|
import static org.mockito.ArgumentMatchers.anyLong;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
import static org.mockito.Mockito.doReturn;
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
@ -107,6 +108,8 @@ public class AAPSMocker {
|
||||||
when(MainApp.gs(R.string.configbuilder_insulin)).thenReturn("Insulin");
|
when(MainApp.gs(R.string.configbuilder_insulin)).thenReturn("Insulin");
|
||||||
when(MainApp.gs(R.string.bolusdelivering)).thenReturn("Delivering 0.0U");
|
when(MainApp.gs(R.string.bolusdelivering)).thenReturn("Delivering 0.0U");
|
||||||
when(MainApp.gs(R.string.profile_per_unit)).thenReturn("/U");
|
when(MainApp.gs(R.string.profile_per_unit)).thenReturn("/U");
|
||||||
|
when(MainApp.gs(R.string.shortday)).thenReturn("d");
|
||||||
|
when(MainApp.gs(R.string.shorthour)).thenReturn("h");
|
||||||
when(MainApp.gs(R.string.profile_carbs_per_unit)).thenReturn("g/U");
|
when(MainApp.gs(R.string.profile_carbs_per_unit)).thenReturn("g/U");
|
||||||
when(MainApp.gs(R.string.profile_ins_units_per_hour)).thenReturn("U/h");
|
when(MainApp.gs(R.string.profile_ins_units_per_hour)).thenReturn("U/h");
|
||||||
when(MainApp.gs(R.string.sms_wrongcode)).thenReturn("Wrong code. Command cancelled.");
|
when(MainApp.gs(R.string.sms_wrongcode)).thenReturn("Wrong code. Command cancelled.");
|
||||||
|
@ -114,6 +117,13 @@ public class AAPSMocker {
|
||||||
when(MainApp.gs(R.string.sms_lastbg)).thenReturn("Last BG:");
|
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.sms_minago)).thenReturn("%1$dmin ago");
|
||||||
when(MainApp.gs(R.string.smscommunicator_remotecommandnotallowed)).thenReturn("Remote command is not allowed");
|
when(MainApp.gs(R.string.smscommunicator_remotecommandnotallowed)).thenReturn("Remote command is not allowed");
|
||||||
|
when(MainApp.gs(R.string.smscommunicator_stopsmswithcode)).thenReturn("To disable the SMS Remote Service reply with code %1$s.\\n\\nKeep in mind that you\\'ll able to reactivate it directly from the AAPS master smartphone only.");
|
||||||
|
when(MainApp.gs(R.string.smscommunicator_mealbolusreplywithcode)).thenReturn("To deliver meal bolus %1$.2fU reply with code %2$s.");
|
||||||
|
when(MainApp.gs(R.string.smscommunicator_temptargetwithcode)).thenReturn("To set the Temp Target %1$s reply with code %2$s");
|
||||||
|
when(MainApp.gs(R.string.smscommunicator_temptargetcancel)).thenReturn("To cancel Temp Target reply with code %1$s");
|
||||||
|
when(MainApp.gs(R.string.smscommunicator_stoppedsms)).thenReturn("SMS Remote Service stopped. To reactivate it, use AAPS on master smartphone.");
|
||||||
|
when(MainApp.gs(R.string.smscommunicator_tt_set)).thenReturn("Target %1$s for %2$d minutes set successfully");
|
||||||
|
when(MainApp.gs(R.string.smscommunicator_tt_canceled)).thenReturn("Temp Target canceled successfully");
|
||||||
when(MainApp.gs(R.string.loopsuspendedfor)).thenReturn("Suspended (%1$d m)");
|
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_loopisdisabled)).thenReturn("Loop is disabled");
|
||||||
when(MainApp.gs(R.string.smscommunicator_loopisenabled)).thenReturn("Loop is enabled");
|
when(MainApp.gs(R.string.smscommunicator_loopisenabled)).thenReturn("Loop is enabled");
|
||||||
|
@ -155,6 +165,11 @@ public class AAPSMocker {
|
||||||
when(MainApp.gs(R.string.pumpNotInitialized)).thenReturn("Pump not initialized!");
|
when(MainApp.gs(R.string.pumpNotInitialized)).thenReturn("Pump not initialized!");
|
||||||
when(MainApp.gs(R.string.increasingmaxbasal)).thenReturn("Increasing max basal value because setting is lower than your max basal in profile");
|
when(MainApp.gs(R.string.increasingmaxbasal)).thenReturn("Increasing max basal value because setting is lower than your max basal in profile");
|
||||||
when(MainApp.gs(R.string.overview_bolusprogress_delivered)).thenReturn("Delivered");
|
when(MainApp.gs(R.string.overview_bolusprogress_delivered)).thenReturn("Delivered");
|
||||||
|
when(MainApp.gs(R.string.smscommunicator_mealbolusreplywithcode)).thenReturn("To deliver meal bolus %1$.2fU reply with code %2$s");
|
||||||
|
when(MainApp.gs(R.string.smscommunicator_mealbolusdelivered)).thenReturn("Meal Bolus %1$.2fU delivered successfully");
|
||||||
|
when(MainApp.gs(R.string.smscommunicator_mealbolusdelivered_tt)).thenReturn("Target %1$s for %2$d minutes");
|
||||||
|
when(MainApp.gs(R.string.smscommunicator_carbsreplywithcode)).thenReturn("To enter %1$dg at %2$s reply with code %3$s");
|
||||||
|
when(MainApp.gs(R.string.smscommunicator_carbsset)).thenReturn("Carbs %1$dg entered successfully");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MainApp mockMainApp() {
|
public static MainApp mockMainApp() {
|
||||||
|
@ -183,6 +198,7 @@ public class AAPSMocker {
|
||||||
when(SP.getLong(anyInt(), anyLong())).thenReturn(0L);
|
when(SP.getLong(anyInt(), anyLong())).thenReturn(0L);
|
||||||
when(SP.getBoolean(anyInt(), anyBoolean())).thenReturn(false);
|
when(SP.getBoolean(anyInt(), anyBoolean())).thenReturn(false);
|
||||||
when(SP.getInt(anyInt(), anyInt())).thenReturn(0);
|
when(SP.getInt(anyInt(), anyInt())).thenReturn(0);
|
||||||
|
when(SP.getString(anyInt(), anyString())).thenReturn("");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void mockL() {
|
public static void mockL() {
|
||||||
|
|
|
@ -30,7 +30,7 @@ public class QuickWizardTest {
|
||||||
try {
|
try {
|
||||||
array = new JSONArray("[" + data1 + "," + data2 + "]");
|
array = new JSONArray("[" + data1 + "," + data2 + "]");
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -124,7 +124,7 @@ public class TriggerBgTest {
|
||||||
try {
|
try {
|
||||||
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":214,\"mills\":" + (now - 1) + ",\"direction\":\"Flat\"}"))));
|
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":214,\"mills\":" + (now - 1) + ",\"direction\":\"Flat\"}"))));
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,7 +152,7 @@ public class TriggerDeltaTest {
|
||||||
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":226,\"mills\":1514765100000,\"direction\":\"Flat\"}"))));
|
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":226,\"mills\":1514765100000,\"direction\":\"Flat\"}"))));
|
||||||
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":228,\"mills\":1514764800000,\"direction\":\"Flat\"}"))));
|
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":228,\"mills\":1514764800000,\"direction\":\"Flat\"}"))));
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,9 +33,7 @@ public class NsClientReceiverDelegateTest {
|
||||||
AAPSMocker.mockMainApp();
|
AAPSMocker.mockMainApp();
|
||||||
AAPSMocker.mockApplicationContext();
|
AAPSMocker.mockApplicationContext();
|
||||||
|
|
||||||
Context context = MainApp.instance().getApplicationContext();
|
sut = new NsClientReceiverDelegate();
|
||||||
|
|
||||||
sut = new NsClientReceiverDelegate(context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -8,8 +8,6 @@ import org.mockito.stubbing.Answer;
|
||||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||||
import org.powermock.modules.junit4.PowerMockRunner;
|
import org.powermock.modules.junit4.PowerMockRunner;
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import info.AAPSMocker;
|
import info.AAPSMocker;
|
||||||
import info.nightscout.androidaps.Constants;
|
import info.nightscout.androidaps.Constants;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
|
@ -28,9 +26,9 @@ import static org.powermock.api.mockito.PowerMockito.when;
|
||||||
@PrepareForTest({SmsCommunicatorPlugin.class, L.class, SP.class, MainApp.class, DateUtil.class})
|
@PrepareForTest({SmsCommunicatorPlugin.class, L.class, SP.class, MainApp.class, DateUtil.class})
|
||||||
|
|
||||||
public class AuthRequestTest {
|
public class AuthRequestTest {
|
||||||
SmsCommunicatorPlugin smsCommunicatorPlugin;
|
private SmsCommunicatorPlugin smsCommunicatorPlugin;
|
||||||
Sms sentSms;
|
private Sms sentSms;
|
||||||
boolean actionCalled = false;
|
private boolean actionCalled = false;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void doTests() {
|
public void doTests() {
|
||||||
|
@ -45,14 +43,14 @@ public class AuthRequestTest {
|
||||||
// Check if SMS requesting code is sent
|
// Check if SMS requesting code is sent
|
||||||
AuthRequest authRequest = new AuthRequest(smsCommunicatorPlugin, requester, "Request text", "ABC", action);
|
AuthRequest authRequest = new AuthRequest(smsCommunicatorPlugin, requester, "Request text", "ABC", action);
|
||||||
|
|
||||||
Assert.assertEquals(sentSms.phoneNumber, "aNumber");
|
Assert.assertEquals(sentSms.getPhoneNumber(), "aNumber");
|
||||||
Assert.assertEquals(sentSms.text, "Request text");
|
Assert.assertEquals(sentSms.getText(), "Request text");
|
||||||
|
|
||||||
// wrong reply
|
// wrong reply
|
||||||
actionCalled = false;
|
actionCalled = false;
|
||||||
authRequest.action("EFG");
|
authRequest.action("EFG");
|
||||||
Assert.assertEquals(sentSms.phoneNumber, "aNumber");
|
Assert.assertEquals(sentSms.getPhoneNumber(), "aNumber");
|
||||||
Assert.assertEquals(sentSms.text, "Wrong code. Command cancelled.");
|
Assert.assertEquals(sentSms.getText(), "Wrong code. Command cancelled.");
|
||||||
Assert.assertFalse(actionCalled);
|
Assert.assertFalse(actionCalled);
|
||||||
|
|
||||||
// correct reply
|
// correct reply
|
||||||
|
@ -77,12 +75,6 @@ public class AuthRequestTest {
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void prepareTests() {
|
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.mockMainApp();
|
||||||
AAPSMocker.mockApplicationContext();
|
AAPSMocker.mockApplicationContext();
|
||||||
AAPSMocker.mockSP();
|
AAPSMocker.mockSP();
|
||||||
|
@ -90,5 +82,12 @@ public class AuthRequestTest {
|
||||||
AAPSMocker.mockStrings();
|
AAPSMocker.mockStrings();
|
||||||
|
|
||||||
mockStatic(DateUtil.class);
|
mockStatic(DateUtil.class);
|
||||||
|
|
||||||
|
smsCommunicatorPlugin = mock(SmsCommunicatorPlugin.class);
|
||||||
|
doAnswer((Answer) invocation -> {
|
||||||
|
sentSms = invocation.getArgument(0);
|
||||||
|
return null;
|
||||||
|
}).when(smsCommunicatorPlugin).sendSMS(any(Sms.class));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ public class SmsActionTest {
|
||||||
};
|
};
|
||||||
smsAction.run();
|
smsAction.run();
|
||||||
Assert.assertEquals(result, "B");
|
Assert.assertEquals(result, "B");
|
||||||
Assert.assertEquals(smsAction.aDouble, 1d, 0.000001d);
|
Assert.assertEquals(smsAction.aDouble(), 1d, 0.000001d);
|
||||||
|
|
||||||
smsAction = new SmsAction(1d, 2) {
|
smsAction = new SmsAction(1d, 2) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -51,8 +51,8 @@ public class SmsActionTest {
|
||||||
};
|
};
|
||||||
smsAction.run();
|
smsAction.run();
|
||||||
Assert.assertEquals(result, "C");
|
Assert.assertEquals(result, "C");
|
||||||
Assert.assertEquals(smsAction.aDouble, 1d, 0.000001d);
|
Assert.assertEquals(smsAction.aDouble(), 1d, 0.000001d);
|
||||||
Assert.assertEquals(smsAction.secondInteger.intValue(), 2);
|
Assert.assertEquals(smsAction.secondInteger(), 2);
|
||||||
|
|
||||||
smsAction = new SmsAction("aString", 3) {
|
smsAction = new SmsAction("aString", 3) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -62,8 +62,8 @@ public class SmsActionTest {
|
||||||
};
|
};
|
||||||
smsAction.run();
|
smsAction.run();
|
||||||
Assert.assertEquals(result, "D");
|
Assert.assertEquals(result, "D");
|
||||||
Assert.assertEquals(smsAction.aString, "aString");
|
Assert.assertEquals(smsAction.aString(), "aString");
|
||||||
Assert.assertEquals(smsAction.secondInteger.intValue(), 3);
|
Assert.assertEquals(smsAction.secondInteger(), 3);
|
||||||
|
|
||||||
smsAction = new SmsAction(4) {
|
smsAction = new SmsAction(4) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -73,7 +73,7 @@ public class SmsActionTest {
|
||||||
};
|
};
|
||||||
smsAction.run();
|
smsAction.run();
|
||||||
Assert.assertEquals(result, "E");
|
Assert.assertEquals(result, "E");
|
||||||
Assert.assertEquals(smsAction.anInteger.intValue(), 4);
|
Assert.assertEquals(smsAction.anInteger(), 4);
|
||||||
|
|
||||||
smsAction = new SmsAction(5, 6) {
|
smsAction = new SmsAction(5, 6) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -83,8 +83,8 @@ public class SmsActionTest {
|
||||||
};
|
};
|
||||||
smsAction.run();
|
smsAction.run();
|
||||||
Assert.assertEquals(result, "F");
|
Assert.assertEquals(result, "F");
|
||||||
Assert.assertEquals(smsAction.anInteger.intValue(), 5);
|
Assert.assertEquals(smsAction.anInteger(), 5);
|
||||||
Assert.assertEquals(smsAction.secondInteger.intValue(), 6);
|
Assert.assertEquals(smsAction.secondInteger(), 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,19 +28,19 @@ public class SmsTest {
|
||||||
when(smsMessage.getMessageBody()).thenReturn("aBody");
|
when(smsMessage.getMessageBody()).thenReturn("aBody");
|
||||||
|
|
||||||
Sms sms = new Sms(smsMessage);
|
Sms sms = new Sms(smsMessage);
|
||||||
Assert.assertEquals(sms.phoneNumber, "aNumber");
|
Assert.assertEquals(sms.getPhoneNumber(), "aNumber");
|
||||||
Assert.assertEquals(sms.text, "aBody");
|
Assert.assertEquals(sms.getText(), "aBody");
|
||||||
Assert.assertTrue(sms.received);
|
Assert.assertTrue(sms.getReceived());
|
||||||
|
|
||||||
sms = new Sms("aNumber", "aBody");
|
sms = new Sms("aNumber", "aBody");
|
||||||
Assert.assertEquals(sms.phoneNumber, "aNumber");
|
Assert.assertEquals(sms.getPhoneNumber(), "aNumber");
|
||||||
Assert.assertEquals(sms.text, "aBody");
|
Assert.assertEquals(sms.getText(), "aBody");
|
||||||
Assert.assertTrue(sms.sent);
|
Assert.assertTrue(sms.getSent());
|
||||||
|
|
||||||
sms = new Sms("aNumber", R.string.insulin_unit_shortname);
|
sms = new Sms("aNumber", R.string.insulin_unit_shortname);
|
||||||
Assert.assertEquals(sms.phoneNumber, "aNumber");
|
Assert.assertEquals(sms.getPhoneNumber(), "aNumber");
|
||||||
Assert.assertEquals(sms.text, MainApp.gs(R.string.insulin_unit_shortname));
|
Assert.assertEquals(sms.getText(), MainApp.gs(R.string.insulin_unit_shortname));
|
||||||
Assert.assertTrue(sms.sent);
|
Assert.assertTrue(sms.getSent());
|
||||||
|
|
||||||
Assert.assertEquals(sms.toString(), "SMS from aNumber: U");
|
Assert.assertEquals(sms.toString(), "SMS from aNumber: U");
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,7 +153,7 @@ public class GlucoseStatusTest {
|
||||||
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":226,\"mills\":1514765100000,\"direction\":\"Flat\"}"))));
|
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":226,\"mills\":1514765100000,\"direction\":\"Flat\"}"))));
|
||||||
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":228,\"mills\":1514764800000,\"direction\":\"Flat\"}"))));
|
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":228,\"mills\":1514764800000,\"direction\":\"Flat\"}"))));
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
@ -165,7 +165,7 @@ public class GlucoseStatusTest {
|
||||||
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":216,\"mills\":1514766800000,\"direction\":\"Flat\"}")))); // +2
|
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":216,\"mills\":1514766800000,\"direction\":\"Flat\"}")))); // +2
|
||||||
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":216,\"mills\":1514766600000,\"direction\":\"Flat\"}"))));
|
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":216,\"mills\":1514766600000,\"direction\":\"Flat\"}"))));
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
@ -180,7 +180,7 @@ public class GlucoseStatusTest {
|
||||||
try {
|
try {
|
||||||
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":228,\"mills\":1514764800000,\"direction\":\"Flat\"}"))));
|
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":228,\"mills\":1514764800000,\"direction\":\"Flat\"}"))));
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
@ -190,7 +190,7 @@ public class GlucoseStatusTest {
|
||||||
try {
|
try {
|
||||||
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":214,\"mills\":1514766900000,\"direction\":\"Flat\"}"))));
|
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":214,\"mills\":1514766900000,\"direction\":\"Flat\"}"))));
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
@ -211,7 +211,7 @@ public class GlucoseStatusTest {
|
||||||
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":" + (latest_reading + (i*2)) + ",\"mills\":" + (end_time - (1000 * 60 * i)) + ",\"direction\":\"Flat\"}"))));
|
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":" + (latest_reading + (i*2)) + ",\"mills\":" + (end_time - (1000 * 60 * i)) + ",\"direction\":\"Flat\"}"))));
|
||||||
}
|
}
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,9 +12,16 @@ public class RoundTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void roundToTest() throws Exception {
|
public void roundToTest() throws Exception {
|
||||||
assertEquals( 0.55d, Round.roundTo(0.54d, 0.05d), 0.00000001d );
|
assertEquals( 0.55d, Round.roundTo(0.54d, 0.05d), 0.00000000000000000001d );
|
||||||
assertEquals( 1d, Round.roundTo(1.49d, 1d), 0.00000001d );
|
assertEquals( -3.26d, Round.roundTo(-3.2553715764602713d, 0.01d), 0.00000000000000000001d );
|
||||||
assertEquals( 0d, Round.roundTo(0d, 1d), 0.00000001d );
|
assertEquals( 0.816d, Round.roundTo(0.8156666666666667d, 0.001d), 0.00000000000000000001d );
|
||||||
|
assertEquals( 0.235d, Round.roundTo(0.235d, 0.001d), 0.00000000000000000001d );
|
||||||
|
assertEquals( 0.3d, Round.roundTo(0.3d, 0.1d), 0.00000000000000001d );
|
||||||
|
assertEquals( 0.0017d, Round.roundTo(0.0016960652144170627d, 0.0001d), 0.00000000000000000001d );
|
||||||
|
assertEquals( 0.0078d, Round.roundTo(0.007804436682291013d, 0.0001d), 0.00000000000000000001d );
|
||||||
|
assertEquals( 0.6d, Round.roundTo(0.6d, 0.05d), 0.00000000000000000001d );
|
||||||
|
assertEquals( 1d, Round.roundTo(1.49d, 1d), 0.00000000000000000001d );
|
||||||
|
assertEquals( 0d, Round.roundTo(0d, 1d), 0.00000000000000000001d );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -8,9 +8,9 @@ buildscript {
|
||||||
maven { url 'https://maven.fabric.io/public' }
|
maven { url 'https://maven.fabric.io/public' }
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:3.5.1'
|
classpath 'com.android.tools.build:gradle:3.5.2'
|
||||||
classpath 'com.google.gms:google-services:4.3.2'
|
classpath 'com.google.gms:google-services:4.3.3'
|
||||||
classpath 'io.fabric.tools:gradle:1.31.0'
|
classpath 'io.fabric.tools:gradle:1.31.2'
|
||||||
|
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
// in the individual module build.gradle files
|
// in the individual module build.gradle files
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="24" height="24" version="1.1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="m5 2v2h-2c-.55228 0-1 .44772-1 1v16c0 .55228.44772 1 1 1h10c.55228 0 1-.44772 1-1v-16c0-.55228-.44772-1-1-1h-2v-2zm15.07 2.9297-1.4102 1.4102c3.13 3.12 3.13 8.1903 0 11.32l1.4102 1.4102c3.9-3.9 3.9-10.231 0-14.141zm-16.07 1.0703h8v14h-2v-1.5h-2v1.5h-2v-1.5h-2zm13.24 1.7598-1.4102 1.4102c1.56 1.56 1.56 4.0902 0 5.6602l1.4102 1.4102c2.34-2.34 2.34-6.1405 0-8.4805z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 522 B |
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="24" height="24" version="1.1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="m5 2v2h-2c-.55228 0-1 .44772-1 1v16c0 .55228.44772 1 1 1h10c.55228 0 1-.44772 1-1v-16c0-.55228-.44772-1-1-1h-2v-2zm15.07 2.9297-1.4102 1.4102c3.13 3.12 3.13 8.1903 0 11.32l1.4102 1.4102c3.9-3.9 3.9-10.231 0-14.141zm-16.07 1.0703h8v11h-2v1h2v2h-2v-2h-2v2h-2v-2h-2zm2 12h2v-1h-2zm11.24-10.24-1.4102 1.4102c1.56 1.56 1.56 4.0902 0 5.6602l1.4102 1.4102c2.34-2.34 2.34-6.1405 0-8.4805z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 538 B |
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="24" height="24" version="1.1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="m5 2v2h-2c-.55228 0-1 .44772-1 1v16c0 .55228.44772 1 1 1h10c.55228 0 1-.44772 1-1v-16c0-.55228-.44772-1-1-1h-2v-2zm15.07 2.9297-1.4102 1.4102c3.13 3.12 3.13 8.1903 0 11.32l1.4102 1.4102c3.9-3.9 3.9-10.231 0-14.141zm-16.07 1.0703h8v10h-2v2h2v2h-2v-2h-2v2h-2v-2h-2zm2 12h2v-2h-2zm11.24-10.24-1.4102 1.4102c1.56 1.56 1.56 4.0902 0 5.6602l1.4102 1.4102c2.34-2.34 2.34-6.1405 0-8.4805z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 538 B |
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="24" height="24" version="1.1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="m5 2v2h-2c-.55228 0-1 .44772-1 1v16c0 .55228.44772 1 1 1h10c.55228 0 1-.44772 1-1v-16c0-.55228-.44772-1-1-1h-2v-2zm15.07 2.9297-1.4102 1.4102c3.13 3.12 3.13 8.1903 0 11.32l1.4102 1.4102c3.9-3.9 3.9-10.231 0-14.141zm-16.07 1.0703h8v10h-2v2h2v2h-2v-2h-2v2h-2v-2h-2v-2h2v-1.5h-2zm2 10v2h2v-2zm2 0h2v-1.5h-2zm9.2402-8.2402-1.4102 1.4102c1.56 1.56 1.56 4.0902 0 5.6602l1.4102 1.4102c2.34-2.34 2.34-6.1405 0-8.4805z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 567 B |
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="24" height="24" version="1.1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="m5 2v2h-2c-.55228 0-1 .44772-1 1v16c0 .55228.44772 1 1 1h10c.55228 0 1-.44772 1-1v-16c0-.55228-.44772-1-1-1h-2v-2zm15.07 2.9297-1.4102 1.4102c3.13 3.12 3.13 8.1903 0 11.32l1.4102 1.4102c3.9-3.9 3.9-10.231 0-14.141zm-16.07 1.0703h8v7h-2v1h2v2h-2v2h2v2h-2v-2h-2v2h-2v-2h-2v-2h2v-2h-2zm2 8h2v-1h-2zm2 0v2h2v-2zm0 2h-2v2h2zm9.2402-8.2402-1.4102 1.4102c1.56 1.56 1.56 4.0902 0 5.6602l1.4102 1.4102c2.34-2.34 2.34-6.1405 0-8.4805z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 582 B |
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="24" height="24" version="1.1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="m5 2v2h-2c-.55228 0-1 .44772-1 1v16c0 .55228.44772 1 1 1h10c.55228 0 1-.44772 1-1v-16c0-.55228-.44772-1-1-1h-2v-2zm15.07 2.9297-1.4102 1.4102c3.13 3.12 3.13 8.1903 0 11.32l1.4102 1.4102c3.9-3.9 3.9-10.231 0-14.141zm-16.07 1.0703h8v6h-2v2h2v2h-2v2h2v2h-2v-2h-2v2h-2v-2h-2v-2h2v-2h-2v-2h2v-.40039h-2zm2 6v2h2v-2zm2 0h2v-.40039h-2zm0 2v2h2v-2zm0 2h-2v2h2zm9.2402-8.2402-1.4102 1.4102c1.56 1.56 1.56 4.0902 0 5.6602l1.4102 1.4102c2.34-2.34 2.34-6.1405 0-8.4805z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 615 B |
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="24" height="24" version="1.1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="m5 2v2h-2c-.55228 0-1 .44772-1 1v16c0 .55228.44772 1 1 1h10c.55228 0 1-.44772 1-1v-16c0-.55228-.44772-1-1-1h-2v-2zm15.07 2.9297-1.4102 1.4102c3.13 3.12 3.13 8.1903 0 11.32l1.4102 1.4102c3.9-3.9 3.9-10.231 0-14.141zm-16.07 1.0703h8v6h-2v2h2v2h-2v2h2v2h-2v-2h-2v2h-2v-2h-2v-2h2v-2h-2v-2h2v-2h-2zm2 6v2h2v-2zm2 0h2v-2h-2zm0 2v2h2v-2zm0 2h-2v2h2zm9.2402-8.2402-1.4102 1.4102c1.56 1.56 1.56 4.0902 0 5.6602l1.4102 1.4102c2.34-2.34 2.34-6.1405 0-8.4805z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 605 B |
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="24" height="24" version="1.1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="m5 2v2h-2c-.55228 0-1 .44772-1 1v16c0 .55228.44772 1 1 1h10c.55228 0 1-.44772 1-1v-16c0-.55228-.44772-1-1-1h-2v-2zm15.07 2.9297-1.4102 1.4102c3.13 3.12 3.13 8.1903 0 11.32l1.4102 1.4102c3.9-3.9 3.9-10.231 0-14.141zm-16.07 1.0703h8v3h-2v1h2v2h-2v2h2v2h-2v2h2v2h-2v-2h-2v2h-2v-2h-2v-2h2v-2h-2v-2h2v-2h-2zm2 4h2v-1h-2zm2 0v2h2v-2zm0 2h-2v2h2zm0 2v2h2v-2zm0 2h-2v2h2zm9.2402-8.2402-1.4102 1.4102c1.56 1.56 1.56 4.0902 0 5.6602l1.4102 1.4102c2.34-2.34 2.34-6.1405 0-8.4805z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 626 B |
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="24" height="24" version="1.1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="m5 2v2h-2c-.55228 0-1 .44772-1 1v16c0 .55228.44772 1 1 1h10c.55228 0 1-.44772 1-1v-16c0-.55228-.44772-1-1-1h-2v-2zm15.07 2.9297-1.4102 1.4102c3.13 3.12 3.13 8.1903 0 11.32l1.4102 1.4102c3.9-3.9 3.9-10.231 0-14.141zm-16.07 1.0703h8v2h-2v2h2v2h-2v2h2v2h-2v2h2v2h-2v-2h-2v2h-2v-2h-2v-2h2v-2h-2v-2h2v-2h-2v-2h2v-.5h-2zm2 2v2h2v-2zm2 0h2v-.5h-2zm0 2v2h2v-2zm0 2h-2v2h2zm0 2v2h2v-2zm0 2h-2v2h2zm9.2402-8.2402-1.4102 1.4102c1.56 1.56 1.56 4.0902 0 5.6602l1.4102 1.4102c2.34-2.34 2.34-6.1405 0-8.4805z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 651 B |
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="24" height="24" version="1.1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="m5 2v2h-2a1 1 0 0 0-1 1v16a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1v-16a1 1 0 0 0-1-1h-2v-2h-6zm15.07 2.9297-1.4102 1.4102c3.13 3.12 3.13 8.1903 0 11.32l1.4102 1.4102c3.9-3.9 3.9-10.231 0-14.141zm-14.07 1.0703h2v2h2v-2h2v2h-2v2h2v2h-2v2h2v2h-2v2h2v2h-2v-2h-2v2h-2v-2h-2v-2h2v-2h-2v-2h2v-2h-2v-2h2v-2zm0 2v2h2v-2h-2zm2 2v2h2v-2h-2zm0 2h-2v2h2v-2zm0 2v2h2v-2h-2zm0 2h-2v2h2v-2zm9.2402-8.2402-1.4102 1.4102c1.56 1.56 1.56 4.0902 0 5.6602l1.4102 1.4102c2.34-2.34 2.34-6.1405 0-8.4805z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 628 B |
4
icons/battery-burnin/battery-unknown-burnin.svg
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="24" height="24" version="1.1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="m9 2v2h-1.6699a1.33 1.33 0 0 0-1.3301 1.3301v15.34c0 .73.60008 1.3301 1.3301 1.3301h9.3398a1.33 1.33 0 0 0 1.3301-1.3301v-15.34c0-.73-.60008-1.3301-1.3301-1.3301h-1.6699v-2h-6zm-1 4h8v14h-8v-14zm3.9922 1.6348c-.20776.0001459-.41627.012296-.53906.035156-.40487.075377-.87711.27315-1.1992.50391-.6162.44145-1.052 1.0995-1.2012 1.8145-.036974.17724-.068135.43288-.068359.54883v.076172h.75.75v-.09375c.0014-.40911.27856-.88798.66211-1.1445.27527-.18413.51594-.25465.85547-.25195.42432.00337.77536.15218 1.0664.45312.18687.19323.29535.3781.37695.64648.041091.13522.045052.18127.044922.39648-.00018.27125-.03153.43084-.12695.63476-.09497.20296-.18126.30868-.59375.72852-.74662.75992-.86069.88539-.99219 1.082-.13974.20897-.2684.46308-.34766.68945-.05321.15199-.14258.52203-.14258.58984v.037109h.75977.75781l.009765-.048828c.03414-.15494.12253-.39847.19141-.5332.15368-.3006.29355-.46626 1.0293-1.2148.18393-.18714.36832-.38472.41211-.4375.25761-.31052.44302-.7197.51172-1.1309.04095-.24512.02889-.73384-.02539-.98828-.12115-.568-.37976-1.0577-.77734-1.4727-.45238-.47215-.98198-.76014-1.6328-.88672-.11668-.022692-.32349-.03335-.53125-.033203zm-.75781 8.2637v.75.75h.75.75195v-.75-.75h-.75195-.75z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.3 KiB |