migrate ProfileFunction

This commit is contained in:
Milos Kozak 2022-11-26 23:06:34 +01:00
parent 7f4c2bd87f
commit 6c86619a35
20 changed files with 536 additions and 475 deletions

View file

@ -58,7 +58,7 @@ import info.nightscout.interfaces.protection.ProtectionCheck
import info.nightscout.interfaces.smsCommunicator.SmsCommunicator import info.nightscout.interfaces.smsCommunicator.SmsCommunicator
import info.nightscout.interfaces.ui.IconsProvider import info.nightscout.interfaces.ui.IconsProvider
import info.nightscout.plugins.constraints.signatureVerifier.SignatureVerifierPlugin import info.nightscout.plugins.constraints.signatureVerifier.SignatureVerifierPlugin
import info.nightscout.plugins.sync.nsclient.data.NSSettingsStatus import info.nightscout.interfaces.nsclient.NSSettingsStatus
import info.nightscout.rx.AapsSchedulers import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.events.EventAppExit import info.nightscout.rx.events.EventAppExit
import info.nightscout.rx.events.EventInitializationChanged import info.nightscout.rx.events.EventInitializationChanged

View file

@ -53,7 +53,7 @@ import info.nightscout.plugins.source.IntelligoPlugin
import info.nightscout.plugins.source.PoctechPlugin import info.nightscout.plugins.source.PoctechPlugin
import info.nightscout.plugins.source.TomatoPlugin import info.nightscout.plugins.source.TomatoPlugin
import info.nightscout.plugins.sync.nsclient.NSClientPlugin import info.nightscout.plugins.sync.nsclient.NSClientPlugin
import info.nightscout.plugins.sync.nsclient.data.NSSettingsStatus import info.nightscout.interfaces.nsclient.NSSettingsStatus
import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin
import info.nightscout.plugins.sync.tidepool.TidepoolPlugin import info.nightscout.plugins.sync.tidepool.TidepoolPlugin
import info.nightscout.pump.combo.ComboPlugin import info.nightscout.pump.combo.ComboPlugin

View file

@ -59,6 +59,7 @@ import javax.inject.Singleton
ImplementationModule.Bindings::class, ImplementationModule.Bindings::class,
OpenHumansModule::class, OpenHumansModule::class,
PluginsModule::class, PluginsModule::class,
PluginsModule.Bindings::class,
RxModule::class, RxModule::class,
SharedModule::class, SharedModule::class,
SharedImplModule::class, SharedImplModule::class,

View file

@ -10,7 +10,7 @@ import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.implementations.ActivityNamesImpl import info.nightscout.androidaps.implementations.ActivityNamesImpl
import info.nightscout.androidaps.implementations.ConfigImpl import info.nightscout.androidaps.implementations.ConfigImpl
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctionImpl import info.nightscout.implementation.profile.ProfileFunctionImpl
import info.nightscout.androidaps.plugins.general.maintenance.ImportExportPrefsImpl import info.nightscout.androidaps.plugins.general.maintenance.ImportExportPrefsImpl
import info.nightscout.androidaps.workflow.CalculationWorkflowImpl import info.nightscout.androidaps.workflow.CalculationWorkflowImpl
import info.nightscout.core.utils.fabric.FabricPrivacy import info.nightscout.core.utils.fabric.FabricPrivacy
@ -38,7 +38,7 @@ import info.nightscout.plugins.general.autotune.AutotunePlugin
import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorPlugin import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorPlugin
import info.nightscout.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin import info.nightscout.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.plugins.sync.nsclient.DataSyncSelectorImplementation import info.nightscout.plugins.sync.nsclient.DataSyncSelectorImplementation
import info.nightscout.plugins.sync.nsclient.data.ProcessedDeviceStatusData import info.nightscout.interfaces.nsclient.ProcessedDeviceStatusData
import info.nightscout.rx.AapsSchedulers import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.logging.AAPSLogger import info.nightscout.rx.logging.AAPSLogger

View file

@ -13,7 +13,7 @@ import info.nightscout.interfaces.maintenance.PrefFileListProvider
import info.nightscout.interfaces.plugin.PluginBase import info.nightscout.interfaces.plugin.PluginBase
import info.nightscout.interfaces.plugin.PluginDescription import info.nightscout.interfaces.plugin.PluginDescription
import info.nightscout.interfaces.plugin.PluginType import info.nightscout.interfaces.plugin.PluginType
import info.nightscout.plugins.sync.nsclient.data.NSSettingsStatus import info.nightscout.interfaces.nsclient.NSSettingsStatus
import info.nightscout.rx.logging.AAPSLogger import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP

View file

@ -78,8 +78,8 @@ import info.nightscout.plugins.general.overview.notifications.events.EventUpdate
import info.nightscout.plugins.skins.SkinProvider import info.nightscout.plugins.skins.SkinProvider
import info.nightscout.plugins.source.DexcomPlugin import info.nightscout.plugins.source.DexcomPlugin
import info.nightscout.plugins.source.XdripPlugin import info.nightscout.plugins.source.XdripPlugin
import info.nightscout.plugins.sync.nsclient.data.NSSettingsStatus import info.nightscout.interfaces.nsclient.NSSettingsStatus
import info.nightscout.plugins.sync.nsclient.data.ProcessedDeviceStatusData import info.nightscout.interfaces.nsclient.ProcessedDeviceStatusData
import info.nightscout.plugins.ui.StatusLightHandler import info.nightscout.plugins.ui.StatusLightHandler
import info.nightscout.rx.AapsSchedulers import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus

View file

@ -16,7 +16,7 @@ import info.nightscout.interfaces.Config
import info.nightscout.interfaces.aps.Loop import info.nightscout.interfaces.aps.Loop
import info.nightscout.interfaces.profile.DefaultValueHelper import info.nightscout.interfaces.profile.DefaultValueHelper
import info.nightscout.interfaces.profile.ProfileFunction import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.plugins.sync.nsclient.data.ProcessedDeviceStatusData import info.nightscout.interfaces.nsclient.ProcessedDeviceStatusData
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.utils.T import info.nightscout.shared.utils.T

View file

@ -6,7 +6,7 @@ import info.nightscout.androidaps.TestBase
import info.nightscout.interfaces.Config import info.nightscout.interfaces.Config
import info.nightscout.interfaces.logging.LoggerUtils import info.nightscout.interfaces.logging.LoggerUtils
import info.nightscout.interfaces.maintenance.PrefFileListProvider import info.nightscout.interfaces.maintenance.PrefFileListProvider
import info.nightscout.plugins.sync.nsclient.data.NSSettingsStatus import info.nightscout.interfaces.nsclient.NSSettingsStatus
import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP
import org.junit.Assert import org.junit.Assert

View file

@ -0,0 +1,13 @@
package info.nightscout.interfaces.nsclient
import android.content.Context
import org.json.JSONObject
interface NSSettingsStatus {
fun handleNewData(status: JSONObject)
fun getVersion(): String
fun extendedPumpSettings(setting: String?): Double
fun pumpExtendedSettingsFields(): String
fun copyStatusLightsNsSettings(context: Context?)
}

View file

@ -0,0 +1,75 @@
package info.nightscout.interfaces.nsclient
import android.text.Spanned
import dagger.android.HasAndroidInjector
import info.nightscout.interfaces.aps.APSResult
import org.json.JSONObject
interface ProcessedDeviceStatusData {
enum class Levels(val level: Int) {
URGENT(2),
WARN(1),
INFO(0);
fun toColor(): String =
when (level) {
INFO.level -> "white"
WARN.level -> "yellow"
URGENT.level -> "red"
else -> "white"
}
}
class PumpData {
var clock = 0L
var isPercent = false
var percent = 0
var voltage = 0.0
var status = "N/A"
var reservoir = 0.0
var reservoirDisplayOverride = ""
var extended: Spanned? = null
var activeProfileName: String? = null
}
var pumpData: PumpData?
data class Device(
val createdAt: Long,
val device: String?
)
var device: Device?
class Uploader {
var clock = 0L
var battery = 0
}
val uploaderMap: HashMap<String, Uploader>
class OpenAPSData {
var clockSuggested = 0L
var clockEnacted = 0L
var suggested: JSONObject? = null
var enacted: JSONObject? = null
}
var openAPSData: OpenAPSData
// test warning level // color
fun pumpStatus(nsSettingsStatus: NSSettingsStatus): Spanned
val extendedPumpStatus: Spanned
val extendedOpenApsStatus: Spanned
val openApsStatus: Spanned
val openApsTimestamp: Long
fun getAPSResult(injector: HasAndroidInjector): APSResult
val uploaderStatus: String
val uploaderStatusSpanned: Spanned
val extendedUploaderStatus: Spanned
}

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.plugins.configBuilder package info.nightscout.implementation.profile
import info.nightscout.androidaps.extensions.fromConstant import info.nightscout.androidaps.extensions.fromConstant
import info.nightscout.core.main.R import info.nightscout.core.main.R
@ -11,12 +11,12 @@ import info.nightscout.database.impl.transactions.InsertOrUpdateProfileSwitch
import info.nightscout.interfaces.Config import info.nightscout.interfaces.Config
import info.nightscout.interfaces.Constants import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.GlucoseUnit import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.nsclient.ProcessedDeviceStatusData
import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.profile.Profile import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.profile.ProfileStore import info.nightscout.interfaces.profile.ProfileStore
import info.nightscout.interfaces.utils.HardLimits import info.nightscout.interfaces.utils.HardLimits
import info.nightscout.plugins.sync.nsclient.data.ProcessedDeviceStatusData
import info.nightscout.rx.AapsSchedulers import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventEffectiveProfileSwitchChanged import info.nightscout.rx.events.EventEffectiveProfileSwitchChanged

View file

@ -1,6 +1,11 @@
package info.nightscout.plugins.di package info.nightscout.plugins.di
import dagger.Binds
import dagger.Module import dagger.Module
import info.nightscout.interfaces.nsclient.ProcessedDeviceStatusData
import info.nightscout.interfaces.nsclient.NSSettingsStatus
import info.nightscout.plugins.sync.nsclient.data.NSSettingsStatusImpl
import info.nightscout.plugins.sync.nsclient.data.ProcessedDeviceStatusDataImpl
@Module( @Module(
includes = [ includes = [
@ -21,4 +26,12 @@ import dagger.Module
) )
@Suppress("unused") @Suppress("unused")
abstract class PluginsModule abstract class PluginsModule {
@Module
interface Bindings {
@Binds fun bindProcessedDeviceStatusData(processedDeviceStatusDataImpl: ProcessedDeviceStatusDataImpl): ProcessedDeviceStatusData
@Binds fun bindNSSettingsStatus(nsSettingsStatusImpl: NSSettingsStatusImpl): NSSettingsStatus
}
}

View file

@ -23,7 +23,7 @@ import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.receivers.Intents import info.nightscout.interfaces.receivers.Intents
import info.nightscout.plugins.R import info.nightscout.plugins.R
import info.nightscout.plugins.aps.loop.events.EventLoopUpdateGui import info.nightscout.plugins.aps.loop.events.EventLoopUpdateGui
import info.nightscout.plugins.sync.nsclient.data.ProcessedDeviceStatusData import info.nightscout.interfaces.nsclient.ProcessedDeviceStatusData
import info.nightscout.rx.AapsSchedulers import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.Event import info.nightscout.rx.events.Event

View file

@ -50,7 +50,7 @@ import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.interfaces.utils.HardLimits import info.nightscout.interfaces.utils.HardLimits
import info.nightscout.interfaces.utils.TrendCalculator import info.nightscout.interfaces.utils.TrendCalculator
import info.nightscout.plugins.R import info.nightscout.plugins.R
import info.nightscout.plugins.sync.nsclient.data.ProcessedDeviceStatusData import info.nightscout.interfaces.nsclient.ProcessedDeviceStatusData
import info.nightscout.rx.AapsSchedulers import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventMobileToWear import info.nightscout.rx.events.EventMobileToWear

View file

@ -1,6 +1,7 @@
package info.nightscout.plugins.sync.nsclient.data package info.nightscout.plugins.sync.nsclient.data
import info.nightscout.interfaces.Config import info.nightscout.interfaces.Config
import info.nightscout.interfaces.nsclient.ProcessedDeviceStatusData
import info.nightscout.interfaces.sync.NsClient import info.nightscout.interfaces.sync.NsClient
import info.nightscout.interfaces.utils.HtmlHelper import info.nightscout.interfaces.utils.HtmlHelper
import info.nightscout.interfaces.utils.JsonHelper import info.nightscout.interfaces.utils.JsonHelper

View file

@ -1,252 +1,2 @@
package info.nightscout.plugins.sync.nsclient.data package info.nightscout.plugins.sync.nsclient.data
import android.content.Context
import info.nightscout.androidaps.annotations.OpenForTesting
import info.nightscout.interfaces.logging.UserEntryLogger
import info.nightscout.core.events.EventNewNotification
import info.nightscout.core.ui.dialogs.OKDialog
import info.nightscout.database.entities.UserEntry
import info.nightscout.database.entities.UserEntry.Action
import info.nightscout.interfaces.Config
import info.nightscout.interfaces.notifications.Notification
import info.nightscout.interfaces.profile.DefaultValueHelper
import info.nightscout.interfaces.utils.JsonHelper
import info.nightscout.plugins.R
import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventDismissNotification
import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import org.json.JSONException
import org.json.JSONObject
import javax.inject.Inject
import javax.inject.Singleton
/*
{
"status": "ok",
"name": "Nightscout",
"version": "0.10.0-dev-20170423",
"versionNum": 1000,
"serverTime": "2017-06-12T07:46:56.006Z",
"apiEnabled": true,
"careportalEnabled": true,
"boluscalcEnabled": true,
"head": "96ee154",
"settings": {
"units": "mmol",
"timeFormat": 24,
"nightMode": false,
"editMode": true,
"showRawbg": "always",
"customTitle": "Bara's CGM",
"theme": "colors",
"alarmUrgentHigh": true,
"alarmUrgentHighMins": [30, 60, 90, 120],
"alarmHigh": true,
"alarmHighMins": [30, 60, 90, 120],
"alarmLow": true,
"alarmLowMins": [15, 30, 45, 60],
"alarmUrgentLow": true,
"alarmUrgentLowMins": [15, 30, 45],
"alarmUrgentMins": [30, 60, 90, 120],
"alarmWarnMins": [30, 60, 90, 120],
"alarmTimeagoWarn": true,
"alarmTimeagoWarnMins": 15,
"alarmTimeagoUrgent": true,
"alarmTimeagoUrgentMins": 30,
"language": "cs",
"scaleY": "linear",
"showPlugins": "careportal boluscalc food bwp cage sage iage iob cob basal ar2 delta direction upbat rawbg",
"showForecast": "ar2",
"focusHours": 3,
"heartbeat": 60,
"baseURL": "http:\/\/barascgm.sysop.cz:82",
"authDefaultRoles": "readable",
"thresholds": {
"bgHigh": 252,
"bgTargetTop": 180,
"bgTargetBottom": 72,
"bgLow": 71
},
"DEFAULT_FEATURES": ["bgnow", "delta", "direction", "timeago", "devicestatus", "upbat", "errorcodes", "profile"],
"alarmTypes": ["predict"],
"enable": ["careportal", "boluscalc", "food", "bwp", "cage", "sage", "iage", "iob", "cob", "basal", "ar2", "rawbg", "pushover", "bgi", "pump", "openaps", "pushover", "treatmentnotify", "bgnow", "delta", "direction", "timeago", "devicestatus", "upbat", "profile", "ar2"]
},
"extendedSettings": {
"pump": {
"fields": "reservoir battery clock",
"urgentBattP": 26,
"warnBattP": 51
},
"openaps": {
"enableAlerts": true
},
"cage": {
"alerts": true,
"display": "days",
"urgent": 96,
"warn": 72
},
"sage": {
"alerts": true,
"urgent": 336,
"warn": 168
},
"iage": {
"alerts": true,
"urgent": 150,
"warn": 120
},
"basal": {
"render": "default"
},
"profile": {
"history": true,
"multiple": true
},
"devicestatus": {
"advanced": true
}
},
"activeProfile": "2016 +30%"
}
*/
@OpenForTesting
@Singleton
class NSSettingsStatus @Inject constructor(
private val aapsLogger: AAPSLogger,
private val rh: ResourceHelper,
private val rxBus: RxBus,
private val defaultValueHelper: DefaultValueHelper,
private val sp: SP,
private val config: Config,
private val uel: UserEntryLogger
) {
// ***** PUMP STATUS ******
private var data: JSONObject? = null
/* Other received data to 2016/02/10
{
status: 'ok'
, name: env.name
, version: env.version
, versionNum: versionNum (for ver 1.2.3 contains 10203)
, serverTime: new Date().toISOString()
, apiEnabled: apiEnabled
, careportalEnabled: apiEnabled && env.settings.enable.indexOf('careportal') > -1
, boluscalcEnabled: apiEnabled && env.settings.enable.indexOf('boluscalc') > -1
, head: env.head
, settings: env.settings
, extendedSettings: ctx.plugins && ctx.plugins.extendedClientSettings ? ctx.plugins.extendedClientSettings(env.extendedSettings) : {}
, activeProfile ..... calculated from treatments or missing
}
*/
fun handleNewData(status: JSONObject) {
data = status
aapsLogger.debug(LTag.NSCLIENT, "Got versions: Nightscout: ${getVersion()}")
if (getVersionNum() < config.SUPPORTEDNSVERSION) {
val notification = Notification(Notification.OLD_NS, rh.gs(R.string.unsupported_ns_version), Notification.NORMAL)
rxBus.send(EventNewNotification(notification))
} else {
rxBus.send(EventDismissNotification(Notification.OLD_NS))
}
data = status
aapsLogger.debug(LTag.NSCLIENT, "Received status: $status")
val targetHigh = getSettingsThreshold("bgTargetTop")
val targetlow = getSettingsThreshold("bgTargetBottom")
if (targetHigh != null) defaultValueHelper.bgTargetHigh = targetHigh
if (targetlow != null) defaultValueHelper.bgTargetLow = targetlow
if (config.NSCLIENT) copyStatusLightsNsSettings(null)
}
fun getVersion(): String =
JsonHelper.safeGetStringAllowNull(data, "version", null) ?: "UNKNOWN"
private fun getVersionNum(): Int =
JsonHelper.safeGetInt(data, "versionNum")
private fun getSettings() =
JsonHelper.safeGetJSONObject(data, "settings", null)
private fun getExtendedSettings(): JSONObject? =
JsonHelper.safeGetJSONObject(data, "extendedSettings", null)
// valid property is "warn" or "urgent"
// plugings "iage" "sage" "cage" "pbage"
private fun getExtendedWarnValue(plugin: String, property: String): Double? {
val extendedSettings = getExtendedSettings() ?: return null
val pluginJson = extendedSettings.optJSONObject(plugin) ?: return null
return try {
pluginJson.getDouble(property)
} catch (e: Exception) {
null
}
}
// "bgHigh": 252,
// "bgTargetTop": 180,
// "bgTargetBottom": 72,
// "bgLow": 71
private fun getSettingsThreshold(what: String): Double? {
val threshold = JsonHelper.safeGetJSONObject(getSettings(), "thresholds", null)
return JsonHelper.safeGetDoubleAllowNull(threshold, what)
}
/*
, warnClock: sbx.extendedSettings.warnClock || 30
, urgentClock: sbx.extendedSettings.urgentClock || 60
, warnRes: sbx.extendedSettings.warnRes || 10
, urgentRes: sbx.extendedSettings.urgentRes || 5
, warnBattV: sbx.extendedSettings.warnBattV || 1.35
, urgentBattV: sbx.extendedSettings.urgentBattV || 1.3
, warnBattP: sbx.extendedSettings.warnBattP || 30
, urgentBattP: sbx.extendedSettings.urgentBattP || 20
, enableAlerts: sbx.extendedSettings.enableAlerts || false
*/
fun extendedPumpSettings(setting: String?): Double {
try {
val pump = extendedPumpSettings()
return when (setting) {
"warnClock" -> JsonHelper.safeGetDouble(pump, setting, 30.0)
"urgentClock" -> JsonHelper.safeGetDouble(pump, setting, 60.0)
"warnRes" -> JsonHelper.safeGetDouble(pump, setting, 10.0)
"urgentRes" -> JsonHelper.safeGetDouble(pump, setting, 5.0)
"warnBattV" -> JsonHelper.safeGetDouble(pump, setting, 1.35)
"urgentBattV" -> JsonHelper.safeGetDouble(pump, setting, 1.3)
"warnBattP" -> JsonHelper.safeGetDouble(pump, setting, 30.0)
"urgentBattP" -> JsonHelper.safeGetDouble(pump, setting, 20.0)
else -> 0.0
}
} catch (e: JSONException) {
aapsLogger.error("Unhandled exception", e)
}
return 0.0
}
private fun extendedPumpSettings(): JSONObject? =
JsonHelper.safeGetJSONObject(getExtendedSettings(), "pump", null)
fun pumpExtendedSettingsFields(): String =
JsonHelper.safeGetString(extendedPumpSettings(), "fields", "")
fun copyStatusLightsNsSettings(context: Context?) {
val action = Runnable {
getExtendedWarnValue("cage", "warn")?.let { sp.putDouble(R.string.key_statuslights_cage_warning, it) }
getExtendedWarnValue("cage", "urgent")?.let { sp.putDouble(R.string.key_statuslights_cage_critical, it) }
getExtendedWarnValue("iage", "warn")?.let { sp.putDouble(R.string.key_statuslights_iage_warning, it) }
getExtendedWarnValue("iage", "urgent")?.let { sp.putDouble(R.string.key_statuslights_iage_critical, it) }
getExtendedWarnValue("sage", "warn")?.let { sp.putDouble(R.string.key_statuslights_sage_warning, it) }
getExtendedWarnValue("sage", "urgent")?.let { sp.putDouble(R.string.key_statuslights_sage_critical, it) }
getExtendedWarnValue("bage", "warn")?.let { sp.putDouble(R.string.key_statuslights_bage_warning, it) }
getExtendedWarnValue("bage", "urgent")?.let { sp.putDouble(R.string.key_statuslights_bage_critical, it) }
uel.log(Action.NS_SETTINGS_COPIED, UserEntry.Sources.NSClient)
}
if (context != null) OKDialog.showConfirmation(context, rh.gs(R.string.statuslights), rh.gs(R.string.copy_existing_values), action)
else action.run()
}
}

View file

@ -0,0 +1,253 @@
package info.nightscout.plugins.sync.nsclient.data
import android.content.Context
import info.nightscout.androidaps.annotations.OpenForTesting
import info.nightscout.interfaces.logging.UserEntryLogger
import info.nightscout.core.events.EventNewNotification
import info.nightscout.core.ui.dialogs.OKDialog
import info.nightscout.database.entities.UserEntry
import info.nightscout.database.entities.UserEntry.Action
import info.nightscout.interfaces.Config
import info.nightscout.interfaces.notifications.Notification
import info.nightscout.interfaces.nsclient.NSSettingsStatus
import info.nightscout.interfaces.profile.DefaultValueHelper
import info.nightscout.interfaces.utils.JsonHelper
import info.nightscout.plugins.R
import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventDismissNotification
import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import org.json.JSONException
import org.json.JSONObject
import javax.inject.Inject
import javax.inject.Singleton
/*
{
"status": "ok",
"name": "Nightscout",
"version": "0.10.0-dev-20170423",
"versionNum": 1000,
"serverTime": "2017-06-12T07:46:56.006Z",
"apiEnabled": true,
"careportalEnabled": true,
"boluscalcEnabled": true,
"head": "96ee154",
"settings": {
"units": "mmol",
"timeFormat": 24,
"nightMode": false,
"editMode": true,
"showRawbg": "always",
"customTitle": "Bara's CGM",
"theme": "colors",
"alarmUrgentHigh": true,
"alarmUrgentHighMins": [30, 60, 90, 120],
"alarmHigh": true,
"alarmHighMins": [30, 60, 90, 120],
"alarmLow": true,
"alarmLowMins": [15, 30, 45, 60],
"alarmUrgentLow": true,
"alarmUrgentLowMins": [15, 30, 45],
"alarmUrgentMins": [30, 60, 90, 120],
"alarmWarnMins": [30, 60, 90, 120],
"alarmTimeagoWarn": true,
"alarmTimeagoWarnMins": 15,
"alarmTimeagoUrgent": true,
"alarmTimeagoUrgentMins": 30,
"language": "cs",
"scaleY": "linear",
"showPlugins": "careportal boluscalc food bwp cage sage iage iob cob basal ar2 delta direction upbat rawbg",
"showForecast": "ar2",
"focusHours": 3,
"heartbeat": 60,
"baseURL": "http:\/\/barascgm.sysop.cz:82",
"authDefaultRoles": "readable",
"thresholds": {
"bgHigh": 252,
"bgTargetTop": 180,
"bgTargetBottom": 72,
"bgLow": 71
},
"DEFAULT_FEATURES": ["bgnow", "delta", "direction", "timeago", "devicestatus", "upbat", "errorcodes", "profile"],
"alarmTypes": ["predict"],
"enable": ["careportal", "boluscalc", "food", "bwp", "cage", "sage", "iage", "iob", "cob", "basal", "ar2", "rawbg", "pushover", "bgi", "pump", "openaps", "pushover", "treatmentnotify", "bgnow", "delta", "direction", "timeago", "devicestatus", "upbat", "profile", "ar2"]
},
"extendedSettings": {
"pump": {
"fields": "reservoir battery clock",
"urgentBattP": 26,
"warnBattP": 51
},
"openaps": {
"enableAlerts": true
},
"cage": {
"alerts": true,
"display": "days",
"urgent": 96,
"warn": 72
},
"sage": {
"alerts": true,
"urgent": 336,
"warn": 168
},
"iage": {
"alerts": true,
"urgent": 150,
"warn": 120
},
"basal": {
"render": "default"
},
"profile": {
"history": true,
"multiple": true
},
"devicestatus": {
"advanced": true
}
},
"activeProfile": "2016 +30%"
}
*/
@OpenForTesting
@Singleton
class NSSettingsStatusImpl @Inject constructor(
private val aapsLogger: AAPSLogger,
private val rh: ResourceHelper,
private val rxBus: RxBus,
private val defaultValueHelper: DefaultValueHelper,
private val sp: SP,
private val config: Config,
private val uel: UserEntryLogger
) : NSSettingsStatus {
// ***** PUMP STATUS ******
private var data: JSONObject? = null
/* Other received data to 2016/02/10
{
status: 'ok'
, name: env.name
, version: env.version
, versionNum: versionNum (for ver 1.2.3 contains 10203)
, serverTime: new Date().toISOString()
, apiEnabled: apiEnabled
, careportalEnabled: apiEnabled && env.settings.enable.indexOf('careportal') > -1
, boluscalcEnabled: apiEnabled && env.settings.enable.indexOf('boluscalc') > -1
, head: env.head
, settings: env.settings
, extendedSettings: ctx.plugins && ctx.plugins.extendedClientSettings ? ctx.plugins.extendedClientSettings(env.extendedSettings) : {}
, activeProfile ..... calculated from treatments or missing
}
*/
override fun handleNewData(status: JSONObject) {
data = status
aapsLogger.debug(LTag.NSCLIENT, "Got versions: Nightscout: ${getVersion()}")
if (getVersionNum() < config.SUPPORTEDNSVERSION) {
val notification = Notification(Notification.OLD_NS, rh.gs(R.string.unsupported_ns_version), Notification.NORMAL)
rxBus.send(EventNewNotification(notification))
} else {
rxBus.send(EventDismissNotification(Notification.OLD_NS))
}
data = status
aapsLogger.debug(LTag.NSCLIENT, "Received status: $status")
val targetHigh = getSettingsThreshold("bgTargetTop")
val targetlow = getSettingsThreshold("bgTargetBottom")
if (targetHigh != null) defaultValueHelper.bgTargetHigh = targetHigh
if (targetlow != null) defaultValueHelper.bgTargetLow = targetlow
if (config.NSCLIENT) copyStatusLightsNsSettings(null)
}
override fun getVersion(): String =
JsonHelper.safeGetStringAllowNull(data, "version", null) ?: "UNKNOWN"
private fun getVersionNum(): Int =
JsonHelper.safeGetInt(data, "versionNum")
private fun getSettings() =
JsonHelper.safeGetJSONObject(data, "settings", null)
private fun getExtendedSettings(): JSONObject? =
JsonHelper.safeGetJSONObject(data, "extendedSettings", null)
// valid property is "warn" or "urgent"
// plugings "iage" "sage" "cage" "pbage"
private fun getExtendedWarnValue(plugin: String, property: String): Double? {
val extendedSettings = getExtendedSettings() ?: return null
val pluginJson = extendedSettings.optJSONObject(plugin) ?: return null
return try {
pluginJson.getDouble(property)
} catch (e: Exception) {
null
}
}
// "bgHigh": 252,
// "bgTargetTop": 180,
// "bgTargetBottom": 72,
// "bgLow": 71
private fun getSettingsThreshold(what: String): Double? {
val threshold = JsonHelper.safeGetJSONObject(getSettings(), "thresholds", null)
return JsonHelper.safeGetDoubleAllowNull(threshold, what)
}
/*
, warnClock: sbx.extendedSettings.warnClock || 30
, urgentClock: sbx.extendedSettings.urgentClock || 60
, warnRes: sbx.extendedSettings.warnRes || 10
, urgentRes: sbx.extendedSettings.urgentRes || 5
, warnBattV: sbx.extendedSettings.warnBattV || 1.35
, urgentBattV: sbx.extendedSettings.urgentBattV || 1.3
, warnBattP: sbx.extendedSettings.warnBattP || 30
, urgentBattP: sbx.extendedSettings.urgentBattP || 20
, enableAlerts: sbx.extendedSettings.enableAlerts || false
*/
override fun extendedPumpSettings(setting: String?): Double {
try {
val pump = extendedPumpSettings()
return when (setting) {
"warnClock" -> JsonHelper.safeGetDouble(pump, setting, 30.0)
"urgentClock" -> JsonHelper.safeGetDouble(pump, setting, 60.0)
"warnRes" -> JsonHelper.safeGetDouble(pump, setting, 10.0)
"urgentRes" -> JsonHelper.safeGetDouble(pump, setting, 5.0)
"warnBattV" -> JsonHelper.safeGetDouble(pump, setting, 1.35)
"urgentBattV" -> JsonHelper.safeGetDouble(pump, setting, 1.3)
"warnBattP" -> JsonHelper.safeGetDouble(pump, setting, 30.0)
"urgentBattP" -> JsonHelper.safeGetDouble(pump, setting, 20.0)
else -> 0.0
}
} catch (e: JSONException) {
aapsLogger.error("Unhandled exception", e)
}
return 0.0
}
private fun extendedPumpSettings(): JSONObject? =
JsonHelper.safeGetJSONObject(getExtendedSettings(), "pump", null)
override fun pumpExtendedSettingsFields(): String =
JsonHelper.safeGetString(extendedPumpSettings(), "fields", "")
override fun copyStatusLightsNsSettings(context: Context?) {
val action = Runnable {
getExtendedWarnValue("cage", "warn")?.let { sp.putDouble(R.string.key_statuslights_cage_warning, it) }
getExtendedWarnValue("cage", "urgent")?.let { sp.putDouble(R.string.key_statuslights_cage_critical, it) }
getExtendedWarnValue("iage", "warn")?.let { sp.putDouble(R.string.key_statuslights_iage_warning, it) }
getExtendedWarnValue("iage", "urgent")?.let { sp.putDouble(R.string.key_statuslights_iage_critical, it) }
getExtendedWarnValue("sage", "warn")?.let { sp.putDouble(R.string.key_statuslights_sage_warning, it) }
getExtendedWarnValue("sage", "urgent")?.let { sp.putDouble(R.string.key_statuslights_sage_critical, it) }
getExtendedWarnValue("bage", "warn")?.let { sp.putDouble(R.string.key_statuslights_bage_warning, it) }
getExtendedWarnValue("bage", "urgent")?.let { sp.putDouble(R.string.key_statuslights_bage_critical, it) }
uel.log(Action.NS_SETTINGS_COPIED, UserEntry.Sources.NSClient)
}
if (context != null) OKDialog.showConfirmation(context, rh.gs(R.string.statuslights), rh.gs(R.string.copy_existing_values), action)
else action.run()
}
}

View file

@ -1,211 +1,2 @@
package info.nightscout.plugins.sync.nsclient.data package info.nightscout.plugins.sync.nsclient.data
import android.text.Spanned
import dagger.android.HasAndroidInjector
import info.nightscout.core.aps.APSResultObject
import info.nightscout.interfaces.utils.HtmlHelper
import info.nightscout.interfaces.utils.JsonHelper
import info.nightscout.interfaces.utils.Round
import info.nightscout.plugins.R
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
import info.nightscout.shared.utils.T
import org.json.JSONObject
import javax.inject.Inject
import javax.inject.Singleton
@Suppress("SpellCheckingInspection")
@Singleton
class ProcessedDeviceStatusData @Inject constructor(
private val rh: ResourceHelper,
private val dateUtil: DateUtil,
private val sp: SP
) {
enum class Levels(val level: Int) {
URGENT(2),
WARN(1),
INFO(0);
fun toColor(): String =
when (level) {
INFO.level -> "white"
WARN.level -> "yellow"
URGENT.level -> "red"
else -> "white"
}
}
class PumpData {
var clock = 0L
var isPercent = false
var percent = 0
var voltage = 0.0
var status = "N/A"
var reservoir = 0.0
var reservoirDisplayOverride = ""
var extended: Spanned? = null
var activeProfileName: String? = null
}
var pumpData: PumpData? = null
data class Device(
val createdAt: Long,
val device: String?
)
var device: Device? = null
class Uploader {
var clock = 0L
var battery = 0
}
val uploaderMap = HashMap<String, Uploader>()
class OpenAPSData {
var clockSuggested = 0L
var clockEnacted = 0L
var suggested: JSONObject? = null
var enacted: JSONObject? = null
}
var openAPSData = OpenAPSData()
// test warning level // color
fun pumpStatus(nsSettingsStatus: NSSettingsStatus): Spanned {
val pumpData = pumpData ?: return HtmlHelper.fromHtml("")
//String[] ALL_STATUS_FIELDS = {"reservoir", "battery", "clock", "status", "device"};
val string = StringBuilder()
.append("<span style=\"color:${rh.gac(R.attr.nsTitleColor)}\">")
.append(rh.gs(R.string.pump))
.append(": </span>")
// test warning level
val level = when {
pumpData.clock + nsSettingsStatus.extendedPumpSettings("urgentClock") * 60 * 1000L < dateUtil.now() -> Levels.URGENT
pumpData.reservoir < nsSettingsStatus.extendedPumpSettings("urgentRes") -> Levels.URGENT
pumpData.isPercent && pumpData.percent < nsSettingsStatus.extendedPumpSettings("urgentBattP") -> Levels.URGENT
!pumpData.isPercent && pumpData.voltage > 0 && pumpData.voltage < nsSettingsStatus.extendedPumpSettings("urgentBattV") -> Levels.URGENT
pumpData.clock + nsSettingsStatus.extendedPumpSettings("warnClock") * 60 * 1000L < dateUtil.now() -> Levels.WARN
pumpData.reservoir < nsSettingsStatus.extendedPumpSettings("warnRes") -> Levels.WARN
pumpData.isPercent && pumpData.percent < nsSettingsStatus.extendedPumpSettings("warnBattP") -> Levels.WARN
!pumpData.isPercent && pumpData.voltage > 0 && pumpData.voltage < nsSettingsStatus.extendedPumpSettings("warnBattV") -> Levels.WARN
else -> Levels.INFO
}
string.append("<span style=\"color:${level.toColor()}\">")
val insulinUnit = rh.gs(R.string.insulin_unit_shortname)
val fields = nsSettingsStatus.pumpExtendedSettingsFields()
if (pumpData.reservoirDisplayOverride != "")
string.append(pumpData.reservoirDisplayOverride).append("$insulinUnit ")
else if (fields.contains("reservoir")) string.append(pumpData.reservoir.toInt()).append("$insulinUnit ")
if (fields.contains("battery") && pumpData.isPercent) string.append(pumpData.percent).append("% ")
if (fields.contains("battery") && !pumpData.isPercent) string.append(Round.roundTo(pumpData.voltage, 0.001)).append(" ")
if (fields.contains("clock")) string.append(dateUtil.minAgo(rh, pumpData.clock)).append(" ")
if (fields.contains("status")) string.append(pumpData.status).append(" ")
if (fields.contains("device")) string.append(device).append(" ")
string.append("</span>") // color
return HtmlHelper.fromHtml(string.toString())
}
val extendedPumpStatus: Spanned get() = pumpData?.extended ?: HtmlHelper.fromHtml("")
val extendedOpenApsStatus: Spanned
get() {
val string = StringBuilder()
val enacted = openAPSData.enacted
val suggested = openAPSData.suggested
if (enacted != null && openAPSData.clockEnacted != openAPSData.clockSuggested) string
.append("<b>")
.append(dateUtil.minAgo(rh, openAPSData.clockEnacted))
.append("</b> ")
.append(JsonHelper.safeGetString(enacted, "reason"))
.append("<br>")
if (suggested != null) string
.append("<b>")
.append(dateUtil.minAgo(rh, openAPSData.clockSuggested))
.append("</b> ")
.append(JsonHelper.safeGetString(suggested, "reason"))
.append("<br>")
return HtmlHelper.fromHtml(string.toString())
}
val openApsStatus: Spanned
get() {
val string = StringBuilder()
.append("<span style=\"color:${rh.gac(R.attr.nsTitleColor)}\">")
.append(rh.gs(R.string.openaps_short))
.append(": </span>")
// test warning level
val level = when {
openAPSData.clockSuggested + T.mins(sp.getLong(R.string.key_ns_alarm_urgent_stale_data_value, 31)).msecs() < dateUtil.now() -> Levels.URGENT
openAPSData.clockSuggested + T.mins(sp.getLong(R.string.key_ns_alarm_stale_data_value, 16)).msecs() < dateUtil.now() -> Levels.WARN
else -> Levels.INFO
}
string.append("<span style=\"color:${level.toColor()}\">")
if (openAPSData.clockSuggested != 0L) string.append(dateUtil.minAgo(rh, openAPSData.clockSuggested)).append(" ")
string.append("</span>") // color
return HtmlHelper.fromHtml(string.toString())
}
val openApsTimestamp: Long
get() = if (openAPSData.clockSuggested != 0L) openAPSData.clockSuggested else -1
fun getAPSResult(injector: HasAndroidInjector): APSResultObject {
val result = APSResultObject(injector)
result.json = openAPSData.suggested
result.date = openAPSData.clockSuggested
return result
}
val uploaderStatus: String
get() {
val iterator: Iterator<*> = uploaderMap.entries.iterator()
var minBattery = 100
while (iterator.hasNext()) {
val pair = iterator.next() as Map.Entry<*, *>
val uploader = pair.value as Uploader
if (minBattery > uploader.battery) minBattery = uploader.battery
}
return "$minBattery%"
}
val uploaderStatusSpanned: Spanned
get() {
val string = StringBuilder()
string.append("<span style=\"color:${rh.gac(R.attr.nsTitleColor)}\">")
string.append(rh.gs(R.string.uploader_short))
string.append(": </span>")
val iterator: Iterator<*> = uploaderMap.entries.iterator()
var minBattery = 100
while (iterator.hasNext()) {
val pair = iterator.next() as Map.Entry<*, *>
val uploader = pair.value as Uploader
if (minBattery > uploader.battery) minBattery = uploader.battery
}
string.append(minBattery)
string.append("%")
return HtmlHelper.fromHtml(string.toString())
}
val extendedUploaderStatus: Spanned
get() {
val string = StringBuilder()
val iterator: Iterator<*> = uploaderMap.entries.iterator()
while (iterator.hasNext()) {
val pair = iterator.next() as Map.Entry<*, *>
val uploader = pair.value as Uploader
val device = pair.key as String
string.append("<b>").append(device).append(":</b> ").append(uploader.battery).append("%<br>")
}
return HtmlHelper.fromHtml(string.toString())
}
}

View file

@ -0,0 +1,164 @@
package info.nightscout.plugins.sync.nsclient.data
import android.text.Spanned
import dagger.android.HasAndroidInjector
import info.nightscout.core.aps.APSResultObject
import info.nightscout.interfaces.nsclient.NSSettingsStatus
import info.nightscout.interfaces.nsclient.ProcessedDeviceStatusData
import info.nightscout.interfaces.utils.HtmlHelper
import info.nightscout.interfaces.utils.JsonHelper
import info.nightscout.interfaces.utils.Round
import info.nightscout.plugins.R
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
import info.nightscout.shared.utils.T
import javax.inject.Inject
import javax.inject.Singleton
@Suppress("SpellCheckingInspection")
@Singleton
class ProcessedDeviceStatusDataImpl @Inject constructor(
private val rh: ResourceHelper,
private val dateUtil: DateUtil,
private val sp: SP
) : ProcessedDeviceStatusData {
override var pumpData: ProcessedDeviceStatusData.PumpData? = null
override var device: ProcessedDeviceStatusData.Device? = null
override val uploaderMap = HashMap<String, ProcessedDeviceStatusData.Uploader>()
override var openAPSData = ProcessedDeviceStatusData.OpenAPSData()
// test warning level // color
override fun pumpStatus(nsSettingsStatus: NSSettingsStatus): Spanned {
val pumpData = pumpData ?: return HtmlHelper.fromHtml("")
//String[] ALL_STATUS_FIELDS = {"reservoir", "battery", "clock", "status", "device"};
val string = StringBuilder()
.append("<span style=\"color:${rh.gac(R.attr.nsTitleColor)}\">")
.append(rh.gs(R.string.pump))
.append(": </span>")
// test warning level
val level = when {
pumpData.clock + nsSettingsStatus.extendedPumpSettings("urgentClock") * 60 * 1000L < dateUtil.now() -> ProcessedDeviceStatusData.Levels.URGENT
pumpData.reservoir < nsSettingsStatus.extendedPumpSettings("urgentRes") -> ProcessedDeviceStatusData.Levels.URGENT
pumpData.isPercent && pumpData.percent < nsSettingsStatus.extendedPumpSettings("urgentBattP") -> ProcessedDeviceStatusData.Levels.URGENT
!pumpData.isPercent && pumpData.voltage > 0 && pumpData.voltage < nsSettingsStatus.extendedPumpSettings("urgentBattV") -> ProcessedDeviceStatusData.Levels.URGENT
pumpData.clock + nsSettingsStatus.extendedPumpSettings("warnClock") * 60 * 1000L < dateUtil.now() -> ProcessedDeviceStatusData.Levels.WARN
pumpData.reservoir < nsSettingsStatus.extendedPumpSettings("warnRes") -> ProcessedDeviceStatusData.Levels.WARN
pumpData.isPercent && pumpData.percent < nsSettingsStatus.extendedPumpSettings("warnBattP") -> ProcessedDeviceStatusData.Levels.WARN
!pumpData.isPercent && pumpData.voltage > 0 && pumpData.voltage < nsSettingsStatus.extendedPumpSettings("warnBattV") -> ProcessedDeviceStatusData.Levels.WARN
else -> ProcessedDeviceStatusData.Levels.INFO
}
string.append("<span style=\"color:${level.toColor()}\">")
val insulinUnit = rh.gs(R.string.insulin_unit_shortname)
val fields = nsSettingsStatus.pumpExtendedSettingsFields()
if (pumpData.reservoirDisplayOverride != "")
string.append(pumpData.reservoirDisplayOverride).append("$insulinUnit ")
else if (fields.contains("reservoir")) string.append(pumpData.reservoir.toInt()).append("$insulinUnit ")
if (fields.contains("battery") && pumpData.isPercent) string.append(pumpData.percent).append("% ")
if (fields.contains("battery") && !pumpData.isPercent) string.append(Round.roundTo(pumpData.voltage, 0.001)).append(" ")
if (fields.contains("clock")) string.append(dateUtil.minAgo(rh, pumpData.clock)).append(" ")
if (fields.contains("status")) string.append(pumpData.status).append(" ")
if (fields.contains("device")) string.append(device).append(" ")
string.append("</span>") // color
return HtmlHelper.fromHtml(string.toString())
}
override val extendedPumpStatus: Spanned get() = pumpData?.extended ?: HtmlHelper.fromHtml("")
override val extendedOpenApsStatus: Spanned
get() {
val string = StringBuilder()
val enacted = openAPSData.enacted
val suggested = openAPSData.suggested
if (enacted != null && openAPSData.clockEnacted != openAPSData.clockSuggested) string
.append("<b>")
.append(dateUtil.minAgo(rh, openAPSData.clockEnacted))
.append("</b> ")
.append(JsonHelper.safeGetString(enacted, "reason"))
.append("<br>")
if (suggested != null) string
.append("<b>")
.append(dateUtil.minAgo(rh, openAPSData.clockSuggested))
.append("</b> ")
.append(JsonHelper.safeGetString(suggested, "reason"))
.append("<br>")
return HtmlHelper.fromHtml(string.toString())
}
override val openApsStatus: Spanned
get() {
val string = StringBuilder()
.append("<span style=\"color:${rh.gac(R.attr.nsTitleColor)}\">")
.append(rh.gs(R.string.openaps_short))
.append(": </span>")
// test warning level
val level = when {
openAPSData.clockSuggested + T.mins(sp.getLong(R.string.key_ns_alarm_urgent_stale_data_value, 31)).msecs() < dateUtil.now() -> ProcessedDeviceStatusData.Levels.URGENT
openAPSData.clockSuggested + T.mins(sp.getLong(R.string.key_ns_alarm_stale_data_value, 16)).msecs() < dateUtil.now() -> ProcessedDeviceStatusData.Levels.WARN
else -> ProcessedDeviceStatusData.Levels.INFO
}
string.append("<span style=\"color:${level.toColor()}\">")
if (openAPSData.clockSuggested != 0L) string.append(dateUtil.minAgo(rh, openAPSData.clockSuggested)).append(" ")
string.append("</span>") // color
return HtmlHelper.fromHtml(string.toString())
}
override val openApsTimestamp: Long
get() = if (openAPSData.clockSuggested != 0L) openAPSData.clockSuggested else -1
override fun getAPSResult(injector: HasAndroidInjector): APSResultObject {
val result = APSResultObject(injector)
result.json = openAPSData.suggested
result.date = openAPSData.clockSuggested
return result
}
override val uploaderStatus: String
get() {
val iterator: Iterator<*> = uploaderMap.entries.iterator()
var minBattery = 100
while (iterator.hasNext()) {
val pair = iterator.next() as Map.Entry<*, *>
val uploader = pair.value as ProcessedDeviceStatusData.Uploader
if (minBattery > uploader.battery) minBattery = uploader.battery
}
return "$minBattery%"
}
override val uploaderStatusSpanned: Spanned
get() {
val string = StringBuilder()
string.append("<span style=\"color:${rh.gac(R.attr.nsTitleColor)}\">")
string.append(rh.gs(R.string.uploader_short))
string.append(": </span>")
val iterator: Iterator<*> = uploaderMap.entries.iterator()
var minBattery = 100
while (iterator.hasNext()) {
val pair = iterator.next() as Map.Entry<*, *>
val uploader = pair.value as ProcessedDeviceStatusData.Uploader
if (minBattery > uploader.battery) minBattery = uploader.battery
}
string.append(minBattery)
string.append("%")
return HtmlHelper.fromHtml(string.toString())
}
override val extendedUploaderStatus: Spanned
get() {
val string = StringBuilder()
val iterator: Iterator<*> = uploaderMap.entries.iterator()
while (iterator.hasNext()) {
val pair = iterator.next() as Map.Entry<*, *>
val uploader = pair.value as ProcessedDeviceStatusData.Uploader
val device = pair.key as String
string.append("<b>").append(device).append(":</b> ").append(uploader.battery).append("%<br>")
}
return HtmlHelper.fromHtml(string.toString())
}
}

View file

@ -42,7 +42,7 @@ import info.nightscout.plugins.sync.nsclient.acks.NSUpdateAck
import info.nightscout.plugins.sync.nsclient.data.AlarmAck import info.nightscout.plugins.sync.nsclient.data.AlarmAck
import info.nightscout.plugins.sync.nsclient.data.NSAlarm import info.nightscout.plugins.sync.nsclient.data.NSAlarm
import info.nightscout.plugins.sync.nsclient.data.NSDeviceStatusHandler import info.nightscout.plugins.sync.nsclient.data.NSDeviceStatusHandler
import info.nightscout.plugins.sync.nsclient.data.NSSettingsStatus import info.nightscout.interfaces.nsclient.NSSettingsStatus
import info.nightscout.plugins.sync.nsclient.workers.NSClientAddAckWorker import info.nightscout.plugins.sync.nsclient.workers.NSClientAddAckWorker
import info.nightscout.plugins.sync.nsclient.workers.NSClientAddUpdateWorker import info.nightscout.plugins.sync.nsclient.workers.NSClientAddUpdateWorker
import info.nightscout.plugins.sync.nsclient.workers.NSClientMbgWorker import info.nightscout.plugins.sync.nsclient.workers.NSClientMbgWorker