DataBroadcastPlugin

This commit is contained in:
Milos Kozak 2020-01-28 18:00:46 +01:00
parent cf2855ab02
commit d559961c12
6 changed files with 227 additions and 22 deletions

View file

@ -58,6 +58,7 @@ import info.nightscout.androidaps.plugins.constraints.versionChecker.VersionChec
import info.nightscout.androidaps.plugins.general.actions.ActionsPlugin;
import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin;
import info.nightscout.androidaps.plugins.general.careportal.CareportalPlugin;
import info.nightscout.androidaps.plugins.general.dataBroadcaster.DataBroadcastPlugin;
import info.nightscout.androidaps.plugins.general.food.FoodPlugin;
import info.nightscout.androidaps.plugins.general.maintenance.LoggerUtils;
import info.nightscout.androidaps.plugins.general.maintenance.MaintenancePlugin;
@ -146,6 +147,7 @@ public class MainApp extends DaggerApplication {
@Inject DanaRSPlugin danaRSPlugin;
@Inject DanaRv2Plugin danaRv2Plugin;
@Inject DanaRKoreanPlugin danaRKoreanPlugin;
@Inject DataBroadcastPlugin dataBroadcastPlugin;
@Inject DstHelperPlugin dstHelperPlugin;
@Inject FoodPlugin foodPlugin;
@Inject InsulinOrefFreePeakPlugin insulinOrefFreePeakPlugin;
@ -295,6 +297,7 @@ public class MainApp extends DaggerApplication {
pluginsList.add(maintenancePlugin);
pluginsList.add(automationPlugin);
pluginsList.add(dstHelperPlugin);
pluginsList.add(dataBroadcastPlugin);
pluginsList.add(configBuilderPlugin);

View file

@ -0,0 +1,213 @@
package info.nightscout.androidaps.plugins.general.dataBroadcaster
import android.content.Context
import android.content.Intent
import android.content.pm.ResolveInfo
import android.os.Bundle
import dagger.Lazy
import info.nightscout.androidaps.Config
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.IobTotal
import info.nightscout.androidaps.db.BgReading
import info.nightscout.androidaps.events.Event
import info.nightscout.androidaps.events.EventExtendedBolusChange
import info.nightscout.androidaps.events.EventNewBasalProfile
import info.nightscout.androidaps.events.EventTempBasalChange
import info.nightscout.androidaps.events.EventTreatmentChange
import info.nightscout.androidaps.interfaces.ActivePluginProvider
import info.nightscout.androidaps.interfaces.PluginBase
import info.nightscout.androidaps.interfaces.PluginDescription
import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.BundleLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
import info.nightscout.androidaps.plugins.aps.openAPSMA.events.EventOpenAPSUpdateGui
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunction
import info.nightscout.androidaps.plugins.general.nsclient.data.NSDeviceStatus
import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensCalculationFinished
import info.nightscout.androidaps.services.Intents
import info.nightscout.androidaps.utils.BatteryLevel
import info.nightscout.androidaps.utils.DefaultValueHelper
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.resources.ResourceHelper
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class DataBroadcastPlugin @Inject constructor(
aapsLogger: AAPSLogger,
resourceHelper: ResourceHelper,
private val context: Context,
private val fabricPrivacy: FabricPrivacy,
private val rxBus: RxBusWrapper,
private val iobCobCalculatorPlugin: IobCobCalculatorPlugin,
private val profileFunction: ProfileFunction,
private val defaultValueHelper: DefaultValueHelper,
private val nsDeviceStatus: NSDeviceStatus,
private val lazyLoopPlugin: Lazy<LoopPlugin>,
private val activePlugin: ActivePluginProvider
) : PluginBase(PluginDescription()
.mainType(PluginType.GENERAL)
.pluginName(R.string.databroadcaster)
.alwaysEnabled(true)
.neverVisible(true)
.showInList(false),
aapsLogger, resourceHelper
) {
private val disposable = CompositeDisposable()
override fun onStart() {
super.onStart()
disposable.add(rxBus
.toObservable(EventOpenAPSUpdateGui::class.java)
.observeOn(Schedulers.io())
.subscribe({ sendData(it) }) { fabricPrivacy.logException(it) })
disposable.add(rxBus
.toObservable(EventExtendedBolusChange::class.java)
.observeOn(Schedulers.io())
.subscribe({ sendData(it) }) { fabricPrivacy.logException(it) })
disposable.add(rxBus
.toObservable(EventTempBasalChange::class.java)
.observeOn(Schedulers.io())
.subscribe({ sendData(it) }) { fabricPrivacy.logException(it) })
disposable.add(rxBus
.toObservable(EventTreatmentChange::class.java)
.observeOn(Schedulers.io())
.subscribe({ sendData(it) }) { fabricPrivacy.logException(it) })
disposable.add(rxBus
.toObservable(EventNewBasalProfile::class.java)
.observeOn(Schedulers.io())
.subscribe({ sendData(it) }) { fabricPrivacy.logException(it) })
disposable.add(rxBus
.toObservable(EventAutosensCalculationFinished::class.java)
.observeOn(Schedulers.io())
.subscribe({ sendData(it) }) { fabricPrivacy.logException(it) })
disposable.add(rxBus
.toObservable(EventOverviewBolusProgress::class.java)
.observeOn(Schedulers.io())
.subscribe({ sendData(it) }) { fabricPrivacy.logException(it) })
}
override fun onStop() {
disposable.clear()
super.onStop()
}
private fun sendData(event: Event) {
val bundle = Bundle()
bgStatus(bundle)
iobCob(bundle)
loopStatus(bundle)
basalStatus(bundle)
pumpStatus(bundle)
if (event is EventOverviewBolusProgress && !event.isSMB()) {
bundle.putInt("progressPercent", event.percent)
bundle.putString("progressStatus", event.status)
}
//aapsLogger.debug("Prepared bundle:\n" + BundleLogger.log(bundle))
sendBroadcast(
Intent(Intents.AAPS_BROADCAST) // "info.nightscout.androidaps.status"
.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
.putExtras(bundle)
)
}
private fun bgStatus(bundle: Bundle) {
val lastBG: BgReading = iobCobCalculatorPlugin.lastBg() ?: return
val glucoseStatus = GlucoseStatus.getGlucoseStatusData() ?: return
bundle.putDouble("glucoseMgdl", lastBG.value) // last BG in mgdl
bundle.putLong("glucoseTimeStamp", lastBG.date) // timestamp
bundle.putString("units", profileFunction.getUnits()) // units used in AAPS "mg/dl" or "mmol"
bundle.putString("slopeArrow", lastBG.directionToSymbol()) // direction arrow as string
bundle.putDouble("deltaMgdl", glucoseStatus.delta) // bg delta in mgdl
bundle.putDouble("avgDeltaMgdl", glucoseStatus.avgdelta) // average bg delta
bundle.putDouble("high", defaultValueHelper.determineHighLine()) // predefined top value of in range (green area)
bundle.putDouble("low", defaultValueHelper.determineLowLine()) // predefined bottom value of in range
}
private fun iobCob(bundle: Bundle) {
profileFunction.getProfile() ?: return
activePlugin.activeTreatments.updateTotalIOBTreatments()
val bolusIob: IobTotal = activePlugin.activeTreatments.lastCalculationTreatments.round()
activePlugin.activeTreatments.updateTotalIOBTempBasals()
val basalIob: IobTotal = activePlugin.activeTreatments.lastCalculationTempBasals.round()
bundle.putDouble("bolusIob", bolusIob.iob)
bundle.putDouble("basalIob", basalIob.basaliob)
bundle.putDouble("iob", bolusIob.iob + basalIob.basaliob) // total IOB
val cob = iobCobCalculatorPlugin.getCobInfo(false, "broadcast")
bundle.putDouble("cob", cob.displayCob ?: -1.0) // COB [g] or -1 if N/A
bundle.putDouble("futureCarbs", cob.futureCarbs) // future scheduled carbs
}
private fun loopStatus(bundle: Bundle) {
//batteries
bundle.putInt("phoneBattery", BatteryLevel.getBatteryLevel())
bundle.putInt("rigBattery", nsDeviceStatus.uploaderStatus.replace("%","").trim { it <= ' ' }.toInt())
if (Config.APS && lazyLoopPlugin.get().lastRun?.lastEnact != null) { //we are AndroidAPS
bundle.putLong("suggestedTimeStamp", lazyLoopPlugin.get().lastRun?.lastAPSRun?.time
?: -1L)
bundle.putString("suggested", lazyLoopPlugin.get().lastRun?.request?.json().toString())
if (lazyLoopPlugin.get().lastRun.tbrSetByPump != null && lazyLoopPlugin.get().lastRun.tbrSetByPump.enacted) {
bundle.putLong("enactedTimeStamp", lazyLoopPlugin.get().lastRun?.lastEnact?.time
?: -1L)
bundle.putString("enacted", lazyLoopPlugin.get().lastRun?.request?.json().toString())
}
} else { //NSClient or remote
val data = NSDeviceStatus.deviceStatusOpenAPSData
if (data.clockSuggested != 0L && data.suggested != null) {
bundle.putLong("suggestedTimeStamp", data.clockSuggested)
bundle.putString("suggested", data.suggested.toString())
}
if (data.clockEnacted != 0L && data.enacted != null) {
bundle.putLong("enactedTimeStamp", data.clockEnacted)
bundle.putString("enacted", data.enacted.toString())
}
}
}
private fun basalStatus(bundle: Bundle) {
val now = System.currentTimeMillis()
val profile = profileFunction.getProfile() ?: return
bundle.putLong("basalTimeStamp", now)
bundle.putDouble("baseBasal", profile.basal)
bundle.putString("profile", profileFunction.getProfileName())
activePlugin.activeTreatments.getTempBasalFromHistory(now)?.let {
bundle.putLong("tempBasalStart", it.date)
bundle.putInt("tempBasalDurationInMinutes", it.durationInMinutes)
if (it.isAbsolute) bundle.putDouble("tempBasalAbsolute", it.absoluteRate) // U/h for absolute TBR
else bundle.putInt("tempBasalPercent", it.percentRate) // % for percent type TBR
bundle.putString("tempBasalString", it.toStringFull()) // user friendly string
}
}
private fun pumpStatus(bundle: Bundle) {
val pump = activePlugin.activePump
bundle.putLong("pumpTimeStamp", pump.lastDataTime())
bundle.putInt("pumpBattery", pump.batteryLevel)
bundle.putDouble("pumpReservoir", pump.reservoirLevel)
bundle.putString("pumpStatus", pump.shortStatus(false))
}
private fun sendBroadcast(intent: Intent) {
val receivers: List<ResolveInfo> = context.packageManager.queryBroadcastReceivers(intent, 0)
for (resolveInfo in receivers)
resolveInfo.activityInfo.packageName?.let {
intent.setPackage(it)
context.sendBroadcast(intent)
aapsLogger.debug(LTag.CORE, "Sending broadcast " + intent.action + " to: " + it)
}
}
}

View file

@ -282,13 +282,13 @@ public class NSDeviceStatus {
// ********* OpenAPS data ***********
static DeviceStatusOpenAPSData deviceStatusOpenAPSData = new DeviceStatusOpenAPSData();
public static DeviceStatusOpenAPSData deviceStatusOpenAPSData = new DeviceStatusOpenAPSData();
static class DeviceStatusOpenAPSData {
long clockSuggested = 0L;
long clockEnacted = 0L;
public static class DeviceStatusOpenAPSData {
public long clockSuggested = 0L;
public long clockEnacted = 0L;
JSONObject suggested = null;
public JSONObject suggested = null;
public JSONObject enacted = null;
}

View file

@ -1,10 +1,7 @@
package info.nightscout.androidaps.plugins.general.wear.wearintegration;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.AsyncTask;
import android.os.BatteryManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
@ -53,6 +50,7 @@ import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
import info.nightscout.androidaps.plugins.treatments.Treatment;
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
import info.nightscout.androidaps.utils.BatteryLevel;
import info.nightscout.androidaps.utils.DecimalFormatter;
import info.nightscout.androidaps.utils.DefaultValueHelper;
import info.nightscout.androidaps.utils.ToastUtils;
@ -706,7 +704,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
//batteries
int phoneBattery = getBatteryLevel(getApplicationContext());
int phoneBattery = BatteryLevel.getBatteryLevel();
String rigBattery = nsDeviceStatus.getUploaderStatus().trim();
@ -848,17 +846,4 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
public static boolean shouldReportLoopStatus(boolean enabled) {
return (lastLoopStatus != enabled);
}
public static int getBatteryLevel(Context context) {
Intent batteryIntent = context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
if (batteryIntent != null) {
int level = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
int scale = batteryIntent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
if (level == -1 || scale == -1) {
return 50;
}
return (int) (((float) level / (float) scale) * 100.0f);
}
return 50;
}
}

View file

@ -34,4 +34,7 @@ public interface Intents {
String POCTECH_BG = "com.china.poctech.data";
String TOMATO_BG = "com.fanqies.tomatofn.BgEstimate";
// Broadcast status
String AAPS_BROADCAST = "info.nightscout.androidaps.status";
}

View file

@ -1695,5 +1695,6 @@
<string name="phonechecker">\"PhoneChecker\"</string>
<string name="chartmenu">Chart menu</string>
<string name="sensitivity_short">AS</string>
<string name="databroadcaster" translatable="false">Data Broadcaster</string>
</resources>