[0.4.1-SNAPSHOT]
- little change in scanning - added error checking into RadioResponse and BasalProfile, also added events - disabled quick scan - synchronized RileyLink state changes - proofed MedtronicConverter - fixed 10 errors found on fabric - fixed SetBasalProfile, after merge
This commit is contained in:
parent
03e38158f4
commit
5b9bd2adfc
|
@ -64,7 +64,7 @@ android {
|
|||
multiDexEnabled true
|
||||
versionCode 1500
|
||||
// dev_version: 2.0i
|
||||
version "medtronic-0.4.0-snapshot"
|
||||
version "medtronic-0.4"
|
||||
buildConfigField "String", "VERSION", '"' + version + '"'
|
||||
buildConfigField "String", "BUILDVERSION", '"' + generateGitBuild() + '-' + generateDate() + '"'
|
||||
buildConfigField "String", "HEAD", '"' + generateGitBuild() + '"'
|
||||
|
@ -103,7 +103,7 @@ android {
|
|||
resValue "string", "app_name", "AndroidAPS"
|
||||
versionName version
|
||||
manifestPlaceholders = [
|
||||
appIcon: "@mipmap/ic_launcher",
|
||||
appIcon : "@mipmap/ic_launcher",
|
||||
appIconRound: "@mipmap/ic_launcher_round"
|
||||
]
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ android {
|
|||
resValue "string", "app_name", "AndroidAPS"
|
||||
versionName version
|
||||
manifestPlaceholders = [
|
||||
appIcon: "@mipmap/blueowl",
|
||||
appIcon : "@mipmap/blueowl",
|
||||
appIconRound: "@null"
|
||||
]
|
||||
}
|
||||
|
@ -123,7 +123,7 @@ android {
|
|||
resValue "string", "app_name", "NSClient"
|
||||
versionName version + "-nsclient"
|
||||
manifestPlaceholders = [
|
||||
appIcon: "@mipmap/yellowowl",
|
||||
appIcon : "@mipmap/yellowowl",
|
||||
appIconRound: "@null"
|
||||
]
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ android {
|
|||
resValue "string", "app_name", "NSClient2"
|
||||
versionName version + "-nsclient"
|
||||
manifestPlaceholders = [
|
||||
appIcon: "@mipmap/yellowowl",
|
||||
appIcon : "@mipmap/yellowowl",
|
||||
appIconRound: "@null"
|
||||
]
|
||||
}
|
||||
|
@ -148,7 +148,7 @@ android {
|
|||
unitTests.includeAndroidResources = true
|
||||
}
|
||||
|
||||
useLibrary "org.apache.http.legacy"
|
||||
useLibrary "org.apache.http.legacy"
|
||||
}
|
||||
|
||||
allprojects {
|
||||
|
|
|
@ -66,7 +66,9 @@
|
|||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name=".plugins.PumpDanaRS.activities.PairingHelperActivity" />
|
||||
<activity android:name=".HistoryBrowseActivity" />
|
||||
|
||||
<activity android:name=".activities.HistoryBrowseActivity" />
|
||||
|
||||
<activity android:name=".plugins.PumpCommon.dialog.RileyLinkBLEScanActivity">
|
||||
<intent-filter>
|
||||
<action android:name="info.nightscout.androidaps.plugins.PumpCommon.dialog.RileyLinkBLEScanActivity" />
|
||||
|
@ -201,7 +203,8 @@
|
|||
android:theme="@style/AppTheme.NoActionBar"
|
||||
android:label="@string/title_activity_setup_wizard" />
|
||||
|
||||
<activity android:name=".activities.SingleFragmentActivity"
|
||||
<activity
|
||||
android:name=".activities.SingleFragmentActivity"
|
||||
android:theme="@style/AppTheme" />
|
||||
<activity android:name=".plugins.Maintenance.activities.LogSettingActivity"></activity>
|
||||
|
||||
|
|
|
@ -469,6 +469,11 @@ public class MainApp extends Application {
|
|||
}
|
||||
|
||||
|
||||
public static boolean isEngineeringMode() {
|
||||
return engineeringMode;
|
||||
}
|
||||
|
||||
|
||||
public static boolean isDev() {
|
||||
return devBranch;
|
||||
}
|
||||
|
|
|
@ -222,9 +222,11 @@ public abstract class RileyLinkCommunicationManager {
|
|||
trial.successes++;
|
||||
} else {
|
||||
LOG.warn("Failed to parse radio response: " + ByteUtil.shortHexString(resp.getRaw()));
|
||||
trial.rssiList.add(-99);
|
||||
}
|
||||
} else {
|
||||
LOG.error("scanForPump: raw response is " + ByteUtil.shortHexString(resp.getRaw()));
|
||||
trial.rssiList.add(-99);
|
||||
}
|
||||
trial.tries++;
|
||||
}
|
||||
|
|
|
@ -83,11 +83,6 @@ public class RileyLinkUtil {
|
|||
}
|
||||
|
||||
|
||||
public static RileyLinkServiceState getServiceState() {
|
||||
return RileyLinkUtil.rileyLinkServiceData.serviceState;
|
||||
}
|
||||
|
||||
|
||||
public static void setServiceState(RileyLinkServiceState newState) {
|
||||
setServiceState(newState, null);
|
||||
}
|
||||
|
@ -98,16 +93,38 @@ public class RileyLinkUtil {
|
|||
}
|
||||
|
||||
|
||||
public static RileyLinkServiceState getServiceState() {
|
||||
return workWithServiceState(null, null, false);
|
||||
}
|
||||
|
||||
|
||||
public static void setServiceState(RileyLinkServiceState newState, RileyLinkError errorCode) {
|
||||
RileyLinkUtil.rileyLinkServiceData.serviceState = newState;
|
||||
RileyLinkUtil.rileyLinkServiceData.errorCode = errorCode;
|
||||
workWithServiceState(newState, errorCode, true);
|
||||
}
|
||||
|
||||
LOG.warn("RileyLink State Changed: {} {}", newState,
|
||||
errorCode == null ? "" : " - Error State: " + errorCode.name());
|
||||
|
||||
RileyLinkUtil.historyRileyLink.add(new RLHistoryItem(RileyLinkUtil.rileyLinkServiceData.serviceState,
|
||||
RileyLinkUtil.rileyLinkServiceData.errorCode, targetDevice));
|
||||
MainApp.bus().post(new EventMedtronicDeviceStatusChange(newState, errorCode));
|
||||
private static synchronized RileyLinkServiceState workWithServiceState(RileyLinkServiceState newState,
|
||||
RileyLinkError errorCode, boolean set) {
|
||||
|
||||
if (set) {
|
||||
|
||||
RileyLinkUtil.rileyLinkServiceData.serviceState = newState;
|
||||
RileyLinkUtil.rileyLinkServiceData.errorCode = errorCode;
|
||||
|
||||
LOG.warn("RileyLink State Changed: {} {}", newState, errorCode == null ? "" : " - Error State: "
|
||||
+ errorCode.name());
|
||||
|
||||
RileyLinkUtil.historyRileyLink.add(new RLHistoryItem(RileyLinkUtil.rileyLinkServiceData.serviceState,
|
||||
RileyLinkUtil.rileyLinkServiceData.errorCode, targetDevice));
|
||||
MainApp.bus().post(new EventMedtronicDeviceStatusChange(newState, errorCode));
|
||||
return null;
|
||||
|
||||
} else {
|
||||
|
||||
return RileyLinkUtil.rileyLinkServiceData.serviceState;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -160,6 +161,63 @@ public class RFTools {
|
|||
}
|
||||
|
||||
|
||||
public static byte[] encode4b6b_newtest(byte[] data) {
|
||||
|
||||
List<Byte> buffer = new ArrayList<Byte>();
|
||||
int bitAccumulator = 0x0;
|
||||
int bitcount = 0;
|
||||
|
||||
for (byte element : data) {
|
||||
bitAccumulator <<= 6;
|
||||
bitAccumulator |= codes[element >> 4];
|
||||
bitcount += 6;
|
||||
|
||||
bitAccumulator <<= 6;
|
||||
bitAccumulator |= codes[element & 0x0f];
|
||||
bitcount += 6;
|
||||
|
||||
while (bitcount >= 8) {
|
||||
buffer.add((byte)((bitAccumulator >> (bitcount - 8)) & 0xff));
|
||||
bitcount -= 8;
|
||||
bitAccumulator &= (0xffff >> (16 - bitcount));
|
||||
}
|
||||
}
|
||||
|
||||
if (bitcount > 0) {
|
||||
bitAccumulator <<= (8 - bitcount);
|
||||
buffer.add((byte)((bitAccumulator) & 0xff));
|
||||
}
|
||||
|
||||
return ByteUtil.getByteArrayFromList(buffer);
|
||||
}
|
||||
|
||||
|
||||
// public func encode4b6b() -> [UInt8] {
|
||||
// var buffer = [UInt8]()
|
||||
// var bitAccumulator = 0x0
|
||||
// var bitcount = 0
|
||||
// for byte in self {
|
||||
// bitAccumulator <<= 6
|
||||
// bitAccumulator |= codes[Int(byte >> 4)]
|
||||
// bitcount += 6
|
||||
//
|
||||
// bitAccumulator <<= 6
|
||||
// bitAccumulator |= codes[Int(byte & 0x0f)]
|
||||
// bitcount += 6
|
||||
//
|
||||
// while bitcount >= 8 {
|
||||
// buffer.append(UInt8(bitAccumulator >> (bitcount-8)) & 0xff)
|
||||
// bitcount -= 8
|
||||
// bitAccumulator &= (0xffff >> (16-bitcount))
|
||||
// }
|
||||
// }
|
||||
// if bitcount > 0 {
|
||||
// bitAccumulator <<= (8-bitcount)
|
||||
// buffer.append(UInt8(bitAccumulator) & 0xff)
|
||||
// }
|
||||
// return buffer
|
||||
// }
|
||||
|
||||
public static void test() {
|
||||
/*
|
||||
* {0xa7} -> {0xa9, 0x60}
|
||||
|
@ -272,6 +330,96 @@ public class RFTools {
|
|||
}
|
||||
|
||||
|
||||
public static DecodeResponseDto decode4b6bWithoutException(byte[] raw) {
|
||||
/*
|
||||
* if ((raw.length % 2) != 0) {
|
||||
* LOG.error("Warning: data is odd number of bytes");
|
||||
* }
|
||||
*/
|
||||
|
||||
DecodeResponseDto response = new DecodeResponseDto();
|
||||
|
||||
StringBuilder errorMessageBuilder = new StringBuilder();
|
||||
|
||||
errorMessageBuilder.append("Input data: " + ByteUtil.getHex(raw) + "\n");
|
||||
|
||||
if ((raw.length % 2) != 0) {
|
||||
errorMessageBuilder.append("Warn: odd number of bytes.");
|
||||
}
|
||||
|
||||
byte[] rval = new byte[] {};
|
||||
int availableBits = 0;
|
||||
int codingErrors = 0;
|
||||
int x = 0;
|
||||
// Log.w(TAG,"decode4b6b: untested code");
|
||||
// Log.w(TAG,String.format("Decoding %d bytes: %s",raw.length,ByteUtil.shortHexString(raw)));
|
||||
for (int i = 0; i < raw.length; i++) {
|
||||
int unsignedValue = raw[i];
|
||||
if (unsignedValue < 0) {
|
||||
unsignedValue += 256;
|
||||
}
|
||||
x = (x << 8) + unsignedValue;
|
||||
availableBits += 8;
|
||||
if (availableBits >= 12) {
|
||||
// take top six
|
||||
int highcode = (x >> (availableBits - 6)) & 0x3F;
|
||||
int highIndex = codeIndex((byte)(highcode));
|
||||
// take bottom six
|
||||
int lowcode = (x >> (availableBits - 12)) & 0x3F;
|
||||
int lowIndex = codeIndex((byte)(lowcode));
|
||||
// special case at end of transmission on uneven boundaries:
|
||||
if ((highIndex >= 0) && (lowIndex >= 0)) {
|
||||
byte decoded = (byte)((highIndex << 4) + lowIndex);
|
||||
rval = ByteUtil.concat(rval, decoded);
|
||||
/*
|
||||
* LOG.debug(String.format(
|
||||
* "i=%d,x=0x%08X,0x%02X->0x%02X, 0x%02X->0x%02X, result: 0x%02X, %d bits remaining, errors %d, bytes remaining: %s"
|
||||
* ,
|
||||
* i,x,highcode,highIndex, lowcode,
|
||||
* lowIndex,decoded,availableBits,codingErrors,ByteUtil.shortHexString
|
||||
* (ByteUtil.substring(raw,i+1,raw.length-i-1))));
|
||||
*/
|
||||
} else {
|
||||
// LOG.debug(String.format("i=%d,x=%08X, coding error: highcode=0x%02X, lowcode=0x%02X, %d bits remaining",i,x,highcode,lowcode,availableBits));
|
||||
errorMessageBuilder.append(String.format(
|
||||
"decode4b6b: i=%d,x=%08X, coding error: highcode=0x%02X, lowcode=0x%02X, %d bits remaining.\n",
|
||||
i, x, highcode, lowcode, availableBits));
|
||||
codingErrors++;
|
||||
}
|
||||
|
||||
availableBits -= 12;
|
||||
x = x & (0x0000ffff >> (16 - availableBits));
|
||||
} else {
|
||||
// LOG.debug(String.format("i=%d, skip: x=0x%08X, available bits %d",i,x,availableBits));
|
||||
}
|
||||
}
|
||||
|
||||
if (availableBits != 0) {
|
||||
if ((availableBits == 4) && (x == 0x05)) {
|
||||
// normal end
|
||||
} else {
|
||||
LOG.error("decode4b6b: failed clean decode -- extra bits available (not marker)(" + availableBits + ")");
|
||||
errorMessageBuilder.append("decode4b6b: failed clean decode -- extra bits available (not marker)("
|
||||
+ availableBits + ")\n");
|
||||
codingErrors++;
|
||||
}
|
||||
} else {
|
||||
// also normal end.
|
||||
}
|
||||
|
||||
if (codingErrors > 0) {
|
||||
LOG.error("decode4b6b: " + codingErrors + " coding errors encountered.");
|
||||
errorMessageBuilder.append("decode4b6b: " + codingErrors + " coding errors encountered.");
|
||||
|
||||
response.errorData = errorMessageBuilder.toString();
|
||||
} else {
|
||||
response.data = rval;
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
public static String toHexString(byte[] array) {
|
||||
return toHexString(array, 0, array.length);
|
||||
}
|
||||
|
@ -290,4 +438,10 @@ public class RFTools {
|
|||
return new String(buf);
|
||||
}
|
||||
|
||||
public static class DecodeResponseDto {
|
||||
|
||||
public byte[] data;
|
||||
public String errorData;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,7 +16,15 @@ public class FrequencyScanResults {
|
|||
|
||||
|
||||
public void sort() {
|
||||
Collections.sort(trials, (trial1, trial2) -> trial1.averageRSSI.compareTo(trial2.averageRSSI));
|
||||
Collections.sort(trials, (trial1, trial2) -> {
|
||||
int res = trial1.averageRSSI.compareTo(trial2.averageRSSI);
|
||||
|
||||
if (res == 0) {
|
||||
return (int)(trial1.frequencyMHz - trial2.frequencyMHz);
|
||||
} else
|
||||
return res;
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.defs.Riley
|
|||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.defs.RileyLinkFirmwareVersion;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.utils.ByteUtil;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.utils.CRC;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.utils.FabricUtil;
|
||||
|
||||
/**
|
||||
* Created by geoff on 5/30/16.
|
||||
|
@ -100,13 +101,19 @@ public class RadioResponse {
|
|||
decodedPayload = encodedPayload;
|
||||
break;
|
||||
case FourByteSixByte:
|
||||
LOG.debug("encodedPayload: {}", ByteUtil.getHex(encodedPayload));
|
||||
byte[] decodeThis = RFTools.decode4b6b(encodedPayload);
|
||||
LOG.debug("decodedPayload: {}", ByteUtil.getHex(decodeThis));
|
||||
RFTools.DecodeResponseDto decodeResponseDto = RFTools.decode4b6bWithoutException(encodedPayload);
|
||||
byte[] decodeThis = decodeResponseDto.data;
|
||||
decodedOK = true;
|
||||
|
||||
if (decodeThis == null || decodeThis.length == 0) {
|
||||
LOG.error("Decoded payload length is zero.");
|
||||
if (decodeThis == null || decodeThis.length == 0 || decodeResponseDto.errorData != null) {
|
||||
LOG.error("=============================================================================");
|
||||
LOG.error(" Decoded payload length is zero.");
|
||||
LOG.error(" encodedPayload: {}", ByteUtil.getHex(encodedPayload));
|
||||
LOG.error(" errors: {}", decodeResponseDto.errorData);
|
||||
LOG.error("=============================================================================");
|
||||
|
||||
FabricUtil.createEvent("MedtronicDecode4b6bError", null);
|
||||
|
||||
decodedOK = false;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.defs;
|
||||
|
||||
/**
|
||||
* Created by andy on 5/19/18.
|
||||
*/
|
||||
|
||||
public enum RileyLinkTargetDevice {
|
||||
MedtronicPump, //
|
||||
Omnipod, //
|
||||
;
|
||||
}
|
|
@ -7,11 +7,9 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
import android.app.Service;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.RileyLinkCommunicationManager;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.RileyLinkConst;
|
||||
|
@ -19,19 +17,12 @@ import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.RileyLinkUtil;
|
|||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.RFSpy;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.RileyLinkBLE;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.defs.RileyLinkEncodingType;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.defs.RileyLinkFirmwareVersion;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.ble.defs.RileyLinkTargetFrequency;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.defs.RileyLinkError;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.defs.RileyLinkServiceState;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.defs.RileyLinkTargetDevice;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.service.data.ServiceNotification;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.service.data.ServiceResult;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.service.data.ServiceTransport;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.service.tasks.DiscoverGattServicesTask;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.service.tasks.InitializePumpManagerTask;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.service.tasks.ServiceTask;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.service.tasks.ServiceTaskExecutor;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.service.tasks.WakeAndTuneTask;
|
||||
import info.nightscout.androidaps.plugins.PumpMedtronic.defs.PumpDeviceState;
|
||||
import info.nightscout.androidaps.plugins.PumpMedtronic.util.MedtronicUtil;
|
||||
import info.nightscout.utils.SP;
|
||||
|
@ -254,20 +245,22 @@ public abstract class RileyLinkService extends Service {
|
|||
}
|
||||
|
||||
double newFrequency;
|
||||
if ((lastGoodFrequency > 0.0d) && getRileyLinkCommunicationManager().isValidFrequency(lastGoodFrequency)) {
|
||||
LOG.info("Checking for pump near last saved frequency of {}MHz", lastGoodFrequency);
|
||||
// we have an old frequency, so let's start there.
|
||||
newFrequency = getDeviceCommunicationManager().quickTuneForPump(lastGoodFrequency);
|
||||
if (newFrequency == 0.0) {
|
||||
// quick scan failed to find pump. Try full scan
|
||||
LOG.warn("Failed to find pump near last saved frequency, doing full scan");
|
||||
newFrequency = getDeviceCommunicationManager().tuneForDevice();
|
||||
}
|
||||
} else {
|
||||
LOG.warn("No saved frequency for pump, doing full scan.");
|
||||
// we don't have a saved frequency, so do the full scan.
|
||||
newFrequency = getDeviceCommunicationManager().tuneForDevice();
|
||||
}
|
||||
// if ((lastGoodFrequency > 0.0d) && getRileyLinkCommunicationManager().isValidFrequency(lastGoodFrequency)) {
|
||||
// LOG.info("Checking for pump near last saved frequency of {}MHz", lastGoodFrequency);
|
||||
// // we have an old frequency, so let's start there.
|
||||
// newFrequency = getDeviceCommunicationManager().quickTuneForPump(lastGoodFrequency);
|
||||
// if (newFrequency == 0.0) {
|
||||
// // quick scan failed to find pump. Try full scan
|
||||
// LOG.warn("Failed to find pump near last saved frequency, doing full scan");
|
||||
// newFrequency = getDeviceCommunicationManager().tuneForDevice();
|
||||
// }
|
||||
// } else {
|
||||
// LOG.warn("No saved frequency for pump, doing full scan.");
|
||||
// // we don't have a saved frequency, so do the full scan.
|
||||
// newFrequency = getDeviceCommunicationManager().tuneForDevice();
|
||||
// }
|
||||
|
||||
newFrequency = getDeviceCommunicationManager().tuneForDevice();
|
||||
|
||||
if ((newFrequency != 0.0) && (newFrequency != lastGoodFrequency)) {
|
||||
LOG.info("Saving new pump frequency of {}MHz", newFrequency);
|
||||
|
@ -277,13 +270,12 @@ public abstract class RileyLinkService extends Service {
|
|||
rileyLinkServiceData.lastTuneUpTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
getRileyLinkCommunicationManager().clearNotConnectedCount();
|
||||
|
||||
if (newFrequency == 0.0d) {
|
||||
// error tuning pump, pump not present ??
|
||||
RileyLinkUtil
|
||||
.setServiceState(RileyLinkServiceState.PumpConnectorError, RileyLinkError.TuneUpOfDeviceFailed);
|
||||
} else {
|
||||
getRileyLinkCommunicationManager().clearNotConnectedCount();
|
||||
RileyLinkUtil.setServiceState(RileyLinkServiceState.PumpConnectorReady);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -347,6 +347,9 @@ public class ByteUtil {
|
|||
|
||||
|
||||
public static String getCompactString(byte[] data) {
|
||||
if (data == null)
|
||||
return "null";
|
||||
|
||||
String vval2 = ByteUtil.getHex(data);
|
||||
vval2 = vval2.replace(" 0x", "");
|
||||
vval2 = vval2.replace("0x", "");
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
package info.nightscout.androidaps.plugins.PumpCommon.utils;
|
||||
|
||||
/**
|
||||
* Created by andy on 10/25/18.
|
||||
*/
|
||||
|
||||
import org.joda.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* This is simple version of ATechDate, limited only to one format (yyyymmddHHMIss)
|
||||
*/
|
||||
public class DateTimeUtil {
|
||||
|
||||
/**
|
||||
* DateTime is packed as long: yyyymmddHHMMss
|
||||
*
|
||||
* @param atechDateTime
|
||||
* @return
|
||||
*/
|
||||
public static LocalDateTime toLocalDateTime(long atechDateTime) {
|
||||
int year = (int)(atechDateTime / 10000000000L);
|
||||
atechDateTime -= year * 10000000000L;
|
||||
|
||||
int month = (int)(atechDateTime / 100000000L);
|
||||
atechDateTime -= month * 100000000L;
|
||||
|
||||
int dayOfMonth = (int)(atechDateTime / 1000000L);
|
||||
atechDateTime -= dayOfMonth * 1000000L;
|
||||
|
||||
int hourOfDay = (int)(atechDateTime / 10000L);
|
||||
atechDateTime -= hourOfDay * 10000L;
|
||||
|
||||
int minute = (int)(atechDateTime / 100L);
|
||||
atechDateTime -= minute * 100L;
|
||||
|
||||
int second = (int)atechDateTime;
|
||||
|
||||
return new LocalDateTime(year, month, dayOfMonth, minute, second);
|
||||
}
|
||||
|
||||
|
||||
public static long toATechDate(LocalDateTime ldt) {
|
||||
long atechDateTime = 0L;
|
||||
|
||||
atechDateTime += ldt.getYear() * 10000000000L;
|
||||
atechDateTime += ldt.getMonthOfYear() * 100000000L;
|
||||
atechDateTime += ldt.getDayOfMonth() * 1000000L;
|
||||
atechDateTime += ldt.getHourOfDay() * 10000L;
|
||||
atechDateTime += ldt.getMinuteOfHour() * 100L;
|
||||
atechDateTime += ldt.getSecondOfMinute();
|
||||
|
||||
return atechDateTime;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package info.nightscout.androidaps.plugins.PumpCommon.utils;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.crashlytics.android.answers.AnswersEvent;
|
||||
import com.crashlytics.android.answers.CustomEvent;
|
||||
import com.google.common.base.Splitter;
|
||||
|
||||
import info.nightscout.androidaps.BuildConfig;
|
||||
import info.nightscout.utils.FabricPrivacy;
|
||||
|
||||
/**
|
||||
* Created by andy on 10/26/18.
|
||||
*/
|
||||
|
||||
public class FabricUtil {
|
||||
|
||||
public static void createEvent(String eventName, Map<String, String> map) {
|
||||
|
||||
CustomEvent customEvent = new CustomEvent("MedtronicDecode4b6bError") //
|
||||
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION) //
|
||||
.putCustomAttribute("version", BuildConfig.VERSION);
|
||||
|
||||
int attributes = 2;
|
||||
boolean interrupted = false;
|
||||
|
||||
if (map != null) {
|
||||
for (Map.Entry<String, String> entry : map.entrySet()) {
|
||||
|
||||
int part = 1;
|
||||
|
||||
if (interrupted)
|
||||
break;
|
||||
|
||||
for (final String token : Splitter.fixedLength(AnswersEvent.MAX_STRING_LENGTH).split(entry.getValue())) {
|
||||
|
||||
if (attributes == AnswersEvent.MAX_NUM_ATTRIBUTES) {
|
||||
interrupted = true;
|
||||
break;
|
||||
}
|
||||
|
||||
customEvent.putCustomAttribute(entry.getKey() + "_" + part, token);
|
||||
attributes++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FabricPrivacy.getInstance().logCustom(customEvent);
|
||||
}
|
||||
|
||||
}
|
|
@ -5,8 +5,6 @@ import java.util.HashMap;
|
|||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.Hours;
|
||||
import org.joda.time.LocalDateTime;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -40,8 +38,10 @@ import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.RileyLinkConst
|
|||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.defs.RileyLinkServiceState;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.service.tasks.ServiceTaskExecutor;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.hw.rileylink.service.tasks.WakeAndTuneTask;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.utils.DateTimeUtil;
|
||||
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.MedtronicCommunicationManager;
|
||||
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.pump.PumpHistoryEntry;
|
||||
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.pump.PumpHistoryResult;
|
||||
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.ui.MedtronicUIComm;
|
||||
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.ui.MedtronicUITask;
|
||||
import info.nightscout.androidaps.plugins.PumpMedtronic.data.MedtronicHistoryData;
|
||||
|
@ -884,25 +884,52 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
|
||||
private void readPumpHistoryLogic() {
|
||||
|
||||
Long lastPumpHistoryEntryTime = null;
|
||||
LocalDateTime targetDate = null;
|
||||
|
||||
// TODO read History
|
||||
// if (lastPumpHistoryEntry == null) {
|
||||
// lastPumpHistoryEntryTime = SP.getLong(MedtronicConst.Statistics.LastPumpHistoryEntry, null);
|
||||
// }
|
||||
|
||||
if (lastPumpHistoryEntry == null) {
|
||||
lastPumpHistoryEntryTime = SP.getLong(MedtronicConst.Statistics.LastPumpHistoryEntry, null);
|
||||
}
|
||||
|
||||
if (firstRun) {
|
||||
DateTime dt = new DateTime();
|
||||
dt.minus(Hours.hours(36));
|
||||
Long lastPumpHistoryEntryTime = SP.getLong(MedtronicConst.Statistics.LastPumpHistoryEntry, null);
|
||||
|
||||
if (lastPumpHistoryEntry == null && lastPumpHistoryEntryTime == null) {
|
||||
LocalDateTime timeMinus36h = new LocalDateTime();
|
||||
timeMinus36h = timeMinus36h.minusHours(36);
|
||||
|
||||
if (lastPumpHistoryEntryTime == null) {
|
||||
targetDate = timeMinus36h;
|
||||
} else {
|
||||
LocalDateTime lastHistoryRecordTime = DateTimeUtil.toLocalDateTime(lastPumpHistoryEntryTime);
|
||||
|
||||
medtronicHistoryData.setLastHistoryRecordTime(DateTimeUtil.toLocalDateTime(lastPumpHistoryEntryTime));
|
||||
|
||||
lastHistoryRecordTime = lastHistoryRecordTime.minusHours(12); // we get last 12 hours of history to
|
||||
// determine pump state
|
||||
// (we don't process that data), we process only
|
||||
|
||||
if (timeMinus36h.isAfter(lastHistoryRecordTime)) {
|
||||
targetDate = timeMinus36h;
|
||||
}
|
||||
|
||||
targetDate = (timeMinus36h.isAfter(lastHistoryRecordTime) ? timeMinus36h : lastHistoryRecordTime);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// FIXME read history
|
||||
|
||||
PumpHistoryResult historyResult = new PumpHistoryResult(null, null);
|
||||
|
||||
PumpHistoryEntry latestEntry = historyResult.getLatestEntry();
|
||||
|
||||
if (latestEntry == null) // no new history to read
|
||||
return;
|
||||
|
||||
this.lastPumpHistoryEntry = latestEntry;
|
||||
SP.putLong(MedtronicConst.Statistics.LastPumpHistoryEntry,
|
||||
DateTimeUtil.toATechDate(latestEntry.getLocalDateTime()));
|
||||
|
||||
// determine if first run, if yes detrmine how much of update do we need
|
||||
// first run:
|
||||
// get last hiostory entry, if not there download 1.5 days of data
|
||||
|
|
|
@ -135,7 +135,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
rfSpyResponse.wasTimeout());
|
||||
} else {
|
||||
|
||||
rememberLastGoodDeviceCommunicationTime();
|
||||
// rememberLastGoodDeviceCommunicationTime();
|
||||
|
||||
// radioResponse.rssi;
|
||||
Object dataResponse = medtronicConverter.convertResponse(MedtronicCommandType.PumpModel,
|
||||
|
@ -774,9 +774,9 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
|
||||
Object responseObject = sendAndGetResponseWithCheck(MedtronicCommandType.PumpModel);
|
||||
|
||||
if (!MedtronicUtil.isModelSet()) {
|
||||
MedtronicUtil.setMedtronicPumpModel((MedtronicDeviceType)responseObject);
|
||||
}
|
||||
// if (!MedtronicUtil.isModelSet()) {
|
||||
// MedtronicUtil.setMedtronicPumpModel((MedtronicDeviceType)responseObject);
|
||||
// }
|
||||
|
||||
return responseObject == null ? null : (MedtronicDeviceType)responseObject;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,12 @@ public class MedtronicConverter {
|
|||
|
||||
public Object convertResponse(MedtronicCommandType commandType, byte[] rawContent) {
|
||||
|
||||
if ((rawContent == null || rawContent.length < 1) && commandType != MedtronicCommandType.PumpModel) {
|
||||
LOG.warn("Content is empty or too shor, no data to convert (type={},isNull={},length={})",
|
||||
commandType.name(), rawContent == null, rawContent == null ? "-" : rawContent.length);
|
||||
return null;
|
||||
}
|
||||
|
||||
LOG.debug("Raw response before convert: " + HexDump.toHexStringDisplayable(rawContent));
|
||||
|
||||
this.pumpModel = MedtronicUtil.getMedtronicPumpModel();
|
||||
|
@ -53,7 +59,7 @@ public class MedtronicConverter {
|
|||
}
|
||||
|
||||
case GetBatteryStatus: {
|
||||
return decodeBatteryStatus(rawContent);
|
||||
return decodeBatteryStatus(rawContent); // 1
|
||||
}
|
||||
|
||||
case GetBasalProfileSTD:
|
||||
|
@ -63,7 +69,7 @@ public class MedtronicConverter {
|
|||
}
|
||||
|
||||
case ReadTemporaryBasal: {
|
||||
return new TempBasalPair(rawContent);
|
||||
return new TempBasalPair(rawContent); // 5
|
||||
}
|
||||
|
||||
case Settings_512: {
|
||||
|
@ -75,7 +81,7 @@ public class MedtronicConverter {
|
|||
}
|
||||
|
||||
case SetBolus: {
|
||||
return rawContent;
|
||||
return rawContent; // 1
|
||||
}
|
||||
|
||||
default: {
|
||||
|
@ -88,12 +94,20 @@ public class MedtronicConverter {
|
|||
|
||||
|
||||
private MedtronicDeviceType decodeModel(byte[] rawContent) {
|
||||
|
||||
if ((rawContent == null || rawContent.length < 4)) {
|
||||
LOG.warn("Error reading PumpModel, returning Unknown_Device");
|
||||
return MedtronicDeviceType.Unknown_Device;
|
||||
}
|
||||
|
||||
String rawModel = StringUtil.fromBytes(ByteUtil.substring(rawContent, 1, 3));
|
||||
MedtronicDeviceType pumpModel = MedtronicDeviceType.getByDescription(rawModel);
|
||||
LOG.debug("PumpModel: [raw={}, resolved={}]", rawModel, pumpModel.name());
|
||||
|
||||
if (pumpModel != MedtronicDeviceType.Unknown_Device) {
|
||||
MedtronicUtil.setMedtronicPumpModel(pumpModel);
|
||||
if (!MedtronicUtil.isModelSet()) {
|
||||
MedtronicUtil.setMedtronicPumpModel(pumpModel);
|
||||
}
|
||||
}
|
||||
|
||||
return pumpModel;
|
||||
|
|
|
@ -13,7 +13,7 @@ import org.slf4j.LoggerFactory;
|
|||
*/
|
||||
|
||||
/**
|
||||
* History page contains data, sorted from oldest to newest
|
||||
* History page contains data, sorted from newest to oldest (0=newest..n=oldest)
|
||||
*/
|
||||
public class PumpHistoryResult {
|
||||
|
||||
|
@ -107,6 +107,19 @@ public class PumpHistoryResult {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return latest entry (entry with highest date time)
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public PumpHistoryEntry getLatestEntry() {
|
||||
if (this.validEntries == null || this.validEntries.size() == 0)
|
||||
return null;
|
||||
else
|
||||
return this.validEntries.get(0);
|
||||
}
|
||||
|
||||
|
||||
public boolean isSearchRequired() {
|
||||
return searchType != SearchType.None;
|
||||
}
|
||||
|
|
|
@ -119,25 +119,9 @@ public class MedtronicUITask {
|
|||
|
||||
case SetBasalProfileSTD:
|
||||
case SetBasalProfileA: {
|
||||
BasalProfile profile = (BasalProfile) parameters[0];
|
||||
BasalProfile profile = (BasalProfile)parameters[0];
|
||||
|
||||
returnData = communicationManager.setBasalProfile(profile);
|
||||
// Float amount = getAmount();
|
||||
//
|
||||
// if (amount != null) {
|
||||
//
|
||||
// BasalProfile profile = new BasalProfile();
|
||||
//
|
||||
// int basalStrokes1 = MedtronicUtil.getBasalStrokesInt(amount);
|
||||
// int basalStrokes2 = MedtronicUtil.getBasalStrokesInt(amount * 2);
|
||||
//
|
||||
// for (int i = 0; i < 24; i++) {
|
||||
// profile.addEntry(new BasalProfileEntry(i % 2 == 0 ? basalStrokes1 : basalStrokes2, i * 2));
|
||||
// }
|
||||
//
|
||||
// returnData = communicationManager.setBasalProfile(profile);
|
||||
// }
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -231,6 +215,7 @@ public class MedtronicUITask {
|
|||
return (responseType == MedtronicUIResponseType.Data);
|
||||
}
|
||||
|
||||
|
||||
public Object getParameter(int index) {
|
||||
return parameters[index];
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@ package info.nightscout.androidaps.plugins.PumpMedtronic.data;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.joda.time.LocalDateTime;
|
||||
|
||||
import info.nightscout.androidaps.plugins.PumpMedtronic.comm.history.pump.PumpHistoryEntry;
|
||||
|
||||
/**
|
||||
|
@ -15,6 +17,7 @@ public class MedtronicHistoryData {
|
|||
private boolean suspended = false;
|
||||
private boolean relevantConfigurationChanged = false;
|
||||
private boolean basalProfileChanged = true;
|
||||
private LocalDateTime lastHistoryRecordTime;
|
||||
|
||||
|
||||
public MedtronicHistoryData() {
|
||||
|
@ -49,4 +52,15 @@ public class MedtronicHistoryData {
|
|||
basalProfileChanged = true; // FIXME when this works this should reset to false
|
||||
}
|
||||
|
||||
|
||||
public void setLastHistoryRecordTime(LocalDateTime lastHistoryRecordTime) {
|
||||
|
||||
this.lastHistoryRecordTime = lastHistoryRecordTime;
|
||||
}
|
||||
|
||||
|
||||
public LocalDateTime getLastHistoryRecordTime() {
|
||||
|
||||
return lastHistoryRecordTime;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,9 @@ import org.joda.time.Instant;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.defs.PumpType;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.utils.ByteUtil;
|
||||
import info.nightscout.androidaps.plugins.PumpCommon.utils.FabricUtil;
|
||||
import info.nightscout.androidaps.plugins.PumpMedtronic.util.MedtronicUtil;
|
||||
|
||||
/**
|
||||
|
@ -109,6 +112,22 @@ public class BasalProfile {
|
|||
}
|
||||
|
||||
|
||||
public String basalProfileToString() {
|
||||
StringBuffer sb = new StringBuffer("Basal Profile [");
|
||||
List<BasalProfileEntry> entries = getEntries();
|
||||
for (int i = 0; i < entries.size(); i++) {
|
||||
BasalProfileEntry entry = entries.get(i);
|
||||
String startString = entry.startTime.toString("HH:mm");
|
||||
|
||||
sb.append(String.format("%s=%.3f, ", startString, entry.rate));
|
||||
}
|
||||
|
||||
sb.append("]");
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
// TODO: this function must be expanded to include changes in which profile is in use.
|
||||
// and changes to the profiles themselves.
|
||||
public BasalProfileEntry getEntryForTime(Instant when) {
|
||||
|
@ -217,14 +236,27 @@ public class BasalProfile {
|
|||
|
||||
public Double[] getProfilesByHour() {
|
||||
|
||||
List<BasalProfileEntry> entries = getEntries();
|
||||
List<BasalProfileEntry> entries = null;
|
||||
|
||||
if (entries.size() == 0) {
|
||||
try {
|
||||
entries = getEntries();
|
||||
} catch (Exception ex) {
|
||||
LOG.error("=============================================================================");
|
||||
LOG.error(" Error generating entries. Ex.: " + ex, ex);
|
||||
LOG.error(" rawBasalValues: " + ByteUtil.getHex(this.getRawData()));
|
||||
LOG.error("=============================================================================");
|
||||
|
||||
FabricUtil.createEvent("MedtronicBasalProfileGetByHourError", null);
|
||||
}
|
||||
|
||||
if (entries == null || entries.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Double[] basalByHour = new Double[24];
|
||||
|
||||
PumpType pumpType = MedtronicUtil.getPumpStatus().pumpType;
|
||||
|
||||
for (int i = 0; i < entries.size(); i++) {
|
||||
BasalProfileEntry current = entries.get(i);
|
||||
|
||||
|
@ -247,7 +279,10 @@ public class BasalProfile {
|
|||
// System.out.println("Current time: " + currentTime + " Next Time: " + lastHour);
|
||||
|
||||
for (int j = currentTime; j < lastHour; j++) {
|
||||
basalByHour[j] = current.rate;
|
||||
if (pumpType == null)
|
||||
basalByHour[j] = current.rate;
|
||||
else
|
||||
basalByHour[j] = pumpType.determineCorrectBasalSize(current.rate);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -270,6 +305,6 @@ public class BasalProfile {
|
|||
|
||||
|
||||
public String toString() {
|
||||
return getBasalProfileAsString();
|
||||
return basalProfileToString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -156,8 +156,14 @@ public class RileyLinkMedtronicService extends RileyLinkService {
|
|||
} else {
|
||||
LOG.info("Using pump ID " + pumpID);
|
||||
|
||||
String oldId = rileyLinkServiceData.pumpID;
|
||||
|
||||
rileyLinkServiceData.setPumpID(pumpID, pumpIDBytes);
|
||||
|
||||
if (oldId != null && !oldId.equals(pumpID)) {
|
||||
MedtronicUtil.setMedtronicPumpModel(null); // if we change pumpId, model probably changed too
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -422,9 +422,9 @@ public class MedtronicUtil extends RileyLinkUtil {
|
|||
|
||||
|
||||
public static void setMedtronicPumpModel(MedtronicDeviceType medtronicPumpModel) {
|
||||
if (medtronicPumpModel != null && medtronicPumpModel != MedtronicDeviceType.Unknown_Device) {
|
||||
MedtronicUtil.medtronicPumpModel = medtronicPumpModel;
|
||||
}
|
||||
// if (medtronicPumpModel != null && medtronicPumpModel != MedtronicDeviceType.Unknown_Device) {
|
||||
MedtronicUtil.medtronicPumpModel = medtronicPumpModel;
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package info.nightscout.utils;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import com.crashlytics.android.Crashlytics;
|
||||
import com.crashlytics.android.answers.Answers;
|
||||
import com.crashlytics.android.answers.CustomEvent;
|
||||
|
@ -10,14 +12,12 @@ import info.nightscout.androidaps.MainApp;
|
|||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Created by jamorham on 21/02/2018.
|
||||
* <p>
|
||||
* Some users do not wish to be tracked, Fabric Answers and Crashlytics do not provide an easy way
|
||||
* to disable them and make calls from a potentially invalid singleton reference. This wrapper
|
||||
* emulates the methods but ignores the request if the instance is null or invalid.
|
||||
* Some users do not wish to be tracked, Fabric Answers and Crashlytics do not provide an easy way to disable them and
|
||||
* make calls from a potentially invalid singleton reference. This wrapper emulates the methods but ignores the request
|
||||
* if the instance is null or invalid.
|
||||
*/
|
||||
|
||||
public class FabricPrivacy {
|
||||
|
@ -33,12 +33,14 @@ public class FabricPrivacy {
|
|||
return instance;
|
||||
}
|
||||
|
||||
|
||||
private static synchronized void initSelf() {
|
||||
if (instance == null) {
|
||||
instance = new FabricPrivacy();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Crashlytics logException
|
||||
public static void logException(Throwable throwable) {
|
||||
try {
|
||||
|
@ -49,6 +51,7 @@ public class FabricPrivacy {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// Crashlytics log
|
||||
public static void log(String msg) {
|
||||
try {
|
||||
|
@ -59,6 +62,7 @@ public class FabricPrivacy {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// Crashlytics log
|
||||
public static void log(int priority, String tag, String msg) {
|
||||
try {
|
||||
|
@ -69,10 +73,15 @@ public class FabricPrivacy {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public static boolean fabricEnabled() {
|
||||
if (MainApp.isEngineeringMode())
|
||||
return true;
|
||||
|
||||
return SP.getBoolean("enable_fabric", true);
|
||||
}
|
||||
|
||||
|
||||
// Answers logCustom
|
||||
public void logCustom(CustomEvent event) {
|
||||
try {
|
||||
|
@ -87,8 +96,10 @@ public class FabricPrivacy {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public static void uploadDailyStats() {
|
||||
if (!fabricEnabled()) return;
|
||||
if (!fabricEnabled())
|
||||
return;
|
||||
|
||||
long lastUploadDay = SP.getLong(MainApp.gs(R.string.key_plugin_stats_report_timestamp), 0L);
|
||||
|
||||
|
@ -106,11 +117,12 @@ public class FabricPrivacy {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private static void uploadPluginStats() {
|
||||
CustomEvent pluginStats = new CustomEvent("PluginStats");
|
||||
pluginStats.putCustomAttribute("version", BuildConfig.VERSION);
|
||||
pluginStats.putCustomAttribute("HEAD", BuildConfig.HEAD);
|
||||
pluginStats.putCustomAttribute("language", SP.getString(R.string.key_language,"default"));
|
||||
pluginStats.putCustomAttribute("language", SP.getString(R.string.key_language, "default"));
|
||||
for (PluginBase plugin : MainApp.getPluginsList()) {
|
||||
if (plugin.isEnabled(plugin.getType()) && !plugin.pluginDescription.alwaysEnabled) {
|
||||
// Fabric allows no more than 20 attributes attached to an event. By reporting disabled plugins as
|
||||
|
@ -123,6 +135,7 @@ public class FabricPrivacy {
|
|||
getInstance().logCustom(pluginStats);
|
||||
}
|
||||
|
||||
|
||||
private static void uploadAppUsageType() {
|
||||
CustomEvent type = new CustomEvent("AppUsageType");
|
||||
if (Config.NSCLIENT)
|
||||
|
|
|
@ -3,7 +3,7 @@ RileyLinkAAPS
|
|||
|
||||
|
||||
Medtronic
|
||||
- set basal profile (try to get to work - see new Loop code)
|
||||
+ set basal profile (try to get to work - see new Loop code)
|
||||
- read history
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue