Rv2,RKorean

This commit is contained in:
Milos Kozak 2021-04-10 10:41:53 +02:00
parent 4a51b276f9
commit 194cf305fd
14 changed files with 144 additions and 7 deletions

View file

@ -29,7 +29,8 @@ class ConfigBuilderPlugin @Inject constructor(
private val sp: SP,
private val rxBus: RxBusWrapper,
private val activePlugin: ActivePluginProvider,
private val uel: UserEntryLogger
private val uel: UserEntryLogger,
private val pumpSync: PumpSync
) : PluginBase(PluginDescription()
.mainType(PluginType.GENERAL)
.fragmentClass(ConfigBuilderFragment::class.java.name)
@ -140,13 +141,15 @@ class ConfigBuilderPlugin @Inject constructor(
val allowHardwarePump = sp.getBoolean("allow_hardware_pump", false)
if (allowHardwarePump || activity == null) {
performPluginSwitch(changedPlugin, newState, type)
pumpSync.connectNewPump()
} else {
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.allow_hardware_pump_text), Runnable {
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.allow_hardware_pump_text), {
performPluginSwitch(changedPlugin, newState, type)
pumpSync.connectNewPump()
sp.putBoolean("allow_hardware_pump", true)
uel.log(Action.HW_PUMP_ALLOWED, Sources.ConfigBuilder)
aapsLogger.debug(LTag.PUMP, "First time HW pump allowed!")
}, Runnable {
}, {
rxBus.send(EventConfigBuilderUpdateGui())
aapsLogger.debug(LTag.PUMP, "User does not allow switching to HW pump!")
})

View file

@ -15,6 +15,7 @@ import info.nightscout.androidaps.events.EventNewBG
import info.nightscout.androidaps.interfaces.DataSyncSelector
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
import info.nightscout.androidaps.interfaces.ImportExportPrefsInterface
import info.nightscout.androidaps.interfaces.PumpSync
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
@ -39,6 +40,7 @@ class MaintenanceFragment : DaggerFragment() {
@Inject lateinit var databaseHelper: DatabaseHelperInterface
@Inject lateinit var uel: UserEntryLogger
@Inject lateinit var dataSyncSelector: DataSyncSelector
@Inject lateinit var pumpSync: PumpSync
private val compositeDisposable = CompositeDisposable()
@ -68,6 +70,7 @@ class MaintenanceFragment : DaggerFragment() {
databaseHelper.resetDatabases()
repository.clearDatabases()
dataSyncSelector.resetToNextFullSync()
pumpSync.connectNewPump()
}
.subscribeOn(aapsSchedulers.io)
.observeOn(aapsSchedulers.main)

View file

@ -67,6 +67,7 @@ fun ExtendedBolus.toRealJson(): JSONObject =
.put("splitExt", 100)
.put("enteredinsulin", amount)
.put("relative", rate)
.put("isValid", isValid)
.put("isEmulatingTempBasal", isEmulatingTempBasal)
.also {
if (interfaceIDs.pumpId != null) it.put("pumpId", interfaceIDs.pumpId)

View file

@ -16,10 +16,10 @@ abstract class PumpPluginBase(
override fun onStart() {
super.onStart()
if (getType() == PluginType.PUMP) {
Thread(Runnable {
Thread {
SystemClock.sleep(3000)
commandQueue.readStatus("Pump driver changed.", null)
}).start()
}.start()
}
}
}

View file

@ -23,6 +23,14 @@ import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
*/
interface PumpSync {
/**
* Reset stored identification of last used pump
*
* Call this function when new pump is paired to accept data from new pump
* to prevent overlapping pump histories
*/
fun connectNewPump()
/*
* GENERAL STATUS
*/

View file

@ -122,6 +122,7 @@ open class Notification {
const val OMNIPOD_STARTUP_STATUS_REFRESH_FAILED = 69
const val OMNIPOD_TIME_OUT_OF_SYNC = 70
const val UNSUPPORTED_ACTION_IN_PUMP = 71
const val WRONG_PUMP_DATA = 71
const val USER_MESSAGE = 1000

View file

@ -1,5 +1,6 @@
package info.nightscout.androidaps.plugins.pump
import info.nightscout.androidaps.core.R
import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.ValueWrapper
@ -14,8 +15,14 @@ import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.interfaces.PumpSync
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.overview.events.EventNewNotification
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.plusAssign
import javax.inject.Inject
@ -23,12 +30,54 @@ import javax.inject.Inject
class PumpSyncImplementation @Inject constructor(
private val aapsLogger: AAPSLogger,
private val dateUtil: DateUtil,
private val sp: SP,
private val rxBus: RxBusWrapper,
private val resourceHelper: ResourceHelper,
private val profileFunction: ProfileFunction,
private val repository: AppRepository
) : PumpSync {
private val disposable = CompositeDisposable()
override fun connectNewPump() {
sp.remove(R.string.key_active_pump_type)
sp.remove(R.string.key_active_pump_serial_number)
sp.remove(R.string.key_active_pump_change_timestamp)
}
/**
* Check if data is coming from currently active pump to prevent overlapping pump histories
*
* @param timestamp timestamp of data coming from pump
* @param type timestamp of of pump
* @param serialNumber serial number of of pump
* @return true if data is allowed
*/
private fun confirmActivePump(timestamp: Long, type: PumpType, serialNumber: String) : Boolean {
val storedType = sp.getString(R.string.key_active_pump_type, "")
val storedSerial = sp.getString(R.string.key_active_pump_serial_number, "")
val storedTimestamp = sp.getLong(R.string.key_active_pump_change_timestamp, 0L)
// If no value stored assume we start using new pump from now
if (storedType.isEmpty() || storedSerial.isEmpty()) {
aapsLogger.debug(LTag.PUMP, "Registering new pump ${type.description} $serialNumber")
sp.putString(R.string.key_active_pump_type, type.description)
sp.putString(R.string.key_active_pump_serial_number, serialNumber)
sp.putLong(R.string.key_active_pump_change_timestamp, dateUtil._now()) // allow only data newer than register time (ie. ignore older history)
return timestamp > dateUtil._now() - T.mins(1).msecs() // allow first record to be 1 min old
}
if (type.description == storedType && serialNumber == storedSerial && timestamp >= storedTimestamp) {
// data match
return true
}
if (type.description != storedType || serialNumber != storedSerial)
rxBus.send(EventNewNotification(Notification(Notification.WRONG_PUMP_DATA, resourceHelper.gs(R.string.wrong_pump_data), Notification.URGENT)))
aapsLogger.error(LTag.PUMP, "Ignoring pump history record $timestamp ${type.description} $serialNumber. Registered pump: $storedType $storedSerial")
return false
}
override fun expectedPumpState(): PumpSync.PumpState {
val bolus = repository.getLastBolusRecord()
val temporaryBasal = repository.getTemporaryBasalActiveAt(dateUtil._now()).blockingGet()
@ -68,6 +117,7 @@ class PumpSyncImplementation @Inject constructor(
}
override fun addBolusWithTempId(timestamp: Long, amount: Double, temporaryId: Long, type: DetailedBolusInfo.BolusType, pumpType: PumpType, pumpSerial: String): Boolean {
if (!confirmActivePump(timestamp, pumpType, pumpSerial)) return false
val bolus = Bolus(
timestamp = timestamp,
amount = amount,
@ -88,6 +138,7 @@ class PumpSyncImplementation @Inject constructor(
}
override fun syncBolusWithTempId(timestamp: Long, amount: Double, temporaryId: Long, type: DetailedBolusInfo.BolusType?, pumpId: Long?, pumpType: PumpType, pumpSerial: String): Boolean {
if (!confirmActivePump(timestamp, pumpType, pumpSerial)) return false
val bolus = Bolus(
timestamp = timestamp,
amount = amount,
@ -109,6 +160,7 @@ class PumpSyncImplementation @Inject constructor(
}
override fun syncBolusWithPumpId(timestamp: Long, amount: Double, type: DetailedBolusInfo.BolusType?, pumpId: Long, pumpType: PumpType, pumpSerial: String): Boolean {
if (!confirmActivePump(timestamp, pumpType, pumpSerial)) return false
val bolus = Bolus(
timestamp = timestamp,
amount = amount,
@ -130,6 +182,7 @@ class PumpSyncImplementation @Inject constructor(
}
override fun syncCarbsWithTimestamp(timestamp: Long, amount: Double, pumpId: Long?, pumpType: PumpType, pumpSerial: String): Boolean {
if (!confirmActivePump(timestamp, pumpType, pumpSerial)) return false
val carbs = Carbs(
timestamp = timestamp,
amount = amount,
@ -149,6 +202,7 @@ class PumpSyncImplementation @Inject constructor(
}
override fun insertTherapyEventIfNewWithTimestamp(timestamp: Long, type: DetailedBolusInfo.EventType, note: String?, pumpId: Long?, pumpType: PumpType, pumpSerial: String): Boolean {
if (!confirmActivePump(timestamp, pumpType, pumpSerial)) return false
val therapyEvent = TherapyEvent(
timestamp = timestamp,
type = type.toDBbEventType(),
@ -175,6 +229,7 @@ class PumpSyncImplementation @Inject constructor(
}
override fun insertAnnouncement(error: String, pumpId: Long?, pumpType: PumpType, pumpSerial: String) {
if (!confirmActivePump(dateUtil._now(), pumpType, pumpSerial)) return
disposable += repository.runTransaction(InsertTherapyEventAnnouncementTransaction(error, pumpId, pumpType.toDbPumpType(), pumpSerial))
.subscribe()
}
@ -184,6 +239,7 @@ class PumpSyncImplementation @Inject constructor(
*/
override fun syncTemporaryBasalWithPumpId(timestamp: Long, rate: Double, duration: Long, isAbsolute: Boolean, type: PumpSync.TemporaryBasalType?, pumpId: Long, pumpType: PumpType, pumpSerial: String): Boolean {
if (!confirmActivePump(timestamp, pumpType, pumpSerial)) return false
val temporaryBasal = TemporaryBasal(
timestamp = timestamp,
rate = rate,
@ -207,6 +263,7 @@ class PumpSyncImplementation @Inject constructor(
}
override fun syncStopTemporaryBasalWithPumpId(timestamp: Long, endPumpId: Long, pumpType: PumpType, pumpSerial: String): Boolean {
if (!confirmActivePump(timestamp, pumpType, pumpSerial)) return false
repository.runTransactionForResult(SyncPumpCancelTemporaryBasalIfAnyTransaction(timestamp, endPumpId, pumpType.toDbPumpType(), pumpSerial))
.doOnError { aapsLogger.error(LTag.DATABASE, "Error while saving temporary basal", it) }
.blockingGet()
@ -231,6 +288,7 @@ class PumpSyncImplementation @Inject constructor(
}
override fun syncExtendedBolusWithPumpId(timestamp: Long, amount: Double, duration: Long, isEmulatingTB: Boolean, pumpId: Long, pumpType: PumpType, pumpSerial: String): Boolean {
if (!confirmActivePump(timestamp, pumpType, pumpSerial)) return false
val extendedBolus = ExtendedBolus(
timestamp = timestamp,
amount = amount,
@ -253,6 +311,7 @@ class PumpSyncImplementation @Inject constructor(
}
override fun syncStopExtendedBolusWithPumpId(timestamp: Long, endPumpId: Long, pumpType: PumpType, pumpSerial: String): Boolean {
if (!confirmActivePump(timestamp, pumpType, pumpSerial)) return false
repository.runTransactionForResult(SyncPumpCancelExtendedBolusIfAnyTransaction(timestamp, endPumpId, pumpType.toDbPumpType(), pumpSerial))
.doOnError { aapsLogger.error(LTag.DATABASE, "Error while saving extended bolus", it) }
.blockingGet()

View file

@ -55,6 +55,9 @@
<string name="key_insight_local_settings" translatable="false">insight_local_settings</string>
<string name="key_data_choices_settings" translatable="false">data_choices_settings</string>
<string name="key_dexcom_settings" translatable="false">dexcom_settings</string>
<string name="key_active_pump_change_timestamp" translatable="false">active_pump_change_timestamp</string>
<string name="key_active_pump_type" translatable="false">active_pump_type</string>
<string name="key_active_pump_serial_number" translatable="false">active_pump_serial_number</string>
<!-- General-->
<string name="refresh">Refresh</string>
@ -160,6 +163,7 @@
<string name="notes_label">Notes</string>
<string name="remove_button">Remove</string>
<string name="addnew">Add new</string>
<string name="wrong_pump_data">Data is coming from different pump. Change pump driver to reset pump state.</string>
<!-- Constraints-->
<string name="limitingbasalratio">Limiting max basal rate to %1$.2f U/h because of %2$s</string>

View file

@ -29,6 +29,7 @@ class MsgInitConnStatusTime_k(
danaRPlugin.setPluginEnabled(PluginType.PUMP, true)
danaRPlugin.setFragmentVisible(PluginType.PUMP, true)
danaPump.reset() // mark not initialized
pumpSync.connectNewPump()
//If profile coming from pump, switch it as well
configBuilder.storeSettings("ChangingKoreanDanaDriver")
rxBus.send(EventRebuildTabs())

View file

@ -19,6 +19,7 @@ import info.nightscout.androidaps.danar.R;
import info.nightscout.androidaps.data.DetailedBolusInfo;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.ExtendedBolus;
import info.nightscout.androidaps.events.EventAppExit;
import info.nightscout.androidaps.interfaces.ActivePluginProvider;
import info.nightscout.androidaps.interfaces.CommandQueueProvider;
@ -344,6 +345,58 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin {
return result;
}
@NonNull @Override
public PumpEnactResult setExtendedBolus(double insulin, int durationInMinutes) {
DanaPump pump = danaPump;
insulin = constraintChecker.applyExtendedBolusConstraints(new Constraint<>(insulin)).value();
// needs to be rounded
int durationInHalfHours = Math.max(durationInMinutes / 30, 1);
insulin = Round.roundTo(insulin, getPumpDescription().getExtendedBolusStep());
PumpEnactResult result = new PumpEnactResult(getInjector());
if (danaPump.isExtendedInProgress() && Math.abs(danaPump.getExtendedBolusAmount() - insulin) < pumpDescription.getExtendedBolusStep()) {
result.enacted(false)
.success(true)
.comment(R.string.ok)
.duration(pump.getExtendedBolusRemainingMinutes())
.absolute(pump.getExtendedBolusAbsoluteRate())
.isPercent(false)
.isTempCancel(false);
getAapsLogger().debug(LTag.PUMP, "setExtendedBolus: Correct extended bolus already set. Current: " + pump.getExtendedBolusAmount() + " Asked: " + insulin);
return result;
}
boolean connectionOK = sExecutionService.extendedBolus(insulin, durationInHalfHours);
if (connectionOK && pump.isExtendedInProgress() && Math.abs(pump.getExtendedBolusAmount() - insulin) < getPumpDescription().getExtendedBolusStep()) {
result.enacted(true)
.success(true)
.comment(R.string.ok)
.isTempCancel(false)
.duration(pump.getExtendedBolusRemainingMinutes())
.absolute(pump.getExtendedBolusAbsoluteRate())
.isPercent(false);
if (!sp.getBoolean("danar_useextended", false))
result.bolusDelivered(pump.getExtendedBolusAmount());
getAapsLogger().debug(LTag.PUMP, "setExtendedBolus: OK");
return result;
}
result.enacted(false).success(false).comment(R.string.danar_valuenotsetproperly);
getAapsLogger().error("setExtendedBolus: Failed to extended bolus");
return result;
}
@NonNull @Override
public PumpEnactResult cancelExtendedBolus() {
PumpEnactResult result = new PumpEnactResult(getInjector());
if (danaPump.isExtendedInProgress()) {
sExecutionService.extendedBolusStop();
result.enacted(true).success(!danaPump.isExtendedInProgress()).isTempCancel(true);
} else {
result.success(true).enacted(false).comment(R.string.ok);
getAapsLogger().debug(LTag.PUMP, "cancelExtendedBolus: OK");
}
return result;
}
@NonNull @Override
public PumpType model() {
return PumpType.DANA_RV2;

View file

@ -27,7 +27,6 @@ class MsgCheckValue_v2(
danaPump.protocol = intFromBuff(bytes, 1, 1)
danaPump.productCode = intFromBuff(bytes, 2, 1)
if (danaPump.hwModel != DanaPump.EXPORT_MODEL) {
danaPump.reset()
val notification = Notification(Notification.WRONG_DRIVER, resourceHelper.gs(R.string.pumpdrivercorrected), Notification.NORMAL)
rxBus.send(EventNewNotification(notification))
danaRPlugin.disconnect("Wrong Model")
@ -37,6 +36,7 @@ class MsgCheckValue_v2(
danaRPlugin.setPluginEnabled(PluginType.PUMP, false)
danaRPlugin.setFragmentVisible(PluginType.PUMP, false)
danaPump.reset() // mark not initialized
pumpSync.connectNewPump()
//If profile coming from pump, switch it as well
configBuilder.storeSettings("ChangingDanaRv2Driver")
rxBus.send(EventRebuildTabs())
@ -44,7 +44,6 @@ class MsgCheckValue_v2(
return
}
if (danaPump.protocol != 2) {
danaPump.reset()
val notification = Notification(Notification.WRONG_DRIVER, resourceHelper.gs(R.string.pumpdrivercorrected), Notification.NORMAL)
rxBus.send(EventNewNotification(notification))
danaRKoreanPlugin.disconnect("Wrong Model")
@ -53,6 +52,8 @@ class MsgCheckValue_v2(
danaRv2Plugin.setFragmentVisible(PluginType.PUMP, false)
danaRPlugin.setPluginEnabled(PluginType.PUMP, true)
danaRPlugin.setFragmentVisible(PluginType.PUMP, true)
danaPump.reset() // mark not initialized
pumpSync.connectNewPump()
//If profile coming from pump, switch it as well
configBuilder.storeSettings("ChangingDanaRv2Driver")
rxBus.send(EventRebuildTabs())

View file

@ -112,6 +112,7 @@ public abstract class AbstractDanaRPlugin extends PumpPluginBase implements Pump
.subscribe(event -> {
if (event.isChanged(getResourceHelper(), R.string.key_danar_bt_name)) {
danaPump.reset();
pumpSync.connectNewPump();
getCommandQueue().readStatus("DeviceChanged", null);
}
})

View file

@ -28,6 +28,7 @@ class MsgInitConnStatusTime(
danaRPlugin.setPluginEnabled(PluginType.PUMP, false)
danaRPlugin.setFragmentVisible(PluginType.PUMP, false)
danaPump.reset() // mark not initialized
pumpSync.connectNewPump()
//If profile coming from pump, switch it as well
configBuilder.storeSettings("ChangingDanaDriver")
rxBus.send(EventRebuildTabs())

View file

@ -134,6 +134,7 @@ class DanaRSPlugin @Inject constructor(
mDeviceAddress = sp.getString(R.string.key_danars_address, "")
mDeviceName = sp.getString(R.string.key_danars_name, "")
danaPump.reset()
pumpSync.connectNewPump()
commandQueue.readStatus("DeviceChanged", null)
}