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:
Andy Rozman 2019-06-25 14:18:52 +01:00
parent 5878a33ac7
commit 2a680cd8e9
28 changed files with 400 additions and 248 deletions

View file

@ -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() + '"'

View file

@ -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 ---------------
}
}

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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"));
}

View file

@ -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) {

View file

@ -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;

View file

@ -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<>();

View file

@ -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());

View file

@ -10,7 +10,6 @@ public interface MedtronicHistoryDecoderInterface<T> {
RecordDecodeStatus decodeRecord(T record);
List<T> createRecords(List<Byte> dataClear);
}

View file

@ -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;

View file

@ -9,10 +9,8 @@ public interface MedtronicHistoryEntryInterface {
String getEntryTypeName();
void setData(List<Byte> listRawData, boolean doNotProcess);
int getDateLength();
}

View file

@ -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 {

View file

@ -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()) + "]";
}

View file

@ -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>();

View file

@ -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);

View file

@ -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) {

View file

@ -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;

View file

@ -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}
*/

View file

@ -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}
*/

View file

@ -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;
}

View file

@ -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);
// }
}

View file

@ -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;
}
}

View file

@ -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();
}

View file

@ -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;
}
}

View file

@ -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), //

View file

@ -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),
//
;