simplify core:validators dependencies

This commit is contained in:
Milos Kozak 2023-09-07 23:59:35 +02:00
parent 64281ccc61
commit 82681b5b12
156 changed files with 1347 additions and 964 deletions

View file

@ -9,13 +9,18 @@ import info.nightscout.core.utils.fabric.FabricPrivacy
import info.nightscout.database.entities.EffectiveProfileSwitch import info.nightscout.database.entities.EffectiveProfileSwitch
import info.nightscout.database.entities.embedments.InsulinConfiguration import info.nightscout.database.entities.embedments.InsulinConfiguration
import info.nightscout.implementation.profile.ProfileStoreObject import info.nightscout.implementation.profile.ProfileStoreObject
import info.nightscout.implementation.profile.ProfileUtilImpl
import info.nightscout.implementation.utils.DecimalFormatterImpl
import info.nightscout.interfaces.Config import info.nightscout.interfaces.Config
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.iob.IobCobCalculator import info.nightscout.interfaces.iob.IobCobCalculator
import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.interfaces.plugin.ActivePlugin
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.DecimalFormatter
import info.nightscout.interfaces.utils.HardLimits import info.nightscout.interfaces.utils.HardLimits
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
import info.nightscout.shared.interfaces.ProfileUtil
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 info.nightscout.shared.utils.DateUtil import info.nightscout.shared.utils.DateUtil
@ -41,6 +46,8 @@ open class TestBaseWithProfile : TestBase() {
@Mock lateinit var sp: SP @Mock lateinit var sp: SP
lateinit var dateUtil: DateUtil lateinit var dateUtil: DateUtil
lateinit var profileUtil: ProfileUtil
lateinit var decimalFormatter: DecimalFormatter
lateinit var hardLimits: HardLimits lateinit var hardLimits: HardLimits
val rxBus = RxBus(aapsSchedulers, aapsLogger) val rxBus = RxBus(aapsSchedulers, aapsLogger)
@ -76,9 +83,12 @@ open class TestBaseWithProfile : TestBase() {
"{\"time\":\"2:00\",\"value\":\"3.4\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4.5\"}]," + "{\"time\":\"2:00\",\"value\":\"3.4\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4.5\"}]," +
"\"target_high\":[{\"time\":\"00:00\",\"value\":\"7\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}" "\"target_high\":[{\"time\":\"00:00\",\"value\":\"7\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}"
dateUtil = Mockito.spy(DateUtil(context)) dateUtil = Mockito.spy(DateUtil(context))
decimalFormatter = DecimalFormatterImpl(rh)
profileUtil = ProfileUtilImpl(sp, decimalFormatter)
testPumpPlugin = TestPumpPlugin(profileInjector) testPumpPlugin = TestPumpPlugin(profileInjector)
Mockito.`when`(dateUtil.now()).thenReturn(now) Mockito.`when`(dateUtil.now()).thenReturn(now)
Mockito.`when`(activePlugin.activePump).thenReturn(testPumpPlugin) Mockito.`when`(activePlugin.activePump).thenReturn(testPumpPlugin)
Mockito.`when`(sp.getString(info.nightscout.core.utils.R.string.key_units, GlucoseUnit.MGDL.asText)).thenReturn(GlucoseUnit.MGDL.asText)
hardLimits = HardLimitsMock(sp, rh) hardLimits = HardLimitsMock(sp, rh)
validProfile = ProfileSealed.Pure(pureProfileFromJson(JSONObject(validProfileJSON), dateUtil)!!) validProfile = ProfileSealed.Pure(pureProfileFromJson(JSONObject(validProfileJSON), dateUtil)!!)
effectiveProfileSwitch = EffectiveProfileSwitch( effectiveProfileSwitch = EffectiveProfileSwitch(

View file

@ -0,0 +1,17 @@
package info.nightscout.interfaces
@Suppress("SpellCheckingInspection")
enum class GlucoseUnit(val asText: String) {
// This is Nightscout's representation
MGDL("mg/dl"),
MMOL("mmol");
companion object {
const val MMOLL_TO_MGDL = 18.0 // 18.0182;
const val MGDL_TO_MMOLL = 1 / MMOLL_TO_MGDL
fun fromText(name: String) = values().firstOrNull { it.asText == name } ?: MGDL
}
}

View file

@ -0,0 +1,21 @@
package info.nightscout.interfaces.utils
import java.text.DecimalFormat
/**
* Format double values to strings
*/
interface DecimalFormatter {
fun to0Decimal(value: Double): String
fun to0Decimal(value: Double, unit: String): String
fun to1Decimal(value: Double): String
fun to1Decimal(value: Double, unit: String): String
fun to2Decimal(value: Double): String
fun to2Decimal(value: Double, unit: String): String
fun to3Decimal(value: Double): String
fun to3Decimal(value: Double, unit: String): String
fun toPumpSupportedBolus(value: Double, bolusStep: Double): String
fun toPumpSupportedBolusWithUnits(value: Double, bolusStep: Double): String
fun pumpSupportedBolusFormat(bolusStep: Double): DecimalFormat
}

View file

@ -0,0 +1,146 @@
package info.nightscout.shared.interfaces
import info.nightscout.interfaces.GlucoseUnit
interface ProfileUtil {
/**
* Units selected in [info.nightscout.shared.sharedPreferences.SP]
*
* @return GlucoseUnit for UI
*/
val units: GlucoseUnit
/**
* Convert value from mg/dl to selected units
*
* @param valueInMgdl glucose value in mgdl
* @param targetUnits target units
* @return value in target units
*/
fun fromMgdlToUnits(valueInMgdl: Double, targetUnits: GlucoseUnit = units): Double
/**
* Convert value from mmol/l to selected units
*
* @param value glucose value in mmol/l
* @param targetUnits target units
* @return value in target units
*/
fun fromMmolToUnits(value: Double, targetUnits: GlucoseUnit = units): Double
/**
* Convert to currently used units
*
* @param anyBg glycemia
* @return value in mg/dl or mmol/l
*/
fun valueInCurrentUnitsDetect(anyBg: Double): Double
/**
* Detect units of [anyBg] and return string in currently used units.
* Values >= 39 are expected to be in mmol/l, below in mg/dl.
*
* @param anyBg value either in mmol/l or mg/dl
* @return formatted string in current units
*/
fun stringInCurrentUnitsDetect(anyBg: Double): String
/**
* Value based on [targetUnits] parameter as a formatted string
*
* @param valueInMgdl known value in mg/dl
* @param targetUnits wanted units
* @return formatted one of the values based on [targetUnits] parameter
*/
fun fromMgdlToStringInUnits(valueInMgdl: Double?, targetUnits: GlucoseUnit = units): String
/**
* Pick from values based on [targetUnits] parameter as a formatted string with +/- sign
*
* @param valueInMgdl known value in mg/dl
* @param targetUnits wanted units
* @return formatted one of the values based on [targetUnits] parameter
*/
fun fromMgdlToSignedStringInUnits(valueInMgdl: Double, targetUnits: GlucoseUnit = units): String
/**
* Test if value is in mg/dl.
*
* @param anyBg glycemia
* @return true if value < 39
*/
fun isMgdl(anyBg: Double): Boolean
/**
* Test if value is in mmol/l
*
* @param anyBg glycemia
* @return true if value >= 39
*/
fun isMmol(anyBg: Double): Boolean
/**
* Detect units of [anyBg]
*
* @param anyBg glycemia
* @return [GlucoseUnit.MMOL] if value >= 39 otherwise [GlucoseUnit.MGDL]
*/
fun unitsDetect(anyBg: Double): GlucoseUnit
/**
* Convert to selected units
*
* @param anyBg glycemia
* @param targetUnits target units
* @return value in mg/dl or mmol/l
*/
fun valueInUnitsDetect(anyBg: Double, targetUnits: GlucoseUnit): Double
/**
* Detect units of [anyBg] and return string in [targetUnits]
* Values >= 39 are expected to be in mmol/l, below in mg/dl.
*
* @param anyBg value either in mmol/l or mg/dl
* @return formatted string
*/
fun stringInUnitsDetect(anyBg: Double, targetUnits: GlucoseUnit): String
/**
* Detect units and convert value to mg/dl
* Values >= 39 are expected to be in mmol/l, below in mg/dl.
*
* @param anyBg in any units
* @return value in mg/dl
*/
fun convertToMgdlDetect(anyBg: Double): Double
/**
* Convert value to mg/dl
*
* @param value value in [sourceUnits]
* @return value in mg/dl
*/
fun convertToMgdl(value: Double, sourceUnits: GlucoseUnit): Double
/**
* Convert value to mmol/l
*
* @param value value in [sourceUnits]
* @return value in mmol/l
*/
fun convertToMmol(value: Double, sourceUnits: GlucoseUnit): Double
/**
* Create properly formatted string of range "low - high".
* Targets are stored in mg/dl but profile vary
*
* @param low low range value
* @param high high range value
* @param sourceUnits units of source values
* @param targetUnits target units for formatting
* @return formatted range string
*/
//
fun toTargetRangeString(low: Double, high: Double, sourceUnits: GlucoseUnit, targetUnits: GlucoseUnit = units): String
}

View file

@ -9,6 +9,7 @@ import info.nightscout.implementation.overview.OverviewDataImpl
import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.interfaces.plugin.ActivePlugin
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.interfaces.utils.DecimalFormatter
import info.nightscout.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin import info.nightscout.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.rx.AapsSchedulers import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
@ -33,7 +34,8 @@ class HistoryBrowserData @Inject constructor(
profileFunction: ProfileFunction, profileFunction: ProfileFunction,
repository: AppRepository, repository: AppRepository,
fabricPrivacy: FabricPrivacy, fabricPrivacy: FabricPrivacy,
calculationWorkflow: CalculationWorkflow calculationWorkflow: CalculationWorkflow,
decimalFormatter: DecimalFormatter
) { ) {
var iobCobCalculator: IobCobCalculatorPlugin var iobCobCalculator: IobCobCalculatorPlugin
@ -50,7 +52,8 @@ class HistoryBrowserData @Inject constructor(
activePlugin, activePlugin,
defaultValueHelper, defaultValueHelper,
profileFunction, profileFunction,
repository repository,
decimalFormatter
) )
iobCobCalculator = iobCobCalculator =
IobCobCalculatorPlugin( IobCobCalculatorPlugin(
@ -66,7 +69,8 @@ class HistoryBrowserData @Inject constructor(
dateUtil, dateUtil,
repository, repository,
overviewData, overviewData,
calculationWorkflow calculationWorkflow,
decimalFormatter
) )
} }
} }

View file

@ -20,7 +20,6 @@ import info.nightscout.androidaps.R
import info.nightscout.androidaps.danaRKorean.DanaRKoreanPlugin import info.nightscout.androidaps.danaRKorean.DanaRKoreanPlugin
import info.nightscout.androidaps.danaRv2.DanaRv2Plugin import info.nightscout.androidaps.danaRv2.DanaRv2Plugin
import info.nightscout.androidaps.danar.DanaRPlugin import info.nightscout.androidaps.danar.DanaRPlugin
import info.nightscout.plugins.sync.openhumans.OpenHumansUploaderPlugin
import info.nightscout.androidaps.plugins.pump.eopatch.EopatchPumpPlugin import info.nightscout.androidaps.plugins.pump.eopatch.EopatchPumpPlugin
import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin
import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin
@ -32,8 +31,6 @@ import info.nightscout.insulin.InsulinOrefFreePeakPlugin
import info.nightscout.interfaces.Config import info.nightscout.interfaces.Config
import info.nightscout.interfaces.nsclient.NSSettingsStatus import info.nightscout.interfaces.nsclient.NSSettingsStatus
import info.nightscout.interfaces.plugin.PluginBase import info.nightscout.interfaces.plugin.PluginBase
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.protection.PasswordCheck import info.nightscout.interfaces.protection.PasswordCheck
import info.nightscout.interfaces.protection.ProtectionCheck.ProtectionType.BIOMETRIC import info.nightscout.interfaces.protection.ProtectionCheck.ProtectionType.BIOMETRIC
import info.nightscout.interfaces.protection.ProtectionCheck.ProtectionType.CUSTOM_PASSWORD import info.nightscout.interfaces.protection.ProtectionCheck.ProtectionType.CUSTOM_PASSWORD
@ -49,6 +46,7 @@ import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorPlugin
import info.nightscout.plugins.general.wear.WearPlugin import info.nightscout.plugins.general.wear.WearPlugin
import info.nightscout.plugins.sync.nsclient.NSClientPlugin import info.nightscout.plugins.sync.nsclient.NSClientPlugin
import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin
import info.nightscout.plugins.sync.openhumans.OpenHumansUploaderPlugin
import info.nightscout.plugins.sync.tidepool.TidepoolPlugin import info.nightscout.plugins.sync.tidepool.TidepoolPlugin
import info.nightscout.plugins.sync.xdrip.XdripPlugin import info.nightscout.plugins.sync.xdrip.XdripPlugin
import info.nightscout.pump.combo.ComboPlugin import info.nightscout.pump.combo.ComboPlugin
@ -63,6 +61,7 @@ import info.nightscout.sensitivity.SensitivityAAPSPlugin
import info.nightscout.sensitivity.SensitivityOref1Plugin import info.nightscout.sensitivity.SensitivityOref1Plugin
import info.nightscout.sensitivity.SensitivityWeightedAveragePlugin import info.nightscout.sensitivity.SensitivityWeightedAveragePlugin
import info.nightscout.shared.SafeParse import info.nightscout.shared.SafeParse
import info.nightscout.shared.interfaces.ProfileUtil
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 info.nightscout.source.AidexPlugin import info.nightscout.source.AidexPlugin
@ -83,7 +82,7 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang
@Inject lateinit var rxBus: RxBus @Inject lateinit var rxBus: RxBus
@Inject lateinit var rh: ResourceHelper @Inject lateinit var rh: ResourceHelper
@Inject lateinit var sp: SP @Inject lateinit var sp: SP
@Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var profileUtil: ProfileUtil
@Inject lateinit var pluginStore: PluginStore @Inject lateinit var pluginStore: PluginStore
@Inject lateinit var config: Config @Inject lateinit var config: Config
@ -326,7 +325,7 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang
rh.gs(info.nightscout.core.utils.R.string.key_low_mark) rh.gs(info.nightscout.core.utils.R.string.key_low_mark)
) )
if (unitDependent.toList().contains(pref.key) && pref is EditTextPreference) { if (unitDependent.toList().contains(pref.key) && pref is EditTextPreference) {
val converted = Profile.toCurrentUnits(profileFunction, SafeParse.stringToDouble(pref.text)) val converted = profileUtil.valueInCurrentUnitsDetect(SafeParse.stringToDouble(pref.text))
pref.summary = converted.toString() pref.summary = converted.toString()
} }
} }

View file

@ -39,6 +39,7 @@ import info.nightscout.pump.combo.ruffyscripter.RuffyScripter
import info.nightscout.pump.dana.DanaPump import info.nightscout.pump.dana.DanaPump
import info.nightscout.pump.dana.R import info.nightscout.pump.dana.R
import info.nightscout.pump.dana.database.DanaHistoryDatabase import info.nightscout.pump.dana.database.DanaHistoryDatabase
import info.nightscout.pump.danars.DanaRSPlugin
import info.nightscout.pump.virtual.VirtualPumpPlugin import info.nightscout.pump.virtual.VirtualPumpPlugin
import info.nightscout.sharedtests.TestBaseWithProfile import info.nightscout.sharedtests.TestBaseWithProfile
import info.nightscout.source.GlimpPlugin import info.nightscout.source.GlimpPlugin
@ -78,7 +79,7 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
private lateinit var objectivesPlugin: ObjectivesPlugin private lateinit var objectivesPlugin: ObjectivesPlugin
private lateinit var comboPlugin: ComboPlugin private lateinit var comboPlugin: ComboPlugin
private lateinit var danaRPlugin: DanaRPlugin private lateinit var danaRPlugin: DanaRPlugin
private lateinit var danaRSPlugin: info.nightscout.pump.danars.DanaRSPlugin private lateinit var danaRSPlugin: DanaRSPlugin
private lateinit var insightPlugin: LocalInsightPlugin private lateinit var insightPlugin: LocalInsightPlugin
private lateinit var openAPSSMBPlugin: OpenAPSSMBPlugin private lateinit var openAPSSMBPlugin: OpenAPSSMBPlugin
private lateinit var openAPSAMAPlugin: OpenAPSAMAPlugin private lateinit var openAPSAMAPlugin: OpenAPSAMAPlugin
@ -135,36 +136,21 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
//SafetyPlugin //SafetyPlugin
constraintChecker = ConstraintsImpl(activePlugin) constraintChecker = ConstraintsImpl(activePlugin)
val glucoseStatusProvider = GlucoseStatusProviderImpl(aapsLogger = aapsLogger, iobCobCalculator = iobCobCalculator, dateUtil = dateUtil) val glucoseStatusProvider = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculator, dateUtil, decimalFormatter)
insightDbHelper = InsightDbHelper(insightDatabaseDao) insightDbHelper = InsightDbHelper(insightDatabaseDao)
danaPump = DanaPump(aapsLogger, sp, dateUtil, instantiator) danaPump = DanaPump(aapsLogger, sp, dateUtil, instantiator, decimalFormatter)
objectivesPlugin = ObjectivesPlugin(injector, aapsLogger, rh, activePlugin, sp, config) objectivesPlugin = ObjectivesPlugin(injector, aapsLogger, rh, activePlugin, sp, config)
comboPlugin = ComboPlugin(injector, aapsLogger, rxBus, rh, profileFunction, sp, commandQueue, pumpSync, dateUtil, ruffyScripter, uiInteraction) comboPlugin = ComboPlugin(injector, aapsLogger, rxBus, rh, profileFunction, sp, commandQueue, pumpSync, dateUtil, ruffyScripter, uiInteraction)
danaRPlugin = DanaRPlugin( danaRPlugin = DanaRPlugin(
injector, aapsLogger, aapsSchedulers, rxBus, context, rh, constraintChecker, activePlugin, sp, commandQueue, danaPump, dateUtil, fabricPrivacy, pumpSync, injector, aapsLogger, aapsSchedulers, rxBus, context, rh, constraintChecker, activePlugin, sp, commandQueue, danaPump, dateUtil, fabricPrivacy, pumpSync,
uiInteraction, danaHistoryDatabase uiInteraction, danaHistoryDatabase, decimalFormatter
) )
danaRSPlugin = danaRSPlugin =
info.nightscout.pump.danars.DanaRSPlugin( DanaRSPlugin(
injector, injector, aapsLogger, aapsSchedulers, rxBus, context, rh, constraintChecker, profileFunction,
aapsLogger, sp, commandQueue, danaPump, pumpSync, detailedBolusInfoStorage, temporaryBasalStorage,
aapsSchedulers, fabricPrivacy, dateUtil, uiInteraction, danaHistoryDatabase, decimalFormatter
rxBus,
context,
rh,
constraintChecker,
profileFunction,
sp,
commandQueue,
danaPump,
pumpSync,
detailedBolusInfoStorage,
temporaryBasalStorage,
fabricPrivacy,
dateUtil,
uiInteraction,
danaHistoryDatabase
) )
insightPlugin = LocalInsightPlugin(injector, aapsLogger, rxBus, rh, sp, commandQueue, profileFunction, context, config, dateUtil, insightDbHelper, pumpSync, insightDatabase) insightPlugin = LocalInsightPlugin(injector, aapsLogger, rxBus, rh, sp, commandQueue, profileFunction, context, config, dateUtil, insightDbHelper, pumpSync, insightDatabase)
openAPSSMBPlugin = openAPSSMBPlugin =
@ -228,18 +214,8 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
) )
safetyPlugin = safetyPlugin =
SafetyPlugin( SafetyPlugin(
injector, injector, aapsLogger, rh, sp, constraintChecker, activePlugin, hardLimits,
aapsLogger, ConfigImpl(fileListProvider), iobCobCalculator, dateUtil, uiInteraction, decimalFormatter
rh,
sp,
rxBus,
constraintChecker,
activePlugin,
hardLimits,
ConfigImpl(fileListProvider),
iobCobCalculator,
dateUtil,
uiInteraction
) )
val constraintsPluginsList = ArrayList<PluginBase>() val constraintsPluginsList = ArrayList<PluginBase>()
constraintsPluginsList.add(safetyPlugin) constraintsPluginsList.add(safetyPlugin)

View file

@ -72,7 +72,7 @@ class SafetyPluginTest : TestBaseWithProfile() {
`when`(activePlugin.activePump).thenReturn(virtualPumpPlugin) `when`(activePlugin.activePump).thenReturn(virtualPumpPlugin)
`when`(virtualPumpPlugin.pumpDescription).thenReturn(pumpDescription) `when`(virtualPumpPlugin.pumpDescription).thenReturn(pumpDescription)
`when`(config.APS).thenReturn(true) `when`(config.APS).thenReturn(true)
safetyPlugin = SafetyPlugin(injector, aapsLogger, rh, sp, rxBus, constraintChecker, activePlugin, hardLimits, config, iobCobCalculator, dateUtil, uiInteraction) safetyPlugin = SafetyPlugin(injector, aapsLogger, rh, sp, constraintChecker, activePlugin, hardLimits, config, iobCobCalculator, dateUtil, uiInteraction, decimalFormatter)
openAPSAMAPlugin = OpenAPSAMAPlugin( openAPSAMAPlugin = OpenAPSAMAPlugin(
injector, aapsLogger, rxBus, constraintChecker, rh, profileFunction, context, activePlugin, iobCobCalculator, hardLimits, profiler, fabricPrivacy, injector, aapsLogger, rxBus, constraintChecker, rh, profileFunction, context, activePlugin, iobCobCalculator, hardLimits, profiler, fabricPrivacy,
dateUtil, repository, glucoseStatusProvider, sp dateUtil, repository, glucoseStatusProvider, sp

View file

@ -159,15 +159,15 @@ class PumpEnactResultTest : TestBaseWithProfile() {
@Test fun toHtmlTest() { @Test fun toHtmlTest() {
var per: PumpEnactResult = PumpEnactResult(injector).enacted(true).bolusDelivered(10.0).comment("AAA") var per: PumpEnactResult = PumpEnactResult(injector).enacted(true).bolusDelivered(10.0).comment("AAA")
Assertions.assertEquals("<b>Success</b>: false<br><b>Enacted</b>: true<br><b>Comment</b>: AAA<br><b>SMB</b>: 10.0 U", per.toHtml(rh)) Assertions.assertEquals("<b>Success</b>: false<br><b>Enacted</b>: true<br><b>Comment</b>: AAA<br><b>SMB</b>: 10.0 U", per.toHtml(rh, decimalFormatter))
per = PumpEnactResult(injector).enacted(true).isTempCancel(true).comment("AAA") per = PumpEnactResult(injector).enacted(true).isTempCancel(true).comment("AAA")
Assertions.assertEquals("<b>Success</b>: false<br><b>Enacted</b>: true<br><b>Comment</b>: AAA<br>Cancel temp basal", per.toHtml(rh)) Assertions.assertEquals("<b>Success</b>: false<br><b>Enacted</b>: true<br><b>Comment</b>: AAA<br>Cancel temp basal", per.toHtml(rh, decimalFormatter))
per = PumpEnactResult(injector).enacted(true).isPercent(true).percent(90).duration(20).comment("AAA") per = PumpEnactResult(injector).enacted(true).isPercent(true).percent(90).duration(20).comment("AAA")
Assertions.assertEquals("<b>Success</b>: false<br><b>Enacted</b>: true<br><b>Comment</b>: AAA<br><b>Duration</b>: 20 min<br><b>Percent</b>: 90%", per.toHtml(rh)) Assertions.assertEquals("<b>Success</b>: false<br><b>Enacted</b>: true<br><b>Comment</b>: AAA<br><b>Duration</b>: 20 min<br><b>Percent</b>: 90%", per.toHtml(rh, decimalFormatter))
per = PumpEnactResult(injector).enacted(true).isPercent(false).absolute(1.0).duration(30).comment("AAA") per = PumpEnactResult(injector).enacted(true).isPercent(false).absolute(1.0).duration(30).comment("AAA")
Assertions.assertEquals("<b>Success</b>: false<br><b>Enacted</b>: true<br><b>Comment</b>: AAA<br><b>Duration</b>: 30 min<br><b>Absolute</b>: 1.00 U/h", per.toHtml(rh)) Assertions.assertEquals("<b>Success</b>: false<br><b>Enacted</b>: true<br><b>Comment</b>: AAA<br><b>Duration</b>: 30 min<br><b>Absolute</b>: 1.00 U/h", per.toHtml(rh, decimalFormatter))
per = PumpEnactResult(injector).enacted(false).comment("AAA") per = PumpEnactResult(injector).enacted(false).comment("AAA")
Assertions.assertEquals("<b>Success</b>: false<br><b>Comment</b>: AAA", per.toHtml(rh)) Assertions.assertEquals("<b>Success</b>: false<br><b>Comment</b>: AAA", per.toHtml(rh, decimalFormatter))
} }
@Test fun jsonTest() { @Test fun jsonTest() {

View file

@ -12,7 +12,8 @@ class BolusDataPoint(
val data: Bolus, val data: Bolus,
private val rh: ResourceHelper, private val rh: ResourceHelper,
private val activePlugin: ActivePlugin, private val activePlugin: ActivePlugin,
private val defaultValueHelper: DefaultValueHelper private val defaultValueHelper: DefaultValueHelper,
private val decimalFormatter: DecimalFormatter
) : DataPointWithLabelInterface { ) : DataPointWithLabelInterface {
private var yValue = 0.0 private var yValue = 0.0
@ -20,7 +21,7 @@ class BolusDataPoint(
override fun getX(): Double = data.timestamp.toDouble() override fun getX(): Double = data.timestamp.toDouble()
override fun getY(): Double = if (data.type == Bolus.Type.SMB) defaultValueHelper.determineLowLine() else yValue override fun getY(): Double = if (data.type == Bolus.Type.SMB) defaultValueHelper.determineLowLine() else yValue
override val label override val label
get() = DecimalFormatter.toPumpSupportedBolus(data.amount, activePlugin.activePump, rh) get() = decimalFormatter.toPumpSupportedBolus(data.amount, activePlugin.activePump.pumpDescription.bolusStep)
override val duration = 0L override val duration = 0L
override val size = 2f override val size = 2f
override val paintStyle: Paint.Style = Paint.Style.FILL // not used override val paintStyle: Paint.Style = Paint.Style.FILL // not used

View file

@ -8,7 +8,8 @@ import info.nightscout.shared.interfaces.ResourceHelper
class ExtendedBolusDataPoint( class ExtendedBolusDataPoint(
val data: ExtendedBolus, val data: ExtendedBolus,
private val rh: ResourceHelper private val rh: ResourceHelper,
private val decimalFormatter: DecimalFormatter
) : DataPointWithLabelInterface { ) : DataPointWithLabelInterface {
private var yValue = 0.0 private var yValue = 0.0
@ -28,5 +29,5 @@ class ExtendedBolusDataPoint(
yValue = y yValue = y
} }
private fun ExtendedBolus.toStringTotal(): String = "${DecimalFormatter.to2Decimal(amount)}U ( ${DecimalFormatter.to2Decimal(rate)} U/h )" private fun ExtendedBolus.toStringTotal(): String = "${decimalFormatter.to2Decimal(amount)}U ( ${decimalFormatter.to2Decimal(rate)} U/h )"
} }

View file

@ -5,24 +5,23 @@ import android.graphics.Paint
import info.nightscout.database.entities.GlucoseValue import info.nightscout.database.entities.GlucoseValue
import info.nightscout.interfaces.Constants import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.GlucoseUnit import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.profile.Profile import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.interfaces.ResourceHelper
class GlucoseValueDataPoint( class GlucoseValueDataPoint(
val data: GlucoseValue, val data: GlucoseValue,
private val profileFunction: ProfileFunction, private val profileUtil: ProfileUtil,
private val rh: ResourceHelper private val rh: ResourceHelper,
) : DataPointWithLabelInterface { ) : DataPointWithLabelInterface {
private fun valueToUnits(units: GlucoseUnit): Double = private fun valueToUnits(units: GlucoseUnit): Double =
if (units == GlucoseUnit.MGDL) data.value else data.value * Constants.MGDL_TO_MMOLL if (units == GlucoseUnit.MGDL) data.value else data.value * Constants.MGDL_TO_MMOLL
override fun getX(): Double = data.timestamp.toDouble() override fun getX(): Double = data.timestamp.toDouble()
override fun getY(): Double = valueToUnits(profileFunction.getUnits()) override fun getY(): Double = valueToUnits(profileUtil.units)
override fun setY(y: Double) {} override fun setY(y: Double) {}
override val label: String = Profile.toCurrentUnitsString(profileFunction, data.value) override val label: String = profileUtil.fromMgdlToStringInUnits(data.value)
override val duration = 0L override val duration = 0L
override val shape get() = if (isPrediction) PointsWithLabelGraphSeries.Shape.PREDICTION else PointsWithLabelGraphSeries.Shape.BG override val shape get() = if (isPrediction) PointsWithLabelGraphSeries.Shape.PREDICTION else PointsWithLabelGraphSeries.Shape.BG
override val size = if (isPrediction) 1f else 0.6f override val size = if (isPrediction) 1f else 0.6f
@ -30,8 +29,8 @@ class GlucoseValueDataPoint(
override fun color(context: Context?): Int { override fun color(context: Context?): Int {
return when { return when {
isPrediction -> predictionColor(context) isPrediction -> predictionColor(context)
else -> rh.gac(context, info.nightscout.core.ui.R.attr.originalBgValueColor) else -> rh.gac(context, info.nightscout.core.ui.R.attr.originalBgValueColor)
} }
} }

View file

@ -5,14 +5,13 @@ import android.graphics.Paint
import info.nightscout.database.entities.TherapyEvent import info.nightscout.database.entities.TherapyEvent
import info.nightscout.interfaces.Constants import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.Translator import info.nightscout.interfaces.Translator
import info.nightscout.interfaces.profile.Profile import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.interfaces.ResourceHelper
class TherapyEventDataPoint( class TherapyEventDataPoint(
val data: TherapyEvent, val data: TherapyEvent,
private val rh: ResourceHelper, private val rh: ResourceHelper,
private val profileFunction: ProfileFunction, private val profileUtil: ProfileUtil,
private val translator: Translator private val translator: Translator
) : DataPointWithLabelInterface { ) : DataPointWithLabelInterface {
@ -21,20 +20,13 @@ class TherapyEventDataPoint(
override fun getX(): Double = data.timestamp.toDouble() override fun getX(): Double = data.timestamp.toDouble()
override fun getY(): Double { override fun getY(): Double {
val units = profileFunction.getUnits() if (data.type == TherapyEvent.Type.NS_MBG) return profileUtil.fromMgdlToUnits(data.glucose!!)
if (data.type == TherapyEvent.Type.NS_MBG) return Profile.fromMgdlToUnits(data.glucose!!, units)
if (data.glucose != null && data.glucose != 0.0) { if (data.glucose != null && data.glucose != 0.0) {
var mmol = 0.0 val mgdl: Double = when (data.glucoseUnit) {
var mgdl = 0.0 TherapyEvent.GlucoseUnit.MGDL -> data.glucose!!
if (data.glucoseUnit == TherapyEvent.GlucoseUnit.MGDL) { TherapyEvent.GlucoseUnit.MMOL -> data.glucose!! * Constants.MMOLL_TO_MGDL
mgdl = data.glucose!!
mmol = data.glucose!! * Constants.MGDL_TO_MMOLL
} }
if (data.glucoseUnit == TherapyEvent.GlucoseUnit.MMOL) { return profileUtil.fromMgdlToUnits(mgdl)
mmol = data.glucose!!
mgdl = data.glucose!! * Constants.MMOLL_TO_MGDL
}
return Profile.toUnits(mgdl, mmol, units)
} }
return yValue return yValue
} }

View file

@ -1,12 +0,0 @@
package info.nightscout.interfaces
enum class GlucoseUnit(val asText: String) {
MGDL(Constants.MGDL),
MMOL(Constants.MMOL);
companion object {
fun fromText(name: String) = values().firstOrNull { it.asText == name } ?: MGDL
}
}

View file

@ -1,10 +1,8 @@
package info.nightscout.interfaces.profile package info.nightscout.interfaces.profile
import info.nightscout.interfaces.Config import info.nightscout.interfaces.Config
import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.GlucoseUnit import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.pump.Pump import info.nightscout.interfaces.pump.Pump
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.interfaces.utils.HardLimits import info.nightscout.interfaces.utils.HardLimits
import info.nightscout.interfaces.utils.Round import info.nightscout.interfaces.utils.Round
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
@ -133,62 +131,4 @@ interface Profile {
return result return result
} }
} }
companion object {
/*
* Units conversion
*/
fun fromMgdlToUnits(value: Double, units: GlucoseUnit): Double =
if (units == GlucoseUnit.MGDL) value else value * Constants.MGDL_TO_MMOLL
fun fromMmolToUnits(value: Double, units: GlucoseUnit): Double =
if (units == GlucoseUnit.MMOL) value else value * Constants.MMOLL_TO_MGDL
fun toUnits(valueInMgdl: Double, valueInMmol: Double, units: GlucoseUnit): Double =
if (units == GlucoseUnit.MGDL) valueInMgdl else valueInMmol
fun toUnitsString(valueInMgdl: Double, valueInMmol: Double, units: GlucoseUnit): String =
if (units == GlucoseUnit.MGDL) DecimalFormatter.to0Decimal(valueInMgdl) else DecimalFormatter.to1Decimal(valueInMmol)
fun toSignedUnitsString(valueInMgdl: Double, valueInMmol: Double, units: GlucoseUnit): String =
if (units == GlucoseUnit.MGDL) (if (valueInMgdl > 0) "+" else "") + DecimalFormatter.to0Decimal(valueInMgdl)
else (if (valueInMmol > 0) "+" else "") + DecimalFormatter.to1Decimal(valueInMmol)
fun isMgdl(anyBg: Double) = anyBg >= 39
fun isMmol(anyBg: Double) = anyBg < 39
fun unit(anyBg: Double) = if (isMgdl(anyBg)) GlucoseUnit.MGDL else GlucoseUnit.MMOL
fun toCurrentUnits(profileFunction: ProfileFunction, anyBg: Double): Double =
if (isMmol(anyBg)) fromMmolToUnits(anyBg, profileFunction.getUnits())
else fromMgdlToUnits(anyBg, profileFunction.getUnits())
fun toCurrentUnits(units: GlucoseUnit, anyBg: Double): Double =
if (isMmol(anyBg)) fromMmolToUnits(anyBg, units)
else fromMgdlToUnits(anyBg, units)
fun toCurrentUnitsString(profileFunction: ProfileFunction, anyBg: Double): String =
if (isMmol(anyBg)) toUnitsString(anyBg * Constants.MMOLL_TO_MGDL, anyBg, profileFunction.getUnits())
else toUnitsString(anyBg, anyBg * Constants.MGDL_TO_MMOLL, profileFunction.getUnits())
fun toMgdl(value: Double): Double =
if (isMgdl(value)) value else value * Constants.MMOLL_TO_MGDL
fun toMgdl(value: Double, units: GlucoseUnit): Double =
if (units == GlucoseUnit.MGDL) value else value * Constants.MMOLL_TO_MGDL
fun toMmol(value: Double, units: GlucoseUnit): Double =
if (units == GlucoseUnit.MGDL) value * Constants.MGDL_TO_MMOLL else value
// targets are stored in mg/dl but profile vary
fun toTargetRangeString(low: Double, high: Double, sourceUnits: GlucoseUnit, units: GlucoseUnit): String {
val lowMgdl = toMgdl(low, sourceUnits)
val highMgdl = toMgdl(high, sourceUnits)
val lowMmol = toMmol(low, sourceUnits)
val highMmol = toMmol(high, sourceUnits)
return if (low == high) toUnitsString(lowMgdl, lowMmol, units)
else toUnitsString(lowMgdl, lowMmol, units) + " - " + toUnitsString(highMgdl, highMmol, units)
}
}
} }

View file

@ -91,10 +91,10 @@ interface PumpSync {
if (isAbsolute) rate if (isAbsolute) rate
else profile.getBasal(time) * rate / 100 else profile.getBasal(time) * rate / 100
fun toStringFull(dateUtil: DateUtil): String { fun toStringFull(dateUtil: DateUtil, decimalFormatter: DecimalFormatter): String {
return when { return when {
isAbsolute -> { isAbsolute -> {
DecimalFormatter.to2Decimal(rate) + "U/h @" + decimalFormatter.to2Decimal(rate) + "U/h @" +
dateUtil.timeString(timestamp) + dateUtil.timeString(timestamp) +
" " + getPassedDurationToTimeInMinutes(dateUtil.now()) + "/" + durationInMinutes + "'" " " + getPassedDurationToTimeInMinutes(dateUtil.now()) + "/" + durationInMinutes + "'"
} }
@ -130,10 +130,12 @@ interface PumpSync {
val plannedRemainingMinutes: Long val plannedRemainingMinutes: Long
get() = max(T.msecs(end - System.currentTimeMillis()).mins(), 0L) get() = max(T.msecs(end - System.currentTimeMillis()).mins(), 0L)
private fun getPassedDurationToTimeInMinutes(time: Long): Int = private fun getPassedDurationToTimeInMinutes(time: Long): Int =
((min(time, end) - timestamp) / 60.0 / 1000).roundToInt() ((min(time, end) - timestamp) / 60.0 / 1000).roundToInt()
fun toStringFull(dateUtil: DateUtil): String =
"E " + DecimalFormatter.to2Decimal(rate) + "U/h @" + fun toStringFull(dateUtil: DateUtil, decimalFormatter: DecimalFormatter): String =
"E " + decimalFormatter.to2Decimal(rate) + "U/h @" +
dateUtil.timeString(timestamp) + dateUtil.timeString(timestamp) +
" " + getPassedDurationToTimeInMinutes(dateUtil.now()) + "/" + T.msecs(duration).mins() + "min" " " + getPassedDurationToTimeInMinutes(dateUtil.now()) + "/" + T.msecs(duration).mins() + "min"
} }

View file

@ -3,14 +3,14 @@ package info.nightscout.interfaces.stats
import android.content.Context import android.content.Context
import android.widget.TableRow import android.widget.TableRow
import android.widget.TextView import android.widget.TextView
import info.nightscout.interfaces.profile.ProfileFunction import info.nightscout.shared.interfaces.ProfileUtil
interface DexcomTIR { interface DexcomTIR {
fun calculateSD(): Double fun calculateSD(): Double
fun toHbA1cView(context: Context): TextView fun toHbA1cView(context: Context): TextView
fun toSDView(context: Context, profileFunction: ProfileFunction): TextView fun toSDView(context: Context, profileUtil: ProfileUtil): TextView
fun toRangeHeaderView(context: Context, profileFunction: ProfileFunction): TextView fun toRangeHeaderView(context: Context, profileUtil: ProfileUtil): TextView
fun toTableRowHeader(context: Context): TableRow fun toTableRowHeader(context: Context): TableRow
fun toTableRow(context: Context): TableRow fun toTableRow(context: Context): TableRow
} }

View file

@ -1,29 +0,0 @@
package info.nightscout.interfaces.utils
import info.nightscout.interfaces.R
import info.nightscout.interfaces.pump.Pump
import info.nightscout.shared.interfaces.ResourceHelper
import java.text.DecimalFormat
object DecimalFormatter {
private val format0dec = DecimalFormat("0")
private val format1dec = DecimalFormat("0.0")
private val format2dec = DecimalFormat("0.00")
private val format3dec = DecimalFormat("0.000")
fun to0Decimal(value: Double): String = format0dec.format(value)
fun to0Decimal(value: Double, unit: String): String = format0dec.format(value) + unit
fun to1Decimal(value: Double): String = format1dec.format(value)
fun to1Decimal(value: Double, unit: String): String = format1dec.format(value) + unit
fun to2Decimal(value: Double): String = format2dec.format(value)
fun to2Decimal(value: Double, unit: String): String = format2dec.format(value) + unit
fun to3Decimal(value: Double): String = format3dec.format(value)
fun to3Decimal(value: Double, unit: String): String = format3dec.format(value) + unit
fun toPumpSupportedBolus(value: Double, pump: Pump): String = if (pump.pumpDescription.bolusStep <= 0.051) to2Decimal(value) else to1Decimal(value)
fun toPumpSupportedBolus(value: Double, pump: Pump, rh: ResourceHelper): String =
if (pump.pumpDescription.bolusStep <= 0.051) rh.gs(R.string.format_insulin_units, value)
else rh.gs(R.string.format_insulin_units1, value)
fun pumpSupportedBolusFormat(pump: Pump): DecimalFormat = if (pump.pumpDescription.bolusStep <= 0.051) DecimalFormat("0.00") else DecimalFormat("0.0")
}

View file

@ -23,12 +23,12 @@ fun ExtendedBolus.isInProgress(dateUtil: DateUtil): Boolean =
val ExtendedBolus.plannedRemainingMinutes: Int val ExtendedBolus.plannedRemainingMinutes: Int
get() = max(round((end - System.currentTimeMillis()) / 1000.0 / 60).toInt(), 0) get() = max(round((end - System.currentTimeMillis()) / 1000.0 / 60).toInt(), 0)
fun ExtendedBolus.toStringFull(dateUtil: DateUtil): String = fun ExtendedBolus.toStringFull(dateUtil: DateUtil, decimalFormatter: DecimalFormatter): String =
"E " + DecimalFormatter.to2Decimal(rate) + "U/h @" + dateUtil.timeString(timestamp) + "E " + decimalFormatter.to2Decimal(rate) + "U/h @" + dateUtil.timeString(timestamp) +
" " + getPassedDurationToTimeInMinutes(dateUtil.now()) + "/" + T.msecs(duration).mins() + "min" " " + getPassedDurationToTimeInMinutes(dateUtil.now()) + "/" + T.msecs(duration).mins() + "min"
fun ExtendedBolus.toStringMedium(dateUtil: DateUtil): String = fun ExtendedBolus.toStringMedium(dateUtil: DateUtil, decimalFormatter: DecimalFormatter): String =
DecimalFormatter.to2Decimal(rate) + "U/h " + getPassedDurationToTimeInMinutes(dateUtil.now()) + "/" + T.msecs(duration).mins() + "'" decimalFormatter.to2Decimal(rate) + "U/h " + getPassedDurationToTimeInMinutes(dateUtil.now()) + "/" + T.msecs(duration).mins() + "'"
fun ExtendedBolus.getPassedDurationToTimeInMinutes(time: Long): Int = fun ExtendedBolus.getPassedDurationToTimeInMinutes(time: Long): Int =
((min(time, end) - timestamp) / 60.0 / 1000).roundToInt() ((min(time, end) - timestamp) / 60.0 / 1000).roundToInt()

View file

@ -5,14 +5,9 @@ import info.nightscout.database.entities.GlucoseValue
import info.nightscout.interfaces.Constants import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.GlucoseUnit import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.iob.InMemoryGlucoseValue import info.nightscout.interfaces.iob.InMemoryGlucoseValue
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.shared.utils.DateUtil import info.nightscout.shared.utils.DateUtil
import org.json.JSONObject import org.json.JSONObject
fun GlucoseValue.valueToUnitsString(units: GlucoseUnit): String =
if (units == GlucoseUnit.MGDL) DecimalFormatter.to0Decimal(value)
else DecimalFormatter.to1Decimal(value * Constants.MGDL_TO_MMOLL)
fun GlucoseValue.toJson(isAdd: Boolean, dateUtil: DateUtil): JSONObject = fun GlucoseValue.toJson(isAdd: Boolean, dateUtil: DateUtil): JSONObject =
JSONObject() JSONObject()
.put("device", sourceSensor.text) .put("device", sourceSensor.text)
@ -28,10 +23,6 @@ fun InMemoryGlucoseValue.valueToUnits(units: GlucoseUnit): Double =
if (units == GlucoseUnit.MGDL) recalculated if (units == GlucoseUnit.MGDL) recalculated
else recalculated * Constants.MGDL_TO_MMOLL else recalculated * Constants.MGDL_TO_MMOLL
fun InMemoryGlucoseValue.valueToUnitsString(units: GlucoseUnit): String =
if (units == GlucoseUnit.MGDL) DecimalFormatter.to0Decimal(recalculated)
else DecimalFormatter.to1Decimal(recalculated * Constants.MGDL_TO_MMOLL)
fun GlucoseValue.TrendArrow.directionToIcon(): Int = fun GlucoseValue.TrendArrow.directionToIcon(): Int =
when (this) { when (this) {
GlucoseValue.TrendArrow.TRIPLE_DOWN -> R.drawable.ic_invalid GlucoseValue.TrendArrow.TRIPLE_DOWN -> R.drawable.ic_invalid

View file

@ -12,10 +12,10 @@ import info.nightscout.shared.utils.T
import org.json.JSONObject import org.json.JSONObject
import java.util.TimeZone import java.util.TimeZone
fun ProfileSwitch.getCustomizedName(): String { fun ProfileSwitch.getCustomizedName(decimalFormatter: DecimalFormatter): String {
var name: String = profileName var name: String = profileName
if (Constants.LOCAL_PROFILE == name) { if (Constants.LOCAL_PROFILE == name) {
name = DecimalFormatter.to2Decimal(ProfileSealed.PS(this).percentageBasalSum()) + "U " name = decimalFormatter.to2Decimal(ProfileSealed.PS(this).percentageBasalSum()) + "U "
} }
if (timeshift != 0L || percentage != 100) { if (timeshift != 0L || percentage != 100) {
name += "($percentage%" name += "($percentage%"

View file

@ -34,16 +34,16 @@ private fun TemporaryBasal.netExtendedRate(profile: Profile) = rate - profile.ge
val TemporaryBasal.durationInMinutes val TemporaryBasal.durationInMinutes
get() = T.msecs(duration).mins() get() = T.msecs(duration).mins()
fun TemporaryBasal.toStringFull(profile: Profile, dateUtil: DateUtil): String { fun TemporaryBasal.toStringFull(profile: Profile, dateUtil: DateUtil, decimalFormatter: DecimalFormatter): String {
return when { return when {
type == TemporaryBasal.Type.FAKE_EXTENDED -> { type == TemporaryBasal.Type.FAKE_EXTENDED -> {
DecimalFormatter.to2Decimal(rate) + "U/h (" + DecimalFormatter.to2Decimal(netExtendedRate(profile)) + "E) @" + decimalFormatter.to2Decimal(rate) + "U/h (" + decimalFormatter.to2Decimal(netExtendedRate(profile)) + "E) @" +
dateUtil.timeString(timestamp) + dateUtil.timeString(timestamp) +
" " + getPassedDurationToTimeInMinutes(dateUtil.now()) + "/" + durationInMinutes + "'" " " + getPassedDurationToTimeInMinutes(dateUtil.now()) + "/" + durationInMinutes + "'"
} }
isAbsolute -> { isAbsolute -> {
DecimalFormatter.to2Decimal(rate) + "U/h @" + decimalFormatter.to2Decimal(rate) + "U/h @" +
dateUtil.timeString(timestamp) + dateUtil.timeString(timestamp) +
" " + getPassedDurationToTimeInMinutes(dateUtil.now()) + "/" + durationInMinutes + "'" " " + getPassedDurationToTimeInMinutes(dateUtil.now()) + "/" + durationInMinutes + "'"
} }
@ -56,9 +56,9 @@ fun TemporaryBasal.toStringFull(profile: Profile, dateUtil: DateUtil): String {
} }
} }
fun TemporaryBasal.toStringShort(): String = fun TemporaryBasal.toStringShort(decimalFormatter: DecimalFormatter): String =
if (isAbsolute || type == TemporaryBasal.Type.FAKE_EXTENDED) DecimalFormatter.to2Decimal(rate) + "U/h" if (isAbsolute || type == TemporaryBasal.Type.FAKE_EXTENDED) decimalFormatter.to2Decimal(rate) + "U/h"
else "${DecimalFormatter.to0Decimal(rate)}%" else "${decimalFormatter.to0Decimal(rate)}%"
fun TemporaryBasal.iobCalc(time: Long, profile: Profile, insulinInterface: Insulin): IobTotal { fun TemporaryBasal.iobCalc(time: Long, profile: Profile, insulinInterface: Insulin): IobTotal {
if (!isValid) return IobTotal(time) if (!isValid) return IobTotal(time)

View file

@ -3,23 +3,23 @@ package info.nightscout.core.extensions
import info.nightscout.database.entities.TemporaryTarget import info.nightscout.database.entities.TemporaryTarget
import info.nightscout.interfaces.Constants import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.GlucoseUnit import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.utils.DecimalFormatter import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.interfaces.ResourceHelper
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
fun TemporaryTarget.lowValueToUnitsToString(units: GlucoseUnit): String = fun TemporaryTarget.lowValueToUnitsToString(units: GlucoseUnit, decimalFormatter: DecimalFormatter): String =
if (units == GlucoseUnit.MGDL) DecimalFormatter.to0Decimal(this.lowTarget) if (units == GlucoseUnit.MGDL) decimalFormatter.to0Decimal(this.lowTarget)
else DecimalFormatter.to1Decimal(this.lowTarget * Constants.MGDL_TO_MMOLL) else decimalFormatter.to1Decimal(this.lowTarget * Constants.MGDL_TO_MMOLL)
fun TemporaryTarget.highValueToUnitsToString(units: GlucoseUnit): String = fun TemporaryTarget.highValueToUnitsToString(units: GlucoseUnit, decimalFormatter: DecimalFormatter): String =
if (units == GlucoseUnit.MGDL) DecimalFormatter.to0Decimal(this.highTarget) if (units == GlucoseUnit.MGDL) decimalFormatter.to0Decimal(this.highTarget)
else DecimalFormatter.to1Decimal(this.highTarget * Constants.MGDL_TO_MMOLL) else decimalFormatter.to1Decimal(this.highTarget * Constants.MGDL_TO_MMOLL)
fun TemporaryTarget.target(): Double = fun TemporaryTarget.target(): Double =
(this.lowTarget + this.highTarget) / 2 (this.lowTarget + this.highTarget) / 2
fun TemporaryTarget.friendlyDescription(units: GlucoseUnit, rh: ResourceHelper): String = fun TemporaryTarget.friendlyDescription(units: GlucoseUnit, rh: ResourceHelper, profileUtil: ProfileUtil): String =
Profile.toTargetRangeString(lowTarget, highTarget, GlucoseUnit.MGDL, units) + profileUtil.toTargetRangeString(lowTarget, highTarget, GlucoseUnit.MGDL, units) +
units.asText + units.asText +
"@" + rh.gs(info.nightscout.core.ui.R.string.format_mins, TimeUnit.MILLISECONDS.toMinutes(duration)) + "(" + reason.text + ")" "@" + rh.gs(info.nightscout.core.ui.R.string.format_mins, TimeUnit.MILLISECONDS.toMinutes(duration)) + "(" + reason.text + ")"

View file

@ -4,20 +4,20 @@ import info.nightscout.interfaces.iob.CobInfo
import info.nightscout.interfaces.utils.DecimalFormatter import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.interfaces.ResourceHelper
fun CobInfo.generateCOBString(): String { fun CobInfo.generateCOBString(decimalFormatter: DecimalFormatter): String {
var cobStringResult = "--g" var cobStringResult = "--g"
displayCob?.let { displayCob -> displayCob?.let { displayCob ->
cobStringResult = DecimalFormatter.to0Decimal(displayCob) cobStringResult = decimalFormatter.to0Decimal(displayCob)
if (futureCarbs > 0) if (futureCarbs > 0)
cobStringResult += "(${DecimalFormatter.to0Decimal(futureCarbs)})" cobStringResult += "(${decimalFormatter.to0Decimal(futureCarbs)})"
cobStringResult += "g" cobStringResult += "g"
} }
return cobStringResult return cobStringResult
} }
fun CobInfo.displayText(rh: ResourceHelper): String? = fun CobInfo.displayText(rh: ResourceHelper, decimalFormatter: DecimalFormatter): String? =
displayCob?.let { displayCob -> displayCob?.let { displayCob ->
var cobText = rh.gs(info.nightscout.core.ui.R.string.format_carbs, displayCob.toInt()) var cobText = rh.gs(info.nightscout.core.ui.R.string.format_carbs, displayCob.toInt())
if (futureCarbs > 0) cobText += "(" + DecimalFormatter.to0Decimal(futureCarbs) + ")" if (futureCarbs > 0) cobText += "(" + decimalFormatter.to0Decimal(futureCarbs) + ")"
cobText cobText
} }

View file

@ -4,11 +4,11 @@ import info.nightscout.interfaces.iob.GlucoseStatus
import info.nightscout.interfaces.utils.DecimalFormatter import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.interfaces.utils.Round import info.nightscout.interfaces.utils.Round
fun GlucoseStatus.log(): String = "Glucose: " + DecimalFormatter.to0Decimal(glucose) + " mg/dl " + fun GlucoseStatus.log(decimalFormatter: DecimalFormatter): String = "Glucose: " + decimalFormatter.to0Decimal(glucose) + " mg/dl " +
"Noise: " + DecimalFormatter.to0Decimal(noise) + " " + "Noise: " + decimalFormatter.to0Decimal(noise) + " " +
"Delta: " + DecimalFormatter.to0Decimal(delta) + " mg/dl" + "Delta: " + decimalFormatter.to0Decimal(delta) + " mg/dl" +
"Short avg. delta: " + " " + DecimalFormatter.to2Decimal(shortAvgDelta) + " mg/dl " + "Short avg. delta: " + " " + decimalFormatter.to2Decimal(shortAvgDelta) + " mg/dl " +
"Long avg. delta: " + DecimalFormatter.to2Decimal(longAvgDelta) + " mg/dl" "Long avg. delta: " + decimalFormatter.to2Decimal(longAvgDelta) + " mg/dl"
fun GlucoseStatus.asRounded() = copy( fun GlucoseStatus.asRounded() = copy(
glucose = Round.roundTo(glucose, 0.1), glucose = Round.roundTo(glucose, 0.1),

View file

@ -156,14 +156,20 @@ sealed class ProfileSealed(
break break
} }
for (isf in isfBlocks) for (isf in isfBlocks)
if (!hardLimits.isInRange(Profile.toMgdl(isf.amount * 100.0 / percentage, units), HardLimits.MIN_ISF, HardLimits.MAX_ISF)) { if (!hardLimits.isInRange(toMgdl(isf.amount * 100.0 / percentage, units), HardLimits.MIN_ISF, HardLimits.MAX_ISF)) {
validityCheck.isValid = false validityCheck.isValid = false
validityCheck.reasons.add(rh.gs(info.nightscout.core.ui.R.string.value_out_of_hard_limits, rh.gs(info.nightscout.core.ui.R.string.profile_sensitivity_value), isf.amount * 100.0 / percentage)) validityCheck.reasons.add(
rh.gs(
info.nightscout.core.ui.R.string.value_out_of_hard_limits,
rh.gs(info.nightscout.core.ui.R.string.profile_sensitivity_value),
isf.amount * 100.0 / percentage
)
)
break break
} }
for (target in targetBlocks) { for (target in targetBlocks) {
if (!hardLimits.isInRange( if (!hardLimits.isInRange(
Profile.toMgdl(target.lowTarget, units), toMgdl(target.lowTarget, units),
HardLimits.VERY_HARD_LIMIT_MIN_BG[0], HardLimits.VERY_HARD_LIMIT_MIN_BG[0],
HardLimits.VERY_HARD_LIMIT_MIN_BG[1] HardLimits.VERY_HARD_LIMIT_MIN_BG[1]
) )
@ -173,7 +179,7 @@ sealed class ProfileSealed(
break break
} }
if (!hardLimits.isInRange( if (!hardLimits.isInRange(
Profile.toMgdl(target.highTarget, units), toMgdl(target.highTarget, units),
HardLimits.VERY_HARD_LIMIT_MAX_BG[0], HardLimits.VERY_HARD_LIMIT_MAX_BG[0],
HardLimits.VERY_HARD_LIMIT_MAX_BG[1] HardLimits.VERY_HARD_LIMIT_MAX_BG[1]
) )
@ -227,23 +233,25 @@ sealed class ProfileSealed(
override fun getBasal(timestamp: Long): Double = basalBlocks.blockValueBySeconds(MidnightUtils.secondsFromMidnight(timestamp), percentage / 100.0, timeshift) override fun getBasal(timestamp: Long): Double = basalBlocks.blockValueBySeconds(MidnightUtils.secondsFromMidnight(timestamp), percentage / 100.0, timeshift)
override fun getIc(): Double = icBlocks.blockValueBySeconds(MidnightUtils.secondsFromMidnight(), 100.0 / percentage, timeshift) override fun getIc(): Double = icBlocks.blockValueBySeconds(MidnightUtils.secondsFromMidnight(), 100.0 / percentage, timeshift)
override fun getIc(timestamp: Long): Double = icBlocks.blockValueBySeconds(MidnightUtils.secondsFromMidnight(timestamp), 100.0 / percentage, timeshift) override fun getIc(timestamp: Long): Double = icBlocks.blockValueBySeconds(MidnightUtils.secondsFromMidnight(timestamp), 100.0 / percentage, timeshift)
override fun getIsfMgdl(): Double = Profile.toMgdl(isfBlocks.blockValueBySeconds(MidnightUtils.secondsFromMidnight(), 100.0 / percentage, timeshift), units) override fun getIsfMgdl(): Double = toMgdl(isfBlocks.blockValueBySeconds(MidnightUtils.secondsFromMidnight(), 100.0 / percentage, timeshift), units)
override fun getIsfMgdl(timestamp: Long): Double = Profile.toMgdl(isfBlocks.blockValueBySeconds(MidnightUtils.secondsFromMidnight(timestamp), 100.0 / percentage, timeshift), units) override fun getIsfMgdl(timestamp: Long): Double = toMgdl(isfBlocks.blockValueBySeconds(MidnightUtils.secondsFromMidnight(timestamp), 100.0 / percentage, timeshift), units)
override fun getTargetMgdl(): Double = Profile.toMgdl(targetBlocks.targetBlockValueBySeconds(MidnightUtils.secondsFromMidnight(), timeshift), units) override fun getTargetMgdl(): Double = toMgdl(targetBlocks.targetBlockValueBySeconds(MidnightUtils.secondsFromMidnight(), timeshift), units)
override fun getTargetLowMgdl(): Double = Profile.toMgdl(targetBlocks.lowTargetBlockValueBySeconds(MidnightUtils.secondsFromMidnight(), timeshift), units) override fun getTargetLowMgdl(): Double = toMgdl(targetBlocks.lowTargetBlockValueBySeconds(MidnightUtils.secondsFromMidnight(), timeshift), units)
override fun getTargetLowMgdl(timestamp: Long): Double = Profile.toMgdl(targetBlocks.lowTargetBlockValueBySeconds(MidnightUtils.secondsFromMidnight(timestamp), timeshift), units) override fun getTargetLowMgdl(timestamp: Long): Double = toMgdl(targetBlocks.lowTargetBlockValueBySeconds(MidnightUtils.secondsFromMidnight(timestamp), timeshift), units)
override fun getTargetHighMgdl(): Double = Profile.toMgdl(targetBlocks.highTargetBlockValueBySeconds(MidnightUtils.secondsFromMidnight(), timeshift), units) override fun getTargetHighMgdl(): Double = toMgdl(targetBlocks.highTargetBlockValueBySeconds(MidnightUtils.secondsFromMidnight(), timeshift), units)
override fun getTargetHighMgdl(timestamp: Long): Double = Profile.toMgdl(targetBlocks.highTargetBlockValueBySeconds(MidnightUtils.secondsFromMidnight(timestamp), timeshift), units) override fun getTargetHighMgdl(timestamp: Long): Double = toMgdl(targetBlocks.highTargetBlockValueBySeconds(MidnightUtils.secondsFromMidnight(timestamp), timeshift), units)
override fun getBasalTimeFromMidnight(timeAsSeconds: Int): Double = basalBlocks.blockValueBySeconds(timeAsSeconds, percentage / 100.0, timeshift) override fun getBasalTimeFromMidnight(timeAsSeconds: Int): Double = basalBlocks.blockValueBySeconds(timeAsSeconds, percentage / 100.0, timeshift)
override fun getIcTimeFromMidnight(timeAsSeconds: Int): Double = icBlocks.blockValueBySeconds(timeAsSeconds, 100.0 / percentage, timeshift) override fun getIcTimeFromMidnight(timeAsSeconds: Int): Double = icBlocks.blockValueBySeconds(timeAsSeconds, 100.0 / percentage, timeshift)
fun getIsfTimeFromMidnight(timeAsSeconds: Int): Double = isfBlocks.blockValueBySeconds(timeAsSeconds, 100.0 / percentage, timeshift) fun getIsfTimeFromMidnight(timeAsSeconds: Int): Double = isfBlocks.blockValueBySeconds(timeAsSeconds, 100.0 / percentage, timeshift)
override fun getIsfMgdlTimeFromMidnight(timeAsSeconds: Int): Double = Profile.toMgdl(isfBlocks.blockValueBySeconds(timeAsSeconds, 100.0 / percentage, timeshift), units) override fun getIsfMgdlTimeFromMidnight(timeAsSeconds: Int): Double = toMgdl(isfBlocks.blockValueBySeconds(timeAsSeconds, 100.0 / percentage, timeshift), units)
override fun getTargetLowMgdlTimeFromMidnight(timeAsSeconds: Int): Double = Profile.toMgdl(targetBlocks.lowTargetBlockValueBySeconds(timeAsSeconds, timeshift), units) override fun getTargetLowMgdlTimeFromMidnight(timeAsSeconds: Int): Double = toMgdl(targetBlocks.lowTargetBlockValueBySeconds(timeAsSeconds, timeshift), units)
private fun getTargetLowTimeFromMidnight(timeAsSeconds: Int): Double = targetBlocks.lowTargetBlockValueBySeconds(timeAsSeconds, timeshift) private fun getTargetLowTimeFromMidnight(timeAsSeconds: Int): Double = targetBlocks.lowTargetBlockValueBySeconds(timeAsSeconds, timeshift)
private fun getTargetHighTimeFromMidnight(timeAsSeconds: Int): Double = targetBlocks.highTargetBlockValueBySeconds(timeAsSeconds, timeshift) private fun getTargetHighTimeFromMidnight(timeAsSeconds: Int): Double = targetBlocks.highTargetBlockValueBySeconds(timeAsSeconds, timeshift)
override fun getTargetHighMgdlTimeFromMidnight(timeAsSeconds: Int): Double = Profile.toMgdl(targetBlocks.highTargetBlockValueBySeconds(timeAsSeconds, timeshift), units) override fun getTargetHighMgdlTimeFromMidnight(timeAsSeconds: Int): Double = toMgdl(targetBlocks.highTargetBlockValueBySeconds(timeAsSeconds, timeshift), units)
override fun getIcList(rh: ResourceHelper, dateUtil: DateUtil): String =
getValuesList(icBlocks, 100.0 / percentage, DecimalFormat("0.0"), rh.gs(info.nightscout.core.ui.R.string.profile_carbs_per_unit), dateUtil)
override fun getIcList(rh: ResourceHelper, dateUtil: DateUtil): String = getValuesList(icBlocks, 100.0 / percentage, DecimalFormat("0.0"), rh.gs(info.nightscout.core.ui.R.string.profile_carbs_per_unit), dateUtil)
override fun getIsfList(rh: ResourceHelper, dateUtil: DateUtil): String = override fun getIsfList(rh: ResourceHelper, dateUtil: DateUtil): String =
getValuesList(isfBlocks, 100.0 / percentage, DecimalFormat("0.0"), units.asText + rh.gs(info.nightscout.core.ui.R.string.profile_per_unit), dateUtil) getValuesList(isfBlocks, 100.0 / percentage, DecimalFormat("0.0"), units.asText + rh.gs(info.nightscout.core.ui.R.string.profile_per_unit), dateUtil)
@ -355,7 +363,7 @@ sealed class ProfileSealed(
val ret = Array(shifted.size) { ProfileValue(0, 0.0) } val ret = Array(shifted.size) { ProfileValue(0, 0.0) }
var elapsed = 0 var elapsed = 0
for (index in shifted.indices) { for (index in shifted.indices) {
ret[index] = ProfileValue(elapsed, Profile.toMgdl(shifted[index].amount, units)) ret[index] = ProfileValue(elapsed, toMgdl(shifted[index].amount, units))
elapsed += T.msecs(shifted[index].duration).secs().toInt() elapsed += T.msecs(shifted[index].duration).secs().toInt()
} }
return ret return ret
@ -377,7 +385,7 @@ sealed class ProfileSealed(
val ret = Array(shifted.size) { ProfileValue(0, 0.0) } val ret = Array(shifted.size) { ProfileValue(0, 0.0) }
var elapsed = 0 var elapsed = 0
for (index in shifted.indices) { for (index in shifted.indices) {
ret[index] = ProfileValue(elapsed, Profile.toMgdl((shifted[index].lowTarget + shifted[index].highTarget) / 2.0, units)) ret[index] = ProfileValue(elapsed, toMgdl((shifted[index].lowTarget + shifted[index].highTarget) / 2.0, units))
elapsed += T.msecs(shifted[index].duration).secs().toInt() elapsed += T.msecs(shifted[index].duration).secs().toInt()
} }
return ret return ret
@ -414,4 +422,6 @@ sealed class ProfileSealed(
fun isInProgress(dateUtil: DateUtil): Boolean = fun isInProgress(dateUtil: DateUtil): Boolean =
dateUtil.now() in timestamp..timestamp + (duration ?: 0L) dateUtil.now() in timestamp..timestamp + (duration ?: 0L)
private fun toMgdl(value: Double, units: GlucoseUnit): Double =
if (units == GlucoseUnit.MGDL) value else value * GlucoseUnit.MMOLL_TO_MGDL
} }

View file

@ -4,7 +4,7 @@ import info.nightscout.interfaces.pump.PumpEnactResult
import info.nightscout.interfaces.utils.DecimalFormatter import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.interfaces.ResourceHelper
fun PumpEnactResult.toHtml(rh: ResourceHelper): String { fun PumpEnactResult.toHtml(rh: ResourceHelper, decimalFormatter: DecimalFormatter): String {
var ret = "<b>" + rh.gs(info.nightscout.core.ui.R.string.success) + "</b>: " + success var ret = "<b>" + rh.gs(info.nightscout.core.ui.R.string.success) + "</b>: " + success
if (queued) { if (queued) {
ret = rh.gs(info.nightscout.core.ui.R.string.waitingforpumpresult) ret = rh.gs(info.nightscout.core.ui.R.string.waitingforpumpresult)
@ -33,7 +33,7 @@ fun PumpEnactResult.toHtml(rh: ResourceHelper): String {
ret += "<br><b>" + rh.gs(info.nightscout.core.ui.R.string.enacted) + "</b>: " + enacted ret += "<br><b>" + rh.gs(info.nightscout.core.ui.R.string.enacted) + "</b>: " + enacted
if (comment.isNotEmpty()) ret += "<br><b>" + rh.gs(info.nightscout.core.ui.R.string.comment) + "</b>: " + comment if (comment.isNotEmpty()) ret += "<br><b>" + rh.gs(info.nightscout.core.ui.R.string.comment) + "</b>: " + comment
ret += "<br><b>" + rh.gs(info.nightscout.core.ui.R.string.duration) + "</b>: " + duration + " min" ret += "<br><b>" + rh.gs(info.nightscout.core.ui.R.string.duration) + "</b>: " + duration + " min"
ret += "<br><b>" + rh.gs(info.nightscout.core.ui.R.string.absolute) + "</b>: " + DecimalFormatter.to2Decimal(absolute) + " U/h" ret += "<br><b>" + rh.gs(info.nightscout.core.ui.R.string.absolute) + "</b>: " + decimalFormatter.to2Decimal(absolute) + " U/h"
} }
} }
} else { } else {

View file

@ -35,12 +35,14 @@ import info.nightscout.interfaces.pump.defs.PumpDescription
import info.nightscout.interfaces.queue.Callback import info.nightscout.interfaces.queue.Callback
import info.nightscout.interfaces.queue.CommandQueue import info.nightscout.interfaces.queue.CommandQueue
import info.nightscout.interfaces.ui.UiInteraction import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.interfaces.utils.HtmlHelper import info.nightscout.interfaces.utils.HtmlHelper
import info.nightscout.interfaces.utils.Round import info.nightscout.interfaces.utils.Round
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventRefreshOverview import info.nightscout.rx.events.EventRefreshOverview
import info.nightscout.rx.logging.AAPSLogger import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag import info.nightscout.rx.logging.LTag
import info.nightscout.shared.interfaces.ProfileUtil
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 info.nightscout.shared.utils.DateUtil import info.nightscout.shared.utils.DateUtil
@ -60,6 +62,7 @@ class BolusWizard @Inject constructor(
@Inject lateinit var rxBus: RxBus @Inject lateinit var rxBus: RxBus
@Inject lateinit var sp: SP @Inject lateinit var sp: SP
@Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var profileUtil: ProfileUtil
@Inject lateinit var constraintChecker: Constraints @Inject lateinit var constraintChecker: Constraints
@Inject lateinit var activePlugin: ActivePlugin @Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var commandQueue: CommandQueue @Inject lateinit var commandQueue: CommandQueue
@ -72,16 +75,15 @@ class BolusWizard @Inject constructor(
@Inject lateinit var glucoseStatusProvider: GlucoseStatusProvider @Inject lateinit var glucoseStatusProvider: GlucoseStatusProvider
@Inject lateinit var uiInteraction: UiInteraction @Inject lateinit var uiInteraction: UiInteraction
@Inject lateinit var persistenceLayer: PersistenceLayer @Inject lateinit var persistenceLayer: PersistenceLayer
@Inject lateinit var decimalFormatter: DecimalFormatter
var timeStamp: Long
var timeStamp : Long
init { init {
injector.androidInjector().inject(this) injector.androidInjector().inject(this)
timeStamp = dateUtil.now() timeStamp = dateUtil.now()
} }
// Intermediate // Intermediate
var sens = 0.0 var sens = 0.0
private set private set
@ -197,12 +199,12 @@ class BolusWizard @Inject constructor(
this.totalPercentage = totalPercentage this.totalPercentage = totalPercentage
// Insulin from BG // Insulin from BG
sens = Profile.fromMgdlToUnits(profile.getIsfMgdl(), profileFunction.getUnits()) sens = profileUtil.fromMgdlToUnits(profile.getIsfMgdl())
targetBGLow = Profile.fromMgdlToUnits(profile.getTargetLowMgdl(), profileFunction.getUnits()) targetBGLow = profileUtil.fromMgdlToUnits(profile.getTargetLowMgdl())
targetBGHigh = Profile.fromMgdlToUnits(profile.getTargetHighMgdl(), profileFunction.getUnits()) targetBGHigh = profileUtil.fromMgdlToUnits(profile.getTargetHighMgdl())
if (useTT && tempTarget != null) { if (useTT && tempTarget != null) {
targetBGLow = Profile.fromMgdlToUnits(tempTarget.lowTarget, profileFunction.getUnits()) targetBGLow = profileUtil.fromMgdlToUnits(tempTarget.lowTarget)
targetBGHigh = Profile.fromMgdlToUnits(tempTarget.highTarget, profileFunction.getUnits()) targetBGHigh = profileUtil.fromMgdlToUnits(tempTarget.highTarget)
} }
if (useBg && bg > 0) { if (useBg && bg > 0) {
bgDiff = when { bgDiff = when {
@ -218,7 +220,7 @@ class BolusWizard @Inject constructor(
glucoseStatus?.let { glucoseStatus?.let {
if (useTrend) { if (useTrend) {
trend = it.shortAvgDelta trend = it.shortAvgDelta
insulinFromTrend = Profile.fromMgdlToUnits(trend, profileFunction.getUnits()) * 3 / sens insulinFromTrend = profileUtil.fromMgdlToUnits(trend) * 3 / sens
} }
} }
@ -281,19 +283,19 @@ class BolusWizard @Inject constructor(
val unit = profileFunction.getUnits() val unit = profileFunction.getUnits()
return BolusCalculatorResult( return BolusCalculatorResult(
timestamp = dateUtil.now(), timestamp = dateUtil.now(),
targetBGLow = Profile.toMgdl(targetBGLow, unit), targetBGLow = profileUtil.convertToMgdl(targetBGLow, unit),
targetBGHigh = Profile.toMgdl(targetBGHigh, unit), targetBGHigh = profileUtil.convertToMgdl(targetBGHigh, unit),
isf = Profile.toMgdl(sens, unit), isf = profileUtil.convertToMgdl(sens, unit),
ic = ic, ic = ic,
bolusIOB = insulinFromBolusIOB, bolusIOB = insulinFromBolusIOB,
wasBolusIOBUsed = includeBolusIOB, wasBolusIOBUsed = includeBolusIOB,
basalIOB = insulinFromBasalIOB, basalIOB = insulinFromBasalIOB,
wasBasalIOBUsed = includeBasalIOB, wasBasalIOBUsed = includeBasalIOB,
glucoseValue = Profile.toMgdl(bg, unit), glucoseValue = profileUtil.convertToMgdl(bg, unit),
wasGlucoseUsed = useBg && bg > 0, wasGlucoseUsed = useBg && bg > 0,
glucoseDifference = bgDiff, glucoseDifference = bgDiff,
glucoseInsulin = insulinFromBG, glucoseInsulin = insulinFromBG,
glucoseTrend = Profile.fromMgdlToUnits(trend, unit), glucoseTrend = profileUtil.fromMgdlToUnits(trend, unit),
wasTrendUsed = useTrend, wasTrendUsed = useTrend,
trendInsulin = insulinFromTrend, trendInsulin = insulinFromTrend,
cob = cob, cob = cob,
@ -318,8 +320,10 @@ class BolusWizard @Inject constructor(
val actions: LinkedList<String> = LinkedList() val actions: LinkedList<String> = LinkedList()
if (insulinAfterConstraints > 0) { if (insulinAfterConstraints > 0) {
val pct = if (percentageCorrection != 100) " ($percentageCorrection%)" else "" val pct = if (percentageCorrection != 100) " ($percentageCorrection%)" else ""
actions.add(rh.gs(info.nightscout.core.ui.R.string.bolus) + ": " + rh.gs(info.nightscout.interfaces.R.string.format_insulin_units, insulinAfterConstraints).formatColor actions.add(
(context, rh, info.nightscout.core.ui.R.attr.bolusColor) + pct) rh.gs(info.nightscout.core.ui.R.string.bolus) + ": " + rh.gs(info.nightscout.interfaces.R.string.format_insulin_units, insulinAfterConstraints).formatColor
(context, rh, info.nightscout.core.ui.R.attr.bolusColor) + pct
)
} }
if (carbs > 0 && !advisor) { if (carbs > 0 && !advisor) {
var timeShift = "" var timeShift = ""
@ -328,19 +332,30 @@ class BolusWizard @Inject constructor(
} else if (carbTime < 0) { } else if (carbTime < 0) {
timeShift += " (" + rh.gs(info.nightscout.core.ui.R.string.mins, carbTime) + ")" timeShift += " (" + rh.gs(info.nightscout.core.ui.R.string.mins, carbTime) + ")"
} }
actions.add(rh.gs(info.nightscout.core.ui.R.string.carbs) + ": " + rh.gs(info.nightscout.core.ui.R.string.format_carbs, carbs).formatColor(context, rh, info.nightscout.core.ui.R.attr.carbsColor) + timeShift) actions.add(
rh.gs(info.nightscout.core.ui.R.string.carbs) + ": " + rh.gs(info.nightscout.core.ui.R.string.format_carbs, carbs)
.formatColor(context, rh, info.nightscout.core.ui.R.attr.carbsColor) + timeShift
)
} }
if (insulinFromCOB > 0) { if (insulinFromCOB > 0) {
actions.add( actions.add(
rh.gs(info.nightscout.core.ui.R.string.cobvsiob) + ": " + rh.gs(info.nightscout.core.ui.R.string.formatsignedinsulinunits, insulinFromBolusIOB + insulinFromBasalIOB + insulinFromCOB + insulinFromBG).formatColor(context, rh, info.nightscout.core.ui.R.attr rh.gs(info.nightscout.core.ui.R.string.cobvsiob) + ": " + rh.gs(
.cobAlertColor) info.nightscout.core.ui.R.string.formatsignedinsulinunits,
insulinFromBolusIOB + insulinFromBasalIOB + insulinFromCOB + insulinFromBG
).formatColor(
context, rh, info.nightscout.core.ui.R.attr
.cobAlertColor
)
) )
val absorptionRate = iobCobCalculator.ads.slowAbsorptionPercentage(60) val absorptionRate = iobCobCalculator.ads.slowAbsorptionPercentage(60)
if (absorptionRate > .25) if (absorptionRate > .25)
actions.add(rh.gs(info.nightscout.core.ui.R.string.slowabsorptiondetected, rh.gac(context, info.nightscout.core.ui.R.attr.cobAlertColor), (absorptionRate * 100).toInt())) actions.add(rh.gs(info.nightscout.core.ui.R.string.slowabsorptiondetected, rh.gac(context, info.nightscout.core.ui.R.attr.cobAlertColor), (absorptionRate * 100).toInt()))
} }
if (abs(insulinAfterConstraints - calculatedTotalInsulin) > activePlugin.activePump.pumpDescription.pumpType.determineCorrectBolusStepSize(insulinAfterConstraints)) if (abs(insulinAfterConstraints - calculatedTotalInsulin) > activePlugin.activePump.pumpDescription.pumpType.determineCorrectBolusStepSize(insulinAfterConstraints))
actions.add(rh.gs(info.nightscout.core.ui.R.string.bolus_constraint_applied_warn, calculatedTotalInsulin, insulinAfterConstraints).formatColor(context, rh, info.nightscout.core.ui.R.attr.warningColor)) actions.add(
rh.gs(info.nightscout.core.ui.R.string.bolus_constraint_applied_warn, calculatedTotalInsulin, insulinAfterConstraints)
.formatColor(context, rh, info.nightscout.core.ui.R.attr.warningColor)
)
if (config.NSCLIENT && insulinAfterConstraints > 0) if (config.NSCLIENT && insulinAfterConstraints > 0)
actions.add(rh.gs(info.nightscout.core.ui.R.string.bolus_recorded_only).formatColor(context, rh, info.nightscout.core.ui.R.attr.warningColor)) actions.add(rh.gs(info.nightscout.core.ui.R.string.bolus_recorded_only).formatColor(context, rh, info.nightscout.core.ui.R.attr.warningColor))
if (useAlarm && !advisor && carbs > 0 && carbTime > 0) if (useAlarm && !advisor && carbs > 0 && carbTime > 0)
@ -362,10 +377,10 @@ class BolusWizard @Inject constructor(
automation.removeAutomationEventBolusReminder() automation.removeAutomationEventBolusReminder()
if (carbs > 0.0) if (carbs > 0.0)
automation.removeAutomationEventEatReminder() automation.removeAutomationEventEatReminder()
if (sp.getBoolean(info.nightscout.core.ui.R.string.key_usebolusadvisor, false) && Profile.toMgdl(bg, profile.units) > 180 && carbs > 0 && carbTime >= 0) if (sp.getBoolean(info.nightscout.core.ui.R.string.key_usebolusadvisor, false) && profileUtil.convertToMgdl(bg, profile.units) > 180 && carbs > 0 && carbTime >= 0)
OKDialog.showYesNoCancel(ctx, rh.gs(info.nightscout.core.ui.R.string.bolus_advisor), rh.gs(info.nightscout.core.ui.R.string.bolus_advisor_message), OKDialog.showYesNoCancel(ctx, rh.gs(info.nightscout.core.ui.R.string.bolus_advisor), rh.gs(info.nightscout.core.ui.R.string.bolus_advisor_message),
{ bolusAdvisorProcessing(ctx) }, { bolusAdvisorProcessing(ctx) },
{ commonProcessing(ctx) } { commonProcessing(ctx) }
) )
else else
commonProcessing(ctx) commonProcessing(ctx)
@ -382,7 +397,7 @@ class BolusWizard @Inject constructor(
insulin = insulinAfterConstraints insulin = insulinAfterConstraints
carbs = 0.0 carbs = 0.0
context = ctx context = ctx
mgdlGlucose = Profile.toMgdl(bg, profile.units) mgdlGlucose = profileUtil.convertToMgdl(bg, profile.units)
glucoseType = DetailedBolusInfo.MeterType.MANUAL glucoseType = DetailedBolusInfo.MeterType.MANUAL
carbTime = 0 carbTime = 0
bolusCalculatorResult = createBolusCalculatorResult() bolusCalculatorResult = createBolusCalculatorResult()
@ -412,8 +427,12 @@ class BolusWizard @Inject constructor(
var message = rh.gs(info.nightscout.core.ui.R.string.wizard_explain_calc, ic, sens) var message = rh.gs(info.nightscout.core.ui.R.string.wizard_explain_calc, ic, sens)
message += "\n" + rh.gs(info.nightscout.core.ui.R.string.wizard_explain_carbs, insulinFromCarbs) message += "\n" + rh.gs(info.nightscout.core.ui.R.string.wizard_explain_carbs, insulinFromCarbs)
if (useTT && tempTarget != null) { if (useTT && tempTarget != null) {
val tt = if (tempTarget?.lowTarget == tempTarget?.highTarget) tempTarget?.lowValueToUnitsToString(profile.units) val tt = if (tempTarget?.lowTarget == tempTarget?.highTarget) tempTarget?.lowValueToUnitsToString(profile.units, decimalFormatter)
else rh.gs(info.nightscout.core.ui.R.string.wizard_explain_tt_to, tempTarget?.lowValueToUnitsToString(profile.units), tempTarget?.highValueToUnitsToString(profile.units)) else rh.gs(
info.nightscout.core.ui.R.string.wizard_explain_tt_to,
tempTarget?.lowValueToUnitsToString(profile.units, decimalFormatter),
tempTarget?.highValueToUnitsToString(profile.units, decimalFormatter)
)
message += "\n" + rh.gs(info.nightscout.core.ui.R.string.wizard_explain_tt, tt) message += "\n" + rh.gs(info.nightscout.core.ui.R.string.wizard_explain_tt, tt)
} }
if (useCob) message += "\n" + rh.gs(info.nightscout.core.ui.R.string.wizard_explain_cob, cob, insulinFromCOB) if (useCob) message += "\n" + rh.gs(info.nightscout.core.ui.R.string.wizard_explain_cob, cob, insulinFromCOB)
@ -464,16 +483,16 @@ class BolusWizard @Inject constructor(
insulin = insulinAfterConstraints insulin = insulinAfterConstraints
carbs = this@BolusWizard.carbs.toDouble() carbs = this@BolusWizard.carbs.toDouble()
context = ctx context = ctx
mgdlGlucose = Profile.toMgdl(bg, profile.units) mgdlGlucose = profileUtil.convertToMgdl(bg, profile.units)
glucoseType = DetailedBolusInfo.MeterType.MANUAL glucoseType = DetailedBolusInfo.MeterType.MANUAL
carbsTimestamp = dateUtil.now() + T.mins(this@BolusWizard.carbTime.toLong()).msecs() carbsTimestamp = dateUtil.now() + T.mins(this@BolusWizard.carbTime.toLong()).msecs()
bolusCalculatorResult = createBolusCalculatorResult() bolusCalculatorResult = createBolusCalculatorResult()
notes = this@BolusWizard.notes notes = this@BolusWizard.notes
if (insulin > 0 || carbs > 0) { if (insulin > 0 || carbs > 0) {
val action = when { val action = when {
insulinAfterConstraints.equals(0.0) -> Action.CARBS insulinAfterConstraints == 0.0 -> Action.CARBS
carbs.equals(0.0) -> Action.BOLUS carbs == 0.0 -> Action.BOLUS
else -> Action.TREATMENT else -> Action.TREATMENT
} }
uel.log(action, if (quickWizard) Sources.QuickWizard else Sources.WizardDialog, uel.log(action, if (quickWizard) Sources.QuickWizard else Sources.WizardDialog,
notes, notes,

View file

@ -5,9 +5,7 @@ import dagger.android.AndroidInjector
import info.nightscout.core.extensions.pureProfileFromJson import info.nightscout.core.extensions.pureProfileFromJson
import info.nightscout.core.profile.ProfileSealed import info.nightscout.core.profile.ProfileSealed
import info.nightscout.interfaces.Config import info.nightscout.interfaces.Config
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.utils.HardLimits import info.nightscout.interfaces.utils.HardLimits
import info.nightscout.rx.TestAapsSchedulers import info.nightscout.rx.TestAapsSchedulers
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
@ -115,18 +113,6 @@ class ProfileTest : TestBase() {
Assertions.assertEquals("00:00 5,0 - 5,0 mmol", p.getTargetList(rh, dateUtil).replace(".", ",")) Assertions.assertEquals("00:00 5,0 - 5,0 mmol", p.getTargetList(rh, dateUtil).replace(".", ","))
Assertions.assertEquals(100, p.percentage) Assertions.assertEquals(100, p.percentage)
Assertions.assertEquals(0, p.timeshift) Assertions.assertEquals(0, p.timeshift)
Assertions.assertEquals(0.1, Profile.toMgdl(0.1, GlucoseUnit.MGDL), 0.01)
Assertions.assertEquals(18.0, Profile.toMgdl(1.0, GlucoseUnit.MMOL), 0.01)
Assertions.assertEquals(1.0, Profile.toMmol(18.0, GlucoseUnit.MGDL), 0.01)
Assertions.assertEquals(18.0, Profile.toMmol(18.0, GlucoseUnit.MMOL), 0.01)
Assertions.assertEquals(18.0, Profile.fromMgdlToUnits(18.0, GlucoseUnit.MGDL), 0.01)
Assertions.assertEquals(1.0, Profile.fromMgdlToUnits(18.0, GlucoseUnit.MMOL), 0.01)
Assertions.assertEquals(18.0, Profile.toUnits(18.0, 1.0, GlucoseUnit.MGDL), 0.01)
Assertions.assertEquals(1.0, Profile.toUnits(18.0, 1.0, GlucoseUnit.MMOL), 0.01)
Assertions.assertEquals("18", Profile.toUnitsString(18.0, 1.0, GlucoseUnit.MGDL))
Assertions.assertEquals("1,0", Profile.toUnitsString(18.0, 1.0, GlucoseUnit.MMOL).replace(".", ","))
Assertions.assertEquals("5 - 6", Profile.toTargetRangeString(5.0, 6.0, GlucoseUnit.MGDL, GlucoseUnit.MGDL))
Assertions.assertEquals("4", Profile.toTargetRangeString(4.0, 4.0, GlucoseUnit.MGDL, GlucoseUnit.MGDL))
//Test basal profile below limit //Test basal profile below limit
p = ProfileSealed.Pure(pureProfileFromJson(JSONObject(belowLimitValidProfile), dateUtil)!!) p = ProfileSealed.Pure(pureProfileFromJson(JSONObject(belowLimitValidProfile), dateUtil)!!)

View file

@ -1,28 +0,0 @@
package info.nightscout.core.utils
import info.nightscout.interfaces.utils.DecimalFormatter
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
class DecimalFormatterTest {
@Test fun to0DecimalTest() {
Assertions.assertEquals("1", DecimalFormatter.to0Decimal(1.33).replace(",", "."))
Assertions.assertEquals("1U", DecimalFormatter.to0Decimal(1.33, "U").replace(",", "."))
}
@Test fun to1DecimalTest() {
Assertions.assertEquals("1.3", DecimalFormatter.to1Decimal(1.33).replace(",", "."))
Assertions.assertEquals("1.3U", DecimalFormatter.to1Decimal(1.33, "U").replace(",", "."))
}
@Test fun to2DecimalTest() {
Assertions.assertEquals("1.33", DecimalFormatter.to2Decimal(1.3333).replace(",", "."))
Assertions.assertEquals("1.33U", DecimalFormatter.to2Decimal(1.3333, "U").replace(",", "."))
}
@Test fun to3DecimalTest() {
Assertions.assertEquals("1.333", DecimalFormatter.to3Decimal(1.3333).replace(",", "."))
Assertions.assertEquals("1.333U", DecimalFormatter.to3Decimal(1.3333, "U").replace(",", "."))
}
}

View file

@ -17,6 +17,5 @@ android {
dependencies { dependencies {
implementation project(':app-wear-shared:shared') implementation project(':app-wear-shared:shared')
implementation project(':core:interfaces')
api "com.google.android.material:material:$material_version" api "com.google.android.material:material:$material_version"
} }

View file

@ -34,8 +34,7 @@ import info.nightscout.core.validators.validators.PinStrengthValidator
import info.nightscout.core.validators.validators.RegexpValidator import info.nightscout.core.validators.validators.RegexpValidator
import info.nightscout.core.validators.validators.Validator import info.nightscout.core.validators.validators.Validator
import info.nightscout.core.validators.validators.WebUrlValidator import info.nightscout.core.validators.validators.WebUrlValidator
import info.nightscout.interfaces.profile.Profile import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.interfaces.profile.ProfileFunction
import javax.inject.Inject import javax.inject.Inject
@Suppress("SpellCheckingInspection") @Suppress("SpellCheckingInspection")
@ -61,7 +60,7 @@ class DefaultEditTextValidator : EditTextValidator {
private var floatminNumber = 0f private var floatminNumber = 0f
private var floatmaxNumber = 0f private var floatmaxNumber = 0f
@Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var profileUtil: ProfileUtil
@Suppress("unused") @Suppress("unused")
constructor(editTextView: EditText, context: Context) { constructor(editTextView: EditText, context: Context) {
@ -98,7 +97,6 @@ class DefaultEditTextValidator : EditTextValidator {
} }
private fun setEditText(editText: EditText) { private fun setEditText(editText: EditText) {
//editTextView?.removeTextChangedListener(textWatcher)
editTextView = editText editTextView = editText
editText.addTextChangedListener(getTextWatcher()) editText.addTextChangedListener(getTextWatcher())
} }
@ -110,7 +108,9 @@ class DefaultEditTextValidator : EditTextValidator {
testValidity() testValidity()
} }
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {} override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) { /* not needed */
}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
if (!TextUtils.isEmpty(s) && isErrorShown) { if (!TextUtils.isEmpty(s) && isErrorShown) {
try { try {
@ -156,9 +156,12 @@ class DefaultEditTextValidator : EditTextValidator {
EditTextValidator.TEST_PERSONNAME -> PersonNameValidator(if (TextUtils.isEmpty(testErrorString)) context.getString(R.string.error_notvalid_personname) else testErrorString) EditTextValidator.TEST_PERSONNAME -> PersonNameValidator(if (TextUtils.isEmpty(testErrorString)) context.getString(R.string.error_notvalid_personname) else testErrorString)
EditTextValidator.TEST_PERSONFULLNAME -> PersonFullNameValidator(if (TextUtils.isEmpty(testErrorString)) context.getString(R.string.error_notvalid_personfullname) else testErrorString) EditTextValidator.TEST_PERSONFULLNAME -> PersonFullNameValidator(if (TextUtils.isEmpty(testErrorString)) context.getString(R.string.error_notvalid_personfullname) else testErrorString)
EditTextValidator.TEST_MIN_LENGTH -> MinDigitLengthValidator(if (TextUtils.isEmpty(testErrorString)) context.getString(R.string.error_not_a_minimum_length) else testErrorString, minLength) EditTextValidator.TEST_MIN_LENGTH -> MinDigitLengthValidator(if (TextUtils.isEmpty(testErrorString)) context.getString(R.string.error_not_a_minimum_length) else testErrorString, minLength)
EditTextValidator.TEST_BG_RANGE -> BgRangeValidator(if (TextUtils.isEmpty(testErrorString)) context.getString(R.string.error_only_numeric_digits_range_allowed, EditTextValidator.TEST_BG_RANGE -> BgRangeValidator(
Profile.fromMgdlToUnits(minMgdl.toDouble(), profileFunction.getUnits()).toString(), Profile.fromMgdlToUnits(maxMgdl.toDouble(), profileFunction.getUnits()).toString()) else if (TextUtils.isEmpty(testErrorString)) context.getString(
testErrorString, minMgdl, maxMgdl, profileFunction) R.string.error_only_numeric_digits_range_allowed,
profileUtil.fromMgdlToUnits(minMgdl.toDouble()).toString(), profileUtil.fromMgdlToUnits(maxMgdl.toDouble()).toString()
) else testErrorString, minMgdl, maxMgdl, profileUtil
)
EditTextValidator.TEST_CUSTOM -> { EditTextValidator.TEST_CUSTOM -> {
// must specify the fully qualified class name & an error message // must specify the fully qualified class name & an error message

View file

@ -5,9 +5,8 @@ import android.util.AttributeSet
import androidx.preference.EditTextPreference import androidx.preference.EditTextPreference
import androidx.preference.PreferenceViewHolder import androidx.preference.PreferenceViewHolder
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.shared.SafeParse import info.nightscout.shared.SafeParse
import info.nightscout.shared.interfaces.ProfileUtil
import javax.inject.Inject import javax.inject.Inject
class ValidatingEditTextPreference(ctx: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : EditTextPreference(ctx, attrs, defStyleAttr, defStyleRes) { class ValidatingEditTextPreference(ctx: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : EditTextPreference(ctx, attrs, defStyleAttr, defStyleRes) {
@ -15,7 +14,7 @@ class ValidatingEditTextPreference(ctx: Context, attrs: AttributeSet, defStyleAt
private val validatorParameters: DefaultEditTextValidator.Parameters = obtainValidatorParameters(attrs) private val validatorParameters: DefaultEditTextValidator.Parameters = obtainValidatorParameters(attrs)
private var validator: DefaultEditTextValidator? = null private var validator: DefaultEditTextValidator? = null
@Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var profileUtil: ProfileUtil
init { init {
(ctx.applicationContext as HasAndroidInjector).androidInjector().inject(this) (ctx.applicationContext as HasAndroidInjector).androidInjector().inject(this)
@ -75,14 +74,14 @@ class ValidatingEditTextPreference(ctx: Context, attrs: AttributeSet, defStyleAt
override fun onSetInitialValue(defaultValue: Any?) { override fun onSetInitialValue(defaultValue: Any?) {
text = text =
if (validatorParameters.testType == EditTextValidator.TEST_BG_RANGE) if (validatorParameters.testType == EditTextValidator.TEST_BG_RANGE)
Profile.fromMgdlToUnits(SafeParse.stringToDouble(getPersistedString(defaultValue as String?)), profileFunction.getUnits()).toString() profileUtil.fromMgdlToUnits(SafeParse.stringToDouble(getPersistedString(defaultValue as String?)), profileUtil.units).toString()
else else
getPersistedString(defaultValue as String?) getPersistedString(defaultValue as String?)
} }
override fun persistString(value: String?): Boolean = override fun persistString(value: String?): Boolean =
when (validatorParameters.testType) { when (validatorParameters.testType) {
EditTextValidator.TEST_BG_RANGE -> super.persistString(Profile.toMgdl(SafeParse.stringToDouble(value, 0.0), profileFunction.getUnits()).toString()) EditTextValidator.TEST_BG_RANGE -> super.persistString(profileUtil.convertToMgdl(SafeParse.stringToDouble(value, 0.0), profileUtil.units).toString())
EditTextValidator.TEST_FLOAT_NUMERIC_RANGE -> super.persistString(SafeParse.stringToDouble(value, 0.0).toString()) EditTextValidator.TEST_FLOAT_NUMERIC_RANGE -> super.persistString(SafeParse.stringToDouble(value, 0.0).toString())
else -> super.persistString(value) else -> super.persistString(value)
} }

View file

@ -1,15 +1,14 @@
package info.nightscout.core.validators.validators package info.nightscout.core.validators.validators
import android.widget.EditText import android.widget.EditText
import info.nightscout.interfaces.profile.Profile import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.interfaces.profile.ProfileFunction
class BgRangeValidator(_customErrorMessage: String?, private val min: Int, private val max: Int, private val profileFunction: ProfileFunction) : Validator(_customErrorMessage) { class BgRangeValidator(customErrorMessage: String?, private val min: Int, private val max: Int, private val profileUtil: ProfileUtil) : Validator(customErrorMessage) {
override fun isValid(editText: EditText): Boolean { override fun isValid(editText: EditText): Boolean {
return try { return try {
val value = editText.text.toString().toDouble() val value = editText.text.toString().toDouble()
value in Profile.fromMgdlToUnits(min.toDouble(), profileFunction.getUnits())..Profile.fromMgdlToUnits(max.toDouble(), profileFunction.getUnits()) value in profileUtil.fromMgdlToUnits(min.toDouble())..profileUtil.fromMgdlToUnits(max.toDouble())
} catch (e: NumberFormatException) { } catch (e: NumberFormatException) {
false false
} }

View file

@ -4,8 +4,7 @@ import info.nightscout.annotations.OpenForTesting
import info.nightscout.interfaces.Constants import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.GlucoseUnit import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.profile.DefaultValueHelper import info.nightscout.interfaces.profile.DefaultValueHelper
import info.nightscout.interfaces.profile.Profile import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
@ -14,7 +13,7 @@ import javax.inject.Singleton
@Singleton @Singleton
class DefaultValueHelperImpl @Inject constructor( class DefaultValueHelperImpl @Inject constructor(
private val sp: SP, private val sp: SP,
private val profileFunction: ProfileFunction private val profileUtil: ProfileUtil
) : DefaultValueHelper { ) : DefaultValueHelper {
/** /**
@ -53,9 +52,9 @@ class DefaultValueHelperImpl @Inject constructor(
* @return * @return
*/ */
override fun determineEatingSoonTT(): Double { override fun determineEatingSoonTT(): Double {
val units = profileFunction.getUnits() val units = profileUtil.units
var value = sp.getDouble(info.nightscout.core.utils.R.string.key_eatingsoon_target, getDefaultEatingSoonTT(units)) var value = sp.getDouble(info.nightscout.core.utils.R.string.key_eatingsoon_target, getDefaultEatingSoonTT(units))
value = Profile.toCurrentUnits(profileFunction, value) value = profileUtil.valueInCurrentUnitsDetect(value)
return if (value > 0) value else getDefaultEatingSoonTT(units) return if (value > 0) value else getDefaultEatingSoonTT(units)
} }
@ -70,9 +69,9 @@ class DefaultValueHelperImpl @Inject constructor(
* @return * @return
*/ */
override fun determineActivityTT(): Double { override fun determineActivityTT(): Double {
val units = profileFunction.getUnits() val units = profileUtil.units
var value = sp.getDouble(info.nightscout.core.utils.R.string.key_activity_target, getDefaultActivityTT(units)) var value = sp.getDouble(info.nightscout.core.utils.R.string.key_activity_target, getDefaultActivityTT(units))
value = Profile.toCurrentUnits(profileFunction, value) value = profileUtil.valueInCurrentUnitsDetect(value)
return if (value > 0) value else getDefaultActivityTT(units) return if (value > 0) value else getDefaultActivityTT(units)
} }
@ -87,9 +86,9 @@ class DefaultValueHelperImpl @Inject constructor(
* @return * @return
*/ */
override fun determineHypoTT(): Double { override fun determineHypoTT(): Double {
val units = profileFunction.getUnits() val units = profileUtil.units
var value = sp.getDouble(info.nightscout.core.utils.R.string.key_hypo_target, getDefaultHypoTT(units)) var value = sp.getDouble(info.nightscout.core.utils.R.string.key_hypo_target, getDefaultHypoTT(units))
value = Profile.toCurrentUnits(profileFunction, value) value = profileUtil.valueInCurrentUnitsDetect(value)
return if (value > 0) value else getDefaultHypoTT(units) return if (value > 0) value else getDefaultHypoTT(units)
} }
@ -104,14 +103,14 @@ class DefaultValueHelperImpl @Inject constructor(
override fun determineHighLine(): Double { override fun determineHighLine(): Double {
var highLineSetting = sp.getDouble(info.nightscout.core.utils.R.string.key_high_mark, bgTargetHigh) var highLineSetting = sp.getDouble(info.nightscout.core.utils.R.string.key_high_mark, bgTargetHigh)
if (highLineSetting < 1) highLineSetting = Constants.HIGH_MARK if (highLineSetting < 1) highLineSetting = Constants.HIGH_MARK
highLineSetting = Profile.toCurrentUnits(profileFunction, highLineSetting) highLineSetting = profileUtil.valueInCurrentUnitsDetect(highLineSetting)
return highLineSetting return highLineSetting
} }
override fun determineLowLine(): Double { override fun determineLowLine(): Double {
var lowLineSetting = sp.getDouble(info.nightscout.core.utils.R.string.key_low_mark, bgTargetLow) var lowLineSetting = sp.getDouble(info.nightscout.core.utils.R.string.key_low_mark, bgTargetLow)
if (lowLineSetting < 1) lowLineSetting = Constants.LOW_MARK if (lowLineSetting < 1) lowLineSetting = Constants.LOW_MARK
lowLineSetting = Profile.toCurrentUnits(profileFunction, lowLineSetting) lowLineSetting = profileUtil.valueInCurrentUnitsDetect(lowLineSetting)
return lowLineSetting return lowLineSetting
} }
} }

View file

@ -18,6 +18,7 @@ import info.nightscout.implementation.overview.OverviewDataImpl
import info.nightscout.implementation.plugin.PluginStore import info.nightscout.implementation.plugin.PluginStore
import info.nightscout.implementation.profile.ProfileFunctionImpl import info.nightscout.implementation.profile.ProfileFunctionImpl
import info.nightscout.implementation.profile.ProfileStoreObject import info.nightscout.implementation.profile.ProfileStoreObject
import info.nightscout.implementation.profile.ProfileUtilImpl
import info.nightscout.implementation.profiling.ProfilerImpl import info.nightscout.implementation.profiling.ProfilerImpl
import info.nightscout.implementation.protection.PasswordCheckImpl import info.nightscout.implementation.protection.PasswordCheckImpl
import info.nightscout.implementation.protection.ProtectionCheckImpl import info.nightscout.implementation.protection.ProtectionCheckImpl
@ -36,6 +37,7 @@ import info.nightscout.implementation.stats.TddCalculatorImpl
import info.nightscout.implementation.stats.TirCalculatorImpl import info.nightscout.implementation.stats.TirCalculatorImpl
import info.nightscout.implementation.storage.FileStorage import info.nightscout.implementation.storage.FileStorage
import info.nightscout.implementation.userEntry.UserEntryPresentationHelperImpl import info.nightscout.implementation.userEntry.UserEntryPresentationHelperImpl
import info.nightscout.implementation.utils.DecimalFormatterImpl
import info.nightscout.interfaces.LocalAlertUtils import info.nightscout.interfaces.LocalAlertUtils
import info.nightscout.interfaces.NotificationHolder import info.nightscout.interfaces.NotificationHolder
import info.nightscout.interfaces.Translator import info.nightscout.interfaces.Translator
@ -62,8 +64,10 @@ import info.nightscout.interfaces.stats.TirCalculator
import info.nightscout.interfaces.storage.Storage import info.nightscout.interfaces.storage.Storage
import info.nightscout.interfaces.ui.IconsProvider import info.nightscout.interfaces.ui.IconsProvider
import info.nightscout.interfaces.userEntry.UserEntryPresentationHelper import info.nightscout.interfaces.userEntry.UserEntryPresentationHelper
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.shared.interfaces.ProfileUtil
import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.interfaces.ResourceHelper
@Module( @Module(
@ -81,6 +85,7 @@ abstract class ImplementationModule {
@Module @Module
interface Bindings { interface Bindings {
@Binds fun bindPersistenceLayer(persistenceLayerImpl: PersistenceLayerImpl): PersistenceLayer @Binds fun bindPersistenceLayer(persistenceLayerImpl: PersistenceLayerImpl): PersistenceLayer
@Binds fun bindActivePlugin(pluginStore: PluginStore): ActivePlugin @Binds fun bindActivePlugin(pluginStore: PluginStore): ActivePlugin
@Binds fun bindOverviewData(overviewData: OverviewDataImpl): OverviewData @Binds fun bindOverviewData(overviewData: OverviewDataImpl): OverviewData
@ -108,9 +113,11 @@ abstract class ImplementationModule {
@Binds fun bindNotificationHolderInterface(notificationHolder: NotificationHolderImpl): NotificationHolder @Binds fun bindNotificationHolderInterface(notificationHolder: NotificationHolderImpl): NotificationHolder
@Binds fun bindCommandQueue(commandQueue: CommandQueueImplementation): CommandQueue @Binds fun bindCommandQueue(commandQueue: CommandQueueImplementation): CommandQueue
@Binds fun bindsProfileFunction(profileFunctionImpl: ProfileFunctionImpl): ProfileFunction @Binds fun bindsProfileFunction(profileFunctionImpl: ProfileFunctionImpl): ProfileFunction
@Binds fun bindsProfileUtil(profileUtilImpl: ProfileUtilImpl): ProfileUtil
@Binds fun bindsStorage(fileStorage: FileStorage): Storage @Binds fun bindsStorage(fileStorage: FileStorage): Storage
@Binds fun bindsReceiverStatusStore(receiverStatusStoreImpl: ReceiverStatusStoreImpl): ReceiverStatusStore @Binds fun bindsReceiverStatusStore(receiverStatusStoreImpl: ReceiverStatusStoreImpl): ReceiverStatusStore
@Binds fun bindsUserEntryPresentationHelper(userEntryPresentationHelperImpl: UserEntryPresentationHelperImpl): UserEntryPresentationHelper @Binds fun bindsUserEntryPresentationHelper(userEntryPresentationHelperImpl: UserEntryPresentationHelperImpl): UserEntryPresentationHelper
@Binds fun bindsGlucoseStatusProvider(glucoseStatusProviderImpl: GlucoseStatusProviderImpl): GlucoseStatusProvider @Binds fun bindsGlucoseStatusProvider(glucoseStatusProviderImpl: GlucoseStatusProviderImpl): GlucoseStatusProvider
@Binds fun bindsDecimalFormatter(decimalFormatterImpl: DecimalFormatterImpl): DecimalFormatter
} }
} }

View file

@ -7,6 +7,7 @@ import info.nightscout.core.iob.log
import info.nightscout.interfaces.iob.GlucoseStatus import info.nightscout.interfaces.iob.GlucoseStatus
import info.nightscout.interfaces.iob.GlucoseStatusProvider import info.nightscout.interfaces.iob.GlucoseStatusProvider
import info.nightscout.interfaces.iob.IobCobCalculator import info.nightscout.interfaces.iob.IobCobCalculator
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.rx.logging.AAPSLogger import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag import info.nightscout.rx.logging.LTag
import info.nightscout.shared.utils.DateUtil import info.nightscout.shared.utils.DateUtil
@ -18,7 +19,8 @@ import kotlin.math.roundToLong
class GlucoseStatusProviderImpl @Inject constructor( class GlucoseStatusProviderImpl @Inject constructor(
private val aapsLogger: AAPSLogger, private val aapsLogger: AAPSLogger,
private val iobCobCalculator: IobCobCalculator, private val iobCobCalculator: IobCobCalculator,
private val dateUtil: DateUtil private val dateUtil: DateUtil,
private val decimalFormatter: DecimalFormatter
) : GlucoseStatusProvider { ) : GlucoseStatusProvider {
override val glucoseStatusData: GlucoseStatus? override val glucoseStatusData: GlucoseStatus?
@ -100,7 +102,7 @@ class GlucoseStatusProviderImpl @Inject constructor(
shortAvgDelta = shortAverageDelta, shortAvgDelta = shortAverageDelta,
delta = delta, delta = delta,
longAvgDelta = average(longDeltas), longAvgDelta = average(longDeltas),
).also { aapsLogger.debug(LTag.GLUCOSE, it.log()) }.asRounded() ).also { aapsLogger.debug(LTag.GLUCOSE, it.log(decimalFormatter)) }.asRounded()
} }
/* Real BG (previous) version /* Real BG (previous) version

View file

@ -34,6 +34,7 @@ import info.nightscout.interfaces.iob.IobTotal
import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.interfaces.plugin.ActivePlugin
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.interfaces.utils.DecimalFormatter
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
@ -52,7 +53,8 @@ class OverviewDataImpl @Inject constructor(
private val activePlugin: ActivePlugin, private val activePlugin: ActivePlugin,
private val defaultValueHelper: DefaultValueHelper, private val defaultValueHelper: DefaultValueHelper,
private val profileFunction: ProfileFunction, private val profileFunction: ProfileFunction,
private val repository: AppRepository private val repository: AppRepository,
private val decimalFormatter: DecimalFormatter
) : OverviewData { ) : OverviewData {
override var rangeToDisplay = 6 // for graph override var rangeToDisplay = 6 // for graph
@ -182,7 +184,7 @@ class OverviewDataImpl @Inject constructor(
profileFunction.getProfile()?.let { profile -> profileFunction.getProfile()?.let { profile ->
var temporaryBasal = iobCobCalculator.getTempBasalIncludingConvertedExtended(dateUtil.now()) var temporaryBasal = iobCobCalculator.getTempBasalIncludingConvertedExtended(dateUtil.now())
if (temporaryBasal?.isInProgress == false) temporaryBasal = null if (temporaryBasal?.isInProgress == false) temporaryBasal = null
temporaryBasal?.let { "T:" + it.toStringShort() } temporaryBasal?.let { "T:" + it.toStringShort(decimalFormatter) }
?: rh.gs(info.nightscout.core.ui.R.string.pump_base_basal_rate, profile.getBasal()) ?: rh.gs(info.nightscout.core.ui.R.string.pump_base_basal_rate, profile.getBasal())
} ?: rh.gs(info.nightscout.core.ui.R.string.value_unavailable_short) } ?: rh.gs(info.nightscout.core.ui.R.string.value_unavailable_short)
@ -190,7 +192,7 @@ class OverviewDataImpl @Inject constructor(
profileFunction.getProfile()?.let { profile -> profileFunction.getProfile()?.let { profile ->
iobCobCalculator.getTempBasalIncludingConvertedExtended(dateUtil.now())?.let { temporaryBasal -> iobCobCalculator.getTempBasalIncludingConvertedExtended(dateUtil.now())?.let { temporaryBasal ->
"${rh.gs(info.nightscout.core.ui.R.string.base_basal_rate_label)}: ${rh.gs(info.nightscout.core.ui.R.string.pump_base_basal_rate, profile.getBasal())}" + "${rh.gs(info.nightscout.core.ui.R.string.base_basal_rate_label)}: ${rh.gs(info.nightscout.core.ui.R.string.pump_base_basal_rate, profile.getBasal())}" +
"\n" + rh.gs(info.nightscout.core.ui.R.string.tempbasal_label) + ": " + temporaryBasal.toStringFull(profile, dateUtil) "\n" + rh.gs(info.nightscout.core.ui.R.string.tempbasal_label) + ": " + temporaryBasal.toStringFull(profile, dateUtil, decimalFormatter)
} }
?: "${rh.gs(info.nightscout.core.ui.R.string.base_basal_rate_label)}: ${rh.gs(info.nightscout.core.ui.R.string.pump_base_basal_rate, profile.getBasal())}" ?: "${rh.gs(info.nightscout.core.ui.R.string.base_basal_rate_label)}: ${rh.gs(info.nightscout.core.ui.R.string.pump_base_basal_rate, profile.getBasal())}"
} ?: rh.gs(info.nightscout.core.ui.R.string.value_unavailable_short) } ?: rh.gs(info.nightscout.core.ui.R.string.value_unavailable_short)
@ -227,7 +229,7 @@ class OverviewDataImpl @Inject constructor(
} ?: "" } ?: ""
override fun extendedBolusDialogText(iobCobCalculator: IobCobCalculator): String = override fun extendedBolusDialogText(iobCobCalculator: IobCobCalculator): String =
iobCobCalculator.getExtendedBolus(dateUtil.now())?.toStringFull(dateUtil) ?: "" iobCobCalculator.getExtendedBolus(dateUtil.now())?.toStringFull(dateUtil, decimalFormatter) ?: ""
/* /*
* IOB, COB * IOB, COB

View file

@ -0,0 +1,72 @@
package info.nightscout.implementation.profile
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.sharedPreferences.SP
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class ProfileUtilImpl @Inject constructor(
private val sp: SP,
private val decimalFormatter: DecimalFormatter
) : ProfileUtil {
override val units: GlucoseUnit
get() =
if (sp.getString(info.nightscout.core.utils.R.string.key_units, GlucoseUnit.MGDL.asText) == GlucoseUnit.MGDL.asText) GlucoseUnit.MGDL
else GlucoseUnit.MMOL
override fun fromMgdlToUnits(valueInMgdl: Double, targetUnits: GlucoseUnit): Double =
if (targetUnits == GlucoseUnit.MGDL) valueInMgdl else valueInMgdl * GlucoseUnit.MGDL_TO_MMOLL
override fun fromMmolToUnits(value: Double, targetUnits: GlucoseUnit): Double =
if (targetUnits == GlucoseUnit.MMOL) value else value * GlucoseUnit.MMOLL_TO_MGDL
override fun valueInCurrentUnitsDetect(anyBg: Double): Double =
if (isMmol(anyBg)) fromMmolToUnits(anyBg, units)
else fromMgdlToUnits(anyBg, units)
override fun stringInCurrentUnitsDetect(anyBg: Double): String =
if (isMmol(anyBg)) toUnitsString(anyBg * GlucoseUnit.MMOLL_TO_MGDL, units)
else toUnitsString(anyBg, units)
override fun fromMgdlToStringInUnits(valueInMgdl: Double?, targetUnits: GlucoseUnit): String =
valueInMgdl?.let { toUnitsString(valueInMgdl, targetUnits) } ?: ""
override fun fromMgdlToSignedStringInUnits(valueInMgdl: Double, targetUnits: GlucoseUnit): String =
if (targetUnits == GlucoseUnit.MGDL) (if (valueInMgdl > 0) "+" else "") + decimalFormatter.to0Decimal(valueInMgdl)
else (if (valueInMgdl > 0) "+" else "") + decimalFormatter.to1Decimal(valueInMgdl * GlucoseUnit.MGDL_TO_MMOLL)
override fun isMgdl(anyBg: Double) = anyBg >= 39
override fun isMmol(anyBg: Double) = anyBg < 39
override fun unitsDetect(anyBg: Double) = if (isMgdl(anyBg)) GlucoseUnit.MGDL else GlucoseUnit.MMOL
override fun valueInUnitsDetect(anyBg: Double, targetUnits: GlucoseUnit): Double =
if (isMmol(anyBg)) fromMmolToUnits(anyBg, targetUnits)
else fromMgdlToUnits(anyBg, targetUnits)
override fun stringInUnitsDetect(anyBg: Double, targetUnits: GlucoseUnit): String =
if (isMmol(anyBg)) toUnitsString(anyBg * GlucoseUnit.MMOLL_TO_MGDL, targetUnits)
else toUnitsString(anyBg, targetUnits)
override fun convertToMgdlDetect(anyBg: Double): Double =
if (isMgdl(anyBg)) anyBg else anyBg * GlucoseUnit.MMOLL_TO_MGDL
override fun convertToMgdl(value: Double, sourceUnits: GlucoseUnit): Double =
if (sourceUnits == GlucoseUnit.MGDL) value else value * GlucoseUnit.MMOLL_TO_MGDL
override fun convertToMmol(value: Double, sourceUnits: GlucoseUnit): Double =
if (sourceUnits == GlucoseUnit.MGDL) value * GlucoseUnit.MGDL_TO_MMOLL else value
override fun toTargetRangeString(low: Double, high: Double, sourceUnits: GlucoseUnit, targetUnits: GlucoseUnit): String {
val lowMgdl = convertToMgdl(low, sourceUnits)
val highMgdl = convertToMgdl(high, sourceUnits)
return if (low == high) toUnitsString(lowMgdl, targetUnits)
else toUnitsString(lowMgdl, targetUnits) + " - " + toUnitsString(highMgdl, targetUnits)
}
private fun toUnitsString(valueInMgdl: Double, targetUnits: GlucoseUnit): String =
if (targetUnits == GlucoseUnit.MGDL) decimalFormatter.to0Decimal(valueInMgdl) else decimalFormatter.to1Decimal(valueInMgdl * GlucoseUnit.MGDL_TO_MMOLL)
}

View file

@ -57,6 +57,7 @@ import info.nightscout.interfaces.queue.Command.CommandType
import info.nightscout.interfaces.queue.CommandQueue import info.nightscout.interfaces.queue.CommandQueue
import info.nightscout.interfaces.queue.CustomCommand import info.nightscout.interfaces.queue.CustomCommand
import info.nightscout.interfaces.ui.UiInteraction import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.interfaces.utils.HtmlHelper import info.nightscout.interfaces.utils.HtmlHelper
import info.nightscout.rx.AapsSchedulers import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
@ -95,7 +96,8 @@ class CommandQueueImplementation @Inject constructor(
private val fabricPrivacy: FabricPrivacy, private val fabricPrivacy: FabricPrivacy,
private val androidPermission: AndroidPermission, private val androidPermission: AndroidPermission,
private val uiInteraction: UiInteraction, private val uiInteraction: UiInteraction,
private val persistenceLayer: PersistenceLayer private val persistenceLayer: PersistenceLayer,
private val decimalFormatter: DecimalFormatter
) : CommandQueue { ) : CommandQueue {
private val disposable = CompositeDisposable() private val disposable = CompositeDisposable()
@ -132,7 +134,7 @@ class CommandQueueImplementation @Inject constructor(
targetBlocks = nonCustomized.targetBlocks, targetBlocks = nonCustomized.targetBlocks,
glucoseUnit = if (it.glucoseUnit == ProfileSwitch.GlucoseUnit.MGDL) EffectiveProfileSwitch.GlucoseUnit.MGDL else EffectiveProfileSwitch.GlucoseUnit.MMOL, glucoseUnit = if (it.glucoseUnit == ProfileSwitch.GlucoseUnit.MGDL) EffectiveProfileSwitch.GlucoseUnit.MGDL else EffectiveProfileSwitch.GlucoseUnit.MMOL,
originalProfileName = it.profileName, originalProfileName = it.profileName,
originalCustomizedName = it.getCustomizedName(), originalCustomizedName = it.getCustomizedName(decimalFormatter),
originalTimeshift = it.timeshift, originalTimeshift = it.timeshift,
originalPercentage = it.percentage, originalPercentage = it.percentage,
originalDuration = it.duration, originalDuration = it.duration,
@ -234,7 +236,7 @@ class CommandQueueImplementation @Inject constructor(
val tempCommandQueue = CommandQueueImplementation( val tempCommandQueue = CommandQueueImplementation(
injector, aapsLogger, rxBus, aapsSchedulers, rh, injector, aapsLogger, rxBus, aapsSchedulers, rh,
constraintChecker, profileFunction, activePlugin, context, sp, constraintChecker, profileFunction, activePlugin, context, sp,
config, dateUtil, repository, fabricPrivacy, androidPermission, uiInteraction, persistenceLayer config, dateUtil, repository, fabricPrivacy, androidPermission, uiInteraction, persistenceLayer, decimalFormatter
) )
tempCommandQueue.readStatus(reason, callback) tempCommandQueue.readStatus(reason, callback)
tempCommandQueue.disposable.clear() tempCommandQueue.disposable.clear()

View file

@ -5,10 +5,10 @@ import android.content.Context
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.TableLayout import android.widget.TableLayout
import info.nightscout.database.impl.AppRepository import info.nightscout.database.impl.AppRepository
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.stats.DexcomTIR import info.nightscout.interfaces.stats.DexcomTIR
import info.nightscout.interfaces.stats.DexcomTirCalculator import info.nightscout.interfaces.stats.DexcomTirCalculator
import info.nightscout.interfaces.utils.MidnightTime import info.nightscout.interfaces.utils.MidnightTime
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.utils.DateUtil import info.nightscout.shared.utils.DateUtil
import info.nightscout.shared.utils.T import info.nightscout.shared.utils.T
import javax.inject.Inject import javax.inject.Inject
@ -16,7 +16,7 @@ import javax.inject.Singleton
@Singleton @Singleton
class DexcomTirCalculatorImpl @Inject constructor( class DexcomTirCalculatorImpl @Inject constructor(
private val profileFunction: ProfileFunction, private val profileUtil: ProfileUtil,
private val dateUtil: DateUtil, private val dateUtil: DateUtil,
private val repository: AppRepository private val repository: AppRepository
) : DexcomTirCalculator { ) : DexcomTirCalculator {
@ -38,10 +38,10 @@ class DexcomTirCalculatorImpl @Inject constructor(
TableLayout(context).also { layout -> TableLayout(context).also { layout ->
val tir = calculate() val tir = calculate()
layout.layoutParams = TableLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1f) layout.layoutParams = TableLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1f)
layout.addView(tir.toRangeHeaderView(context, profileFunction)) layout.addView(tir.toRangeHeaderView(context, profileUtil))
layout.addView(tir.toTableRowHeader(context)) layout.addView(tir.toTableRowHeader(context))
layout.addView(tir.toTableRow(context)) layout.addView(tir.toTableRow(context))
layout.addView(tir.toSDView(context, profileFunction)) layout.addView(tir.toSDView(context, profileUtil))
layout.addView(tir.toHbA1cView(context)) layout.addView(tir.toHbA1cView(context))
} }
} }

View file

@ -8,9 +8,8 @@ import android.widget.TableRow
import android.widget.TextView import android.widget.TextView
import info.nightscout.implementation.R import info.nightscout.implementation.R
import info.nightscout.interfaces.Constants import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.stats.DexcomTIR import info.nightscout.interfaces.stats.DexcomTIR
import info.nightscout.shared.interfaces.ProfileUtil
import java.util.Calendar import java.util.Calendar
import kotlin.math.pow import kotlin.math.pow
import kotlin.math.roundToInt import kotlin.math.roundToInt
@ -86,42 +85,42 @@ class DexcomTirImpl : DexcomTIR {
} }
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
override fun toSDView(context: Context, profileFunction: ProfileFunction): TextView = override fun toSDView(context: Context, profileUtil: ProfileUtil): TextView =
TextView(context).apply { TextView(context).apply {
val sd = calculateSD() val sd = calculateSD()
text = "\n" + context.getString(R.string.std_deviation, Profile.toUnitsString(sd, sd * Constants.MGDL_TO_MMOLL, profileFunction.getUnits())) text = "\n" + context.getString(R.string.std_deviation, profileUtil.fromMgdlToStringInUnits(sd))
setTypeface(typeface, Typeface.NORMAL) setTypeface(typeface, Typeface.NORMAL)
gravity = Gravity.CENTER_HORIZONTAL gravity = Gravity.CENTER_HORIZONTAL
} }
override fun toRangeHeaderView(context: Context, profileFunction: ProfileFunction): TextView = override fun toRangeHeaderView(context: Context, profileUtil: ProfileUtil): TextView =
TextView(context).apply { TextView(context).apply {
text = StringBuilder() text = StringBuilder()
.append(context.getString(R.string.detailed_14_days)) .append(context.getString(R.string.detailed_14_days))
.append("\n") .append("\n")
.append(context.getString(R.string.day_tir)) .append(context.getString(R.string.day_tir))
.append(" (") .append(" (")
.append(Profile.toUnitsString(0.0, 0.0, profileFunction.getUnits())) .append(profileUtil.fromMgdlToStringInUnits(0.0))
.append("-") .append("-")
.append(Profile.toCurrentUnitsString(profileFunction, veryLowTirMgdl)) .append(profileUtil.stringInCurrentUnitsDetect(veryLowTirMgdl))
.append("-") .append("-")
.append(Profile.toCurrentUnitsString(profileFunction, lowTirMgdl)) .append(profileUtil.stringInCurrentUnitsDetect(lowTirMgdl))
.append("-") .append("-")
.append(Profile.toCurrentUnitsString(profileFunction, highTirMgdl)) .append(profileUtil.stringInCurrentUnitsDetect(highTirMgdl))
.append("-") .append("-")
.append(Profile.toCurrentUnitsString(profileFunction, veryHighTirMgdl)) .append(profileUtil.stringInCurrentUnitsDetect(veryHighTirMgdl))
.append("-∞)\n") .append("-∞)\n")
.append(context.getString(R.string.night_tir)) .append(context.getString(R.string.night_tir))
.append(" (") .append(" (")
.append(Profile.toUnitsString(0.0, 0.0, profileFunction.getUnits())) .append(profileUtil.fromMgdlToStringInUnits(0.0))
.append("-") .append("-")
.append(Profile.toCurrentUnitsString(profileFunction, veryLowTirMgdl)) .append(profileUtil.stringInCurrentUnitsDetect(veryLowTirMgdl))
.append("-") .append("-")
.append(Profile.toCurrentUnitsString(profileFunction, lowTirMgdl)) .append(profileUtil.stringInCurrentUnitsDetect(lowTirMgdl))
.append("-") .append("-")
.append(Profile.toCurrentUnitsString(profileFunction, highNightTirMgdl)) .append(profileUtil.stringInCurrentUnitsDetect(highNightTirMgdl))
.append("-") .append("-")
.append(Profile.toCurrentUnitsString(profileFunction, veryHighTirMgdl)) .append(profileUtil.stringInCurrentUnitsDetect(veryHighTirMgdl))
.append("-∞)\n") .append("-∞)\n")
.toString() .toString()
setTypeface(typeface, Typeface.BOLD) setTypeface(typeface, Typeface.BOLD)

View file

@ -10,11 +10,10 @@ import android.widget.TableLayout
import android.widget.TextView import android.widget.TextView
import info.nightscout.database.impl.AppRepository import info.nightscout.database.impl.AppRepository
import info.nightscout.interfaces.Constants import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.stats.TIR import info.nightscout.interfaces.stats.TIR
import info.nightscout.interfaces.stats.TirCalculator import info.nightscout.interfaces.stats.TirCalculator
import info.nightscout.interfaces.utils.MidnightTime import info.nightscout.interfaces.utils.MidnightTime
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.utils.DateUtil import info.nightscout.shared.utils.DateUtil
import info.nightscout.shared.utils.T import info.nightscout.shared.utils.T
@ -24,7 +23,7 @@ import javax.inject.Singleton
@Singleton @Singleton
class TirCalculatorImpl @Inject constructor( class TirCalculatorImpl @Inject constructor(
private val rh: ResourceHelper, private val rh: ResourceHelper,
private val profileFunction: ProfileFunction, private val profileUtil: ProfileUtil,
private val dateUtil: DateUtil, private val dateUtil: DateUtil,
private val repository: AppRepository private val repository: AppRepository
) : TirCalculator { ) : TirCalculator {
@ -88,7 +87,7 @@ class TirCalculatorImpl @Inject constructor(
layout.layoutParams = TableLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1f) layout.layoutParams = TableLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1f)
layout.addView( layout.addView(
TextView(context).apply { TextView(context).apply {
text = rh.gs(info.nightscout.core.ui.R.string.tir) + " (" + Profile.toCurrentUnitsString(profileFunction, lowTirMgdl) + "-" + Profile.toCurrentUnitsString(profileFunction, highTirMgdl) + ")" text = rh.gs(info.nightscout.core.ui.R.string.tir) + " (" + profileUtil.stringInCurrentUnitsDetect(lowTirMgdl) + "-" + profileUtil.stringInCurrentUnitsDetect(highTirMgdl) + ")"
setTypeface(typeface, Typeface.BOLD) setTypeface(typeface, Typeface.BOLD)
gravity = Gravity.CENTER_HORIZONTAL gravity = Gravity.CENTER_HORIZONTAL
setTextAppearance(android.R.style.TextAppearance_Material_Medium) setTextAppearance(android.R.style.TextAppearance_Material_Medium)
@ -97,7 +96,7 @@ class TirCalculatorImpl @Inject constructor(
for (i in 0 until tir7.size()) layout.addView(tir7.valueAt(i).toTableRow(context, rh, dateUtil)) for (i in 0 until tir7.size()) layout.addView(tir7.valueAt(i).toTableRow(context, rh, dateUtil))
layout.addView( layout.addView(
TextView(context).apply { TextView(context).apply {
text = rh.gs(info.nightscout.core.ui.R.string.average) + " (" + Profile.toCurrentUnitsString(profileFunction, lowTirMgdl) + "-" + Profile.toCurrentUnitsString(profileFunction, highTirMgdl) + ")" text = rh.gs(info.nightscout.core.ui.R.string.average) + " (" + profileUtil.stringInCurrentUnitsDetect(lowTirMgdl) + "-" + profileUtil.stringInCurrentUnitsDetect(highTirMgdl) + ")"
setTypeface(typeface, Typeface.BOLD) setTypeface(typeface, Typeface.BOLD)
gravity = Gravity.CENTER_HORIZONTAL gravity = Gravity.CENTER_HORIZONTAL
setTextAppearance(android.R.style.TextAppearance_Material_Medium) setTextAppearance(android.R.style.TextAppearance_Material_Medium)
@ -106,7 +105,7 @@ class TirCalculatorImpl @Inject constructor(
layout.addView(averageTir30.toTableRow(context, rh, tir30.size())) layout.addView(averageTir30.toTableRow(context, rh, tir30.size()))
layout.addView( layout.addView(
TextView(context).apply { TextView(context).apply {
text = rh.gs(info.nightscout.core.ui.R.string.average) + " (" + Profile.toCurrentUnitsString(profileFunction, lowTitMgdl) + "-" + Profile.toCurrentUnitsString(profileFunction, highTitMgdl) + ")" text = rh.gs(info.nightscout.core.ui.R.string.average) + " (" + profileUtil.stringInCurrentUnitsDetect(lowTitMgdl) + "-" + profileUtil.stringInCurrentUnitsDetect(highTitMgdl) + ")"
setTypeface(typeface, Typeface.BOLD) setTypeface(typeface, Typeface.BOLD)
gravity = Gravity.CENTER_HORIZONTAL gravity = Gravity.CENTER_HORIZONTAL
setTextAppearance(android.R.style.TextAppearance_Material_Medium) setTextAppearance(android.R.style.TextAppearance_Material_Medium)

View file

@ -11,11 +11,10 @@ import info.nightscout.database.entities.ValueWithUnit
import info.nightscout.interfaces.Constants import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.GlucoseUnit import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.Translator import info.nightscout.interfaces.Translator
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.userEntry.UserEntryPresentationHelper import info.nightscout.interfaces.userEntry.UserEntryPresentationHelper
import info.nightscout.interfaces.utils.DecimalFormatter import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.interfaces.utils.HtmlHelper import info.nightscout.interfaces.utils.HtmlHelper
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.utils.DateUtil import info.nightscout.shared.utils.DateUtil
import javax.inject.Inject import javax.inject.Inject
@ -23,9 +22,10 @@ import javax.inject.Inject
@Reusable @Reusable
class UserEntryPresentationHelperImpl @Inject constructor( class UserEntryPresentationHelperImpl @Inject constructor(
private val translator: Translator, private val translator: Translator,
private val profileFunction: ProfileFunction, private val profileUtil: ProfileUtil,
private val rh: ResourceHelper, private val rh: ResourceHelper,
private val dateUtil: DateUtil private val dateUtil: DateUtil,
private val decimalFormatter: DecimalFormatter
) : UserEntryPresentationHelper { ) : UserEntryPresentationHelper {
override fun colorId(colorGroup: ColorGroup): Int = when (colorGroup) { override fun colorId(colorGroup: ColorGroup): Int = when (colorGroup) {
@ -126,8 +126,8 @@ class UserEntryPresentationHelperImpl @Inject constructor(
is ValueWithUnit.Hour -> "${valueWithUnit.value}${translator.translate(valueWithUnit)}" is ValueWithUnit.Hour -> "${valueWithUnit.value}${translator.translate(valueWithUnit)}"
is ValueWithUnit.Minute -> "${valueWithUnit.value}${translator.translate(valueWithUnit)}" is ValueWithUnit.Minute -> "${valueWithUnit.value}${translator.translate(valueWithUnit)}"
is ValueWithUnit.Percent -> "${valueWithUnit.value}${translator.translate(valueWithUnit)}" is ValueWithUnit.Percent -> "${valueWithUnit.value}${translator.translate(valueWithUnit)}"
is ValueWithUnit.Insulin -> DecimalFormatter.to2Decimal(valueWithUnit.value) + translator.translate(valueWithUnit) is ValueWithUnit.Insulin -> decimalFormatter.to2Decimal(valueWithUnit.value) + translator.translate(valueWithUnit)
is ValueWithUnit.UnitPerHour -> DecimalFormatter.to2Decimal(valueWithUnit.value) + translator.translate(valueWithUnit) is ValueWithUnit.UnitPerHour -> decimalFormatter.to2Decimal(valueWithUnit.value) + translator.translate(valueWithUnit)
is ValueWithUnit.SimpleInt -> valueWithUnit.value.toString() is ValueWithUnit.SimpleInt -> valueWithUnit.value.toString()
is ValueWithUnit.SimpleString -> valueWithUnit.value is ValueWithUnit.SimpleString -> valueWithUnit.value
is ValueWithUnit.TherapyEventMeterType -> translator.translate(valueWithUnit.value) is ValueWithUnit.TherapyEventMeterType -> translator.translate(valueWithUnit.value)
@ -137,13 +137,13 @@ class UserEntryPresentationHelperImpl @Inject constructor(
is ValueWithUnit.Timestamp -> dateUtil.dateAndTimeAndSecondsString(valueWithUnit.value) is ValueWithUnit.Timestamp -> dateUtil.dateAndTimeAndSecondsString(valueWithUnit.value)
is ValueWithUnit.Mgdl -> { is ValueWithUnit.Mgdl -> {
if (profileFunction.getUnits() == GlucoseUnit.MGDL) DecimalFormatter.to0Decimal(valueWithUnit.value) + rh.gs(info.nightscout.core.ui.R.string.mgdl) if (profileUtil.units == GlucoseUnit.MGDL) decimalFormatter.to0Decimal(valueWithUnit.value) + rh.gs(info.nightscout.core.ui.R.string.mgdl)
else DecimalFormatter.to1Decimal(valueWithUnit.value * Constants.MGDL_TO_MMOLL) + rh.gs(info.nightscout.core.ui.R.string.mmol) else decimalFormatter.to1Decimal(valueWithUnit.value * Constants.MGDL_TO_MMOLL) + rh.gs(info.nightscout.core.ui.R.string.mmol)
} }
is ValueWithUnit.Mmoll -> { is ValueWithUnit.Mmoll -> {
if (profileFunction.getUnits() == GlucoseUnit.MMOL) DecimalFormatter.to1Decimal(valueWithUnit.value) + rh.gs(info.nightscout.core.ui.R.string.mmol) if (profileUtil.units == GlucoseUnit.MMOL) decimalFormatter.to1Decimal(valueWithUnit.value) + rh.gs(info.nightscout.core.ui.R.string.mmol)
else DecimalFormatter.to0Decimal(valueWithUnit.value * Constants.MMOLL_TO_MGDL) + rh.gs(info.nightscout.core.ui.R.string.mgdl) else decimalFormatter.to0Decimal(valueWithUnit.value * Constants.MMOLL_TO_MGDL) + rh.gs(info.nightscout.core.ui.R.string.mgdl)
} }
ValueWithUnit.UNKNOWN -> "" ValueWithUnit.UNKNOWN -> ""
@ -165,7 +165,7 @@ class UserEntryPresentationHelperImpl @Inject constructor(
csvString(info.nightscout.core.ui.R.string.careportal_note), csvString(info.nightscout.core.ui.R.string.careportal_note),
csvString(info.nightscout.core.ui.R.string.ue_string), csvString(info.nightscout.core.ui.R.string.ue_string),
csvString(info.nightscout.core.ui.R.string.event_time_label), csvString(info.nightscout.core.ui.R.string.event_time_label),
csvString(if (profileFunction.getUnits() == GlucoseUnit.MGDL) info.nightscout.core.ui.R.string.mgdl else info.nightscout.core.ui.R.string.mmol), csvString(if (profileUtil.units == GlucoseUnit.MGDL) info.nightscout.core.ui.R.string.mgdl else info.nightscout.core.ui.R.string.mmol),
csvString(info.nightscout.core.ui.R.string.shortgram), csvString(info.nightscout.core.ui.R.string.shortgram),
csvString(info.nightscout.core.ui.R.string.insulin_unit_shortname), csvString(info.nightscout.core.ui.R.string.insulin_unit_shortname),
csvString(info.nightscout.core.ui.R.string.profile_ins_units_per_hour), csvString(info.nightscout.core.ui.R.string.profile_ins_units_per_hour),
@ -201,8 +201,8 @@ class UserEntryPresentationHelperImpl @Inject constructor(
is ValueWithUnit.Hour -> hour = valueWithUnit.value.toString() is ValueWithUnit.Hour -> hour = valueWithUnit.value.toString()
is ValueWithUnit.Minute -> minute = valueWithUnit.value.toString() is ValueWithUnit.Minute -> minute = valueWithUnit.value.toString()
is ValueWithUnit.Percent -> percent = valueWithUnit.value.toString() is ValueWithUnit.Percent -> percent = valueWithUnit.value.toString()
is ValueWithUnit.Insulin -> insulin = DecimalFormatter.to2Decimal(valueWithUnit.value) is ValueWithUnit.Insulin -> insulin = decimalFormatter.to2Decimal(valueWithUnit.value)
is ValueWithUnit.UnitPerHour -> unitPerHour = DecimalFormatter.to2Decimal(valueWithUnit.value) is ValueWithUnit.UnitPerHour -> unitPerHour = decimalFormatter.to2Decimal(valueWithUnit.value)
is ValueWithUnit.SimpleInt -> noUnit = noUnit.addWithSeparator(valueWithUnit.value) is ValueWithUnit.SimpleInt -> noUnit = noUnit.addWithSeparator(valueWithUnit.value)
is ValueWithUnit.SimpleString -> simpleString = simpleString.addWithSeparator(valueWithUnit.value) is ValueWithUnit.SimpleString -> simpleString = simpleString.addWithSeparator(valueWithUnit.value)
is ValueWithUnit.TherapyEventMeterType -> therapyEvent = therapyEvent.addWithSeparator(translator.translate(valueWithUnit.value)) is ValueWithUnit.TherapyEventMeterType -> therapyEvent = therapyEvent.addWithSeparator(translator.translate(valueWithUnit.value))
@ -212,10 +212,10 @@ class UserEntryPresentationHelperImpl @Inject constructor(
is ValueWithUnit.Timestamp -> timestamp = dateUtil.dateAndTimeAndSecondsString(valueWithUnit.value) is ValueWithUnit.Timestamp -> timestamp = dateUtil.dateAndTimeAndSecondsString(valueWithUnit.value)
is ValueWithUnit.Mgdl -> is ValueWithUnit.Mgdl ->
bg = Profile.toUnitsString(valueWithUnit.value, valueWithUnit.value * Constants.MGDL_TO_MMOLL, profileFunction.getUnits()) bg = profileUtil.fromMgdlToStringInUnits(valueWithUnit.value)
is ValueWithUnit.Mmoll -> is ValueWithUnit.Mmoll ->
bg = Profile.toUnitsString(valueWithUnit.value * Constants.MMOLL_TO_MGDL, valueWithUnit.value, profileFunction.getUnits()) bg = profileUtil.fromMgdlToStringInUnits(valueWithUnit.value * Constants.MMOLL_TO_MGDL)
ValueWithUnit.UNKNOWN -> Unit ValueWithUnit.UNKNOWN -> Unit
} }

View file

@ -0,0 +1,33 @@
package info.nightscout.implementation.utils
import info.nightscout.interfaces.R
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.shared.interfaces.ResourceHelper
import java.text.DecimalFormat
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class DecimalFormatterImpl @Inject constructor(
private val rh: ResourceHelper
) : DecimalFormatter {
private val format0dec = DecimalFormat("0")
private val format1dec = DecimalFormat("0.0")
private val format2dec = DecimalFormat("0.00")
private val format3dec = DecimalFormat("0.000")
override fun to0Decimal(value: Double): String = format0dec.format(value)
override fun to0Decimal(value: Double, unit: String): String = format0dec.format(value) + unit
override fun to1Decimal(value: Double): String = format1dec.format(value)
override fun to1Decimal(value: Double, unit: String): String = format1dec.format(value) + unit
override fun to2Decimal(value: Double): String = format2dec.format(value)
override fun to2Decimal(value: Double, unit: String): String = format2dec.format(value) + unit
override fun to3Decimal(value: Double): String = format3dec.format(value)
override fun to3Decimal(value: Double, unit: String): String = format3dec.format(value) + unit
override fun toPumpSupportedBolus(value: Double, bolusStep: Double): String = if (bolusStep <= 0.051) to2Decimal(value) else to1Decimal(value)
override fun toPumpSupportedBolusWithUnits(value: Double, bolusStep: Double): String =
if (bolusStep <= 0.051) rh.gs(R.string.format_insulin_units, value) else rh.gs(R.string.format_insulin_units1, value)
override fun pumpSupportedBolusFormat(bolusStep: Double): DecimalFormat = if (bolusStep <= 0.051) DecimalFormat("0.00") else DecimalFormat("0.0")
}

View file

@ -7,9 +7,8 @@ import info.nightscout.interfaces.aps.AutosensDataStore
import info.nightscout.interfaces.iob.GlucoseStatus import info.nightscout.interfaces.iob.GlucoseStatus
import info.nightscout.interfaces.iob.InMemoryGlucoseValue import info.nightscout.interfaces.iob.InMemoryGlucoseValue
import info.nightscout.interfaces.iob.IobCobCalculator import info.nightscout.interfaces.iob.IobCobCalculator
import info.nightscout.shared.utils.DateUtil
import info.nightscout.shared.utils.T import info.nightscout.shared.utils.T
import info.nightscout.sharedtests.TestBase import info.nightscout.sharedtests.TestBaseWithProfile
import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
@ -19,9 +18,8 @@ import org.mockito.Mockito
/** /**
* Created by mike on 26.03.2018. * Created by mike on 26.03.2018.
*/ */
class GlucoseStatusTest : TestBase() { class GlucoseStatusTest : TestBaseWithProfile() {
@Mock lateinit var dateUtil: DateUtil
@Mock lateinit var iobCobCalculatorPlugin: IobCobCalculator @Mock lateinit var iobCobCalculatorPlugin: IobCobCalculator
@Mock lateinit var autosensDataStore: AutosensDataStore @Mock lateinit var autosensDataStore: AutosensDataStore
@ -32,7 +30,7 @@ class GlucoseStatusTest : TestBase() {
@Test fun toStringShouldBeOverloaded() { @Test fun toStringShouldBeOverloaded() {
val glucoseStatus = GlucoseStatus(glucose = 0.0, noise = 0.0, delta = 0.0, shortAvgDelta = 0.0, longAvgDelta = 0.0, date = 0) val glucoseStatus = GlucoseStatus(glucose = 0.0, noise = 0.0, delta = 0.0, shortAvgDelta = 0.0, longAvgDelta = 0.0, date = 0)
Assertions.assertEquals(true, glucoseStatus.log().contains("Delta")) Assertions.assertEquals(true, glucoseStatus.log(decimalFormatter).contains("Delta"))
} }
@Test fun roundTest() { @Test fun roundTest() {
@ -42,7 +40,7 @@ class GlucoseStatusTest : TestBase() {
@Test fun calculateValidGlucoseStatus() { @Test fun calculateValidGlucoseStatus() {
Mockito.`when`(autosensDataStore.getBucketedDataTableCopy()).thenReturn(generateValidBgData()) Mockito.`when`(autosensDataStore.getBucketedDataTableCopy()).thenReturn(generateValidBgData())
val glucoseStatus = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculatorPlugin, dateUtil).glucoseStatusData!! val glucoseStatus = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculatorPlugin, dateUtil, decimalFormatter).glucoseStatusData!!
Assertions.assertEquals(214.0, glucoseStatus.glucose, 0.001) Assertions.assertEquals(214.0, glucoseStatus.glucose, 0.001)
Assertions.assertEquals(-2.0, glucoseStatus.delta, 0.001) Assertions.assertEquals(-2.0, glucoseStatus.delta, 0.001)
Assertions.assertEquals(-2.5, glucoseStatus.shortAvgDelta, 0.001) // -2 -2.5 -3 deltas are relative to current value Assertions.assertEquals(-2.5, glucoseStatus.shortAvgDelta, 0.001) // -2 -2.5 -3 deltas are relative to current value
@ -73,7 +71,7 @@ class GlucoseStatusTest : TestBase() {
@Test fun oneRecordShouldProduceZeroDeltas() { @Test fun oneRecordShouldProduceZeroDeltas() {
Mockito.`when`(autosensDataStore.getBucketedDataTableCopy()).thenReturn(generateOneCurrentRecordBgData()) Mockito.`when`(autosensDataStore.getBucketedDataTableCopy()).thenReturn(generateOneCurrentRecordBgData())
val glucoseStatus: GlucoseStatus = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculatorPlugin, dateUtil).glucoseStatusData!! val glucoseStatus: GlucoseStatus = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculatorPlugin, dateUtil, decimalFormatter).glucoseStatusData!!
Assertions.assertEquals(214.0, glucoseStatus.glucose, 0.001) Assertions.assertEquals(214.0, glucoseStatus.glucose, 0.001)
Assertions.assertEquals(0.0, glucoseStatus.delta, 0.001) Assertions.assertEquals(0.0, glucoseStatus.delta, 0.001)
Assertions.assertEquals(0.0, glucoseStatus.shortAvgDelta, 0.001) // -2 -2.5 -3 deltas are relative to current value Assertions.assertEquals(0.0, glucoseStatus.shortAvgDelta, 0.001) // -2 -2.5 -3 deltas are relative to current value
@ -83,19 +81,19 @@ class GlucoseStatusTest : TestBase() {
@Test fun insufficientDataShouldReturnNull() { @Test fun insufficientDataShouldReturnNull() {
Mockito.`when`(autosensDataStore.getBucketedDataTableCopy()).thenReturn(generateInsufficientBgData()) Mockito.`when`(autosensDataStore.getBucketedDataTableCopy()).thenReturn(generateInsufficientBgData())
val glucoseStatus: GlucoseStatus? = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculatorPlugin, dateUtil).glucoseStatusData val glucoseStatus: GlucoseStatus? = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculatorPlugin, dateUtil, decimalFormatter).glucoseStatusData
Assertions.assertEquals(null, glucoseStatus) Assertions.assertEquals(null, glucoseStatus)
} }
@Test fun oldDataShouldReturnNull() { @Test fun oldDataShouldReturnNull() {
Mockito.`when`(autosensDataStore.getBucketedDataTableCopy()).thenReturn(generateOldBgData()) Mockito.`when`(autosensDataStore.getBucketedDataTableCopy()).thenReturn(generateOldBgData())
val glucoseStatus: GlucoseStatus? = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculatorPlugin, dateUtil).glucoseStatusData val glucoseStatus: GlucoseStatus? = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculatorPlugin, dateUtil, decimalFormatter).glucoseStatusData
Assertions.assertEquals(null, glucoseStatus) Assertions.assertEquals(null, glucoseStatus)
} }
@Test fun returnOldDataIfAllowed() { @Test fun returnOldDataIfAllowed() {
Mockito.`when`(autosensDataStore.getBucketedDataTableCopy()).thenReturn(generateOldBgData()) Mockito.`when`(autosensDataStore.getBucketedDataTableCopy()).thenReturn(generateOldBgData())
val glucoseStatus: GlucoseStatus? = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculatorPlugin, dateUtil).getGlucoseStatusData(true) val glucoseStatus: GlucoseStatus? = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculatorPlugin, dateUtil, decimalFormatter).getGlucoseStatusData(true)
Assertions.assertNotEquals(null, glucoseStatus) Assertions.assertNotEquals(null, glucoseStatus)
} }

View file

@ -6,14 +6,9 @@ import info.nightscout.database.impl.AppRepository
import info.nightscout.interfaces.GlucoseUnit import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.aps.AutosensDataStore import info.nightscout.interfaces.aps.AutosensDataStore
import info.nightscout.interfaces.iob.InMemoryGlucoseValue import info.nightscout.interfaces.iob.InMemoryGlucoseValue
import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.profile.DefaultValueHelper import info.nightscout.interfaces.profile.DefaultValueHelper
import info.nightscout.interfaces.profile.ProfileFunction
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 info.nightscout.shared.utils.T
import info.nightscout.sharedtests.TestBase import info.nightscout.sharedtests.TestBaseWithProfile
import io.reactivex.rxjava3.core.Single import io.reactivex.rxjava3.core.Single
import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.BeforeEach
@ -21,14 +16,9 @@ import org.junit.jupiter.api.Test
import org.mockito.Mock import org.mockito.Mock
import org.mockito.Mockito import org.mockito.Mockito
class OverviewDataImplTest : TestBase() { class OverviewDataImplTest : TestBaseWithProfile() {
@Mock lateinit var rh: ResourceHelper
@Mock lateinit var dateUtil: DateUtil
@Mock lateinit var sp: SP
@Mock lateinit var activePlugin: ActivePlugin
@Mock lateinit var defaultValueHelper: DefaultValueHelper @Mock lateinit var defaultValueHelper: DefaultValueHelper
@Mock lateinit var profileFunction: ProfileFunction
@Mock lateinit var repository: AppRepository @Mock lateinit var repository: AppRepository
@Mock lateinit var autosensDataStore: AutosensDataStore @Mock lateinit var autosensDataStore: AutosensDataStore
@ -40,7 +30,7 @@ class OverviewDataImplTest : TestBase() {
@BeforeEach @BeforeEach
fun setup() { fun setup() {
sut = OverviewDataImpl(aapsLogger, rh, dateUtil, sp, activePlugin, defaultValueHelper, profileFunction, repository) sut = OverviewDataImpl(aapsLogger, rh, dateUtil, sp, activePlugin, defaultValueHelper, profileFunction, repository, decimalFormatter)
Mockito.`when`(defaultValueHelper.determineLowLine()).thenReturn(80.0) Mockito.`when`(defaultValueHelper.determineLowLine()).thenReturn(80.0)
Mockito.`when`(defaultValueHelper.determineHighLine()).thenReturn(180.0) Mockito.`when`(defaultValueHelper.determineHighLine()).thenReturn(180.0)
Mockito.`when`(profileFunction.getUnits()).thenReturn(GlucoseUnit.MGDL) Mockito.`when`(profileFunction.getUnits()).thenReturn(GlucoseUnit.MGDL)

View file

@ -0,0 +1,47 @@
package info.nightscout.implementation.profile
import info.nightscout.database.entities.GlucoseValue
import info.nightscout.implementation.utils.DecimalFormatterImpl
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.sharedtests.TestBase
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.mockito.Mock
class ProfileUtilImplTest : TestBase() {
@Mock lateinit var rh: ResourceHelper
@Mock lateinit var sp: SP
private val glucoseValue =
GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = 1514766900000, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT)
private lateinit var sut: ProfileUtilImpl
@BeforeEach
fun setup() {
val decimalFormatter = DecimalFormatterImpl(rh)
sut = ProfileUtilImpl(sp, decimalFormatter)
}
@Test
fun toUnitsString() {
Assertions.assertEquals("100", sut.fromMgdlToStringInUnits(glucoseValue.value, GlucoseUnit.MGDL))
Assertions.assertEquals("5.6", sut.fromMgdlToStringInUnits(glucoseValue.value, GlucoseUnit.MMOL))
Assertions.assertEquals(0.1, sut.convertToMgdl(0.1, GlucoseUnit.MGDL), 0.01)
Assertions.assertEquals(18.0, sut.convertToMgdl(1.0, GlucoseUnit.MMOL), 0.01)
Assertions.assertEquals(1.0, sut.convertToMmol(18.0, GlucoseUnit.MGDL), 0.01)
Assertions.assertEquals(18.0, sut.convertToMmol(18.0, GlucoseUnit.MMOL), 0.01)
Assertions.assertEquals(18.0, sut.fromMgdlToUnits(18.0, GlucoseUnit.MGDL), 0.01)
Assertions.assertEquals(1.0, sut.fromMgdlToUnits(18.0, GlucoseUnit.MMOL), 0.01)
Assertions.assertEquals(18.0, sut.fromMgdlToUnits(18.0, GlucoseUnit.MGDL), 0.01)
Assertions.assertEquals(1.0, sut.fromMgdlToUnits(18.0, GlucoseUnit.MMOL), 0.01)
Assertions.assertEquals("18", sut.fromMgdlToStringInUnits(18.0, GlucoseUnit.MGDL))
Assertions.assertEquals("1.0", sut.fromMgdlToStringInUnits(18.0, GlucoseUnit.MMOL).replace(",", "."))
Assertions.assertEquals("5 - 6", sut.toTargetRangeString(5.0, 6.0, GlucoseUnit.MGDL, GlucoseUnit.MGDL))
Assertions.assertEquals("4", sut.toTargetRangeString(4.0, 4.0, GlucoseUnit.MGDL, GlucoseUnit.MGDL))
}
}

View file

@ -28,6 +28,7 @@ import info.nightscout.interfaces.queue.Callback
import info.nightscout.interfaces.queue.Command import info.nightscout.interfaces.queue.Command
import info.nightscout.interfaces.queue.CustomCommand import info.nightscout.interfaces.queue.CustomCommand
import info.nightscout.interfaces.ui.UiInteraction import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.interfaces.utils.DecimalFormatter
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
@ -73,11 +74,12 @@ class CommandQueueImplementationTest : TestBaseWithProfile() {
fabricPrivacy: FabricPrivacy, fabricPrivacy: FabricPrivacy,
androidPermission: AndroidPermission, androidPermission: AndroidPermission,
uiInteraction: UiInteraction, uiInteraction: UiInteraction,
persistenceLayer: PersistenceLayer persistenceLayer: PersistenceLayer,
decimalFormatter: DecimalFormatter
) : CommandQueueImplementation( ) : CommandQueueImplementation(
injector, aapsLogger, rxBus, aapsSchedulers, rh, constraintChecker, profileFunction, injector, aapsLogger, rxBus, aapsSchedulers, rh, constraintChecker, profileFunction,
activePlugin, context, sp, config, dateUtil, repository, fabricPrivacy, activePlugin, context, sp, config, dateUtil, repository, fabricPrivacy,
androidPermission, uiInteraction, persistenceLayer androidPermission, uiInteraction, persistenceLayer, decimalFormatter
) { ) {
override fun notifyAboutNewCommand(): Boolean = true override fun notifyAboutNewCommand(): Boolean = true
@ -120,7 +122,7 @@ class CommandQueueImplementationTest : TestBaseWithProfile() {
injector, aapsLogger, rxBus, aapsSchedulers, rh, injector, aapsLogger, rxBus, aapsSchedulers, rh,
constraintChecker, profileFunction, activePlugin, context, sp, constraintChecker, profileFunction, activePlugin, context, sp,
config, dateUtil, repository, config, dateUtil, repository,
fabricPrivacy, androidPermission, uiInteraction, persistenceLayer fabricPrivacy, androidPermission, uiInteraction, persistenceLayer, decimalFormatter
) )
testPumpPlugin = TestPumpPlugin(injector) testPumpPlugin = TestPumpPlugin(injector)
@ -157,7 +159,7 @@ class CommandQueueImplementationTest : TestBaseWithProfile() {
val commandQueue = CommandQueueImplementation( val commandQueue = CommandQueueImplementation(
injector, aapsLogger, rxBus, aapsSchedulers, rh, injector, aapsLogger, rxBus, aapsSchedulers, rh,
constraintChecker, profileFunction, activePlugin, context, sp, constraintChecker, profileFunction, activePlugin, context, sp,
config, dateUtil, repository, fabricPrivacy, androidPermission, uiInteraction, persistenceLayer config, dateUtil, repository, fabricPrivacy, androidPermission, uiInteraction, persistenceLayer, decimalFormatter
) )
val handler = mock(Handler::class.java) val handler = mock(Handler::class.java)
`when`(handler.post(anyObject())).thenAnswer { invocation: InvocationOnMock -> `when`(handler.post(anyObject())).thenAnswer { invocation: InvocationOnMock ->

View file

@ -55,7 +55,7 @@ class QueueThreadTest : TestBaseWithProfile() {
commandQueue = CommandQueueImplementation( commandQueue = CommandQueueImplementation(
injector, aapsLogger, rxBus, aapsSchedulers, rh, constraintChecker, injector, aapsLogger, rxBus, aapsSchedulers, rh, constraintChecker,
profileFunction, activePlugin, context, sp, profileFunction, activePlugin, context, sp,
config, dateUtil, repository, fabricPrivacy, androidPermission, uiInteraction, persistenceLayer config, dateUtil, repository, fabricPrivacy, androidPermission, uiInteraction, persistenceLayer, decimalFormatter
) )
val pumpDescription = PumpDescription() val pumpDescription = PumpDescription()

View file

@ -0,0 +1,41 @@
package info.nightscout.implementation.utils
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.sharedtests.TestBase
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.mockito.Mock
class DecimalFormatterTest : TestBase() {
@Mock lateinit var rh: ResourceHelper
private lateinit var sut: DecimalFormatter
@BeforeEach
fun setup() {
sut = DecimalFormatterImpl(rh)
}
@Test fun to0DecimalTest() {
Assertions.assertEquals("1", sut.to0Decimal(1.33).replace(",", "."))
Assertions.assertEquals("1U", sut.to0Decimal(1.33, "U").replace(",", "."))
}
@Test fun to1DecimalTest() {
Assertions.assertEquals("1.3", sut.to1Decimal(1.33).replace(",", "."))
Assertions.assertEquals("1.3U", sut.to1Decimal(1.33, "U").replace(",", "."))
}
@Test fun to2DecimalTest() {
Assertions.assertEquals("1.33", sut.to2Decimal(1.3333).replace(",", "."))
Assertions.assertEquals("1.33U", sut.to2Decimal(1.3333, "U").replace(",", "."))
}
@Test fun to3DecimalTest() {
Assertions.assertEquals("1.333", sut.to3Decimal(1.3333).replace(",", "."))
Assertions.assertEquals("1.333U", sut.to3Decimal(1.3333, "U").replace(",", "."))
}
}

View file

@ -4,7 +4,6 @@ import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.core.wizard.BolusWizard import info.nightscout.core.wizard.BolusWizard
import info.nightscout.implementation.iob.GlucoseStatusProviderImpl import info.nightscout.implementation.iob.GlucoseStatusProviderImpl
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.aps.AutosensDataStore import info.nightscout.interfaces.aps.AutosensDataStore
import info.nightscout.interfaces.aps.Loop import info.nightscout.interfaces.aps.Loop
import info.nightscout.interfaces.constraints.Constraint import info.nightscout.interfaces.constraints.Constraint
@ -43,7 +42,8 @@ class BolusWizardTest : TestBaseWithProfile() {
it.loop = loop it.loop = loop
it.dateUtil = dateUtil it.dateUtil = dateUtil
it.iobCobCalculator = iobCobCalculator it.iobCobCalculator = iobCobCalculator
it.glucoseStatusProvider = GlucoseStatusProviderImpl(aapsLogger = aapsLogger, iobCobCalculator = iobCobCalculator, dateUtil = dateUtil) it.glucoseStatusProvider = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculator, dateUtil, decimalFormatter)
it.profileUtil = profileUtil
} }
} }
} }
@ -56,7 +56,6 @@ class BolusWizardTest : TestBaseWithProfile() {
Mockito.`when`(profile.getIsfMgdl()).thenReturn(insulinSensitivityFactor) Mockito.`when`(profile.getIsfMgdl()).thenReturn(insulinSensitivityFactor)
Mockito.`when`(profile.getIc()).thenReturn(insulinToCarbRatio) Mockito.`when`(profile.getIc()).thenReturn(insulinToCarbRatio)
Mockito.`when`(profileFunction.getUnits()).thenReturn(GlucoseUnit.MGDL)
Mockito.`when`(iobCobCalculator.calculateIobFromBolus()).thenReturn(IobTotal(System.currentTimeMillis())) Mockito.`when`(iobCobCalculator.calculateIobFromBolus()).thenReturn(IobTotal(System.currentTimeMillis()))
Mockito.`when`(iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended()).thenReturn(IobTotal(System.currentTimeMillis())) Mockito.`when`(iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended()).thenReturn(IobTotal(System.currentTimeMillis()))
testPumpPlugin.pumpDescription = PumpDescription().also { testPumpPlugin.pumpDescription = PumpDescription().also {

View file

@ -47,6 +47,7 @@ public class LocalInsightFragment extends DaggerFragment implements View.OnClick
@Inject FabricPrivacy fabricPrivacy; @Inject FabricPrivacy fabricPrivacy;
@Inject DateUtil dateUtil; @Inject DateUtil dateUtil;
@Inject AapsSchedulers aapsSchedulers; @Inject AapsSchedulers aapsSchedulers;
@Inject DecimalFormatter decimalFormatter;
private final CompositeDisposable disposable = new CompositeDisposable(); private final CompositeDisposable disposable = new CompositeDisposable();
@ -289,7 +290,7 @@ public class LocalInsightFragment extends DaggerFragment implements View.OnClick
if (cartridgeStatus == null) return; if (cartridgeStatus == null) return;
String status; String status;
if (cartridgeStatus.isInserted()) if (cartridgeStatus.isInserted())
status = DecimalFormatter.INSTANCE.to2Decimal(cartridgeStatus.getRemainingAmount()) + "U"; status = decimalFormatter.to2Decimal(cartridgeStatus.getRemainingAmount()) + "U";
else status = rh.gs(R.string.not_inserted); else status = rh.gs(R.string.not_inserted);
statusItems.add(getStatusItem(rh.gs(info.nightscout.core.ui.R.string.reservoir_label), status)); statusItems.add(getStatusItem(rh.gs(info.nightscout.core.ui.R.string.reservoir_label), status));
} }
@ -297,16 +298,16 @@ public class LocalInsightFragment extends DaggerFragment implements View.OnClick
private void getTDDItems(List<View> statusItems) { private void getTDDItems(List<View> statusItems) {
if (localInsightPlugin.getTotalDailyDose() == null) return; if (localInsightPlugin.getTotalDailyDose() == null) return;
TotalDailyDose tdd = localInsightPlugin.getTotalDailyDose(); TotalDailyDose tdd = localInsightPlugin.getTotalDailyDose();
statusItems.add(getStatusItem(rh.gs(R.string.tdd_bolus), DecimalFormatter.INSTANCE.to2Decimal(tdd.getBolus()))); statusItems.add(getStatusItem(rh.gs(R.string.tdd_bolus), decimalFormatter.to2Decimal(tdd.getBolus())));
statusItems.add(getStatusItem(rh.gs(R.string.tdd_basal), DecimalFormatter.INSTANCE.to2Decimal(tdd.getBasal()))); statusItems.add(getStatusItem(rh.gs(R.string.tdd_basal), decimalFormatter.to2Decimal(tdd.getBasal())));
statusItems.add(getStatusItem(rh.gs(info.nightscout.core.ui.R.string.tdd_total), DecimalFormatter.INSTANCE.to2Decimal(tdd.getBolusAndBasal()))); statusItems.add(getStatusItem(rh.gs(info.nightscout.core.ui.R.string.tdd_total), decimalFormatter.to2Decimal(tdd.getBolusAndBasal())));
} }
private void getBaseBasalRateItem(List<View> statusItems) { private void getBaseBasalRateItem(List<View> statusItems) {
if (localInsightPlugin.getActiveBasalRate() == null) return; if (localInsightPlugin.getActiveBasalRate() == null) return;
ActiveBasalRate activeBasalRate = localInsightPlugin.getActiveBasalRate(); ActiveBasalRate activeBasalRate = localInsightPlugin.getActiveBasalRate();
statusItems.add(getStatusItem(rh.gs(info.nightscout.core.ui.R.string.base_basal_rate_label), statusItems.add(getStatusItem(rh.gs(info.nightscout.core.ui.R.string.base_basal_rate_label),
DecimalFormatter.INSTANCE.to2Decimal(activeBasalRate.getActiveBasalRate()) + " U/h (" + activeBasalRate.getActiveBasalProfileName() + ")")); decimalFormatter.to2Decimal(activeBasalRate.getActiveBasalRate()) + " U/h (" + activeBasalRate.getActiveBasalProfileName() + ")"));
} }
private void getTBRItem(List<View> statusItems) { private void getTBRItem(List<View> statusItems) {

View file

@ -41,6 +41,7 @@ open class APSResultObject @Inject constructor(val injector: HasAndroidInjector)
@Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var rh: ResourceHelper @Inject lateinit var rh: ResourceHelper
@Inject lateinit var dateUtil: DateUtil @Inject lateinit var dateUtil: DateUtil
@Inject lateinit var decimalFormatter: DecimalFormatter
override var date: Long = 0 override var date: Long = 0
override var reason: String = "" override var reason: String = ""
@ -67,7 +68,7 @@ open class APSResultObject @Inject constructor(val injector: HasAndroidInjector)
} }
override val carbsRequiredText: String override val carbsRequiredText: String
get() = rh.gs(info.nightscout.core.ui.R.string.carbsreq, carbsReq, carbsReqWithin) get() = rh.gs(R.string.carbsreq, carbsReq, carbsReqWithin)
override fun toString(): String { override fun toString(): String {
val pump = activePlugin.activePump val pump = activePlugin.activePump
@ -75,18 +76,18 @@ open class APSResultObject @Inject constructor(val injector: HasAndroidInjector)
// rate // rate
var ret: String = if (rate == 0.0 && duration == 0) "${rh.gs(info.nightscout.core.ui.R.string.cancel_temp)} " var ret: String = if (rate == 0.0 && duration == 0) "${rh.gs(info.nightscout.core.ui.R.string.cancel_temp)} "
else if (rate == -1.0) "${rh.gs(info.nightscout.core.ui.R.string.let_temp_basal_run)}\n" else if (rate == -1.0) "${rh.gs(info.nightscout.core.ui.R.string.let_temp_basal_run)}\n"
else if (usePercent) "${rh.gs(info.nightscout.core.ui.R.string.rate)}: ${DecimalFormatter.to2Decimal(percent.toDouble())}% (${DecimalFormatter.to2Decimal(percent * pump.baseBasalRate / 100.0)} U/h) " + else if (usePercent) "${rh.gs(info.nightscout.core.ui.R.string.rate)}: ${decimalFormatter.to2Decimal(percent.toDouble())}% (${decimalFormatter.to2Decimal(percent * pump.baseBasalRate / 100.0)} U/h) " +
"${rh.gs(info.nightscout.core.ui.R.string.duration)}: ${DecimalFormatter.to2Decimal(duration.toDouble())} min " "${rh.gs(info.nightscout.core.ui.R.string.duration)}: ${decimalFormatter.to2Decimal(duration.toDouble())} min "
else "${rh.gs(info.nightscout.core.ui.R.string.rate)}: ${DecimalFormatter.to2Decimal(rate)} U/h (${DecimalFormatter.to2Decimal(rate / pump.baseBasalRate * 100)}%) " + else "${rh.gs(info.nightscout.core.ui.R.string.rate)}: ${decimalFormatter.to2Decimal(rate)} U/h (${decimalFormatter.to2Decimal(rate / pump.baseBasalRate * 100)}%) " +
"${rh.gs(info.nightscout.core.ui.R.string.duration)}: ${DecimalFormatter.to2Decimal(duration.toDouble())} min " "${rh.gs(info.nightscout.core.ui.R.string.duration)}: ${decimalFormatter.to2Decimal(duration.toDouble())} min "
// smb // smb
if (smb != 0.0) ret += "SMB: ${DecimalFormatter.toPumpSupportedBolus(smb, activePlugin.activePump, rh)} " if (smb != 0.0) ret += "SMB: ${decimalFormatter.toPumpSupportedBolus(smb, activePlugin.activePump.pumpDescription.bolusStep)} "
if (isCarbsRequired) { if (isCarbsRequired) {
ret += "$carbsRequiredText " ret += "$carbsRequiredText "
} }
// reason // reason
ret += rh.gs(info.nightscout.core.ui.R.string.reason) + ": " + reason ret += rh.gs(R.string.reason) + ": " + reason
return ret return ret
} }
return if (isCarbsRequired) { return if (isCarbsRequired) {
@ -99,24 +100,26 @@ open class APSResultObject @Inject constructor(val injector: HasAndroidInjector)
if (isChangeRequested) { if (isChangeRequested) {
// rate // rate
var ret: String = var ret: String =
if (rate == 0.0 && duration == 0) rh.gs(info.nightscout.core.ui.R.string.cancel_temp) + "<br>" else if (rate == -1.0) rh.gs(info.nightscout.core.ui.R.string.let_temp_basal_run) + "<br>" else if (usePercent) "<b>" + rh.gs(info.nightscout.core.ui.R.string.rate) + "</b>: " + DecimalFormatter.to2Decimal( if (rate == 0.0 && duration == 0) rh.gs(info.nightscout.core.ui.R.string.cancel_temp) + "<br>" else if (rate == -1.0) rh.gs(info.nightscout.core.ui.R.string.let_temp_basal_run) + "<br>" else if (usePercent) "<b>" + rh.gs(
info.nightscout.core.ui.R.string.rate
) + "</b>: " + decimalFormatter.to2Decimal(
percent.toDouble() percent.toDouble()
) + "% " + ) + "% " +
"(" + DecimalFormatter.to2Decimal(percent * pump.baseBasalRate / 100.0) + " U/h)<br>" + "(" + decimalFormatter.to2Decimal(percent * pump.baseBasalRate / 100.0) + " U/h)<br>" +
"<b>" + rh.gs(info.nightscout.core.ui.R.string.duration) + "</b>: " + DecimalFormatter.to2Decimal(duration.toDouble()) + " min<br>" else "<b>" + rh.gs(info.nightscout.core.ui.R.string.rate) + "</b>: " + DecimalFormatter.to2Decimal( "<b>" + rh.gs(info.nightscout.core.ui.R.string.duration) + "</b>: " + decimalFormatter.to2Decimal(duration.toDouble()) + " min<br>" else "<b>" + rh.gs(info.nightscout.core.ui.R.string.rate) + "</b>: " + decimalFormatter.to2Decimal(
rate rate
) + " U/h " + ) + " U/h " +
"(" + DecimalFormatter.to2Decimal(rate / pump.baseBasalRate * 100.0) + "%) <br>" + "(" + decimalFormatter.to2Decimal(rate / pump.baseBasalRate * 100.0) + "%) <br>" +
"<b>" + rh.gs(info.nightscout.core.ui.R.string.duration) + "</b>: " + DecimalFormatter.to2Decimal(duration.toDouble()) + " min<br>" "<b>" + rh.gs(info.nightscout.core.ui.R.string.duration) + "</b>: " + decimalFormatter.to2Decimal(duration.toDouble()) + " min<br>"
// smb // smb
if (smb != 0.0) ret += "<b>" + "SMB" + "</b>: " + DecimalFormatter.toPumpSupportedBolus(smb, activePlugin.activePump, rh) + "<br>" if (smb != 0.0) ret += "<b>" + "SMB" + "</b>: " + decimalFormatter.toPumpSupportedBolus(smb, activePlugin.activePump.pumpDescription.bolusStep) + "<br>"
if (isCarbsRequired) { if (isCarbsRequired) {
ret += "$carbsRequiredText<br>" ret += "$carbsRequiredText<br>"
} }
// reason // reason
ret += "<b>" + rh.gs(info.nightscout.core.ui.R.string.reason) + "</b>: " + reason.replace("<", "&lt;").replace(">", "&gt;") ret += "<b>" + rh.gs(R.string.reason) + "</b>: " + reason.replace("<", "&lt;").replace(">", "&gt;")
return HtmlHelper.fromHtml(ret) return HtmlHelper.fromHtml(ret)
} }
return if (isCarbsRequired) { return if (isCarbsRequired) {

View file

@ -17,6 +17,7 @@ import info.nightscout.core.pump.toHtml
import info.nightscout.core.utils.fabric.FabricPrivacy import info.nightscout.core.utils.fabric.FabricPrivacy
import info.nightscout.interfaces.aps.Loop import info.nightscout.interfaces.aps.Loop
import info.nightscout.interfaces.constraints.Constraint import info.nightscout.interfaces.constraints.Constraint
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.interfaces.utils.HtmlHelper import info.nightscout.interfaces.utils.HtmlHelper
import info.nightscout.plugins.aps.R import info.nightscout.plugins.aps.R
import info.nightscout.plugins.aps.databinding.LoopFragmentBinding import info.nightscout.plugins.aps.databinding.LoopFragmentBinding
@ -42,6 +43,7 @@ class LoopFragment : DaggerFragment(), MenuProvider {
@Inject lateinit var fabricPrivacy: FabricPrivacy @Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var loop: Loop @Inject lateinit var loop: Loop
@Inject lateinit var dateUtil: DateUtil @Inject lateinit var dateUtil: DateUtil
@Inject lateinit var decimalFormatter: DecimalFormatter
@Suppress("PrivatePropertyName") @Suppress("PrivatePropertyName")
private val ID_MENU_RUN = 501 private val ID_MENU_RUN = 501
@ -64,7 +66,11 @@ class LoopFragment : DaggerFragment(), MenuProvider {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
binding.swipeRefresh.setColorSchemeColors(rh.gac(context, android.R.attr.colorPrimaryDark), rh.gac(context, android.R.attr.colorPrimary), rh.gac(context,com.google.android.material.R.attr.colorSecondary)) binding.swipeRefresh.setColorSchemeColors(
rh.gac(context, android.R.attr.colorPrimaryDark),
rh.gac(context, android.R.attr.colorPrimary),
rh.gac(context, com.google.android.material.R.attr.colorSecondary)
)
binding.swipeRefresh.setOnRefreshListener { binding.swipeRefresh.setOnRefreshListener {
binding.lastrun.text = rh.gs(R.string.executing) binding.lastrun.text = rh.gs(R.string.executing)
handler.post { handler.post {
@ -137,9 +143,9 @@ class LoopFragment : DaggerFragment(), MenuProvider {
binding.tbrrequestTime.text = dateUtil.dateAndTimeAndSecondsString(it.lastTBRRequest) binding.tbrrequestTime.text = dateUtil.dateAndTimeAndSecondsString(it.lastTBRRequest)
binding.tbrexecutionTime.text = dateUtil.dateAndTimeAndSecondsString(it.lastTBREnact) binding.tbrexecutionTime.text = dateUtil.dateAndTimeAndSecondsString(it.lastTBREnact)
binding.tbrsetbypump.text = it.tbrSetByPump?.let { tbrSetByPump -> HtmlHelper.fromHtml(tbrSetByPump.toHtml(rh)) } binding.tbrsetbypump.text = it.tbrSetByPump?.let { tbrSetByPump -> HtmlHelper.fromHtml(tbrSetByPump.toHtml(rh, decimalFormatter)) }
?: "" ?: ""
binding.smbsetbypump.text = it.smbSetByPump?.let { smbSetByPump -> HtmlHelper.fromHtml(smbSetByPump.toHtml(rh)) } binding.smbsetbypump.text = it.smbSetByPump?.let { smbSetByPump -> HtmlHelper.fromHtml(smbSetByPump.toHtml(rh, decimalFormatter)) }
?: "" ?: ""
var constraints = var constraints =

View file

@ -22,6 +22,7 @@ import info.nightscout.plugins.aps.utils.ScriptReader
import info.nightscout.rx.logging.AAPSLogger import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag import info.nightscout.rx.logging.LTag
import info.nightscout.shared.SafeParse import info.nightscout.shared.SafeParse
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP
import org.json.JSONArray import org.json.JSONArray
import org.json.JSONException import org.json.JSONException
@ -48,6 +49,7 @@ class DetermineBasalAdapterSMBDynamicISFJS internal constructor(private val scri
@Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var iobCobCalculator: IobCobCalculator @Inject lateinit var iobCobCalculator: IobCobCalculator
@Inject lateinit var activePlugin: ActivePlugin @Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var profileUtil: ProfileUtil
private var profile = JSONObject() private var profile = JSONObject()
private var mGlucoseStatus = JSONObject() private var mGlucoseStatus = JSONObject()
@ -202,7 +204,7 @@ class DetermineBasalAdapterSMBDynamicISFJS internal constructor(private val scri
this.profile.put("sens", profile.getIsfMgdl()) this.profile.put("sens", profile.getIsfMgdl())
this.profile.put("max_daily_safety_multiplier", sp.getInt(R.string.key_openapsama_max_daily_safety_multiplier, 3)) this.profile.put("max_daily_safety_multiplier", sp.getInt(R.string.key_openapsama_max_daily_safety_multiplier, 3))
this.profile.put("current_basal_safety_multiplier", sp.getDouble(R.string.key_openapsama_current_basal_safety_multiplier, 4.0)) this.profile.put("current_basal_safety_multiplier", sp.getDouble(R.string.key_openapsama_current_basal_safety_multiplier, 4.0))
this.profile.put("lgsThreshold", Profile.toMgdl(sp.getDouble(R.string.key_lgs_threshold, 65.0))) this.profile.put("lgsThreshold", profileUtil.convertToMgdlDetect(sp.getDouble(R.string.key_lgs_threshold, 65.0)))
//mProfile.put("high_temptarget_raises_sensitivity", SP.getBoolean(R.string.key_high_temptarget_raises_sensitivity, SMBDefaults.high_temptarget_raises_sensitivity)); //mProfile.put("high_temptarget_raises_sensitivity", SP.getBoolean(R.string.key_high_temptarget_raises_sensitivity, SMBDefaults.high_temptarget_raises_sensitivity));
this.profile.put("high_temptarget_raises_sensitivity", sp.getBoolean(info.nightscout.core.utils.R.string.key_high_temptarget_raises_sensitivity, SMBDefaults.high_temptarget_raises_sensitivity)) this.profile.put("high_temptarget_raises_sensitivity", sp.getBoolean(info.nightscout.core.utils.R.string.key_high_temptarget_raises_sensitivity, SMBDefaults.high_temptarget_raises_sensitivity))

View file

@ -30,7 +30,6 @@ import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.logging.UserEntryLogger import info.nightscout.interfaces.logging.UserEntryLogger
import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.profile.Instantiator import info.nightscout.interfaces.profile.Instantiator
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.ui.UiInteraction import info.nightscout.interfaces.ui.UiInteraction
@ -47,6 +46,7 @@ import info.nightscout.rx.events.EventLocalProfileChanged
import info.nightscout.shared.SafeParse import info.nightscout.shared.SafeParse
import info.nightscout.shared.extensions.runOnUiThread import info.nightscout.shared.extensions.runOnUiThread
import info.nightscout.shared.extensions.toVisibility import info.nightscout.shared.extensions.toVisibility
import info.nightscout.shared.interfaces.ProfileUtil
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 info.nightscout.shared.utils.DateUtil import info.nightscout.shared.utils.DateUtil
@ -59,6 +59,7 @@ import javax.inject.Inject
class AutotuneFragment : DaggerFragment() { class AutotuneFragment : DaggerFragment() {
@Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var profileUtil: ProfileUtil
@Inject lateinit var autotunePlugin: AutotunePlugin @Inject lateinit var autotunePlugin: AutotunePlugin
@Inject lateinit var autotuneFS: AutotuneFS @Inject lateinit var autotuneFS: AutotuneFS
@Inject lateinit var sp: SP @Inject lateinit var sp: SP
@ -389,7 +390,7 @@ class AutotuneFragment : DaggerFragment() {
nl = "\n" nl = "\n"
} }
if (profile.isfSize > 1) { if (profile.isfSize > 1) {
warning += nl + rh.gs(info.nightscout.core.ui.R.string.autotune_isf_warning, profile.isfSize, Profile.fromMgdlToUnits(profile.isf, profileFunction.getUnits()), profileFunction.getUnits().asText) warning += nl + rh.gs(info.nightscout.core.ui.R.string.autotune_isf_warning, profile.isfSize, profileUtil.fromMgdlToUnits(profile.isf), profileFunction.getUnits().asText)
} }
} }
} }

View file

@ -12,7 +12,6 @@ import info.nightscout.interfaces.insulin.Insulin
import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.profile.Instantiator import info.nightscout.interfaces.profile.Instantiator
import info.nightscout.interfaces.profile.Profile import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.profile.ProfileStore import info.nightscout.interfaces.profile.ProfileStore
import info.nightscout.interfaces.profile.PureProfile import info.nightscout.interfaces.profile.PureProfile
import info.nightscout.interfaces.utils.Round import info.nightscout.interfaces.utils.Round
@ -20,6 +19,7 @@ import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.logging.AAPSLogger import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag import info.nightscout.rx.logging.LTag
import info.nightscout.shared.SafeParse import info.nightscout.shared.SafeParse
import info.nightscout.shared.interfaces.ProfileUtil
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 info.nightscout.shared.utils.DateUtil import info.nightscout.shared.utils.DateUtil
@ -36,7 +36,7 @@ class ATProfile(profile: Profile, var localInsulin: LocalInsulin, val injector:
@Inject lateinit var activePlugin: ActivePlugin @Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var sp: SP @Inject lateinit var sp: SP
@Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var profileUtil: ProfileUtil
@Inject lateinit var dateUtil: DateUtil @Inject lateinit var dateUtil: DateUtil
@Inject lateinit var config: Config @Inject lateinit var config: Config
@Inject lateinit var rxBus: RxBus @Inject lateinit var rxBus: RxBus
@ -81,7 +81,7 @@ class ATProfile(profile: Profile, var localInsulin: LocalInsulin, val injector:
fun isf(circadian: Boolean = false): JSONArray { fun isf(circadian: Boolean = false): JSONArray {
if (circadian) if (circadian)
return jsonArray(pumpProfile.isfBlocks, avgISF / pumpProfileAvgISF) return jsonArray(pumpProfile.isfBlocks, avgISF / pumpProfileAvgISF)
return jsonArray(Profile.fromMgdlToUnits(isf, profile.units)) return jsonArray(profileUtil.fromMgdlToUnits(isf, profile.units))
} }
fun getProfile(circadian: Boolean = false): PureProfile { fun getProfile(circadian: Boolean = false): PureProfile {
@ -162,7 +162,7 @@ class ATProfile(profile: Profile, var localInsulin: LocalInsulin, val injector:
json.put("sens", jsonArray(pumpProfile.isfBlocks, avgISF / pumpProfileAvgISF)) json.put("sens", jsonArray(pumpProfile.isfBlocks, avgISF / pumpProfileAvgISF))
json.put("carbratio", jsonArray(pumpProfile.icBlocks, avgIC / pumpProfileAvgIC)) json.put("carbratio", jsonArray(pumpProfile.icBlocks, avgIC / pumpProfileAvgIC))
} else { } else {
json.put("sens", jsonArray(Profile.fromMgdlToUnits(isf, profile.units))) json.put("sens", jsonArray(profileUtil.fromMgdlToUnits(isf, profile.units)))
json.put("carbratio", jsonArray(ic)) json.put("carbratio", jsonArray(ic))
} }
json.put("basal", jsonArray(basal)) json.put("basal", jsonArray(basal))

View file

@ -6,6 +6,7 @@ import info.nightscout.database.entities.data.TargetBlock
import info.nightscout.interfaces.GlucoseUnit import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.profile.PureProfile import info.nightscout.interfaces.profile.PureProfile
import info.nightscout.interfaces.utils.JsonHelper import info.nightscout.interfaces.utils.JsonHelper
import info.nightscout.plugins.general.autotune.data.ATProfile
import info.nightscout.plugins.general.autotune.data.PreppedGlucose import info.nightscout.plugins.general.autotune.data.PreppedGlucose
import info.nightscout.shared.utils.DateUtil import info.nightscout.shared.utils.DateUtil
import info.nightscout.shared.utils.T import info.nightscout.shared.utils.T
@ -85,7 +86,7 @@ class AutotuneCoreTest : TestBaseWithProfile() {
* OpenAPS profile for Autotune only have one ISF value and one IC value * OpenAPS profile for Autotune only have one ISF value and one IC value
*/ */
@Suppress("SpellCheckingInspection") @Suppress("SpellCheckingInspection")
private fun atProfileFromOapsJson(jsonObject: JSONObject, dateUtil: DateUtil, defaultUnits: String? = null): info.nightscout.plugins.general.autotune.data.ATProfile? { private fun atProfileFromOapsJson(jsonObject: JSONObject, dateUtil: DateUtil, defaultUnits: String? = null): ATProfile? {
try { try {
min5mCarbImpact = JsonHelper.safeGetDoubleAllowNull(jsonObject, "min_5m_carbimpact") ?: return null min5mCarbImpact = JsonHelper.safeGetDoubleAllowNull(jsonObject, "min_5m_carbimpact") ?: return null
autotuneMin = JsonHelper.safeGetDoubleAllowNull(jsonObject, "autosens_min") ?: return null autotuneMin = JsonHelper.safeGetDoubleAllowNull(jsonObject, "autosens_min") ?: return null
@ -122,7 +123,7 @@ class AutotuneCoreTest : TestBaseWithProfile() {
timeZone = timezone, timeZone = timezone,
dia = dia dia = dia
) )
return info.nightscout.plugins.general.autotune.data.ATProfile(ProfileSealed.Pure(pure), localInsulin, profileInjector).also { it.dateUtil = dateUtil } return ATProfile(ProfileSealed.Pure(pure), localInsulin, profileInjector).also { it.dateUtil = dateUtil; it.profileUtil = profileUtil }
} catch (ignored: Exception) { } catch (ignored: Exception) {
return null return null
} }

View file

@ -21,13 +21,13 @@ import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.GlucoseUnit import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.logging.UserEntryLogger import info.nightscout.interfaces.logging.UserEntryLogger
import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.pump.PumpEnactResult import info.nightscout.interfaces.pump.PumpEnactResult
import info.nightscout.interfaces.queue.Callback import info.nightscout.interfaces.queue.Callback
import info.nightscout.interfaces.utils.JsonHelper import info.nightscout.interfaces.utils.JsonHelper
import info.nightscout.interfaces.utils.JsonHelper.safeGetDouble import info.nightscout.interfaces.utils.JsonHelper.safeGetDouble
import info.nightscout.rx.logging.LTag import info.nightscout.rx.logging.LTag
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.utils.DateUtil import info.nightscout.shared.utils.DateUtil
import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.kotlin.plusAssign import io.reactivex.rxjava3.kotlin.plusAssign
@ -42,6 +42,7 @@ class ActionStartTempTarget(injector: HasAndroidInjector) : Action(injector) {
@Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var dateUtil: DateUtil @Inject lateinit var dateUtil: DateUtil
@Inject lateinit var uel: UserEntryLogger @Inject lateinit var uel: UserEntryLogger
@Inject lateinit var profileUtil: ProfileUtil
private val disposable = CompositeDisposable() private val disposable = CompositeDisposable()
@ -53,7 +54,7 @@ class ActionStartTempTarget(injector: HasAndroidInjector) : Action(injector) {
} }
override fun friendlyName(): Int = R.string.starttemptarget override fun friendlyName(): Int = R.string.starttemptarget
override fun shortDescription(): String = rh.gs(R.string.starttemptarget) + ": " + tt().friendlyDescription(value.units, rh) override fun shortDescription(): String = rh.gs(R.string.starttemptarget) + ": " + tt().friendlyDescription(value.units, rh, profileUtil)
@DrawableRes override fun icon(): Int = info.nightscout.core.main.R.drawable.ic_temptarget_high @DrawableRes override fun icon(): Int = info.nightscout.core.main.R.drawable.ic_temptarget_high
override fun doAction(callback: Callback) { override fun doAction(callback: Callback) {
@ -110,8 +111,8 @@ class ActionStartTempTarget(injector: HasAndroidInjector) : Action(injector) {
timestamp = dateUtil.now(), timestamp = dateUtil.now(),
duration = TimeUnit.MINUTES.toMillis(duration.getMinutes().toLong()), duration = TimeUnit.MINUTES.toMillis(duration.getMinutes().toLong()),
reason = TemporaryTarget.Reason.AUTOMATION, reason = TemporaryTarget.Reason.AUTOMATION,
lowTarget = Profile.toMgdl(value.value, value.units), lowTarget = profileUtil.convertToMgdl(value.value, value.units),
highTarget = Profile.toMgdl(value.value, value.units) highTarget = profileUtil.convertToMgdl(value.value, value.units)
) )
override fun isValid(): Boolean = override fun isValid(): Boolean =

View file

@ -23,6 +23,7 @@ import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.logging.AAPSLogger import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag import info.nightscout.rx.logging.LTag
import info.nightscout.shared.interfaces.ProfileUtil
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 info.nightscout.shared.utils.DateUtil import info.nightscout.shared.utils.DateUtil
@ -35,6 +36,7 @@ abstract class Trigger(val injector: HasAndroidInjector) {
@Inject lateinit var rxBus: RxBus @Inject lateinit var rxBus: RxBus
@Inject lateinit var rh: ResourceHelper @Inject lateinit var rh: ResourceHelper
@Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var profileUtil: ProfileUtil
@Inject lateinit var sp: SP @Inject lateinit var sp: SP
@Inject lateinit var locationDataContainer: LastLocationDataContainer @Inject lateinit var locationDataContainer: LastLocationDataContainer
@Inject lateinit var repository: AppRepository @Inject lateinit var repository: AppRepository

View file

@ -11,7 +11,6 @@ import info.nightscout.automation.elements.LayoutBuilder
import info.nightscout.automation.elements.StaticLabel import info.nightscout.automation.elements.StaticLabel
import info.nightscout.interfaces.Constants import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.GlucoseUnit import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.utils.JsonHelper import info.nightscout.interfaces.utils.JsonHelper
import info.nightscout.rx.logging.LTag import info.nightscout.rx.logging.LTag
import org.json.JSONObject import org.json.JSONObject
@ -56,7 +55,7 @@ class TriggerBg(injector: HasAndroidInjector) : Trigger(injector) {
aapsLogger.debug(LTag.AUTOMATION, "NOT ready for execution: " + friendlyDescription()) aapsLogger.debug(LTag.AUTOMATION, "NOT ready for execution: " + friendlyDescription())
return false return false
} }
if (comparator.value.check(glucoseStatus.glucose, Profile.toMgdl(bg.value, bg.units))) { if (comparator.value.check(glucoseStatus.glucose, profileUtil.convertToMgdl(bg.value, bg.units))) {
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription()) aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
return true return true
} }

View file

@ -12,7 +12,6 @@ import info.nightscout.automation.elements.LayoutBuilder
import info.nightscout.automation.elements.StaticLabel import info.nightscout.automation.elements.StaticLabel
import info.nightscout.interfaces.Constants import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.GlucoseUnit import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.utils.JsonHelper import info.nightscout.interfaces.utils.JsonHelper
import info.nightscout.rx.logging.LTag import info.nightscout.rx.logging.LTag
import org.json.JSONObject import org.json.JSONObject
@ -78,7 +77,7 @@ class TriggerDelta(injector: HasAndroidInjector) : Trigger(injector) {
DeltaType.LONG_AVERAGE -> glucoseStatus.longAvgDelta DeltaType.LONG_AVERAGE -> glucoseStatus.longAvgDelta
else -> glucoseStatus.delta else -> glucoseStatus.delta
} }
if (comparator.value.check(calculatedDelta, Profile.toMgdl(delta.value, units))) { if (comparator.value.check(calculatedDelta, profileUtil.convertToMgdl(delta.value, units))) {
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: delta is " + calculatedDelta + " " + friendlyDescription()) aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: delta is " + calculatedDelta + " " + friendlyDescription())
return true return true
} }

View file

@ -12,7 +12,6 @@ import info.nightscout.automation.elements.StaticLabel
import info.nightscout.database.ValueWrapper import info.nightscout.database.ValueWrapper
import info.nightscout.interfaces.Constants import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.GlucoseUnit import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.utils.JsonHelper import info.nightscout.interfaces.utils.JsonHelper
import info.nightscout.rx.logging.LTag import info.nightscout.rx.logging.LTag
import org.json.JSONObject import org.json.JSONObject
@ -53,7 +52,7 @@ class TriggerTempTargetValue(injector: HasAndroidInjector) : Trigger(injector) {
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription()) aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
return true return true
} }
if (tt is ValueWrapper.Existing && comparator.value.check(tt.value.lowTarget, Profile.toMgdl(ttValue.value, ttValue.units))) { if (tt is ValueWrapper.Existing && comparator.value.check(tt.value.lowTarget, profileUtil.convertToMgdl(ttValue.value, ttValue.units))) {
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription()) aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
return true return true
} }

View file

@ -101,6 +101,7 @@ ActionsTestBase : TestBaseWithProfile() {
it.profileFunction = profileFunction it.profileFunction = profileFunction
it.uel = uel it.uel = uel
it.dateUtil = dateUtil it.dateUtil = dateUtil
it.profileUtil = profileUtil
} }
if (it is ActionSendSMS) { if (it is ActionSendSMS) {
it.aapsLogger = aapsLogger it.aapsLogger = aapsLogger

View file

@ -39,8 +39,9 @@ open class TriggerTestBase : TestBaseWithProfile() {
it.repository = repository it.repository = repository
it.activePlugin = activePlugin it.activePlugin = activePlugin
it.iobCobCalculator = iobCobCalculator it.iobCobCalculator = iobCobCalculator
it.glucoseStatusProvider = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculator, dateUtil) it.glucoseStatusProvider = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculator, dateUtil, decimalFormatter)
it.dateUtil = dateUtil it.dateUtil = dateUtil
it.profileUtil = profileUtil
} }
if (it is TriggerBg) { if (it is TriggerBg) {
it.profileFunction = profileFunction it.profileFunction = profileFunction

View file

@ -11,18 +11,17 @@ import info.nightscout.configuration.setupwizard.SWNumberValidator
import info.nightscout.core.ui.elements.NumberPicker import info.nightscout.core.ui.elements.NumberPicker
import info.nightscout.interfaces.Constants import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.GlucoseUnit import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.shared.SafeParse import info.nightscout.shared.SafeParse
import info.nightscout.shared.interfaces.ProfileUtil
import java.text.DecimalFormat import java.text.DecimalFormat
import javax.inject.Inject import javax.inject.Inject
class SWEditNumberWithUnits(injector: HasAndroidInjector, private val init: Double, private val minMmol: Double, private val maxMmol: Double) : SWItem(injector, Type.UNIT_NUMBER) { class SWEditNumberWithUnits(injector: HasAndroidInjector, private val init: Double, private val minMmol: Double, private val maxMmol: Double) : SWItem(injector, Type.UNIT_NUMBER) {
@Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var profileUtil: ProfileUtil
private val validator: SWNumberValidator = private val validator: SWNumberValidator =
if (profileFunction.getUnits() == GlucoseUnit.MMOL) if (profileUtil.units == GlucoseUnit.MMOL)
SWNumberValidator { value -> value in minMmol..maxMmol } SWNumberValidator { value -> value in minMmol..maxMmol }
else else
SWNumberValidator { value -> value in minMmol * Constants.MMOLL_TO_MGDL..maxMmol * Constants.MMOLL_TO_MGDL } SWNumberValidator { value -> value in minMmol * Constants.MMOLL_TO_MGDL..maxMmol * Constants.MMOLL_TO_MGDL }
@ -46,9 +45,9 @@ class SWEditNumberWithUnits(injector: HasAndroidInjector, private val init: Doub
l.setTypeface(l.typeface, Typeface.BOLD) l.setTypeface(l.typeface, Typeface.BOLD)
layout.addView(l) layout.addView(l)
var initValue = sp.getDouble(preferenceId, init) var initValue = sp.getDouble(preferenceId, init)
initValue = Profile.toCurrentUnits(profileFunction.getUnits(), initValue) initValue = profileUtil.valueInCurrentUnitsDetect(initValue)
val numberPicker = NumberPicker(context) val numberPicker = NumberPicker(context)
if (profileFunction.getUnits() == GlucoseUnit.MMOL) if (profileUtil.units == GlucoseUnit.MMOL)
numberPicker.setParams(initValue, minMmol, maxMmol, 0.1, DecimalFormat("0.0"), false, null, watcher) numberPicker.setParams(initValue, minMmol, maxMmol, 0.1, DecimalFormat("0.0"), false, null, watcher)
else else
numberPicker.setParams(initValue, minMmol * Constants.MMOLL_TO_MGDL, maxMmol * Constants.MMOLL_TO_MGDL, 1.0, DecimalFormat("0"), false, null, watcher) numberPicker.setParams(initValue, minMmol * Constants.MMOLL_TO_MGDL, maxMmol * Constants.MMOLL_TO_MGDL, 1.0, DecimalFormat("0"), false, null, watcher)

View file

@ -7,8 +7,8 @@ import info.nightscout.core.utils.extensions.putString
import info.nightscout.core.utils.extensions.storeDouble import info.nightscout.core.utils.extensions.storeDouble
import info.nightscout.core.utils.extensions.storeInt import info.nightscout.core.utils.extensions.storeInt
import info.nightscout.core.utils.extensions.storeString import info.nightscout.core.utils.extensions.storeString
import info.nightscout.interfaces.Config
import info.nightscout.interfaces.ApsMode import info.nightscout.interfaces.ApsMode
import info.nightscout.interfaces.Config
import info.nightscout.interfaces.constraints.Constraint import info.nightscout.interfaces.constraints.Constraint
import info.nightscout.interfaces.constraints.Constraints import info.nightscout.interfaces.constraints.Constraints
import info.nightscout.interfaces.constraints.Safety import info.nightscout.interfaces.constraints.Safety
@ -25,7 +25,6 @@ import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.interfaces.utils.HardLimits import info.nightscout.interfaces.utils.HardLimits
import info.nightscout.interfaces.utils.Round import info.nightscout.interfaces.utils.Round
import info.nightscout.plugins.constraints.R import info.nightscout.plugins.constraints.R
import info.nightscout.rx.bus.RxBus
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
@ -40,22 +39,22 @@ class SafetyPlugin @Inject constructor(
aapsLogger: AAPSLogger, aapsLogger: AAPSLogger,
rh: ResourceHelper, rh: ResourceHelper,
private val sp: SP, private val sp: SP,
private val rxBus: RxBus,
private val constraintChecker: Constraints, private val constraintChecker: Constraints,
private val activePlugin: ActivePlugin, private val activePlugin: ActivePlugin,
private val hardLimits: HardLimits, private val hardLimits: HardLimits,
private val config: Config, private val config: Config,
private val iobCobCalculator: IobCobCalculator, private val iobCobCalculator: IobCobCalculator,
private val dateUtil: DateUtil, private val dateUtil: DateUtil,
private val uiInteraction: UiInteraction private val uiInteraction: UiInteraction,
private val decimalFormatter: DecimalFormatter
) : PluginBase( ) : PluginBase(
PluginDescription() PluginDescription()
.mainType(PluginType.CONSTRAINTS) .mainType(PluginType.CONSTRAINTS)
.neverVisible(true) .neverVisible(true)
.alwaysEnabled(true) .alwaysEnabled(true)
.showInList(false) .showInList(false)
.pluginName(R.string.safety) .pluginName(R.string.safety)
.preferencesId(R.xml.pref_safety), .preferencesId(R.xml.pref_safety),
aapsLogger, rh, injector aapsLogger, rh, injector
), Constraints, Safety { ), Constraints, Safety {
@ -115,7 +114,11 @@ class SafetyPlugin @Inject constructor(
override fun applyBasalPercentConstraints(percentRate: Constraint<Int>, profile: Profile): Constraint<Int> { override fun applyBasalPercentConstraints(percentRate: Constraint<Int>, profile: Profile): Constraint<Int> {
val currentBasal = profile.getBasal() val currentBasal = profile.getBasal()
val absoluteRate = currentBasal * (percentRate.originalValue().toDouble() / 100) val absoluteRate = currentBasal * (percentRate.originalValue().toDouble() / 100)
percentRate.addReason("Percent rate " + percentRate.originalValue() + "% recalculated to " + DecimalFormatter.to2Decimal(absoluteRate) + " U/h with current basal " + DecimalFormatter.to2Decimal(currentBasal) + " U/h", this) percentRate.addReason(
"Percent rate " + percentRate.originalValue() + "% recalculated to " + decimalFormatter.to2Decimal(absoluteRate) + " U/h with current basal " + decimalFormatter.to2Decimal(
currentBasal
) + " U/h", this
)
val absoluteConstraint = Constraint(absoluteRate) val absoluteConstraint = Constraint(absoluteRate)
applyBasalConstraints(absoluteConstraint, profile) applyBasalConstraints(absoluteConstraint, profile)
percentRate.copyReasons(absoluteConstraint) percentRate.copyReasons(absoluteConstraint)

View file

@ -29,6 +29,7 @@ import info.nightscout.interfaces.pump.actions.CustomAction
import info.nightscout.interfaces.queue.Callback import info.nightscout.interfaces.queue.Callback
import info.nightscout.interfaces.queue.CommandQueue import info.nightscout.interfaces.queue.CommandQueue
import info.nightscout.interfaces.ui.UiInteraction import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.plugins.R import info.nightscout.plugins.R
import info.nightscout.plugins.databinding.ActionsFragmentBinding import info.nightscout.plugins.databinding.ActionsFragmentBinding
import info.nightscout.plugins.general.overview.ui.StatusLightHandler import info.nightscout.plugins.general.overview.ui.StatusLightHandler
@ -57,6 +58,7 @@ class ActionsFragment : DaggerFragment() {
@Inject lateinit var sp: SP @Inject lateinit var sp: SP
@Inject lateinit var dateUtil: DateUtil @Inject lateinit var dateUtil: DateUtil
@Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var decimalFormatter: DecimalFormatter
@Inject lateinit var rh: ResourceHelper @Inject lateinit var rh: ResourceHelper
@Inject lateinit var statusLightHandler: StatusLightHandler @Inject lateinit var statusLightHandler: StatusLightHandler
@Inject lateinit var fabricPrivacy: FabricPrivacy @Inject lateinit var fabricPrivacy: FabricPrivacy
@ -243,7 +245,7 @@ class ActionsFragment : DaggerFragment() {
binding.extendedBolus.visibility = View.GONE binding.extendedBolus.visibility = View.GONE
binding.extendedBolusCancel.visibility = View.VISIBLE binding.extendedBolusCancel.visibility = View.VISIBLE
@Suppress("SetTextI18n") @Suppress("SetTextI18n")
binding.extendedBolusCancel.text = rh.gs(info.nightscout.core.ui.R.string.cancel) + " " + activeExtendedBolus.value.toStringMedium(dateUtil) binding.extendedBolusCancel.text = rh.gs(info.nightscout.core.ui.R.string.cancel) + " " + activeExtendedBolus.value.toStringMedium(dateUtil, decimalFormatter)
} else { } else {
binding.extendedBolus.visibility = View.VISIBLE binding.extendedBolus.visibility = View.VISIBLE
binding.extendedBolusCancel.visibility = View.GONE binding.extendedBolusCancel.visibility = View.GONE
@ -259,7 +261,7 @@ class ActionsFragment : DaggerFragment() {
binding.setTempBasal.visibility = View.GONE binding.setTempBasal.visibility = View.GONE
binding.cancelTempBasal.visibility = View.VISIBLE binding.cancelTempBasal.visibility = View.VISIBLE
@Suppress("SetTextI18n") @Suppress("SetTextI18n")
binding.cancelTempBasal.text = rh.gs(info.nightscout.core.ui.R.string.cancel) + " " + activeTemp.toStringShort() binding.cancelTempBasal.text = rh.gs(info.nightscout.core.ui.R.string.cancel) + " " + activeTemp.toStringShort(decimalFormatter)
} else { } else {
binding.setTempBasal.visibility = View.VISIBLE binding.setTempBasal.visibility = View.VISIBLE
binding.cancelTempBasal.visibility = View.GONE binding.cancelTempBasal.visibility = View.GONE

View file

@ -28,7 +28,6 @@ import com.jjoe64.graphview.GraphView
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import dagger.android.support.DaggerFragment import dagger.android.support.DaggerFragment
import info.nightscout.core.extensions.directionToIcon import info.nightscout.core.extensions.directionToIcon
import info.nightscout.core.extensions.valueToUnitsString
import info.nightscout.core.graph.OverviewData import info.nightscout.core.graph.OverviewData
import info.nightscout.core.iob.displayText import info.nightscout.core.iob.displayText
import info.nightscout.core.profile.ProfileSealed import info.nightscout.core.profile.ProfileSealed
@ -60,13 +59,13 @@ import info.nightscout.interfaces.overview.OverviewMenus
import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.plugin.PluginBase import info.nightscout.interfaces.plugin.PluginBase
import info.nightscout.interfaces.profile.DefaultValueHelper import info.nightscout.interfaces.profile.DefaultValueHelper
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.protection.ProtectionCheck import info.nightscout.interfaces.protection.ProtectionCheck
import info.nightscout.interfaces.pump.defs.PumpType import info.nightscout.interfaces.pump.defs.PumpType
import info.nightscout.interfaces.source.DexcomBoyda import info.nightscout.interfaces.source.DexcomBoyda
import info.nightscout.interfaces.source.XDripSource import info.nightscout.interfaces.source.XDripSource
import info.nightscout.interfaces.ui.UiInteraction import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.interfaces.utils.JsonHelper import info.nightscout.interfaces.utils.JsonHelper
import info.nightscout.interfaces.utils.TrendCalculator import info.nightscout.interfaces.utils.TrendCalculator
import info.nightscout.plugins.R import info.nightscout.plugins.R
@ -99,6 +98,7 @@ import info.nightscout.rx.weardata.EventData
import info.nightscout.shared.extensions.runOnUiThread import info.nightscout.shared.extensions.runOnUiThread
import info.nightscout.shared.extensions.toVisibility import info.nightscout.shared.extensions.toVisibility
import info.nightscout.shared.extensions.toVisibilityKeepSpace import info.nightscout.shared.extensions.toVisibilityKeepSpace
import info.nightscout.shared.interfaces.ProfileUtil
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 info.nightscout.shared.utils.DateUtil import info.nightscout.shared.utils.DateUtil
@ -120,6 +120,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
@Inject lateinit var rh: ResourceHelper @Inject lateinit var rh: ResourceHelper
@Inject lateinit var defaultValueHelper: DefaultValueHelper @Inject lateinit var defaultValueHelper: DefaultValueHelper
@Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var profileUtil: ProfileUtil
@Inject lateinit var constraintChecker: Constraints @Inject lateinit var constraintChecker: Constraints
@Inject lateinit var statusLightHandler: StatusLightHandler @Inject lateinit var statusLightHandler: StatusLightHandler
@Inject lateinit var processedDeviceStatusData: ProcessedDeviceStatusData @Inject lateinit var processedDeviceStatusData: ProcessedDeviceStatusData
@ -145,6 +146,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
@Inject lateinit var automation: Automation @Inject lateinit var automation: Automation
@Inject lateinit var bgQualityCheck: BgQualityCheck @Inject lateinit var bgQualityCheck: BgQualityCheck
@Inject lateinit var uiInteraction: UiInteraction @Inject lateinit var uiInteraction: UiInteraction
@Inject lateinit var decimalFormatter: DecimalFormatter
private val disposable = CompositeDisposable() private val disposable = CompositeDisposable()
@ -777,7 +779,6 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
fun updateBg() { fun updateBg() {
val units = profileFunction.getUnits()
val lastBg = overviewData.lastBg(iobCobCalculator.ads) val lastBg = overviewData.lastBg(iobCobCalculator.ads)
val lastBgColor = overviewData.lastBgColor(context, iobCobCalculator.ads) val lastBgColor = overviewData.lastBgColor(context, iobCobCalculator.ads)
val isActualBg = overviewData.isActualBg(iobCobCalculator.ads) val isActualBg = overviewData.isActualBg(iobCobCalculator.ads)
@ -787,7 +788,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
val lastBgDescription = overviewData.lastBgDescription(iobCobCalculator.ads) val lastBgDescription = overviewData.lastBgDescription(iobCobCalculator.ads)
runOnUiThread { runOnUiThread {
_binding ?: return@runOnUiThread _binding ?: return@runOnUiThread
binding.infoLayout.bg.text = lastBg?.valueToUnitsString(units) ?: "" binding.infoLayout.bg.text = profileUtil.fromMgdlToStringInUnits(lastBg?.value)
binding.infoLayout.bg.setTextColor(lastBgColor) binding.infoLayout.bg.setTextColor(lastBgColor)
trendArrow?.let { binding.infoLayout.arrow.setImageResource(it.directionToIcon()) } trendArrow?.let { binding.infoLayout.arrow.setImageResource(it.directionToIcon()) }
binding.infoLayout.arrow.visibility = (trendArrow != null).toVisibilityKeepSpace() binding.infoLayout.arrow.visibility = (trendArrow != null).toVisibilityKeepSpace()
@ -795,11 +796,11 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
binding.infoLayout.arrow.contentDescription = lastBgDescription + " " + rh.gs(info.nightscout.core.ui.R.string.and) + " " + trendDescription binding.infoLayout.arrow.contentDescription = lastBgDescription + " " + rh.gs(info.nightscout.core.ui.R.string.and) + " " + trendDescription
if (glucoseStatus != null) { if (glucoseStatus != null) {
binding.infoLayout.deltaLarge.text = Profile.toSignedUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units) binding.infoLayout.deltaLarge.text = profileUtil.fromMgdlToSignedStringInUnits(glucoseStatus.delta)
binding.infoLayout.deltaLarge.setTextColor(lastBgColor) binding.infoLayout.deltaLarge.setTextColor(lastBgColor)
binding.infoLayout.delta.text = Profile.toSignedUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units) binding.infoLayout.delta.text = profileUtil.fromMgdlToSignedStringInUnits(glucoseStatus.delta)
binding.infoLayout.avgDelta.text = Profile.toSignedUnitsString(glucoseStatus.shortAvgDelta, glucoseStatus.shortAvgDelta * Constants.MGDL_TO_MMOLL, units) binding.infoLayout.avgDelta.text = profileUtil.fromMgdlToSignedStringInUnits(glucoseStatus.shortAvgDelta)
binding.infoLayout.longAvgDelta.text = Profile.toSignedUnitsString(glucoseStatus.longAvgDelta, glucoseStatus.longAvgDelta * Constants.MGDL_TO_MMOLL, units) binding.infoLayout.longAvgDelta.text = profileUtil.fromMgdlToSignedStringInUnits(glucoseStatus.longAvgDelta)
} else { } else {
binding.infoLayout.deltaLarge.text = "" binding.infoLayout.deltaLarge.text = ""
binding.infoLayout.delta.text = "Δ " + rh.gs(info.nightscout.core.ui.R.string.value_unavailable_short) binding.infoLayout.delta.text = "Δ " + rh.gs(info.nightscout.core.ui.R.string.value_unavailable_short)
@ -915,7 +916,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
private fun updateIobCob() { private fun updateIobCob() {
val iobText = overviewData.iobText(iobCobCalculator) val iobText = overviewData.iobText(iobCobCalculator)
val iobDialogText = overviewData.iobDialogText(iobCobCalculator) val iobDialogText = overviewData.iobDialogText(iobCobCalculator)
val displayText = overviewData.cobInfo(iobCobCalculator).displayText(rh) val displayText = overviewData.cobInfo(iobCobCalculator).displayText(rh, decimalFormatter)
val lastCarbsTime = overviewData.lastCarbsTime val lastCarbsTime = overviewData.lastCarbsTime
runOnUiThread { runOnUiThread {
_binding ?: return@runOnUiThread _binding ?: return@runOnUiThread
@ -954,7 +955,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
binding.tempTarget, binding.tempTarget,
info.nightscout.core.ui.R.attr.ribbonTextWarningColor, info.nightscout.core.ui.R.attr.ribbonTextWarningColor,
info.nightscout.core.ui.R.attr.ribbonWarningColor, info.nightscout.core.ui.R.attr.ribbonWarningColor,
Profile.toTargetRangeString(tempTarget.lowTarget, tempTarget.highTarget, GlucoseUnit.MGDL, units) + " " + dateUtil.untilString(tempTarget.end, rh) profileUtil.toTargetRangeString(tempTarget.lowTarget, tempTarget.highTarget, GlucoseUnit.MGDL, units) + " " + dateUtil.untilString(tempTarget.end, rh)
) )
} else { } else {
// If the target is not the same as set in the profile then oref has overridden it // If the target is not the same as set in the profile then oref has overridden it
@ -967,14 +968,14 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
binding.tempTarget, binding.tempTarget,
info.nightscout.core.ui.R.attr.ribbonTextWarningColor, info.nightscout.core.ui.R.attr.ribbonTextWarningColor,
info.nightscout.core.ui.R.attr.tempTargetBackgroundColor, info.nightscout.core.ui.R.attr.tempTargetBackgroundColor,
Profile.toTargetRangeString(targetUsed, targetUsed, GlucoseUnit.MGDL, units) profileUtil.toTargetRangeString(targetUsed, targetUsed, GlucoseUnit.MGDL, units)
) )
} else { } else {
setRibbon( setRibbon(
binding.tempTarget, binding.tempTarget,
info.nightscout.core.ui.R.attr.ribbonTextDefaultColor, info.nightscout.core.ui.R.attr.ribbonTextDefaultColor,
info.nightscout.core.ui.R.attr.ribbonDefaultColor, info.nightscout.core.ui.R.attr.ribbonDefaultColor,
Profile.toTargetRangeString(profile.getTargetLowMgdl(), profile.getTargetHighMgdl(), GlucoseUnit.MGDL, units) profileUtil.toTargetRangeString(profile.getTargetLowMgdl(), profile.getTargetHighMgdl(), GlucoseUnit.MGDL, units)
) )
} }
} }
@ -1110,8 +1111,8 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
binding.infoLayout.variableSensitivity.text = binding.infoLayout.variableSensitivity.text =
String.format( String.format(
Locale.getDefault(), "%1$.1f→%2$.1f", Locale.getDefault(), "%1$.1f→%2$.1f",
Profile.toUnits(isfMgdl, isfMgdl * Constants.MGDL_TO_MMOLL, profileFunction.getUnits()), profileUtil.fromMgdlToUnits(isfMgdl, profileFunction.getUnits()),
Profile.toUnits(variableSens, variableSens * Constants.MGDL_TO_MMOLL, profileFunction.getUnits()) profileUtil.fromMgdlToUnits(variableSens, profileFunction.getUnits())
) )
binding.infoLayout.variableSensitivity.visibility = View.VISIBLE binding.infoLayout.variableSensitivity.visibility = View.VISIBLE
} else binding.infoLayout.variableSensitivity.visibility = View.GONE } else binding.infoLayout.variableSensitivity.visibility = View.GONE

View file

@ -32,7 +32,8 @@ class StatusLightHandler @Inject constructor(
private val warnColors: WarnColors, private val warnColors: WarnColors,
private val config: Config, private val config: Config,
private val repository: AppRepository, private val repository: AppRepository,
private val tddCalculator: TddCalculator private val tddCalculator: TddCalculator,
private val decimalFormatter: DecimalFormatter
) { ) {
private var handler = Handler(HandlerThread(this::class.simpleName + "Handler").also { it.start() }.looper) private var handler = Handler(HandlerThread(this::class.simpleName + "Handler").also { it.start() }.looper)
@ -112,7 +113,7 @@ class StatusLightHandler @Inject constructor(
private fun handleLevel(view: TextView?, criticalSetting: Int, criticalDefaultValue: Double, warnSetting: Int, warnDefaultValue: Double, level: Double, units: String) { private fun handleLevel(view: TextView?, criticalSetting: Int, criticalDefaultValue: Double, warnSetting: Int, warnDefaultValue: Double, level: Double, units: String) {
val resUrgent = sp.getDouble(criticalSetting, criticalDefaultValue) val resUrgent = sp.getDouble(criticalSetting, criticalDefaultValue)
val resWarn = sp.getDouble(warnSetting, warnDefaultValue) val resWarn = sp.getDouble(warnSetting, warnDefaultValue)
if (level > 0) view?.text = " " + DecimalFormatter.to0Decimal(level, units) if (level > 0) view?.text = " " + decimalFormatter.to0Decimal(level, units)
else view?.text = "" else view?.text = ""
warnColors.setColorInverse(view, level, resWarn, resUrgent) warnColors.setColorInverse(view, level, resWarn, resUrgent)
} }
@ -124,7 +125,7 @@ class StatusLightHandler @Inject constructor(
warnDefaultValue: Double, level: Double, units: String, maxReading: Double warnDefaultValue: Double, level: Double, units: String, maxReading: Double
) { ) {
if (level >= maxReading) { if (level >= maxReading) {
view?.text = DecimalFormatter.to0Decimal(maxReading, units) view?.text = decimalFormatter.to0Decimal(maxReading, units)
view?.setTextColor(rh.gac(view.context, info.nightscout.core.ui.R.attr.defaultTextColor)) view?.setTextColor(rh.gac(view.context, info.nightscout.core.ui.R.attr.defaultTextColor))
} else { } else {
handleLevel(view, criticalSetting, criticalDefaultValue, warnSetting, warnDefaultValue, level, units) handleLevel(view, criticalSetting, criticalDefaultValue, warnSetting, warnDefaultValue, level, units)
@ -139,7 +140,7 @@ class StatusLightHandler @Inject constructor(
tddCalculator.calculate(therapyEvent.value.timestamp, dateUtil.now(), allowMissingData = false)?.totalAmount ?: 0.0 tddCalculator.calculate(therapyEvent.value.timestamp, dateUtil.now(), allowMissingData = false)?.totalAmount ?: 0.0
} else 0.0 } else 0.0
runOnUiThread { runOnUiThread {
view?.text = DecimalFormatter.to0Decimal(usage, units) view?.text = decimalFormatter.to0Decimal(usage, units)
} }
} }
} }

View file

@ -8,12 +8,10 @@ import androidx.core.app.NotificationCompat
import androidx.core.app.RemoteInput import androidx.core.app.RemoteInput
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.core.extensions.toStringShort import info.nightscout.core.extensions.toStringShort
import info.nightscout.core.extensions.valueToUnitsString
import info.nightscout.core.iob.generateCOBString import info.nightscout.core.iob.generateCOBString
import info.nightscout.core.iob.round import info.nightscout.core.iob.round
import info.nightscout.core.utils.fabric.FabricPrivacy import info.nightscout.core.utils.fabric.FabricPrivacy
import info.nightscout.interfaces.Config import info.nightscout.interfaces.Config
import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.NotificationHolder import info.nightscout.interfaces.NotificationHolder
import info.nightscout.interfaces.iob.GlucoseStatusProvider import info.nightscout.interfaces.iob.GlucoseStatusProvider
import info.nightscout.interfaces.iob.IobCobCalculator import info.nightscout.interfaces.iob.IobCobCalculator
@ -21,7 +19,6 @@ import info.nightscout.interfaces.plugin.ActivePlugin
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.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.ui.IconsProvider import info.nightscout.interfaces.ui.IconsProvider
import info.nightscout.interfaces.utils.DecimalFormatter import info.nightscout.interfaces.utils.DecimalFormatter
@ -33,6 +30,7 @@ import info.nightscout.rx.events.EventInitializationChanged
import info.nightscout.rx.events.EventPreferenceChange import info.nightscout.rx.events.EventPreferenceChange
import info.nightscout.rx.events.EventRefreshOverview import info.nightscout.rx.events.EventRefreshOverview
import info.nightscout.rx.logging.AAPSLogger import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.interfaces.ResourceHelper
import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.kotlin.plusAssign import io.reactivex.rxjava3.kotlin.plusAssign
@ -47,6 +45,7 @@ class PersistentNotificationPlugin @Inject constructor(
rh: ResourceHelper, rh: ResourceHelper,
private val aapsSchedulers: AapsSchedulers, private val aapsSchedulers: AapsSchedulers,
private val profileFunction: ProfileFunction, private val profileFunction: ProfileFunction,
private val profileUtil: ProfileUtil,
private val fabricPrivacy: FabricPrivacy, private val fabricPrivacy: FabricPrivacy,
private val activePlugins: ActivePlugin, private val activePlugins: ActivePlugin,
private val iobCobCalculator: IobCobCalculator, private val iobCobCalculator: IobCobCalculator,
@ -56,7 +55,8 @@ class PersistentNotificationPlugin @Inject constructor(
private val dummyServiceHelper: DummyServiceHelper, private val dummyServiceHelper: DummyServiceHelper,
private val iconsProvider: IconsProvider, private val iconsProvider: IconsProvider,
private val glucoseStatusProvider: GlucoseStatusProvider, private val glucoseStatusProvider: GlucoseStatusProvider,
private val config: Config private val config: Config,
private val decimalFormatter: DecimalFormatter
) : PluginBase( ) : PluginBase(
PluginDescription() PluginDescription()
.mainType(PluginType.GENERAL) .mainType(PluginType.GENERAL)
@ -121,15 +121,14 @@ class PersistentNotificationPlugin @Inject constructor(
var unreadConversationBuilder: NotificationCompat.CarExtender.UnreadConversation.Builder? = null var unreadConversationBuilder: NotificationCompat.CarExtender.UnreadConversation.Builder? = null
if (profileFunction.isProfileValid("Notification")) { if (profileFunction.isProfileValid("Notification")) {
var line1aa: String var line1aa: String
val units = profileFunction.getUnits()
val lastBG = iobCobCalculator.ads.lastBg() val lastBG = iobCobCalculator.ads.lastBg()
val glucoseStatus = glucoseStatusProvider.glucoseStatusData val glucoseStatus = glucoseStatusProvider.glucoseStatusData
if (lastBG != null) { if (lastBG != null) {
line1aa = lastBG.valueToUnitsString(units) line1aa = profileUtil.fromMgdlToStringInUnits(lastBG.value)
line1 = line1aa line1 = line1aa
if (glucoseStatus != null) { if (glucoseStatus != null) {
line1 += (" Δ" + Profile.toSignedUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units) line1 += (" Δ" + profileUtil.fromMgdlToSignedStringInUnits(glucoseStatus.delta)
+ " avgΔ" + Profile.toSignedUnitsString(glucoseStatus.shortAvgDelta, glucoseStatus.shortAvgDelta * Constants.MGDL_TO_MMOLL, units)) + " avgΔ" + profileUtil.fromMgdlToSignedStringInUnits(glucoseStatus.shortAvgDelta))
line1aa += " " + lastBG.trendArrow.symbol line1aa += " " + lastBG.trendArrow.symbol
} else { } else {
line1 += " " + line1 += " " +
@ -143,22 +142,28 @@ class PersistentNotificationPlugin @Inject constructor(
} }
val activeTemp = iobCobCalculator.getTempBasalIncludingConvertedExtended(System.currentTimeMillis()) val activeTemp = iobCobCalculator.getTempBasalIncludingConvertedExtended(System.currentTimeMillis())
if (activeTemp != null) { if (activeTemp != null) {
line1 += " " + activeTemp.toStringShort() line1 += " " + activeTemp.toStringShort(decimalFormatter)
line1aa += " " + activeTemp.toStringShort() + "." line1aa += " " + activeTemp.toStringShort(decimalFormatter) + "."
} }
//IOB //IOB
val bolusIob = iobCobCalculator.calculateIobFromBolus().round() val bolusIob = iobCobCalculator.calculateIobFromBolus().round()
val basalIob = iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended().round() val basalIob = iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended().round()
line2 = line2 =
rh.gs(info.nightscout.core.ui.R.string.treatments_iob_label_string) + " " + DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U " + rh.gs(info.nightscout.core.ui.R.string.cob) + ": " + iobCobCalculator.getCobInfo( rh.gs(info.nightscout.core.ui.R.string.treatments_iob_label_string) + " " + decimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U " + rh.gs(
info.nightscout.core.ui.R
.string.cob
) + ": " + iobCobCalculator.getCobInfo(
"PersistentNotificationPlugin" "PersistentNotificationPlugin"
).generateCOBString() ).generateCOBString(decimalFormatter)
val line2aa = val line2aa =
rh.gs(info.nightscout.core.ui.R.string.treatments_iob_label_string) + " " + DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U. " + rh.gs(info.nightscout.core.ui.R.string.cob) + ": " + iobCobCalculator.getCobInfo( rh.gs(info.nightscout.core.ui.R.string.treatments_iob_label_string) + " " + decimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U. " + rh.gs(
info.nightscout.core.ui.R
.string.cob
) + ": " + iobCobCalculator.getCobInfo(
"PersistentNotificationPlugin" "PersistentNotificationPlugin"
).generateCOBString() + "." ).generateCOBString(decimalFormatter) + "."
line3 = DecimalFormatter.to2Decimal(pump.baseBasalRate) + " U/h" line3 = decimalFormatter.to2Decimal(pump.baseBasalRate) + " U/h"
var line3aa = DecimalFormatter.to2Decimal(pump.baseBasalRate) + " U/h." var line3aa = decimalFormatter.to2Decimal(pump.baseBasalRate) + " U/h."
line3 += " - " + profileFunction.getProfileName() line3 += " - " + profileFunction.getProfileName()
line3aa += " - " + profileFunction.getProfileName() + "." line3aa += " - " + profileFunction.getProfileName() + "."
/// For Android Auto /// For Android Auto

View file

@ -12,7 +12,6 @@ import androidx.work.workDataOf
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.annotations.OpenForTesting import info.nightscout.annotations.OpenForTesting
import info.nightscout.core.events.EventNewNotification import info.nightscout.core.events.EventNewNotification
import info.nightscout.core.extensions.valueToUnitsString
import info.nightscout.core.iob.generateCOBString import info.nightscout.core.iob.generateCOBString
import info.nightscout.core.iob.round import info.nightscout.core.iob.round
import info.nightscout.core.utils.fabric.FabricPrivacy import info.nightscout.core.utils.fabric.FabricPrivacy
@ -45,7 +44,6 @@ import info.nightscout.interfaces.plugin.ActivePlugin
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.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.pump.DetailedBolusInfo import info.nightscout.interfaces.pump.DetailedBolusInfo
import info.nightscout.interfaces.pump.PumpSync import info.nightscout.interfaces.pump.PumpSync
@ -65,6 +63,7 @@ import info.nightscout.rx.events.EventRefreshOverview
import info.nightscout.rx.logging.AAPSLogger import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag import info.nightscout.rx.logging.LTag
import info.nightscout.shared.SafeParse import info.nightscout.shared.SafeParse
import info.nightscout.shared.interfaces.ProfileUtil
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 info.nightscout.shared.utils.DateUtil import info.nightscout.shared.utils.DateUtil
@ -95,6 +94,7 @@ class SmsCommunicatorPlugin @Inject constructor(
private val constraintChecker: Constraints, private val constraintChecker: Constraints,
private val rxBus: RxBus, private val rxBus: RxBus,
private val profileFunction: ProfileFunction, private val profileFunction: ProfileFunction,
private val profileUtil: ProfileUtil,
private val fabricPrivacy: FabricPrivacy, private val fabricPrivacy: FabricPrivacy,
private val activePlugin: ActivePlugin, private val activePlugin: ActivePlugin,
private val commandQueue: CommandQueue, private val commandQueue: CommandQueue,
@ -106,7 +106,8 @@ class SmsCommunicatorPlugin @Inject constructor(
private val dateUtil: DateUtil, private val dateUtil: DateUtil,
private val uel: UserEntryLogger, private val uel: UserEntryLogger,
private val glucoseStatusProvider: GlucoseStatusProvider, private val glucoseStatusProvider: GlucoseStatusProvider,
private val repository: AppRepository private val repository: AppRepository,
private val decimalFormatter: DecimalFormatter
) : PluginBase( ) : PluginBase(
PluginDescription() PluginDescription()
.mainType(PluginType.GENERAL) .mainType(PluginType.GENERAL)
@ -353,23 +354,23 @@ class SmsCommunicatorPlugin @Inject constructor(
val actualBG = iobCobCalculator.ads.actualBg() val actualBG = iobCobCalculator.ads.actualBg()
val lastBG = iobCobCalculator.ads.lastBg() val lastBG = iobCobCalculator.ads.lastBg()
var reply = "" var reply = ""
val units = profileFunction.getUnits() val units = profileUtil.units
if (actualBG != null) { if (actualBG != null) {
reply = rh.gs(R.string.sms_actual_bg) + " " + actualBG.valueToUnitsString(units) + ", " reply = rh.gs(R.string.sms_actual_bg) + " " + profileUtil.fromMgdlToStringInUnits(actualBG.value) + ", "
} else if (lastBG != null) { } else if (lastBG != null) {
val agoMilliseconds = dateUtil.now() - lastBG.timestamp val agoMilliseconds = dateUtil.now() - lastBG.timestamp
val agoMin = (agoMilliseconds / 60.0 / 1000.0).toInt() val agoMin = (agoMilliseconds / 60.0 / 1000.0).toInt()
reply = rh.gs(R.string.sms_last_bg) + " " + lastBG.valueToUnitsString(units) + " " + rh.gs(R.string.sms_min_ago, agoMin) + ", " reply = rh.gs(R.string.sms_last_bg) + " " + profileUtil.valueInCurrentUnitsDetect(lastBG.value) + " " + rh.gs(R.string.sms_min_ago, agoMin) + ", "
} }
val glucoseStatus = glucoseStatusProvider.glucoseStatusData val glucoseStatus = glucoseStatusProvider.glucoseStatusData
if (glucoseStatus != null) reply += rh.gs(R.string.sms_delta) + " " + Profile.toUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units) + " " + units + ", " if (glucoseStatus != null) reply += rh.gs(R.string.sms_delta) + " " + profileUtil.fromMgdlToUnits(glucoseStatus.delta) + " " + units + ", "
val bolusIob = iobCobCalculator.calculateIobFromBolus().round() val bolusIob = iobCobCalculator.calculateIobFromBolus().round()
val basalIob = iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended().round() val basalIob = iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended().round()
val cobInfo = iobCobCalculator.getCobInfo("SMS COB") val cobInfo = iobCobCalculator.getCobInfo("SMS COB")
reply += (rh.gs(R.string.sms_iob) + " " + DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U (" reply += (rh.gs(R.string.sms_iob) + " " + decimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U ("
+ rh.gs(R.string.sms_bolus) + " " + DecimalFormatter.to2Decimal(bolusIob.iob) + "U " + rh.gs(R.string.sms_bolus) + " " + decimalFormatter.to2Decimal(bolusIob.iob) + "U "
+ rh.gs(R.string.sms_basal) + " " + DecimalFormatter.to2Decimal(basalIob.basaliob) + "U), " + rh.gs(R.string.sms_basal) + " " + decimalFormatter.to2Decimal(basalIob.basaliob) + "U), "
+ rh.gs(info.nightscout.core.ui.R.string.cob) + ": " + cobInfo.generateCOBString()) + rh.gs(info.nightscout.core.ui.R.string.cob) + ": " + cobInfo.generateCOBString(decimalFormatter))
sendSMS(Sms(receivedSms.phoneNumber, reply)) sendSMS(Sms(receivedSms.phoneNumber, reply))
receivedSms.processed = true receivedSms.processed = true
} }
@ -966,8 +967,8 @@ class SmsCommunicatorPlugin @Inject constructor(
timestamp = dateUtil.now(), timestamp = dateUtil.now(),
duration = TimeUnit.MINUTES.toMillis(eatingSoonTTDuration.toLong()), duration = TimeUnit.MINUTES.toMillis(eatingSoonTTDuration.toLong()),
reason = TemporaryTarget.Reason.EATING_SOON, reason = TemporaryTarget.Reason.EATING_SOON,
lowTarget = Profile.toMgdl(eatingSoonTT, profileFunction.getUnits()), lowTarget = profileUtil.convertToMgdl(eatingSoonTT, profileUtil.units),
highTarget = Profile.toMgdl(eatingSoonTT, profileFunction.getUnits()) highTarget = profileUtil.convertToMgdl(eatingSoonTT, profileUtil.units)
) )
).subscribe({ result -> ).subscribe({ result ->
result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted temp target $it") } result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted temp target $it") }
@ -976,8 +977,8 @@ class SmsCommunicatorPlugin @Inject constructor(
aapsLogger.error(LTag.DATABASE, "Error while saving temporary target", it) aapsLogger.error(LTag.DATABASE, "Error while saving temporary target", it)
}) })
val tt = if (currentProfile.units == GlucoseUnit.MMOL) { val tt = if (currentProfile.units == GlucoseUnit.MMOL) {
DecimalFormatter.to1Decimal(eatingSoonTT) decimalFormatter.to1Decimal(eatingSoonTT)
} else DecimalFormatter.to0Decimal(eatingSoonTT) } else decimalFormatter.to0Decimal(eatingSoonTT)
replyText += "\n" + rh.gs(R.string.smscommunicator_meal_bolus_delivered_tt, tt, eatingSoonTTDuration) replyText += "\n" + rh.gs(R.string.smscommunicator_meal_bolus_delivered_tt, tt, eatingSoonTTDuration)
} }
} }
@ -1078,7 +1079,7 @@ class SmsCommunicatorPlugin @Inject constructor(
receivedSms.processed = true receivedSms.processed = true
messageToConfirm = AuthRequest(injector, receivedSms, reply, passCode, object : SmsAction(pumpCommand = false) { messageToConfirm = AuthRequest(injector, receivedSms, reply, passCode, object : SmsAction(pumpCommand = false) {
override fun run() { override fun run() {
val units = profileFunction.getUnits() val units = profileUtil.units
var keyDuration = 0 var keyDuration = 0
var defaultTargetDuration = 0 var defaultTargetDuration = 0
var keyTarget = 0 var keyTarget = 0
@ -1116,15 +1117,15 @@ class SmsCommunicatorPlugin @Inject constructor(
var ttDuration = sp.getInt(keyDuration, defaultTargetDuration) var ttDuration = sp.getInt(keyDuration, defaultTargetDuration)
ttDuration = if (ttDuration > 0) ttDuration else defaultTargetDuration ttDuration = if (ttDuration > 0) ttDuration else defaultTargetDuration
var tt = sp.getDouble(keyTarget, if (units == GlucoseUnit.MMOL) defaultTargetMMOL else defaultTargetMGDL) var tt = sp.getDouble(keyTarget, if (units == GlucoseUnit.MMOL) defaultTargetMMOL else defaultTargetMGDL)
tt = Profile.toCurrentUnits(profileFunction, tt) tt = profileUtil.valueInCurrentUnitsDetect(tt)
tt = if (tt > 0) tt else if (units == GlucoseUnit.MMOL) defaultTargetMMOL else defaultTargetMGDL tt = if (tt > 0) tt else if (units == GlucoseUnit.MMOL) defaultTargetMMOL else defaultTargetMGDL
disposable += repository.runTransactionForResult( disposable += repository.runTransactionForResult(
InsertAndCancelCurrentTemporaryTargetTransaction( InsertAndCancelCurrentTemporaryTargetTransaction(
timestamp = dateUtil.now(), timestamp = dateUtil.now(),
duration = TimeUnit.MINUTES.toMillis(ttDuration.toLong()), duration = TimeUnit.MINUTES.toMillis(ttDuration.toLong()),
reason = reason, reason = reason,
lowTarget = Profile.toMgdl(tt, profileFunction.getUnits()), lowTarget = profileUtil.convertToMgdl(tt, profileUtil.units),
highTarget = Profile.toMgdl(tt, profileFunction.getUnits()) highTarget = profileUtil.convertToMgdl(tt, profileUtil.units)
) )
).subscribe({ result -> ).subscribe({ result ->
result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted temp target $it") } result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted temp target $it") }
@ -1132,7 +1133,7 @@ class SmsCommunicatorPlugin @Inject constructor(
}, { }, {
aapsLogger.error(LTag.DATABASE, "Error while saving temporary target", it) aapsLogger.error(LTag.DATABASE, "Error while saving temporary target", it)
}) })
val ttString = if (units == GlucoseUnit.MMOL) DecimalFormatter.to1Decimal(tt) else DecimalFormatter.to0Decimal(tt) val ttString = if (units == GlucoseUnit.MMOL) decimalFormatter.to1Decimal(tt) else decimalFormatter.to0Decimal(tt)
val replyText = rh.gs(R.string.smscommunicator_tt_set, ttString, ttDuration) val replyText = rh.gs(R.string.smscommunicator_tt_set, ttString, ttDuration)
sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, replyText)) sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, replyText))
uel.log( uel.log(

View file

@ -6,7 +6,6 @@ import dagger.android.HasAndroidInjector
import info.nightscout.core.extensions.convertedToAbsolute import info.nightscout.core.extensions.convertedToAbsolute
import info.nightscout.core.extensions.toStringShort import info.nightscout.core.extensions.toStringShort
import info.nightscout.core.extensions.valueToUnits import info.nightscout.core.extensions.valueToUnits
import info.nightscout.core.extensions.valueToUnitsString
import info.nightscout.core.graph.data.GlucoseValueDataPoint import info.nightscout.core.graph.data.GlucoseValueDataPoint
import info.nightscout.core.iob.generateCOBString import info.nightscout.core.iob.generateCOBString
import info.nightscout.core.iob.round import info.nightscout.core.iob.round
@ -64,6 +63,7 @@ import info.nightscout.rx.events.EventWearUpdateGui
import info.nightscout.rx.logging.AAPSLogger import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag import info.nightscout.rx.logging.LTag
import info.nightscout.rx.weardata.EventData import info.nightscout.rx.weardata.EventData
import info.nightscout.shared.interfaces.ProfileUtil
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 info.nightscout.shared.utils.DateUtil import info.nightscout.shared.utils.DateUtil
@ -96,6 +96,7 @@ class DataHandlerMobile @Inject constructor(
private val repository: AppRepository, private val repository: AppRepository,
private val glucoseStatusProvider: GlucoseStatusProvider, private val glucoseStatusProvider: GlucoseStatusProvider,
private val profileFunction: ProfileFunction, private val profileFunction: ProfileFunction,
private val profileUtil: ProfileUtil,
private val loop: Loop, private val loop: Loop,
private val processedDeviceStatusData: ProcessedDeviceStatusData, private val processedDeviceStatusData: ProcessedDeviceStatusData,
private val receiverStatusStore: ReceiverStatusStore, private val receiverStatusStore: ReceiverStatusStore,
@ -110,7 +111,8 @@ class DataHandlerMobile @Inject constructor(
private val fabricPrivacy: FabricPrivacy, private val fabricPrivacy: FabricPrivacy,
private val uiInteraction: UiInteraction, private val uiInteraction: UiInteraction,
private val persistenceLayer: PersistenceLayer, private val persistenceLayer: PersistenceLayer,
private val importExportPrefs: ImportExportPrefs private val importExportPrefs: ImportExportPrefs,
private val decimalFormatter: DecimalFormatter
) { ) {
private val disposable = CompositeDisposable() private val disposable = CompositeDisposable()
@ -875,7 +877,7 @@ class DataHandlerMobile @Inject constructor(
val finalLastRun = loop.lastRun val finalLastRun = loop.lastRun
if (finalLastRun?.request?.hasPredictions == true && finalLastRun.constraintsProcessed != null) { if (finalLastRun?.request?.hasPredictions == true && finalLastRun.constraintsProcessed != null) {
val predArray = finalLastRun.constraintsProcessed!!.predictions val predArray = finalLastRun.constraintsProcessed!!.predictions
.stream().map { bg: GlucoseValue -> GlucoseValueDataPoint(bg, profileFunction, rh) } .stream().map { bg: GlucoseValue -> GlucoseValueDataPoint(bg, profileUtil, rh) }
.collect(Collectors.toList()) .collect(Collectors.toList())
if (predArray.isNotEmpty()) if (predArray.isNotEmpty())
for (bg in predArray) if (bg.data.value > 39) for (bg in predArray) if (bg.data.value > 39)
@ -904,15 +906,18 @@ class DataHandlerMobile @Inject constructor(
if (config.appInitialized && profile != null) { if (config.appInitialized && profile != null) {
val bolusIob = iobCobCalculator.calculateIobFromBolus().round() val bolusIob = iobCobCalculator.calculateIobFromBolus().round()
val basalIob = iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended().round() val basalIob = iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended().round()
iobSum = DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) iobSum = decimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob)
iobDetail = "(${DecimalFormatter.to2Decimal(bolusIob.iob)}|${DecimalFormatter.to2Decimal(basalIob.basaliob)})" iobDetail = "(${decimalFormatter.to2Decimal(bolusIob.iob)}|${decimalFormatter.to2Decimal(basalIob.basaliob)})"
cobString = iobCobCalculator.getCobInfo("WatcherUpdaterService").generateCOBString() cobString = iobCobCalculator.getCobInfo("WatcherUpdaterService").generateCOBString(decimalFormatter)
currentBasal = currentBasal =
iobCobCalculator.getTempBasalIncludingConvertedExtended(System.currentTimeMillis())?.toStringShort() ?: rh.gs(info.nightscout.core.ui.R.string.pump_base_basal_rate, profile.getBasal()) iobCobCalculator.getTempBasalIncludingConvertedExtended(System.currentTimeMillis())?.toStringShort(decimalFormatter) ?: rh.gs(
info.nightscout.core.ui.R.string.pump_base_basal_rate, profile
.getBasal()
)
//bgi //bgi
val bgi = -(bolusIob.activity + basalIob.activity) * 5 * Profile.fromMgdlToUnits(profile.getIsfMgdl(), profileFunction.getUnits()) val bgi = -(bolusIob.activity + basalIob.activity) * 5 * profileUtil.fromMgdlToUnits(profile.getIsfMgdl())
bgiString = "" + (if (bgi >= 0) "+" else "") + DecimalFormatter.to1Decimal(bgi) bgiString = "" + (if (bgi >= 0) "+" else "") + decimalFormatter.to1Decimal(bgi)
status = generateStatusString(profile) status = generateStatusString(profile)
} }
@ -945,18 +950,19 @@ class DataHandlerMobile @Inject constructor(
private fun deltaString(deltaMGDL: Double, deltaMMOL: Double, units: GlucoseUnit): String { private fun deltaString(deltaMGDL: Double, deltaMMOL: Double, units: GlucoseUnit): String {
var deltaString = if (deltaMGDL >= 0) "+" else "-" var deltaString = if (deltaMGDL >= 0) "+" else "-"
deltaString += if (units == GlucoseUnit.MGDL) { deltaString += if (units == GlucoseUnit.MGDL) {
DecimalFormatter.to0Decimal(abs(deltaMGDL)) decimalFormatter.to0Decimal(abs(deltaMGDL))
} else { } else {
DecimalFormatter.to1Decimal(abs(deltaMMOL)) decimalFormatter.to1Decimal(abs(deltaMMOL))
} }
return deltaString return deltaString
} }
private fun deltaStringDetailed(deltaMGDL: Double, deltaMMOL: Double, units: GlucoseUnit): String { private fun deltaStringDetailed(deltaMGDL: Double, deltaMMOL: Double, units: GlucoseUnit): String {
var deltaStringDetailed = if (deltaMGDL >= 0) "+" else "-" var deltaStringDetailed = if (deltaMGDL >= 0) "+" else "-"
deltaStringDetailed += if (units == GlucoseUnit.MGDL) { deltaStringDetailed += if (units == GlucoseUnit.MGDL) {
DecimalFormatter.to1Decimal(abs(deltaMGDL)) decimalFormatter.to1Decimal(abs(deltaMGDL))
} else { } else {
DecimalFormatter.to2Decimal(abs(deltaMMOL)) decimalFormatter.to2Decimal(abs(deltaMMOL))
} }
return deltaStringDetailed return deltaStringDetailed
} }
@ -964,12 +970,12 @@ class DataHandlerMobile @Inject constructor(
private fun getSingleBG(glucoseValue: InMemoryGlucoseValue): EventData.SingleBg { private fun getSingleBG(glucoseValue: InMemoryGlucoseValue): EventData.SingleBg {
val glucoseStatus = glucoseStatusProvider.getGlucoseStatusData(true) val glucoseStatus = glucoseStatusProvider.getGlucoseStatusData(true)
val units = profileFunction.getUnits() val units = profileFunction.getUnits()
val lowLine = Profile.toMgdl(defaultValueHelper.determineLowLine(), units) val lowLine = profileUtil.convertToMgdl(defaultValueHelper.determineLowLine(), units)
val highLine = Profile.toMgdl(defaultValueHelper.determineHighLine(), units) val highLine = profileUtil.convertToMgdl(defaultValueHelper.determineHighLine(), units)
return EventData.SingleBg( return EventData.SingleBg(
timeStamp = glucoseValue.timestamp, timeStamp = glucoseValue.timestamp,
sgvString = glucoseValue.valueToUnitsString(units), sgvString = profileUtil.stringInCurrentUnitsDetect(glucoseValue.value),
glucoseUnits = units.asText, glucoseUnits = units.asText,
slopeArrow = trendCalculator.getTrendArrow(glucoseValue).symbol, slopeArrow = trendCalculator.getTrendArrow(glucoseValue).symbol,
delta = glucoseStatus?.let { deltaString(it.delta, it.delta * Constants.MGDL_TO_MMOLL, units) } ?: "--", delta = glucoseStatus?.let { deltaString(it.delta, it.delta * Constants.MGDL_TO_MMOLL, units) } ?: "--",
@ -996,17 +1002,14 @@ class DataHandlerMobile @Inject constructor(
//Check for Temp-Target: //Check for Temp-Target:
val tempTarget = repository.getTemporaryTargetActiveAt(dateUtil.now()).blockingGet() val tempTarget = repository.getTemporaryTargetActiveAt(dateUtil.now()).blockingGet()
if (tempTarget is ValueWrapper.Existing) { if (tempTarget is ValueWrapper.Existing) {
val target = Profile.toTargetRangeString(tempTarget.value.lowTarget, tempTarget.value.lowTarget, GlucoseUnit.MGDL, profileFunction.getUnits()) val target = profileUtil.toTargetRangeString(tempTarget.value.lowTarget, tempTarget.value.lowTarget, GlucoseUnit.MGDL)
ret += rh.gs(R.string.temp_target) + ": " + target ret += rh.gs(R.string.temp_target) + ": " + target
ret += "\n"+ rh.gs(R.string.until) + ": " + dateUtil.timeString(tempTarget.value.end) ret += "\n" + rh.gs(R.string.until) + ": " + dateUtil.timeString(tempTarget.value.end)
ret += "\n\n" ret += "\n\n"
} }
ret += rh.gs(R.string.default_range) + ": " ret += rh.gs(R.string.default_range) + ": "
ret += Profile.fromMgdlToUnits(profile.getTargetLowMgdl(), profileFunction.getUnits()).toString() + " - " + Profile.fromMgdlToUnits( ret += profileUtil.toTargetRangeString(profile.getTargetLowMgdl(), profile.getTargetHighMgdl(), GlucoseUnit.MGDL)
profile.getTargetHighMgdl(), ret += " " + rh.gs(R.string.target) + ": " + profileUtil.fromMgdlToStringInUnits(profile.getTargetMgdl())
profileFunction.getUnits()
)
ret += " " + rh.gs(R.string.target) + ": " + Profile.fromMgdlToUnits(profile.getTargetMgdl(), profileFunction.getUnits())
return ret return ret
} }
@ -1145,8 +1148,8 @@ class DataHandlerMobile @Inject constructor(
timestamp = System.currentTimeMillis(), timestamp = System.currentTimeMillis(),
duration = TimeUnit.MINUTES.toMillis(command.duration.toLong()), duration = TimeUnit.MINUTES.toMillis(command.duration.toLong()),
reason = TemporaryTarget.Reason.WEAR, reason = TemporaryTarget.Reason.WEAR,
lowTarget = Profile.toMgdl(command.low, profileFunction.getUnits()), lowTarget = profileUtil.convertToMgdl(command.low, profileFunction.getUnits()),
highTarget = Profile.toMgdl(command.high, profileFunction.getUnits()) highTarget = profileUtil.convertToMgdl(command.high, profileFunction.getUnits())
) )
).subscribe({ result -> ).subscribe({ result ->
result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted temp target $it") } result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted temp target $it") }
@ -1253,11 +1256,11 @@ class DataHandlerMobile @Inject constructor(
duration = actionHeartRate.duration, duration = actionHeartRate.duration,
timestamp = actionHeartRate.timestamp, timestamp = actionHeartRate.timestamp,
beatsPerMinute = actionHeartRate.beatsPerMinute, beatsPerMinute = actionHeartRate.beatsPerMinute,
device = actionHeartRate.device) device = actionHeartRate.device
)
repository.runTransaction(InsertOrUpdateHeartRateTransaction(hr)).blockingAwait() repository.runTransaction(InsertOrUpdateHeartRateTransaction(hr)).blockingAwait()
} }
private fun handleGetCustomWatchface(command: EventData.ActionGetCustomWatchface) { private fun handleGetCustomWatchface(command: EventData.ActionGetCustomWatchface) {
val customWatchface = command.customWatchface val customWatchface = command.customWatchface
aapsLogger.debug(LTag.WEAR, "Custom Watchface received from ${command.sourceNodeId}: ${customWatchface.customWatchfaceData.json}") aapsLogger.debug(LTag.WEAR, "Custom Watchface received from ${command.sourceNodeId}: ${customWatchface.customWatchfaceData.json}")

View file

@ -79,7 +79,8 @@ class IobCobCalculatorPlugin @Inject constructor(
private val dateUtil: DateUtil, private val dateUtil: DateUtil,
private val repository: AppRepository, private val repository: AppRepository,
val overviewData: OverviewData, val overviewData: OverviewData,
private val calculationWorkflow: CalculationWorkflow private val calculationWorkflow: CalculationWorkflow,
private val decimalFormatter: DecimalFormatter
) : PluginBase( ) : PluginBase(
PluginDescription() PluginDescription()
.mainType(PluginType.GENERAL) .mainType(PluginType.GENERAL)
@ -368,7 +369,7 @@ class IobCobCalculatorPlugin @Inject constructor(
val sb = StringBuilder() val sb = StringBuilder()
sb.append("[") sb.append("[")
for (i in array) { for (i in array) {
sb.append(DecimalFormatter.to2Decimal(i.iob)) sb.append(decimalFormatter.to2Decimal(i.iob))
sb.append(", ") sb.append(", ")
} }
sb.append("]") sb.append("]")

View file

@ -19,7 +19,6 @@ import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.GlucoseUnit import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.logging.UserEntryLogger import info.nightscout.interfaces.logging.UserEntryLogger
import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.protection.ProtectionCheck import info.nightscout.interfaces.protection.ProtectionCheck
import info.nightscout.interfaces.ui.UiInteraction import info.nightscout.interfaces.ui.UiInteraction
@ -35,6 +34,7 @@ import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag import info.nightscout.rx.logging.LTag
import info.nightscout.shared.SafeParse import info.nightscout.shared.SafeParse
import info.nightscout.shared.extensions.toVisibility import info.nightscout.shared.extensions.toVisibility
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.utils.DateUtil import info.nightscout.shared.utils.DateUtil
import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.disposables.CompositeDisposable
@ -52,12 +52,14 @@ class ProfileFragment : DaggerFragment() {
@Inject lateinit var fabricPrivacy: FabricPrivacy @Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var profilePlugin: ProfilePlugin @Inject lateinit var profilePlugin: ProfilePlugin
@Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var profileUtil: ProfileUtil
@Inject lateinit var hardLimits: HardLimits @Inject lateinit var hardLimits: HardLimits
@Inject lateinit var protectionCheck: ProtectionCheck @Inject lateinit var protectionCheck: ProtectionCheck
@Inject lateinit var dateUtil: DateUtil @Inject lateinit var dateUtil: DateUtil
@Inject lateinit var aapsSchedulers: AapsSchedulers @Inject lateinit var aapsSchedulers: AapsSchedulers
@Inject lateinit var uel: UserEntryLogger @Inject lateinit var uel: UserEntryLogger
@Inject lateinit var uiInteraction: UiInteraction @Inject lateinit var uiInteraction: UiInteraction
@Inject lateinit var decimalFormatter: DecimalFormatter
private var disposable: CompositeDisposable = CompositeDisposable() private var disposable: CompositeDisposable = CompositeDisposable()
private var inMenu = false private var inMenu = false
@ -89,7 +91,7 @@ class ProfileFragment : DaggerFragment() {
private fun sumLabel(): String { private fun sumLabel(): String {
val profile = profilePlugin.getEditedProfile() val profile = profilePlugin.getEditedProfile()
val sum = profile?.let { ProfileSealed.Pure(profile).baseBasalSum() } ?: 0.0 val sum = profile?.let { ProfileSealed.Pure(profile).baseBasalSum() } ?: 0.0
return "" + DecimalFormatter.to2Decimal(sum) + rh.gs(info.nightscout.core.ui.R.string.insulin_unit_shortname) return "" + decimalFormatter.to2Decimal(sum) + rh.gs(info.nightscout.core.ui.R.string.insulin_unit_shortname)
} }
private var _binding: ProfileFragmentBinding? = null private var _binding: ProfileFragmentBinding? = null
@ -207,19 +209,19 @@ class ProfileFragment : DaggerFragment() {
) )
} else { } else {
val isfRange = doubleArrayOf( val isfRange = doubleArrayOf(
roundUp(Profile.fromMgdlToUnits(HardLimits.MIN_ISF, GlucoseUnit.MMOL)), roundUp(profileUtil.fromMgdlToUnits(HardLimits.MIN_ISF, GlucoseUnit.MMOL)),
roundDown(Profile.fromMgdlToUnits(HardLimits.MAX_ISF, GlucoseUnit.MMOL)) roundDown(profileUtil.fromMgdlToUnits(HardLimits.MAX_ISF, GlucoseUnit.MMOL))
) )
TimeListEdit(requireContext(), aapsLogger, dateUtil, requireView(), R.id.isf_holder, "ISF", rh.gs(info.nightscout.core.ui.R.string.isf_long_label), currentProfile.isf, null, isfRange, null, 0.1, TimeListEdit(requireContext(), aapsLogger, dateUtil, requireView(), R.id.isf_holder, "ISF", rh.gs(info.nightscout.core.ui.R.string.isf_long_label), currentProfile.isf, null, isfRange, null, 0.1,
DecimalFormat DecimalFormat
("0.0"), save) ("0.0"), save)
val range1 = doubleArrayOf( val range1 = doubleArrayOf(
roundUp(Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_MIN_BG[0], GlucoseUnit.MMOL)), roundUp(profileUtil.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_MIN_BG[0], GlucoseUnit.MMOL)),
roundDown(Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_MIN_BG[1], GlucoseUnit.MMOL)) roundDown(profileUtil.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_MIN_BG[1], GlucoseUnit.MMOL))
) )
val range2 = doubleArrayOf( val range2 = doubleArrayOf(
roundUp(Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_MAX_BG[0], GlucoseUnit.MMOL)), roundUp(profileUtil.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_MAX_BG[0], GlucoseUnit.MMOL)),
roundDown(Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_MAX_BG[1], GlucoseUnit.MMOL)) roundDown(profileUtil.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_MAX_BG[1], GlucoseUnit.MMOL))
) )
aapsLogger.info(LTag.CORE, "TimeListEdit", "build: range1" + range1[0] + " " + range1[1] + " range2" + range2[0] + " " + range2[1]) aapsLogger.info(LTag.CORE, "TimeListEdit", "build: range1" + range1[0] + " " + range1[1] + " range2" + range2[0] + " " + range2[1])
TimeListEdit( TimeListEdit(

View file

@ -31,6 +31,7 @@ import info.nightscout.rx.events.EventLocalProfileChanged
import info.nightscout.rx.events.EventProfileStoreChanged import info.nightscout.rx.events.EventProfileStoreChanged
import info.nightscout.rx.logging.AAPSLogger import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag import info.nightscout.rx.logging.LTag
import info.nightscout.shared.interfaces.ProfileUtil
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 info.nightscout.shared.utils.DateUtil import info.nightscout.shared.utils.DateUtil
@ -50,11 +51,13 @@ class ProfilePlugin @Inject constructor(
rh: ResourceHelper, rh: ResourceHelper,
private val sp: SP, private val sp: SP,
private val profileFunction: ProfileFunction, private val profileFunction: ProfileFunction,
private val profileUtil: ProfileUtil,
private val activePlugin: ActivePlugin, private val activePlugin: ActivePlugin,
private val hardLimits: HardLimits, private val hardLimits: HardLimits,
private val dateUtil: DateUtil, private val dateUtil: DateUtil,
private val config: Config, private val config: Config,
private val instantiator: Instantiator private val instantiator: Instantiator,
private val decimalFormatter: DecimalFormatter
) : PluginBase( ) : PluginBase(
PluginDescription() PluginDescription()
.mainType(PluginType.PROFILE) .mainType(PluginType.PROFILE)
@ -121,7 +124,7 @@ class ProfilePlugin @Inject constructor(
return false return false
} }
} else { } else {
if (blockFromJsonArray(isf, dateUtil)?.all { hardLimits.isInRange(Profile.toMgdl(it.amount, GlucoseUnit.MMOL), HardLimits.MIN_ISF, HardLimits.MAX_ISF) } == false) { if (blockFromJsonArray(isf, dateUtil)?.all { hardLimits.isInRange(profileUtil.convertToMgdl(it.amount, GlucoseUnit.MMOL), HardLimits.MIN_ISF, HardLimits.MAX_ISF) } == false) {
ToastUtils.errorToast(activity, rh.gs(R.string.error_in_isf_values)) ToastUtils.errorToast(activity, rh.gs(R.string.error_in_isf_values))
return false return false
} }
@ -129,11 +132,11 @@ class ProfilePlugin @Inject constructor(
ToastUtils.errorToast(activity, rh.gs(R.string.error_in_basal_values)) ToastUtils.errorToast(activity, rh.gs(R.string.error_in_basal_values))
return false return false
} }
if (low?.all { hardLimits.isInRange(Profile.toMgdl(it.amount, GlucoseUnit.MMOL), HardLimits.VERY_HARD_LIMIT_MIN_BG[0], HardLimits.VERY_HARD_LIMIT_MIN_BG[1]) } == false) { if (low?.all { hardLimits.isInRange(profileUtil.convertToMgdl(it.amount, GlucoseUnit.MMOL), HardLimits.VERY_HARD_LIMIT_MIN_BG[0], HardLimits.VERY_HARD_LIMIT_MIN_BG[1]) } == false) {
ToastUtils.errorToast(activity, rh.gs(R.string.error_in_target_values)) ToastUtils.errorToast(activity, rh.gs(R.string.error_in_target_values))
return false return false
} }
if (high?.all { hardLimits.isInRange(Profile.toMgdl(it.amount, GlucoseUnit.MMOL), HardLimits.VERY_HARD_LIMIT_MAX_BG[0], HardLimits.VERY_HARD_LIMIT_MAX_BG[1]) } == false) { if (high?.all { hardLimits.isInRange(profileUtil.convertToMgdl(it.amount, GlucoseUnit.MMOL), HardLimits.VERY_HARD_LIMIT_MAX_BG[0], HardLimits.VERY_HARD_LIMIT_MAX_BG[1]) } == false) {
ToastUtils.errorToast(activity, rh.gs(R.string.error_in_target_values)) ToastUtils.errorToast(activity, rh.gs(R.string.error_in_target_values))
return false return false
} }
@ -420,6 +423,6 @@ class ProfilePlugin @Inject constructor(
override val profileName: String override val profileName: String
get() = rawProfile?.getDefaultProfile()?.let { get() = rawProfile?.getDefaultProfile()?.let {
DecimalFormatter.to2Decimal(ProfileSealed.Pure(it).percentageBasalSum()) + "U " decimalFormatter.to2Decimal(ProfileSealed.Pure(it).percentageBasalSum()) + "U "
} ?: "INVALID" } ?: "INVALID"
} }

View file

@ -14,13 +14,6 @@ class GlucoseValueExtensionKtTest : TestBaseWithProfile() {
private val inMemoryGlucoseValue = InMemoryGlucoseValue(1000, 100.0, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN) private val inMemoryGlucoseValue = InMemoryGlucoseValue(1000, 100.0, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN)
@Test @Test
fun valueToUnitsString() { fun valueToUnitsString() {
Assertions.assertEquals("100", glucoseValue.valueToUnitsString(GlucoseUnit.MGDL))
Assertions.assertEquals("5.6", glucoseValue.valueToUnitsString(GlucoseUnit.MMOL))
}
@Test
fun inMemoryValueToUnitsString() {
Assertions.assertEquals("100", inMemoryGlucoseValue.valueToUnitsString(GlucoseUnit.MGDL))
Assertions.assertEquals("5.6", inMemoryGlucoseValue.valueToUnitsString(GlucoseUnit.MMOL))
} }
@Test @Test
fun inMemoryValueToUnits() { fun inMemoryValueToUnits() {

View file

@ -24,13 +24,13 @@ class TemporaryTargetExtensionKtTest : TestBaseWithProfile() {
) )
@Test @Test
fun lowValueToUnitsToString() { fun lowValueToUnitsToString() {
Assertions.assertEquals("110", temporaryTarget.lowValueToUnitsToString(GlucoseUnit.MGDL)) Assertions.assertEquals("110", temporaryTarget.lowValueToUnitsToString(GlucoseUnit.MGDL, decimalFormatter))
Assertions.assertEquals("6.1", temporaryTarget.lowValueToUnitsToString(GlucoseUnit.MMOL)) Assertions.assertEquals("6.1", temporaryTarget.lowValueToUnitsToString(GlucoseUnit.MMOL, decimalFormatter))
} }
@Test @Test
fun highValueToUnitsToString() { fun highValueToUnitsToString() {
Assertions.assertEquals("120", temporaryTarget.highValueToUnitsToString(GlucoseUnit.MGDL)) Assertions.assertEquals("120", temporaryTarget.highValueToUnitsToString(GlucoseUnit.MGDL, decimalFormatter))
Assertions.assertEquals("6.7", temporaryTarget.highValueToUnitsToString(GlucoseUnit.MMOL)) Assertions.assertEquals("6.7", temporaryTarget.highValueToUnitsToString(GlucoseUnit.MMOL, decimalFormatter))
} }
@Test @Test
fun target() { fun target() {

View file

@ -12,7 +12,6 @@ import info.nightscout.database.impl.transactions.Transaction
import info.nightscout.implementation.iob.GlucoseStatusProviderImpl import info.nightscout.implementation.iob.GlucoseStatusProviderImpl
import info.nightscout.interfaces.ApsMode import info.nightscout.interfaces.ApsMode
import info.nightscout.interfaces.Constants import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.XDripBroadcast import info.nightscout.interfaces.XDripBroadcast
import info.nightscout.interfaces.aps.AutosensDataStore import info.nightscout.interfaces.aps.AutosensDataStore
import info.nightscout.interfaces.aps.Loop import info.nightscout.interfaces.aps.Loop
@ -99,13 +98,13 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
repository.runTransactionForResult(anyObject<InsertAndCancelCurrentTemporaryTargetTransaction>()) repository.runTransactionForResult(anyObject<InsertAndCancelCurrentTemporaryTargetTransaction>())
).thenReturn(Single.just(InsertAndCancelCurrentTemporaryTargetTransaction.TransactionResult().apply { ).thenReturn(Single.just(InsertAndCancelCurrentTemporaryTargetTransaction.TransactionResult().apply {
})) }))
val glucoseStatusProvider = GlucoseStatusProviderImpl(aapsLogger = aapsLogger, iobCobCalculator = iobCobCalculator, dateUtil = dateUtilMocked) val glucoseStatusProvider = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculator, dateUtilMocked, decimalFormatter)
smsCommunicatorPlugin = SmsCommunicatorPlugin( smsCommunicatorPlugin = SmsCommunicatorPlugin(
injector, aapsLogger, rh, smsManager, aapsSchedulers, sp, constraintChecker, rxBus, profileFunction, fabricPrivacy, activePlugin, commandQueue, injector, aapsLogger, rh, smsManager, aapsSchedulers, sp, constraintChecker, rxBus, profileFunction, profileUtil, fabricPrivacy, activePlugin, commandQueue,
loop, iobCobCalculator, xDripBroadcast, loop, iobCobCalculator, xDripBroadcast,
otp, config, dateUtilMocked, uel, otp, config, dateUtilMocked, uel,
glucoseStatusProvider, repository glucoseStatusProvider, repository, decimalFormatter
) )
smsCommunicatorPlugin.setPluginEnabled(PluginType.GENERAL, true) smsCommunicatorPlugin.setPluginEnabled(PluginType.GENERAL, true)
Mockito.doAnswer { invocation: InvocationOnMock -> Mockito.doAnswer { invocation: InvocationOnMock ->
@ -158,7 +157,6 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
`when`(activePlugin.activeProfileSource).thenReturn(profileSource) `when`(activePlugin.activeProfileSource).thenReturn(profileSource)
`when`(profileFunction.getUnits()).thenReturn(GlucoseUnit.MGDL)
`when`(otp.name()).thenReturn("User") `when`(otp.name()).thenReturn("User")
`when`(otp.checkOTP(ArgumentMatchers.anyString())).thenReturn(OneTimePasswordValidationResult.OK) `when`(otp.checkOTP(ArgumentMatchers.anyString())).thenReturn(OneTimePasswordValidationResult.OK)

View file

@ -15,7 +15,6 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import dagger.android.support.DaggerFragment import dagger.android.support.DaggerFragment
import info.nightscout.core.extensions.directionToIcon import info.nightscout.core.extensions.directionToIcon
import info.nightscout.core.extensions.valueToUnitsString
import info.nightscout.core.ui.dialogs.OKDialog import info.nightscout.core.ui.dialogs.OKDialog
import info.nightscout.core.utils.ActionModeHelper import info.nightscout.core.utils.ActionModeHelper
import info.nightscout.core.utils.fabric.FabricPrivacy import info.nightscout.core.utils.fabric.FabricPrivacy
@ -36,6 +35,7 @@ import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag import info.nightscout.rx.logging.LTag
import info.nightscout.shared.extensions.toVisibility import info.nightscout.shared.extensions.toVisibility
import info.nightscout.shared.extensions.toVisibilityKeepSpace import info.nightscout.shared.extensions.toVisibilityKeepSpace
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.utils.DateUtil import info.nightscout.shared.utils.DateUtil
import info.nightscout.shared.utils.T import info.nightscout.shared.utils.T
@ -58,6 +58,7 @@ class BGSourceFragment : DaggerFragment(), MenuProvider {
@Inject lateinit var uel: UserEntryLogger @Inject lateinit var uel: UserEntryLogger
@Inject lateinit var activePlugin: ActivePlugin @Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var aapsLogger: AAPSLogger @Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var profileUtil: ProfileUtil
private val disposable = CompositeDisposable() private val disposable = CompositeDisposable()
private val millsToThePast = T.hours(36).msecs() private val millsToThePast = T.hours(36).msecs()
@ -142,7 +143,7 @@ class BGSourceFragment : DaggerFragment(), MenuProvider {
holder.binding.date.visibility = newDay.toVisibility() holder.binding.date.visibility = newDay.toVisibility()
holder.binding.date.text = if (newDay) dateUtil.dateStringRelative(glucoseValue.timestamp, rh) else "" holder.binding.date.text = if (newDay) dateUtil.dateStringRelative(glucoseValue.timestamp, rh) else ""
holder.binding.time.text = dateUtil.timeStringWithSeconds(glucoseValue.timestamp) holder.binding.time.text = dateUtil.timeStringWithSeconds(glucoseValue.timestamp)
holder.binding.value.text = glucoseValue.valueToUnitsString(profileFunction.getUnits()) holder.binding.value.text = profileUtil.fromMgdlToStringInUnits(glucoseValue.value)
holder.binding.direction.setImageResource(glucoseValue.trendArrow.directionToIcon()) holder.binding.direction.setImageResource(glucoseValue.trendArrow.directionToIcon())
if (position > 0) { if (position > 0) {
val previous = glucoseValues[position - 1] val previous = glucoseValues[position - 1]
@ -183,7 +184,7 @@ class BGSourceFragment : DaggerFragment(), MenuProvider {
private fun getConfirmationText(selectedItems: SparseArray<GlucoseValue>): String { private fun getConfirmationText(selectedItems: SparseArray<GlucoseValue>): String {
if (selectedItems.size() == 1) { if (selectedItems.size() == 1) {
val glucoseValue = selectedItems.valueAt(0) val glucoseValue = selectedItems.valueAt(0)
return dateUtil.dateAndTimeString(glucoseValue.timestamp) + "\n" + glucoseValue.valueToUnitsString(profileFunction.getUnits()) return dateUtil.dateAndTimeString(glucoseValue.timestamp) + "\n" + profileUtil.fromMgdlToUnits(glucoseValue.value)
} }
return rh.gs(info.nightscout.core.ui.R.string.confirm_remove_multiple_items, selectedItems.size()) return rh.gs(info.nightscout.core.ui.R.string.confirm_remove_multiple_items, selectedItems.size())
} }

View file

@ -24,12 +24,12 @@ import info.nightscout.interfaces.logging.UserEntryLogger
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.interfaces.profile.Profile
import info.nightscout.interfaces.source.BgSource import info.nightscout.interfaces.source.BgSource
import info.nightscout.interfaces.source.DexcomBoyda import info.nightscout.interfaces.source.DexcomBoyda
import info.nightscout.rx.logging.AAPSLogger import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag import info.nightscout.rx.logging.LTag
import info.nightscout.shared.extensions.safeGetInstalledPackages import info.nightscout.shared.extensions.safeGetInstalledPackages
import info.nightscout.shared.interfaces.ProfileUtil
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 info.nightscout.shared.utils.DateUtil import info.nightscout.shared.utils.DateUtil
@ -85,6 +85,7 @@ class DexcomPlugin @Inject constructor(
@Inject lateinit var dataWorkerStorage: DataWorkerStorage @Inject lateinit var dataWorkerStorage: DataWorkerStorage
@Inject lateinit var repository: AppRepository @Inject lateinit var repository: AppRepository
@Inject lateinit var uel: UserEntryLogger @Inject lateinit var uel: UserEntryLogger
@Inject lateinit var profileUtil: ProfileUtil
override suspend fun doWorkAndLog(): Result { override suspend fun doWorkAndLog(): Result {
var ret = Result.success() var ret = Result.success()
@ -110,7 +111,7 @@ class DexcomPlugin @Inject constructor(
CgmSourceTransaction.Calibration( CgmSourceTransaction.Calibration(
timestamp = it.getLong("timestamp") * 1000, timestamp = it.getLong("timestamp") * 1000,
value = value, value = value,
glucoseUnit = TherapyEvent.GlucoseUnit.fromConstant(Profile.unit(value)) glucoseUnit = TherapyEvent.GlucoseUnit.fromConstant(profileUtil.unitsDetect(value))
) )
) )
} }

View file

@ -22,6 +22,7 @@ import info.nightscout.interfaces.profile.DefaultValueHelper
import info.nightscout.interfaces.profile.ProfileFunction import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.receivers.Intents import info.nightscout.interfaces.receivers.Intents
import info.nightscout.interfaces.receivers.ReceiverStatusStore import info.nightscout.interfaces.receivers.ReceiverStatusStore
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.plugins.sync.R import info.nightscout.plugins.sync.R
import info.nightscout.rx.AapsSchedulers import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
@ -57,7 +58,8 @@ class DataBroadcastPlugin @Inject constructor(
private val activePlugin: ActivePlugin, private val activePlugin: ActivePlugin,
private var receiverStatusStore: ReceiverStatusStore, private var receiverStatusStore: ReceiverStatusStore,
private val config: Config, private val config: Config,
private val glucoseStatusProvider: GlucoseStatusProvider private val glucoseStatusProvider: GlucoseStatusProvider,
private val decimalFormatter: DecimalFormatter
) : PluginBase( ) : PluginBase(
PluginDescription() PluginDescription()
.mainType(PluginType.SYNC) .mainType(PluginType.SYNC)
@ -105,7 +107,6 @@ class DataBroadcastPlugin @Inject constructor(
val bundle = Bundle() val bundle = Bundle()
prepareData(event, bundle) prepareData(event, bundle)
//aapsLogger.debug("Prepared bundle:\n" + BundleLogger.log(bundle))
sendBroadcast( sendBroadcast(
Intent(Intents.AAPS_BROADCAST) // "info.nightscout.androidaps.status" Intent(Intents.AAPS_BROADCAST) // "info.nightscout.androidaps.status"
.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES) .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
@ -176,7 +177,7 @@ class DataBroadcastPlugin @Inject constructor(
bundle.putLong("tempBasalDurationInMinutes", it.durationInMinutes) bundle.putLong("tempBasalDurationInMinutes", it.durationInMinutes)
if (it.isAbsolute) bundle.putDouble("tempBasalAbsolute", it.rate) // U/h for absolute TBR if (it.isAbsolute) bundle.putDouble("tempBasalAbsolute", it.rate) // U/h for absolute TBR
else bundle.putInt("tempBasalPercent", it.rate.toInt()) // % for percent type TBR else bundle.putInt("tempBasalPercent", it.rate.toInt()) // % for percent type TBR
bundle.putString("tempBasalString", it.toStringFull(profile, dateUtil)) // user friendly string bundle.putString("tempBasalString", it.toStringFull(profile, dateUtil, decimalFormatter)) // user friendly string
} }
} }

View file

@ -15,15 +15,14 @@ import info.nightscout.interfaces.Config
import info.nightscout.interfaces.Constants import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.nsclient.NSAlarm import info.nightscout.interfaces.nsclient.NSAlarm
import info.nightscout.interfaces.nsclient.NSSettingsStatus import info.nightscout.interfaces.nsclient.NSSettingsStatus
import info.nightscout.interfaces.plugin.ActivePlugin
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.interfaces.profile.Profile import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.sync.DataSyncSelector import info.nightscout.interfaces.sync.DataSyncSelector
import info.nightscout.interfaces.sync.NsClient import info.nightscout.interfaces.sync.NsClient
import info.nightscout.interfaces.sync.Sync import info.nightscout.interfaces.sync.Sync
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.plugins.sync.R import info.nightscout.plugins.sync.R
import info.nightscout.plugins.sync.nsShared.NSClientFragment import info.nightscout.plugins.sync.nsShared.NSClientFragment
import info.nightscout.plugins.sync.nsShared.events.EventNSClientStatus import info.nightscout.plugins.sync.nsShared.events.EventNSClientStatus
@ -40,6 +39,7 @@ import info.nightscout.rx.events.EventPreferenceChange
import info.nightscout.rx.events.EventSWSyncStatus import info.nightscout.rx.events.EventSWSyncStatus
import info.nightscout.rx.logging.AAPSLogger import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag import info.nightscout.rx.logging.LTag
import info.nightscout.shared.interfaces.ProfileUtil
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 info.nightscout.shared.utils.DateUtil import info.nightscout.shared.utils.DateUtil
@ -61,10 +61,10 @@ class NSClientPlugin @Inject constructor(
private val receiverDelegate: ReceiverDelegate, private val receiverDelegate: ReceiverDelegate,
private val config: Config, private val config: Config,
private val dataSyncSelectorV1: DataSyncSelectorV1, private val dataSyncSelectorV1: DataSyncSelectorV1,
private val activePlugin: ActivePlugin,
private val dateUtil: DateUtil, private val dateUtil: DateUtil,
private val profileFunction: ProfileFunction, private val profileUtil: ProfileUtil,
private val nsSettingsStatus: NSSettingsStatus private val nsSettingsStatus: NSSettingsStatus,
private val decimalFormatter: DecimalFormatter
) : NsClient, Sync, PluginBase( ) : NsClient, Sync, PluginBase(
PluginDescription() PluginDescription()
.mainType(PluginType.SYNC) .mainType(PluginType.SYNC)
@ -200,15 +200,15 @@ class NSClientPlugin @Inject constructor(
when (dataPair) { when (dataPair) {
is DataSyncSelector.PairBolus -> dataPair.value.toJson(true, dateUtil) is DataSyncSelector.PairBolus -> dataPair.value.toJson(true, dateUtil)
is DataSyncSelector.PairCarbs -> dataPair.value.toJson(true, dateUtil) is DataSyncSelector.PairCarbs -> dataPair.value.toJson(true, dateUtil)
is DataSyncSelector.PairBolusCalculatorResult -> dataPair.value.toJson(true, dateUtil, profileFunction) is DataSyncSelector.PairBolusCalculatorResult -> dataPair.value.toJson(true, dateUtil, profileUtil)
is DataSyncSelector.PairTemporaryTarget -> dataPair.value.toJson(true, profileFunction.getUnits(), dateUtil) is DataSyncSelector.PairTemporaryTarget -> dataPair.value.toJson(true, dateUtil, profileUtil)
is DataSyncSelector.PairFood -> dataPair.value.toJson(true) is DataSyncSelector.PairFood -> dataPair.value.toJson(true)
is DataSyncSelector.PairGlucoseValue -> dataPair.value.toJson(true, dateUtil) is DataSyncSelector.PairGlucoseValue -> dataPair.value.toJson(true, dateUtil)
is DataSyncSelector.PairTherapyEvent -> dataPair.value.toJson(true, dateUtil) is DataSyncSelector.PairTherapyEvent -> dataPair.value.toJson(true, dateUtil)
is DataSyncSelector.PairDeviceStatus -> dataPair.value.toJson(dateUtil) is DataSyncSelector.PairDeviceStatus -> dataPair.value.toJson(dateUtil)
is DataSyncSelector.PairTemporaryBasal -> dataPair.value.toJson(true, profile, dateUtil) is DataSyncSelector.PairTemporaryBasal -> dataPair.value.toJson(true, profile, dateUtil)
is DataSyncSelector.PairExtendedBolus -> dataPair.value.toJson(true, profile, dateUtil) is DataSyncSelector.PairExtendedBolus -> dataPair.value.toJson(true, profile, dateUtil)
is DataSyncSelector.PairProfileSwitch -> dataPair.value.toJson(true, dateUtil) is DataSyncSelector.PairProfileSwitch -> dataPair.value.toJson(true, dateUtil, decimalFormatter)
is DataSyncSelector.PairEffectiveProfileSwitch -> dataPair.value.toJson(true, dateUtil) is DataSyncSelector.PairEffectiveProfileSwitch -> dataPair.value.toJson(true, dateUtil)
is DataSyncSelector.PairOfflineEvent -> dataPair.value.toJson(true, dateUtil) is DataSyncSelector.PairOfflineEvent -> dataPair.value.toJson(true, dateUtil)
is DataSyncSelector.PairProfileStore -> dataPair.value is DataSyncSelector.PairProfileStore -> dataPair.value
@ -238,14 +238,14 @@ class NSClientPlugin @Inject constructor(
when (dataPair) { when (dataPair) {
is DataSyncSelector.PairBolus -> dataPair.value.toJson(false, dateUtil) is DataSyncSelector.PairBolus -> dataPair.value.toJson(false, dateUtil)
is DataSyncSelector.PairCarbs -> dataPair.value.toJson(false, dateUtil) is DataSyncSelector.PairCarbs -> dataPair.value.toJson(false, dateUtil)
is DataSyncSelector.PairBolusCalculatorResult -> dataPair.value.toJson(false, dateUtil, profileFunction) is DataSyncSelector.PairBolusCalculatorResult -> dataPair.value.toJson(false, dateUtil, profileUtil)
is DataSyncSelector.PairTemporaryTarget -> dataPair.value.toJson(false, profileFunction.getUnits(), dateUtil) is DataSyncSelector.PairTemporaryTarget -> dataPair.value.toJson(false, dateUtil, profileUtil)
is DataSyncSelector.PairFood -> dataPair.value.toJson(false) is DataSyncSelector.PairFood -> dataPair.value.toJson(false)
is DataSyncSelector.PairGlucoseValue -> dataPair.value.toJson(false, dateUtil) is DataSyncSelector.PairGlucoseValue -> dataPair.value.toJson(false, dateUtil)
is DataSyncSelector.PairTherapyEvent -> dataPair.value.toJson(false, dateUtil) is DataSyncSelector.PairTherapyEvent -> dataPair.value.toJson(false, dateUtil)
is DataSyncSelector.PairTemporaryBasal -> dataPair.value.toJson(false, profile, dateUtil) is DataSyncSelector.PairTemporaryBasal -> dataPair.value.toJson(false, profile, dateUtil)
is DataSyncSelector.PairExtendedBolus -> dataPair.value.toJson(false, profile, dateUtil) is DataSyncSelector.PairExtendedBolus -> dataPair.value.toJson(false, profile, dateUtil)
is DataSyncSelector.PairProfileSwitch -> dataPair.value.toJson(false, dateUtil) is DataSyncSelector.PairProfileSwitch -> dataPair.value.toJson(false, dateUtil, decimalFormatter)
is DataSyncSelector.PairEffectiveProfileSwitch -> dataPair.value.toJson(false, dateUtil) is DataSyncSelector.PairEffectiveProfileSwitch -> dataPair.value.toJson(false, dateUtil)
is DataSyncSelector.PairOfflineEvent -> dataPair.value.toJson(false, dateUtil) is DataSyncSelector.PairOfflineEvent -> dataPair.value.toJson(false, dateUtil)
else -> null else -> null

View file

@ -3,21 +3,20 @@ package info.nightscout.plugins.sync.nsclient.extensions
import com.google.gson.Gson import com.google.gson.Gson
import com.google.gson.JsonSyntaxException import com.google.gson.JsonSyntaxException
import info.nightscout.database.entities.BolusCalculatorResult import info.nightscout.database.entities.BolusCalculatorResult
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.utils.JsonHelper import info.nightscout.interfaces.utils.JsonHelper
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.utils.DateUtil import info.nightscout.shared.utils.DateUtil
import org.json.JSONObject import org.json.JSONObject
fun BolusCalculatorResult.toJson(isAdd: Boolean, dateUtil: DateUtil, profileFunction: ProfileFunction): JSONObject = fun BolusCalculatorResult.toJson(isAdd: Boolean, dateUtil: DateUtil, profileUtil: ProfileUtil): JSONObject =
JSONObject() JSONObject()
.put("eventType", info.nightscout.database.entities.TherapyEvent.Type.BOLUS_WIZARD.text) .put("eventType", info.nightscout.database.entities.TherapyEvent.Type.BOLUS_WIZARD.text)
.put("created_at", dateUtil.toISOString(timestamp)) .put("created_at", dateUtil.toISOString(timestamp))
.put("isValid", isValid) .put("isValid", isValid)
.put("bolusCalculatorResult", Gson().toJson(this)) .put("bolusCalculatorResult", Gson().toJson(this))
.put("date", timestamp) .put("date", timestamp)
.put("glucose", Profile.fromMgdlToUnits(glucoseValue, profileFunction.getUnits())) .put("glucose", profileUtil.fromMgdlToUnits(glucoseValue))
.put("units", profileFunction.getUnits().asText) .put("units", profileUtil.units.asText)
.put("notes", note) .put("notes", note)
.also { if (isAdd && interfaceIDs.nightscoutId != null) it.put("_id", interfaceIDs.nightscoutId) } .also { if (isAdd && interfaceIDs.nightscoutId != null) it.put("_id", interfaceIDs.nightscoutId) }

View file

@ -8,17 +8,18 @@ import info.nightscout.database.entities.ProfileSwitch
import info.nightscout.database.entities.TherapyEvent import info.nightscout.database.entities.TherapyEvent
import info.nightscout.database.entities.embedments.InterfaceIDs import info.nightscout.database.entities.embedments.InterfaceIDs
import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.interfaces.utils.JsonHelper import info.nightscout.interfaces.utils.JsonHelper
import info.nightscout.shared.utils.DateUtil import info.nightscout.shared.utils.DateUtil
import info.nightscout.shared.utils.T import info.nightscout.shared.utils.T
import org.json.JSONObject import org.json.JSONObject
fun ProfileSwitch.toJson(isAdd: Boolean, dateUtil: DateUtil): JSONObject = fun ProfileSwitch.toJson(isAdd: Boolean, dateUtil: DateUtil, decimalFormatter: DecimalFormatter): JSONObject =
JSONObject() JSONObject()
.put("timeshift", timeshift) .put("timeshift", timeshift)
.put("percentage", percentage) .put("percentage", percentage)
.put("duration", T.msecs(duration).mins()) .put("duration", T.msecs(duration).mins())
.put("profile", getCustomizedName()) .put("profile", getCustomizedName(decimalFormatter))
.put("originalProfileName", profileName) .put("originalProfileName", profileName)
.put("originalDuration", duration) .put("originalDuration", duration)
.put("created_at", dateUtil.toISOString(timestamp)) .put("created_at", dateUtil.toISOString(timestamp))

View file

@ -3,21 +3,21 @@ package info.nightscout.plugins.sync.nsclient.extensions
import info.nightscout.database.entities.TemporaryTarget import info.nightscout.database.entities.TemporaryTarget
import info.nightscout.interfaces.Constants import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.GlucoseUnit import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.utils.JsonHelper import info.nightscout.interfaces.utils.JsonHelper
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.utils.DateUtil import info.nightscout.shared.utils.DateUtil
import info.nightscout.shared.utils.T import info.nightscout.shared.utils.T
import org.json.JSONObject import org.json.JSONObject
fun TemporaryTarget.Companion.fromJson(jsonObject: JSONObject): TemporaryTarget? { fun TemporaryTarget.Companion.fromJson(jsonObject: JSONObject, profileUtil: ProfileUtil): TemporaryTarget? {
val units = GlucoseUnit.fromText(JsonHelper.safeGetString(jsonObject, "units", Constants.MGDL)) val units = GlucoseUnit.fromText(JsonHelper.safeGetString(jsonObject, "units", Constants.MGDL))
val timestamp = JsonHelper.safeGetLongAllowNull(jsonObject, "mills", null) ?: return null val timestamp = JsonHelper.safeGetLongAllowNull(jsonObject, "mills", null) ?: return null
val duration = JsonHelper.safeGetLongAllowNull(jsonObject, "duration", null) ?: return null val duration = JsonHelper.safeGetLongAllowNull(jsonObject, "duration", null) ?: return null
val durationInMilliseconds = JsonHelper.safeGetLongAllowNull(jsonObject, "durationInMilliseconds") val durationInMilliseconds = JsonHelper.safeGetLongAllowNull(jsonObject, "durationInMilliseconds")
var low = JsonHelper.safeGetDouble(jsonObject, "targetBottom") var low = JsonHelper.safeGetDouble(jsonObject, "targetBottom")
low = Profile.toMgdl(low, units) low = profileUtil.convertToMgdl(low, units)
var high = JsonHelper.safeGetDouble(jsonObject, "targetTop") var high = JsonHelper.safeGetDouble(jsonObject, "targetTop")
high = Profile.toMgdl(high, units) high = profileUtil.convertToMgdl(high, units)
val reasonString = if (duration != 0L) JsonHelper.safeGetStringAllowNull(jsonObject, "reason", null) val reasonString = if (duration != 0L) JsonHelper.safeGetStringAllowNull(jsonObject, "reason", null)
?: return null else "" ?: return null else ""
// this string can be localized from NS, it will not work in this case CUSTOM will be used // this string can be localized from NS, it will not work in this case CUSTOM will be used
@ -47,7 +47,7 @@ fun TemporaryTarget.Companion.fromJson(jsonObject: JSONObject): TemporaryTarget?
return tt return tt
} }
fun TemporaryTarget.toJson(isAdd: Boolean, units: GlucoseUnit, dateUtil: DateUtil): JSONObject = fun TemporaryTarget.toJson(isAdd: Boolean, dateUtil: DateUtil, profileUtil: ProfileUtil): JSONObject =
JSONObject() JSONObject()
.put("eventType", info.nightscout.database.entities.TherapyEvent.Type.TEMPORARY_TARGET.text) .put("eventType", info.nightscout.database.entities.TherapyEvent.Type.TEMPORARY_TARGET.text)
.put("duration", T.msecs(duration).mins()) .put("duration", T.msecs(duration).mins())
@ -58,8 +58,8 @@ fun TemporaryTarget.toJson(isAdd: Boolean, units: GlucoseUnit, dateUtil: DateUti
.put("enteredBy", "AndroidAPS").also { .put("enteredBy", "AndroidAPS").also {
if (lowTarget > 0) it if (lowTarget > 0) it
.put("reason", reason.text) .put("reason", reason.text)
.put("targetBottom", Profile.fromMgdlToUnits(lowTarget, units)) .put("targetBottom", profileUtil.fromMgdlToUnits(lowTarget))
.put("targetTop", Profile.fromMgdlToUnits(highTarget, units)) .put("targetTop", profileUtil.fromMgdlToUnits(highTarget))
.put("units", units.asText) .put("units", profileUtil.units.asText)
if (isAdd && interfaceIDs.nightscoutId != null) it.put("_id", interfaceIDs.nightscoutId) if (isAdd && interfaceIDs.nightscoutId != null) it.put("_id", interfaceIDs.nightscoutId)
} }

View file

@ -28,6 +28,7 @@ import info.nightscout.plugins.sync.nsclient.extensions.isEffectiveProfileSwitch
import info.nightscout.plugins.sync.nsclient.extensions.temporaryBasalFromJson import info.nightscout.plugins.sync.nsclient.extensions.temporaryBasalFromJson
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.logging.LTag import info.nightscout.rx.logging.LTag
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil import info.nightscout.shared.utils.DateUtil
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@ -46,6 +47,7 @@ class NSClientAddUpdateWorker(
@Inject lateinit var activePlugin: ActivePlugin @Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var rxBus: RxBus @Inject lateinit var rxBus: RxBus
@Inject lateinit var storeDataForDb: StoreDataForDb @Inject lateinit var storeDataForDb: StoreDataForDb
@Inject lateinit var profileUtil: ProfileUtil
override suspend fun doWorkAndLog(): Result { override suspend fun doWorkAndLog(): Result {
val treatments = dataWorkerStorage.pickupJSONArray(inputData.getLong(DataWorkerStorage.STORE_KEY, -1)) val treatments = dataWorkerStorage.pickupJSONArray(inputData.getLong(DataWorkerStorage.STORE_KEY, -1))
@ -100,7 +102,7 @@ class NSClientAddUpdateWorker(
insulin > 0 || carbs > 0 -> Any() insulin > 0 || carbs > 0 -> Any()
eventType == TherapyEvent.Type.TEMPORARY_TARGET.text -> eventType == TherapyEvent.Type.TEMPORARY_TARGET.text ->
if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_receive_temp_target, false) || config.NSCLIENT) { if (sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_receive_temp_target, false) || config.NSCLIENT) {
TemporaryTarget.fromJson(json)?.let { temporaryTarget -> TemporaryTarget.fromJson(json, profileUtil)?.let { temporaryTarget ->
storeDataForDb.temporaryTargets.add(temporaryTarget) storeDataForDb.temporaryTargets.add(temporaryTarget)
} ?: aapsLogger.error("Error parsing TT json $json") } ?: aapsLogger.error("Error parsing TT json $json")
} }

View file

@ -33,6 +33,7 @@ import info.nightscout.interfaces.sync.DataSyncSelector
import info.nightscout.interfaces.sync.NsClient import info.nightscout.interfaces.sync.NsClient
import info.nightscout.interfaces.sync.Sync import info.nightscout.interfaces.sync.Sync
import info.nightscout.interfaces.ui.UiInteraction import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.plugins.sync.R import info.nightscout.plugins.sync.R
import info.nightscout.plugins.sync.nsShared.NSClientFragment import info.nightscout.plugins.sync.nsShared.NSClientFragment
import info.nightscout.plugins.sync.nsShared.NsIncomingDataProcessor import info.nightscout.plugins.sync.nsShared.NsIncomingDataProcessor
@ -121,7 +122,8 @@ class NSClientV3Plugin @Inject constructor(
private val nsDeviceStatusHandler: NSDeviceStatusHandler, private val nsDeviceStatusHandler: NSDeviceStatusHandler,
private val nsClientSource: NSClientSource, private val nsClientSource: NSClientSource,
private val nsIncomingDataProcessor: NsIncomingDataProcessor, private val nsIncomingDataProcessor: NsIncomingDataProcessor,
private val storeDataForDb: StoreDataForDb private val storeDataForDb: StoreDataForDb,
private val decimalFormatter: DecimalFormatter
) : NsClient, Sync, PluginBase( ) : NsClient, Sync, PluginBase(
PluginDescription() PluginDescription()
.mainType(PluginType.SYNC) .mainType(PluginType.SYNC)
@ -795,7 +797,7 @@ class NSClientV3Plugin @Inject constructor(
dataPair.value.toNSExtendedBolus(profile) dataPair.value.toNSExtendedBolus(profile)
} }
is DataSyncSelector.PairProfileSwitch -> dataPair.value.toNSProfileSwitch(dateUtil) is DataSyncSelector.PairProfileSwitch -> dataPair.value.toNSProfileSwitch(dateUtil, decimalFormatter)
is DataSyncSelector.PairEffectiveProfileSwitch -> dataPair.value.toNSEffectiveProfileSwitch(dateUtil) is DataSyncSelector.PairEffectiveProfileSwitch -> dataPair.value.toNSEffectiveProfileSwitch(dateUtil)
is DataSyncSelector.PairOfflineEvent -> dataPair.value.toNSOfflineEvent() is DataSyncSelector.PairOfflineEvent -> dataPair.value.toNSOfflineEvent()
else -> null else -> null

View file

@ -7,6 +7,7 @@ import info.nightscout.core.profile.ProfileSealed
import info.nightscout.database.entities.ProfileSwitch import info.nightscout.database.entities.ProfileSwitch
import info.nightscout.database.entities.embedments.InterfaceIDs import info.nightscout.database.entities.embedments.InterfaceIDs
import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.sdk.localmodel.treatment.EventType import info.nightscout.sdk.localmodel.treatment.EventType
import info.nightscout.sdk.localmodel.treatment.NSProfileSwitch import info.nightscout.sdk.localmodel.treatment.NSProfileSwitch
import info.nightscout.shared.utils.DateUtil import info.nightscout.shared.utils.DateUtil
@ -38,8 +39,8 @@ fun NSProfileSwitch.toProfileSwitch(activePlugin: ActivePlugin, dateUtil: DateUt
) )
} }
fun ProfileSwitch.toNSProfileSwitch(dateUtil: DateUtil): NSProfileSwitch { fun ProfileSwitch.toNSProfileSwitch(dateUtil: DateUtil, decimalFormatter: DecimalFormatter): NSProfileSwitch {
val unmodifiedCustomizedName = getCustomizedName() val unmodifiedCustomizedName = getCustomizedName(decimalFormatter)
// ProfileSealed.PS doesn't provide unmodified json -> reset it // ProfileSealed.PS doesn't provide unmodified json -> reset it
val notCustomized = this.copy() val notCustomized = this.copy()
notCustomized.timeshift = 0 notCustomized.timeshift = 0

View file

@ -18,6 +18,7 @@ import info.nightscout.plugins.sync.tidepool.utils.GsonInstance
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.logging.AAPSLogger import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag import info.nightscout.rx.logging.LTag
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil import info.nightscout.shared.utils.DateUtil
import info.nightscout.shared.utils.T import info.nightscout.shared.utils.T
@ -33,6 +34,7 @@ class UploadChunk @Inject constructor(
private val rxBus: RxBus, private val rxBus: RxBus,
private val aapsLogger: AAPSLogger, private val aapsLogger: AAPSLogger,
private val profileFunction: ProfileFunction, private val profileFunction: ProfileFunction,
private val profileUtil: ProfileUtil,
private val activePlugin: ActivePlugin, private val activePlugin: ActivePlugin,
private val repository: AppRepository, private val repository: AppRepository,
private val dateUtil: DateUtil private val dateUtil: DateUtil
@ -111,7 +113,7 @@ class UploadChunk @Inject constructor(
private fun getBloodTests(start: Long, end: Long): List<BloodGlucoseElement> { private fun getBloodTests(start: Long, end: Long): List<BloodGlucoseElement> {
val readings = repository.compatGetTherapyEventDataFromToTime(start, end).blockingGet() val readings = repository.compatGetTherapyEventDataFromToTime(start, end).blockingGet()
val selection = BloodGlucoseElement.fromCareportalEvents(readings, dateUtil) val selection = BloodGlucoseElement.fromCareportalEvents(readings, dateUtil, profileUtil)
if (selection.isNotEmpty()) if (selection.isNotEmpty())
rxBus.send(EventTidepoolStatus("${selection.size} BGs selected for upload")) rxBus.send(EventTidepoolStatus("${selection.size} BGs selected for upload"))
return selection return selection
@ -140,14 +142,14 @@ class UploadChunk @Inject constructor(
private fun getBasals(start: Long, end: Long): List<BasalElement> { private fun getBasals(start: Long, end: Long): List<BasalElement> {
val temporaryBasals = repository.getTemporaryBasalsDataFromTimeToTime(start, end, true).blockingGet() val temporaryBasals = repository.getTemporaryBasalsDataFromTimeToTime(start, end, true).blockingGet()
val selection = fromTemporaryBasals(temporaryBasals, start, end) // TODO do not upload running TBR val selection = fromTemporaryBasals(temporaryBasals, start, end)
if (selection.isNotEmpty()) if (selection.isNotEmpty())
rxBus.send(EventTidepoolStatus("${selection.size} TBRs selected for upload")) rxBus.send(EventTidepoolStatus("${selection.size} TBRs selected for upload"))
return selection return selection
} }
private fun newInstanceOrNull(ps: EffectiveProfileSwitch): ProfileElement? = try { private fun newInstanceOrNull(ps: EffectiveProfileSwitch): ProfileElement? = try {
ProfileElement(ps, activePlugin.activePump.serialNumber(), dateUtil) ProfileElement(ps, activePlugin.activePump.serialNumber(), dateUtil, profileUtil)
} catch (e: Throwable) { } catch (e: Throwable) {
null null
} }

View file

@ -2,14 +2,14 @@ package info.nightscout.plugins.sync.tidepool.elements
import com.google.gson.annotations.Expose import com.google.gson.annotations.Expose
import info.nightscout.database.entities.TherapyEvent import info.nightscout.database.entities.TherapyEvent
import info.nightscout.interfaces.profile.Profile
import info.nightscout.plugins.sync.nsclient.extensions.toMainUnit import info.nightscout.plugins.sync.nsclient.extensions.toMainUnit
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.utils.DateUtil import info.nightscout.shared.utils.DateUtil
import java.util.LinkedList import java.util.LinkedList
import java.util.UUID import java.util.UUID
class BloodGlucoseElement(therapyEvent: TherapyEvent, dateUtil: DateUtil) class BloodGlucoseElement(therapyEvent: TherapyEvent, dateUtil: DateUtil, profileUtil: ProfileUtil) :
: BaseElement(therapyEvent.timestamp, UUID.nameUUIDFromBytes(("AAPS-bg" + therapyEvent.timestamp).toByteArray()).toString(), dateUtil) { BaseElement(therapyEvent.timestamp, UUID.nameUUIDFromBytes(("AAPS-bg" + therapyEvent.timestamp).toByteArray()).toString(), dateUtil) {
@Expose @Expose
var subType: String = "manual" var subType: String = "manual"
@ -22,21 +22,21 @@ class BloodGlucoseElement(therapyEvent: TherapyEvent, dateUtil: DateUtil)
init { init {
type = "smbg" type = "smbg"
subType = "manual" // TODO subType = "manual"
value = if (therapyEvent.glucose != null) value = if (therapyEvent.glucose != null)
Profile.toMgdl(therapyEvent.glucose!!, therapyEvent.glucoseUnit.toMainUnit()).toInt() profileUtil.convertToMgdl(therapyEvent.glucose!!, therapyEvent.glucoseUnit.toMainUnit()).toInt()
else 0 else 0
} }
companion object { companion object {
fun fromCareportalEvents(careportalList: List<TherapyEvent>, dateUtil: DateUtil): List<BloodGlucoseElement> { fun fromCareportalEvents(careportalList: List<TherapyEvent>, dateUtil: DateUtil, profileUtil: ProfileUtil): List<BloodGlucoseElement> {
val results = LinkedList<BloodGlucoseElement>() val results = LinkedList<BloodGlucoseElement>()
for (bt in careportalList) { for (bt in careportalList) {
if (bt.type == TherapyEvent.Type.NS_MBG || bt.type == TherapyEvent.Type.FINGER_STICK_BG_VALUE) { if (bt.type == TherapyEvent.Type.NS_MBG || bt.type == TherapyEvent.Type.FINGER_STICK_BG_VALUE) {
val bge = BloodGlucoseElement(bt, dateUtil) val bge = BloodGlucoseElement(bt, dateUtil, profileUtil)
if (bge.value > 0) if (bge.value > 0)
results.add(BloodGlucoseElement(bt, dateUtil)) results.add(BloodGlucoseElement(bt, dateUtil, profileUtil))
} }
} }
return results return results

View file

@ -5,18 +5,22 @@ import info.nightscout.core.profile.ProfileSealed
import info.nightscout.database.entities.EffectiveProfileSwitch import info.nightscout.database.entities.EffectiveProfileSwitch
import info.nightscout.interfaces.profile.Profile import info.nightscout.interfaces.profile.Profile
import info.nightscout.plugins.sync.tidepool.comm.TidepoolUploader import info.nightscout.plugins.sync.tidepool.comm.TidepoolUploader
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.utils.DateUtil import info.nightscout.shared.utils.DateUtil
import java.util.UUID import java.util.UUID
class ProfileElement(ps: EffectiveProfileSwitch, serialNumber: String, dateUtil: DateUtil) class ProfileElement(ps: EffectiveProfileSwitch, serialNumber: String, dateUtil: DateUtil, profileUtil: ProfileUtil) :
: BaseElement(ps.timestamp, UUID.nameUUIDFromBytes(("AAPS-profile" + ps.timestamp).toByteArray()).toString(), dateUtil) { BaseElement(ps.timestamp, UUID.nameUUIDFromBytes(("AAPS-profile" + ps.timestamp).toByteArray()).toString(), dateUtil) {
@Expose @Expose
internal var activeSchedule = "Normal" internal var activeSchedule = "Normal"
@Expose @Expose
internal var basalSchedules: BasalProfile = BasalProfile() internal var basalSchedules: BasalProfile = BasalProfile()
@Expose @Expose
internal var units: Units = Units() internal var units: Units = Units()
@Expose @Expose
internal var bgTargets: TargetProfile = TargetProfile() internal var bgTargets: TargetProfile = TargetProfile()
@Expose @Expose
@ -46,7 +50,12 @@ class ProfileElement(ps: EffectiveProfileSwitch, serialNumber: String, dateUtil:
for (hour in 0..23) { for (hour in 0..23) {
val seconds = hour * 3600 val seconds = hour * 3600
basalSchedules.Normal.add(BasalRate(seconds * 1000, profile.getBasalTimeFromMidnight(seconds))) basalSchedules.Normal.add(BasalRate(seconds * 1000, profile.getBasalTimeFromMidnight(seconds)))
bgTargets.Normal.add(Target(seconds * 1000, Profile.toMgdl((((profile.getTargetLowMgdlTimeFromMidnight(seconds) + profile.getTargetLowMgdlTimeFromMidnight(seconds))) / 2)).toInt())) bgTargets.Normal.add(
Target(
seconds * 1000,
profileUtil.convertToMgdlDetect((((profile.getTargetLowMgdlTimeFromMidnight(seconds) + profile.getTargetLowMgdlTimeFromMidnight(seconds))) / 2)).toInt()
)
)
carbRatios.Normal.add(Ratio(seconds * 1000, profile.getIcTimeFromMidnight(seconds).toInt())) carbRatios.Normal.add(Ratio(seconds * 1000, profile.getIcTimeFromMidnight(seconds).toInt()))
insulinSensitivities.Normal.add(Ratio(seconds * 1000, profile.getIsfMgdlTimeFromMidnight(seconds).toInt())) insulinSensitivities.Normal.add(Ratio(seconds * 1000, profile.getIsfMgdlTimeFromMidnight(seconds).toInt()))
} }

View file

@ -11,7 +11,6 @@ import androidx.work.OneTimeWorkRequest
import androidx.work.WorkInfo import androidx.work.WorkInfo
import androidx.work.WorkManager import androidx.work.WorkManager
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.core.extensions.toJson
import info.nightscout.core.extensions.toStringShort import info.nightscout.core.extensions.toStringShort
import info.nightscout.core.iob.generateCOBString import info.nightscout.core.iob.generateCOBString
import info.nightscout.core.iob.round import info.nightscout.core.iob.round
@ -49,6 +48,7 @@ import info.nightscout.rx.events.EventXdripNewLog
import info.nightscout.rx.logging.AAPSLogger import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag import info.nightscout.rx.logging.LTag
import info.nightscout.shared.extensions.safeQueryBroadcastReceivers import info.nightscout.shared.extensions.safeQueryBroadcastReceivers
import info.nightscout.shared.interfaces.ProfileUtil
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 info.nightscout.shared.utils.DateUtil import info.nightscout.shared.utils.DateUtil
@ -70,6 +70,7 @@ class XdripPlugin @Inject constructor(
injector: HasAndroidInjector, injector: HasAndroidInjector,
private val sp: SP, private val sp: SP,
private val profileFunction: ProfileFunction, private val profileFunction: ProfileFunction,
private val profileUtil: ProfileUtil,
rh: ResourceHelper, rh: ResourceHelper,
private val aapsSchedulers: AapsSchedulers, private val aapsSchedulers: AapsSchedulers,
private val context: Context, private val context: Context,
@ -79,7 +80,8 @@ class XdripPlugin @Inject constructor(
private val rxBus: RxBus, private val rxBus: RxBus,
private val uiInteraction: UiInteraction, private val uiInteraction: UiInteraction,
private val dateUtil: DateUtil, private val dateUtil: DateUtil,
aapsLogger: AAPSLogger aapsLogger: AAPSLogger,
private val decimalFormatter: DecimalFormatter
) : XDripBroadcast, Sync, PluginBase( ) : XDripBroadcast, Sync, PluginBase(
PluginDescription() PluginDescription()
.mainType(PluginType.SYNC) .mainType(PluginType.SYNC)
@ -238,26 +240,26 @@ class XdripPlugin @Inject constructor(
//Temp basal //Temp basal
iobCobCalculator.getTempBasalIncludingConvertedExtended(System.currentTimeMillis())?.let { iobCobCalculator.getTempBasalIncludingConvertedExtended(System.currentTimeMillis())?.let {
status.append(it.toStringShort()).append(" ") status.append(it.toStringShort(decimalFormatter)).append(" ")
} }
//IOB //IOB
val bolusIob = iobCobCalculator.calculateIobFromBolus().round() val bolusIob = iobCobCalculator.calculateIobFromBolus().round()
val basalIob = iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended().round() val basalIob = iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended().round()
status.append(DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob)).append(rh.gs(info.nightscout.core.ui.R.string.insulin_unit_shortname)) status.append(decimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob)).append(rh.gs(info.nightscout.core.ui.R.string.insulin_unit_shortname))
if (sp.getBoolean(R.string.key_xdrip_status_detailed_iob, true)) if (sp.getBoolean(R.string.key_xdrip_status_detailed_iob, true))
status.append("(") status.append("(")
.append(DecimalFormatter.to2Decimal(bolusIob.iob)) .append(decimalFormatter.to2Decimal(bolusIob.iob))
.append("|") .append("|")
.append(DecimalFormatter.to2Decimal(basalIob.basaliob)) .append(decimalFormatter.to2Decimal(basalIob.basaliob))
.append(")") .append(")")
if (sp.getBoolean(R.string.key_xdrip_status_show_bgi, true)) { if (sp.getBoolean(R.string.key_xdrip_status_show_bgi, true)) {
val bgi = -(bolusIob.activity + basalIob.activity) * 5 * Profile.fromMgdlToUnits(profile.getIsfMgdl(), profileFunction.getUnits()) val bgi = -(bolusIob.activity + basalIob.activity) * 5 * profileUtil.fromMgdlToUnits(profile.getIsfMgdl())
status.append(" ") status.append(" ")
.append(if (bgi >= 0) "+" else "") .append(if (bgi >= 0) "+" else "")
.append(DecimalFormatter.to2Decimal(bgi)) .append(decimalFormatter.to2Decimal(bgi))
} }
// COB // COB
status.append(" ").append(iobCobCalculator.getCobInfo("StatusLinePlugin").generateCOBString()) status.append(" ").append(iobCobCalculator.getCobInfo("StatusLinePlugin").generateCOBString(decimalFormatter))
return status.toString() return status.toString()
} }
@ -392,8 +394,8 @@ class XdripPlugin @Inject constructor(
when (dataPair) { when (dataPair) {
is DataSyncSelector.PairBolus -> dataPair.value.toJson(true, dateUtil) is DataSyncSelector.PairBolus -> dataPair.value.toJson(true, dateUtil)
is DataSyncSelector.PairCarbs -> dataPair.value.toJson(true, dateUtil) is DataSyncSelector.PairCarbs -> dataPair.value.toJson(true, dateUtil)
is DataSyncSelector.PairBolusCalculatorResult -> dataPair.value.toJson(true, dateUtil, profileFunction) is DataSyncSelector.PairBolusCalculatorResult -> dataPair.value.toJson(true, dateUtil, profileUtil)
is DataSyncSelector.PairTemporaryTarget -> dataPair.value.toJson(true, profileFunction.getUnits(), dateUtil) is DataSyncSelector.PairTemporaryTarget -> dataPair.value.toJson(true, dateUtil, profileUtil)
is DataSyncSelector.PairTherapyEvent -> dataPair.value.toJson(true, dateUtil) is DataSyncSelector.PairTherapyEvent -> dataPair.value.toJson(true, dateUtil)
is DataSyncSelector.PairTemporaryBasal -> { is DataSyncSelector.PairTemporaryBasal -> {
@ -406,7 +408,7 @@ class XdripPlugin @Inject constructor(
dataPair.value.toJson(true, profile, dateUtil) dataPair.value.toJson(true, profile, dateUtil)
} }
is DataSyncSelector.PairProfileSwitch -> dataPair.value.toJson(true, dateUtil) is DataSyncSelector.PairProfileSwitch -> dataPair.value.toJson(true, dateUtil, decimalFormatter)
is DataSyncSelector.PairEffectiveProfileSwitch -> dataPair.value.toJson(true, dateUtil) is DataSyncSelector.PairEffectiveProfileSwitch -> dataPair.value.toJson(true, dateUtil)
is DataSyncSelector.PairOfflineEvent -> dataPair.value.toJson(true, dateUtil) is DataSyncSelector.PairOfflineEvent -> dataPair.value.toJson(true, dateUtil)
else -> null else -> null

View file

@ -43,7 +43,7 @@ internal class DataBroadcastPluginTest : TestBaseWithProfile() {
fun setUp() { fun setUp() {
sut = DataBroadcastPlugin( sut = DataBroadcastPlugin(
injector, aapsLogger, rh, aapsSchedulers, context, dateUtil, fabricPrivacy, rxBus, iobCobCalculator, profileFunction, defaultValueHelper, processedDeviceStatusData, injector, aapsLogger, rh, aapsSchedulers, context, dateUtil, fabricPrivacy, rxBus, iobCobCalculator, profileFunction, defaultValueHelper, processedDeviceStatusData,
loop, activePlugin, receiverStatusStore, config, glucoseStatusProvider loop, activePlugin, receiverStatusStore, config, glucoseStatusProvider, decimalFormatter
) )
Mockito.`when`(iobCobCalculator.ads).thenReturn(autosensDataStore) Mockito.`when`(iobCobCalculator.ads).thenReturn(autosensDataStore)
Mockito.`when`(autosensDataStore.lastBg()).thenReturn(InMemoryGlucoseValue(1000, 100.0, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN)) Mockito.`when`(autosensDataStore.lastBg()).thenReturn(InMemoryGlucoseValue(1000, 100.0, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN))

View file

@ -82,7 +82,7 @@ internal class NSClientV3PluginTest : TestBaseWithProfile() {
NSClientV3Plugin( NSClientV3Plugin(
injector, aapsLogger, aapsSchedulers, rxBus, rh, context, fabricPrivacy, injector, aapsLogger, aapsSchedulers, rxBus, rh, context, fabricPrivacy,
sp, receiverDelegate, config, dateUtil, uiInteraction, dataSyncSelectorV3, repository, sp, receiverDelegate, config, dateUtil, uiInteraction, dataSyncSelectorV3, repository,
nsDeviceStatusHandler, nsClientSource, nsIncomingDataProcessor, storeDataForDb nsDeviceStatusHandler, nsClientSource, nsIncomingDataProcessor, storeDataForDb, decimalFormatter
) )
sut.nsAndroidClient = nsAndroidClient sut.nsAndroidClient = nsAndroidClient
Mockito.`when`(mockedProfileFunction.getProfile(anyLong())).thenReturn(validProfile) Mockito.`when`(mockedProfileFunction.getProfile(anyLong())).thenReturn(validProfile)

View file

@ -51,7 +51,7 @@ internal class ProfileSwitchExtensionKtTest : TestBaseWithProfile() {
) )
) )
var profileSwitch2 = (profileSwitch.toNSProfileSwitch(dateUtil).convertToRemoteAndBack() as NSProfileSwitch).toProfileSwitch(activePlugin, dateUtil)!! var profileSwitch2 = (profileSwitch.toNSProfileSwitch(dateUtil, decimalFormatter).convertToRemoteAndBack() as NSProfileSwitch).toProfileSwitch(activePlugin, dateUtil)!!
Assertions.assertTrue(profileSwitch.contentEqualsTo(profileSwitch2)) Assertions.assertTrue(profileSwitch.contentEqualsTo(profileSwitch2))
Assertions.assertTrue(profileSwitch.interfaceIdsEqualsTo(profileSwitch2)) Assertions.assertTrue(profileSwitch.interfaceIdsEqualsTo(profileSwitch2))
@ -78,7 +78,7 @@ internal class ProfileSwitchExtensionKtTest : TestBaseWithProfile() {
) )
) )
profileSwitch2 = (profileSwitch.toNSProfileSwitch(dateUtil).convertToRemoteAndBack() as NSProfileSwitch).toProfileSwitch(activePlugin, dateUtil)!! profileSwitch2 = (profileSwitch.toNSProfileSwitch(dateUtil, decimalFormatter).convertToRemoteAndBack() as NSProfileSwitch).toProfileSwitch(activePlugin, dateUtil)!!
Assertions.assertTrue(profileSwitch.contentEqualsTo(profileSwitch2)) Assertions.assertTrue(profileSwitch.contentEqualsTo(profileSwitch2))
Assertions.assertTrue(profileSwitch.interfaceIdsEqualsTo(profileSwitch2)) Assertions.assertTrue(profileSwitch.interfaceIdsEqualsTo(profileSwitch2))
} }

View file

@ -13,11 +13,13 @@ import info.nightscout.core.utils.receivers.DataWorkerStorage
import info.nightscout.database.entities.GlucoseValue import info.nightscout.database.entities.GlucoseValue
import info.nightscout.database.entities.embedments.InterfaceIDs import info.nightscout.database.entities.embedments.InterfaceIDs
import info.nightscout.database.impl.AppRepository import info.nightscout.database.impl.AppRepository
import info.nightscout.implementation.utils.DecimalFormatterImpl
import info.nightscout.interfaces.Config import info.nightscout.interfaces.Config
import info.nightscout.interfaces.nsclient.StoreDataForDb import info.nightscout.interfaces.nsclient.StoreDataForDb
import info.nightscout.interfaces.receivers.ReceiverStatusStore import info.nightscout.interfaces.receivers.ReceiverStatusStore
import info.nightscout.interfaces.source.NSClientSource import info.nightscout.interfaces.source.NSClientSource
import info.nightscout.interfaces.ui.UiInteraction import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.plugins.sync.nsShared.NsIncomingDataProcessor import info.nightscout.plugins.sync.nsShared.NsIncomingDataProcessor
import info.nightscout.plugins.sync.nsclient.ReceiverDelegate import info.nightscout.plugins.sync.nsclient.ReceiverDelegate
import info.nightscout.plugins.sync.nsclient.data.NSDeviceStatusHandler import info.nightscout.plugins.sync.nsclient.data.NSDeviceStatusHandler
@ -68,6 +70,7 @@ internal class LoadBgWorkerTest : TestBase() {
private lateinit var nsClientV3Plugin: NSClientV3Plugin private lateinit var nsClientV3Plugin: NSClientV3Plugin
private lateinit var receiverDelegate: ReceiverDelegate private lateinit var receiverDelegate: ReceiverDelegate
private lateinit var dataWorkerStorage: DataWorkerStorage private lateinit var dataWorkerStorage: DataWorkerStorage
private lateinit var decimalFormatter: DecimalFormatter
private lateinit var sut: LoadBgWorker private lateinit var sut: LoadBgWorker
private val now = 1000000000L private val now = 1000000000L
@ -90,6 +93,7 @@ internal class LoadBgWorkerTest : TestBase() {
@BeforeEach @BeforeEach
fun setUp() { fun setUp() {
decimalFormatter = DecimalFormatterImpl(rh)
Mockito.`when`(context.applicationContext).thenReturn(context) Mockito.`when`(context.applicationContext).thenReturn(context)
Mockito.`when`(context.androidInjector()).thenReturn(injector.androidInjector()) Mockito.`when`(context.androidInjector()).thenReturn(injector.androidInjector())
Mockito.`when`(dateUtil.now()).thenReturn(now) Mockito.`when`(dateUtil.now()).thenReturn(now)
@ -99,7 +103,7 @@ internal class LoadBgWorkerTest : TestBase() {
nsClientV3Plugin = NSClientV3Plugin( nsClientV3Plugin = NSClientV3Plugin(
injector, aapsLogger, aapsSchedulers, rxBus, rh, context, fabricPrivacy, injector, aapsLogger, aapsSchedulers, rxBus, rh, context, fabricPrivacy,
sp, receiverDelegate, config, dateUtil, uiInteraction, dataSyncSelectorV3, repository, sp, receiverDelegate, config, dateUtil, uiInteraction, dataSyncSelectorV3, repository,
nsDeviceStatusHandler, nsClientSource, nsIncomingDataProcessor, storeDataForDb nsDeviceStatusHandler, nsClientSource, nsIncomingDataProcessor, storeDataForDb, decimalFormatter
) )
nsClientV3Plugin.newestDataOnServer = LastModified(LastModified.Collections()) nsClientV3Plugin.newestDataOnServer = LastModified(LastModified.Collections())
} }

View file

@ -11,9 +11,6 @@ import info.nightscout.comboctl.base.toBluetoothAddress
import info.nightscout.comboctl.base.toCipher import info.nightscout.comboctl.base.toCipher
import info.nightscout.comboctl.base.toNonce import info.nightscout.comboctl.base.toNonce
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.sharedPreferences.SPDelegateInt
import info.nightscout.shared.sharedPreferences.SPDelegateLong
import info.nightscout.shared.sharedPreferences.SPDelegateString
import kotlinx.datetime.Instant import kotlinx.datetime.Instant
import kotlinx.datetime.UtcOffset import kotlinx.datetime.UtcOffset
import kotlin.reflect.KClassifier import kotlin.reflect.KClassifier

View file

@ -114,7 +114,8 @@ class ComboV2Plugin @Inject constructor (
private val dateUtil: DateUtil, private val dateUtil: DateUtil,
private val uiInteraction: UiInteraction, private val uiInteraction: UiInteraction,
private val androidPermission: AndroidPermission, private val androidPermission: AndroidPermission,
private val config: Config private val config: Config,
private val decimalFormatter: DecimalFormatter
) : ) :
PumpPluginBase( PumpPluginBase(
PluginDescription() PluginDescription()
@ -1456,7 +1457,7 @@ class ComboV2Plugin @Inject constructor (
lastBolusUIFlow.value?.let { lastBolusUIFlow.value?.let {
val localBolusTimestamp = it.timestamp.toLocalDateTime(TimeZone.currentSystemDefault()) val localBolusTimestamp = it.timestamp.toLocalDateTime(TimeZone.currentSystemDefault())
lines += rh.gs( lines += rh.gs(
R.string.combov2_short_status_last_bolus, DecimalFormatter.to2Decimal(it.bolusAmount.cctlBolusToIU()), R.string.combov2_short_status_last_bolus, decimalFormatter.to2Decimal(it.bolusAmount.cctlBolusToIU()),
String.format("%02d:%02d", localBolusTimestamp.hour, localBolusTimestamp.minute) String.format("%02d:%02d", localBolusTimestamp.hour, localBolusTimestamp.minute)
) )
} }
@ -1465,7 +1466,7 @@ class ComboV2Plugin @Inject constructor (
temporaryBasal?.let { temporaryBasal?.let {
lines += rh.gs( lines += rh.gs(
R.string.combov2_short_status_temp_basal, R.string.combov2_short_status_temp_basal,
it.toStringFull(dateUtil) it.toStringFull(dateUtil, decimalFormatter)
) )
} }

Some files were not shown because too many files have changed in this diff Show more