bypass Intents on NS received data

This commit is contained in:
Milos Kozak 2021-03-20 20:31:44 +01:00
parent 98c7508383
commit 415729f243
15 changed files with 361 additions and 408 deletions

View file

@ -5,7 +5,6 @@ import android.content.Intent
import android.content.IntentFilter
import android.net.ConnectivityManager
import android.net.wifi.WifiManager
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import com.j256.ormlite.android.apptools.OpenHelperManager
import dagger.android.AndroidInjector
import dagger.android.DaggerApplication
@ -24,11 +23,9 @@ import info.nightscout.androidaps.plugins.constraints.versionChecker.VersionChec
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
import info.nightscout.androidaps.receivers.BTReceiver
import info.nightscout.androidaps.receivers.ChargingStateReceiver
import info.nightscout.androidaps.receivers.DataReceiver
import info.nightscout.androidaps.receivers.KeepAliveReceiver.KeepAliveManager
import info.nightscout.androidaps.receivers.NetworkChangeReceiver
import info.nightscout.androidaps.receivers.TimeDateOrTZChangeReceiver
import info.nightscout.androidaps.services.Intents
import info.nightscout.androidaps.utils.ActivityMonitor
import info.nightscout.androidaps.utils.locale.LocaleHelper.update
import info.nightscout.androidaps.utils.sharedPreferences.SP
@ -102,11 +99,6 @@ class MainApp : DaggerApplication() {
private fun registerLocalBroadcastReceiver() {
var filter = IntentFilter()
filter.addAction(Intents.ACTION_NEW_TREATMENT)
filter.addAction(Intents.ACTION_CHANGED_TREATMENT)
filter.addAction(Intents.ACTION_REMOVED_TREATMENT)
LocalBroadcastManager.getInstance(this).registerReceiver(DataReceiver(), filter)
filter = IntentFilter()
filter.addAction(Intent.ACTION_TIME_CHANGED)
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED)
registerReceiver(TimeDateOrTZChangeReceiver(), filter)

View file

@ -67,6 +67,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
@Inject RxBusWrapper rxBus;
@Inject VirtualPumpPlugin virtualPumpPlugin;
@Inject OpenHumansUploader openHumansUploader;
@Inject ActivePluginProvider activePlugin;
@Inject NSUpload nsUpload;
public static final String DATABASE_NAME = "AndroidAPSDb";
public static final String DATABASE_EXTENDEDBOLUSES = "ExtendedBoluses";
@ -1216,7 +1218,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
}
*/
public void createProfileSwitchFromJsonIfNotExists(ActivePluginProvider activePluginProvider, NSUpload nsUpload, JSONObject trJson) {
public void createProfileSwitchFromJsonIfNotExists(JSONObject trJson) {
try {
ProfileSwitch profileSwitch = new ProfileSwitch(StaticInjector.Companion.getInstance());
profileSwitch.date = trJson.getLong("mills");
@ -1233,7 +1235,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
if (trJson.has("profileJson"))
profileSwitch.profileJson = trJson.getString("profileJson");
else {
ProfileInterface profileInterface = activePluginProvider.getActiveProfileInterface();
ProfileInterface profileInterface = activePlugin.getActiveProfileInterface();
ProfileStore store = profileInterface.getProfile();
if (store != null) {
Profile profile = store.getSpecificProfile(profileSwitch.profileName);

View file

@ -14,9 +14,7 @@ import javax.inject.Inject;
import javax.inject.Singleton;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.interfaces.ActivePluginProvider;
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface;
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
@Singleton
public class DatabaseHelperProvider implements DatabaseHelperInterface {
@ -172,8 +170,8 @@ public class DatabaseHelperProvider implements DatabaseHelperInterface {
MainApp.Companion.getDbHelper().createExtendedBolusFromJsonIfNotExists(json);
}
@Override public void createProfileSwitchFromJsonIfNotExists(@NonNull ActivePluginProvider activePluginProvider, @NonNull NSUpload nsUpload, @NonNull JSONObject trJson) {
MainApp.Companion.getDbHelper().createProfileSwitchFromJsonIfNotExists(activePluginProvider, nsUpload, trJson);
@Override public void createProfileSwitchFromJsonIfNotExists(@NonNull JSONObject trJson) {
MainApp.Companion.getDbHelper().createProfileSwitchFromJsonIfNotExists(trJson);
}
@Override public void resetDatabases() {

View file

@ -3,8 +3,9 @@ package info.nightscout.androidaps.dependencyInjection
import dagger.Module
import dagger.android.ContributesAndroidInjector
import info.nightscout.androidaps.plugins.general.food.FoodPlugin
import info.nightscout.androidaps.plugins.general.nsclient.NSClientAddUpdateWorker
import info.nightscout.androidaps.plugins.general.nsclient.NSClientMbgWorker
import info.nightscout.androidaps.plugins.general.nsclient.NSClientWorker
import info.nightscout.androidaps.plugins.general.nsclient.NSClientRemoveWorker
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin
import info.nightscout.androidaps.plugins.profile.ns.NSProfilePlugin
import info.nightscout.androidaps.plugins.source.*
@ -23,7 +24,8 @@ abstract class WorkersModule {
@ContributesAndroidInjector abstract fun contributesNSClientSourceWorker(): NSClientSourcePlugin.NSClientSourceWorker
@ContributesAndroidInjector abstract fun contributesNSProfileWorker(): NSProfilePlugin.NSProfileWorker
@ContributesAndroidInjector abstract fun contributesSmsCommunicatorWorker(): SmsCommunicatorPlugin.SmsCommunicatorWorker
@ContributesAndroidInjector abstract fun contributesNSClientWorker(): NSClientWorker
@ContributesAndroidInjector abstract fun contributesNSClientWorker(): NSClientAddUpdateWorker
@ContributesAndroidInjector abstract fun contributesNSClientRemoveWorker(): NSClientRemoveWorker
@ContributesAndroidInjector abstract fun contributesNSClientMbgWorker(): NSClientMbgWorker
@ContributesAndroidInjector abstract fun contributesFoodWorker(): FoodPlugin.FoodWorker
}

View file

@ -0,0 +1,178 @@
package info.nightscout.androidaps.plugins.general.nsclient
import android.content.Context
import androidx.work.Worker
import androidx.work.WorkerParameters
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.TherapyEvent
import info.nightscout.androidaps.database.entities.UserEntry
import info.nightscout.androidaps.database.entities.UserEntry.ValueWithUnit
import info.nightscout.androidaps.database.transactions.SyncTemporaryTargetTransaction
import info.nightscout.androidaps.database.transactions.SyncTherapyEventTransaction
import info.nightscout.androidaps.events.EventNsTreatment
import info.nightscout.androidaps.interfaces.ConfigInterface
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
import info.nightscout.androidaps.receivers.DataWorker
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.JsonHelper
import info.nightscout.androidaps.utils.JsonHelper.safeGetLong
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
import info.nightscout.androidaps.utils.extensions.temporaryTargetFromJson
import info.nightscout.androidaps.utils.extensions.therapyEventFromJson
import info.nightscout.androidaps.utils.sharedPreferences.SP
import javax.inject.Inject
class NSClientAddUpdateWorker(
context: Context,
params: WorkerParameters
) : Worker(context, params) {
@Inject lateinit var nsClientPlugin: NSClientPlugin
@Inject lateinit var dataWorker: DataWorker
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var buildHelper: BuildHelper
@Inject lateinit var sp: SP
@Inject lateinit var dateutil: DateUtil
@Inject lateinit var config: ConfigInterface
@Inject lateinit var repository: AppRepository
@Inject lateinit var databaseHelper: DatabaseHelperInterface
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var uel: UserEntryLogger
override fun doWork(): Result {
val acceptNSData = !sp.getBoolean(R.string.key_ns_upload_only, true) && buildHelper.isEngineeringMode() || config.NSCLIENT
if (!acceptNSData) return Result.failure()
val treatments = dataWorker.pickupJSONArray(inputData.getLong(DataWorker.STORE_KEY, -1))
?: return Result.failure()
var ret = Result.success()
var latestDateInReceivedData = 0L
for (i in 0 until treatments.length()) {
val json = treatments.getJSONObject(i)
// new DB model
val insulin = JsonHelper.safeGetDouble(json, "insulin")
val carbs = JsonHelper.safeGetDouble(json, "carbs")
val eventType = JsonHelper.safeGetString(json, "eventType")
if (eventType == null) {
aapsLogger.debug(LTag.DATASERVICE, "Wrong treatment. Ignoring : $json")
continue
}
//Find latest date in treatment
val mills = safeGetLong(json, "mills")
if (mills != 0L && mills < dateutil._now())
if (mills > latestDateInReceivedData) latestDateInReceivedData = mills
when {
insulin > 0 || carbs > 0 ->
rxBus.send(EventNsTreatment(EventNsTreatment.ADD, json))
eventType == TherapyEvent.Type.TEMPORARY_TARGET.text ->
temporaryTargetFromJson(json)?.let { temporaryTarget ->
repository.runTransactionForResult(SyncTemporaryTargetTransaction(temporaryTarget))
.doOnError {
aapsLogger.error(LTag.DATABASE, "Error while saving temporary target", it)
ret = Result.failure()
}
.blockingGet()
.also { result ->
result.inserted.forEach {
uel.log(UserEntry.Action.TT_FROM_NS,
ValueWithUnit(it.reason.text, UserEntry.Units.TherapyEvent),
ValueWithUnit(it.lowTarget, UserEntry.Units.Mg_Dl, true),
ValueWithUnit(it.highTarget, UserEntry.Units.Mg_Dl, it.lowTarget != it.highTarget),
ValueWithUnit(it.duration.toInt() / 60000, UserEntry.Units.M, true)
)
}
result.invalidated.forEach {
uel.log(UserEntry.Action.TT_DELETED_FROM_NS,
ValueWithUnit(it.reason.text, UserEntry.Units.TherapyEvent),
ValueWithUnit(it.lowTarget, UserEntry.Units.Mg_Dl, true),
ValueWithUnit(it.highTarget, UserEntry.Units.Mg_Dl, it.lowTarget != it.highTarget),
ValueWithUnit(it.duration.toInt() / 60000, UserEntry.Units.M, true)
)
}
result.ended.forEach {
uel.log(UserEntry.Action.TT_CANCELED_FROM_NS,
ValueWithUnit(it.reason.text, UserEntry.Units.TherapyEvent),
ValueWithUnit(it.lowTarget, UserEntry.Units.Mg_Dl, true),
ValueWithUnit(it.highTarget, UserEntry.Units.Mg_Dl, it.lowTarget != it.highTarget),
ValueWithUnit(it.duration.toInt() / 60000, UserEntry.Units.M, true)
)
}
}
} ?: aapsLogger.error("Error parsing TT json $json")
eventType == TherapyEvent.Type.CANNULA_CHANGE.text ||
eventType == TherapyEvent.Type.INSULIN_CHANGE.text ||
eventType == TherapyEvent.Type.SENSOR_CHANGE.text ||
eventType == TherapyEvent.Type.FINGER_STICK_BG_VALUE.text ||
eventType == TherapyEvent.Type.NOTE.text ||
eventType == TherapyEvent.Type.NONE.text ||
eventType == TherapyEvent.Type.ANNOUNCEMENT.text ||
eventType == TherapyEvent.Type.QUESTION.text ||
eventType == TherapyEvent.Type.EXERCISE.text ||
eventType == TherapyEvent.Type.APS_OFFLINE.text ||
eventType == TherapyEvent.Type.PUMP_BATTERY_CHANGE.text ->
therapyEventFromJson(json)?.let { therapyEvent ->
repository.runTransactionForResult(SyncTherapyEventTransaction(therapyEvent))
.doOnError {
aapsLogger.error(LTag.DATABASE, "Error while saving therapy event", it)
ret = Result.failure()
}
.blockingGet()
.also { result ->
result.inserted.forEach {
uel.log(UserEntry.Action.CAREPORTAL_FROM_NS,
it.note ?: "",
ValueWithUnit(it.timestamp, UserEntry.Units.Timestamp, true),
ValueWithUnit(it.type.text, UserEntry.Units.TherapyEvent)
)
}
result.invalidated.forEach {
uel.log(UserEntry.Action.CAREPORTAL_DELETED_FROM_NS,
it.note ?: "",
ValueWithUnit(it.timestamp, UserEntry.Units.Timestamp, true),
ValueWithUnit(it.type.text, UserEntry.Units.TherapyEvent)
)
}
}
} ?: aapsLogger.error("Error parsing TherapyEvent json $json")
eventType == TherapyEvent.Type.TEMPORARY_BASAL.text ->
databaseHelper.createTempBasalFromJsonIfNotExists(json)
eventType == TherapyEvent.Type.COMBO_BOLUS.text ->
databaseHelper.createExtendedBolusFromJsonIfNotExists(json)
eventType == TherapyEvent.Type.PROFILE_SWITCH.text ->
databaseHelper.createProfileSwitchFromJsonIfNotExists(json)
}
if (eventType == TherapyEvent.Type.ANNOUNCEMENT.text) {
val date = safeGetLong(json, "mills")
val now = System.currentTimeMillis()
val enteredBy = JsonHelper.safeGetString(json, "enteredBy", "")
val notes = JsonHelper.safeGetString(json, "notes", "")
if (date > now - 15 * 60 * 1000L && notes.isNotEmpty()
&& enteredBy != sp.getString("careportal_enteredby", "AndroidAPS")) {
val defaultVal = config.NSCLIENT
if (sp.getBoolean(R.string.key_ns_announcements, defaultVal)) {
val announcement = Notification(Notification.NS_ANNOUNCEMENT, notes, Notification.ANNOUNCEMENT, 60)
rxBus.send(EventNewNotification(announcement))
}
}
}
}
nsClientPlugin.updateLatestDateReceivedIfNewer(latestDateInReceivedData)
return ret
}
init {
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
}
}

View file

@ -4,13 +4,17 @@ import android.content.Context
import androidx.work.Worker
import androidx.work.WorkerParameters
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.transactions.SyncTherapyEventTransaction
import info.nightscout.androidaps.interfaces.ConfigInterface
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.general.nsclient.data.NSMbg
import info.nightscout.androidaps.receivers.DataWorker
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
import info.nightscout.androidaps.utils.extensions.therapyEventFromNsMbg
import info.nightscout.androidaps.utils.sharedPreferences.SP
import javax.inject.Inject
class NSClientMbgWorker(
@ -21,10 +25,16 @@ class NSClientMbgWorker(
@Inject lateinit var repository: AppRepository
@Inject lateinit var dataWorker: DataWorker
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var sp: SP
@Inject lateinit var buildHelper: BuildHelper
@Inject lateinit var config: ConfigInterface
override fun doWork(): Result {
var ret = Result.success()
val acceptNSData = !sp.getBoolean(R.string.key_ns_upload_only, true) && buildHelper.isEngineeringMode() || config.NSCLIENT
if (!acceptNSData) return ret
val mbgArray = dataWorker.pickupJSONArray(inputData.getLong(DataWorker.STORE_KEY, -1))
?: return Result.failure()
for (i in 0 until mbgArray.length()) {

View file

@ -353,149 +353,8 @@ 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);
}
}
public void updateLatestDateReceivedIfNewer(long latestReceived) {
if (latestReceived > nsClientService.latestDateInReceivedData)
nsClientService.latestDateInReceivedData = latestReceived;
}
private void handleRemovedTreatmentFromNS(JSONObject json) {
String _id = JsonHelper.safeGetString(json, "_id");
if (_id == null) return;
// room Temporary target
TemporaryTarget temporaryTarget = temporaryTargetFromNsIdForInvalidating(_id);
disposable.add(repository.runTransactionForResult(new SyncTemporaryTargetTransaction(temporaryTarget)).subscribe(
result -> result.getInvalidated().forEach(record -> uel.log(Action.TT_DELETED_FROM_NS, new ValueWithUnit(record.getReason().getText(), Units.TherapyEvent), new ValueWithUnit(record.getLowTarget(), Units.Mg_Dl, true), new ValueWithUnit(record.getHighTarget(), Units.Mg_Dl, record.getLowTarget() != record.getHighTarget()), new ValueWithUnit((int) record.getDuration()/60000, Units.M, record.getDuration() != 0))),
error -> aapsLogger.error(LTag.DATABASE, "Error while removing temporary target", error)));
// room Therapy Event
TherapyEvent therapyEvent = therapyEventFromNsIdForInvalidating(_id);
disposable.add(repository.runTransactionForResult(new SyncTherapyEventTransaction(therapyEvent)).subscribe(
result -> result.getInvalidated().forEach(record -> uel.log(Action.CAREPORTAL_DELETED_FROM_NS, record.getNote() != null ? record.getNote() : "" , new ValueWithUnit(record.getTimestamp(), Units.Timestamp, true), new ValueWithUnit(record.getType().getText(), Units.TherapyEvent))),
error -> aapsLogger.error(LTag.DATABASE, "Error while removing therapy event", error)));
// new DB model
EventNsTreatment evtTreatment = new EventNsTreatment(EventNsTreatment.Companion.getREMOVE(), json);
rxBus.send(evtTreatment);
// old DB model
databaseHelper.deleteTempBasalById(_id);
databaseHelper.deleteExtendedBolusById(_id);
databaseHelper.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(TherapyEvent.Type.TEMPORARY_TARGET.getText())) {
TemporaryTarget temporaryTarget = temporaryTargetFromJson(json);
if (temporaryTarget != null) {
disposable.add(repository.runTransactionForResult(new SyncTemporaryTargetTransaction(temporaryTarget))
.subscribe(
result -> {
result.getInserted().forEach(record -> uel.log(Action.TT_FROM_NS, new ValueWithUnit(record.getReason().getText(), Units.TherapyEvent), new ValueWithUnit(record.getLowTarget(), Units.Mg_Dl, true), new ValueWithUnit(record.getHighTarget(), Units.Mg_Dl, record.getLowTarget() != record.getHighTarget()), new ValueWithUnit((int) record.getDuration()/60000, Units.M, true)));
result.getInvalidated().forEach(record -> uel.log(Action.TT_DELETED_FROM_NS, new ValueWithUnit(record.getReason().getText(), Units.TherapyEvent), new ValueWithUnit(record.getLowTarget(), Units.Mg_Dl, true), new ValueWithUnit(record.getHighTarget(), Units.Mg_Dl, record.getLowTarget() != record.getHighTarget()), new ValueWithUnit((int) record.getDuration()/60000, Units.M, true)));
result.getEnded().forEach(record -> uel.log(Action.TT_CANCELED_FROM_NS, new ValueWithUnit(record.getReason().getText(), Units.TherapyEvent), new ValueWithUnit(record.getLowTarget(), Units.Mg_Dl, true), new ValueWithUnit(record.getHighTarget(), Units.Mg_Dl, record.getLowTarget() != record.getHighTarget()), new ValueWithUnit((int) record.getDuration()/60000, Units.M, true)));
},
error -> aapsLogger.error(LTag.DATABASE, "Error while saving temporary target", error)));
} else {
aapsLogger.error("Error parsing TT json " + json.toString());
}
} else if (eventType.equals(TherapyEvent.Type.TEMPORARY_BASAL.getText())) {
databaseHelper.createTempBasalFromJsonIfNotExists(json);
} else if (eventType.equals(TherapyEvent.Type.COMBO_BOLUS.getText())) {
databaseHelper.createExtendedBolusFromJsonIfNotExists(json);
} else if (eventType.equals(TherapyEvent.Type.PROFILE_SWITCH.getText())) {
databaseHelper.createProfileSwitchFromJsonIfNotExists(activePlugin, nsUpload, json);
} else if (eventType.equals(TherapyEvent.Type.CANNULA_CHANGE.getText()) ||
eventType.equals(TherapyEvent.Type.INSULIN_CHANGE.getText()) ||
eventType.equals(TherapyEvent.Type.SENSOR_CHANGE.getText()) ||
eventType.equals(TherapyEvent.Type.FINGER_STICK_BG_VALUE.getText()) ||
eventType.equals(TherapyEvent.Type.NOTE.getText()) ||
eventType.equals(TherapyEvent.Type.NONE.getText()) ||
eventType.equals(TherapyEvent.Type.ANNOUNCEMENT.getText()) ||
eventType.equals(TherapyEvent.Type.QUESTION.getText()) ||
eventType.equals(TherapyEvent.Type.EXERCISE.getText()) ||
eventType.equals(TherapyEvent.Type.APS_OFFLINE.getText()) ||
eventType.equals(TherapyEvent.Type.PUMP_BATTERY_CHANGE.getText())) {
TherapyEvent therapyEvent = therapyEventFromJson(json);
if (therapyEvent != null) {
disposable.add(repository.runTransactionForResult(new SyncTherapyEventTransaction(therapyEvent))
.subscribe(
result -> {
result.getInserted().forEach(record -> uel.log(Action.CAREPORTAL_FROM_NS, record.getNote() != null ? record.getNote() : "", new ValueWithUnit(record.getTimestamp(), Units.Timestamp, true), new ValueWithUnit(record.getType().getText(), Units.TherapyEvent)));
result.getInvalidated().forEach(record -> uel.log(Action.CAREPORTAL_DELETED_FROM_NS, record.getNote() != null ? record.getNote() : "" , new ValueWithUnit(record.getTimestamp(), Units.Timestamp, true), new ValueWithUnit(record.getType().getText(), Units.TherapyEvent)));
},
error -> aapsLogger.error(LTag.DATABASE, "Error while saving therapy event", error)));
} else {
aapsLogger.error("Error parsing TherapyEvent json " + json.toString());
}
}
if (eventType.equals(TherapyEvent.Type.ANNOUNCEMENT.getText())) {
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.NS_ANNOUNCEMENT, notes, Notification.ANNOUNCEMENT, 60);
rxBus.send(new EventNewNotification(announcement));
}
}
}
}
}

View file

@ -0,0 +1,111 @@
package info.nightscout.androidaps.plugins.general.nsclient
import android.content.Context
import androidx.work.Worker
import androidx.work.WorkerParameters
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.UserEntry
import info.nightscout.androidaps.database.entities.UserEntry.ValueWithUnit
import info.nightscout.androidaps.database.transactions.SyncTemporaryTargetTransaction
import info.nightscout.androidaps.database.transactions.SyncTherapyEventTransaction
import info.nightscout.androidaps.events.EventNsTreatment
import info.nightscout.androidaps.events.EventNsTreatment.Companion.REMOVE
import info.nightscout.androidaps.interfaces.ConfigInterface
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.receivers.DataWorker
import info.nightscout.androidaps.utils.JsonHelper
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
import info.nightscout.androidaps.utils.extensions.temporaryTargetFromNsIdForInvalidating
import info.nightscout.androidaps.utils.extensions.therapyEventFromNsIdForInvalidating
import info.nightscout.androidaps.utils.sharedPreferences.SP
import javax.inject.Inject
// This will not be needed fpr NS v3
// Now NS provides on _id of removed records
class NSClientRemoveWorker(
context: Context,
params: WorkerParameters) : Worker(context, params) {
@Inject lateinit var nsClientPlugin: NSClientPlugin
@Inject lateinit var dataWorker: DataWorker
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var buildHelper: BuildHelper
@Inject lateinit var sp: SP
@Inject lateinit var config: ConfigInterface
@Inject lateinit var repository: AppRepository
@Inject lateinit var databaseHelper: DatabaseHelperInterface
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var uel: UserEntryLogger
override fun doWork(): Result {
val acceptNSData = !sp.getBoolean(R.string.key_ns_upload_only, true) && buildHelper.isEngineeringMode() || config.NSCLIENT
if (!acceptNSData) return Result.failure()
var ret = Result.success()
val treatments = dataWorker.pickupJSONArray(inputData.getLong(DataWorker.STORE_KEY, -1))
?: return Result.failure()
for (i in 0 until treatments.length()) {
val json = treatments.getJSONObject(i)
val nsId = JsonHelper.safeGetString(json, "_id") ?: continue
// room Temporary target
val temporaryTarget = temporaryTargetFromNsIdForInvalidating(nsId)
repository.runTransactionForResult(SyncTemporaryTargetTransaction(temporaryTarget))
.doOnError {
aapsLogger.error(LTag.DATABASE, "Error while removing temporary target", it)
ret = Result.failure()
}
.blockingGet()
.also { result ->
result.invalidated.forEach {
uel.log(
UserEntry.Action.TT_DELETED_FROM_NS,
ValueWithUnit(it.reason.text, UserEntry.Units.TherapyEvent),
ValueWithUnit(it.lowTarget, UserEntry.Units.Mg_Dl, true),
ValueWithUnit(it.highTarget, UserEntry.Units.Mg_Dl, it.lowTarget != it.highTarget),
ValueWithUnit(it.duration.toInt() / 60000, UserEntry.Units.M, it.duration != 0L)
)
}
}
// room Therapy Event
val therapyEvent = therapyEventFromNsIdForInvalidating(nsId)
repository.runTransactionForResult(SyncTherapyEventTransaction(therapyEvent))
.doOnError {
aapsLogger.error(LTag.DATABASE, "Error while removing therapy event", it)
ret = Result.failure()
}
.blockingGet()
.also { result ->
result.invalidated.forEach {
uel.log(
UserEntry.Action.CAREPORTAL_DELETED_FROM_NS, (it.note ?: ""),
ValueWithUnit(it.timestamp, UserEntry.Units.Timestamp, true),
ValueWithUnit(it.type.text, UserEntry.Units.TherapyEvent))
}
}
// Insulin, carbs
rxBus.send(EventNsTreatment(REMOVE, json))
// old DB model
databaseHelper.deleteTempBasalById(nsId)
databaseHelper.deleteExtendedBolusById(nsId)
databaseHelper.deleteProfileSwitchById(nsId)
}
return ret
}
init {
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
}
}

View file

@ -1,37 +0,0 @@
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 javax.inject.Inject;
import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.receivers.DataWorker;
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 DataWorker dataWorker;
@NonNull
@Override
public Result doWork() {
Bundle bundle = dataWorker.pickupBundle(getInputData().getLong(DataWorker.STORE_KEY, -1));
if (bundle == null) return Result.failure();
String action = getInputData().getString(DataWorker.ACTION_KEY);
nsClientPlugin.handleNewDataFromNSClient(action, bundle);
return Result.success();
}
}

View file

@ -1,127 +0,0 @@
package info.nightscout.androidaps.plugins.general.nsclient.data;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import java.util.Date;
import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.logging.StacktraceLoggerWrapper;
public class NSTreatment {
private static final Logger log = StacktraceLoggerWrapper.getLogger(LTag.NSCLIENT);
private final JSONObject data;
private String action = null; // "update", "remove" or null (add)
public NSTreatment(JSONObject obj) {
this.data = obj;
this.action = getStringOrNull("action");
this.data.remove("action");
}
private String getStringOrNull(String key) {
String ret = null;
if (data.has(key)) {
try {
ret = data.getString(key);
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
}
return ret;
}
private Double getDoubleOrNull(String key) {
Double ret = null;
if (data.has(key)) {
try {
ret = data.getDouble(key);
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
}
return ret;
}
private Integer getIntegerOrNull(String key) {
Integer ret = null;
if (data.has(key)) {
try {
ret = data.getInt(key);
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
}
return ret;
}
private Long getLongOrNull(String key) {
Long ret = null;
if (data.has(key)) {
try {
ret = data.getLong(key);
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
}
return ret;
}
private Date getDateOrNull(String key) {
Date ret = null;
if (data.has(key)) {
try {
ret = new Date(data.getString(key));
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
}
return ret;
}
public String getAction() {
return action;
}
public JSONObject getData() {
return data;
}
public String get_id() {
return getStringOrNull("_id");
}
public String getEnteredBy() {
return getStringOrNull("enteredBy");
}
public String getEventType() {
return getStringOrNull("eventType");
}
public Integer getHapp_id() {
return getIntegerOrNull("happ_id");
}
public Integer getDuration() {
return getIntegerOrNull("duration");
}
public Integer getMgdl() {
return getIntegerOrNull("mgdl");
}
public Double getAbsolute() {
return getDoubleOrNull("absolute");
}
public Long getMills() {
return getLongOrNull("mills");
}
public Date getCreated_at() {
return getDateOrNull("created_at");
}
}

View file

@ -38,13 +38,14 @@ import info.nightscout.androidaps.events.EventConfigBuilderChange;
import info.nightscout.androidaps.events.EventPreferenceChange;
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface;
import info.nightscout.androidaps.interfaces.PluginType;
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;
import info.nightscout.androidaps.plugins.general.food.FoodPlugin;
import info.nightscout.androidaps.plugins.general.nsclient.NSClientAddUpdateWorker;
import info.nightscout.androidaps.plugins.general.nsclient.NSClientMbgWorker;
import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin;
import info.nightscout.androidaps.plugins.general.nsclient.NSClientRemoveWorker;
import info.nightscout.androidaps.plugins.general.nsclient.UploadQueue;
import info.nightscout.androidaps.plugins.general.nsclient.acks.NSAddAck;
import info.nightscout.androidaps.plugins.general.nsclient.acks.NSAuthAck;
@ -53,7 +54,6 @@ 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.NSDeviceStatus;
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus;
import info.nightscout.androidaps.plugins.general.nsclient.data.NSTreatment;
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientNewLog;
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart;
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientStatus;
@ -568,38 +568,54 @@ public class NSClientService extends DaggerService {
if (data.has("treatments")) {
JSONArray treatments = data.getJSONArray("treatments");
JSONArray removedTreatments = new JSONArray();
JSONArray updatedTreatments = new JSONArray();
JSONArray addedTreatments = new JSONArray();
JSONArray addedOrUpdatedTreatments = new JSONArray();
if (treatments.length() > 0)
rxBus.send(new EventNSClientNewLog("DATA", "received " + treatments.length() + " treatments"));
for (Integer index = 0; index < treatments.length(); index++) {
JSONObject jsonTreatment = treatments.getJSONObject(index);
NSTreatment treatment = new NSTreatment(jsonTreatment);
String action = JsonHelper.safeGetStringAllowNull(jsonTreatment, "action", null);
long mills = JsonHelper.safeGetLong(jsonTreatment, "mills");
// remove from upload queue if Ack is failing
uploadQueue.removeID(jsonTreatment);
//Find latest date in treatment
if (treatment.getMills() != null && treatment.getMills() < System.currentTimeMillis())
if (treatment.getMills() > latestDateInReceivedData)
latestDateInReceivedData = treatment.getMills();
if (treatment.getAction() == null) {
addedTreatments.put(jsonTreatment);
} else if (treatment.getAction().equals("update")) {
updatedTreatments.put(jsonTreatment);
} else if (treatment.getAction().equals("remove")) {
if (treatment.getMills() != null && treatment.getMills() > System.currentTimeMillis() - 24 * 60 * 60 * 1000L) // handle 1 day old deletions only
removedTreatments.put(jsonTreatment);
}
if (action == null) addedOrUpdatedTreatments.put(jsonTreatment);
else if (action.equals("update"))
addedOrUpdatedTreatments.put(jsonTreatment);
else if (action.equals("remove") && mills > dateUtil._now() - T.days(1).msecs()) // handle 1 day old deletions only
removedTreatments.put(jsonTreatment);
}
if (removedTreatments.length() > 0) {
handleRemovedTreatment(removedTreatments, isDelta);
dataWorker.enqueue(
new OneTimeWorkRequest.Builder(NSClientRemoveWorker.class)
.setInputData(dataWorker.storeInputData(removedTreatments, null))
.build());
if (sp.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
Bundle bundle = new Bundle();
bundle.putString("treatments", removedTreatments.toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_REMOVED_TREATMENT);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
sendBroadcast(intent);
}
}
if (updatedTreatments.length() > 0) {
handleChangedTreatment(updatedTreatments, isDelta);
}
if (addedTreatments.length() > 0) {
handleNewTreatment(addedTreatments, isDelta);
if (addedOrUpdatedTreatments.length() > 0) {
dataWorker.enqueue(
new OneTimeWorkRequest.Builder(NSClientAddUpdateWorker.class)
.setInputData(dataWorker.storeInputData(addedOrUpdatedTreatments, null))
.build());
if (sp.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
List<JSONArray> splitted = splitArray(addedOrUpdatedTreatments);
for (JSONArray part : splitted) {
Bundle bundle = new Bundle();
bundle.putString("treatments", part.toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_CHANGED_TREATMENT);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
sendBroadcast(intent);
}
}
}
}
if (data.has("devicestatus")) {
@ -848,54 +864,6 @@ public class NSClientService extends DaggerService {
}
}
public void handleChangedTreatment(JSONArray treatments, boolean isDelta) {
List<JSONArray> splitted = splitArray(treatments);
for (JSONArray part : splitted) {
Bundle bundle = new Bundle();
bundle.putString("treatments", part.toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_CHANGED_TREATMENT);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
if (sp.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
splitted = splitArray(treatments);
for (JSONArray part : splitted) {
Bundle bundle = new Bundle();
bundle.putString("treatments", part.toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_CHANGED_TREATMENT);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
this.getApplicationContext().sendBroadcast(intent);
}
}
}
public void handleRemovedTreatment(JSONArray treatments, boolean isDelta) {
Bundle bundle = new Bundle();
bundle.putString("treatments", treatments.toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_REMOVED_TREATMENT);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
if (sp.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
bundle = new Bundle();
bundle.putString("treatments", treatments.toString());
bundle.putBoolean("delta", isDelta);
intent = new Intent(Intents.ACTION_REMOVED_TREATMENT);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
this.getApplicationContext().sendBroadcast(intent);
}
}
public List<JSONArray> splitArray(JSONArray array) {
List<JSONArray> ret = new ArrayList<>();
try {

View file

@ -16,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.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSgv
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification
@ -26,7 +27,6 @@ import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.XDripBroadcast
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import org.json.JSONArray
import org.json.JSONObject
import javax.inject.Inject
import javax.inject.Singleton
@ -91,6 +91,7 @@ class NSClientSourcePlugin @Inject constructor(
@Inject lateinit var repository: AppRepository
@Inject lateinit var broadcastToXDrip: XDripBroadcast
@Inject lateinit var dexcomPlugin: DexcomPlugin
@Inject lateinit var nsClientPlugin: NSClientPlugin
init {
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
@ -135,6 +136,8 @@ class NSClientSourcePlugin @Inject constructor(
rxBus.send(EventDismissNotification(Notification.NS_URGENT_ALARM))
}
nsClientPlugin.updateLatestDateReceivedIfNewer(latestDateInReceivedData)
repository.runTransactionForResult(CgmSourceTransaction(glucoseValues, emptyList(), null, !nsClientSourcePlugin.isEnabled()))
.doOnError {
aapsLogger.error("Error while saving values from NSClient App", it)

View file

@ -9,7 +9,6 @@ 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.plugins.general.nsclient.NSClientWorker
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin
import info.nightscout.androidaps.plugins.source.*
import info.nightscout.androidaps.services.Intents
@ -72,11 +71,6 @@ open class DataReceiver : DaggerBroadcastReceiver() {
Intents.DEXCOM_BG ->
OneTimeWorkRequest.Builder(DexcomPlugin.DexcomWorker::class.java)
.setInputData(dataWorker.storeInputData(bundle, intent)).build()
Intents.ACTION_NEW_TREATMENT,
Intents.ACTION_CHANGED_TREATMENT,
Intents.ACTION_REMOVED_TREATMENT ->
OneTimeWorkRequest.Builder(NSClientWorker::class.java)
.setInputData(dataWorker.storeInputData(bundle, intent)).build()
else -> null
}?.let { request -> dataWorker.enqueue(request) }
}

View file

@ -2,7 +2,6 @@ package info.nightscout.androidaps.interfaces
import com.j256.ormlite.dao.CloseableIterator
import info.nightscout.androidaps.db.*
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
import org.json.JSONObject
interface DatabaseHelperInterface {
@ -54,7 +53,7 @@ interface DatabaseHelperInterface {
fun deleteProfileSwitchById(_id: String)
fun createTempBasalFromJsonIfNotExists(json: JSONObject)
fun createExtendedBolusFromJsonIfNotExists(json: JSONObject)
fun createProfileSwitchFromJsonIfNotExists(activePluginProvider: ActivePluginProvider, nsUpload: NSUpload, trJson: JSONObject)
fun createProfileSwitchFromJsonIfNotExists(trJson: JSONObject)
fun getInsightBolusID(pumpSerial: String, bolusID: Int, timestamp: Long): InsightBolusID?
fun getInsightHistoryOffset(pumpSerial: String): InsightHistoryOffset?

View file

@ -51,6 +51,7 @@ object JsonHelper {
return result
}
@JvmStatic
fun safeGetStringAllowNull(json: JSONObject?, fieldName: String, defaultValue: String?): String? {
var result = defaultValue
if (json != null && json.has(fieldName)) {
@ -112,7 +113,7 @@ object JsonHelper {
}
fun safeGetIntAllowNull(json: JSONObject?, fieldName: String): Int? {
var result : Int? = null
var result: Int? = null
if (json != null && json.has(fieldName)) {
try {
result = json.getInt(fieldName)