medtronic-0.11.3-SNAPSHOT:
- fix for problem with TBRs - added code to prevent crashing if it comes to error by parsing (will possibly be removed later) or modified - fixed problem with configuration parsing (returns error/or rather retries if configuration is too short) - added validation for BasalProfiles... might need to extend that though...
This commit is contained in:
parent
5878a33ac7
commit
2a680cd8e9
|
@ -105,7 +105,7 @@ android {
|
|||
multiDexEnabled true
|
||||
versionCode 1500
|
||||
// dev_version: 2.3.1-dev
|
||||
version "medtronic-0.11.2-SNAPSHOT"
|
||||
version "medtronic-0.11.3-SNAPSHOT"
|
||||
buildConfigField "String", "VERSION", '"' + version + '"'
|
||||
buildConfigField "String", "BUILDVERSION", '"' + generateGitBuild() + '-' + generateDate() + '"'
|
||||
buildConfigField "String", "HEAD", '"' + generateGitBuild() + '"'
|
||||
|
|
|
@ -22,7 +22,6 @@ import org.slf4j.LoggerFactory;
|
|||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executors;
|
||||
|
@ -1127,16 +1126,17 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
try {
|
||||
QueryBuilder<TemporaryBasal, Long> queryBuilder = null;
|
||||
queryBuilder = getDaoTemporaryBasal().queryBuilder();
|
||||
queryBuilder.orderBy("date", false);
|
||||
Where where = queryBuilder.where();
|
||||
where.eq("pumpId", pumpId);
|
||||
PreparedQuery<TemporaryBasal> preparedQuery = queryBuilder.prepare();
|
||||
List<TemporaryBasal> list = getDaoTemporaryBasal().query(preparedQuery);
|
||||
|
||||
if (list.size() != 1) {
|
||||
return null;
|
||||
} else {
|
||||
if (list.size() > 0)
|
||||
return list.get(0);
|
||||
}
|
||||
else
|
||||
return null;
|
||||
|
||||
} catch (SQLException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
|
@ -1821,4 +1821,4 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
}
|
||||
|
||||
// ---------------- Food handling ---------------
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,7 +92,10 @@ public class RileyLinkUtil {
|
|||
|
||||
|
||||
public static RileyLinkError getError() {
|
||||
return RileyLinkUtil.rileyLinkServiceData.errorCode;
|
||||
if (RileyLinkUtil.rileyLinkServiceData != null)
|
||||
return RileyLinkUtil.rileyLinkServiceData.errorCode;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -189,7 +189,7 @@ public abstract class RileyLinkService extends Service {
|
|||
if (RileyLinkUtil.getServiceState() == RileyLinkServiceState.NotStarted) {
|
||||
if (!bluetoothInit()) {
|
||||
LOG.error("RileyLink can't get activated, Bluetooth is not functioning correctly. {}",
|
||||
RileyLinkUtil.getError().name());
|
||||
RileyLinkUtil.getError() != null ? RileyLinkUtil.getError().name() : "Unknown error (null)");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,8 +4,6 @@ package info.nightscout.androidaps.plugins.pump.common.utils;
|
|||
* Created by andy on 10/25/18.
|
||||
*/
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import org.joda.time.LocalDateTime;
|
||||
import org.joda.time.Minutes;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -26,27 +24,27 @@ public class DateTimeUtil {
|
|||
|
||||
/**
|
||||
* DateTime is packed as long: yyyymmddHHMMss
|
||||
*
|
||||
*
|
||||
* @param atechDateTime
|
||||
* @return
|
||||
*/
|
||||
public static LocalDateTime toLocalDateTime(long atechDateTime) {
|
||||
int year = (int)(atechDateTime / 10000000000L);
|
||||
int year = (int) (atechDateTime / 10000000000L);
|
||||
atechDateTime -= year * 10000000000L;
|
||||
|
||||
int month = (int)(atechDateTime / 100000000L);
|
||||
int month = (int) (atechDateTime / 100000000L);
|
||||
atechDateTime -= month * 100000000L;
|
||||
|
||||
int dayOfMonth = (int)(atechDateTime / 1000000L);
|
||||
int dayOfMonth = (int) (atechDateTime / 1000000L);
|
||||
atechDateTime -= dayOfMonth * 1000000L;
|
||||
|
||||
int hourOfDay = (int)(atechDateTime / 10000L);
|
||||
int hourOfDay = (int) (atechDateTime / 10000L);
|
||||
atechDateTime -= hourOfDay * 10000L;
|
||||
|
||||
int minute = (int)(atechDateTime / 100L);
|
||||
int minute = (int) (atechDateTime / 100L);
|
||||
atechDateTime -= minute * 100L;
|
||||
|
||||
int second = (int)atechDateTime;
|
||||
int second = (int) atechDateTime;
|
||||
|
||||
try {
|
||||
return new LocalDateTime(year, month, dayOfMonth, hourOfDay, minute, second);
|
||||
|
@ -59,6 +57,41 @@ public class DateTimeUtil {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* DateTime is packed as long: yyyymmddHHMMss
|
||||
*
|
||||
* @param atechDateTime
|
||||
* @return
|
||||
*/
|
||||
public static GregorianCalendar toGregorianCalendar(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;
|
||||
|
||||
try {
|
||||
return new GregorianCalendar(year, month, dayOfMonth, hourOfDay, minute, second);
|
||||
} catch (Exception ex) {
|
||||
if (L.isEnabled(L.PUMPCOMM))
|
||||
LOG.error("DateTimeUtil", String.format("Error creating GregorianCalendar from values [atechDateTime=%d, year=%d, month=%d, day=%d, hour=%d, minute=%d, second=%d]", atechDateTime, year, month, dayOfMonth, hourOfDay, minute, second));
|
||||
//return null;
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static long toATechDate(LocalDateTime ldt) {
|
||||
long atechDateTime = 0L;
|
||||
|
||||
|
@ -125,7 +158,7 @@ public class DateTimeUtil {
|
|||
long atechDateTime = 0L;
|
||||
|
||||
atechDateTime += (date.getYear() + 1900) * 10000000000L;
|
||||
atechDateTime += (date.getMonth() +1) * 100000000L;
|
||||
atechDateTime += (date.getMonth() + 1) * 100000000L;
|
||||
atechDateTime += date.getDate() * 1000000L;
|
||||
atechDateTime += date.getHours() * 10000L;
|
||||
atechDateTime += date.getMinutes() * 100L;
|
||||
|
|
|
@ -17,7 +17,10 @@ public class StringUtil {
|
|||
|
||||
|
||||
public static String fromBytes(byte[] ra) {
|
||||
return new String(ra, Charset.forName("UTF-8"));
|
||||
if (ra == null)
|
||||
return "null array";
|
||||
else
|
||||
return new String(ra, Charset.forName("UTF-8"));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -66,6 +66,7 @@ import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicCommandTy
|
|||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicCustomActionType;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicNotificationType;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicStatusRefreshType;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicUIResponseType;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.driver.MedtronicPumpStatus;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.events.EventMedtronicPumpValuesChanged;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.service.RileyLinkMedtronicService;
|
||||
|
@ -560,7 +561,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
medtronicUIComm.executeCommand(MedtronicCommandType.getSettings(MedtronicUtil.getMedtronicPumpModel()));
|
||||
|
||||
// read profile (once, later its controlled by isThisProfileSet method)
|
||||
medtronicUIComm.executeCommand(MedtronicCommandType.GetBasalProfileSTD);
|
||||
getBasalProfiles();
|
||||
|
||||
int errorCount = medtronicUIComm.getInvalidResponsesCount();
|
||||
|
||||
|
@ -593,6 +594,17 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
|||
this.firstRun = false;
|
||||
}
|
||||
|
||||
private void getBasalProfiles() {
|
||||
|
||||
MedtronicUITask medtronicUITask = medtronicUIComm.executeCommand(MedtronicCommandType.GetBasalProfileSTD);
|
||||
|
||||
if (medtronicUITask.getResponseType() == MedtronicUIResponseType.Error) {
|
||||
medtronicUIComm.executeCommand(MedtronicCommandType.GetBasalProfileSTD);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isThisProfileSet(Profile profile) {
|
||||
|
|
|
@ -51,9 +51,10 @@ import info.nightscout.androidaps.utils.SP;
|
|||
|
||||
/**
|
||||
* Original file created by geoff on 5/30/16.
|
||||
* <p>
|
||||
*
|
||||
* Split into 2 implementations, so that we can split it by target device. - Andy
|
||||
* This was mostly rewritten from Original version
|
||||
* This was mostly rewritten from Original version, and lots of commands and
|
||||
* functionality added.
|
||||
*/
|
||||
public class MedtronicCommunicationManager extends RileyLinkCommunicationManager {
|
||||
|
||||
|
@ -65,7 +66,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
static MedtronicCommunicationManager medtronicCommunicationManager;
|
||||
String errorMessage;
|
||||
private MedtronicConverter medtronicConverter;
|
||||
private boolean debugSetCommands = isLogEnabled();
|
||||
private boolean debugSetCommands = false;
|
||||
|
||||
private MedtronicPumpHistoryDecoder pumpHistoryDecoder;
|
||||
private boolean doWakeUpBeforeCommand = true;
|
||||
|
@ -110,8 +111,8 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
|
||||
|
||||
/**
|
||||
* We do actual wakeUp and compare PumpModel with currently selected one. If returned model is not Unknown,
|
||||
* pump is reachable.
|
||||
* We do actual wakeUp and compare PumpModel with currently selected one. If returned model is
|
||||
* not Unknown, pump is reachable.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
|
@ -163,8 +164,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
LOG.info("wakeup: raw response is " + ByteUtil.shortHexString(rfSpyResponse.getRaw()));
|
||||
|
||||
if (rfSpyResponse.wasTimeout()) {
|
||||
if (isLogEnabled())
|
||||
LOG.error("isDeviceReachable. Failed to find pump (timeout).");
|
||||
LOG.error("isDeviceReachable. Failed to find pump (timeout).");
|
||||
} else if (rfSpyResponse.looksLikeRadioPacket()) {
|
||||
RadioResponse radioResponse = new RadioResponse();
|
||||
|
||||
|
@ -177,9 +177,8 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
PumpMessage pumpResponse = createResponseMessage(radioResponse.getPayload(), PumpMessage.class);
|
||||
|
||||
if (!pumpResponse.isValid()) {
|
||||
if (isLogEnabled())
|
||||
LOG.warn("Response is invalid ! [interrupted={}, timeout={}]", rfSpyResponse.wasInterrupted(),
|
||||
rfSpyResponse.wasTimeout());
|
||||
LOG.warn("Response is invalid ! [interrupted={}, timeout={}]", rfSpyResponse.wasInterrupted(),
|
||||
rfSpyResponse.wasTimeout());
|
||||
} else {
|
||||
|
||||
// radioResponse.rssi;
|
||||
|
@ -215,20 +214,17 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
}
|
||||
|
||||
} else {
|
||||
if (isLogEnabled())
|
||||
LOG.warn("isDeviceReachable. Failed to parse radio response: "
|
||||
+ ByteUtil.shortHexString(rfSpyResponse.getRaw()));
|
||||
LOG.warn("isDeviceReachable. Failed to parse radio response: "
|
||||
+ ByteUtil.shortHexString(rfSpyResponse.getRaw()));
|
||||
}
|
||||
|
||||
} catch (RileyLinkCommunicationException e) {
|
||||
if (isLogEnabled())
|
||||
LOG.warn("isDeviceReachable. Failed to decode radio response: "
|
||||
+ ByteUtil.shortHexString(rfSpyResponse.getRaw()));
|
||||
LOG.warn("isDeviceReachable. Failed to decode radio response: "
|
||||
+ ByteUtil.shortHexString(rfSpyResponse.getRaw()));
|
||||
}
|
||||
|
||||
} else {
|
||||
if (isLogEnabled())
|
||||
LOG.warn("isDeviceReachable. Unknown response: " + ByteUtil.shortHexString(rfSpyResponse.getRaw()));
|
||||
LOG.warn("isDeviceReachable. Unknown response: " + ByteUtil.shortHexString(rfSpyResponse.getRaw()));
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -303,12 +299,10 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
// LOG.debug("PumpResponse: " + rval);
|
||||
|
||||
if (rval.commandType != MedtronicCommandType.CommandACK) {
|
||||
if (isLogEnabled())
|
||||
LOG.error("runCommandWithFrames: Pump did not ACK frame #{}", frameNr);
|
||||
LOG.error("runCommandWithFrames: Pump did not ACK frame #{}", frameNr);
|
||||
|
||||
if (isLogEnabled())
|
||||
LOG.error("Run command with Frames FAILED (command={}, response={})", commandType.name(),
|
||||
rval.toString());
|
||||
LOG.error("Run command with Frames FAILED (command={}, response={})", commandType.name(),
|
||||
rval.toString());
|
||||
|
||||
return new PumpMessage("No ACK after frame #" + frameNr);
|
||||
} else {
|
||||
|
@ -482,7 +476,7 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
if (isLogEnabled())
|
||||
LOG.debug("getPumpHistory: Found {} history entries.", medtronicHistoryEntries.size());
|
||||
|
||||
pumpTotalResult.addHistoryEntries(medtronicHistoryEntries);
|
||||
pumpTotalResult.addHistoryEntries(medtronicHistoryEntries, pageNumber);
|
||||
|
||||
if (isLogEnabled())
|
||||
LOG.debug("getPumpHistory: Search status: Search finished: {}", pumpTotalResult.isSearchFinished());
|
||||
|
@ -613,10 +607,15 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
|
||||
Object dataResponse = medtronicConverter.convertResponse(commandType, response.getRawContent());
|
||||
|
||||
if (isLogEnabled())
|
||||
LOG.debug("Converted response for {} is {}.", commandType.name(), dataResponse);
|
||||
if (dataResponse != null) {
|
||||
this.errorMessage = null;
|
||||
if (isLogEnabled())
|
||||
LOG.debug("Converted response for {} is {}.", commandType.name(), dataResponse);
|
||||
|
||||
return dataResponse;
|
||||
return dataResponse;
|
||||
} else {
|
||||
this.errorMessage = "Error decoding response.";
|
||||
}
|
||||
} else {
|
||||
this.errorMessage = check;
|
||||
// return null;
|
||||
|
@ -766,13 +765,11 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
return basalProfile;
|
||||
|
||||
} catch (RileyLinkCommunicationException e) {
|
||||
if (isLogEnabled())
|
||||
LOG.warn("Error getting response from RileyLink (error={}, retry={})", e.getMessage(), retries + 1);
|
||||
LOG.error("Error getting response from RileyLink (error={}, retry={})", e.getMessage(), retries + 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (isLogEnabled())
|
||||
LOG.warn("Error reading profile in max retries.");
|
||||
LOG.warn("Error reading profile in max retries.");
|
||||
MedtronicUtil.setCurrentCommand(null);
|
||||
MedtronicUtil.setPumpDeviceState(PumpDeviceState.Sleeping);
|
||||
|
||||
|
@ -944,18 +941,20 @@ public class MedtronicCommunicationManager extends RileyLinkCommunicationManager
|
|||
|
||||
for (int retries = 0; retries <= MAX_COMMAND_TRIES; retries++) {
|
||||
|
||||
// PumpMessage responseMessage = null;
|
||||
PumpMessage responseMessage = null;
|
||||
try {
|
||||
PumpMessage responseMessage = runCommandWithFrames(MedtronicCommandType.SetBasalProfileSTD,
|
||||
responseMessage = runCommandWithFrames(MedtronicCommandType.SetBasalProfileSTD,
|
||||
basalProfileFrames);
|
||||
|
||||
return responseMessage.commandType == MedtronicCommandType.CommandACK;
|
||||
if (responseMessage.commandType == MedtronicCommandType.CommandACK)
|
||||
return true;
|
||||
|
||||
} catch (RileyLinkCommunicationException e) {
|
||||
if (isLogEnabled())
|
||||
LOG.warn("Error getting response from RileyLink (error={}, retry={})", e.getMessage(), retries + 1);
|
||||
}
|
||||
|
||||
// LOG.debug("Set Basal Profile: {}", HexDump.toHexStringDisplayable(responseMessage.getRawContent()));
|
||||
LOG.warn("Set Basal Profile: Invalid response: commandType={},rawData={}", responseMessage.commandType, ByteUtil.getHex(responseMessage.getRawContent()));
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -67,7 +67,8 @@ public class MedtronicConverter {
|
|||
case GetBasalProfileSTD:
|
||||
case GetBasalProfileA:
|
||||
case GetBasalProfileB: {
|
||||
return new BasalProfile(rawContent);
|
||||
return decodeBasalProfile(rawContent);
|
||||
|
||||
}
|
||||
|
||||
case ReadTemporaryBasal: {
|
||||
|
@ -75,11 +76,11 @@ public class MedtronicConverter {
|
|||
}
|
||||
|
||||
case Settings_512: {
|
||||
return decodeSettings512(rawContent);
|
||||
return decodeSettingsLoop(rawContent);
|
||||
}
|
||||
|
||||
case Settings: {
|
||||
return decodeSettings(rawContent);
|
||||
return decodeSettingsLoop(rawContent);
|
||||
}
|
||||
|
||||
case SetBolus: {
|
||||
|
@ -94,6 +95,14 @@ public class MedtronicConverter {
|
|||
|
||||
}
|
||||
|
||||
|
||||
private BasalProfile decodeBasalProfile(byte[] rawContent) {
|
||||
|
||||
BasalProfile basalProfile = new BasalProfile(rawContent);
|
||||
|
||||
return basalProfile.verify() ? basalProfile : null;
|
||||
}
|
||||
|
||||
|
||||
private MedtronicDeviceType decodeModel(byte[] rawContent) {
|
||||
|
||||
|
@ -185,7 +194,54 @@ public class MedtronicConverter {
|
|||
}
|
||||
|
||||
|
||||
public Map<String, PumpSettingDTO> decodeSettings512(byte[] rd) {
|
||||
public Map<String, PumpSettingDTO> decodeSettingsLoop(byte[] rd) {
|
||||
|
||||
Map<String, PumpSettingDTO> map = new HashMap<>();
|
||||
|
||||
addSettingToMap("PCFG_MAX_BOLUS", "" + decodeMaxBolus(rd), PumpConfigurationGroup.Bolus, map);
|
||||
addSettingToMap(
|
||||
"PCFG_MAX_BASAL",
|
||||
""
|
||||
+ decodeBasalInsulin(ByteUtil.makeUnsignedShort(rd[getSettingIndexMaxBasal()],
|
||||
rd[getSettingIndexMaxBasal() + 1])), PumpConfigurationGroup.Basal, map);
|
||||
addSettingToMap("CFG_BASE_CLOCK_MODE", rd[getSettingIndexTimeDisplayFormat()] == 0 ? "12h" : "24h",
|
||||
PumpConfigurationGroup.General, map);
|
||||
|
||||
addSettingToMap("PCFG_BASAL_PROFILES_ENABLED", parseResultEnable(rd[10]), PumpConfigurationGroup.Basal, map);
|
||||
|
||||
if (rd[10] == 1) {
|
||||
String patt;
|
||||
switch (rd[11]) {
|
||||
case 0:
|
||||
patt = "STD";
|
||||
break;
|
||||
|
||||
case 1:
|
||||
patt = "A";
|
||||
break;
|
||||
|
||||
case 2:
|
||||
patt = "B";
|
||||
break;
|
||||
|
||||
default:
|
||||
patt = "???";
|
||||
break;
|
||||
}
|
||||
|
||||
addSettingToMap("PCFG_ACTIVE_BASAL_PROFILE", patt, PumpConfigurationGroup.Basal, map);
|
||||
|
||||
} else {
|
||||
addSettingToMap("PCFG_ACTIVE_BASAL_PROFILE", "STD", PumpConfigurationGroup.Basal, map);
|
||||
}
|
||||
|
||||
addSettingToMap("PCFG_TEMP_BASAL_TYPE", rd[14] != 0 ? "Percent" : "Units", PumpConfigurationGroup.Basal, map);
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
private Map<String, PumpSettingDTO> decodeSettings512(byte[] rd) {
|
||||
|
||||
Map<String, PumpSettingDTO> map = new HashMap<>();
|
||||
|
||||
|
|
|
@ -1,40 +1,28 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.comm.history;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.StringUtil;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicDeviceType;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
|
||||
|
||||
|
||||
/**
|
||||
* Application: GGC - GNU Gluco Control
|
||||
* Plug-in: GGC PlugIn Base (base class for all plugins)
|
||||
* <p>
|
||||
* See AUTHORS for copyright information.
|
||||
* <p>
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later
|
||||
* version.
|
||||
* <p>
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
* <p>
|
||||
* You should have received a copy of the GNU General Public License along with this program; if not, write to the Free
|
||||
* Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* <p>
|
||||
* Filename: DeviceIdentification Description: Class for display of Device Identification.
|
||||
* <p>
|
||||
* Author: Andy {andy@atech-software.com}
|
||||
* This file was taken from GGC - GNU Gluco Control (ggc.sourceforge.net), application for diabetes
|
||||
* management and modified/extended for AAPS.
|
||||
*
|
||||
* Author: Andy {andy.rozman@gmail.com}
|
||||
*/
|
||||
|
||||
public abstract class MedtronicHistoryDecoder<T extends MedtronicHistoryEntry> implements MedtronicHistoryDecoderInterface<T> {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(L.PUMPCOMM);
|
||||
|
@ -59,12 +47,10 @@ public abstract class MedtronicHistoryDecoder<T extends MedtronicHistoryEntry> i
|
|||
public abstract void postProcess();
|
||||
|
||||
|
||||
|
||||
protected abstract void runPostDecodeTasks();
|
||||
|
||||
|
||||
// TODO_ extend this to also use bigger pages (for now we support only 1024
|
||||
// pages)
|
||||
// TODO_ extend this to also use bigger pages (for now we support only 1024 pages)
|
||||
private List<Byte> checkPage(RawHistoryPage page, boolean partial) throws RuntimeException {
|
||||
List<Byte> byteList = new ArrayList<Byte>();
|
||||
|
||||
|
@ -109,7 +95,7 @@ public abstract class MedtronicHistoryDecoder<T extends MedtronicHistoryEntry> i
|
|||
|
||||
|
||||
protected void addToStatistics(MedtronicHistoryEntryInterface pumpHistoryEntry, RecordDecodeStatus status,
|
||||
Integer opCode) {
|
||||
Integer opCode) {
|
||||
if (!statisticsEnabled)
|
||||
return;
|
||||
|
||||
|
@ -155,7 +141,7 @@ public abstract class MedtronicHistoryDecoder<T extends MedtronicHistoryEntry> i
|
|||
|
||||
if (isLogEnabled())
|
||||
LOG.debug(" {}{} - {}. Elements: {}", entry.getKey().name(), spaces, entry.getValue().size(),
|
||||
sb.toString());
|
||||
sb.toString());
|
||||
} else {
|
||||
if (isLogEnabled())
|
||||
LOG.debug(" {} - {}", entry.getKey().name(), entry.getValue().size());
|
||||
|
|
|
@ -10,7 +10,6 @@ public interface MedtronicHistoryDecoderInterface<T> {
|
|||
|
||||
RecordDecodeStatus decodeRecord(T record);
|
||||
|
||||
|
||||
List<T> createRecords(List<Byte> dataClear);
|
||||
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.comm.history;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import com.google.gson.annotations.Expose;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil;
|
||||
|
@ -15,24 +15,10 @@ import info.nightscout.androidaps.plugins.pump.common.utils.HexDump;
|
|||
import info.nightscout.androidaps.plugins.pump.common.utils.StringUtil;
|
||||
|
||||
/**
|
||||
* Application: GGC - GNU Gluco Control
|
||||
* Plug-in: GGC PlugIn Base (base class for all plugins)
|
||||
* <p>
|
||||
* See AUTHORS for copyright information.
|
||||
* <p>
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later
|
||||
* version.
|
||||
* <p>
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
* <p>
|
||||
* You should have received a copy of the GNU General Public License along with this program; if not, write to the Free
|
||||
* Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* <p>
|
||||
* Filename: MinimedHistoryRecord Description: Minimed History Record.
|
||||
* <p>
|
||||
* Author: Andy {andy@atech-software.com}
|
||||
* This file was taken from GGC - GNU Gluco Control (ggc.sourceforge.net), application for diabetes
|
||||
* management and modified/extended for AAPS.
|
||||
*
|
||||
* Author: Andy {andy.rozman@gmail.com}
|
||||
*/
|
||||
|
||||
public abstract class MedtronicHistoryEntry implements MedtronicHistoryEntryInterface {
|
||||
|
@ -66,7 +52,8 @@ public abstract class MedtronicHistoryEntry implements MedtronicHistoryEntryInte
|
|||
protected Long pumpId;
|
||||
|
||||
/**
|
||||
* if history object is already linked to AAPS object (either Treatment, TempBasal or TDD (tdd's are not actually
|
||||
* if history object is already linked to AAPS object (either Treatment, TempBasal or TDD (tdd's
|
||||
* are not actually
|
||||
* linked))
|
||||
*/
|
||||
public boolean linked = false;
|
||||
|
|
|
@ -9,10 +9,8 @@ public interface MedtronicHistoryEntryInterface {
|
|||
|
||||
String getEntryTypeName();
|
||||
|
||||
|
||||
void setData(List<Byte> listRawData, boolean doNotProcess);
|
||||
|
||||
|
||||
int getDateLength();
|
||||
|
||||
}
|
||||
|
|
|
@ -1,25 +1,10 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.comm.history;
|
||||
|
||||
/**
|
||||
* Application: GGC - GNU Gluco Control
|
||||
* Plug-in: GGC PlugIn Base (base class for all plugins)
|
||||
* <p>
|
||||
* See AUTHORS for copyright information.
|
||||
* <p>
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later
|
||||
* version.
|
||||
* <p>
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
* <p>
|
||||
* You should have received a copy of the GNU General Public License along with this program; if not, write to the Free
|
||||
* Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* <p>
|
||||
* Filename: Record Decode Status Description: Record Decode Status shows if entry was decoded. Used mostly for
|
||||
* statistics.
|
||||
* <p>
|
||||
* Author: Andy {andy@atech-software.com}
|
||||
* This file was taken from GGC - GNU Gluco Control (ggc.sourceforge.net), application for diabetes
|
||||
* management and modified/extended for AAPS.
|
||||
*
|
||||
* Author: Andy {andy.rozman@gmail.com}
|
||||
*/
|
||||
|
||||
public enum RecordDecodeStatus {
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.comm.history.cgms;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.joda.time.LocalDateTime;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.MedtronicHistoryEntry;
|
||||
|
||||
/**
|
||||
* This file was taken from GGC - GNU Gluco Control and modified/extended for AAPS.
|
||||
* This file was taken from GGC - GNU Gluco Control (ggc.sourceforge.net), application for diabetes
|
||||
* management and modified/extended for AAPS.
|
||||
*
|
||||
* Author: Andy {andy.rozman@gmail.com}
|
||||
*/
|
||||
|
@ -79,7 +80,7 @@ public class CGMSHistoryEntry extends MedtronicHistoryEntry {
|
|||
public String getToStringStart() {
|
||||
|
||||
return "CGMSHistoryEntry [type=" + StringUtils.rightPad(entryType.name(), 18) + " ["
|
||||
+ StringUtils.leftPad("" + getOpCode(), 3) + ", 0x" + ByteUtil.getCorrectHexValue(getOpCode()) + "]";
|
||||
+ StringUtils.leftPad("" + getOpCode(), 3) + ", 0x" + ByteUtil.getCorrectHexValue(getOpCode()) + "]";
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -4,7 +4,8 @@ import java.util.HashMap;
|
|||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* This file was taken from GGC - GNU Gluco Control and modified/extended for AAPS.
|
||||
* This file was taken from GGC - GNU Gluco Control (ggc.sourceforge.net), application for diabetes
|
||||
* management and modified/extended for AAPS.
|
||||
*
|
||||
* Author: Andy {andy.rozman@gmail.com}
|
||||
*/
|
||||
|
@ -29,8 +30,7 @@ public enum CGMSHistoryEntryType {
|
|||
SensorCalFactor(0x0f, "SensorCalFactor", 1, 4, 2, DateType.MinuteSpecific), //
|
||||
Something10(0x10, "10-Something", 1, 4, 0, DateType.MinuteSpecific), //
|
||||
Something19(0x13, "19-Something", 1, 0, 0, DateType.PreviousTimeStamp),
|
||||
GlucoseSensorData(0xFF, "GlucoseSensorData", 1, 0, 0, DateType.PreviousTimeStamp);
|
||||
;
|
||||
GlucoseSensorData(0xFF, "GlucoseSensorData", 1, 0, 0, DateType.PreviousTimeStamp);;
|
||||
|
||||
private static Map<Integer, CGMSHistoryEntryType> opCodeMap = new HashMap<Integer, CGMSHistoryEntryType>();
|
||||
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.comm.history.cgms;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.joda.time.LocalDateTime;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.MedtronicHistoryDecoder;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.RecordDecodeStatus;
|
||||
|
||||
/**
|
||||
* This file was taken from GGC - GNU Gluco Control and modified/extended for AAPS.
|
||||
* This file was taken from GGC - GNU Gluco Control (ggc.sourceforge.net), application for diabetes
|
||||
* management and modified/extended for AAPS.
|
||||
*
|
||||
* Author: Andy {andy.rozman@gmail.com}
|
||||
*/
|
||||
|
@ -150,14 +150,14 @@ public class MedtronicCGMSHistoryDecoder extends MedtronicHistoryDecoder<CGMSHis
|
|||
pe.setEntryType(CGMSHistoryEntryType.None);
|
||||
pe.setOpCode(opCode);
|
||||
|
||||
pe.setData(Arrays.asList((byte)opCode), false);
|
||||
pe.setData(Arrays.asList((byte) opCode), false);
|
||||
|
||||
outList.add(pe);
|
||||
} else {
|
||||
// System.out.println("OpCode: " + opCode);
|
||||
|
||||
List<Byte> listRawData = new ArrayList<Byte>();
|
||||
listRawData.add((byte)opCode);
|
||||
listRawData.add((byte) opCode);
|
||||
|
||||
for (int j = 0; j < (entryType.getTotalLength() - 1); j++) {
|
||||
listRawData.add(dataClear.get(counter));
|
||||
|
@ -178,7 +178,7 @@ public class MedtronicCGMSHistoryDecoder extends MedtronicHistoryDecoder<CGMSHis
|
|||
CGMSHistoryEntry pe = new CGMSHistoryEntry();
|
||||
pe.setEntryType(CGMSHistoryEntryType.GlucoseSensorData);
|
||||
|
||||
pe.setData(Arrays.asList((byte)opCode), false);
|
||||
pe.setData(Arrays.asList((byte) opCode), false);
|
||||
|
||||
outList.add(pe);
|
||||
}
|
||||
|
@ -268,7 +268,7 @@ public class MedtronicCGMSHistoryDecoder extends MedtronicHistoryDecoder<CGMSHis
|
|||
if (entry.getEntryType().getDateType() == CGMSHistoryEntryType.DateType.MinuteSpecific) {
|
||||
|
||||
Long atechDateTime = DateTimeUtil.toATechDate(parseYear(data[3]), parseMonths(data[0], data[1]),
|
||||
parseDay(data[2]), parseHours(data[0]), parseMinutes(data[1]), 0);
|
||||
parseDay(data[2]), parseHours(data[0]), parseMinutes(data[1]), 0);
|
||||
|
||||
entry.setAtechDateTime(atechDateTime);
|
||||
|
||||
|
|
|
@ -25,8 +25,9 @@ import info.nightscout.androidaps.plugins.pump.medtronic.defs.PumpBolusType;
|
|||
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
|
||||
|
||||
/**
|
||||
* This file was taken from GGC - GNU Gluco Control and modified/extended for AAPS.
|
||||
* <p>
|
||||
* This file was taken from GGC - GNU Gluco Control (ggc.sourceforge.net), application for diabetes
|
||||
* management and modified/extended for AAPS.
|
||||
*
|
||||
* Author: Andy {andy.rozman@gmail.com}
|
||||
*/
|
||||
|
||||
|
@ -403,14 +404,14 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder<PumpHis
|
|||
// int bodyOffset = headerSize + timestampSize;
|
||||
int offset = body[0] * 1000 * 30 * 60;
|
||||
Float rate = null;
|
||||
int index = body[2];
|
||||
int index = entry.getHead()[0];
|
||||
|
||||
if (MedtronicDeviceType.isSameDevice(MedtronicUtil.getMedtronicPumpModel(),
|
||||
MedtronicDeviceType.Medtronic_523andHigher)) {
|
||||
rate = body[1] * 0.025f;
|
||||
}
|
||||
|
||||
LOG.info("Basal Profile Start (ERROR): offset={}, rate={}, index={}, body_raw={}", offset, rate, index,
|
||||
LOG.info("Basal Profile Start: offset={}, rate={}, index={}, body_raw={}", offset, rate, index,
|
||||
body);
|
||||
|
||||
if (rate == null) {
|
||||
|
|
|
@ -1,18 +1,19 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump;
|
||||
|
||||
import java.util.Objects;
|
||||
import com.google.gson.annotations.Expose;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import java.util.Objects;
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.HexDump;
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.StringUtil;
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.MedtronicHistoryEntry;
|
||||
|
||||
/**
|
||||
* This file was taken from GGC - GNU Gluco Control and modified/extended for AAPS.
|
||||
* This file was taken from GGC - GNU Gluco Control (ggc.sourceforge.net), application for diabetes
|
||||
* management and modified/extended for AAPS.
|
||||
*
|
||||
* Author: Andy {andy.rozman@gmail.com}
|
||||
*/
|
||||
|
@ -67,8 +68,8 @@ public class PumpHistoryEntry extends MedtronicHistoryEntry {
|
|||
@Override
|
||||
public String getToStringStart() {
|
||||
return "PumpHistoryRecord [type=" + StringUtil.getStringInLength(entryType.name(), 20) + " ["
|
||||
+ StringUtil.getStringInLength("" + getOpCode(), 3) + ", 0x"
|
||||
+ HexDump.getCorrectHexValue((byte)getOpCode()) + "]";
|
||||
+ StringUtil.getStringInLength("" + getOpCode(), 3) + ", 0x"
|
||||
+ HexDump.getCorrectHexValue((byte) getOpCode()) + "]";
|
||||
}
|
||||
|
||||
|
||||
|
@ -102,10 +103,10 @@ public class PumpHistoryEntry extends MedtronicHistoryEntry {
|
|||
if (!(o instanceof PumpHistoryEntry))
|
||||
return false;
|
||||
|
||||
PumpHistoryEntry that = (PumpHistoryEntry)o;
|
||||
PumpHistoryEntry that = (PumpHistoryEntry) o;
|
||||
|
||||
return entryType == that.entryType && //
|
||||
this.atechDateTime == that.atechDateTime; // && //
|
||||
this.atechDateTime == that.atechDateTime; // && //
|
||||
// Objects.equals(this.decodedData, that.decodedData);
|
||||
}
|
||||
|
||||
|
@ -146,7 +147,7 @@ public class PumpHistoryEntry extends MedtronicHistoryEntry {
|
|||
|
||||
@Override
|
||||
public int compare(PumpHistoryEntry o1, PumpHistoryEntry o2) {
|
||||
int data = (int)(o2.atechDateTime - o1.atechDateTime);
|
||||
int data = (int) (o2.atechDateTime - o1.atechDateTime);
|
||||
|
||||
if (data != 0)
|
||||
return data;
|
||||
|
|
|
@ -7,8 +7,9 @@ import info.nightscout.androidaps.MainApp;
|
|||
import info.nightscout.androidaps.R;
|
||||
|
||||
/**
|
||||
* This file was taken from GGC - GNU Gluco Control and modified/extended for AAPS.
|
||||
* <p>
|
||||
* This file was taken from GGC - GNU Gluco Control (ggc.sourceforge.net), application for diabetes
|
||||
* management and modified/extended for AAPS.
|
||||
*
|
||||
* Author: Andy {andy.rozman@gmail.com}
|
||||
*/
|
||||
|
||||
|
|
|
@ -9,8 +9,9 @@ import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicDeviceTyp
|
|||
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
|
||||
|
||||
/**
|
||||
* This file was taken from GGC - GNU Gluco Control and modified/extended for AAPS.
|
||||
* <p>
|
||||
* This file was taken from GGC - GNU Gluco Control (ggc.sourceforge.net), application for diabetes
|
||||
* management and modified/extended for AAPS.
|
||||
*
|
||||
* Author: Andy {andy.rozman@gmail.com}
|
||||
*/
|
||||
|
||||
|
|
|
@ -55,16 +55,18 @@ public class PumpHistoryResult {
|
|||
}
|
||||
|
||||
|
||||
public void addHistoryEntries(List<PumpHistoryEntry> entries) {
|
||||
public void addHistoryEntries(List<PumpHistoryEntry> entries, int page) {
|
||||
this.unprocessedEntries = entries;
|
||||
//LOG.debug("PumpHistoryResult. Unprocessed entries: {}", MedtronicUtil.getGsonInstance().toJson(entries));
|
||||
processEntries();
|
||||
}
|
||||
|
||||
|
||||
// TODO Bug #145 need to check if we had timeChange that went -1, that situation needs to be evaluated separately
|
||||
public void processEntries() {
|
||||
int olderEntries = 0;
|
||||
|
||||
Collections.reverse(this.unprocessedEntries);
|
||||
|
||||
switch (searchType) {
|
||||
case None:
|
||||
//LOG.debug("PE. None search");
|
||||
|
@ -72,11 +74,11 @@ public class PumpHistoryResult {
|
|||
break;
|
||||
|
||||
case LastEntry: {
|
||||
//LOG.debug("PE. Last entry search");
|
||||
LOG.debug("PE. Last entry search");
|
||||
|
||||
Collections.sort(this.unprocessedEntries, new PumpHistoryEntry.Comparator());
|
||||
//Collections.sort(this.unprocessedEntries, new PumpHistoryEntry.Comparator());
|
||||
|
||||
//LOG.debug("PE. PumpHistoryResult. Search entry date: " + searchEntry.atechDateTime);
|
||||
LOG.debug("PE. PumpHistoryResult. Search entry date: " + searchEntry.atechDateTime);
|
||||
|
||||
Long date = searchEntry.atechDateTime;
|
||||
|
||||
|
@ -94,24 +96,29 @@ public class PumpHistoryResult {
|
|||
}
|
||||
break;
|
||||
case Date: {
|
||||
//LOG.debug("PE. Date search");
|
||||
LOG.debug("PE. Date search: Search date: {}", this.searchDate);
|
||||
|
||||
|
||||
for (PumpHistoryEntry unprocessedEntry : unprocessedEntries) {
|
||||
|
||||
if (unprocessedEntry.atechDateTime == null || unprocessedEntry.atechDateTime == 0) {
|
||||
LOG.debug("PE. PumpHistoryResult. Search entry date: Entry with no date: {}", unprocessedEntry);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (unprocessedEntry.isAfter(this.searchDate)) {
|
||||
this.validEntries.add(unprocessedEntry);
|
||||
} else {
|
||||
LOG.debug("PE. PumpHistoryResult. Not after.. Unprocessed Entry [year={},entry={}]",
|
||||
DateTimeUtil.getYear(unprocessedEntry.atechDateTime), unprocessedEntry);
|
||||
|
||||
if (DateTimeUtil.getYear(unprocessedEntry.atechDateTime) > 2015)
|
||||
olderEntries++;
|
||||
}
|
||||
}
|
||||
|
||||
if (olderEntries > 0) {
|
||||
Collections.sort(this.validEntries, new PumpHistoryEntry.Comparator());
|
||||
//Collections.sort(this.validEntries, new PumpHistoryEntry.Comparator());
|
||||
|
||||
searchFinished = true;
|
||||
}
|
||||
|
|
|
@ -59,10 +59,17 @@ public class MedtronicUIPostprocessor {
|
|||
|
||||
Double[] profilesByHour = basalProfile.getProfilesByHour();
|
||||
|
||||
if (profilesByHour != null) {
|
||||
pumpStatus.basalsByHour = profilesByHour;
|
||||
pumpStatus.basalProfileStatus = BasalProfileStatus.ProfileOK;
|
||||
} else {
|
||||
try {
|
||||
|
||||
if (profilesByHour != null) {
|
||||
pumpStatus.basalsByHour = profilesByHour;
|
||||
pumpStatus.basalProfileStatus = BasalProfileStatus.ProfileOK;
|
||||
} else {
|
||||
uiTask.responseType = MedtronicUIResponseType.Error;
|
||||
uiTask.errorDescription = "No profile found.";
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
LOG.error("Basal Profile was returned, but was invalid.");
|
||||
uiTask.responseType = MedtronicUIResponseType.Error;
|
||||
uiTask.errorDescription = "No profile found.";
|
||||
}
|
||||
|
@ -161,17 +168,17 @@ public class MedtronicUIPostprocessor {
|
|||
LOG.debug("Pump Time: " + clockDTO.localDeviceTime + ", DeviceTime=" + clockDTO.pumpTime + //
|
||||
", diff: " + dur.getStandardSeconds() + " s");
|
||||
|
||||
if (dur.getStandardMinutes() >= 10) {
|
||||
if (isLogEnabled())
|
||||
LOG.warn("Pump clock needs update, pump time: " + clockDTO.pumpTime.toString("HH:mm:ss") + " (difference: "
|
||||
+ dur.getStandardSeconds() + " s)");
|
||||
sendNotification(MedtronicNotificationType.PumpWrongTimeUrgent);
|
||||
} else if (dur.getStandardMinutes() >= 4) {
|
||||
if (isLogEnabled())
|
||||
LOG.warn("Pump clock needs update, pump time: " + clockDTO.pumpTime.toString("HH:mm:ss") + " (difference: "
|
||||
+ dur.getStandardSeconds() + " s)");
|
||||
sendNotification(MedtronicNotificationType.PumpWrongTimeNormal);
|
||||
}
|
||||
// if (dur.getStandardMinutes() >= 10) {
|
||||
// if (isLogEnabled())
|
||||
// LOG.warn("Pump clock needs update, pump time: " + clockDTO.pumpTime.toString("HH:mm:ss") + " (difference: "
|
||||
// + dur.getStandardSeconds() + " s)");
|
||||
// sendNotification(MedtronicNotificationType.PumpWrongTimeUrgent);
|
||||
// } else if (dur.getStandardMinutes() >= 4) {
|
||||
// if (isLogEnabled())
|
||||
// LOG.warn("Pump clock needs update, pump time: " + clockDTO.pumpTime.toString("HH:mm:ss") + " (difference: "
|
||||
// + dur.getStandardSeconds() + " s)");
|
||||
// sendNotification(MedtronicNotificationType.PumpWrongTimeNormal);
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ public class MedtronicUITask {
|
|||
public void execute(MedtronicCommunicationManager communicationManager) {
|
||||
|
||||
if (isLogEnabled())
|
||||
LOG.warn("@@@ In execute. {}", commandType);
|
||||
LOG.debug("MedtronicUITask: @@@ In execute. {}", commandType);
|
||||
|
||||
switch (commandType) {
|
||||
case PumpModel: {
|
||||
|
@ -129,8 +129,7 @@ public class MedtronicUITask {
|
|||
break;
|
||||
|
||||
default: {
|
||||
if (isLogEnabled())
|
||||
LOG.warn("This commandType is not supported (yet) - {}.", commandType);
|
||||
LOG.warn("This commandType is not supported (yet) - {}.", commandType);
|
||||
// invalid = true;
|
||||
responseType = MedtronicUIResponseType.Invalid;
|
||||
}
|
||||
|
@ -185,7 +184,7 @@ public class MedtronicUITask {
|
|||
|
||||
EventMedtronicDeviceStatusChange statusChange;
|
||||
if (isLogEnabled())
|
||||
LOG.warn("@@@ In execute. {}", commandType);
|
||||
LOG.debug("MedtronicUITask: @@@ In execute. {}", commandType);
|
||||
|
||||
if (responseType == MedtronicUIResponseType.Data) {
|
||||
postprocessor.postProcessData(this);
|
||||
|
@ -201,10 +200,9 @@ public class MedtronicUITask {
|
|||
MainApp.bus().post(statusChange);
|
||||
} else {
|
||||
MainApp.bus().post(new EventMedtronicPumpValuesChanged());
|
||||
MedtronicUtil.getPumpStatus().setLastCommunicationToNow();
|
||||
}
|
||||
|
||||
MedtronicUtil.getPumpStatus().setLastCommunicationToNow();
|
||||
|
||||
MedtronicUtil.setCurrentCommand(null);
|
||||
}
|
||||
|
||||
|
@ -223,4 +221,9 @@ public class MedtronicUITask {
|
|||
return L.isEnabled(L.PUMP);
|
||||
}
|
||||
|
||||
|
||||
public MedtronicUIResponseType getResponseType() {
|
||||
return this.responseType;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -383,26 +383,44 @@ public class MedtronicHistoryData {
|
|||
LOG.debug("ProcessHistoryData: Bolus [count={}, items={}]", treatments.size(), gson.toJson(treatments));
|
||||
|
||||
if (treatments.size() > 0) {
|
||||
processBolusEntries(treatments);
|
||||
try {
|
||||
processBolusEntries(treatments);
|
||||
} catch (Exception ex) {
|
||||
LOG.error("ProcessHistoryData: Error processing Bolus entries: " + ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
// TBR
|
||||
List<PumpHistoryEntry> tbrs = getFilteredItems(PumpHistoryEntryType.TempBasalCombined);
|
||||
|
||||
LOG.debug("ProcessHistoryData: TBRs NOT Processed [count={}, items={}]", tbrs.size(), gson.toJson(tbrs));
|
||||
LOG.debug("ProcessHistoryData: TBRs Processed [count={}, items={}]", tbrs.size(), gson.toJson(tbrs));
|
||||
|
||||
if (tbrs.size() > 0) {
|
||||
processTBREntries(tbrs);
|
||||
try {
|
||||
processTBREntries(tbrs);
|
||||
} catch (Exception ex) {
|
||||
LOG.error("ProcessHistoryData: Error processing TBR entries: " + ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
// 'Delivery Suspend'
|
||||
List<TempBasalProcessDTO> suspends = getSuspends();
|
||||
List<TempBasalProcessDTO> suspends = null;
|
||||
|
||||
try {
|
||||
suspends = getSuspends();
|
||||
} catch (Exception ex) {
|
||||
LOG.error("ProcessHistoryData: Error getting Suspend entries: " + ex.getMessage(), ex);
|
||||
}
|
||||
|
||||
LOG.debug("ProcessHistoryData: 'Delivery Suspend' Processed [count={}, items={}]", suspends.size(),
|
||||
gson.toJson(suspends));
|
||||
|
||||
if (suspends.size() > 0) {
|
||||
processSuspends(suspends);
|
||||
if (suspends != null && suspends.size() > 0) {
|
||||
try {
|
||||
processSuspends(suspends);
|
||||
} catch (Exception ex) {
|
||||
LOG.error("ProcessHistoryData: Error processing Suspends entries: " + ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -486,7 +504,7 @@ public class MedtronicHistoryData {
|
|||
if (isCollectionEmpty(entriesFromHistory)) {
|
||||
for (PumpHistoryEntry treatment : entryList) {
|
||||
if (isLogEnabled())
|
||||
LOG.debug("Add Bolus (no db entries): " + treatment);
|
||||
LOG.debug("Add Bolus (no db entry): " + treatment);
|
||||
|
||||
addBolus(treatment, null);
|
||||
}
|
||||
|
@ -528,15 +546,6 @@ public class MedtronicHistoryData {
|
|||
LOG.debug(ProcessHistoryRecord.TBR.getDescription() + " List (before filter): {}, FromDb={}", gson.toJson(entryList),
|
||||
gson.toJson(entriesFromHistory));
|
||||
|
||||
//filterOutAlreadyAddedEntries(entryList, entriesFromHistory);
|
||||
|
||||
if (entryList.isEmpty())
|
||||
return;
|
||||
|
||||
// LOG.debug(processHistoryRecord.getDescription() + " List (after filter): {}, FromDb={}", gson.toJson(entryList),
|
||||
// gson.toJson(entriesFromHistory));
|
||||
|
||||
//PumpHistoryEntry startRecord = null;
|
||||
|
||||
TempBasalProcessDTO processDTO = null;
|
||||
List<TempBasalProcessDTO> processList = new ArrayList<>();
|
||||
|
@ -546,13 +555,16 @@ public class MedtronicHistoryData {
|
|||
TempBasalPair tbr2 = (TempBasalPair) treatment.getDecodedDataEntry("Object");
|
||||
|
||||
if (tbr2.isCancelTBR()) {
|
||||
processDTO.itemTwo = treatment;
|
||||
|
||||
if (readOldItem) {
|
||||
processDTO.processOperation = TempBasalProcessDTO.Operation.Edit;
|
||||
readOldItem = false;
|
||||
if (processDTO != null) {
|
||||
processDTO.itemTwo = treatment;
|
||||
|
||||
if (readOldItem) {
|
||||
processDTO.processOperation = TempBasalProcessDTO.Operation.Edit;
|
||||
readOldItem = false;
|
||||
}
|
||||
} else {
|
||||
processDTO.processOperation = TempBasalProcessDTO.Operation.Add;
|
||||
LOG.error("processDTO was null - shouldn't happen. ItemTwo={}", treatment);
|
||||
}
|
||||
} else {
|
||||
if (processDTO != null) {
|
||||
|
@ -561,23 +573,35 @@ public class MedtronicHistoryData {
|
|||
|
||||
processDTO = new TempBasalProcessDTO();
|
||||
processDTO.itemOne = treatment;
|
||||
processDTO.processOperation = TempBasalProcessDTO.Operation.Add;
|
||||
}
|
||||
}
|
||||
|
||||
if (processDTO != null) {
|
||||
processList.add(processDTO);
|
||||
processDTO = null;
|
||||
}
|
||||
|
||||
|
||||
if (!isCollectionEmpty(processList)) {
|
||||
|
||||
for (TempBasalProcessDTO tempBasalProcessDTO : processList) {
|
||||
|
||||
if (tempBasalProcessDTO.processOperation == TempBasalProcessDTO.Operation.Edit) {
|
||||
// edit
|
||||
TemporaryBasal tempBasal = databaseHelper.findTempBasalByPumpId(tempBasalProcessDTO.itemOne.getPumpId());
|
||||
TemporaryBasal tempBasal = findTempBasalWithPumpId(tempBasalProcessDTO.itemOne.getPumpId(), entriesFromHistory);
|
||||
|
||||
tempBasal.durationInMinutes = tempBasalProcessDTO.getDuration();
|
||||
if (tempBasal != null) {
|
||||
|
||||
databaseHelper.createOrUpdate(tempBasal);
|
||||
tempBasal.durationInMinutes = tempBasalProcessDTO.getDuration();
|
||||
|
||||
if (isLogEnabled())
|
||||
LOG.debug("Edit " + ProcessHistoryRecord.TBR.getDescription() + " - (entryFromDb={}) ", tempBasal);
|
||||
databaseHelper.createOrUpdate(tempBasal);
|
||||
|
||||
if (isLogEnabled())
|
||||
LOG.debug("Edit " + ProcessHistoryRecord.TBR.getDescription() + " - (entryFromDb={}) ", tempBasal);
|
||||
} else {
|
||||
LOG.error("TempBasal not found. Item: {}", tempBasalProcessDTO.itemOne);
|
||||
}
|
||||
|
||||
} else {
|
||||
// add
|
||||
|
@ -587,12 +611,23 @@ public class MedtronicHistoryData {
|
|||
TempBasalPair tbr2 = (TempBasalPair) treatment.getDecodedData().get("Object");
|
||||
tbr2.setDurationMinutes(tempBasalProcessDTO.getDuration());
|
||||
|
||||
DbObjectBase treatmentDb = findDbEntry(treatment, entriesFromHistory);
|
||||
TemporaryBasal tempBasal = findTempBasalWithPumpId(tempBasalProcessDTO.itemOne.getPumpId(), entriesFromHistory);
|
||||
|
||||
if (isLogEnabled())
|
||||
LOG.debug("Add " + ProcessHistoryRecord.TBR.getDescription() + " {} - (entryFromDb={}) ", treatment, treatmentDb);
|
||||
if (tempBasal == null) {
|
||||
DbObjectBase treatmentDb = findDbEntry(treatment, entriesFromHistory);
|
||||
|
||||
addTBR(treatment, (TemporaryBasal) treatmentDb);
|
||||
if (isLogEnabled())
|
||||
LOG.debug("Add " + ProcessHistoryRecord.TBR.getDescription() + " {} - (entryFromDb={}) ", treatment, treatmentDb);
|
||||
|
||||
addTBR(treatment, (TemporaryBasal) treatmentDb);
|
||||
} else {
|
||||
// this shouldn't happen
|
||||
if (tempBasal.durationInMinutes != tempBasalProcessDTO.getDuration()) {
|
||||
LOG.debug("Found entry with wrong duration (shouldn't happen)... updating");
|
||||
tempBasal.durationInMinutes = tempBasalProcessDTO.getDuration();
|
||||
}
|
||||
|
||||
}
|
||||
} // if
|
||||
} // for
|
||||
|
||||
|
@ -600,6 +635,21 @@ public class MedtronicHistoryData {
|
|||
}
|
||||
|
||||
|
||||
private TemporaryBasal findTempBasalWithPumpId(long pumpId, List<? extends DbObjectBase> entriesFromHistory) {
|
||||
|
||||
for (DbObjectBase dbObjectBase : entriesFromHistory) {
|
||||
TemporaryBasal tbr = (TemporaryBasal) dbObjectBase;
|
||||
|
||||
if (tbr.pumpId == pumpId) {
|
||||
return tbr;
|
||||
}
|
||||
}
|
||||
|
||||
TemporaryBasal tempBasal = databaseHelper.findTempBasalByPumpId(pumpId);
|
||||
return tempBasal;
|
||||
}
|
||||
|
||||
|
||||
private DbObjectBase findDbEntry(PumpHistoryEntry treatment, List<? extends DbObjectBase> entriesFromHistory) {
|
||||
|
||||
long proposedTime = DateTimeUtil.toMillisFromATD(treatment.atechDateTime);
|
||||
|
@ -1060,21 +1110,24 @@ public class MedtronicHistoryData {
|
|||
return null;
|
||||
}
|
||||
|
||||
|
||||
// is same now
|
||||
private long tryToGetByLocalTime(long atechDateTime) {
|
||||
|
||||
LocalDateTime ldt = DateTimeUtil.toLocalDateTime(atechDateTime);
|
||||
GregorianCalendar gc = DateTimeUtil.toGregorianCalendar(atechDateTime);
|
||||
return gc.getTimeInMillis();
|
||||
|
||||
ldt = ldt.plusSeconds(pumpTime.timeDifference);
|
||||
ldt = ldt.millisOfSecond().setCopy(000);
|
||||
|
||||
if (isLogEnabled())
|
||||
LOG.debug("tryToGetByLocalTime: [TimeOfEntry={}, ClockPump={}, LocalTime={}, DifferenceSec={}, "
|
||||
+ "NewTimeOfEntry={}, time={}", atechDateTime, pumpTime.pumpTime.toString("HH:mm:ss"),
|
||||
pumpTime.localDeviceTime.toString("HH:mm:ss"), pumpTime.timeDifference, ldt.toString("HH:mm:ss"), ldt
|
||||
.toDate().getTime());
|
||||
|
||||
return ldt.toDate().getTime();
|
||||
// LocalDateTime ldt = DateTimeUtil.toLocalDateTime(atechDateTime);
|
||||
//
|
||||
// ldt = ldt.plusSeconds(pumpTime.timeDifference);
|
||||
// ldt = ldt.millisOfSecond().setCopy(000);
|
||||
//
|
||||
// if (isLogEnabled())
|
||||
// LOG.debug("tryToGetByLocalTime: [TimeOfEntry={}, ClockPump={}, LocalTime={}, DifferenceSec={}, "
|
||||
// + "NewTimeOfEntry={}, time={}", atechDateTime, pumpTime.pumpTime.toString("HH:mm:ss"),
|
||||
// pumpTime.localDeviceTime.toString("HH:mm:ss"), pumpTime.timeDifference, ldt.toString("HH:mm:ss"), ldt
|
||||
// .toDate().getTime());
|
||||
//
|
||||
// return ldt.toDate().getTime();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
package info.nightscout.androidaps.plugins.pump.medtronic.data.dto;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import com.google.gson.annotations.Expose;
|
||||
|
||||
import org.joda.time.Instant;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType;
|
||||
|
@ -73,7 +73,7 @@ public class BasalProfile {
|
|||
|
||||
// if we have just one entry through all day it looks like just length 1
|
||||
if (data.length == 1) {
|
||||
data = MedtronicUtil.createByteArray(data[0], (byte)0, (byte)0);
|
||||
data = MedtronicUtil.createByteArray(data[0], (byte) 0, (byte) 0);
|
||||
}
|
||||
|
||||
if (data.length == MAX_RAW_DATA_SIZE) {
|
||||
|
@ -122,7 +122,7 @@ public class BasalProfile {
|
|||
String startString = entry.startTime.toString("HH:mm");
|
||||
// this doesn't work
|
||||
LOG.debug(String.format("Entry %d, rate=%.3f (0x%02X), start=%s (0x%02X)", i + 1, entry.rate,
|
||||
entry.rate_raw, startString, entry.startTime_raw));
|
||||
entry.rate_raw, startString, entry.startTime_raw));
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -165,7 +165,7 @@ public class BasalProfile {
|
|||
List<BasalProfileEntry> entries = getEntries();
|
||||
if (entries.size() == 0) {
|
||||
LOG.warn(String.format("getEntryForTime(%s): table is empty",
|
||||
when.toDateTime().toLocalTime().toString("HH:mm")));
|
||||
when.toDateTime().toLocalTime().toString("HH:mm")));
|
||||
return rval;
|
||||
}
|
||||
// Log.w(TAG,"Assuming first entry");
|
||||
|
@ -182,7 +182,7 @@ public class BasalProfile {
|
|||
BasalProfileEntry entry = entries.get(i);
|
||||
if (DEBUG_BASALPROFILE) {
|
||||
LOG.debug(String.format("Comparing 'now'=%s to entry 'start time'=%s", when.toDateTime().toLocalTime()
|
||||
.toString("HH:mm"), entry.startTime.toString("HH:mm")));
|
||||
.toString("HH:mm"), entry.startTime.toString("HH:mm")));
|
||||
}
|
||||
if (localMillis >= entry.startTime.getMillisOfDay()) {
|
||||
rval = entry;
|
||||
|
@ -201,8 +201,8 @@ public class BasalProfile {
|
|||
}
|
||||
if (DEBUG_BASALPROFILE) {
|
||||
LOG.debug(String.format("getEntryForTime(%s): Returning entry: rate=%.3f (%d), start=%s (%d)", when
|
||||
.toDateTime().toLocalTime().toString("HH:mm"), rval.rate, rval.rate_raw,
|
||||
rval.startTime.toString("HH:mm"), rval.startTime_raw));
|
||||
.toDateTime().toLocalTime().toString("HH:mm"), rval.rate, rval.rate_raw,
|
||||
rval.startTime.toString("HH:mm"), rval.startTime_raw));
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
@ -317,7 +317,7 @@ public class BasalProfile {
|
|||
BasalProfileEntry basalProfileEntry = entries.get(i + 1);
|
||||
|
||||
int rawTime = (basalProfileEntry.startTime_raw % 2 == 0) ? basalProfileEntry.startTime_raw
|
||||
: basalProfileEntry.startTime_raw - 1;
|
||||
: basalProfileEntry.startTime_raw - 1;
|
||||
|
||||
lastHour = (rawTime * 30) / 60;
|
||||
}
|
||||
|
@ -364,4 +364,21 @@ public class BasalProfile {
|
|||
return L.isEnabled(L.PUMPCOMM);
|
||||
}
|
||||
|
||||
public boolean verify() {
|
||||
|
||||
try {
|
||||
getEntries();
|
||||
} catch (Exception ex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Double[] profilesByHour = getProfilesByHour();
|
||||
|
||||
for (Double aDouble : profilesByHour) {
|
||||
if (aDouble > 35.0d)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -102,7 +102,7 @@ public enum MedtronicCommandType implements Serializable // , MinimedCommandType
|
|||
// MinimedCommandParameterType.NoParameters), //
|
||||
|
||||
Settings_512(145, "Configuration", MedtronicDeviceType.Medtronic_512_712, MinimedCommandParameterType.NoParameters, //
|
||||
64, 1, 0, R.string.medtronic_cmd_desc_get_settings), //
|
||||
64, 1, 18, R.string.medtronic_cmd_desc_get_settings), //
|
||||
|
||||
// BGAlarmClocks(142, "BG Alarm Clocks", MinimedTargetType.PumpConfiguration,
|
||||
// MedtronicDeviceType.Medtronic_512andHigher, MinimedCommandParameterType.NoParameters), //
|
||||
|
@ -142,7 +142,7 @@ public enum MedtronicCommandType implements Serializable // , MinimedCommandType
|
|||
PumpStatus(206, "Pump Status", MedtronicDeviceType.Medtronic_515andHigher, MinimedCommandParameterType.NoParameters), // PumpConfiguration
|
||||
|
||||
Settings(192, "Configuration", MedtronicDeviceType.Medtronic_515andHigher, MinimedCommandParameterType.NoParameters, //
|
||||
64, 1, 0, R.string.medtronic_cmd_desc_get_settings), //
|
||||
64, 1, 21, R.string.medtronic_cmd_desc_get_settings), //
|
||||
|
||||
// 522
|
||||
SensorSettings_522(153, "Sensor Configuration", MedtronicDeviceType.Medtronic_522andHigher, MinimedCommandParameterType.NoParameters), //
|
||||
|
|
|
@ -18,7 +18,6 @@ public enum MedtronicNotificationType {
|
|||
PumpWrongMaxBasalSet(R.string.medtronic_error_pump_wrong_max_basal_set, Notification.NORMAL), //
|
||||
PumpWrongTimeUrgent(R.string.combo_notification_check_time_date, Notification.URGENT),
|
||||
PumpWrongTimeNormal(R.string.combo_notification_check_time_date, Notification.NORMAL),
|
||||
|
||||
//
|
||||
;
|
||||
|
||||
|
|
Loading…
Reference in a new issue