Profile sync, removed NSProfile
This commit is contained in:
parent
88f5eec306
commit
0f2f5cd1fa
33 changed files with 516 additions and 1521 deletions
|
@ -1,7 +1,5 @@
|
|||
package info.nightscout.androidaps.data.defaultProfile
|
||||
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.data.ProfileImplOld
|
||||
import info.nightscout.androidaps.data.PureProfile
|
||||
import info.nightscout.androidaps.extensions.pureProfileFromJson
|
||||
import info.nightscout.androidaps.interfaces.GlucoseUnit
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package info.nightscout.androidaps.data.defaultProfile
|
||||
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.data.ProfileImplOld
|
||||
import info.nightscout.androidaps.data.PureProfile
|
||||
import info.nightscout.androidaps.extensions.pureProfileFromJson
|
||||
import info.nightscout.androidaps.interfaces.GlucoseUnit
|
||||
|
|
|
@ -29,7 +29,6 @@ import info.nightscout.androidaps.plugins.general.tidepool.TidepoolFragment
|
|||
import info.nightscout.androidaps.plugins.general.wear.WearFragment
|
||||
import info.nightscout.androidaps.plugins.insulin.InsulinFragment
|
||||
import info.nightscout.androidaps.plugins.profile.local.LocalProfileFragment
|
||||
import info.nightscout.androidaps.plugins.profile.ns.NSProfileFragment
|
||||
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpFragment
|
||||
import info.nightscout.androidaps.plugins.source.BGSourceFragment
|
||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsFragment
|
||||
|
@ -46,8 +45,7 @@ abstract class FragmentsModule {
|
|||
@ContributesAndroidInjector abstract fun contributesAutomationFragment(): AutomationFragment
|
||||
@ContributesAndroidInjector abstract fun contributesBGSourceFragment(): BGSourceFragment
|
||||
|
||||
@ContributesAndroidInjector
|
||||
abstract fun contributesConfigBuilderFragment(): ConfigBuilderFragment
|
||||
@ContributesAndroidInjector abstract fun contributesConfigBuilderFragment(): ConfigBuilderFragment
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesFoodFragment(): FoodFragment
|
||||
@ContributesAndroidInjector abstract fun contributesInsulinFragment(): InsulinFragment
|
||||
|
@ -58,10 +56,8 @@ abstract class FragmentsModule {
|
|||
@ContributesAndroidInjector abstract fun contributesOverviewFragment(): OverviewFragment
|
||||
@ContributesAndroidInjector abstract fun contributesLoopFragment(): LoopFragment
|
||||
@ContributesAndroidInjector abstract fun contributesMaintenanceFragment(): MaintenanceFragment
|
||||
@ContributesAndroidInjector abstract fun contributesNSProfileFragment(): NSProfileFragment
|
||||
@ContributesAndroidInjector abstract fun contributesNSClientFragment(): NSClientFragment
|
||||
@ContributesAndroidInjector
|
||||
abstract fun contributesSmsCommunicatorFragment(): SmsCommunicatorFragment
|
||||
@ContributesAndroidInjector abstract fun contributesSmsCommunicatorFragment(): SmsCommunicatorFragment
|
||||
@ContributesAndroidInjector abstract fun contributesWearFragment(): WearFragment
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesTidepoolFragment(): TidepoolFragment
|
||||
|
@ -85,8 +81,7 @@ abstract class FragmentsModule {
|
|||
@ContributesAndroidInjector abstract fun contributesEditEventDialog(): EditEventDialog
|
||||
@ContributesAndroidInjector abstract fun contributesEditTriggerDialog(): EditTriggerDialog
|
||||
|
||||
@ContributesAndroidInjector
|
||||
abstract fun contributesEditQuickWizardDialog(): EditQuickWizardDialog
|
||||
@ContributesAndroidInjector abstract fun contributesEditQuickWizardDialog(): EditQuickWizardDialog
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesExtendedBolusDialog(): ExtendedBolusDialog
|
||||
@ContributesAndroidInjector abstract fun contributesFillDialog(): FillDialog
|
||||
|
@ -102,8 +97,7 @@ abstract class FragmentsModule {
|
|||
@ContributesAndroidInjector abstract fun contributesWizardDialog(): WizardDialog
|
||||
@ContributesAndroidInjector abstract fun contributesWizardInfoDialog(): WizardInfoDialog
|
||||
|
||||
@ContributesAndroidInjector
|
||||
abstract fun contributesExchangeAuthTokenDialot(): OpenHumansLoginActivity.ExchangeAuthTokenDialog
|
||||
@ContributesAndroidInjector abstract fun contributesExchangeAuthTokenDialog(): OpenHumansLoginActivity.ExchangeAuthTokenDialog
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesPasswordCheck(): PasswordCheck
|
||||
}
|
|
@ -37,7 +37,6 @@ import info.nightscout.androidaps.plugins.insulin.InsulinOrefRapidActingPlugin
|
|||
import info.nightscout.androidaps.plugins.insulin.InsulinOrefUltraRapidActingPlugin
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
||||
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin
|
||||
import info.nightscout.androidaps.plugins.profile.ns.NSProfilePlugin
|
||||
import info.nightscout.androidaps.plugins.pump.combo.ComboPlugin
|
||||
import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin
|
||||
import info.nightscout.androidaps.plugins.pump.mdi.MDIPlugin
|
||||
|
@ -192,12 +191,6 @@ abstract class PluginsModule {
|
|||
@IntKey(220)
|
||||
abstract fun bindOpenAPSSMBPlugin(plugin: OpenAPSSMBPlugin): PluginBase
|
||||
|
||||
@Binds
|
||||
@AllConfigs
|
||||
@IntoMap
|
||||
@IntKey(230)
|
||||
abstract fun bindNSProfilePlugin(plugin: NSProfilePlugin): PluginBase
|
||||
|
||||
@Binds
|
||||
@NotNSClient
|
||||
@IntoMap
|
||||
|
|
|
@ -9,7 +9,7 @@ import info.nightscout.androidaps.plugins.general.nsclient.NSClientMbgWorker
|
|||
import info.nightscout.androidaps.plugins.general.nsclient.NSClientRemoveWorker
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.NSClientUpdateRemoveAckWorker
|
||||
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin
|
||||
import info.nightscout.androidaps.plugins.profile.ns.NSProfilePlugin
|
||||
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin
|
||||
import info.nightscout.androidaps.plugins.source.*
|
||||
|
||||
@Module
|
||||
|
@ -24,7 +24,7 @@ abstract class WorkersModule {
|
|||
@ContributesAndroidInjector abstract fun contributesTomatoWorker(): TomatoPlugin.TomatoWorker
|
||||
@ContributesAndroidInjector abstract fun contributesEversenseWorker(): EversensePlugin.EversenseWorker
|
||||
@ContributesAndroidInjector abstract fun contributesNSClientSourceWorker(): NSClientSourcePlugin.NSClientSourceWorker
|
||||
@ContributesAndroidInjector abstract fun contributesNSProfileWorker(): NSProfilePlugin.NSProfileWorker
|
||||
@ContributesAndroidInjector abstract fun contributesNSProfileWorker(): LocalProfilePlugin.NSProfileWorker
|
||||
@ContributesAndroidInjector abstract fun contributesSmsCommunicatorWorker(): SmsCommunicatorPlugin.SmsCommunicatorWorker
|
||||
@ContributesAndroidInjector abstract fun contributesNSClientWorker(): NSClientAddUpdateWorker
|
||||
@ContributesAndroidInjector abstract fun contributesNSClientAddAckWorker(): NSClientAddAckWorker
|
||||
|
|
|
@ -2,14 +2,13 @@ package info.nightscout.androidaps.plugins.general.nsclient
|
|||
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.database.entities.DeviceStatus
|
||||
import info.nightscout.androidaps.database.entities.*
|
||||
import info.nightscout.androidaps.extensions.toJson
|
||||
import info.nightscout.androidaps.interfaces.ActivePlugin
|
||||
import info.nightscout.androidaps.interfaces.DataSyncSelector
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.extensions.toJson
|
||||
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
|
@ -26,6 +25,23 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
private val localProfilePlugin: LocalProfilePlugin
|
||||
) : DataSyncSelector {
|
||||
|
||||
override fun doUpload() {
|
||||
if (sp.getBoolean(R.string.key_ns_upload, true)) {
|
||||
processChangedBolusesCompat()
|
||||
processChangedCarbsCompat()
|
||||
processChangedBolusCalculatorResultsCompat()
|
||||
processChangedTemporaryBasalsCompat()
|
||||
processChangedExtendedBolusesCompat()
|
||||
processChangedProfileSwitchesCompat()
|
||||
processChangedGlucoseValuesCompat()
|
||||
processChangedTempTargetsCompat()
|
||||
processChangedFoodsCompat()
|
||||
processChangedTherapyEventsCompat()
|
||||
processChangedDeviceStatusesCompat()
|
||||
processChangedProfileStore()
|
||||
}
|
||||
}
|
||||
|
||||
override fun resetToNextFullSync() {
|
||||
sp.remove(R.string.key_ns_temporary_target_last_synced_id)
|
||||
sp.remove(R.string.key_ns_glucose_value_last_synced_id)
|
||||
|
@ -459,8 +475,7 @@ class DataSyncSelectorImplementation @Inject constructor(
|
|||
if (lastChange == 0L) return
|
||||
localProfilePlugin.createProfileStore()
|
||||
val profileJson = localProfilePlugin.profile?.data ?: return
|
||||
if (sp.getBoolean(R.string.key_ns_uploadlocalprofile, false))
|
||||
if (lastChange > lastSync)
|
||||
nsClientPlugin.nsClientService?.dbAdd("profile", profileJson, DataSyncSelector.PairProfileStore(profileJson, dateUtil.now()))
|
||||
if (lastChange > lastSync)
|
||||
nsClientPlugin.nsClientService?.dbAdd("profile", profileJson, DataSyncSelector.PairProfileStore(profileJson, dateUtil.now()))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,9 +49,6 @@ class NSClientAddUpdateWorker(
|
|||
@Inject lateinit var uel: UserEntryLogger
|
||||
|
||||
override fun doWork(): Result {
|
||||
val acceptNSData = !sp.getBoolean(R.string.key_ns_upload_only, true) && buildHelper.isEngineeringMode() || config.NSCLIENT
|
||||
if (!acceptNSData) return Result.success()
|
||||
|
||||
val treatments = dataWorker.pickupJSONArray(inputData.getLong(DataWorker.STORE_KEY, -1))
|
||||
?: return Result.failure(workDataOf("Error" to "missing input data"))
|
||||
|
||||
|
@ -75,62 +72,66 @@ class NSClientAddUpdateWorker(
|
|||
if (mills > latestDateInReceivedData) latestDateInReceivedData = mills
|
||||
|
||||
if (insulin > 0) {
|
||||
bolusFromJson(json)?.let { bolus ->
|
||||
repository.runTransactionForResult(SyncNsBolusTransaction(bolus, invalidateByNsOnly = false))
|
||||
.doOnError {
|
||||
aapsLogger.error(LTag.DATABASE, "Error while saving bolus", it)
|
||||
ret = Result.failure(workDataOf("Error" to it.toString()))
|
||||
}
|
||||
.blockingGet()
|
||||
.also { result ->
|
||||
result.inserted.forEach {
|
||||
uel.log(Action.BOLUS, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.Insulin(it.amount)
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted bolus $it")
|
||||
if (sp.getBoolean(R.string.key_ns_receive_insulin, false) && buildHelper.isEngineeringMode() || config.NSCLIENT) {
|
||||
bolusFromJson(json)?.let { bolus ->
|
||||
repository.runTransactionForResult(SyncNsBolusTransaction(bolus, invalidateByNsOnly = false))
|
||||
.doOnError {
|
||||
aapsLogger.error(LTag.DATABASE, "Error while saving bolus", it)
|
||||
ret = Result.failure(workDataOf("Error" to it.toString()))
|
||||
}
|
||||
result.invalidated.forEach {
|
||||
uel.log(Action.BOLUS_REMOVED, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.Insulin(it.amount)
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Invalidated bolus $it")
|
||||
.blockingGet()
|
||||
.also { result ->
|
||||
result.inserted.forEach {
|
||||
uel.log(Action.BOLUS, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.Insulin(it.amount)
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted bolus $it")
|
||||
}
|
||||
result.invalidated.forEach {
|
||||
uel.log(Action.BOLUS_REMOVED, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.Insulin(it.amount)
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Invalidated bolus $it")
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId bolus $it")
|
||||
}
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId bolus $it")
|
||||
}
|
||||
}
|
||||
} ?: aapsLogger.error("Error parsing bolus json $json")
|
||||
} ?: aapsLogger.error("Error parsing bolus json $json")
|
||||
}
|
||||
}
|
||||
if (carbs > 0) {
|
||||
carbsFromJson(json)?.let { carb ->
|
||||
repository.runTransactionForResult(SyncNsCarbsTransaction(carb, invalidateByNsOnly = false))
|
||||
.doOnError {
|
||||
aapsLogger.error(LTag.DATABASE, "Error while saving carbs", it)
|
||||
ret = Result.failure(workDataOf("Error" to it.toString()))
|
||||
}
|
||||
.blockingGet()
|
||||
.also { result ->
|
||||
result.inserted.forEach {
|
||||
uel.log(Action.CARBS, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.Gram(it.amount.toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted carbs $it")
|
||||
if (sp.getBoolean(R.string.key_ns_receive_carbs, false) && buildHelper.isEngineeringMode() || config.NSCLIENT) {
|
||||
carbsFromJson(json)?.let { carb ->
|
||||
repository.runTransactionForResult(SyncNsCarbsTransaction(carb, invalidateByNsOnly = false))
|
||||
.doOnError {
|
||||
aapsLogger.error(LTag.DATABASE, "Error while saving carbs", it)
|
||||
ret = Result.failure(workDataOf("Error" to it.toString()))
|
||||
}
|
||||
result.invalidated.forEach {
|
||||
uel.log(Action.CARBS_REMOVED, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.Gram(it.amount.toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Invalidated carbs $it")
|
||||
.blockingGet()
|
||||
.also { result ->
|
||||
result.inserted.forEach {
|
||||
uel.log(Action.CARBS, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.Gram(it.amount.toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted carbs $it")
|
||||
}
|
||||
result.invalidated.forEach {
|
||||
uel.log(Action.CARBS_REMOVED, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.Gram(it.amount.toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Invalidated carbs $it")
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId carbs $it")
|
||||
}
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId carbs $it")
|
||||
}
|
||||
}
|
||||
} ?: aapsLogger.error("Error parsing bolus json $json")
|
||||
} ?: aapsLogger.error("Error parsing bolus json $json")
|
||||
}
|
||||
}
|
||||
// Convert back emulated TBR -> EB
|
||||
if (eventType == TherapyEvent.Type.TEMPORARY_BASAL.text && json.has("extendedEmulated")) {
|
||||
|
@ -142,46 +143,48 @@ class NSClientAddUpdateWorker(
|
|||
when {
|
||||
insulin > 0 || carbs > 0 -> Any()
|
||||
eventType == TherapyEvent.Type.TEMPORARY_TARGET.text ->
|
||||
temporaryTargetFromJson(json)?.let { temporaryTarget ->
|
||||
repository.runTransactionForResult(SyncNsTemporaryTargetTransaction(temporaryTarget, invalidateByNsOnly = false))
|
||||
.doOnError {
|
||||
aapsLogger.error(LTag.DATABASE, "Error while saving temporary target", it)
|
||||
ret = Result.failure(workDataOf("Error" to it.toString()))
|
||||
}
|
||||
.blockingGet()
|
||||
.also { result ->
|
||||
result.inserted.forEach { tt ->
|
||||
uel.log(Action.TT, Sources.NSClient,
|
||||
ValueWithUnit.TherapyEventTTReason(tt.reason),
|
||||
ValueWithUnit.fromGlucoseUnit(tt.lowTarget, Constants.MGDL),
|
||||
ValueWithUnit.fromGlucoseUnit(tt.highTarget, Constants.MGDL).takeIf { tt.lowTarget != tt.highTarget },
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(tt.duration).toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted TemporaryTarget $tt")
|
||||
if (sp.getBoolean(R.string.key_ns_receive_temp_target, false) && buildHelper.isEngineeringMode() || config.NSCLIENT) {
|
||||
temporaryTargetFromJson(json)?.let { temporaryTarget ->
|
||||
repository.runTransactionForResult(SyncNsTemporaryTargetTransaction(temporaryTarget, invalidateByNsOnly = false))
|
||||
.doOnError {
|
||||
aapsLogger.error(LTag.DATABASE, "Error while saving temporary target", it)
|
||||
ret = Result.failure(workDataOf("Error" to it.toString()))
|
||||
}
|
||||
result.invalidated.forEach { tt ->
|
||||
uel.log(Action.TT_REMOVED, Sources.NSClient,
|
||||
ValueWithUnit.TherapyEventTTReason(tt.reason),
|
||||
ValueWithUnit.Mgdl(tt.lowTarget),
|
||||
ValueWithUnit.Mgdl(tt.highTarget).takeIf { tt.lowTarget != tt.highTarget },
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(tt.duration).toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Invalidated TemporaryTarget $tt")
|
||||
.blockingGet()
|
||||
.also { result ->
|
||||
result.inserted.forEach { tt ->
|
||||
uel.log(Action.TT, Sources.NSClient,
|
||||
ValueWithUnit.TherapyEventTTReason(tt.reason),
|
||||
ValueWithUnit.fromGlucoseUnit(tt.lowTarget, Constants.MGDL),
|
||||
ValueWithUnit.fromGlucoseUnit(tt.highTarget, Constants.MGDL).takeIf { tt.lowTarget != tt.highTarget },
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(tt.duration).toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted TemporaryTarget $tt")
|
||||
}
|
||||
result.invalidated.forEach { tt ->
|
||||
uel.log(Action.TT_REMOVED, Sources.NSClient,
|
||||
ValueWithUnit.TherapyEventTTReason(tt.reason),
|
||||
ValueWithUnit.Mgdl(tt.lowTarget),
|
||||
ValueWithUnit.Mgdl(tt.highTarget).takeIf { tt.lowTarget != tt.highTarget },
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(tt.duration).toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Invalidated TemporaryTarget $tt")
|
||||
}
|
||||
result.ended.forEach { tt ->
|
||||
uel.log(Action.CANCEL_TT, Sources.NSClient,
|
||||
ValueWithUnit.TherapyEventTTReason(tt.reason),
|
||||
ValueWithUnit.Mgdl(tt.lowTarget),
|
||||
ValueWithUnit.Mgdl(tt.highTarget).takeIf { tt.lowTarget != tt.highTarget },
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(tt.duration).toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated TemporaryTarget $tt")
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId TemporaryTarget $it")
|
||||
}
|
||||
}
|
||||
result.ended.forEach { tt ->
|
||||
uel.log(Action.CANCEL_TT, Sources.NSClient,
|
||||
ValueWithUnit.TherapyEventTTReason(tt.reason),
|
||||
ValueWithUnit.Mgdl(tt.lowTarget),
|
||||
ValueWithUnit.Mgdl(tt.highTarget).takeIf { tt.lowTarget != tt.highTarget },
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(tt.duration).toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated TemporaryTarget $tt")
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId TemporaryTarget $it")
|
||||
}
|
||||
}
|
||||
} ?: aapsLogger.error("Error parsing TT json $json")
|
||||
} ?: aapsLogger.error("Error parsing TT json $json")
|
||||
}
|
||||
eventType == TherapyEvent.Type.CANNULA_CHANGE.text ||
|
||||
eventType == TherapyEvent.Type.INSULIN_CHANGE.text ||
|
||||
eventType == TherapyEvent.Type.SENSOR_CHANGE.text ||
|
||||
|
@ -192,158 +195,167 @@ class NSClientAddUpdateWorker(
|
|||
eventType == TherapyEvent.Type.EXERCISE.text ||
|
||||
eventType == TherapyEvent.Type.APS_OFFLINE.text ||
|
||||
eventType == TherapyEvent.Type.PUMP_BATTERY_CHANGE.text ->
|
||||
therapyEventFromJson(json)?.let { therapyEvent ->
|
||||
repository.runTransactionForResult(SyncNsTherapyEventTransaction(therapyEvent, invalidateByNsOnly = false))
|
||||
.doOnError {
|
||||
aapsLogger.error(LTag.DATABASE, "Error while saving therapy event", it)
|
||||
ret = Result.failure(workDataOf("Error" to it.toString()))
|
||||
}
|
||||
.blockingGet()
|
||||
.also { result ->
|
||||
val action = when (eventType) {
|
||||
TherapyEvent.Type.CANNULA_CHANGE.text -> Action.SITE_CHANGE
|
||||
TherapyEvent.Type.INSULIN_CHANGE.text -> Action.RESERVOIR_CHANGE
|
||||
else -> Action.CAREPORTAL
|
||||
if (sp.getBoolean(R.string.key_ns_receive_therapy_events, false) || config.NSCLIENT) {
|
||||
therapyEventFromJson(json)?.let { therapyEvent ->
|
||||
repository.runTransactionForResult(SyncNsTherapyEventTransaction(therapyEvent, invalidateByNsOnly = false))
|
||||
.doOnError {
|
||||
aapsLogger.error(LTag.DATABASE, "Error while saving therapy event", it)
|
||||
ret = Result.failure(workDataOf("Error" to it.toString()))
|
||||
}
|
||||
result.inserted.forEach {
|
||||
uel.log(action, Sources.NSClient,
|
||||
it.note ?: "",
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.TherapyEventType(it.type)
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted TherapyEvent $it")
|
||||
.blockingGet()
|
||||
.also { result ->
|
||||
val action = when (eventType) {
|
||||
TherapyEvent.Type.CANNULA_CHANGE.text -> Action.SITE_CHANGE
|
||||
TherapyEvent.Type.INSULIN_CHANGE.text -> Action.RESERVOIR_CHANGE
|
||||
else -> Action.CAREPORTAL
|
||||
}
|
||||
result.inserted.forEach {
|
||||
uel.log(action, Sources.NSClient,
|
||||
it.note ?: "",
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.TherapyEventType(it.type)
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted TherapyEvent $it")
|
||||
}
|
||||
result.invalidated.forEach {
|
||||
uel.log(Action.CAREPORTAL_REMOVED, Sources.NSClient,
|
||||
it.note ?: "",
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.TherapyEventType(it.type)
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Invalidated TherapyEvent $it")
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId TherapyEvent $it")
|
||||
}
|
||||
}
|
||||
result.invalidated.forEach {
|
||||
uel.log(Action.CAREPORTAL_REMOVED, Sources.NSClient,
|
||||
it.note ?: "",
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.TherapyEventType(it.type)
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Invalidated TherapyEvent $it")
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId TherapyEvent $it")
|
||||
}
|
||||
}
|
||||
} ?: aapsLogger.error("Error parsing TherapyEvent json $json")
|
||||
} ?: aapsLogger.error("Error parsing TherapyEvent json $json")
|
||||
}
|
||||
eventType == TherapyEvent.Type.COMBO_BOLUS.text ->
|
||||
extendedBolusFromJson(json)?.let { extendedBolus ->
|
||||
repository.runTransactionForResult(SyncNsExtendedBolusTransaction(extendedBolus, invalidateByNsOnly = false))
|
||||
.doOnError {
|
||||
aapsLogger.error(LTag.DATABASE, "Error while saving extended bolus", it)
|
||||
ret = Result.failure(workDataOf("Error" to it.toString()))
|
||||
}
|
||||
.blockingGet()
|
||||
.also { result ->
|
||||
result.inserted.forEach {
|
||||
uel.log(Action.EXTENDED_BOLUS, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.Insulin(it.amount),
|
||||
ValueWithUnit.UnitPerHour(it.rate),
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(it.duration).toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted ExtendedBolus $it")
|
||||
if (config.NSCLIENT) {
|
||||
extendedBolusFromJson(json)?.let { extendedBolus ->
|
||||
repository.runTransactionForResult(SyncNsExtendedBolusTransaction(extendedBolus, invalidateByNsOnly = false))
|
||||
.doOnError {
|
||||
aapsLogger.error(LTag.DATABASE, "Error while saving extended bolus", it)
|
||||
ret = Result.failure(workDataOf("Error" to it.toString()))
|
||||
}
|
||||
result.invalidated.forEach {
|
||||
uel.log(Action.EXTENDED_BOLUS_REMOVED, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.Insulin(it.amount),
|
||||
ValueWithUnit.UnitPerHour(it.rate),
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(it.duration).toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Invalidated ExtendedBolus $it")
|
||||
.blockingGet()
|
||||
.also { result ->
|
||||
result.inserted.forEach {
|
||||
uel.log(Action.EXTENDED_BOLUS, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.Insulin(it.amount),
|
||||
ValueWithUnit.UnitPerHour(it.rate),
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(it.duration).toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted ExtendedBolus $it")
|
||||
}
|
||||
result.invalidated.forEach {
|
||||
uel.log(Action.EXTENDED_BOLUS_REMOVED, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.Insulin(it.amount),
|
||||
ValueWithUnit.UnitPerHour(it.rate),
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(it.duration).toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Invalidated ExtendedBolus $it")
|
||||
}
|
||||
result.ended.forEach {
|
||||
uel.log(Action.CANCEL_EXTENDED_BOLUS, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.Insulin(it.amount),
|
||||
ValueWithUnit.UnitPerHour(it.rate),
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(it.duration).toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated ExtendedBolus $it")
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId ExtendedBolus $it")
|
||||
}
|
||||
}
|
||||
result.ended.forEach {
|
||||
uel.log(Action.CANCEL_EXTENDED_BOLUS, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.Insulin(it.amount),
|
||||
ValueWithUnit.UnitPerHour(it.rate),
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(it.duration).toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated ExtendedBolus $it")
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId ExtendedBolus $it")
|
||||
}
|
||||
}
|
||||
} ?: aapsLogger.error("Error parsing ExtendedBolus json $json")
|
||||
} ?: aapsLogger.error("Error parsing ExtendedBolus json $json")
|
||||
}
|
||||
eventType == TherapyEvent.Type.TEMPORARY_BASAL.text ->
|
||||
temporaryBasalFromJson(json)?.let { temporaryBasal ->
|
||||
repository.runTransactionForResult(SyncNsTemporaryBasalTransaction(temporaryBasal, invalidateByNsOnly = false))
|
||||
.doOnError {
|
||||
aapsLogger.error(LTag.DATABASE, "Error while saving temporary basal", it)
|
||||
ret = Result.failure(workDataOf("Error" to it.toString()))
|
||||
}
|
||||
.blockingGet()
|
||||
.also { result ->
|
||||
result.inserted.forEach {
|
||||
uel.log(Action.TEMP_BASAL, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.UnitPerHour(it.rate),
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(it.duration).toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted TemporaryBasal $it")
|
||||
if (config.NSCLIENT) {
|
||||
temporaryBasalFromJson(json)?.let { temporaryBasal ->
|
||||
repository.runTransactionForResult(SyncNsTemporaryBasalTransaction(temporaryBasal, invalidateByNsOnly = false))
|
||||
.doOnError {
|
||||
aapsLogger.error(LTag.DATABASE, "Error while saving temporary basal", it)
|
||||
ret = Result.failure(workDataOf("Error" to it.toString()))
|
||||
}
|
||||
result.invalidated.forEach {
|
||||
uel.log(Action.TEMP_BASAL_REMOVED, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.UnitPerHour(it.rate),
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(it.duration).toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Invalidated TemporaryBasal $it")
|
||||
.blockingGet()
|
||||
.also { result ->
|
||||
result.inserted.forEach {
|
||||
uel.log(Action.TEMP_BASAL, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.UnitPerHour(it.rate),
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(it.duration).toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted TemporaryBasal $it")
|
||||
}
|
||||
result.invalidated.forEach {
|
||||
uel.log(Action.TEMP_BASAL_REMOVED, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.UnitPerHour(it.rate),
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(it.duration).toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Invalidated TemporaryBasal $it")
|
||||
}
|
||||
result.ended.forEach {
|
||||
uel.log(Action.CANCEL_TEMP_BASAL, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.UnitPerHour(it.rate),
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(it.duration).toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Ended TemporaryBasal $it")
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId TemporaryBasal $it")
|
||||
}
|
||||
}
|
||||
result.ended.forEach {
|
||||
uel.log(Action.CANCEL_TEMP_BASAL, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp),
|
||||
ValueWithUnit.UnitPerHour(it.rate),
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(it.duration).toInt())
|
||||
)
|
||||
aapsLogger.debug(LTag.DATABASE, "Ended TemporaryBasal $it")
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId TemporaryBasal $it")
|
||||
}
|
||||
}
|
||||
} ?: aapsLogger.error("Error parsing TemporaryBasal json $json")
|
||||
} ?: aapsLogger.error("Error parsing TemporaryBasal json $json")
|
||||
}
|
||||
eventType == TherapyEvent.Type.PROFILE_SWITCH.text ->
|
||||
profileSwitchFromJson(json, dateUtil, activePlugin)?.let { profileSwitch ->
|
||||
repository.runTransactionForResult(SyncNsProfileSwitchTransaction(profileSwitch, invalidateByNsOnly = false))
|
||||
.doOnError {
|
||||
aapsLogger.error(LTag.DATABASE, "Error while saving ProfileSwitch", it)
|
||||
ret = Result.failure(workDataOf("Error" to it.toString()))
|
||||
}
|
||||
.blockingGet()
|
||||
.also { result ->
|
||||
result.inserted.forEach {
|
||||
uel.log(Action.PROFILE_SWITCH, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp))
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted ProfileSwitch $it")
|
||||
if (sp.getBoolean(R.string.key_ns_receive_profile_switch, false) && buildHelper.isEngineeringMode() || config.NSCLIENT) {
|
||||
profileSwitchFromJson(json, dateUtil, activePlugin)?.let { profileSwitch ->
|
||||
repository.runTransactionForResult(SyncNsProfileSwitchTransaction(profileSwitch, invalidateByNsOnly = false))
|
||||
.doOnError {
|
||||
aapsLogger.error(LTag.DATABASE, "Error while saving ProfileSwitch", it)
|
||||
ret = Result.failure(workDataOf("Error" to it.toString()))
|
||||
}
|
||||
result.invalidated.forEach {
|
||||
uel.log(Action.PROFILE_SWITCH_REMOVED, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp))
|
||||
aapsLogger.debug(LTag.DATABASE, "Invalidated ProfileSwitch $it")
|
||||
.blockingGet()
|
||||
.also { result ->
|
||||
result.inserted.forEach {
|
||||
uel.log(Action.PROFILE_SWITCH, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp))
|
||||
aapsLogger.debug(LTag.DATABASE, "Inserted ProfileSwitch $it")
|
||||
}
|
||||
result.invalidated.forEach {
|
||||
uel.log(Action.PROFILE_SWITCH_REMOVED, Sources.NSClient,
|
||||
ValueWithUnit.Timestamp(it.timestamp))
|
||||
aapsLogger.debug(LTag.DATABASE, "Invalidated ProfileSwitch $it")
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId ProfileSwitch $it")
|
||||
}
|
||||
}
|
||||
result.updatedNsId.forEach {
|
||||
aapsLogger.debug(LTag.DATABASE, "Updated nsId ProfileSwitch $it")
|
||||
}
|
||||
}
|
||||
} ?: aapsLogger.error("Error parsing ProfileSwitch json $json")
|
||||
} ?: aapsLogger.error("Error parsing ProfileSwitch json $json")
|
||||
}
|
||||
}
|
||||
if (eventType == TherapyEvent.Type.ANNOUNCEMENT.text) {
|
||||
val date = safeGetLong(json, "mills")
|
||||
val now = System.currentTimeMillis()
|
||||
val enteredBy = JsonHelper.safeGetString(json, "enteredBy", "")
|
||||
val notes = JsonHelper.safeGetString(json, "notes", "")
|
||||
if (date > now - 15 * 60 * 1000L && notes.isNotEmpty()
|
||||
&& enteredBy != sp.getString("careportal_enteredby", "AndroidAPS")) {
|
||||
val defaultVal = config.NSCLIENT
|
||||
if (sp.getBoolean(R.string.key_ns_announcements, defaultVal)) {
|
||||
val announcement = Notification(Notification.NS_ANNOUNCEMENT, notes, Notification.ANNOUNCEMENT, 60)
|
||||
rxBus.send(EventNewNotification(announcement))
|
||||
if (sp.getBoolean(R.string.key_ns_receive_therapy_events, false) || config.NSCLIENT)
|
||||
if (eventType == TherapyEvent.Type.ANNOUNCEMENT.text) {
|
||||
val date = safeGetLong(json, "mills")
|
||||
val now = System.currentTimeMillis()
|
||||
val enteredBy = JsonHelper.safeGetString(json, "enteredBy", "")
|
||||
val notes = JsonHelper.safeGetString(json, "notes", "")
|
||||
if (date > now - 15 * 60 * 1000L && notes.isNotEmpty()
|
||||
&& enteredBy != sp.getString("careportal_enteredby", "AndroidAPS")) {
|
||||
val defaultVal = config.NSCLIENT
|
||||
if (sp.getBoolean(R.string.key_ns_announcements, defaultVal)) {
|
||||
val announcement = Notification(Notification.NS_ANNOUNCEMENT, notes, Notification.ANNOUNCEMENT, 60)
|
||||
rxBus.send(EventNewNotification(announcement))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
nsClientPlugin.updateLatestDateReceivedIfNewer(latestDateInReceivedData)
|
||||
return ret
|
||||
|
|
|
@ -8,13 +8,13 @@ import dagger.android.HasAndroidInjector
|
|||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.database.transactions.SyncNsTherapyEventTransaction
|
||||
import info.nightscout.androidaps.extensions.therapyEventFromNsMbg
|
||||
import info.nightscout.androidaps.interfaces.Config
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.data.NSMbg
|
||||
import info.nightscout.androidaps.receivers.DataWorker
|
||||
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
|
||||
import info.nightscout.androidaps.extensions.therapyEventFromNsMbg
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
import javax.inject.Inject
|
||||
|
||||
|
@ -33,7 +33,7 @@ class NSClientMbgWorker(
|
|||
override fun doWork(): Result {
|
||||
var ret = Result.success()
|
||||
|
||||
val acceptNSData = !sp.getBoolean(R.string.key_ns_upload_only, true) && buildHelper.isEngineeringMode() || config.NSCLIENT
|
||||
val acceptNSData = sp.getBoolean(R.string.key_ns_receive_therapy_events, false) || config.NSCLIENT
|
||||
if (!acceptNSData) return ret
|
||||
|
||||
val mbgArray = dataWorker.pickupJSONArray(inputData.getLong(DataWorker.STORE_KEY, -1))
|
||||
|
|
|
@ -8,6 +8,7 @@ import android.os.Handler
|
|||
import android.os.HandlerThread
|
||||
import android.os.IBinder
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import androidx.preference.PreferenceScreen
|
||||
import androidx.preference.SwitchPreference
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.Constants
|
||||
|
@ -147,25 +148,17 @@ class NSClientPlugin @Inject constructor(
|
|||
override fun preprocessPreferences(preferenceFragment: PreferenceFragmentCompat) {
|
||||
super.preprocessPreferences(preferenceFragment)
|
||||
if (config.NSCLIENT) {
|
||||
val key_ns_uploadlocalprofile = preferenceFragment.findPreference<SwitchPreference>(resourceHelper.gs(R.string.key_ns_uploadlocalprofile))
|
||||
if (key_ns_uploadlocalprofile != null) key_ns_uploadlocalprofile.isVisible = false
|
||||
val key_ns_autobackfill = preferenceFragment.findPreference<SwitchPreference>(resourceHelper.gs(R.string.key_ns_autobackfill))
|
||||
if (key_ns_autobackfill != null) key_ns_autobackfill.isVisible = false
|
||||
val key_ns_create_announcements_from_errors = preferenceFragment.findPreference<SwitchPreference>(resourceHelper.gs(R.string.key_ns_create_announcements_from_errors))
|
||||
if (key_ns_create_announcements_from_errors != null) key_ns_create_announcements_from_errors.isVisible = false
|
||||
val key_ns_create_announcements_from_carbs_req = preferenceFragment.findPreference<SwitchPreference>(resourceHelper.gs(R.string.key_ns_create_announcements_from_carbs_req))
|
||||
if (key_ns_create_announcements_from_carbs_req != null) key_ns_create_announcements_from_carbs_req.isVisible = false
|
||||
val key_ns_upload_only = preferenceFragment.findPreference<SwitchPreference>(resourceHelper.gs(R.string.key_ns_upload_only))
|
||||
if (key_ns_upload_only != null) {
|
||||
key_ns_upload_only.isVisible = false
|
||||
key_ns_upload_only.isEnabled = false
|
||||
}
|
||||
val key_ns_sync_use_absolute = preferenceFragment.findPreference<SwitchPreference>(resourceHelper.gs(R.string.key_ns_sync_use_absolute))
|
||||
if (key_ns_sync_use_absolute != null) key_ns_sync_use_absolute.isVisible = false
|
||||
preferenceFragment.findPreference<PreferenceScreen>(resourceHelper.gs(R.string.ns_sync_options))?.isVisible = false
|
||||
|
||||
preferenceFragment.findPreference<SwitchPreference>(resourceHelper.gs(R.string.key_ns_create_announcements_from_errors))?.isVisible = false
|
||||
preferenceFragment.findPreference<SwitchPreference>(resourceHelper.gs(R.string.key_ns_create_announcements_from_carbs_req))?.isVisible = false
|
||||
preferenceFragment.findPreference<SwitchPreference>(resourceHelper.gs(R.string.key_ns_sync_use_absolute))?.isVisible = false
|
||||
} else {
|
||||
// APS or pumpControl mode
|
||||
val key_ns_upload_only = preferenceFragment.findPreference<SwitchPreference>(resourceHelper.gs(R.string.key_ns_upload_only))
|
||||
if (key_ns_upload_only != null) key_ns_upload_only.isVisible = buildHelper.isEngineeringMode()
|
||||
preferenceFragment.findPreference<SwitchPreference>(resourceHelper.gs(R.string.key_ns_receive_profile_switch))?.isVisible = buildHelper.isEngineeringMode()
|
||||
preferenceFragment.findPreference<SwitchPreference>(resourceHelper.gs(R.string.key_ns_receive_insulin))?.isVisible = buildHelper.isEngineeringMode()
|
||||
preferenceFragment.findPreference<SwitchPreference>(resourceHelper.gs(R.string.key_ns_receive_carbs))?.isVisible = buildHelper.isEngineeringMode()
|
||||
preferenceFragment.findPreference<SwitchPreference>(resourceHelper.gs(R.string.key_ns_receive_temp_target))?.isVisible = buildHelper.isEngineeringMode()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -232,7 +225,7 @@ class NSClientPlugin @Inject constructor(
|
|||
|
||||
fun handleClearAlarm(originalAlarm: NSAlarm, silenceTimeInMilliseconds: Long) {
|
||||
if (!isEnabled(PluginType.GENERAL)) return
|
||||
if (sp.getBoolean(R.string.key_ns_noupload, false)) {
|
||||
if (!sp.getBoolean(R.string.key_ns_upload, false)) {
|
||||
aapsLogger.debug(LTag.NSCLIENT, "Upload disabled. Message dropped")
|
||||
return
|
||||
}
|
||||
|
|
|
@ -42,8 +42,9 @@ class NSClientRemoveWorker(
|
|||
@Inject lateinit var uel: UserEntryLogger
|
||||
|
||||
override fun doWork(): Result {
|
||||
val acceptNSData = !sp.getBoolean(R.string.key_ns_upload_only, true) && buildHelper.isEngineeringMode() || config.NSCLIENT
|
||||
if (!acceptNSData) return Result.success()
|
||||
// Do not accept removed data over WS. Only invalidated trough NSClient
|
||||
@Suppress("ConstantConditionIf")
|
||||
if (true) return Result.success()
|
||||
|
||||
var ret = Result.success()
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNo
|
|||
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
|
||||
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
|
||||
import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationWithAction
|
||||
import info.nightscout.androidaps.plugins.profile.ns.NSProfilePlugin.NSProfileWorker
|
||||
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin
|
||||
import info.nightscout.androidaps.plugins.source.NSClientSourcePlugin.NSClientSourceWorker
|
||||
import info.nightscout.androidaps.receivers.DataWorker
|
||||
import info.nightscout.androidaps.services.Intents
|
||||
|
@ -472,7 +472,7 @@ class NSClientService : DaggerService() {
|
|||
val profileStoreJson = profiles[profiles.length() - 1] as JSONObject
|
||||
rxBus.send(EventNSClientNewLog("PROFILE", "profile received"))
|
||||
dataWorker.enqueue(
|
||||
OneTimeWorkRequest.Builder(NSProfileWorker::class.java)
|
||||
OneTimeWorkRequest.Builder(LocalProfilePlugin.NSProfileWorker::class.java)
|
||||
.setInputData(dataWorker.storeInputData(profileStoreJson, null))
|
||||
.build())
|
||||
if (sp.getBoolean(R.string.key_nsclient_localbroadcasts, false)) {
|
||||
|
@ -652,18 +652,7 @@ class NSClientService : DaggerService() {
|
|||
wakeLock.acquire(mins(10).msecs())
|
||||
try {
|
||||
rxBus.send(EventNSClientNewLog("QUEUE", "Resend started: $reason"))
|
||||
dataSyncSelector.processChangedBolusesCompat()
|
||||
dataSyncSelector.processChangedCarbsCompat()
|
||||
dataSyncSelector.processChangedBolusCalculatorResultsCompat()
|
||||
dataSyncSelector.processChangedTemporaryBasalsCompat()
|
||||
dataSyncSelector.processChangedExtendedBolusesCompat()
|
||||
dataSyncSelector.processChangedProfileSwitchesCompat()
|
||||
dataSyncSelector.processChangedGlucoseValuesCompat()
|
||||
dataSyncSelector.processChangedTempTargetsCompat()
|
||||
dataSyncSelector.processChangedFoodsCompat()
|
||||
dataSyncSelector.processChangedTherapyEventsCompat()
|
||||
dataSyncSelector.processChangedDeviceStatusesCompat()
|
||||
dataSyncSelector.processChangedProfileStore()
|
||||
dataSyncSelector.doUpload()
|
||||
rxBus.send(EventNSClientNewLog("QUEUE", "Resend ended: $reason"))
|
||||
} finally {
|
||||
if (wakeLock.isHeld) wakeLock.release()
|
||||
|
|
|
@ -54,6 +54,9 @@ class LocalProfileFragment : DaggerFragment() {
|
|||
private val save = Runnable {
|
||||
doEdit()
|
||||
basalView?.updateLabel(resourceHelper.gs(R.string.basal_label) + ": " + sumLabel())
|
||||
localProfilePlugin.profile?.getSpecificProfile(spinner?.selectedItem.toString())?.let {
|
||||
binding.basalGraph.show(ProfileSealed.Pure(it))
|
||||
}
|
||||
}
|
||||
|
||||
private val textWatch = object : TextWatcher {
|
||||
|
@ -124,7 +127,7 @@ class LocalProfileFragment : DaggerFragment() {
|
|||
binding.dia.setParams(currentProfile.dia, hardLimits.minDia(), hardLimits.maxDia(), 0.1, DecimalFormat("0.0"), false, binding.save, textWatch)
|
||||
binding.dia.tag = "LP_DIA"
|
||||
TimeListEdit(context, aapsLogger, dateUtil, view, R.id.ic, "IC", resourceHelper.gs(R.string.ic_label), currentProfile.ic, null, hardLimits.minIC(), hardLimits.maxIC(), 0.1, DecimalFormat("0.0"), save)
|
||||
basalView = TimeListEdit(context, aapsLogger, dateUtil, view, R.id.basal, "BASAL", resourceHelper.gs(R.string.basal_label) + ": " + sumLabel(), currentProfile.basal, null, pumpDescription.basalMinimumRate, 10.0, 0.01, DecimalFormat("0.00"), save)
|
||||
basalView = TimeListEdit(context, aapsLogger, dateUtil, view, R.id.basal_holder, "BASAL", resourceHelper.gs(R.string.basal_label) + ": " + sumLabel(), currentProfile.basal, null, pumpDescription.basalMinimumRate, 10.0, 0.01, DecimalFormat("0.00"), save)
|
||||
if (units == Constants.MGDL) {
|
||||
TimeListEdit(context, aapsLogger, dateUtil, view, R.id.isf, "ISF", resourceHelper.gs(R.string.isf_label), currentProfile.isf, null, HardLimits.MIN_ISF, HardLimits.MAX_ISF, 1.0, DecimalFormat("0"), save)
|
||||
TimeListEdit(context, aapsLogger, dateUtil, view, R.id.target, "TARGET", resourceHelper.gs(R.string.target_label), currentProfile.targetLow, currentProfile.targetHigh, HardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble(), 1.0, DecimalFormat("0"), save)
|
||||
|
@ -162,6 +165,9 @@ class LocalProfileFragment : DaggerFragment() {
|
|||
}
|
||||
}
|
||||
})
|
||||
localProfilePlugin.profile?.getSpecificProfile(spinner?.selectedItem.toString())?.let {
|
||||
binding.basalGraph.show(ProfileSealed.Pure(it))
|
||||
}
|
||||
|
||||
binding.profileAdd.setOnClickListener {
|
||||
if (localProfilePlugin.isEdited) {
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
package info.nightscout.androidaps.plugins.profile.local
|
||||
|
||||
import android.content.Context
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.work.Worker
|
||||
import androidx.work.WorkerParameters
|
||||
import androidx.work.workDataOf
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.Constants
|
||||
import info.nightscout.androidaps.R
|
||||
|
@ -12,6 +16,8 @@ import info.nightscout.androidaps.interfaces.*
|
|||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||
import info.nightscout.androidaps.plugins.profile.local.events.EventLocalProfileChanged
|
||||
import info.nightscout.androidaps.receivers.DataWorker
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.DecimalFormatter
|
||||
import info.nightscout.androidaps.utils.HardLimits
|
||||
|
@ -165,61 +171,64 @@ class LocalProfilePlugin @Inject constructor(
|
|||
p.dia = sp.getDouble(localProfileNumbered + "dia", Constants.defaultDIA)
|
||||
try {
|
||||
p.ic = JSONArray(sp.getString(localProfileNumbered + "ic", defaultArray))
|
||||
} catch (e1: JSONException) {
|
||||
try {
|
||||
p.ic = JSONArray(defaultArray)
|
||||
} catch (ignored: JSONException) {
|
||||
}
|
||||
aapsLogger.error("Exception", e1)
|
||||
}
|
||||
|
||||
try {
|
||||
p.isf = JSONArray(sp.getString(localProfileNumbered + "isf", defaultArray))
|
||||
} catch (e1: JSONException) {
|
||||
try {
|
||||
p.isf = JSONArray(defaultArray)
|
||||
} catch (ignored: JSONException) {
|
||||
}
|
||||
aapsLogger.error("Exception", e1)
|
||||
}
|
||||
|
||||
try {
|
||||
p.basal = JSONArray(sp.getString(localProfileNumbered + "basal", defaultArray))
|
||||
} catch (e1: JSONException) {
|
||||
try {
|
||||
p.basal = JSONArray(defaultArray)
|
||||
} catch (ignored: JSONException) {
|
||||
}
|
||||
aapsLogger.error("Exception", e1)
|
||||
}
|
||||
|
||||
try {
|
||||
p.targetLow = JSONArray(sp.getString(localProfileNumbered + "targetlow", defaultArray))
|
||||
} catch (e1: JSONException) {
|
||||
try {
|
||||
p.targetLow = JSONArray(defaultArray)
|
||||
} catch (ignored: JSONException) {
|
||||
}
|
||||
aapsLogger.error("Exception", e1)
|
||||
}
|
||||
|
||||
try {
|
||||
p.targetHigh = JSONArray(sp.getString(localProfileNumbered + "targethigh", defaultArray))
|
||||
} catch (e1: JSONException) {
|
||||
try {
|
||||
p.targetHigh = JSONArray(defaultArray)
|
||||
} catch (ignored: JSONException) {
|
||||
}
|
||||
aapsLogger.error("Exception", e1)
|
||||
profiles.add(p)
|
||||
} catch (e: JSONException) {
|
||||
aapsLogger.error("Exception", e)
|
||||
}
|
||||
|
||||
profiles.add(p)
|
||||
}
|
||||
// create at least one profile if doesn't exist
|
||||
if (profiles.size < 1) profiles.add(defaultProfile())
|
||||
isEdited = false
|
||||
numOfProfiles = profiles.size
|
||||
createAndStoreConvertedProfile()
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun loadFromStore(store: ProfileStore) {
|
||||
try {
|
||||
val newProfiles: ArrayList<SingleProfile> = ArrayList()
|
||||
for (p in store.getProfileList()) {
|
||||
store.getSpecificProfile(p.toString())?.let {
|
||||
val sp = copyFrom(it, p.toString())
|
||||
sp.name = p.toString()
|
||||
newProfiles.add(sp)
|
||||
}
|
||||
}
|
||||
if (newProfiles.size > 0) {
|
||||
profiles = newProfiles
|
||||
numOfProfiles = profiles.size
|
||||
currentProfileIndex = 0
|
||||
isEdited = false
|
||||
createAndStoreConvertedProfile()
|
||||
aapsLogger.debug(LTag.PROFILE, "Accepted ${profiles.size} profiles")
|
||||
rxBus.send(EventLocalProfileChanged())
|
||||
} else
|
||||
aapsLogger.debug(LTag.PROFILE, "ProfileStore not accepted")
|
||||
} catch (e: Exception) {
|
||||
aapsLogger.error("Error loading ProfileStore", e)
|
||||
}
|
||||
}
|
||||
|
||||
private fun defaultProfile(): SingleProfile =
|
||||
SingleProfile().also { p ->
|
||||
p.name = Constants.LOCAL_PROFILE
|
||||
p.mgdl = profileFunction.getUnits() == GlucoseUnit.MGDL
|
||||
p.dia = Constants.defaultDIA
|
||||
try {
|
||||
p.ic = JSONArray(defaultArray)
|
||||
p.isf = JSONArray(defaultArray)
|
||||
p.basal = JSONArray(defaultArray)
|
||||
p.targetLow = JSONArray(defaultArray)
|
||||
p.targetHigh = JSONArray(defaultArray)
|
||||
} catch (e: JSONException) {
|
||||
aapsLogger.error("Exception", e)
|
||||
}
|
||||
}
|
||||
|
||||
fun copyFrom(pureProfile: PureProfile, newName: String): SingleProfile {
|
||||
var verifiedName = newName
|
||||
if (rawProfile?.getSpecificProfile(newName) != null) {
|
||||
|
@ -378,4 +387,36 @@ class LocalProfilePlugin @Inject constructor(
|
|||
get() = rawProfile?.getDefaultProfile()?.let {
|
||||
DecimalFormatter.to2Decimal(ProfileSealed.Pure(it).percentageBasalSum()) + "U "
|
||||
} ?: "INVALID"
|
||||
|
||||
// cannot be inner class because of needed injection
|
||||
class NSProfileWorker(
|
||||
context: Context,
|
||||
params: WorkerParameters
|
||||
) : Worker(context, params) {
|
||||
|
||||
@Inject lateinit var injector: HasAndroidInjector
|
||||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
@Inject lateinit var rxBus: RxBusWrapper
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var dataWorker: DataWorker
|
||||
@Inject lateinit var sp: SP
|
||||
@Inject lateinit var config: Config
|
||||
@Inject lateinit var localProfilePlugin: LocalProfilePlugin
|
||||
|
||||
init {
|
||||
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
|
||||
}
|
||||
|
||||
override fun doWork(): Result {
|
||||
val profileJson = dataWorker.pickupJSONObject(inputData.getLong(DataWorker.STORE_KEY, -1))
|
||||
?: return Result.failure(workDataOf("Error" to "missing input data"))
|
||||
if (sp.getBoolean(R.string.key_ns_receive_profile_store, false) || config.NSCLIENT) {
|
||||
localProfilePlugin.loadFromStore(ProfileStore(injector, profileJson, dateUtil))
|
||||
aapsLogger.debug(LTag.PROFILE, "Received profileStore: $profileJson")
|
||||
return Result.success(workDataOf("Data" to profileJson.toString()))
|
||||
}
|
||||
return Result.success()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,170 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.profile.ns
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.AdapterView
|
||||
import android.widget.ArrayAdapter
|
||||
import dagger.android.support.DaggerFragment
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.data.ProfileSealed
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Action
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Sources
|
||||
import info.nightscout.androidaps.database.entities.ValueWithUnit
|
||||
import info.nightscout.androidaps.databinding.NsprofileFragmentBinding
|
||||
import info.nightscout.androidaps.interfaces.ActivePlugin
|
||||
import info.nightscout.androidaps.interfaces.Config
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.logging.UserEntryLogger
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||
import info.nightscout.androidaps.plugins.profile.ns.events.EventNSProfileUpdateGUI
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.DecimalFormatter
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.rxkotlin.plusAssign
|
||||
import javax.inject.Inject
|
||||
|
||||
class NSProfileFragment : DaggerFragment() {
|
||||
|
||||
@Inject lateinit var rxBus: RxBusWrapper
|
||||
@Inject lateinit var resourceHelper: ResourceHelper
|
||||
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
||||
@Inject lateinit var profileFunction: ProfileFunction
|
||||
@Inject lateinit var nsProfilePlugin: NSProfilePlugin
|
||||
@Inject lateinit var aapsSchedulers: AapsSchedulers
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var uel: UserEntryLogger
|
||||
@Inject lateinit var activePlugin: ActivePlugin
|
||||
@Inject lateinit var config: Config
|
||||
|
||||
private var disposable: CompositeDisposable = CompositeDisposable()
|
||||
|
||||
private var _binding: NsprofileFragmentBinding? = null
|
||||
|
||||
// This property is only valid between onCreateView and
|
||||
// onDestroyView.
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View {
|
||||
_binding = NsprofileFragmentBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
binding.profileviewer.closeLayout.close.visibility = View.GONE // not needed for fragment
|
||||
|
||||
binding.profileswitch.setOnClickListener {
|
||||
val name = binding.spinner.selectedItem?.toString() ?: ""
|
||||
nsProfilePlugin.profile?.let { store ->
|
||||
store.getSpecificProfile(name)?.let {
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.nsprofile),
|
||||
resourceHelper.gs(R.string.activate_profile) + ": " + name + " ?", Runnable {
|
||||
uel.log(Action.PROFILE_SWITCH, Sources.NSProfile,
|
||||
ValueWithUnit.SimpleString(name),
|
||||
ValueWithUnit.Percent(100))
|
||||
profileFunction.createProfileSwitch(store, name, 0, 100, 0, dateUtil.now())
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
binding.spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
||||
override fun onNothingSelected(parent: AdapterView<*>?) {
|
||||
if (_binding == null) return
|
||||
binding.profileviewer.invalidprofile.visibility = View.VISIBLE
|
||||
binding.profileviewer.noprofile.visibility = View.VISIBLE
|
||||
binding.profileviewer.units.text = ""
|
||||
binding.profileviewer.dia.text = ""
|
||||
binding.profileviewer.activeprofile.text = ""
|
||||
binding.profileviewer.ic.text = ""
|
||||
binding.profileviewer.isf.text = ""
|
||||
binding.profileviewer.basal.text = ""
|
||||
binding.profileviewer.basaltotal.text = ""
|
||||
binding.profileviewer.target.text = ""
|
||||
binding.profileswitch.visibility = View.GONE
|
||||
}
|
||||
|
||||
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
|
||||
if (_binding == null) return
|
||||
val name = binding.spinner.getItemAtPosition(position).toString()
|
||||
|
||||
binding.profileswitch.visibility = View.GONE
|
||||
|
||||
nsProfilePlugin.profile?.let { store ->
|
||||
store.getSpecificProfile(name)?.let { profile ->
|
||||
if (_binding == null) return
|
||||
val pss = ProfileSealed.Pure(profile)
|
||||
binding.profileviewer.units.text = pss.units.asText
|
||||
binding.profileviewer.dia.text = resourceHelper.gs(R.string.format_hours, pss.dia)
|
||||
binding.profileviewer.activeprofile.text = name
|
||||
binding.profileviewer.ic.text = pss.getIcList(resourceHelper, dateUtil)
|
||||
binding.profileviewer.isf.text = pss.getIsfList(resourceHelper, dateUtil)
|
||||
binding.profileviewer.basal.text = pss.getBasalList(resourceHelper, dateUtil)
|
||||
binding.profileviewer.basaltotal.text = String.format(resourceHelper.gs(R.string.profile_total), DecimalFormatter.to2Decimal(pss.baseBasalSum()))
|
||||
binding.profileviewer.target.text = pss.getTargetList(resourceHelper, dateUtil)
|
||||
binding.profileviewer.basalGraph.show(pss)
|
||||
if (pss.isValid("NSProfileFragment", activePlugin.activePump, config, resourceHelper, rxBus)) {
|
||||
binding.profileviewer.invalidprofile.visibility = View.GONE
|
||||
binding.profileswitch.visibility = View.VISIBLE
|
||||
} else {
|
||||
binding.profileviewer.invalidprofile.visibility = View.VISIBLE
|
||||
binding.profileswitch.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
disposable += rxBus
|
||||
.toObservable(EventNSProfileUpdateGUI::class.java)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe({ updateGUI() }, fabricPrivacy::logException)
|
||||
updateGUI()
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
disposable.clear()
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun updateGUI() {
|
||||
if (_binding == null) return
|
||||
binding.profileviewer.noprofile.visibility = View.VISIBLE
|
||||
|
||||
nsProfilePlugin.profile?.let { profileStore ->
|
||||
context?.let { context ->
|
||||
val profileList = profileStore.getProfileList()
|
||||
val adapter = ArrayAdapter(context, R.layout.spinner_centered, profileList)
|
||||
binding.spinner.adapter = adapter
|
||||
// set selected to actual profile
|
||||
for (p in profileList.indices) {
|
||||
if (profileList[p] == profileFunction.getProfileName())
|
||||
binding.spinner.setSelection(p)
|
||||
}
|
||||
binding.profileviewer.noprofile.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,110 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.profile.ns
|
||||
|
||||
import android.content.Context
|
||||
import androidx.work.Worker
|
||||
import androidx.work.WorkerParameters
|
||||
import androidx.work.workDataOf
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.interfaces.Config
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.events.EventProfileStoreChanged
|
||||
import info.nightscout.androidaps.interfaces.PluginBase
|
||||
import info.nightscout.androidaps.interfaces.PluginDescription
|
||||
import info.nightscout.androidaps.interfaces.PluginType
|
||||
import info.nightscout.androidaps.interfaces.ProfileSource
|
||||
import info.nightscout.androidaps.interfaces.ProfileStore
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart
|
||||
import info.nightscout.androidaps.plugins.profile.ns.events.EventNSProfileUpdateGUI
|
||||
import info.nightscout.androidaps.receivers.DataWorker
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
import org.json.JSONObject
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class NSProfilePlugin @Inject constructor(
|
||||
injector: HasAndroidInjector,
|
||||
aapsLogger: AAPSLogger,
|
||||
private val rxBus: RxBusWrapper,
|
||||
resourceHelper: ResourceHelper,
|
||||
private val sp: SP,
|
||||
private val dateUtil: DateUtil,
|
||||
config: Config
|
||||
) : PluginBase(PluginDescription()
|
||||
.mainType(PluginType.PROFILE)
|
||||
.fragmentClass(NSProfileFragment::class.java.name)
|
||||
.pluginIcon(R.drawable.ic_nightscout_profile)
|
||||
.pluginName(R.string.nsprofile)
|
||||
.shortName(R.string.profileviewer_shortname)
|
||||
.alwaysEnabled(config.NSCLIENT)
|
||||
.alwaysVisible(config.NSCLIENT)
|
||||
.showInList(!config.NSCLIENT)
|
||||
.description(R.string.description_profile_nightscout),
|
||||
aapsLogger, resourceHelper, injector
|
||||
), ProfileSource {
|
||||
|
||||
override var profile: ProfileStore? = null
|
||||
|
||||
override val profileName: String?
|
||||
get() = profile?.getDefaultProfileName()
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
loadNSProfile()
|
||||
}
|
||||
|
||||
private fun storeNSProfile() {
|
||||
sp.putString("profile", profile!!.data.toString())
|
||||
aapsLogger.debug(LTag.PROFILE, "Storing profile")
|
||||
}
|
||||
|
||||
private fun loadNSProfile() {
|
||||
aapsLogger.debug(LTag.PROFILE, "Loading stored profile")
|
||||
val profileString = sp.getStringOrNull("profile", null)
|
||||
if (profileString != null) {
|
||||
aapsLogger.debug(LTag.PROFILE, "Loaded profile: $profileString")
|
||||
profile = ProfileStore(injector, JSONObject(profileString), dateUtil)
|
||||
} else {
|
||||
aapsLogger.debug(LTag.PROFILE, "Stored profile not found")
|
||||
// force restart of nsclient to fetch profile
|
||||
rxBus.send(EventNSClientRestart())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// cannot be inner class because of needed injection
|
||||
class NSProfileWorker(
|
||||
context: Context,
|
||||
params: WorkerParameters
|
||||
) : Worker(context, params) {
|
||||
|
||||
@Inject lateinit var injector: HasAndroidInjector
|
||||
@Inject lateinit var nsProfilePlugin: NSProfilePlugin
|
||||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
@Inject lateinit var rxBus: RxBusWrapper
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var dataWorker: DataWorker
|
||||
|
||||
init {
|
||||
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
|
||||
}
|
||||
|
||||
override fun doWork(): Result {
|
||||
val profileString = dataWorker.pickupJSONObject(inputData.getLong(DataWorker.STORE_KEY, -1))
|
||||
?: return Result.failure(workDataOf("Error" to "missing input data"))
|
||||
nsProfilePlugin.profile = ProfileStore(injector, profileString, dateUtil)
|
||||
nsProfilePlugin.storeNSProfile()
|
||||
if (nsProfilePlugin.isEnabled()) {
|
||||
rxBus.send(EventProfileStoreChanged())
|
||||
rxBus.send(EventNSProfileUpdateGUI())
|
||||
}
|
||||
aapsLogger.debug(LTag.PROFILE, "Received profileStore: ${nsProfilePlugin.profile}")
|
||||
return Result.success()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.profile.ns.events
|
||||
|
||||
import info.nightscout.androidaps.events.EventUpdateGui
|
||||
|
||||
class EventNSProfileUpdateGUI : EventUpdateGui()
|
|
@ -5,12 +5,12 @@ import androidx.work.Worker
|
|||
import androidx.work.WorkerParameters
|
||||
import androidx.work.workDataOf
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.interfaces.Config
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||
import info.nightscout.androidaps.database.transactions.CgmSourceTransaction
|
||||
import info.nightscout.androidaps.interfaces.BgSource
|
||||
import info.nightscout.androidaps.interfaces.Config
|
||||
import info.nightscout.androidaps.interfaces.PluginBase
|
||||
import info.nightscout.androidaps.interfaces.PluginDescription
|
||||
import info.nightscout.androidaps.interfaces.PluginType
|
||||
|
@ -115,7 +115,7 @@ class NSClientSourcePlugin @Inject constructor(
|
|||
override fun doWork(): Result {
|
||||
var ret = Result.success()
|
||||
|
||||
if (!nsClientSourcePlugin.isEnabled() && !sp.getBoolean(R.string.key_ns_autobackfill, true) && !dexcomPlugin.isEnabled()) return Result.success()
|
||||
if (!nsClientSourcePlugin.isEnabled() && !sp.getBoolean(R.string.key_ns_receive_cgm, true) && !dexcomPlugin.isEnabled()) return Result.success()
|
||||
|
||||
val sgvs = dataWorker.pickupJSONArray(inputData.getLong(DataWorker.STORE_KEY, -1))
|
||||
?: return Result.failure(workDataOf("Error" to "missing input data"))
|
||||
|
|
|
@ -156,7 +156,7 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() {
|
|||
})
|
||||
}
|
||||
}
|
||||
val nsUploadOnly = sp.getBoolean(R.string.key_ns_upload_only, true) || !buildHelper.isEngineeringMode()
|
||||
val nsUploadOnly = !sp.getBoolean(R.string.key_ns_receive_insulin, false) || !sp.getBoolean(R.string.key_ns_receive_carbs, false) || !buildHelper.isEngineeringMode()
|
||||
if (nsUploadOnly) binding.refreshFromNightscout.visibility = View.GONE
|
||||
binding.showInvalidated.setOnCheckedChangeListener { _, _ ->
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
|
|
|
@ -102,7 +102,7 @@ class TreatmentsCareportalFragment : DaggerFragment() {
|
|||
}
|
||||
}
|
||||
|
||||
val nsUploadOnly = sp.getBoolean(R.string.key_ns_upload_only, true) || !buildHelper.isEngineeringMode()
|
||||
val nsUploadOnly = !sp.getBoolean(R.string.key_ns_receive_therapy_events, false) || !buildHelper.isEngineeringMode()
|
||||
if (nsUploadOnly) binding.refreshFromNightscout.visibility = View.GONE
|
||||
binding.showInvalidated.setOnCheckedChangeListener { _, _ ->
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
|
|
|
@ -99,7 +99,7 @@ class TreatmentsProfileSwitchFragment : DaggerFragment() {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (sp.getBoolean(R.string.key_ns_upload_only, true) || !buildHelper.isEngineeringMode()) binding.refreshFromNightscout.visibility = View.GONE
|
||||
if (!sp.getBoolean(R.string.key_ns_receive_profile_switch, false) || !buildHelper.isEngineeringMode()) binding.refreshFromNightscout.visibility = View.GONE
|
||||
binding.showInvalidated.setOnCheckedChangeListener { _, _ ->
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ class TreatmentsTempTargetFragment : DaggerFragment() {
|
|||
})
|
||||
}
|
||||
}
|
||||
val nsUploadOnly = sp.getBoolean(R.string.key_ns_upload_only, true) || !buildHelper.isEngineeringMode()
|
||||
val nsUploadOnly = !sp.getBoolean(R.string.key_ns_receive_temp_target, false) || !buildHelper.isEngineeringMode()
|
||||
if (nsUploadOnly) binding.refreshFromNightscout.visibility = View.INVISIBLE
|
||||
binding.showInvalidated.setOnCheckedChangeListener { _, _ ->
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
|
|
|
@ -19,11 +19,8 @@ import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesFragm
|
|||
import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesPlugin
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientStatus
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.services.NSClientService
|
||||
import info.nightscout.androidaps.plugins.profile.local.LocalProfileFragment
|
||||
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin
|
||||
import info.nightscout.androidaps.plugins.profile.ns.NSProfileFragment
|
||||
import info.nightscout.androidaps.plugins.profile.ns.NSProfilePlugin
|
||||
import info.nightscout.androidaps.plugins.pump.common.events.EventRileyLinkDeviceStatusChange
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.OmnipodDashPumpPlugin
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.eros.OmnipodErosPumpPlugin
|
||||
|
@ -53,7 +50,6 @@ class SWDefinition @Inject constructor(
|
|||
private val configBuilder: ConfigBuilder,
|
||||
private val loopPlugin: LoopPlugin,
|
||||
private val nsClientPlugin: NSClientPlugin,
|
||||
private val nsProfilePlugin: NSProfilePlugin,
|
||||
private val importExportPrefs: ImportExportPrefs,
|
||||
private val androidPermission: AndroidPermission,
|
||||
private val cryptoUtil: CryptoUtil,
|
||||
|
@ -254,25 +250,6 @@ class SWDefinition @Inject constructor(
|
|||
.option(PluginType.BGSOURCE, R.string.configbuilder_bgsource_description)
|
||||
.label(R.string.configbuilder_bgsource))
|
||||
.add(SWBreak(injector))
|
||||
private val screenProfile = SWScreen(injector, R.string.configbuilder_profile)
|
||||
.skippable(false)
|
||||
.add(SWInfoText(injector)
|
||||
.label(R.string.setupwizard_profile_description))
|
||||
.add(SWBreak(injector))
|
||||
.add(SWPlugin(injector, this)
|
||||
.option(PluginType.PROFILE, R.string.configbuilder_profile_description)
|
||||
.label(R.string.configbuilder_profile))
|
||||
private val screenNsProfile = SWScreen(injector, R.string.nsprofile)
|
||||
.skippable(false)
|
||||
.add(SWInfoText(injector)
|
||||
.label(R.string.adjustprofileinns))
|
||||
.add(SWFragment(injector, this)
|
||||
.add(NSProfileFragment()))
|
||||
.validator {
|
||||
nsProfilePlugin.profile?.getDefaultProfile()?.let { ProfileSealed.Pure(it).isValid("StartupWizard", activePlugin.activePump, config, resourceHelper, rxBus) }
|
||||
?: false
|
||||
}
|
||||
.visibility { nsProfilePlugin.isEnabled() }
|
||||
private val screenLocalProfile = SWScreen(injector, R.string.localprofile)
|
||||
.skippable(false)
|
||||
.add(SWFragment(injector, this)
|
||||
|
@ -405,8 +382,6 @@ class SWDefinition @Inject constructor(
|
|||
.add(screenAge)
|
||||
.add(screenInsulin)
|
||||
.add(screenBgSource)
|
||||
.add(screenProfile)
|
||||
.add(screenNsProfile)
|
||||
.add(screenLocalProfile)
|
||||
.add(screenProfileSwitch)
|
||||
.add(screenPump)
|
||||
|
@ -434,8 +409,6 @@ class SWDefinition @Inject constructor(
|
|||
.add(screenAge)
|
||||
.add(screenInsulin)
|
||||
.add(screenBgSource)
|
||||
.add(screenProfile)
|
||||
.add(screenNsProfile)
|
||||
.add(screenLocalProfile)
|
||||
.add(screenProfileSwitch)
|
||||
.add(screenPump)
|
||||
|
|
|
@ -92,8 +92,8 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
android:weightSum="5"
|
||||
android:paddingBottom="10dp">
|
||||
android:paddingBottom="10dp"
|
||||
android:weightSum="5">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/dia_tab"
|
||||
|
@ -228,10 +228,24 @@
|
|||
|
||||
<LinearLayout
|
||||
android:id="@+id/basal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:orientation="vertical" />
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/basal_holder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:orientation="vertical" />
|
||||
|
||||
<info.nightscout.androidaps.plugins.treatments.fragments.ProfileGraph
|
||||
android:id="@+id/basal_graph"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="100dip"
|
||||
android:layout_margin="20dp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/target"
|
||||
|
@ -248,15 +262,15 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginBottom="3dp"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:layout_marginTop="3dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:layout_marginBottom="3dp"
|
||||
android:layout_weight="1"
|
||||
android:drawableStart="@drawable/ic_local_activate"
|
||||
android:paddingLeft="10dp"
|
||||
android:paddingRight="10dp"
|
||||
android:text="@string/activate_profile"
|
||||
android:drawableStart="@drawable/ic_local_activate" />
|
||||
android:text="@string/activate_profile" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical" android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/spinner"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginBottom="5dp" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/profileswitch"
|
||||
style="?android:attr/buttonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:text="@string/activate_profile"
|
||||
android:textColor="@color/colorProfileSwitchButton" />
|
||||
|
||||
<include
|
||||
android:id="@+id/profileviewer"
|
||||
layout="@layout/profileviewer_fragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
|
||||
</LinearLayout>
|
|
@ -78,7 +78,6 @@
|
|||
<string name="description_overview">Displays the current state of your loop and buttons for most common actions</string>
|
||||
<string name="description_persistent_notification">Shows an ongoing notification with a short overview of what your loop is doing</string>
|
||||
<string name="description_profile_local">Define a profile which is available offline.</string>
|
||||
<string name="description_profile_nightscout">Provides the profile you have defined in Nightscout</string>
|
||||
<string name="description_pump_mdi">Pump integration for people who do multiple daily injections for their diabetes therapy</string>
|
||||
<string name="description_pump_virtual">Pump integration for pumps which don\'t have any driver yet (Open Loop)</string>
|
||||
<string name="description_sensitivity_aaps">Sensitivity is calculated the same way like Oref0, but you can specify timeframe to the past. Minimal carb absorption is calculated from max carb absorption time from preferences.</string>
|
||||
|
@ -128,7 +127,6 @@
|
|||
|
||||
<string name="configbuilder">Config Builder</string>
|
||||
<string name="overview">Overview</string>
|
||||
<string name="nsprofile">NS Profile</string>
|
||||
<string name="treatments">Treatments</string>
|
||||
<string name="virtualpump">Virtual Pump</string>
|
||||
<string name="careportal">Careportal</string>
|
||||
|
@ -340,7 +338,6 @@
|
|||
<string name="localprofile_shortname">LP</string>
|
||||
<string name="overview_shortname">HOME</string>
|
||||
<string name="virtualpump_shortname">VPUMP</string>
|
||||
<string name="profileviewer_shortname">NSPROFILE</string>
|
||||
<string name="treatments_shortname">TREAT</string>
|
||||
<string name="objectives_shortname">OBJ</string>
|
||||
<string name="wear_shortname">WEAR</string>
|
||||
|
@ -499,10 +496,6 @@
|
|||
<string name="xdripstatus_shortname">xds</string>
|
||||
<string name="wear_showbgi_title">Show BGI</string>
|
||||
<string name="wear_showbgi_summary">Add BGI to status line</string>
|
||||
<string name="ns_noupload">No upload to NS</string>
|
||||
<string name="ns_noupload_summary">All data sent to NS are dropped. AAPS is connected to NS but no change in NS is done</string>
|
||||
<string name="key_ns_upload_only" translatable="false">ns_upload_only2</string>
|
||||
<string name="key_ns_noupload" translatable="false">ns_noupload</string>
|
||||
<string name="overview_extendedbolus_cancel_button">Cancel Extended Bolus</string>
|
||||
<string name="doprofileswitch">Do Profile Switch</string>
|
||||
<string name="careportal_sensor_label">Sensor</string>
|
||||
|
@ -699,8 +692,6 @@
|
|||
<string name="category">Category</string>
|
||||
<string name="subcategory">Subcategory</string>
|
||||
<string name="bolusrecordedonly">Bolus will be recorded only (not delivered by pump)</string>
|
||||
<string name="ns_autobackfill_summary">Autobackfill missig BGs from NS</string>
|
||||
<string name="key_ns_autobackfill" translatable="false">ns_autobackfill</string>
|
||||
<string name="loop_smbsetbypump_label">SMB set by pump</string>
|
||||
<string name="overview_show_activity">Activity</string>
|
||||
<string name="overview_show_bgi">Blood Glucose Impact</string>
|
||||
|
@ -783,7 +774,6 @@
|
|||
<string name="virtualpump_type">Virtual Pump Type</string>
|
||||
<string name="virtualpump_definition">Pump Definition</string>
|
||||
<string name="virtualpump_pump_def">Bolus: Step=%1$s\nExtended Bolus: [Step=%2$s, Duration=%3$smin-%4$sh]\nBasal: Step=%5$s\nTBR: %6$s (by %7$s), Duration=%8$smin-%9$sh\n%10$s</string>
|
||||
<string name="ns_autobackfill_title">Autobackfill BG</string>
|
||||
<string name="wear_wizard_settings">Wizard Settings</string>
|
||||
<string name="key_wearwizard_bg" translatable="false">wearwizard_bg</string>
|
||||
<string name="key_wearwizard_tt" translatable="false">wearwizard_tt</string>
|
||||
|
@ -797,7 +787,6 @@
|
|||
<string name="enable_nsclient">Enable NSClient</string>
|
||||
<string name="welcometosetupwizard">Welcome to setup wizard. It will guide you through the setup process\n</string>
|
||||
<string name="readstatus">Read status</string>
|
||||
<string name="adjustprofileinns">Changes must be done in NS</string>
|
||||
<string name="exitwizard">Skip setup wizard</string>
|
||||
<string name="setupwizard_loop_description">Press the button below to enable AndroidAPS to suggest/make basal changes</string>
|
||||
<string name="key_setupwizard_processed" translatable="false">startupwizard_processed</string>
|
||||
|
@ -805,7 +794,6 @@
|
|||
<string name="setupwizard_sensitivity_url">https://github.com/MilosKozak/AndroidAPS/wiki/Sensitivity-detection-and-COB</string>
|
||||
<string name="nsclientinfotext">NSClient handles connection to Nightscout. You can skip this part now but you will not be able to pass objectives until you set it up.</string>
|
||||
<string name="diawarning">Please remember: new insulin profiles require DIA at least 5h. DIA 5–6h on new profile is equal to DIA 3h on old insulin profiles.</string>
|
||||
<string name="setupwizard_profile_description">Please select source of profile. If patient is a child you should use NS profile. If there is nobody following you on Nightscout you will probably prefer Local profile. Please remember that you are only selecting the profile source. To use it you must activate it by executing \"Profile switch\"</string>
|
||||
<string name="setupwizard_aps_description">Select one from availables algorithms. They are sorted from oldest to newest. Newer algorithm is usually more powerful and more aggressive. Thus if you are new looper you may probably start with AMA and not with latest one. Do not forget to read the OpenAPS documentation and configure it before use.</string>
|
||||
<string name="setupwizard_pump_waiting_for_riley_link_connection">Please configure your RileyLink below. After selecting a RileyLink, it will be possible to continue setup once the RileyLink status is \"Connected\". This might take a minute.\n</string>
|
||||
<string name="setupwizard_pump_pump_not_initialized"><b>Note:</b> You can continue setup once the pump has been set up.\n</string>
|
||||
|
@ -954,7 +942,6 @@
|
|||
<string name="objectives_button_unstart">Clear started</string>
|
||||
<string name="doyouwantresetstart">Do you want reset objective start? You may lose your progress.</string>
|
||||
<string name="setupwizard_units_prompt">Select units you want to display values in</string>
|
||||
<string name="ns_ploadlocalprofile">Upload local profile changes to NS</string>
|
||||
<string name="key_wear_detailediob" translatable="false">wear_detailediob</string>
|
||||
<string name="key_wear_showbgi" translatable="false">wear_showbgi</string>
|
||||
<string name="dia_short">DIA</string>
|
||||
|
@ -1139,5 +1126,30 @@
|
|||
<string name="profile_carbs_ratio_value">Profile carbs ratio value</string>
|
||||
<string name="full_sync">Full sync</string>
|
||||
<string name="prime">Prime</string>
|
||||
<string name="ns_sync_options">Synchronization</string>
|
||||
<string name="key_ns_upload" translatable="false">ns_upload</string>
|
||||
<string name="ns_upload_summary">Profiles, boluses, carbs, temporary basals are uploaded to NS</string>
|
||||
<string name="ns_upload">Upload data to NS</string>
|
||||
<string name="key_ns_receive_profile_store" translatable="false">ns_receive_profile_store</string>
|
||||
<string name="ns_receive_profile_store">Receive profile store</string>
|
||||
<string name="ns_receive_profile_store_summary">Synchronized profiles from NS profile editor to Local profile</string>
|
||||
<string name="key_ns_receive_temp_target" translatable="false">ns_receive_temp_target</string>
|
||||
<string name="ns_receive_temp_target">Receive temporary targets</string>
|
||||
<string name="ns_receive_temp_target_summary">Accept temporary targets entered through NS or NSClient</string>
|
||||
<string name="key_ns_receive_profile_switch" translatable="false">ns_receive_profile_switch</string>
|
||||
<string name="ns_receive_profile_switch">Receive profile switches</string>
|
||||
<string name="ns_receive_profile_switch_summary">Accept profile switches entered through NS or NSClient</string>
|
||||
<string name="key_ns_receive_insulin" translatable="false">ns_receive_insulin</string>
|
||||
<string name="ns_receive_insulin">Receive insulin</string>
|
||||
<string name="ns_receive_insulin_summary">Accept insulin entered through NS or NSClient (it\'s not delivered, only calculated towards IOB)</string>
|
||||
<string name="key_ns_receive_carbs" translatable="false">ns_receive_carbs</string>
|
||||
<string name="ns_receive_carbs">Receive carbs</string>
|
||||
<string name="ns_receive_carbs_summary">Accept carbs entered through NS or NSClient</string>
|
||||
<string name="key_ns_receive_therapy_events" translatable="false">ns_receive_therapy_events</string>
|
||||
<string name="ns_receive_therapy_events">Receive therapy events</string>
|
||||
<string name="ns_receive_therapy_events_summary">Accept therapy events (cannula, insulin, battery change etc) entered through NS or NSClient</string>
|
||||
<string name="key_ns_receive_cgm" translatable="false">ns_receive_cgm</string>
|
||||
<string name="ns_receive_cgm">Receive/backfill CGM data</string>
|
||||
<string name="ns_receive_cgm_summary">Accept CGM data from NS</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -26,17 +26,59 @@
|
|||
validate:minLength="12"
|
||||
validate:testType="minLength"/>
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="@string/key_ns_logappstartedevent"
|
||||
android:title="@string/ns_logappstartedevent"
|
||||
android:summary="@string/ns_logappstartedevent"
|
||||
/>
|
||||
<androidx.preference.PreferenceScreen
|
||||
android:key="@string/ns_sync_options"
|
||||
android:title="@string/ns_sync_options">
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/key_ns_uploadlocalprofile"
|
||||
android:title="@string/ns_ploadlocalprofile" />
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="@string/key_ns_upload"
|
||||
android:summary="@string/ns_upload_summary"
|
||||
android:title="@string/ns_upload" />
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/key_ns_receive_cgm"
|
||||
android:summary="@string/ns_receive_cgm_summary"
|
||||
android:title="@string/ns_receive_cgm" />
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/key_ns_receive_profile_store"
|
||||
android:summary="@string/ns_receive_profile_store_summary"
|
||||
android:title="@string/ns_receive_profile_store" />
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/key_ns_receive_temp_target"
|
||||
android:summary="@string/ns_receive_temp_target_summary"
|
||||
android:title="@string/ns_receive_temp_target" />
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/key_ns_receive_profile_switch"
|
||||
android:summary="@string/ns_receive_profile_switch_summary"
|
||||
android:title="@string/ns_receive_profile_switch" />
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/key_ns_receive_insulin"
|
||||
android:summary="@string/ns_receive_insulin_summary"
|
||||
android:title="@string/ns_receive_insulin" />
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/key_ns_receive_carbs"
|
||||
android:summary="@string/ns_receive_carbs_summary"
|
||||
android:title="@string/ns_receive_carbs" />
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/key_ns_receive_therapy_events"
|
||||
android:summary="@string/ns_receive_therapy_events_summary"
|
||||
android:title="@string/ns_receive_therapy_events" />
|
||||
|
||||
</androidx.preference.PreferenceScreen>>
|
||||
|
||||
<androidx.preference.PreferenceScreen
|
||||
android:key="@string/ns_alarmoptions"
|
||||
|
@ -113,9 +155,10 @@
|
|||
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="@string/key_ns_autobackfill"
|
||||
android:summary="@string/ns_autobackfill_summary"
|
||||
android:title="@string/ns_autobackfill_title" />
|
||||
android:key="@string/key_ns_logappstartedevent"
|
||||
android:title="@string/ns_logappstartedevent"
|
||||
android:summary="@string/ns_logappstartedevent"
|
||||
/>
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
|
@ -135,18 +178,6 @@
|
|||
android:summary="@string/ns_localbroadcasts"
|
||||
android:title="@string/ns_localbroadcasts_title" />
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="@string/key_ns_upload_only"
|
||||
android:summary="@string/ns_upload_only_summary"
|
||||
android:title="@string/ns_upload_only" />
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/key_ns_noupload"
|
||||
android:summary="@string/ns_noupload_summary"
|
||||
android:title="@string/ns_noupload" />
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/key_ns_sync_use_absolute"
|
||||
|
|
|
@ -1,728 +0,0 @@
|
|||
package info.nightscout.androidaps.data;
|
||||
|
||||
import static info.nightscout.androidaps.extensions.ProfileSwitchExtensionKt.pureProfileFromJson;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.collection.LongSparseArray;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.android.HasAndroidInjector;
|
||||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.core.R;
|
||||
import info.nightscout.androidaps.interfaces.ActivePlugin;
|
||||
import info.nightscout.androidaps.interfaces.Config;
|
||||
import info.nightscout.androidaps.interfaces.GlucoseUnit;
|
||||
import info.nightscout.androidaps.interfaces.Profile;
|
||||
import info.nightscout.androidaps.interfaces.Pump;
|
||||
import info.nightscout.androidaps.interfaces.PumpDescription;
|
||||
import info.nightscout.androidaps.logging.AAPSLogger;
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
|
||||
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification;
|
||||
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
|
||||
import info.nightscout.androidaps.utils.DateUtil;
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy;
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper;
|
||||
|
||||
public class ProfileImplOld implements Profile {
|
||||
@Inject public AAPSLogger aapsLogger;
|
||||
@Inject public ActivePlugin activePlugin;
|
||||
@Inject public ResourceHelper resourceHelper;
|
||||
@Inject public RxBusWrapper rxBus;
|
||||
@Inject public FabricPrivacy fabricPrivacy;
|
||||
@Inject public Config config;
|
||||
@Inject public DateUtil dateUtil;
|
||||
|
||||
private final HasAndroidInjector injector;
|
||||
|
||||
private JSONObject json;
|
||||
private String jsonUnits;
|
||||
private double dia; // TODO change to insulinInterface link
|
||||
private TimeZone timeZone;
|
||||
private JSONArray isf;
|
||||
private LongSparseArray<Double> isf_v; // oldest at index 0
|
||||
private JSONArray ic;
|
||||
private LongSparseArray<Double> ic_v; // oldest at index 0
|
||||
private JSONArray basal;
|
||||
private LongSparseArray<Double> basal_v; // oldest at index 0
|
||||
private JSONArray targetLow;
|
||||
private LongSparseArray<Double> targetLow_v; // oldest at index 0
|
||||
private JSONArray targetHigh;
|
||||
private LongSparseArray<Double> targetHigh_v; // oldest at index 0
|
||||
|
||||
private int percentage;
|
||||
private int timeshift;
|
||||
|
||||
protected boolean isValid;
|
||||
protected boolean isValidated;
|
||||
|
||||
protected ProfileImplOld(HasAndroidInjector injector) {
|
||||
injector.androidInjector().inject(this);
|
||||
this.injector = injector;
|
||||
}
|
||||
|
||||
@NonNull @Override
|
||||
public String toString() {
|
||||
if (json != null)
|
||||
return json.toString();
|
||||
else
|
||||
return "Profile has no JSON";
|
||||
}
|
||||
|
||||
// Constructor from profileStore JSON
|
||||
public ProfileImplOld(HasAndroidInjector injector, JSONObject json, GlucoseUnit units) {
|
||||
this(injector);
|
||||
init(json, 100, 0);
|
||||
if (this.jsonUnits == null) {
|
||||
if (units != null)
|
||||
this.jsonUnits = units.getAsText();
|
||||
else {
|
||||
fabricPrivacy.logCustom("Profile failover failed too");
|
||||
this.jsonUnits = Constants.MGDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ProfileImplOld(HasAndroidInjector injector, JSONObject json, int percentage, int timeshift) {
|
||||
this(injector);
|
||||
init(json, percentage, timeshift);
|
||||
}
|
||||
|
||||
protected void init(JSONObject json, int percentage, int timeshift) {
|
||||
if (json == null) return;
|
||||
jsonUnits = null;
|
||||
dia = Constants.defaultDIA;
|
||||
timeZone = TimeZone.getDefault();
|
||||
isf_v = null;
|
||||
ic_v = null;
|
||||
basal_v = null;
|
||||
targetLow_v = null;
|
||||
targetHigh_v = null;
|
||||
|
||||
isValid = true;
|
||||
isValidated = false;
|
||||
|
||||
this.percentage = percentage;
|
||||
this.timeshift = timeshift;
|
||||
this.json = json;
|
||||
try {
|
||||
if (json.has("units"))
|
||||
jsonUnits = json.getString("units").toLowerCase();
|
||||
if (json.has("dia"))
|
||||
dia = json.getDouble("dia");
|
||||
if (json.has("timezone"))
|
||||
timeZone = TimeZone.getTimeZone(json.getString("timezone"));
|
||||
isf = json.getJSONArray("sens");
|
||||
ic = json.getJSONArray("carbratio");
|
||||
basal = json.getJSONArray("basal");
|
||||
targetLow = json.getJSONArray("target_low");
|
||||
targetHigh = json.getJSONArray("target_high");
|
||||
} catch (JSONException e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
isValid = false;
|
||||
isValidated = true;
|
||||
}
|
||||
}
|
||||
|
||||
public String log() {
|
||||
String ret = "\n";
|
||||
for (int hour = 0; hour < 24; hour++) {
|
||||
double value = getBasalTimeFromMidnight(hour * 60 * 60);
|
||||
ret += "NS basal value for " + hour + ":00 is " + value + "\n";
|
||||
}
|
||||
ret += "NS units: " + getUnits();
|
||||
return ret;
|
||||
}
|
||||
|
||||
public JSONObject getData() {
|
||||
if (!json.has("units"))
|
||||
try {
|
||||
json.put("units", jsonUnits);
|
||||
} catch (JSONException e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
public double getDia() {
|
||||
return dia;
|
||||
}
|
||||
|
||||
// mmol or mg/dl
|
||||
public void setUnits(String units) {
|
||||
this.jsonUnits = units;
|
||||
}
|
||||
|
||||
public GlucoseUnit getUnits() {
|
||||
if (jsonUnits.equals(Constants.MMOL)) return GlucoseUnit.MMOL;
|
||||
else return GlucoseUnit.MGDL;
|
||||
}
|
||||
|
||||
TimeZone getTimeZone() {
|
||||
return timeZone;
|
||||
}
|
||||
|
||||
private LongSparseArray<Double> convertToSparseArray(JSONArray array) {
|
||||
if (array == null) {
|
||||
isValid = false;
|
||||
return new LongSparseArray<>();
|
||||
}
|
||||
|
||||
double multiplier = getMultiplier(array);
|
||||
|
||||
LongSparseArray<Double> sparse = new LongSparseArray<>();
|
||||
for (int index = 0; index < array.length(); index++) {
|
||||
try {
|
||||
final JSONObject o = array.getJSONObject(index);
|
||||
long tas;
|
||||
try {
|
||||
String time = o.getString("time");
|
||||
tas = getShitfTimeSecs(dateUtil.toSeconds(time));
|
||||
} catch (JSONException e) {
|
||||
//log.debug(">>>>>>>>>>>> Used recalculated timeAsSeconds: " + time + " " + tas);
|
||||
tas = getShitfTimeSecs((int) o.getLong("timeAsSeconds"));
|
||||
}
|
||||
double value = o.getDouble("value") * multiplier;
|
||||
sparse.put(tas, value);
|
||||
} catch (Exception e) {
|
||||
aapsLogger.error("Unhandled exception", e);
|
||||
aapsLogger.error(json.toString());
|
||||
fabricPrivacy.logException(e);
|
||||
}
|
||||
}
|
||||
|
||||
// check if start is at 0 (midnight)
|
||||
// and add last value before midnight if not
|
||||
if (sparse.keyAt(0) != 0) {
|
||||
sparse.put(0, sparse.valueAt(sparse.size() - 1));
|
||||
}
|
||||
return sparse;
|
||||
}
|
||||
|
||||
public synchronized boolean isValid(String from, Pump pump, Config config, ResourceHelper resourceHelper, RxBusWrapper rxBus) {
|
||||
if (!isValid)
|
||||
return false;
|
||||
if (!isValidated) {
|
||||
if (basal_v == null)
|
||||
basal_v = convertToSparseArray(basal);
|
||||
validate(basal_v);
|
||||
if (isf_v == null)
|
||||
isf_v = convertToSparseArray(isf);
|
||||
validate(isf_v);
|
||||
if (ic_v == null)
|
||||
ic_v = convertToSparseArray(ic);
|
||||
validate(ic_v);
|
||||
if (targetLow_v == null)
|
||||
targetLow_v = convertToSparseArray(targetLow);
|
||||
validate(targetLow_v);
|
||||
if (targetHigh_v == null)
|
||||
targetHigh_v = convertToSparseArray(targetHigh);
|
||||
validate(targetHigh_v);
|
||||
|
||||
if (targetHigh_v.size() != targetLow_v.size()) isValid = false;
|
||||
else for (int i = 0; i < targetHigh_v.size(); i++)
|
||||
if (targetHigh_v.valueAt(i) < targetLow_v.valueAt(i))
|
||||
isValid = false;
|
||||
|
||||
isValidated = true;
|
||||
}
|
||||
|
||||
boolean notify = true;
|
||||
if (isValid) {
|
||||
// Check for hours alignment
|
||||
if (!pump.getPumpDescription().is30minBasalRatesCapable()) {
|
||||
for (int index = 0; index < basal_v.size(); index++) {
|
||||
long secondsFromMidnight = basal_v.keyAt(index);
|
||||
if (notify && secondsFromMidnight % 3600 != 0) {
|
||||
if (config.getAPS()) {
|
||||
Notification notification = new Notification(Notification.BASAL_PROFILE_NOT_ALIGNED_TO_HOURS, resourceHelper.gs(R.string.basalprofilenotaligned, from), Notification.NORMAL);
|
||||
rxBus.send(new EventNewNotification(notification));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check for minimal basal value
|
||||
PumpDescription description = pump.getPumpDescription();
|
||||
for (int i = 0; i < basal_v.size(); i++) {
|
||||
if (basal_v.valueAt(i) < description.getBasalMinimumRate()) {
|
||||
basal_v.setValueAt(i, description.getBasalMinimumRate());
|
||||
if (notify)
|
||||
sendBelowMinimumNotification(from);
|
||||
} else if (basal_v.valueAt(i) > description.getBasalMaximumRate()) {
|
||||
basal_v.setValueAt(i, description.getBasalMaximumRate());
|
||||
if (notify)
|
||||
sendAboveMaximumNotification(from);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return isValid;
|
||||
}
|
||||
|
||||
protected void sendBelowMinimumNotification(String from) {
|
||||
rxBus.send(new EventNewNotification(new Notification(Notification.MINIMAL_BASAL_VALUE_REPLACED, resourceHelper.gs(R.string.minimalbasalvaluereplaced, from), Notification.NORMAL)));
|
||||
}
|
||||
|
||||
protected void sendAboveMaximumNotification(String from) {
|
||||
rxBus.send(new EventNewNotification(new Notification(Notification.MAXIMUM_BASAL_VALUE_REPLACED, resourceHelper.gs(R.string.maximumbasalvaluereplaced, from), Notification.NORMAL)));
|
||||
}
|
||||
|
||||
private void validate(LongSparseArray array) {
|
||||
if (array.size() == 0) {
|
||||
isValid = false;
|
||||
return;
|
||||
}
|
||||
for (int index = 0; index < array.size(); index++) {
|
||||
if (array.valueAt(index).equals(0d)) {
|
||||
isValid = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
private Double getValueToTime(JSONArray array, Integer timeAsSeconds) {
|
||||
Double lastValue = null;
|
||||
|
||||
for (Integer index = 0; index < array.length(); index++) {
|
||||
try {
|
||||
JSONObject o = array.getJSONObject(index);
|
||||
Integer tas = o.getInt("timeAsSeconds");
|
||||
Double value = o.getDouble("value");
|
||||
if (lastValue == null) lastValue = value;
|
||||
if (timeAsSeconds < tas) {
|
||||
break;
|
||||
}
|
||||
lastValue = value;
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
}
|
||||
return lastValue;
|
||||
}
|
||||
*/
|
||||
|
||||
Integer getShitfTimeSecs(Integer originalTime) {
|
||||
int shiftedTime = originalTime + timeshift * 60 * 60;
|
||||
shiftedTime = (shiftedTime + 24 * 60 * 60) % (24 * 60 * 60);
|
||||
return shiftedTime;
|
||||
}
|
||||
|
||||
private double getMultiplier(LongSparseArray<Double> array) {
|
||||
double multiplier = 1d;
|
||||
|
||||
if (array == isf_v)
|
||||
multiplier = 100d / percentage;
|
||||
else if (array == ic_v)
|
||||
multiplier = 100d / percentage;
|
||||
else if (array == basal_v)
|
||||
multiplier = percentage / 100d;
|
||||
else
|
||||
aapsLogger.error("Unknown array type");
|
||||
return multiplier;
|
||||
}
|
||||
|
||||
private double getMultiplier(JSONArray array) {
|
||||
double multiplier = 1d;
|
||||
|
||||
if (array == isf)
|
||||
multiplier = 100d / percentage;
|
||||
else if (array == ic)
|
||||
multiplier = 100d / percentage;
|
||||
else if (array == basal)
|
||||
multiplier = percentage / 100d;
|
||||
else if (array == targetLow)
|
||||
multiplier = 1d;
|
||||
else if (array == targetHigh)
|
||||
multiplier = 1d;
|
||||
else
|
||||
aapsLogger.error("Unknown array type");
|
||||
return multiplier;
|
||||
}
|
||||
|
||||
private double getValueToTime(LongSparseArray<Double> array, Integer timeAsSeconds) {
|
||||
Double lastValue = null;
|
||||
|
||||
for (int index = 0; index < array.size(); index++) {
|
||||
long tas = array.keyAt(index);
|
||||
double value = array.valueAt(index);
|
||||
if (lastValue == null) lastValue = value;
|
||||
if (timeAsSeconds < tas) {
|
||||
break;
|
||||
}
|
||||
lastValue = value;
|
||||
}
|
||||
return lastValue;
|
||||
}
|
||||
|
||||
private String getValuesList(LongSparseArray<Double> array, LongSparseArray<Double> array2, DecimalFormat format, String units) {
|
||||
String retValue = "";
|
||||
|
||||
for (Integer index = 0; index < array.size(); index++) {
|
||||
retValue += dateUtil.format_HH_MM((int) array.keyAt(index));
|
||||
retValue += " ";
|
||||
retValue += format.format(array.valueAt(index));
|
||||
if (array2 != null) {
|
||||
retValue += " - ";
|
||||
retValue += format.format(array2.valueAt(index));
|
||||
}
|
||||
retValue += " " + units;
|
||||
if (index + 1 < array.size())
|
||||
retValue += "\n";
|
||||
}
|
||||
return retValue;
|
||||
}
|
||||
|
||||
public double getIsfMgdl() {
|
||||
return info.nightscout.androidaps.interfaces.Profile.Companion.toMgdl(getIsfTimeFromMidnight(info.nightscout.androidaps.interfaces.Profile.Companion.secondsFromMidnight()), getUnits());
|
||||
}
|
||||
|
||||
public double getIsfMgdl(long time) {
|
||||
return info.nightscout.androidaps.interfaces.Profile.Companion.toMgdl(getIsfTimeFromMidnight(info.nightscout.androidaps.interfaces.Profile.Companion.secondsFromMidnight(time)), getUnits());
|
||||
}
|
||||
|
||||
public double getIsfMgdlTimeFromMidnight(int timeAsSeconds) {
|
||||
return info.nightscout.androidaps.interfaces.Profile.Companion.toMgdl(getIsfTimeFromMidnight(timeAsSeconds), getUnits());
|
||||
}
|
||||
|
||||
public double getIsfTimeFromMidnight(int timeAsSeconds) {
|
||||
if (isf_v == null)
|
||||
isf_v = convertToSparseArray(isf);
|
||||
return getValueToTime(isf_v, timeAsSeconds);
|
||||
}
|
||||
|
||||
public String getIsfList(ResourceHelper resourceHelper, DateUtil dateUtil) {
|
||||
if (isf_v == null)
|
||||
isf_v = convertToSparseArray(isf);
|
||||
return getValuesList(isf_v, null, new DecimalFormat("0.0"), getUnits().getAsText() + resourceHelper.gs(R.string.profile_per_unit));
|
||||
}
|
||||
|
||||
public ProfileValue[] getIsfsMgdlValues() {
|
||||
if (isf_v == null)
|
||||
isf_v = convertToSparseArray(ic);
|
||||
ProfileValue[] ret = new ProfileValue[isf_v.size()];
|
||||
|
||||
for (int index = 0; index < isf_v.size(); index++) {
|
||||
int tas = (int) isf_v.keyAt(index);
|
||||
double value = isf_v.valueAt(index);
|
||||
ret[index] = new ProfileValue(tas, info.nightscout.androidaps.interfaces.Profile.Companion.toMgdl(value, getUnits()));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public double getIc() {
|
||||
return getIcTimeFromMidnight(info.nightscout.androidaps.interfaces.Profile.Companion.secondsFromMidnight());
|
||||
}
|
||||
|
||||
public double getIc(long time) {
|
||||
return getIcTimeFromMidnight(info.nightscout.androidaps.interfaces.Profile.Companion.secondsFromMidnight(time));
|
||||
}
|
||||
|
||||
public double getIcTimeFromMidnight(int timeAsSeconds) {
|
||||
if (ic_v == null)
|
||||
ic_v = convertToSparseArray(ic);
|
||||
return getValueToTime(ic_v, timeAsSeconds);
|
||||
}
|
||||
|
||||
public String getIcList(ResourceHelper resourceHelper, DateUtil dateUtil) {
|
||||
if (ic_v == null)
|
||||
ic_v = convertToSparseArray(ic);
|
||||
return getValuesList(ic_v, null, new DecimalFormat("0.0"), resourceHelper.gs(R.string.profile_carbs_per_unit));
|
||||
}
|
||||
|
||||
public ProfileValue[] getIcsValues() {
|
||||
if (ic_v == null)
|
||||
ic_v = convertToSparseArray(ic);
|
||||
ProfileValue[] ret = new ProfileValue[ic_v.size()];
|
||||
|
||||
for (int index = 0; index < ic_v.size(); index++) {
|
||||
int tas = (int) ic_v.keyAt(index);
|
||||
double value = ic_v.valueAt(index);
|
||||
ret[index] = new ProfileValue(tas, value);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public double getBasal() {
|
||||
return getBasalTimeFromMidnight(info.nightscout.androidaps.interfaces.Profile.Companion.secondsFromMidnight());
|
||||
}
|
||||
|
||||
public double getBasal(long time) {
|
||||
return getBasalTimeFromMidnight(info.nightscout.androidaps.interfaces.Profile.Companion.secondsFromMidnight(time));
|
||||
}
|
||||
|
||||
public synchronized double getBasalTimeFromMidnight(int timeAsSeconds) {
|
||||
if (basal_v == null) {
|
||||
basal_v = convertToSparseArray(basal);
|
||||
}
|
||||
return getValueToTime(basal_v, timeAsSeconds);
|
||||
}
|
||||
|
||||
public String getBasalList(ResourceHelper resourceHelper, DateUtil dateUtil) {
|
||||
if (basal_v == null)
|
||||
basal_v = convertToSparseArray(basal);
|
||||
return getValuesList(basal_v, null, new DecimalFormat("0.00"), resourceHelper.gs(R.string.profile_ins_units_per_hour));
|
||||
}
|
||||
|
||||
@NonNull @Override public JSONObject toPureNsJson(DateUtil dateUtil) {
|
||||
return getData();
|
||||
}
|
||||
|
||||
public synchronized ProfileValue[] getBasalValues() {
|
||||
if (basal_v == null)
|
||||
basal_v = convertToSparseArray(basal);
|
||||
ProfileValue[] ret = new ProfileValue[basal_v.size()];
|
||||
|
||||
for (int index = 0; index < basal_v.size(); index++) {
|
||||
int tas = (int) basal_v.keyAt(index);
|
||||
double value = basal_v.valueAt(index);
|
||||
ret[index] = new ProfileValue(tas, value);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public double getTargetMgdl() {
|
||||
return getTargetMgdl(info.nightscout.androidaps.interfaces.Profile.Companion.secondsFromMidnight());
|
||||
}
|
||||
|
||||
public double getTargetMgdl(int timeAsSeconds) {
|
||||
return info.nightscout.androidaps.interfaces.Profile.Companion.toMgdl((getTargetLowTimeFromMidnight(timeAsSeconds) + getTargetHighTimeFromMidnight(timeAsSeconds)) / 2, getUnits());
|
||||
}
|
||||
|
||||
public double getTargetLowMgdl() {
|
||||
return info.nightscout.androidaps.interfaces.Profile.Companion.toMgdl(getTargetLowTimeFromMidnight(info.nightscout.androidaps.interfaces.Profile.Companion.secondsFromMidnight()), getUnits());
|
||||
}
|
||||
|
||||
public double getTargetLowMgdl(long time) {
|
||||
return info.nightscout.androidaps.interfaces.Profile.Companion.toMgdl(getTargetLowTimeFromMidnight(info.nightscout.androidaps.interfaces.Profile.Companion.secondsFromMidnight(time)), getUnits());
|
||||
}
|
||||
|
||||
double getTargetLowTimeFromMidnight(int timeAsSeconds) {
|
||||
if (targetLow_v == null)
|
||||
targetLow_v = convertToSparseArray(targetLow);
|
||||
return getValueToTime(targetLow_v, timeAsSeconds);
|
||||
}
|
||||
|
||||
public double getTargetLowMgdlTimeFromMidnight(int timeAsSeconds) {
|
||||
return info.nightscout.androidaps.interfaces.Profile.Companion.toMgdl(getTargetLowTimeFromMidnight(timeAsSeconds), getUnits());
|
||||
}
|
||||
|
||||
public double getTargetHighMgdl() {
|
||||
return info.nightscout.androidaps.interfaces.Profile.Companion.toMgdl(getTargetHighTimeFromMidnight(info.nightscout.androidaps.interfaces.Profile.Companion.secondsFromMidnight()), getUnits());
|
||||
}
|
||||
|
||||
public double getTargetHighMgdl(long time) {
|
||||
return info.nightscout.androidaps.interfaces.Profile.Companion.toMgdl(getTargetHighTimeFromMidnight(info.nightscout.androidaps.interfaces.Profile.Companion.secondsFromMidnight(time)), getUnits());
|
||||
}
|
||||
|
||||
public double getTargetHighTimeFromMidnight(int timeAsSeconds) {
|
||||
if (targetHigh_v == null)
|
||||
targetHigh_v = convertToSparseArray(targetHigh);
|
||||
return getValueToTime(targetHigh_v, timeAsSeconds);
|
||||
}
|
||||
|
||||
public double getTargetHighMgdlTimeFromMidnight(int timeAsSeconds) {
|
||||
return info.nightscout.androidaps.interfaces.Profile.Companion.toMgdl(getTargetHighTimeFromMidnight(timeAsSeconds), getUnits());
|
||||
}
|
||||
|
||||
public static class TargetValue {
|
||||
TargetValue(int timeAsSeconds, double low, double high) {
|
||||
this.timeAsSeconds = timeAsSeconds;
|
||||
this.low = low;
|
||||
this.high = high;
|
||||
}
|
||||
|
||||
public int timeAsSeconds;
|
||||
public double low;
|
||||
public double high;
|
||||
}
|
||||
|
||||
public TargetValue[] getTargets() {
|
||||
if (targetLow_v == null)
|
||||
targetLow_v = convertToSparseArray(targetLow);
|
||||
if (targetHigh_v == null)
|
||||
targetHigh_v = convertToSparseArray(targetHigh);
|
||||
TargetValue[] ret = new TargetValue[targetLow_v.size()];
|
||||
|
||||
for (int index = 0; index < targetLow_v.size(); index++) {
|
||||
int tas = (int) targetLow_v.keyAt(index);
|
||||
double low = targetLow_v.valueAt(index);
|
||||
double high = targetHigh_v.valueAt(index);
|
||||
ret[index] = new TargetValue(tas, low, high);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public ProfileValue[] getSingleTargetsMgdl() {
|
||||
if (targetLow_v == null)
|
||||
targetLow_v = convertToSparseArray(targetLow);
|
||||
if (targetHigh_v == null)
|
||||
targetHigh_v = convertToSparseArray(targetHigh);
|
||||
ProfileValue[] ret = new ProfileValue[targetLow_v.size()];
|
||||
|
||||
for (int index = 0; index < targetLow_v.size(); index++) {
|
||||
int tas = (int) targetLow_v.keyAt(index);
|
||||
double target = (targetLow_v.valueAt(index) + targetHigh_v.valueAt(index)) / 2;
|
||||
ret[index] = new ProfileValue(tas, info.nightscout.androidaps.interfaces.Profile.Companion.toMgdl(target, getUnits()));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@NonNull public String getTargetList(ResourceHelper resourceHelper, DateUtil dateUtil) {
|
||||
if (targetLow_v == null)
|
||||
targetLow_v = convertToSparseArray(targetLow);
|
||||
if (targetHigh_v == null)
|
||||
targetHigh_v = convertToSparseArray(targetHigh);
|
||||
return getValuesList(targetLow_v, targetHigh_v, new DecimalFormat("0.0"), getUnits().getAsText());
|
||||
}
|
||||
|
||||
public double getMaxDailyBasal() {
|
||||
double max = 0d;
|
||||
for (int hour = 0; hour < 24; hour++) {
|
||||
double value = getBasalTimeFromMidnight(hour * 60 * 60);
|
||||
if (value > max) max = value;
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
public double percentageBasalSum() {
|
||||
double result = 0d;
|
||||
for (int i = 0; i < 24; i++) {
|
||||
result += getBasalTimeFromMidnight(i * 60 * 60);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public double baseBasalSum() {
|
||||
double result = 0d;
|
||||
for (int i = 0; i < 24; i++) {
|
||||
result += getBasalTimeFromMidnight(i * 60 * 60) / getMultiplier(basal_v);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public int getPercentage() {
|
||||
return percentage;
|
||||
}
|
||||
|
||||
public int getTimeshift() {
|
||||
return timeshift;
|
||||
}
|
||||
|
||||
public PureProfile convertToNonCustomizedProfile(DateUtil dateUtil) {
|
||||
JSONObject o = new JSONObject();
|
||||
try {
|
||||
o.put("units", jsonUnits);
|
||||
o.put("dia", dia);
|
||||
o.put("timezone", timeZone.getID());
|
||||
// SENS
|
||||
JSONArray sens = new JSONArray();
|
||||
double lastValue = -1d;
|
||||
for (int i = 0; i < 24; i++) {
|
||||
int timeAsSeconds = i * 60 * 60;
|
||||
double value = getIsfTimeFromMidnight(timeAsSeconds);
|
||||
if (value != lastValue) {
|
||||
JSONObject item = new JSONObject();
|
||||
String time;
|
||||
DecimalFormat df = new DecimalFormat("00");
|
||||
time = df.format(i) + ":00";
|
||||
item.put("time", time);
|
||||
item.put("timeAsSeconds", timeAsSeconds);
|
||||
item.put("value", value);
|
||||
lastValue = value;
|
||||
sens.put(item);
|
||||
}
|
||||
}
|
||||
o.put("sens", sens);
|
||||
// CARBRATIO
|
||||
JSONArray carbratio = new JSONArray();
|
||||
lastValue = -1d;
|
||||
for (int i = 0; i < 24; i++) {
|
||||
int timeAsSeconds = i * 60 * 60;
|
||||
double value = getIcTimeFromMidnight(timeAsSeconds);
|
||||
if (value != lastValue) {
|
||||
JSONObject item = new JSONObject();
|
||||
String time;
|
||||
DecimalFormat df = new DecimalFormat("00");
|
||||
time = df.format(i) + ":00";
|
||||
item.put("time", time);
|
||||
item.put("timeAsSeconds", timeAsSeconds);
|
||||
item.put("value", value);
|
||||
lastValue = value;
|
||||
carbratio.put(item);
|
||||
}
|
||||
}
|
||||
o.put("carbratio", carbratio);
|
||||
// BASAL
|
||||
JSONArray basal = new JSONArray();
|
||||
lastValue = -1d;
|
||||
for (int i = 0; i < 24; i++) {
|
||||
int timeAsSeconds = i * 60 * 60;
|
||||
double value = getBasalTimeFromMidnight(timeAsSeconds);
|
||||
if (value != lastValue) {
|
||||
JSONObject item = new JSONObject();
|
||||
String time;
|
||||
DecimalFormat df = new DecimalFormat("00");
|
||||
time = df.format(i) + ":00";
|
||||
item.put("time", time);
|
||||
item.put("timeAsSeconds", timeAsSeconds);
|
||||
item.put("value", value);
|
||||
lastValue = value;
|
||||
basal.put(item);
|
||||
}
|
||||
}
|
||||
o.put("basal", basal);
|
||||
// TARGET_LOW
|
||||
JSONArray target_low = new JSONArray();
|
||||
lastValue = -1d;
|
||||
for (int i = 0; i < 24; i++) {
|
||||
int timeAsSeconds = i * 60 * 60;
|
||||
double value = getTargetLowTimeFromMidnight(timeAsSeconds);
|
||||
if (value != lastValue) {
|
||||
JSONObject item = new JSONObject();
|
||||
String time;
|
||||
DecimalFormat df = new DecimalFormat("00");
|
||||
time = df.format(i) + ":00";
|
||||
item.put("time", time);
|
||||
item.put("timeAsSeconds", timeAsSeconds);
|
||||
item.put("value", value);
|
||||
lastValue = value;
|
||||
target_low.put(item);
|
||||
}
|
||||
}
|
||||
o.put("target_low", target_low);
|
||||
// TARGET_HIGH
|
||||
JSONArray target_high = new JSONArray();
|
||||
lastValue = -1d;
|
||||
for (int i = 0; i < 24; i++) {
|
||||
int timeAsSeconds = i * 60 * 60;
|
||||
double value = getTargetHighTimeFromMidnight(timeAsSeconds);
|
||||
if (value != lastValue) {
|
||||
JSONObject item = new JSONObject();
|
||||
String time;
|
||||
DecimalFormat df = new DecimalFormat("00");
|
||||
time = df.format(i) + ":00";
|
||||
item.put("time", time);
|
||||
item.put("timeAsSeconds", timeAsSeconds);
|
||||
item.put("value", value);
|
||||
lastValue = value;
|
||||
target_high.put(item);
|
||||
}
|
||||
}
|
||||
o.put("target_high", target_high);
|
||||
|
||||
} catch (JSONException e) {
|
||||
aapsLogger.error("Unhandled exception" + e);
|
||||
}
|
||||
return pureProfileFromJson(o, dateUtil);
|
||||
}
|
||||
}
|
|
@ -2,7 +2,6 @@ package info.nightscout.androidaps.di
|
|||
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import info.nightscout.androidaps.data.ProfileImplOld
|
||||
import info.nightscout.androidaps.data.PumpEnactResult
|
||||
import info.nightscout.androidaps.interfaces.ProfileStore
|
||||
import info.nightscout.androidaps.plugins.aps.loop.APSResult
|
||||
|
@ -16,6 +15,5 @@ abstract class CoreDataClassesModule {
|
|||
@ContributesAndroidInjector abstract fun apsResultInjector(): APSResult
|
||||
@ContributesAndroidInjector abstract fun autosensDataInjector(): AutosensData
|
||||
|
||||
@ContributesAndroidInjector abstract fun profileInjector(): ProfileImplOld
|
||||
@ContributesAndroidInjector abstract fun profileStoreInjector(): ProfileStore
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import info.nightscout.androidaps.database.data.TargetBlock
|
|||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.T
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
|
||||
private fun getShiftedTimeSecs(originalSeconds: Int, timeShiftHours: Int): Int {
|
||||
|
@ -86,33 +85,18 @@ fun blockFromJsonArray(jsonArray: JSONArray?, dateUtil: DateUtil): List<Block>?
|
|||
val ret = ArrayList<Block>(size)
|
||||
try {
|
||||
for (index in 0 until jsonArray.length() - 1) {
|
||||
val o: JSONObject = jsonArray.getJSONObject(index)
|
||||
val tas: Int = try {
|
||||
o.getInt("timeAsSeconds")
|
||||
} catch (e: JSONException) {
|
||||
val time = o.getString("time")
|
||||
dateUtil.toSeconds(time)
|
||||
}
|
||||
val next: JSONObject = jsonArray.getJSONObject(index + 1)
|
||||
val nextTas: Int = try {
|
||||
next.getInt("timeAsSeconds")
|
||||
} catch (e: JSONException) {
|
||||
val time = next.getString("time")
|
||||
dateUtil.toSeconds(time)
|
||||
}
|
||||
val value: Double = o.getDouble("value")
|
||||
val o = jsonArray.getJSONObject(index)
|
||||
val tas = dateUtil.toSeconds(o.getString("time"))
|
||||
val next = jsonArray.getJSONObject(index + 1)
|
||||
val nextTas = dateUtil.toSeconds(next.getString("time"))
|
||||
val value = o.getDouble("value")
|
||||
if (tas % 3600 != 0) return null
|
||||
if (nextTas % 3600 != 0) return null
|
||||
ret.add(index, Block((nextTas - tas) * 1000L, value))
|
||||
}
|
||||
val last: JSONObject = jsonArray.getJSONObject(jsonArray.length() - 1)
|
||||
val lastTas: Int = try {
|
||||
last.getInt("timeAsSeconds")
|
||||
} catch (e: JSONException) {
|
||||
val time = last.getString("time")
|
||||
dateUtil.toSeconds(time)
|
||||
}
|
||||
val value: Double = last.getDouble("value")
|
||||
val lastTas = dateUtil.toSeconds(last.getString("time"))
|
||||
val value = last.getDouble("value")
|
||||
ret.add(jsonArray.length() - 1, Block((T.hours(24).secs() - lastTas) * 1000L, value))
|
||||
} catch (e: Exception) {
|
||||
return null
|
||||
|
@ -128,41 +112,23 @@ fun targetBlockFromJsonArray(jsonArray1: JSONArray?, jsonArray2: JSONArray?, dat
|
|||
try {
|
||||
for (index in 0 until jsonArray1.length() - 1) {
|
||||
val o1: JSONObject = jsonArray1.getJSONObject(index)
|
||||
val tas1: Int = try {
|
||||
o1.getInt("timeAsSeconds")
|
||||
} catch (e: JSONException) {
|
||||
val time = o1.getString("time")
|
||||
dateUtil.toSeconds(time)
|
||||
}
|
||||
val value1: Double = o1.getDouble("value")
|
||||
val next1: JSONObject = jsonArray1.getJSONObject(index + 1)
|
||||
val nextTas1: Int = try {
|
||||
next1.getInt("timeAsSeconds")
|
||||
} catch (e: JSONException) {
|
||||
val time = next1.getString("time")
|
||||
dateUtil.toSeconds(time)
|
||||
}
|
||||
val o2: JSONObject = jsonArray2.getJSONObject(index)
|
||||
val tas2: Int = try {
|
||||
o2.getInt("timeAsSeconds")
|
||||
} catch (e: JSONException) {
|
||||
val time = o2.getString("time")
|
||||
dateUtil.toSeconds(time)
|
||||
}
|
||||
val value2: Double = o2.getDouble("value")
|
||||
val tas1 = dateUtil.toSeconds(o1.getString("time"))
|
||||
val value1 = o1.getDouble("value")
|
||||
val next1 = jsonArray1.getJSONObject(index + 1)
|
||||
val nextTas1 = dateUtil.toSeconds(next1.getString("time"))
|
||||
val o2 = jsonArray2.getJSONObject(index)
|
||||
val tas2 = dateUtil.toSeconds(o2.getString("time"))
|
||||
val value2 = o2.getDouble("value")
|
||||
if (tas1 != tas2) return null
|
||||
if (tas1 % 3600 != 0) return null
|
||||
if (nextTas1 % 3600 != 0) return null
|
||||
ret.add(index, TargetBlock((nextTas1 - tas1) * 1000L, value1, value2))
|
||||
}
|
||||
val last1: JSONObject = jsonArray1.getJSONObject(jsonArray1.length() - 1)
|
||||
val lastTas1: Int = try {
|
||||
last1.getInt("timeAsSeconds")
|
||||
} catch (e: JSONException) {
|
||||
val time = last1.getString("time")
|
||||
dateUtil.toSeconds(time)
|
||||
}
|
||||
val value1: Double = last1.getDouble("value")
|
||||
val last2: JSONObject = jsonArray2.getJSONObject(jsonArray2.length() - 1)
|
||||
val value2: Double = last2.getDouble("value")
|
||||
val last1 = jsonArray1.getJSONObject(jsonArray1.length() - 1)
|
||||
val lastTas1 = dateUtil.toSeconds(last1.getString("time"))
|
||||
val value1 = last1.getDouble("value")
|
||||
val last2 = jsonArray2.getJSONObject(jsonArray2.length() - 1)
|
||||
val value2 = last2.getDouble("value")
|
||||
ret.add(jsonArray1.length() - 1, TargetBlock((T.hours(24).secs() - lastTas1) * 1000L, value1, value2))
|
||||
} catch (e: Exception) {
|
||||
return null
|
||||
|
|
|
@ -94,9 +94,9 @@ fun profileSwitchFromJson(jsonObject: JSONObject, dateUtil: DateUtil, activePlug
|
|||
/**
|
||||
* Pure profile doesn't contain timestamp, percentage, timeshift, profileName
|
||||
*/
|
||||
fun pureProfileFromJson(jsonObject: JSONObject, dateUtil: DateUtil): PureProfile? {
|
||||
fun pureProfileFromJson(jsonObject: JSONObject, dateUtil: DateUtil, defaultUnits: String? = null): PureProfile? {
|
||||
try {
|
||||
JsonHelper.safeGetStringAllowNull(jsonObject, "units", null) ?: return null
|
||||
JsonHelper.safeGetStringAllowNull(jsonObject, "units", defaultUnits) ?: return null
|
||||
val units = GlucoseUnit.fromText(JsonHelper.safeGetString(jsonObject, "units", Constants.MGDL))
|
||||
val dia = JsonHelper.safeGetDoubleAllowNull(jsonObject, "dia") ?: return null
|
||||
val timezone = TimeZone.getTimeZone(JsonHelper.safeGetString(jsonObject, "timezone", "UTC"))
|
||||
|
|
|
@ -18,6 +18,8 @@ interface DataSyncSelector {
|
|||
data class PairProfileSwitch(val value: ProfileSwitch, val updateRecordId: Long)
|
||||
data class PairProfileStore(val value: JSONObject, val timestampSync: Long)
|
||||
|
||||
fun doUpload()
|
||||
|
||||
fun resetToNextFullSync()
|
||||
|
||||
fun confirmLastBolusIdIfGreater(lastSynced: Long)
|
||||
|
|
|
@ -52,12 +52,13 @@ class ProfileStore(val injector: HasAndroidInjector, val data: JSONObject, val d
|
|||
|
||||
fun getSpecificProfile(profileName: String): PureProfile? {
|
||||
var profile: PureProfile? = null
|
||||
val defaultUnits = JsonHelper.safeGetStringAllowNull(data, "units", null)
|
||||
getStore()?.let { store ->
|
||||
if (store.has(profileName)) {
|
||||
profile = cachedObjects[profileName]
|
||||
if (profile == null) {
|
||||
JsonHelper.safeGetJSONObject(store, profileName, null)?.let { profileObject ->
|
||||
profile = pureProfileFromJson(profileObject, dateUtil)
|
||||
profile = pureProfileFromJson(profileObject, dateUtil, defaultUnits)
|
||||
cachedObjects[profileName] = profile
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
<string name="key_high_mark" translatable="false">high_mark</string>
|
||||
<string name="key_ns_create_announcements_from_errors" translatable="false">ns_create_announcements_from_errors</string>
|
||||
<string name="key_ns_logappstartedevent" translatable="false">ns_logappstartedevent</string>
|
||||
<string name="key_ns_uploadlocalprofile" translatable="false">ns_uploadlocalprofile</string>
|
||||
<string name="key_btwatchdog" translatable="false">bt_watchdog</string>
|
||||
<string name="key_btwatchdog_lastbark" translatable="false">bt_watchdog_last</string>
|
||||
<string name="key_pump_unreachable_threshold_minutes" translatable="false">pump_unreachable_threshold</string>
|
||||
|
|
Loading…
Reference in a new issue