Decrease I/O load and number of events during command exchange; remove queue status from Omnipod tab and switch reservoir & units delivered; small bug fixes

This commit is contained in:
Bart Sopers 2020-08-24 23:30:26 +02:00
parent c84798e368
commit ae4b25af89
10 changed files with 158 additions and 166 deletions

View file

@ -76,6 +76,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.mess
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager;
import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodPodStateActionsAllowedChanged;
import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodPumpValuesChanged;
import info.nightscout.androidaps.plugins.pump.omnipod.manager.AapsOmnipodManager;
import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.RileyLinkOmnipodService;
import info.nightscout.androidaps.plugins.pump.omnipod.ui.OmnipodFragment;
@ -429,10 +430,10 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface,
}
break;
case AcknowledgeAlerts:
executeCommand(OmnipodCommandType.GetPodPulseLog, aapsOmnipodManager::acknowledgeAlerts);
executeCommand(OmnipodCommandType.AcknowledgeAlerts, aapsOmnipodManager::acknowledgeAlerts);
break;
case GetPodState:
executeCommand(OmnipodCommandType.GetPodPulseLog, aapsOmnipodManager::getPodStatus);
executeCommand(OmnipodCommandType.GetPodStatus, aapsOmnipodManager::getPodStatus);
break;
default:
aapsLogger.error(LTag.PUMP, "Unknown status request: " + statusRequest.name());
@ -882,6 +883,8 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface,
// TODO maybe only do this for specific commands
rxBus.send(new EventRefreshOverview("Omnipod command: " + commandType.name(), false));
rxBus.send(new EventOmnipodPumpValuesChanged());
return pumpEnactResult;
}

View file

@ -46,7 +46,6 @@ public abstract class PodStateManager {
public final void removeState() {
this.podState = null;
storePodState();
notifyPodStateChanged();
}
public final void initState(int address) {
@ -55,7 +54,6 @@ public abstract class PodStateManager {
}
podState = new PodState(address);
storePodState();
notifyPodStateChanged();
}
/**
@ -98,9 +96,6 @@ public abstract class PodStateManager {
}
public final void setInitializationParameters(int lot, int tid, FirmwareVersion piVersion, FirmwareVersion pmVersion, DateTimeZone timeZone, PodProgressStatus podProgressStatus) {
if (!hasPodState()) {
throw new IllegalStateException("Cannot set pairing parameters: podState is null");
}
if (isPodInitialized() && getPodProgressStatus().isAfter(PodProgressStatus.REMINDER_INITIALIZED)) {
throw new IllegalStateException("Cannot set pairing parameters: pairing parameters have already been set");
}
@ -137,26 +132,34 @@ public abstract class PodStateManager {
return getSafe(() -> podState.getMessageNumber());
}
/**
* Does not automatically store pod state in order to decrease I/O load
*/
public final void setMessageNumber(int messageNumber) {
setAndStore(() -> podState.setMessageNumber(messageNumber), false);
setSafe(() -> podState.setMessageNumber(messageNumber));
}
public final int getPacketNumber() {
return getSafe(() -> podState.getPacketNumber());
}
public final void setPacketNumber(int packetNumber) {
setAndStore(() -> podState.setPacketNumber(packetNumber), false);
}
/**
* Does not automatically store pod state in order to decrease I/O load
*/
public final void increaseMessageNumber() {
setAndStore(() -> podState.setMessageNumber((podState.getMessageNumber() + 1) & 0b1111), false);
setSafe(() -> podState.setMessageNumber((podState.getMessageNumber() + 1) & 0b1111));
}
/**
* Does not automatically store pod state in order to decrease I/O load
*/
public final void increasePacketNumber() {
setAndStore(() -> podState.setPacketNumber((podState.getPacketNumber() + 1) & 0b11111), false);
setSafe(() -> podState.setPacketNumber((podState.getPacketNumber() + 1) & 0b11111));
}
/**
* Does not automatically store pod state in order to decrease I/O load
*/
public final synchronized void resyncNonce(int syncWord, int sentNonce, int sequenceNumber) {
if (!isPodInitialized()) {
throw new IllegalStateException("Cannot resync nonce: Pod is not paired yet");
@ -169,7 +172,7 @@ public abstract class PodStateManager {
int seed = ((sum & 0xFFFF) ^ syncWord);
NonceState nonceState = new NonceState(podState.getLot(), podState.getTid(), (byte) (seed & 0xFF));
setAndStore(() -> podState.setNonceState(nonceState), false);
setSafe(() -> podState.setNonceState(nonceState));
}
public final synchronized int getCurrentNonce() {
@ -179,27 +182,36 @@ public abstract class PodStateManager {
return podState.getNonceState().getCurrentNonce();
}
/**
* Does not automatically store pod state in order to decrease I/O load
*/
public final synchronized void advanceToNextNonce() {
if (!isPodInitialized()) {
throw new IllegalStateException("Cannot advance to next nonce: Pod is not paired yet");
}
setAndStore(() -> podState.getNonceState().advanceToNextNonce(), false);
setSafe(() -> podState.getNonceState().advanceToNextNonce());
}
public final DateTime getLastSuccessfulCommunication() {
return getSafe(() -> podState.getLastSuccessfulCommunication());
}
public final void setLastSuccessfulCommunication(DateTime dateTime, boolean notifyPodStateChanged) {
setAndStore(() -> podState.setLastSuccessfulCommunication(dateTime), notifyPodStateChanged);
/**
* Does not automatically store pod state in order to decrease I/O load
*/
public final void setLastSuccessfulCommunication(DateTime dateTime) {
setSafe(() -> podState.setLastSuccessfulCommunication(dateTime));
}
public final DateTime getLastFailedCommunication() {
return getSafe(() -> podState.getLastFailedCommunication());
}
/**
* Does not automatically store pod state in order to decrease I/O load
*/
public final void setLastFailedCommunication(DateTime dateTime) {
setAndStore(() -> podState.setLastFailedCommunication(dateTime));
setSafe(() -> podState.setLastFailedCommunication(dateTime));
}
public final DateTime getLastUpdatedFromStatusResponse() {
@ -359,11 +371,11 @@ public abstract class PodStateManager {
return getSafe(() -> podState.getLastDeliveryStatus());
}
/**
* Does not automatically store pod state in order to decrease I/O load
*/
public final void updateFromStatusResponse(StatusResponse statusResponse) {
if (!hasPodState()) {
throw new IllegalStateException("Cannot update from status response: podState is null");
}
setAndStore(() -> {
setSafe(() -> {
if (podState.getActivatedAt() == null) {
DateTime activatedAtCalculated = getTime().minus(statusResponse.getTimeActive());
podState.setActivatedAt(activatedAtCalculated);
@ -385,23 +397,21 @@ public abstract class PodStateManager {
}
private void setAndStore(Runnable runnable) {
setAndStore(runnable, true);
setSafe(runnable);
storePodState();
}
private void setAndStore(Runnable runnable, boolean notifyPodStateChanged) {
// Not actually "safe" as it throws an Exception, but it prevents NPEs
private void setSafe(Runnable runnable) {
if (!hasPodState()) {
throw new IllegalStateException("Cannot mutate PodState: podState is null");
}
runnable.run();
storePodState();
if (notifyPodStateChanged) {
notifyPodStateChanged();
}
}
private void storePodState() {
public void storePodState() {
String podState = gsonInstance.toJson(this.podState);
aapsLogger.info(LTag.PUMP, "storePodState: storing podState: " + podState);
aapsLogger.debug(LTag.PUMP, "storePodState: storing podState: {}", podState);
storePodState(podState);
}
@ -425,12 +435,8 @@ public abstract class PodStateManager {
aapsLogger.error(LTag.PUMP, "loadPodState: could not deserialize PodState: " + storedPodState, ex);
}
}
notifyPodStateChanged();
}
protected abstract void notifyPodStateChanged();
// Not actually "safe" as it throws an Exception, but it prevents NPEs
private <T> T getSafe(Supplier<T> supplier) {
if (!hasPodState()) {

View file

@ -69,6 +69,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.PodRetur
import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.OmnipodManager;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.SetupActionResult;
import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodPumpValuesChanged;
import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.OmnipodRileyLinkCommunicationManager;
import info.nightscout.androidaps.plugins.pump.omnipod.util.AapsOmnipodUtil;
import info.nightscout.androidaps.utils.resources.ResourceHelper;
@ -317,6 +318,11 @@ public class AapsOmnipodManager {
aapsLogger.error(LTag.PUMP, "Failed to store active bolus to SP", ex);
}
// Bolus is already updated in Pod state. If this was an SMB, it could be that
// the user is looking at the Pod tab right now, so send an extra event
// (this is normally done in OmnipodPumpPlugin)
sendEvent(new EventOmnipodPumpValuesChanged());
// Wait for the bolus to finish
OmnipodManager.BolusDeliveryResult bolusDeliveryResult =
bolusCommandResult.getDeliveryResultSubject().blockingGet();

View file

@ -3,23 +3,17 @@ package info.nightscout.androidaps.plugins.pump.omnipod.manager;
import javax.inject.Inject;
import javax.inject.Singleton;
import info.nightscout.androidaps.events.Event;
import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
import info.nightscout.androidaps.plugins.pump.omnipod.definition.OmnipodStorageKeys;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager;
import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodPumpValuesChanged;
import info.nightscout.androidaps.utils.sharedPreferences.SP;
@Singleton
public class AapsPodStateManager extends PodStateManager {
private final AAPSLogger aapsLogger;
private final SP sp;
private final RxBusWrapper rxBus;
@Inject
public AapsPodStateManager(AAPSLogger aapsLogger, SP sp, RxBusWrapper rxBus) {
public AapsPodStateManager(AAPSLogger aapsLogger, SP sp) {
super(aapsLogger);
if (aapsLogger == null) {
@ -28,13 +22,8 @@ public class AapsPodStateManager extends PodStateManager {
if (sp == null) {
throw new IllegalArgumentException("sp can not be null");
}
if (rxBus == null) {
throw new IllegalArgumentException("rxBus can not be null");
}
this.aapsLogger = aapsLogger;
this.sp = sp;
this.rxBus = rxBus;
}
@Override
@ -46,15 +35,4 @@ public class AapsPodStateManager extends PodStateManager {
protected void storePodState(String podState) {
sp.putString(OmnipodStorageKeys.Prefs.PodState, podState);
}
@Override
protected void notifyPodStateChanged() {
aapsLogger.debug(LTag.PUMP, "Pod State changed. Sending events.");
sendEvent(new EventOmnipodPumpValuesChanged());
}
private void sendEvent(Event event) {
rxBus.send(event);
}
}

View file

@ -105,10 +105,10 @@ public class OmnipodRileyLinkCommunicationManager extends RileyLinkCommunication
}
public synchronized <T extends MessageBlock> T exchangeMessages(Class<T> responseClass, PodStateManager podStateManager, OmnipodMessage message, Integer addressOverride, Integer ackAddressOverride, boolean automaticallyResyncNonce) {
aapsLogger.debug(LTag.PUMPCOMM, "Exchanging OmnipodMessage [responseClass={}, podStateManager={}, message={}, addressOverride={}, ackAddressOverride={}, automaticallyResyncNonce={}]: {}", //
aapsLogger.debug(LTag.PUMPCOMM, "Exchanging OmnipodMessage: responseClass={}, podStateManager={}, message={}, addressOverride={}, ackAddressOverride={}, automaticallyResyncNonce={}", //
responseClass.getSimpleName(), podStateManager, message, addressOverride, ackAddressOverride, automaticallyResyncNonce);
try {
for (int i = 0; 2 > i; i++) {
if (podStateManager.isPodInitialized() && message.isNonceResyncable()) {
@ -125,18 +125,12 @@ public class OmnipodRileyLinkCommunicationManager extends RileyLinkCommunication
aapsLogger.debug(LTag.PUMPCOMM, "Received response from the Pod [responseMessageBlock={}]", responseMessageBlock);
boolean isExpectedResponseType = responseClass.isInstance(responseMessageBlock);
// Set last successful communication before updating from status response to prevent duplicately notifying Pod state changes
// as podStateManager.updateFromStatusResponse() also notifies of Pod state changes.
if (isExpectedResponseType) {
podStateManager.setLastSuccessfulCommunication(DateTime.now(), !(responseMessageBlock instanceof StatusResponse));
}
if (responseMessageBlock instanceof StatusResponse) {
podStateManager.updateFromStatusResponse((StatusResponse) responseMessageBlock);
}
if (isExpectedResponseType) {
if (responseClass.isInstance(responseMessageBlock)) {
podStateManager.setLastSuccessfulCommunication(DateTime.now());
return (T) responseMessageBlock;
} else {
if (responseMessageBlock.getType() == MessageBlockType.ERROR_RESPONSE) {
@ -169,6 +163,9 @@ public class OmnipodRileyLinkCommunicationManager extends RileyLinkCommunication
podStateManager.setLastFailedCommunication(DateTime.now());
throw new NonceResyncException();
} finally {
podStateManager.storePodState();
}
}
private MessageBlock transportMessages(PodStateManager podStateManager, OmnipodMessage message, Integer addressOverride, Integer ackAddressOverride) {

View file

@ -243,8 +243,10 @@ class OmnipodFragment : DaggerFragment() {
omnipod_lastbolus.text = "-"
}
val now = DateTime.now()
// base basal rate
omnipod_base_basal_rate.text = resourceHelper.gs(R.string.pump_basebasalrate, omnipodPumpPlugin.model().determineCorrectBasalSize(omnipodPumpPlugin.baseBasalRate))
omnipod_base_basal_rate.text = resourceHelper.gs(R.string.pump_basebasalrate, omnipodPumpPlugin.model().determineCorrectBasalSize(podStateManager.basalSchedule.rateAt(Duration(now.withTimeAtStartOfDay(), now))))
omnipod_tempbasal.text = activePlugin.activeTreatments
.getTempBasalFromHistory(System.currentTimeMillis())?.toStringFull() ?: "-"
@ -265,7 +267,7 @@ class OmnipodFragment : DaggerFragment() {
warnColors.setColorInverse(omnipod_reservoir, podStateManager.reservoirLevel, 50.0, 20.0)
}
omnipod_pod_active_alerts.text = TextUtils.join(System.lineSeparator(), aapsOmnipodUtil.getTranslatedActiveAlerts(podStateManager))
omnipod_pod_active_alerts.text = if (podStateManager.hasActiveAlerts()) TextUtils.join(System.lineSeparator(), aapsOmnipodUtil.getTranslatedActiveAlerts(podStateManager)) else "-"
}
if (errors.size == 0) {
@ -275,14 +277,6 @@ class OmnipodFragment : DaggerFragment() {
omnipod_errors.text = StringUtils.join(errors, System.lineSeparator())
omnipod_errors.setTextColor(Color.RED)
}
val status = commandQueue.spannedStatus()
if (status.toString() == "") {
omnipod_queue.visibility = View.GONE
} else {
omnipod_queue.visibility = View.VISIBLE
omnipod_queue.text = status
}
}
private fun updateLastConnection() {

View file

@ -18,6 +18,7 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.Riley
import info.nightscout.androidaps.plugins.pump.omnipod.R
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus
import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager
import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodPumpValuesChanged
import info.nightscout.androidaps.plugins.pump.omnipod.manager.AapsOmnipodManager
import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.defs.PodActionType
import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.model.FullInitPodWizardModel
@ -76,6 +77,10 @@ class PodManagementActivity : NoSplashAppCompatActivity() {
.toObservable(EventRileyLinkDeviceStatusChange::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ refreshButtons() }, { fabricPrivacy.logException(it) })
disposables += rxBus
.toObservable(EventOmnipodPumpValuesChanged::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ refreshButtons() }, { fabricPrivacy.logException(it) })
refreshButtons()
}
@ -142,7 +147,7 @@ class PodManagementActivity : NoSplashAppCompatActivity() {
OKDialog.showConfirmation(this,
resourceHelper.gs(R.string.omnipod_cmd_reset_pod_desc), Thread {
aapsOmnipodManager.resetPodStatus()
refreshButtons()
rxBus.send(EventOmnipodPumpValuesChanged())
})
}

View file

@ -7,7 +7,9 @@ import javax.inject.Inject;
import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.interfaces.ProfileFunction;
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
import info.nightscout.androidaps.plugins.pump.omnipod.definition.PodInitActionType;
import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodPumpValuesChanged;
import info.nightscout.androidaps.plugins.pump.omnipod.manager.AapsOmnipodManager;
/**
@ -17,6 +19,7 @@ public class InitPodTask extends AsyncTask<Void, Void, String> {
@Inject ProfileFunction profileFunction;
@Inject AapsOmnipodManager aapsOmnipodManager;
@Inject RxBusWrapper rxBus;
private InitActionFragment initActionFragment;
public InitPodTask(HasAndroidInjector injector, InitActionFragment initActionFragment) {
@ -49,6 +52,8 @@ public class InitPodTask extends AsyncTask<Void, Void, String> {
initActionFragment.callResult = aapsOmnipodManager.deactivatePod(initActionFragment);
}
rxBus.send(new EventOmnipodPumpValuesChanged());
return "OK";
}

View file

@ -320,13 +320,6 @@
</LinearLayout>
<TextView
android:id="@+id/omnipod_queue"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=""
android:textAlignment="center" />
<View
android:layout_width="fill_parent"
android:layout_height="2dip"
@ -517,43 +510,6 @@
android:layout_marginBottom="5dp"
android:background="@color/listdelimiter" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1.5"
android:gravity="end"
android:paddingRight="5dp"
android:text="@string/omnipod_total_delivered_label"
android:textSize="14sp" />
<TextView
android:layout_width="5dp"
android:layout_height="wrap_content"
android:layout_weight="0"
android:gravity="center_horizontal"
android:paddingStart="2dp"
android:paddingEnd="2dp"
android:text=":"
android:textSize="14sp" />
<TextView
android:id="@+id/omnipod_total_delivered"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="start"
android:paddingLeft="5dp"
android:textColor="@android:color/white"
android:textSize="14sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -590,6 +546,50 @@
</LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="2dip"
android:layout_marginLeft="20dp"
android:layout_marginTop="5dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="5dp"
android:background="@color/listdelimiter" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1.5"
android:gravity="end"
android:paddingRight="5dp"
android:text="@string/omnipod_total_delivered_label"
android:textSize="14sp" />
<TextView
android:layout_width="5dp"
android:layout_height="wrap_content"
android:layout_weight="0"
android:gravity="center_horizontal"
android:paddingStart="2dp"
android:paddingEnd="2dp"
android:text=":"
android:textSize="14sp" />
<TextView
android:id="@+id/omnipod_total_delivered"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="start"
android:paddingLeft="5dp"
android:textColor="@android:color/white"
android:textSize="14sp" />
</LinearLayout>
<View
android:layout_width="fill_parent"

View file

@ -11,7 +11,6 @@ import org.mockito.Mock;
import org.powermock.modules.junit4.PowerMockRunner;
import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.FirmwareVersion;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus;
import info.nightscout.androidaps.utils.sharedPreferences.SP;
@ -22,7 +21,6 @@ import static org.junit.Assert.assertEquals;
public class AapsPodStateManagerTest {
@Mock AAPSLogger aapsLogger;
@Mock SP sp;
RxBusWrapper rxBus = new RxBusWrapper();
@Test
public void times() {
@ -33,7 +31,7 @@ public class AapsPodStateManagerTest {
DateTimeUtils.setCurrentMillisFixed(now.getMillis());
AapsPodStateManager podStateManager = new AapsPodStateManager(aapsLogger, sp, rxBus);
AapsPodStateManager podStateManager = new AapsPodStateManager(aapsLogger, sp);
podStateManager.initState(0x0);
podStateManager.setInitializationParameters(0, 0, new FirmwareVersion(1, 1, 1),
new FirmwareVersion(2, 2, 2), timeZone, PodProgressStatus.ABOVE_FIFTY_UNITS);
@ -51,7 +49,7 @@ public class AapsPodStateManagerTest {
DateTimeUtils.setCurrentMillisFixed(now.getMillis());
AapsPodStateManager podStateManager = new AapsPodStateManager(aapsLogger, sp, rxBus);
AapsPodStateManager podStateManager = new AapsPodStateManager(aapsLogger, sp);
podStateManager.initState(0x0);
podStateManager.setInitializationParameters(0, 0, new FirmwareVersion(1, 1, 1),
new FirmwareVersion(2, 2, 2), timeZone, PodProgressStatus.ABOVE_FIFTY_UNITS);
@ -74,7 +72,7 @@ public class AapsPodStateManagerTest {
DateTimeUtils.setCurrentMillisFixed(now.getMillis());
AapsPodStateManager podStateManager = new AapsPodStateManager(aapsLogger, sp, rxBus);
AapsPodStateManager podStateManager = new AapsPodStateManager(aapsLogger, sp);
podStateManager.initState(0x0);
podStateManager.setInitializationParameters(0, 0, new FirmwareVersion(1, 1, 1),
new FirmwareVersion(2, 2, 2), timeZone, PodProgressStatus.ABOVE_FIFTY_UNITS);