DeviceStatus
This commit is contained in:
parent
93b1b37021
commit
a5ea0d9027
|
@ -17,6 +17,7 @@ abstract class ReceiversModule {
|
||||||
@ContributesAndroidInjector abstract fun contributesChargingStateReceiver(): ChargingStateReceiver
|
@ContributesAndroidInjector abstract fun contributesChargingStateReceiver(): ChargingStateReceiver
|
||||||
@ContributesAndroidInjector abstract fun contributesDataReceiver(): DataReceiver
|
@ContributesAndroidInjector abstract fun contributesDataReceiver(): DataReceiver
|
||||||
@ContributesAndroidInjector abstract fun contributesKeepAliveReceiver(): KeepAliveReceiver
|
@ContributesAndroidInjector abstract fun contributesKeepAliveReceiver(): KeepAliveReceiver
|
||||||
|
@ContributesAndroidInjector abstract fun contributesKeepAliveWorker(): KeepAliveReceiver.KeepAliveWorker
|
||||||
@ContributesAndroidInjector abstract fun contributesRileyLinkBluetoothStateReceiver(): RileyLinkBluetoothStateReceiver
|
@ContributesAndroidInjector abstract fun contributesRileyLinkBluetoothStateReceiver(): RileyLinkBluetoothStateReceiver
|
||||||
@ContributesAndroidInjector abstract fun contributesSmsReceiver(): SmsReceiver
|
@ContributesAndroidInjector abstract fun contributesSmsReceiver(): SmsReceiver
|
||||||
@ContributesAndroidInjector abstract fun contributesTimeDateOrTZChangeReceiver(): TimeDateOrTZChangeReceiver
|
@ContributesAndroidInjector abstract fun contributesTimeDateOrTZChangeReceiver(): TimeDateOrTZChangeReceiver
|
||||||
|
|
|
@ -32,6 +32,7 @@ import info.nightscout.androidaps.plugins.aps.loop.events.EventLoopUpdateGui
|
||||||
import info.nightscout.androidaps.plugins.aps.loop.events.EventNewOpenLoopNotification
|
import info.nightscout.androidaps.plugins.aps.loop.events.EventNewOpenLoopNotification
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||||
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
|
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
|
||||||
|
import info.nightscout.androidaps.plugins.configBuilder.RunningConfiguration
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
|
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
|
||||||
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification
|
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification
|
||||||
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
|
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
|
||||||
|
@ -48,6 +49,7 @@ import info.nightscout.androidaps.utils.DateUtil
|
||||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||||
import info.nightscout.androidaps.utils.HardLimits
|
import info.nightscout.androidaps.utils.HardLimits
|
||||||
import info.nightscout.androidaps.utils.T
|
import info.nightscout.androidaps.utils.T
|
||||||
|
import info.nightscout.androidaps.utils.extensions.buildDeviceStatus
|
||||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||||
|
@ -78,7 +80,8 @@ open class LoopPlugin @Inject constructor(
|
||||||
private val fabricPrivacy: FabricPrivacy,
|
private val fabricPrivacy: FabricPrivacy,
|
||||||
private val nsUpload: NSUpload,
|
private val nsUpload: NSUpload,
|
||||||
private val dateUtil: DateUtil,
|
private val dateUtil: DateUtil,
|
||||||
private val repository: AppRepository
|
private val repository: AppRepository,
|
||||||
|
private val runningConfiguration: RunningConfiguration
|
||||||
) : PluginBase(PluginDescription()
|
) : PluginBase(PluginDescription()
|
||||||
.mainType(PluginType.LOOP)
|
.mainType(PluginType.LOOP)
|
||||||
.fragmentClass(LoopFragment::class.java.name)
|
.fragmentClass(LoopFragment::class.java.name)
|
||||||
|
@ -316,7 +319,12 @@ open class LoopPlugin @Inject constructor(
|
||||||
lastRun!!.lastTBRRequest = 0
|
lastRun!!.lastTBRRequest = 0
|
||||||
lastRun!!.lastSMBEnact = 0
|
lastRun!!.lastSMBEnact = 0
|
||||||
lastRun!!.lastSMBRequest = 0
|
lastRun!!.lastSMBRequest = 0
|
||||||
nsUpload.uploadDeviceStatus(this, iobCobCalculatorPlugin, profileFunction, activePlugin.activePump, receiverStatusStore, BuildConfig.VERSION_NAME + "-" + BuildConfig.BUILDVERSION)
|
buildDeviceStatus(dateUtil, this, iobCobCalculatorPlugin, profileFunction,
|
||||||
|
activePlugin.activePump, receiverStatusStore, runningConfiguration,
|
||||||
|
BuildConfig.VERSION_NAME + "-" + BuildConfig.BUILDVERSION)?.also {
|
||||||
|
repository.insert(it)
|
||||||
|
}
|
||||||
|
|
||||||
if (isSuspended) {
|
if (isSuspended) {
|
||||||
aapsLogger.debug(LTag.APS, resourceHelper.gs(R.string.loopsuspended))
|
aapsLogger.debug(LTag.APS, resourceHelper.gs(R.string.loopsuspended))
|
||||||
rxBus.send(EventLoopSetLastRunGui(resourceHelper.gs(R.string.loopsuspended)))
|
rxBus.send(EventLoopSetLastRunGui(resourceHelper.gs(R.string.loopsuspended)))
|
||||||
|
@ -489,7 +497,6 @@ open class LoopPlugin @Inject constructor(
|
||||||
|
|
||||||
fun acceptChangeRequest() {
|
fun acceptChangeRequest() {
|
||||||
val profile = profileFunction.getProfile()
|
val profile = profileFunction.getProfile()
|
||||||
val lp = this
|
|
||||||
applyTBRRequest(lastRun!!.constraintsProcessed, profile, object : Callback() {
|
applyTBRRequest(lastRun!!.constraintsProcessed, profile, object : Callback() {
|
||||||
override fun run() {
|
override fun run() {
|
||||||
if (result.enacted) {
|
if (result.enacted) {
|
||||||
|
@ -497,7 +504,11 @@ open class LoopPlugin @Inject constructor(
|
||||||
lastRun!!.lastTBRRequest = lastRun!!.lastAPSRun
|
lastRun!!.lastTBRRequest = lastRun!!.lastAPSRun
|
||||||
lastRun!!.lastTBREnact = DateUtil.now()
|
lastRun!!.lastTBREnact = DateUtil.now()
|
||||||
lastRun!!.lastOpenModeAccept = DateUtil.now()
|
lastRun!!.lastOpenModeAccept = DateUtil.now()
|
||||||
nsUpload.uploadDeviceStatus(lp, iobCobCalculatorPlugin, profileFunction, activePlugin.activePump, receiverStatusStore, BuildConfig.VERSION_NAME + "-" + BuildConfig.BUILDVERSION)
|
buildDeviceStatus(dateUtil, this@LoopPlugin, iobCobCalculatorPlugin, profileFunction,
|
||||||
|
activePlugin.activePump, receiverStatusStore, runningConfiguration,
|
||||||
|
BuildConfig.VERSION_NAME + "-" + BuildConfig.BUILDVERSION)?.also {
|
||||||
|
repository.insert(it)
|
||||||
|
}
|
||||||
sp.incInt(R.string.key_ObjectivesmanualEnacts)
|
sp.incInt(R.string.key_ObjectivesmanualEnacts)
|
||||||
}
|
}
|
||||||
rxBus.send(EventAcceptOpenLoopChange())
|
rxBus.send(EventAcceptOpenLoopChange())
|
||||||
|
|
|
@ -2,6 +2,7 @@ package info.nightscout.androidaps.plugins.general.nsclient
|
||||||
|
|
||||||
import info.nightscout.androidaps.R
|
import info.nightscout.androidaps.R
|
||||||
import info.nightscout.androidaps.database.AppRepository
|
import info.nightscout.androidaps.database.AppRepository
|
||||||
|
import info.nightscout.androidaps.database.entities.DeviceStatus
|
||||||
import info.nightscout.androidaps.database.entities.*
|
import info.nightscout.androidaps.database.entities.*
|
||||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
||||||
import info.nightscout.androidaps.interfaces.DataSyncSelector
|
import info.nightscout.androidaps.interfaces.DataSyncSelector
|
||||||
|
@ -28,6 +29,7 @@ class DataSyncSelectorImplementation @Inject constructor(
|
||||||
sp.remove(R.string.key_ns_bolus_last_synced_id)
|
sp.remove(R.string.key_ns_bolus_last_synced_id)
|
||||||
sp.remove(R.string.key_ns_carbs_last_synced_id)
|
sp.remove(R.string.key_ns_carbs_last_synced_id)
|
||||||
sp.remove(R.string.key_ns_bolus_calculator_result_last_synced_id)
|
sp.remove(R.string.key_ns_bolus_calculator_result_last_synced_id)
|
||||||
|
sp.remove(R.string.key_ns_device_status_last_synced_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun confirmLastBolusIdIfGreater(lastSynced: Long) {
|
override fun confirmLastBolusIdIfGreater(lastSynced: Long) {
|
||||||
|
@ -294,4 +296,34 @@ class DataSyncSelectorImplementation @Inject constructor(
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun confirmLastDeviceStatusIdIfGreater(lastSynced: Long) {
|
||||||
|
if (lastSynced > sp.getLong(R.string.key_ns_device_status_last_synced_id, 0)) {
|
||||||
|
aapsLogger.debug(LTag.NSCLIENT, "Setting DeviceStatus data sync from $lastSynced")
|
||||||
|
sp.putLong(R.string.key_ns_device_status_last_synced_id, lastSynced)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun changedDeviceStatuses(): List<DeviceStatus> {
|
||||||
|
val startId = sp.getLong(R.string.key_ns_device_status_last_synced_id, 0)
|
||||||
|
return appRepository.getModifiedDeviceStatusDataFromId(startId).blockingGet().also {
|
||||||
|
aapsLogger.debug(LTag.NSCLIENT, "Loading DeviceStatus data for sync from $startId. Records ${it.size}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun processChangedDeviceStatusesCompat(): Boolean {
|
||||||
|
val startId = sp.getLong(R.string.key_ns_device_status_last_synced_id, 0)
|
||||||
|
appRepository.getNextSyncElementDeviceStatus(startId).blockingGet()?.let { deviceStatus ->
|
||||||
|
aapsLogger.info(LTag.DATABASE, "Loading DeviceStatus data Start: $startId ID: ${deviceStatus.id}")
|
||||||
|
when {
|
||||||
|
// without nsId = create new
|
||||||
|
deviceStatus.interfaceIDs.nightscoutId == null ->
|
||||||
|
nsClientPlugin.nsClientService?.dbAdd("devicestatus", deviceStatus.toJson(), deviceStatus)
|
||||||
|
// with nsId = ignore
|
||||||
|
deviceStatus.interfaceIDs.nightscoutId != null -> Any()
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,10 +32,11 @@ import dagger.android.HasAndroidInjector;
|
||||||
import info.nightscout.androidaps.Config;
|
import info.nightscout.androidaps.Config;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.database.AppRepository;
|
import info.nightscout.androidaps.database.AppRepository;
|
||||||
import info.nightscout.androidaps.database.entities.Carbs;
|
import info.nightscout.androidaps.database.entities.DeviceStatus;
|
||||||
import info.nightscout.androidaps.database.transactions.UpdateNsIdBolusCalculatorResultTransaction;
|
import info.nightscout.androidaps.database.transactions.UpdateNsIdBolusCalculatorResultTransaction;
|
||||||
import info.nightscout.androidaps.database.transactions.UpdateNsIdBolusTransaction;
|
import info.nightscout.androidaps.database.transactions.UpdateNsIdBolusTransaction;
|
||||||
import info.nightscout.androidaps.database.transactions.UpdateNsIdCarbsTransaction;
|
import info.nightscout.androidaps.database.transactions.UpdateNsIdCarbsTransaction;
|
||||||
|
import info.nightscout.androidaps.database.transactions.UpdateNsIdDeviceStatusTransaction;
|
||||||
import info.nightscout.androidaps.database.transactions.UpdateNsIdFoodTransaction;
|
import info.nightscout.androidaps.database.transactions.UpdateNsIdFoodTransaction;
|
||||||
import info.nightscout.androidaps.database.transactions.UpdateNsIdGlucoseValueTransaction;
|
import info.nightscout.androidaps.database.transactions.UpdateNsIdGlucoseValueTransaction;
|
||||||
import info.nightscout.androidaps.database.transactions.UpdateNsIdTemporaryTargetTransaction;
|
import info.nightscout.androidaps.database.transactions.UpdateNsIdTemporaryTargetTransaction;
|
||||||
|
@ -339,6 +340,22 @@ public class NSClientService extends DaggerService {
|
||||||
dataSyncSelector.processChangedBolusCalculatorResultsCompat();
|
dataSyncSelector.processChangedBolusCalculatorResultsCompat();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (ack.getOriginalObject() instanceof DeviceStatus) {
|
||||||
|
DeviceStatus deviceStatus = (DeviceStatus) ack.getOriginalObject();
|
||||||
|
deviceStatus.getInterfaceIDs().setNightscoutId(ack.getId());
|
||||||
|
|
||||||
|
disposable.add(repository.runTransactionForResult(new UpdateNsIdDeviceStatusTransaction(deviceStatus))
|
||||||
|
.observeOn(aapsSchedulers.getIo())
|
||||||
|
.subscribe(
|
||||||
|
result -> aapsLogger.debug(LTag.DATABASE, "Updated ns id of DeviceStatus " + deviceStatus),
|
||||||
|
error -> aapsLogger.error(LTag.DATABASE, "Updated ns id of DeviceStatus failed", error)
|
||||||
|
));
|
||||||
|
dataSyncSelector.confirmLastDeviceStatusIdIfGreater(deviceStatus.getId());
|
||||||
|
rxBus.send(new EventNSClientNewLog("DBADD", "Acked DeviceStatus" + deviceStatus.getInterfaceIDs().getNightscoutId()));
|
||||||
|
// Send new if waiting
|
||||||
|
dataSyncSelector.processChangedBolusCalculatorResultsCompat();
|
||||||
|
return;
|
||||||
|
}
|
||||||
// old way
|
// old way
|
||||||
if (ack.nsClientID != null) {
|
if (ack.nsClientID != null) {
|
||||||
uploadQueue.removeByNsClientIdIfExists(ack.json);
|
uploadQueue.removeByNsClientIdIfExists(ack.json);
|
||||||
|
@ -977,6 +994,7 @@ public class NSClientService extends DaggerService {
|
||||||
dataSyncSelector.processChangedTempTargetsCompat();
|
dataSyncSelector.processChangedTempTargetsCompat();
|
||||||
dataSyncSelector.processChangedFoodsCompat();
|
dataSyncSelector.processChangedFoodsCompat();
|
||||||
dataSyncSelector.processChangedTherapyEventsCompat();
|
dataSyncSelector.processChangedTherapyEventsCompat();
|
||||||
|
dataSyncSelector.processChangedDeviceStatusesCompat();
|
||||||
|
|
||||||
if (uploadQueue.size() == 0)
|
if (uploadQueue.size() == 0)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -3,13 +3,19 @@ package info.nightscout.androidaps.receivers
|
||||||
import android.app.AlarmManager
|
import android.app.AlarmManager
|
||||||
import android.app.PendingIntent
|
import android.app.PendingIntent
|
||||||
import android.app.PendingIntent.CanceledException
|
import android.app.PendingIntent.CanceledException
|
||||||
|
import android.app.PendingIntent.FLAG_IMMUTABLE
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.PowerManager
|
|
||||||
import android.os.SystemClock
|
import android.os.SystemClock
|
||||||
|
import androidx.work.OneTimeWorkRequest
|
||||||
|
import androidx.work.WorkManager
|
||||||
|
import androidx.work.Worker
|
||||||
|
import androidx.work.WorkerParameters
|
||||||
import dagger.android.DaggerBroadcastReceiver
|
import dagger.android.DaggerBroadcastReceiver
|
||||||
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.androidaps.BuildConfig
|
import info.nightscout.androidaps.BuildConfig
|
||||||
import info.nightscout.androidaps.Config
|
import info.nightscout.androidaps.Config
|
||||||
|
import info.nightscout.androidaps.database.AppRepository
|
||||||
import info.nightscout.androidaps.events.EventProfileNeedsUpdate
|
import info.nightscout.androidaps.events.EventProfileNeedsUpdate
|
||||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
||||||
import info.nightscout.androidaps.interfaces.CommandQueueProvider
|
import info.nightscout.androidaps.interfaces.CommandQueueProvider
|
||||||
|
@ -18,37 +24,62 @@ import info.nightscout.androidaps.logging.AAPSLogger
|
||||||
import info.nightscout.androidaps.logging.LTag
|
import info.nightscout.androidaps.logging.LTag
|
||||||
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
|
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
|
import info.nightscout.androidaps.plugins.configBuilder.RunningConfiguration
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
||||||
import info.nightscout.androidaps.queue.commands.Command
|
import info.nightscout.androidaps.queue.commands.Command
|
||||||
import info.nightscout.androidaps.utils.DateUtil
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||||
import info.nightscout.androidaps.utils.LocalAlertUtils
|
import info.nightscout.androidaps.utils.LocalAlertUtils
|
||||||
import info.nightscout.androidaps.utils.T
|
import info.nightscout.androidaps.utils.T
|
||||||
|
import info.nightscout.androidaps.utils.extensions.buildDeviceStatus
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
|
|
||||||
class KeepAliveReceiver : DaggerBroadcastReceiver() {
|
class KeepAliveReceiver : DaggerBroadcastReceiver() {
|
||||||
|
|
||||||
@Inject lateinit var aapsLogger: AAPSLogger
|
@Inject lateinit var aapsLogger: AAPSLogger
|
||||||
@Inject lateinit var rxBus: RxBusWrapper
|
|
||||||
@Inject lateinit var activePlugin: ActivePluginProvider
|
|
||||||
@Inject lateinit var commandQueue: CommandQueueProvider
|
|
||||||
@Inject lateinit var profileFunction: ProfileFunction
|
|
||||||
@Inject lateinit var loopPlugin: LoopPlugin
|
|
||||||
@Inject lateinit var iobCobCalculatorPlugin: IobCobCalculatorPlugin
|
|
||||||
@Inject lateinit var localAlertUtils: LocalAlertUtils
|
|
||||||
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
|
||||||
@Inject lateinit var receiverStatusStore: ReceiverStatusStore
|
|
||||||
@Inject lateinit var config: Config
|
|
||||||
@Inject lateinit var nsUpload: NSUpload
|
|
||||||
@Inject lateinit var dateUtil: DateUtil
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
private val KEEP_ALIVE_MILLISECONDS = T.mins(5).msecs()
|
private val KEEP_ALIVE_MILLISECONDS = T.mins(5).msecs()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
|
super.onReceive(context, intent)
|
||||||
|
aapsLogger.debug(LTag.CORE, "KeepAlive received")
|
||||||
|
|
||||||
|
WorkManager.getInstance(context)
|
||||||
|
.enqueue(OneTimeWorkRequest.Builder(KeepAliveWorker::class.java).build())
|
||||||
|
}
|
||||||
|
|
||||||
|
class KeepAliveWorker(
|
||||||
|
context: Context,
|
||||||
|
params: WorkerParameters
|
||||||
|
) : Worker(context, params) {
|
||||||
|
|
||||||
|
@Inject lateinit var aapsLogger: AAPSLogger
|
||||||
|
@Inject lateinit var localAlertUtils: LocalAlertUtils
|
||||||
|
@Inject lateinit var repository: AppRepository
|
||||||
|
@Inject lateinit var config: Config
|
||||||
|
@Inject lateinit var iobCobCalculatorPlugin: IobCobCalculatorPlugin
|
||||||
|
@Inject lateinit var loopPlugin: LoopPlugin
|
||||||
|
@Inject lateinit var dateUtil: DateUtil
|
||||||
|
@Inject lateinit var activePlugin: ActivePluginProvider
|
||||||
|
@Inject lateinit var profileFunction: ProfileFunction
|
||||||
|
@Inject lateinit var runningConfiguration: RunningConfiguration
|
||||||
|
@Inject lateinit var receiverStatusStore: ReceiverStatusStore
|
||||||
|
@Inject lateinit var rxBus: RxBusWrapper
|
||||||
|
@Inject lateinit var commandQueue: CommandQueueProvider
|
||||||
|
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
||||||
|
|
||||||
|
init {
|
||||||
|
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
private val STATUS_UPDATE_FREQUENCY = T.mins(15).msecs()
|
private val STATUS_UPDATE_FREQUENCY = T.mins(15).msecs()
|
||||||
private val IOB_UPDATE_FREQUENCY_IN_MINS = 5L
|
private const val IOB_UPDATE_FREQUENCY_IN_MINUTES = 5L
|
||||||
|
|
||||||
private var lastReadStatus: Long = 0
|
private var lastReadStatus: Long = 0
|
||||||
private var lastRun: Long = 0
|
private var lastRun: Long = 0
|
||||||
|
@ -56,48 +87,12 @@ class KeepAliveReceiver : DaggerBroadcastReceiver() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onReceive(context: Context, intent: Intent) {
|
override fun doWork(): Result {
|
||||||
super.onReceive(context, intent)
|
|
||||||
aapsLogger.debug(LTag.CORE, "KeepAlive received")
|
|
||||||
val pm = context.getSystemService(Context.POWER_SERVICE) as PowerManager
|
|
||||||
val wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "AndroidAPS:KeepAliveReceiver")
|
|
||||||
wl.acquire(T.mins(2).msecs())
|
|
||||||
localAlertUtils.shortenSnoozeInterval()
|
localAlertUtils.shortenSnoozeInterval()
|
||||||
localAlertUtils.checkStaleBGAlert()
|
localAlertUtils.checkStaleBGAlert()
|
||||||
checkPump()
|
checkPump()
|
||||||
checkAPS()
|
checkAPS()
|
||||||
wl.release()
|
return Result.success()
|
||||||
}
|
|
||||||
|
|
||||||
class KeepAliveManager @Inject constructor(
|
|
||||||
private val aapsLogger: AAPSLogger,
|
|
||||||
private val localAlertUtils: LocalAlertUtils
|
|
||||||
) {
|
|
||||||
|
|
||||||
//called by MainApp at first app start
|
|
||||||
fun setAlarm(context: Context) {
|
|
||||||
aapsLogger.debug(LTag.CORE, "KeepAlive scheduled")
|
|
||||||
SystemClock.sleep(5000) // wait for app initialization
|
|
||||||
localAlertUtils.shortenSnoozeInterval()
|
|
||||||
localAlertUtils.preSnoozeAlarms()
|
|
||||||
val am = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
|
||||||
val i = Intent(context, KeepAliveReceiver::class.java)
|
|
||||||
val pi = PendingIntent.getBroadcast(context, 0, i, 0)
|
|
||||||
try {
|
|
||||||
pi.send()
|
|
||||||
} catch (e: CanceledException) {
|
|
||||||
}
|
|
||||||
am.cancel(pi)
|
|
||||||
am.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), KEEP_ALIVE_MILLISECONDS, pi)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun cancelAlarm(context: Context) {
|
|
||||||
aapsLogger.debug(LTag.CORE, "KeepAlive canceled")
|
|
||||||
val intent = Intent(context, KeepAliveReceiver::class.java)
|
|
||||||
val sender = PendingIntent.getBroadcast(context, 0, intent, 0)
|
|
||||||
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
|
||||||
alarmManager.cancel(sender)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Usually deviceStatus is uploaded through LoopPlugin after every loop cycle.
|
// Usually deviceStatus is uploaded through LoopPlugin after every loop cycle.
|
||||||
|
@ -110,9 +105,13 @@ class KeepAliveReceiver : DaggerBroadcastReceiver() {
|
||||||
else if (!loopPlugin.isEnabled() || iobCobCalculatorPlugin.actualBg() == null)
|
else if (!loopPlugin.isEnabled() || iobCobCalculatorPlugin.actualBg() == null)
|
||||||
shouldUploadStatus = true
|
shouldUploadStatus = true
|
||||||
else if (DateUtil.isOlderThan(activePlugin.activeAPS.lastAPSRun, 5)) shouldUploadStatus = true
|
else if (DateUtil.isOlderThan(activePlugin.activeAPS.lastAPSRun, 5)) shouldUploadStatus = true
|
||||||
if (DateUtil.isOlderThan(lastIobUpload, IOB_UPDATE_FREQUENCY_IN_MINS) && shouldUploadStatus) {
|
if (DateUtil.isOlderThan(lastIobUpload, IOB_UPDATE_FREQUENCY_IN_MINUTES) && shouldUploadStatus) {
|
||||||
lastIobUpload = DateUtil.now()
|
lastIobUpload = dateUtil._now()
|
||||||
nsUpload.uploadDeviceStatus(loopPlugin, iobCobCalculatorPlugin, profileFunction, activePlugin.activePump, receiverStatusStore, BuildConfig.VERSION_NAME + "-" + BuildConfig.BUILDVERSION)
|
buildDeviceStatus(dateUtil, loopPlugin, iobCobCalculatorPlugin, profileFunction,
|
||||||
|
activePlugin.activePump, receiverStatusStore, runningConfiguration,
|
||||||
|
BuildConfig.VERSION_NAME + "-" + BuildConfig.BUILDVERSION)?.also {
|
||||||
|
repository.insert(it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,4 +142,36 @@ class KeepAliveReceiver : DaggerBroadcastReceiver() {
|
||||||
}
|
}
|
||||||
lastRun = System.currentTimeMillis()
|
lastRun = System.currentTimeMillis()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class KeepAliveManager @Inject constructor(
|
||||||
|
private val aapsLogger: AAPSLogger,
|
||||||
|
private val localAlertUtils: LocalAlertUtils
|
||||||
|
) {
|
||||||
|
|
||||||
|
//called by MainApp at first app start
|
||||||
|
fun setAlarm(context: Context) {
|
||||||
|
aapsLogger.debug(LTag.CORE, "KeepAlive scheduled")
|
||||||
|
SystemClock.sleep(5000) // wait for app initialization
|
||||||
|
localAlertUtils.shortenSnoozeInterval()
|
||||||
|
localAlertUtils.preSnoozeAlarms()
|
||||||
|
val am = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
||||||
|
val i = Intent(context, KeepAliveReceiver::class.java)
|
||||||
|
val pi = PendingIntent.getBroadcast(context, 0, i, FLAG_IMMUTABLE)
|
||||||
|
try {
|
||||||
|
pi.send()
|
||||||
|
} catch (e: CanceledException) {
|
||||||
|
}
|
||||||
|
am.cancel(pi)
|
||||||
|
am.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), KEEP_ALIVE_MILLISECONDS, pi)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun cancelAlarm(context: Context) {
|
||||||
|
aapsLogger.debug(LTag.CORE, "KeepAlive canceled")
|
||||||
|
val intent = Intent(context, KeepAliveReceiver::class.java)
|
||||||
|
val sender = PendingIntent.getBroadcast(context, 0, intent, FLAG_IMMUTABLE)
|
||||||
|
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
||||||
|
alarmManager.cancel(sender)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -43,6 +43,7 @@
|
||||||
<string name="key_ns_bolus_calculator_result_last_synced_id" translatable="false">ns_bolus_calculator_result_last_synced_id</string>
|
<string name="key_ns_bolus_calculator_result_last_synced_id" translatable="false">ns_bolus_calculator_result_last_synced_id</string>
|
||||||
<string name="key_ns_carbs_last_synced_id" translatable="false">ns_carbs_last_synced_id</string>
|
<string name="key_ns_carbs_last_synced_id" translatable="false">ns_carbs_last_synced_id</string>
|
||||||
<string name="key_ns_bolus_last_synced_id" translatable="false">ns_bolus_last_synced_id</string>
|
<string name="key_ns_bolus_last_synced_id" translatable="false">ns_bolus_last_synced_id</string>
|
||||||
|
<string name="key_ns_device_status_last_synced_id" translatable="false">ns_device_status_last_synced_id</string>
|
||||||
|
|
||||||
<string name="treatmentssafety_title">Treatments safety</string>
|
<string name="treatmentssafety_title">Treatments safety</string>
|
||||||
<string name="treatmentssafety_maxbolus_title">Max allowed bolus [U]</string>
|
<string name="treatmentssafety_maxbolus_title">Max allowed bolus [U]</string>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package info.nightscout.androidaps.interfaces
|
package info.nightscout.androidaps.interfaces
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.database.entities.DeviceStatus
|
||||||
import info.nightscout.androidaps.database.entities.*
|
import info.nightscout.androidaps.database.entities.*
|
||||||
|
|
||||||
interface DataSyncSelector {
|
interface DataSyncSelector {
|
||||||
|
@ -48,4 +49,9 @@ interface DataSyncSelector {
|
||||||
fun changedFoods() : List<Food>
|
fun changedFoods() : List<Food>
|
||||||
// Until NS v3
|
// Until NS v3
|
||||||
fun processChangedFoodsCompat(): Boolean
|
fun processChangedFoodsCompat(): Boolean
|
||||||
|
|
||||||
|
fun confirmLastDeviceStatusIdIfGreater(lastSynced: Long)
|
||||||
|
fun changedDeviceStatuses() : List<DeviceStatus>
|
||||||
|
// Until NS v3
|
||||||
|
fun processChangedDeviceStatusesCompat(): Boolean
|
||||||
}
|
}
|
|
@ -1,35 +1,22 @@
|
||||||
package info.nightscout.androidaps.plugins.general.nsclient;
|
package info.nightscout.androidaps.plugins.general.nsclient;
|
||||||
|
|
||||||
import android.os.Build;
|
|
||||||
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import info.nightscout.androidaps.core.R;
|
import info.nightscout.androidaps.core.R;
|
||||||
import info.nightscout.androidaps.data.DetailedBolusInfo;
|
import info.nightscout.androidaps.data.DetailedBolusInfo;
|
||||||
import info.nightscout.androidaps.data.IobTotal;
|
|
||||||
import info.nightscout.androidaps.data.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
import info.nightscout.androidaps.database.entities.TherapyEvent;
|
import info.nightscout.androidaps.database.entities.TherapyEvent;
|
||||||
import info.nightscout.androidaps.db.DbRequest;
|
import info.nightscout.androidaps.db.DbRequest;
|
||||||
import info.nightscout.androidaps.db.ExtendedBolus;
|
import info.nightscout.androidaps.db.ExtendedBolus;
|
||||||
import info.nightscout.androidaps.db.ProfileSwitch;
|
import info.nightscout.androidaps.db.ProfileSwitch;
|
||||||
import info.nightscout.androidaps.db.TemporaryBasal;
|
import info.nightscout.androidaps.db.TemporaryBasal;
|
||||||
import info.nightscout.androidaps.interfaces.IobCobCalculator;
|
|
||||||
import info.nightscout.androidaps.interfaces.LoopInterface;
|
|
||||||
import info.nightscout.androidaps.interfaces.ProfileFunction;
|
|
||||||
import info.nightscout.androidaps.interfaces.PumpInterface;
|
|
||||||
import info.nightscout.androidaps.interfaces.UploadQueueInterface;
|
import info.nightscout.androidaps.interfaces.UploadQueueInterface;
|
||||||
import info.nightscout.androidaps.logging.AAPSLogger;
|
import info.nightscout.androidaps.logging.AAPSLogger;
|
||||||
import info.nightscout.androidaps.logging.LTag;
|
|
||||||
import info.nightscout.androidaps.plugins.aps.loop.APSResult;
|
|
||||||
import info.nightscout.androidaps.plugins.aps.loop.DeviceStatus;
|
|
||||||
import info.nightscout.androidaps.plugins.configBuilder.RunningConfiguration;
|
import info.nightscout.androidaps.plugins.configBuilder.RunningConfiguration;
|
||||||
import info.nightscout.androidaps.receivers.ReceiverStatusStore;
|
|
||||||
import info.nightscout.androidaps.utils.DateUtil;
|
import info.nightscout.androidaps.utils.DateUtil;
|
||||||
import info.nightscout.androidaps.utils.sharedPreferences.SP;
|
import info.nightscout.androidaps.utils.sharedPreferences.SP;
|
||||||
|
|
||||||
|
@ -165,70 +152,6 @@ public class NSUpload {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void uploadDeviceStatus(LoopInterface loopPlugin, IobCobCalculator iobCobCalculatorPlugin, ProfileFunction profileFunction, PumpInterface pumpInterface, ReceiverStatusStore receiverStatusStore, String version) {
|
|
||||||
Profile profile = profileFunction.getProfile();
|
|
||||||
String profileName = profileFunction.getProfileName();
|
|
||||||
|
|
||||||
if (profile == null) {
|
|
||||||
aapsLogger.error("Profile is null. Skipping upload");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DeviceStatus deviceStatus = new DeviceStatus(aapsLogger);
|
|
||||||
try {
|
|
||||||
LoopInterface.LastRun lastRun = loopPlugin.getLastRun();
|
|
||||||
if (lastRun != null && lastRun.getLastAPSRun() > System.currentTimeMillis() - 300 * 1000L) {
|
|
||||||
// do not send if result is older than 1 min
|
|
||||||
APSResult apsResult = lastRun.getRequest();
|
|
||||||
apsResult.json().put("timestamp", DateUtil.toISOString(lastRun.getLastAPSRun()));
|
|
||||||
deviceStatus.suggested = apsResult.json();
|
|
||||||
|
|
||||||
deviceStatus.iob = lastRun.getRequest().getIob().json();
|
|
||||||
deviceStatus.iob.put("time", DateUtil.toISOString(lastRun.getLastAPSRun()));
|
|
||||||
|
|
||||||
JSONObject requested = new JSONObject();
|
|
||||||
|
|
||||||
if (lastRun.getTbrSetByPump() != null && lastRun.getTbrSetByPump().getEnacted()) { // enacted
|
|
||||||
deviceStatus.enacted = lastRun.getRequest().json();
|
|
||||||
deviceStatus.enacted.put("rate", lastRun.getTbrSetByPump().json(profile).get("rate"));
|
|
||||||
deviceStatus.enacted.put("duration", lastRun.getTbrSetByPump().json(profile).get("duration"));
|
|
||||||
deviceStatus.enacted.put("recieved", true);
|
|
||||||
requested.put("duration", lastRun.getRequest().getDuration());
|
|
||||||
requested.put("rate", lastRun.getRequest().getRate());
|
|
||||||
requested.put("temp", "absolute");
|
|
||||||
deviceStatus.enacted.put("requested", requested);
|
|
||||||
}
|
|
||||||
if (lastRun.getTbrSetByPump() != null && lastRun.getTbrSetByPump().getEnacted()) { // enacted
|
|
||||||
if (deviceStatus.enacted == null) {
|
|
||||||
deviceStatus.enacted = lastRun.getRequest().json();
|
|
||||||
}
|
|
||||||
deviceStatus.enacted.put("smb", lastRun.getTbrSetByPump().getBolusDelivered());
|
|
||||||
requested.put("smb", lastRun.getRequest().getSmb());
|
|
||||||
deviceStatus.enacted.put("requested", requested);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
aapsLogger.debug(LTag.NSCLIENT, "OpenAPS data too old to upload, sending iob only");
|
|
||||||
IobTotal[] iob = iobCobCalculatorPlugin.calculateIobArrayInDia(profile);
|
|
||||||
if (iob.length > 0) {
|
|
||||||
deviceStatus.iob = iob[0].json();
|
|
||||||
deviceStatus.iob.put("time", DateUtil.toISOString(dateUtil._now()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
deviceStatus.device = "openaps://" + Build.MANUFACTURER + " " + Build.MODEL;
|
|
||||||
JSONObject pumpstatus = pumpInterface.getJSONStatus(profile, profileName, version);
|
|
||||||
deviceStatus.pump = pumpstatus;
|
|
||||||
|
|
||||||
deviceStatus.uploaderBattery = receiverStatusStore.getBatteryLevel();
|
|
||||||
|
|
||||||
deviceStatus.created_at = DateUtil.toISOString(new Date());
|
|
||||||
|
|
||||||
deviceStatus.configuration = runningConfiguration.configuration();
|
|
||||||
|
|
||||||
uploadQueue.add(new DbRequest("dbAdd", "devicestatus", deviceStatus.mongoRecord(), System.currentTimeMillis()));
|
|
||||||
} catch (JSONException e) {
|
|
||||||
aapsLogger.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void uploadTreatmentRecord(DetailedBolusInfo detailedBolusInfo) {
|
public void uploadTreatmentRecord(DetailedBolusInfo detailedBolusInfo) {
|
||||||
throw new IllegalStateException("DO NOT USE");
|
throw new IllegalStateException("DO NOT USE");
|
||||||
|
|
|
@ -1,12 +1,88 @@
|
||||||
package info.nightscout.androidaps.plugins.aps.loop;
|
package info.nightscout.androidaps.utils.extensions
|
||||||
|
|
||||||
import org.json.JSONException;
|
import android.os.Build
|
||||||
import org.json.JSONObject;
|
import info.nightscout.androidaps.database.entities.DeviceStatus
|
||||||
import org.slf4j.Logger;
|
import info.nightscout.androidaps.interfaces.IobCobCalculator
|
||||||
|
import info.nightscout.androidaps.interfaces.LoopInterface
|
||||||
|
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||||
|
import info.nightscout.androidaps.interfaces.PumpInterface
|
||||||
|
import info.nightscout.androidaps.plugins.configBuilder.RunningConfiguration
|
||||||
|
import info.nightscout.androidaps.receivers.ReceiverStatusStore
|
||||||
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
|
import org.json.JSONObject
|
||||||
|
|
||||||
import info.nightscout.androidaps.logging.AAPSLogger;
|
fun DeviceStatus.toJson(): JSONObject =
|
||||||
import info.nightscout.androidaps.logging.LTag;
|
JSONObject()
|
||||||
import info.nightscout.androidaps.logging.StacktraceLoggerWrapper;
|
.put("created_at", DateUtil.toISOString(timestamp))
|
||||||
|
.also {
|
||||||
|
if (device != null) it.put("device", device)
|
||||||
|
if (pump != null) it.put("pump", JSONObject(pump))
|
||||||
|
it.put("openaps", JSONObject().also { openaps ->
|
||||||
|
if (enacted != null) openaps.put("enacted", JSONObject(enacted))
|
||||||
|
if (suggested != null) openaps.put("suggested", JSONObject(suggested))
|
||||||
|
if (iob != null) openaps.put("iob", iob)
|
||||||
|
})
|
||||||
|
if (uploaderBattery != 0) it.put("uploaderBattery", uploaderBattery)
|
||||||
|
if (configuration != null) it.put("configuration", JSONObject(configuration))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun buildDeviceStatus(
|
||||||
|
dateUtil: DateUtil,
|
||||||
|
loopPlugin: LoopInterface,
|
||||||
|
iobCobCalculatorPlugin: IobCobCalculator,
|
||||||
|
profileFunction: ProfileFunction,
|
||||||
|
pumpInterface: PumpInterface,
|
||||||
|
receiverStatusStore: ReceiverStatusStore,
|
||||||
|
runningConfiguration: RunningConfiguration,
|
||||||
|
version: String
|
||||||
|
): DeviceStatus? {
|
||||||
|
val profile = profileFunction.getProfile() ?: return null
|
||||||
|
val profileName = profileFunction.getProfileName() ?: return null
|
||||||
|
|
||||||
|
val lastRun = loopPlugin.lastRun
|
||||||
|
var apsResult: JSONObject? = null
|
||||||
|
var iob: JSONObject? = null
|
||||||
|
var enacted: JSONObject? = null
|
||||||
|
if (lastRun != null && lastRun.lastAPSRun > dateUtil._now() - 300 * 1000L) {
|
||||||
|
// do not send if result is older than 1 min
|
||||||
|
apsResult = lastRun.request?.json()?.also {
|
||||||
|
it.put("timestamp", DateUtil.toISOString(lastRun.lastAPSRun))
|
||||||
|
}
|
||||||
|
iob = lastRun.request?.iob?.json()?.also {
|
||||||
|
it.put("time", DateUtil.toISOString(lastRun.lastAPSRun))
|
||||||
|
}
|
||||||
|
val requested = JSONObject()
|
||||||
|
if (lastRun.tbrSetByPump?.enacted == true) { // enacted
|
||||||
|
enacted = lastRun.request?.json()?.also {
|
||||||
|
it.put("rate", lastRun.tbrSetByPump!!.json(profile)["rate"])
|
||||||
|
it.put("duration", lastRun.tbrSetByPump!!.json(profile)["duration"])
|
||||||
|
it.put("received", true)
|
||||||
|
}
|
||||||
|
requested.put("duration", lastRun.request?.duration)
|
||||||
|
requested.put("rate", lastRun.request?.rate)
|
||||||
|
requested.put("temp", "absolute")
|
||||||
|
requested.put("smb", lastRun.request?.smb)
|
||||||
|
enacted?.put("requested", requested)
|
||||||
|
enacted?.put("smb", lastRun.tbrSetByPump?.bolusDelivered)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val calcIob = iobCobCalculatorPlugin.calculateIobArrayInDia(profile)
|
||||||
|
if (calcIob.isNotEmpty()) {
|
||||||
|
iob = calcIob[0].json()
|
||||||
|
iob.put("time", DateUtil.toISOString(dateUtil._now()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return DeviceStatus(
|
||||||
|
timestamp = dateUtil._now(),
|
||||||
|
suggested = apsResult?.toString(),
|
||||||
|
iob = iob?.toString(),
|
||||||
|
enacted = enacted?.toString(),
|
||||||
|
device = "openaps://" + Build.MANUFACTURER + " " + Build.MODEL,
|
||||||
|
pump = pumpInterface.getJSONStatus(profile, profileName, version).toString(),
|
||||||
|
uploaderBattery = receiverStatusStore.batteryLevel,
|
||||||
|
configuration = runningConfiguration.configuration().toString()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
{
|
{
|
||||||
|
@ -364,41 +440,3 @@ import info.nightscout.androidaps.logging.StacktraceLoggerWrapper;
|
||||||
"created_at": "2016-06-24T09:27:49.230Z"
|
"created_at": "2016-06-24T09:27:49.230Z"
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class DeviceStatus {
|
|
||||||
private final AAPSLogger aapsLogger;
|
|
||||||
|
|
||||||
public String device = null;
|
|
||||||
public JSONObject pump = null;
|
|
||||||
public JSONObject enacted = null;
|
|
||||||
public JSONObject suggested = null;
|
|
||||||
public JSONObject iob = null;
|
|
||||||
public int uploaderBattery = 0;
|
|
||||||
public String created_at = null;
|
|
||||||
public JSONObject configuration = null;
|
|
||||||
|
|
||||||
public DeviceStatus(AAPSLogger aapsLogger) {
|
|
||||||
this.aapsLogger = aapsLogger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public JSONObject mongoRecord() {
|
|
||||||
JSONObject record = new JSONObject();
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (device != null) record.put("device", device);
|
|
||||||
if (pump != null) record.put("pump", pump);
|
|
||||||
JSONObject openaps = new JSONObject();
|
|
||||||
if (enacted != null) openaps.put("enacted", enacted);
|
|
||||||
if (suggested != null) openaps.put("suggested", suggested);
|
|
||||||
if (iob != null) openaps.put("iob", iob);
|
|
||||||
record.put("openaps", openaps);
|
|
||||||
if (uploaderBattery != 0) record.put("uploaderBattery", uploaderBattery);
|
|
||||||
if (created_at != null) record.put("created_at", created_at);
|
|
||||||
if (configuration != null) record.put("configuration", configuration);
|
|
||||||
} catch (JSONException e) {
|
|
||||||
aapsLogger.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
return record;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load diff
|
@ -6,14 +6,14 @@ import androidx.room.TypeConverters
|
||||||
import info.nightscout.androidaps.database.daos.*
|
import info.nightscout.androidaps.database.daos.*
|
||||||
import info.nightscout.androidaps.database.entities.*
|
import info.nightscout.androidaps.database.entities.*
|
||||||
|
|
||||||
const val DATABASE_VERSION = 9
|
const val DATABASE_VERSION = 10
|
||||||
|
|
||||||
@Database(version = DATABASE_VERSION,
|
@Database(version = DATABASE_VERSION,
|
||||||
entities = [APSResult::class, Bolus::class, BolusCalculatorResult::class, Carbs::class,
|
entities = [APSResult::class, Bolus::class, BolusCalculatorResult::class, Carbs::class,
|
||||||
EffectiveProfileSwitch::class, ExtendedBolus::class, GlucoseValue::class, ProfileSwitch::class,
|
EffectiveProfileSwitch::class, ExtendedBolus::class, GlucoseValue::class, ProfileSwitch::class,
|
||||||
TemporaryBasal::class, TemporaryTarget::class, TherapyEvent::class, TotalDailyDose::class, APSResultLink::class,
|
TemporaryBasal::class, TemporaryTarget::class, TherapyEvent::class, TotalDailyDose::class, APSResultLink::class,
|
||||||
MultiwaveBolusLink::class, PreferenceChange::class, VersionChange::class, UserEntry::class,
|
MultiwaveBolusLink::class, PreferenceChange::class, VersionChange::class, UserEntry::class,
|
||||||
Food::class],
|
Food::class, DeviceStatus::class],
|
||||||
exportSchema = true)
|
exportSchema = true)
|
||||||
@TypeConverters(Converters::class)
|
@TypeConverters(Converters::class)
|
||||||
internal abstract class AppDatabase : RoomDatabase() {
|
internal abstract class AppDatabase : RoomDatabase() {
|
||||||
|
@ -54,4 +54,6 @@ internal abstract class AppDatabase : RoomDatabase() {
|
||||||
|
|
||||||
abstract val foodDao: FoodDao
|
abstract val foodDao: FoodDao
|
||||||
|
|
||||||
|
abstract val deviceStatusDao: DeviceStatusDao
|
||||||
|
|
||||||
}
|
}
|
|
@ -455,6 +455,26 @@ open class AppRepository @Inject internal constructor(
|
||||||
fun deleteAllBolusCalculatorResults() =
|
fun deleteAllBolusCalculatorResults() =
|
||||||
database.bolusCalculatorResultDao.deleteAllEntries()
|
database.bolusCalculatorResultDao.deleteAllEntries()
|
||||||
|
|
||||||
|
// DEVICE STATUS
|
||||||
|
fun insert(deviceStatus: DeviceStatus) : Long =
|
||||||
|
database.deviceStatusDao.insert(deviceStatus)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* returns a Pair of the next entity to sync and the ID of the "update".
|
||||||
|
* The update id might either be the entry id itself if it is a new entry - or the id
|
||||||
|
* of the update ("historic") entry. The sync counter should be incremented to that id if it was synced successfully.
|
||||||
|
*
|
||||||
|
* It is a Maybe as there might be no next element.
|
||||||
|
* */
|
||||||
|
|
||||||
|
fun getNextSyncElementDeviceStatus(id: Long): Maybe<DeviceStatus> =
|
||||||
|
database.deviceStatusDao.getNextModifiedOrNewAfter(id)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
|
||||||
|
fun getModifiedDeviceStatusDataFromId(lastId: Long): Single<List<DeviceStatus>> =
|
||||||
|
database.deviceStatusDao.getModifiedFrom(lastId)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("USELESS_CAST")
|
@Suppress("USELESS_CAST")
|
||||||
|
|
|
@ -24,5 +24,6 @@ internal class DelegatedAppDatabase(val changes: MutableList<DBEntry>, val datab
|
||||||
val userEntryDao: UserEntryDao = DelegatedUserEntryDao(changes, database.userEntryDao)
|
val userEntryDao: UserEntryDao = DelegatedUserEntryDao(changes, database.userEntryDao)
|
||||||
val preferenceChangeDao: PreferenceChangeDao = DelegatedPreferenceChangeDao(changes, database.preferenceChangeDao)
|
val preferenceChangeDao: PreferenceChangeDao = DelegatedPreferenceChangeDao(changes, database.preferenceChangeDao)
|
||||||
val foodDao: FoodDao = DelegatedFoodDao(changes, database.foodDao)
|
val foodDao: FoodDao = DelegatedFoodDao(changes, database.foodDao)
|
||||||
|
val deviceStatusDao: DeviceStatusDao = DelegatedDeviceStatusDao(changes, database.deviceStatusDao)
|
||||||
fun clearAllTables() = database.clearAllTables()
|
fun clearAllTables() = database.clearAllTables()
|
||||||
}
|
}
|
|
@ -5,11 +5,11 @@ const val TABLE_APS_RESULT_LINKS = "apsResultLinks"
|
||||||
const val TABLE_BOLUSES = "boluses"
|
const val TABLE_BOLUSES = "boluses"
|
||||||
const val TABLE_BOLUS_CALCULATOR_RESULTS = "bolusCalculatorResults"
|
const val TABLE_BOLUS_CALCULATOR_RESULTS = "bolusCalculatorResults"
|
||||||
const val TABLE_CARBS = "carbs"
|
const val TABLE_CARBS = "carbs"
|
||||||
|
const val TABLE_DEVICE_STATUS = "deviceStatus"
|
||||||
const val TABLE_EFFECTIVE_PROFILE_SWITCHES = "effectiveProfileSwitches"
|
const val TABLE_EFFECTIVE_PROFILE_SWITCHES = "effectiveProfileSwitches"
|
||||||
const val TABLE_EXTENDED_BOLUSES = "extendedBoluses"
|
const val TABLE_EXTENDED_BOLUSES = "extendedBoluses"
|
||||||
const val TABLE_GLUCOSE_VALUES = "glucoseValues"
|
const val TABLE_GLUCOSE_VALUES = "glucoseValues"
|
||||||
const val TABLE_FOODS = "foods"
|
const val TABLE_FOODS = "foods"
|
||||||
const val TABLE_MEAL_LINKS = "mealLinks"
|
|
||||||
const val TABLE_MULTIWAVE_BOLUS_LINKS = "multiwaveBolusLinks"
|
const val TABLE_MULTIWAVE_BOLUS_LINKS = "multiwaveBolusLinks"
|
||||||
const val TABLE_PROFILE_SWITCHES = "profileSwitches"
|
const val TABLE_PROFILE_SWITCHES = "profileSwitches"
|
||||||
const val TABLE_TEMPORARY_BASALS = "temporaryBasals"
|
const val TABLE_TEMPORARY_BASALS = "temporaryBasals"
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
package info.nightscout.androidaps.database.daos
|
||||||
|
|
||||||
|
import androidx.room.Dao
|
||||||
|
import androidx.room.Insert
|
||||||
|
import androidx.room.Query
|
||||||
|
import androidx.room.Update
|
||||||
|
import info.nightscout.androidaps.database.entities.DeviceStatus
|
||||||
|
import info.nightscout.androidaps.database.TABLE_DEVICE_STATUS
|
||||||
|
import io.reactivex.Maybe
|
||||||
|
import io.reactivex.Single
|
||||||
|
|
||||||
|
@Suppress("FunctionName")
|
||||||
|
@Dao
|
||||||
|
internal interface DeviceStatusDao {
|
||||||
|
|
||||||
|
@Insert
|
||||||
|
fun insert(entry: DeviceStatus): Long
|
||||||
|
|
||||||
|
@Update
|
||||||
|
fun update(entry: DeviceStatus)
|
||||||
|
|
||||||
|
@Query("SELECT * FROM $TABLE_DEVICE_STATUS WHERE id = :id")
|
||||||
|
fun findById(id: Long): DeviceStatus?
|
||||||
|
|
||||||
|
@Query("DELETE FROM $TABLE_DEVICE_STATUS")
|
||||||
|
fun deleteAllEntries()
|
||||||
|
|
||||||
|
@Query("DELETE FROM $TABLE_DEVICE_STATUS WHERE id NOT IN (SELECT MAX(id) FROM $TABLE_DEVICE_STATUS)")
|
||||||
|
fun deleteAllEntriesExceptLast()
|
||||||
|
|
||||||
|
@Query("SELECT * FROM $TABLE_DEVICE_STATUS WHERE nightscoutId = :nsId")
|
||||||
|
fun findByNSId(nsId: String): DeviceStatus?
|
||||||
|
|
||||||
|
// This query will be used with v3 to get all changed records
|
||||||
|
@Query("SELECT * FROM $TABLE_DEVICE_STATUS WHERE id > :id ORDER BY id ASC")
|
||||||
|
fun getModifiedFrom(id: Long): Single<List<DeviceStatus>>
|
||||||
|
|
||||||
|
// for WS we need 1 record only
|
||||||
|
@Query("SELECT * FROM $TABLE_DEVICE_STATUS WHERE id > :id ORDER BY id ASC limit 1")
|
||||||
|
fun getNextModifiedOrNewAfter(id: Long): Maybe<DeviceStatus>
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
package info.nightscout.androidaps.database.daos.delegated
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.database.daos.DeviceStatusDao
|
||||||
|
import info.nightscout.androidaps.database.interfaces.DBEntry
|
||||||
|
|
||||||
|
internal class DelegatedDeviceStatusDao(changes: MutableList<DBEntry>, private val dao: DeviceStatusDao) : DelegatedDao(changes), DeviceStatusDao by dao
|
|
@ -0,0 +1,44 @@
|
||||||
|
package info.nightscout.androidaps.database.entities
|
||||||
|
|
||||||
|
import androidx.room.Embedded
|
||||||
|
import androidx.room.Entity
|
||||||
|
import androidx.room.Index
|
||||||
|
import androidx.room.PrimaryKey
|
||||||
|
import info.nightscout.androidaps.database.TABLE_DEVICE_STATUS
|
||||||
|
import info.nightscout.androidaps.database.embedments.InterfaceIDs
|
||||||
|
import info.nightscout.androidaps.database.interfaces.DBEntryWithTime
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
@Entity(tableName = TABLE_DEVICE_STATUS,
|
||||||
|
foreignKeys = [],
|
||||||
|
indices = [Index("timestamp")])
|
||||||
|
data class DeviceStatus(
|
||||||
|
@PrimaryKey(autoGenerate = true)
|
||||||
|
var id: Long = 0,
|
||||||
|
@Embedded
|
||||||
|
var interfaceIDs_backing: InterfaceIDs? = null,
|
||||||
|
override var timestamp: Long,
|
||||||
|
override var utcOffset: Long = TimeZone.getDefault().getOffset(timestamp).toLong(),
|
||||||
|
var device: String? = null,
|
||||||
|
var pump: String? = null,
|
||||||
|
var enacted: String? = null,
|
||||||
|
var suggested: String? = null,
|
||||||
|
var iob: String? = null,
|
||||||
|
var uploaderBattery: Int = 0,
|
||||||
|
var configuration: String? = null
|
||||||
|
|
||||||
|
) : DBEntryWithTime {
|
||||||
|
|
||||||
|
var interfaceIDs: InterfaceIDs
|
||||||
|
get() {
|
||||||
|
var value = this.interfaceIDs_backing
|
||||||
|
if (value == null) {
|
||||||
|
value = InterfaceIDs()
|
||||||
|
interfaceIDs_backing = value
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
set(value) {
|
||||||
|
interfaceIDs_backing = value
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package info.nightscout.androidaps.database.transactions
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.database.entities.DeviceStatus
|
||||||
|
|
||||||
|
class UpdateNsIdDeviceStatusTransaction(val deviceStatus: DeviceStatus) : Transaction<Unit>() {
|
||||||
|
|
||||||
|
override fun run() {
|
||||||
|
val current = database.deviceStatusDao.findById(deviceStatus.id)
|
||||||
|
if (current != null && current.interfaceIDs.nightscoutId != deviceStatus.interfaceIDs.nightscoutId)
|
||||||
|
database.deviceStatusDao.update(deviceStatus)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue