commit
f4b36ae095
|
@ -9,10 +9,10 @@ Hardware requirements:
|
||||||
- A Roche Accu-Chek Combo (any firmware, they all work)
|
- A Roche Accu-Chek Combo (any firmware, they all work)
|
||||||
- A Smartpix or Realtyme device together with the 360 Configuration
|
- A Smartpix or Realtyme device together with the 360 Configuration
|
||||||
Software to configure the pump.
|
Software to configure the pump.
|
||||||
Roche sends these out Smartpix devices and the configuration software
|
Roche sends out Smartpix devices and the configuration software
|
||||||
free of charge to their customers upon request.
|
free of charge to their customers upon request.
|
||||||
- A compatible phone: An Android phone with a phone running LineageOS 14.1 (formerly CyanogenMod)
|
- A compatible phone: An Android phone with a phone running LineageOS 14.1 (formerly CyanogenMod)
|
||||||
- To build AndroidAPS with Combo support you need the lastet Android Studio 3 version
|
- To build AndroidAPS with Combo support you need the latest Android Studio 3 version
|
||||||
|
|
||||||
Limitations:
|
Limitations:
|
||||||
- Extended bolus and multiwave bolus are not supported.
|
- Extended bolus and multiwave bolus are not supported.
|
||||||
|
@ -24,10 +24,11 @@ Limitations:
|
||||||
changes have to be performed manually.
|
changes have to be performed manually.
|
||||||
- There's a bug in the pump's firmware that's triggered when "too much" communication happens
|
- There's a bug in the pump's firmware that's triggered when "too much" communication happens
|
||||||
with the pump. Specifically, this issue occurs when going from just issuing commands to the pump
|
with the pump. Specifically, this issue occurs when going from just issuing commands to the pump
|
||||||
to reading the pumps data and history. For that reason, a minimal amount of data is read from
|
to reading the pump's data and history. For that reason, a minimal amount of data is read from
|
||||||
the pump.
|
the pump.
|
||||||
The bug might still rarely occur and causes the pump to not accept any connection
|
The bug might still rarely occur and causes the pump to not accept any connection
|
||||||
unless a button is physically pressed on the pump.
|
unless a button is physically pressed on the pump (make sure the 'pump unreachable' alert is enabled
|
||||||
|
so you'll get an alarm if the bug occurs.
|
||||||
Therefore, the pump's reservoir level is not read and the pump status information uploaded to Nightscout
|
Therefore, the pump's reservoir level is not read and the pump status information uploaded to Nightscout
|
||||||
shows fake numbers of 150 (above low threshold - which can be configured via the configuration
|
shows fake numbers of 150 (above low threshold - which can be configured via the configuration
|
||||||
tool), 8 (below low threshold, triggers NS alarm since < 10) and 0 if the reservoir is empty.
|
tool), 8 (below low threshold, triggers NS alarm since < 10) and 0 if the reservoir is empty.
|
||||||
|
@ -48,20 +49,20 @@ Setup:
|
||||||
- Set maximum TBR to 500%
|
- Set maximum TBR to 500%
|
||||||
- Disable end of TBR alert
|
- Disable end of TBR alert
|
||||||
- Set TBR duration step-size to 15 min
|
- Set TBR duration step-size to 15 min
|
||||||
- Set low cartridge alarm to your licking
|
- Set low cartridge alarm to your liking
|
||||||
- Enable keylock (can also be set on the pump directly, see usage section on reasoning)
|
- Enable keylock (can also be set on the pump directly, see usage section on reasoning)
|
||||||
- Get Android Studio 3
|
- Get Android Studio 3 https://developer.android.com/studio/index.html
|
||||||
- Get ruffy from https://github.com/jotomo/ruffy (branch `combo-scripter-v2`)
|
- Clone ruffy from https://github.com/jotomo/ruffy (branch `combo-scripter-v2`)
|
||||||
- Pair the pump, if it doesn't work, switch to the `pairing` branch, pair,
|
- Pair the pump, if it doesn't work after multiple attempts, switch to the `pairing` branch, pair,
|
||||||
then switch back the original branch. If the pump is already paired and
|
then switch back the original branch. If the pump is already paired and
|
||||||
can be controlled via ruffy, installing the above version is sufficient.
|
can be controlled via ruffy, installing the above version is sufficient.
|
||||||
If AAPS is already installed, switch to the MDI plugin to avoid the Combo
|
If AAPS is already installed, switch to the MDI plugin to avoid the Combo
|
||||||
plugin from interfering with ruffy during the pairing process.
|
plugin from interfering with ruffy during the pairing process.
|
||||||
Note that the pairing processing is somewhat fragile and may need a few attempts;
|
Note that the pairing processing is somewhat fragile and may need a few attempts;
|
||||||
quickly acknowledge prompts and when starting over, remove the pump device
|
quickly acknowledge prompts and when starting over, remove the pump device
|
||||||
from the bluetooth settings beforehand
|
from the bluetooth settings beforehand.
|
||||||
- Get AndroidAPS from https://github.com/jotomo/AndroidAPS (Branch `combo-scripter-v2`)
|
- Clone AndroidAPS from https://github.com/jotomo/AndroidAPS (Branch `combo-scripter-v2`)
|
||||||
- Before enabling the Combo plugin in AAPS make sure you're profile is set up
|
- Before enabling the Combo plugin in AAPS make sure your profile is set up
|
||||||
correctly and your basal profile is up to date as AAPS will sync the basal profile
|
correctly and your basal profile is up to date as AAPS will sync the basal profile
|
||||||
to the pump.
|
to the pump.
|
||||||
|
|
||||||
|
|
|
@ -169,7 +169,7 @@ public class MainApp extends Application {
|
||||||
else
|
else
|
||||||
Answers.getInstance().logCustom(new CustomEvent("AppStart"));
|
Answers.getInstance().logCustom(new CustomEvent("AppStart"));
|
||||||
|
|
||||||
new Thread(new Runnable() {
|
new Thread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
SystemClock.sleep(5000);
|
SystemClock.sleep(5000);
|
||||||
|
|
|
@ -228,6 +228,9 @@ public class DataService extends IntentService {
|
||||||
if (isNew && SP.getBoolean(R.string.key_dexcomg5_nsupload, false)) {
|
if (isNew && SP.getBoolean(R.string.key_dexcomg5_nsupload, false)) {
|
||||||
NSUpload.uploadBg(bgReading);
|
NSUpload.uploadBg(bgReading);
|
||||||
}
|
}
|
||||||
|
if (isNew && SP.getBoolean(R.string.key_dexcomg5_xdripupload, false)) {
|
||||||
|
NSUpload.sendToXdrip(bgReading);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
|
|
|
@ -159,12 +159,16 @@ public class Profile {
|
||||||
LongSparseArray<Double> sparse = new LongSparseArray<>();
|
LongSparseArray<Double> sparse = new LongSparseArray<>();
|
||||||
for (Integer index = 0; index < array.length(); index++) {
|
for (Integer index = 0; index < array.length(); index++) {
|
||||||
try {
|
try {
|
||||||
JSONObject o = array.getJSONObject(index);
|
final JSONObject o = array.getJSONObject(index);
|
||||||
long tas = getShitfTimeSecs((int) o.getLong("timeAsSeconds"));
|
long tas = getShitfTimeSecs((int) o.getLong("timeAsSeconds"));
|
||||||
Double value = o.getDouble("value") * multiplier;
|
Double value = o.getDouble("value") * multiplier;
|
||||||
sparse.put(tas, value);
|
sparse.put(tas, value);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
log.error("Unhandled exception", e);
|
log.error("Unhandled exception", e);
|
||||||
|
try {
|
||||||
|
log.error(array.getJSONObject(index).toString());
|
||||||
|
} catch (JSONException e1) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,11 +69,6 @@ public class NotificationStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WearPlugin wearPlugin = MainApp.getSpecificPlugin(WearPlugin.class);
|
|
||||||
if (wearPlugin != null && wearPlugin.isEnabled()) {
|
|
||||||
wearPlugin.overviewNotification(n.id, "OverviewNotification:\n" + n.text);
|
|
||||||
}
|
|
||||||
|
|
||||||
Collections.sort(store, new NotificationComparator());
|
Collections.sort(store, new NotificationComparator());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
|
||||||
pumpDescription.tempMaxDuration = 24 * 60;
|
pumpDescription.tempMaxDuration = 24 * 60;
|
||||||
|
|
||||||
|
|
||||||
pumpDescription.isSetBasalProfileCapable = false;
|
pumpDescription.isSetBasalProfileCapable = true;
|
||||||
pumpDescription.basalStep = 0.01d;
|
pumpDescription.basalStep = 0.01d;
|
||||||
pumpDescription.basalMinimumRate = 0.0d;
|
pumpDescription.basalMinimumRate = 0.0d;
|
||||||
|
|
||||||
|
|
|
@ -185,7 +185,7 @@ public class DanaRSService extends Service {
|
||||||
while (!msg.done && bleComm.isConnected()) {
|
while (!msg.done && bleComm.isConnected()) {
|
||||||
SystemClock.sleep(100);
|
SystemClock.sleep(100);
|
||||||
}
|
}
|
||||||
lastHistoryFetched = DanaRS_Packet_APS_History_Events.lastEventTimeLoaded;
|
lastHistoryFetched = DanaRS_Packet_APS_History_Events.lastEventTimeLoaded - 45 * 60 * 1000L; // always load last 45 min
|
||||||
log.debug("Events loaded");
|
log.debug("Events loaded");
|
||||||
return new PumpEnactResult().success(true);
|
return new PumpEnactResult().success(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -527,7 +527,7 @@ public class DanaRv2ExecutionService extends Service {
|
||||||
waitMsec(100);
|
waitMsec(100);
|
||||||
}
|
}
|
||||||
waitMsec(200);
|
waitMsec(200);
|
||||||
lastHistoryFetched = MsgHistoryEvents_v2.lastEventTimeLoaded;
|
lastHistoryFetched = MsgHistoryEvents_v2.lastEventTimeLoaded - 45 * 60 * 1000L; //always load last 45 min;
|
||||||
return new PumpEnactResult().success(true);
|
return new PumpEnactResult().success(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -153,6 +153,10 @@ public class CommandQueue {
|
||||||
// remove all unfinished boluses
|
// remove all unfinished boluses
|
||||||
removeAll(Command.CommandType.BOLUS);
|
removeAll(Command.CommandType.BOLUS);
|
||||||
|
|
||||||
|
// apply constraints
|
||||||
|
detailedBolusInfo.insulin = MainApp.getConfigBuilder().applyBolusConstraints(detailedBolusInfo.insulin);
|
||||||
|
detailedBolusInfo.carbs = MainApp.getConfigBuilder().applyCarbsConstraints((int) detailedBolusInfo.carbs);
|
||||||
|
|
||||||
// add new command to queue
|
// add new command to queue
|
||||||
add(new CommandBolus(detailedBolusInfo, callback));
|
add(new CommandBolus(detailedBolusInfo, callback));
|
||||||
|
|
||||||
|
@ -161,14 +165,9 @@ public class CommandQueue {
|
||||||
// Notify Wear about upcoming bolus
|
// Notify Wear about upcoming bolus
|
||||||
MainApp.bus().post(new EventBolusRequested(detailedBolusInfo.insulin));
|
MainApp.bus().post(new EventBolusRequested(detailedBolusInfo.insulin));
|
||||||
|
|
||||||
// Apply constraints
|
|
||||||
detailedBolusInfo.insulin = MainApp.getConfigBuilder().applyBolusConstraints(detailedBolusInfo.insulin);
|
|
||||||
detailedBolusInfo.carbs = MainApp.getConfigBuilder().applyCarbsConstraints((int) detailedBolusInfo.carbs);
|
|
||||||
|
|
||||||
// Bring up bolus progress dialog
|
// Bring up bolus progress dialog
|
||||||
BolusProgressDialog bolusProgressDialog = null;
|
|
||||||
if (detailedBolusInfo.context != null) {
|
if (detailedBolusInfo.context != null) {
|
||||||
bolusProgressDialog = new BolusProgressDialog();
|
BolusProgressDialog bolusProgressDialog = new BolusProgressDialog();
|
||||||
bolusProgressDialog.setInsulin(detailedBolusInfo.insulin);
|
bolusProgressDialog.setInsulin(detailedBolusInfo.insulin);
|
||||||
bolusProgressDialog.show(((AppCompatActivity) detailedBolusInfo.context).getSupportFragmentManager(), "BolusProgress");
|
bolusProgressDialog.show(((AppCompatActivity) detailedBolusInfo.context).getSupportFragmentManager(), "BolusProgress");
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -3,33 +3,37 @@ package info.nightscout.utils;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
import android.content.pm.ResolveInfo;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.Services.Intents;
|
import info.nightscout.androidaps.Services.Intents;
|
||||||
import info.nightscout.androidaps.data.DetailedBolusInfo;
|
import info.nightscout.androidaps.data.DetailedBolusInfo;
|
||||||
|
import info.nightscout.androidaps.data.Profile;
|
||||||
import info.nightscout.androidaps.db.BgReading;
|
import info.nightscout.androidaps.db.BgReading;
|
||||||
import info.nightscout.androidaps.db.CareportalEvent;
|
import info.nightscout.androidaps.db.CareportalEvent;
|
||||||
import info.nightscout.androidaps.db.ExtendedBolus;
|
import info.nightscout.androidaps.db.ExtendedBolus;
|
||||||
import info.nightscout.androidaps.db.ProfileSwitch;
|
import info.nightscout.androidaps.db.ProfileSwitch;
|
||||||
import info.nightscout.androidaps.db.TemporaryBasal;
|
import info.nightscout.androidaps.db.TemporaryBasal;
|
||||||
import info.nightscout.androidaps.db.Treatment;
|
|
||||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Loop.APSResult;
|
import info.nightscout.androidaps.plugins.Loop.APSResult;
|
||||||
import info.nightscout.androidaps.plugins.Loop.DeviceStatus;
|
import info.nightscout.androidaps.plugins.Loop.DeviceStatus;
|
||||||
import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
|
import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
|
||||||
import info.nightscout.androidaps.plugins.NSClientInternal.data.DbLogger;
|
import info.nightscout.androidaps.plugins.NSClientInternal.data.DbLogger;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
|
||||||
import info.nightscout.androidaps.plugins.OpenAPSAMA.DetermineBasalResultAMA;
|
import info.nightscout.androidaps.plugins.OpenAPSAMA.DetermineBasalResultAMA;
|
||||||
import info.nightscout.androidaps.plugins.OpenAPSMA.DetermineBasalResultMA;
|
import info.nightscout.androidaps.plugins.OpenAPSMA.DetermineBasalResultMA;
|
||||||
|
|
||||||
|
@ -449,4 +453,44 @@ public class NSUpload {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void sendToXdrip(BgReading bgReading) {
|
||||||
|
final String XDRIP_PLUS_NS_EMULATOR = "com.eveningoutpost.dexdrip.NS_EMULATOR";
|
||||||
|
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.US);
|
||||||
|
|
||||||
|
try {
|
||||||
|
final JSONArray entriesBody = new JSONArray();
|
||||||
|
JSONObject json = new JSONObject();
|
||||||
|
json.put("sgv", bgReading.value);
|
||||||
|
if (bgReading.direction == null) {
|
||||||
|
json.put("direction", "NONE");
|
||||||
|
} else {
|
||||||
|
json.put("direction", bgReading.direction);
|
||||||
|
}
|
||||||
|
json.put("device", "G5");
|
||||||
|
json.put("type", "sgv");
|
||||||
|
json.put("date", bgReading.date);
|
||||||
|
json.put("dateString", format.format(bgReading.date));
|
||||||
|
entriesBody.put(json);
|
||||||
|
|
||||||
|
final Bundle bundle = new Bundle();
|
||||||
|
bundle.putString("action", "add");
|
||||||
|
bundle.putString("collection", "entries");
|
||||||
|
bundle.putString("data", entriesBody.toString());
|
||||||
|
final Intent intent = new Intent(XDRIP_PLUS_NS_EMULATOR);
|
||||||
|
intent.putExtras(bundle).addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
|
||||||
|
MainApp.instance().sendBroadcast(intent);
|
||||||
|
List<ResolveInfo> receivers = MainApp.instance().getPackageManager().queryBroadcastReceivers(intent, 0);
|
||||||
|
if (receivers.size() < 1) {
|
||||||
|
log.debug("No xDrip receivers found. ");
|
||||||
|
} else {
|
||||||
|
log.debug(receivers.size() + " xDrip receivers");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -787,6 +787,9 @@
|
||||||
<string name="wear_detailed_delta_title">Show detailed delta</string>
|
<string name="wear_detailed_delta_title">Show detailed delta</string>
|
||||||
<string name="wear_detailed_delta_summary">Show delta with one more decimal place</string>
|
<string name="wear_detailed_delta_summary">Show delta with one more decimal place</string>
|
||||||
<string name="unsupportedfirmware">Unsupported pump firmware</string>
|
<string name="unsupportedfirmware">Unsupported pump firmware</string>
|
||||||
|
<string name="dexcomg5_xdripupload_title">Send BG data to xDrip+</string>
|
||||||
|
<string name="key_dexcomg5_xdripupload" translatable="false">dexcomg5_xdripupload</string>
|
||||||
|
<string name="dexcomg5_xdripupload_summary">In xDrip+ select 640g/Eversense data source</string>
|
||||||
<string name="bolusstopping">Stopping bolus delivery</string>
|
<string name="bolusstopping">Stopping bolus delivery</string>
|
||||||
<string name="bolusstopped">Bolus delivery stopped</string>
|
<string name="bolusstopped">Bolus delivery stopped</string>
|
||||||
<string name="combo_programming_bolus">Programming pump for bolusing</string>
|
<string name="combo_programming_bolus">Programming pump for bolusing</string>
|
||||||
|
|
|
@ -9,6 +9,12 @@
|
||||||
android:key="@string/key_dexcomg5_nsupload"
|
android:key="@string/key_dexcomg5_nsupload"
|
||||||
android:title="@string/dexcomg5_nsupload_title" />
|
android:title="@string/dexcomg5_nsupload_title" />
|
||||||
|
|
||||||
|
<SwitchPreference
|
||||||
|
android:defaultValue="false"
|
||||||
|
android:key="@string/key_dexcomg5_xdripupload"
|
||||||
|
android:summary="@string/dexcomg5_xdripupload_summary"
|
||||||
|
android:title="@string/dexcomg5_xdripupload_title" />
|
||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
|
@ -124,9 +124,8 @@ public class SetTbrCommand extends BaseCommand {
|
||||||
scripter.waitForScreenUpdate();
|
scripter.waitForScreenUpdate();
|
||||||
state = scripter.readPumpStateInternal();
|
state = scripter.readPumpStateInternal();
|
||||||
}
|
}
|
||||||
// if we waited above and a cancellation (fake or hard) was requested,
|
// if we waited above and a cancellation was requested, we already completed the request
|
||||||
// we already completed the request
|
if (!state.tbrActive && percentage == 100) {
|
||||||
if (!state.tbrActive && percentage >= 90 && percentage <= 110) {
|
|
||||||
result.success = true;
|
result.success = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue