SmsCommunicator -> plugins module

This commit is contained in:
Milos Kozak 2022-11-01 14:42:49 +01:00
parent 4c5d015b40
commit bd2a7fc198
62 changed files with 692 additions and 328 deletions

View file

@ -177,6 +177,7 @@ dependencies {
implementation project(':shared')
implementation project(':core')
implementation project(':ui')
implementation project(':plugins')
implementation project(':implementation')
implementation project(':automation')
implementation project(':combo')

View file

@ -10,11 +10,6 @@
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.RECEIVE_MMS" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.SEND_MMS" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="com.google.android.permission.PROVIDE_BACKGROUND" />
@ -240,15 +235,6 @@
<activity
android:name=".activities.RequestDexcomPermissionActivity"
android:exported="false" />
<activity
android:name=".plugins.general.smsCommunicator.activities.SmsCommunicatorOtpActivity"
android:exported="false">
<intent-filter>
<action android:name="info.nightscout.androidaps.plugins.general.smsCommunicator.activities.SmsCommunicatorOtpActivity" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<uses-library
android:name="org.apache.http.legacy"

View file

@ -32,7 +32,7 @@ import info.nightscout.androidaps.plugins.general.autotune.AutotunePlugin
import info.nightscout.androidaps.plugins.general.maintenance.MaintenancePlugin
import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin
import info.nightscout.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

View file

@ -35,7 +35,7 @@ import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart
import info.nightscout.plugins.general.nsclient.events.EventNSClientRestart
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryData
import info.nightscout.androidaps.utils.ActionModeHelper
import info.nightscout.androidaps.utils.DateUtil
@ -271,7 +271,7 @@ class TreatmentsBolusCarbsFragment : DaggerFragment(), MenuProvider {
holder.binding.calculation.tag = ml
var notes = ml.carbs?.notes ?: ml.bolus?.notes ?: ""
val notes = ml.carbs?.notes ?: ml.bolus?.notes ?: ""
holder.binding.notes.text = notes
holder.binding.notes.visibility = if (notes != "") View.VISIBLE else View.GONE
}

View file

@ -26,7 +26,7 @@ import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart
import info.nightscout.plugins.general.nsclient.events.EventNSClientRestart
import info.nightscout.androidaps.utils.*
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.utils.rx.AapsSchedulers

View file

@ -28,7 +28,7 @@ import info.nightscout.androidaps.extensions.getCustomizedName
import info.nightscout.androidaps.extensions.toVisibility
import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart
import info.nightscout.plugins.general.nsclient.events.EventNSClientRestart
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryData
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin
import info.nightscout.androidaps.plugins.profile.local.events.EventLocalProfileChanged

View file

@ -34,7 +34,7 @@ import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart
import info.nightscout.plugins.general.nsclient.events.EventNSClientRestart
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryData
import info.nightscout.androidaps.utils.*
import info.nightscout.androidaps.utils.alertDialogs.OKDialog

View file

@ -7,7 +7,6 @@ import info.nightscout.androidaps.activities.*
import info.nightscout.androidaps.activities.HistoryBrowseActivity
import info.nightscout.androidaps.plugins.general.maintenance.activities.LogSettingActivity
import info.nightscout.androidaps.plugins.general.overview.activities.QuickWizardListActivity
import info.nightscout.androidaps.plugins.general.smsCommunicator.activities.SmsCommunicatorOtpActivity
import info.nightscout.androidaps.setupwizard.SetupWizardActivity
@Module
@ -23,7 +22,6 @@ abstract class ActivitiesModule {
@ContributesAndroidInjector abstract fun contributesRequestDexcomPermissionActivity(): RequestDexcomPermissionActivity
@ContributesAndroidInjector abstract fun contributesSetupWizardActivity(): SetupWizardActivity
@ContributesAndroidInjector abstract fun contributesSingleFragmentActivity(): SingleFragmentActivity
@ContributesAndroidInjector abstract fun contributesSmsCommunicatorOtpActivity(): SmsCommunicatorOtpActivity
@ContributesAndroidInjector abstract fun contributesStatsActivity(): StatsActivity
@ContributesAndroidInjector abstract fun contributesSurveyActivity(): SurveyActivity
@ContributesAndroidInjector abstract fun contributesDefaultProfileActivity(): ProfileHelperActivity

View file

@ -23,6 +23,7 @@ import info.nightscout.androidaps.plugins.pump.medtronic.di.MedtronicModule
import info.nightscout.androidaps.plugins.pump.omnipod.dash.di.OmnipodDashModule
import info.nightscout.androidaps.plugins.pump.omnipod.eros.di.OmnipodErosModule
import info.nightscout.implementation.di.CommandQueueModule
import info.nightscout.plugins.di.SMSCommunicatorModule
import info.nightscout.shared.di.SharedModule
import info.nightscout.ui.di.UiModule
import javax.inject.Singleton
@ -54,7 +55,7 @@ import javax.inject.Singleton
PreferencesModule::class,
OverviewModule::class,
DataClassesModule::class,
SMSModule::class,
SMSCommunicatorModule::class,
UIModule::class,
CoreModule::class,
DanaModule::class,

View file

@ -40,7 +40,7 @@ import info.nightscout.androidaps.plugins.general.maintenance.ImportExportPrefsI
import info.nightscout.androidaps.plugins.general.maintenance.PrefFileListProvider
import info.nightscout.androidaps.plugins.general.nsclient.DataSyncSelectorImplementation
import info.nightscout.androidaps.plugins.general.nsclient.data.DeviceStatusData
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin
import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorPlugin
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.plugins.pump.PumpSyncImplementation
import info.nightscout.androidaps.utils.DateUtil

View file

@ -41,7 +41,6 @@ import info.nightscout.androidaps.plugins.general.maintenance.MaintenanceFragmen
import info.nightscout.androidaps.plugins.general.nsclient.NSClientFragment
import info.nightscout.androidaps.plugins.general.overview.OverviewFragment
import info.nightscout.androidaps.plugins.general.overview.dialogs.EditQuickWizardDialog
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorFragment
import info.nightscout.androidaps.plugins.general.tidepool.TidepoolFragment
import info.nightscout.androidaps.plugins.general.wear.WearFragment
import info.nightscout.androidaps.plugins.insulin.InsulinFragment
@ -72,7 +71,6 @@ abstract class FragmentsModule {
@ContributesAndroidInjector abstract fun contributesLoopFragment(): LoopFragment
@ContributesAndroidInjector abstract fun contributesMaintenanceFragment(): MaintenanceFragment
@ContributesAndroidInjector abstract fun contributesNSClientFragment(): NSClientFragment
@ContributesAndroidInjector abstract fun contributesSmsCommunicatorFragment(): SmsCommunicatorFragment
@ContributesAndroidInjector abstract fun contributesWearFragment(): WearFragment
@ContributesAndroidInjector abstract fun contributesTidepoolFragment(): TidepoolFragment

View file

@ -32,7 +32,7 @@ import info.nightscout.androidaps.plugins.general.maintenance.MaintenancePlugin
import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin
import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin
import info.nightscout.androidaps.plugins.general.persistentNotification.PersistentNotificationPlugin
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin
import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorPlugin
import info.nightscout.androidaps.plugins.general.themes.ThemeSwitcherPlugin
import info.nightscout.androidaps.plugins.general.tidepool.TidepoolPlugin
import info.nightscout.androidaps.plugins.general.wear.WearPlugin

View file

@ -5,7 +5,13 @@ import dagger.android.ContributesAndroidInjector
import info.nightscout.androidaps.plugins.aps.loop.CarbSuggestionReceiver
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkBluetoothStateReceiver
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkBroadcastReceiver
import info.nightscout.androidaps.receivers.*
import info.nightscout.androidaps.receivers.AutoStartReceiver
import info.nightscout.androidaps.receivers.BTReceiver
import info.nightscout.androidaps.receivers.ChargingStateReceiver
import info.nightscout.androidaps.receivers.DataReceiver
import info.nightscout.androidaps.receivers.KeepAliveWorker
import info.nightscout.androidaps.receivers.SmsReceiver
import info.nightscout.androidaps.receivers.TimeDateOrTZChangeReceiver
@Module
@Suppress("unused")

View file

@ -1,12 +0,0 @@
package info.nightscout.androidaps.di
import dagger.Module
import dagger.android.ContributesAndroidInjector
import info.nightscout.androidaps.plugins.general.smsCommunicator.AuthRequest
@Module
@Suppress("unused")
abstract class SMSModule {
@ContributesAndroidInjector abstract fun authRequestInjector(): AuthRequest
}

View file

@ -8,9 +8,16 @@ import info.nightscout.androidaps.plugins.general.nsclient.NSClientAddAckWorker
import info.nightscout.androidaps.plugins.general.nsclient.NSClientAddUpdateWorker
import info.nightscout.androidaps.plugins.general.nsclient.NSClientMbgWorker
import info.nightscout.androidaps.plugins.general.nsclient.NSClientUpdateRemoveAckWorker
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin
import info.nightscout.androidaps.plugins.source.*
import info.nightscout.androidaps.plugins.source.AidexPlugin
import info.nightscout.androidaps.plugins.source.DexcomPlugin
import info.nightscout.androidaps.plugins.source.EversensePlugin
import info.nightscout.androidaps.plugins.source.GlimpPlugin
import info.nightscout.androidaps.plugins.source.MM640gPlugin
import info.nightscout.androidaps.plugins.source.NSClientSourcePlugin
import info.nightscout.androidaps.plugins.source.PoctechPlugin
import info.nightscout.androidaps.plugins.source.TomatoPlugin
import info.nightscout.androidaps.plugins.source.XdripPlugin
@Module
@Suppress("unused")
@ -25,7 +32,6 @@ abstract class WorkersModule {
@ContributesAndroidInjector abstract fun contributesEversenseWorker(): EversensePlugin.EversenseWorker
@ContributesAndroidInjector abstract fun contributesNSClientSourceWorker(): NSClientSourcePlugin.NSClientSourceWorker
@ContributesAndroidInjector abstract fun contributesNSProfileWorker(): LocalProfilePlugin.NSProfileWorker
@ContributesAndroidInjector abstract fun contributesSmsCommunicatorWorker(): SmsCommunicatorPlugin.SmsCommunicatorWorker
@ContributesAndroidInjector abstract fun contributesNSClientWorker(): NSClientAddUpdateWorker
@ContributesAndroidInjector abstract fun contributesNSClientAddAckWorker(): NSClientAddAckWorker
@ContributesAndroidInjector abstract fun contributesNSClientUpdateRemoveAckWorker(): NSClientUpdateRemoveAckWorker

View file

@ -14,7 +14,7 @@ import info.nightscout.androidaps.interfaces.DataSyncSelector
import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart
import info.nightscout.plugins.general.nsclient.events.EventNSClientRestart
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientUpdateGUI
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.alertDialogs.OKDialog

View file

@ -4,7 +4,7 @@ import info.nightscout.androidaps.events.Event
import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag
import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart
import info.nightscout.plugins.general.nsclient.events.EventNSClientRestart
import io.socket.client.Ack
import org.json.JSONArray
import org.json.JSONObject

View file

@ -33,7 +33,7 @@ import info.nightscout.androidaps.plugins.general.nsclient.data.NSAlarm
import info.nightscout.androidaps.plugins.general.nsclient.data.NSDeviceStatus
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientNewLog
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart
import info.nightscout.plugins.general.nsclient.events.EventNSClientRestart
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientStatus
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientUpdateGUI
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification

View file

@ -1,5 +0,0 @@
package info.nightscout.androidaps.plugins.general.smsCommunicator.events
import info.nightscout.androidaps.events.EventUpdateGui
class EventSmsCommunicatorUpdateGui : EventUpdateGui()

View file

@ -6,7 +6,7 @@ import android.provider.Telephony
import androidx.work.Data
import androidx.work.OneTimeWorkRequest
import dagger.android.DaggerBroadcastReceiver
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin
import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorPlugin
import info.nightscout.androidaps.plugins.source.*
import info.nightscout.androidaps.utils.extensions.copyDouble
import info.nightscout.androidaps.utils.extensions.copyLong

View file

@ -39,7 +39,6 @@
<string name="key_ns_glucose_value_new_data_id" translatable="false">ns_glucose_value_new_data_id</string>
<string name="key_ns_food_last_synced_id" translatable="false">ns_food_last_sync</string>
<string name="key_ns_therapy_event_last_synced_id" translatable="false">ns_therapy_event_last_sync</string>
<string name="key_smscommunicator_remotebolusmindistance" translatable="false">smscommunicator_remotebolusmindistance</string>
<string name="key_openapsama_bolussnooze_dia_divisor" translatable="false">bolussnooze_dia_divisor</string>
<string name="key_openapsama_autosens_adjusttargets" translatable="false">autosens_adjust_targets</string>
<string name="key_ns_bolus_calculator_result_last_synced_id" translatable="false">ns_bolus_calculator_result_last_synced_id</string>
@ -95,11 +94,9 @@
<string name="description_treatments">Saves all treatments that were made</string>
<string name="description_wear">Monitor and control AAPS using your WearOS watch.</string>
<string name="description_xdrip_status_line">Show information about your loop on your xDrip+ watchface.</string>
<string name="description_sms_communicator">Remote control AAPS using SMS commands.</string>
<string name="treatments_insulin_label_string">Insulin:</string>
<string name="treatments_carbs_label_string">Carbs:</string>
<string name="treatments_iob_label_string">IOB:</string>
<string name="sms_iob">IOB:</string>
<string name="treatments_iobtotal_label_string">Total IOB:</string>
<string name="treatments_iobactivitytotal_label_string">Total IOB activity:</string>
<string name="tempbasals_realduration_label_string">Dur:</string>
@ -124,7 +121,6 @@
<string name="openapsma_noglucosedata">No glucose data available</string>
<string name="openapsma_request_label">Request</string>
<string name="delta">Delta</string>
<string name="sms_delta">Delta:</string>
<string name="configbuilder">Config Builder</string>
<string name="overview">Overview</string>
<string name="treatments">Treatments</string>
@ -151,8 +147,6 @@
<string name="setbasalquestion">Accept new temp basal:</string>
<string name="overview_treatment_label">Treatment</string>
<string name="overview_calculator_label">Calculator</string>
<string name="sms_bolus">Bolus:</string>
<string name="sms_basal">Basal:</string>
<string name="changeyourinput">Change your input!</string>
<string name="configbuilder_bgsource">BG Source</string>
<string name="configbuilder_bgsource_description">Where should AAPS gain it\'s data from?</string>
@ -210,59 +204,6 @@
<string name="end_user_license_agreement_i_understand">I UNDERSTAND AND AGREE</string>
<string name="save">Save</string>
<string name="reloadprofile">Reload profile</string>
<string name="smscommunicator">SMS Communicator</string>
<string name="smscommunicator_allowednumbers">Allowed phone numbers</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_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_bolusfailed">Bolus failed</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="smscommunicator_bolusdelivered">Bolus %1$.2f U delivered successfully</string>
<string name="smscommunicator_mealbolusdelivered">Meal Bolus %1$.2f U 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="smscommunicator_remotecommandsallowed">Allow remote commands via SMS</string>
<string name="smscommunicator_loophasbeendisabled">Loop has been disabled</string>
<string name="smscommunicator_loophasbeenenabled">Loop has been enabled</string>
<string name="smscommunicator_loopisenabled">Loop is enabled</string>
<string name="smscommunicator_pumpconnectwithcode">To connect pump reply with code %1$s</string>
<string name="smscommunicator_pumpconnectfail">Connection to pump failed</string>
<string name="smscommunicator_pumpdisconnectwithcode">To disconnect pump for %1$d minutes reply with code %2$s</string>
<string name="smscommunicator_pumpdisconnected">Pump disconnected</string>
<string name="smscommunicator_reconnect">Pump reconnected</string>
<string name="smscommunicator_remotecommandnotallowed">Remote command is not allowed</string>
<string name="smscommunicator_remotebolusnotallowed">Remote bolus not available. Try again later.</string>
<string name="smscommunicator_basalreplywithcode">To start basal %1$.2f U/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_extendedreplywithcode">To start extended bolus %1$.2f U 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_suspendreplywithcode">To suspend loop for %1$d minutes reply with code %2$s</string>
<string name="smscommunicator_loopresumereplywithcode">To resume loop reply with code %1$s</string>
<string name="smscommunicator_loopenablereplywithcode">To enable loop reply with code %1$s</string>
<string name="smscommunicator_loopdisablereplywithcode">To disable loop reply with code %1$s</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_carbsset">Carbs %1$d g 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_tempbasalfailed">Temp basal start failed</string>
<string name="smscommunicator_extendedfailed">Extended bolus start failed</string>
<string name="smscommunicator_basalstopreplywithcode">To stop temp basal reply with code %1$s</string>
<string name="smscommunicator_extendedstopreplywithcode">To stop extended bolus reply with code %1$s</string>
<string name="smscommunicator_tempbasalcanceled">Temp basal canceled</string>
<string name="smscommunicator_extendedcanceled">Extended bolus canceled</string>
<string name="smscommunicator_tempbasalcancelfailed">Canceling temp basal failed</string>
<string name="smscommunicator_extendedcancelfailed">Canceling extended bolus failed</string>
<string name="smscommunicator_unknowncommand">Unknown command or wrong reply</string>
<string name="quickwizard">QuickWizard</string>
<string name="quickwizardsettings">QuickWizard settings</string>
<string name="overview_editquickwizard_buttontext">Button text:</string>
@ -293,12 +234,9 @@
<string name="resend_all_data">Resend All Data</string>
<string name="open_settings_on_wear">Open Settings on Wear</string>
<string name="basal_rate">Basal rate</string>
<string name="sms_actualbg">BG:</string>
<string name="sms_lastbg">Last BG:</string>
<string name="MM640g">MM640g</string>
<string name="ongoingnotificaction">Ongoing Notification</string>
<string name="old_data">OLD DATA</string>
<string name="sms_minago">%1$dmin ago</string>
<string name="localprofile">Profile</string>
<string name="openapsama">OpenAPS AMA</string>
<string name="array_of_elements">Array of %1$d elements.\nActual value:</string>
@ -318,7 +256,6 @@
<string name="treatments_shortname">TREAT</string>
<string name="objectives_shortname">OBJ</string>
<string name="wear_shortname">WEAR</string>
<string name="smscommunicator_shortname">SMS</string>
<string name="short_tabtitles">Shorten tab titles</string>
<string name="always_use_shortavg">Always use short average delta instead of simple delta</string>
<string name="always_use_shortavg_summary">Useful when data from unfiltered sources like xDrip+ gets noisy.</string>
@ -334,10 +271,6 @@
<string name="openapsama_min_5m_carbimpact_summary">Default value: 3.0 (AMA) or 8.0 (SMB). This is a setting for default carb absorption impact per 5 minutes. The default is an expected 3mg/dl/5min. This affects how fast COB are decayed, and how much carb absorption is assumed in calculating future predicted BG, when BG is falling more than expected, or not rising as much as expected.</string>
<string name="openapsama_link_to_preferncejson_doc_txt">Attention!\nNormally you do not have to change these values below. Please CLICK HERE and READ the text and make sure you UNDERSTAND it before change any of these values.</string>
<string name="openapsama_link_to_preferncejson_doc" translatable="false">http://openaps.readthedocs.io/en/latest/docs/walkthrough/phase-3/beyond-low-glucose-suspend.html</string>
<string name="smscommunicator_invalidphonennumber">Invalid SMS phone number</string>
<string name="smscommunicator_calibrationsent">Calibration sent. Receiving must be enabled in xDrip+.</string>
<string name="smscommunicator_calibrationfailed">xDrip+ is not receiving calibrations</string>
<string name="pumpsuspended">Pump suspended</string>
<string name="executing">Executing</string>
<string name="virtualpump_settings">Virtual pump settings</string>
<string name="virtualpump_uploadstatus_title">Upload status to NS</string>
@ -368,8 +301,6 @@
<string name="wear_detailedIOB_summary">Break down IOB into bolus and basal IOB on the watchface</string>
<string name="nosuccess">not successful - please check phone</string>
<string name="notavailable">n/a</string>
<string name="key_smscommunicator_allowednumbers" translatable="false">smscommunicator_allowednumbers</string>
<string name="key_smscommunicator_remotecommandsallowed" translatable="false">smscommunicator_remotecommandsallowed</string>
<string name="patientage">Patient type</string>
<string name="child">Child</string>
<string name="teenage">Teenage</string>
@ -379,12 +310,8 @@
<string name="patientage_summary">Please select patient type to setup safety limits</string>
<string name="patient_name">Patient name</string>
<string name="patient_name_summary">Please provide patient name or nickname to differentiate among multiple setups</string>
<string name="patient_name_default" comment="This is default patient display name, when user does not provide real one">User</string>
<string name="key_patient_name" translatable="false">patient_name</string>
<string name="key_i_understand" translatable="false">I_understand</string>
<string name="Glimp">Glimp</string>
<string name="loopsuspended">Loop suspended</string>
<string name="loopsuspendedfor">Suspended (%1$d m)</string>
<string name="suspendloopfor1h">Suspend loop for 1h</string>
<string name="suspendloopfor2h">Suspend loop for 2h</string>
<string name="suspendloopfor3h">Suspend loop for 3h</string>
@ -403,9 +330,6 @@
<string name="duration10h">10 hours</string>
<string name="resume">Resume</string>
<string name="reconnect">Reconnect Pump</string>
<string name="smscommunicator_wrongduration">Wrong duration</string>
<string name="smscommunicator_loopsuspended">Loop suspended</string>
<string name="smscommunicator_loopresumed">Loop resumed</string>
<string name="bg_trend_label">15min trend</string>
<string name="treatments_wizard_cob_label">COB</string>
<string name="superbolus">Superbolus</string>
@ -680,7 +604,6 @@
<string name="maxvalueinpreferences">max value in preferences</string>
<string name="hardlimit">hard limit</string>
<string name="key_openapsama_useautosens" translatable="false">openapsama_useautosens</string>
<string name="readstatusfailed">Read status failed</string>
<string name="record_pump_site_change">Record pump site change</string>
<string name="record_insulin_cartridge_change">Record insulin cartridge change</string>
<string name="smbalwaysdisabled">SMB always and after carbs disabled because active BG source doesn\'t support advanced filtering</string>
@ -857,11 +780,6 @@
<string name="dst_loop_disabled_warning">Daylight Saving time change less than 3 hours ago - Closed loop disabled</string>
<string name="storage">internal storage constraint</string>
<string name="diskfull">Free at least %1$d MB from internal storage! Loop disabled!</string>
<string name="wrongformat">Wrong format</string>
<string name="wrongTbrDuration">TBR duration must be a multiple of %1$d minutes and greater than 0.</string>
<string name="sms_wrongcode">Wrong code. Command cancelled.</string>
<string name="notconfigured">Not configured</string>
<string name="profileswitchcreated">Profile switch created</string>
<string name="versionChecker">Version Checker</string>
<string name="old_version">old version</string>
<string name="very_old_version">very old version</string>
@ -879,7 +797,6 @@
<string name="deliverpartofboluswizard">Bolus wizard performs calculation but only this part of calculated insulin is delivered. Useful with SMB algorithm.</string>
<string name="snooze">Snooze</string>
<string name="increasingmaxbasal">Increasing max basal value because setting is lower than your max basal in profile</string>
<string name="smscommunicator_messagebody">Invalid message body</string>
<string name="format_bg_isf">%1$s ISF: %2$.1f</string>
<string name="format_carbs_ic">%1$.0fg IC: %2$.1f</string>
<string name="format_cob_ic">%1$.1fg IC: %2$.1f</string>
@ -948,29 +865,6 @@
<string name="loop_smbexecution_time_label">SMB execution time</string>
<string name="loop_tbrrequest_time_label">Temp basal request time</string>
<string name="loop_tbrexecution_time_label">Temp basal execution time</string>
<!-- SMS Communicator & OTP Authenticator -->
<string name="key_smscommunicator_otp_password" translatable="false">smscommunicator_otp_password</string>
<string name="key_smscommunicator_otp_secret" translatable="false">smscommunicator_otp_secret</string>
<string name="smscommunicator_code_from_authenticator_for" comment="This is continuation of sentence: To [ACTION] reply with code">from Authenticator app for: %1$s followed by PIN</string>
<string name="smscommunicator_otp_pin">Additional mandatory PIN at token end</string>
<string name="smscommunicator_otp_pin_summary">Additional digits that should be memorised and glued at end of each generated One Time Password</string>
<string name="smscomunicator_tab_otp_label">Authenticator setup</string>
<string name="smscommunicator_code_verify_label">Code to check:</string>
<string name="smscommunicator_code_verify_hint">OTP + PIN</string>
<string name="smscommunicator_code_verify_info">The verification code consist of 6 digits displayed by Authenticator app (known as OTP) followed by 3 or more digits of mandatory PIN.</string>
<string name="smscommunicator_otp_reset_btn">Reset Authenticators</string>
<string name="smscommunicator_otp_reset_title">Reset Authenticator Key</string>
<string name="smscommunicator_otp_reset_prompt">Are you sure to reset Authenticator key? It will render all currently configured Authenticators invalid, and you will need to set them up again.</string>
<string name="smscommunicator_otp_reset_successful">New Authenticator Key was generated! Please use updated QRCode to provision authenticators.</string>
<string name="smscommunicator_otp_export_title">Exporting OTP secret</string>
<string name="smscommunicator_otp_export_prompt">Are you sure you want to copy OTP secret to clipboard?\n\nYou may only need that if your authenticator app have issues scanning QRCode, you want to enter it manually or you want to configure hardware OTP token using dedicated app.</string>
<string name="smscommunicator_otp_export_successful">OTP secret (in Base32 format) exported and copied into clipboard. Paste it into authenticator or hardware OTP burner!</string>
<string name="smscommunicator_otp_step1_install_header">1. Install Authenticator</string>
<string name="smscommunicator_otp_step2_provisioning_header">2. Scan code to setup AAPS OTP codes</string>
<string name="smscommunicator_otp_step3_test_header">3. Test One-Time-Password</string>
<string name="smscommunicator_otp_reset_header">Reset Authenticators</string>
<string name="smscommunicator_otp_install_info">On each follower phone install Authenticator app that support RFC 6238 TOTP tokens. Popular free apps are:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator</string>
<string name="smscommunicator_otp_reset_warning">By resetting authenticator you make all already provisioned authenticators invalid. You will need to set up them again!</string>
<string name="overview_show_predictions">Predictions</string>
<string name="overview_show_treatments">Treatments</string>
<string name="overview_show_deviationslope">Deviation slope</string>
@ -1005,8 +899,6 @@
<string name="filter">Filter</string>
<string name="copytolocalprofile_invalid">Unable to create profile. Profile is invalid.</string>
<string name="cta_dont_kill_my_app_info">Don\'t kill my app?</string>
<string name="smscommunicator_report_pump_ureachable_summary">Send SMS if unreachable pump event is triggered</string>
<string name="smscommunicator_pump_ureachable">Report pump unreachable</string>
<string name="advisoralarm">Run alarm when is time to eat</string>
<string name="key_usebolusadvisor" translatable="false">use_bolus_advisor</string>
<string name="time_to_eat">Time to eat!\nRun Bolus wizard and do calculation again.</string>
@ -1058,8 +950,6 @@
<string name="key_ns_receive_cgm" translatable="false">ns_receive_cgm</string>
<string name="ns_receive_cgm">Receive/backfill CGM data</string>
<string name="ns_receive_cgm_summary">Accept CGM data from NS</string>
<string name="sms_timeout_while_wating">Timeout while waiting for finish of previous pump communication</string>
<string name="smscommunicator_another_bolus_in_queue">There is another bolus in queue. Try again later.</string>
<string name="calculation_in_progress">Calculation in progress</string>
<string name="missing_profile_name">Missing profile name</string>
<string name="error_in_ic_values">Error in IC values</string>
@ -1186,7 +1076,6 @@
<string name="login">Login</string>
<string name="remove_all">Remove all</string>
<string name="reset_start">Reset start</string>
<string name="a11y_otp_qr_code">QR Code for setup one time password</string>
<string name="a11y_open_settings">open settings</string>
<string name="a11y_set_carb_timer">set carb timer alarm</string>
<string name="device_all">All</string>

View file

@ -15,7 +15,7 @@ import javax.inject.Inject
class ActionSendSMS(injector: HasAndroidInjector) : Action(injector) {
@Inject lateinit var smsCommunicatorPlugin: SmsCommunicator
@Inject lateinit var smsCommunicator: SmsCommunicator
var text = InputString()
@ -24,7 +24,7 @@ class ActionSendSMS(injector: HasAndroidInjector) : Action(injector) {
override fun icon(): Int = R.drawable.ic_notifications
override fun doAction(callback: Callback) {
val result = smsCommunicatorPlugin.sendNotificationToAllNumbers(text.value)
val result = smsCommunicator.sendNotificationToAllNumbers(text.value)
callback.result(PumpEnactResult(injector).success(result).comment(if (result) R.string.ok else R.string.error)).run()
}

View file

@ -36,7 +36,7 @@ class ActionSendSMSTest : ActionsTestBase() {
}
@Test fun doActionTest() {
`when`(smsCommunicatorPlugin.sendNotificationToAllNumbers(anyString())).thenReturn(true)
`when`(smsCommunicator.sendNotificationToAllNumbers(anyString())).thenReturn(true)
sut.text = InputString("Asd")
sut.doAction(object : Callback() {
override fun run() {

View file

@ -54,7 +54,7 @@ ActionsTestBase : TestBaseWithProfile() {
@Mock lateinit var configBuilder: ConfigBuilder
@Mock lateinit var activePlugin: ActivePlugin
@Mock lateinit var profilePlugin: ProfileSource
@Mock lateinit var smsCommunicatorPlugin: SmsCommunicator
@Mock lateinit var smsCommunicator: SmsCommunicator
@Mock lateinit var loopPlugin: TestLoopPlugin
@Mock lateinit var uel: UserEntryLogger
@ -82,7 +82,7 @@ ActionsTestBase : TestBaseWithProfile() {
if (it is ActionSendSMS) {
it.aapsLogger = aapsLogger
it.rh = rh
it.smsCommunicatorPlugin = smsCommunicatorPlugin
it.smsCommunicator = smsCommunicator
}
if (it is ActionProfileSwitch) {
it.aapsLogger = aapsLogger

View file

@ -4,7 +4,6 @@ import android.content.Context
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.Round
import org.json.JSONException
import org.json.JSONObject

View file

@ -6,6 +6,7 @@ import info.nightscout.androidaps.plugins.aps.loop.APSResult
interface Loop {
fun isEnabled(): Boolean
class LastRun {
var request: APSResult? = null

View file

@ -4,6 +4,7 @@ import info.nightscout.androidaps.data.Sms
interface SmsCommunicator {
var messages: ArrayList<Sms>
fun sendNotificationToAllNumbers(text: String): Boolean
fun sendSMS(sms: Sms): Boolean
}

View file

@ -205,6 +205,9 @@
<string name="bolus_reminder">Bolus reminder</string>
<string name="duration_label">Duration</string>
<string name="shortgramm">g</string>
<string name="pumpsuspended">Pump suspended</string>
<string name="notconfigured">Not configured</string>
<string name="loopsuspended">Loop suspended</string>
<!-- Constraints-->
<string name="limitingbasalratio">Limiting max basal rate to %1$.2f U/h because of %2$s</string>

View file

@ -53,4 +53,6 @@ files:
translation: /implementation/src/main/res/values-%android_code%/strings.xml
- source: /ui/src/main/res/values/strings.xml
translation: /ui/src/main/res/values-%android_code%/strings.xml
- source: /plugins/src/main/res/values/strings.xml
translation: /plugins/src/main/res/values-%android_code%/strings.xml
translate_attributes: 0

View file

@ -41,7 +41,7 @@ class LocalAlertUtilsImpl @Inject constructor(
private val rh: ResourceHelper,
private val activePlugin: ActivePlugin,
private val profileFunction: ProfileFunction,
private val smsCommunicatorPlugin: SmsCommunicator,
private val smsCommunicator: SmsCommunicator,
private val config: Config,
private val repository: AppRepository,
private val dateUtil: DateUtil,
@ -71,7 +71,7 @@ class LocalAlertUtilsImpl @Inject constructor(
disposable += repository.runTransaction(InsertTherapyEventAnnouncementTransaction(rh.gs(R.string.pump_unreachable))).subscribe()
}
if (sp.getBoolean(R.string.key_smscommunicator_report_pump_unreachable, true))
smsCommunicatorPlugin.sendNotificationToAllNumbers(rh.gs(R.string.pump_unreachable))
smsCommunicator.sendNotificationToAllNumbers(rh.gs(R.string.pump_unreachable))
}
if (!isStatusOutdated && !alarmTimeoutExpired) rxBus.send(EventDismissNotification(Notification.PUMP_UNREACHABLE))
}

View file

@ -23,7 +23,7 @@ class CommandSetProfile constructor(
callback: Callback?
) : Command(injector, CommandType.BASAL_PROFILE, callback) {
@Inject lateinit var smsCommunicatorPlugin: SmsCommunicator
@Inject lateinit var smsCommunicator: SmsCommunicator
@Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var dateUtil: DateUtil
@Inject lateinit var commandQueue: CommandQueue
@ -41,8 +41,8 @@ class CommandSetProfile constructor(
// Send SMS notification if ProfileSwitch is coming from NS
val profileSwitch = repository.getEffectiveProfileSwitchActiveAt(dateUtil.now()).blockingGet()
if (profileSwitch is ValueWrapper.Existing && r.enacted && hasNsId && !config.NSCLIENT) {
if ((smsCommunicatorPlugin as PluginBase).isEnabled())
smsCommunicatorPlugin.sendNotificationToAllNumbers(rh.gs(R.string.profile_set_ok))
if ((smsCommunicator as PluginBase).isEnabled())
smsCommunicator.sendNotificationToAllNumbers(rh.gs(R.string.profile_set_ok))
}
}

View file

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 60 KiB

View file

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 60 KiB

View file

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 60 KiB

1
plugins/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/build

20
plugins/build.gradle Normal file
View file

@ -0,0 +1,20 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-allopen'
apply plugin: 'com.hiya.jacoco-android'
apply from: "${project.rootDir}/core/android_dependencies.gradle"
apply from: "${project.rootDir}/core/android_module_dependencies.gradle"
apply from: "${project.rootDir}/core/test_dependencies.gradle"
apply from: "${project.rootDir}/core/jacoco_global.gradle"
android {
namespace 'info.nightscout.plugins'
}
dependencies {
implementation project(':shared')
implementation project(':database')
implementation project(':graphview')
implementation project(':core')
}

View file

21
plugins/proguard-rules.pro vendored Normal file
View file

@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.RECEIVE_MMS" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.SEND_MMS" />
<application>
<activity
android:name="info.nightscout.plugins.general.smsCommunicator.activities.SmsCommunicatorOtpActivity"
android:exported="false">
<intent-filter>
<action android:name="info.nightscout.androidaps.plugins.general.smsCommunicator.activities.SmsCommunicatorOtpActivity" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>

View file

@ -0,0 +1,18 @@
package info.nightscout.plugins.di
import dagger.Module
import dagger.android.ContributesAndroidInjector
import info.nightscout.plugins.general.smsCommunicator.AuthRequest
import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorFragment
import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorPlugin
import info.nightscout.plugins.general.smsCommunicator.activities.SmsCommunicatorOtpActivity
@Module
@Suppress("unused")
abstract class SMSCommunicatorModule {
@ContributesAndroidInjector abstract fun authRequestInjector(): AuthRequest
@ContributesAndroidInjector abstract fun contributesSmsCommunicatorOtpActivity(): SmsCommunicatorOtpActivity
@ContributesAndroidInjector abstract fun contributesSmsCommunicatorFragment(): SmsCommunicatorFragment
@ContributesAndroidInjector abstract fun contributesSmsCommunicatorWorker(): SmsCommunicatorPlugin.SmsCommunicatorWorker
}

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.plugins.general.nsclient.events
package info.nightscout.plugins.general.nsclient.events
import info.nightscout.androidaps.events.Event

View file

@ -1,17 +1,17 @@
package info.nightscout.androidaps.plugins.general.smsCommunicator
package info.nightscout.plugins.general.smsCommunicator
import android.os.SystemClock
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Sms
import info.nightscout.androidaps.interfaces.CommandQueue
import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.interfaces.SmsCommunicator
import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePassword
import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePasswordValidationResult
import info.nightscout.plugins.general.smsCommunicator.otp.OneTimePassword
import info.nightscout.plugins.general.smsCommunicator.otp.OneTimePasswordValidationResult
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.T
import info.nightscout.plugins.R
import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag
import javax.inject.Inject
@ -21,7 +21,8 @@ class AuthRequest internal constructor(
var requester: Sms,
requestText: String,
var confirmCode: String,
val action: SmsAction) {
val action: SmsAction
) {
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var smsCommunicator: SmsCommunicator
@ -50,7 +51,7 @@ class AuthRequest internal constructor(
if (!codeIsValid(codeReceived)) {
processed = true
aapsLogger.debug(LTag.SMS, "Wrong code")
smsCommunicator.sendSMS(Sms(requester.phoneNumber, rh.gs(R.string.sms_wrongcode)))
smsCommunicator.sendSMS(Sms(requester.phoneNumber, rh.gs(R.string.sms_wrong_code)))
return
}
if (dateUtil.now() - date < Constants.SMS_CONFIRM_TIMEOUT) {
@ -64,7 +65,7 @@ class AuthRequest internal constructor(
}
if (commandQueue.size() != 0) {
aapsLogger.debug(LTag.SMS, "Command timed out: " + requester.text)
smsCommunicator.sendSMS(Sms(requester.phoneNumber, rh.gs(R.string.sms_timeout_while_wating)))
smsCommunicator.sendSMS(Sms(requester.phoneNumber, rh.gs(R.string.sms_timeout_while_waiting)))
return
}
}

View file

@ -1,12 +1,12 @@
package info.nightscout.androidaps.plugins.general.smsCommunicator
package info.nightscout.plugins.general.smsCommunicator
abstract class SmsAction(val pumpCommand: Boolean) : Runnable {
var aDouble: Double? = null
var anInteger: Int? = null
var secondInteger: Int? = null
var secondLong: Long? = null
var aString: String? = null
private var secondInteger: Int? = null
private var secondLong: Long? = null
private var aString: String? = null
internal constructor(pumpCommand: Boolean, aDouble: Double) : this(pumpCommand) {
this.aDouble = aDouble

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.plugins.general.smsCommunicator
package info.nightscout.plugins.general.smsCommunicator
import android.os.Bundle
import android.view.LayoutInflater
@ -6,16 +6,17 @@ import android.view.View
import android.view.ViewGroup
import dagger.android.support.DaggerFragment
import info.nightscout.androidaps.data.Sms
import info.nightscout.androidaps.databinding.SmscommunicatorFragmentBinding
import info.nightscout.androidaps.interfaces.SmsCommunicator
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 info.nightscout.androidaps.utils.HtmlHelper
import io.reactivex.rxjava3.kotlin.plusAssign
import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.plugins.databinding.SmscommunicatorFragmentBinding
import info.nightscout.plugins.general.smsCommunicator.events.EventSmsCommunicatorUpdateGui
import io.reactivex.rxjava3.disposables.CompositeDisposable
import java.util.*
import io.reactivex.rxjava3.kotlin.plusAssign
import java.util.Collections
import javax.inject.Inject
import kotlin.math.max
@ -24,7 +25,7 @@ class SmsCommunicatorFragment : DaggerFragment() {
@Inject lateinit var aapsSchedulers: AapsSchedulers
@Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var rxBus: RxBus
@Inject lateinit var smsCommunicatorPlugin: SmsCommunicatorPlugin
@Inject lateinit var smsCommunicator: SmsCommunicator
@Inject lateinit var dateUtil: DateUtil
private val disposable = CompositeDisposable()
@ -35,8 +36,10 @@ class SmsCommunicatorFragment : DaggerFragment() {
// onDestroyView.
private val binding get() = _binding!!
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = SmscommunicatorFragmentBinding.inflate(inflater, container, false)
return binding.root
@ -63,7 +66,7 @@ class SmsCommunicatorFragment : DaggerFragment() {
_binding = null
}
fun updateGui() {
private fun updateGui() {
if (_binding == null) return
class CustomComparator : Comparator<Sms> {
@ -71,12 +74,12 @@ class SmsCommunicatorFragment : DaggerFragment() {
return (object1.date - object2.date).toInt()
}
}
Collections.sort(smsCommunicatorPlugin.messages, CustomComparator())
Collections.sort(smsCommunicator.messages, CustomComparator())
val messagesToShow = 40
val start = max(0, smsCommunicatorPlugin.messages.size - messagesToShow)
val start = max(0, smsCommunicator.messages.size - messagesToShow)
var logText = ""
for (x in start until smsCommunicatorPlugin.messages.size) {
val sms = smsCommunicatorPlugin.messages[x]
for (x in start until smsCommunicator.messages.size) {
val sms = smsCommunicator.messages[x]
when {
sms.ignored -> {
logText += dateUtil.timeString(sms.date) + " &lt;&lt;&lt; " + "" + sms.phoneNumber + " <b>" + sms.text + "</b><br>"

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.plugins.general.smsCommunicator
package info.nightscout.plugins.general.smsCommunicator
import android.content.Context
import android.telephony.SmsManager
@ -12,7 +12,7 @@ import androidx.work.WorkerParameters
import androidx.work.workDataOf
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.plugins.R
import info.nightscout.androidaps.annotations.OpenForTesting
import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.data.Sms
@ -35,11 +35,10 @@ import info.nightscout.shared.logging.LTag
import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
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.general.smsCommunicator.otp.OneTimePassword
import info.nightscout.plugins.general.smsCommunicator.events.EventSmsCommunicatorUpdateGui
import info.nightscout.plugins.general.smsCommunicator.otp.OneTimePassword
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.receivers.DataWorkerStorage
@ -48,6 +47,7 @@ import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.androidaps.utils.textValidator.ValidatingEditTextPreference
import info.nightscout.plugins.general.nsclient.events.EventNSClientRestart
import info.nightscout.shared.SafeParse
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.kotlin.plusAssign
@ -101,7 +101,7 @@ class SmsCommunicatorPlugin @Inject constructor(
var allowedNumbers: MutableList<String> = ArrayList()
@Volatile var messageToConfirm: AuthRequest? = null
@Volatile var lastRemoteBolusTime: Long = 0
var messages = ArrayList<Sms>()
override var messages = ArrayList<Sms>()
val commands = mapOf(
"BG" to "BG",
@ -135,7 +135,7 @@ class SmsCommunicatorPlugin @Inject constructor(
override fun preprocessPreferences(preferenceFragment: PreferenceFragmentCompat) {
super.preprocessPreferences(preferenceFragment)
val distance = preferenceFragment.findPreference(rh.gs(R.string.key_smscommunicator_remotebolusmindistance)) as ValidatingEditTextPreference?
val distance = preferenceFragment.findPreference(rh.gs(R.string.key_smscommunicator_remote_bolus_min_distance)) as ValidatingEditTextPreference?
?: return
val allowedNumbers = preferenceFragment.findPreference(rh.gs(R.string.key_smscommunicator_allowednumbers)) as EditTextPreference?
?: return
@ -243,67 +243,67 @@ class SmsCommunicatorPlugin @Inject constructor(
messages.add(receivedSms)
aapsLogger.debug(LTag.SMS, receivedSms.toString())
val divided = receivedSms.text.split(Regex("\\s+")).toTypedArray()
val remoteCommandsAllowed = sp.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)
val remoteCommandsAllowed = sp.getBoolean(R.string.key_smscommunicator_remote_commands_allowed, false)
val minDistance =
if (areMoreNumbers(sp.getString(R.string.key_smscommunicator_allowednumbers, "")))
T.mins(sp.getLong(R.string.key_smscommunicator_remotebolusmindistance, T.msecs(Constants.remoteBolusMinDistance).mins())).msecs()
T.mins(sp.getLong(R.string.key_smscommunicator_remote_bolus_min_distance, T.msecs(Constants.remoteBolusMinDistance).mins())).msecs()
else Constants.remoteBolusMinDistance
if (divided.isNotEmpty() && isCommand(divided[0].uppercase(Locale.getDefault()), receivedSms.phoneNumber)) {
when (divided[0].uppercase(Locale.getDefault())) {
"BG" ->
if (divided.size == 1) processBG(receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat)))
else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
"LOOP" ->
if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.smscommunicator_remotecommandnotallowed)))
else if (divided.size == 2 || divided.size == 3) processLOOP(divided, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat)))
else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
"NSCLIENT" ->
if (divided.size == 2) processNSCLIENT(divided, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat)))
else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
"PUMP" ->
if (!remoteCommandsAllowed && divided.size > 1) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.smscommunicator_remotecommandnotallowed)))
else if (divided.size <= 3) processPUMP(divided, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat)))
else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
"PROFILE" ->
if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.smscommunicator_remotecommandnotallowed)))
else if (divided.size == 2 || divided.size == 3) processPROFILE(divided, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat)))
else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
"BASAL" ->
if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.smscommunicator_remotecommandnotallowed)))
else if (divided.size == 2 || divided.size == 3) processBASAL(divided, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat)))
else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
"EXTENDED" ->
if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.smscommunicator_remotecommandnotallowed)))
else if (divided.size == 2 || divided.size == 3) processEXTENDED(divided, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat)))
else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
"BOLUS" ->
if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.smscommunicator_remotecommandnotallowed)))
else if (commandQueue.bolusInQueue()) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.smscommunicator_another_bolus_in_queue)))
else if (divided.size == 2 && dateUtil.now() - lastRemoteBolusTime < minDistance) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.smscommunicator_remotebolusnotallowed)))
else if (divided.size == 2 && pump.isSuspended()) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.pumpsuspended)))
else if (divided.size == 2 || divided.size == 3) processBOLUS(divided, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat)))
else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
"CARBS" ->
if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.smscommunicator_remotecommandnotallowed)))
else if (divided.size == 2 || divided.size == 3) processCARBS(divided, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat)))
else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
"CAL" ->
if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.smscommunicator_remotecommandnotallowed)))
else if (divided.size == 2) processCAL(divided, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat)))
else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
"TARGET" ->
if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.smscommunicator_remotecommandnotallowed)))
else if (divided.size == 2) processTARGET(divided, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat)))
else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
"SMS" ->
if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.smscommunicator_remotecommandnotallowed)))
else if (divided.size == 2) processSMS(divided, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat)))
else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
"HELP" ->
if (divided.size == 1 || divided.size == 2) processHELP(divided, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat)))
else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
else ->
if (messageToConfirm?.requester?.phoneNumber == receivedSms.phoneNumber) {
val execute = messageToConfirm
@ -324,11 +324,11 @@ class SmsCommunicatorPlugin @Inject constructor(
var reply = ""
val units = profileFunction.getUnits()
if (actualBG != null) {
reply = rh.gs(R.string.sms_actualbg) + " " + actualBG.valueToUnitsString(units) + ", "
reply = rh.gs(R.string.sms_actual_bg) + " " + actualBG.valueToUnitsString(units) + ", "
} else if (lastBG != null) {
val agoMilliseconds = dateUtil.now() - lastBG.timestamp
val agoMin = (agoMilliseconds / 60.0 / 1000.0).toInt()
reply = rh.gs(R.string.sms_lastbg) + " " + lastBG.valueToUnitsString(units) + " " + rh.gs(R.string.sms_minago, agoMin) + ", "
reply = rh.gs(R.string.sms_last_bg) + " " + lastBG.valueToUnitsString(units) + " " + rh.gs(R.string.sms_min_ago, agoMin) + ", "
}
val glucoseStatus = glucoseStatusProvider.glucoseStatusData
if (glucoseStatus != null) reply += rh.gs(R.string.sms_delta) + " " + Profile.toUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units) + " " + units + ", "
@ -389,7 +389,7 @@ class SmsCommunicatorPlugin @Inject constructor(
"STATUS" -> {
val reply = if (loop.enabled) {
if (loop.isSuspended) rh.gs(R.string.loopsuspendedfor, loop.minutesToEndOfSuspend())
if (loop.isSuspended) rh.gs(R.string.sms_loop_suspended_for, loop.minutesToEndOfSuspend())
else rh.gs(R.string.smscommunicator_loopisenabled)
} else
rh.gs(R.string.loopisdisabled)
@ -467,7 +467,7 @@ class SmsCommunicatorPlugin @Inject constructor(
}
}
else -> sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat)))
else -> sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
}
}
@ -477,7 +477,7 @@ class SmsCommunicatorPlugin @Inject constructor(
sendSMS(Sms(receivedSms.phoneNumber, "NSCLIENT RESTART SENT"))
receivedSms.processed = true
} else
sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat)))
sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
}
private fun processHELP(divided: Array<String>, receivedSms: Sms) {
@ -494,7 +494,7 @@ class SmsCommunicatorPlugin @Inject constructor(
}
}
else -> sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat)))
else -> sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
}
}
@ -507,7 +507,7 @@ class SmsCommunicatorPlugin @Inject constructor(
val reply = pump.shortStatus(true)
sendSMS(Sms(receivedSms.phoneNumber, reply))
} else {
val reply = rh.gs(R.string.readstatusfailed)
val reply = rh.gs(R.string.sms_read_status_failed)
sendSMS(Sms(receivedSms.phoneNumber, reply))
}
}
@ -561,7 +561,7 @@ class SmsCommunicatorPlugin @Inject constructor(
})
}
} else {
sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat)))
sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
return
}
}
@ -593,9 +593,9 @@ class SmsCommunicatorPlugin @Inject constructor(
val pIndex = SafeParse.stringToInt(divided[1])
var percentage = 100
if (divided.size > 2) percentage = SafeParse.stringToInt(divided[2])
if (pIndex > list.size) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat)))
else if (percentage == 0) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat)))
else if (pIndex == 0) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat)))
if (pIndex > list.size) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
else if (percentage == 0) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
else if (pIndex == 0) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
else {
val profile = store.getSpecificProfile(list[pIndex - 1] as String)
if (profile == null) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.noprofile)))
@ -607,11 +607,11 @@ class SmsCommunicatorPlugin @Inject constructor(
messageToConfirm = AuthRequest(injector, receivedSms, reply, passCode, object : SmsAction(pumpCommand = true, list[pIndex - 1] as String, finalPercentage) {
override fun run() {
if (profileFunction.createProfileSwitch(store, list[pIndex - 1] as String, 0, finalPercentage, 0, dateUtil.now())) {
val replyText = rh.gs(R.string.profileswitchcreated)
val replyText = rh.gs(R.string.sms_profile_switch_created)
sendSMS(Sms(receivedSms.phoneNumber, replyText))
uel.log(
Action.PROFILE_SWITCH, Sources.SMS, rh.gs(R.string.profileswitchcreated),
ValueWithUnit.SimpleString(rh.gsNotLocalised(R.string.profileswitchcreated))
Action.PROFILE_SWITCH, Sources.SMS, rh.gs(R.string.sms_profile_switch_created),
ValueWithUnit.SimpleString(rh.gsNotLocalised(R.string.sms_profile_switch_created))
)
} else {
sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.invalidprofile)))
@ -657,8 +657,8 @@ class SmsCommunicatorPlugin @Inject constructor(
if (divided.size > 2) duration = SafeParse.stringToInt(divided[2])
val profile = profileFunction.getProfile()
if (profile == null) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.noprofile)))
else if (tempBasalPct == 0 && divided[1] != "0%") sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat)))
else if (duration <= 0 || duration % durationStep != 0) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongTbrDuration, durationStep)))
else if (tempBasalPct == 0 && divided[1] != "0%") sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
else if (duration <= 0 || duration % durationStep != 0) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.sms_wrong_tbr_duration, durationStep)))
else {
tempBasalPct = constraintChecker.applyBasalPercentConstraints(Constraint(tempBasalPct), profile).value()
val passCode = generatePassCode()
@ -701,8 +701,8 @@ class SmsCommunicatorPlugin @Inject constructor(
if (divided.size > 2) duration = SafeParse.stringToInt(divided[2])
val profile = profileFunction.getProfile()
if (profile == null) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.noprofile)))
else if (tempBasal == 0.0 && divided[1] != "0") sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat)))
else if (duration <= 0 || duration % durationStep != 0) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongTbrDuration, durationStep)))
else if (tempBasal == 0.0 && divided[1] != "0") sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
else if (duration <= 0 || duration % durationStep != 0) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.sms_wrong_tbr_duration, durationStep)))
else {
tempBasal = constraintChecker.applyBasalConstraints(Constraint(tempBasal), profile).value()
val passCode = generatePassCode()
@ -765,12 +765,12 @@ class SmsCommunicatorPlugin @Inject constructor(
}
})
} else if (divided.size != 3) {
sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat)))
sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
} else {
var extended = SafeParse.stringToDouble(divided[1])
val duration = SafeParse.stringToInt(divided[2])
extended = constraintChecker.applyExtendedBolusConstraints(Constraint(extended)).value()
if (extended == 0.0 || duration == 0) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat)))
if (extended == 0.0 || duration == 0) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
else {
val passCode = generatePassCode()
val reply = rh.gs(R.string.smscommunicator_extendedreplywithcode, extended, duration, passCode)
@ -813,13 +813,13 @@ class SmsCommunicatorPlugin @Inject constructor(
val isMeal = divided.size > 2 && divided[2].equals("MEAL", ignoreCase = true)
bolus = constraintChecker.applyBolusConstraints(Constraint(bolus)).value()
if (divided.size == 3 && !isMeal) {
sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat)))
sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
} else if (bolus > 0.0) {
val passCode = generatePassCode()
val reply = if (isMeal)
rh.gs(R.string.smscommunicator_mealbolusreplywithcode, bolus, passCode)
rh.gs(R.string.smscommunicator_meal_bolus_reply_with_code, bolus, passCode)
else
rh.gs(R.string.smscommunicator_bolusreplywithcode, bolus, passCode)
rh.gs(R.string.smscommunicator_bolus_reply_with_code, bolus, passCode)
receivedSms.processed = true
messageToConfirm = AuthRequest(injector, receivedSms, reply, passCode, object : SmsAction(pumpCommand = true, bolus) {
override fun run() {
@ -884,7 +884,7 @@ class SmsCommunicatorPlugin @Inject constructor(
})
}
})
} else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat)))
} else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
}
private fun toTodayTime(hh_colon_mm: String): Long {
@ -912,12 +912,12 @@ class SmsCommunicatorPlugin @Inject constructor(
if (divided.size > 2) {
time = toTodayTime(divided[2].uppercase(Locale.getDefault()))
if (time == 0L) {
sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat)))
sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
return
}
}
grams = constraintChecker.applyCarbsConstraints(Constraint(grams)).value()
if (grams == 0) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat)))
if (grams == 0) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
else {
val passCode = generatePassCode()
val reply = rh.gs(R.string.smscommunicator_carbsreplywithcode, grams, dateUtil.timeString(time), passCode)
@ -1039,7 +1039,7 @@ class SmsCommunicatorPlugin @Inject constructor(
}
})
} else
sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat)))
sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
}
private fun processSMS(divided: Array<String>, receivedSms: Sms) {
@ -1051,14 +1051,14 @@ class SmsCommunicatorPlugin @Inject constructor(
receivedSms.processed = true
messageToConfirm = AuthRequest(injector, receivedSms, reply, passCode, object : SmsAction(pumpCommand = false) {
override fun run() {
sp.putBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)
sp.putBoolean(R.string.key_smscommunicator_remote_commands_allowed, false)
val replyText = rh.gs(R.string.smscommunicator_stoppedsms)
sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, replyText))
uel.log(Action.STOP_SMS, Sources.SMS, rh.gs(R.string.smscommunicator_stoppedsms),
ValueWithUnit.SimpleString(rh.gsNotLocalised(R.string.smscommunicator_stoppedsms)))
}
})
} else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat)))
} else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
}
private fun processCAL(divided: Array<String>, receivedSms: Sms) {
@ -1081,7 +1081,7 @@ class SmsCommunicatorPlugin @Inject constructor(
ValueWithUnit.SimpleString(rh.gsNotLocalised(R.string.smscommunicator_calibrationfailed)))
}
})
} else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrongformat)))
} else sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
}
override fun sendNotificationToAllNumbers(text: String): Boolean {

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.plugins.general.smsCommunicator.activities
package info.nightscout.plugins.general.smsCommunicator.activities
import android.content.ClipData
import android.content.ClipboardManager
@ -12,25 +12,25 @@ import android.view.View
import android.view.WindowManager
import com.google.common.primitives.Ints.min
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel
import info.nightscout.androidaps.R
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity
import info.nightscout.androidaps.database.entities.UserEntry.Action
import info.nightscout.androidaps.database.entities.UserEntry.Sources
import info.nightscout.androidaps.databinding.ActivitySmscommunicatorOtpBinding
import info.nightscout.androidaps.interfaces.SmsCommunicator
import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin
import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePassword
import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePasswordValidationResult
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.ToastUtils
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.plugins.R
import info.nightscout.plugins.databinding.ActivitySmscommunicatorOtpBinding
import info.nightscout.plugins.general.smsCommunicator.otp.OneTimePassword
import info.nightscout.plugins.general.smsCommunicator.otp.OneTimePasswordValidationResult
import net.glxn.qrgen.android.QRCode
import javax.inject.Inject
class SmsCommunicatorOtpActivity : NoSplashAppCompatActivity() {
@Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var smsCommunicatorPlugin: SmsCommunicatorPlugin
@Inject lateinit var smsCommunicator: SmsCommunicator
@Inject lateinit var otp: OneTimePassword
@Inject lateinit var uel: UserEntryLogger
@ -105,7 +105,7 @@ class SmsCommunicatorOtpActivity : NoSplashAppCompatActivity() {
updateGui()
}
fun updateGui() {
private fun updateGui() {
val displayMetrics = Resources.getSystem().displayMetrics
val width = displayMetrics.widthPixels
val height = displayMetrics.heightPixels

View file

@ -0,0 +1,5 @@
package info.nightscout.plugins.general.smsCommunicator.events
import info.nightscout.androidaps.events.EventUpdateGui
internal class EventSmsCommunicatorUpdateGui : EventUpdateGui()

View file

@ -1,13 +1,13 @@
package info.nightscout.androidaps.plugins.general.smsCommunicator.otp
package info.nightscout.plugins.general.smsCommunicator.otp
import android.util.Base64
import com.eatthepath.otp.HmacOneTimePasswordGenerator
import com.google.common.io.BaseEncoding
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.annotations.OpenForTesting
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.plugins.R
import info.nightscout.shared.sharedPreferences.SP
import java.net.URLEncoder
import javax.crypto.KeyGenerator

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.plugins.general.smsCommunicator.otp
package info.nightscout.plugins.general.smsCommunicator.otp
enum class OneTimePasswordValidationResult {
OK,

View file

@ -2,7 +2,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
tools:context=".plugins.general.smsCommunicator.activities.SmsCommunicatorOtpActivity">
tools:context="info.nightscout.plugins.general.smsCommunicator.activities.SmsCommunicatorOtpActivity">
<LinearLayout
android:id="@+id/otp_layout"

View file

@ -2,7 +2,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".plugins.general.smsCommunicator.SmsCommunicatorFragment">
tools:context="info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorFragment">
<TextView
android:id="@+id/log"

View file

@ -0,0 +1,114 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- SMS Communicator & OTP Authenticator -->
<string name="key_smscommunicator_otp_password" translatable="false">smscommunicator_otp_password</string>
<string name="key_smscommunicator_otp_secret" translatable="false">smscommunicator_otp_secret</string>
<string name="key_patient_name" translatable="false">patient_name</string>
<string name="key_smscommunicator_remote_bolus_min_distance" translatable="false">smscommunicator_remotebolusmindistance</string>
<string name="key_smscommunicator_allowednumbers" translatable="false">smscommunicator_allowednumbers</string>
<string name="key_smscommunicator_remote_commands_allowed" translatable="false">smscommunicator_remotecommandsallowed</string>
<string name="smscommunicator">SMS Communicator</string>
<string name="smscommunicator_shortname">SMS</string>
<string name="description_sms_communicator">Remote control AAPS using SMS commands.</string>
<string name="smscommunicator_code_from_authenticator_for" comment="This is continuation of sentence: To [ACTION] reply with code">from Authenticator app for: %1$s followed by PIN</string>
<string name="smscommunicator_otp_pin">Additional mandatory PIN at token end</string>
<string name="smscommunicator_otp_pin_summary">Additional digits that should be memorised and glued at end of each generated One Time Password</string>
<string name="smscommunicator_tab_otp_label">Authenticator setup</string>
<string name="smscommunicator_code_verify_label">Code to check:</string>
<string name="smscommunicator_code_verify_hint">OTP + PIN</string>
<string name="smscommunicator_code_verify_info">The verification code consist of 6 digits displayed by Authenticator app (known as OTP) followed by 3 or more digits of mandatory PIN.</string>
<string name="smscommunicator_otp_reset_btn">Reset Authenticators</string>
<string name="smscommunicator_otp_reset_title">Reset Authenticator Key</string>
<string name="smscommunicator_otp_reset_prompt">Are you sure to reset Authenticator key? It will render all currently configured Authenticators invalid, and you will need to set them up again.</string>
<string name="smscommunicator_otp_reset_successful">New Authenticator Key was generated! Please use updated QRCode to provision authenticators.</string>
<string name="smscommunicator_otp_export_title">Exporting OTP secret</string>
<string name="smscommunicator_otp_export_prompt">Are you sure you want to copy OTP secret to clipboard?\n\nYou may only need that if your authenticator app have issues scanning QRCode, you want to enter it manually or you want to configure hardware OTP token using dedicated app.</string>
<string name="smscommunicator_otp_export_successful">OTP secret (in Base32 format) exported and copied into clipboard. Paste it into authenticator or hardware OTP burner!</string>
<string name="smscommunicator_otp_step1_install_header">1. Install Authenticator</string>
<string name="smscommunicator_otp_step2_provisioning_header">2. Scan code to setup AAPS OTP codes</string>
<string name="smscommunicator_otp_step3_test_header">3. Test One-Time-Password</string>
<string name="smscommunicator_otp_reset_header">Reset Authenticators</string>
<string name="smscommunicator_otp_install_info">On each follower phone install Authenticator app that support RFC 6238 TOTP tokens. Popular free apps are:\n • Authy\n • Google Authenticator\n • LastPass Authenticator\n • FreeOTP Authenticator</string>
<string name="smscommunicator_otp_reset_warning">By resetting authenticator you make all already provisioned authenticators invalid. You will need to set up them again!</string>
<string name="sms_wrong_code">Wrong code. Command cancelled.</string>
<string name="sms_timeout_while_waiting">Timeout while waiting for finish of previous pump communication</string>
<string name="patient_name_default" comment="This is default patient display name, when user does not provide real one">User</string>
<string name="smscommunicator_allowednumbers">Allowed phone numbers</string>
<string name="smscommunicator_allowednumbers_summary">+XXXXXXXXXX;+YYYYYYYYYY</string>
<string name="smscommunicator_bolus_reply_with_code">To deliver bolus %1$.2fU reply with code %2$s</string>
<string name="smscommunicator_meal_bolus_reply_with_code">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_bolusfailed">Bolus failed</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="smscommunicator_bolusdelivered">Bolus %1$.2f U delivered successfully</string>
<string name="smscommunicator_mealbolusdelivered">Meal Bolus %1$.2f U 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="smscommunicator_remotecommandsallowed">Allow remote commands via SMS</string>
<string name="smscommunicator_loophasbeendisabled">Loop has been disabled</string>
<string name="smscommunicator_loophasbeenenabled">Loop has been enabled</string>
<string name="smscommunicator_loopisenabled">Loop is enabled</string>
<string name="smscommunicator_pumpconnectwithcode">To connect pump reply with code %1$s</string>
<string name="smscommunicator_pumpconnectfail">Connection to pump failed</string>
<string name="smscommunicator_pumpdisconnectwithcode">To disconnect pump for %1$d minutes reply with code %2$s</string>
<string name="smscommunicator_pumpdisconnected">Pump disconnected</string>
<string name="smscommunicator_reconnect">Pump reconnected</string>
<string name="smscommunicator_remotecommandnotallowed">Remote command is not allowed</string>
<string name="smscommunicator_remotebolusnotallowed">Remote bolus not available. Try again later.</string>
<string name="smscommunicator_basalreplywithcode">To start basal %1$.2f U/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_extendedreplywithcode">To start extended bolus %1$.2f U 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_suspendreplywithcode">To suspend loop for %1$d minutes reply with code %2$s</string>
<string name="smscommunicator_loopresumereplywithcode">To resume loop reply with code %1$s</string>
<string name="smscommunicator_loopenablereplywithcode">To enable loop reply with code %1$s</string>
<string name="smscommunicator_loopdisablereplywithcode">To disable loop reply with code %1$s</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_carbsset">Carbs %1$d g 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_tempbasalfailed">Temp basal start failed</string>
<string name="smscommunicator_extendedfailed">Extended bolus start failed</string>
<string name="smscommunicator_basalstopreplywithcode">To stop temp basal reply with code %1$s</string>
<string name="smscommunicator_extendedstopreplywithcode">To stop extended bolus reply with code %1$s</string>
<string name="smscommunicator_tempbasalcanceled">Temp basal canceled</string>
<string name="smscommunicator_extendedcanceled">Extended bolus canceled</string>
<string name="smscommunicator_tempbasalcancelfailed">Canceling temp basal failed</string>
<string name="smscommunicator_extendedcancelfailed">Canceling extended bolus failed</string>
<string name="smscommunicator_unknowncommand">Unknown command or wrong reply</string>
<string name="smscommunicator_another_bolus_in_queue">There is another bolus in queue. Try again later.</string>
<string name="smscommunicator_wrongduration">Wrong duration</string>
<string name="smscommunicator_loopsuspended">Loop suspended</string>
<string name="smscommunicator_loopresumed">Loop resumed</string>
<string name="smscommunicator_invalidphonennumber">Invalid SMS phone number</string>
<string name="smscommunicator_calibrationsent">Calibration sent. Receiving must be enabled in xDrip+.</string>
<string name="smscommunicator_calibrationfailed">xDrip+ is not receiving calibrations</string>
<string name="smscommunicator_messagebody">Invalid message body</string>
<string name="smscommunicator_report_pump_ureachable_summary">Send SMS if unreachable pump event is triggered</string>
<string name="smscommunicator_pump_ureachable">Report pump unreachable</string>
<string name="wrong_format">Wrong format</string>
<string name="sms_actual_bg">BG:</string>
<string name="sms_last_bg">Last BG:</string>
<string name="sms_delta">Delta:</string>
<string name="sms_iob">IOB:</string>
<string name="sms_bolus">Bolus:</string>
<string name="sms_basal">Basal:</string>
<string name="sms_min_ago">%1$dmin ago</string>
<string name="sms_loop_suspended_for">Suspended (%1$d m)</string>
<string name="sms_read_status_failed">Read status failed</string>
<string name="sms_profile_switch_created">Profile switch created</string>
<string name="sms_wrong_tbr_duration">TBR duration must be a multiple of %1$d minutes and greater than 0.</string>
<string name="a11y_otp_qr_code">QR Code for setup one time password</string>
</resources>

View file

@ -16,12 +16,12 @@
<SwitchPreference
android:defaultValue="false"
android:key="@string/key_smscommunicator_remotecommandsallowed"
android:key="@string/key_smscommunicator_remote_commands_allowed"
android:title="@string/smscommunicator_remotecommandsallowed" />
<info.nightscout.androidaps.utils.textValidator.ValidatingEditTextPreference
android:defaultValue="15"
android:key="@string/key_smscommunicator_remotebolusmindistance"
android:key="@string/key_smscommunicator_remote_bolus_min_distance"
android:summary="@string/smscommunicator_remotebolusmindistance_summary"
android:title="@string/smscommunicator_remotebolusmindistance"
validate:maxNumber="60"
@ -29,16 +29,16 @@
validate:testType="numericRange" />
<info.nightscout.androidaps.utils.textValidator.ValidatingEditTextPreference
android:dependency="@string/key_smscommunicator_remotecommandsallowed"
android:dependency="@string/key_smscommunicator_remote_commands_allowed"
android:key="@string/key_smscommunicator_otp_password"
android:summary="@string/smscommunicator_otp_pin_summary"
android:title="@string/smscommunicator_otp_pin"
validate:testType="pinStrength" />
<Preference
android:dependency="@string/key_smscommunicator_remotecommandsallowed"
android:dependency="@string/key_smscommunicator_remote_commands_allowed"
android:key="otpsetup"
android:title="@string/smscomunicator_tab_otp_label">
android:title="@string/smscommunicator_tab_otp_label">
<intent android:action="info.nightscout.androidaps.plugins.general.smsCommunicator.activities.SmsCommunicatorOtpActivity" />
</Preference>

View file

@ -0,0 +1,39 @@
package info.nightscout.androidaps
import info.nightscout.shared.logging.AAPSLoggerTest
import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.androidaps.utils.rx.TestAapsSchedulers
import org.junit.Before
import org.junit.Rule
import org.mockito.Mockito
import org.mockito.junit.MockitoJUnit
import org.mockito.junit.MockitoRule
import java.util.*
open class TestBase {
val aapsLogger = AAPSLoggerTest()
val aapsSchedulers: AapsSchedulers = TestAapsSchedulers()
// Add a JUnit rule that will setup the @Mock annotated vars and log.
// Another possibility would be to add `MockitoAnnotations.initMocks(this) to the setup method.
@get:Rule
val mockitoRule: MockitoRule = MockitoJUnit.rule()
@Before
fun setupLocale() {
Locale.setDefault(Locale.ENGLISH)
System.setProperty("disableFirebase", "true")
}
// Workaround for Kotlin nullability.
// https://medium.com/@elye.project/befriending-kotlin-and-mockito-1c2e7b0ef791
// https://stackoverflow.com/questions/30305217/is-it-possible-to-use-mockito-in-kotlin
fun <T> anyObject(): T {
Mockito.any<T>()
return uninitialized()
}
@Suppress("Unchecked_Cast")
fun <T> uninitialized(): T = null as T
}

View file

@ -0,0 +1,177 @@
package info.nightscout.androidaps
import android.content.Context
import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.data.ProfileSealed
import info.nightscout.androidaps.database.embedments.InsulinConfiguration
import info.nightscout.androidaps.database.entities.EffectiveProfileSwitch
import info.nightscout.androidaps.extensions.pureProfileFromJson
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.interfaces.IobCobCalculator
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.interfaces.ProfileStore
import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.interfaces.ResourceHelper
import org.json.JSONObject
import org.junit.Before
import org.mockito.ArgumentMatchers.anyDouble
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.ArgumentMatchers.anyString
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.Mockito.`when`
import org.mockito.invocation.InvocationOnMock
@Suppress("SpellCheckingInspection")
open class TestBaseWithProfile : TestBase() {
@Mock lateinit var activePluginProvider: ActivePlugin
@Mock lateinit var rh: ResourceHelper
@Mock lateinit var iobCobCalculator: IobCobCalculator
@Mock lateinit var fabricPrivacy: FabricPrivacy
@Mock lateinit var profileFunction: ProfileFunction
@Mock lateinit var config: Config
@Mock lateinit var context: Context
lateinit var dateUtil: DateUtil
val rxBus = RxBus(aapsSchedulers, aapsLogger)
val profileInjector = HasAndroidInjector { AndroidInjector { } }
private lateinit var validProfileJSON: String
lateinit var validProfile: ProfileSealed.Pure
lateinit var effectiveProfileSwitch: EffectiveProfileSwitch
@Suppress("PropertyName") val TESTPROFILENAME = "someProfile"
@Before
fun prepareMock() {
validProfileJSON = "{\"dia\":\"5\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"3\"}," +
"{\"time\":\"2:00\",\"value\":\"3.4\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4.5\"}]," +
"\"target_high\":[{\"time\":\"00:00\",\"value\":\"7\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}"
dateUtil = Mockito.spy(DateUtil(context))
`when`(dateUtil.now()).thenReturn(1656358822000)
validProfile = ProfileSealed.Pure(pureProfileFromJson(JSONObject(validProfileJSON), dateUtil)!!)
effectiveProfileSwitch = EffectiveProfileSwitch(
timestamp = dateUtil.now(),
basalBlocks = validProfile.basalBlocks,
isfBlocks = validProfile.isfBlocks,
icBlocks = validProfile.icBlocks,
targetBlocks = validProfile.targetBlocks,
glucoseUnit = EffectiveProfileSwitch.GlucoseUnit.MMOL,
originalProfileName = "",
originalCustomizedName = "",
originalTimeshift = 0,
originalPercentage = 100,
originalDuration = 0,
originalEnd = 0,
insulinConfiguration = InsulinConfiguration("", 0, 0)
)
Mockito.doAnswer { invocation: InvocationOnMock ->
val string = invocation.getArgument<Int>(0)
val arg1 = invocation.getArgument<Int?>(1)
String.format(rh.gs(string), arg1)
}.`when`(rh).gs(anyInt(), anyInt())
Mockito.doAnswer { invocation: InvocationOnMock ->
val string = invocation.getArgument<Int>(0)
val arg1 = invocation.getArgument<Double?>(1)
String.format(rh.gs(string), arg1)
}.`when`(rh).gs(anyInt(), anyDouble())
Mockito.doAnswer { invocation: InvocationOnMock ->
val string = invocation.getArgument<Int>(0)
val arg1 = invocation.getArgument<String?>(1)
String.format(rh.gs(string), arg1)
}.`when`(rh).gs(anyInt(), anyString())
Mockito.doAnswer { invocation: InvocationOnMock ->
val string = invocation.getArgument<Int>(0)
val arg1 = invocation.getArgument<String?>(1)
val arg2 = invocation.getArgument<String?>(2)
String.format(rh.gs(string), arg1, arg2)
}.`when`(rh).gs(anyInt(), anyString(), anyString())
Mockito.doAnswer { invocation: InvocationOnMock ->
val string = invocation.getArgument<Int>(0)
val arg1 = invocation.getArgument<String?>(1)
val arg2 = invocation.getArgument<Int?>(2)
String.format(rh.gs(string), arg1, arg2)
}.`when`(rh).gs(anyInt(), anyString(), anyInt())
Mockito.doAnswer { invocation: InvocationOnMock ->
val string = invocation.getArgument<Int>(0)
val arg1 = invocation.getArgument<Double?>(1)
val arg2 = invocation.getArgument<String?>(2)
String.format(rh.gs(string), arg1, arg2)
}.`when`(rh).gs(anyInt(), anyDouble(), anyString())
Mockito.doAnswer { invocation: InvocationOnMock ->
val string = invocation.getArgument<Int>(0)
val arg1 = invocation.getArgument<Double?>(1)
val arg2 = invocation.getArgument<Int?>(2)
String.format(rh.gs(string), arg1, arg2)
}.`when`(rh).gs(anyInt(), anyDouble(), anyInt())
Mockito.doAnswer { invocation: InvocationOnMock ->
val string = invocation.getArgument<Int>(0)
val arg1 = invocation.getArgument<Int?>(1)
val arg2 = invocation.getArgument<Int?>(2)
String.format(rh.gs(string), arg1, arg2)
}.`when`(rh).gs(anyInt(), anyInt(), anyInt())
Mockito.doAnswer { invocation: InvocationOnMock ->
val string = invocation.getArgument<Int>(0)
val arg1 = invocation.getArgument<Int?>(1)
val arg2 = invocation.getArgument<String?>(2)
String.format(rh.gs(string), arg1, arg2)
}.`when`(rh).gs(anyInt(), anyInt(), anyString())
Mockito.doAnswer { invocation: InvocationOnMock ->
val string = invocation.getArgument<Int>(0)
val arg1 = invocation.getArgument<Int?>(1)
val arg2 = invocation.getArgument<Int?>(2)
val arg3 = invocation.getArgument<String?>(3)
String.format(rh.gs(string), arg1, arg2, arg3)
}.`when`(rh).gs(anyInt(), anyInt(), anyInt(), anyString())
Mockito.doAnswer { invocation: InvocationOnMock ->
val string = invocation.getArgument<Int>(0)
val arg1 = invocation.getArgument<Int?>(1)
val arg2 = invocation.getArgument<String?>(2)
val arg3 = invocation.getArgument<String?>(3)
String.format(rh.gs(string), arg1, arg2, arg3)
}.`when`(rh).gs(anyInt(), anyInt(), anyString(), anyString())
Mockito.doAnswer { invocation: InvocationOnMock ->
val string = invocation.getArgument<Int>(0)
val arg1 = invocation.getArgument<Double?>(1)
val arg2 = invocation.getArgument<Int?>(2)
val arg3 = invocation.getArgument<String?>(3)
String.format(rh.gs(string), arg1, arg2, arg3)
}.`when`(rh).gs(anyInt(), anyDouble(), anyInt(), anyString())
Mockito.doAnswer { invocation: InvocationOnMock ->
val string = invocation.getArgument<Int>(0)
val arg1 = invocation.getArgument<String?>(1)
val arg2 = invocation.getArgument<Int?>(2)
val arg3 = invocation.getArgument<String?>(3)
String.format(rh.gs(string), arg1, arg2, arg3)
}.`when`(rh).gs(anyInt(), anyString(), anyInt(), anyString())
}
fun getValidProfileStore(): ProfileStore {
val json = JSONObject()
val store = JSONObject()
store.put(TESTPROFILENAME, JSONObject(validProfileJSON))
json.put("defaultProfile", TESTPROFILENAME)
json.put("store", store)
return ProfileStore(profileInjector, json, dateUtil)
}
}

View file

@ -0,0 +1,68 @@
package info.nightscout.androidaps
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.interfaces.PumpDescription
import info.nightscout.androidaps.interfaces.Pump
import info.nightscout.androidaps.interfaces.PumpSync
import info.nightscout.androidaps.plugins.common.ManufacturerType
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
import info.nightscout.androidaps.utils.TimeChangeType
import org.json.JSONObject
@Suppress("MemberVisibilityCanBePrivate")
class TestPumpPlugin(val injector: HasAndroidInjector) : Pump {
var connected = false
var isProfileSet = true
override fun isConnected() = connected
override fun isConnecting() = false
override fun isHandshakeInProgress() = false
val lastData = 0L
val baseBasal = 0.0
override val pumpDescription = PumpDescription()
override fun isInitialized(): Boolean = true
override fun isSuspended(): Boolean = false
override fun isBusy(): Boolean = false
override fun connect(reason: String) {
connected = true
}
override fun disconnect(reason: String) {
connected = false
}
override fun stopConnecting() {
connected = false
}
override fun waitForDisconnectionInSeconds(): Int = 0
override fun getPumpStatus(reason: String) {}
override fun setNewBasalProfile(profile: Profile): PumpEnactResult = PumpEnactResult(injector)
override fun isThisProfileSet(profile: Profile): Boolean = isProfileSet
override fun lastDataTime(): Long = lastData
override val baseBasalRate: Double = baseBasal
override val reservoirLevel: Double = 0.0
override val batteryLevel: Int = 0
override fun deliverTreatment(detailedBolusInfo: DetailedBolusInfo): PumpEnactResult = PumpEnactResult(injector).success(true)
override fun stopBolusDelivering() {}
override fun setTempBasalAbsolute(absoluteRate: Double, durationInMinutes: Int, profile: Profile, enforceNew: Boolean, tbrType: PumpSync.TemporaryBasalType): PumpEnactResult = PumpEnactResult(injector).success(true)
override fun setTempBasalPercent(percent: Int, durationInMinutes: Int, profile: Profile, enforceNew: Boolean, tbrType: PumpSync.TemporaryBasalType): PumpEnactResult = PumpEnactResult(injector).success(true)
override fun setExtendedBolus(insulin: Double, durationInMinutes: Int): PumpEnactResult = PumpEnactResult(injector).success(true)
override fun cancelTempBasal(enforceNew: Boolean): PumpEnactResult = PumpEnactResult(injector).success(true)
override fun cancelExtendedBolus(): PumpEnactResult = PumpEnactResult(injector).success(true)
override fun getJSONStatus(profile: Profile, profileName: String, version: String): JSONObject = JSONObject()
override fun manufacturer(): ManufacturerType = ManufacturerType.AAPS
override fun model(): PumpType = PumpType.GENERIC_AAPS
override fun serialNumber(): String = "1"
override fun shortStatus(veryShort: Boolean): String = ""
override val isFakingTempsByExtendedBoluses: Boolean = false
override fun loadTDDs(): PumpEnactResult = PumpEnactResult(injector).success(true)
override fun canHandleDST(): Boolean = true
override fun timezoneOrDSTChanged(timeChangeType: TimeChangeType) {}
}

View file

@ -1,38 +1,39 @@
package info.nightscout.androidaps.plugins.general.smsCommunicator
package info.nightscout.plugins.general.smsCommunicator
import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.TestBase
import info.nightscout.androidaps.data.Sms
import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePassword
import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePasswordValidationResult
import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.interfaces.SmsCommunicator
import info.nightscout.plugins.general.smsCommunicator.otp.OneTimePassword
import info.nightscout.plugins.general.smsCommunicator.otp.OneTimePasswordValidationResult
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.plugins.R
import org.junit.Assert
import org.junit.Before
import org.junit.Test
import org.mockito.Mock
import org.mockito.Mockito.`when`
import org.mockito.Mockito.doAnswer
import org.mockito.Mockito.`when`
import org.mockito.invocation.InvocationOnMock
import org.mockito.stubbing.Answer
class AuthRequestTest : TestBase() {
@Mock lateinit var smsCommunicatorPlugin: SmsCommunicatorPlugin
@Mock lateinit var smsCommunicator: SmsCommunicator
@Mock lateinit var rh: ResourceHelper
@Mock lateinit var otp: OneTimePassword
@Mock lateinit var dateUtil: DateUtil
var injector: HasAndroidInjector = HasAndroidInjector {
private var injector: HasAndroidInjector = HasAndroidInjector {
AndroidInjector {
if (it is AuthRequest) {
it.aapsLogger = aapsLogger
it.rh = rh
it.smsCommunicatorPlugin = smsCommunicatorPlugin
it.smsCommunicator = smsCommunicator
it.otp = otp
it.dateUtil = dateUtil
}
@ -43,11 +44,11 @@ class AuthRequestTest : TestBase() {
private var actionCalled = false
@Before fun prepareTests() {
`when`(rh.gs(R.string.sms_wrongcode)).thenReturn("Wrong code. Command cancelled.")
`when`(rh.gs(R.string.sms_wrong_code)).thenReturn("Wrong code. Command cancelled.")
doAnswer(Answer { invocation: InvocationOnMock ->
sentSms = invocation.getArgument(0)
null
} as Answer<*>).`when`(smsCommunicatorPlugin).sendSMS(anyObject())
} as Answer<*>).`when`(smsCommunicator).sendSMS(anyObject())
}
@Test fun doTests() {

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.plugins.general.smsCommunicator
package info.nightscout.plugins.general.smsCommunicator
import org.junit.Assert
import org.junit.Test

View file

@ -1,11 +1,12 @@
package info.nightscout.androidaps.plugins.general.smsCommunicator
package info.nightscout.plugins.general.smsCommunicator
import android.telephony.SmsManager
import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.plugins.R
import info.nightscout.androidaps.TestBaseWithProfile
import info.nightscout.androidaps.TestPumpPlugin
import info.nightscout.androidaps.data.IobTotal
import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.data.Sms
@ -17,16 +18,13 @@ import info.nightscout.androidaps.database.transactions.InsertAndCancelCurrentTe
import info.nightscout.androidaps.database.transactions.Transaction
import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePassword
import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePasswordValidationResult
import info.nightscout.plugins.general.smsCommunicator.otp.OneTimePassword
import info.nightscout.plugins.general.smsCommunicator.otp.OneTimePasswordValidationResult
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensDataStore
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.CobInfo
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.T
@ -52,9 +50,9 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
@Mock lateinit var constraintChecker: ConstraintChecker
@Mock lateinit var activePlugin: ActivePlugin
@Mock lateinit var commandQueue: CommandQueue
@Mock lateinit var loop: LoopPlugin
@Mock lateinit var virtualPumpPlugin: VirtualPumpPlugin
@Mock lateinit var localProfilePlugin: LocalProfilePlugin
@Mock lateinit var loop: Loop
@Mock lateinit var testPumpPlugin: TestPumpPlugin
@Mock lateinit var profileSource: ProfileSource
@Mock lateinit var otp: OneTimePassword
@Mock lateinit var xDripBroadcast: XDripBroadcast
@Mock lateinit var uel: UserEntryLogger
@ -70,7 +68,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
}
if (it is AuthRequest) {
it.aapsLogger = aapsLogger
it.smsCommunicatorPlugin = smsCommunicatorPlugin
it.smsCommunicator = smsCommunicatorPlugin
it.rh = rh
it.otp = otp
it.dateUtil = dateUtil
@ -147,17 +145,17 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
null
}.`when`(commandQueue).extendedBolus(ArgumentMatchers.anyDouble(), ArgumentMatchers.anyInt(), ArgumentMatchers.any(Callback::class.java))
`when`(activePlugin.activePump).thenReturn(virtualPumpPlugin)
`when`(activePlugin.activePump).thenReturn(testPumpPlugin)
`when`(virtualPumpPlugin.shortStatus(ArgumentMatchers.anyBoolean())).thenReturn("Virtual Pump")
`when`(virtualPumpPlugin.isSuspended()).thenReturn(false)
`when`(virtualPumpPlugin.pumpDescription).thenReturn(PumpDescription())
`when`(virtualPumpPlugin.model()).thenReturn(PumpType.GENERIC_AAPS)
`when`(testPumpPlugin.shortStatus(ArgumentMatchers.anyBoolean())).thenReturn("Virtual Pump")
`when`(testPumpPlugin.isSuspended()).thenReturn(false)
`when`(testPumpPlugin.pumpDescription).thenReturn(PumpDescription())
`when`(testPumpPlugin.model()).thenReturn(PumpType.GENERIC_AAPS)
`when`(iobCobCalculator.calculateIobFromBolus()).thenReturn(IobTotal(0))
`when`(iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended()).thenReturn(IobTotal(0))
`when`(activePlugin.activeProfileSource).thenReturn(localProfilePlugin)
`when`(activePlugin.activeProfileSource).thenReturn(profileSource)
`when`(profileFunction.getUnits()).thenReturn(GlucoseUnit.MGDL)
@ -165,23 +163,24 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
`when`(otp.checkOTP(anyString())).thenReturn(OneTimePasswordValidationResult.OK)
`when`(rh.gs(R.string.smscommunicator_remotecommandnotallowed)).thenReturn("Remote command is not allowed")
`when`(rh.gs(R.string.sms_wrongcode)).thenReturn("Wrong code. Command cancelled.")
`when`(rh.gs(R.string.sms_wrong_code)).thenReturn("Wrong code. Command cancelled.")
`when`(rh.gs(R.string.sms_iob)).thenReturn("IOB:")
`when`(rh.gs(R.string.sms_lastbg)).thenReturn("Last BG:")
`when`(rh.gs(R.string.sms_minago)).thenReturn("%1\$dmin ago")
`when`(rh.gs(R.string.sms_last_bg)).thenReturn("Last BG:")
`when`(rh.gs(R.string.sms_min_ago)).thenReturn("%1\$dmin ago")
`when`(rh.gs(R.string.smscommunicator_remotecommandnotallowed)).thenReturn("Remote command is not allowed")
`when`(rh.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`(rh.gs(R.string.smscommunicator_mealbolusreplywithcode)).thenReturn("To deliver meal bolus %1$.2fU reply with code %2\$s.")
`when`(rh.gs(R.string.smscommunicator_meal_bolus_reply_with_code)).thenReturn("To deliver meal bolus %1$.2fU reply with code %2\$s.")
`when`(rh.gs(R.string.smscommunicator_temptargetwithcode)).thenReturn("To set the Temp Target %1\$s reply with code %2\$s")
`when`(rh.gs(R.string.smscommunicator_temptargetcancel)).thenReturn("To cancel Temp Target reply with code %1\$s")
`when`(rh.gs(R.string.smscommunicator_stoppedsms)).thenReturn("SMS Remote Service stopped. To reactivate it, use AAPS on master smartphone.")
`when`(rh.gs(R.string.smscommunicator_tt_set)).thenReturn("Target %1\$s for %2\$d minutes set successfully")
`when`(rh.gs(R.string.smscommunicator_tt_canceled)).thenReturn("Temp Target canceled successfully")
`when`(rh.gs(R.string.loopsuspendedfor)).thenReturn("Suspended (%1\$d m)")
`when`(rh.gs(R.string.sms_loop_suspended_for)).thenReturn("Suspended (%1\$d m)")
`when`(rh.gs(R.string.loopisdisabled)).thenReturn("Loop is disabled")
`when`(rh.gs(R.string.smscommunicator_loopisenabled)).thenReturn("Loop is enabled")
`when`(rh.gs(R.string.wrongformat)).thenReturn("Wrong format")
`when`(rh.gs(eq(R.string.wrongTbrDuration), ArgumentMatchers.any())).thenAnswer { i: InvocationOnMock -> "TBR duration must be a multiple of " + i.arguments[1] + " minutes and greater than 0." }
`when`(rh.gs(R.string.wrong_format)).thenReturn("Wrong format")
`when`(rh.gs(eq(R.string.sms_wrong_tbr_duration), ArgumentMatchers.any())).thenAnswer { i: InvocationOnMock -> "TBR duration must be a multiple of " + i.arguments[1] + " minutes and greater than " +
"0." }
`when`(rh.gs(R.string.smscommunicator_loophasbeendisabled)).thenReturn("Loop has been disabled")
`when`(rh.gs(R.string.smscommunicator_loophasbeenenabled)).thenReturn("Loop has been enabled")
`when`(rh.gs(R.string.smscommunicator_tempbasalcanceled)).thenReturn("Temp basal canceled")
@ -192,7 +191,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
`when`(rh.gs(R.string.smscommunicator_unknowncommand)).thenReturn("Unknown command or wrong reply")
`when`(rh.gs(R.string.notconfigured)).thenReturn("Not configured")
`when`(rh.gs(R.string.smscommunicator_profilereplywithcode)).thenReturn("To switch profile to %1\$s %2\$d%% reply with code %3\$s")
`when`(rh.gs(R.string.profileswitchcreated)).thenReturn("Profile switch created")
`when`(rh.gs(R.string.sms_profile_switch_created)).thenReturn("Profile switch created")
`when`(rh.gs(R.string.smscommunicator_basalstopreplywithcode)).thenReturn("To stop temp basal reply with code %1\$s")
`when`(rh.gs(R.string.smscommunicator_basalpctreplywithcode)).thenReturn("To start basal %1\$d%% for %2\$d min reply with code %3\$s")
`when`(rh.gs(R.string.smscommunicator_tempbasalset_percent)).thenReturn("Temp basal %1\$d%% for %2\$d min started successfully")
@ -202,7 +201,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
`when`(rh.gs(R.string.smscommunicator_extendedcanceled)).thenReturn("Extended bolus canceled")
`when`(rh.gs(R.string.smscommunicator_extendedreplywithcode)).thenReturn("To start extended bolus %1$.2fU for %2\$d min reply with code %3\$s")
`when`(rh.gs(R.string.smscommunicator_extendedset)).thenReturn("Extended bolus %1$.2fU for %2\$d min started successfully")
`when`(rh.gs(R.string.smscommunicator_bolusreplywithcode)).thenReturn("To deliver bolus %1$.2fU reply with code %2\$s")
`when`(rh.gs(R.string.smscommunicator_bolus_reply_with_code)).thenReturn("To deliver bolus %1$.2fU reply with code %2\$s")
`when`(rh.gs(R.string.smscommunicator_bolusdelivered)).thenReturn("Bolus %1$.2fU delivered successfully")
`when`(rh.gs(R.string.smscommunicator_remotebolusnotallowed)).thenReturn("Remote bolus not available. Try again later.")
`when`(rh.gs(R.string.smscommunicator_calibrationreplywithcode)).thenReturn("To send calibration %1$.2f reply with code %2\$s")
@ -217,8 +216,8 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
`when`(rh.gs(R.string.cob)).thenReturn("COB")
`when`(rh.gs(R.string.smscommunicator_mealbolusdelivered)).thenReturn("Meal Bolus %1\$.2fU delivered successfully")
`when`(rh.gs(R.string.smscommunicator_mealbolusdelivered_tt)).thenReturn("Target %1\$s for %2\$d minutes")
`when`(rh.gs(R.string.sms_actualbg)).thenReturn("BG:")
`when`(rh.gs(R.string.sms_lastbg)).thenReturn("Last BG:")
`when`(rh.gs(R.string.sms_actual_bg)).thenReturn("BG:")
`when`(rh.gs(R.string.sms_last_bg)).thenReturn("Last BG:")
`when`(rh.gs(R.string.smscommunicator_loopdisablereplywithcode)).thenReturn("To disable loop reply with code %1\$s")
`when`(rh.gs(R.string.smscommunicator_loopenablereplywithcode)).thenReturn("To enable loop reply with code %1\$s")
`when`(rh.gs(R.string.smscommunicator_loopresumereplywithcode)).thenReturn("To resume loop reply with code %1\$s")
@ -233,7 +232,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
`when`(rh.gs(R.string.sms)).thenReturn("SMS")
`when`(rh.gsNotLocalised(R.string.loopsuspended)).thenReturn("Loop suspended")
`when`(rh.gsNotLocalised(R.string.smscommunicator_stoppedsms)).thenReturn("SMS Remote Service stopped. To reactivate it, use AAPS on master smartphone.")
`when`(rh.gsNotLocalised(R.string.profileswitchcreated)).thenReturn("Profile switch created")
`when`(rh.gsNotLocalised(R.string.sms_profile_switch_created)).thenReturn("Profile switch created")
`when`(rh.gsNotLocalised(R.string.smscommunicator_tempbasalcanceled)).thenReturn("Temp basal canceled")
`when`(rh.gsNotLocalised(R.string.smscommunicator_calibrationsent)).thenReturn("Calibration sent. Receiving must be enabled in xDrip+.")
`when`(rh.gsNotLocalised(R.string.smscommunicator_tt_canceled)).thenReturn("Temp Target canceled successfully")
@ -291,14 +290,14 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
Assert.assertTrue(smsCommunicatorPlugin.messages[1].text.contains("COB: 10(2)g"))
// LOOP : test remote control disabled
`when`(sp.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)).thenReturn(false)
`when`(sp.getBoolean(R.string.key_smscommunicator_remote_commands_allowed, false)).thenReturn(false)
smsCommunicatorPlugin.messages = ArrayList()
sms = Sms("1234", "LOOP STATUS")
smsCommunicatorPlugin.processSms(sms)
Assert.assertFalse(sms.ignored)
Assert.assertEquals("LOOP STATUS", smsCommunicatorPlugin.messages[0].text)
Assert.assertTrue(smsCommunicatorPlugin.messages[1].text.contains("Remote command is not allowed"))
`when`(sp.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)).thenReturn(true)
`when`(sp.getBoolean(R.string.key_smscommunicator_remote_commands_allowed, false)).thenReturn(true)
//LOOP STATUS : disabled
`when`(loop.enabled).thenReturn(false)
@ -470,7 +469,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
Assert.assertEquals("Wrong format", smsCommunicatorPlugin.messages[1].text)
//NSCLIENT RESTART
`when`((loop as PluginBase).isEnabled()).thenReturn(true)
`when`(loop.isEnabled()).thenReturn(true)
`when`(loop.isSuspended).thenReturn(false)
smsCommunicatorPlugin.messages = ArrayList()
sms = Sms("1234", "NSCLIENT RESTART")
@ -480,7 +479,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
Assert.assertTrue(smsCommunicatorPlugin.messages[1].text.contains("NSCLIENT RESTART"))
//NSCLIENT BLA BLA
`when`((loop as PluginBase).isEnabled()).thenReturn(true)
`when`(loop.isEnabled()).thenReturn(true)
`when`(loop.isSuspended).thenReturn(false)
smsCommunicatorPlugin.messages = ArrayList()
sms = Sms("1234", "NSCLIENT BLA BLA")
@ -490,7 +489,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
Assert.assertEquals("Wrong format", smsCommunicatorPlugin.messages[1].text)
//NSCLIENT BLABLA
`when`((loop as PluginBase).isEnabled()).thenReturn(true)
`when`(loop.isEnabled()).thenReturn(true)
`when`(loop.isSuspended).thenReturn(false)
smsCommunicatorPlugin.messages = ArrayList()
sms = Sms("1234", "NSCLIENT BLABLA")
@ -651,7 +650,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
smsCommunicatorPlugin.processSms(sms)
Assert.assertEquals("PROFILE", smsCommunicatorPlugin.messages[0].text)
Assert.assertEquals("Remote command is not allowed", smsCommunicatorPlugin.messages[1].text)
`when`(sp.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)).thenReturn(true)
`when`(sp.getBoolean(R.string.key_smscommunicator_remote_commands_allowed, false)).thenReturn(true)
//PROFILE
smsCommunicatorPlugin.messages = ArrayList()
@ -667,7 +666,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
Assert.assertEquals("PROFILE LIST", smsCommunicatorPlugin.messages[0].text)
Assert.assertEquals("Not configured", smsCommunicatorPlugin.messages[1].text)
`when`(localProfilePlugin.profile).thenReturn(getValidProfileStore())
`when`(profileSource.profile).thenReturn(getValidProfileStore())
`when`(profileFunction.getProfileName()).thenReturn(TESTPROFILENAME)
//PROFILE STATUS
@ -733,7 +732,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
smsCommunicatorPlugin.processSms(sms)
Assert.assertEquals("BASAL", smsCommunicatorPlugin.messages[0].text)
Assert.assertEquals("Remote command is not allowed", smsCommunicatorPlugin.messages[1].text)
`when`(sp.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)).thenReturn(true)
`when`(sp.getBoolean(R.string.key_smscommunicator_remote_commands_allowed, false)).thenReturn(true)
//BASAL
smsCommunicatorPlugin.messages = ArrayList()
@ -830,7 +829,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
smsCommunicatorPlugin.processSms(sms)
Assert.assertEquals("EXTENDED", smsCommunicatorPlugin.messages[0].text)
Assert.assertEquals("Remote command is not allowed", smsCommunicatorPlugin.messages[1].text)
`when`(sp.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)).thenReturn(true)
`when`(sp.getBoolean(R.string.key_smscommunicator_remote_commands_allowed, false)).thenReturn(true)
//EXTENDED
smsCommunicatorPlugin.messages = ArrayList()
@ -885,7 +884,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
smsCommunicatorPlugin.processSms(sms)
Assert.assertEquals("BOLUS", smsCommunicatorPlugin.messages[0].text)
Assert.assertEquals("Remote command is not allowed", smsCommunicatorPlugin.messages[1].text)
`when`(sp.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)).thenReturn(true)
`when`(sp.getBoolean(R.string.key_smscommunicator_remote_commands_allowed, false)).thenReturn(true)
//BOLUS
smsCommunicatorPlugin.messages = ArrayList()
@ -895,7 +894,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
Assert.assertEquals("Wrong format", smsCommunicatorPlugin.messages[1].text)
`when`(constraintChecker.applyBolusConstraints(anyObject())).thenReturn(Constraint(1.0))
`when`(dateUtilMocked.now()).thenReturn(1000L)
`when`(sp.getLong(R.string.key_smscommunicator_remotebolusmindistance, T.msecs(Constants.remoteBolusMinDistance).mins())).thenReturn(15L)
`when`(sp.getLong(R.string.key_smscommunicator_remote_bolus_min_distance, T.msecs(Constants.remoteBolusMinDistance).mins())).thenReturn(15L)
//BOLUS 1
smsCommunicatorPlugin.messages = ArrayList()
sms = Sms("1234", "BOLUS 1")
@ -934,13 +933,13 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
//BOLUS 1 (Suspended pump)
smsCommunicatorPlugin.lastRemoteBolusTime = 0
`when`(virtualPumpPlugin.isSuspended()).thenReturn(true)
`when`(testPumpPlugin.isSuspended()).thenReturn(true)
smsCommunicatorPlugin.messages = ArrayList()
sms = Sms("1234", "BOLUS 1")
smsCommunicatorPlugin.processSms(sms)
Assert.assertEquals("BOLUS 1", smsCommunicatorPlugin.messages[0].text)
Assert.assertEquals("Pump suspended", smsCommunicatorPlugin.messages[1].text)
`when`(virtualPumpPlugin.isSuspended()).thenReturn(false)
`when`(testPumpPlugin.isSuspended()).thenReturn(false)
//BOLUS 1 a
smsCommunicatorPlugin.messages = ArrayList()
@ -970,7 +969,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
smsCommunicatorPlugin.processSms(sms)
Assert.assertEquals("CAL", smsCommunicatorPlugin.messages[0].text)
Assert.assertEquals("Remote command is not allowed", smsCommunicatorPlugin.messages[1].text)
`when`(sp.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)).thenReturn(true)
`when`(sp.getBoolean(R.string.key_smscommunicator_remote_commands_allowed, false)).thenReturn(true)
//CAL
smsCommunicatorPlugin.messages = ArrayList()
@ -1001,14 +1000,14 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
@Test fun processCarbsTest() {
`when`(dateUtilMocked.now()).thenReturn(1000000L)
`when`(dateUtilMocked.timeString(anyLong())).thenReturn("03:01AM")
`when`(sp.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)).thenReturn(false)
`when`(sp.getBoolean(R.string.key_smscommunicator_remote_commands_allowed, false)).thenReturn(false)
//CAL
smsCommunicatorPlugin.messages = ArrayList()
var sms = Sms("1234", "CARBS")
smsCommunicatorPlugin.processSms(sms)
Assert.assertEquals("CARBS", smsCommunicatorPlugin.messages[0].text)
Assert.assertEquals("Remote command is not allowed", smsCommunicatorPlugin.messages[1].text)
`when`(sp.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)).thenReturn(true)
`when`(sp.getBoolean(R.string.key_smscommunicator_remote_commands_allowed, false)).thenReturn(true)
//CARBS
smsCommunicatorPlugin.messages = ArrayList()

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.plugins.general.smsCommunicator
package info.nightscout.plugins.general.smsCommunicator
import android.telephony.SmsMessage
import info.nightscout.androidaps.TestBase

View file

@ -21,3 +21,4 @@ include ':graphview'
include ':libraries'
include ':ui'
include ':implementation'
include ':plugins'