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.embedments.InsulinConfiguration
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.GlucoseUnit
import info.nightscout.interfaces.iob.IobCobCalculator
import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.profile.ProfileStore
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.interfaces.utils.HardLimits
import info.nightscout.rx.bus.RxBus
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
@ -41,6 +46,8 @@ open class TestBaseWithProfile : TestBase() {
@Mock lateinit var sp: SP
lateinit var dateUtil: DateUtil
lateinit var profileUtil: ProfileUtil
lateinit var decimalFormatter: DecimalFormatter
lateinit var hardLimits: HardLimits
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\"}]," +
"\"target_high\":[{\"time\":\"00:00\",\"value\":\"7\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}"
dateUtil = Mockito.spy(DateUtil(context))
decimalFormatter = DecimalFormatterImpl(rh)
profileUtil = ProfileUtilImpl(sp, decimalFormatter)
testPumpPlugin = TestPumpPlugin(profileInjector)
Mockito.`when`(dateUtil.now()).thenReturn(now)
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)
validProfile = ProfileSealed.Pure(pureProfileFromJson(JSONObject(validProfileJSON), dateUtil)!!)
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.profile.DefaultValueHelper
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.bus.RxBus
@ -33,7 +34,8 @@ class HistoryBrowserData @Inject constructor(
profileFunction: ProfileFunction,
repository: AppRepository,
fabricPrivacy: FabricPrivacy,
calculationWorkflow: CalculationWorkflow
calculationWorkflow: CalculationWorkflow,
decimalFormatter: DecimalFormatter
) {
var iobCobCalculator: IobCobCalculatorPlugin
@ -50,7 +52,8 @@ class HistoryBrowserData @Inject constructor(
activePlugin,
defaultValueHelper,
profileFunction,
repository
repository,
decimalFormatter
)
iobCobCalculator =
IobCobCalculatorPlugin(
@ -66,7 +69,8 @@ class HistoryBrowserData @Inject constructor(
dateUtil,
repository,
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.danaRv2.DanaRv2Plugin
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.insight.LocalInsightPlugin
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.nsclient.NSSettingsStatus
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.ProtectionCheck.ProtectionType.BIOMETRIC
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.sync.nsclient.NSClientPlugin
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.xdrip.XdripPlugin
import info.nightscout.pump.combo.ComboPlugin
@ -63,6 +61,7 @@ import info.nightscout.sensitivity.SensitivityAAPSPlugin
import info.nightscout.sensitivity.SensitivityOref1Plugin
import info.nightscout.sensitivity.SensitivityWeightedAveragePlugin
import info.nightscout.shared.SafeParse
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.source.AidexPlugin
@ -83,7 +82,7 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang
@Inject lateinit var rxBus: RxBus
@Inject lateinit var rh: ResourceHelper
@Inject lateinit var sp: SP
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var profileUtil: ProfileUtil
@Inject lateinit var pluginStore: PluginStore
@Inject lateinit var config: Config
@ -326,7 +325,7 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang
rh.gs(info.nightscout.core.utils.R.string.key_low_mark)
)
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()
}
}

View file

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

View file

@ -72,7 +72,7 @@ class SafetyPluginTest : TestBaseWithProfile() {
`when`(activePlugin.activePump).thenReturn(virtualPumpPlugin)
`when`(virtualPumpPlugin.pumpDescription).thenReturn(pumpDescription)
`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(
injector, aapsLogger, rxBus, constraintChecker, rh, profileFunction, context, activePlugin, iobCobCalculator, hardLimits, profiler, fabricPrivacy,
dateUtil, repository, glucoseStatusProvider, sp

View file

@ -159,15 +159,15 @@ class PumpEnactResultTest : TestBaseWithProfile() {
@Test fun toHtmlTest() {
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")
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")
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")
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")
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() {

View file

@ -12,7 +12,8 @@ class BolusDataPoint(
val data: Bolus,
private val rh: ResourceHelper,
private val activePlugin: ActivePlugin,
private val defaultValueHelper: DefaultValueHelper
private val defaultValueHelper: DefaultValueHelper,
private val decimalFormatter: DecimalFormatter
) : DataPointWithLabelInterface {
private var yValue = 0.0
@ -20,7 +21,7 @@ class BolusDataPoint(
override fun getX(): Double = data.timestamp.toDouble()
override fun getY(): Double = if (data.type == Bolus.Type.SMB) defaultValueHelper.determineLowLine() else yValue
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 size = 2f
override val paintStyle: Paint.Style = Paint.Style.FILL // not used

View file

@ -8,7 +8,8 @@ import info.nightscout.shared.interfaces.ResourceHelper
class ExtendedBolusDataPoint(
val data: ExtendedBolus,
private val rh: ResourceHelper
private val rh: ResourceHelper,
private val decimalFormatter: DecimalFormatter
) : DataPointWithLabelInterface {
private var yValue = 0.0
@ -28,5 +29,5 @@ class ExtendedBolusDataPoint(
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.interfaces.Constants
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.interfaces.ResourceHelper
class GlucoseValueDataPoint(
val data: GlucoseValue,
private val profileFunction: ProfileFunction,
private val rh: ResourceHelper
private val profileUtil: ProfileUtil,
private val rh: ResourceHelper,
) : DataPointWithLabelInterface {
private fun valueToUnits(units: GlucoseUnit): Double =
if (units == GlucoseUnit.MGDL) data.value else data.value * Constants.MGDL_TO_MMOLL
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 val label: String = Profile.toCurrentUnitsString(profileFunction, data.value)
override val label: String = profileUtil.fromMgdlToStringInUnits(data.value)
override val duration = 0L
override val shape get() = if (isPrediction) PointsWithLabelGraphSeries.Shape.PREDICTION else PointsWithLabelGraphSeries.Shape.BG
override val size = if (isPrediction) 1f else 0.6f
@ -30,8 +29,8 @@ class GlucoseValueDataPoint(
override fun color(context: Context?): Int {
return when {
isPrediction -> predictionColor(context)
else -> rh.gac(context, info.nightscout.core.ui.R.attr.originalBgValueColor)
isPrediction -> predictionColor(context)
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.interfaces.Constants
import info.nightscout.interfaces.Translator
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.interfaces.ResourceHelper
class TherapyEventDataPoint(
val data: TherapyEvent,
private val rh: ResourceHelper,
private val profileFunction: ProfileFunction,
private val profileUtil: ProfileUtil,
private val translator: Translator
) : DataPointWithLabelInterface {
@ -21,20 +20,13 @@ class TherapyEventDataPoint(
override fun getX(): Double = data.timestamp.toDouble()
override fun getY(): Double {
val units = profileFunction.getUnits()
if (data.type == TherapyEvent.Type.NS_MBG) return Profile.fromMgdlToUnits(data.glucose!!, units)
if (data.type == TherapyEvent.Type.NS_MBG) return profileUtil.fromMgdlToUnits(data.glucose!!)
if (data.glucose != null && data.glucose != 0.0) {
var mmol = 0.0
var mgdl = 0.0
if (data.glucoseUnit == TherapyEvent.GlucoseUnit.MGDL) {
mgdl = data.glucose!!
mmol = data.glucose!! * Constants.MGDL_TO_MMOLL
val mgdl: Double = when (data.glucoseUnit) {
TherapyEvent.GlucoseUnit.MGDL -> data.glucose!!
TherapyEvent.GlucoseUnit.MMOL -> data.glucose!! * Constants.MMOLL_TO_MGDL
}
if (data.glucoseUnit == TherapyEvent.GlucoseUnit.MMOL) {
mmol = data.glucose!!
mgdl = data.glucose!! * Constants.MMOLL_TO_MGDL
}
return Profile.toUnits(mgdl, mmol, units)
return profileUtil.fromMgdlToUnits(mgdl)
}
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
import info.nightscout.interfaces.Config
import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.pump.Pump
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.interfaces.utils.HardLimits
import info.nightscout.interfaces.utils.Round
import info.nightscout.rx.bus.RxBus
@ -133,62 +131,4 @@ interface Profile {
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
else profile.getBasal(time) * rate / 100
fun toStringFull(dateUtil: DateUtil): String {
fun toStringFull(dateUtil: DateUtil, decimalFormatter: DecimalFormatter): String {
return when {
isAbsolute -> {
DecimalFormatter.to2Decimal(rate) + "U/h @" +
decimalFormatter.to2Decimal(rate) + "U/h @" +
dateUtil.timeString(timestamp) +
" " + getPassedDurationToTimeInMinutes(dateUtil.now()) + "/" + durationInMinutes + "'"
}
@ -130,10 +130,12 @@ interface PumpSync {
val plannedRemainingMinutes: Long
get() = max(T.msecs(end - System.currentTimeMillis()).mins(), 0L)
private fun getPassedDurationToTimeInMinutes(time: Long): Int =
((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) +
" " + 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.widget.TableRow
import android.widget.TextView
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.shared.interfaces.ProfileUtil
interface DexcomTIR {
fun calculateSD(): Double
fun toHbA1cView(context: Context): TextView
fun toSDView(context: Context, profileFunction: ProfileFunction): TextView
fun toRangeHeaderView(context: Context, profileFunction: ProfileFunction): TextView
fun toSDView(context: Context, profileUtil: ProfileUtil): TextView
fun toRangeHeaderView(context: Context, profileUtil: ProfileUtil): TextView
fun toTableRowHeader(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
get() = max(round((end - System.currentTimeMillis()) / 1000.0 / 60).toInt(), 0)
fun ExtendedBolus.toStringFull(dateUtil: DateUtil): String =
"E " + DecimalFormatter.to2Decimal(rate) + "U/h @" + dateUtil.timeString(timestamp) +
fun ExtendedBolus.toStringFull(dateUtil: DateUtil, decimalFormatter: DecimalFormatter): String =
"E " + decimalFormatter.to2Decimal(rate) + "U/h @" + dateUtil.timeString(timestamp) +
" " + getPassedDurationToTimeInMinutes(dateUtil.now()) + "/" + T.msecs(duration).mins() + "min"
fun ExtendedBolus.toStringMedium(dateUtil: DateUtil): String =
DecimalFormatter.to2Decimal(rate) + "U/h " + getPassedDurationToTimeInMinutes(dateUtil.now()) + "/" + T.msecs(duration).mins() + "'"
fun ExtendedBolus.toStringMedium(dateUtil: DateUtil, decimalFormatter: DecimalFormatter): String =
decimalFormatter.to2Decimal(rate) + "U/h " + getPassedDurationToTimeInMinutes(dateUtil.now()) + "/" + T.msecs(duration).mins() + "'"
fun ExtendedBolus.getPassedDurationToTimeInMinutes(time: Long): Int =
((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.GlucoseUnit
import info.nightscout.interfaces.iob.InMemoryGlucoseValue
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.shared.utils.DateUtil
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 =
JSONObject()
.put("device", sourceSensor.text)
@ -28,10 +23,6 @@ fun InMemoryGlucoseValue.valueToUnits(units: GlucoseUnit): Double =
if (units == GlucoseUnit.MGDL) recalculated
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 =
when (this) {
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 java.util.TimeZone
fun ProfileSwitch.getCustomizedName(): String {
fun ProfileSwitch.getCustomizedName(decimalFormatter: DecimalFormatter): String {
var name: String = profileName
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) {
name += "($percentage%"

View file

@ -34,16 +34,16 @@ private fun TemporaryBasal.netExtendedRate(profile: Profile) = rate - profile.ge
val TemporaryBasal.durationInMinutes
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 {
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) +
" " + getPassedDurationToTimeInMinutes(dateUtil.now()) + "/" + durationInMinutes + "'"
}
isAbsolute -> {
DecimalFormatter.to2Decimal(rate) + "U/h @" +
decimalFormatter.to2Decimal(rate) + "U/h @" +
dateUtil.timeString(timestamp) +
" " + getPassedDurationToTimeInMinutes(dateUtil.now()) + "/" + durationInMinutes + "'"
}
@ -56,9 +56,9 @@ fun TemporaryBasal.toStringFull(profile: Profile, dateUtil: DateUtil): String {
}
}
fun TemporaryBasal.toStringShort(): String =
if (isAbsolute || type == TemporaryBasal.Type.FAKE_EXTENDED) DecimalFormatter.to2Decimal(rate) + "U/h"
else "${DecimalFormatter.to0Decimal(rate)}%"
fun TemporaryBasal.toStringShort(decimalFormatter: DecimalFormatter): String =
if (isAbsolute || type == TemporaryBasal.Type.FAKE_EXTENDED) decimalFormatter.to2Decimal(rate) + "U/h"
else "${decimalFormatter.to0Decimal(rate)}%"
fun TemporaryBasal.iobCalc(time: Long, profile: Profile, insulinInterface: Insulin): IobTotal {
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.interfaces.Constants
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.interfaces.ResourceHelper
import java.util.concurrent.TimeUnit
fun TemporaryTarget.lowValueToUnitsToString(units: GlucoseUnit): String =
if (units == GlucoseUnit.MGDL) DecimalFormatter.to0Decimal(this.lowTarget)
else DecimalFormatter.to1Decimal(this.lowTarget * Constants.MGDL_TO_MMOLL)
fun TemporaryTarget.lowValueToUnitsToString(units: GlucoseUnit, decimalFormatter: DecimalFormatter): String =
if (units == GlucoseUnit.MGDL) decimalFormatter.to0Decimal(this.lowTarget)
else decimalFormatter.to1Decimal(this.lowTarget * Constants.MGDL_TO_MMOLL)
fun TemporaryTarget.highValueToUnitsToString(units: GlucoseUnit): String =
if (units == GlucoseUnit.MGDL) DecimalFormatter.to0Decimal(this.highTarget)
else DecimalFormatter.to1Decimal(this.highTarget * Constants.MGDL_TO_MMOLL)
fun TemporaryTarget.highValueToUnitsToString(units: GlucoseUnit, decimalFormatter: DecimalFormatter): String =
if (units == GlucoseUnit.MGDL) decimalFormatter.to0Decimal(this.highTarget)
else decimalFormatter.to1Decimal(this.highTarget * Constants.MGDL_TO_MMOLL)
fun TemporaryTarget.target(): Double =
(this.lowTarget + this.highTarget) / 2
fun TemporaryTarget.friendlyDescription(units: GlucoseUnit, rh: ResourceHelper): String =
Profile.toTargetRangeString(lowTarget, highTarget, GlucoseUnit.MGDL, units) +
fun TemporaryTarget.friendlyDescription(units: GlucoseUnit, rh: ResourceHelper, profileUtil: ProfileUtil): String =
profileUtil.toTargetRangeString(lowTarget, highTarget, GlucoseUnit.MGDL, units) +
units.asText +
"@" + 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.shared.interfaces.ResourceHelper
fun CobInfo.generateCOBString(): String {
fun CobInfo.generateCOBString(decimalFormatter: DecimalFormatter): String {
var cobStringResult = "--g"
displayCob?.let { displayCob ->
cobStringResult = DecimalFormatter.to0Decimal(displayCob)
cobStringResult = decimalFormatter.to0Decimal(displayCob)
if (futureCarbs > 0)
cobStringResult += "(${DecimalFormatter.to0Decimal(futureCarbs)})"
cobStringResult += "(${decimalFormatter.to0Decimal(futureCarbs)})"
cobStringResult += "g"
}
return cobStringResult
}
fun CobInfo.displayText(rh: ResourceHelper): String? =
fun CobInfo.displayText(rh: ResourceHelper, decimalFormatter: DecimalFormatter): String? =
displayCob?.let { displayCob ->
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
}

View file

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

View file

@ -156,14 +156,20 @@ sealed class ProfileSealed(
break
}
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.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
}
for (target in targetBlocks) {
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[1]
)
@ -173,7 +179,7 @@ sealed class ProfileSealed(
break
}
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[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 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 getIsfMgdl(): Double = Profile.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 getTargetMgdl(): Double = Profile.toMgdl(targetBlocks.targetBlockValueBySeconds(MidnightUtils.secondsFromMidnight(), timeshift), units)
override fun getTargetLowMgdl(): Double = Profile.toMgdl(targetBlocks.lowTargetBlockValueBySeconds(MidnightUtils.secondsFromMidnight(), timeshift), units)
override fun getTargetLowMgdl(timestamp: Long): Double = Profile.toMgdl(targetBlocks.lowTargetBlockValueBySeconds(MidnightUtils.secondsFromMidnight(timestamp), timeshift), units)
override fun getTargetHighMgdl(): Double = Profile.toMgdl(targetBlocks.highTargetBlockValueBySeconds(MidnightUtils.secondsFromMidnight(), timeshift), units)
override fun getTargetHighMgdl(timestamp: Long): Double = Profile.toMgdl(targetBlocks.highTargetBlockValueBySeconds(MidnightUtils.secondsFromMidnight(timestamp), timeshift), units)
override fun getIsfMgdl(): Double = toMgdl(isfBlocks.blockValueBySeconds(MidnightUtils.secondsFromMidnight(), 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 = toMgdl(targetBlocks.targetBlockValueBySeconds(MidnightUtils.secondsFromMidnight(), timeshift), units)
override fun getTargetLowMgdl(): Double = toMgdl(targetBlocks.lowTargetBlockValueBySeconds(MidnightUtils.secondsFromMidnight(), timeshift), units)
override fun getTargetLowMgdl(timestamp: Long): Double = toMgdl(targetBlocks.lowTargetBlockValueBySeconds(MidnightUtils.secondsFromMidnight(timestamp), timeshift), units)
override fun getTargetHighMgdl(): Double = toMgdl(targetBlocks.highTargetBlockValueBySeconds(MidnightUtils.secondsFromMidnight(), 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 getIcTimeFromMidnight(timeAsSeconds: Int): Double = icBlocks.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 getTargetLowMgdlTimeFromMidnight(timeAsSeconds: Int): Double = Profile.toMgdl(targetBlocks.lowTargetBlockValueBySeconds(timeAsSeconds, timeshift), units)
override fun getIsfMgdlTimeFromMidnight(timeAsSeconds: Int): Double = toMgdl(isfBlocks.blockValueBySeconds(timeAsSeconds, 100.0 / percentage, 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 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 =
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) }
var elapsed = 0
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()
}
return ret
@ -377,7 +385,7 @@ sealed class ProfileSealed(
val ret = Array(shifted.size) { ProfileValue(0, 0.0) }
var elapsed = 0
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()
}
return ret
@ -414,4 +422,6 @@ sealed class ProfileSealed(
fun isInProgress(dateUtil: DateUtil): Boolean =
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.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
if (queued) {
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
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.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 {

View file

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

View file

@ -5,9 +5,7 @@ import dagger.android.AndroidInjector
import info.nightscout.core.extensions.pureProfileFromJson
import info.nightscout.core.profile.ProfileSealed
import info.nightscout.interfaces.Config
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.utils.HardLimits
import info.nightscout.rx.TestAapsSchedulers
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(100, p.percentage)
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
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 {
implementation project(':app-wear-shared:shared')
implementation project(':core:interfaces')
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.Validator
import info.nightscout.core.validators.validators.WebUrlValidator
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.shared.interfaces.ProfileUtil
import javax.inject.Inject
@Suppress("SpellCheckingInspection")
@ -61,7 +60,7 @@ class DefaultEditTextValidator : EditTextValidator {
private var floatminNumber = 0f
private var floatmaxNumber = 0f
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var profileUtil: ProfileUtil
@Suppress("unused")
constructor(editTextView: EditText, context: Context) {
@ -98,7 +97,6 @@ class DefaultEditTextValidator : EditTextValidator {
}
private fun setEditText(editText: EditText) {
//editTextView?.removeTextChangedListener(textWatcher)
editTextView = editText
editText.addTextChangedListener(getTextWatcher())
}
@ -110,7 +108,9 @@ class DefaultEditTextValidator : EditTextValidator {
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) {
if (!TextUtils.isEmpty(s) && isErrorShown) {
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_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_BG_RANGE -> BgRangeValidator(if (TextUtils.isEmpty(testErrorString)) context.getString(R.string.error_only_numeric_digits_range_allowed,
Profile.fromMgdlToUnits(minMgdl.toDouble(), profileFunction.getUnits()).toString(), Profile.fromMgdlToUnits(maxMgdl.toDouble(), profileFunction.getUnits()).toString()) else
testErrorString, minMgdl, maxMgdl, profileFunction)
EditTextValidator.TEST_BG_RANGE -> BgRangeValidator(
if (TextUtils.isEmpty(testErrorString)) context.getString(
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 -> {
// 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.PreferenceViewHolder
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.interfaces.ProfileUtil
import javax.inject.Inject
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 var validator: DefaultEditTextValidator? = null
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var profileUtil: ProfileUtil
init {
(ctx.applicationContext as HasAndroidInjector).androidInjector().inject(this)
@ -75,14 +74,14 @@ class ValidatingEditTextPreference(ctx: Context, attrs: AttributeSet, defStyleAt
override fun onSetInitialValue(defaultValue: Any?) {
text =
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
getPersistedString(defaultValue as String?)
}
override fun persistString(value: String?): Boolean =
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())
else -> super.persistString(value)
}

View file

@ -1,15 +1,14 @@
package info.nightscout.core.validators.validators
import android.widget.EditText
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.shared.interfaces.ProfileUtil
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 {
return try {
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) {
false
}

View file

@ -4,8 +4,7 @@ import info.nightscout.annotations.OpenForTesting
import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.profile.DefaultValueHelper
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.sharedPreferences.SP
import javax.inject.Inject
import javax.inject.Singleton
@ -14,7 +13,7 @@ import javax.inject.Singleton
@Singleton
class DefaultValueHelperImpl @Inject constructor(
private val sp: SP,
private val profileFunction: ProfileFunction
private val profileUtil: ProfileUtil
) : DefaultValueHelper {
/**
@ -53,9 +52,9 @@ class DefaultValueHelperImpl @Inject constructor(
* @return
*/
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))
value = Profile.toCurrentUnits(profileFunction, value)
value = profileUtil.valueInCurrentUnitsDetect(value)
return if (value > 0) value else getDefaultEatingSoonTT(units)
}
@ -70,9 +69,9 @@ class DefaultValueHelperImpl @Inject constructor(
* @return
*/
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))
value = Profile.toCurrentUnits(profileFunction, value)
value = profileUtil.valueInCurrentUnitsDetect(value)
return if (value > 0) value else getDefaultActivityTT(units)
}
@ -87,9 +86,9 @@ class DefaultValueHelperImpl @Inject constructor(
* @return
*/
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))
value = Profile.toCurrentUnits(profileFunction, value)
value = profileUtil.valueInCurrentUnitsDetect(value)
return if (value > 0) value else getDefaultHypoTT(units)
}
@ -104,14 +103,14 @@ class DefaultValueHelperImpl @Inject constructor(
override fun determineHighLine(): Double {
var highLineSetting = sp.getDouble(info.nightscout.core.utils.R.string.key_high_mark, bgTargetHigh)
if (highLineSetting < 1) highLineSetting = Constants.HIGH_MARK
highLineSetting = Profile.toCurrentUnits(profileFunction, highLineSetting)
highLineSetting = profileUtil.valueInCurrentUnitsDetect(highLineSetting)
return highLineSetting
}
override fun determineLowLine(): Double {
var lowLineSetting = sp.getDouble(info.nightscout.core.utils.R.string.key_low_mark, bgTargetLow)
if (lowLineSetting < 1) lowLineSetting = Constants.LOW_MARK
lowLineSetting = Profile.toCurrentUnits(profileFunction, lowLineSetting)
lowLineSetting = profileUtil.valueInCurrentUnitsDetect(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.profile.ProfileFunctionImpl
import info.nightscout.implementation.profile.ProfileStoreObject
import info.nightscout.implementation.profile.ProfileUtilImpl
import info.nightscout.implementation.profiling.ProfilerImpl
import info.nightscout.implementation.protection.PasswordCheckImpl
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.storage.FileStorage
import info.nightscout.implementation.userEntry.UserEntryPresentationHelperImpl
import info.nightscout.implementation.utils.DecimalFormatterImpl
import info.nightscout.interfaces.LocalAlertUtils
import info.nightscout.interfaces.NotificationHolder
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.ui.IconsProvider
import info.nightscout.interfaces.userEntry.UserEntryPresentationHelper
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.interfaces.utils.HardLimits
import info.nightscout.interfaces.utils.TrendCalculator
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.interfaces.ResourceHelper
@Module(
@ -81,6 +85,7 @@ abstract class ImplementationModule {
@Module
interface Bindings {
@Binds fun bindPersistenceLayer(persistenceLayerImpl: PersistenceLayerImpl): PersistenceLayer
@Binds fun bindActivePlugin(pluginStore: PluginStore): ActivePlugin
@Binds fun bindOverviewData(overviewData: OverviewDataImpl): OverviewData
@ -108,9 +113,11 @@ abstract class ImplementationModule {
@Binds fun bindNotificationHolderInterface(notificationHolder: NotificationHolderImpl): NotificationHolder
@Binds fun bindCommandQueue(commandQueue: CommandQueueImplementation): CommandQueue
@Binds fun bindsProfileFunction(profileFunctionImpl: ProfileFunctionImpl): ProfileFunction
@Binds fun bindsProfileUtil(profileUtilImpl: ProfileUtilImpl): ProfileUtil
@Binds fun bindsStorage(fileStorage: FileStorage): Storage
@Binds fun bindsReceiverStatusStore(receiverStatusStoreImpl: ReceiverStatusStoreImpl): ReceiverStatusStore
@Binds fun bindsUserEntryPresentationHelper(userEntryPresentationHelperImpl: UserEntryPresentationHelperImpl): UserEntryPresentationHelper
@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.GlucoseStatusProvider
import info.nightscout.interfaces.iob.IobCobCalculator
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag
import info.nightscout.shared.utils.DateUtil
@ -18,7 +19,8 @@ import kotlin.math.roundToLong
class GlucoseStatusProviderImpl @Inject constructor(
private val aapsLogger: AAPSLogger,
private val iobCobCalculator: IobCobCalculator,
private val dateUtil: DateUtil
private val dateUtil: DateUtil,
private val decimalFormatter: DecimalFormatter
) : GlucoseStatusProvider {
override val glucoseStatusData: GlucoseStatus?
@ -100,7 +102,7 @@ class GlucoseStatusProviderImpl @Inject constructor(
shortAvgDelta = shortAverageDelta,
delta = delta,
longAvgDelta = average(longDeltas),
).also { aapsLogger.debug(LTag.GLUCOSE, it.log()) }.asRounded()
).also { aapsLogger.debug(LTag.GLUCOSE, it.log(decimalFormatter)) }.asRounded()
}
/* 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.profile.DefaultValueHelper
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
@ -52,7 +53,8 @@ class OverviewDataImpl @Inject constructor(
private val activePlugin: ActivePlugin,
private val defaultValueHelper: DefaultValueHelper,
private val profileFunction: ProfileFunction,
private val repository: AppRepository
private val repository: AppRepository,
private val decimalFormatter: DecimalFormatter
) : OverviewData {
override var rangeToDisplay = 6 // for graph
@ -182,7 +184,7 @@ class OverviewDataImpl @Inject constructor(
profileFunction.getProfile()?.let { profile ->
var temporaryBasal = iobCobCalculator.getTempBasalIncludingConvertedExtended(dateUtil.now())
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.value_unavailable_short)
@ -190,7 +192,7 @@ class OverviewDataImpl @Inject constructor(
profileFunction.getProfile()?.let { profile ->
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())}" +
"\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.value_unavailable_short)
@ -227,7 +229,7 @@ class OverviewDataImpl @Inject constructor(
} ?: ""
override fun extendedBolusDialogText(iobCobCalculator: IobCobCalculator): String =
iobCobCalculator.getExtendedBolus(dateUtil.now())?.toStringFull(dateUtil) ?: ""
iobCobCalculator.getExtendedBolus(dateUtil.now())?.toStringFull(dateUtil, decimalFormatter) ?: ""
/*
* 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.CustomCommand
import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.interfaces.utils.HtmlHelper
import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.bus.RxBus
@ -95,7 +96,8 @@ class CommandQueueImplementation @Inject constructor(
private val fabricPrivacy: FabricPrivacy,
private val androidPermission: AndroidPermission,
private val uiInteraction: UiInteraction,
private val persistenceLayer: PersistenceLayer
private val persistenceLayer: PersistenceLayer,
private val decimalFormatter: DecimalFormatter
) : CommandQueue {
private val disposable = CompositeDisposable()
@ -132,7 +134,7 @@ class CommandQueueImplementation @Inject constructor(
targetBlocks = nonCustomized.targetBlocks,
glucoseUnit = if (it.glucoseUnit == ProfileSwitch.GlucoseUnit.MGDL) EffectiveProfileSwitch.GlucoseUnit.MGDL else EffectiveProfileSwitch.GlucoseUnit.MMOL,
originalProfileName = it.profileName,
originalCustomizedName = it.getCustomizedName(),
originalCustomizedName = it.getCustomizedName(decimalFormatter),
originalTimeshift = it.timeshift,
originalPercentage = it.percentage,
originalDuration = it.duration,
@ -234,7 +236,7 @@ class CommandQueueImplementation @Inject constructor(
val tempCommandQueue = CommandQueueImplementation(
injector, aapsLogger, rxBus, aapsSchedulers, rh,
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.disposable.clear()

View file

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

View file

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

View file

@ -10,11 +10,10 @@ import android.widget.TableLayout
import android.widget.TextView
import info.nightscout.database.impl.AppRepository
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.TirCalculator
import info.nightscout.interfaces.utils.MidnightTime
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.utils.DateUtil
import info.nightscout.shared.utils.T
@ -24,7 +23,7 @@ import javax.inject.Singleton
@Singleton
class TirCalculatorImpl @Inject constructor(
private val rh: ResourceHelper,
private val profileFunction: ProfileFunction,
private val profileUtil: ProfileUtil,
private val dateUtil: DateUtil,
private val repository: AppRepository
) : TirCalculator {
@ -88,7 +87,7 @@ class TirCalculatorImpl @Inject constructor(
layout.layoutParams = TableLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1f)
layout.addView(
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)
gravity = Gravity.CENTER_HORIZONTAL
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))
layout.addView(
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)
gravity = Gravity.CENTER_HORIZONTAL
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(
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)
gravity = Gravity.CENTER_HORIZONTAL
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.GlucoseUnit
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.utils.DecimalFormatter
import info.nightscout.interfaces.utils.HtmlHelper
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.utils.DateUtil
import javax.inject.Inject
@ -23,9 +22,10 @@ import javax.inject.Inject
@Reusable
class UserEntryPresentationHelperImpl @Inject constructor(
private val translator: Translator,
private val profileFunction: ProfileFunction,
private val profileUtil: ProfileUtil,
private val rh: ResourceHelper,
private val dateUtil: DateUtil
private val dateUtil: DateUtil,
private val decimalFormatter: DecimalFormatter
) : UserEntryPresentationHelper {
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.Minute -> "${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.UnitPerHour -> 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.SimpleInt -> valueWithUnit.value.toString()
is ValueWithUnit.SimpleString -> 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.Mgdl -> {
if (profileFunction.getUnits() == 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)
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)
}
is ValueWithUnit.Mmoll -> {
if (profileFunction.getUnits() == 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)
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)
}
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.ue_string),
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.insulin_unit_shortname),
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.Minute -> minute = valueWithUnit.value.toString()
is ValueWithUnit.Percent -> percent = valueWithUnit.value.toString()
is ValueWithUnit.Insulin -> insulin = DecimalFormatter.to2Decimal(valueWithUnit.value)
is ValueWithUnit.UnitPerHour -> unitPerHour = DecimalFormatter.to2Decimal(valueWithUnit.value)
is ValueWithUnit.Insulin -> insulin = decimalFormatter.to2Decimal(valueWithUnit.value)
is ValueWithUnit.UnitPerHour -> unitPerHour = decimalFormatter.to2Decimal(valueWithUnit.value)
is ValueWithUnit.SimpleInt -> noUnit = noUnit.addWithSeparator(valueWithUnit.value)
is ValueWithUnit.SimpleString -> simpleString = simpleString.addWithSeparator(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.Mgdl ->
bg = Profile.toUnitsString(valueWithUnit.value, valueWithUnit.value * Constants.MGDL_TO_MMOLL, profileFunction.getUnits())
bg = profileUtil.fromMgdlToStringInUnits(valueWithUnit.value)
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
}

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.InMemoryGlucoseValue
import info.nightscout.interfaces.iob.IobCobCalculator
import info.nightscout.shared.utils.DateUtil
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.BeforeEach
import org.junit.jupiter.api.Test
@ -19,9 +18,8 @@ import org.mockito.Mockito
/**
* 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 autosensDataStore: AutosensDataStore
@ -32,7 +30,7 @@ class GlucoseStatusTest : TestBase() {
@Test fun toStringShouldBeOverloaded() {
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() {
@ -42,7 +40,7 @@ class GlucoseStatusTest : TestBase() {
@Test fun calculateValidGlucoseStatus() {
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(-2.0, glucoseStatus.delta, 0.001)
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() {
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(0.0, glucoseStatus.delta, 0.001)
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() {
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)
}
@Test fun oldDataShouldReturnNull() {
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)
}
@Test fun returnOldDataIfAllowed() {
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)
}

View file

@ -6,14 +6,9 @@ import info.nightscout.database.impl.AppRepository
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.aps.AutosensDataStore
import info.nightscout.interfaces.iob.InMemoryGlucoseValue
import info.nightscout.interfaces.plugin.ActivePlugin
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.sharedtests.TestBase
import info.nightscout.sharedtests.TestBaseWithProfile
import io.reactivex.rxjava3.core.Single
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
@ -21,14 +16,9 @@ import org.junit.jupiter.api.Test
import org.mockito.Mock
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 profileFunction: ProfileFunction
@Mock lateinit var repository: AppRepository
@Mock lateinit var autosensDataStore: AutosensDataStore
@ -40,7 +30,7 @@ class OverviewDataImplTest : TestBase() {
@BeforeEach
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.determineHighLine()).thenReturn(180.0)
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.CustomCommand
import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.logging.AAPSLogger
@ -73,11 +74,12 @@ class CommandQueueImplementationTest : TestBaseWithProfile() {
fabricPrivacy: FabricPrivacy,
androidPermission: AndroidPermission,
uiInteraction: UiInteraction,
persistenceLayer: PersistenceLayer
persistenceLayer: PersistenceLayer,
decimalFormatter: DecimalFormatter
) : CommandQueueImplementation(
injector, aapsLogger, rxBus, aapsSchedulers, rh, constraintChecker, profileFunction,
activePlugin, context, sp, config, dateUtil, repository, fabricPrivacy,
androidPermission, uiInteraction, persistenceLayer
androidPermission, uiInteraction, persistenceLayer, decimalFormatter
) {
override fun notifyAboutNewCommand(): Boolean = true
@ -120,7 +122,7 @@ class CommandQueueImplementationTest : TestBaseWithProfile() {
injector, aapsLogger, rxBus, aapsSchedulers, rh,
constraintChecker, profileFunction, activePlugin, context, sp,
config, dateUtil, repository,
fabricPrivacy, androidPermission, uiInteraction, persistenceLayer
fabricPrivacy, androidPermission, uiInteraction, persistenceLayer, decimalFormatter
)
testPumpPlugin = TestPumpPlugin(injector)
@ -157,7 +159,7 @@ class CommandQueueImplementationTest : TestBaseWithProfile() {
val commandQueue = CommandQueueImplementation(
injector, aapsLogger, rxBus, aapsSchedulers, rh,
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)
`when`(handler.post(anyObject())).thenAnswer { invocation: InvocationOnMock ->

View file

@ -55,7 +55,7 @@ class QueueThreadTest : TestBaseWithProfile() {
commandQueue = CommandQueueImplementation(
injector, aapsLogger, rxBus, aapsSchedulers, rh, constraintChecker,
profileFunction, activePlugin, context, sp,
config, dateUtil, repository, fabricPrivacy, androidPermission, uiInteraction, persistenceLayer
config, dateUtil, repository, fabricPrivacy, androidPermission, uiInteraction, persistenceLayer, decimalFormatter
)
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 info.nightscout.core.wizard.BolusWizard
import info.nightscout.implementation.iob.GlucoseStatusProviderImpl
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.aps.AutosensDataStore
import info.nightscout.interfaces.aps.Loop
import info.nightscout.interfaces.constraints.Constraint
@ -43,7 +42,8 @@ class BolusWizardTest : TestBaseWithProfile() {
it.loop = loop
it.dateUtil = dateUtil
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.getIc()).thenReturn(insulinToCarbRatio)
Mockito.`when`(profileFunction.getUnits()).thenReturn(GlucoseUnit.MGDL)
Mockito.`when`(iobCobCalculator.calculateIobFromBolus()).thenReturn(IobTotal(System.currentTimeMillis()))
Mockito.`when`(iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended()).thenReturn(IobTotal(System.currentTimeMillis()))
testPumpPlugin.pumpDescription = PumpDescription().also {

View file

@ -47,6 +47,7 @@ public class LocalInsightFragment extends DaggerFragment implements View.OnClick
@Inject FabricPrivacy fabricPrivacy;
@Inject DateUtil dateUtil;
@Inject AapsSchedulers aapsSchedulers;
@Inject DecimalFormatter decimalFormatter;
private final CompositeDisposable disposable = new CompositeDisposable();
@ -289,7 +290,7 @@ public class LocalInsightFragment extends DaggerFragment implements View.OnClick
if (cartridgeStatus == null) return;
String status;
if (cartridgeStatus.isInserted())
status = DecimalFormatter.INSTANCE.to2Decimal(cartridgeStatus.getRemainingAmount()) + "U";
status = decimalFormatter.to2Decimal(cartridgeStatus.getRemainingAmount()) + "U";
else status = rh.gs(R.string.not_inserted);
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) {
if (localInsightPlugin.getTotalDailyDose() == null) return;
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_basal), DecimalFormatter.INSTANCE.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(R.string.tdd_bolus), decimalFormatter.to2Decimal(tdd.getBolus())));
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.to2Decimal(tdd.getBolusAndBasal())));
}
private void getBaseBasalRateItem(List<View> statusItems) {
if (localInsightPlugin.getActiveBasalRate() == null) return;
ActiveBasalRate activeBasalRate = localInsightPlugin.getActiveBasalRate();
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) {

View file

@ -41,6 +41,7 @@ open class APSResultObject @Inject constructor(val injector: HasAndroidInjector)
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var rh: ResourceHelper
@Inject lateinit var dateUtil: DateUtil
@Inject lateinit var decimalFormatter: DecimalFormatter
override var date: Long = 0
override var reason: String = ""
@ -67,7 +68,7 @@ open class APSResultObject @Inject constructor(val injector: HasAndroidInjector)
}
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 {
val pump = activePlugin.activePump
@ -75,18 +76,18 @@ open class APSResultObject @Inject constructor(val injector: HasAndroidInjector)
// rate
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 (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 "
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 "
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 "
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 "
// 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) {
ret += "$carbsRequiredText "
}
// reason
ret += rh.gs(info.nightscout.core.ui.R.string.reason) + ": " + reason
ret += rh.gs(R.string.reason) + ": " + reason
return ret
}
return if (isCarbsRequired) {
@ -99,24 +100,26 @@ open class APSResultObject @Inject constructor(val injector: HasAndroidInjector)
if (isChangeRequested) {
// rate
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()
) + "% " +
"(" + 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(
"(" + 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(
rate
) + " U/h " +
"(" + 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>"
"(" + 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>"
// 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) {
ret += "$carbsRequiredText<br>"
}
// 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 if (isCarbsRequired) {

View file

@ -17,6 +17,7 @@ import info.nightscout.core.pump.toHtml
import info.nightscout.core.utils.fabric.FabricPrivacy
import info.nightscout.interfaces.aps.Loop
import info.nightscout.interfaces.constraints.Constraint
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.interfaces.utils.HtmlHelper
import info.nightscout.plugins.aps.R
import info.nightscout.plugins.aps.databinding.LoopFragmentBinding
@ -42,6 +43,7 @@ class LoopFragment : DaggerFragment(), MenuProvider {
@Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var loop: Loop
@Inject lateinit var dateUtil: DateUtil
@Inject lateinit var decimalFormatter: DecimalFormatter
@Suppress("PrivatePropertyName")
private val ID_MENU_RUN = 501
@ -64,7 +66,11 @@ class LoopFragment : DaggerFragment(), MenuProvider {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
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.lastrun.text = rh.gs(R.string.executing)
handler.post {
@ -137,9 +143,9 @@ class LoopFragment : DaggerFragment(), MenuProvider {
binding.tbrrequestTime.text = dateUtil.dateAndTimeAndSecondsString(it.lastTBRRequest)
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 =

View file

@ -22,6 +22,7 @@ import info.nightscout.plugins.aps.utils.ScriptReader
import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag
import info.nightscout.shared.SafeParse
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.sharedPreferences.SP
import org.json.JSONArray
import org.json.JSONException
@ -48,6 +49,7 @@ class DetermineBasalAdapterSMBDynamicISFJS internal constructor(private val scri
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var iobCobCalculator: IobCobCalculator
@Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var profileUtil: ProfileUtil
private var profile = 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("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("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));
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.plugin.ActivePlugin
import info.nightscout.interfaces.profile.Instantiator
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.profile.ProfileStore
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.extensions.runOnUiThread
import info.nightscout.shared.extensions.toVisibility
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
@ -59,6 +59,7 @@ import javax.inject.Inject
class AutotuneFragment : DaggerFragment() {
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var profileUtil: ProfileUtil
@Inject lateinit var autotunePlugin: AutotunePlugin
@Inject lateinit var autotuneFS: AutotuneFS
@Inject lateinit var sp: SP
@ -389,7 +390,7 @@ class AutotuneFragment : DaggerFragment() {
nl = "\n"
}
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.profile.Instantiator
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.profile.ProfileStore
import info.nightscout.interfaces.profile.PureProfile
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.LTag
import info.nightscout.shared.SafeParse
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
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 sp: SP
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var profileUtil: ProfileUtil
@Inject lateinit var dateUtil: DateUtil
@Inject lateinit var config: Config
@Inject lateinit var rxBus: RxBus
@ -81,7 +81,7 @@ class ATProfile(profile: Profile, var localInsulin: LocalInsulin, val injector:
fun isf(circadian: Boolean = false): JSONArray {
if (circadian)
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 {
@ -162,7 +162,7 @@ class ATProfile(profile: Profile, var localInsulin: LocalInsulin, val injector:
json.put("sens", jsonArray(pumpProfile.isfBlocks, avgISF / pumpProfileAvgISF))
json.put("carbratio", jsonArray(pumpProfile.icBlocks, avgIC / pumpProfileAvgIC))
} 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("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.profile.PureProfile
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.shared.utils.DateUtil
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
*/
@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 {
min5mCarbImpact = JsonHelper.safeGetDoubleAllowNull(jsonObject, "min_5m_carbimpact") ?: return null
autotuneMin = JsonHelper.safeGetDoubleAllowNull(jsonObject, "autosens_min") ?: return null
@ -122,7 +123,7 @@ class AutotuneCoreTest : TestBaseWithProfile() {
timeZone = timezone,
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) {
return null
}

View file

@ -21,13 +21,13 @@ import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.logging.UserEntryLogger
import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.pump.PumpEnactResult
import info.nightscout.interfaces.queue.Callback
import info.nightscout.interfaces.utils.JsonHelper
import info.nightscout.interfaces.utils.JsonHelper.safeGetDouble
import info.nightscout.rx.logging.LTag
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.utils.DateUtil
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.kotlin.plusAssign
@ -42,6 +42,7 @@ class ActionStartTempTarget(injector: HasAndroidInjector) : Action(injector) {
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var dateUtil: DateUtil
@Inject lateinit var uel: UserEntryLogger
@Inject lateinit var profileUtil: ProfileUtil
private val disposable = CompositeDisposable()
@ -53,7 +54,7 @@ class ActionStartTempTarget(injector: HasAndroidInjector) : Action(injector) {
}
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
override fun doAction(callback: Callback) {
@ -110,8 +111,8 @@ class ActionStartTempTarget(injector: HasAndroidInjector) : Action(injector) {
timestamp = dateUtil.now(),
duration = TimeUnit.MINUTES.toMillis(duration.getMinutes().toLong()),
reason = TemporaryTarget.Reason.AUTOMATION,
lowTarget = Profile.toMgdl(value.value, value.units),
highTarget = Profile.toMgdl(value.value, value.units)
lowTarget = profileUtil.convertToMgdl(value.value, value.units),
highTarget = profileUtil.convertToMgdl(value.value, value.units)
)
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.logging.AAPSLogger
import info.nightscout.rx.logging.LTag
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
@ -35,6 +36,7 @@ abstract class Trigger(val injector: HasAndroidInjector) {
@Inject lateinit var rxBus: RxBus
@Inject lateinit var rh: ResourceHelper
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var profileUtil: ProfileUtil
@Inject lateinit var sp: SP
@Inject lateinit var locationDataContainer: LastLocationDataContainer
@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.interfaces.Constants
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.utils.JsonHelper
import info.nightscout.rx.logging.LTag
import org.json.JSONObject
@ -56,7 +55,7 @@ class TriggerBg(injector: HasAndroidInjector) : Trigger(injector) {
aapsLogger.debug(LTag.AUTOMATION, "NOT ready for execution: " + friendlyDescription())
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())
return true
}

View file

@ -12,7 +12,6 @@ import info.nightscout.automation.elements.LayoutBuilder
import info.nightscout.automation.elements.StaticLabel
import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.utils.JsonHelper
import info.nightscout.rx.logging.LTag
import org.json.JSONObject
@ -78,7 +77,7 @@ class TriggerDelta(injector: HasAndroidInjector) : Trigger(injector) {
DeltaType.LONG_AVERAGE -> glucoseStatus.longAvgDelta
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())
return true
}

View file

@ -12,7 +12,6 @@ import info.nightscout.automation.elements.StaticLabel
import info.nightscout.database.ValueWrapper
import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.utils.JsonHelper
import info.nightscout.rx.logging.LTag
import org.json.JSONObject
@ -53,7 +52,7 @@ class TriggerTempTargetValue(injector: HasAndroidInjector) : Trigger(injector) {
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
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())
return true
}

View file

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

View file

@ -39,8 +39,9 @@ open class TriggerTestBase : TestBaseWithProfile() {
it.repository = repository
it.activePlugin = activePlugin
it.iobCobCalculator = iobCobCalculator
it.glucoseStatusProvider = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculator, dateUtil)
it.glucoseStatusProvider = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculator, dateUtil, decimalFormatter)
it.dateUtil = dateUtil
it.profileUtil = profileUtil
}
if (it is TriggerBg) {
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.interfaces.Constants
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.interfaces.ProfileUtil
import java.text.DecimalFormat
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) {
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var profileUtil: ProfileUtil
private val validator: SWNumberValidator =
if (profileFunction.getUnits() == GlucoseUnit.MMOL)
if (profileUtil.units == GlucoseUnit.MMOL)
SWNumberValidator { value -> value in minMmol..maxMmol }
else
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)
layout.addView(l)
var initValue = sp.getDouble(preferenceId, init)
initValue = Profile.toCurrentUnits(profileFunction.getUnits(), initValue)
initValue = profileUtil.valueInCurrentUnitsDetect(initValue)
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)
else
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.storeInt
import info.nightscout.core.utils.extensions.storeString
import info.nightscout.interfaces.Config
import info.nightscout.interfaces.ApsMode
import info.nightscout.interfaces.Config
import info.nightscout.interfaces.constraints.Constraint
import info.nightscout.interfaces.constraints.Constraints
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.Round
import info.nightscout.plugins.constraints.R
import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
@ -40,22 +39,22 @@ class SafetyPlugin @Inject constructor(
aapsLogger: AAPSLogger,
rh: ResourceHelper,
private val sp: SP,
private val rxBus: RxBus,
private val constraintChecker: Constraints,
private val activePlugin: ActivePlugin,
private val hardLimits: HardLimits,
private val config: Config,
private val iobCobCalculator: IobCobCalculator,
private val dateUtil: DateUtil,
private val uiInteraction: UiInteraction
private val uiInteraction: UiInteraction,
private val decimalFormatter: DecimalFormatter
) : PluginBase(
PluginDescription()
.mainType(PluginType.CONSTRAINTS)
.neverVisible(true)
.alwaysEnabled(true)
.showInList(false)
.pluginName(R.string.safety)
.preferencesId(R.xml.pref_safety),
.mainType(PluginType.CONSTRAINTS)
.neverVisible(true)
.alwaysEnabled(true)
.showInList(false)
.pluginName(R.string.safety)
.preferencesId(R.xml.pref_safety),
aapsLogger, rh, injector
), Constraints, Safety {
@ -115,7 +114,11 @@ class SafetyPlugin @Inject constructor(
override fun applyBasalPercentConstraints(percentRate: Constraint<Int>, profile: Profile): Constraint<Int> {
val currentBasal = profile.getBasal()
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)
applyBasalConstraints(absoluteConstraint, profile)
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.CommandQueue
import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.plugins.R
import info.nightscout.plugins.databinding.ActionsFragmentBinding
import info.nightscout.plugins.general.overview.ui.StatusLightHandler
@ -57,6 +58,7 @@ class ActionsFragment : DaggerFragment() {
@Inject lateinit var sp: SP
@Inject lateinit var dateUtil: DateUtil
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var decimalFormatter: DecimalFormatter
@Inject lateinit var rh: ResourceHelper
@Inject lateinit var statusLightHandler: StatusLightHandler
@Inject lateinit var fabricPrivacy: FabricPrivacy
@ -243,7 +245,7 @@ class ActionsFragment : DaggerFragment() {
binding.extendedBolus.visibility = View.GONE
binding.extendedBolusCancel.visibility = View.VISIBLE
@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 {
binding.extendedBolus.visibility = View.VISIBLE
binding.extendedBolusCancel.visibility = View.GONE
@ -259,7 +261,7 @@ class ActionsFragment : DaggerFragment() {
binding.setTempBasal.visibility = View.GONE
binding.cancelTempBasal.visibility = View.VISIBLE
@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 {
binding.setTempBasal.visibility = View.VISIBLE
binding.cancelTempBasal.visibility = View.GONE

View file

@ -28,7 +28,6 @@ import com.jjoe64.graphview.GraphView
import dagger.android.HasAndroidInjector
import dagger.android.support.DaggerFragment
import info.nightscout.core.extensions.directionToIcon
import info.nightscout.core.extensions.valueToUnitsString
import info.nightscout.core.graph.OverviewData
import info.nightscout.core.iob.displayText
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.PluginBase
import info.nightscout.interfaces.profile.DefaultValueHelper
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.protection.ProtectionCheck
import info.nightscout.interfaces.pump.defs.PumpType
import info.nightscout.interfaces.source.DexcomBoyda
import info.nightscout.interfaces.source.XDripSource
import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.interfaces.utils.JsonHelper
import info.nightscout.interfaces.utils.TrendCalculator
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.toVisibility
import info.nightscout.shared.extensions.toVisibilityKeepSpace
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
@ -120,6 +120,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
@Inject lateinit var rh: ResourceHelper
@Inject lateinit var defaultValueHelper: DefaultValueHelper
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var profileUtil: ProfileUtil
@Inject lateinit var constraintChecker: Constraints
@Inject lateinit var statusLightHandler: StatusLightHandler
@Inject lateinit var processedDeviceStatusData: ProcessedDeviceStatusData
@ -145,6 +146,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
@Inject lateinit var automation: Automation
@Inject lateinit var bgQualityCheck: BgQualityCheck
@Inject lateinit var uiInteraction: UiInteraction
@Inject lateinit var decimalFormatter: DecimalFormatter
private val disposable = CompositeDisposable()
@ -777,7 +779,6 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
@SuppressLint("SetTextI18n")
fun updateBg() {
val units = profileFunction.getUnits()
val lastBg = overviewData.lastBg(iobCobCalculator.ads)
val lastBgColor = overviewData.lastBgColor(context, iobCobCalculator.ads)
val isActualBg = overviewData.isActualBg(iobCobCalculator.ads)
@ -787,7 +788,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
val lastBgDescription = overviewData.lastBgDescription(iobCobCalculator.ads)
runOnUiThread {
_binding ?: return@runOnUiThread
binding.infoLayout.bg.text = lastBg?.valueToUnitsString(units) ?: ""
binding.infoLayout.bg.text = profileUtil.fromMgdlToStringInUnits(lastBg?.value)
binding.infoLayout.bg.setTextColor(lastBgColor)
trendArrow?.let { binding.infoLayout.arrow.setImageResource(it.directionToIcon()) }
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
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.delta.text = Profile.toSignedUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units)
binding.infoLayout.avgDelta.text = Profile.toSignedUnitsString(glucoseStatus.shortAvgDelta, glucoseStatus.shortAvgDelta * Constants.MGDL_TO_MMOLL, units)
binding.infoLayout.longAvgDelta.text = Profile.toSignedUnitsString(glucoseStatus.longAvgDelta, glucoseStatus.longAvgDelta * Constants.MGDL_TO_MMOLL, units)
binding.infoLayout.delta.text = profileUtil.fromMgdlToSignedStringInUnits(glucoseStatus.delta)
binding.infoLayout.avgDelta.text = profileUtil.fromMgdlToSignedStringInUnits(glucoseStatus.shortAvgDelta)
binding.infoLayout.longAvgDelta.text = profileUtil.fromMgdlToSignedStringInUnits(glucoseStatus.longAvgDelta)
} else {
binding.infoLayout.deltaLarge.text = ""
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() {
val iobText = overviewData.iobText(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
runOnUiThread {
_binding ?: return@runOnUiThread
@ -954,7 +955,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
binding.tempTarget,
info.nightscout.core.ui.R.attr.ribbonTextWarningColor,
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 {
// 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,
info.nightscout.core.ui.R.attr.ribbonTextWarningColor,
info.nightscout.core.ui.R.attr.tempTargetBackgroundColor,
Profile.toTargetRangeString(targetUsed, targetUsed, GlucoseUnit.MGDL, units)
profileUtil.toTargetRangeString(targetUsed, targetUsed, GlucoseUnit.MGDL, units)
)
} else {
setRibbon(
binding.tempTarget,
info.nightscout.core.ui.R.attr.ribbonTextDefaultColor,
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 =
String.format(
Locale.getDefault(), "%1$.1f→%2$.1f",
Profile.toUnits(isfMgdl, isfMgdl * Constants.MGDL_TO_MMOLL, profileFunction.getUnits()),
Profile.toUnits(variableSens, variableSens * Constants.MGDL_TO_MMOLL, profileFunction.getUnits())
profileUtil.fromMgdlToUnits(isfMgdl, profileFunction.getUnits()),
profileUtil.fromMgdlToUnits(variableSens, profileFunction.getUnits())
)
binding.infoLayout.variableSensitivity.visibility = View.VISIBLE
} else binding.infoLayout.variableSensitivity.visibility = View.GONE

View file

@ -32,7 +32,8 @@ class StatusLightHandler @Inject constructor(
private val warnColors: WarnColors,
private val config: Config,
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)
@ -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) {
val resUrgent = sp.getDouble(criticalSetting, criticalDefaultValue)
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 = ""
warnColors.setColorInverse(view, level, resWarn, resUrgent)
}
@ -124,7 +125,7 @@ class StatusLightHandler @Inject constructor(
warnDefaultValue: Double, level: Double, units: String, maxReading: Double
) {
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))
} else {
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
} else 0.0
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 dagger.android.HasAndroidInjector
import info.nightscout.core.extensions.toStringShort
import info.nightscout.core.extensions.valueToUnitsString
import info.nightscout.core.iob.generateCOBString
import info.nightscout.core.iob.round
import info.nightscout.core.utils.fabric.FabricPrivacy
import info.nightscout.interfaces.Config
import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.NotificationHolder
import info.nightscout.interfaces.iob.GlucoseStatusProvider
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.PluginDescription
import info.nightscout.interfaces.plugin.PluginType
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.ui.IconsProvider
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.EventRefreshOverview
import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.interfaces.ResourceHelper
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.kotlin.plusAssign
@ -47,6 +45,7 @@ class PersistentNotificationPlugin @Inject constructor(
rh: ResourceHelper,
private val aapsSchedulers: AapsSchedulers,
private val profileFunction: ProfileFunction,
private val profileUtil: ProfileUtil,
private val fabricPrivacy: FabricPrivacy,
private val activePlugins: ActivePlugin,
private val iobCobCalculator: IobCobCalculator,
@ -56,7 +55,8 @@ class PersistentNotificationPlugin @Inject constructor(
private val dummyServiceHelper: DummyServiceHelper,
private val iconsProvider: IconsProvider,
private val glucoseStatusProvider: GlucoseStatusProvider,
private val config: Config
private val config: Config,
private val decimalFormatter: DecimalFormatter
) : PluginBase(
PluginDescription()
.mainType(PluginType.GENERAL)
@ -121,15 +121,14 @@ class PersistentNotificationPlugin @Inject constructor(
var unreadConversationBuilder: NotificationCompat.CarExtender.UnreadConversation.Builder? = null
if (profileFunction.isProfileValid("Notification")) {
var line1aa: String
val units = profileFunction.getUnits()
val lastBG = iobCobCalculator.ads.lastBg()
val glucoseStatus = glucoseStatusProvider.glucoseStatusData
if (lastBG != null) {
line1aa = lastBG.valueToUnitsString(units)
line1aa = profileUtil.fromMgdlToStringInUnits(lastBG.value)
line1 = line1aa
if (glucoseStatus != null) {
line1 += (" Δ" + Profile.toSignedUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units)
+ " avgΔ" + Profile.toSignedUnitsString(glucoseStatus.shortAvgDelta, glucoseStatus.shortAvgDelta * Constants.MGDL_TO_MMOLL, units))
line1 += (" Δ" + profileUtil.fromMgdlToSignedStringInUnits(glucoseStatus.delta)
+ " avgΔ" + profileUtil.fromMgdlToSignedStringInUnits(glucoseStatus.shortAvgDelta))
line1aa += " " + lastBG.trendArrow.symbol
} else {
line1 += " " +
@ -143,22 +142,28 @@ class PersistentNotificationPlugin @Inject constructor(
}
val activeTemp = iobCobCalculator.getTempBasalIncludingConvertedExtended(System.currentTimeMillis())
if (activeTemp != null) {
line1 += " " + activeTemp.toStringShort()
line1aa += " " + activeTemp.toStringShort() + "."
line1 += " " + activeTemp.toStringShort(decimalFormatter)
line1aa += " " + activeTemp.toStringShort(decimalFormatter) + "."
}
//IOB
val bolusIob = iobCobCalculator.calculateIobFromBolus().round()
val basalIob = iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended().round()
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"
).generateCOBString()
).generateCOBString(decimalFormatter)
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"
).generateCOBString() + "."
line3 = DecimalFormatter.to2Decimal(pump.baseBasalRate) + " U/h"
var line3aa = DecimalFormatter.to2Decimal(pump.baseBasalRate) + " U/h."
).generateCOBString(decimalFormatter) + "."
line3 = decimalFormatter.to2Decimal(pump.baseBasalRate) + " U/h"
var line3aa = decimalFormatter.to2Decimal(pump.baseBasalRate) + " U/h."
line3 += " - " + profileFunction.getProfileName()
line3aa += " - " + profileFunction.getProfileName() + "."
/// For Android Auto

View file

@ -12,7 +12,6 @@ import androidx.work.workDataOf
import dagger.android.HasAndroidInjector
import info.nightscout.annotations.OpenForTesting
import info.nightscout.core.events.EventNewNotification
import info.nightscout.core.extensions.valueToUnitsString
import info.nightscout.core.iob.generateCOBString
import info.nightscout.core.iob.round
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.PluginDescription
import info.nightscout.interfaces.plugin.PluginType
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.pump.DetailedBolusInfo
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.LTag
import info.nightscout.shared.SafeParse
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
@ -95,6 +94,7 @@ class SmsCommunicatorPlugin @Inject constructor(
private val constraintChecker: Constraints,
private val rxBus: RxBus,
private val profileFunction: ProfileFunction,
private val profileUtil: ProfileUtil,
private val fabricPrivacy: FabricPrivacy,
private val activePlugin: ActivePlugin,
private val commandQueue: CommandQueue,
@ -106,7 +106,8 @@ class SmsCommunicatorPlugin @Inject constructor(
private val dateUtil: DateUtil,
private val uel: UserEntryLogger,
private val glucoseStatusProvider: GlucoseStatusProvider,
private val repository: AppRepository
private val repository: AppRepository,
private val decimalFormatter: DecimalFormatter
) : PluginBase(
PluginDescription()
.mainType(PluginType.GENERAL)
@ -353,23 +354,23 @@ class SmsCommunicatorPlugin @Inject constructor(
val actualBG = iobCobCalculator.ads.actualBg()
val lastBG = iobCobCalculator.ads.lastBg()
var reply = ""
val units = profileFunction.getUnits()
val units = profileUtil.units
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) {
val agoMilliseconds = dateUtil.now() - lastBG.timestamp
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
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 basalIob = iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended().round()
val cobInfo = iobCobCalculator.getCobInfo("SMS COB")
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_basal) + " " + DecimalFormatter.to2Decimal(basalIob.basaliob) + "U), "
+ rh.gs(info.nightscout.core.ui.R.string.cob) + ": " + cobInfo.generateCOBString())
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_basal) + " " + decimalFormatter.to2Decimal(basalIob.basaliob) + "U), "
+ rh.gs(info.nightscout.core.ui.R.string.cob) + ": " + cobInfo.generateCOBString(decimalFormatter))
sendSMS(Sms(receivedSms.phoneNumber, reply))
receivedSms.processed = true
}
@ -966,8 +967,8 @@ class SmsCommunicatorPlugin @Inject constructor(
timestamp = dateUtil.now(),
duration = TimeUnit.MINUTES.toMillis(eatingSoonTTDuration.toLong()),
reason = TemporaryTarget.Reason.EATING_SOON,
lowTarget = Profile.toMgdl(eatingSoonTT, profileFunction.getUnits()),
highTarget = Profile.toMgdl(eatingSoonTT, profileFunction.getUnits())
lowTarget = profileUtil.convertToMgdl(eatingSoonTT, profileUtil.units),
highTarget = profileUtil.convertToMgdl(eatingSoonTT, profileUtil.units)
)
).subscribe({ result ->
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)
})
val tt = if (currentProfile.units == GlucoseUnit.MMOL) {
DecimalFormatter.to1Decimal(eatingSoonTT)
} else DecimalFormatter.to0Decimal(eatingSoonTT)
decimalFormatter.to1Decimal(eatingSoonTT)
} else decimalFormatter.to0Decimal(eatingSoonTT)
replyText += "\n" + rh.gs(R.string.smscommunicator_meal_bolus_delivered_tt, tt, eatingSoonTTDuration)
}
}
@ -1078,7 +1079,7 @@ class SmsCommunicatorPlugin @Inject constructor(
receivedSms.processed = true
messageToConfirm = AuthRequest(injector, receivedSms, reply, passCode, object : SmsAction(pumpCommand = false) {
override fun run() {
val units = profileFunction.getUnits()
val units = profileUtil.units
var keyDuration = 0
var defaultTargetDuration = 0
var keyTarget = 0
@ -1116,15 +1117,15 @@ class SmsCommunicatorPlugin @Inject constructor(
var ttDuration = sp.getInt(keyDuration, defaultTargetDuration)
ttDuration = if (ttDuration > 0) ttDuration else defaultTargetDuration
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
disposable += repository.runTransactionForResult(
InsertAndCancelCurrentTemporaryTargetTransaction(
timestamp = dateUtil.now(),
duration = TimeUnit.MINUTES.toMillis(ttDuration.toLong()),
reason = reason,
lowTarget = Profile.toMgdl(tt, profileFunction.getUnits()),
highTarget = Profile.toMgdl(tt, profileFunction.getUnits())
lowTarget = profileUtil.convertToMgdl(tt, profileUtil.units),
highTarget = profileUtil.convertToMgdl(tt, profileUtil.units)
)
).subscribe({ result ->
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)
})
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)
sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, replyText))
uel.log(

View file

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

View file

@ -19,7 +19,6 @@ import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.logging.UserEntryLogger
import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.protection.ProtectionCheck
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.shared.SafeParse
import info.nightscout.shared.extensions.toVisibility
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.utils.DateUtil
import io.reactivex.rxjava3.disposables.CompositeDisposable
@ -52,12 +52,14 @@ class ProfileFragment : DaggerFragment() {
@Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var profilePlugin: ProfilePlugin
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var profileUtil: ProfileUtil
@Inject lateinit var hardLimits: HardLimits
@Inject lateinit var protectionCheck: ProtectionCheck
@Inject lateinit var dateUtil: DateUtil
@Inject lateinit var aapsSchedulers: AapsSchedulers
@Inject lateinit var uel: UserEntryLogger
@Inject lateinit var uiInteraction: UiInteraction
@Inject lateinit var decimalFormatter: DecimalFormatter
private var disposable: CompositeDisposable = CompositeDisposable()
private var inMenu = false
@ -89,7 +91,7 @@ class ProfileFragment : DaggerFragment() {
private fun sumLabel(): String {
val profile = profilePlugin.getEditedProfile()
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
@ -207,19 +209,19 @@ class ProfileFragment : DaggerFragment() {
)
} else {
val isfRange = doubleArrayOf(
roundUp(Profile.fromMgdlToUnits(HardLimits.MIN_ISF, GlucoseUnit.MMOL)),
roundDown(Profile.fromMgdlToUnits(HardLimits.MAX_ISF, GlucoseUnit.MMOL))
roundUp(profileUtil.fromMgdlToUnits(HardLimits.MIN_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,
DecimalFormat
("0.0"), save)
val range1 = doubleArrayOf(
roundUp(Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_MIN_BG[0], GlucoseUnit.MMOL)),
roundDown(Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_MIN_BG[1], GlucoseUnit.MMOL))
roundUp(profileUtil.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_MIN_BG[0], GlucoseUnit.MMOL)),
roundDown(profileUtil.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_MIN_BG[1], GlucoseUnit.MMOL))
)
val range2 = doubleArrayOf(
roundUp(Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_MAX_BG[0], GlucoseUnit.MMOL)),
roundDown(Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_MAX_BG[1], GlucoseUnit.MMOL))
roundUp(profileUtil.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_MAX_BG[0], 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])
TimeListEdit(

View file

@ -31,6 +31,7 @@ import info.nightscout.rx.events.EventLocalProfileChanged
import info.nightscout.rx.events.EventProfileStoreChanged
import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
@ -50,11 +51,13 @@ class ProfilePlugin @Inject constructor(
rh: ResourceHelper,
private val sp: SP,
private val profileFunction: ProfileFunction,
private val profileUtil: ProfileUtil,
private val activePlugin: ActivePlugin,
private val hardLimits: HardLimits,
private val dateUtil: DateUtil,
private val config: Config,
private val instantiator: Instantiator
private val instantiator: Instantiator,
private val decimalFormatter: DecimalFormatter
) : PluginBase(
PluginDescription()
.mainType(PluginType.PROFILE)
@ -121,7 +124,7 @@ class ProfilePlugin @Inject constructor(
return false
}
} 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))
return false
}
@ -129,11 +132,11 @@ class ProfilePlugin @Inject constructor(
ToastUtils.errorToast(activity, rh.gs(R.string.error_in_basal_values))
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))
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))
return false
}
@ -420,6 +423,6 @@ class ProfilePlugin @Inject constructor(
override val profileName: String
get() = rawProfile?.getDefaultProfile()?.let {
DecimalFormatter.to2Decimal(ProfileSealed.Pure(it).percentageBasalSum()) + "U "
decimalFormatter.to2Decimal(ProfileSealed.Pure(it).percentageBasalSum()) + "U "
} ?: "INVALID"
}

View file

@ -14,13 +14,6 @@ class GlucoseValueExtensionKtTest : TestBaseWithProfile() {
private val inMemoryGlucoseValue = InMemoryGlucoseValue(1000, 100.0, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN)
@Test
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
fun inMemoryValueToUnits() {

View file

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

View file

@ -12,7 +12,6 @@ import info.nightscout.database.impl.transactions.Transaction
import info.nightscout.implementation.iob.GlucoseStatusProviderImpl
import info.nightscout.interfaces.ApsMode
import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.XDripBroadcast
import info.nightscout.interfaces.aps.AutosensDataStore
import info.nightscout.interfaces.aps.Loop
@ -99,13 +98,13 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
repository.runTransactionForResult(anyObject<InsertAndCancelCurrentTemporaryTargetTransaction>())
).thenReturn(Single.just(InsertAndCancelCurrentTemporaryTargetTransaction.TransactionResult().apply {
}))
val glucoseStatusProvider = GlucoseStatusProviderImpl(aapsLogger = aapsLogger, iobCobCalculator = iobCobCalculator, dateUtil = dateUtilMocked)
val glucoseStatusProvider = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculator, dateUtilMocked, decimalFormatter)
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,
otp, config, dateUtilMocked, uel,
glucoseStatusProvider, repository
glucoseStatusProvider, repository, decimalFormatter
)
smsCommunicatorPlugin.setPluginEnabled(PluginType.GENERAL, true)
Mockito.doAnswer { invocation: InvocationOnMock ->
@ -158,7 +157,6 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
`when`(activePlugin.activeProfileSource).thenReturn(profileSource)
`when`(profileFunction.getUnits()).thenReturn(GlucoseUnit.MGDL)
`when`(otp.name()).thenReturn("User")
`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 dagger.android.support.DaggerFragment
import info.nightscout.core.extensions.directionToIcon
import info.nightscout.core.extensions.valueToUnitsString
import info.nightscout.core.ui.dialogs.OKDialog
import info.nightscout.core.utils.ActionModeHelper
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.shared.extensions.toVisibility
import info.nightscout.shared.extensions.toVisibilityKeepSpace
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.utils.DateUtil
import info.nightscout.shared.utils.T
@ -58,6 +58,7 @@ class BGSourceFragment : DaggerFragment(), MenuProvider {
@Inject lateinit var uel: UserEntryLogger
@Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var profileUtil: ProfileUtil
private val disposable = CompositeDisposable()
private val millsToThePast = T.hours(36).msecs()
@ -142,7 +143,7 @@ class BGSourceFragment : DaggerFragment(), MenuProvider {
holder.binding.date.visibility = newDay.toVisibility()
holder.binding.date.text = if (newDay) dateUtil.dateStringRelative(glucoseValue.timestamp, rh) else ""
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())
if (position > 0) {
val previous = glucoseValues[position - 1]
@ -183,7 +184,7 @@ class BGSourceFragment : DaggerFragment(), MenuProvider {
private fun getConfirmationText(selectedItems: SparseArray<GlucoseValue>): String {
if (selectedItems.size() == 1) {
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())
}

View file

@ -24,12 +24,12 @@ import info.nightscout.interfaces.logging.UserEntryLogger
import info.nightscout.interfaces.plugin.PluginBase
import info.nightscout.interfaces.plugin.PluginDescription
import info.nightscout.interfaces.plugin.PluginType
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.source.BgSource
import info.nightscout.interfaces.source.DexcomBoyda
import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag
import info.nightscout.shared.extensions.safeGetInstalledPackages
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
@ -85,6 +85,7 @@ class DexcomPlugin @Inject constructor(
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
@Inject lateinit var repository: AppRepository
@Inject lateinit var uel: UserEntryLogger
@Inject lateinit var profileUtil: ProfileUtil
override suspend fun doWorkAndLog(): Result {
var ret = Result.success()
@ -110,7 +111,7 @@ class DexcomPlugin @Inject constructor(
CgmSourceTransaction.Calibration(
timestamp = it.getLong("timestamp") * 1000,
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.receivers.Intents
import info.nightscout.interfaces.receivers.ReceiverStatusStore
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.plugins.sync.R
import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.bus.RxBus
@ -57,7 +58,8 @@ class DataBroadcastPlugin @Inject constructor(
private val activePlugin: ActivePlugin,
private var receiverStatusStore: ReceiverStatusStore,
private val config: Config,
private val glucoseStatusProvider: GlucoseStatusProvider
private val glucoseStatusProvider: GlucoseStatusProvider,
private val decimalFormatter: DecimalFormatter
) : PluginBase(
PluginDescription()
.mainType(PluginType.SYNC)
@ -105,7 +107,6 @@ class DataBroadcastPlugin @Inject constructor(
val bundle = Bundle()
prepareData(event, bundle)
//aapsLogger.debug("Prepared bundle:\n" + BundleLogger.log(bundle))
sendBroadcast(
Intent(Intents.AAPS_BROADCAST) // "info.nightscout.androidaps.status"
.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
@ -176,7 +177,7 @@ class DataBroadcastPlugin @Inject constructor(
bundle.putLong("tempBasalDurationInMinutes", it.durationInMinutes)
if (it.isAbsolute) bundle.putDouble("tempBasalAbsolute", it.rate) // U/h for absolute 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.nsclient.NSAlarm
import info.nightscout.interfaces.nsclient.NSSettingsStatus
import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.plugin.PluginBase
import info.nightscout.interfaces.plugin.PluginDescription
import info.nightscout.interfaces.plugin.PluginType
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.sync.DataSyncSelector
import info.nightscout.interfaces.sync.NsClient
import info.nightscout.interfaces.sync.Sync
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.plugins.sync.R
import info.nightscout.plugins.sync.nsShared.NSClientFragment
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.logging.AAPSLogger
import info.nightscout.rx.logging.LTag
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
@ -61,10 +61,10 @@ class NSClientPlugin @Inject constructor(
private val receiverDelegate: ReceiverDelegate,
private val config: Config,
private val dataSyncSelectorV1: DataSyncSelectorV1,
private val activePlugin: ActivePlugin,
private val dateUtil: DateUtil,
private val profileFunction: ProfileFunction,
private val nsSettingsStatus: NSSettingsStatus
private val profileUtil: ProfileUtil,
private val nsSettingsStatus: NSSettingsStatus,
private val decimalFormatter: DecimalFormatter
) : NsClient, Sync, PluginBase(
PluginDescription()
.mainType(PluginType.SYNC)
@ -200,15 +200,15 @@ class NSClientPlugin @Inject constructor(
when (dataPair) {
is DataSyncSelector.PairBolus -> dataPair.value.toJson(true, dateUtil)
is DataSyncSelector.PairCarbs -> dataPair.value.toJson(true, dateUtil)
is DataSyncSelector.PairBolusCalculatorResult -> dataPair.value.toJson(true, dateUtil, profileFunction)
is DataSyncSelector.PairTemporaryTarget -> dataPair.value.toJson(true, profileFunction.getUnits(), dateUtil)
is DataSyncSelector.PairBolusCalculatorResult -> dataPair.value.toJson(true, dateUtil, profileUtil)
is DataSyncSelector.PairTemporaryTarget -> dataPair.value.toJson(true, dateUtil, profileUtil)
is DataSyncSelector.PairFood -> dataPair.value.toJson(true)
is DataSyncSelector.PairGlucoseValue -> dataPair.value.toJson(true, dateUtil)
is DataSyncSelector.PairTherapyEvent -> dataPair.value.toJson(true, dateUtil)
is DataSyncSelector.PairDeviceStatus -> dataPair.value.toJson(dateUtil)
is DataSyncSelector.PairTemporaryBasal -> 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.PairOfflineEvent -> dataPair.value.toJson(true, dateUtil)
is DataSyncSelector.PairProfileStore -> dataPair.value
@ -238,14 +238,14 @@ class NSClientPlugin @Inject constructor(
when (dataPair) {
is DataSyncSelector.PairBolus -> dataPair.value.toJson(false, dateUtil)
is DataSyncSelector.PairCarbs -> dataPair.value.toJson(false, dateUtil)
is DataSyncSelector.PairBolusCalculatorResult -> dataPair.value.toJson(false, dateUtil, profileFunction)
is DataSyncSelector.PairTemporaryTarget -> dataPair.value.toJson(false, profileFunction.getUnits(), dateUtil)
is DataSyncSelector.PairBolusCalculatorResult -> dataPair.value.toJson(false, dateUtil, profileUtil)
is DataSyncSelector.PairTemporaryTarget -> dataPair.value.toJson(false, dateUtil, profileUtil)
is DataSyncSelector.PairFood -> dataPair.value.toJson(false)
is DataSyncSelector.PairGlucoseValue -> dataPair.value.toJson(false, dateUtil)
is DataSyncSelector.PairTherapyEvent -> dataPair.value.toJson(false, dateUtil)
is DataSyncSelector.PairTemporaryBasal -> 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.PairOfflineEvent -> dataPair.value.toJson(false, dateUtil)
else -> null

View file

@ -3,21 +3,20 @@ package info.nightscout.plugins.sync.nsclient.extensions
import com.google.gson.Gson
import com.google.gson.JsonSyntaxException
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.shared.interfaces.ProfileUtil
import info.nightscout.shared.utils.DateUtil
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()
.put("eventType", info.nightscout.database.entities.TherapyEvent.Type.BOLUS_WIZARD.text)
.put("created_at", dateUtil.toISOString(timestamp))
.put("isValid", isValid)
.put("bolusCalculatorResult", Gson().toJson(this))
.put("date", timestamp)
.put("glucose", Profile.fromMgdlToUnits(glucoseValue, profileFunction.getUnits()))
.put("units", profileFunction.getUnits().asText)
.put("glucose", profileUtil.fromMgdlToUnits(glucoseValue))
.put("units", profileUtil.units.asText)
.put("notes", note)
.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.embedments.InterfaceIDs
import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.interfaces.utils.JsonHelper
import info.nightscout.shared.utils.DateUtil
import info.nightscout.shared.utils.T
import org.json.JSONObject
fun ProfileSwitch.toJson(isAdd: Boolean, dateUtil: DateUtil): JSONObject =
fun ProfileSwitch.toJson(isAdd: Boolean, dateUtil: DateUtil, decimalFormatter: DecimalFormatter): JSONObject =
JSONObject()
.put("timeshift", timeshift)
.put("percentage", percentage)
.put("duration", T.msecs(duration).mins())
.put("profile", getCustomizedName())
.put("profile", getCustomizedName(decimalFormatter))
.put("originalProfileName", profileName)
.put("originalDuration", duration)
.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.interfaces.Constants
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.utils.JsonHelper
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.utils.DateUtil
import info.nightscout.shared.utils.T
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 timestamp = JsonHelper.safeGetLongAllowNull(jsonObject, "mills", null) ?: return null
val duration = JsonHelper.safeGetLongAllowNull(jsonObject, "duration", null) ?: return null
val durationInMilliseconds = JsonHelper.safeGetLongAllowNull(jsonObject, "durationInMilliseconds")
var low = JsonHelper.safeGetDouble(jsonObject, "targetBottom")
low = Profile.toMgdl(low, units)
low = profileUtil.convertToMgdl(low, units)
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)
?: return null else ""
// 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
}
fun TemporaryTarget.toJson(isAdd: Boolean, units: GlucoseUnit, dateUtil: DateUtil): JSONObject =
fun TemporaryTarget.toJson(isAdd: Boolean, dateUtil: DateUtil, profileUtil: ProfileUtil): JSONObject =
JSONObject()
.put("eventType", info.nightscout.database.entities.TherapyEvent.Type.TEMPORARY_TARGET.text)
.put("duration", T.msecs(duration).mins())
@ -58,8 +58,8 @@ fun TemporaryTarget.toJson(isAdd: Boolean, units: GlucoseUnit, dateUtil: DateUti
.put("enteredBy", "AndroidAPS").also {
if (lowTarget > 0) it
.put("reason", reason.text)
.put("targetBottom", Profile.fromMgdlToUnits(lowTarget, units))
.put("targetTop", Profile.fromMgdlToUnits(highTarget, units))
.put("units", units.asText)
.put("targetBottom", profileUtil.fromMgdlToUnits(lowTarget))
.put("targetTop", profileUtil.fromMgdlToUnits(highTarget))
.put("units", profileUtil.units.asText)
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.rx.bus.RxBus
import info.nightscout.rx.logging.LTag
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
import kotlinx.coroutines.Dispatchers
@ -46,6 +47,7 @@ class NSClientAddUpdateWorker(
@Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var rxBus: RxBus
@Inject lateinit var storeDataForDb: StoreDataForDb
@Inject lateinit var profileUtil: ProfileUtil
override suspend fun doWorkAndLog(): Result {
val treatments = dataWorkerStorage.pickupJSONArray(inputData.getLong(DataWorkerStorage.STORE_KEY, -1))
@ -100,7 +102,7 @@ class NSClientAddUpdateWorker(
insulin > 0 || carbs > 0 -> Any()
eventType == TherapyEvent.Type.TEMPORARY_TARGET.text ->
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)
} ?: 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.Sync
import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.plugins.sync.R
import info.nightscout.plugins.sync.nsShared.NSClientFragment
import info.nightscout.plugins.sync.nsShared.NsIncomingDataProcessor
@ -121,7 +122,8 @@ class NSClientV3Plugin @Inject constructor(
private val nsDeviceStatusHandler: NSDeviceStatusHandler,
private val nsClientSource: NSClientSource,
private val nsIncomingDataProcessor: NsIncomingDataProcessor,
private val storeDataForDb: StoreDataForDb
private val storeDataForDb: StoreDataForDb,
private val decimalFormatter: DecimalFormatter
) : NsClient, Sync, PluginBase(
PluginDescription()
.mainType(PluginType.SYNC)
@ -795,7 +797,7 @@ class NSClientV3Plugin @Inject constructor(
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.PairOfflineEvent -> dataPair.value.toNSOfflineEvent()
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.embedments.InterfaceIDs
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.NSProfileSwitch
import info.nightscout.shared.utils.DateUtil
@ -38,8 +39,8 @@ fun NSProfileSwitch.toProfileSwitch(activePlugin: ActivePlugin, dateUtil: DateUt
)
}
fun ProfileSwitch.toNSProfileSwitch(dateUtil: DateUtil): NSProfileSwitch {
val unmodifiedCustomizedName = getCustomizedName()
fun ProfileSwitch.toNSProfileSwitch(dateUtil: DateUtil, decimalFormatter: DecimalFormatter): NSProfileSwitch {
val unmodifiedCustomizedName = getCustomizedName(decimalFormatter)
// ProfileSealed.PS doesn't provide unmodified json -> reset it
val notCustomized = this.copy()
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.logging.AAPSLogger
import info.nightscout.rx.logging.LTag
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
import info.nightscout.shared.utils.T
@ -33,6 +34,7 @@ class UploadChunk @Inject constructor(
private val rxBus: RxBus,
private val aapsLogger: AAPSLogger,
private val profileFunction: ProfileFunction,
private val profileUtil: ProfileUtil,
private val activePlugin: ActivePlugin,
private val repository: AppRepository,
private val dateUtil: DateUtil
@ -111,7 +113,7 @@ class UploadChunk @Inject constructor(
private fun getBloodTests(start: Long, end: Long): List<BloodGlucoseElement> {
val readings = repository.compatGetTherapyEventDataFromToTime(start, end).blockingGet()
val selection = BloodGlucoseElement.fromCareportalEvents(readings, dateUtil)
val selection = BloodGlucoseElement.fromCareportalEvents(readings, dateUtil, profileUtil)
if (selection.isNotEmpty())
rxBus.send(EventTidepoolStatus("${selection.size} BGs selected for upload"))
return selection
@ -140,14 +142,14 @@ class UploadChunk @Inject constructor(
private fun getBasals(start: Long, end: Long): List<BasalElement> {
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())
rxBus.send(EventTidepoolStatus("${selection.size} TBRs selected for upload"))
return selection
}
private fun newInstanceOrNull(ps: EffectiveProfileSwitch): ProfileElement? = try {
ProfileElement(ps, activePlugin.activePump.serialNumber(), dateUtil)
ProfileElement(ps, activePlugin.activePump.serialNumber(), dateUtil, profileUtil)
} catch (e: Throwable) {
null
}

View file

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

View file

@ -5,18 +5,22 @@ import info.nightscout.core.profile.ProfileSealed
import info.nightscout.database.entities.EffectiveProfileSwitch
import info.nightscout.interfaces.profile.Profile
import info.nightscout.plugins.sync.tidepool.comm.TidepoolUploader
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.utils.DateUtil
import java.util.UUID
class ProfileElement(ps: EffectiveProfileSwitch, serialNumber: String, dateUtil: DateUtil)
: BaseElement(ps.timestamp, UUID.nameUUIDFromBytes(("AAPS-profile" + ps.timestamp).toByteArray()).toString(), dateUtil) {
class ProfileElement(ps: EffectiveProfileSwitch, serialNumber: String, dateUtil: DateUtil, profileUtil: ProfileUtil) :
BaseElement(ps.timestamp, UUID.nameUUIDFromBytes(("AAPS-profile" + ps.timestamp).toByteArray()).toString(), dateUtil) {
@Expose
internal var activeSchedule = "Normal"
@Expose
internal var basalSchedules: BasalProfile = BasalProfile()
@Expose
internal var units: Units = Units()
@Expose
internal var bgTargets: TargetProfile = TargetProfile()
@Expose
@ -46,7 +50,12 @@ class ProfileElement(ps: EffectiveProfileSwitch, serialNumber: String, dateUtil:
for (hour in 0..23) {
val seconds = hour * 3600
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()))
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.WorkManager
import dagger.android.HasAndroidInjector
import info.nightscout.core.extensions.toJson
import info.nightscout.core.extensions.toStringShort
import info.nightscout.core.iob.generateCOBString
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.LTag
import info.nightscout.shared.extensions.safeQueryBroadcastReceivers
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
@ -70,6 +70,7 @@ class XdripPlugin @Inject constructor(
injector: HasAndroidInjector,
private val sp: SP,
private val profileFunction: ProfileFunction,
private val profileUtil: ProfileUtil,
rh: ResourceHelper,
private val aapsSchedulers: AapsSchedulers,
private val context: Context,
@ -79,7 +80,8 @@ class XdripPlugin @Inject constructor(
private val rxBus: RxBus,
private val uiInteraction: UiInteraction,
private val dateUtil: DateUtil,
aapsLogger: AAPSLogger
aapsLogger: AAPSLogger,
private val decimalFormatter: DecimalFormatter
) : XDripBroadcast, Sync, PluginBase(
PluginDescription()
.mainType(PluginType.SYNC)
@ -238,26 +240,26 @@ class XdripPlugin @Inject constructor(
//Temp basal
iobCobCalculator.getTempBasalIncludingConvertedExtended(System.currentTimeMillis())?.let {
status.append(it.toStringShort()).append(" ")
status.append(it.toStringShort(decimalFormatter)).append(" ")
}
//IOB
val bolusIob = iobCobCalculator.calculateIobFromBolus().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))
status.append("(")
.append(DecimalFormatter.to2Decimal(bolusIob.iob))
.append(decimalFormatter.to2Decimal(bolusIob.iob))
.append("|")
.append(DecimalFormatter.to2Decimal(basalIob.basaliob))
.append(decimalFormatter.to2Decimal(basalIob.basaliob))
.append(")")
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(" ")
.append(if (bgi >= 0) "+" else "")
.append(DecimalFormatter.to2Decimal(bgi))
.append(decimalFormatter.to2Decimal(bgi))
}
// COB
status.append(" ").append(iobCobCalculator.getCobInfo("StatusLinePlugin").generateCOBString())
status.append(" ").append(iobCobCalculator.getCobInfo("StatusLinePlugin").generateCOBString(decimalFormatter))
return status.toString()
}
@ -392,8 +394,8 @@ class XdripPlugin @Inject constructor(
when (dataPair) {
is DataSyncSelector.PairBolus -> dataPair.value.toJson(true, dateUtil)
is DataSyncSelector.PairCarbs -> dataPair.value.toJson(true, dateUtil)
is DataSyncSelector.PairBolusCalculatorResult -> dataPair.value.toJson(true, dateUtil, profileFunction)
is DataSyncSelector.PairTemporaryTarget -> dataPair.value.toJson(true, profileFunction.getUnits(), dateUtil)
is DataSyncSelector.PairBolusCalculatorResult -> dataPair.value.toJson(true, dateUtil, profileUtil)
is DataSyncSelector.PairTemporaryTarget -> dataPair.value.toJson(true, dateUtil, profileUtil)
is DataSyncSelector.PairTherapyEvent -> dataPair.value.toJson(true, dateUtil)
is DataSyncSelector.PairTemporaryBasal -> {
@ -406,7 +408,7 @@ class XdripPlugin @Inject constructor(
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.PairOfflineEvent -> dataPair.value.toJson(true, dateUtil)
else -> null

View file

@ -43,7 +43,7 @@ internal class DataBroadcastPluginTest : TestBaseWithProfile() {
fun setUp() {
sut = DataBroadcastPlugin(
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`(autosensDataStore.lastBg()).thenReturn(InMemoryGlucoseValue(1000, 100.0, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN))

View file

@ -82,7 +82,7 @@ internal class NSClientV3PluginTest : TestBaseWithProfile() {
NSClientV3Plugin(
injector, aapsLogger, aapsSchedulers, rxBus, rh, context, fabricPrivacy,
sp, receiverDelegate, config, dateUtil, uiInteraction, dataSyncSelectorV3, repository,
nsDeviceStatusHandler, nsClientSource, nsIncomingDataProcessor, storeDataForDb
nsDeviceStatusHandler, nsClientSource, nsIncomingDataProcessor, storeDataForDb, decimalFormatter
)
sut.nsAndroidClient = nsAndroidClient
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.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.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.embedments.InterfaceIDs
import info.nightscout.database.impl.AppRepository
import info.nightscout.implementation.utils.DecimalFormatterImpl
import info.nightscout.interfaces.Config
import info.nightscout.interfaces.nsclient.StoreDataForDb
import info.nightscout.interfaces.receivers.ReceiverStatusStore
import info.nightscout.interfaces.source.NSClientSource
import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.plugins.sync.nsShared.NsIncomingDataProcessor
import info.nightscout.plugins.sync.nsclient.ReceiverDelegate
import info.nightscout.plugins.sync.nsclient.data.NSDeviceStatusHandler
@ -68,6 +70,7 @@ internal class LoadBgWorkerTest : TestBase() {
private lateinit var nsClientV3Plugin: NSClientV3Plugin
private lateinit var receiverDelegate: ReceiverDelegate
private lateinit var dataWorkerStorage: DataWorkerStorage
private lateinit var decimalFormatter: DecimalFormatter
private lateinit var sut: LoadBgWorker
private val now = 1000000000L
@ -90,6 +93,7 @@ internal class LoadBgWorkerTest : TestBase() {
@BeforeEach
fun setUp() {
decimalFormatter = DecimalFormatterImpl(rh)
Mockito.`when`(context.applicationContext).thenReturn(context)
Mockito.`when`(context.androidInjector()).thenReturn(injector.androidInjector())
Mockito.`when`(dateUtil.now()).thenReturn(now)
@ -99,7 +103,7 @@ internal class LoadBgWorkerTest : TestBase() {
nsClientV3Plugin = NSClientV3Plugin(
injector, aapsLogger, aapsSchedulers, rxBus, rh, context, fabricPrivacy,
sp, receiverDelegate, config, dateUtil, uiInteraction, dataSyncSelectorV3, repository,
nsDeviceStatusHandler, nsClientSource, nsIncomingDataProcessor, storeDataForDb
nsDeviceStatusHandler, nsClientSource, nsIncomingDataProcessor, storeDataForDb, decimalFormatter
)
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.toNonce
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.UtcOffset
import kotlin.reflect.KClassifier

View file

@ -114,7 +114,8 @@ class ComboV2Plugin @Inject constructor (
private val dateUtil: DateUtil,
private val uiInteraction: UiInteraction,
private val androidPermission: AndroidPermission,
private val config: Config
private val config: Config,
private val decimalFormatter: DecimalFormatter
) :
PumpPluginBase(
PluginDescription()
@ -1456,7 +1457,7 @@ class ComboV2Plugin @Inject constructor (
lastBolusUIFlow.value?.let {
val localBolusTimestamp = it.timestamp.toLocalDateTime(TimeZone.currentSystemDefault())
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)
)
}
@ -1465,7 +1466,7 @@ class ComboV2Plugin @Inject constructor (
temporaryBasal?.let {
lines += rh.gs(
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