Display Pod time in Omnipod tab and add button to manually set time

This commit is contained in:
Bart Sopers 2020-09-10 20:13:16 +02:00
parent b474e72a53
commit df1731e6b7
9 changed files with 170 additions and 45 deletions

View file

@ -19,11 +19,14 @@ import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.EnumSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
import java.util.function.Supplier; import java.util.function.Supplier;
import javax.inject.Inject; import javax.inject.Inject;
@ -125,7 +128,7 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface,
private final PumpType pumpType = PumpType.Insulet_Omnipod; private final PumpType pumpType = PumpType.Insulet_Omnipod;
private final List<CustomAction> customActions = new ArrayList<>(); private final List<CustomAction> customActions = new ArrayList<>();
private final List<OmnipodStatusRequestType> statusRequestList = new ArrayList<>(); private final Set<OmnipodStatusRequestType> statusRequests = Collections.synchronizedSet(EnumSet.noneOf(OmnipodStatusRequestType.class));
private final CompositeDisposable disposables = new CompositeDisposable(); private final CompositeDisposable disposables = new CompositeDisposable();
// variables for handling statuses and history // variables for handling statuses and history
@ -229,7 +232,7 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface,
} }
if (!getCommandQueue().statusInQueue()) { if (!getCommandQueue().statusInQueue()) {
if (!OmnipodPumpPlugin.this.statusRequestList.isEmpty()) { if (!OmnipodPumpPlugin.this.statusRequests.isEmpty()) {
getCommandQueue().readStatus("Status Refresh Requested", null); getCommandQueue().readStatus("Status Refresh Requested", null);
} else if (OmnipodPumpPlugin.this.hasTimeDateOrTimeZoneChanged) { } else if (OmnipodPumpPlugin.this.hasTimeDateOrTimeZoneChanged) {
getCommandQueue().readStatus("Date or Time Zone Changed", null); getCommandQueue().readStatus("Date or Time Zone Changed", null);
@ -461,9 +464,9 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface,
public void getPumpStatus() { public void getPumpStatus() {
if (firstRun) { if (firstRun) {
initializeAfterRileyLinkConnection(); initializeAfterRileyLinkConnection();
} else if (!statusRequestList.isEmpty()) { } else if (!statusRequests.isEmpty()) {
synchronized (statusRequestList) { synchronized (statusRequests) {
Iterator<OmnipodStatusRequestType> iterator = statusRequestList.iterator(); Iterator<OmnipodStatusRequestType> iterator = statusRequests.iterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {
OmnipodStatusRequestType statusRequest = iterator.next(); OmnipodStatusRequestType statusRequest = iterator.next();
@ -497,6 +500,9 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface,
case SUSPEND_DELIVERY: case SUSPEND_DELIVERY:
executeCommand(OmnipodCommandType.SUSPEND_DELIVERY, aapsOmnipodManager::suspendDelivery); executeCommand(OmnipodCommandType.SUSPEND_DELIVERY, aapsOmnipodManager::suspendDelivery);
break; break;
case SET_TIME:
executeCommand(OmnipodCommandType.SET_TIME, aapsOmnipodManager::setTime);
break;
default: default:
aapsLogger.error(LTag.PUMP, "Unknown status request: " + statusRequest.name()); aapsLogger.error(LTag.PUMP, "Unknown status request: " + statusRequest.name());
} }
@ -832,9 +838,7 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface,
} }
public void addPodStatusRequest(OmnipodStatusRequestType pumpStatusRequest) { public void addPodStatusRequest(OmnipodStatusRequestType pumpStatusRequest) {
synchronized (statusRequestList) { statusRequests.add(pumpStatusRequest);
statusRequestList.add(pumpStatusRequest);
}
} }
@Override @Override
@ -889,6 +893,10 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface,
return getOperationNotSupportedWithCustomText(info.nightscout.androidaps.core.R.string.pump_operation_not_supported_by_pump_driver); return getOperationNotSupportedWithCustomText(info.nightscout.androidaps.core.R.string.pump_operation_not_supported_by_pump_driver);
} }
public OmnipodCommandType getCurrentCommand() {
return currentCommand;
}
private void initializeAfterRileyLinkConnection() { private void initializeAfterRileyLinkConnection() {
if (podStateManager.isPodInitialized() && podStateManager.getPodProgressStatus().isAtLeast(PodProgressStatus.PAIRING_COMPLETED)) { if (podStateManager.isPodInitialized() && podStateManager.getPodProgressStatus().isAtLeast(PodProgressStatus.PAIRING_COMPLETED)) {
PumpEnactResult result = executeCommand(OmnipodCommandType.GET_POD_STATUS, aapsOmnipodManager::getPodStatus); PumpEnactResult result = executeCommand(OmnipodCommandType.GET_POD_STATUS, aapsOmnipodManager::getPodStatus);
@ -933,14 +941,11 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface,
rileyLinkUtil.getRileyLinkHistory().add(new RLHistoryItemOmnipod(getInjector(), commandType)); rileyLinkUtil.getRileyLinkHistory().add(new RLHistoryItemOmnipod(getInjector(), commandType));
T pumpEnactResult = supplier.get(); return supplier.get();
rxBus.send(new EventRefreshOverview("Omnipod command: " + commandType.name(), false));
rxBus.send(new EventOmnipodPumpValuesChanged());
return pumpEnactResult;
} finally { } finally {
currentCommand = null; currentCommand = null;
rxBus.send(new EventRefreshOverview("Omnipod command: " + commandType.name(), false));
rxBus.send(new EventOmnipodPumpValuesChanged());
} }
} }

View file

@ -4,5 +4,6 @@ public enum OmnipodStatusRequestType {
ACKNOWLEDGE_ALERTS, ACKNOWLEDGE_ALERTS,
GET_POD_STATE, GET_POD_STATE,
GET_PULSE_LOG, GET_PULSE_LOG,
SUSPEND_DELIVERY SUSPEND_DELIVERY,
SET_TIME
} }

View file

@ -56,7 +56,7 @@ public final class ExpirationReminderBuilder {
} }
public ExpirationReminderBuilder lowReservoir(boolean active, int units) { public ExpirationReminderBuilder lowReservoir(boolean active, int units) {
if (podStateManager.getReservoirLevel() == null || podStateManager.getReservoirLevel().intValue() > units) { if (podStateManager.getReservoirLevel() == null || podStateManager.getReservoirLevel().intValue() >= units) {
AlertConfiguration lowReservoirAlertConfiguration = AlertConfigurationUtil.createLowReservoirAlertConfiguration(active, (double) units); AlertConfiguration lowReservoirAlertConfiguration = AlertConfigurationUtil.createLowReservoirAlertConfiguration(active, (double) units);
alerts.put(lowReservoirAlertConfiguration.getAlertSlot(), lowReservoirAlertConfiguration); alerts.put(lowReservoirAlertConfiguration.getAlertSlot(), lowReservoirAlertConfiguration);
} }

View file

@ -533,6 +533,8 @@ public class OmnipodManager {
podStateManager.setTimeZone(oldTimeZone); podStateManager.setTimeZone(oldTimeZone);
throw ex; throw ex;
} }
podStateManager.updateActivatedAt();
} finally { } finally {
logCommandExecutionFinished("setTime"); logCommandExecutionFinished("setTime");
} }

View file

@ -84,6 +84,7 @@ public abstract class PodStateManager {
/** /**
* @return true if we have a Pod state and the Pod is running, meaning the activation process has completed and the Pod is not deactivated or in a fault state * @return true if we have a Pod state and the Pod is running, meaning the activation process has completed and the Pod is not deactivated or in a fault state
* This does not mean the Pod is actually delivering insulin, combine with {@link #isSuspended() isSuspended()} for that
*/ */
public final boolean isPodRunning() { public final boolean isPodRunning() {
return isPodInitialized() && getPodProgressStatus().isRunning(); return isPodInitialized() && getPodProgressStatus().isRunning();
@ -295,8 +296,21 @@ public abstract class PodStateManager {
} }
public final DateTime getTime() { public final DateTime getTime() {
DateTime now = DateTime.now(); DateTimeZone timeZone = getSafe(() -> podState.getTimeZone());
return now.withZone(getSafe(() -> podState.getTimeZone())); if (timeZone == null) {
return DateTime.now();
}
Duration timeActive = getSafe(() -> podState.getTimeActive());
DateTime activatedAt = getSafe(() -> podState.getActivatedAt());
DateTime lastUpdatedFromResponse = getSafe(() -> podState.getLastUpdatedFromResponse());
if (timeActive == null || activatedAt == null) {
return DateTime.now().withZone(timeZone);
}
return activatedAt.plus(timeActive).plus(new Duration(lastUpdatedFromResponse, DateTime.now()));
}
public final boolean timeDeviatesMoreThan(Duration duration) {
return new Duration(getTime(), DateTime.now().withZoneRetainFields(getSafe(() -> podState.getTimeZone()))).abs().isLongerThan(duration);
} }
public final DateTime getActivatedAt() { public final DateTime getActivatedAt() {
@ -304,22 +318,23 @@ public abstract class PodStateManager {
return activatedAt == null ? null : activatedAt.withZone(getSafe(() -> podState.getTimeZone())); return activatedAt == null ? null : activatedAt.withZone(getSafe(() -> podState.getTimeZone()));
} }
public final void updateActivatedAt() {
setAndStore(() -> podState.setActivatedAt(DateTime.now().withZone(getSafe(() -> podState.getTimeZone())).minus(getSafe(this::getTimeActive))));
}
public final Duration getTimeActive() {
return getSafe(() -> podState.getTimeActive());
}
public final DateTime getExpiresAt() { public final DateTime getExpiresAt() {
DateTime expiresAt = getSafe(() -> podState.getExpiresAt()); DateTime activatedAt = getSafe(() -> podState.getActivatedAt());
return expiresAt == null ? null : expiresAt.withZone(getSafe(() -> podState.getTimeZone())); return activatedAt == null ? null : activatedAt.withZone(getSafe(() -> podState.getTimeZone())).plus(OmnipodConstants.NOMINAL_POD_LIFE);
} }
public final PodProgressStatus getPodProgressStatus() { public final PodProgressStatus getPodProgressStatus() {
return getSafe(() -> podState.getPodProgressStatus()); return getSafe(() -> podState.getPodProgressStatus());
} }
public final void setPodProgressStatus(PodProgressStatus podProgressStatus) {
if (podProgressStatus == null) {
throw new IllegalArgumentException("Pod progress status can not be null");
}
setAndStore(() -> podState.setPodProgressStatus(podProgressStatus));
}
public final boolean isSuspended() { public final boolean isSuspended() {
return getSafe(() -> podState.isSuspended()); return getSafe(() -> podState.isSuspended());
} }
@ -501,21 +516,16 @@ public abstract class PodStateManager {
public final void updateFromResponse(StatusUpdatableResponse statusResponse) { public final void updateFromResponse(StatusUpdatableResponse statusResponse) {
setSafe(() -> { setSafe(() -> {
if (podState.getActivatedAt() == null) { if (podState.getActivatedAt() == null) {
DateTime activatedAtCalculated = getTime().minus(statusResponse.getTimeActive()); DateTime activatedAtCalculated = DateTime.now().withZone(podState.getTimeZone()).minus(statusResponse.getTimeActive());
podState.setActivatedAt(activatedAtCalculated); podState.setActivatedAt(activatedAtCalculated);
} }
DateTime expiresAt = podState.getExpiresAt();
DateTime expiresAtCalculated = podState.getActivatedAt().plus(OmnipodConstants.NOMINAL_POD_LIFE);
if (expiresAt == null || expiresAtCalculated.isBefore(expiresAt) || expiresAtCalculated.isAfter(expiresAt.plusMinutes(1))) {
podState.setExpiresAt(expiresAtCalculated);
}
podState.setSuspended(statusResponse.getDeliveryStatus() == DeliveryStatus.SUSPENDED); podState.setSuspended(statusResponse.getDeliveryStatus() == DeliveryStatus.SUSPENDED);
podState.setActiveAlerts(statusResponse.getUnacknowledgedAlerts()); podState.setActiveAlerts(statusResponse.getUnacknowledgedAlerts());
podState.setLastDeliveryStatus(statusResponse.getDeliveryStatus()); podState.setLastDeliveryStatus(statusResponse.getDeliveryStatus());
podState.setReservoirLevel(statusResponse.getReservoirLevel()); podState.setReservoirLevel(statusResponse.getReservoirLevel());
podState.setTotalTicksDelivered(statusResponse.getTicksDelivered()); podState.setTotalTicksDelivered(statusResponse.getTicksDelivered());
podState.setPodProgressStatus(statusResponse.getPodProgressStatus()); podState.setPodProgressStatus(statusResponse.getPodProgressStatus());
podState.setTimeActive(statusResponse.getTimeActive());
if (statusResponse.getDeliveryStatus().isTbrRunning()) { if (statusResponse.getDeliveryStatus().isTbrRunning()) {
if (!isTempBasalCertain() && isTempBasalRunning()) { if (!isTempBasalCertain() && isTempBasalRunning()) {
podState.setTempBasalCertain(true); podState.setTempBasalCertain(true);
@ -615,7 +625,7 @@ public abstract class PodStateManager {
private DateTime lastUpdatedFromResponse; private DateTime lastUpdatedFromResponse;
private DateTimeZone timeZone; private DateTimeZone timeZone;
private DateTime activatedAt; private DateTime activatedAt;
private DateTime expiresAt; private Duration timeActive;
private PodInfoFaultEvent faultEvent; private PodInfoFaultEvent faultEvent;
private Double reservoirLevel; private Double reservoirLevel;
private Integer totalTicksDelivered; private Integer totalTicksDelivered;
@ -733,12 +743,12 @@ public abstract class PodStateManager {
this.activatedAt = activatedAt; this.activatedAt = activatedAt;
} }
DateTime getExpiresAt() { public Duration getTimeActive() {
return expiresAt; return timeActive;
} }
void setExpiresAt(DateTime expiresAt) { public void setTimeActive(Duration timeActive) {
this.expiresAt = expiresAt; this.timeActive = timeActive;
} }
PodInfoFaultEvent getFaultEvent() { PodInfoFaultEvent getFaultEvent() {
@ -919,7 +929,7 @@ public abstract class PodStateManager {
", lastUpdatedFromResponse=" + lastUpdatedFromResponse + ", lastUpdatedFromResponse=" + lastUpdatedFromResponse +
", timeZone=" + timeZone + ", timeZone=" + timeZone +
", activatedAt=" + activatedAt + ", activatedAt=" + activatedAt +
", expiresAt=" + expiresAt + ", timeActive=" + timeActive +
", faultEvent=" + faultEvent + ", faultEvent=" + faultEvent +
", reservoirLevel=" + reservoirLevel + ", reservoirLevel=" + reservoirLevel +
", totalTicksDelivered=" + totalTicksDelivered + ", totalTicksDelivered=" + totalTicksDelivered +
@ -937,7 +947,7 @@ public abstract class PodStateManager {
", tempBasalStartTime=" + tempBasalStartTime + ", tempBasalStartTime=" + tempBasalStartTime +
", tempBasalDuration=" + tempBasalDuration + ", tempBasalDuration=" + tempBasalDuration +
", tempBasalCertain=" + tempBasalCertain + ", tempBasalCertain=" + tempBasalCertain +
", expirationAlertHoursBeforeShutdown=" + expirationAlertTimeBeforeShutdown + ", expirationAlertTimeBeforeShutdown=" + expirationAlertTimeBeforeShutdown +
", lowReservoirAlertUnits=" + lowReservoirAlertUnits + ", lowReservoirAlertUnits=" + lowReservoirAlertUnits +
", configuredAlerts=" + configuredAlerts + ", configuredAlerts=" + configuredAlerts +
'}'; '}';

View file

@ -22,6 +22,7 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.dialog.RileyL
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData
import info.nightscout.androidaps.plugins.pump.omnipod.OmnipodPumpPlugin import info.nightscout.androidaps.plugins.pump.omnipod.OmnipodPumpPlugin
import info.nightscout.androidaps.plugins.pump.omnipod.R import info.nightscout.androidaps.plugins.pump.omnipod.R
import info.nightscout.androidaps.plugins.pump.omnipod.definition.OmnipodCommandType
import info.nightscout.androidaps.plugins.pump.omnipod.definition.OmnipodStatusRequestType import info.nightscout.androidaps.plugins.pump.omnipod.definition.OmnipodStatusRequestType
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus
@ -47,7 +48,9 @@ import kotlinx.android.synthetic.main.omnipod_fragment.*
import org.apache.commons.lang3.StringUtils import org.apache.commons.lang3.StringUtils
import org.joda.time.DateTime import org.joda.time.DateTime
import org.joda.time.Duration import org.joda.time.Duration
import java.util.*
import javax.inject.Inject import javax.inject.Inject
import kotlin.collections.ArrayList
class OmnipodFragment : DaggerFragment() { class OmnipodFragment : DaggerFragment() {
companion object { companion object {
@ -133,6 +136,12 @@ class OmnipodFragment : DaggerFragment() {
commandQueue.readStatus("Clicked Suspend Delivery", null) commandQueue.readStatus("Clicked Suspend Delivery", null)
} }
omnipod_button_set_time.setOnClickListener {
disablePodActionButtons()
omnipodPumpPlugin.addPodStatusRequest(OmnipodStatusRequestType.SET_TIME);
commandQueue.readStatus("Clicked Set Time", null)
}
omnipod_button_pulse_log.setOnClickListener { omnipod_button_pulse_log.setOnClickListener {
disablePodActionButtons() disablePodActionButtons()
omnipodPumpPlugin.addPodStatusRequest(OmnipodStatusRequestType.GET_PULSE_LOG); omnipodPumpPlugin.addPodStatusRequest(OmnipodStatusRequestType.GET_PULSE_LOG);
@ -168,7 +177,7 @@ class OmnipodFragment : DaggerFragment() {
.toObservable(EventPreferenceChange::class.java) .toObservable(EventPreferenceChange::class.java)
.observeOn(Schedulers.io()) .observeOn(Schedulers.io())
.subscribe({ .subscribe({
updatePulseLogButton() updatePodActionButtons()
}, { fabricPrivacy.logException(it) }) }, { fabricPrivacy.logException(it) })
updateUi() updateUi()
} }
@ -227,23 +236,32 @@ class OmnipodFragment : DaggerFragment() {
omnipod_pod_lot.text = PLACEHOLDER omnipod_pod_lot.text = PLACEHOLDER
omnipod_pod_tid.text = PLACEHOLDER omnipod_pod_tid.text = PLACEHOLDER
omnipod_pod_firmware_version.text = PLACEHOLDER omnipod_pod_firmware_version.text = PLACEHOLDER
omnipod_time_on_pod.text = PLACEHOLDER
omnipod_pod_expiry.text = PLACEHOLDER omnipod_pod_expiry.text = PLACEHOLDER
omnipod_pod_expiry.setTextColor(Color.WHITE) omnipod_pod_expiry.setTextColor(Color.WHITE)
omnipod_base_basal_rate.text = PLACEHOLDER omnipod_base_basal_rate.text = PLACEHOLDER
omnipod_total_delivered.text = PLACEHOLDER omnipod_total_delivered.text = PLACEHOLDER
omnipod_reservoir.text = PLACEHOLDER omnipod_reservoir.text = PLACEHOLDER
omnipod_reservoir.setTextColor(Color.WHITE)
omnipod_pod_active_alerts.text = PLACEHOLDER omnipod_pod_active_alerts.text = PLACEHOLDER
} else { } else {
omnipod_pod_address.text = podStateManager.address.toString() omnipod_pod_address.text = podStateManager.address.toString()
omnipod_pod_lot.text = podStateManager.lot.toString() omnipod_pod_lot.text = podStateManager.lot.toString()
omnipod_pod_tid.text = podStateManager.tid.toString() omnipod_pod_tid.text = podStateManager.tid.toString()
omnipod_pod_firmware_version.text = resourceHelper.gs(R.string.omnipod_pod_firmware_version_value, podStateManager.pmVersion.toString(), podStateManager.piVersion.toString()) omnipod_pod_firmware_version.text = resourceHelper.gs(R.string.omnipod_pod_firmware_version_value, podStateManager.pmVersion.toString(), podStateManager.piVersion.toString())
omnipod_time_on_pod.text = readableZonedTime(podStateManager.time)
omnipod_time_on_pod.setTextColor(if (podStateManager.timeDeviatesMoreThan(Duration.standardMinutes(5))) {
Color.RED
} else {
Color.WHITE
})
val expiresAt = podStateManager.expiresAt val expiresAt = podStateManager.expiresAt
if (expiresAt == null) { if (expiresAt == null) {
omnipod_pod_expiry.text = PLACEHOLDER omnipod_pod_expiry.text = PLACEHOLDER
omnipod_pod_expiry.setTextColor(Color.WHITE) omnipod_pod_expiry.setTextColor(Color.WHITE)
} else { } else {
omnipod_pod_expiry.text = dateUtil.dateAndTimeString(expiresAt.toDate()) omnipod_pod_expiry.text = readableZonedTime(expiresAt)
omnipod_pod_expiry.setTextColor(if (DateTime.now().isAfter(expiresAt)) { omnipod_pod_expiry.setTextColor(if (DateTime.now().isAfter(expiresAt)) {
Color.RED Color.RED
} else { } else {
@ -419,12 +437,15 @@ class OmnipodFragment : DaggerFragment() {
updateResumeDeliveryButton() updateResumeDeliveryButton()
updateAcknowledgeAlertsButton() updateAcknowledgeAlertsButton()
updateSuspendDeliveryButton() updateSuspendDeliveryButton()
updateSetTimeButton()
updatePulseLogButton() updatePulseLogButton()
} }
private fun disablePodActionButtons() { private fun disablePodActionButtons() {
omnipod_button_acknowledge_active_alerts.isEnabled = false omnipod_button_acknowledge_active_alerts.isEnabled = false
omnipod_button_resume_delivery.isEnabled = false omnipod_button_resume_delivery.isEnabled = false
omnipod_button_suspend_delivery.isEnabled = false
omnipod_button_set_time.isEnabled = false
omnipod_button_refresh_status.isEnabled = false omnipod_button_refresh_status.isEnabled = false
omnipod_button_pulse_log.isEnabled = false omnipod_button_pulse_log.isEnabled = false
} }
@ -445,8 +466,12 @@ class OmnipodFragment : DaggerFragment() {
} }
private fun updateAcknowledgeAlertsButton() { private fun updateAcknowledgeAlertsButton() {
omnipod_button_acknowledge_active_alerts.isEnabled = podStateManager.isPodActivationCompleted && podStateManager.hasActiveAlerts() if (podStateManager.isPodRunning && podStateManager.hasActiveAlerts()) {
&& !podStateManager.isPodDead && rileyLinkServiceData.rileyLinkServiceState.isReady && isQueueEmpty() omnipod_button_acknowledge_active_alerts.visibility = View.VISIBLE
omnipod_button_acknowledge_active_alerts.isEnabled = rileyLinkServiceData.rileyLinkServiceState.isReady && isQueueEmpty()
} else {
omnipod_button_acknowledge_active_alerts.visibility = View.GONE
}
} }
private fun updateSuspendDeliveryButton() { private fun updateSuspendDeliveryButton() {
@ -459,6 +484,15 @@ class OmnipodFragment : DaggerFragment() {
} }
} }
private fun updateSetTimeButton() {
if (podStateManager.isPodRunning && (podStateManager.timeDeviatesMoreThan(Duration.standardMinutes(5)) || omnipodPumpPlugin.currentCommand == OmnipodCommandType.SET_TIME)) {
omnipod_button_set_time.visibility = View.VISIBLE
omnipod_button_set_time.isEnabled = !podStateManager.isSuspended && rileyLinkServiceData.rileyLinkServiceState.isReady && isQueueEmpty()
} else {
omnipod_button_set_time.visibility = View.GONE
}
}
private fun updatePulseLogButton() { private fun updatePulseLogButton() {
if (omnipodManager.isPulseLogButtonEnabled) { if (omnipodManager.isPulseLogButtonEnabled) {
omnipod_button_pulse_log.visibility = View.VISIBLE omnipod_button_pulse_log.visibility = View.VISIBLE
@ -475,6 +509,19 @@ class OmnipodFragment : DaggerFragment() {
} }
} }
private fun readableZonedTime(time: DateTime): String {
val timeAsJavaData = time.toLocalDateTime().toDate()
val timeZone = podStateManager.timeZone.toTimeZone()
if (timeZone == TimeZone.getDefault()) {
return dateUtil.dateAndTimeString(timeAsJavaData)
}
val isDaylightTime = timeZone.inDaylightTime(timeAsJavaData)
val locale = resources.configuration.locales.get(0)
val timeZoneDisplayName = timeZone.getDisplayName(isDaylightTime, TimeZone.SHORT, locale) + " " + timeZone.getDisplayName(isDaylightTime, TimeZone.LONG, locale)
return resourceHelper.gs(R.string.omnipod_pod_time_with_timezone, dateUtil.dateAndTimeString(timeAsJavaData), timeZoneDisplayName)
}
private fun readableDuration(dateTime: DateTime): String { private fun readableDuration(dateTime: DateTime): String {
val duration = Duration(dateTime, DateTime.now()) val duration = Duration(dateTime, DateTime.now())
val hours = duration.standardHours.toInt() val hours = duration.standardHours.toInt()

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#72a8ff"
android:pathData="M22,5.72l-4.6,-3.86 -1.29,1.53 4.6,3.86L22,5.72zM7.88,3.39L6.6,1.86 2,5.71l1.29,1.53 4.59,-3.85zM12.5,8L11,8v6l4.75,2.85 0.75,-1.23 -4,-2.37L12.5,8zM12,4c-4.97,0 -9,4.03 -9,9s4.02,9 9,9c4.97,0 9,-4.03 9,-9s-4.03,-9 -9,-9zM12,20c-3.87,0 -7,-3.13 -7,-7s3.13,-7 7,-7 7,3.13 7,7 -3.13,7 -7,7z"/>
</vector>

View file

@ -243,6 +243,42 @@
android:textSize="14sp" /> android:textSize="14sp" />
</LinearLayout> </LinearLayout>
<!-- Pod Time -->
<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_pod_time_on_pod"
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_time_on_pod"
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>
<!-- Pod Expires --> <!-- Pod Expires -->
<LinearLayout <LinearLayout
@ -782,6 +818,18 @@
android:text="@string/omnipod_suspend_delivery_short" android:text="@string/omnipod_suspend_delivery_short"
android:visibility="gone" /> android:visibility="gone" />
<Button
android:id="@+id/omnipod_button_set_time"
style="@style/ButtonSmallFontStyle"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:drawableTop="@drawable/ic_access_alarm"
android:paddingLeft="0dp"
android:paddingRight="0dp"
android:text="@string/omnipod_set_time"
android:visibility="gone" />
<Button <Button
android:id="@+id/omnipod_button_resume_delivery" android:id="@+id/omnipod_button_resume_delivery"
style="@style/ButtonSmallFontStyle" style="@style/ButtonSmallFontStyle"

View file

@ -157,6 +157,7 @@
<string name="omnipod_pod_tid">TID</string> <string name="omnipod_pod_tid">TID</string>
<string name="omnipod_pod_firmware_version">Firmware version</string> <string name="omnipod_pod_firmware_version">Firmware version</string>
<string name="omnipod_pod_firmware_version_value" translatable="false">PM %1$s / PI %2$s</string> <string name="omnipod_pod_firmware_version_value" translatable="false">PM %1$s / PI %2$s</string>
<string name="omnipod_pod_time_with_timezone" translatable="false">%1$s (%2$s)</string>
<string name="omnipod_errors">Errors</string> <string name="omnipod_errors">Errors</string>
<string name="omnipod_cmd_basal_profile_not_set_is_same">Basal profile is the same, so it will not be set again.</string> <string name="omnipod_cmd_basal_profile_not_set_is_same">Basal profile is the same, so it will not be set again.</string>
<string name="omnipod_custom_action_reset_rileylink">Reset RileyLink config</string> <string name="omnipod_custom_action_reset_rileylink">Reset RileyLink config</string>
@ -193,6 +194,8 @@
<string name="omnipod_history_type">Type:</string> <string name="omnipod_history_type">Type:</string>
<string name="omnipod_error_failed_to_set_profile_empty_profile">Failed to set basal profile: received an empty profile. Make sure to activate your basal profile.</string> <string name="omnipod_error_failed_to_set_profile_empty_profile">Failed to set basal profile: received an empty profile. Make sure to activate your basal profile.</string>
<string name="omnipod_error_set_initial_basal_schedule_no_profile">No basal profile is active. Make sure to activate your basal profile.</string> <string name="omnipod_error_set_initial_basal_schedule_no_profile">No basal profile is active. Make sure to activate your basal profile.</string>
<string name="omnipod_pod_time_on_pod">Time on Pod</string>
<string name="omnipod_set_time">Set time</string>
<plurals name="omnipod_minutes"> <plurals name="omnipod_minutes">
<item quantity="one">%1$d minute</item> <item quantity="one">%1$d minute</item>