- first commit for Omnipod
This commit is contained in:
parent
0d5ea4f700
commit
1047403923
34 changed files with 3369 additions and 124 deletions
|
@ -45,6 +45,7 @@
|
|||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
@ -78,33 +79,33 @@
|
|||
|
||||
<!-- Receive new BG readings from other local apps -->
|
||||
<receiver
|
||||
android:name=".receivers.DataReceiver"
|
||||
android:enabled="true"
|
||||
android:exported="true">
|
||||
android:name=".receivers.DataReceiver"
|
||||
android:enabled="true"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<!-- Receiver from xDrip -->
|
||||
<action android:name="com.eveningoutpost.dexdrip.BgEstimate"/>
|
||||
<action android:name="com.eveningoutpost.dexdrip.BgEstimate" />
|
||||
<!-- Receiver from 640g uploader -->
|
||||
<action android:name="com.eveningoutpost.dexdrip.NS_EMULATOR"/>
|
||||
<action android:name="com.eveningoutpost.dexdrip.NS_EMULATOR" />
|
||||
<!-- Receiver from glimp -->
|
||||
<action android:name="it.ct.glicemia.ACTION_GLUCOSE_MEASURED"/>
|
||||
<action android:name="it.ct.glicemia.ACTION_GLUCOSE_MEASURED" />
|
||||
<!-- Receiver from Dexcom -->
|
||||
<action android:name="com.dexcom.cgm.EXTERNAL_BROADCAST"/>
|
||||
<action android:name="com.dexcom.cgm.EXTERNAL_BROADCAST" />
|
||||
<!-- Receiver from Poctech -->
|
||||
<action android:name="com.china.poctech.data"/>
|
||||
<action android:name="com.china.poctech.data" />
|
||||
<!-- Receiver from Tomato -->
|
||||
<action android:name="com.fanqies.tomatofn.BgEstimate"/>
|
||||
<action android:name="com.fanqies.tomatofn.BgEstimate" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<!-- Receive new SMS messages -->
|
||||
<receiver
|
||||
android:name=".receivers.SmsReceiver"
|
||||
android:enabled="true"
|
||||
android:exported="true"
|
||||
android:permission="android.permission.BROADCAST_SMS">
|
||||
android:name=".receivers.SmsReceiver"
|
||||
android:enabled="true"
|
||||
android:exported="true"
|
||||
android:permission="android.permission.BROADCAST_SMS">
|
||||
<intent-filter>
|
||||
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
|
||||
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
|
@ -289,6 +290,7 @@
|
|||
android:name=".plugins.pump.medtronic.service.RileyLinkMedtronicService"
|
||||
android:enabled="true"
|
||||
android:exported="true" />
|
||||
|
||||
<activity android:name=".plugins.pump.common.dialog.RileyLinkBLEScanActivity">
|
||||
<intent-filter>
|
||||
<action android:name="info.nightscout.androidaps.plugins.PumpCommon.dialog.RileyLinkBLEScanActivity" />
|
||||
|
@ -301,7 +303,16 @@
|
|||
android:theme="@style/Theme.AppCompat.NoTitle" />
|
||||
<activity android:name=".plugins.pump.medtronic.dialog.MedtronicHistoryActivity" />
|
||||
|
||||
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
|
||||
<!-- Omnipod service and activities -->
|
||||
<service
|
||||
android:name=".plugins.pump.omnipod.service.RileyLinkOmnipodService"
|
||||
android:enabled="true"
|
||||
android:exported="true" />
|
||||
|
||||
|
||||
<uses-library
|
||||
android:name="org.apache.http.legacy"
|
||||
android:required="false" />
|
||||
|
||||
</application>
|
||||
|
||||
|
|
|
@ -1,14 +1,10 @@
|
|||
package info.nightscout.androidaps;
|
||||
|
||||
import android.app.Application;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.res.Resources;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.PluralsRes;
|
||||
|
@ -68,8 +64,6 @@ import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin;
|
|||
import info.nightscout.androidaps.plugins.profile.ns.NSProfilePlugin;
|
||||
import info.nightscout.androidaps.plugins.profile.simple.SimpleProfilePlugin;
|
||||
import info.nightscout.androidaps.plugins.pump.combo.ComboPlugin;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkConst;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil;
|
||||
import info.nightscout.androidaps.plugins.pump.danaR.DanaRPlugin;
|
||||
import info.nightscout.androidaps.plugins.pump.danaRKorean.DanaRKoreanPlugin;
|
||||
import info.nightscout.androidaps.plugins.pump.danaRS.DanaRSPlugin;
|
||||
|
@ -77,6 +71,7 @@ import info.nightscout.androidaps.plugins.pump.danaRv2.DanaRv2Plugin;
|
|||
import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin;
|
||||
import info.nightscout.androidaps.plugins.pump.mdi.MDIPlugin;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.OmnipodPumpPlugin;
|
||||
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin;
|
||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityAAPSPlugin;
|
||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref0Plugin;
|
||||
|
@ -187,7 +182,10 @@ public class MainApp extends Application {
|
|||
if (Config.PUMPDRIVERS) pluginsList.add(LocalInsightPlugin.getPlugin());
|
||||
pluginsList.add(CareportalPlugin.getPlugin());
|
||||
if (Config.PUMPDRIVERS) pluginsList.add(ComboPlugin.getPlugin());
|
||||
if (Config.PUMPDRIVERS && engineeringMode) pluginsList.add(MedtronicPumpPlugin.getPlugin());
|
||||
if (Config.PUMPDRIVERS && engineeringMode)
|
||||
pluginsList.add(MedtronicPumpPlugin.getPlugin());
|
||||
if (Config.PUMPDRIVERS && engineeringMode)
|
||||
pluginsList.add(OmnipodPumpPlugin.getPlugin());
|
||||
if (Config.MDI) pluginsList.add(MDIPlugin.getPlugin());
|
||||
pluginsList.add(VirtualPumpPlugin.getPlugin());
|
||||
if (Config.APS) pluginsList.add(LoopPlugin.getPlugin());
|
||||
|
@ -461,7 +459,7 @@ public class MainApp extends Application {
|
|||
unregisterReceiver(btReceiver);
|
||||
}
|
||||
|
||||
if (timeDateOrTZChangeReceiver!=null) {
|
||||
if (timeDateOrTZChangeReceiver != null) {
|
||||
unregisterReceiver(timeDateOrTZChangeReceiver);
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ import info.nightscout.androidaps.utils.DateUtil;
|
|||
import info.nightscout.androidaps.utils.DecimalFormatter;
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy;
|
||||
import info.nightscout.androidaps.utils.MidnightTime;
|
||||
import info.nightscout.androidaps.utils.Round;
|
||||
|
||||
public class Profile {
|
||||
private static Logger log = LoggerFactory.getLogger(Profile.class);
|
||||
|
@ -475,6 +476,17 @@ public class Profile {
|
|||
|
||||
public int timeAsSeconds;
|
||||
public double value;
|
||||
|
||||
public boolean equals(Object otherObject) {
|
||||
if (!(otherObject instanceof ProfileValue)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ProfileValue otherProfileValue = (ProfileValue) otherObject;
|
||||
|
||||
return (timeAsSeconds == otherProfileValue.timeAsSeconds) && Round.isSame(value, otherProfileValue.value);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized ProfileValue[] getBasalValues() {
|
||||
|
@ -665,4 +677,27 @@ public class Profile {
|
|||
public int getTimeshift() {
|
||||
return timeshift;
|
||||
}
|
||||
|
||||
|
||||
public boolean isProfileTheSame(Profile otherProfile) {
|
||||
|
||||
if (!Round.isSame(this.baseBasalSum(), otherProfile.baseBasalSum()))
|
||||
return false;
|
||||
|
||||
ProfileValue[] basalValues = this.getBasalValues();
|
||||
ProfileValue[] otherBasalValues = otherProfile.getBasalValues();
|
||||
|
||||
if (basalValues.length != otherBasalValues.length)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < basalValues.length; i++) {
|
||||
if (!basalValues[i].equals(otherBasalValues[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
package info.nightscout.androidaps.plugins.pump.common;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import info.nightscout.androidaps.BuildConfig;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
|
@ -22,12 +22,14 @@ import info.nightscout.androidaps.data.PumpEnactResult;
|
|||
import info.nightscout.androidaps.db.ExtendedBolus;
|
||||
import info.nightscout.androidaps.db.TemporaryBasal;
|
||||
import info.nightscout.androidaps.events.EventAppExit;
|
||||
import info.nightscout.androidaps.events.EventCustomActionsChanged;
|
||||
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
|
||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
import info.nightscout.androidaps.interfaces.PluginDescription;
|
||||
import info.nightscout.androidaps.interfaces.PumpDescription;
|
||||
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.common.ManufacturerType;
|
||||
import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress;
|
||||
import info.nightscout.androidaps.plugins.pump.common.data.PumpStatus;
|
||||
import info.nightscout.androidaps.plugins.pump.common.defs.PumpDriverState;
|
||||
|
@ -48,9 +50,9 @@ public abstract class PumpPluginAbstract extends PluginBase implements PumpInter
|
|||
private static final Logger LOG = LoggerFactory.getLogger(L.PUMP);
|
||||
|
||||
protected static final PumpEnactResult OPERATION_NOT_SUPPORTED = new PumpEnactResult().success(false)
|
||||
.enacted(false).comment(MainApp.gs(R.string.pump_operation_not_supported_by_pump_driver));
|
||||
.enacted(false).comment(MainApp.gs(R.string.pump_operation_not_supported_by_pump_driver));
|
||||
protected static final PumpEnactResult OPERATION_NOT_YET_SUPPORTED = new PumpEnactResult().success(false)
|
||||
.enacted(false).comment(MainApp.gs(R.string.pump_operation_not_yet_supported_by_pump));
|
||||
.enacted(false).comment(MainApp.gs(R.string.pump_operation_not_yet_supported_by_pump));
|
||||
|
||||
protected PumpDescription pumpDescription = new PumpDescription();
|
||||
protected PumpStatus pumpStatus;
|
||||
|
@ -231,7 +233,7 @@ public abstract class PumpPluginAbstract extends PluginBase implements PumpInter
|
|||
|
||||
@Override
|
||||
public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, Profile profile,
|
||||
boolean enforceNew) {
|
||||
boolean enforceNew) {
|
||||
if (isLoggingEnabled())
|
||||
LOG.warn("setTempBasalAbsolute [PumpPluginAbstract] - Not implemented.");
|
||||
return getOperationNotSupportedWithCustomText(R.string.pump_operation_not_supported_by_pump_driver);
|
||||
|
@ -240,7 +242,7 @@ public abstract class PumpPluginAbstract extends PluginBase implements PumpInter
|
|||
|
||||
@Override
|
||||
public PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes, Profile profile,
|
||||
boolean enforceNew) {
|
||||
boolean enforceNew) {
|
||||
if (isLoggingEnabled())
|
||||
LOG.warn("setTempBasalPercent [PumpPluginAbstract] - Not implemented.");
|
||||
return getOperationNotSupportedWithCustomText(R.string.pump_operation_not_supported_by_pump_driver);
|
||||
|
@ -294,8 +296,8 @@ public abstract class PumpPluginAbstract extends PluginBase implements PumpInter
|
|||
// Short info for SMS, Wear etc
|
||||
|
||||
public boolean isFakingTempsByExtendedBoluses() {
|
||||
if (isLoggingEnabled())
|
||||
LOG.warn("isFakingTempsByExtendedBoluses [PumpPluginAbstract] - Not implemented.");
|
||||
//if (isLoggingEnabled())
|
||||
// LOG.warn("isFakingTempsByExtendedBoluses [PumpPluginAbstract] - Not implemented.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -332,7 +334,7 @@ public abstract class PumpPluginAbstract extends PluginBase implements PumpInter
|
|||
TemporaryBasal tb = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(System.currentTimeMillis());
|
||||
if (tb != null) {
|
||||
extended.put("TempBasalAbsoluteRate",
|
||||
tb.tempBasalConvertedToAbsolute(System.currentTimeMillis(), profile));
|
||||
tb.tempBasalConvertedToAbsolute(System.currentTimeMillis(), profile));
|
||||
extended.put("TempBasalStart", DateUtil.dateAndTimeString(tb.date));
|
||||
extended.put("TempBasalRemaining", tb.getPlannedRemainingMinutes());
|
||||
}
|
||||
|
@ -364,20 +366,20 @@ public abstract class PumpPluginAbstract extends PluginBase implements PumpInter
|
|||
String ret = "";
|
||||
if (pumpStatus.lastConnection != 0) {
|
||||
Long agoMsec = System.currentTimeMillis() - pumpStatus.lastConnection;
|
||||
int agoMin = (int)(agoMsec / 60d / 1000d);
|
||||
int agoMin = (int) (agoMsec / 60d / 1000d);
|
||||
ret += "LastConn: " + agoMin + " min ago\n";
|
||||
}
|
||||
if (pumpStatus.lastBolusTime != null && pumpStatus.lastBolusTime.getTime() != 0) {
|
||||
ret += "LastBolus: " + DecimalFormatter.to2Decimal(pumpStatus.lastBolusAmount) + "U @" + //
|
||||
android.text.format.DateFormat.format("HH:mm", pumpStatus.lastBolusTime) + "\n";
|
||||
android.text.format.DateFormat.format("HH:mm", pumpStatus.lastBolusTime) + "\n";
|
||||
}
|
||||
TemporaryBasal activeTemp = TreatmentsPlugin.getPlugin()
|
||||
.getRealTempBasalFromHistory(System.currentTimeMillis());
|
||||
.getRealTempBasalFromHistory(System.currentTimeMillis());
|
||||
if (activeTemp != null) {
|
||||
ret += "Temp: " + activeTemp.toStringFull() + "\n";
|
||||
}
|
||||
ExtendedBolus activeExtendedBolus = TreatmentsPlugin.getPlugin().getExtendedBolusFromHistory(
|
||||
System.currentTimeMillis());
|
||||
System.currentTimeMillis());
|
||||
if (activeExtendedBolus != null) {
|
||||
ret += "Extended: " + activeExtendedBolus.toString() + "\n";
|
||||
}
|
||||
|
@ -401,7 +403,7 @@ public abstract class PumpPluginAbstract extends PluginBase implements PumpInter
|
|||
if (isLoggingEnabled())
|
||||
LOG.error("deliverTreatment: Invalid input");
|
||||
return new PumpEnactResult().success(false).enacted(false).bolusDelivered(0d).carbsDelivered(0d)
|
||||
.comment(MainApp.gs(R.string.danar_invalidinput));
|
||||
.comment(MainApp.gs(R.string.danar_invalidinput));
|
||||
} else if (detailedBolusInfo.insulin > 0) {
|
||||
// bolus needed, ask pump to deliver it
|
||||
return deliverBolus(detailedBolusInfo);
|
||||
|
@ -419,7 +421,7 @@ public abstract class PumpPluginAbstract extends PluginBase implements PumpInter
|
|||
LOG.debug("deliverTreatment: Carb only treatment.");
|
||||
|
||||
return new PumpEnactResult().success(true).enacted(true).bolusDelivered(0d)
|
||||
.carbsDelivered(detailedBolusInfo.carbs).comment(MainApp.gs(R.string.virtualpump_resultok));
|
||||
.carbsDelivered(detailedBolusInfo.carbs).comment(MainApp.gs(R.string.virtualpump_resultok));
|
||||
}
|
||||
} finally {
|
||||
triggerUIChange();
|
||||
|
@ -443,4 +445,32 @@ public abstract class PumpPluginAbstract extends PluginBase implements PumpInter
|
|||
return new PumpEnactResult().success(false).enacted(false).comment(MainApp.gs(resourceId));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canHandleDST() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ManufacturerType manufacturer() {
|
||||
return pumpStatus.pumpType.getManufacturer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PumpType model() {
|
||||
return pumpStatus.pumpType;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void timeDateOrTimeZoneChanged() {
|
||||
}
|
||||
|
||||
|
||||
public void refreshCustomActionsList() {
|
||||
MainApp.bus().post(new EventCustomActionsChanged());
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
package info.nightscout.androidaps.plugins.pump.common.data;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
|
||||
public class TempBasalPair {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(L.PUMPCOMM);
|
||||
|
||||
@Expose
|
||||
protected double insulinRate = 0.0d;
|
||||
@Expose
|
||||
protected int durationMinutes = 0;
|
||||
@Expose
|
||||
protected boolean isPercent = false;
|
||||
|
||||
private Long start;
|
||||
private Long end;
|
||||
|
||||
public TempBasalPair() {
|
||||
}
|
||||
|
||||
|
||||
public TempBasalPair(double insulinRate, boolean isPercent, int durationMinutes) {
|
||||
this.insulinRate = insulinRate;
|
||||
this.isPercent = isPercent;
|
||||
this.durationMinutes = durationMinutes;
|
||||
}
|
||||
|
||||
|
||||
public double getInsulinRate() {
|
||||
return insulinRate;
|
||||
}
|
||||
|
||||
|
||||
public void setInsulinRate(double insulinRate) {
|
||||
this.insulinRate = insulinRate;
|
||||
}
|
||||
|
||||
|
||||
public int getDurationMinutes() {
|
||||
return durationMinutes;
|
||||
}
|
||||
|
||||
|
||||
public void setDurationMinutes(int durationMinutes) {
|
||||
this.durationMinutes = durationMinutes;
|
||||
}
|
||||
|
||||
|
||||
public boolean isPercent() {
|
||||
return isPercent;
|
||||
}
|
||||
|
||||
|
||||
public void setIsPercent(boolean yesIsPercent) {
|
||||
this.isPercent = yesIsPercent;
|
||||
}
|
||||
|
||||
public void setStartTime(Long startTime) {
|
||||
this.start = startTime;
|
||||
}
|
||||
|
||||
|
||||
public void setEndTime(Long endTime) {
|
||||
this.end = endTime;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TempBasalPair [" + "Rate=" + insulinRate + ", DurationMinutes=" + durationMinutes + ", IsPercent="
|
||||
+ isPercent + "]";
|
||||
}
|
||||
}
|
|
@ -3,8 +3,6 @@ package info.nightscout.androidaps.plugins.pump.common.hw.rileylink;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.pump.common.data.PumpStatus;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RFSpy;
|
||||
|
@ -38,7 +36,6 @@ public abstract class RileyLinkCommunicationManager {
|
|||
private static final int ALLOWED_PUMP_UNREACHABLE = 10 * 60 * 1000; // 10 minutes
|
||||
|
||||
protected final RFSpy rfspy;
|
||||
protected final Context context;
|
||||
protected int receiverDeviceAwakeForMinutes = 1; // override this in constructor of specific implementation
|
||||
protected String receiverDeviceID; // String representation of receiver device (ex. Pump (xxxxxx) or Pod (yyyyyy))
|
||||
protected long lastGoodReceiverCommunicationTime = 0;
|
||||
|
@ -51,8 +48,7 @@ public abstract class RileyLinkCommunicationManager {
|
|||
private int timeoutCount = 0;
|
||||
|
||||
|
||||
public RileyLinkCommunicationManager(Context context, RFSpy rfspy) {
|
||||
this.context = context;
|
||||
public RileyLinkCommunicationManager(RFSpy rfspy) {
|
||||
this.rfspy = rfspy;
|
||||
this.rileyLinkServiceData = RileyLinkUtil.getRileyLinkServiceData();
|
||||
RileyLinkUtil.setRileyLinkCommunicationManager(this);
|
||||
|
@ -125,7 +121,6 @@ public abstract class RileyLinkCommunicationManager {
|
|||
}
|
||||
|
||||
|
||||
|
||||
// FIXME change wakeup
|
||||
// TODO we might need to fix this. Maybe make pump awake for shorter time (battery factor for pump) - Andy
|
||||
public void wakeUp(int duration_minutes, boolean force) {
|
||||
|
@ -143,8 +138,8 @@ public abstract class RileyLinkCommunicationManager {
|
|||
LOG.info("Waking pump...");
|
||||
|
||||
byte[] pumpMsgContent = createPumpMessageContent(RLMessageType.ReadSimpleData); // simple
|
||||
RFSpyResponse resp = rfspy.transmitThenReceive(new RadioPacket(pumpMsgContent), (byte)0, (byte)200,
|
||||
(byte)0, (byte)0, 25000, (byte)0);
|
||||
RFSpyResponse resp = rfspy.transmitThenReceive(new RadioPacket(pumpMsgContent), (byte) 0, (byte) 200,
|
||||
(byte) 0, (byte) 0, 25000, (byte) 0);
|
||||
if (isLogEnabled())
|
||||
LOG.info("wakeup: raw response is " + ByteUtil.shortHexString(resp.getRaw()));
|
||||
|
||||
|
@ -225,8 +220,8 @@ public abstract class RileyLinkCommunicationManager {
|
|||
for (int j = 0; j < tries; j++) {
|
||||
|
||||
byte[] pumpMsgContent = createPumpMessageContent(RLMessageType.ReadSimpleData);
|
||||
RFSpyResponse resp = rfspy.transmitThenReceive(new RadioPacket(pumpMsgContent), (byte)0, (byte)0,
|
||||
(byte)0, (byte)0, 1250, (byte)0);
|
||||
RFSpyResponse resp = rfspy.transmitThenReceive(new RadioPacket(pumpMsgContent), (byte) 0, (byte) 0,
|
||||
(byte) 0, (byte) 0, 1250, (byte) 0);
|
||||
if (resp.wasTimeout()) {
|
||||
LOG.error("scanForPump: Failed to find pump at frequency {}", frequencies[i]);
|
||||
} else if (resp.looksLikeRadioPacket()) {
|
||||
|
@ -258,7 +253,7 @@ public abstract class RileyLinkCommunicationManager {
|
|||
trial.tries++;
|
||||
}
|
||||
sumRSSI += -99.0 * (trial.tries - trial.successes);
|
||||
trial.averageRSSI2 = (double)(sumRSSI) / (double)(trial.tries);
|
||||
trial.averageRSSI2 = (double) (sumRSSI) / (double) (trial.tries);
|
||||
|
||||
trial.calculateAverage();
|
||||
|
||||
|
@ -273,7 +268,7 @@ public abstract class RileyLinkCommunicationManager {
|
|||
FrequencyTrial one = results.trials.get(k);
|
||||
|
||||
stringBuilder.append(String.format("Scan Result[%s]: Freq=%s, avg RSSI = %s\n", "" + k, ""
|
||||
+ one.frequencyMHz, "" + one.averageRSSI + ", RSSIs =" + one.rssiList));
|
||||
+ one.frequencyMHz, "" + one.averageRSSI + ", RSSIs =" + one.rssiList));
|
||||
}
|
||||
|
||||
LOG.info(stringBuilder.toString());
|
||||
|
@ -315,7 +310,7 @@ public abstract class RileyLinkCommunicationManager {
|
|||
// RLMessage msg = makeRLMessage(RLMessageType.ReadSimpleData);
|
||||
byte[] pumpMsgContent = createPumpMessageContent(RLMessageType.ReadSimpleData);
|
||||
RadioPacket pkt = new RadioPacket(pumpMsgContent);
|
||||
RFSpyResponse resp = rfspy.transmitThenReceive(pkt, (byte)0, (byte)0, (byte)0, (byte)0, SCAN_TIMEOUT, (byte)0);
|
||||
RFSpyResponse resp = rfspy.transmitThenReceive(pkt, (byte) 0, (byte) 0, (byte) 0, (byte) 0, SCAN_TIMEOUT, (byte) 0);
|
||||
if (resp.wasTimeout()) {
|
||||
LOG.warn("tune_tryFrequency: no pump response at frequency {}", freqMHz);
|
||||
} else if (resp.looksLikeRadioPacket()) {
|
||||
|
@ -327,8 +322,8 @@ public abstract class RileyLinkCommunicationManager {
|
|||
LOG.warn("tune_tryFrequency: saw response level {} at frequency {}", radioResponse.rssi, freqMHz);
|
||||
return calculateRssi(radioResponse.rssi);
|
||||
} else {
|
||||
LOG.warn("tune_tryFrequency: invalid radio response:"
|
||||
+ ByteUtil.shortHexString(radioResponse.getPayload()));
|
||||
LOG.warn("tune_tryFrequency: invalid radio response:"
|
||||
+ ByteUtil.shortHexString(radioResponse.getPayload()));
|
||||
}
|
||||
|
||||
} catch (RileyLinkCommunicationException e) {
|
||||
|
@ -350,7 +345,7 @@ public abstract class RileyLinkCommunicationManager {
|
|||
// Try again at larger step size
|
||||
stepsize += 0.05;
|
||||
} else {
|
||||
if ((int)(evenBetterFrequency * 100) == (int)(betterFrequency * 100)) {
|
||||
if ((int) (evenBetterFrequency * 100) == (int) (betterFrequency * 100)) {
|
||||
// value did not change, so we're done.
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLin
|
|||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicCommandType;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.PumpDeviceState;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.defs.OmnipodCommandType;
|
||||
|
||||
/**
|
||||
* Created by andy on 5/19/18.
|
||||
|
@ -23,10 +24,11 @@ public class RLHistoryItem {
|
|||
|
||||
private RileyLinkTargetDevice targetDevice;
|
||||
private PumpDeviceState pumpDeviceState;
|
||||
private OmnipodCommandType omnipodCommandType;
|
||||
|
||||
|
||||
public RLHistoryItem(RileyLinkServiceState serviceState, RileyLinkError errorCode,
|
||||
RileyLinkTargetDevice targetDevice) {
|
||||
RileyLinkTargetDevice targetDevice) {
|
||||
this.targetDevice = targetDevice;
|
||||
this.dateTime = new LocalDateTime();
|
||||
this.serviceState = serviceState;
|
||||
|
@ -50,6 +52,13 @@ public class RLHistoryItem {
|
|||
}
|
||||
|
||||
|
||||
public RLHistoryItem(OmnipodCommandType omnipodCommandType) {
|
||||
this.dateTime = new LocalDateTime();
|
||||
this.omnipodCommandType = omnipodCommandType;
|
||||
source = RLHistoryItemSource.OmnipodCommand;
|
||||
}
|
||||
|
||||
|
||||
public LocalDateTime getDateTime() {
|
||||
return dateTime;
|
||||
}
|
||||
|
@ -71,7 +80,7 @@ public class RLHistoryItem {
|
|||
switch (this.source) {
|
||||
case RileyLink:
|
||||
return "State: " + MainApp.gs(serviceState.getResourceId(targetDevice))
|
||||
+ (this.errorCode == null ? "" : ", Error Code: " + errorCode);
|
||||
+ (this.errorCode == null ? "" : ", Error Code: " + errorCode);
|
||||
|
||||
case MedtronicPump:
|
||||
return MainApp.gs(pumpDeviceState.getResourceId());
|
||||
|
@ -79,6 +88,9 @@ public class RLHistoryItem {
|
|||
case MedtronicCommand:
|
||||
return medtronicCommandType.name();
|
||||
|
||||
case OmnipodCommand:
|
||||
return omnipodCommandType.name();
|
||||
|
||||
default:
|
||||
return "Unknown Description";
|
||||
}
|
||||
|
@ -97,7 +109,8 @@ public class RLHistoryItem {
|
|||
public enum RLHistoryItemSource {
|
||||
RileyLink("RileyLink"), //
|
||||
MedtronicPump("Medtronic"), //
|
||||
MedtronicCommand("Medtronic");
|
||||
MedtronicCommand("Medtronic"), //
|
||||
OmnipodCommand("Omnipod");
|
||||
|
||||
private String desc;
|
||||
|
||||
|
|
|
@ -33,7 +33,6 @@ import info.nightscout.androidaps.data.Profile;
|
|||
import info.nightscout.androidaps.data.PumpEnactResult;
|
||||
import info.nightscout.androidaps.db.Source;
|
||||
import info.nightscout.androidaps.db.TemporaryBasal;
|
||||
import info.nightscout.androidaps.events.EventCustomActionsChanged;
|
||||
import info.nightscout.androidaps.events.EventRefreshOverview;
|
||||
import info.nightscout.androidaps.interfaces.PluginDescription;
|
||||
import info.nightscout.androidaps.interfaces.PluginType;
|
||||
|
@ -1560,11 +1559,6 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
this.hasTimeDateOrTimeZoneChanged = true;
|
||||
}
|
||||
|
||||
private void refreshCustomActionsList() {
|
||||
MainApp.bus().post(new EventCustomActionsChanged());
|
||||
}
|
||||
|
||||
|
||||
public void setEnableCustomAction(MedtronicCustomActionType customAction, boolean isEnabled) {
|
||||
|
||||
if (customAction == MedtronicCustomActionType.ClearBolusBlock) {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.comm;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.SystemClock;
|
||||
|
||||
import org.joda.time.LocalDateTime;
|
||||
|
@ -71,8 +70,8 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
private boolean doWakeUpBeforeCommand = true;
|
||||
|
||||
|
||||
public MedtronicCommunicationManager(Context context, RFSpy rfspy) {
|
||||
super(context, rfspy);
|
||||
public MedtronicCommunicationManager(RFSpy rfspy) {
|
||||
super(rfspy);
|
||||
medtronicCommunicationManager = this;
|
||||
this.medtronicConverter = new MedtronicConverter();
|
||||
this.pumpHistoryDecoder = new MedtronicPumpHistoryDecoder();
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.data.dto;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -18,18 +16,10 @@ import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
|
|||
* <p>
|
||||
* Just need a class to keep the pair together, for parcel transport.
|
||||
*/
|
||||
public class TempBasalPair {
|
||||
public class TempBasalPair extends info.nightscout.androidaps.plugins.pump.common.data.TempBasalPair {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(L.PUMPCOMM);
|
||||
|
||||
@Expose
|
||||
private double insulinRate = 0.0d;
|
||||
@Expose
|
||||
private int durationMinutes = 0;
|
||||
@Expose
|
||||
private boolean isPercent = false;
|
||||
|
||||
|
||||
public TempBasalPair() {
|
||||
}
|
||||
|
||||
|
@ -42,6 +32,8 @@ public class TempBasalPair {
|
|||
* @param isPercent
|
||||
*/
|
||||
public TempBasalPair(byte rateByte, int startTimeByte, boolean isPercent) {
|
||||
super();
|
||||
|
||||
int rateInt = ByteUtil.asUINT8(rateByte);
|
||||
|
||||
if (isPercent)
|
||||
|
@ -53,13 +45,6 @@ public class TempBasalPair {
|
|||
}
|
||||
|
||||
|
||||
public TempBasalPair(double insulinRate, boolean isPercent, int durationMinutes) {
|
||||
this.insulinRate = insulinRate;
|
||||
this.isPercent = isPercent;
|
||||
this.durationMinutes = durationMinutes;
|
||||
}
|
||||
|
||||
|
||||
public TempBasalPair(byte[] response) {
|
||||
|
||||
if (L.isEnabled(L.PUMPCOMM))
|
||||
|
@ -80,33 +65,8 @@ public class TempBasalPair {
|
|||
}
|
||||
|
||||
|
||||
public double getInsulinRate() {
|
||||
return insulinRate;
|
||||
}
|
||||
|
||||
|
||||
public void setInsulinRate(double insulinRate) {
|
||||
this.insulinRate = insulinRate;
|
||||
}
|
||||
|
||||
|
||||
public int getDurationMinutes() {
|
||||
return durationMinutes;
|
||||
}
|
||||
|
||||
|
||||
public void setDurationMinutes(int durationMinutes) {
|
||||
this.durationMinutes = durationMinutes;
|
||||
}
|
||||
|
||||
|
||||
public boolean isPercent() {
|
||||
return isPercent;
|
||||
}
|
||||
|
||||
|
||||
public void setIsPercent(boolean yesIsPercent) {
|
||||
this.isPercent = yesIsPercent;
|
||||
public TempBasalPair(double insulinRate, boolean isPercent, int durationMinutes) {
|
||||
super(insulinRate, isPercent, durationMinutes);
|
||||
}
|
||||
|
||||
|
||||
|
@ -160,10 +120,4 @@ public class TempBasalPair {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TempBasalPair [" + "Rate=" + insulinRate + ", DurationMinutes=" + durationMinutes + ", IsPercent="
|
||||
+ isPercent + "]";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -109,7 +109,7 @@ public class RileyLinkMedtronicService extends RileyLinkService {
|
|||
RileyLinkUtil.setRileyLinkBLE(rileyLinkBLE);
|
||||
|
||||
// init rileyLinkCommunicationManager
|
||||
medtronicCommunicationManager = new MedtronicCommunicationManager(context, rfspy);
|
||||
medtronicCommunicationManager = new MedtronicCommunicationManager(rfspy);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,514 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.text.Spanned;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.crashlytics.android.Crashlytics;
|
||||
import com.joanzapata.iconify.widget.IconTextView;
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.events.EventExtendedBolusChange;
|
||||
import info.nightscout.androidaps.events.EventPumpStatusChanged;
|
||||
import info.nightscout.androidaps.events.EventTempBasalChange;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.common.SubscriberFragment;
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkError;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkServiceState;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.dialog.RileyLinkStatusActivity;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.events.EventOmnipodDeviceStatusChange;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.events.EventOmnipodPumpValuesChanged;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.service.OmnipodPumpStatus;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodUtil;
|
||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
|
||||
import info.nightscout.androidaps.queue.events.EventQueueChanged;
|
||||
import info.nightscout.androidaps.utils.DateUtil;
|
||||
import info.nightscout.androidaps.utils.DecimalFormatter;
|
||||
import info.nightscout.androidaps.utils.SetWarnColor;
|
||||
|
||||
/**
|
||||
* Created by andy on 4.8.2019
|
||||
*/
|
||||
public class OmnipodFragment extends SubscriberFragment {
|
||||
|
||||
private static Logger LOG = LoggerFactory.getLogger(L.PUMP);
|
||||
|
||||
@BindView(R.id.omnipod_lastconnection)
|
||||
TextView lastConnectionView;
|
||||
@BindView(R.id.omnipod_lastbolus)
|
||||
TextView lastBolusView;
|
||||
@BindView(R.id.omnipod_basabasalrate)
|
||||
TextView basaBasalRateView;
|
||||
|
||||
@BindView(R.id.omnipod_tempbasal)
|
||||
TextView tempBasalView;
|
||||
@BindView(R.id.omnipod_pumpstate_battery)
|
||||
TextView batteryView;
|
||||
@BindView(R.id.omnipod_rl_status)
|
||||
IconTextView rileyLinkStatus;
|
||||
@BindView(R.id.omnipod_reservoir)
|
||||
TextView reservoirView;
|
||||
@BindView(R.id.omnipod_errors)
|
||||
TextView errorsView;
|
||||
@BindView(R.id.omnipod_queue)
|
||||
TextView queueView;
|
||||
@BindView(R.id.overview_pumpstatuslayout_omnipod)
|
||||
LinearLayout pumpStatusLayout;
|
||||
@BindView(R.id.overview_pump_omnipod)
|
||||
TextView overviewPumpOmnipodView;
|
||||
@BindView(R.id.omnipod_pod_status)
|
||||
IconTextView pumpStatusIconView;
|
||||
@BindView(R.id.omnipod_refresh)
|
||||
Button refreshButton;
|
||||
private Handler loopHandler = new Handler();
|
||||
private static Activity localActivity;
|
||||
|
||||
static Button refreshButtonStatic;
|
||||
|
||||
private Runnable refreshLoop = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
updateGUI();
|
||||
loopHandler.postDelayed(refreshLoop, 60 * 1000L);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
public OmnipodFragment() {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
loopHandler.postDelayed(refreshLoop, 60 * 1000L);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
loopHandler.removeCallbacks(refreshLoop);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
try {
|
||||
View view = inflater.inflate(R.layout.omnipod_fragment, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
|
||||
overviewPumpOmnipodView.setBackgroundColor(MainApp.sResources.getColor(R.color.colorInitializingBorder));
|
||||
|
||||
rileyLinkStatus.setText(getTranslation(RileyLinkServiceState.NotStarted.getResourceId(getTargetDevice())));
|
||||
rileyLinkStatus.setTextSize(14);
|
||||
|
||||
pumpStatusIconView.setTextColor(Color.WHITE);
|
||||
pumpStatusIconView.setTextSize(14);
|
||||
pumpStatusIconView.setText("{fa-bed}");
|
||||
|
||||
refreshButtonStatic = refreshButton;
|
||||
|
||||
return view;
|
||||
} catch (Exception e) {
|
||||
Crashlytics.logException(e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@OnClick(R.id.omnipod_pod_mgmt)
|
||||
void onHistoryClick() {
|
||||
// TODO
|
||||
// if (MedtronicUtil.getPumpStatus().verifyConfiguration()) {
|
||||
// startActivity(new Intent(getContext(), MedtronicHistoryActivity.class));
|
||||
// } else {
|
||||
// MedtronicUtil.displayNotConfiguredDialog(getContext());
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
@OnClick(R.id.omnipod_refresh)
|
||||
void onRefreshClick() {
|
||||
// TODO
|
||||
// if (!MedtronicUtil.getPumpStatus().verifyConfiguration()) {
|
||||
// MedtronicUtil.displayNotConfiguredDialog(getContext());
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if (refreshButtonStatic != null)
|
||||
// refreshButtonStatic.setEnabled(false);
|
||||
//
|
||||
// MedtronicPumpPlugin.getPlugin().resetStatusState();
|
||||
//
|
||||
// ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("Clicked refresh", new Callback() {
|
||||
//
|
||||
// @Override
|
||||
// public void run() {
|
||||
// Activity activity = getActivity();
|
||||
//
|
||||
// if (activity != null) {
|
||||
// activity.runOnUiThread(() -> {
|
||||
// if (refreshButtonStatic != null)
|
||||
// refreshButtonStatic.setEnabled(true);
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
|
||||
@OnClick(R.id.omnipod_stats)
|
||||
void onStatsClick() {
|
||||
if (OmnipodUtil.getPumpStatus().verifyConfiguration()) {
|
||||
startActivity(new Intent(getContext(), RileyLinkStatusActivity.class));
|
||||
} else {
|
||||
OmnipodUtil.displayNotConfiguredDialog(getContext());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventPumpStatusChanged c) {
|
||||
updateGUI();
|
||||
}
|
||||
|
||||
|
||||
public static void refreshButtonEnabled(boolean enable) {
|
||||
if (localActivity != null) {
|
||||
localActivity.runOnUiThread(() -> {
|
||||
if (refreshButtonStatic != null) {
|
||||
refreshButtonStatic.setEnabled(enable);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static Activity getCustomActivity() {
|
||||
return localActivity;
|
||||
}
|
||||
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventOmnipodDeviceStatusChange eventStatusChange) {
|
||||
if (isLogEnabled())
|
||||
LOG.info("onStatusEvent(EventOmnipodDeviceStatusChange): {}", eventStatusChange);
|
||||
Activity activity = getActivity();
|
||||
|
||||
if (activity != null) {
|
||||
localActivity = activity;
|
||||
activity.runOnUiThread(() -> {
|
||||
OmnipodPumpStatus pumpStatus = OmnipodUtil.getPumpStatus();
|
||||
setDeviceStatus(pumpStatus);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private synchronized void setDeviceStatus(OmnipodPumpStatus pumpStatus) {
|
||||
|
||||
pumpStatus.rileyLinkServiceState = (RileyLinkServiceState) checkStatusSet(pumpStatus.rileyLinkServiceState,
|
||||
RileyLinkUtil.getServiceState());
|
||||
|
||||
if (pumpStatus.rileyLinkServiceState != null && rileyLinkStatus != null) {
|
||||
|
||||
int resourceId = pumpStatus.rileyLinkServiceState.getResourceId(getTargetDevice());
|
||||
rileyLinkStatus.setTextColor(Color.WHITE);
|
||||
rileyLinkStatus.setTextSize(14);
|
||||
|
||||
if (pumpStatus.rileyLinkServiceState == RileyLinkServiceState.NotStarted) {
|
||||
rileyLinkStatus.setText(getTranslation(resourceId));
|
||||
rileyLinkStatus.setTextSize(14);
|
||||
} else if (pumpStatus.rileyLinkServiceState.isConnecting()) {
|
||||
rileyLinkStatus.setText("{fa-bluetooth-b spin} " + getTranslation(resourceId));
|
||||
} else if (pumpStatus.rileyLinkServiceState.isError()) {
|
||||
|
||||
RileyLinkError rileyLinkError = RileyLinkUtil.getError();
|
||||
|
||||
if (rileyLinkError == null)
|
||||
rileyLinkStatus.setText("{fa-bluetooth-b} " + getTranslation(resourceId));
|
||||
else
|
||||
rileyLinkStatus.setText("{fa-bluetooth-b} "
|
||||
+ getTranslation(rileyLinkError.getResourceId(RileyLinkTargetDevice.MedtronicPump)));
|
||||
|
||||
rileyLinkStatus.setTextColor(Color.RED);
|
||||
} else {
|
||||
rileyLinkStatus.setText("{fa-bluetooth-b} " + getTranslation(resourceId));
|
||||
}
|
||||
}
|
||||
|
||||
pumpStatus.rileyLinkError = (RileyLinkError) checkStatusSet(pumpStatus.rileyLinkError, RileyLinkUtil.getError());
|
||||
|
||||
if (errorsView != null) {
|
||||
if (pumpStatus.rileyLinkError != null) {
|
||||
int resourceId = pumpStatus.rileyLinkError.getResourceId(getTargetDevice());
|
||||
errorsView.setText(getTranslation(resourceId));
|
||||
} else
|
||||
errorsView.setText("-");
|
||||
}
|
||||
|
||||
// pumpStatus.pumpDeviceState = (PumpDeviceState) checkStatusSet(pumpStatus.pumpDeviceState,
|
||||
// MedtronicUtil.getPumpDeviceState());
|
||||
//
|
||||
if (pumpStatusIconView != null) {
|
||||
//
|
||||
// if (pumpStatus.pumpDeviceState != null) {
|
||||
//
|
||||
// switch (pumpStatus.pumpDeviceState) {
|
||||
// case Sleeping:
|
||||
// pumpStatusIconView.setText("{fa-bed} "); // + pumpStatus.pumpDeviceState.name());
|
||||
// break;
|
||||
//
|
||||
// case NeverContacted:
|
||||
// case WakingUp:
|
||||
// case PumpUnreachable:
|
||||
// case ErrorWhenCommunicating:
|
||||
// case TimeoutWhenCommunicating:
|
||||
// case InvalidConfiguration:
|
||||
// pumpStatusIconView.setText(" " + getTranslation(pumpStatus.pumpDeviceState.getResourceId()));
|
||||
// break;
|
||||
//
|
||||
// case Active: {
|
||||
// MedtronicCommandType cmd = MedtronicUtil.getCurrentCommand();
|
||||
//
|
||||
// LOG.debug("Command: " + cmd);
|
||||
//
|
||||
// if (cmd == null)
|
||||
// pumpStatusIconView.setText(" " + MainApp.gs(pumpStatus.pumpDeviceState.getResourceId()));
|
||||
// else {
|
||||
// Integer resourceId = cmd.getResourceId();
|
||||
//
|
||||
// if (cmd == MedtronicCommandType.GetHistoryData) {
|
||||
//
|
||||
// if (MedtronicUtil.frameNumber == null) {
|
||||
// pumpStatusIconView.setText(MainApp.gs(
|
||||
// R.string.medtronic_cmd_desc_get_history_request, MedtronicUtil.pageNumber));
|
||||
// } else {
|
||||
// pumpStatusIconView.setText(MainApp.gs(resourceId, MedtronicUtil.pageNumber,
|
||||
// MedtronicUtil.frameNumber));
|
||||
// }
|
||||
//
|
||||
// } else {
|
||||
// if (resourceId == null) {
|
||||
// pumpStatusIconView.setText(" " + cmd.getCommandDescription());
|
||||
// } else {
|
||||
// pumpStatusIconView.setText(" " + getTranslation(resourceId));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// break;
|
||||
//
|
||||
// default:
|
||||
// LOG.warn("Unknown pump state: " + pumpStatus.pumpDeviceState);
|
||||
// }
|
||||
// } else {
|
||||
// pumpStatusIconView.setText("{fa-bed} ");
|
||||
// }
|
||||
|
||||
// TODO
|
||||
pumpStatusIconView.setText("{fa-bed} ");
|
||||
}
|
||||
|
||||
if (queueView != null) {
|
||||
Spanned status = ConfigBuilderPlugin.getPlugin().getCommandQueue().spannedStatus();
|
||||
if (status.toString().equals("")) {
|
||||
queueView.setVisibility(View.GONE);
|
||||
} else {
|
||||
queueView.setVisibility(View.VISIBLE);
|
||||
queueView.setText(status);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public Object checkStatusSet(Object object1, Object object2) {
|
||||
if (object1 == null) {
|
||||
return object2;
|
||||
} else {
|
||||
if (!object1.equals(object2)) {
|
||||
return object2;
|
||||
} else
|
||||
return object1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public RileyLinkTargetDevice getTargetDevice() {
|
||||
return RileyLinkTargetDevice.Omnipod;
|
||||
}
|
||||
|
||||
|
||||
public String getTranslation(int resourceId) {
|
||||
return MainApp.gs(resourceId);
|
||||
}
|
||||
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventOmnipodPumpValuesChanged s) {
|
||||
if (isLogEnabled())
|
||||
LOG.debug("EventOmnipodPumpValuesChanged triggered");
|
||||
updateGUI();
|
||||
}
|
||||
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventTempBasalChange s) {
|
||||
updateGUI();
|
||||
}
|
||||
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventExtendedBolusChange s) {
|
||||
updateGUI();
|
||||
}
|
||||
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventQueueChanged s) {
|
||||
updateGUI();
|
||||
}
|
||||
|
||||
|
||||
// GUI functions
|
||||
@Override
|
||||
protected void updateGUI() {
|
||||
Activity activity = getActivity();
|
||||
if (activity != null && basaBasalRateView != null)
|
||||
activity.runOnUiThread(() -> {
|
||||
|
||||
if (lastConnectionView == null) // ui not yet initialized
|
||||
return;
|
||||
|
||||
localActivity = activity;
|
||||
OmnipodPumpPlugin plugin = OmnipodPumpPlugin.getPlugin();
|
||||
OmnipodPumpStatus pumpStatus = OmnipodUtil.getPumpStatus();
|
||||
|
||||
setDeviceStatus(pumpStatus);
|
||||
|
||||
// last connection
|
||||
String minAgo = DateUtil.minAgo(pumpStatus.lastConnection);
|
||||
long min = (System.currentTimeMillis() - pumpStatus.lastConnection) / 1000 / 60;
|
||||
if (pumpStatus.lastConnection + 60 * 1000 > System.currentTimeMillis()) {
|
||||
lastConnectionView.setText(R.string.combo_pump_connected_now);
|
||||
lastConnectionView.setTextColor(Color.WHITE);
|
||||
} else if (pumpStatus.lastConnection + 30 * 60 * 1000 < System.currentTimeMillis()) {
|
||||
|
||||
if (min < 60) {
|
||||
lastConnectionView.setText(MainApp.gs(R.string.minago, min));
|
||||
} else if (min < 1440) {
|
||||
int h = (int) (min / 60);
|
||||
|
||||
lastConnectionView.setText(MainApp.gq(R.plurals.objective_hours, h, h) + " "
|
||||
+ MainApp.gs(R.string.ago));
|
||||
} else {
|
||||
|
||||
int h = (int) (min / 60);
|
||||
int d = h / 24;
|
||||
// h = h - (d * 24);
|
||||
|
||||
lastConnectionView.setText(MainApp.gq(R.plurals.objective_days, d, d) + " "
|
||||
+ MainApp.gs(R.string.ago));
|
||||
}
|
||||
lastConnectionView.setTextColor(Color.RED);
|
||||
} else {
|
||||
lastConnectionView.setText(minAgo);
|
||||
lastConnectionView.setTextColor(Color.WHITE);
|
||||
}
|
||||
|
||||
// last bolus
|
||||
Double bolus = pumpStatus.lastBolusAmount;
|
||||
Date bolusTime = pumpStatus.lastBolusTime;
|
||||
if (bolus != null && bolusTime != null) {
|
||||
long agoMsc = System.currentTimeMillis() - pumpStatus.lastBolusTime.getTime();
|
||||
double bolusMinAgo = agoMsc / 60d / 1000d;
|
||||
String unit = MainApp.gs(R.string.insulin_unit_shortname);
|
||||
String ago;
|
||||
if ((agoMsc < 60 * 1000)) {
|
||||
ago = MainApp.gs(R.string.combo_pump_connected_now);
|
||||
} else if (bolusMinAgo < 60) {
|
||||
ago = DateUtil.minAgo(pumpStatus.lastBolusTime.getTime());
|
||||
} else {
|
||||
ago = DateUtil.hourAgo(pumpStatus.lastBolusTime.getTime());
|
||||
}
|
||||
lastBolusView.setText(MainApp.gs(R.string.combo_last_bolus, bolus, unit, ago));
|
||||
} else {
|
||||
lastBolusView.setText("");
|
||||
}
|
||||
|
||||
// base basal rate
|
||||
basaBasalRateView.setText("(" + (pumpStatus.activeProfileName) + ") "
|
||||
+ MainApp.gs(R.string.pump_basebasalrate, plugin.getBaseBasalRate()));
|
||||
|
||||
if (ConfigBuilderPlugin.getPlugin().getActivePump().isFakingTempsByExtendedBoluses()) {
|
||||
if (TreatmentsPlugin.getPlugin().isInHistoryRealTempBasalInProgress()) {
|
||||
tempBasalView.setText(TreatmentsPlugin.getPlugin()
|
||||
.getRealTempBasalFromHistory(System.currentTimeMillis()).toStringFull());
|
||||
} else {
|
||||
tempBasalView.setText("");
|
||||
}
|
||||
} else {
|
||||
// v2 plugin
|
||||
if (TreatmentsPlugin.getPlugin().isTempBasalInProgress()) {
|
||||
tempBasalView.setText(TreatmentsPlugin.getPlugin()
|
||||
.getTempBasalFromHistory(System.currentTimeMillis()).toStringFull());
|
||||
} else {
|
||||
tempBasalView.setText("");
|
||||
}
|
||||
}
|
||||
|
||||
// battery
|
||||
// TODO this might need to be removed, I am not sure if pods have battery status
|
||||
batteryView.setText("{fa-battery-" + (pumpStatus.batteryRemaining / 25) + "} ");
|
||||
// if (MedtronicUtil.getBatteryType() == BatteryType.None || pumpStatus.batteryVoltage == null) {
|
||||
// batteryView.setText("{fa-battery-" + (pumpStatus.batteryRemaining / 25) + "} ");
|
||||
// } else {
|
||||
// batteryView.setText("{fa-battery-" + (pumpStatus.batteryRemaining / 25) + "} " + pumpStatus.batteryRemaining + "%" + String.format(" (%.2f V)", pumpStatus.batteryVoltage));
|
||||
// }
|
||||
SetWarnColor.setColorInverse(batteryView, pumpStatus.batteryRemaining, 25d, 10d);
|
||||
|
||||
// reservoir
|
||||
reservoirView.setText(DecimalFormatter.to0Decimal(pumpStatus.reservoirRemainingUnits) + " / "
|
||||
+ pumpStatus.reservoirFullUnits + " " + MainApp.gs(R.string.insulin_unit_shortname));
|
||||
SetWarnColor.setColorInverse(reservoirView, pumpStatus.reservoirRemainingUnits, 50d, 20d);
|
||||
|
||||
errorsView.setText(pumpStatus.getErrorInfo());
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private boolean isLogEnabled() {
|
||||
return L.isEnabled(L.PUMP);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,848 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.ServiceConnection;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.SystemClock;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.joda.time.LocalDateTime;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import info.nightscout.androidaps.BuildConfig;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.DetailedBolusInfo;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.data.PumpEnactResult;
|
||||
import info.nightscout.androidaps.db.Source;
|
||||
import info.nightscout.androidaps.db.TemporaryBasal;
|
||||
import info.nightscout.androidaps.events.EventRefreshOverview;
|
||||
import info.nightscout.androidaps.interfaces.PluginDescription;
|
||||
import info.nightscout.androidaps.interfaces.PluginType;
|
||||
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.general.actions.defs.CustomAction;
|
||||
import info.nightscout.androidaps.plugins.general.actions.defs.CustomActionType;
|
||||
import info.nightscout.androidaps.plugins.pump.common.PumpPluginAbstract;
|
||||
import info.nightscout.androidaps.plugins.pump.common.data.TempBasalPair;
|
||||
import info.nightscout.androidaps.plugins.pump.common.defs.PumpDriverState;
|
||||
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkConst;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.ResetRileyLinkConfigurationTask;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.ServiceTaskExecutor;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.ui.OmnipodUIComm;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.ui.OmnipodUITask;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.defs.OmnipodCommandType;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.defs.OmnipodCustomActionType;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.events.EventOmnipodPumpValuesChanged;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.service.OmnipodPumpStatus;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.service.RileyLinkOmnipodService;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodUtil;
|
||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
|
||||
import info.nightscout.androidaps.utils.SP;
|
||||
|
||||
/**
|
||||
* Created by andy on 23.04.18.
|
||||
*
|
||||
* @author Andy Rozman (andy.rozman@gmail.com)
|
||||
*/
|
||||
public class OmnipodPumpPlugin extends PumpPluginAbstract implements PumpInterface {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(L.PUMP);
|
||||
|
||||
protected static OmnipodPumpPlugin plugin = null;
|
||||
private RileyLinkOmnipodService omnipodService;
|
||||
private OmnipodPumpStatus pumpStatusLocal = null;
|
||||
private OmnipodUIComm omnipodUIComm = new OmnipodUIComm();
|
||||
|
||||
// variables for handling statuses and history
|
||||
private boolean firstRun = true;
|
||||
private boolean isRefresh = false;
|
||||
private boolean isBasalProfileInvalid = false;
|
||||
private boolean basalProfileChanged = false;
|
||||
private boolean isInitialized = false;
|
||||
private OmnipodCommunicationManager omnipodCommunicationManager;
|
||||
|
||||
public static boolean isBusy = false;
|
||||
private List<Long> busyTimestamps = new ArrayList<>();
|
||||
private boolean sentIdToFirebase = false;
|
||||
private boolean hasTimeDateOrTimeZoneChanged = false;
|
||||
|
||||
private Profile currentProfile;
|
||||
|
||||
|
||||
private OmnipodPumpPlugin() {
|
||||
|
||||
super(new PluginDescription() //
|
||||
.mainType(PluginType.PUMP) //
|
||||
.fragmentClass(OmnipodFragment.class.getName()) //
|
||||
.pluginName(R.string.omnipod_name) //
|
||||
.shortName(R.string.omnipod_name_short) //
|
||||
.preferencesId(R.xml.pref_omnipod) //
|
||||
.description(R.string.description_pump_omnipod), //
|
||||
PumpType.Insulet_Omnipod
|
||||
);
|
||||
|
||||
displayConnectionMessages = false;
|
||||
|
||||
serviceConnection = new ServiceConnection() {
|
||||
|
||||
public void onServiceDisconnected(ComponentName name) {
|
||||
if (isLoggingEnabled())
|
||||
LOG.debug("RileyLinkOmnipodService is disconnected");
|
||||
omnipodService = null;
|
||||
}
|
||||
|
||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||
if (isLoggingEnabled())
|
||||
LOG.debug("RileyLinkOmnipodService is connected");
|
||||
RileyLinkOmnipodService.LocalBinder mLocalBinder = (RileyLinkOmnipodService.LocalBinder) service;
|
||||
omnipodService = mLocalBinder.getServiceInstance();
|
||||
|
||||
new Thread(() -> {
|
||||
|
||||
for (int i = 0; i < 20; i++) {
|
||||
SystemClock.sleep(5000);
|
||||
|
||||
if (OmnipodUtil.getPumpStatus() != null) {
|
||||
if (isLoggingEnabled())
|
||||
LOG.debug("Starting OmniPod-RileyLink service");
|
||||
if (OmnipodUtil.getPumpStatus().setNotInPreInit()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static OmnipodPumpPlugin getPlugin() {
|
||||
if (plugin == null)
|
||||
plugin = new OmnipodPumpPlugin();
|
||||
return plugin;
|
||||
}
|
||||
|
||||
|
||||
private String getLogPrefix() {
|
||||
return "OmnipodPlugin::";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void initPumpStatusData() {
|
||||
|
||||
this.pumpStatusLocal = new OmnipodPumpStatus(pumpDescription);
|
||||
OmnipodUtil.setPumpStatus(pumpStatusLocal);
|
||||
|
||||
pumpStatusLocal.lastConnection = SP.getLong(RileyLinkConst.Prefs.LastGoodDeviceCommunicationTime, 0L);
|
||||
pumpStatusLocal.lastDataTime = new LocalDateTime(pumpStatusLocal.lastConnection);
|
||||
pumpStatusLocal.previousConnection = pumpStatusLocal.lastConnection;
|
||||
|
||||
pumpStatusLocal.refreshConfiguration();
|
||||
|
||||
if (isLoggingEnabled())
|
||||
LOG.debug("initPumpStatusData: {}", this.pumpStatusLocal);
|
||||
|
||||
this.pumpStatus = pumpStatusLocal;
|
||||
|
||||
// set first Omnipod Start
|
||||
if (!SP.contains(OmnipodConst.Statistics.FirstPumpStart)) {
|
||||
SP.putLong(OmnipodConst.Statistics.FirstPumpStart, System.currentTimeMillis());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void onStartCustomActions() {
|
||||
|
||||
// check status every minute (if any status needs refresh we send readStatus command)
|
||||
new Thread(() -> {
|
||||
|
||||
do {
|
||||
SystemClock.sleep(60000);
|
||||
|
||||
if (this.isInitialized) {
|
||||
clearBusyQueue();
|
||||
}
|
||||
|
||||
} while (serviceRunning);
|
||||
|
||||
}).start();
|
||||
}
|
||||
|
||||
|
||||
public Class getServiceClass() {
|
||||
return RileyLinkOmnipodService.class;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String deviceID() {
|
||||
return "Omnipod";
|
||||
}
|
||||
|
||||
|
||||
// Pump Plugin
|
||||
|
||||
private boolean isServiceSet() {
|
||||
return omnipodService != null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isInitialized() {
|
||||
if (isLoggingEnabled() && displayConnectionMessages)
|
||||
LOG.debug(getLogPrefix() + "isInitialized");
|
||||
return isServiceSet() && isInitialized;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isBusy() {
|
||||
if (isLoggingEnabled() && displayConnectionMessages)
|
||||
LOG.debug(getLogPrefix() + "isBusy");
|
||||
|
||||
if (isServiceSet()) {
|
||||
|
||||
if (isBusy)
|
||||
return true;
|
||||
|
||||
if (busyTimestamps.size() > 0) {
|
||||
|
||||
clearBusyQueue();
|
||||
|
||||
if (busyTimestamps.size() > 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private synchronized void clearBusyQueue() {
|
||||
|
||||
if (busyTimestamps.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Set<Long> deleteFromQueue = new HashSet<>();
|
||||
|
||||
for (Long busyTimestamp : busyTimestamps) {
|
||||
|
||||
if (System.currentTimeMillis() > busyTimestamp) {
|
||||
deleteFromQueue.add(busyTimestamp);
|
||||
}
|
||||
}
|
||||
|
||||
if (deleteFromQueue.size() == busyTimestamps.size()) {
|
||||
busyTimestamps.clear();
|
||||
//setEnableCustomAction(MedtronicCustomActionType.ClearBolusBlock, false);
|
||||
}
|
||||
|
||||
if (deleteFromQueue.size() > 0) {
|
||||
busyTimestamps.removeAll(deleteFromQueue);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isConnected() {
|
||||
if (isLoggingEnabled() && displayConnectionMessages)
|
||||
LOG.debug(getLogPrefix() + "isConnected");
|
||||
return isServiceSet() && omnipodService.isInitialized();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isConnecting() {
|
||||
if (isLoggingEnabled() && displayConnectionMessages)
|
||||
LOG.debug(getLogPrefix() + "isConnecting");
|
||||
return !isServiceSet() || !omnipodService.isInitialized();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void getPumpStatus() {
|
||||
|
||||
if (firstRun) {
|
||||
initializePump(!isRefresh);
|
||||
}
|
||||
|
||||
// getPodPumpStatus();
|
||||
//
|
||||
// if (firstRun) {
|
||||
// initializePump(!isRefresh);
|
||||
// } else {
|
||||
// refreshAnyStatusThatNeedsToBeRefreshed();
|
||||
// }
|
||||
//
|
||||
// MainApp.bus().post(new EventMedtronicPumpValuesChanged());
|
||||
}
|
||||
|
||||
|
||||
void resetStatusState() {
|
||||
firstRun = true;
|
||||
isRefresh = true;
|
||||
}
|
||||
|
||||
|
||||
private void setRefreshButtonEnabled(boolean enabled) {
|
||||
OmnipodFragment.refreshButtonEnabled(enabled);
|
||||
}
|
||||
|
||||
|
||||
private void initializePump(boolean realInit) {
|
||||
|
||||
if (isLoggingEnabled())
|
||||
LOG.info(getLogPrefix() + "initializePump - start");
|
||||
|
||||
if (omnipodCommunicationManager == null) {
|
||||
omnipodCommunicationManager = OmnipodCommunicationManager.getInstance();
|
||||
}
|
||||
|
||||
// setRefreshButtonEnabled(false);
|
||||
//
|
||||
// getPodPumpStatus();
|
||||
//
|
||||
// if (isRefresh) {
|
||||
// if (isPumpNotReachable()) {
|
||||
// if (isLoggingEnabled())
|
||||
// LOG.error(getLogPrefix() + "initializePump::Pump unreachable.");
|
||||
// MedtronicUtil.sendNotification(MedtronicNotificationType.PumpUnreachable);
|
||||
//
|
||||
// setRefreshButtonEnabled(true);
|
||||
//
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// MedtronicUtil.dismissNotification(MedtronicNotificationType.PumpUnreachable);
|
||||
// }
|
||||
//
|
||||
// this.pumpState = PumpDriverState.Connected;
|
||||
//
|
||||
// pumpStatusLocal.setLastCommunicationToNow();
|
||||
// setRefreshButtonEnabled(true);
|
||||
|
||||
// TODO need to read status and BasalProfile if pod inited and pod status and set correct commands enabled
|
||||
|
||||
if (!isRefresh) {
|
||||
pumpState = PumpDriverState.Initialized;
|
||||
}
|
||||
|
||||
if (!sentIdToFirebase) {
|
||||
Bundle params = new Bundle();
|
||||
params.putString("version", BuildConfig.VERSION);
|
||||
MainApp.getFirebaseAnalytics().logEvent("OmnipodPumpInit", params);
|
||||
|
||||
sentIdToFirebase = true;
|
||||
}
|
||||
|
||||
isInitialized = true;
|
||||
// this.pumpState = PumpDriverState.Initialized;
|
||||
|
||||
this.firstRun = false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isThisProfileSet(Profile profile) {
|
||||
|
||||
// status was not yet read from pod
|
||||
if (currentProfile == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return (currentProfile.isProfileTheSame(profile));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long lastDataTime() {
|
||||
getPodPumpStatusObject();
|
||||
|
||||
if (pumpStatusLocal.lastConnection != 0) {
|
||||
return pumpStatusLocal.lastConnection;
|
||||
}
|
||||
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public double getBaseBasalRate() {
|
||||
|
||||
if (currentProfile != null) {
|
||||
int hour = (new GregorianCalendar()).get(Calendar.HOUR_OF_DAY);
|
||||
return currentProfile.getBasalTimeFromMidnight(getTimeInS(hour * 60));
|
||||
} else {
|
||||
return 0.0d;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public double getReservoirLevel() {
|
||||
// TODO
|
||||
return getPodPumpStatusObject().reservoirRemainingUnits;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getBatteryLevel() {
|
||||
// TODO
|
||||
return getPodPumpStatusObject().batteryRemaining;
|
||||
}
|
||||
|
||||
|
||||
private OmnipodPumpStatus getPodPumpStatusObject() {
|
||||
if (pumpStatusLocal == null) {
|
||||
// FIXME I don't know why this happens
|
||||
if (isLoggingEnabled())
|
||||
LOG.warn("!!!! Reset Pump Status Local");
|
||||
pumpStatusLocal = OmnipodUtil.getPumpStatus();
|
||||
}
|
||||
|
||||
return pumpStatusLocal;
|
||||
}
|
||||
|
||||
|
||||
protected void triggerUIChange() {
|
||||
MainApp.bus().post(new EventOmnipodPumpValuesChanged());
|
||||
}
|
||||
|
||||
|
||||
@NonNull
|
||||
protected PumpEnactResult deliverBolus(final DetailedBolusInfo detailedBolusInfo) {
|
||||
|
||||
LOG.info(getLogPrefix() + "deliverBolus - {}", detailedBolusInfo);
|
||||
|
||||
setRefreshButtonEnabled(false);
|
||||
|
||||
try {
|
||||
|
||||
OmnipodUITask responseTask = omnipodUIComm.executeCommand(OmnipodCommandType.SetBolus,
|
||||
detailedBolusInfo.insulin);
|
||||
|
||||
Boolean response = (Boolean) responseTask.returnData;
|
||||
|
||||
setRefreshButtonEnabled(true);
|
||||
|
||||
if (response) {
|
||||
|
||||
TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, true);
|
||||
|
||||
// we subtract insulin, exact amount will be visible with next remainingInsulin update.
|
||||
getPodPumpStatusObject().reservoirRemainingUnits -= detailedBolusInfo.insulin;
|
||||
|
||||
incrementStatistics(detailedBolusInfo.isSMB ? OmnipodConst.Statistics.SMBBoluses
|
||||
: OmnipodConst.Statistics.StandardBoluses);
|
||||
|
||||
// calculate time for bolus and set driver to busy for that time
|
||||
// TODO fix this
|
||||
int bolusTime = (int) (detailedBolusInfo.insulin * 42.0d);
|
||||
long time = System.currentTimeMillis() + (bolusTime * 1000);
|
||||
|
||||
this.busyTimestamps.add(time);
|
||||
|
||||
return new PumpEnactResult().success(true) //
|
||||
.enacted(true) //
|
||||
.bolusDelivered(detailedBolusInfo.insulin) //
|
||||
.carbsDelivered(detailedBolusInfo.carbs);
|
||||
|
||||
} else {
|
||||
return new PumpEnactResult() //
|
||||
.success(false) //
|
||||
.enacted(false) //
|
||||
.comment(MainApp.gs(R.string.medtronic_cmd_bolus_could_not_be_delivered));
|
||||
}
|
||||
|
||||
} finally {
|
||||
finishAction("Bolus");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private PumpEnactResult setNotReachable(boolean isBolus, boolean success) {
|
||||
setRefreshButtonEnabled(true);
|
||||
|
||||
if (success) {
|
||||
return new PumpEnactResult() //
|
||||
.success(true) //
|
||||
.enacted(false);
|
||||
} else {
|
||||
return new PumpEnactResult() //
|
||||
.success(false) //
|
||||
.enacted(false) //
|
||||
.comment(MainApp.gs(R.string.medtronic_pump_status_pump_unreachable));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void stopBolusDelivering() {
|
||||
|
||||
LOG.info(getLogPrefix() + "stopBolusDelivering");
|
||||
|
||||
setRefreshButtonEnabled(false);
|
||||
|
||||
try {
|
||||
|
||||
OmnipodUITask responseTask = omnipodUIComm.executeCommand(OmnipodCommandType.CancelBolus);
|
||||
|
||||
Boolean response = (Boolean) responseTask.returnData;
|
||||
|
||||
setRefreshButtonEnabled(true);
|
||||
|
||||
LOG.info(getLogPrefix() + "stopBolusDelivering - wasSuccess={}", response);
|
||||
|
||||
if (response) {
|
||||
// TODO fix bolus record with cancel
|
||||
|
||||
//TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, true);
|
||||
}
|
||||
|
||||
} finally {
|
||||
finishAction("Bolus");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void incrementStatistics(String statsKey) {
|
||||
long currentCount = SP.getLong(statsKey, 0L);
|
||||
currentCount++;
|
||||
SP.putLong(statsKey, currentCount);
|
||||
}
|
||||
|
||||
|
||||
// if enforceNew===true current temp basal is canceled and new TBR set (duration is prolonged),
|
||||
// if false and the same rate is requested enacted=false and success=true is returned and TBR is not changed
|
||||
@Override
|
||||
public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, Profile profile,
|
||||
boolean enforceNew) {
|
||||
|
||||
getPodPumpStatusObject();
|
||||
|
||||
setRefreshButtonEnabled(false);
|
||||
|
||||
if (isLoggingEnabled())
|
||||
LOG.info(getLogPrefix() + "setTempBasalAbsolute: rate: {}, duration={}", absoluteRate, durationInMinutes);
|
||||
|
||||
// read current TBR
|
||||
TempBasalPair tbrCurrent = readTBR();
|
||||
|
||||
if (tbrCurrent != null) {
|
||||
if (isLoggingEnabled())
|
||||
LOG.info(getLogPrefix() + "setTempBasalAbsolute: Current Basal: duration: {} min, rate={}",
|
||||
tbrCurrent.getDurationMinutes(), tbrCurrent.getInsulinRate());
|
||||
}
|
||||
|
||||
if (tbrCurrent != null && !enforceNew) {
|
||||
|
||||
if (OmnipodUtil.isSame(tbrCurrent.getInsulinRate(), absoluteRate)) {
|
||||
if (isLoggingEnabled())
|
||||
LOG.info(getLogPrefix() + "setTempBasalAbsolute - No enforceNew and same rate. Exiting.");
|
||||
finishAction("TBR");
|
||||
return new PumpEnactResult().success(true).enacted(false);
|
||||
}
|
||||
}
|
||||
|
||||
// if TBR is running we will cancel it.
|
||||
if (tbrCurrent != null) {
|
||||
if (isLoggingEnabled())
|
||||
LOG.info(getLogPrefix() + "setTempBasalAbsolute - TBR running - so canceling it.");
|
||||
|
||||
// CANCEL
|
||||
OmnipodUITask responseTask2 = omnipodUIComm.executeCommand(OmnipodCommandType.CancelTemporaryBasal);
|
||||
|
||||
Boolean response = (Boolean) responseTask2.returnData;
|
||||
|
||||
if (response) {
|
||||
if (isLoggingEnabled())
|
||||
LOG.info(getLogPrefix() + "setTempBasalAbsolute - Current TBR cancelled.");
|
||||
} else {
|
||||
if (isLoggingEnabled())
|
||||
LOG.error(getLogPrefix() + "setTempBasalAbsolute - Cancel TBR failed.");
|
||||
|
||||
finishAction("TBR");
|
||||
|
||||
return new PumpEnactResult().success(false).enacted(false)
|
||||
.comment(MainApp.gs(R.string.medtronic_cmd_cant_cancel_tbr_stop_op));
|
||||
}
|
||||
}
|
||||
|
||||
// now start new TBR
|
||||
OmnipodUITask responseTask = omnipodUIComm.executeCommand(OmnipodCommandType.SetTemporaryBasal,
|
||||
absoluteRate, durationInMinutes);
|
||||
|
||||
Boolean response = (Boolean) responseTask.returnData;
|
||||
|
||||
if (isLoggingEnabled())
|
||||
LOG.info(getLogPrefix() + "setTempBasalAbsolute - setTBR. Response: " + response);
|
||||
|
||||
if (response) {
|
||||
pumpStatusLocal.tempBasalStart = System.currentTimeMillis();
|
||||
pumpStatusLocal.tempBasalAmount = absoluteRate;
|
||||
pumpStatusLocal.tempBasalLength = durationInMinutes;
|
||||
pumpStatusLocal.tempBasalEnd = getTimeInFutureFromMinutes(durationInMinutes);
|
||||
|
||||
TemporaryBasal tempStart = new TemporaryBasal() //
|
||||
.date(System.currentTimeMillis()) //
|
||||
.duration(durationInMinutes) //
|
||||
.absolute(absoluteRate) //
|
||||
.source(Source.USER);
|
||||
|
||||
TreatmentsPlugin.getPlugin().addToHistoryTempBasal(tempStart);
|
||||
|
||||
incrementStatistics(OmnipodConst.Statistics.TBRsSet);
|
||||
|
||||
finishAction("TBR");
|
||||
|
||||
return new PumpEnactResult().success(true).enacted(true) //
|
||||
.absolute(absoluteRate).duration(durationInMinutes);
|
||||
|
||||
} else {
|
||||
finishAction("TBR");
|
||||
|
||||
return new PumpEnactResult().success(false).enacted(false) //
|
||||
.comment(MainApp.gs(R.string.medtronic_cmd_tbr_could_not_be_delivered));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private TempBasalPair readTBR() {
|
||||
// TODO we can do it like this or read status from pod ??
|
||||
if (pumpStatusLocal.tempBasalEnd < System.currentTimeMillis()) {
|
||||
// TBR done
|
||||
pumpStatusLocal.clearTemporaryBasal();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return pumpStatusLocal.getTemporaryBasal();
|
||||
}
|
||||
|
||||
|
||||
private void finishAction(String overviewKey) {
|
||||
if (overviewKey != null)
|
||||
MainApp.bus().post(new EventRefreshOverview(overviewKey));
|
||||
|
||||
triggerUIChange();
|
||||
|
||||
setRefreshButtonEnabled(true);
|
||||
}
|
||||
|
||||
|
||||
private long getTimeInFutureFromMinutes(int minutes) {
|
||||
return System.currentTimeMillis() + getTimeInMs(minutes);
|
||||
}
|
||||
|
||||
|
||||
private long getTimeInMs(int minutes) {
|
||||
return getTimeInS(minutes) * 1000L;
|
||||
}
|
||||
|
||||
private int getTimeInS(int minutes) {
|
||||
return minutes * 60;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public PumpEnactResult cancelTempBasal(boolean enforceNew) {
|
||||
|
||||
if (isLoggingEnabled())
|
||||
LOG.info(getLogPrefix() + "cancelTempBasal - started");
|
||||
|
||||
setRefreshButtonEnabled(false);
|
||||
|
||||
TempBasalPair tbrCurrent = readTBR();
|
||||
|
||||
if (tbrCurrent == null) {
|
||||
|
||||
if (isLoggingEnabled())
|
||||
LOG.info(getLogPrefix() + "cancelTempBasal - TBR already canceled.");
|
||||
finishAction("TBR");
|
||||
return new PumpEnactResult().success(true).enacted(false);
|
||||
|
||||
}
|
||||
|
||||
OmnipodUITask responseTask2 = omnipodUIComm.executeCommand(OmnipodCommandType.CancelTemporaryBasal);
|
||||
|
||||
Boolean response = (Boolean) responseTask2.returnData;
|
||||
|
||||
finishAction("TBR");
|
||||
|
||||
if (response) {
|
||||
if (isLoggingEnabled())
|
||||
LOG.info(getLogPrefix() + "cancelTempBasal - Cancel TBR successful.");
|
||||
|
||||
TemporaryBasal tempBasal = new TemporaryBasal() //
|
||||
.date(System.currentTimeMillis()) //
|
||||
.duration(0) //
|
||||
.source(Source.USER);
|
||||
|
||||
TreatmentsPlugin.getPlugin().addToHistoryTempBasal(tempBasal);
|
||||
|
||||
return new PumpEnactResult().success(true).enacted(true) //
|
||||
.isTempCancel(true);
|
||||
} else {
|
||||
if (isLoggingEnabled())
|
||||
LOG.info(getLogPrefix() + "cancelTempBasal - Cancel TBR failed.");
|
||||
|
||||
return new PumpEnactResult().success(response).enacted(response) //
|
||||
.comment(MainApp.gs(R.string.medtronic_cmd_cant_cancel_tbr));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String serialNumber() {
|
||||
return getPodPumpStatusObject().podNumber;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PumpEnactResult setNewBasalProfile(Profile profile) {
|
||||
if (isLoggingEnabled())
|
||||
LOG.info(getLogPrefix() + "setNewBasalProfile");
|
||||
|
||||
// this shouldn't be needed, but let's do check if profile setting we are setting is same as current one
|
||||
if (this.currentProfile != null && this.currentProfile.isProfileTheSame(profile)) {
|
||||
return new PumpEnactResult() //
|
||||
.success(true) //
|
||||
.enacted(false) //
|
||||
.comment(MainApp.gs(R.string.medtronic_cmd_basal_profile_not_set_is_same));
|
||||
}
|
||||
|
||||
setRefreshButtonEnabled(false);
|
||||
|
||||
OmnipodUITask responseTask = omnipodUIComm.executeCommand(OmnipodCommandType.SetBasalProfile,
|
||||
profile);
|
||||
|
||||
Boolean response = (Boolean) responseTask.returnData;
|
||||
|
||||
if (isLoggingEnabled())
|
||||
LOG.info(getLogPrefix() + "Basal Profile was set: " + response);
|
||||
|
||||
if (response) {
|
||||
this.currentProfile = profile;
|
||||
return new PumpEnactResult().success(true).enacted(true);
|
||||
} else {
|
||||
return new PumpEnactResult().success(response).enacted(response) //
|
||||
.comment(MainApp.gs(R.string.medtronic_cmd_basal_profile_could_not_be_set));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// OPERATIONS not supported by Pump or Plugin
|
||||
|
||||
private List<CustomAction> customActions = null;
|
||||
|
||||
private CustomAction customActionResetRLConfig = new CustomAction(
|
||||
R.string.medtronic_custom_action_reset_rileylink, OmnipodCustomActionType.ResetRileyLinkConfiguration, true);
|
||||
|
||||
private CustomAction customActionInitPod = new CustomAction(
|
||||
R.string.omnipod_cmd_init_pod, OmnipodCustomActionType.InitPod, true);
|
||||
|
||||
private CustomAction customActionDeactivatePod = new CustomAction(
|
||||
R.string.omnipod_cmd_deactivate_pod, OmnipodCustomActionType.DeactivatePod, false);
|
||||
|
||||
private CustomAction customActionResetPod = new CustomAction(
|
||||
R.string.omnipod_cmd_reset_pod, OmnipodCustomActionType.ResetPodStatus, true);
|
||||
|
||||
|
||||
@Override
|
||||
public List<CustomAction> getCustomActions() {
|
||||
|
||||
if (customActions == null) {
|
||||
this.customActions = Arrays.asList(
|
||||
customActionResetRLConfig);
|
||||
}
|
||||
|
||||
return this.customActions;
|
||||
}
|
||||
|
||||
// TODO we need to brainstorm how we want to do this -- Andy
|
||||
@Override
|
||||
public void executeCustomAction(CustomActionType customActionType) {
|
||||
|
||||
OmnipodCustomActionType mcat = (OmnipodCustomActionType) customActionType;
|
||||
|
||||
switch (mcat) {
|
||||
|
||||
case ResetRileyLinkConfiguration: {
|
||||
ServiceTaskExecutor.startTask(new ResetRileyLinkConfigurationTask());
|
||||
}
|
||||
break;
|
||||
|
||||
case InitPod: {
|
||||
omnipodUIComm.executeCommand(OmnipodCommandType.InitPod);
|
||||
}
|
||||
break;
|
||||
|
||||
case DeactivatePod: {
|
||||
omnipodUIComm.executeCommand(OmnipodCommandType.DeactivatePod);
|
||||
}
|
||||
break;
|
||||
|
||||
case ResetPodStatus: {
|
||||
omnipodUIComm.executeCommand(OmnipodCommandType.ResetPodStatus);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void timeDateOrTimeZoneChanged() {
|
||||
|
||||
// if (isLoggingEnabled())
|
||||
// LOG.warn(getLogPrefix() + "Time, Date and/or TimeZone changed. ");
|
||||
//
|
||||
// this.hasTimeDateOrTimeZoneChanged = true;
|
||||
}
|
||||
|
||||
|
||||
public void setEnableCustomAction(OmnipodCustomActionType customAction, boolean isEnabled) {
|
||||
|
||||
switch (customAction) {
|
||||
|
||||
case InitPod: {
|
||||
this.customActionInitPod.setEnabled(isEnabled);
|
||||
}
|
||||
break;
|
||||
|
||||
case DeactivatePod: {
|
||||
this.customActionDeactivatePod.setEnabled(isEnabled);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
refreshCustomActionsList();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.comm;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkCommunicationManager;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkConst;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RFSpy;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.RLMessage;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RLMessageType;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.TempBasalPair;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.data.PodCommResponse;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodUtil;
|
||||
import info.nightscout.androidaps.utils.SP;
|
||||
|
||||
/**
|
||||
* Created by andy on 4.8.2019
|
||||
*/
|
||||
public class OmnipodCommunicationManager extends RileyLinkCommunicationManager implements OmnipodCommunicationManagerInterface {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(L.PUMPCOMM);
|
||||
|
||||
private static OmnipodCommunicationManager omnipodCommunicationManager;
|
||||
String errorMessage;
|
||||
|
||||
|
||||
public OmnipodCommunicationManager(Context context, RFSpy rfspy) {
|
||||
super(rfspy);
|
||||
omnipodCommunicationManager = this;
|
||||
OmnipodUtil.getPumpStatus().previousConnection = SP.getLong(
|
||||
RileyLinkConst.Prefs.LastGoodDeviceCommunicationTime, 0L);
|
||||
}
|
||||
|
||||
|
||||
public static OmnipodCommunicationManager getInstance() {
|
||||
return omnipodCommunicationManager;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void configurePumpSpecificSettings() {
|
||||
pumpStatus = MedtronicUtil.getPumpStatus();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public <E extends RLMessage> E createResponseMessage(byte[] payload, Class<E> clazz) {
|
||||
//PumpMessage pumpMessage = new PumpMessage(payload);
|
||||
//eturn (E) pumpMessage;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean tryToConnectToDevice() {
|
||||
return false; //isDeviceReachable(true);
|
||||
}
|
||||
|
||||
|
||||
public String getErrorResponse() {
|
||||
return this.errorMessage;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public byte[] createPumpMessageContent(RLMessageType type) {
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
|
||||
private boolean isLogEnabled() {
|
||||
return L.isEnabled(L.PUMPCOMM);
|
||||
}
|
||||
|
||||
|
||||
// This are just skeleton methods, we need to see what we can get returned and act accordingly
|
||||
|
||||
public PodCommResponse initPod() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public PodCommResponse getPodStatus() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public PodCommResponse deactivatePod() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public PodCommResponse setBasalProfile(Profile profile) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public PodCommResponse resetPodStatus() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public PodCommResponse setBolus(Double parameter) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public PodCommResponse cancelBolus() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public PodCommResponse setTemporaryBasal(TempBasalPair tbr) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public PodCommResponse cancelTemporaryBasal() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.comm;
|
||||
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.TempBasalPair;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.data.PodCommResponse;
|
||||
|
||||
public interface OmnipodCommunicationManagerInterface {
|
||||
|
||||
// TODO add methods that can be used by OmniPod Eros and Omnipod Dash
|
||||
|
||||
/**
|
||||
* Initialize Pod
|
||||
*/
|
||||
PodCommResponse initPod();
|
||||
|
||||
/**
|
||||
* Get Pod Status (is pod running, battery left ?, reservoir, etc)
|
||||
*/
|
||||
PodCommResponse getPodStatus();
|
||||
|
||||
/**
|
||||
* Deactivate Pod
|
||||
*/
|
||||
PodCommResponse deactivatePod();
|
||||
|
||||
/**
|
||||
* Set Basal Profile
|
||||
*/
|
||||
PodCommResponse setBasalProfile(Profile profile);
|
||||
|
||||
/**
|
||||
* Reset Pod status (if we forget to disconnect Pod and want to init new pod, and want to forget current pod)
|
||||
*/
|
||||
PodCommResponse resetPodStatus();
|
||||
|
||||
/**
|
||||
* Set Bolus
|
||||
*
|
||||
* @param amount amount of bolus in U
|
||||
*/
|
||||
PodCommResponse setBolus(Double amount);
|
||||
|
||||
/**
|
||||
* Cancel Bolus (if bolus is already stopped, return acknowledgment)
|
||||
*/
|
||||
PodCommResponse cancelBolus();
|
||||
|
||||
/**
|
||||
* Set Temporary Basal
|
||||
*
|
||||
* @param tbr TempBasalPair object containg amount and duration in minutes
|
||||
*/
|
||||
PodCommResponse setTemporaryBasal(TempBasalPair tbr);
|
||||
|
||||
/**
|
||||
* Cancel Temporary Basal (if TB is already stopped, return acknowledgment)
|
||||
*/
|
||||
PodCommResponse cancelTemporaryBasal();
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.comm.data;
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodResponseType;
|
||||
|
||||
public class PodCommResponse {
|
||||
|
||||
PodResponseType podResponseType;
|
||||
|
||||
Boolean acknowledged;
|
||||
Object customData;
|
||||
Object errorResponse;
|
||||
|
||||
// some status data if it can be returned (battery, reservoir, etc)
|
||||
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.comm.ui;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.defs.OmnipodCommandType;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodUtil;
|
||||
|
||||
/**
|
||||
* Created by andy on 4.8.2019
|
||||
*/
|
||||
public class OmnipodUIComm {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(L.PUMP);
|
||||
|
||||
OmnipodCommunicationManager ocmInstance = null;
|
||||
OmnipodUIPostprocessor uiPostprocessor = new OmnipodUIPostprocessor();
|
||||
|
||||
|
||||
private OmnipodCommunicationManager getCommunicationManager() {
|
||||
if (ocmInstance == null) {
|
||||
ocmInstance = OmnipodCommunicationManager.getInstance();
|
||||
}
|
||||
|
||||
return ocmInstance;
|
||||
}
|
||||
|
||||
|
||||
public synchronized OmnipodUITask executeCommand(OmnipodCommandType commandType, Object... parameters) {
|
||||
|
||||
if (isLogEnabled())
|
||||
LOG.warn("Execute Command: " + commandType.name());
|
||||
|
||||
OmnipodUITask task = new OmnipodUITask(commandType, parameters);
|
||||
|
||||
OmnipodUtil.setCurrentCommand(commandType);
|
||||
|
||||
// new Thread(() -> {
|
||||
// LOG.warn("@@@ Start Thread");
|
||||
//
|
||||
// task.execute(getCommunicationManager());
|
||||
//
|
||||
// LOG.warn("@@@ End Thread");
|
||||
// });
|
||||
|
||||
task.execute(getCommunicationManager());
|
||||
|
||||
// for (int i = 0; i < getMaxWaitTime(commandType); i++) {
|
||||
// synchronized (task) {
|
||||
// // try {
|
||||
// //
|
||||
// // //task.wait(1000);
|
||||
// // } catch (InterruptedException e) {
|
||||
// // LOG.error("executeCommand InterruptedException", e);
|
||||
// // }
|
||||
//
|
||||
//
|
||||
// SystemClock.sleep(1000);
|
||||
// }
|
||||
//
|
||||
// if (task.isReceived()) {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
if (!task.isReceived() && isLogEnabled()) {
|
||||
LOG.warn("Reply not received for " + commandType);
|
||||
}
|
||||
|
||||
task.postProcess(uiPostprocessor);
|
||||
|
||||
return task;
|
||||
|
||||
}
|
||||
|
||||
|
||||
private boolean isLogEnabled() {
|
||||
return L.isEnabled(L.PUMP);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.comm.ui;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.OmnipodPumpPlugin;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.defs.OmnipodCustomActionType;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.service.OmnipodPumpStatus;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodUtil;
|
||||
|
||||
/**
|
||||
* Created by andy on 4.8.2019
|
||||
*/
|
||||
|
||||
public class OmnipodUIPostprocessor {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(L.PUMP);
|
||||
|
||||
OmnipodPumpStatus pumpStatus;
|
||||
OmnipodPumpPlugin omnipodPumpPlugin;
|
||||
|
||||
|
||||
public OmnipodUIPostprocessor() {
|
||||
pumpStatus = OmnipodUtil.getPumpStatus();
|
||||
omnipodPumpPlugin = OmnipodPumpPlugin.getPlugin();
|
||||
}
|
||||
|
||||
|
||||
// this is mostly intended for command that return certain statuses (Remaining Insulin, ...), and
|
||||
// where responses won't be directly used
|
||||
public void postProcessData(OmnipodUITask uiTask) {
|
||||
|
||||
switch (uiTask.commandType) {
|
||||
|
||||
case InitPod: {
|
||||
omnipodPumpPlugin.setEnableCustomAction(OmnipodCustomActionType.InitPod, false);
|
||||
omnipodPumpPlugin.setEnableCustomAction(OmnipodCustomActionType.DeactivatePod, true);
|
||||
}
|
||||
break;
|
||||
|
||||
case DeactivatePod:
|
||||
case ResetPodStatus: {
|
||||
omnipodPumpPlugin.setEnableCustomAction(OmnipodCustomActionType.InitPod, true);
|
||||
omnipodPumpPlugin.setEnableCustomAction(OmnipodCustomActionType.DeactivatePod, false);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
if (isLogEnabled())
|
||||
LOG.trace("Post-processing not implemented for {}.", uiTask.commandType.name());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private boolean isLogEnabled() {
|
||||
return L.isEnabled(L.PUMP);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,184 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.comm.ui;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.TempBasalPair;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.PumpDeviceState;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.events.EventMedtronicPumpValuesChanged;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.defs.OmnipodCommandType;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodResponseType;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.events.EventOmnipodDeviceStatusChange;
|
||||
|
||||
/**
|
||||
* Created by andy on 4.8.2019
|
||||
*/
|
||||
|
||||
public class OmnipodUITask {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(L.PUMP);
|
||||
|
||||
public OmnipodCommandType commandType;
|
||||
public Object returnData;
|
||||
private String errorDescription;
|
||||
private Object[] parameters;
|
||||
private PodResponseType responseType;
|
||||
|
||||
|
||||
public OmnipodUITask(OmnipodCommandType commandType) {
|
||||
this.commandType = commandType;
|
||||
}
|
||||
|
||||
|
||||
public OmnipodUITask(OmnipodCommandType commandType, Object... parameters) {
|
||||
this.commandType = commandType;
|
||||
this.parameters = parameters;
|
||||
}
|
||||
|
||||
|
||||
public void execute(OmnipodCommunicationManager communicationManager) {
|
||||
|
||||
if (isLogEnabled())
|
||||
LOG.debug("OmnipodUITask: @@@ In execute. {}", commandType);
|
||||
|
||||
switch (commandType) {
|
||||
// TODO add commands this is just sample
|
||||
// case PumpModel: {
|
||||
// returnData = communicationManager.getPumpModel();
|
||||
// }
|
||||
// break;
|
||||
|
||||
case InitPod:
|
||||
returnData = communicationManager.initPod();
|
||||
break;
|
||||
|
||||
case DeactivatePod:
|
||||
returnData = communicationManager.deactivatePod();
|
||||
break;
|
||||
|
||||
case ResetPodStatus:
|
||||
returnData = communicationManager.resetPodStatus();
|
||||
break;
|
||||
|
||||
case SetBasalProfile:
|
||||
returnData = communicationManager.setBasalProfile((Profile) parameters[0]);
|
||||
break;
|
||||
|
||||
case SetBolus: {
|
||||
Double amount = getDoubleFromParameters(0);
|
||||
|
||||
if (amount != null)
|
||||
returnData = communicationManager.setBolus(amount);
|
||||
}
|
||||
break;
|
||||
|
||||
case CancelBolus:
|
||||
returnData = communicationManager.cancelBolus();
|
||||
break;
|
||||
|
||||
case SetTemporaryBasal: {
|
||||
TempBasalPair tbr = getTBRSettings();
|
||||
if (tbr != null) {
|
||||
returnData = communicationManager.setTemporaryBasal(tbr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CancelTemporaryBasal:
|
||||
returnData = communicationManager.cancelTemporaryBasal();
|
||||
break;
|
||||
|
||||
|
||||
default: {
|
||||
LOG.warn("This commandType is not supported (yet) - {}.", commandType);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private TempBasalPair getTBRSettings() {
|
||||
return new TempBasalPair(getDoubleFromParameters(0), //
|
||||
false, //
|
||||
getIntegerFromParameters(1));
|
||||
}
|
||||
|
||||
|
||||
private Float getFloatFromParameters(int index) {
|
||||
return (Float) parameters[index];
|
||||
}
|
||||
|
||||
|
||||
public Double getDoubleFromParameters(int index) {
|
||||
return (Double) parameters[index];
|
||||
}
|
||||
|
||||
|
||||
public Integer getIntegerFromParameters(int index) {
|
||||
return (Integer) parameters[index];
|
||||
}
|
||||
|
||||
|
||||
public Object getResult() {
|
||||
return returnData;
|
||||
}
|
||||
|
||||
|
||||
public boolean isReceived() {
|
||||
return (returnData != null || errorDescription != null);
|
||||
}
|
||||
|
||||
|
||||
public void postProcess(OmnipodUIPostprocessor postprocessor) {
|
||||
|
||||
EventOmnipodDeviceStatusChange statusChange;
|
||||
if (isLogEnabled())
|
||||
LOG.debug("OmnipodUITask: @@@ In execute. {}", commandType);
|
||||
|
||||
if (responseType == PodResponseType.Data || responseType == PodResponseType.Acknowledgment) {
|
||||
postprocessor.postProcessData(this);
|
||||
}
|
||||
|
||||
if (responseType == PodResponseType.Invalid) {
|
||||
statusChange = new EventOmnipodDeviceStatusChange(PumpDeviceState.ErrorWhenCommunicating,
|
||||
"Unsupported command in OmnipodUITask");
|
||||
MainApp.bus().post(statusChange);
|
||||
} else if (responseType == PodResponseType.Error) {
|
||||
statusChange = new EventOmnipodDeviceStatusChange(PumpDeviceState.ErrorWhenCommunicating,
|
||||
errorDescription);
|
||||
MainApp.bus().post(statusChange);
|
||||
} else {
|
||||
MainApp.bus().post(new EventMedtronicPumpValuesChanged());
|
||||
MedtronicUtil.getPumpStatus().setLastCommunicationToNow();
|
||||
}
|
||||
|
||||
MedtronicUtil.setCurrentCommand(null);
|
||||
}
|
||||
|
||||
|
||||
public boolean hasData() {
|
||||
return (responseType == PodResponseType.Data || responseType == PodResponseType.Acknowledgment);
|
||||
}
|
||||
|
||||
|
||||
public Object getParameter(int index) {
|
||||
return parameters[index];
|
||||
}
|
||||
|
||||
|
||||
private boolean isLogEnabled() {
|
||||
return L.isEnabled(L.PUMP);
|
||||
}
|
||||
|
||||
|
||||
public PodResponseType getResponseType() {
|
||||
return this.responseType;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.defs;
|
||||
|
||||
/**
|
||||
* Created by andy on 4.8.2019
|
||||
*/
|
||||
public enum OmnipodCommandType {
|
||||
|
||||
InitPod, //
|
||||
DeactivatePod, //
|
||||
SetBasalProfile, //
|
||||
SetBolus, //
|
||||
CancelBolus, //
|
||||
SetTemporaryBasal,
|
||||
CancelTemporaryBasal,
|
||||
ResetPodStatus;
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.defs;
|
||||
|
||||
import info.nightscout.androidaps.plugins.general.actions.defs.CustomActionType;
|
||||
|
||||
/**
|
||||
* Created by andy on 4.8.2019
|
||||
*/
|
||||
|
||||
public enum OmnipodCustomActionType implements CustomActionType {
|
||||
|
||||
ResetRileyLinkConfiguration(), //
|
||||
InitPod(), //
|
||||
DeactivatePod(), //
|
||||
ResetPodStatus(), //
|
||||
;
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return this.name();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.defs;
|
||||
|
||||
/**
|
||||
* Created by andy on 10/18/18.
|
||||
*/
|
||||
|
||||
public enum OmnipodUIResponseType {
|
||||
|
||||
Data,
|
||||
Error,
|
||||
Invalid;
|
||||
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.defs;
|
||||
|
||||
import info.nightscout.androidaps.R;
|
||||
|
||||
/**
|
||||
* Created by andy on 4.8.2019
|
||||
*/
|
||||
|
||||
public enum PodDeviceState {
|
||||
|
||||
// FIXME
|
||||
NeverContacted(R.string.medtronic_pump_status_never_contacted), //
|
||||
Sleeping(R.string.medtronic_pump_status_sleeping), //
|
||||
WakingUp(R.string.medtronic_pump_status_waking_up), //
|
||||
Active(R.string.medtronic_pump_status_active), //
|
||||
ErrorWhenCommunicating(R.string.medtronic_pump_status_error_comm), //
|
||||
TimeoutWhenCommunicating(R.string.medtronic_pump_status_timeout_comm), //
|
||||
// ProblemContacting(R.string.medtronic_pump_status_problem_contacting), //
|
||||
PumpUnreachable(R.string.medtronic_pump_status_pump_unreachable), //
|
||||
InvalidConfiguration(R.string.medtronic_pump_status_invalid_config);
|
||||
|
||||
Integer resourceId = null;
|
||||
|
||||
|
||||
PodDeviceState() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
PodDeviceState(int resourceId) {
|
||||
this.resourceId = resourceId;
|
||||
}
|
||||
|
||||
|
||||
public Integer getResourceId() {
|
||||
return resourceId;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.defs;
|
||||
|
||||
public enum PodResponseType {
|
||||
|
||||
Acknowledgment, // set commands would just acknowledge if data was sent
|
||||
Data, // query commands would return data
|
||||
Error, // communication/response produced an error
|
||||
Invalid // invalid response (not supported, should never be returned)
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.events;
|
||||
|
||||
import info.nightscout.androidaps.events.Event;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkError;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkServiceState;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.PumpDeviceState;
|
||||
|
||||
/**
|
||||
* Created by andy on 4.8.2019
|
||||
*/
|
||||
public class EventOmnipodDeviceStatusChange extends Event {
|
||||
|
||||
public RileyLinkServiceState rileyLinkServiceState;
|
||||
public RileyLinkError rileyLinkError;
|
||||
|
||||
public PumpDeviceState pumpDeviceState;
|
||||
public String errorDescription;
|
||||
|
||||
|
||||
public EventOmnipodDeviceStatusChange(RileyLinkServiceState rileyLinkServiceState) {
|
||||
this(rileyLinkServiceState, null);
|
||||
}
|
||||
|
||||
|
||||
public EventOmnipodDeviceStatusChange(RileyLinkServiceState rileyLinkServiceState, RileyLinkError rileyLinkError) {
|
||||
this.rileyLinkServiceState = rileyLinkServiceState;
|
||||
this.rileyLinkError = rileyLinkError;
|
||||
}
|
||||
|
||||
|
||||
public EventOmnipodDeviceStatusChange(PumpDeviceState pumpDeviceState) {
|
||||
this.pumpDeviceState = pumpDeviceState;
|
||||
}
|
||||
|
||||
|
||||
public EventOmnipodDeviceStatusChange(PumpDeviceState pumpDeviceState, String errorDescription) {
|
||||
this.pumpDeviceState = pumpDeviceState;
|
||||
this.errorDescription = errorDescription;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "EventOmnipodDeviceStatusChange [" + "rileyLinkServiceState=" + rileyLinkServiceState
|
||||
+ ", rileyLinkError=" + rileyLinkError + ", pumpDeviceState=" + pumpDeviceState + ']';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.events;
|
||||
|
||||
import info.nightscout.androidaps.events.Event;
|
||||
|
||||
/**
|
||||
* Created by andy on 04.06.2018.
|
||||
*/
|
||||
public class EventOmnipodPumpValuesChanged extends Event {
|
||||
}
|
|
@ -0,0 +1,157 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.service;
|
||||
|
||||
import org.joda.time.LocalDateTime;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.interfaces.PumpDescription;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.pump.common.data.PumpStatus;
|
||||
import info.nightscout.androidaps.plugins.pump.common.data.TempBasalPair;
|
||||
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkConst;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkError;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkServiceState;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodUtil;
|
||||
import info.nightscout.androidaps.utils.SP;
|
||||
|
||||
/**
|
||||
* Created by andy on 4.8.2019
|
||||
*/
|
||||
public class OmnipodPumpStatus extends PumpStatus {
|
||||
|
||||
private static Logger LOG = LoggerFactory.getLogger(L.PUMP);
|
||||
|
||||
public String errorDescription = null;
|
||||
public String rileyLinkAddress = null;
|
||||
public boolean inPreInit = true;
|
||||
|
||||
// statuses
|
||||
public RileyLinkServiceState rileyLinkServiceState = RileyLinkServiceState.NotStarted;
|
||||
public RileyLinkError rileyLinkError;
|
||||
public double currentBasal = 0;
|
||||
public long tempBasalStart;
|
||||
public long tempBasalEnd;
|
||||
public Double tempBasalAmount = 0.0d;
|
||||
public Integer tempBasalLength;
|
||||
|
||||
private boolean rileyLinkAddressChanged = false;
|
||||
private String regexMac = "([\\da-fA-F]{1,2}(?:\\:|$)){6}";
|
||||
|
||||
|
||||
public String podNumber;
|
||||
|
||||
|
||||
public OmnipodPumpStatus(PumpDescription pumpDescription) {
|
||||
super(pumpDescription);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void initSettings() {
|
||||
this.activeProfileName = "";
|
||||
this.reservoirRemainingUnits = 75d;
|
||||
this.batteryRemaining = 75;
|
||||
this.lastConnection = SP.getLong(OmnipodConst.Statistics.LastGoodPumpCommunicationTime, 0L);
|
||||
this.lastDataTime = new LocalDateTime(this.lastConnection);
|
||||
this.pumpType = PumpType.Insulet_Omnipod;
|
||||
}
|
||||
|
||||
|
||||
public boolean verifyConfiguration() {
|
||||
try {
|
||||
|
||||
this.errorDescription = "-";
|
||||
|
||||
String rileyLinkAddress = SP.getString(RileyLinkConst.Prefs.RileyLinkAddress, null);
|
||||
|
||||
if (rileyLinkAddress == null) {
|
||||
if (isLogEnabled())
|
||||
LOG.debug("RileyLink address invalid: null");
|
||||
this.errorDescription = MainApp.gs(R.string.medtronic_error_rileylink_address_invalid);
|
||||
return false;
|
||||
} else {
|
||||
if (!rileyLinkAddress.matches(regexMac)) {
|
||||
this.errorDescription = MainApp.gs(R.string.medtronic_error_rileylink_address_invalid);
|
||||
if (isLogEnabled())
|
||||
LOG.debug("RileyLink address invalid: {}", rileyLinkAddress);
|
||||
} else {
|
||||
if (!rileyLinkAddress.equals(this.rileyLinkAddress)) {
|
||||
this.rileyLinkAddress = rileyLinkAddress;
|
||||
rileyLinkAddressChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reconfigureService();
|
||||
|
||||
return true;
|
||||
|
||||
} catch (Exception ex) {
|
||||
this.errorDescription = ex.getMessage();
|
||||
LOG.error("Error on Verification: " + ex.getMessage(), ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean reconfigureService() {
|
||||
|
||||
if (!inPreInit && OmnipodUtil.getOmnipodService() != null) {
|
||||
|
||||
if (rileyLinkAddressChanged) {
|
||||
OmnipodUtil.sendBroadcastMessage(RileyLinkConst.Intents.RileyLinkNewAddressSet);
|
||||
rileyLinkAddressChanged = false;
|
||||
}
|
||||
}
|
||||
|
||||
return (!rileyLinkAddressChanged);
|
||||
}
|
||||
|
||||
|
||||
public String getErrorInfo() {
|
||||
verifyConfiguration();
|
||||
|
||||
return (this.errorDescription == null) ? "-" : this.errorDescription;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void refreshConfiguration() {
|
||||
verifyConfiguration();
|
||||
}
|
||||
|
||||
|
||||
public boolean setNotInPreInit() {
|
||||
this.inPreInit = false;
|
||||
|
||||
return reconfigureService();
|
||||
}
|
||||
|
||||
|
||||
public void clearTemporaryBasal() {
|
||||
this.tempBasalStart = 0L;
|
||||
this.tempBasalEnd = 0L;
|
||||
this.tempBasalAmount = 0.0d;
|
||||
this.tempBasalLength = 0;
|
||||
}
|
||||
|
||||
|
||||
private boolean isLogEnabled() {
|
||||
return L.isEnabled(L.PUMP);
|
||||
}
|
||||
|
||||
public TempBasalPair getTemporaryBasal() {
|
||||
|
||||
TempBasalPair tbr = new TempBasalPair();
|
||||
tbr.setDurationMinutes(tempBasalLength);
|
||||
tbr.setInsulinRate(tempBasalAmount);
|
||||
tbr.setStartTime(tempBasalStart);
|
||||
tbr.setEndTime(tempBasalEnd);
|
||||
|
||||
return tbr;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,155 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.service;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkCommunicationManager;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkConst;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RFSpy;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RileyLinkBLE;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkEncodingType;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkServiceState;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkService;
|
||||
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.comm.OmnipodCommunicationManager;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodUtil;
|
||||
import info.nightscout.androidaps.utils.SP;
|
||||
|
||||
/**
|
||||
* Created by andy on 4.8.2019
|
||||
* RileyLinkOmnipodService is intended to stay running when the gui-app is closed.
|
||||
*/
|
||||
public class RileyLinkOmnipodService extends RileyLinkService {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(L.PUMPCOMM);
|
||||
|
||||
private static RileyLinkOmnipodService instance;
|
||||
|
||||
OmnipodCommunicationManager omnipodCommunicationManager;
|
||||
OmnipodPumpStatus pumpStatus = null;
|
||||
private IBinder mBinder = new LocalBinder();
|
||||
|
||||
|
||||
public RileyLinkOmnipodService() {
|
||||
super(MainApp.instance().getApplicationContext());
|
||||
instance = this;
|
||||
if (isLogEnabled())
|
||||
LOG.debug("RileyLinkOmnipodService newly constructed");
|
||||
OmnipodUtil.setOmnipodService(this);
|
||||
pumpStatus = (OmnipodPumpStatus) OmnipodPumpPlugin.getPlugin().getPumpStatusData();
|
||||
}
|
||||
|
||||
|
||||
public static RileyLinkOmnipodService getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
// public static MedtronicCommunicationManager getCommunicationManager() {
|
||||
// return instance.medtronicCommunicationManager;
|
||||
// }
|
||||
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
if (isLogEnabled())
|
||||
LOG.warn("onConfigurationChanged");
|
||||
super.onConfigurationChanged(newConfig);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return mBinder;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RileyLinkEncodingType getEncoding() {
|
||||
return RileyLinkEncodingType.Manchester;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If you have customized RileyLinkServiceData you need to override this
|
||||
*/
|
||||
public void initRileyLinkServiceData() {
|
||||
|
||||
rileyLinkServiceData = new RileyLinkServiceData(RileyLinkTargetDevice.Omnipod);
|
||||
|
||||
RileyLinkUtil.setRileyLinkServiceData(rileyLinkServiceData);
|
||||
RileyLinkUtil.setTargetDevice(RileyLinkTargetDevice.Omnipod);
|
||||
|
||||
// get most recently used RileyLink address
|
||||
rileyLinkServiceData.rileylinkAddress = SP.getString(RileyLinkConst.Prefs.RileyLinkAddress, "");
|
||||
|
||||
rileyLinkBLE = new RileyLinkBLE(this.context); // or this
|
||||
rfspy = new RFSpy(rileyLinkBLE);
|
||||
rfspy.startReader();
|
||||
|
||||
RileyLinkUtil.setRileyLinkBLE(rileyLinkBLE);
|
||||
|
||||
// init rileyLinkCommunicationManager
|
||||
omnipodCommunicationManager = new OmnipodCommunicationManager(context, rfspy);
|
||||
}
|
||||
|
||||
|
||||
public void resetRileyLinkConfiguration() {
|
||||
rfspy.resetRileyLinkConfiguration();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RileyLinkCommunicationManager getDeviceCommunicationManager() {
|
||||
return this.omnipodCommunicationManager;
|
||||
}
|
||||
|
||||
|
||||
public class LocalBinder extends Binder {
|
||||
|
||||
public RileyLinkOmnipodService getServiceInstance() {
|
||||
return RileyLinkOmnipodService.this;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* private functions */
|
||||
|
||||
// PumpInterface - REMOVE
|
||||
|
||||
public boolean isInitialized() {
|
||||
return RileyLinkServiceState.isReady(RileyLinkUtil.getRileyLinkServiceData().serviceState);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getDeviceSpecificBroadcastsIdentifierPrefix() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public boolean handleDeviceSpecificBroadcasts(Intent intent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void registerDeviceSpecificBroadcasts(IntentFilter intentFilter) {
|
||||
}
|
||||
|
||||
|
||||
private boolean isLogEnabled() {
|
||||
return L.isEnabled(L.PUMPCOMM);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.util;
|
||||
|
||||
/**
|
||||
* Created by andy on 4.8.2019
|
||||
*/
|
||||
|
||||
public class OmnipodConst {
|
||||
|
||||
static final String Prefix = "AAPS.Omnipod.";
|
||||
|
||||
public class Prefs {
|
||||
|
||||
//public static final int BatteryType = R.string.pref_key_medtronic_battery_type;
|
||||
}
|
||||
|
||||
public class Statistics {
|
||||
|
||||
public static final String StatsPrefix = "omnipod_";
|
||||
public static final String FirstPumpStart = Prefix + "first_pump_use";
|
||||
public static final String LastGoodPumpCommunicationTime = Prefix + "lastGoodPumpCommunicationTime";
|
||||
public static final String LastGoodPumpFrequency = Prefix + "LastGoodPumpFrequency";
|
||||
public static final String TBRsSet = StatsPrefix + "tbrs_set";
|
||||
public static final String StandardBoluses = StatsPrefix + "std_boluses_delivered";
|
||||
public static final String SMBBoluses = StatsPrefix + "smb_boluses_delivered";
|
||||
public static final String LastPumpHistoryEntry = StatsPrefix + "pump_history_entry";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,170 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.util;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification;
|
||||
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.hw.rileylink.RileyLinkUtil;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.data.RLHistoryItem;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicNotificationType;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.defs.OmnipodCommandType;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.service.OmnipodPumpStatus;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.service.RileyLinkOmnipodService;
|
||||
import info.nightscout.androidaps.utils.OKDialog;
|
||||
|
||||
/**
|
||||
* Created by andy on 4/8/19.
|
||||
*/
|
||||
// FIXME
|
||||
public class OmnipodUtil extends RileyLinkUtil {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(L.PUMPCOMM);
|
||||
|
||||
private static boolean lowLevelDebug = true;
|
||||
private static RileyLinkOmnipodService omnipodService;
|
||||
private static OmnipodPumpStatus omnipodPumpStatus;
|
||||
private static OmnipodCommandType currentCommand;
|
||||
public static Gson gsonInstance = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
|
||||
public static Gson gsonInstancePretty = new GsonBuilder().excludeFieldsWithoutExposeAnnotation()
|
||||
.setPrettyPrinting().create();
|
||||
|
||||
|
||||
public static Gson getGsonInstance() {
|
||||
return gsonInstance;
|
||||
}
|
||||
|
||||
public static Gson getGsonInstancePretty() {
|
||||
return gsonInstancePretty;
|
||||
}
|
||||
|
||||
|
||||
public static int makeUnsignedShort(int b2, int b1) {
|
||||
int k = (b2 & 0xff) << 8 | b1 & 0xff;
|
||||
return k;
|
||||
}
|
||||
|
||||
public static byte[] getByteArrayFromUnsignedShort(int shortValue, boolean returnFixedSize) {
|
||||
byte highByte = (byte) (shortValue >> 8 & 0xFF);
|
||||
byte lowByte = (byte) (shortValue & 0xFF);
|
||||
|
||||
if (highByte > 0) {
|
||||
return createByteArray(highByte, lowByte);
|
||||
} else {
|
||||
return returnFixedSize ? createByteArray(highByte, lowByte) : createByteArray(lowByte);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static byte[] createByteArray(byte... data) {
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
public static byte[] createByteArray(List<Byte> data) {
|
||||
|
||||
byte[] array = new byte[data.size()];
|
||||
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
array[i] = data.get(i);
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
|
||||
public static void sendNotification(MedtronicNotificationType notificationType) {
|
||||
Notification notification = new Notification( //
|
||||
notificationType.getNotificationType(), //
|
||||
MainApp.gs(notificationType.getResourceId()), //
|
||||
notificationType.getNotificationUrgency());
|
||||
MainApp.bus().post(new EventNewNotification(notification));
|
||||
}
|
||||
|
||||
|
||||
public static void sendNotification(MedtronicNotificationType notificationType, Object... parameters) {
|
||||
Notification notification = new Notification( //
|
||||
notificationType.getNotificationType(), //
|
||||
MainApp.gs(notificationType.getResourceId(), parameters), //
|
||||
notificationType.getNotificationUrgency());
|
||||
MainApp.bus().post(new EventNewNotification(notification));
|
||||
}
|
||||
|
||||
|
||||
public static void dismissNotification(MedtronicNotificationType notificationType) {
|
||||
MainApp.bus().post(new EventDismissNotification(notificationType.getNotificationType()));
|
||||
}
|
||||
|
||||
|
||||
public static boolean isLowLevelDebug() {
|
||||
return lowLevelDebug;
|
||||
}
|
||||
|
||||
|
||||
public static void setLowLevelDebug(boolean lowLevelDebug) {
|
||||
OmnipodUtil.lowLevelDebug = lowLevelDebug;
|
||||
}
|
||||
|
||||
|
||||
public static OmnipodCommunicationManager getOmnipodCommunicationManager() {
|
||||
return (OmnipodCommunicationManager) RileyLinkUtil.rileyLinkCommunicationManager;
|
||||
}
|
||||
|
||||
|
||||
public static RileyLinkOmnipodService getOmnipodService() {
|
||||
return OmnipodUtil.omnipodService;
|
||||
}
|
||||
|
||||
|
||||
public static void setOmnipodService(RileyLinkOmnipodService medtronicService) {
|
||||
OmnipodUtil.omnipodService = medtronicService;
|
||||
}
|
||||
|
||||
public static OmnipodCommandType getCurrentCommand() {
|
||||
return OmnipodUtil.currentCommand;
|
||||
}
|
||||
|
||||
|
||||
// FIXME
|
||||
public static void setCurrentCommand(OmnipodCommandType currentCommand) {
|
||||
OmnipodUtil.currentCommand = currentCommand;
|
||||
|
||||
if (currentCommand != null)
|
||||
historyRileyLink.add(new RLHistoryItem(currentCommand));
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static boolean isSame(Double d1, Double d2) {
|
||||
double diff = d1 - d2;
|
||||
|
||||
return (Math.abs(diff) <= 0.000001);
|
||||
}
|
||||
|
||||
|
||||
public static void displayNotConfiguredDialog(Context context) {
|
||||
OKDialog.show(context, MainApp.gs(R.string.combo_warning),
|
||||
MainApp.gs(R.string.medtronic_error_operation_not_possible_no_configuration), null);
|
||||
}
|
||||
|
||||
public static OmnipodPumpStatus getPumpStatus() {
|
||||
return omnipodPumpStatus;
|
||||
}
|
||||
|
||||
public static void setPumpStatus(OmnipodPumpStatus omnipodPumpStatus) {
|
||||
OmnipodUtil.omnipodPumpStatus = omnipodPumpStatus;
|
||||
}
|
||||
}
|
|
@ -10,16 +10,25 @@ public class Round {
|
|||
}
|
||||
return 0d;
|
||||
}
|
||||
|
||||
public static Double floorTo(Double x, Double step) {
|
||||
if (x != 0d) {
|
||||
return Math.floor(x / step) * step;
|
||||
}
|
||||
return 0d;
|
||||
}
|
||||
|
||||
public static Double ceilTo(Double x, Double step) {
|
||||
if (x != 0d) {
|
||||
return Math.ceil(x / step) * step;
|
||||
}
|
||||
return 0d;
|
||||
}
|
||||
|
||||
public static boolean isSame(Double d1, Double d2) {
|
||||
double diff = d1 - d2;
|
||||
|
||||
return (Math.abs(diff) <= 0.000001);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
533
app/src/main/res/layout/omnipod_fragment.xml
Normal file
533
app/src/main/res/layout/omnipod_fragment.xml
Normal file
|
@ -0,0 +1,533 @@
|
|||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context="info.nightscout.androidaps.plugins.pump.omnipod.OmnipodFragment">
|
||||
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_above="@+id/omnipod_buttons"
|
||||
android:fillViewport="true">
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/overview_pumpstatuslayout_omnipod"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:paddingBottom="5dp"
|
||||
android:paddingTop="2dp"
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/overview_pump_omnipod"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:layout_marginRight="5dp"
|
||||
android:gravity="center_vertical|center_horizontal"
|
||||
android:text="@string/initializing"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="2dip"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:layout_marginTop="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/rileylink_status"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="5dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:gravity="center_horizontal"
|
||||
android:paddingEnd="2dp"
|
||||
android:paddingStart="2dp"
|
||||
android:text=":"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<com.joanzapata.iconify.widget.IconTextView
|
||||
android:id="@+id/omnipod_rl_status"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start"
|
||||
android:paddingLeft="5dp"
|
||||
android:text="{fa-bluetooth-b}"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp" />
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="2dip"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:layout_marginTop="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_pod_status"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="5dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:gravity="center_horizontal"
|
||||
android:paddingEnd="2dp"
|
||||
android:paddingStart="2dp"
|
||||
android:text=":"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<com.joanzapata.iconify.widget.IconTextView
|
||||
android:id="@+id/omnipod_pod_status"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start"
|
||||
android:paddingLeft="5dp"
|
||||
android:text="{fa-bluetooth-b}"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp" />
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/omnipod_queue"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="content"
|
||||
android:textAlignment="center" />
|
||||
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="2dip"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:layout_marginTop="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/pump_battery_label"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="5dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:gravity="center_horizontal"
|
||||
android:paddingEnd="2dp"
|
||||
android:paddingStart="2dp"
|
||||
android:text=":"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<com.joanzapata.iconify.widget.IconTextView
|
||||
android:id="@+id/omnipod_pumpstate_battery"
|
||||
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:text=""
|
||||
android:textSize="14sp" />
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="2dip"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:layout_marginTop="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/pump_lastconnection_label"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="5dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:gravity="center_horizontal"
|
||||
android:paddingEnd="2dp"
|
||||
android:paddingStart="2dp"
|
||||
android:text=":"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/omnipod_lastconnection"
|
||||
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"
|
||||
android:layout_height="2dip"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:layout_marginTop="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/pump_lastbolus_label"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="5dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:gravity="center_horizontal"
|
||||
android:paddingEnd="2dp"
|
||||
android:paddingStart="2dp"
|
||||
android:text=":"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/omnipod_lastbolus"
|
||||
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"
|
||||
android:layout_height="2dip"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:layout_marginTop="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/pump_basebasalrate_label"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="5dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:gravity="center_horizontal"
|
||||
android:paddingEnd="2dp"
|
||||
android:paddingStart="2dp"
|
||||
android:text=":"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/omnipod_basabasalrate"
|
||||
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"
|
||||
android:layout_height="2dip"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:layout_marginTop="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/pump_tempbasal_label"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="5dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:gravity="center_horizontal"
|
||||
android:paddingEnd="2dp"
|
||||
android:paddingStart="2dp"
|
||||
android:text=":"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/omnipod_tempbasal"
|
||||
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"
|
||||
android:layout_height="2dip"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:layout_marginTop="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/pump_reservoir_label"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="5dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:gravity="center_horizontal"
|
||||
android:paddingEnd="2dp"
|
||||
android:paddingStart="2dp"
|
||||
android:text=":"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/omnipod_reservoir"
|
||||
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"
|
||||
android:layout_height="2dip"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:layout_marginTop="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/medtronic_errors"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="5dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:gravity="center_horizontal"
|
||||
android:paddingEnd="2dp"
|
||||
android:paddingStart="2dp"
|
||||
android:text=":"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/omnipod_errors"
|
||||
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"
|
||||
android:layout_height="2dip"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:background="@color/listdelimiter" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/omnipod_buttons"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
|
||||
<Button
|
||||
android:id="@+id/omnipod_refresh"
|
||||
style="@style/ButtonSmallFontStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:drawableTop="@drawable/icon_actions_refill"
|
||||
android:paddingLeft="0dp"
|
||||
android:paddingRight="0dp"
|
||||
android:text="@string/combo_refresh" />
|
||||
|
||||
|
||||
<Button
|
||||
android:id="@+id/omnipod_pod_mgmt"
|
||||
style="@style/ButtonSmallFontStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:drawableTop="@drawable/icon_danarhistory"
|
||||
android:paddingLeft="0dp"
|
||||
android:paddingRight="0dp"
|
||||
android:text="@string/omnipod_pod_mgmt" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/omnipod_stats"
|
||||
style="@style/ButtonSmallFontStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:drawableTop="@drawable/icon_danarstats"
|
||||
android:paddingLeft="0dp"
|
||||
android:paddingRight="0dp"
|
||||
android:text="RL Stats" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</FrameLayout>
|
|
@ -1557,6 +1557,31 @@
|
|||
<string name="pump_no_connection_h">No connection for %1$d hour(s) %2$d min</string>
|
||||
<string name="pump_no_connection_d">No connection for %1$d day(s) %2$d hours</string>
|
||||
|
||||
<!-- Omnipod -->
|
||||
|
||||
<!-- Omnipod - Base -->
|
||||
<string name="omnipod_name" translatable="false">Omnipod</string>
|
||||
<string name="omnipod_name_short" translatable="false">POD</string>
|
||||
<string name="description_pump_omnipod">Pump integration for Omnipod, requires RileyLink (with at least 2.0 firmware) device.</string>
|
||||
|
||||
<!-- Omnipod - Fragment -->
|
||||
<string name="omnipod_pod_mgmt">Pod Mgmt</string>
|
||||
<string name="omnipod_pod_status">Pod Status</string>
|
||||
|
||||
<!-- Omnipod - Error -->
|
||||
<string name="omnipod_error_operation_not_possible_no_configuration">Operation is not possible.\n\n You need to configure Omnipod first, before you can use this operation.</string>
|
||||
|
||||
<!-- Omnipod - Pod Mgmt -->
|
||||
<string name="omnipod_cmd_init_pod">Init Pod</string>
|
||||
<string name="omnipod_cmd_deactivate_pod">Deactivate Pod</string>
|
||||
<string name="omnipod_cmd_reset_pod">Reset Pod</string>
|
||||
|
||||
|
||||
<string name="omnipod_namex" translatable="false">Omnipod</string>
|
||||
<string name="omnipod_namex2" translatable="false">Omnipod</string>
|
||||
<string name="omnipod_namexxx" translatable="false">Omnipod</string>
|
||||
|
||||
|
||||
<plurals name="objective_days">
|
||||
<item quantity="one">%1$d day</item>
|
||||
<item quantity="other">%1$d days</item>
|
||||
|
|
15
app/src/main/res/xml/pref_omnipod.xml
Normal file
15
app/src/main/res/xml/pref_omnipod.xml
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<PreferenceCategory android:title="@string/omnipod_name">
|
||||
|
||||
<info.nightscout.androidaps.plugins.pump.common.ui.RileyLinkSelectPreference
|
||||
android:id="@+id/rileylink_mac_address_omnipod"
|
||||
android:enabled="true"
|
||||
android:summary=""
|
||||
android:title="RileyLink Configuration"
|
||||
android:key="@string/pref_key_rileylink_mac_address">
|
||||
<intent android:action="info.nightscout.androidaps.plugins.PumpCommon.dialog.RileyLinkBLEScanActivity" />
|
||||
</info.nightscout.androidaps.plugins.pump.common.ui.RileyLinkSelectPreference>
|
||||
|
||||
</PreferenceCategory>
|
||||
</PreferenceScreen>
|
Loading…
Reference in a new issue