DataService refactor

This commit is contained in:
Milos Kozak 2021-01-30 22:34:05 +01:00
parent 0c682cfe95
commit 920cba5219
23 changed files with 836 additions and 622 deletions

View file

@ -136,10 +136,6 @@
android:resource="@xml/filepaths" />
</provider>
<!-- Service processing incomming data -->
<service
android:name=".services.DataService"
android:exported="false" />
<service
android:name=".services.LocationService"
android:exported="false" />

View file

@ -41,6 +41,7 @@ import javax.inject.Singleton
DanaModule::class,
DanaRModule::class,
DanaRSModule::class,
WorkersModule::class,
OHUploaderModule::class
]
)

View file

@ -12,7 +12,6 @@ import info.nightscout.androidaps.plugins.pump.insight.connection_service.Insigh
import info.nightscout.androidaps.plugins.pump.medtronic.service.RileyLinkMedtronicService
import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.service.RileyLinkOmnipodService
import info.nightscout.androidaps.services.AlarmSoundService
import info.nightscout.androidaps.services.DataService
import info.nightscout.androidaps.services.LocationService
@Module
@ -20,7 +19,6 @@ import info.nightscout.androidaps.services.LocationService
abstract class ServicesModule {
@ContributesAndroidInjector abstract fun contributesAlarmSoundService(): AlarmSoundService
@ContributesAndroidInjector abstract fun contributesDataService(): DataService
@ContributesAndroidInjector abstract fun contributesDismissNotificationService(): DismissNotificationService
@ContributesAndroidInjector abstract fun contributesDummyService(): DummyService
@ContributesAndroidInjector abstract fun contributesLocationService(): LocationService

View file

@ -0,0 +1,25 @@
package info.nightscout.androidaps.dependencyInjection
import dagger.Module
import dagger.android.ContributesAndroidInjector
import info.nightscout.androidaps.plugins.general.nsclient.NSClientWorker
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin
import info.nightscout.androidaps.plugins.profile.ns.NSProfilePlugin
import info.nightscout.androidaps.plugins.source.*
@Module
@Suppress("unused")
abstract class WorkersModule {
@ContributesAndroidInjector abstract fun contributesXdripWorker(): XdripPlugin.XdripWorker
@ContributesAndroidInjector abstract fun contributesDexcomWorker(): DexcomPlugin.DexcomWorker
@ContributesAndroidInjector abstract fun contributesMM640gWorker(): MM640gPlugin.MM640gWorker
@ContributesAndroidInjector abstract fun contributesGlimpWorker(): GlimpPlugin.GlimpWorker
@ContributesAndroidInjector abstract fun contributesPoctechWorker(): PoctechPlugin.PoctechWorker
@ContributesAndroidInjector abstract fun contributesTomatoWorker(): TomatoPlugin.TomatoWorker
@ContributesAndroidInjector abstract fun contributesEversenseWorker(): EversensePlugin.EversenseWorker
@ContributesAndroidInjector abstract fun contributesNSClientSourceWorker(): NSClientSourcePlugin.NSClientSourceWorker
@ContributesAndroidInjector abstract fun contributesNSProfileWorker(): NSProfilePlugin.NSProfileWorker
@ContributesAndroidInjector abstract fun contributesSmsCommunicatorWorker(): SmsCommunicatorPlugin.SmsCommunicatorWorker
@ContributesAndroidInjector abstract fun contributesNSClientWorker(): NSClientWorker
}

View file

@ -4,6 +4,7 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
@ -13,6 +14,9 @@ import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.SwitchPreference;
import org.jetbrains.annotations.NotNull;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
@ -23,11 +27,15 @@ import javax.inject.Singleton;
import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.events.EventAppExit;
import info.nightscout.androidaps.events.EventChargingState;
import info.nightscout.androidaps.events.EventNetworkChange;
import info.nightscout.androidaps.events.EventNsTreatment;
import info.nightscout.androidaps.events.EventPreferenceChange;
import info.nightscout.androidaps.interfaces.ActivePluginProvider;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.PluginDescription;
import info.nightscout.androidaps.interfaces.PluginType;
@ -36,13 +44,18 @@ import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
import info.nightscout.androidaps.plugins.general.nsclient.data.AlarmAck;
import info.nightscout.androidaps.plugins.general.nsclient.data.NSAlarm;
import info.nightscout.androidaps.plugins.general.nsclient.data.NSMbg;
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientNewLog;
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientResend;
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientStatus;
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientUpdateGUI;
import info.nightscout.androidaps.plugins.general.nsclient.services.NSClientService;
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification;
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
import info.nightscout.androidaps.services.Intents;
import info.nightscout.androidaps.utils.FabricPrivacy;
import info.nightscout.androidaps.utils.HtmlHelper;
import info.nightscout.androidaps.utils.JsonHelper;
import info.nightscout.androidaps.utils.ToastUtils;
import info.nightscout.androidaps.utils.buildHelper.BuildHelper;
import info.nightscout.androidaps.utils.resources.ResourceHelper;
@ -62,6 +75,8 @@ public class NSClientPlugin extends PluginBase {
private final SP sp;
private final Config config;
private final BuildHelper buildHelper;
private final ActivePluginProvider activePlugin;
private final NSUpload nsUpload;
public Handler handler;
@ -88,7 +103,9 @@ public class NSClientPlugin extends PluginBase {
SP sp,
NsClientReceiverDelegate nsClientReceiverDelegate,
Config config,
BuildHelper buildHelper
BuildHelper buildHelper,
ActivePluginProvider activePlugin,
NSUpload nsUpload
) {
super(new PluginDescription()
.mainType(PluginType.GENERAL)
@ -110,6 +127,8 @@ public class NSClientPlugin extends PluginBase {
this.nsClientReceiverDelegate = nsClientReceiverDelegate;
this.config = config;
this.buildHelper = buildHelper;
this.activePlugin = activePlugin;
this.nsUpload = nsUpload;
if (config.getNSCLIENT()) {
getPluginDescription().alwaysEnabled(true).visibleByDefault(true);
@ -310,4 +329,143 @@ public class NSClientPlugin extends PluginBase {
nsClientService.sendAlarmAck(ack);
}
// Parsing input data
public void handleNewDataFromNSClient(String action, Bundle bundle) {
boolean acceptNSData = !sp.getBoolean(R.string.key_ns_upload_only, true) && buildHelper.isEngineeringMode() || config.getNSCLIENT();
if (!acceptNSData) return;
aapsLogger.debug(LTag.DATASERVICE, "Got intent: " + action);
if (action.equals(Intents.ACTION_NEW_TREATMENT) || action.equals(Intents.ACTION_CHANGED_TREATMENT)) {
try {
if (bundle.containsKey("treatment")) {
JSONObject json = new JSONObject(bundle.getString("treatment"));
handleTreatmentFromNS(json, action);
}
if (bundle.containsKey("treatments")) {
String trstring = bundle.getString("treatments");
JSONArray jsonArray = new JSONArray(trstring);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject json = jsonArray.getJSONObject(i);
handleTreatmentFromNS(json, action);
}
}
} catch (JSONException e) {
aapsLogger.error(LTag.DATASERVICE, "Unhandled exception", e);
}
}
if (action.equals(Intents.ACTION_REMOVED_TREATMENT)) {
try {
if (bundle.containsKey("treatment")) {
String trstring = bundle.getString("treatment");
JSONObject json = new JSONObject(trstring);
handleRemovedTreatmentFromNS(json);
}
if (bundle.containsKey("treatments")) {
String trstring = bundle.getString("treatments");
JSONArray jsonArray = new JSONArray(trstring);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject json = jsonArray.getJSONObject(i);
handleRemovedTreatmentFromNS(json);
}
}
} catch (JSONException e) {
aapsLogger.error(LTag.DATASERVICE, "Unhandled exception", e);
}
}
if (action.equals(Intents.ACTION_NEW_MBG)) {
try {
if (bundle.containsKey("mbg")) {
String mbgstring = bundle.getString("mbg");
JSONObject mbgJson = new JSONObject(mbgstring);
storeMbg(mbgJson);
}
if (bundle.containsKey("mbgs")) {
String sgvstring = bundle.getString("mbgs");
JSONArray jsonArray = new JSONArray(sgvstring);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject mbgJson = jsonArray.getJSONObject(i);
storeMbg(mbgJson);
}
}
} catch (Exception e) {
aapsLogger.error(LTag.DATASERVICE, "Unhandled exception", e);
}
}
}
private void handleRemovedTreatmentFromNS(JSONObject json) {
// new DB model
EventNsTreatment evtTreatment = new EventNsTreatment(EventNsTreatment.Companion.getREMOVE(), json);
rxBus.send(evtTreatment);
// old DB model
String _id = JsonHelper.safeGetString(json, "_id");
MainApp.getDbHelper().deleteTempTargetById(_id);
MainApp.getDbHelper().deleteTempBasalById(_id);
MainApp.getDbHelper().deleteExtendedBolusById(_id);
MainApp.getDbHelper().deleteCareportalEventById(_id);
MainApp.getDbHelper().deleteProfileSwitchById(_id);
}
private void handleTreatmentFromNS(JSONObject json, String action) {
// new DB model
int mode = Intents.ACTION_NEW_TREATMENT.equals(action) ? EventNsTreatment.Companion.getADD() : EventNsTreatment.Companion.getUPDATE();
double insulin = JsonHelper.safeGetDouble(json, "insulin");
double carbs = JsonHelper.safeGetDouble(json, "carbs");
String eventType = JsonHelper.safeGetString(json, "eventType");
if (eventType == null) {
aapsLogger.debug(LTag.DATASERVICE, "Wrong treatment. Ignoring : " + json.toString());
return;
}
if (insulin > 0 || carbs > 0) {
EventNsTreatment evtTreatment = new EventNsTreatment(mode, json);
rxBus.send(evtTreatment);
} else if (eventType.equals(CareportalEvent.TEMPORARYTARGET)) {
MainApp.getDbHelper().createTemptargetFromJsonIfNotExists(json);
} else if (eventType.equals(CareportalEvent.TEMPBASAL)) {
MainApp.getDbHelper().createTempBasalFromJsonIfNotExists(json);
} else if (eventType.equals(CareportalEvent.COMBOBOLUS)) {
MainApp.getDbHelper().createExtendedBolusFromJsonIfNotExists(json);
} else if (eventType.equals(CareportalEvent.PROFILESWITCH)) {
MainApp.getDbHelper().createProfileSwitchFromJsonIfNotExists(activePlugin, nsUpload, json);
} else if (eventType.equals(CareportalEvent.SITECHANGE) ||
eventType.equals(CareportalEvent.INSULINCHANGE) ||
eventType.equals(CareportalEvent.SENSORCHANGE) ||
eventType.equals(CareportalEvent.BGCHECK) ||
eventType.equals(CareportalEvent.NOTE) ||
eventType.equals(CareportalEvent.NONE) ||
eventType.equals(CareportalEvent.ANNOUNCEMENT) ||
eventType.equals(CareportalEvent.QUESTION) ||
eventType.equals(CareportalEvent.EXERCISE) ||
eventType.equals(CareportalEvent.OPENAPSOFFLINE) ||
eventType.equals(CareportalEvent.PUMPBATTERYCHANGE)) {
MainApp.getDbHelper().createCareportalEventFromJsonIfNotExists(json);
}
if (eventType.equals(CareportalEvent.ANNOUNCEMENT)) {
long date = JsonHelper.safeGetLong(json, "mills");
long now = System.currentTimeMillis();
String enteredBy = JsonHelper.safeGetString(json, "enteredBy", "");
String notes = JsonHelper.safeGetString(json, "notes", "");
if (date > now - 15 * 60 * 1000L && !notes.isEmpty()
&& !enteredBy.equals(sp.getString("careportal_enteredby", "AndroidAPS"))) {
boolean defaultVal = config.getNSCLIENT();
if (sp.getBoolean(R.string.key_ns_announcements, defaultVal)) {
Notification announcement = new Notification(Notification.NSANNOUNCEMENT, notes, Notification.ANNOUNCEMENT, 60);
rxBus.send(new EventNewNotification(announcement));
}
}
}
}
private void storeMbg(JSONObject mbgJson) {
NSMbg nsMbg = new NSMbg(mbgJson);
CareportalEvent careportalEvent = new CareportalEvent(nsMbg);
MainApp.getDbHelper().createOrUpdate(careportalEvent);
aapsLogger.debug(LTag.DATASERVICE, "Adding/Updating new MBG: " + careportalEvent.toString());
}
}

View file

@ -0,0 +1,39 @@
package info.nightscout.androidaps.plugins.general.nsclient;
import android.content.Context;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.work.Worker;
import androidx.work.WorkerParameters;
import com.google.gson.Gson;
import org.jetbrains.annotations.NotNull;
import javax.inject.Inject;
import dagger.android.HasAndroidInjector;
// cannot be inner class because of needed injection
public class NSClientWorker extends Worker {
public NSClientWorker(
@NonNull Context context,
@NonNull WorkerParameters params) {
super(context, params);
((HasAndroidInjector) context.getApplicationContext()).androidInjector().inject(this);
}
@Inject NSClientPlugin nsClientPlugin;
@NotNull
@Override
public Result doWork() {
Bundle bundle = new Gson().fromJson(getInputData().getString("data"), Bundle.class);
String action = getInputData().getString("action");
nsClientPlugin.handleNewDataFromNSClient(action, bundle);
return Result.success();
}
}

View file

@ -1,18 +1,24 @@
package info.nightscout.androidaps.plugins.general.smsCommunicator
import android.content.Intent
import android.content.Context
import android.os.Bundle
import android.telephony.SmsManager
import android.telephony.SmsMessage
import android.text.TextUtils
import androidx.preference.EditTextPreference
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import androidx.work.Worker
import androidx.work.WorkerParameters
import com.google.gson.Gson
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Config
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.db.BgReading
import info.nightscout.androidaps.db.Source
import info.nightscout.androidaps.db.TempTarget
import info.nightscout.androidaps.events.EventPreferenceChange
@ -23,6 +29,7 @@ import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
@ -30,6 +37,7 @@ import info.nightscout.androidaps.plugins.general.smsCommunicator.events.EventSm
import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePassword
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.plugins.source.PoctechPlugin
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.utils.*
@ -40,6 +48,8 @@ import info.nightscout.androidaps.utils.textValidator.ValidatingEditTextPreferen
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers
import org.apache.commons.lang3.StringUtils
import org.json.JSONArray
import org.json.JSONException
import java.text.Normalizer
import java.util.*
import javax.inject.Inject
@ -151,6 +161,30 @@ class SmsCommunicatorPlugin @Inject constructor(
}
}
// cannot be inner class because of needed injection
class SmsCommunicatorWorker(
context: Context,
params: WorkerParameters
) : Worker(context, params) {
@Inject lateinit var smsCommunicatorPlugin: SmsCommunicatorPlugin
init {
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
}
override fun doWork(): Result {
val bundle = Gson().fromJson(inputData.getString("data"), Bundle::class.java)
val format = bundle.getString("format") ?: return Result.failure()
val pdus = bundle["pdus"] as Array<*>
for (pdu in pdus) {
val message = SmsMessage.createFromPdu(pdu as ByteArray, format)
smsCommunicatorPlugin.processSms(Sms(message))
}
return Result.success()
}
}
private fun processSettings(ev: EventPreferenceChange?) {
if (ev == null || ev.isChanged(resourceHelper, R.string.key_smscommunicator_allowednumbers)) {
val settings = sp.getString(R.string.key_smscommunicator_allowednumbers, "")
@ -179,16 +213,6 @@ class SmsCommunicatorPlugin @Inject constructor(
return false
}
fun handleNewData(intent: Intent) {
val bundle = intent.extras ?: return
val format = bundle.getString("format") ?: return
val pdus = bundle["pdus"] as Array<*>
for (pdu in pdus) {
val message = SmsMessage.createFromPdu(pdu as ByteArray, format)
processSms(Sms(message))
}
}
fun processSms(receivedSms: Sms) {
if (!isEnabled(PluginType.GENERAL)) {
aapsLogger.debug(LTag.SMS, "Ignoring SMS. Plugin disabled.")
@ -214,58 +238,58 @@ class SmsCommunicatorPlugin @Inject constructor(
if (splitted.isNotEmpty() && isCommand(splitted[0].toUpperCase(Locale.getDefault()), receivedSms.phoneNumber)) {
when (splitted[0].toUpperCase(Locale.getDefault())) {
"BG" ->
"BG" ->
if (splitted.size == 1) processBG(receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat)))
"LOOP" ->
"LOOP" ->
if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.smscommunicator_remotecommandnotallowed)))
else if (splitted.size == 2 || splitted.size == 3) processLOOP(splitted, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat)))
"TREATMENTS" ->
if (splitted.size == 2) processTREATMENTS(splitted, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat)))
"NSCLIENT" ->
"NSCLIENT" ->
if (splitted.size == 2) processNSCLIENT(splitted, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat)))
"PUMP" ->
"PUMP" ->
if (!remoteCommandsAllowed && splitted.size > 1) sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.smscommunicator_remotecommandnotallowed)))
else if (splitted.size <= 3) processPUMP(splitted, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat)))
"PROFILE" ->
"PROFILE" ->
if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.smscommunicator_remotecommandnotallowed)))
else if (splitted.size == 2 || splitted.size == 3) processPROFILE(splitted, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat)))
"BASAL" ->
"BASAL" ->
if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.smscommunicator_remotecommandnotallowed)))
else if (splitted.size == 2 || splitted.size == 3) processBASAL(splitted, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat)))
"EXTENDED" ->
"EXTENDED" ->
if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.smscommunicator_remotecommandnotallowed)))
else if (splitted.size == 2 || splitted.size == 3) processEXTENDED(splitted, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat)))
"BOLUS" ->
"BOLUS" ->
if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.smscommunicator_remotecommandnotallowed)))
else if (splitted.size == 2 && DateUtil.now() - lastRemoteBolusTime < minDistance) sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.smscommunicator_remotebolusnotallowed)))
else if (splitted.size == 2 && pump.isSuspended) sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.pumpsuspended)))
else if (splitted.size == 2 || splitted.size == 3) processBOLUS(splitted, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat)))
"CARBS" ->
"CARBS" ->
if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.smscommunicator_remotecommandnotallowed)))
else if (splitted.size == 2 || splitted.size == 3) processCARBS(splitted, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat)))
"CAL" ->
"CAL" ->
if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.smscommunicator_remotecommandnotallowed)))
else if (splitted.size == 2) processCAL(splitted, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat)))
"TARGET" ->
"TARGET" ->
if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.smscommunicator_remotecommandnotallowed)))
else if (splitted.size == 2) processTARGET(splitted, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat)))
"SMS" ->
"SMS" ->
if (!remoteCommandsAllowed) sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.smscommunicator_remotecommandnotallowed)))
else if (splitted.size == 2) processSMS(splitted, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat)))
"HELP" ->
"HELP" ->
if (splitted.size == 1 || splitted.size == 2) processHELP(splitted, receivedSms)
else sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat)))
else ->
@ -349,7 +373,7 @@ class SmsCommunicatorPlugin @Inject constructor(
receivedSms.processed = true
}
"STATUS" -> {
"STATUS" -> {
val reply = if (loopPlugin.isEnabled(PluginType.LOOP)) {
if (loopPlugin.isSuspended) String.format(resourceHelper.gs(R.string.loopsuspendedfor), loopPlugin.minutesToEndOfSuspend())
else resourceHelper.gs(R.string.smscommunicator_loopisenabled)
@ -359,7 +383,7 @@ class SmsCommunicatorPlugin @Inject constructor(
receivedSms.processed = true
}
"RESUME" -> {
"RESUME" -> {
val passCode = generatePasscode()
val reply = String.format(resourceHelper.gs(R.string.smscommunicator_loopresumereplywithcode), passCode)
receivedSms.processed = true
@ -383,7 +407,7 @@ class SmsCommunicatorPlugin @Inject constructor(
})
}
"SUSPEND" -> {
"SUSPEND" -> {
var duration = 0
if (splitted.size == 3) duration = SafeParse.stringToInt(splitted[2])
duration = Math.max(0, duration)

View file

@ -1,15 +1,17 @@
package info.nightscout.androidaps.plugins.profile.ns
import android.content.Intent
import android.content.Context
import androidx.work.Worker
import androidx.work.WorkerParameters
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Config
import info.nightscout.androidaps.R
import info.nightscout.androidaps.interfaces.ProfileStore
import info.nightscout.androidaps.events.EventProfileStoreChanged
import info.nightscout.androidaps.interfaces.PluginBase
import info.nightscout.androidaps.interfaces.PluginDescription
import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.interfaces.ProfileInterface
import info.nightscout.androidaps.interfaces.ProfileStore
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
@ -49,21 +51,6 @@ class NSProfilePlugin @Inject constructor(
loadNSProfile()
}
fun handleNewData(intent: Intent) {
val bundles = intent.extras ?: return
@Suppress("SpellCheckingInspection")
val activeProfile = bundles.getString("activeprofile")
val profileString = bundles.getString("profile")
profile = ProfileStore(injector, JSONObject(profileString))
storeNSProfile()
if (isEnabled()) {
rxBus.send(EventProfileStoreChanged())
rxBus.send(EventNSProfileUpdateGUI())
}
aapsLogger.debug(LTag.PROFILE, "Received profileStore: $activeProfile $profile")
}
private fun storeNSProfile() {
sp.putString("profile", profile!!.data.toString())
aapsLogger.debug(LTag.PROFILE, "Storing profile")
@ -90,4 +77,33 @@ class NSProfilePlugin @Inject constructor(
return profile!!.getDefaultProfileName()!!
}
// cannot be inner class because of needed injection
class NSProfileWorker(
context: Context,
params: WorkerParameters
) : Worker(context, params) {
@Inject lateinit var injector: HasAndroidInjector
@Inject lateinit var nsProfilePlugin: NSProfilePlugin
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var rxBus: RxBusWrapper
init {
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
}
override fun doWork(): Result {
inputData.getString("profile")?.let { profileString ->
nsProfilePlugin.profile = ProfileStore(injector, JSONObject(profileString))
nsProfilePlugin.storeNSProfile()
if (nsProfilePlugin.isEnabled()) {
rxBus.send(EventProfileStoreChanged())
rxBus.send(EventNSProfileUpdateGUI())
}
aapsLogger.debug(LTag.PROFILE, "Received profileStore: ${nsProfilePlugin.profile}")
return Result.success()
}
return Result.failure()
}
}
}

View file

@ -1,8 +1,13 @@
package info.nightscout.androidaps.plugins.source
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Bundle
import androidx.core.content.ContextCompat
import androidx.work.Worker
import androidx.work.WorkerParameters
import com.google.gson.Gson
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Config
import info.nightscout.androidaps.Constants
@ -29,11 +34,9 @@ import javax.inject.Singleton
@Singleton
class DexcomPlugin @Inject constructor(
injector: HasAndroidInjector,
private val sp: SP,
private val mainApp: MainApp,
resourceHelper: ResourceHelper,
aapsLogger: AAPSLogger,
private val nsUpload: NSUpload,
config: Config
) : PluginBase(PluginDescription()
.mainType(PluginType.BGSOURCE)
@ -73,80 +76,102 @@ class DexcomPlugin @Inject constructor(
return null
}
override fun handleNewData(intent: Intent) {
if (!isEnabled(PluginType.BGSOURCE)) return
try {
val sensorType = intent.getStringExtra("sensorType") ?: ""
val glucoseValues = intent.getBundleExtra("glucoseValues")
for (i in 0 until glucoseValues.size()) {
glucoseValues.getBundle(i.toString())?.let { glucoseValue ->
val bgReading = BgReading()
bgReading.value = glucoseValue.getInt("glucoseValue").toDouble()
bgReading.direction = glucoseValue.getString("trendArrow")
bgReading.date = glucoseValue.getLong("timestamp") * 1000
bgReading.raw = 0.0
if (MainApp.getDbHelper().createIfNotExists(bgReading, "Dexcom$sensorType")) {
if (sp.getBoolean(R.string.key_dexcomg5_nsupload, false)) {
nsUpload.uploadBg(bgReading, "AndroidAPS-Dexcom$sensorType")
}
if (sp.getBoolean(R.string.key_dexcomg5_xdripupload, false)) {
nsUpload.sendToXdrip(bgReading)
// cannot be inner class because of needed injection
class DexcomWorker(
context: Context,
params: WorkerParameters
) : Worker(context, params) {
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var injector: HasAndroidInjector
@Inject lateinit var dexcomPlugin: DexcomPlugin
@Inject lateinit var nsUpload: NSUpload
@Inject lateinit var sp: SP
init {
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
}
override fun doWork(): Result {
if (!dexcomPlugin.isEnabled(PluginType.BGSOURCE)) return Result.failure()
val action = inputData.getString("action")
val bundle = Gson().fromJson(inputData.getString("data"), Bundle::class.java)
try {
val sensorType = bundle.getString("sensorType") ?: ""
val glucoseValues = bundle.getBundle("glucoseValues") ?: return Result.failure()
for (i in 0 until glucoseValues.size()) {
glucoseValues.getBundle(i.toString())?.let { glucoseValue ->
val bgReading = BgReading()
bgReading.value = glucoseValue.getInt("glucoseValue").toDouble()
bgReading.direction = glucoseValue.getString("trendArrow")
bgReading.date = glucoseValue.getLong("timestamp") * 1000
bgReading.raw = 0.0
if (MainApp.getDbHelper().createIfNotExists(bgReading, "Dexcom$sensorType")) {
if (sp.getBoolean(R.string.key_dexcomg5_nsupload, false)) {
nsUpload.uploadBg(bgReading, "AndroidAPS-Dexcom$sensorType")
}
if (sp.getBoolean(R.string.key_dexcomg5_xdripupload, false)) {
nsUpload.sendToXdrip(bgReading)
}
}
}
}
}
val meters = intent.getBundleExtra("meters")
for (i in 0 until meters.size()) {
val meter = meters.getBundle(i.toString())
meter?.let {
val timestamp = it.getLong("timestamp") * 1000
val now = DateUtil.now()
if (timestamp > now - T.months(1).msecs() && timestamp < now)
if (MainApp.getDbHelper().getCareportalEventFromTimestamp(timestamp) == null) {
val jsonObject = JSONObject()
jsonObject.put("enteredBy", "AndroidAPS-Dexcom$sensorType")
jsonObject.put("created_at", DateUtil.toISOString(timestamp))
jsonObject.put("eventType", CareportalEvent.BGCHECK)
jsonObject.put("glucoseType", "Finger")
jsonObject.put("glucose", meter.getInt("meterValue"))
jsonObject.put("units", Constants.MGDL)
bundle.getBundle("meters")?.let { meters ->
for (i in 0 until meters.size()) {
val meter = meters.getBundle(i.toString())
meter?.let {
val timestamp = it.getLong("timestamp") * 1000
val now = DateUtil.now()
if (timestamp > now - T.months(1).msecs() && timestamp < now)
if (MainApp.getDbHelper().getCareportalEventFromTimestamp(timestamp) == null) {
val jsonObject = JSONObject()
jsonObject.put("enteredBy", "AndroidAPS-Dexcom$sensorType")
jsonObject.put("created_at", DateUtil.toISOString(timestamp))
jsonObject.put("eventType", CareportalEvent.BGCHECK)
jsonObject.put("glucoseType", "Finger")
jsonObject.put("glucose", meter.getInt("meterValue"))
jsonObject.put("units", Constants.MGDL)
val careportalEvent = CareportalEvent(injector)
careportalEvent.date = timestamp
careportalEvent.source = Source.USER
careportalEvent.eventType = CareportalEvent.BGCHECK
careportalEvent.json = jsonObject.toString()
MainApp.getDbHelper().createOrUpdate(careportalEvent)
nsUpload.uploadCareportalEntryToNS(jsonObject)
val careportalEvent = CareportalEvent(injector)
careportalEvent.date = timestamp
careportalEvent.source = Source.USER
careportalEvent.eventType = CareportalEvent.BGCHECK
careportalEvent.json = jsonObject.toString()
MainApp.getDbHelper().createOrUpdate(careportalEvent)
nsUpload.uploadCareportalEntryToNS(jsonObject)
}
}
}
}
}
if (sp.getBoolean(R.string.key_dexcom_lognssensorchange, false) && intent.hasExtra("sensorInsertionTime")) {
intent.extras?.let {
val sensorInsertionTime = it.getLong("sensorInsertionTime") * 1000
val now = DateUtil.now()
if (sensorInsertionTime > now - T.months(1).msecs() && sensorInsertionTime < now)
if (MainApp.getDbHelper().getCareportalEventFromTimestamp(sensorInsertionTime) == null) {
val jsonObject = JSONObject()
jsonObject.put("enteredBy", "AndroidAPS-Dexcom$sensorType")
jsonObject.put("created_at", DateUtil.toISOString(sensorInsertionTime))
jsonObject.put("eventType", CareportalEvent.SENSORCHANGE)
val careportalEvent = CareportalEvent(injector)
careportalEvent.date = sensorInsertionTime
careportalEvent.source = Source.USER
careportalEvent.eventType = CareportalEvent.SENSORCHANGE
careportalEvent.json = jsonObject.toString()
MainApp.getDbHelper().createOrUpdate(careportalEvent)
nsUpload.uploadCareportalEntryToNS(jsonObject)
}
if (sp.getBoolean(R.string.key_dexcom_lognssensorchange, false) && bundle.containsKey("sensorInsertionTime")) {
bundle.let {
val sensorInsertionTime = it.getLong("sensorInsertionTime") * 1000
val now = DateUtil.now()
if (sensorInsertionTime > now - T.months(1).msecs() && sensorInsertionTime < now)
if (MainApp.getDbHelper().getCareportalEventFromTimestamp(sensorInsertionTime) == null) {
val jsonObject = JSONObject()
jsonObject.put("enteredBy", "AndroidAPS-Dexcom$sensorType")
jsonObject.put("created_at", DateUtil.toISOString(sensorInsertionTime))
jsonObject.put("eventType", CareportalEvent.SENSORCHANGE)
val careportalEvent = CareportalEvent(injector)
careportalEvent.date = sensorInsertionTime
careportalEvent.source = Source.USER
careportalEvent.eventType = CareportalEvent.SENSORCHANGE
careportalEvent.json = jsonObject.toString()
MainApp.getDbHelper().createOrUpdate(careportalEvent)
nsUpload.uploadCareportalEntryToNS(jsonObject)
}
}
}
} catch (e: Exception) {
aapsLogger.error("Error while processing intent from Dexcom App", e)
}
} catch (e: Exception) {
aapsLogger.error("Error while processing intent from Dexcom App", e)
return Result.success()
}
}
companion object {
private val PACKAGE_NAMES = arrayOf("com.dexcom.cgm.region1.mgdl", "com.dexcom.cgm.region1.mmol",
"com.dexcom.cgm.region2.mgdl", "com.dexcom.cgm.region2.mmol",
"com.dexcom.g6.region1.mmol", "com.dexcom.g6.region2.mgdl",

View file

@ -1,6 +1,10 @@
package info.nightscout.androidaps.plugins.source
import android.content.Intent
import android.content.Context
import android.os.Bundle
import androidx.work.Worker
import androidx.work.WorkerParameters
import com.google.gson.Gson
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.MainApp
@ -26,11 +30,8 @@ import javax.inject.Singleton
@Singleton
class EversensePlugin @Inject constructor(
injector: HasAndroidInjector,
private val sp: SP,
resourceHelper: ResourceHelper,
aapsLogger: AAPSLogger,
private val dateUtil: DateUtil,
private val nsUpload: NSUpload
aapsLogger: AAPSLogger
) : PluginBase(PluginDescription()
.mainType(PluginType.BGSOURCE)
.fragmentClass(BGSourceFragment::class.java.name)
@ -42,85 +43,96 @@ class EversensePlugin @Inject constructor(
aapsLogger, resourceHelper, injector
), BgSourceInterface {
private var sensorBatteryLevel = -1
override var sensorBatteryLevel = -1
override fun advancedFilteringSupported(): Boolean {
return false
}
// cannot be inner class because of needed injection
class EversenseWorker(
context: Context,
params: WorkerParameters
) : Worker(context, params) {
override fun handleNewData(intent: Intent) {
if (!isEnabled(PluginType.BGSOURCE)) return
val bundle = intent.extras ?: return
if (bundle.containsKey("currentCalibrationPhase")) aapsLogger.debug(LTag.BGSOURCE, "currentCalibrationPhase: " + bundle.getString("currentCalibrationPhase"))
if (bundle.containsKey("placementModeInProgress")) aapsLogger.debug(LTag.BGSOURCE, "placementModeInProgress: " + bundle.getBoolean("placementModeInProgress"))
if (bundle.containsKey("glucoseLevel")) aapsLogger.debug(LTag.BGSOURCE, "glucoseLevel: " + bundle.getInt("glucoseLevel"))
if (bundle.containsKey("glucoseTrendDirection")) aapsLogger.debug(LTag.BGSOURCE, "glucoseTrendDirection: " + bundle.getString("glucoseTrendDirection"))
if (bundle.containsKey("glucoseTimestamp")) aapsLogger.debug(LTag.BGSOURCE, "glucoseTimestamp: " + dateUtil.dateAndTimeString(bundle.getLong("glucoseTimestamp")))
if (bundle.containsKey("batteryLevel")) {
aapsLogger.debug(LTag.BGSOURCE, "batteryLevel: " + bundle.getString("batteryLevel"))
//sensorBatteryLevel = bundle.getString("batteryLevel").toInt() // TODO: Philoul: Line to check I don't have eversens so I don't know what kind of information is sent...
@Inject lateinit var eversensePlugin: EversensePlugin
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var sp: SP
@Inject lateinit var nsUpload: NSUpload
@Inject lateinit var dateUtil: DateUtil
init {
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
}
if (bundle.containsKey("signalStrength")) aapsLogger.debug(LTag.BGSOURCE, "signalStrength: " + bundle.getString("signalStrength"))
if (bundle.containsKey("transmitterVersionNumber")) aapsLogger.debug(LTag.BGSOURCE, "transmitterVersionNumber: " + bundle.getString("transmitterVersionNumber"))
if (bundle.containsKey("isXLVersion")) aapsLogger.debug(LTag.BGSOURCE, "isXLVersion: " + bundle.getBoolean("isXLVersion"))
if (bundle.containsKey("transmitterModelNumber")) aapsLogger.debug(LTag.BGSOURCE, "transmitterModelNumber: " + bundle.getString("transmitterModelNumber"))
if (bundle.containsKey("transmitterSerialNumber")) aapsLogger.debug(LTag.BGSOURCE, "transmitterSerialNumber: " + bundle.getString("transmitterSerialNumber"))
if (bundle.containsKey("transmitterAddress")) aapsLogger.debug(LTag.BGSOURCE, "transmitterAddress: " + bundle.getString("transmitterAddress"))
if (bundle.containsKey("sensorInsertionTimestamp")) aapsLogger.debug(LTag.BGSOURCE, "sensorInsertionTimestamp: " + dateUtil.dateAndTimeString(bundle.getLong("sensorInsertionTimestamp")))
if (bundle.containsKey("transmitterVersionNumber")) aapsLogger.debug(LTag.BGSOURCE, "transmitterVersionNumber: " + bundle.getString("transmitterVersionNumber"))
if (bundle.containsKey("transmitterConnectionState")) aapsLogger.debug(LTag.BGSOURCE, "transmitterConnectionState: " + bundle.getString("transmitterConnectionState"))
if (bundle.containsKey("glucoseLevels")) {
val glucoseLevels = bundle.getIntArray("glucoseLevels")
val glucoseRecordNumbers = bundle.getIntArray("glucoseRecordNumbers")
val glucoseTimestamps = bundle.getLongArray("glucoseTimestamps")
if (glucoseLevels != null && glucoseRecordNumbers != null && glucoseTimestamps != null) {
aapsLogger.debug(LTag.BGSOURCE, "glucoseLevels" + Arrays.toString(glucoseLevels))
aapsLogger.debug(LTag.BGSOURCE, "glucoseRecordNumbers" + Arrays.toString(glucoseRecordNumbers))
aapsLogger.debug(LTag.BGSOURCE, "glucoseTimestamps" + Arrays.toString(glucoseTimestamps))
for (i in glucoseLevels.indices) {
val bgReading = BgReading()
bgReading.value = glucoseLevels[i].toDouble()
bgReading.date = glucoseTimestamps[i]
bgReading.raw = 0.0
val isNew = MainApp.getDbHelper().createIfNotExists(bgReading, "Eversense")
if (isNew && sp.getBoolean(R.string.key_dexcomg5_nsupload, false)) {
nsUpload.uploadBg(bgReading, "AndroidAPS-Eversense")
}
if (isNew && sp.getBoolean(R.string.key_dexcomg5_xdripupload, false)) {
nsUpload.sendToXdrip(bgReading)
}
}
override fun doWork(): Result {
if (!eversensePlugin.isEnabled(PluginType.BGSOURCE)) return Result.failure()
val bundle = Gson().fromJson(inputData.getString("data"), Bundle::class.java)
if (bundle.containsKey("currentCalibrationPhase")) aapsLogger.debug(LTag.BGSOURCE, "currentCalibrationPhase: " + bundle.getString("currentCalibrationPhase"))
if (bundle.containsKey("placementModeInProgress")) aapsLogger.debug(LTag.BGSOURCE, "placementModeInProgress: " + bundle.getBoolean("placementModeInProgress"))
if (bundle.containsKey("glucoseLevel")) aapsLogger.debug(LTag.BGSOURCE, "glucoseLevel: " + bundle.getInt("glucoseLevel"))
if (bundle.containsKey("glucoseTrendDirection")) aapsLogger.debug(LTag.BGSOURCE, "glucoseTrendDirection: " + bundle.getString("glucoseTrendDirection"))
if (bundle.containsKey("glucoseTimestamp")) aapsLogger.debug(LTag.BGSOURCE, "glucoseTimestamp: " + dateUtil.dateAndTimeString(bundle.getLong("glucoseTimestamp")))
if (bundle.containsKey("batteryLevel")) {
aapsLogger.debug(LTag.BGSOURCE, "batteryLevel: " + bundle.getString("batteryLevel"))
//sensorBatteryLevel = bundle.getString("batteryLevel").toInt()
// TODO: Philoul: Line to check I don't have eversense so I don't know what kind of information is sent...
}
}
if (bundle.containsKey("calibrationGlucoseLevels")) {
val calibrationGlucoseLevels = bundle.getIntArray("calibrationGlucoseLevels")
val calibrationTimestamps = bundle.getLongArray("calibrationTimestamps")
val calibrationRecordNumbers = bundle.getLongArray("calibrationRecordNumbers")
if (calibrationGlucoseLevels != null && calibrationTimestamps != null && calibrationRecordNumbers != null) {
aapsLogger.debug(LTag.BGSOURCE, "calibrationGlucoseLevels" + Arrays.toString(calibrationGlucoseLevels))
aapsLogger.debug(LTag.BGSOURCE, "calibrationTimestamps" + Arrays.toString(calibrationTimestamps))
aapsLogger.debug(LTag.BGSOURCE, "calibrationRecordNumbers" + Arrays.toString(calibrationRecordNumbers))
for (i in calibrationGlucoseLevels.indices) {
try {
if (MainApp.getDbHelper().getCareportalEventFromTimestamp(calibrationTimestamps[i]) == null) {
val data = JSONObject()
data.put("enteredBy", "AndroidAPS-Eversense")
data.put("created_at", DateUtil.toISOString(calibrationTimestamps[i]))
data.put("eventType", CareportalEvent.BGCHECK)
data.put("glucoseType", "Finger")
data.put("glucose", calibrationGlucoseLevels[i])
data.put("units", Constants.MGDL)
nsUpload.uploadCareportalEntryToNS(data)
if (bundle.containsKey("signalStrength")) aapsLogger.debug(LTag.BGSOURCE, "signalStrength: " + bundle.getString("signalStrength"))
if (bundle.containsKey("transmitterVersionNumber")) aapsLogger.debug(LTag.BGSOURCE, "transmitterVersionNumber: " + bundle.getString("transmitterVersionNumber"))
if (bundle.containsKey("isXLVersion")) aapsLogger.debug(LTag.BGSOURCE, "isXLVersion: " + bundle.getBoolean("isXLVersion"))
if (bundle.containsKey("transmitterModelNumber")) aapsLogger.debug(LTag.BGSOURCE, "transmitterModelNumber: " + bundle.getString("transmitterModelNumber"))
if (bundle.containsKey("transmitterSerialNumber")) aapsLogger.debug(LTag.BGSOURCE, "transmitterSerialNumber: " + bundle.getString("transmitterSerialNumber"))
if (bundle.containsKey("transmitterAddress")) aapsLogger.debug(LTag.BGSOURCE, "transmitterAddress: " + bundle.getString("transmitterAddress"))
if (bundle.containsKey("sensorInsertionTimestamp")) aapsLogger.debug(LTag.BGSOURCE, "sensorInsertionTimestamp: " + dateUtil.dateAndTimeString(bundle.getLong("sensorInsertionTimestamp")))
if (bundle.containsKey("transmitterVersionNumber")) aapsLogger.debug(LTag.BGSOURCE, "transmitterVersionNumber: " + bundle.getString("transmitterVersionNumber"))
if (bundle.containsKey("transmitterConnectionState")) aapsLogger.debug(LTag.BGSOURCE, "transmitterConnectionState: " + bundle.getString("transmitterConnectionState"))
if (bundle.containsKey("glucoseLevels")) {
val glucoseLevels = bundle.getIntArray("glucoseLevels")
val glucoseRecordNumbers = bundle.getIntArray("glucoseRecordNumbers")
val glucoseTimestamps = bundle.getLongArray("glucoseTimestamps")
if (glucoseLevels != null && glucoseRecordNumbers != null && glucoseTimestamps != null) {
aapsLogger.debug(LTag.BGSOURCE, "glucoseLevels" + Arrays.toString(glucoseLevels))
aapsLogger.debug(LTag.BGSOURCE, "glucoseRecordNumbers" + Arrays.toString(glucoseRecordNumbers))
aapsLogger.debug(LTag.BGSOURCE, "glucoseTimestamps" + Arrays.toString(glucoseTimestamps))
for (i in glucoseLevels.indices) {
val bgReading = BgReading()
bgReading.value = glucoseLevels[i].toDouble()
bgReading.date = glucoseTimestamps[i]
bgReading.raw = 0.0
val isNew = MainApp.getDbHelper().createIfNotExists(bgReading, "Eversense")
if (isNew && sp.getBoolean(R.string.key_dexcomg5_nsupload, false)) {
nsUpload.uploadBg(bgReading, "AndroidAPS-Eversense")
}
if (isNew && sp.getBoolean(R.string.key_dexcomg5_xdripupload, false)) {
nsUpload.sendToXdrip(bgReading)
}
} catch (e: JSONException) {
aapsLogger.error("Unhandled exception", e)
}
}
}
if (bundle.containsKey("calibrationGlucoseLevels")) {
val calibrationGlucoseLevels = bundle.getIntArray("calibrationGlucoseLevels")
val calibrationTimestamps = bundle.getLongArray("calibrationTimestamps")
val calibrationRecordNumbers = bundle.getLongArray("calibrationRecordNumbers")
if (calibrationGlucoseLevels != null && calibrationTimestamps != null && calibrationRecordNumbers != null) {
aapsLogger.debug(LTag.BGSOURCE, "calibrationGlucoseLevels" + Arrays.toString(calibrationGlucoseLevels))
aapsLogger.debug(LTag.BGSOURCE, "calibrationTimestamps" + Arrays.toString(calibrationTimestamps))
aapsLogger.debug(LTag.BGSOURCE, "calibrationRecordNumbers" + Arrays.toString(calibrationRecordNumbers))
for (i in calibrationGlucoseLevels.indices) {
try {
if (MainApp.getDbHelper().getCareportalEventFromTimestamp(calibrationTimestamps[i]) == null) {
val data = JSONObject()
data.put("enteredBy", "AndroidAPS-Eversense")
data.put("created_at", DateUtil.toISOString(calibrationTimestamps[i]))
data.put("eventType", CareportalEvent.BGCHECK)
data.put("glucoseType", "Finger")
data.put("glucose", calibrationGlucoseLevels[i])
data.put("units", Constants.MGDL)
nsUpload.uploadCareportalEntryToNS(data)
}
} catch (e: JSONException) {
aapsLogger.error("Unhandled exception", e)
}
}
}
}
return Result.success()
}
}
override fun getSensorBatteryLevel(): Int {
return sensorBatteryLevel
}
}

View file

@ -1,6 +1,8 @@
package info.nightscout.androidaps.plugins.source
import android.content.Intent
import android.content.Context
import androidx.work.Worker
import androidx.work.WorkerParameters
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
@ -10,7 +12,6 @@ import info.nightscout.androidaps.interfaces.PluginBase
import info.nightscout.androidaps.interfaces.PluginDescription
import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.BundleLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.utils.resources.ResourceHelper
import javax.inject.Inject
@ -31,19 +32,29 @@ class GlimpPlugin @Inject constructor(
aapsLogger, resourceHelper, injector
), BgSourceInterface {
override fun advancedFilteringSupported(): Boolean {
return false
}
// cannot be inner class because of needed injection
class GlimpWorker(
context: Context,
params: WorkerParameters
) : Worker(context, params) {
override fun handleNewData(intent: Intent) {
if (!isEnabled(PluginType.BGSOURCE)) return
val bundle = intent.extras ?: return
aapsLogger.debug(LTag.BGSOURCE, "Received Glimp Data: ${BundleLogger.log(bundle)}")
val bgReading = BgReading()
bgReading.value = bundle.getDouble("mySGV")
bgReading.direction = bundle.getString("myTrend")
bgReading.date = bundle.getLong("myTimestamp")
bgReading.raw = 0.0
MainApp.getDbHelper().createIfNotExists(bgReading, "GLIMP")
@Inject lateinit var glimpPlugin: GlimpPlugin
@Inject lateinit var aapsLogger: AAPSLogger
init {
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
}
override fun doWork(): Result {
if (!glimpPlugin.isEnabled(PluginType.BGSOURCE)) return Result.failure()
aapsLogger.debug(LTag.BGSOURCE, "Received Glimp Data: $inputData}")
val bgReading = BgReading()
bgReading.value = inputData.getDouble("mySGV", 0.0)
bgReading.direction = inputData.getString("myTrend")
bgReading.date = inputData.getLong("myTimestamp", 0)
bgReading.raw = 0.0
MainApp.getDbHelper().createIfNotExists(bgReading, "GLIMP")
return Result.success()
}
}
}

View file

@ -1,6 +1,8 @@
package info.nightscout.androidaps.plugins.source
import android.content.Intent
import android.content.Context
import androidx.work.Worker
import androidx.work.WorkerParameters
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
@ -31,39 +33,49 @@ class MM640gPlugin @Inject constructor(
aapsLogger, resourceHelper, injector
), BgSourceInterface {
override fun advancedFilteringSupported(): Boolean {
return false
}
// cannot be inner class because of needed injection
class MM640gWorker(
context: Context,
params: WorkerParameters
) : Worker(context, params) {
override fun handleNewData(intent: Intent) {
if (!isEnabled(PluginType.BGSOURCE)) return
val bundle = intent.extras ?: return
val collection = bundle.getString("collection") ?: return
if (collection == "entries") {
val data = bundle.getString("data")
aapsLogger.debug(LTag.BGSOURCE, "Received MM640g Data: $data")
if (data != null && data.isNotEmpty()) {
try {
val jsonArray = JSONArray(data)
for (i in 0 until jsonArray.length()) {
val jsonObject = jsonArray.getJSONObject(i)
when (val type = jsonObject.getString("type")) {
"sgv" -> {
val bgReading = BgReading()
bgReading.value = jsonObject.getDouble("sgv")
bgReading.direction = jsonObject.getString("direction")
bgReading.date = jsonObject.getLong("date")
bgReading.raw = jsonObject.getDouble("sgv")
MainApp.getDbHelper().createIfNotExists(bgReading, "MM640g")
@Inject lateinit var mM640gPlugin: MM640gPlugin
@Inject lateinit var aapsLogger: AAPSLogger
init {
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
}
override fun doWork(): Result {
if (!mM640gPlugin.isEnabled(PluginType.BGSOURCE)) return Result.failure()
val collection = inputData.getString("collection") ?: return Result.failure()
if (collection == "entries") {
val data = inputData.getString("data")
aapsLogger.debug(LTag.BGSOURCE, "Received MM640g Data: $data")
if (data != null && data.isNotEmpty()) {
try {
val jsonArray = JSONArray(data)
for (i in 0 until jsonArray.length()) {
val jsonObject = jsonArray.getJSONObject(i)
when (val type = jsonObject.getString("type")) {
"sgv" -> {
val bgReading = BgReading()
bgReading.value = jsonObject.getDouble("sgv")
bgReading.direction = jsonObject.getString("direction")
bgReading.date = jsonObject.getLong("date")
bgReading.raw = jsonObject.getDouble("sgv")
MainApp.getDbHelper().createIfNotExists(bgReading, "MM640g")
}
else -> aapsLogger.debug(LTag.BGSOURCE, "Unknown entries type: $type")
}
else -> aapsLogger.debug(LTag.BGSOURCE, "Unknown entries type: $type")
}
} catch (e: JSONException) {
aapsLogger.error("Exception: ", e)
}
} catch (e: JSONException) {
aapsLogger.error("Exception: ", e)
}
}
return Result.success()
}
}
}

View file

@ -1,6 +1,8 @@
package info.nightscout.androidaps.plugins.source
import android.content.Intent
import android.content.Context
import androidx.work.Worker
import androidx.work.WorkerParameters
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Config
import info.nightscout.androidaps.MainApp
@ -27,7 +29,6 @@ class NSClientSourcePlugin @Inject constructor(
injector: HasAndroidInjector,
resourceHelper: ResourceHelper,
aapsLogger: AAPSLogger,
private val sp: SP,
config: Config
) : PluginBase(PluginDescription()
.mainType(PluginType.BGSOURCE)
@ -53,32 +54,6 @@ class NSClientSourcePlugin @Inject constructor(
return isAdvancedFilteringEnabled
}
override fun handleNewData(intent: Intent) {
if (!isEnabled(PluginType.BGSOURCE) && !sp.getBoolean(R.string.key_ns_autobackfill, true)) return
val bundles = intent.extras ?: return
try {
if (bundles.containsKey("sgv")) {
val sgvString = bundles.getString("sgv")
aapsLogger.debug(LTag.BGSOURCE, "Received NS Data: $sgvString")
val sgvJson = JSONObject(sgvString)
storeSgv(sgvJson)
}
if (bundles.containsKey("sgvs")) {
val sgvString = bundles.getString("sgvs")
aapsLogger.debug(LTag.BGSOURCE, "Received NS Data: $sgvString")
val jsonArray = JSONArray(sgvString)
for (i in 0 until jsonArray.length()) {
val sgvJson = jsonArray.getJSONObject(i)
storeSgv(sgvJson)
}
}
} catch (e: Exception) {
aapsLogger.error("Unhandled exception", e)
}
// Objectives 0
sp.putBoolean(R.string.key_ObjectivesbgIsAvailableInNS, true)
}
private fun storeSgv(sgvJson: JSONObject) {
val nsSgv = NSSgv(sgvJson)
val bgReading = BgReading(injector, nsSgv)
@ -92,4 +67,44 @@ class NSClientSourcePlugin @Inject constructor(
lastBGTimeStamp = timeStamp
}
}
// cannot be inner class because of needed injection
class NSClientSourceWorker(
context: Context,
params: WorkerParameters
) : Worker(context, params) {
@Inject lateinit var nsClientSourcePlugin: NSClientSourcePlugin
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var sp: SP
init {
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
}
override fun doWork(): Result {
if (!nsClientSourcePlugin.isEnabled(PluginType.BGSOURCE) && !sp.getBoolean(R.string.key_ns_autobackfill, true)) return Result.failure()
try {
inputData.getString("sgv")?.let { sgvString ->
aapsLogger.debug(LTag.BGSOURCE, "Received NS Data: $sgvString")
val sgvJson = JSONObject(sgvString)
nsClientSourcePlugin.storeSgv(sgvJson)
}
inputData.getString("sgvs")?.let { sgvString ->
aapsLogger.debug(LTag.BGSOURCE, "Received NS Data: $sgvString")
val jsonArray = JSONArray(sgvString)
for (i in 0 until jsonArray.length()) {
val sgvJson = jsonArray.getJSONObject(i)
nsClientSourcePlugin.storeSgv(sgvJson)
}
}
} catch (e: Exception) {
aapsLogger.error("Unhandled exception", e)
return Result.failure()
}
// Objectives 0
sp.putBoolean(R.string.key_ObjectivesbgIsAvailableInNS, true)
return Result.success()
}
}
}

View file

@ -1,6 +1,8 @@
package info.nightscout.androidaps.plugins.source
import android.content.Intent
import android.content.Context
import androidx.work.Worker
import androidx.work.WorkerParameters
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.MainApp
@ -25,9 +27,7 @@ import javax.inject.Singleton
class PoctechPlugin @Inject constructor(
injector: HasAndroidInjector,
resourceHelper: ResourceHelper,
aapsLogger: AAPSLogger,
private val sp: SP,
private val nsUpload: NSUpload
aapsLogger: AAPSLogger
) : PluginBase(PluginDescription()
.mainType(PluginType.BGSOURCE)
.fragmentClass(BGSourceFragment::class.java.name)
@ -38,36 +38,48 @@ class PoctechPlugin @Inject constructor(
aapsLogger, resourceHelper, injector
), BgSourceInterface {
override fun advancedFilteringSupported(): Boolean {
return false
}
// cannot be inner class because of needed injection
class PoctechWorker(
context: Context,
params: WorkerParameters
) : Worker(context, params) {
override fun handleNewData(intent: Intent) {
if (!isEnabled(PluginType.BGSOURCE)) return
val bundle = intent.extras ?: return
val bgReading = BgReading()
val data = bundle.getString("data")
aapsLogger.debug(LTag.BGSOURCE, "Received Poctech Data $data")
try {
val jsonArray = JSONArray(data)
aapsLogger.debug(LTag.BGSOURCE, "Received Poctech Data size:" + jsonArray.length())
for (i in 0 until jsonArray.length()) {
val json = jsonArray.getJSONObject(i)
bgReading.value = json.getDouble("current")
bgReading.direction = json.getString("direction")
bgReading.date = json.getLong("date")
bgReading.raw = json.getDouble("raw")
if (safeGetString(json, "units", Constants.MGDL) == "mmol/L") bgReading.value = bgReading.value * Constants.MMOLL_TO_MGDL
val isNew = MainApp.getDbHelper().createIfNotExists(bgReading, "Poctech")
if (isNew && sp.getBoolean(R.string.key_dexcomg5_nsupload, false)) {
nsUpload.uploadBg(bgReading, "AndroidAPS-Poctech")
}
if (isNew && sp.getBoolean(R.string.key_dexcomg5_xdripupload, false)) {
nsUpload.sendToXdrip(bgReading)
@Inject lateinit var poctechPlugin: PoctechPlugin
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var sp: SP
@Inject lateinit var nsUpload: NSUpload
init {
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
}
override fun doWork(): Result {
if (!poctechPlugin.isEnabled(PluginType.BGSOURCE)) return Result.failure()
aapsLogger.debug(LTag.BGSOURCE, "Received Poctech Data $inputData")
try {
val jsonArray = JSONArray(inputData.getString("data"))
aapsLogger.debug(LTag.BGSOURCE, "Received Poctech Data size:" + jsonArray.length())
for (i in 0 until jsonArray.length()) {
val json = jsonArray.getJSONObject(i)
val bgReading = BgReading()
bgReading.value = json.getDouble("current")
bgReading.direction = json.getString("direction")
bgReading.date = json.getLong("date")
bgReading.raw = json.getDouble("raw")
if (safeGetString(json, "units", Constants.MGDL) == "mmol/L") bgReading.value = bgReading.value * Constants.MMOLL_TO_MGDL
val isNew = MainApp.getDbHelper().createIfNotExists(bgReading, "Poctech")
if (isNew && sp.getBoolean(R.string.key_dexcomg5_nsupload, false)) {
nsUpload.uploadBg(bgReading, "AndroidAPS-Poctech")
}
if (isNew && sp.getBoolean(R.string.key_dexcomg5_xdripupload, false)) {
nsUpload.sendToXdrip(bgReading)
}
}
} catch (e: JSONException) {
aapsLogger.error("Exception: ", e)
return Result.failure()
}
} catch (e: JSONException) {
aapsLogger.error("Exception: ", e)
return Result.success()
}
}
}

View file

@ -1,6 +1,5 @@
package info.nightscout.androidaps.plugins.source
import android.content.Intent
import android.os.Handler
import android.os.HandlerThread
import dagger.android.HasAndroidInjector
@ -13,7 +12,6 @@ import info.nightscout.androidaps.interfaces.PluginDescription
import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
import info.nightscout.androidaps.utils.DateUtil
@ -48,16 +46,17 @@ class RandomBgPlugin @Inject constructor(
aapsLogger, resourceHelper, injector
), BgSourceInterface {
private val loopHandler : Handler = Handler(HandlerThread(RandomBgPlugin::class.java.simpleName + "Handler").also { it.start() }.looper)
private val loopHandler: Handler = Handler(HandlerThread(RandomBgPlugin::class.java.simpleName + "Handler").also { it.start() }.looper)
private lateinit var refreshLoop: Runnable
companion object {
const val interval = 5L // minutes
}
init {
refreshLoop = Runnable {
handleNewData(Intent())
handleNewData()
loopHandler.postDelayed(refreshLoop, T.mins(interval).msecs())
}
}
@ -80,14 +79,14 @@ class RandomBgPlugin @Inject constructor(
return isRunningTest() || virtualPumpPlugin.isEnabled(PluginType.PUMP) && buildHelper.isEngineeringMode()
}
override fun handleNewData(intent: Intent) {
private fun handleNewData() {
if (!isEnabled(PluginType.BGSOURCE)) return
val min = 70
val max = 190
val cal = GregorianCalendar()
val currentMinute = cal.get(Calendar.MINUTE) + (cal.get(Calendar.HOUR_OF_DAY) % 2) * 60
val bgMgdl = min + ((max - min) + (max - min) * sin(currentMinute / 120.0 * 2 * PI))/2
val bgMgdl = min + ((max - min) + (max - min) * sin(currentMinute / 120.0 * 2 * PI)) / 2
val bgReading = BgReading()
bgReading.value = bgMgdl

View file

@ -1,6 +1,8 @@
package info.nightscout.androidaps.plugins.source
import android.content.Intent
import android.content.Context
import androidx.work.Worker
import androidx.work.WorkerParameters
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
@ -21,9 +23,7 @@ import javax.inject.Singleton
class TomatoPlugin @Inject constructor(
injector: HasAndroidInjector,
resourceHelper: ResourceHelper,
aapsLogger: AAPSLogger,
private val sp: SP,
private val nsUpload: NSUpload
aapsLogger: AAPSLogger
) : PluginBase(PluginDescription()
.mainType(PluginType.BGSOURCE)
.fragmentClass(BGSourceFragment::class.java.name)
@ -35,23 +35,35 @@ class TomatoPlugin @Inject constructor(
aapsLogger, resourceHelper, injector
), BgSourceInterface {
override fun advancedFilteringSupported(): Boolean {
return false
}
// cannot be inner class because of needed injection
class TomatoWorker(
context: Context,
params: WorkerParameters
) : Worker(context, params) {
override fun handleNewData(intent: Intent) {
if (!isEnabled(PluginType.BGSOURCE)) return
val bundle = intent.extras ?: return
val bgReading = BgReading()
aapsLogger.debug(LTag.BGSOURCE, "Received Tomato Data")
bgReading.value = bundle.getDouble("com.fanqies.tomatofn.Extras.BgEstimate")
bgReading.date = bundle.getLong("com.fanqies.tomatofn.Extras.Time")
val isNew = MainApp.getDbHelper().createIfNotExists(bgReading, "Tomato")
if (isNew && sp.getBoolean(R.string.key_dexcomg5_nsupload, false)) {
nsUpload.uploadBg(bgReading, "AndroidAPS-Tomato")
@Inject lateinit var tomatoPlugin: TomatoPlugin
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var sp: SP
@Inject lateinit var nsUpload: NSUpload
init {
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
}
if (isNew && sp.getBoolean(R.string.key_dexcomg5_xdripupload, false)) {
nsUpload.sendToXdrip(bgReading)
override fun doWork(): Result {
if (!tomatoPlugin.isEnabled(PluginType.BGSOURCE)) return Result.failure()
val bgReading = BgReading()
aapsLogger.debug(LTag.BGSOURCE, "Received Tomato Data")
bgReading.value = inputData.getDouble("com.fanqies.tomatofn.Extras.BgEstimate", 0.0)
bgReading.date = inputData.getLong("com.fanqies.tomatofn.Extras.Time", 0)
val isNew = MainApp.getDbHelper().createIfNotExists(bgReading, "Tomato")
if (isNew && sp.getBoolean(R.string.key_dexcomg5_nsupload, false)) {
nsUpload.uploadBg(bgReading, "AndroidAPS-Tomato")
}
if (isNew && sp.getBoolean(R.string.key_dexcomg5_xdripupload, false)) {
nsUpload.sendToXdrip(bgReading)
}
return Result.success()
}
}
}

View file

@ -1,6 +1,8 @@
package info.nightscout.androidaps.plugins.source
import android.content.Intent
import android.content.Context
import androidx.work.Worker
import androidx.work.WorkerParameters
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
@ -10,7 +12,6 @@ import info.nightscout.androidaps.interfaces.PluginBase
import info.nightscout.androidaps.interfaces.PluginDescription
import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.BundleLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.services.Intents
import info.nightscout.androidaps.utils.resources.ResourceHelper
@ -32,32 +33,41 @@ class XdripPlugin @Inject constructor(
), BgSourceInterface {
private var advancedFiltering = false
private var sensorBatteryLevel = -1
override var sensorBatteryLevel = -1
override fun advancedFilteringSupported(): Boolean {
return advancedFiltering
}
override fun handleNewData(intent: Intent) {
if (!isEnabled(PluginType.BGSOURCE)) return
val bundle = intent.extras ?: return
aapsLogger.debug(LTag.BGSOURCE, "Received xDrip data: " + BundleLogger.log(intent.extras))
val bgReading = BgReading()
bgReading.value = bundle.getDouble(Intents.EXTRA_BG_ESTIMATE)
bgReading.direction = bundle.getString(Intents.EXTRA_BG_SLOPE_NAME)
bgReading.date = bundle.getLong(Intents.EXTRA_TIMESTAMP)
bgReading.raw = bundle.getDouble(Intents.EXTRA_RAW)
if (bundle.containsKey(Intents.EXTRA_SENSOR_BATTERY)) sensorBatteryLevel = bundle.getInt(Intents.EXTRA_SENSOR_BATTERY)
val source = bundle.getString(Intents.XDRIP_DATA_SOURCE_DESCRIPTION, "no Source specified")
setSource(source)
MainApp.getDbHelper().createIfNotExists(bgReading, "XDRIP")
}
private fun setSource(source: String) {
advancedFiltering = source.contains("G5 Native") || source.contains("G6 Native")
}
override fun getSensorBatteryLevel(): Int {
return sensorBatteryLevel
// cannot be inner class because of needed injection
class XdripWorker(
context: Context,
params: WorkerParameters
) : Worker(context, params) {
@Inject lateinit var xdripPlugin: XdripPlugin
init {
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
}
override fun doWork(): Result {
if (!xdripPlugin.isEnabled(PluginType.BGSOURCE)) return Result.failure()
xdripPlugin.aapsLogger.debug(LTag.BGSOURCE, "Received xDrip data: $inputData")
val bgReading = BgReading()
bgReading.value = inputData.getDouble(Intents.EXTRA_BG_ESTIMATE, 0.0)
bgReading.direction = inputData.getString(Intents.EXTRA_BG_SLOPE_NAME)
bgReading.date = inputData.getLong(Intents.EXTRA_TIMESTAMP, 0)
bgReading.raw = inputData.getDouble(Intents.EXTRA_RAW, 0.0)
xdripPlugin.sensorBatteryLevel = inputData.getInt(Intents.EXTRA_SENSOR_BATTERY, -1)
val source = inputData.getString(Intents.XDRIP_DATA_SOURCE_DESCRIPTION) ?: ""
xdripPlugin.setSource(source)
MainApp.getDbHelper().createIfNotExists(bgReading, "XDRIP")
return Result.success()
}
}
}

View file

@ -2,23 +2,117 @@ package info.nightscout.androidaps.receivers
import android.content.Context
import android.content.Intent
import androidx.legacy.content.*
import dagger.android.AndroidInjection
import android.provider.Telephony
import androidx.work.Data
import androidx.work.ExistingWorkPolicy
import androidx.work.OneTimeWorkRequest
import androidx.work.WorkManager
import com.google.gson.Gson
import dagger.android.DaggerBroadcastReceiver
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.BundleLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.services.DataService
import info.nightscout.androidaps.plugins.general.nsclient.NSClientWorker
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin
import info.nightscout.androidaps.plugins.profile.ns.NSProfilePlugin
import info.nightscout.androidaps.plugins.source.*
import info.nightscout.androidaps.services.Intents
import info.nightscout.androidaps.utils.extensions.copyDouble
import info.nightscout.androidaps.utils.extensions.copyInt
import info.nightscout.androidaps.utils.extensions.copyLong
import info.nightscout.androidaps.utils.extensions.copyString
import javax.inject.Inject
// We are not ready to switch to JobScheduler
@Suppress("DEPRECATION")
open class DataReceiver : WakefulBroadcastReceiver() {
open class DataReceiver : DaggerBroadcastReceiver() {
@Inject lateinit var aapsLogger: AAPSLogger
private val jobGroupName = "data"
override fun onReceive(context: Context, intent: Intent) {
AndroidInjection.inject(this, context)
aapsLogger.debug(LTag.DATASERVICE, "onReceive $intent")
startWakefulService(context, Intent(context, DataService::class.java)
.setAction(intent.action)
.putExtras(intent))
super.onReceive(context, intent)
val bundle = intent.extras ?: return
aapsLogger.debug(LTag.DATASERVICE, "onReceive ${intent.action} ${BundleLogger.log(bundle)}")
when (intent.action) {
Intents.ACTION_NEW_BG_ESTIMATE ->
OneTimeWorkRequest.Builder(XdripPlugin.XdripWorker::class.java)
.setInputData(Data.Builder().also {
it.copyString("collection", bundle, null)
it.copyString("data", bundle)
}.build()).build()
Intents.POCTECH_BG ->
OneTimeWorkRequest.Builder(PoctechPlugin.PoctechWorker::class.java)
.setInputData(Data.Builder().also {
it.copyString("data", bundle)
}.build()).build()
Intents.GLIMP_BG ->
OneTimeWorkRequest.Builder(GlimpPlugin.GlimpWorker::class.java)
.setInputData(Data.Builder().also {
it.copyDouble("mySGV", bundle)
it.copyString("myTrend", bundle)
it.copyLong("myTimestamp", bundle)
}.build()).build()
Intents.TOMATO_BG ->
OneTimeWorkRequest.Builder(TomatoPlugin.TomatoWorker::class.java)
.setInputData(Data.Builder().also {
it.copyDouble("com.fanqies.tomatofn.Extras.BgEstimate", bundle)
it.copyLong("com.fanqies.tomatofn.Extras.Time", bundle)
}.build()).build()
Intents.ACTION_NEW_PROFILE ->
OneTimeWorkRequest.Builder(NSProfilePlugin.NSProfileWorker::class.java)
.setInputData(Data.Builder().also {
it.copyString("profile", bundle, null)
}.build()).build()
Intents.ACTION_NEW_SGV ->
OneTimeWorkRequest.Builder(NSClientSourcePlugin.NSClientSourceWorker::class.java)
.setInputData(Data.Builder().also {
it.copyString("sgv", bundle, null)
it.copyString("sgvs", bundle, null)
}.build()).build()
Intents.NS_EMULATOR ->
OneTimeWorkRequest.Builder(MM640gPlugin.MM640gWorker::class.java)
.setInputData(Data.Builder().also {
it.copyDouble(Intents.EXTRA_BG_ESTIMATE, bundle)
it.copyString(Intents.EXTRA_BG_SLOPE_NAME, bundle)
it.copyLong(Intents.EXTRA_TIMESTAMP, bundle)
it.copyDouble(Intents.EXTRA_RAW, bundle)
it.copyInt(Intents.EXTRA_SENSOR_BATTERY, bundle, -1)
it.copyString(Intents.XDRIP_DATA_SOURCE_DESCRIPTION, bundle)
}.build()).build()
Telephony.Sms.Intents.SMS_RECEIVED_ACTION ->
OneTimeWorkRequest.Builder(SmsCommunicatorPlugin.SmsCommunicatorWorker::class.java)
.setInputData(Data.Builder().also {
it.putString("data", Gson().toJson(bundle))
it.putString("action", intent.action)
}.build()).build()
Intents.EVERSENSE_BG ->
OneTimeWorkRequest.Builder(EversensePlugin.EversenseWorker::class.java)
.setInputData(Data.Builder().also {
it.putString("data", Gson().toJson(bundle))
it.putString("action", intent.action)
}.build()).build()
Intents.DEXCOM_BG ->
OneTimeWorkRequest.Builder(DexcomPlugin.DexcomWorker::class.java)
.setInputData(Data.Builder().also {
it.putString("data", Gson().toJson(bundle))
it.putString("action", intent.action)
}.build()).build()
Intents.ACTION_NEW_TREATMENT,
Intents.ACTION_CHANGED_TREATMENT,
Intents.ACTION_REMOVED_TREATMENT,
Intents.ACTION_NEW_CAL,
Intents.ACTION_NEW_MBG ->
OneTimeWorkRequest.Builder(NSClientWorker::class.java)
.setInputData(Data.Builder().also {
it.putString("data", Gson().toJson(bundle))
it.putString("action", intent.action)
}.build()).build()
else -> null
}?.let { request ->
WorkManager.getInstance(context)
.enqueueUniqueWork(jobGroupName, ExistingWorkPolicy.APPEND_OR_REPLACE , request)
}
}
}

View file

@ -1,256 +0,0 @@
package info.nightscout.androidaps.services;
import android.content.Intent;
import android.os.Bundle;
import android.provider.Telephony;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import javax.inject.Inject;
import dagger.android.DaggerIntentService;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.events.EventNsTreatment;
import info.nightscout.androidaps.interfaces.ActivePluginProvider;
import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.BundleLogger;
import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
import info.nightscout.androidaps.plugins.general.nsclient.data.NSMbg;
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.SmsCommunicatorPlugin;
import info.nightscout.androidaps.plugins.profile.ns.NSProfilePlugin;
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;
import info.nightscout.androidaps.receivers.DataReceiver;
import info.nightscout.androidaps.utils.JsonHelper;
import info.nightscout.androidaps.utils.buildHelper.BuildHelper;
import info.nightscout.androidaps.utils.sharedPreferences.SP;
public class DataService extends DaggerIntentService {
@Inject AAPSLogger aapsLogger;
@Inject SP sp;
@Inject RxBusWrapper rxBus;
@Inject NSUpload nsUpload;
@Inject SmsCommunicatorPlugin smsCommunicatorPlugin;
@Inject DexcomPlugin dexcomPlugin;
@Inject EversensePlugin eversensePlugin;
@Inject GlimpPlugin glimpPlugin;
@Inject MM640gPlugin mm640GPlugin;
@Inject NSClientSourcePlugin nsClientSourcePlugin;
@Inject PoctechPlugin poctechPlugin;
@Inject TomatoPlugin tomatoPlugin;
@Inject XdripPlugin xdripPlugin;
@Inject NSProfilePlugin nsProfilePlugin;
@Inject ActivePluginProvider activePlugin;
@Inject Config config;
@Inject BuildHelper buildHelper;
public DataService() {
super("DataService");
}
@Override
protected void onHandleIntent(final Intent intent) {
aapsLogger.debug(LTag.DATASERVICE, "onHandleIntent " + intent);
aapsLogger.debug(LTag.DATASERVICE, "onHandleIntent " + BundleLogger.log(intent.getExtras()));
boolean acceptNSData = !sp.getBoolean(R.string.key_ns_upload_only, true) && buildHelper.isEngineeringMode() || config.getNSCLIENT();
final String action = intent.getAction();
if (Intents.ACTION_NEW_BG_ESTIMATE.equals(action)) {
xdripPlugin.handleNewData(intent);
} else if (Intents.NS_EMULATOR.equals(action)) {
mm640GPlugin.handleNewData(intent);
} else if (Intents.GLIMP_BG.equals(action)) {
glimpPlugin.handleNewData(intent);
} else if (Intents.DEXCOM_BG.equals(action)) {
dexcomPlugin.handleNewData(intent);
} else if (Intents.POCTECH_BG.equals(action)) {
poctechPlugin.handleNewData(intent);
} else if (Intents.TOMATO_BG.equals(action)) {
tomatoPlugin.handleNewData(intent);
} else if (Intents.EVERSENSE_BG.equals(action)) {
eversensePlugin.handleNewData(intent);
} else if (Intents.ACTION_NEW_SGV.equals(action)) {
nsClientSourcePlugin.handleNewData(intent);
} else if (Intents.ACTION_NEW_PROFILE.equals(action)) {
// always handle Profile if NSProfile is enabled without looking at nsUploadOnly
nsProfilePlugin.handleNewData(intent);
} else if (acceptNSData &&
(Intents.ACTION_NEW_TREATMENT.equals(action) ||
Intents.ACTION_CHANGED_TREATMENT.equals(action) ||
Intents.ACTION_REMOVED_TREATMENT.equals(action) ||
Intents.ACTION_NEW_CAL.equals(action) ||
Intents.ACTION_NEW_MBG.equals(action))
) {
handleNewDataFromNSClient(intent);
} else if (Telephony.Sms.Intents.SMS_RECEIVED_ACTION.equals(action)) {
smsCommunicatorPlugin.handleNewData(intent);
}
aapsLogger.debug(LTag.DATASERVICE, "onHandleIntent exit " + intent);
DataReceiver.completeWakefulIntent(intent);
}
@Override
public void onDestroy() {
super.onDestroy();
}
private void handleNewDataFromNSClient(Intent intent) {
Bundle bundles = intent.getExtras();
if (bundles == null) return;
aapsLogger.debug(LTag.DATASERVICE, "Got intent: " + intent.getAction());
if (intent.getAction().equals(Intents.ACTION_NEW_TREATMENT) || intent.getAction().equals(Intents.ACTION_CHANGED_TREATMENT)) {
try {
if (bundles.containsKey("treatment")) {
JSONObject json = new JSONObject(bundles.getString("treatment"));
handleTreatmentFromNS(json, intent);
}
if (bundles.containsKey("treatments")) {
String trstring = bundles.getString("treatments");
JSONArray jsonArray = new JSONArray(trstring);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject json = jsonArray.getJSONObject(i);
handleTreatmentFromNS(json, intent);
}
}
} catch (JSONException e) {
aapsLogger.error(LTag.DATASERVICE, "Unhandled exception", e);
}
}
if (intent.getAction().equals(Intents.ACTION_REMOVED_TREATMENT)) {
try {
if (bundles.containsKey("treatment")) {
String trstring = bundles.getString("treatment");
JSONObject json = new JSONObject(trstring);
handleRemovedTreatmentFromNS(json);
}
if (bundles.containsKey("treatments")) {
String trstring = bundles.getString("treatments");
JSONArray jsonArray = new JSONArray(trstring);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject json = jsonArray.getJSONObject(i);
handleRemovedTreatmentFromNS(json);
}
}
} catch (JSONException e) {
aapsLogger.error(LTag.DATASERVICE, "Unhandled exception", e);
}
}
if (intent.getAction().equals(Intents.ACTION_NEW_MBG)) {
try {
if (bundles.containsKey("mbg")) {
String mbgstring = bundles.getString("mbg");
JSONObject mbgJson = new JSONObject(mbgstring);
storeMbg(mbgJson);
}
if (bundles.containsKey("mbgs")) {
String sgvstring = bundles.getString("mbgs");
JSONArray jsonArray = new JSONArray(sgvstring);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject mbgJson = jsonArray.getJSONObject(i);
storeMbg(mbgJson);
}
}
} catch (Exception e) {
aapsLogger.error(LTag.DATASERVICE, "Unhandled exception", e);
}
}
}
private void handleRemovedTreatmentFromNS(JSONObject json) {
// new DB model
EventNsTreatment evtTreatment = new EventNsTreatment(EventNsTreatment.Companion.getREMOVE(), json);
rxBus.send(evtTreatment);
// old DB model
String _id = JsonHelper.safeGetString(json, "_id");
MainApp.getDbHelper().deleteTempTargetById(_id);
MainApp.getDbHelper().deleteTempBasalById(_id);
MainApp.getDbHelper().deleteExtendedBolusById(_id);
MainApp.getDbHelper().deleteCareportalEventById(_id);
MainApp.getDbHelper().deleteProfileSwitchById(_id);
}
private void handleTreatmentFromNS(JSONObject json, Intent intent) {
// new DB model
int mode = Intents.ACTION_NEW_TREATMENT.equals(intent.getAction()) ? EventNsTreatment.Companion.getADD() : EventNsTreatment.Companion.getUPDATE();
double insulin = JsonHelper.safeGetDouble(json, "insulin");
double carbs = JsonHelper.safeGetDouble(json, "carbs");
String eventType = JsonHelper.safeGetString(json, "eventType");
if (eventType == null) {
aapsLogger.debug(LTag.DATASERVICE, "Wrong treatment. Ignoring : " + json.toString());
return;
}
if (insulin > 0 || carbs > 0) {
EventNsTreatment evtTreatment = new EventNsTreatment(mode, json);
rxBus.send(evtTreatment);
} else if (eventType.equals(CareportalEvent.TEMPORARYTARGET)) {
MainApp.getDbHelper().createTemptargetFromJsonIfNotExists(json);
} else if (eventType.equals(CareportalEvent.TEMPBASAL)) {
MainApp.getDbHelper().createTempBasalFromJsonIfNotExists(json);
} else if (eventType.equals(CareportalEvent.COMBOBOLUS)) {
MainApp.getDbHelper().createExtendedBolusFromJsonIfNotExists(json);
} else if (eventType.equals(CareportalEvent.PROFILESWITCH)) {
MainApp.getDbHelper().createProfileSwitchFromJsonIfNotExists(activePlugin, nsUpload, json);
} else if (eventType.equals(CareportalEvent.SITECHANGE) ||
eventType.equals(CareportalEvent.INSULINCHANGE) ||
eventType.equals(CareportalEvent.SENSORCHANGE) ||
eventType.equals(CareportalEvent.BGCHECK) ||
eventType.equals(CareportalEvent.NOTE) ||
eventType.equals(CareportalEvent.NONE) ||
eventType.equals(CareportalEvent.ANNOUNCEMENT) ||
eventType.equals(CareportalEvent.QUESTION) ||
eventType.equals(CareportalEvent.EXERCISE) ||
eventType.equals(CareportalEvent.OPENAPSOFFLINE) ||
eventType.equals(CareportalEvent.PUMPBATTERYCHANGE)) {
MainApp.getDbHelper().createCareportalEventFromJsonIfNotExists(json);
}
if (eventType.equals(CareportalEvent.ANNOUNCEMENT)) {
long date = JsonHelper.safeGetLong(json, "mills");
long now = System.currentTimeMillis();
String enteredBy = JsonHelper.safeGetString(json, "enteredBy", "");
String notes = JsonHelper.safeGetString(json, "notes", "");
if (date > now - 15 * 60 * 1000L && !notes.isEmpty()
&& !enteredBy.equals(sp.getString("careportal_enteredby", "AndroidAPS"))) {
boolean defaultVal = config.getNSCLIENT();
if (sp.getBoolean(R.string.key_ns_announcements, defaultVal)) {
Notification announcement = new Notification(Notification.NSANNOUNCEMENT, notes, Notification.ANNOUNCEMENT, 60);
rxBus.send(new EventNewNotification(announcement));
}
}
}
}
private void storeMbg(JSONObject mbgJson) {
NSMbg nsMbg = new NSMbg(mbgJson);
CareportalEvent careportalEvent = new CareportalEvent(nsMbg);
MainApp.getDbHelper().createOrUpdate(careportalEvent);
aapsLogger.debug(LTag.DATASERVICE, "Adding/Updating new MBG: " + careportalEvent.toString());
}
}

View file

@ -0,0 +1,16 @@
package info.nightscout.androidaps.utils.extensions
import android.os.Bundle
import androidx.work.Data
fun Data.Builder.copyString(key: String, bundle: Bundle?, defaultValue : String? = ""): Data.Builder =
this.also { putString(key, bundle?.getString(key) ?: defaultValue) }
fun Data.Builder.copyLong(key: String, bundle: Bundle?, defaultValue : Long = 0): Data.Builder =
this.also { putLong(key, bundle?.getLong(key) ?: defaultValue) }
fun Data.Builder.copyInt(key: String, bundle: Bundle?, defaultValue : Int = 0): Data.Builder =
this.also { putInt(key, bundle?.getInt(key) ?: defaultValue) }
fun Data.Builder.copyDouble(key: String, bundle: Bundle?, defaultValue : Double = 0.0): Data.Builder =
this.also { putDouble(key, bundle?.getDouble(key) ?: defaultValue) }

View file

@ -20,7 +20,7 @@ buildscript {
constraintlayout_version = '2.0.4'
preferencektx_version = '1.1.1'
commonslang3_version = '3.11'
work_version = '2.4.0'
work_version = '2.5.0'
junit_version = '4.13.1'
mockitoVersion = '2.8.47'

View file

@ -1,16 +0,0 @@
package info.nightscout.androidaps.interfaces;
import android.content.Intent;
/**
* Created by mike on 20.06.2016.
*/
public interface BgSourceInterface {
boolean advancedFilteringSupported();
void handleNewData(Intent intent);
default int getSensorBatteryLevel() {
return -1;
}
}

View file

@ -0,0 +1,11 @@
package info.nightscout.androidaps.interfaces
/**
* Created by mike on 20.06.2016.
*/
interface BgSourceInterface {
fun advancedFilteringSupported(): Boolean = false
val sensorBatteryLevel: Int
get() = -1
}