move XDripBroadcast to XdripPlugin

This commit is contained in:
Milos Kozak 2023-01-17 17:10:54 +01:00
parent d57ec150a5
commit 36153c9b49
19 changed files with 303 additions and 224 deletions

View file

@ -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)
}

View file

@ -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"

View file

@ -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)
}
}
}
}

View file

@ -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

View file

@ -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>

View file

@ -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 {

View file

@ -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")
}
}

View file

@ -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")
}
}

View file

@ -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 ->

View file

@ -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 ->

View file

@ -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")
}
}

View file

@ -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)

View file

@ -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")
}
}

View file

@ -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) }

View file

@ -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")
}
}

View file

@ -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
}
}

View file

@ -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)

View file

@ -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)
}
}
}
}

View file

@ -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>