loop suspend menu
This commit is contained in:
parent
42883a81a0
commit
f596050239
4 changed files with 211 additions and 11 deletions
|
@ -32,6 +32,7 @@ import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Loop.events.EventLoopSetLastRunGui;
|
import info.nightscout.androidaps.plugins.Loop.events.EventLoopSetLastRunGui;
|
||||||
import info.nightscout.androidaps.plugins.Loop.events.EventLoopUpdateGui;
|
import info.nightscout.androidaps.plugins.Loop.events.EventLoopUpdateGui;
|
||||||
import info.nightscout.androidaps.plugins.Loop.events.EventNewOpenLoopNotification;
|
import info.nightscout.androidaps.plugins.Loop.events.EventNewOpenLoopNotification;
|
||||||
|
import info.nightscout.utils.SP;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by mike on 05.08.2016.
|
* Created by mike on 05.08.2016.
|
||||||
|
@ -45,6 +46,8 @@ public class LoopPlugin implements PluginBase {
|
||||||
private boolean fragmentEnabled = false;
|
private boolean fragmentEnabled = false;
|
||||||
private boolean fragmentVisible = true;
|
private boolean fragmentVisible = true;
|
||||||
|
|
||||||
|
private long loopSuspendedTill = 0L; // end of manual loop suspend
|
||||||
|
|
||||||
public class LastRun {
|
public class LastRun {
|
||||||
public APSResult request = null;
|
public APSResult request = null;
|
||||||
public APSResult constraintsProcessed = null;
|
public APSResult constraintsProcessed = null;
|
||||||
|
@ -64,6 +67,7 @@ public class LoopPlugin implements PluginBase {
|
||||||
sHandler = new Handler(sHandlerThread.getLooper());
|
sHandler = new Handler(sHandlerThread.getLooper());
|
||||||
}
|
}
|
||||||
MainApp.bus().register(this);
|
MainApp.bus().register(this);
|
||||||
|
loopSuspendedTill = SP.getLong("loopSuspendedTill", 0L);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -127,6 +131,44 @@ public class LoopPlugin implements PluginBase {
|
||||||
invoke("EventNewBG", true);
|
invoke("EventNewBG", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long suspendedTo() {
|
||||||
|
return loopSuspendedTill;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void suspendTo(long endTime) {
|
||||||
|
loopSuspendedTill = endTime;
|
||||||
|
SP.putLong("loopSuspendedTill", loopSuspendedTill);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int minutesToEndOfSuspend() {
|
||||||
|
if (loopSuspendedTill == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
long now = new Date().getTime();
|
||||||
|
long msecDiff = loopSuspendedTill - now;
|
||||||
|
|
||||||
|
if (loopSuspendedTill <= now) { // time exceeded
|
||||||
|
suspendTo(0L);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (int) (msecDiff / 60d / 1000d);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSuspended() {
|
||||||
|
if (loopSuspendedTill == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
long now = new Date().getTime();
|
||||||
|
|
||||||
|
if (loopSuspendedTill <= now) { // time exceeded
|
||||||
|
suspendTo(0L);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public void invoke(String initiator, boolean allowNotification) {
|
public void invoke(String initiator, boolean allowNotification) {
|
||||||
try {
|
try {
|
||||||
if (Config.logFunctionCalls)
|
if (Config.logFunctionCalls)
|
||||||
|
@ -140,15 +182,21 @@ public class LoopPlugin implements PluginBase {
|
||||||
final ConfigBuilderPlugin configBuilder = MainApp.getConfigBuilder();
|
final ConfigBuilderPlugin configBuilder = MainApp.getConfigBuilder();
|
||||||
APSResult result = null;
|
APSResult result = null;
|
||||||
|
|
||||||
|
if (configBuilder == null || !isEnabled(PluginBase.LOOP))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (isSuspended()) {
|
||||||
|
log.debug(MainApp.sResources.getString(R.string.loopsuspended));
|
||||||
|
MainApp.bus().post(new EventLoopSetLastRunGui(MainApp.sResources.getString(R.string.loopsuspended)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (configBuilder.isSuspended()) {
|
if (configBuilder.isSuspended()) {
|
||||||
log.debug(MainApp.sResources.getString(R.string.pumpsuspended));
|
log.debug(MainApp.sResources.getString(R.string.pumpsuspended));
|
||||||
MainApp.bus().post(new EventLoopSetLastRunGui(MainApp.sResources.getString(R.string.pumpsuspended)));
|
MainApp.bus().post(new EventLoopSetLastRunGui(MainApp.sResources.getString(R.string.pumpsuspended)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (configBuilder == null || !isEnabled(PluginBase.LOOP))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Check if pump info is loaded
|
// Check if pump info is loaded
|
||||||
if (configBuilder.getBaseBasalRate() < 0.01d) return;
|
if (configBuilder.getBaseBasalRate() < 0.01d) return;
|
||||||
|
|
||||||
|
|
|
@ -18,8 +18,10 @@ import android.support.v7.app.AlertDialog;
|
||||||
import android.support.v7.widget.CardView;
|
import android.support.v7.widget.CardView;
|
||||||
import android.support.v7.widget.LinearLayoutManager;
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
|
import android.view.ContextMenu;
|
||||||
import android.view.HapticFeedbackConstants;
|
import android.view.HapticFeedbackConstants;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
|
@ -95,6 +97,7 @@ import info.nightscout.utils.DateUtil;
|
||||||
import info.nightscout.utils.DecimalFormatter;
|
import info.nightscout.utils.DecimalFormatter;
|
||||||
import info.nightscout.utils.Round;
|
import info.nightscout.utils.Round;
|
||||||
import info.nightscout.utils.SP;
|
import info.nightscout.utils.SP;
|
||||||
|
import info.nightscout.utils.ToastUtils;
|
||||||
|
|
||||||
|
|
||||||
public class OverviewFragment extends Fragment {
|
public class OverviewFragment extends Fragment {
|
||||||
|
@ -310,6 +313,133 @@ public class OverviewFragment extends Fragment {
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
|
||||||
|
super.onCreateContextMenu(menu, v, menuInfo);
|
||||||
|
final LoopPlugin activeloop = MainApp.getConfigBuilder().getActiveLoop();
|
||||||
|
if (activeloop == null)
|
||||||
|
return;
|
||||||
|
menu.setHeaderTitle(MainApp.sResources.getString(R.string.loop));
|
||||||
|
if (activeloop.isEnabled(PluginBase.LOOP)) {
|
||||||
|
menu.add(MainApp.sResources.getString(R.string.disabledloop));
|
||||||
|
if (!activeloop.isSuspended()) {
|
||||||
|
menu.add(MainApp.sResources.getString(R.string.suspendloopfor1h));
|
||||||
|
menu.add(MainApp.sResources.getString(R.string.suspendloopfor2h));
|
||||||
|
menu.add(MainApp.sResources.getString(R.string.suspendloopfor3h));
|
||||||
|
menu.add(MainApp.sResources.getString(R.string.suspendloopfor10h));
|
||||||
|
menu.add(MainApp.sResources.getString(R.string.disconnectpumpfor30m));
|
||||||
|
menu.add(MainApp.sResources.getString(R.string.disconnectpumpfor1h));
|
||||||
|
menu.add(MainApp.sResources.getString(R.string.disconnectpumpfor2h));
|
||||||
|
menu.add(MainApp.sResources.getString(R.string.disconnectpumpfor3h));
|
||||||
|
} else {
|
||||||
|
menu.add(MainApp.sResources.getString(R.string.resume));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!activeloop.isEnabled(PluginBase.LOOP))
|
||||||
|
menu.add(MainApp.sResources.getString(R.string.enabledloop));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onContextItemSelected(MenuItem item) {
|
||||||
|
final LoopPlugin activeloop = MainApp.getConfigBuilder().getActiveLoop();
|
||||||
|
if (item.getTitle() == MainApp.sResources.getString(R.string.disabledloop)) {
|
||||||
|
activeloop.setFragmentEnabled(PluginBase.LOOP, false);
|
||||||
|
activeloop.setFragmentVisible(PluginBase.LOOP, false);
|
||||||
|
MainApp.getConfigBuilder().storeSettings();
|
||||||
|
MainApp.bus().post(new EventRefreshGui(false));
|
||||||
|
return true;
|
||||||
|
} else if (item.getTitle() == MainApp.sResources.getString(R.string.enabledloop)) {
|
||||||
|
activeloop.setFragmentEnabled(PluginBase.LOOP, true);
|
||||||
|
activeloop.setFragmentVisible(PluginBase.LOOP, true);
|
||||||
|
MainApp.getConfigBuilder().storeSettings();
|
||||||
|
MainApp.bus().post(new EventRefreshGui(false));
|
||||||
|
return true;
|
||||||
|
} else if (item.getTitle() == MainApp.sResources.getString(R.string.resume)) {
|
||||||
|
activeloop.suspendTo(0L);
|
||||||
|
sHandler.post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
PumpEnactResult result = MainApp.getConfigBuilder().cancelTempBasal();
|
||||||
|
if (!result.success) {
|
||||||
|
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror));
|
||||||
|
}
|
||||||
|
MainApp.bus().post(new EventRefreshGui(false));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
} else if (item.getTitle() == MainApp.sResources.getString(R.string.suspendloopfor1h)) {
|
||||||
|
activeloop.suspendTo(new Date().getTime() + 60L * 60 * 1000);
|
||||||
|
MainApp.bus().post(new EventRefreshGui(false));
|
||||||
|
return true;
|
||||||
|
} else if (item.getTitle() == MainApp.sResources.getString(R.string.suspendloopfor2h)) {
|
||||||
|
activeloop.suspendTo(new Date().getTime() + 2 * 60L * 60 * 1000);
|
||||||
|
MainApp.bus().post(new EventRefreshGui(false));
|
||||||
|
return true;
|
||||||
|
} else if (item.getTitle() == MainApp.sResources.getString(R.string.suspendloopfor3h)) {
|
||||||
|
activeloop.suspendTo(new Date().getTime() + 3 * 60L * 60 * 1000);
|
||||||
|
MainApp.bus().post(new EventRefreshGui(false));
|
||||||
|
return true;
|
||||||
|
} else if (item.getTitle() == MainApp.sResources.getString(R.string.suspendloopfor10h)) {
|
||||||
|
activeloop.suspendTo(new Date().getTime() + 10 * 60L * 60 * 1000);
|
||||||
|
MainApp.bus().post(new EventRefreshGui(false));
|
||||||
|
return true;
|
||||||
|
} else if (item.getTitle() == MainApp.sResources.getString(R.string.disconnectpumpfor30m)) {
|
||||||
|
activeloop.suspendTo(new Date().getTime() + 30L * 60 * 1000);
|
||||||
|
sHandler.post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
PumpEnactResult result = MainApp.getConfigBuilder().setTempBasalAbsolute(0d, 30);
|
||||||
|
if (!result.success) {
|
||||||
|
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror));
|
||||||
|
}
|
||||||
|
MainApp.bus().post(new EventRefreshGui(false));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
} else if (item.getTitle() == MainApp.sResources.getString(R.string.disconnectpumpfor1h)) {
|
||||||
|
activeloop.suspendTo(new Date().getTime() + 1 * 60L * 60 * 1000);
|
||||||
|
sHandler.post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
PumpEnactResult result = MainApp.getConfigBuilder().setTempBasalAbsolute(0d, 60);
|
||||||
|
if (!result.success) {
|
||||||
|
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror));
|
||||||
|
}
|
||||||
|
MainApp.bus().post(new EventRefreshGui(false));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
} else if (item.getTitle() == MainApp.sResources.getString(R.string.disconnectpumpfor2h)) {
|
||||||
|
activeloop.suspendTo(new Date().getTime() + 2 * 60L * 60 * 1000);
|
||||||
|
sHandler.post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
PumpEnactResult result = MainApp.getConfigBuilder().setTempBasalAbsolute(0d, 2 * 60);
|
||||||
|
if (!result.success) {
|
||||||
|
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror));
|
||||||
|
}
|
||||||
|
MainApp.bus().post(new EventRefreshGui(false));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
} else if (item.getTitle() == MainApp.sResources.getString(R.string.disconnectpumpfor3h)) {
|
||||||
|
activeloop.suspendTo(new Date().getTime() + 3 * 60L * 60 * 1000);
|
||||||
|
sHandler.post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
PumpEnactResult result = MainApp.getConfigBuilder().setTempBasalAbsolute(0d, 3 * 60);
|
||||||
|
if (!result.success) {
|
||||||
|
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror));
|
||||||
|
}
|
||||||
|
MainApp.bus().post(new EventRefreshGui(false));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.onContextItemSelected(item);
|
||||||
|
}
|
||||||
|
|
||||||
void processQuickWizard() {
|
void processQuickWizard() {
|
||||||
final BgReading actualBg = GlucoseStatus.actualBg();
|
final BgReading actualBg = GlucoseStatus.actualBg();
|
||||||
if (MainApp.getConfigBuilder() == null || ConfigBuilderPlugin.getActiveProfile() == null) // app not initialized yet
|
if (MainApp.getConfigBuilder() == null || ConfigBuilderPlugin.getActiveProfile() == null) // app not initialized yet
|
||||||
|
@ -410,6 +540,7 @@ public class OverviewFragment extends Fragment {
|
||||||
super.onPause();
|
super.onPause();
|
||||||
MainApp.bus().unregister(this);
|
MainApp.bus().unregister(this);
|
||||||
sLoopHandler.removeCallbacksAndMessages(null);
|
sLoopHandler.removeCallbacksAndMessages(null);
|
||||||
|
unregisterForContextMenu(apsModeView);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -424,6 +555,7 @@ public class OverviewFragment extends Fragment {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
sLoopHandler.postDelayed(sRefreshLoop, 60 * 1000L);
|
sLoopHandler.postDelayed(sRefreshLoop, 60 * 1000L);
|
||||||
|
registerForContextMenu(apsModeView);
|
||||||
updateGUIIfVisible();
|
updateGUIIfVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -562,7 +694,11 @@ public class OverviewFragment extends Fragment {
|
||||||
apsModeView.setBackgroundResource(R.drawable.loopmodeborder);
|
apsModeView.setBackgroundResource(R.drawable.loopmodeborder);
|
||||||
apsModeView.setTextColor(Color.BLACK);
|
apsModeView.setTextColor(Color.BLACK);
|
||||||
final LoopPlugin activeloop = MainApp.getConfigBuilder().getActiveLoop();
|
final LoopPlugin activeloop = MainApp.getConfigBuilder().getActiveLoop();
|
||||||
if (pump.isSuspended()) {
|
if (activeloop != null && activeloop.isEnabled(activeloop.getType()) && activeloop.isSuspended()) {
|
||||||
|
apsModeView.setBackgroundResource(R.drawable.loopmodesuspendedborder);
|
||||||
|
apsModeView.setText(String.format(MainApp.sResources.getString(R.string.loopsuspendedfor), activeloop.minutesToEndOfSuspend()));
|
||||||
|
apsModeView.setTextColor(Color.WHITE);
|
||||||
|
} else if (pump.isSuspended()) {
|
||||||
apsModeView.setBackgroundResource(R.drawable.loopmodesuspendedborder);
|
apsModeView.setBackgroundResource(R.drawable.loopmodesuspendedborder);
|
||||||
apsModeView.setText(MainApp.sResources.getString(R.string.pumpsuspended));
|
apsModeView.setText(MainApp.sResources.getString(R.string.pumpsuspended));
|
||||||
apsModeView.setTextColor(Color.WHITE);
|
apsModeView.setTextColor(Color.WHITE);
|
||||||
|
@ -576,10 +712,8 @@ public class OverviewFragment extends Fragment {
|
||||||
apsModeView.setBackgroundResource(R.drawable.loopmodedisabledborder);
|
apsModeView.setBackgroundResource(R.drawable.loopmodedisabledborder);
|
||||||
apsModeView.setText(MainApp.sResources.getString(R.string.disabledloop));
|
apsModeView.setText(MainApp.sResources.getString(R.string.disabledloop));
|
||||||
apsModeView.setTextColor(Color.WHITE);
|
apsModeView.setTextColor(Color.WHITE);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
|
||||||
apsModeView.setOnLongClickListener(new View.OnLongClickListener() {
|
apsModeView.setOnLongClickListener(new View.OnLongClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public boolean onLongClick(View view) {
|
public boolean onLongClick(View view) {
|
||||||
|
@ -600,7 +734,7 @@ public class OverviewFragment extends Fragment {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
apsModeView.setLongClickable(true);
|
apsModeView.setLongClickable(true);
|
||||||
|
*/
|
||||||
} else {
|
} else {
|
||||||
apsModeView.setVisibility(View.GONE);
|
apsModeView.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,11 @@ public class SP {
|
||||||
}
|
}
|
||||||
|
|
||||||
static public long getLong(String key, Long defaultValue) {
|
static public long getLong(String key, Long defaultValue) {
|
||||||
return SafeParse.stringToLong(sharedPreferences.getString(key, defaultValue.toString()));
|
try {
|
||||||
|
return sharedPreferences.getLong(key, defaultValue);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return SafeParse.stringToLong(sharedPreferences.getString(key, defaultValue.toString()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static public void putBoolean(String key, boolean value) {
|
static public void putBoolean(String key, boolean value) {
|
||||||
|
@ -82,9 +86,9 @@ public class SP {
|
||||||
editor.apply();
|
editor.apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
static public void putString(String key, String value) {
|
static public void putLong(String key, long value) {
|
||||||
SharedPreferences.Editor editor = sharedPreferences.edit();
|
SharedPreferences.Editor editor = sharedPreferences.edit();
|
||||||
editor.putString(key, value);
|
editor.putLong(key, value);
|
||||||
editor.apply();
|
editor.apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -139,6 +139,7 @@
|
||||||
<string name="closedloop">Closed Loop</string>
|
<string name="closedloop">Closed Loop</string>
|
||||||
<string name="openloop">Open Loop</string>
|
<string name="openloop">Open Loop</string>
|
||||||
<string name="disabledloop">Loop Disabled</string>
|
<string name="disabledloop">Loop Disabled</string>
|
||||||
|
<string name="enabledloop">Loop Enabled</string>
|
||||||
|
|
||||||
<string name="openloop_newsuggestion">New suggestion available</string>
|
<string name="openloop_newsuggestion">New suggestion available</string>
|
||||||
<string name="unsupportedclientver">Unsupported version of NSClient</string>
|
<string name="unsupportedclientver">Unsupported version of NSClient</string>
|
||||||
|
@ -557,4 +558,17 @@
|
||||||
<string name="batteryoptimalizationerror">Device does not appear to support battery optimization whitelisting!</string>
|
<string name="batteryoptimalizationerror">Device does not appear to support battery optimization whitelisting!</string>
|
||||||
<string name="pleaseallowpermission">Please Allow Permission</string>
|
<string name="pleaseallowpermission">Please Allow Permission</string>
|
||||||
<string name="needwhitelisting">%s needs battery optimalization whitelisting for proper performance</string>
|
<string name="needwhitelisting">%s needs battery optimalization whitelisting for proper performance</string>
|
||||||
|
<string name="loopsuspended">Loop suspended</string>
|
||||||
|
<string name="loopsuspendedfor">Suspended (%d m)</string>
|
||||||
|
<string name="loopmenu">Loop menu</string>
|
||||||
|
<string name="suspendloopfor1h">Suspend loop for 1h</string>
|
||||||
|
<string name="suspendloopfor2h">Suspend loop for 2h</string>
|
||||||
|
<string name="suspendloopfor3h">Suspend loop for 3h</string>
|
||||||
|
<string name="suspendloopfor10h">Suspend loop for 10h</string>
|
||||||
|
<string name="disconnectpumpfor30m">Disconnect pump for 30 min</string>
|
||||||
|
<string name="disconnectpumpfor1h">Disconnect pump for 1 h</string>
|
||||||
|
<string name="disconnectpumpfor2h">Disconnect pump for 2 h</string>
|
||||||
|
<string name="disconnectpumpfor3h">Disconnect pump for 3 h</string>
|
||||||
|
<string name="disconnectpumpfor10h">Disconnect pump for 10 h</string>
|
||||||
|
<string name="resume">Resume</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Reference in a new issue