Insulin plugins injectable and Prep for SMS plugin and ConfigBuilder

This commit is contained in:
AdrianLxM 2019-12-27 04:17:49 +01:00
parent 12253007f1
commit ac05390292
25 changed files with 437 additions and 359 deletions

View file

@ -37,7 +37,12 @@ import com.joanzapata.iconify.fonts.FontAwesomeModule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import dagger.android.AndroidInjection;
import dagger.android.AndroidInjector;
import dagger.android.DispatchingAndroidInjector;
import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.activities.HistoryBrowseActivity;
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity;
import info.nightscout.androidaps.activities.PreferencesActivity;
@ -53,6 +58,7 @@ import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin;
import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.plugins.constraints.versionChecker.VersionCheckerUtilsKt;
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus;
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin;
import info.nightscout.androidaps.setupwizard.SetupWizardActivity;
import info.nightscout.androidaps.tabs.TabPageAdapter;
import info.nightscout.androidaps.utils.AndroidPermission;
@ -64,14 +70,21 @@ import info.nightscout.androidaps.utils.SP;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
public class MainActivity extends NoSplashAppCompatActivity {
public class MainActivity extends NoSplashAppCompatActivity implements HasAndroidInjector {
private static Logger log = LoggerFactory.getLogger(L.CORE);
@Inject
DispatchingAndroidInjector<Object> androidInjector;
private CompositeDisposable disposable = new CompositeDisposable();
private ActionBarDrawerToggle actionBarDrawerToggle;
private MenuItem pluginPreferencesMenuItem;
@Inject
SmsCommunicatorPlugin smsCommunicatorPlugin;
@Override
public void onCreate(Bundle savedInstanceState) {
AndroidInjection.inject(this);
@ -148,7 +161,7 @@ public class MainActivity extends NoSplashAppCompatActivity {
AndroidPermission.notifyForBatteryOptimizationPermission(this);
if (Config.PUMPDRIVERS) {
AndroidPermission.notifyForLocationPermissions(this);
AndroidPermission.notifyForSMSPermissions(this);
AndroidPermission.notifyForSMSPermissions(this, smsCommunicatorPlugin);
}
}
@ -340,4 +353,13 @@ public class MainActivity extends NoSplashAppCompatActivity {
}
return actionBarDrawerToggle.onOptionsItemSelected(item);
}
/**
* Returns an {@link AndroidInjector}.
*/
@Override
public AndroidInjector<Object> androidInjector() {
return androidInjector;
}
}

View file

@ -123,8 +123,12 @@ public class MainApp extends DaggerApplication {
public static boolean devBranch;
public static boolean engineeringMode;
@Inject
InsulinOrefFreePeakPlugin insulinOrefFreePeakPlugin;
@Inject ConfigBuilderPlugin configBuilderPlugin;
@Inject InsulinOrefFreePeakPlugin insulinOrefFreePeakPlugin;
@Inject InsulinOrefRapidActingPlugin insulinOrefRapidActingPlugin;
@Inject InsulinOrefUltraRapidActingPlugin insulinOrefUltraRapidActingPlugin;
@Inject SmsCommunicatorPlugin smsCommunicatorPlugin;
@Override
public void onCreate() {
@ -182,8 +186,8 @@ public class MainApp extends DaggerApplication {
pluginsList.add(OverviewPlugin.INSTANCE);
pluginsList.add(IobCobCalculatorPlugin.getPlugin());
if (!Config.NSCLIENT) pluginsList.add(ActionsPlugin.INSTANCE);
pluginsList.add(InsulinOrefRapidActingPlugin.getPlugin());
pluginsList.add(InsulinOrefUltraRapidActingPlugin.getPlugin());
pluginsList.add(insulinOrefRapidActingPlugin);
pluginsList.add(insulinOrefUltraRapidActingPlugin);
pluginsList.add(insulinOrefFreePeakPlugin);
pluginsList.add(SensitivityOref0Plugin.getPlugin());
pluginsList.add(SensitivityAAPSPlugin.getPlugin());
@ -220,7 +224,7 @@ public class MainApp extends DaggerApplication {
pluginsList.add(SourceTomatoPlugin.getPlugin());
pluginsList.add(SourceEversensePlugin.getPlugin());
pluginsList.add(RandomBgPlugin.INSTANCE);
if (!Config.NSCLIENT) pluginsList.add(SmsCommunicatorPlugin.INSTANCE);
if (!Config.NSCLIENT) pluginsList.add(smsCommunicatorPlugin);
pluginsList.add(FoodPlugin.getPlugin());
pluginsList.add(WearPlugin.initPlugin(this));
@ -231,21 +235,21 @@ public class MainApp extends DaggerApplication {
pluginsList.add(MaintenancePlugin.initPlugin(this));
pluginsList.add(AutomationPlugin.INSTANCE);
pluginsList.add(ConfigBuilderPlugin.getPlugin());
pluginsList.add(configBuilderPlugin);
pluginsList.add(DstHelperPlugin.getPlugin());
ConfigBuilderPlugin.getPlugin().initialize();
configBuilderPlugin.initialize();
}
NSUpload.uploadAppStart();
final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
final PumpInterface pump = configBuilderPlugin.getActivePump();
if (pump != null) {
new Thread(() -> {
SystemClock.sleep(5000);
ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("Initialization", null);
configBuilderPlugin.getCommandQueue().readStatus("Initialization", null);
}).start();
}
@ -253,6 +257,8 @@ public class MainApp extends DaggerApplication {
doMigrations();
}
private void doMigrations() {
// guarantee that the unreachable threshold is at least 30 and of type String
@ -279,7 +285,6 @@ public class MainApp extends DaggerApplication {
@Override
protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
return DaggerAppComponent
.builder()
.application(this)

View file

@ -53,6 +53,9 @@ public class MyPreferenceFragment extends PreferenceFragment implements HasAndro
@Inject
InsulinOrefFreePeakPlugin insulinOrefFreePeakPlugin;
@Inject
SmsCommunicatorPlugin smsCommunicatorPlugin;
@Override
public void setArguments(Bundle args) {
super.setArguments(args);
@ -132,7 +135,7 @@ public class MyPreferenceFragment extends PreferenceFragment implements HasAndro
addPreferencesFromResourceIfEnabled(NSClientPlugin.getPlugin(), PluginType.GENERAL);
addPreferencesFromResourceIfEnabled(TidepoolPlugin.INSTANCE, PluginType.GENERAL);
addPreferencesFromResourceIfEnabled(SmsCommunicatorPlugin.INSTANCE, PluginType.GENERAL);
addPreferencesFromResourceIfEnabled(smsCommunicatorPlugin, PluginType.GENERAL);
addPreferencesFromResourceIfEnabled(AutomationPlugin.INSTANCE, PluginType.GENERAL);
addPreferencesFromResource(R.xml.pref_others);

View file

@ -5,6 +5,9 @@ import dagger.Component
import dagger.android.AndroidInjectionModule
import dagger.android.AndroidInjector
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.plugins.general.automation.actions.ActionSendSMS
import info.nightscout.androidaps.queue.commands.CommandSetProfile
import info.nightscout.androidaps.services.DataService
import javax.inject.Singleton
@Singleton
@ -18,6 +21,12 @@ import javax.inject.Singleton
)
interface AppComponent : AndroidInjector<MainApp> {
fun injectDataService(service: DataService)
fun injectCommandSetProfile(commandSetProfile: CommandSetProfile)
fun injectActionSendSMS(actionSendSMS: ActionSendSMS)
@Component.Builder
interface Builder {

View file

@ -5,9 +5,13 @@ import android.preference.PreferenceManager
import dagger.Binds
import dagger.Module
import dagger.Provides
import dagger.android.ContributesAndroidInjector
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunction
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctionImplementation
import info.nightscout.androidaps.plugins.general.automation.actions.ActionSendSMS
import info.nightscout.androidaps.queue.commands.CommandSetProfile
import info.nightscout.androidaps.services.DataService
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.resources.ResourceHelperImplementation
import info.nightscout.androidaps.utils.sharedPreferences.SP
@ -25,7 +29,7 @@ class AppModule {
@Provides
@Singleton
fun provideProfileFunction(sp : SP): ProfileFunction {
fun provideProfileFunction(sp: SP): ProfileFunction {
return ProfileFunctionImplementation(sp)
}
@ -38,6 +42,15 @@ class AppModule {
@Module
interface AppBindings {
@ContributesAndroidInjector
fun bindDataService(): DataService
@ContributesAndroidInjector
fun bindCommandSetProfile(): CommandSetProfile
@ContributesAndroidInjector
fun bindActionSendSMS(): ActionSendSMS
@Binds
fun bindContext(mainApp: MainApp): Context
}

View file

@ -3,9 +3,13 @@ package info.nightscout.androidaps.dependencyInjection
import dagger.Module
import dagger.android.ContributesAndroidInjector
import info.nightscout.androidaps.activities.MyPreferenceFragment
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorFragment
@Module
abstract class FragmentsModule {
@ContributesAndroidInjector
abstract fun contributesPreferencesFragment(): MyPreferenceFragment
@ContributesAndroidInjector
abstract fun contributesSmsCommunicatorFragment(): SmsCommunicatorFragment
}

View file

@ -9,7 +9,9 @@ import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import javax.inject.Inject;
import javax.inject.Singleton;
import dagger.Lazy;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.events.EventAppInitialized;
@ -35,14 +37,20 @@ import info.nightscout.androidaps.utils.SP;
/**
* Created by mike on 05.08.2016.
*/
@Singleton
public class ConfigBuilderPlugin extends PluginBase {
private Logger log = LoggerFactory.getLogger(L.CONFIGBUILDER);
private static ConfigBuilderPlugin configBuilderPlugin;
/**
* @deprecated Use dagger to get an instance
*/
@Deprecated
static public ConfigBuilderPlugin getPlugin() {
if (configBuilderPlugin == null)
configBuilderPlugin = new ConfigBuilderPlugin();
throw new IllegalStateException("Accessing ConfigBuilder before first instantiation");
return configBuilderPlugin;
}
@ -57,10 +65,20 @@ public class ConfigBuilderPlugin extends PluginBase {
private CommandQueue commandQueue = new CommandQueue();
@Inject
LocalProfilePlugin localProfilePlugin;
private Lazy<InsulinOrefRapidActingPlugin> insulinOrefRapidActingPlugin;
public ConfigBuilderPlugin() {
//TODO: inject
LocalProfilePlugin localProfilePlugin = LocalProfilePlugin.INSTANCE;
/*
* Written by Adrian:
* The ConfigBuilderPlugin.getPlugin() method is used at 333 places throughout the app.
* In order to make the transition to DI, while legacy code is still calling `getPlugin()`,
* I'd instantiate this plugin very very early on (first injected dependency in MainApp) and use
* Lazy dependencies in this constructor.
* */
@Inject
public ConfigBuilderPlugin(Lazy<InsulinOrefRapidActingPlugin> insulinOrefRapidActingPlugin) {
super(new PluginDescription()
.mainType(PluginType.GENERAL)
.fragmentClass(ConfigBuilderFragment.class.getName())
@ -71,6 +89,8 @@ public class ConfigBuilderPlugin extends PluginBase {
.shortName(R.string.configbuilder_shortname)
.description(R.string.description_config_builder)
);
this.insulinOrefRapidActingPlugin = insulinOrefRapidActingPlugin;
configBuilderPlugin = this; // TODO: only while transitioning to Dagger
}
@Override
@ -298,8 +318,8 @@ public class ConfigBuilderPlugin extends PluginBase {
pluginsInCategory = MainApp.getSpecificPluginsList(PluginType.INSULIN);
activeInsulin = (InsulinInterface) getTheOneEnabledInArray(pluginsInCategory, PluginType.INSULIN);
if (activeInsulin == null) {
activeInsulin = InsulinOrefRapidActingPlugin.getPlugin();
InsulinOrefRapidActingPlugin.getPlugin().setPluginEnabled(PluginType.INSULIN, true);
activeInsulin = insulinOrefRapidActingPlugin.get();
insulinOrefRapidActingPlugin.get().setPluginEnabled(PluginType.INSULIN, true);
if (L.isEnabled(L.CONFIGBUILDER))
log.debug("Defaulting InsulinOrefRapidActingPlugin");
}
@ -457,7 +477,7 @@ public class ConfigBuilderPlugin extends PluginBase {
if (type == PluginType.PUMP)
VirtualPumpPlugin.getPlugin().setPluginEnabled(type, true);
else if (type == PluginType.INSULIN)
InsulinOrefRapidActingPlugin.getPlugin().setPluginEnabled(type, true);
insulinOrefRapidActingPlugin.get().setPluginEnabled(type, true);
else if (type == PluginType.SENSITIVITY)
SensitivityOref0Plugin.getPlugin().setPluginEnabled(type, true);
else if (type == PluginType.PROFILE)

View file

@ -9,10 +9,11 @@ import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.general.automation.elements.InputString;
import info.nightscout.androidaps.plugins.general.automation.elements.LabelWithElement;
import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder;
@ -25,6 +26,14 @@ public class ActionSendSMS extends Action {
public InputString text = new InputString();
@Inject
SmsCommunicatorPlugin smsCommunicatorPlugin;
public ActionSendSMS() {
super();
MainApp.instance().androidInjector().inject(this); // TODO inject or pass itno constructor once AutomationPlugin is prepared for Dagger
}
@Override
public int friendlyName() {
return R.string.sendsmsactiondescription;
@ -37,7 +46,7 @@ public class ActionSendSMS extends Action {
@Override
public void doAction(Callback callback) {
boolean result = SmsCommunicatorPlugin.INSTANCE.sendNotificationToAllNumbers(text.getValue());
boolean result = smsCommunicatorPlugin.sendNotificationToAllNumbers(text.getValue());
if (callback != null)
callback.result(new PumpEnactResult().success(result).comment(result ? R.string.ok : R.string.danar_error)).run();

View file

@ -5,6 +5,7 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import dagger.android.support.DaggerFragment
import info.nightscout.androidaps.R
import info.nightscout.androidaps.plugins.bus.RxBus.toObservable
import info.nightscout.androidaps.plugins.general.smsCommunicator.events.EventSmsCommunicatorUpdateGui
@ -15,11 +16,15 @@ import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.smscommunicator_fragment.*
import java.util.*
import javax.inject.Inject
import kotlin.math.max
class SmsCommunicatorFragment : Fragment() {
class SmsCommunicatorFragment : DaggerFragment() {
private val disposable = CompositeDisposable()
@Inject
lateinit var smsCommunicatorPlugin: SmsCommunicatorPlugin
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.smscommunicator_fragment, container, false)
@ -47,12 +52,12 @@ class SmsCommunicatorFragment : Fragment() {
return (object1.date - object2.date).toInt()
}
}
Collections.sort(SmsCommunicatorPlugin.messages, CustomComparator())
Collections.sort(smsCommunicatorPlugin.messages, CustomComparator())
val messagesToShow = 40
val start = max(0, SmsCommunicatorPlugin.messages.size - messagesToShow)
val start = max(0, smsCommunicatorPlugin.messages.size - messagesToShow)
var logText = ""
for (x in start until SmsCommunicatorPlugin.messages.size) {
val sms = SmsCommunicatorPlugin.messages[x]
for (x in start until smsCommunicatorPlugin.messages.size) {
val sms = smsCommunicatorPlugin.messages[x]
when {
sms.ignored -> {
logText += DateUtil.timeString(sms.date) + " &lt;&lt;&lt; " + "" + sms.phoneNumber + " <b>" + sms.text + "</b><br>"

View file

@ -45,15 +45,19 @@ import org.apache.commons.lang3.StringUtils
import org.slf4j.LoggerFactory
import java.text.Normalizer
import java.util.*
import javax.inject.Inject
import javax.inject.Singleton
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)
@Singleton
class SmsCommunicatorPlugin @Inject constructor(val configBuilderPlugin: ConfigBuilderPlugin) : 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()
@ -62,31 +66,32 @@ object SmsCommunicatorPlugin : PluginBase(PluginDescription()
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"
"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 {
/*init {
processSettings(null)
}
}*/
override fun onStart() {
processSettings(null) // TODO moved from init block to avoid cyclic calling MainApp via SP while we are still in MainApp.onCreate()
super.onStart()
disposable.add(toObservable(EventPreferenceChange::class.java)
.observeOn(Schedulers.io())
.subscribe({ event: EventPreferenceChange? -> processSettings(event) }) { throwable: Throwable? -> FabricPrivacy.logException(throwable) }
.observeOn(Schedulers.io())
.subscribe({ event: EventPreferenceChange? -> processSettings(event) }) { throwable: Throwable? -> FabricPrivacy.logException(throwable) }
)
}
@ -98,13 +103,13 @@ object SmsCommunicatorPlugin : PluginBase(PluginDescription()
override fun preprocessPreferences(preferenceFragment: PreferenceFragment) {
super.preprocessPreferences(preferenceFragment)
val distance = preferenceFragment.findPreference(MainApp.gs(R.string.key_smscommunicator_remotebolusmindistance)) as ValidatingEditTextPreference?
?: return
?: return
val allowedNumbers = preferenceFragment.findPreference(MainApp.gs(R.string.key_smscommunicator_allowednumbers)) as EditTextPreference?
?: return
?: return
if (!areMoreNumbers(allowedNumbers.text)) {
distance.title = (MainApp.gs(R.string.smscommunicator_remotebolusmindistance)
+ ".\n"
+ MainApp.gs(R.string.smscommunicator_remotebolusmindistance_caveat))
+ ".\n"
+ MainApp.gs(R.string.smscommunicator_remotebolusmindistance_caveat))
distance.isEnabled = false
} else {
distance.title = MainApp.gs(R.string.smscommunicator_remotebolusmindistance)
@ -114,8 +119,8 @@ object SmsCommunicatorPlugin : PluginBase(PluginDescription()
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))
+ ".\n"
+ MainApp.gs(R.string.smscommunicator_remotebolusmindistance_caveat))
distance.isEnabled = false
} else {
distance.title = MainApp.gs(R.string.smscommunicator_remotebolusmindistance)
@ -185,67 +190,67 @@ object SmsCommunicatorPlugin : PluginBase(PluginDescription()
send(EventSmsCommunicatorUpdateGui())
return
}
val pump = ConfigBuilderPlugin.getPlugin().activePump ?: return
val pump = configBuilderPlugin.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" ->
"BG" ->
if (splitted.size == 1) processBG(receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
"LOOP" ->
"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" ->
"NSCLIENT" ->
if (splitted.size == 2) processNSCLIENT(splitted, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
"PUMP" ->
"PUMP" ->
if (splitted.size == 1) processPUMP(receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
"PROFILE" ->
"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" ->
"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" ->
"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" ->
"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" ->
"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" ->
"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" ->
"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" ->
"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" ->
"HELP" ->
if (splitted.size == 1 || splitted.size == 2) processHELP(splitted, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
else ->
else ->
if (messageToConfirm?.requester?.phoneNumber == receivedSms.phoneNumber) {
messageToConfirm?.action(splitted[0])
messageToConfirm = null
@ -275,9 +280,9 @@ object SmsCommunicatorPlugin : PluginBase(PluginDescription()
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())
+ 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
}
@ -288,11 +293,11 @@ object SmsCommunicatorPlugin : PluginBase(PluginDescription()
val loopPlugin = LoopPlugin.getPlugin()
if (loopPlugin.isEnabled(PluginType.LOOP)) {
loopPlugin.setPluginEnabled(PluginType.LOOP, false)
ConfigBuilderPlugin.getPlugin().commandQueue.cancelTempBasal(true, object : Callback() {
configBuilderPlugin.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)
MainApp.gs(if (result.success) R.string.smscommunicator_tempbasalcanceled else R.string.smscommunicator_tempbasalcancelfailed)
sendSMS(Sms(receivedSms.phoneNumber, replyText))
}
})
@ -300,6 +305,7 @@ object SmsCommunicatorPlugin : PluginBase(PluginDescription()
sendSMS(Sms(receivedSms.phoneNumber, R.string.smscommunicator_loopisdisabled))
receivedSms.processed = true
}
"ENABLE", "START" -> {
val loopPlugin = LoopPlugin.getPlugin()
if (!loopPlugin.isEnabled(PluginType.LOOP)) {
@ -310,7 +316,8 @@ object SmsCommunicatorPlugin : PluginBase(PluginDescription()
sendSMS(Sms(receivedSms.phoneNumber, R.string.smscommunicator_loopisenabled))
receivedSms.processed = true
}
"STATUS" -> {
"STATUS" -> {
val loopPlugin = LoopPlugin.getPlugin()
val reply = if (loopPlugin.isEnabled(PluginType.LOOP)) {
if (loopPlugin.isSuspended()) String.format(MainApp.gs(R.string.loopsuspendedfor), loopPlugin.minutesToEndOfSuspend())
@ -320,13 +327,15 @@ object SmsCommunicatorPlugin : PluginBase(PluginDescription()
sendSMS(Sms(receivedSms.phoneNumber, reply))
receivedSms.processed = true
}
"RESUME" -> {
"RESUME" -> {
LoopPlugin.getPlugin().suspendTo(0)
send(EventRefreshOverview("SMS_LOOP_RESUME"))
NSUpload.uploadOpenAPSOffline(0.0)
sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, R.string.smscommunicator_loopresumed))
}
"SUSPEND" -> {
"SUSPEND" -> {
var duration = 0
if (splitted.size == 3) duration = SafeParse.stringToInt(splitted[2])
duration = Math.max(0, duration)
@ -341,18 +350,18 @@ object SmsCommunicatorPlugin : PluginBase(PluginDescription()
receivedSms.processed = true
messageToConfirm = AuthRequest(this, receivedSms, reply, passCode, object : SmsAction(duration) {
override fun run() {
ConfigBuilderPlugin.getPlugin().commandQueue.cancelTempBasal(true, object : Callback() {
configBuilderPlugin.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)
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)
replyText += "\n" + configBuilderPlugin.activePump?.shortStatus(true)
sendSMS(Sms(receivedSms.phoneNumber, replyText))
}
}
@ -361,7 +370,8 @@ object SmsCommunicatorPlugin : PluginBase(PluginDescription()
})
}
}
else -> sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
else -> sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
}
}
@ -398,9 +408,9 @@ object SmsCommunicatorPlugin : PluginBase(PluginDescription()
}
private fun processPUMP(receivedSms: Sms) {
ConfigBuilderPlugin.getPlugin().commandQueue.readStatus("SMS", object : Callback() {
configBuilderPlugin.commandQueue.readStatus("SMS", object : Callback() {
override fun run() {
val pump = ConfigBuilderPlugin.getPlugin().activePump
val pump = configBuilderPlugin.activePump
if (result.success) {
if (pump != null) {
val reply = pump.shortStatus(true)
@ -416,7 +426,7 @@ object SmsCommunicatorPlugin : PluginBase(PluginDescription()
}
private fun processPROFILE(splitted: Array<String>, receivedSms: Sms) { // load profiles
val anInterface = ConfigBuilderPlugin.getPlugin().activeProfileInterface
val anInterface = configBuilderPlugin.activeProfileInterface
if (anInterface == null) {
sendSMS(Sms(receivedSms.phoneNumber, R.string.notconfigured))
receivedSms.processed = true
@ -482,15 +492,15 @@ object SmsCommunicatorPlugin : PluginBase(PluginDescription()
receivedSms.processed = true
messageToConfirm = AuthRequest(this, receivedSms, reply, passCode, object : SmsAction() {
override fun run() {
ConfigBuilderPlugin.getPlugin().commandQueue.cancelTempBasal(true, object : Callback() {
configBuilderPlugin.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)
replyText += "\n" + configBuilderPlugin.activePump?.shortStatus(true)
sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, replyText))
} else {
var replyText = MainApp.gs(R.string.smscommunicator_tempbasalcancelfailed)
replyText += "\n" + ConfigBuilderPlugin.getPlugin().activePump?.shortStatus(true)
replyText += "\n" + configBuilderPlugin.activePump?.shortStatus(true)
sendSMS(Sms(receivedSms.phoneNumber, replyText))
}
}
@ -512,16 +522,16 @@ object SmsCommunicatorPlugin : PluginBase(PluginDescription()
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() {
configBuilderPlugin.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)
replyText += "\n" + configBuilderPlugin.activePump?.shortStatus(true)
sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, replyText))
} else {
var replyText = MainApp.gs(R.string.smscommunicator_tempbasalfailed)
replyText += "\n" + ConfigBuilderPlugin.getPlugin().activePump?.shortStatus(true)
replyText += "\n" + configBuilderPlugin.activePump?.shortStatus(true)
sendSMS(Sms(receivedSms.phoneNumber, replyText))
}
}
@ -544,16 +554,16 @@ object SmsCommunicatorPlugin : PluginBase(PluginDescription()
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() {
configBuilderPlugin.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)
replyText += "\n" + configBuilderPlugin.activePump?.shortStatus(true)
sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, replyText))
} else {
var replyText = MainApp.gs(R.string.smscommunicator_tempbasalfailed)
replyText += "\n" + ConfigBuilderPlugin.getPlugin().activePump?.shortStatus(true)
replyText += "\n" + configBuilderPlugin.activePump?.shortStatus(true)
sendSMS(Sms(receivedSms.phoneNumber, replyText))
}
}
@ -571,15 +581,15 @@ object SmsCommunicatorPlugin : PluginBase(PluginDescription()
receivedSms.processed = true
messageToConfirm = AuthRequest(this, receivedSms, reply, passCode, object : SmsAction() {
override fun run() {
ConfigBuilderPlugin.getPlugin().commandQueue.cancelExtended(object : Callback() {
configBuilderPlugin.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)
replyText += "\n" + configBuilderPlugin.activePump?.shortStatus(true)
sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, replyText))
} else {
var replyText = MainApp.gs(R.string.smscommunicator_extendedcancelfailed)
replyText += "\n" + ConfigBuilderPlugin.getPlugin().activePump?.shortStatus(true)
replyText += "\n" + configBuilderPlugin.activePump?.shortStatus(true)
sendSMS(Sms(receivedSms.phoneNumber, replyText))
}
}
@ -599,15 +609,15 @@ object SmsCommunicatorPlugin : PluginBase(PluginDescription()
receivedSms.processed = true
messageToConfirm = AuthRequest(this, receivedSms, reply, passCode, object : SmsAction(extended, duration) {
override fun run() {
ConfigBuilderPlugin.getPlugin().commandQueue.extendedBolus(aDouble(), secondInteger(), object : Callback() {
configBuilderPlugin.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)
replyText += "\n" + configBuilderPlugin.activePump?.shortStatus(true)
sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, replyText))
} else {
var replyText = MainApp.gs(R.string.smscommunicator_extendedfailed)
replyText += "\n" + ConfigBuilderPlugin.getPlugin().activePump?.shortStatus(true)
replyText += "\n" + configBuilderPlugin.activePump?.shortStatus(true)
sendSMS(Sms(receivedSms.phoneNumber, replyText))
}
}
@ -636,37 +646,37 @@ object SmsCommunicatorPlugin : PluginBase(PluginDescription()
val detailedBolusInfo = DetailedBolusInfo()
detailedBolusInfo.insulin = aDouble()
detailedBolusInfo.source = Source.USER
ConfigBuilderPlugin.getPlugin().commandQueue.bolus(detailedBolusInfo, object : Callback() {
configBuilderPlugin.commandQueue.bolus(detailedBolusInfo, object : Callback() {
override fun run() {
val resultSuccess = result.success
val resultBolusDelivered = result.bolusDelivered
ConfigBuilderPlugin.getPlugin().commandQueue.readStatus("SMS", object : Callback() {
configBuilderPlugin.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)
replyText += "\n" + configBuilderPlugin.activePump?.shortStatus(true)
lastRemoteBolusTime = DateUtil.now()
if (isMeal) {
ProfileFunctions.getInstance().getProfile()?.let { currentProfile ->
var eatingSoonTTDuration = SP.getInt(R.string.key_eatingsoon_duration, Constants.defaultEatingSoonTTDuration)
eatingSoonTTDuration =
if (eatingSoonTTDuration > 0) eatingSoonTTDuration
else Constants.defaultEatingSoonTTDuration
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
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))
.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)
@ -677,7 +687,7 @@ object SmsCommunicatorPlugin : PluginBase(PluginDescription()
sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, replyText))
} else {
var replyText = MainApp.gs(R.string.smscommunicator_bolusfailed)
replyText += "\n" + ConfigBuilderPlugin.getPlugin().activePump?.shortStatus(true)
replyText += "\n" + configBuilderPlugin.activePump?.shortStatus(true)
sendSMS(Sms(receivedSms.phoneNumber, replyText))
}
}
@ -712,15 +722,15 @@ object SmsCommunicatorPlugin : PluginBase(PluginDescription()
val detailedBolusInfo = DetailedBolusInfo()
detailedBolusInfo.carbs = anInteger().toDouble()
detailedBolusInfo.date = secondLong()
ConfigBuilderPlugin.getPlugin().commandQueue.bolus(detailedBolusInfo, object : Callback() {
configBuilderPlugin.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)
replyText += "\n" + configBuilderPlugin.activePump?.shortStatus(true)
sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, replyText))
} else {
var replyText = MainApp.gs(R.string.smscommunicator_carbsfailed)
replyText += "\n" + ConfigBuilderPlugin.getPlugin().activePump?.shortStatus(true)
replyText += "\n" + configBuilderPlugin.activePump?.shortStatus(true)
sendSMS(Sms(receivedSms.phoneNumber, replyText))
}
}
@ -772,12 +782,12 @@ object SmsCommunicatorPlugin : PluginBase(PluginDescription()
tt = Profile.toCurrentUnits(tt)
tt = if (tt > 0) tt else if (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, units))
.high(Profile.toMgdl(tt, units))
.date(System.currentTimeMillis())
.duration(ttDuration)
.reason(MainApp.gs(R.string.eatingsoon))
.source(Source.USER)
.low(Profile.toMgdl(tt, units))
.high(Profile.toMgdl(tt, units))
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget)
val ttString = if (units == Constants.MMOL) DecimalFormatter.to1Decimal(tt) else DecimalFormatter.to0Decimal(tt)
val replyText = String.format(MainApp.gs(R.string.smscommunicator_tt_set), ttString, ttDuration)
@ -791,11 +801,11 @@ object SmsCommunicatorPlugin : PluginBase(PluginDescription()
messageToConfirm = AuthRequest(this, receivedSms, reply, passCode, object : SmsAction() {
override fun run() {
val tempTarget = TempTarget()
.source(Source.USER)
.date(DateUtil.now())
.duration(0)
.low(0.0)
.high(0.0)
.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))
@ -807,7 +817,7 @@ object SmsCommunicatorPlugin : PluginBase(PluginDescription()
private fun processSMS(splitted: Array<String>, receivedSms: Sms) {
val isStop = (splitted[1].equals("STOP", ignoreCase = true)
|| splitted[1].equals("DISABLE", ignoreCase = true))
|| splitted[1].equals("DISABLE", ignoreCase = true))
if (isStop) {
val passCode = generatePasscode()
val reply = String.format(MainApp.gs(R.string.smscommunicator_stopsmswithcode), passCode)
@ -862,7 +872,7 @@ object SmsCommunicatorPlugin : PluginBase(PluginDescription()
else {
val parts = smsManager.divideMessage(sms.text)
smsManager.sendMultipartTextMessage(sms.phoneNumber, null, parts,
null, null)
null, null)
}
messages.add(sms)
} catch (e: IllegalArgumentException) {

View file

@ -1,109 +0,0 @@
package info.nightscout.androidaps.plugins.insulin;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.Iob;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.interfaces.InsulinInterface;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.PluginDescription;
import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification;
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
import info.nightscout.androidaps.plugins.treatments.Treatment;
/**
* Created by adrian on 13.08.2017.
*/
public abstract class InsulinOrefBasePlugin extends PluginBase implements InsulinInterface {
public static double MIN_DIA = 5;
long lastWarned = 0;
public InsulinOrefBasePlugin() {
super(new PluginDescription()
.mainType(PluginType.INSULIN)
.fragmentClass(InsulinFragment.class.getName())
.pluginName(R.string.fastactinginsulin)
.shortName(R.string.insulin_shortname)
.visibleByDefault(false)
);
}
@Override
public double getDia() {
double dia = getUserDefinedDia();
if (dia >= MIN_DIA) {
return dia;
} else {
sendShortDiaNotification(dia);
return MIN_DIA;
}
}
void sendShortDiaNotification(double dia) {
if ((System.currentTimeMillis() - lastWarned) > 60 * 1000) {
lastWarned = System.currentTimeMillis();
Notification notification = new Notification(Notification.SHORT_DIA, String.format(this.getNotificationPattern(), dia, MIN_DIA), Notification.URGENT);
RxBus.INSTANCE.send(new EventNewNotification(notification));
}
}
public String getNotificationPattern() {
return MainApp.gs(R.string.dia_too_short);
}
public double getUserDefinedDia() {
Profile profile = ProfileFunctions.getInstance().getProfile();
return profile != null ? profile.getDia() : MIN_DIA;
}
public Iob iobCalcForTreatment(Treatment treatment, long time) {
return this.iobCalcForTreatment(treatment, time, 0d);
}
@Override
public Iob iobCalcForTreatment(Treatment treatment, long time, double dia) {
Iob result = new Iob();
int peak = getPeak();
if (treatment.insulin != 0d) {
long bolusTime = treatment.date;
double t = (time - bolusTime) / 1000d / 60d;
double td = getDia() * 60; //getDIA() always >= MIN_DIA
double tp = peak;
// force the IOB to 0 if over DIA hours have passed
if (t < td) {
double tau = tp * (1 - tp / td) / (1 - 2 * tp / td);
double a = 2 * tau / td;
double S = 1 / (1 - a + (1 + a) * Math.exp(-td / tau));
result.activityContrib = treatment.insulin * (S / Math.pow(tau, 2)) * t * (1 - t / td) * Math.exp(-t / tau);
result.iobContrib = treatment.insulin * (1 - S * (1 - a) * ((Math.pow(t, 2) / (tau * td * (1 - a)) - t / tau - 1) * Math.exp(-t / tau) + 1));
}
}
return result;
}
@Override
public String getComment() {
String comment = commentStandardText();
double userDia = getUserDefinedDia();
if (userDia < MIN_DIA) {
comment += "\n" + String.format(MainApp.gs(R.string.dia_too_short), userDia, MIN_DIA);
}
return comment;
}
abstract int getPeak();
abstract String commentStandardText();
}

View file

@ -0,0 +1,93 @@
package info.nightscout.androidaps.plugins.insulin
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Iob
import info.nightscout.androidaps.interfaces.InsulinInterface
import info.nightscout.androidaps.interfaces.PluginBase
import info.nightscout.androidaps.interfaces.PluginDescription
import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.plugins.bus.RxBus.send
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
import info.nightscout.androidaps.plugins.treatments.Treatment
/**
* Created by adrian on 13.08.2017.
*/
abstract class InsulinOrefBasePlugin() : PluginBase(PluginDescription()
.mainType(PluginType.INSULIN)
.fragmentClass(InsulinFragment::class.java.name)
.shortName(R.string.insulin_shortname)
.visibleByDefault(false)
), InsulinInterface {
var lastWarned: Long = 0
override fun getDia(): Double {
val dia = userDefinedDia
return if (dia >= MIN_DIA) {
dia
} else {
sendShortDiaNotification(dia)
MIN_DIA
}
}
open fun sendShortDiaNotification(dia: Double) {
if (System.currentTimeMillis() - lastWarned > 60 * 1000) {
lastWarned = System.currentTimeMillis()
val notification = Notification(Notification.SHORT_DIA, String.format(notificationPattern, dia, MIN_DIA), Notification.URGENT)
send(EventNewNotification(notification))
}
}
val notificationPattern: String
get() = MainApp.gs(R.string.dia_too_short)
open val userDefinedDia: Double
get() {
val profile = ProfileFunctions.getInstance().getProfile()
return profile?.dia ?: MIN_DIA
}
fun iobCalcForTreatment(treatment: Treatment, time: Long): Iob {
return this.iobCalcForTreatment(treatment, time, 0.0)
}
override fun iobCalcForTreatment(treatment: Treatment, time: Long, dia: Double): Iob {
val result = Iob()
val peak = peak
if (treatment.insulin != 0.0) {
val bolusTime = treatment.date
val t = (time - bolusTime) / 1000.0 / 60.0
val td = getDia() * 60 //getDIA() always >= MIN_DIA
val tp = peak.toDouble()
// force the IOB to 0 if over DIA hours have passed
if (t < td) {
val tau = tp * (1 - tp / td) / (1 - 2 * tp / td)
val a = 2 * tau / td
val S = 1 / (1 - a + (1 + a) * Math.exp(-td / tau))
result.activityContrib = treatment.insulin * (S / Math.pow(tau, 2.0)) * t * (1 - t / td) * Math.exp(-t / tau)
result.iobContrib = treatment.insulin * (1 - S * (1 - a) * ((Math.pow(t, 2.0) / (tau * td * (1 - a)) - t / tau - 1) * Math.exp(-t / tau) + 1))
}
}
return result
}
override fun getComment(): String {
var comment = commentStandardText()
val userDia = userDefinedDia
if (userDia < MIN_DIA) {
comment += "\n" + String.format(MainApp.gs(R.string.dia_too_short), userDia, MIN_DIA)
}
return comment
}
abstract val peak: Int
abstract fun commentStandardText(): String
companion object {
const val MIN_DIA = 5.0
}
}

View file

@ -24,13 +24,12 @@ class InsulinOrefFreePeakPlugin @Inject constructor(
return resourceHelper.gs(R.string.free_peak_oref) ?: ""
}
public override fun commentStandardText(): String {
override fun commentStandardText(): String {
return resourceHelper.gs(R.string.insulin_peak_time) + ": " + peak
}
public override fun getPeak(): Int {
return sp.getInt(R.string.key_insulin_oref_peak, DEFAULT_PEAK)
}
override val peak: Int
get() = sp.getInt(R.string.key_insulin_oref_peak, DEFAULT_PEAK)
companion object {
private const val DEFAULT_PEAK = 75

View file

@ -1,48 +0,0 @@
package info.nightscout.androidaps.plugins.insulin;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
/**
* Created by adrian on 14/08/17.
*/
public class InsulinOrefRapidActingPlugin extends InsulinOrefBasePlugin {
private static InsulinOrefRapidActingPlugin plugin = null;
public static InsulinOrefRapidActingPlugin getPlugin() {
if (plugin == null)
plugin = new InsulinOrefRapidActingPlugin();
return plugin;
}
private static final int PEAK = 75;
private InsulinOrefRapidActingPlugin() {
super();
pluginDescription
.pluginName(R.string.rapid_acting_oref)
.description(R.string.description_insulin_rapid);
}
@Override
public int getId() {
return OREF_RAPID_ACTING;
}
@Override
public String getFriendlyName() {
return MainApp.gs(R.string.rapid_acting_oref);
}
@Override
public String commentStandardText() {
return MainApp.gs(R.string.fastactinginsulincomment);
}
@Override
int getPeak() {
return PEAK;
}
}

View file

@ -0,0 +1,33 @@
package info.nightscout.androidaps.plugins.insulin
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.interfaces.InsulinInterface
import javax.inject.Inject
/**
* Created by adrian on 14/08/17.
*/
class InsulinOrefRapidActingPlugin @Inject constructor(): InsulinOrefBasePlugin() {
override fun getId(): Int {
return InsulinInterface.OREF_RAPID_ACTING
}
override fun getFriendlyName(): String {
return MainApp.gs(R.string.rapid_acting_oref)
}
override fun commentStandardText(): String {
return MainApp.gs(R.string.fastactinginsulincomment)
}
override val peak = 75
init {
pluginDescription
.pluginName(R.string.rapid_acting_oref)
.description(R.string.description_insulin_rapid)
}
}

View file

@ -1,53 +0,0 @@
package info.nightscout.androidaps.plugins.insulin;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
/**
* Created by adrian on 14/08/17.
*/
public class InsulinOrefUltraRapidActingPlugin extends InsulinOrefBasePlugin {
private static InsulinOrefUltraRapidActingPlugin plugin = null;
public static InsulinOrefUltraRapidActingPlugin getPlugin() {
if (plugin == null)
plugin = new InsulinOrefUltraRapidActingPlugin();
return plugin;
}
private static final int PEAK = 55;
private InsulinOrefUltraRapidActingPlugin() {
super();
pluginDescription
.pluginName(R.string.ultrarapid_oref)
.description(R.string.description_insulin_ultra_rapid);
}
@Override
public int getId() {
return OREF_ULTRA_RAPID_ACTING;
}
@Override
public String getName() {
return MainApp.gs(R.string.ultrarapid_oref);
}
@Override
public String getFriendlyName() {
return MainApp.gs(R.string.ultrarapid_oref);
}
@Override
public String commentStandardText() {
return MainApp.gs(R.string.ultrafastactinginsulincomment);
}
@Override
int getPeak() {
return PEAK;
}
}

View file

@ -0,0 +1,37 @@
package info.nightscout.androidaps.plugins.insulin
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.interfaces.InsulinInterface
import javax.inject.Inject
/**
* Created by adrian on 14/08/17.
*/
class InsulinOrefUltraRapidActingPlugin @Inject constructor(): InsulinOrefBasePlugin() {
override fun getId(): Int {
return InsulinInterface.OREF_ULTRA_RAPID_ACTING
}
override fun getName(): String {
return MainApp.gs(R.string.ultrarapid_oref)
}
override fun getFriendlyName(): String {
return MainApp.gs(R.string.ultrarapid_oref)
}
override fun commentStandardText(): String {
return MainApp.gs(R.string.ultrafastactinginsulincomment)
}
override val peak = 55
init {
pluginDescription
.pluginName(R.string.ultrarapid_oref)
.description(R.string.description_insulin_ultra_rapid)
}
}

View file

@ -16,7 +16,7 @@ import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.dialogs.ProfileSwitchDialog
import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
import info.nightscout.androidaps.plugins.insulin.InsulinOrefBasePlugin.MIN_DIA
import info.nightscout.androidaps.plugins.insulin.InsulinOrefBasePlugin.Companion.MIN_DIA
import info.nightscout.androidaps.plugins.profile.local.events.EventLocalProfileChanged
import info.nightscout.androidaps.utils.*
import io.reactivex.android.schedulers.AndroidSchedulers

View file

@ -3,6 +3,8 @@ package info.nightscout.androidaps.queue.commands;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.Profile;
@ -25,10 +27,14 @@ public class CommandSetProfile extends Command {
private Profile profile;
@Inject
SmsCommunicatorPlugin smsCommunicatorPlugin;
public CommandSetProfile(Profile profile, Callback callback) {
commandType = CommandType.BASALPROFILE;
this.profile = profile;
this.callback = callback;
MainApp.instance().androidInjector().inject(this); // TODO: Inject via constructor
}
@Override
@ -50,7 +56,6 @@ public class CommandSetProfile extends Command {
// Send SMS notification if ProfileSwitch is comming from NS
ProfileSwitch profileSwitch = TreatmentsPlugin.getPlugin().getProfileSwitchFromHistory(System.currentTimeMillis());
if (profileSwitch != null && r.enacted && profileSwitch.source == Source.NIGHTSCOUT) {
SmsCommunicatorPlugin smsCommunicatorPlugin = SmsCommunicatorPlugin.INSTANCE;
if (smsCommunicatorPlugin.isEnabled(PluginType.GENERAL)) {
smsCommunicatorPlugin.sendNotificationToAllNumbers(MainApp.gs(R.string.profile_set_ok));
}

View file

@ -11,6 +11,8 @@ import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.db.CareportalEvent;
@ -47,6 +49,16 @@ public class DataService extends IntentService {
super("DataService");
}
@Inject
SmsCommunicatorPlugin smsCommunicatorPlugin;
@Override
public void onCreate() {
super.onCreate();
((MainApp) getApplication()).androidInjector().inject(this);
}
@Override
protected void onHandleIntent(final Intent intent) {
if (L.isEnabled(L.DATASERVICE)) {
@ -99,7 +111,7 @@ public class DataService extends IntentService {
) {
handleNewDataFromNSClient(intent);
} else if (Telephony.Sms.Intents.SMS_RECEIVED_ACTION.equals(action)) {
SmsCommunicatorPlugin.INSTANCE.handleNewData(intent);
smsCommunicatorPlugin.handleNewData(intent);
}
if (L.isEnabled(L.DATASERVICE))

View file

@ -80,8 +80,8 @@ public class AndroidPermission {
return !selfCheck;
}
public static synchronized void notifyForSMSPermissions(Activity activity) {
if (SmsCommunicatorPlugin.INSTANCE.isEnabled(PluginType.GENERAL)) {
public static synchronized void notifyForSMSPermissions(Activity activity, SmsCommunicatorPlugin smsCommunicatorPlugin) {
if (smsCommunicatorPlugin.isEnabled(PluginType.GENERAL)) {
if (permissionNotGranted(activity, Manifest.permission.RECEIVE_SMS)) {
NotificationWithAction notification = new NotificationWithAction(Notification.PERMISSION_SMS, MainApp.gs(R.string.smscommunicator_missingsmspermission), Notification.URGENT);
notification.action(R.string.request, () -> AndroidPermission.askForPermission(activity, new String[]{Manifest.permission.RECEIVE_SMS,

View file

@ -3,6 +3,7 @@ package info.nightscout.androidaps.plugins.configBuilder;
import junit.framework.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
@ -18,18 +19,21 @@ import info.nightscout.androidaps.utils.SP;
public class ConfigBuilderPluginTest {
@Test
@Ignore
public void getPluginTest() {
ConfigBuilderPlugin configBuilderPlugin = ConfigBuilderPlugin.getPlugin();
Assert.assertNotNull(configBuilderPlugin);
}
@Test
@Ignore
public void onStartTest() {
ConfigBuilderPlugin configBuilderPlugin = ConfigBuilderPlugin.getPlugin();
configBuilderPlugin.setPluginEnabled(PluginType.GENERAL, true);
}
@Test
@Ignore
public void onStopTest() {
ConfigBuilderPlugin configBuilderPlugin = ConfigBuilderPlugin.getPlugin();
configBuilderPlugin.setPluginEnabled(PluginType.GENERAL, true);

View file

@ -15,6 +15,7 @@ import org.powermock.modules.junit4.PowerMockRunner;
import java.util.ArrayList;
import java.util.List;
import dagger.Lazy;
import info.AAPSMocker;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp;
@ -30,6 +31,7 @@ import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
import info.nightscout.androidaps.plugins.insulin.InsulinOrefRapidActingPlugin;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.CobInfo;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin;
@ -902,7 +904,9 @@ public class SmsCommunicatorPluginTest {
when(SmsManager.getDefault()).thenReturn(smsManager);
when(SP.getString(R.string.key_smscommunicator_allowednumbers, "")).thenReturn("1234;5678");
smsCommunicatorPlugin = SmsCommunicatorPlugin.INSTANCE;
Lazy<InsulinOrefRapidActingPlugin> insulinOrefRapidActingPlugin = InsulinOrefRapidActingPlugin::new;
ConfigBuilderPlugin configBuilderPlugin = new ConfigBuilderPlugin(insulinOrefRapidActingPlugin);
smsCommunicatorPlugin = new SmsCommunicatorPlugin(configBuilderPlugin);
smsCommunicatorPlugin.setPluginEnabled(PluginType.GENERAL, true);
mockStatic(LoopPlugin.class);

View file

@ -82,7 +82,7 @@ public class InsulinOrefBasePluginTest extends InsulinOrefBasePlugin {
* @return
*/
@Override
int getPeak() {
public int getPeak() {
return this.peak;
}
@ -95,7 +95,7 @@ public class InsulinOrefBasePluginTest extends InsulinOrefBasePlugin {
return this.dia;
}
void sendShortDiaNotification(double dia) {
public void sendShortDiaNotification(double dia) {
this.shortDiaNotificationSend = true;
}
@ -110,7 +110,7 @@ public class InsulinOrefBasePluginTest extends InsulinOrefBasePlugin {
}
@Override
String commentStandardText() {
public String commentStandardText() {
return null;
}

View file

@ -1,6 +1,7 @@
package info.nightscout.androidaps.plugins.insulin
import info.nightscout.androidaps.R
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.resources.ResourceHelperImplementation
import info.nightscout.androidaps.utils.sharedPreferences.SP
import junit.framework.Assert.assertEquals
@ -34,7 +35,7 @@ class InsulinOrefFreePeakPluginTest {
lateinit var sp: SP
@Mock
lateinit var resourceHelper: ResourceHelperImplementation
lateinit var resourceHelper: ResourceHelper
@Before
fun setup() {