Merge pull request #280 from nightscout/dataservice

Dataservice
This commit is contained in:
Milos Kozak 2021-02-04 18:03:19 +01:00 committed by GitHub
commit 230cc943af
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 842 additions and 606 deletions

View file

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

View file

@ -41,6 +41,7 @@ import javax.inject.Singleton
DanaModule::class, DanaModule::class,
DanaRModule::class, DanaRModule::class,
DanaRSModule::class, DanaRSModule::class,
WorkersModule::class,
OHUploaderModule::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.medtronic.service.RileyLinkMedtronicService
import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.service.RileyLinkOmnipodService import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.service.RileyLinkOmnipodService
import info.nightscout.androidaps.services.AlarmSoundService import info.nightscout.androidaps.services.AlarmSoundService
import info.nightscout.androidaps.services.DataService
import info.nightscout.androidaps.services.LocationService import info.nightscout.androidaps.services.LocationService
@Module @Module
@ -20,7 +19,6 @@ import info.nightscout.androidaps.services.LocationService
abstract class ServicesModule { abstract class ServicesModule {
@ContributesAndroidInjector abstract fun contributesAlarmSoundService(): AlarmSoundService @ContributesAndroidInjector abstract fun contributesAlarmSoundService(): AlarmSoundService
@ContributesAndroidInjector abstract fun contributesDataService(): DataService
@ContributesAndroidInjector abstract fun contributesDismissNotificationService(): DismissNotificationService @ContributesAndroidInjector abstract fun contributesDismissNotificationService(): DismissNotificationService
@ContributesAndroidInjector abstract fun contributesDummyService(): DummyService @ContributesAndroidInjector abstract fun contributesDummyService(): DummyService
@ContributesAndroidInjector abstract fun contributesLocationService(): LocationService @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.Context;
import android.content.Intent; import android.content.Intent;
import android.content.ServiceConnection; import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.HandlerThread; import android.os.HandlerThread;
import android.os.IBinder; import android.os.IBinder;
@ -13,6 +14,9 @@ import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.SwitchPreference; import androidx.preference.SwitchPreference;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -23,11 +27,15 @@ import javax.inject.Singleton;
import dagger.android.HasAndroidInjector; import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.events.EventAppExit; import info.nightscout.androidaps.events.EventAppExit;
import info.nightscout.androidaps.events.EventChargingState; import info.nightscout.androidaps.events.EventChargingState;
import info.nightscout.androidaps.events.EventNetworkChange; import info.nightscout.androidaps.events.EventNetworkChange;
import info.nightscout.androidaps.events.EventNsTreatment;
import info.nightscout.androidaps.events.EventPreferenceChange; import info.nightscout.androidaps.events.EventPreferenceChange;
import info.nightscout.androidaps.interfaces.ActivePluginProvider;
import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginDescription;
import info.nightscout.androidaps.interfaces.PluginType; 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.bus.RxBusWrapper;
import info.nightscout.androidaps.plugins.general.nsclient.data.AlarmAck; 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.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.EventNSClientNewLog;
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientResend; 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.EventNSClientStatus;
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientUpdateGUI; import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientUpdateGUI;
import info.nightscout.androidaps.plugins.general.nsclient.services.NSClientService; 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.FabricPrivacy;
import info.nightscout.androidaps.utils.HtmlHelper; import info.nightscout.androidaps.utils.HtmlHelper;
import info.nightscout.androidaps.utils.JsonHelper;
import info.nightscout.androidaps.utils.ToastUtils; import info.nightscout.androidaps.utils.ToastUtils;
import info.nightscout.androidaps.utils.buildHelper.BuildHelper; import info.nightscout.androidaps.utils.buildHelper.BuildHelper;
import info.nightscout.androidaps.utils.resources.ResourceHelper; import info.nightscout.androidaps.utils.resources.ResourceHelper;
@ -62,6 +75,8 @@ public class NSClientPlugin extends PluginBase {
private final SP sp; private final SP sp;
private final Config config; private final Config config;
private final BuildHelper buildHelper; private final BuildHelper buildHelper;
private final ActivePluginProvider activePlugin;
private final NSUpload nsUpload;
public Handler handler; public Handler handler;
@ -88,7 +103,9 @@ public class NSClientPlugin extends PluginBase {
SP sp, SP sp,
NsClientReceiverDelegate nsClientReceiverDelegate, NsClientReceiverDelegate nsClientReceiverDelegate,
Config config, Config config,
BuildHelper buildHelper BuildHelper buildHelper,
ActivePluginProvider activePlugin,
NSUpload nsUpload
) { ) {
super(new PluginDescription() super(new PluginDescription()
.mainType(PluginType.GENERAL) .mainType(PluginType.GENERAL)
@ -110,6 +127,8 @@ public class NSClientPlugin extends PluginBase {
this.nsClientReceiverDelegate = nsClientReceiverDelegate; this.nsClientReceiverDelegate = nsClientReceiverDelegate;
this.config = config; this.config = config;
this.buildHelper = buildHelper; this.buildHelper = buildHelper;
this.activePlugin = activePlugin;
this.nsUpload = nsUpload;
if (config.getNSCLIENT()) { if (config.getNSCLIENT()) {
getPluginDescription().alwaysEnabled(true).visibleByDefault(true); getPluginDescription().alwaysEnabled(true).visibleByDefault(true);
@ -310,4 +329,143 @@ public class NSClientPlugin extends PluginBase {
nsClientService.sendAlarmAck(ack); 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,40 @@
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 org.jetbrains.annotations.NotNull;
import javax.inject.Inject;
import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.receivers.BundleStore;
// 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;
@Inject BundleStore bundleStore;
@NotNull
@Override
public Result doWork() {
Bundle bundle = bundleStore.pickup(getInputData().getLong("storeKey", -1));
if (bundle == null) Result.failure();
String action = getInputData().getString("action");
nsClientPlugin.handleNewDataFromNSClient(action, bundle);
return Result.success();
}
}

View file

@ -1,12 +1,14 @@
package info.nightscout.androidaps.plugins.general.smsCommunicator package info.nightscout.androidaps.plugins.general.smsCommunicator
import android.content.Intent import android.content.Context
import android.telephony.SmsManager import android.telephony.SmsManager
import android.telephony.SmsMessage import android.telephony.SmsMessage
import android.text.TextUtils import android.text.TextUtils
import androidx.preference.EditTextPreference import androidx.preference.EditTextPreference
import androidx.preference.Preference import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceFragmentCompat
import androidx.work.Worker
import androidx.work.WorkerParameters
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Config import info.nightscout.androidaps.Config
import info.nightscout.androidaps.Constants import info.nightscout.androidaps.Constants
@ -32,6 +34,7 @@ import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.receivers.BundleStore
import info.nightscout.androidaps.utils.* import info.nightscout.androidaps.utils.*
import info.nightscout.androidaps.utils.extensions.plusAssign import info.nightscout.androidaps.utils.extensions.plusAssign
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
@ -152,6 +155,32 @@ 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
@Inject lateinit var bundleStore: BundleStore
init {
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
}
override fun doWork(): Result {
val bundle = bundleStore.pickup(inputData.getLong("storeKey", -1))
?: return Result.failure()
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?) { private fun processSettings(ev: EventPreferenceChange?) {
if (ev == null || ev.isChanged(resourceHelper, R.string.key_smscommunicator_allowednumbers)) { if (ev == null || ev.isChanged(resourceHelper, R.string.key_smscommunicator_allowednumbers)) {
val settings = sp.getString(R.string.key_smscommunicator_allowednumbers, "") val settings = sp.getString(R.string.key_smscommunicator_allowednumbers, "")
@ -180,16 +209,6 @@ class SmsCommunicatorPlugin @Inject constructor(
return false 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) { fun processSms(receivedSms: Sms) {
if (!isEnabled(PluginType.GENERAL)) { if (!isEnabled(PluginType.GENERAL)) {
aapsLogger.debug(LTag.SMS, "Ignoring SMS. Plugin disabled.") aapsLogger.debug(LTag.SMS, "Ignoring SMS. Plugin disabled.")

View file

@ -1,15 +1,17 @@
package info.nightscout.androidaps.plugins.profile.ns 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 dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Config import info.nightscout.androidaps.Config
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.interfaces.ProfileStore
import info.nightscout.androidaps.events.EventProfileStoreChanged import info.nightscout.androidaps.events.EventProfileStoreChanged
import info.nightscout.androidaps.interfaces.PluginBase import info.nightscout.androidaps.interfaces.PluginBase
import info.nightscout.androidaps.interfaces.PluginDescription import info.nightscout.androidaps.interfaces.PluginDescription
import info.nightscout.androidaps.interfaces.PluginType import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.interfaces.ProfileInterface import info.nightscout.androidaps.interfaces.ProfileInterface
import info.nightscout.androidaps.interfaces.ProfileStore
import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.bus.RxBusWrapper
@ -49,21 +51,6 @@ class NSProfilePlugin @Inject constructor(
loadNSProfile() 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() { private fun storeNSProfile() {
sp.putString("profile", profile!!.data.toString()) sp.putString("profile", profile!!.data.toString())
aapsLogger.debug(LTag.PROFILE, "Storing profile") aapsLogger.debug(LTag.PROFILE, "Storing profile")
@ -90,4 +77,33 @@ class NSProfilePlugin @Inject constructor(
return profile!!.getDefaultProfileName()!! 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,11 @@
package info.nightscout.androidaps.plugins.source package info.nightscout.androidaps.plugins.source
import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.work.Worker
import androidx.work.WorkerParameters
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Config import info.nightscout.androidaps.Config
import info.nightscout.androidaps.Constants import info.nightscout.androidaps.Constants
@ -18,6 +21,7 @@ import info.nightscout.androidaps.interfaces.PluginDescription
import info.nightscout.androidaps.interfaces.PluginType import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
import info.nightscout.androidaps.receivers.BundleStore
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
@ -29,11 +33,9 @@ import javax.inject.Singleton
@Singleton @Singleton
class DexcomPlugin @Inject constructor( class DexcomPlugin @Inject constructor(
injector: HasAndroidInjector, injector: HasAndroidInjector,
private val sp: SP,
private val mainApp: MainApp, private val mainApp: MainApp,
resourceHelper: ResourceHelper, resourceHelper: ResourceHelper,
aapsLogger: AAPSLogger, aapsLogger: AAPSLogger,
private val nsUpload: NSUpload,
config: Config config: Config
) : PluginBase(PluginDescription() ) : PluginBase(PluginDescription()
.mainType(PluginType.BGSOURCE) .mainType(PluginType.BGSOURCE)
@ -73,80 +75,103 @@ class DexcomPlugin @Inject constructor(
return null return null
} }
override fun handleNewData(intent: Intent) { // cannot be inner class because of needed injection
if (!isEnabled(PluginType.BGSOURCE)) return class DexcomWorker(
try { context: Context,
val sensorType = intent.getStringExtra("sensorType") ?: "" params: WorkerParameters
val glucoseValues = intent.getBundleExtra("glucoseValues") ) : Worker(context, params) {
for (i in 0 until glucoseValues.size()) {
glucoseValues.getBundle(i.toString())?.let { glucoseValue -> @Inject lateinit var aapsLogger: AAPSLogger
val bgReading = BgReading() @Inject lateinit var injector: HasAndroidInjector
bgReading.value = glucoseValue.getInt("glucoseValue").toDouble() @Inject lateinit var dexcomPlugin: DexcomPlugin
bgReading.direction = glucoseValue.getString("trendArrow") @Inject lateinit var nsUpload: NSUpload
bgReading.date = glucoseValue.getLong("timestamp") * 1000 @Inject lateinit var sp: SP
bgReading.raw = 0.0 @Inject lateinit var bundleStore: BundleStore
if (MainApp.getDbHelper().createIfNotExists(bgReading, "Dexcom$sensorType")) {
if (sp.getBoolean(R.string.key_dexcomg5_nsupload, false)) { init {
nsUpload.uploadBg(bgReading, "AndroidAPS-Dexcom$sensorType") (context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
} }
if (sp.getBoolean(R.string.key_dexcomg5_xdripupload, false)) {
nsUpload.sendToXdrip(bgReading) override fun doWork(): Result {
if (!dexcomPlugin.isEnabled(PluginType.BGSOURCE)) return Result.failure()
val bundle = bundleStore.pickup(inputData.getLong("storeKey", -1))
?: return Result.failure()
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)
}
} }
} }
} }
} bundle.getBundle("meters")?.let { meters ->
val meters = intent.getBundleExtra("meters") for (i in 0 until meters.size()) {
for (i in 0 until meters.size()) { val meter = meters.getBundle(i.toString())
val meter = meters.getBundle(i.toString()) meter?.let {
meter?.let { val timestamp = it.getLong("timestamp") * 1000
val timestamp = it.getLong("timestamp") * 1000 val now = DateUtil.now()
val now = DateUtil.now() if (timestamp > now - T.months(1).msecs() && timestamp < now)
if (timestamp > now - T.months(1).msecs() && timestamp < now) if (MainApp.getDbHelper().getCareportalEventFromTimestamp(timestamp) == null) {
if (MainApp.getDbHelper().getCareportalEventFromTimestamp(timestamp) == null) { val jsonObject = JSONObject()
val jsonObject = JSONObject() jsonObject.put("enteredBy", "AndroidAPS-Dexcom$sensorType")
jsonObject.put("enteredBy", "AndroidAPS-Dexcom$sensorType") jsonObject.put("created_at", DateUtil.toISOString(timestamp))
jsonObject.put("created_at", DateUtil.toISOString(timestamp)) jsonObject.put("eventType", CareportalEvent.BGCHECK)
jsonObject.put("eventType", CareportalEvent.BGCHECK) jsonObject.put("glucoseType", "Finger")
jsonObject.put("glucoseType", "Finger") jsonObject.put("glucose", meter.getInt("meterValue"))
jsonObject.put("glucose", meter.getInt("meterValue")) jsonObject.put("units", Constants.MGDL)
jsonObject.put("units", Constants.MGDL)
val careportalEvent = CareportalEvent(injector) val careportalEvent = CareportalEvent(injector)
careportalEvent.date = timestamp careportalEvent.date = timestamp
careportalEvent.source = Source.USER careportalEvent.source = Source.USER
careportalEvent.eventType = CareportalEvent.BGCHECK careportalEvent.eventType = CareportalEvent.BGCHECK
careportalEvent.json = jsonObject.toString() careportalEvent.json = jsonObject.toString()
MainApp.getDbHelper().createOrUpdate(careportalEvent) MainApp.getDbHelper().createOrUpdate(careportalEvent)
nsUpload.uploadCareportalEntryToNS(jsonObject) nsUpload.uploadCareportalEntryToNS(jsonObject)
}
} }
}
} }
} if (sp.getBoolean(R.string.key_dexcom_lognssensorchange, false) && bundle.containsKey("sensorInsertionTime")) {
if (sp.getBoolean(R.string.key_dexcom_lognssensorchange, false) && intent.hasExtra("sensorInsertionTime")) { bundle.let {
intent.extras?.let { val sensorInsertionTime = it.getLong("sensorInsertionTime") * 1000
val sensorInsertionTime = it.getLong("sensorInsertionTime") * 1000 val now = DateUtil.now()
val now = DateUtil.now() if (sensorInsertionTime > now - T.months(1).msecs() && sensorInsertionTime < now)
if (sensorInsertionTime > now - T.months(1).msecs() && sensorInsertionTime < now) if (MainApp.getDbHelper().getCareportalEventFromTimestamp(sensorInsertionTime) == null) {
if (MainApp.getDbHelper().getCareportalEventFromTimestamp(sensorInsertionTime) == null) { val jsonObject = JSONObject()
val jsonObject = JSONObject() jsonObject.put("enteredBy", "AndroidAPS-Dexcom$sensorType")
jsonObject.put("enteredBy", "AndroidAPS-Dexcom$sensorType") jsonObject.put("created_at", DateUtil.toISOString(sensorInsertionTime))
jsonObject.put("created_at", DateUtil.toISOString(sensorInsertionTime)) jsonObject.put("eventType", CareportalEvent.SENSORCHANGE)
jsonObject.put("eventType", CareportalEvent.SENSORCHANGE) val careportalEvent = CareportalEvent(injector)
val careportalEvent = CareportalEvent(injector) careportalEvent.date = sensorInsertionTime
careportalEvent.date = sensorInsertionTime careportalEvent.source = Source.USER
careportalEvent.source = Source.USER careportalEvent.eventType = CareportalEvent.SENSORCHANGE
careportalEvent.eventType = CareportalEvent.SENSORCHANGE careportalEvent.json = jsonObject.toString()
careportalEvent.json = jsonObject.toString() MainApp.getDbHelper().createOrUpdate(careportalEvent)
MainApp.getDbHelper().createOrUpdate(careportalEvent) nsUpload.uploadCareportalEntryToNS(jsonObject)
nsUpload.uploadCareportalEntryToNS(jsonObject) }
} }
} }
} catch (e: Exception) {
aapsLogger.error("Error while processing intent from Dexcom App", e)
} }
} catch (e: Exception) { return Result.success()
aapsLogger.error("Error while processing intent from Dexcom App", e)
} }
} }
companion object { companion object {
private val PACKAGE_NAMES = arrayOf("com.dexcom.cgm.region1.mgdl", "com.dexcom.cgm.region1.mmol", 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.cgm.region2.mgdl", "com.dexcom.cgm.region2.mmol",
"com.dexcom.g6.region1.mmol", "com.dexcom.g6.region2.mgdl", "com.dexcom.g6.region1.mmol", "com.dexcom.g6.region2.mgdl",

View file

@ -1,6 +1,8 @@
package info.nightscout.androidaps.plugins.source 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 dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Constants import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.MainApp
@ -14,6 +16,7 @@ import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
import info.nightscout.androidaps.receivers.BundleStore
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP import info.nightscout.androidaps.utils.sharedPreferences.SP
@ -26,11 +29,8 @@ import javax.inject.Singleton
@Singleton @Singleton
class EversensePlugin @Inject constructor( class EversensePlugin @Inject constructor(
injector: HasAndroidInjector, injector: HasAndroidInjector,
private val sp: SP,
resourceHelper: ResourceHelper, resourceHelper: ResourceHelper,
aapsLogger: AAPSLogger, aapsLogger: AAPSLogger
private val dateUtil: DateUtil,
private val nsUpload: NSUpload
) : PluginBase(PluginDescription() ) : PluginBase(PluginDescription()
.mainType(PluginType.BGSOURCE) .mainType(PluginType.BGSOURCE)
.fragmentClass(BGSourceFragment::class.java.name) .fragmentClass(BGSourceFragment::class.java.name)
@ -42,85 +42,98 @@ class EversensePlugin @Inject constructor(
aapsLogger, resourceHelper, injector aapsLogger, resourceHelper, injector
), BgSourceInterface { ), BgSourceInterface {
private var sensorBatteryLevel = -1 override var sensorBatteryLevel = -1
override fun advancedFilteringSupported(): Boolean { // cannot be inner class because of needed injection
return false class EversenseWorker(
} context: Context,
params: WorkerParameters
) : Worker(context, params) {
override fun handleNewData(intent: Intent) { @Inject lateinit var eversensePlugin: EversensePlugin
if (!isEnabled(PluginType.BGSOURCE)) return @Inject lateinit var aapsLogger: AAPSLogger
val bundle = intent.extras ?: return @Inject lateinit var sp: SP
if (bundle.containsKey("currentCalibrationPhase")) aapsLogger.debug(LTag.BGSOURCE, "currentCalibrationPhase: " + bundle.getString("currentCalibrationPhase")) @Inject lateinit var nsUpload: NSUpload
if (bundle.containsKey("placementModeInProgress")) aapsLogger.debug(LTag.BGSOURCE, "placementModeInProgress: " + bundle.getBoolean("placementModeInProgress")) @Inject lateinit var dateUtil: DateUtil
if (bundle.containsKey("glucoseLevel")) aapsLogger.debug(LTag.BGSOURCE, "glucoseLevel: " + bundle.getInt("glucoseLevel")) @Inject lateinit var bundleStore: BundleStore
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"))) init {
if (bundle.containsKey("batteryLevel")) { (context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
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...
} }
if (bundle.containsKey("signalStrength")) aapsLogger.debug(LTag.BGSOURCE, "signalStrength: " + bundle.getString("signalStrength"))
if (bundle.containsKey("transmitterVersionNumber")) aapsLogger.debug(LTag.BGSOURCE, "transmitterVersionNumber: " + bundle.getString("transmitterVersionNumber")) override fun doWork(): Result {
if (bundle.containsKey("isXLVersion")) aapsLogger.debug(LTag.BGSOURCE, "isXLVersion: " + bundle.getBoolean("isXLVersion")) if (!eversensePlugin.isEnabled(PluginType.BGSOURCE)) return Result.failure()
if (bundle.containsKey("transmitterModelNumber")) aapsLogger.debug(LTag.BGSOURCE, "transmitterModelNumber: " + bundle.getString("transmitterModelNumber")) val bundle = bundleStore.pickup(inputData.getLong("storeKey", -1))
if (bundle.containsKey("transmitterSerialNumber")) aapsLogger.debug(LTag.BGSOURCE, "transmitterSerialNumber: " + bundle.getString("transmitterSerialNumber")) ?: return Result.failure()
if (bundle.containsKey("transmitterAddress")) aapsLogger.debug(LTag.BGSOURCE, "transmitterAddress: " + bundle.getString("transmitterAddress")) if (bundle.containsKey("currentCalibrationPhase")) aapsLogger.debug(LTag.BGSOURCE, "currentCalibrationPhase: " + bundle.getString("currentCalibrationPhase"))
if (bundle.containsKey("sensorInsertionTimestamp")) aapsLogger.debug(LTag.BGSOURCE, "sensorInsertionTimestamp: " + dateUtil.dateAndTimeString(bundle.getLong("sensorInsertionTimestamp"))) if (bundle.containsKey("placementModeInProgress")) aapsLogger.debug(LTag.BGSOURCE, "placementModeInProgress: " + bundle.getBoolean("placementModeInProgress"))
if (bundle.containsKey("transmitterVersionNumber")) aapsLogger.debug(LTag.BGSOURCE, "transmitterVersionNumber: " + bundle.getString("transmitterVersionNumber")) if (bundle.containsKey("glucoseLevel")) aapsLogger.debug(LTag.BGSOURCE, "glucoseLevel: " + bundle.getInt("glucoseLevel"))
if (bundle.containsKey("transmitterConnectionState")) aapsLogger.debug(LTag.BGSOURCE, "transmitterConnectionState: " + bundle.getString("transmitterConnectionState")) if (bundle.containsKey("glucoseTrendDirection")) aapsLogger.debug(LTag.BGSOURCE, "glucoseTrendDirection: " + bundle.getString("glucoseTrendDirection"))
if (bundle.containsKey("glucoseLevels")) { if (bundle.containsKey("glucoseTimestamp")) aapsLogger.debug(LTag.BGSOURCE, "glucoseTimestamp: " + dateUtil.dateAndTimeString(bundle.getLong("glucoseTimestamp")))
val glucoseLevels = bundle.getIntArray("glucoseLevels") if (bundle.containsKey("batteryLevel")) {
val glucoseRecordNumbers = bundle.getIntArray("glucoseRecordNumbers") aapsLogger.debug(LTag.BGSOURCE, "batteryLevel: " + bundle.getString("batteryLevel"))
val glucoseTimestamps = bundle.getLongArray("glucoseTimestamps") //sensorBatteryLevel = bundle.getString("batteryLevel").toInt()
if (glucoseLevels != null && glucoseRecordNumbers != null && glucoseTimestamps != null) { // TODO: Philoul: Line to check I don't have eversense so I don't know what kind of information is sent...
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)
}
}
} }
} if (bundle.containsKey("signalStrength")) aapsLogger.debug(LTag.BGSOURCE, "signalStrength: " + bundle.getString("signalStrength"))
if (bundle.containsKey("calibrationGlucoseLevels")) { if (bundle.containsKey("transmitterVersionNumber")) aapsLogger.debug(LTag.BGSOURCE, "transmitterVersionNumber: " + bundle.getString("transmitterVersionNumber"))
val calibrationGlucoseLevels = bundle.getIntArray("calibrationGlucoseLevels") if (bundle.containsKey("isXLVersion")) aapsLogger.debug(LTag.BGSOURCE, "isXLVersion: " + bundle.getBoolean("isXLVersion"))
val calibrationTimestamps = bundle.getLongArray("calibrationTimestamps") if (bundle.containsKey("transmitterModelNumber")) aapsLogger.debug(LTag.BGSOURCE, "transmitterModelNumber: " + bundle.getString("transmitterModelNumber"))
val calibrationRecordNumbers = bundle.getLongArray("calibrationRecordNumbers") if (bundle.containsKey("transmitterSerialNumber")) aapsLogger.debug(LTag.BGSOURCE, "transmitterSerialNumber: " + bundle.getString("transmitterSerialNumber"))
if (calibrationGlucoseLevels != null && calibrationTimestamps != null && calibrationRecordNumbers != null) { if (bundle.containsKey("transmitterAddress")) aapsLogger.debug(LTag.BGSOURCE, "transmitterAddress: " + bundle.getString("transmitterAddress"))
aapsLogger.debug(LTag.BGSOURCE, "calibrationGlucoseLevels" + Arrays.toString(calibrationGlucoseLevels)) if (bundle.containsKey("sensorInsertionTimestamp")) aapsLogger.debug(LTag.BGSOURCE, "sensorInsertionTimestamp: " + dateUtil.dateAndTimeString(bundle.getLong("sensorInsertionTimestamp")))
aapsLogger.debug(LTag.BGSOURCE, "calibrationTimestamps" + Arrays.toString(calibrationTimestamps)) if (bundle.containsKey("transmitterVersionNumber")) aapsLogger.debug(LTag.BGSOURCE, "transmitterVersionNumber: " + bundle.getString("transmitterVersionNumber"))
aapsLogger.debug(LTag.BGSOURCE, "calibrationRecordNumbers" + Arrays.toString(calibrationRecordNumbers)) if (bundle.containsKey("transmitterConnectionState")) aapsLogger.debug(LTag.BGSOURCE, "transmitterConnectionState: " + bundle.getString("transmitterConnectionState"))
for (i in calibrationGlucoseLevels.indices) { if (bundle.containsKey("glucoseLevels")) {
try { val glucoseLevels = bundle.getIntArray("glucoseLevels")
if (MainApp.getDbHelper().getCareportalEventFromTimestamp(calibrationTimestamps[i]) == null) { val glucoseRecordNumbers = bundle.getIntArray("glucoseRecordNumbers")
val data = JSONObject() val glucoseTimestamps = bundle.getLongArray("glucoseTimestamps")
data.put("enteredBy", "AndroidAPS-Eversense") if (glucoseLevels != null && glucoseRecordNumbers != null && glucoseTimestamps != null) {
data.put("created_at", DateUtil.toISOString(calibrationTimestamps[i])) aapsLogger.debug(LTag.BGSOURCE, "glucoseLevels" + Arrays.toString(glucoseLevels))
data.put("eventType", CareportalEvent.BGCHECK) aapsLogger.debug(LTag.BGSOURCE, "glucoseRecordNumbers" + Arrays.toString(glucoseRecordNumbers))
data.put("glucoseType", "Finger") aapsLogger.debug(LTag.BGSOURCE, "glucoseTimestamps" + Arrays.toString(glucoseTimestamps))
data.put("glucose", calibrationGlucoseLevels[i]) for (i in glucoseLevels.indices) {
data.put("units", Constants.MGDL) val bgReading = BgReading()
nsUpload.uploadCareportalEntryToNS(data) 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 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 dagger.android.HasAndroidInjector
import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R 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.PluginDescription
import info.nightscout.androidaps.interfaces.PluginType import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.BundleLogger
import info.nightscout.androidaps.logging.LTag import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import javax.inject.Inject import javax.inject.Inject
@ -31,19 +32,29 @@ class GlimpPlugin @Inject constructor(
aapsLogger, resourceHelper, injector aapsLogger, resourceHelper, injector
), BgSourceInterface { ), BgSourceInterface {
override fun advancedFilteringSupported(): Boolean { // cannot be inner class because of needed injection
return false class GlimpWorker(
} context: Context,
params: WorkerParameters
) : Worker(context, params) {
override fun handleNewData(intent: Intent) { @Inject lateinit var glimpPlugin: GlimpPlugin
if (!isEnabled(PluginType.BGSOURCE)) return @Inject lateinit var aapsLogger: AAPSLogger
val bundle = intent.extras ?: return
aapsLogger.debug(LTag.BGSOURCE, "Received Glimp Data: ${BundleLogger.log(bundle)}") init {
val bgReading = BgReading() (context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
bgReading.value = bundle.getDouble("mySGV") }
bgReading.direction = bundle.getString("myTrend")
bgReading.date = bundle.getLong("myTimestamp") override fun doWork(): Result {
bgReading.raw = 0.0 if (!glimpPlugin.isEnabled(PluginType.BGSOURCE)) return Result.failure()
MainApp.getDbHelper().createIfNotExists(bgReading, "GLIMP") 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 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 dagger.android.HasAndroidInjector
import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
@ -31,39 +33,49 @@ class MM640gPlugin @Inject constructor(
aapsLogger, resourceHelper, injector aapsLogger, resourceHelper, injector
), BgSourceInterface { ), BgSourceInterface {
override fun advancedFilteringSupported(): Boolean { // cannot be inner class because of needed injection
return false class MM640gWorker(
} context: Context,
params: WorkerParameters
) : Worker(context, params) {
override fun handleNewData(intent: Intent) { @Inject lateinit var mM640gPlugin: MM640gPlugin
if (!isEnabled(PluginType.BGSOURCE)) return @Inject lateinit var aapsLogger: AAPSLogger
val bundle = intent.extras ?: return
val collection = bundle.getString("collection") ?: return init {
if (collection == "entries") { (context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
val data = bundle.getString("data") }
aapsLogger.debug(LTag.BGSOURCE, "Received MM640g Data: $data")
if (data != null && data.isNotEmpty()) { override fun doWork(): Result {
try { if (!mM640gPlugin.isEnabled(PluginType.BGSOURCE)) return Result.failure()
val jsonArray = JSONArray(data) val collection = inputData.getString("collection") ?: return Result.failure()
for (i in 0 until jsonArray.length()) { if (collection == "entries") {
val jsonObject = jsonArray.getJSONObject(i) val data = inputData.getString("data")
when (val type = jsonObject.getString("type")) { aapsLogger.debug(LTag.BGSOURCE, "Received MM640g Data: $data")
"sgv" -> { if (data != null && data.isNotEmpty()) {
val bgReading = BgReading() try {
bgReading.value = jsonObject.getDouble("sgv") val jsonArray = JSONArray(data)
bgReading.direction = jsonObject.getString("direction") for (i in 0 until jsonArray.length()) {
bgReading.date = jsonObject.getLong("date") val jsonObject = jsonArray.getJSONObject(i)
bgReading.raw = jsonObject.getDouble("sgv") when (val type = jsonObject.getString("type")) {
MainApp.getDbHelper().createIfNotExists(bgReading, "MM640g") "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 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 dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Config import info.nightscout.androidaps.Config
import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.MainApp
@ -27,7 +29,6 @@ class NSClientSourcePlugin @Inject constructor(
injector: HasAndroidInjector, injector: HasAndroidInjector,
resourceHelper: ResourceHelper, resourceHelper: ResourceHelper,
aapsLogger: AAPSLogger, aapsLogger: AAPSLogger,
private val sp: SP,
config: Config config: Config
) : PluginBase(PluginDescription() ) : PluginBase(PluginDescription()
.mainType(PluginType.BGSOURCE) .mainType(PluginType.BGSOURCE)
@ -53,32 +54,6 @@ class NSClientSourcePlugin @Inject constructor(
return isAdvancedFilteringEnabled 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) { private fun storeSgv(sgvJson: JSONObject) {
val nsSgv = NSSgv(sgvJson) val nsSgv = NSSgv(sgvJson)
val bgReading = BgReading(injector, nsSgv) val bgReading = BgReading(injector, nsSgv)
@ -92,4 +67,44 @@ class NSClientSourcePlugin @Inject constructor(
lastBGTimeStamp = timeStamp 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 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 dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Constants import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.MainApp
@ -25,9 +27,7 @@ import javax.inject.Singleton
class PoctechPlugin @Inject constructor( class PoctechPlugin @Inject constructor(
injector: HasAndroidInjector, injector: HasAndroidInjector,
resourceHelper: ResourceHelper, resourceHelper: ResourceHelper,
aapsLogger: AAPSLogger, aapsLogger: AAPSLogger
private val sp: SP,
private val nsUpload: NSUpload
) : PluginBase(PluginDescription() ) : PluginBase(PluginDescription()
.mainType(PluginType.BGSOURCE) .mainType(PluginType.BGSOURCE)
.fragmentClass(BGSourceFragment::class.java.name) .fragmentClass(BGSourceFragment::class.java.name)
@ -38,36 +38,48 @@ class PoctechPlugin @Inject constructor(
aapsLogger, resourceHelper, injector aapsLogger, resourceHelper, injector
), BgSourceInterface { ), BgSourceInterface {
override fun advancedFilteringSupported(): Boolean { // cannot be inner class because of needed injection
return false class PoctechWorker(
} context: Context,
params: WorkerParameters
) : Worker(context, params) {
override fun handleNewData(intent: Intent) { @Inject lateinit var poctechPlugin: PoctechPlugin
if (!isEnabled(PluginType.BGSOURCE)) return @Inject lateinit var aapsLogger: AAPSLogger
val bundle = intent.extras ?: return @Inject lateinit var sp: SP
val bgReading = BgReading() @Inject lateinit var nsUpload: NSUpload
val data = bundle.getString("data")
aapsLogger.debug(LTag.BGSOURCE, "Received Poctech Data $data") init {
try { (context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
val jsonArray = JSONArray(data) }
aapsLogger.debug(LTag.BGSOURCE, "Received Poctech Data size:" + jsonArray.length())
for (i in 0 until jsonArray.length()) { override fun doWork(): Result {
val json = jsonArray.getJSONObject(i) if (!poctechPlugin.isEnabled(PluginType.BGSOURCE)) return Result.failure()
bgReading.value = json.getDouble("current") aapsLogger.debug(LTag.BGSOURCE, "Received Poctech Data $inputData")
bgReading.direction = json.getString("direction") try {
bgReading.date = json.getLong("date") val jsonArray = JSONArray(inputData.getString("data"))
bgReading.raw = json.getDouble("raw") aapsLogger.debug(LTag.BGSOURCE, "Received Poctech Data size:" + jsonArray.length())
if (safeGetString(json, "units", Constants.MGDL) == "mmol/L") bgReading.value = bgReading.value * Constants.MMOLL_TO_MGDL for (i in 0 until jsonArray.length()) {
val isNew = MainApp.getDbHelper().createIfNotExists(bgReading, "Poctech") val json = jsonArray.getJSONObject(i)
if (isNew && sp.getBoolean(R.string.key_dexcomg5_nsupload, false)) { val bgReading = BgReading()
nsUpload.uploadBg(bgReading, "AndroidAPS-Poctech") bgReading.value = json.getDouble("current")
} bgReading.direction = json.getString("direction")
if (isNew && sp.getBoolean(R.string.key_dexcomg5_xdripupload, false)) { bgReading.date = json.getLong("date")
nsUpload.sendToXdrip(bgReading) 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) { return Result.success()
aapsLogger.error("Exception: ", e)
} }
} }
} }

View file

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

View file

@ -1,6 +1,8 @@
package info.nightscout.androidaps.plugins.source 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 dagger.android.HasAndroidInjector
import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
@ -21,9 +23,7 @@ import javax.inject.Singleton
class TomatoPlugin @Inject constructor( class TomatoPlugin @Inject constructor(
injector: HasAndroidInjector, injector: HasAndroidInjector,
resourceHelper: ResourceHelper, resourceHelper: ResourceHelper,
aapsLogger: AAPSLogger, aapsLogger: AAPSLogger
private val sp: SP,
private val nsUpload: NSUpload
) : PluginBase(PluginDescription() ) : PluginBase(PluginDescription()
.mainType(PluginType.BGSOURCE) .mainType(PluginType.BGSOURCE)
.fragmentClass(BGSourceFragment::class.java.name) .fragmentClass(BGSourceFragment::class.java.name)
@ -35,23 +35,35 @@ class TomatoPlugin @Inject constructor(
aapsLogger, resourceHelper, injector aapsLogger, resourceHelper, injector
), BgSourceInterface { ), BgSourceInterface {
override fun advancedFilteringSupported(): Boolean { // cannot be inner class because of needed injection
return false class TomatoWorker(
} context: Context,
params: WorkerParameters
) : Worker(context, params) {
override fun handleNewData(intent: Intent) { @Inject lateinit var tomatoPlugin: TomatoPlugin
if (!isEnabled(PluginType.BGSOURCE)) return @Inject lateinit var aapsLogger: AAPSLogger
val bundle = intent.extras ?: return @Inject lateinit var sp: SP
val bgReading = BgReading() @Inject lateinit var nsUpload: NSUpload
aapsLogger.debug(LTag.BGSOURCE, "Received Tomato Data")
bgReading.value = bundle.getDouble("com.fanqies.tomatofn.Extras.BgEstimate") init {
bgReading.date = bundle.getLong("com.fanqies.tomatofn.Extras.Time") (context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
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) 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 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 dagger.android.HasAndroidInjector
import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R 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.PluginDescription
import info.nightscout.androidaps.interfaces.PluginType import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.BundleLogger
import info.nightscout.androidaps.logging.LTag import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.services.Intents import info.nightscout.androidaps.services.Intents
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
@ -32,32 +33,41 @@ class XdripPlugin @Inject constructor(
), BgSourceInterface { ), BgSourceInterface {
private var advancedFiltering = false private var advancedFiltering = false
private var sensorBatteryLevel = -1 override var sensorBatteryLevel = -1
override fun advancedFilteringSupported(): Boolean { override fun advancedFilteringSupported(): Boolean {
return advancedFiltering 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) { private fun setSource(source: String) {
advancedFiltering = source.contains("G5 Native") || source.contains("G6 Native") advancedFiltering = source.contains("G5 Native") || source.contains("G6 Native")
} }
override fun getSensorBatteryLevel(): Int { // cannot be inner class because of needed injection
return sensorBatteryLevel 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

@ -0,0 +1,24 @@
package info.nightscout.androidaps.receivers
import android.os.Bundle
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class BundleStore @Inject constructor() {
private val store = HashMap<Long, Bundle>()
private var counter = 0L
@Synchronized
fun store(bundle: Bundle) : Long {
store.put(counter, bundle)
return counter++
}
@Synchronized
fun pickup(key: Long) : Bundle? {
val bundle = store[key]
store.remove(key)
return bundle
}
}

View file

@ -2,23 +2,118 @@ package info.nightscout.androidaps.receivers
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import androidx.legacy.content.* import android.provider.Telephony
import dagger.android.AndroidInjection import androidx.work.Data
import androidx.work.ExistingWorkPolicy
import androidx.work.OneTimeWorkRequest
import androidx.work.WorkManager
import dagger.android.DaggerBroadcastReceiver
import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.BundleLogger
import info.nightscout.androidaps.logging.LTag 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 org.json.JSONObject
import javax.inject.Inject import javax.inject.Inject
// We are not ready to switch to JobScheduler open class DataReceiver : DaggerBroadcastReceiver() {
@Suppress("DEPRECATION")
open class DataReceiver : WakefulBroadcastReceiver() {
@Inject lateinit var aapsLogger: AAPSLogger @Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var bundleStore: BundleStore
private val jobGroupName = "data"
override fun onReceive(context: Context, intent: Intent) { override fun onReceive(context: Context, intent: Intent) {
AndroidInjection.inject(this, context) super.onReceive(context, intent)
aapsLogger.debug(LTag.DATASERVICE, "onReceive $intent") val bundle = intent.extras ?: return
startWakefulService(context, Intent(context, DataService::class.java) aapsLogger.debug(LTag.DATASERVICE, "onReceive ${intent.action} ${BundleLogger.log(bundle)}")
.setAction(intent.action)
.putExtras(intent))
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.putLong("storeKey", bundleStore.store(bundle))
it.putString("action", intent.action)
}.build()).build()
Intents.EVERSENSE_BG ->
OneTimeWorkRequest.Builder(EversensePlugin.EversenseWorker::class.java)
.setInputData(Data.Builder().also {
it.putLong("storeKey", bundleStore.store(bundle))
it.putString("action", intent.action)
}.build()).build()
Intents.DEXCOM_BG ->
OneTimeWorkRequest.Builder(DexcomPlugin.DexcomWorker::class.java)
.setInputData(Data.Builder().also {
it.putLong("storeKey", bundleStore.store(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.putLong("storeKey", bundleStore.store(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' constraintlayout_version = '2.0.4'
preferencektx_version = '1.1.1' preferencektx_version = '1.1.1'
commonslang3_version = '3.11' commonslang3_version = '3.11'
work_version = '2.4.0' work_version = '2.5.0'
junit_version = '4.13.1' junit_version = '4.13.1'
mockitoVersion = '2.8.47' 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
}