ProfileSwitch improvements, resolve initial PS

This commit is contained in:
Milos Kozak 2021-05-03 18:19:10 +02:00
parent 5d55bdadf4
commit e8ecf43894
7 changed files with 40 additions and 21 deletions

View file

@ -14,6 +14,7 @@ import info.nightscout.androidaps.database.entities.UserEntry.Sources
import info.nightscout.androidaps.database.entities.ValueWithUnit import info.nightscout.androidaps.database.entities.ValueWithUnit
import info.nightscout.androidaps.database.transactions.* import info.nightscout.androidaps.database.transactions.*
import info.nightscout.androidaps.extensions.* import info.nightscout.androidaps.extensions.*
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag import info.nightscout.androidaps.logging.LTag
@ -43,6 +44,7 @@ class NSClientAddUpdateWorker(
@Inject lateinit var dateUtil: DateUtil @Inject lateinit var dateUtil: DateUtil
@Inject lateinit var config: Config @Inject lateinit var config: Config
@Inject lateinit var repository: AppRepository @Inject lateinit var repository: AppRepository
@Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var rxBus: RxBusWrapper @Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var uel: UserEntryLogger @Inject lateinit var uel: UserEntryLogger
@ -304,7 +306,7 @@ class NSClientAddUpdateWorker(
} }
} ?: aapsLogger.error("Error parsing TemporaryBasal json $json") } ?: aapsLogger.error("Error parsing TemporaryBasal json $json")
eventType == TherapyEvent.Type.PROFILE_SWITCH.text -> eventType == TherapyEvent.Type.PROFILE_SWITCH.text ->
profileSwitchFromJson(json, dateUtil)?.let { profileSwitch -> profileSwitchFromJson(json, dateUtil, activePlugin)?.let { profileSwitch ->
repository.runTransactionForResult(SyncNsProfileSwitchTransaction(profileSwitch, invalidateByNsOnly = false)) repository.runTransactionForResult(SyncNsProfileSwitchTransaction(profileSwitch, invalidateByNsOnly = false))
.doOnError { .doOnError {
aapsLogger.error(LTag.DATABASE, "Error while saving ProfileSwitch", it) aapsLogger.error(LTag.DATABASE, "Error while saving ProfileSwitch", it)
@ -326,7 +328,7 @@ class NSClientAddUpdateWorker(
aapsLogger.debug(LTag.DATABASE, "Updated nsId ProfileSwitch $it") aapsLogger.debug(LTag.DATABASE, "Updated nsId ProfileSwitch $it")
} }
} }
} ?: aapsLogger.error("Error parsing TemporaryBasal json $json") } ?: aapsLogger.error("Error parsing ProfileSwitch json $json")
} }
if (eventType == TherapyEvent.Type.ANNOUNCEMENT.text) { if (eventType == TherapyEvent.Type.ANNOUNCEMENT.text) {
val date = safeGetLong(json, "mills") val date = safeGetLong(json, "mills")

View file

@ -296,8 +296,7 @@ class NSClientService : DaggerService() {
synchronized(reconnections) { synchronized(reconnections) {
val now = dateUtil.now() val now = dateUtil.now()
reconnections.add(now) reconnections.add(now)
for (i in reconnections.indices) { for (r in reconnections.reversed()) {
val r = reconnections[i]
if (r < now - mins(WATCHDOG_INTERVAL_MINUTES.toLong()).msecs()) { if (r < now - mins(WATCHDOG_INTERVAL_MINUTES.toLong()).msecs()) {
reconnections.remove(r) reconnections.remove(r)
} }

View file

@ -61,7 +61,7 @@ class MDIPlugin @Inject constructor(
override fun waitForDisconnectionInSeconds(): Int = 0 override fun waitForDisconnectionInSeconds(): Int = 0
override fun stopConnecting() {} override fun stopConnecting() {}
override fun getPumpStatus(reason: String) {} override fun getPumpStatus(reason: String) {}
override fun setNewBasalProfile(profile: Profile): PumpEnactResult = PumpEnactResult(injector).success(true) override fun setNewBasalProfile(profile: Profile): PumpEnactResult = PumpEnactResult(injector).success(true).enacted(true)
override fun isThisProfileSet(profile: Profile): Boolean = false override fun isThisProfileSet(profile: Profile): Boolean = false
override fun lastDataTime(): Long = System.currentTimeMillis() override fun lastDataTime(): Long = System.currentTimeMillis()
override val baseBasalRate: Double = 0.0 override val baseBasalRate: Double = 0.0

View file

@ -4,12 +4,12 @@ import android.os.SystemClock
import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceFragmentCompat
import androidx.preference.SwitchPreference import androidx.preference.SwitchPreference
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.DetailedBolusInfo import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.data.PumpEnactResult import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.events.EventPreferenceChange import info.nightscout.androidaps.events.EventPreferenceChange
import info.nightscout.androidaps.extensions.convertedToAbsolute
import info.nightscout.androidaps.extensions.plannedRemainingMinutes
import info.nightscout.androidaps.interfaces.* import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag import info.nightscout.androidaps.logging.LTag
@ -25,8 +25,6 @@ import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.InstanceId.instanceId import info.nightscout.androidaps.utils.InstanceId.instanceId
import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.TimeChangeType import info.nightscout.androidaps.utils.TimeChangeType
import info.nightscout.androidaps.extensions.convertedToAbsolute
import info.nightscout.androidaps.extensions.plannedRemainingMinutes
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.androidaps.utils.sharedPreferences.SP import info.nightscout.androidaps.utils.sharedPreferences.SP
@ -151,12 +149,9 @@ open class VirtualPumpPlugin @Inject constructor(
override fun setNewBasalProfile(profile: Profile): PumpEnactResult { override fun setNewBasalProfile(profile: Profile): PumpEnactResult {
lastDataTime = System.currentTimeMillis() lastDataTime = System.currentTimeMillis()
rxBus.send(EventNewNotification(Notification(Notification.PROFILE_SET_OK, resourceHelper.gs(R.string.profile_set_ok), Notification.INFO, 60)))
// Do nothing here. we are using database profile // Do nothing here. we are using database profile
val result = PumpEnactResult(injector) return PumpEnactResult(injector).success(true).enacted(true)
result.success = true
val notification = Notification(Notification.PROFILE_SET_OK, resourceHelper.gs(R.string.profile_set_ok), Notification.INFO, 60)
rxBus.send(EventNewNotification(notification))
return result
} }
override fun isThisProfileSet(profile: Profile): Boolean { override fun isThisProfileSet(profile: Profile): Boolean {

View file

@ -6,6 +6,7 @@ import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.database.ValueWrapper import info.nightscout.androidaps.database.ValueWrapper
import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.CommandQueueProvider import info.nightscout.androidaps.interfaces.CommandQueueProvider
import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.interfaces.PluginType import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.interfaces.Profile import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.logging.LTag import info.nightscout.androidaps.logging.LTag
@ -25,9 +26,10 @@ class CommandSetProfile constructor(
@Inject lateinit var activePlugin: ActivePlugin @Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var dateUtil: DateUtil @Inject lateinit var dateUtil: DateUtil
@Inject lateinit var commandQueue: CommandQueueProvider @Inject lateinit var commandQueue: CommandQueueProvider
@Inject lateinit var config: Config
override fun execute() { override fun execute() {
if (commandQueue.isThisProfileSet(profile)) { if (commandQueue.isThisProfileSet(profile) && repository.getEffectiveProfileSwitchActiveAt(dateUtil.now()).blockingGet() is ValueWrapper.Existing) {
aapsLogger.debug(LTag.PUMPQUEUE, "Correct profile already set. profile: $profile") aapsLogger.debug(LTag.PUMPQUEUE, "Correct profile already set. profile: $profile")
callback?.result(PumpEnactResult(injector).success(true).enacted(false))?.run() callback?.result(PumpEnactResult(injector).success(true).enacted(false))?.run()
return return
@ -37,7 +39,7 @@ class CommandSetProfile constructor(
callback?.result(r)?.run() callback?.result(r)?.run()
// Send SMS notification if ProfileSwitch is coming from NS // Send SMS notification if ProfileSwitch is coming from NS
val profileSwitch = repository.getEffectiveProfileSwitchActiveAt(dateUtil.now()).blockingGet() val profileSwitch = repository.getEffectiveProfileSwitchActiveAt(dateUtil.now()).blockingGet()
if (profileSwitch is ValueWrapper.Existing && r.enacted && hasNsId) { if (profileSwitch is ValueWrapper.Existing && r.enacted && hasNsId && !config.NSCLIENT) {
if (smsCommunicatorPlugin.isEnabled(PluginType.GENERAL)) if (smsCommunicatorPlugin.isEnabled(PluginType.GENERAL))
smsCommunicatorPlugin.sendNotificationToAllNumbers(resourceHelper.gs(R.string.profile_set_ok)) smsCommunicatorPlugin.sendNotificationToAllNumbers(resourceHelper.gs(R.string.profile_set_ok))
} }

View file

@ -129,7 +129,8 @@ class KeepAliveReceiver : DaggerBroadcastReceiver() {
if (lastReadStatus != 0L && lastReadStatus > System.currentTimeMillis() - T.mins(5).msecs()) { if (lastReadStatus != 0L && lastReadStatus > System.currentTimeMillis() - T.mins(5).msecs()) {
localAlertUtils.checkPumpUnreachableAlarm(lastConnection, isStatusOutdated, loopPlugin.isDisconnected) localAlertUtils.checkPumpUnreachableAlarm(lastConnection, isStatusOutdated, loopPlugin.isDisconnected)
} }
if (!pump.isThisProfileSet(profile) && !commandQueue.isRunning(Command.CommandType.BASAL_PROFILE)) { if (!pump.isThisProfileSet(profile) && !commandQueue.isRunning(Command.CommandType.BASAL_PROFILE)
|| profileFunction.getProfile() == null) {
rxBus.send(EventProfileSwitchChanged()) rxBus.send(EventProfileSwitchChanged())
} else if (isStatusOutdated && !pump.isBusy()) { } else if (isStatusOutdated && !pump.isBusy()) {
lastReadStatus = System.currentTimeMillis() lastReadStatus = System.currentTimeMillis()

View file

@ -7,6 +7,7 @@ import info.nightscout.androidaps.database.embedments.InterfaceIDs
import info.nightscout.androidaps.database.entities.ProfileSwitch import info.nightscout.androidaps.database.entities.ProfileSwitch
import info.nightscout.androidaps.database.entities.TemporaryBasal import info.nightscout.androidaps.database.entities.TemporaryBasal
import info.nightscout.androidaps.database.entities.TherapyEvent import info.nightscout.androidaps.database.entities.TherapyEvent
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.GlucoseUnit import info.nightscout.androidaps.interfaces.GlucoseUnit
import info.nightscout.androidaps.interfaces.Profile import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
@ -23,7 +24,7 @@ fun ProfileSwitch.toJson(dateUtil: DateUtil): JSONObject =
.put("eventType", TherapyEvent.Type.PROFILE_SWITCH.text) .put("eventType", TherapyEvent.Type.PROFILE_SWITCH.text)
.put("duration", T.msecs(duration).mins()) .put("duration", T.msecs(duration).mins())
.put("profile", getCustomizedName()) .put("profile", getCustomizedName())
.put("profileJson", ProfileSealed.PS(this).toPureNsJson(dateUtil)) .put("profileJson", ProfileSealed.PS(this).toPureNsJson(dateUtil).toString())
.put("timeshift", T.msecs(timeshift).hours()) .put("timeshift", T.msecs(timeshift).hours())
.put("percentage", percentage) .put("percentage", percentage)
.also { .also {
@ -33,7 +34,20 @@ fun ProfileSwitch.toJson(dateUtil: DateUtil): JSONObject =
if (interfaceIDs.nightscoutId != null) it.put("_id", interfaceIDs.nightscoutId) if (interfaceIDs.nightscoutId != null) it.put("_id", interfaceIDs.nightscoutId)
} }
fun profileSwitchFromJson(jsonObject: JSONObject, dateUtil: DateUtil): ProfileSwitch? { /* NS PS
{
"_id":"608ffa268db0676196a772d7",
"enteredBy":"undefined",
"eventType":"Profile Switch",
"duration":10,
"profile":"LocalProfile0",
"created_at":"2021-05-03T13:26:58.537Z",
"utcOffset":0,
"mills":1620048418537,
"mgdl":98
}
*/
fun profileSwitchFromJson(jsonObject: JSONObject, dateUtil: DateUtil, activePlugin: ActivePlugin): ProfileSwitch? {
val timestamp = JsonHelper.safeGetLongAllowNull(jsonObject, "mills", null) ?: return null val timestamp = JsonHelper.safeGetLongAllowNull(jsonObject, "mills", null) ?: return null
val duration = JsonHelper.safeGetLong(jsonObject, "duration") val duration = JsonHelper.safeGetLong(jsonObject, "duration")
val timeshift = JsonHelper.safeGetLong(jsonObject, "timeshift") val timeshift = JsonHelper.safeGetLong(jsonObject, "timeshift")
@ -41,15 +55,21 @@ fun profileSwitchFromJson(jsonObject: JSONObject, dateUtil: DateUtil): ProfileSw
val isValid = JsonHelper.safeGetBoolean(jsonObject, "isValid", true) val isValid = JsonHelper.safeGetBoolean(jsonObject, "isValid", true)
val id = JsonHelper.safeGetStringAllowNull(jsonObject, "_id", null) val id = JsonHelper.safeGetStringAllowNull(jsonObject, "_id", null)
val profileName = JsonHelper.safeGetStringAllowNull(jsonObject, "profile", null) ?: return null val profileName = JsonHelper.safeGetStringAllowNull(jsonObject, "profile", null) ?: return null
val profileJson = JsonHelper.safeGetStringAllowNull(jsonObject, "profileJson", null) ?: return null val profileJson = JsonHelper.safeGetStringAllowNull(jsonObject, "profileJson", null)
val pumpId = JsonHelper.safeGetLongAllowNull(jsonObject, "pumpId", null) val pumpId = JsonHelper.safeGetLongAllowNull(jsonObject, "pumpId", null)
val pumpType = InterfaceIDs.PumpType.fromString(JsonHelper.safeGetStringAllowNull(jsonObject, "pumpType", null)) val pumpType = InterfaceIDs.PumpType.fromString(JsonHelper.safeGetStringAllowNull(jsonObject, "pumpType", null))
val pumpSerial = JsonHelper.safeGetStringAllowNull(jsonObject, "pumpSerial", null) val pumpSerial = JsonHelper.safeGetStringAllowNull(jsonObject, "pumpSerial", null)
if (timestamp == 0L) return null if (timestamp == 0L) return null
val pureProfile = pureProfileFromJson(JSONObject(profileJson), dateUtil) ?: return null val pureProfile =
if (profileJson == null) { // entered through NS, no JSON attached
val profilePlugin = activePlugin.activeProfileSource
val store = profilePlugin.profile ?: return null
store.getSpecificProfile(profileName) ?: return null
} else pureProfileFromJson(JSONObject(profileJson), dateUtil) ?: return null
val profileSealed = ProfileSealed.Pure(pureProfile) val profileSealed = ProfileSealed.Pure(pureProfile)
return ProfileSwitch( return ProfileSwitch(
timestamp = timestamp, timestamp = timestamp,
basalBlocks = profileSealed.basalBlocks, basalBlocks = profileSealed.basalBlocks,