MDT refactor pass 5
This commit is contained in:
parent
e2e0de25bc
commit
3598e00290
9 changed files with 82 additions and 116 deletions
|
@ -156,11 +156,13 @@ public class RileyLinkUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public RileyLinkBLE getRileyLinkBLE() {
|
public RileyLinkBLE getRileyLinkBLE() {
|
||||||
return rileyLinkBLE;
|
return rileyLinkBLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public void setRileyLinkBLE(RileyLinkBLE rileyLinkBLEIn) {
|
public void setRileyLinkBLE(RileyLinkBLE rileyLinkBLEIn) {
|
||||||
rileyLinkBLE = rileyLinkBLEIn;
|
rileyLinkBLE = rileyLinkBLEIn;
|
||||||
}
|
}
|
||||||
|
@ -180,12 +182,13 @@ public class RileyLinkUtil {
|
||||||
return rileyLinkServiceData.tuneUpDone;
|
return rileyLinkServiceData.tuneUpDone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public RileyLinkService getRileyLinkService() {
|
public RileyLinkService getRileyLinkService() {
|
||||||
return rileyLinkService;
|
return rileyLinkService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public void setRileyLinkService(RileyLinkService rileyLinkService) {
|
public void setRileyLinkService(RileyLinkService rileyLinkService) {
|
||||||
this.rileyLinkService = rileyLinkService;
|
this.rileyLinkService = rileyLinkService;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@ import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import dagger.android.DaggerService;
|
import dagger.android.DaggerService;
|
||||||
|
@ -35,10 +37,10 @@ public abstract class RileyLinkService extends DaggerService {
|
||||||
@Inject protected SP sp;
|
@Inject protected SP sp;
|
||||||
@Inject protected Context context;
|
@Inject protected Context context;
|
||||||
@Inject protected RileyLinkUtil rileyLinkUtil;
|
@Inject protected RileyLinkUtil rileyLinkUtil;
|
||||||
@Inject protected MedtronicUtil medtronicUtil;
|
@Inject protected MedtronicUtil medtronicUtil; // TODO should be avoided here as it's MDT
|
||||||
|
|
||||||
|
|
||||||
public RileyLinkBLE rileyLinkBLE; // android-bluetooth management
|
@NotNull protected RileyLinkBLE rileyLinkBLE; // android-bluetooth management, must be set in initRileyLinkServiceData
|
||||||
protected BluetoothAdapter bluetoothAdapter;
|
protected BluetoothAdapter bluetoothAdapter;
|
||||||
protected RFSpy rfspy; // interface for RL xxx Mhz radio.
|
protected RFSpy rfspy; // interface for RL xxx Mhz radio.
|
||||||
protected RileyLinkBroadcastReceiver mBroadcastReceiver;
|
protected RileyLinkBroadcastReceiver mBroadcastReceiver;
|
||||||
|
@ -251,6 +253,9 @@ public abstract class RileyLinkService extends DaggerService {
|
||||||
rileyLinkUtil.setServiceState(RileyLinkServiceState.BluetoothReady);
|
rileyLinkUtil.setServiceState(RileyLinkServiceState.BluetoothReady);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RileyLinkBLE getRileyLinkBLE() {
|
||||||
|
return rileyLinkBLE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Target Device for Service
|
* Get Target Device for Service
|
||||||
|
|
|
@ -1,13 +1,18 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks;
|
package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import dagger.android.HasAndroidInjector;
|
import dagger.android.HasAndroidInjector;
|
||||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil;
|
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil;
|
||||||
|
import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by geoff on 7/9/16.
|
* Created by geoff on 7/9/16.
|
||||||
*/
|
*/
|
||||||
public class DiscoverGattServicesTask extends ServiceTask {
|
public class DiscoverGattServicesTask extends ServiceTask {
|
||||||
|
|
||||||
|
@Inject MedtronicPumpPlugin medtronicPumpPlugin;
|
||||||
|
|
||||||
public boolean needToConnect = false;
|
public boolean needToConnect = false;
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,8 +31,8 @@ public class DiscoverGattServicesTask extends ServiceTask {
|
||||||
public void run() {
|
public void run() {
|
||||||
|
|
||||||
if (needToConnect)
|
if (needToConnect)
|
||||||
RileyLinkUtil.getInstance().getRileyLinkBLE().connectGatt();
|
medtronicPumpPlugin.getRileyLinkService().getRileyLinkBLE().connectGatt();
|
||||||
|
|
||||||
RileyLinkUtil.getInstance().getRileyLinkBLE().discoverServices();
|
medtronicPumpPlugin.getRileyLinkService().getRileyLinkBLE().discoverServices();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,10 +59,8 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks
|
||||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.ServiceTaskExecutor;
|
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.ServiceTaskExecutor;
|
||||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.WakeAndTuneTask;
|
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.WakeAndTuneTask;
|
||||||
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil;
|
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil;
|
||||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.MedtronicCommunicationManager;
|
|
||||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntry;
|
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntry;
|
||||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryResult;
|
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryResult;
|
||||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.ui.MedtronicUIComm;
|
|
||||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.ui.MedtronicUITask;
|
import info.nightscout.androidaps.plugins.pump.medtronic.comm.ui.MedtronicUITask;
|
||||||
import info.nightscout.androidaps.plugins.pump.medtronic.data.MedtronicHistoryData;
|
import info.nightscout.androidaps.plugins.pump.medtronic.data.MedtronicHistoryData;
|
||||||
import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.BasalProfile;
|
import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.BasalProfile;
|
||||||
|
@ -99,7 +97,6 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
||||||
private final RileyLinkUtil rileyLinkUtil;
|
private final RileyLinkUtil rileyLinkUtil;
|
||||||
private final MedtronicUtil medtronicUtil;
|
private final MedtronicUtil medtronicUtil;
|
||||||
private final MedtronicPumpStatus medtronicPumpStatus;
|
private final MedtronicPumpStatus medtronicPumpStatus;
|
||||||
private final MedtronicUIComm medtronicUIComm;
|
|
||||||
|
|
||||||
protected static MedtronicPumpPlugin plugin = null;
|
protected static MedtronicPumpPlugin plugin = null;
|
||||||
private RileyLinkMedtronicService rileyLinkMedtronicService;
|
private RileyLinkMedtronicService rileyLinkMedtronicService;
|
||||||
|
@ -130,8 +127,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
||||||
FabricPrivacy fabricPrivacy,
|
FabricPrivacy fabricPrivacy,
|
||||||
RileyLinkUtil rileyLinkUtil,
|
RileyLinkUtil rileyLinkUtil,
|
||||||
MedtronicUtil medtronicUtil,
|
MedtronicUtil medtronicUtil,
|
||||||
MedtronicPumpStatus medtronicPumpStatus,
|
MedtronicPumpStatus medtronicPumpStatus
|
||||||
MedtronicUIComm medtronicUIComm
|
|
||||||
) {
|
) {
|
||||||
|
|
||||||
super(new PluginDescription() //
|
super(new PluginDescription() //
|
||||||
|
@ -150,7 +146,6 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
||||||
this.medtronicUtil = medtronicUtil;
|
this.medtronicUtil = medtronicUtil;
|
||||||
this.sp = sp;
|
this.sp = sp;
|
||||||
this.medtronicPumpStatus = medtronicPumpStatus;
|
this.medtronicPumpStatus = medtronicPumpStatus;
|
||||||
this.medtronicUIComm = medtronicUIComm;
|
|
||||||
|
|
||||||
displayConnectionMessages = false;
|
displayConnectionMessages = false;
|
||||||
|
|
||||||
|
@ -486,14 +481,14 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
||||||
|
|
||||||
case BatteryStatus:
|
case BatteryStatus:
|
||||||
case RemainingInsulin: {
|
case RemainingInsulin: {
|
||||||
medtronicUIComm.executeCommand(refreshType.getKey().getCommandType());
|
rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(refreshType.getKey().getCommandType());
|
||||||
refreshTypesNeededToReschedule.add(refreshType.getKey());
|
refreshTypesNeededToReschedule.add(refreshType.getKey());
|
||||||
resetTime = true;
|
resetTime = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Configuration: {
|
case Configuration: {
|
||||||
medtronicUIComm.executeCommand(refreshType.getKey().getCommandType());
|
rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(refreshType.getKey().getCommandType());
|
||||||
resetTime = true;
|
resetTime = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -554,7 +549,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
||||||
|
|
||||||
// model (once)
|
// model (once)
|
||||||
if (medtronicUtil.getMedtronicPumpModel() == null) {
|
if (medtronicUtil.getMedtronicPumpModel() == null) {
|
||||||
medtronicUIComm.executeCommand(MedtronicCommandType.PumpModel);
|
rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.PumpModel);
|
||||||
} else {
|
} else {
|
||||||
if (medtronicPumpStatus.medtronicDeviceType != medtronicUtil.getMedtronicPumpModel()) {
|
if (medtronicPumpStatus.medtronicDeviceType != medtronicUtil.getMedtronicPumpModel()) {
|
||||||
aapsLogger.warn(LTag.PUMP, getLogPrefix() + "Configured pump is not the same as one detected.");
|
aapsLogger.warn(LTag.PUMP, getLogPrefix() + "Configured pump is not the same as one detected.");
|
||||||
|
@ -570,20 +565,20 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
||||||
readPumpHistory();
|
readPumpHistory();
|
||||||
|
|
||||||
// remaining insulin (>50 = 4h; 50-20 = 1h; 15m)
|
// remaining insulin (>50 = 4h; 50-20 = 1h; 15m)
|
||||||
medtronicUIComm.executeCommand(MedtronicCommandType.GetRemainingInsulin);
|
rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.GetRemainingInsulin);
|
||||||
scheduleNextRefresh(MedtronicStatusRefreshType.RemainingInsulin, 10);
|
scheduleNextRefresh(MedtronicStatusRefreshType.RemainingInsulin, 10);
|
||||||
|
|
||||||
// remaining power (1h)
|
// remaining power (1h)
|
||||||
medtronicUIComm.executeCommand(MedtronicCommandType.GetBatteryStatus);
|
rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.GetBatteryStatus);
|
||||||
scheduleNextRefresh(MedtronicStatusRefreshType.BatteryStatus, 20);
|
scheduleNextRefresh(MedtronicStatusRefreshType.BatteryStatus, 20);
|
||||||
|
|
||||||
// configuration (once and then if history shows config changes)
|
// configuration (once and then if history shows config changes)
|
||||||
medtronicUIComm.executeCommand(MedtronicCommandType.getSettings(medtronicUtil.getMedtronicPumpModel()));
|
rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.getSettings(medtronicUtil.getMedtronicPumpModel()));
|
||||||
|
|
||||||
// read profile (once, later its controlled by isThisProfileSet method)
|
// read profile (once, later its controlled by isThisProfileSet method)
|
||||||
getBasalProfiles();
|
getBasalProfiles();
|
||||||
|
|
||||||
int errorCount = medtronicUIComm.getInvalidResponsesCount();
|
int errorCount = rileyLinkMedtronicService.getMedtronicUIComm().getInvalidResponsesCount();
|
||||||
|
|
||||||
if (errorCount >= 5) {
|
if (errorCount >= 5) {
|
||||||
aapsLogger.error("Number of error counts was 5 or more. Starting tunning.");
|
aapsLogger.error("Number of error counts was 5 or more. Starting tunning.");
|
||||||
|
@ -607,10 +602,10 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
||||||
|
|
||||||
private void getBasalProfiles() {
|
private void getBasalProfiles() {
|
||||||
|
|
||||||
MedtronicUITask medtronicUITask = medtronicUIComm.executeCommand(MedtronicCommandType.GetBasalProfileSTD);
|
MedtronicUITask medtronicUITask = rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.GetBasalProfileSTD);
|
||||||
|
|
||||||
if (medtronicUITask.getResponseType() == MedtronicUIResponseType.Error) {
|
if (medtronicUITask.getResponseType() == MedtronicUIResponseType.Error) {
|
||||||
medtronicUIComm.executeCommand(MedtronicCommandType.GetBasalProfileSTD);
|
rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.GetBasalProfileSTD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -732,12 +727,12 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
||||||
|
|
||||||
medtronicUtil.dismissNotification(MedtronicNotificationType.PumpUnreachable, rxBus);
|
medtronicUtil.dismissNotification(MedtronicNotificationType.PumpUnreachable, rxBus);
|
||||||
|
|
||||||
medtronicUIComm.executeCommand(MedtronicCommandType.GetRealTimeClock);
|
rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.GetRealTimeClock);
|
||||||
|
|
||||||
ClockDTO clock = medtronicUtil.getPumpTime();
|
ClockDTO clock = medtronicUtil.getPumpTime();
|
||||||
|
|
||||||
if (clock == null) { // retry
|
if (clock == null) { // retry
|
||||||
medtronicUIComm.executeCommand(MedtronicCommandType.GetRealTimeClock);
|
rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.GetRealTimeClock);
|
||||||
|
|
||||||
clock = medtronicUtil.getPumpTime();
|
clock = medtronicUtil.getPumpTime();
|
||||||
}
|
}
|
||||||
|
@ -753,7 +748,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
||||||
|
|
||||||
aapsLogger.info(LTag.PUMP, "MedtronicPumpPlugin::checkTimeAndOptionallySetTime - Time difference is {} s. Set time on pump." + timeDiff);
|
aapsLogger.info(LTag.PUMP, "MedtronicPumpPlugin::checkTimeAndOptionallySetTime - Time difference is {} s. Set time on pump." + timeDiff);
|
||||||
|
|
||||||
medtronicUIComm.executeCommand(MedtronicCommandType.SetRealTimeClock);
|
rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.SetRealTimeClock);
|
||||||
|
|
||||||
if (clock.timeDifference == 0) {
|
if (clock.timeDifference == 0) {
|
||||||
Notification notification = new Notification(Notification.INSIGHT_DATE_TIME_UPDATED, getResourceHelper().gs(R.string.pump_time_updated), Notification.INFO, 60);
|
Notification notification = new Notification(Notification.INSIGHT_DATE_TIME_UPDATED, getResourceHelper().gs(R.string.pump_time_updated), Notification.INFO, 60);
|
||||||
|
@ -823,7 +818,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
||||||
|
|
||||||
// LOG.debug("MedtronicPumpPlugin::deliverBolus - Start delivery");
|
// LOG.debug("MedtronicPumpPlugin::deliverBolus - Start delivery");
|
||||||
|
|
||||||
MedtronicUITask responseTask = medtronicUIComm.executeCommand(MedtronicCommandType.SetBolus,
|
MedtronicUITask responseTask = rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.SetBolus,
|
||||||
detailedBolusInfo.insulin);
|
detailedBolusInfo.insulin);
|
||||||
|
|
||||||
Boolean response = (Boolean) responseTask.returnData;
|
Boolean response = (Boolean) responseTask.returnData;
|
||||||
|
@ -989,7 +984,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
||||||
|
|
||||||
// CANCEL
|
// CANCEL
|
||||||
|
|
||||||
MedtronicUITask responseTask2 = medtronicUIComm.executeCommand(MedtronicCommandType.CancelTBR);
|
MedtronicUITask responseTask2 = rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.CancelTBR);
|
||||||
|
|
||||||
Boolean response = (Boolean) responseTask2.returnData;
|
Boolean response = (Boolean) responseTask2.returnData;
|
||||||
|
|
||||||
|
@ -1006,7 +1001,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
||||||
}
|
}
|
||||||
|
|
||||||
// now start new TBR
|
// now start new TBR
|
||||||
MedtronicUITask responseTask = medtronicUIComm.executeCommand(MedtronicCommandType.SetTemporaryBasal,
|
MedtronicUITask responseTask = rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.SetTemporaryBasal,
|
||||||
absoluteRate, durationInMinutes);
|
absoluteRate, durationInMinutes);
|
||||||
|
|
||||||
Boolean response = (Boolean) responseTask.returnData;
|
Boolean response = (Boolean) responseTask.returnData;
|
||||||
|
@ -1160,7 +1155,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
||||||
|
|
||||||
aapsLogger.debug(LTag.PUMP, "HST: Target Date: " + targetDate);
|
aapsLogger.debug(LTag.PUMP, "HST: Target Date: " + targetDate);
|
||||||
|
|
||||||
MedtronicUITask responseTask2 = medtronicUIComm.executeCommand(MedtronicCommandType.GetHistoryData,
|
MedtronicUITask responseTask2 = rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.GetHistoryData,
|
||||||
lastPumpHistoryEntry, targetDate);
|
lastPumpHistoryEntry, targetDate);
|
||||||
|
|
||||||
aapsLogger.debug(LTag.PUMP, "HST: After task");
|
aapsLogger.debug(LTag.PUMP, "HST: After task");
|
||||||
|
@ -1300,7 +1295,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
||||||
|
|
||||||
|
|
||||||
private TempBasalPair readTBR() {
|
private TempBasalPair readTBR() {
|
||||||
MedtronicUITask responseTask = medtronicUIComm.executeCommand(MedtronicCommandType.ReadTemporaryBasal);
|
MedtronicUITask responseTask = rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.ReadTemporaryBasal);
|
||||||
|
|
||||||
if (responseTask.hasData()) {
|
if (responseTask.hasData()) {
|
||||||
TempBasalPair tbr = (TempBasalPair) responseTask.returnData;
|
TempBasalPair tbr = (TempBasalPair) responseTask.returnData;
|
||||||
|
@ -1350,7 +1345,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
||||||
.comment(getResourceHelper().gs(R.string.medtronic_cmd_cant_read_tbr));
|
.comment(getResourceHelper().gs(R.string.medtronic_cmd_cant_read_tbr));
|
||||||
}
|
}
|
||||||
|
|
||||||
MedtronicUITask responseTask2 = medtronicUIComm.executeCommand(MedtronicCommandType.CancelTBR);
|
MedtronicUITask responseTask2 = rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.CancelTBR);
|
||||||
|
|
||||||
Boolean response = (Boolean) responseTask2.returnData;
|
Boolean response = (Boolean) responseTask2.returnData;
|
||||||
|
|
||||||
|
@ -1428,7 +1423,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
|
||||||
.comment(getResourceHelper().gs(R.string.medtronic_cmd_set_profile_pattern_overflow, profileInvalid));
|
.comment(getResourceHelper().gs(R.string.medtronic_cmd_set_profile_pattern_overflow, profileInvalid));
|
||||||
}
|
}
|
||||||
|
|
||||||
MedtronicUITask responseTask = medtronicUIComm.executeCommand(MedtronicCommandType.SetBasalProfileSTD,
|
MedtronicUITask responseTask = rileyLinkMedtronicService.getMedtronicUIComm().executeCommand(MedtronicCommandType.SetBasalProfileSTD,
|
||||||
basalProfile);
|
basalProfile);
|
||||||
|
|
||||||
Boolean response = (Boolean) responseTask.returnData;
|
Boolean response = (Boolean) responseTask.returnData;
|
||||||
|
|
|
@ -1,15 +1,10 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.medtronic.comm.ui;
|
package info.nightscout.androidaps.plugins.pump.medtronic.comm.ui;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
|
||||||
|
|
||||||
import dagger.android.HasAndroidInjector;
|
import dagger.android.HasAndroidInjector;
|
||||||
import info.nightscout.androidaps.logging.AAPSLogger;
|
import info.nightscout.androidaps.logging.AAPSLogger;
|
||||||
import info.nightscout.androidaps.logging.LTag;
|
import info.nightscout.androidaps.logging.LTag;
|
||||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkConst;
|
|
||||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil;
|
|
||||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.MedtronicCommunicationManager;
|
import info.nightscout.androidaps.plugins.pump.medtronic.comm.MedtronicCommunicationManager;
|
||||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicCommandType;
|
import info.nightscout.androidaps.plugins.pump.medtronic.defs.MedtronicCommandType;
|
||||||
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
|
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
|
||||||
|
@ -17,42 +12,29 @@ import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
|
||||||
/**
|
/**
|
||||||
* Created by andy on 6/14/18.
|
* Created by andy on 6/14/18.
|
||||||
*/
|
*/
|
||||||
@Singleton
|
|
||||||
public class MedtronicUIComm {
|
public class MedtronicUIComm {
|
||||||
|
|
||||||
@NotNull private final HasAndroidInjector injector;
|
private final HasAndroidInjector injector;
|
||||||
@NotNull private final AAPSLogger aapsLogger;
|
private final AAPSLogger aapsLogger;
|
||||||
@NotNull private final RileyLinkUtil rileyLinkUtil;
|
private final MedtronicUtil medtronicUtil;
|
||||||
@NotNull private final MedtronicUtil medtronicUtil;
|
private final MedtronicCommunicationManager medtronicCommunicationManager;
|
||||||
|
private final MedtronicUIPostprocessor medtronicUIPostprocessor;
|
||||||
MedtronicCommunicationManager mcmInstance = null;
|
|
||||||
@NotNull private final MedtronicUIPostprocessor medtronicUIPostprocessor;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public MedtronicUIComm(
|
public MedtronicUIComm(
|
||||||
@NotNull HasAndroidInjector injector,
|
HasAndroidInjector injector,
|
||||||
@NotNull AAPSLogger aapsLogger,
|
AAPSLogger aapsLogger,
|
||||||
@NotNull RileyLinkUtil rileyLinkUtil,
|
MedtronicUtil medtronicUtil,
|
||||||
@NotNull MedtronicUtil medtronicUtil,
|
MedtronicUIPostprocessor medtronicUIPostprocessor,
|
||||||
@NotNull MedtronicUIPostprocessor medtronicUIPostprocessor
|
MedtronicCommunicationManager medtronicCommunicationManager
|
||||||
) {
|
) {
|
||||||
this.injector = injector;
|
this.injector = injector;
|
||||||
this.aapsLogger = aapsLogger;
|
this.aapsLogger = aapsLogger;
|
||||||
this.rileyLinkUtil = rileyLinkUtil;
|
|
||||||
this.medtronicUtil = medtronicUtil;
|
this.medtronicUtil = medtronicUtil;
|
||||||
this.medtronicUIPostprocessor = medtronicUIPostprocessor;
|
this.medtronicUIPostprocessor = medtronicUIPostprocessor;
|
||||||
|
this.medtronicCommunicationManager = medtronicCommunicationManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private MedtronicCommunicationManager getCommunicationManager() {
|
|
||||||
if (mcmInstance == null) {
|
|
||||||
mcmInstance = MedtronicCommunicationManager.getInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
return mcmInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public synchronized MedtronicUITask executeCommand(MedtronicCommandType commandType, Object... parameters) {
|
public synchronized MedtronicUITask executeCommand(MedtronicCommandType commandType, Object... parameters) {
|
||||||
|
|
||||||
aapsLogger.warn(LTag.PUMP, "Execute Command: " + commandType.name());
|
aapsLogger.warn(LTag.PUMP, "Execute Command: " + commandType.name());
|
||||||
|
@ -69,7 +51,7 @@ public class MedtronicUIComm {
|
||||||
// LOG.warn("@@@ End Thread");
|
// LOG.warn("@@@ End Thread");
|
||||||
// });
|
// });
|
||||||
|
|
||||||
task.execute(getCommunicationManager());
|
task.execute(medtronicCommunicationManager);
|
||||||
|
|
||||||
// for (int i = 0; i < getMaxWaitTime(commandType); i++) {
|
// for (int i = 0; i < getMaxWaitTime(commandType); i++) {
|
||||||
// synchronized (task) {
|
// synchronized (task) {
|
||||||
|
@ -99,28 +81,7 @@ public class MedtronicUIComm {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* We return 25s as waitTime (17 for wakeUp, and addtional 8 for data retrieval) for normal commands and
|
|
||||||
* 120s for History. Real time for returning data would be arround 5s, but lets be sure.
|
|
||||||
*
|
|
||||||
* @param commandType
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private int getMaxWaitTime(MedtronicCommandType commandType) {
|
|
||||||
if (commandType == MedtronicCommandType.GetHistoryData)
|
|
||||||
return 120;
|
|
||||||
else
|
|
||||||
return 25;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public int getInvalidResponsesCount() {
|
public int getInvalidResponsesCount() {
|
||||||
return getCommunicationManager().getNotConnectedCount();
|
return medtronicCommunicationManager.getNotConnectedCount();
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void startTunning() {
|
|
||||||
rileyLinkUtil.sendBroadcastMessage(RileyLinkConst.IPC.MSG_PUMP_tunePump);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ import info.nightscout.androidaps.utils.resources.ResourceHelper;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class MedtronicUIPostprocessor {
|
public class MedtronicUIPostprocessor {
|
||||||
|
|
||||||
@NotNull private final AAPSLogger aapsLogger;
|
@NotNull private final AAPSLogger aapsLogger;
|
||||||
@NotNull private final RxBusWrapper rxBus;
|
@NotNull private final RxBusWrapper rxBus;
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.medtronic.comm.ui;
|
package info.nightscout.androidaps.plugins.pump.medtronic.comm.ui;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.joda.time.LocalDateTime;
|
import org.joda.time.LocalDateTime;
|
||||||
import org.slf4j.Logger;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import dagger.android.HasAndroidInjector;
|
import dagger.android.HasAndroidInjector;
|
||||||
import info.nightscout.androidaps.logging.L;
|
import info.nightscout.androidaps.logging.AAPSLogger;
|
||||||
import info.nightscout.androidaps.logging.StacktraceLoggerWrapper;
|
import info.nightscout.androidaps.logging.LTag;
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBus;
|
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
|
||||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.MedtronicCommunicationManager;
|
import info.nightscout.androidaps.plugins.pump.medtronic.comm.MedtronicCommunicationManager;
|
||||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntry;
|
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntry;
|
||||||
import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.BasalProfile;
|
import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.BasalProfile;
|
||||||
|
@ -28,11 +26,12 @@ import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
|
||||||
|
|
||||||
public class MedtronicUITask {
|
public class MedtronicUITask {
|
||||||
|
|
||||||
|
@Inject RxBusWrapper rxBus;
|
||||||
|
@Inject AAPSLogger aapsLogger;
|
||||||
@Inject MedtronicPumpStatus medtronicPumpStatus;
|
@Inject MedtronicPumpStatus medtronicPumpStatus;
|
||||||
|
@Inject MedtronicUtil medtronicUtil;
|
||||||
|
|
||||||
@NotNull private final HasAndroidInjector injector;
|
private final HasAndroidInjector injector;
|
||||||
|
|
||||||
private static final Logger LOG = StacktraceLoggerWrapper.getLogger(L.PUMP);
|
|
||||||
|
|
||||||
public MedtronicCommandType commandType;
|
public MedtronicCommandType commandType;
|
||||||
public Object returnData;
|
public Object returnData;
|
||||||
|
@ -45,14 +44,14 @@ public class MedtronicUITask {
|
||||||
|
|
||||||
public MedtronicUITask(HasAndroidInjector injector, MedtronicCommandType commandType) {
|
public MedtronicUITask(HasAndroidInjector injector, MedtronicCommandType commandType) {
|
||||||
this.injector = injector;
|
this.injector = injector;
|
||||||
injector.androidInjector().inject(this);
|
this.injector.androidInjector().inject(this);
|
||||||
this.commandType = commandType;
|
this.commandType = commandType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public MedtronicUITask(HasAndroidInjector injector, MedtronicCommandType commandType, Object... parameters) {
|
public MedtronicUITask(HasAndroidInjector injector, MedtronicCommandType commandType, Object... parameters) {
|
||||||
this.injector = injector;
|
this.injector = injector;
|
||||||
injector.androidInjector().inject(this);
|
this.injector.androidInjector().inject(this);
|
||||||
this.commandType = commandType;
|
this.commandType = commandType;
|
||||||
this.parameters = parameters;
|
this.parameters = parameters;
|
||||||
}
|
}
|
||||||
|
@ -60,8 +59,7 @@ public class MedtronicUITask {
|
||||||
|
|
||||||
public void execute(MedtronicCommunicationManager communicationManager) {
|
public void execute(MedtronicCommunicationManager communicationManager) {
|
||||||
|
|
||||||
if (isLogEnabled())
|
aapsLogger.debug(LTag.PUMP, "MedtronicUITask: @@@ In execute. {}", commandType);
|
||||||
LOG.debug("MedtronicUITask: @@@ In execute. {}", commandType);
|
|
||||||
|
|
||||||
switch (commandType) {
|
switch (commandType) {
|
||||||
case PumpModel: {
|
case PumpModel: {
|
||||||
|
@ -81,7 +79,7 @@ public class MedtronicUITask {
|
||||||
|
|
||||||
case GetRealTimeClock: {
|
case GetRealTimeClock: {
|
||||||
returnData = communicationManager.getPumpTime();
|
returnData = communicationManager.getPumpTime();
|
||||||
MedtronicUtil.getInstance().setPumpTime(null);
|
medtronicUtil.setPumpTime(null);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -143,7 +141,7 @@ public class MedtronicUITask {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
LOG.warn("This commandType is not supported (yet) - {}.", commandType);
|
aapsLogger.warn(LTag.PUMP, "This commandType is not supported (yet) - {}.", commandType);
|
||||||
// invalid = true;
|
// invalid = true;
|
||||||
responseType = MedtronicUIResponseType.Invalid;
|
responseType = MedtronicUIResponseType.Invalid;
|
||||||
}
|
}
|
||||||
|
@ -174,12 +172,12 @@ public class MedtronicUITask {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Double getDoubleFromParameters(int index) {
|
Double getDoubleFromParameters(int index) {
|
||||||
return (Double) parameters[index];
|
return (Double) parameters[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Integer getIntegerFromParameters(int index) {
|
private Integer getIntegerFromParameters(int index) {
|
||||||
return (Integer) parameters[index];
|
return (Integer) parameters[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,25 +194,24 @@ public class MedtronicUITask {
|
||||||
|
|
||||||
void postProcess(MedtronicUIPostprocessor postprocessor) {
|
void postProcess(MedtronicUIPostprocessor postprocessor) {
|
||||||
|
|
||||||
if (isLogEnabled())
|
aapsLogger.debug(LTag.PUMP, "MedtronicUITask: @@@ In execute. {}", commandType);
|
||||||
LOG.debug("MedtronicUITask: @@@ In execute. {}", commandType);
|
|
||||||
|
|
||||||
if (responseType == MedtronicUIResponseType.Data) {
|
if (responseType == MedtronicUIResponseType.Data) {
|
||||||
postprocessor.postProcessData(this);
|
postprocessor.postProcessData(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (responseType == MedtronicUIResponseType.Invalid) {
|
if (responseType == MedtronicUIResponseType.Invalid) {
|
||||||
RxBus.Companion.getINSTANCE().send(new EventMedtronicDeviceStatusChange(PumpDeviceState.ErrorWhenCommunicating,
|
rxBus.send(new EventMedtronicDeviceStatusChange(PumpDeviceState.ErrorWhenCommunicating,
|
||||||
"Unsupported command in MedtronicUITask"));
|
"Unsupported command in MedtronicUITask"));
|
||||||
} else if (responseType == MedtronicUIResponseType.Error) {
|
} else if (responseType == MedtronicUIResponseType.Error) {
|
||||||
RxBus.Companion.getINSTANCE().send(new EventMedtronicDeviceStatusChange(PumpDeviceState.ErrorWhenCommunicating,
|
rxBus.send(new EventMedtronicDeviceStatusChange(PumpDeviceState.ErrorWhenCommunicating,
|
||||||
errorDescription));
|
errorDescription));
|
||||||
} else {
|
} else {
|
||||||
RxBus.Companion.getINSTANCE().send(new EventMedtronicPumpValuesChanged());
|
rxBus.send(new EventMedtronicPumpValuesChanged());
|
||||||
medtronicPumpStatus.setLastCommunicationToNow();
|
medtronicPumpStatus.setLastCommunicationToNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
MedtronicUtil.getInstance().setCurrentCommand(null);
|
medtronicUtil.setCurrentCommand(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -223,16 +220,11 @@ public class MedtronicUITask {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Object getParameter(int index) {
|
Object getParameter(int index) {
|
||||||
return parameters[index];
|
return parameters[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private boolean isLogEnabled() {
|
|
||||||
return L.isEnabled(L.PUMP);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public MedtronicUIResponseType getResponseType() {
|
public MedtronicUIResponseType getResponseType() {
|
||||||
return this.responseType;
|
return this.responseType;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,8 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.Riley
|
||||||
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
|
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
|
||||||
import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin;
|
import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin;
|
||||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.MedtronicCommunicationManager;
|
import info.nightscout.androidaps.plugins.pump.medtronic.comm.MedtronicCommunicationManager;
|
||||||
|
import info.nightscout.androidaps.plugins.pump.medtronic.comm.ui.MedtronicUIComm;
|
||||||
|
import info.nightscout.androidaps.plugins.pump.medtronic.comm.ui.MedtronicUIPostprocessor;
|
||||||
import info.nightscout.androidaps.plugins.pump.medtronic.defs.PumpDeviceState;
|
import info.nightscout.androidaps.plugins.pump.medtronic.defs.PumpDeviceState;
|
||||||
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicConst;
|
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicConst;
|
||||||
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
|
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
|
||||||
|
@ -34,8 +36,10 @@ public class RileyLinkMedtronicService extends RileyLinkService {
|
||||||
@Inject HasAndroidInjector injector;
|
@Inject HasAndroidInjector injector;
|
||||||
@Inject MedtronicPumpPlugin medtronicPumpPlugin;
|
@Inject MedtronicPumpPlugin medtronicPumpPlugin;
|
||||||
@Inject MedtronicUtil medtronicUtil;
|
@Inject MedtronicUtil medtronicUtil;
|
||||||
|
@Inject MedtronicUIPostprocessor medtronicUIPostprocessor;
|
||||||
|
|
||||||
// cache of most recently received set of pump history pages. Probably shouldn't be here.
|
|
||||||
|
private MedtronicUIComm medtronicUIComm;
|
||||||
private MedtronicCommunicationManager medtronicCommunicationManager;
|
private MedtronicCommunicationManager medtronicCommunicationManager;
|
||||||
private IBinder mBinder = new LocalBinder();
|
private IBinder mBinder = new LocalBinder();
|
||||||
|
|
||||||
|
@ -87,6 +91,7 @@ public class RileyLinkMedtronicService extends RileyLinkService {
|
||||||
|
|
||||||
// init rileyLinkCommunicationManager
|
// init rileyLinkCommunicationManager
|
||||||
medtronicCommunicationManager = new MedtronicCommunicationManager(injector, rfspy);
|
medtronicCommunicationManager = new MedtronicCommunicationManager(injector, rfspy);
|
||||||
|
medtronicUIComm = new MedtronicUIComm(injector, aapsLogger, medtronicUtil, medtronicUIPostprocessor, medtronicCommunicationManager);
|
||||||
|
|
||||||
aapsLogger.debug(LTag.PUMPCOMM, "RileyLinkMedtronicService newly constructed");
|
aapsLogger.debug(LTag.PUMPCOMM, "RileyLinkMedtronicService newly constructed");
|
||||||
medtronicUtil.setMedtronicService(this);
|
medtronicUtil.setMedtronicService(this);
|
||||||
|
@ -103,6 +108,10 @@ public class RileyLinkMedtronicService extends RileyLinkService {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public MedtronicUIComm getMedtronicUIComm() {
|
||||||
|
return medtronicUIComm;
|
||||||
|
}
|
||||||
|
|
||||||
public void setPumpIDString(String pumpID) {
|
public void setPumpIDString(String pumpID) {
|
||||||
if (pumpID.length() != 6) {
|
if (pumpID.length() != 6) {
|
||||||
aapsLogger.error("setPumpIDString: invalid pump id string: " + pumpID);
|
aapsLogger.error("setPumpIDString: invalid pump id string: " + pumpID);
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.medtronic.util;
|
package info.nightscout.androidaps.plugins.pump.medtronic.util;
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
|
|
||||||
|
@ -17,7 +15,6 @@ import java.util.Map;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import info.nightscout.androidaps.interfaces.PluginType;
|
|
||||||
import info.nightscout.androidaps.logging.AAPSLogger;
|
import info.nightscout.androidaps.logging.AAPSLogger;
|
||||||
import info.nightscout.androidaps.logging.LTag;
|
import info.nightscout.androidaps.logging.LTag;
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
|
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
|
||||||
|
@ -28,7 +25,6 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil
|
||||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.data.RLHistoryItem;
|
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.data.RLHistoryItem;
|
||||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice;
|
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice;
|
||||||
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
|
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
|
||||||
import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin;
|
|
||||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.MedtronicCommunicationManager;
|
import info.nightscout.androidaps.plugins.pump.medtronic.comm.MedtronicCommunicationManager;
|
||||||
import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.ClockDTO;
|
import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.ClockDTO;
|
||||||
import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.PumpSettingDTO;
|
import info.nightscout.androidaps.plugins.pump.medtronic.data.dto.PumpSettingDTO;
|
||||||
|
|
Loading…
Reference in a new issue