move XDripBroadcast to XdripPlugin
This commit is contained in:
parent
d57ec150a5
commit
36153c9b49
19 changed files with 303 additions and 224 deletions
|
@ -1,14 +1,87 @@
|
|||
package info.nightscout.interfaces
|
||||
|
||||
import info.nightscout.database.entities.Bolus
|
||||
import info.nightscout.database.entities.Carbs
|
||||
import info.nightscout.database.entities.DeviceStatus
|
||||
import info.nightscout.database.entities.EffectiveProfileSwitch
|
||||
import info.nightscout.database.entities.ExtendedBolus
|
||||
import info.nightscout.database.entities.GlucoseValue
|
||||
import info.nightscout.database.entities.OfflineEvent
|
||||
import info.nightscout.database.entities.ProfileSwitch
|
||||
import info.nightscout.database.entities.TemporaryBasal
|
||||
import info.nightscout.database.entities.TemporaryTarget
|
||||
import info.nightscout.database.entities.TherapyEvent
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
|
||||
/**
|
||||
* Send data to xDrip+ via Inter-app settings
|
||||
*/
|
||||
interface XDripBroadcast {
|
||||
|
||||
/**
|
||||
* Send calibration to xDrip+
|
||||
* Accepting must be enabled in Inter-app settings - Accept Calibrations
|
||||
*/
|
||||
fun sendCalibration(bg: Double): Boolean
|
||||
fun send(glucoseValue: GlucoseValue)
|
||||
fun sendIn640gMode(glucoseValue: GlucoseValue)
|
||||
fun sendProfile(profileStoreJson: JSONObject)
|
||||
fun sendTreatments(addedOrUpdatedTreatments: JSONArray)
|
||||
fun sendSgvs(sgvs: JSONArray)
|
||||
|
||||
/**
|
||||
* Send data to xDrip+
|
||||
* Accepting must be enabled in Inter-app settings - Accept Glucose
|
||||
*/
|
||||
fun send(gv: GlucoseValue)
|
||||
/**
|
||||
* Send data to xDrip+
|
||||
* Accepting must be enabled in Inter-app settings - Accept treatments
|
||||
*/
|
||||
fun send(bolus: Bolus)
|
||||
/**
|
||||
* Send data to xDrip+
|
||||
* Accepting must be enabled in Inter-app settings - Accept treatments
|
||||
*/
|
||||
fun send(carbs: Carbs)
|
||||
/**
|
||||
* Send data to xDrip+
|
||||
* Accepting must be enabled in Inter-app settings - Accept treatments
|
||||
*/
|
||||
fun send(tt: TemporaryTarget)
|
||||
/**
|
||||
* Send data to xDrip+
|
||||
* Accepting must be enabled in Inter-app settings - Accept treatments
|
||||
*/
|
||||
fun send(te: TherapyEvent)
|
||||
/**
|
||||
* Send data to xDrip+
|
||||
* Accepting must be enabled in Inter-app settings - Accept treatments
|
||||
*/
|
||||
fun send(deviceStatus: DeviceStatus)
|
||||
/**
|
||||
* Send data to xDrip+
|
||||
* Accepting must be enabled in Inter-app settings - Accept treatments
|
||||
*/
|
||||
fun send(tb: TemporaryBasal)
|
||||
/**
|
||||
* Send data to xDrip+
|
||||
* Accepting must be enabled in Inter-app settings - Accept treatments
|
||||
*/
|
||||
fun send(eb: ExtendedBolus)
|
||||
/**
|
||||
* Send data to xDrip+
|
||||
* Accepting must be enabled in Inter-app settings - Accept treatments
|
||||
*/
|
||||
fun send(ps: ProfileSwitch)
|
||||
/**
|
||||
* Send data to xDrip+
|
||||
* Accepting must be enabled in Inter-app settings - Accept treatments
|
||||
*/
|
||||
fun send(ps: EffectiveProfileSwitch)
|
||||
/**
|
||||
* Send data to xDrip+
|
||||
* Accepting must be enabled in Inter-app settings - Accept treatments
|
||||
*/
|
||||
fun send(ps: OfflineEvent)
|
||||
}
|
|
@ -10,6 +10,10 @@ interface Intents {
|
|||
const val ACTION_NEW_PROFILE = "info.nightscout.client.NEW_PROFILE"
|
||||
const val ACTION_NEW_SGV = "info.nightscout.client.NEW_SGV"
|
||||
|
||||
const val EXTRA_STATUSLINE = "com.eveningoutpost.dexdrip.Extras.Statusline"
|
||||
const val ACTION_NEW_EXTERNAL_STATUSLINE = "com.eveningoutpost.dexdrip.ExternalStatusline"
|
||||
const val RECEIVER_PERMISSION = "com.eveningoutpost.dexdrip.permissions.RECEIVE_EXTERNAL_STATUSLINE"
|
||||
|
||||
// AAPS -> xDrip 640G mode
|
||||
const val XDRIP_PLUS_NS_EMULATOR = "com.eveningoutpost.dexdrip.NS_EMULATOR"
|
||||
|
||||
|
|
|
@ -1,163 +0,0 @@
|
|||
package info.nightscout.implementation
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import info.nightscout.androidaps.annotations.OpenForTesting
|
||||
import info.nightscout.core.ui.toast.ToastUtils
|
||||
import info.nightscout.database.entities.GlucoseValue
|
||||
import info.nightscout.interfaces.GlucoseUnit
|
||||
import info.nightscout.interfaces.XDripBroadcast
|
||||
import info.nightscout.interfaces.profile.ProfileFunction
|
||||
import info.nightscout.interfaces.receivers.Intents
|
||||
import info.nightscout.rx.logging.AAPSLogger
|
||||
import info.nightscout.rx.logging.LTag
|
||||
import info.nightscout.shared.extensions.safeQueryBroadcastReceivers
|
||||
import info.nightscout.shared.interfaces.ResourceHelper
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Suppress("SpellCheckingInspection")
|
||||
@OpenForTesting
|
||||
@Singleton
|
||||
class XDripBroadcastImpl @Inject constructor(
|
||||
private val context: Context,
|
||||
private val aapsLogger: AAPSLogger,
|
||||
private val sp: SP,
|
||||
private val rh: ResourceHelper,
|
||||
private val profileFunction: ProfileFunction
|
||||
) : XDripBroadcast {
|
||||
|
||||
override fun sendCalibration(bg: Double): Boolean {
|
||||
val bundle = Bundle()
|
||||
bundle.putDouble("glucose_number", bg)
|
||||
bundle.putString("units", if (profileFunction.getUnits() == GlucoseUnit.MGDL) "mgdl" else "mmol")
|
||||
bundle.putLong("timestamp", System.currentTimeMillis())
|
||||
val intent = Intent(Intents.ACTION_REMOTE_CALIBRATION)
|
||||
intent.putExtras(bundle)
|
||||
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
|
||||
context.sendBroadcast(intent)
|
||||
val q = context.packageManager.safeQueryBroadcastReceivers(intent, 0)
|
||||
return if (q.isEmpty()) {
|
||||
ToastUtils.errorToast(context, R.string.xdrip_not_installed)
|
||||
aapsLogger.debug(rh.gs(R.string.xdrip_not_installed))
|
||||
false
|
||||
} else {
|
||||
ToastUtils.errorToast(context, R.string.calibration_sent)
|
||||
aapsLogger.debug(rh.gs(R.string.calibration_sent))
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
// sent in 640G mode
|
||||
override fun send(glucoseValue: GlucoseValue) {
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_dexcomg5_xdripupload, false)) {
|
||||
val format = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.US)
|
||||
try {
|
||||
val entriesBody = JSONArray()
|
||||
val json = JSONObject()
|
||||
json.put("sgv", glucoseValue.value)
|
||||
json.put("direction", glucoseValue.trendArrow.text)
|
||||
json.put("device", "G5")
|
||||
json.put("type", "sgv")
|
||||
json.put("date", glucoseValue.timestamp)
|
||||
json.put("dateString", format.format(glucoseValue.timestamp))
|
||||
entriesBody.put(json)
|
||||
val bundle = Bundle()
|
||||
bundle.putString("action", "add")
|
||||
bundle.putString("collection", "entries")
|
||||
bundle.putString("data", entriesBody.toString())
|
||||
val intent = Intent(Intents.XDRIP_PLUS_NS_EMULATOR)
|
||||
intent.putExtras(bundle).addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
|
||||
context.sendBroadcast(intent)
|
||||
val receivers = context.packageManager.safeQueryBroadcastReceivers(intent, 0)
|
||||
if (receivers.isEmpty()) {
|
||||
//NSUpload.log.debug("No xDrip receivers found. ")
|
||||
aapsLogger.debug(LTag.BGSOURCE, "No xDrip receivers found.")
|
||||
} else {
|
||||
aapsLogger.debug(LTag.BGSOURCE, "${receivers.size} xDrip receivers")
|
||||
}
|
||||
} catch (e: JSONException) {
|
||||
aapsLogger.error(LTag.BGSOURCE, "Unhandled exception", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sent in NSClient dbaccess mode
|
||||
override fun sendProfile(profileStoreJson: JSONObject) {
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_nsclient_localbroadcasts, false))
|
||||
broadcast(
|
||||
Intent(Intents.ACTION_NEW_PROFILE).apply {
|
||||
addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
|
||||
putExtras(Bundle().apply { putString("profile", profileStoreJson.toString()) })
|
||||
}
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
// sent in NSClient dbaccess mode
|
||||
override fun sendTreatments(addedOrUpdatedTreatments: JSONArray) {
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_nsclient_localbroadcasts, false))
|
||||
splitArray(addedOrUpdatedTreatments).forEach { part ->
|
||||
broadcast(
|
||||
Intent(Intents.ACTION_NEW_TREATMENT).apply {
|
||||
addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
|
||||
putExtras(Bundle().apply { putString("treatments", part.toString()) })
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// sent in NSClient dbaccess mode
|
||||
override fun sendSgvs(sgvs: JSONArray) {
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_nsclient_localbroadcasts, false))
|
||||
splitArray(sgvs).forEach { part ->
|
||||
broadcast(
|
||||
Intent(Intents.ACTION_NEW_SGV).apply {
|
||||
addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
|
||||
putExtras(Bundle().apply { putString("sgvs", part.toString()) })
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun splitArray(array: JSONArray): List<JSONArray> {
|
||||
var ret: MutableList<JSONArray> = ArrayList()
|
||||
try {
|
||||
val size = array.length()
|
||||
var count = 0
|
||||
var newarr: JSONArray? = null
|
||||
for (i in 0 until size) {
|
||||
if (count == 0) {
|
||||
if (newarr != null) ret.add(newarr)
|
||||
newarr = JSONArray()
|
||||
count = 20
|
||||
}
|
||||
newarr?.put(array[i])
|
||||
--count
|
||||
}
|
||||
if (newarr != null && newarr.length() > 0) ret.add(newarr)
|
||||
} catch (e: JSONException) {
|
||||
aapsLogger.error("Unhandled exception", e)
|
||||
ret = ArrayList()
|
||||
ret.add(array)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
private fun broadcast(intent: Intent) {
|
||||
context.packageManager.safeQueryBroadcastReceivers(intent, 0).forEach { resolveInfo ->
|
||||
resolveInfo.activityInfo.packageName?.let {
|
||||
intent.setPackage(it)
|
||||
context.sendBroadcast(intent)
|
||||
aapsLogger.debug(LTag.CORE, "Sending broadcast " + intent.action + " to: " + it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,7 +10,6 @@ import info.nightscout.implementation.LocalAlertUtilsImpl
|
|||
import info.nightscout.implementation.TranslatorImpl
|
||||
import info.nightscout.implementation.TrendCalculatorImpl
|
||||
import info.nightscout.implementation.UserEntryLoggerImpl
|
||||
import info.nightscout.implementation.XDripBroadcastImpl
|
||||
import info.nightscout.implementation.androidNotification.NotificationHolderImpl
|
||||
import info.nightscout.implementation.db.PersistenceLayerImpl
|
||||
import info.nightscout.implementation.iob.GlucoseStatusProviderImpl
|
||||
|
@ -40,7 +39,6 @@ import info.nightscout.implementation.userEntry.UserEntryPresentationHelperImpl
|
|||
import info.nightscout.interfaces.LocalAlertUtils
|
||||
import info.nightscout.interfaces.NotificationHolder
|
||||
import info.nightscout.interfaces.Translator
|
||||
import info.nightscout.interfaces.XDripBroadcast
|
||||
import info.nightscout.interfaces.db.PersistenceLayer
|
||||
import info.nightscout.interfaces.iob.GlucoseStatusProvider
|
||||
import info.nightscout.interfaces.logging.LoggerUtils
|
||||
|
@ -105,7 +103,6 @@ abstract class ImplementationModule {
|
|||
@Binds fun bindTirCalculatorInterface(tirCalculator: TirCalculatorImpl): TirCalculator
|
||||
@Binds fun bindDexcomTirCalculatorInterface(dexcomTirCalculator: DexcomTirCalculatorImpl): DexcomTirCalculator
|
||||
@Binds fun bindPumpSyncInterface(pumpSyncImplementation: PumpSyncImplementation): PumpSync
|
||||
@Binds fun bindXDripBroadcastInterface(xDripBroadcastImpl: XDripBroadcastImpl): XDripBroadcast
|
||||
@Binds fun bindLocalAlertUtilsInterface(localAlertUtils: LocalAlertUtilsImpl): LocalAlertUtils
|
||||
@Binds fun bindIconsProviderInterface(iconsProvider: IconsProviderImplementation): IconsProvider
|
||||
@Binds fun bindNotificationHolderInterface(notificationHolder: NotificationHolderImpl): NotificationHolder
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="xdrip_not_installed">xDrip+ not installed</string>
|
||||
<string name="calibration_sent">Calibration sent to xDrip+</string>
|
||||
|
||||
<string name="bg_label">BG</string>
|
||||
|
||||
<string name="executing_right_now">Command is executed right now</string>
|
||||
|
|
|
@ -185,11 +185,11 @@ class DexcomPlugin @Inject constructor(
|
|||
}
|
||||
}
|
||||
}
|
||||
xDripBroadcast.send(result.inserted[i])
|
||||
xDripBroadcast.sendIn640gMode(result.inserted[i])
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted bg ${result.inserted[i]}")
|
||||
}
|
||||
result.updated.forEach {
|
||||
xDripBroadcast.send(it)
|
||||
xDripBroadcast.sendIn640gMode(it)
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated bg $it")
|
||||
}
|
||||
result.sensorInsertionsInserted.forEach {
|
||||
|
|
|
@ -114,7 +114,7 @@ class EversensePlugin @Inject constructor(
|
|||
.blockingGet()
|
||||
.also { savedValues ->
|
||||
savedValues.inserted.forEach {
|
||||
xDripBroadcast.send(it)
|
||||
xDripBroadcast.sendIn640gMode(it)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted bg $it")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ class GlimpPlugin @Inject constructor(
|
|||
.blockingGet()
|
||||
.also { savedValues ->
|
||||
savedValues.inserted.forEach {
|
||||
xDripBroadcast.send(it)
|
||||
xDripBroadcast.sendIn640gMode(it)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted bg $it")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -148,7 +148,7 @@ class GlunovoPlugin @Inject constructor(
|
|||
.blockingGet()
|
||||
.also { savedValues ->
|
||||
savedValues.inserted.forEach {
|
||||
xDripBroadcast.send(it)
|
||||
xDripBroadcast.sendIn640gMode(it)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted bg $it")
|
||||
}
|
||||
savedValues.calibrationsInserted.forEach { calibration ->
|
||||
|
|
|
@ -159,7 +159,7 @@ class IntelligoPlugin @Inject constructor(
|
|||
.blockingGet()
|
||||
.also { savedValues ->
|
||||
savedValues.inserted.forEach {
|
||||
xDripBroadcast.send(it)
|
||||
xDripBroadcast.sendIn640gMode(it)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted bg $it")
|
||||
}
|
||||
savedValues.calibrationsInserted.forEach { calibration ->
|
||||
|
|
|
@ -90,7 +90,7 @@ class MM640gPlugin @Inject constructor(
|
|||
.blockingGet()
|
||||
.also { savedValues ->
|
||||
savedValues.all().forEach {
|
||||
xDripBroadcast.send(it)
|
||||
xDripBroadcast.sendIn640gMode(it)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted bg $it")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -150,7 +150,6 @@ class NSClientSourcePlugin @Inject constructor(
|
|||
}
|
||||
|
||||
} else if (sgvs is List<*>) { // V3 client
|
||||
// xDripBroadcast.sendSgvs(sgvs)
|
||||
|
||||
for (i in 0 until sgvs.size) {
|
||||
val sgv = toGv(sgvs[i] as NSSgvV3)
|
||||
|
|
|
@ -83,7 +83,7 @@ class PoctechPlugin @Inject constructor(
|
|||
.blockingGet()
|
||||
.also { savedValues ->
|
||||
savedValues.inserted.forEach {
|
||||
xDripBroadcast.send(it)
|
||||
xDripBroadcast.sendIn640gMode(it)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted bg $it")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -119,7 +119,7 @@ class RandomBgPlugin @Inject constructor(
|
|||
disposable += repository.runTransactionForResult(CgmSourceTransaction(glucoseValues, emptyList(), null))
|
||||
.subscribe({ savedValues ->
|
||||
savedValues.inserted.forEach {
|
||||
xDripBroadcast.send(it)
|
||||
xDripBroadcast.sendIn640gMode(it)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted bg $it")
|
||||
}
|
||||
}, { aapsLogger.error(LTag.DATABASE, "Error while saving values from Random plugin", it) }
|
||||
|
|
|
@ -74,7 +74,7 @@ class TomatoPlugin @Inject constructor(
|
|||
.blockingGet()
|
||||
.also { savedValues ->
|
||||
savedValues.inserted.forEach {
|
||||
xDripBroadcast.send(it)
|
||||
xDripBroadcast.sendIn640gMode(it)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted bg $it")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import dagger.Module
|
|||
import dagger.Provides
|
||||
import dagger.Reusable
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import info.nightscout.interfaces.XDripBroadcast
|
||||
import info.nightscout.interfaces.nsclient.NSSettingsStatus
|
||||
import info.nightscout.interfaces.nsclient.ProcessedDeviceStatusData
|
||||
import info.nightscout.interfaces.nsclient.StoreDataForDb
|
||||
|
@ -32,6 +33,7 @@ import info.nightscout.plugins.sync.nsclientV3.workers.LoadTreatmentsWorker
|
|||
import info.nightscout.plugins.sync.nsclientV3.workers.ProcessFoodWorker
|
||||
import info.nightscout.plugins.sync.nsclientV3.workers.ProcessTreatmentsWorker
|
||||
import info.nightscout.plugins.sync.tidepool.TidepoolFragment
|
||||
import info.nightscout.plugins.sync.xdrip.XdripPlugin
|
||||
|
||||
@Module(
|
||||
includes = [
|
||||
|
@ -80,6 +82,7 @@ abstract class SyncModule {
|
|||
@Binds fun bindNSSettingsStatus(nsSettingsStatusImpl: NSSettingsStatusImpl): NSSettingsStatus
|
||||
@Binds fun bindDataSyncSelectorInterface(dataSyncSelectorImplementation: DataSyncSelectorImplementation): DataSyncSelector
|
||||
@Binds fun bindStoreDataForDb(storeDataForDbImpl: StoreDataForDbImpl): StoreDataForDb
|
||||
@Binds fun bindXDripBroadcastInterface(xDripBroadcastImpl: XdripPlugin): XDripBroadcast
|
||||
}
|
||||
|
||||
}
|
|
@ -163,19 +163,19 @@ class StoreDataForDbImpl @Inject constructor(
|
|||
.also { result ->
|
||||
glucoseValues.clear()
|
||||
result.updated.forEach {
|
||||
xDripBroadcast.send(it)
|
||||
xDripBroadcast.sendIn640gMode(it)
|
||||
nsClientSource.detectSource(it)
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated bg $it")
|
||||
updated.inc(GlucoseValue::class.java.simpleName)
|
||||
}
|
||||
result.inserted.forEach {
|
||||
xDripBroadcast.send(it)
|
||||
xDripBroadcast.sendIn640gMode(it)
|
||||
nsClientSource.detectSource(it)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted bg $it")
|
||||
inserted.inc(GlucoseValue::class.java.simpleName)
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
xDripBroadcast.send(it)
|
||||
xDripBroadcast.sendIn640gMode(it)
|
||||
nsClientSource.detectSource(it)
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId bg $it")
|
||||
nsIdUpdated.inc(GlucoseValue::class.java.simpleName)
|
||||
|
|
|
@ -7,7 +7,21 @@ import dagger.android.HasAndroidInjector
|
|||
import info.nightscout.core.extensions.toStringShort
|
||||
import info.nightscout.core.iob.generateCOBString
|
||||
import info.nightscout.core.iob.round
|
||||
import info.nightscout.core.ui.toast.ToastUtils
|
||||
import info.nightscout.core.utils.fabric.FabricPrivacy
|
||||
import info.nightscout.database.entities.Bolus
|
||||
import info.nightscout.database.entities.Carbs
|
||||
import info.nightscout.database.entities.DeviceStatus
|
||||
import info.nightscout.database.entities.EffectiveProfileSwitch
|
||||
import info.nightscout.database.entities.ExtendedBolus
|
||||
import info.nightscout.database.entities.GlucoseValue
|
||||
import info.nightscout.database.entities.OfflineEvent
|
||||
import info.nightscout.database.entities.ProfileSwitch
|
||||
import info.nightscout.database.entities.TemporaryBasal
|
||||
import info.nightscout.database.entities.TemporaryTarget
|
||||
import info.nightscout.database.entities.TherapyEvent
|
||||
import info.nightscout.interfaces.GlucoseUnit
|
||||
import info.nightscout.interfaces.XDripBroadcast
|
||||
import info.nightscout.interfaces.aps.Loop
|
||||
import info.nightscout.interfaces.iob.IobCobCalculator
|
||||
import info.nightscout.interfaces.plugin.PluginBase
|
||||
|
@ -15,23 +29,27 @@ import info.nightscout.interfaces.plugin.PluginDescription
|
|||
import info.nightscout.interfaces.plugin.PluginType
|
||||
import info.nightscout.interfaces.profile.Profile
|
||||
import info.nightscout.interfaces.profile.ProfileFunction
|
||||
import info.nightscout.interfaces.receivers.Intents
|
||||
import info.nightscout.interfaces.utils.DecimalFormatter
|
||||
import info.nightscout.plugins.sync.R
|
||||
import info.nightscout.rx.AapsSchedulers
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
import info.nightscout.rx.events.EventAppInitialized
|
||||
import info.nightscout.rx.events.EventAutosensCalculationFinished
|
||||
import info.nightscout.rx.events.EventConfigBuilderChange
|
||||
import info.nightscout.rx.events.EventExtendedBolusChange
|
||||
import info.nightscout.rx.events.EventPreferenceChange
|
||||
import info.nightscout.rx.events.EventNewHistoryData
|
||||
import info.nightscout.rx.events.EventRefreshOverview
|
||||
import info.nightscout.rx.events.EventTempBasalChange
|
||||
import info.nightscout.rx.events.EventTreatmentChange
|
||||
import info.nightscout.rx.logging.AAPSLogger
|
||||
import info.nightscout.rx.logging.LTag
|
||||
import info.nightscout.shared.extensions.safeQueryBroadcastReceivers
|
||||
import info.nightscout.shared.interfaces.ResourceHelper
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||
import io.reactivex.rxjava3.kotlin.plusAssign
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
|
@ -58,65 +76,40 @@ class XdripPlugin @Inject constructor(
|
|||
.preferencesId(R.xml.pref_xdrip)
|
||||
.description(R.string.description_xdrip),
|
||||
aapsLogger, rh, injector
|
||||
) {
|
||||
), XDripBroadcast {
|
||||
|
||||
private val disposable = CompositeDisposable()
|
||||
private var lastLoopStatus = false
|
||||
|
||||
companion object {
|
||||
|
||||
//broadcast related constants
|
||||
@Suppress("SpellCheckingInspection")
|
||||
private const val EXTRA_STATUSLINE = "com.eveningoutpost.dexdrip.Extras.Statusline"
|
||||
|
||||
@Suppress("SpellCheckingInspection")
|
||||
private const val ACTION_NEW_EXTERNAL_STATUSLINE = "com.eveningoutpost.dexdrip.ExternalStatusline"
|
||||
|
||||
@Suppress("SpellCheckingInspection", "unused")
|
||||
private const val RECEIVER_PERMISSION = "com.eveningoutpost.dexdrip.permissions.RECEIVE_EXTERNAL_STATUSLINE"
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
disposable += rxBus.toObservable(EventRefreshOverview::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ if (lastLoopStatus != (loop as PluginBase).isEnabled()) sendStatus() }, fabricPrivacy::logException)
|
||||
disposable += rxBus.toObservable(EventExtendedBolusChange::class.java)
|
||||
.subscribe({ if (lastLoopStatus != loop.isEnabled()) sendStatusLine() }, fabricPrivacy::logException)
|
||||
disposable += rxBus.toObservable(EventNewHistoryData::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ sendStatus() }, fabricPrivacy::logException)
|
||||
disposable += rxBus.toObservable(EventTempBasalChange::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ sendStatus() }, fabricPrivacy::logException)
|
||||
disposable += rxBus.toObservable(EventTreatmentChange::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ sendStatus() }, fabricPrivacy::logException)
|
||||
disposable += rxBus.toObservable(EventConfigBuilderChange::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ sendStatus() }, fabricPrivacy::logException)
|
||||
.subscribe({ sendStatusLine() }, fabricPrivacy::logException)
|
||||
disposable += rxBus.toObservable(EventAutosensCalculationFinished::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ sendStatus() }, fabricPrivacy::logException)
|
||||
disposable += rxBus.toObservable(EventPreferenceChange::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ sendStatus() }, fabricPrivacy::logException)
|
||||
.subscribe({ sendStatusLine() }, fabricPrivacy::logException)
|
||||
disposable += rxBus.toObservable(EventAppInitialized::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ sendStatus() }, fabricPrivacy::logException)
|
||||
.subscribe({ sendStatusLine() }, fabricPrivacy::logException)
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
disposable.clear()
|
||||
sendStatus()
|
||||
sendStatusLine()
|
||||
}
|
||||
|
||||
private fun sendStatus() {
|
||||
private fun sendStatusLine() {
|
||||
if (sp.getBoolean(R.string.key_xdrip_send_status, false)) {
|
||||
val status = profileFunction.getProfile()?.let { buildStatusLine(it) } ?: ""
|
||||
context.sendBroadcast(
|
||||
Intent(ACTION_NEW_EXTERNAL_STATUSLINE).also {
|
||||
Intent(Intents.ACTION_NEW_EXTERNAL_STATUSLINE).also {
|
||||
it.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
|
||||
it.putExtras(Bundle().apply { putString(EXTRA_STATUSLINE, status) })
|
||||
it.putExtras(Bundle().apply { putString(Intents.EXTRA_STATUSLINE, status) })
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -154,4 +147,176 @@ class XdripPlugin @Inject constructor(
|
|||
status.append(" ").append(iobCobCalculator.getCobInfo("StatusLinePlugin").generateCOBString())
|
||||
return status.toString()
|
||||
}
|
||||
|
||||
override fun sendCalibration(bg: Double): Boolean {
|
||||
val bundle = Bundle()
|
||||
bundle.putDouble("glucose_number", bg)
|
||||
bundle.putString("units", if (profileFunction.getUnits() == GlucoseUnit.MGDL) "mgdl" else "mmol")
|
||||
bundle.putLong("timestamp", System.currentTimeMillis())
|
||||
val intent = Intent(Intents.ACTION_REMOTE_CALIBRATION)
|
||||
intent.putExtras(bundle)
|
||||
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
|
||||
context.sendBroadcast(intent)
|
||||
val q = context.packageManager.safeQueryBroadcastReceivers(intent, 0)
|
||||
return if (q.isEmpty()) {
|
||||
ToastUtils.errorToast(context, R.string.xdrip_not_installed)
|
||||
aapsLogger.debug(rh.gs(R.string.xdrip_not_installed))
|
||||
false
|
||||
} else {
|
||||
ToastUtils.errorToast(context, R.string.calibration_sent)
|
||||
aapsLogger.debug(rh.gs(R.string.calibration_sent))
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
// sent in 640G mode
|
||||
// com.eveningoutpost.dexdrip.NSEmulatorReceiver
|
||||
override fun sendIn640gMode(glucoseValue: GlucoseValue) {
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_dexcomg5_xdripupload, false)) {
|
||||
val format = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.US)
|
||||
try {
|
||||
val entriesBody = JSONArray()
|
||||
val json = JSONObject()
|
||||
json.put("sgv", glucoseValue.value)
|
||||
json.put("direction", glucoseValue.trendArrow.text)
|
||||
json.put("device", "G5")
|
||||
json.put("type", "sgv")
|
||||
json.put("date", glucoseValue.timestamp)
|
||||
json.put("dateString", format.format(glucoseValue.timestamp))
|
||||
entriesBody.put(json)
|
||||
val bundle = Bundle()
|
||||
bundle.putString("action", "add")
|
||||
bundle.putString("collection", "entries")
|
||||
bundle.putString("data", entriesBody.toString())
|
||||
val intent = Intent(Intents.XDRIP_PLUS_NS_EMULATOR)
|
||||
intent.putExtras(bundle).addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
|
||||
context.sendBroadcast(intent)
|
||||
val receivers = context.packageManager.safeQueryBroadcastReceivers(intent, 0)
|
||||
if (receivers.isEmpty()) {
|
||||
//NSUpload.log.debug("No xDrip receivers found. ")
|
||||
aapsLogger.debug(LTag.BGSOURCE, "No xDrip receivers found.")
|
||||
} else {
|
||||
aapsLogger.debug(LTag.BGSOURCE, "${receivers.size} xDrip receivers")
|
||||
}
|
||||
} catch (e: JSONException) {
|
||||
aapsLogger.error(LTag.BGSOURCE, "Unhandled exception", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sent in NSClient dbaccess mode
|
||||
override fun sendProfile(profileStoreJson: JSONObject) {
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_nsclient_localbroadcasts, false))
|
||||
broadcast(
|
||||
Intent(Intents.ACTION_NEW_PROFILE).apply {
|
||||
addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
|
||||
putExtras(Bundle().apply { putString("profile", profileStoreJson.toString()) })
|
||||
}
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
// sent in NSClient dbaccess mode
|
||||
override fun sendTreatments(addedOrUpdatedTreatments: JSONArray) {
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_nsclient_localbroadcasts, false))
|
||||
splitArray(addedOrUpdatedTreatments).forEach { part ->
|
||||
broadcast(
|
||||
Intent(Intents.ACTION_NEW_TREATMENT).apply {
|
||||
addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
|
||||
putExtras(Bundle().apply { putString("treatments", part.toString()) })
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// sent in NSClient dbaccess mode
|
||||
override fun sendSgvs(sgvs: JSONArray) {
|
||||
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_nsclient_localbroadcasts, false))
|
||||
splitArray(sgvs).forEach { part ->
|
||||
broadcast(
|
||||
Intent(Intents.ACTION_NEW_SGV).apply {
|
||||
addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
|
||||
putExtras(Bundle().apply { putString("sgvs", part.toString()) })
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun send(gv: GlucoseValue) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun send(bolus: Bolus) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun send(carbs: Carbs) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun send(tt: TemporaryTarget) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun send(te: TherapyEvent) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun send(deviceStatus: DeviceStatus) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun send(tb: TemporaryBasal) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun send(eb: ExtendedBolus) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun send(ps: ProfileSwitch) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun send(ps: EffectiveProfileSwitch) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun send(ps: OfflineEvent) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
private fun splitArray(array: JSONArray): List<JSONArray> {
|
||||
var ret: MutableList<JSONArray> = ArrayList()
|
||||
try {
|
||||
val size = array.length()
|
||||
var count = 0
|
||||
var newarr: JSONArray? = null
|
||||
for (i in 0 until size) {
|
||||
if (count == 0) {
|
||||
if (newarr != null) ret.add(newarr)
|
||||
newarr = JSONArray()
|
||||
count = 20
|
||||
}
|
||||
newarr?.put(array[i])
|
||||
--count
|
||||
}
|
||||
if (newarr != null && newarr.length() > 0) ret.add(newarr)
|
||||
} catch (e: JSONException) {
|
||||
aapsLogger.error("Unhandled exception", e)
|
||||
ret = ArrayList()
|
||||
ret.add(array)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
private fun broadcast(intent: Intent) {
|
||||
context.packageManager.safeQueryBroadcastReceivers(intent, 0).forEach { resolveInfo ->
|
||||
resolveInfo.activityInfo.packageName?.let {
|
||||
intent.setPackage(it)
|
||||
context.sendBroadcast(intent)
|
||||
aapsLogger.debug(LTag.CORE, "Sending broadcast " + intent.action + " to: " + it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -165,6 +165,10 @@
|
|||
<string name="disabled_loop">Loop Disabled</string>
|
||||
<string name="xdrip_send_status_title">Send Status line to xDrip+</string>
|
||||
|
||||
<string name="xdrip_not_installed">xDrip+ not installed</string>
|
||||
<string name="calibration_sent">Calibration sent to xDrip+</string>
|
||||
|
||||
|
||||
<!-- DataBroadcast-->
|
||||
<string name="data_broadcaster" translatable="false">Data Broadcaster</string>
|
||||
|
||||
|
|
Loading…
Reference in a new issue