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" />
</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,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
import android.content.Intent
import android.content.Context
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 dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Config
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.treatments.TreatmentsPlugin
import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.receivers.BundleStore
import info.nightscout.androidaps.utils.*
import info.nightscout.androidaps.utils.extensions.plusAssign
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?) {
if (ev == null || ev.isChanged(resourceHelper, R.string.key_smscommunicator_allowednumbers)) {
val settings = sp.getString(R.string.key_smscommunicator_allowednumbers, "")
@ -180,16 +209,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.")

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,11 @@
package info.nightscout.androidaps.plugins.source
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import androidx.core.content.ContextCompat
import androidx.work.Worker
import androidx.work.WorkerParameters
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Config
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.logging.AAPSLogger
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.T
import info.nightscout.androidaps.utils.resources.ResourceHelper
@ -29,11 +33,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,11 +75,30 @@ class DexcomPlugin @Inject constructor(
return null
}
override fun handleNewData(intent: Intent) {
if (!isEnabled(PluginType.BGSOURCE)) return
// 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
@Inject lateinit var bundleStore: BundleStore
init {
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
}
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 = intent.getStringExtra("sensorType") ?: ""
val glucoseValues = intent.getBundleExtra("glucoseValues")
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()
@ -95,7 +116,7 @@ class DexcomPlugin @Inject constructor(
}
}
}
val meters = intent.getBundleExtra("meters")
bundle.getBundle("meters")?.let { meters ->
for (i in 0 until meters.size()) {
val meter = meters.getBundle(i.toString())
meter?.let {
@ -121,8 +142,9 @@ class DexcomPlugin @Inject constructor(
}
}
}
if (sp.getBoolean(R.string.key_dexcom_lognssensorchange, false) && intent.hasExtra("sensorInsertionTime")) {
intent.extras?.let {
}
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)
@ -144,9 +166,12 @@ class DexcomPlugin @Inject constructor(
} 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,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
@ -14,6 +16,7 @@ import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
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.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
@ -26,11 +29,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,15 +42,29 @@ 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) {
@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
@Inject lateinit var bundleStore: BundleStore
init {
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
}
override fun handleNewData(intent: Intent) {
if (!isEnabled(PluginType.BGSOURCE)) return
val bundle = intent.extras ?: return
override fun doWork(): Result {
if (!eversensePlugin.isEnabled(PluginType.BGSOURCE)) return Result.failure()
val bundle = bundleStore.pickup(inputData.getLong("storeKey", -1))
?: return Result.failure()
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"))
@ -58,7 +72,8 @@ class EversensePlugin @Inject constructor(
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...
//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("signalStrength")) aapsLogger.debug(LTag.BGSOURCE, "signalStrength: " + bundle.getString("signalStrength"))
if (bundle.containsKey("transmitterVersionNumber")) aapsLogger.debug(LTag.BGSOURCE, "transmitterVersionNumber: " + bundle.getString("transmitterVersionNumber"))
@ -118,9 +133,7 @@ class EversensePlugin @Inject constructor(
}
}
}
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) {
@Inject lateinit var glimpPlugin: GlimpPlugin
@Inject lateinit var aapsLogger: AAPSLogger
init {
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
}
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)}")
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 = bundle.getDouble("mySGV")
bgReading.direction = bundle.getString("myTrend")
bgReading.date = bundle.getLong("myTimestamp")
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,16 +33,24 @@ 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) {
@Inject lateinit var mM640gPlugin: MM640gPlugin
@Inject lateinit var aapsLogger: AAPSLogger
init {
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
}
override fun handleNewData(intent: Intent) {
if (!isEnabled(PluginType.BGSOURCE)) return
val bundle = intent.extras ?: return
val collection = bundle.getString("collection") ?: return
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 = bundle.getString("data")
val data = inputData.getString("data")
aapsLogger.debug(LTag.BGSOURCE, "Received MM640g Data: $data")
if (data != null && data.isNotEmpty()) {
try {
@ -65,5 +75,7 @@ class MM640gPlugin @Inject constructor(
}
}
}
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,21 +38,30 @@ 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) {
@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 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")
override fun doWork(): Result {
if (!poctechPlugin.isEnabled(PluginType.BGSOURCE)) return Result.failure()
aapsLogger.debug(LTag.BGSOURCE, "Received Poctech Data $inputData")
try {
val jsonArray = JSONArray(data)
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")
@ -68,6 +77,9 @@ class PoctechPlugin @Inject constructor(
}
} catch (e: JSONException) {
aapsLogger.error("Exception: ", e)
return Result.failure()
}
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,17 +35,27 @@ 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) {
@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)
}
override fun handleNewData(intent: Intent) {
if (!isEnabled(PluginType.BGSOURCE)) return
val bundle = intent.extras ?: return
override fun doWork(): Result {
if (!tomatoPlugin.isEnabled(PluginType.BGSOURCE)) return Result.failure()
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")
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")
@ -53,5 +63,7 @@ class TomatoPlugin @Inject constructor(
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

@ -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.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 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 org.json.JSONObject
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
@Inject lateinit var bundleStore: BundleStore
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.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'
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
}