core.pump.common cleanup

This commit is contained in:
Milos Kozak 2021-03-29 10:45:48 +02:00
parent f37e3ab4c2
commit 0a61585836
30 changed files with 168 additions and 298 deletions

View file

@ -1,72 +0,0 @@
package info.nightscout.androidaps.plugins.pump.common.data;
import com.google.gson.annotations.Expose;
public class TempBasalPair {
@Expose
protected double insulinRate = 0.0d;
@Expose
protected int durationMinutes = 0;
@Expose
protected boolean isPercent = false;
private Long start;
private Long end;
public TempBasalPair() {
}
public TempBasalPair(double insulinRate, boolean isPercent, int durationMinutes) {
this.insulinRate = insulinRate;
this.isPercent = isPercent;
this.durationMinutes = durationMinutes;
}
public double getInsulinRate() {
return insulinRate;
}
public void setInsulinRate(double insulinRate) {
this.insulinRate = insulinRate;
}
public int getDurationMinutes() {
return durationMinutes;
}
public void setDurationMinutes(int durationMinutes) {
this.durationMinutes = durationMinutes;
}
public boolean isPercent() {
return isPercent;
}
public void setIsPercent(boolean yesIsPercent) {
this.isPercent = yesIsPercent;
}
public void setStartTime(Long startTime) {
this.start = startTime;
}
public void setEndTime(Long endTime) {
this.end = endTime;
}
@Override
public String toString() {
return "TempBasalPair [" + "Rate=" + insulinRate + ", DurationMinutes=" + durationMinutes + ", IsPercent="
+ isPercent + "]";
}
}

View file

@ -1,3 +1,3 @@
package info.nightscout.androidaps.plugins.pump.common.data package info.nightscout.androidaps.plugins.pump.common.defs
class DoseSettings constructor(val step: Double, val durationStep: Int, val maxDuration: Int, val minDose: Double, val maxDose: Double = Double.MAX_VALUE) class DoseSettings constructor(val step: Double, val durationStep: Int, val maxDuration: Int, val minDose: Double, val maxDose: Double = Double.MAX_VALUE)

View file

@ -1,100 +0,0 @@
package info.nightscout.androidaps.plugins.pump.common.defs;
import java.util.Locale;
/**
* Created by andy on 02/05/2018.
*/
public enum DoseStepSize {
ComboBasal( //
new DoseStepSizeEntry(0f, 1f, 0.01f), //
new DoseStepSizeEntry(1f, 10f, 0.05f), //
new DoseStepSizeEntry(10f, Double.MAX_VALUE, 0.1f)), //
InsightBolus(
new DoseStepSizeEntry(0f, 2f, 0.05f), //
new DoseStepSizeEntry(2f, 5f, 0.1f), //
new DoseStepSizeEntry(5f, 10f, 0.2f), //
new DoseStepSizeEntry(10f, Double.MAX_VALUE, 0.5f)),
InsightBasal(
new DoseStepSizeEntry(0f, 5f, 0.01f),
new DoseStepSizeEntry(5f, Double.MAX_VALUE, 0.1f)),
MedtronicVeoBasal( //
new DoseStepSizeEntry(0f, 1f, 0.025f), //
new DoseStepSizeEntry(1f, 10f, 0.05f), //
new DoseStepSizeEntry(10f, Double.MAX_VALUE, 0.1f)), //
YpsopumpBasal( //
new DoseStepSizeEntry(0.0f, 1f, 0.01f), //
new DoseStepSizeEntry(1f, 2f, 0.02f), //
new DoseStepSizeEntry(2f, 15f, 0.1f), //
new DoseStepSizeEntry(15f, 40f, 0.5f)
)
;
DoseStepSizeEntry[] entries;
DoseStepSize(DoseStepSizeEntry... entries) {
this.entries = entries;
}
public double getStepSizeForAmount(double amount) {
for (DoseStepSizeEntry entry : entries) {
if (entry.from <= amount && entry.to > amount)
return entry.value;
}
// should never come to this
return entries[entries.length - 1].value;
}
public String getDescription() {
StringBuilder sb = new StringBuilder();
boolean first = true;
for (DoseStepSizeEntry entry : entries) {
if (first) {
first = false;
} else {
sb.append(", ");
}
sb.append(String.format(Locale.ENGLISH, "%.3f", entry.value));
sb.append(" {");
sb.append(String.format(Locale.ENGLISH,"%.3f", entry.from));
sb.append("-");
if (entry.to == Double.MAX_VALUE) {
sb.append("~}");
} else {
sb.append(String.format(Locale.ENGLISH, "%.3f", entry.to));
sb.append("}");
}
}
return sb.toString();
}
static class DoseStepSizeEntry {
double from;
double to;
double value;
// to = this value is not included, but would actually mean <, so for rates between 0.025-0.975 u/h, we would have [from=0, to=10]
DoseStepSizeEntry(double from, double to, double value) {
this.from = from;
this.to = to;
this.value = value;
}
}
}

View file

@ -0,0 +1,56 @@
package info.nightscout.androidaps.plugins.pump.common.defs
import java.util.*
enum class DoseStepSize(private val entries: Array<DoseStepSizeEntry>) {
ComboBasal(arrayOf(
DoseStepSizeEntry(0.0, 1.0, 0.01),
DoseStepSizeEntry(1.0, 10.0, 0.05),
DoseStepSizeEntry(10.0, Double.MAX_VALUE, 0.1))),
InsightBolus(arrayOf(
DoseStepSizeEntry(0.0, 2.0, 0.05),
DoseStepSizeEntry(2.0, 5.0, 0.1),
DoseStepSizeEntry(5.0, 10.0, 0.2),
DoseStepSizeEntry(10.0, Double.MAX_VALUE, 0.5))),
InsightBasal(arrayOf(
DoseStepSizeEntry(0.0, 5.0, 0.01),
DoseStepSizeEntry(5.0, Double.MAX_VALUE, 0.1))),
MedtronicVeoBasal(arrayOf(
DoseStepSizeEntry(0.0, 1.0, 0.025),
DoseStepSizeEntry(1.0, 10.0, 0.05),
DoseStepSizeEntry(10.0, Double.MAX_VALUE, 0.1))),
YpsopumpBasal(arrayOf(
DoseStepSizeEntry(0.0, 1.0, 0.01),
DoseStepSizeEntry(1.0, 2.0, 0.02),
DoseStepSizeEntry(2.0, 15.0, 0.1),
DoseStepSizeEntry(15.0, 40.0, 0.5))
);
fun getStepSizeForAmount(amount: Double): Double {
for (entry in entries)
if (entry.from <= amount && entry.to > amount) return entry.value
// should never come to this
return entries[entries.size - 1].value
}
val description: String
get() = StringBuilder().also { sb ->
var first = true
for (entry in entries) {
if (first) first = false else sb.append(", ")
sb.append(String.format(Locale.ENGLISH, "%.3f", entry.value))
.append(" {")
.append(String.format(Locale.ENGLISH, "%.3f", entry.from))
.append("-")
if (entry.to == Double.MAX_VALUE) sb.append("~}")
else sb.append(String.format(Locale.ENGLISH, "%.3f", entry.to)).append("}")
}
}.toString()
// to = this value is not included, but would actually mean <, so for rates between 0.025-0.975 u/h, we would have [from=0, to=10]
internal class DoseStepSizeEntry(var from: Double, var to: Double, var value: Double)
}

View file

@ -1,10 +1,5 @@
package info.nightscout.androidaps.plugins.pump.common.defs package info.nightscout.androidaps.plugins.pump.common.defs
import info.nightscout.androidaps.plugins.pump.common.defs.PumpCapability
/**
* Created by andy on 03/05/2018.
*/
enum class PumpCapability { enum class PumpCapability {
Bolus, // isBolusCapable Bolus, // isBolusCapable
@ -35,7 +30,10 @@ enum class PumpCapability {
var children: ArrayList<PumpCapability> = ArrayList() var children: ArrayList<PumpCapability> = ArrayList()
constructor() { children.add(this)} constructor() {
children.add(this)
}
constructor(list: Array<PumpCapability>) { constructor(list: Array<PumpCapability>) {
children.addAll(list) children.addAll(list)
} }

View file

@ -1,29 +0,0 @@
package info.nightscout.androidaps.plugins.pump.common.defs;
import info.nightscout.androidaps.core.R;
/**
* Created by andy on 6/11/18.
*/
public enum PumpDeviceState {
NeverContacted(R.string.pump_status_never_contacted), //
Sleeping(R.string.pump_status_sleeping), //
WakingUp(R.string.pump_status_waking_up), //
Active(R.string.pump_status_active), //
ErrorWhenCommunicating(R.string.pump_status_error_comm), //
TimeoutWhenCommunicating(R.string.pump_status_timeout_comm), //
// ProblemContacting(R.string.medtronic_pump_status_problem_contacting), //
PumpUnreachable(R.string.pump_status_pump_unreachable), //
InvalidConfiguration(R.string.pump_status_invalid_config);
Integer resourceId;
PumpDeviceState(int resourceId) {
this.resourceId = resourceId;
}
public Integer getResourceId() {
return resourceId;
}
}

View file

@ -1,26 +0,0 @@
package info.nightscout.androidaps.plugins.pump.common.defs;
/**
* Created by andy on 10/15/18.
*/
public enum PumpDriverState {
NotInitialized, //
Connecting, //
Connected, //
Initialized, //
Ready,
Busy, //
Suspended, //
;
public static boolean isConnected(PumpDriverState pumpState) {
return pumpState == Connected || pumpState == Initialized || pumpState == Busy || pumpState == Suspended;
}
public static boolean isInitialized(PumpDriverState pumpState) {
return pumpState == Initialized || pumpState == Busy || pumpState == Suspended;
}
}

View file

@ -1,23 +0,0 @@
package info.nightscout.androidaps.plugins.pump.common.defs;
/**
* Created by andy on 5/12/18.
*/
public enum PumpStatusType {
Running("normal"), //
Suspended("suspended") //
;
private final String statusString;
PumpStatusType(String statusString) {
this.statusString = statusString;
}
public String getStatus() {
return statusString;
}
}

View file

@ -1,10 +0,0 @@
package info.nightscout.androidaps.plugins.pump.common.defs;
/**
* Created by andy on 02/05/2018.
*/
public enum PumpTempBasalType {
Percent, //
Absolute,
}

View file

@ -0,0 +1,7 @@
package info.nightscout.androidaps.plugins.pump.common.defs
enum class PumpTempBasalType {
Percent,
Absolute
}

View file

@ -3,7 +3,6 @@ package info.nightscout.androidaps.plugins.pump.common.defs
import info.nightscout.androidaps.core.R import info.nightscout.androidaps.core.R
import info.nightscout.androidaps.database.embedments.InterfaceIDs import info.nightscout.androidaps.database.embedments.InterfaceIDs
import info.nightscout.androidaps.plugins.common.ManufacturerType import info.nightscout.androidaps.plugins.common.ManufacturerType
import info.nightscout.androidaps.plugins.pump.common.data.DoseSettings
import info.nightscout.androidaps.utils.Round import info.nightscout.androidaps.utils.Round
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import kotlin.math.min import kotlin.math.min

View file

@ -157,7 +157,7 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements PumpI
public boolean isInitialized() { public boolean isInitialized() {
return PumpDriverState.isInitialized(pumpState); return pumpState.isInitialized();
} }
@ -174,7 +174,7 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements PumpI
public boolean isConnected() { public boolean isConnected() {
if (displayConnectionMessages) if (displayConnectionMessages)
aapsLogger.debug(LTag.PUMP, "isConnected [PumpPluginAbstract]."); aapsLogger.debug(LTag.PUMP, "isConnected [PumpPluginAbstract].");
return PumpDriverState.isConnected(pumpState); return pumpState.isConnected();
} }

View file

@ -0,0 +1,14 @@
package info.nightscout.androidaps.plugins.pump.common.defs
enum class PumpDriverState {
NotInitialized,
Connecting,
Connected,
Initialized,
Ready, Busy,
Suspended;
fun isConnected(): Boolean = this == Connected || this == Initialized || this == Busy || this == Suspended
fun isInitialized(): Boolean = this == Initialized || this == Busy || this == Suspended
}

View file

@ -0,0 +1,7 @@
package info.nightscout.androidaps.plugins.pump.common.defs
enum class PumpStatusType(val status: String) {
Running("normal"),
Suspended("suspended");
}

View file

@ -16,7 +16,7 @@ import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
* <p> * <p>
* Just need a class to keep the pair together, for parcel transport. * Just need a class to keep the pair together, for parcel transport.
*/ */
public class TempBasalPair extends info.nightscout.androidaps.plugins.pump.common.data.TempBasalPair { public class TempBasalPair extends info.nightscout.androidaps.plugins.pump.common.defs.TempBasalPair {
/** /**
* This constructor is for use with PumpHistoryDecoder * This constructor is for use with PumpHistoryDecoder
@ -30,11 +30,11 @@ public class TempBasalPair extends info.nightscout.androidaps.plugins.pump.commo
int rateInt = ByteUtil.asUINT8(rateByte); int rateInt = ByteUtil.asUINT8(rateByte);
if (isPercent) if (isPercent)
this.insulinRate = rateByte; this.setInsulinRate(rateByte);
else else
this.insulinRate = rateInt * 0.025; this.setInsulinRate(rateInt * 0.025);
this.durationMinutes = startTimeByte * 30; this.setDurationMinutes(startTimeByte * 30);
this.isPercent = isPercent; this.setPercent(isPercent);
} }
@ -47,12 +47,12 @@ public class TempBasalPair extends info.nightscout.androidaps.plugins.pump.commo
*/ */
public TempBasalPair(byte rateByte0, byte rateByte1, int startTimeByte, boolean isPercent) { public TempBasalPair(byte rateByte0, byte rateByte1, int startTimeByte, boolean isPercent) {
if (isPercent) { if (isPercent) {
this.insulinRate = rateByte0; this.setInsulinRate(rateByte0);
} else { } else {
this.insulinRate = ByteUtil.toInt(rateByte1, rateByte0) * 0.025; this.setInsulinRate(ByteUtil.toInt(rateByte1, rateByte0) * 0.025);
} }
this.durationMinutes = startTimeByte * 30; this.setDurationMinutes(startTimeByte * 30);
this.isPercent = isPercent; this.setPercent(isPercent);
} }
public TempBasalPair(AAPSLogger aapsLogger, byte[] response) { public TempBasalPair(AAPSLogger aapsLogger, byte[] response) {
@ -60,20 +60,20 @@ public class TempBasalPair extends info.nightscout.androidaps.plugins.pump.commo
aapsLogger.debug(LTag.PUMPBTCOMM, "Received TempBasal response: " + ByteUtil.getHex(response)); aapsLogger.debug(LTag.PUMPBTCOMM, "Received TempBasal response: " + ByteUtil.getHex(response));
isPercent = response[0] == 1; setPercent(response[0] == 1);
if (isPercent) { if (isPercent()) {
insulinRate = response[1]; setInsulinRate(response[1]);
} else { } else {
int strokes = MedtronicUtil.makeUnsignedShort(response[2], response[3]); int strokes = MedtronicUtil.makeUnsignedShort(response[2], response[3]);
insulinRate = strokes / 40.0d; setInsulinRate(strokes / 40.0d);
} }
if (response.length < 6) { if (response.length < 6) {
durationMinutes = ByteUtil.asUINT8(response[4]); setDurationMinutes(ByteUtil.asUINT8(response[4]));
} else { } else {
durationMinutes = MedtronicUtil.makeUnsignedShort(response[4], response[5]); setDurationMinutes(MedtronicUtil.makeUnsignedShort(response[4], response[5]));
} }
aapsLogger.warn(LTag.PUMPBTCOMM, String.format(Locale.ENGLISH, "TempBasalPair (with %d byte response): %s", response.length, toString())); aapsLogger.warn(LTag.PUMPBTCOMM, String.format(Locale.ENGLISH, "TempBasalPair (with %d byte response): %s", response.length, toString()));
@ -92,8 +92,8 @@ public class TempBasalPair extends info.nightscout.androidaps.plugins.pump.commo
list.add((byte) 5); list.add((byte) 5);
byte[] insulinRate = MedtronicUtil.getBasalStrokes(this.insulinRate, true); byte[] insulinRate = MedtronicUtil.getBasalStrokes(this.getInsulinRate(), true);
byte timeMin = (byte) MedtronicUtil.getIntervalFromMinutes(durationMinutes); byte timeMin = (byte) MedtronicUtil.getIntervalFromMinutes(getDurationMinutes());
// list.add((byte) 0); // ? // list.add((byte) 0); // ?
@ -120,7 +120,7 @@ public class TempBasalPair extends info.nightscout.androidaps.plugins.pump.commo
} }
public boolean isCancelTBR() { public boolean isCancelTBR() {
return (MedtronicUtil.isSame(insulinRate, 0.0d) && durationMinutes == 0); return (MedtronicUtil.isSame(getInsulinRate(), 0.0d) && getDurationMinutes() == 0);
} }
@ -129,17 +129,17 @@ public class TempBasalPair extends info.nightscout.androidaps.plugins.pump.commo
return "Cancel TBR"; return "Cancel TBR";
} }
if (isPercent) { if (isPercent()) {
return String.format(Locale.ENGLISH, "Rate: %.0f%%, Duration: %d min", insulinRate, durationMinutes); return String.format(Locale.ENGLISH, "Rate: %.0f%%, Duration: %d min", getInsulinRate(), getDurationMinutes());
} else { } else {
return String.format(Locale.ENGLISH, "Rate: %.3f U, Duration: %d min", insulinRate, durationMinutes); return String.format(Locale.ENGLISH, "Rate: %.3f U, Duration: %d min", getInsulinRate(), getDurationMinutes());
} }
} }
@NonNull @Override @NonNull @Override
public String toString() { public String toString() {
return "TempBasalPair [" + "Rate=" + insulinRate + ", DurationMinutes=" + durationMinutes + ", IsPercent=" return "TempBasalPair [" + "Rate=" + getInsulinRate() + ", DurationMinutes=" + getDurationMinutes() + ", IsPercent="
+ isPercent + "]"; + isPercent() + "]";
} }
} }

View file

@ -57,7 +57,7 @@ import info.nightscout.androidaps.plugins.general.actions.defs.CustomActionType;
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification; import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification;
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification;
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification; import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
import info.nightscout.androidaps.plugins.pump.common.data.TempBasalPair; import info.nightscout.androidaps.plugins.pump.common.defs.TempBasalPair;
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType; import info.nightscout.androidaps.plugins.pump.common.defs.PumpType;
import info.nightscout.androidaps.plugins.pump.common.events.EventRileyLinkDeviceStatusChange; import info.nightscout.androidaps.plugins.pump.common.events.EventRileyLinkDeviceStatusChange;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkConst; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkConst;

View file

@ -33,7 +33,7 @@ import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNo
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification;
import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress; import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress;
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification; import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
import info.nightscout.androidaps.plugins.pump.common.data.TempBasalPair; import info.nightscout.androidaps.plugins.pump.common.defs.TempBasalPair;
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType; import info.nightscout.androidaps.plugins.pump.common.defs.PumpType;
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
import info.nightscout.androidaps.plugins.pump.omnipod.common.definition.OmnipodCommandType; import info.nightscout.androidaps.plugins.pump.omnipod.common.definition.OmnipodCommandType;

View file

@ -29,7 +29,7 @@ import info.nightscout.androidaps.db.OmnipodHistoryRecord;
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface; import info.nightscout.androidaps.interfaces.DatabaseHelperInterface;
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.data.TempBasalPair; import info.nightscout.androidaps.plugins.pump.common.defs.TempBasalPair;
import info.nightscout.androidaps.plugins.pump.common.defs.PumpHistoryEntryGroup; import info.nightscout.androidaps.plugins.pump.common.defs.PumpHistoryEntryGroup;
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType; import info.nightscout.androidaps.plugins.pump.common.defs.PumpType;
import info.nightscout.androidaps.plugins.pump.common.utils.ProfileUtil; import info.nightscout.androidaps.plugins.pump.common.utils.ProfileUtil;

View file

@ -23,7 +23,7 @@ import info.nightscout.androidaps.interfaces.CommandQueueProvider;
import info.nightscout.androidaps.logging.AAPSLogger; import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.AAPSLoggerTest; import info.nightscout.androidaps.logging.AAPSLoggerTest;
import info.nightscout.androidaps.plugins.bus.RxBusWrapper; import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
import info.nightscout.androidaps.plugins.pump.common.data.TempBasalPair; import info.nightscout.androidaps.plugins.pump.common.defs.TempBasalPair;
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType; import info.nightscout.androidaps.plugins.pump.common.defs.PumpType;
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.omnipod.eros.manager.AapsOmnipodErosManager; import info.nightscout.androidaps.plugins.pump.omnipod.eros.manager.AapsOmnipodErosManager;

View file

@ -0,0 +1,17 @@
package info.nightscout.androidaps.plugins.pump.common.defs
import info.nightscout.androidaps.core.R
enum class PumpDeviceState(var resourceId: Int) {
NeverContacted(R.string.pump_status_never_contacted),
Sleeping(R.string.pump_status_sleeping),
WakingUp(R.string.pump_status_waking_up),
Active(R.string.pump_status_active),
ErrorWhenCommunicating(R.string.pump_status_error_comm),
TimeoutWhenCommunicating(R.string.pump_status_timeout_comm),
// ProblemContacting(R.string.medtronic_pump_status_problem_contacting),
PumpUnreachable(R.string.pump_status_pump_unreachable),
InvalidConfiguration(R.string.pump_status_invalid_config);
}

View file

@ -0,0 +1,32 @@
package info.nightscout.androidaps.plugins.pump.common.defs
import com.google.gson.annotations.Expose
open class TempBasalPair {
@Expose var insulinRate = 0.0
@Expose var durationMinutes = 0
@Expose var isPercent = false
private var start: Long? = null
private var end: Long? = null
constructor()
constructor(insulinRate: Double, isPercent: Boolean, durationMinutes: Int) {
this.insulinRate = insulinRate
this.isPercent = isPercent
this.durationMinutes = durationMinutes
}
fun setStartTime(startTime: Long?) {
start = startTime
}
fun setEndTime(endTime: Long?) {
end = endTime
}
override fun toString(): String {
return ("TempBasalPair [" + "Rate=" + insulinRate + ", DurationMinutes=" + durationMinutes + ", IsPercent="
+ isPercent + "]")
}
}