Merge pull request #83 from MilosKozak/koreandanar

Koreandanar
This commit is contained in:
Milos Kozak 2016-12-27 14:27:40 +01:00 committed by GitHub
commit b3f026992e
97 changed files with 4641 additions and 662 deletions

View file

@ -35,6 +35,7 @@
<activity android:name=".PreferencesActivity" /> <activity android:name=".PreferencesActivity" />
<activity android:name=".AgreementActivity" /> <activity android:name=".AgreementActivity" />
<activity android:name=".plugins.DanaR.History.DanaRHistoryActivity" /> <activity android:name=".plugins.DanaR.History.DanaRHistoryActivity" />
<activity android:name=".plugins.DanaRKorean.History.DanaRHistoryActivity" />
<activity android:name=".plugins.Overview.activities.QuickWizardListActivity"> <activity android:name=".plugins.Overview.activities.QuickWizardListActivity">
<intent-filter> <intent-filter>
<action android:name="info.nightscout.androidaps.plugins.Overview.activities.QuickWizardListActivity" /> <action android:name="info.nightscout.androidaps.plugins.Overview.activities.QuickWizardListActivity" />
@ -80,6 +81,10 @@
android:name=".plugins.DanaR.Services.ExecutionService" android:name=".plugins.DanaR.Services.ExecutionService"
android:enabled="true" android:enabled="true"
android:exported="false" /> android:exported="false" />
<service
android:name=".plugins.DanaRKorean.Services.ExecutionService"
android:enabled="true"
android:exported="false" />
<service android:name=".plugins.Wear.wearintegration.WatchUpdaterService" android:exported="true" > <service android:name=".plugins.Wear.wearintegration.WatchUpdaterService" android:exported="true" >
<intent-filter> <action android:name="com.google.android.gms.wearable.BIND_LISTENER" /> </intent-filter> <intent-filter> <action android:name="com.google.android.gms.wearable.BIND_LISTENER" /> </intent-filter>

View file

@ -15,7 +15,7 @@ public class Config {
public static final boolean SMSCOMMUNICATORENABLED = true; public static final boolean SMSCOMMUNICATORENABLED = true;
public static final boolean DANAR = true && BuildConfig.PUMPDRIVERS; public static final boolean DANAR = true && BuildConfig.PUMPDRIVERS;
public static final boolean MM640G = false && BuildConfig.PUMPDRIVERS; public static final boolean DANARKOREAN = true && BuildConfig.PUMPDRIVERS;
public static final boolean detailedLog = true; public static final boolean detailedLog = true;
public static final boolean logFunctionCalls = true; public static final boolean logFunctionCalls = true;

View file

@ -39,8 +39,6 @@ import info.nightscout.utils.LocaleHelper;
public class MainActivity extends AppCompatActivity { public class MainActivity extends AppCompatActivity {
private static Logger log = LoggerFactory.getLogger(MainActivity.class); private static Logger log = LoggerFactory.getLogger(MainActivity.class);
private static KeepAliveReceiver keepAliveReceiver;
static final int CASE_STORAGE = 0x1; static final int CASE_STORAGE = 0x1;
static final int CASE_SMS = 0x2; static final int CASE_SMS = 0x2;
@ -77,11 +75,7 @@ public class MainActivity extends AppCompatActivity {
// no action // no action
} }
if (keepAliveReceiver == null) {
keepAliveReceiver = new KeepAliveReceiver();
startService(new Intent(this, ExecutionService.class));
keepAliveReceiver.setAlarm(this);
}
setUpTabs(false); setUpTabs(false);
} }
@ -90,12 +84,17 @@ public class MainActivity extends AppCompatActivity {
SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
String lang = SP.getString("language", "en"); String lang = SP.getString("language", "en");
LocaleHelper.setLocale(getApplicationContext(), lang); LocaleHelper.setLocale(getApplicationContext(), lang);
recreate(); runOnUiThread(new Runnable() {
try { // activity may be destroyed @Override
setUpTabs(ev.isSwitchToLast()); public void run() {
} catch (IllegalStateException e) { recreate();
e.printStackTrace(); try { // activity may be destroyed
} setUpTabs(ev.isSwitchToLast());
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
});
} }
private void setUpTabs(boolean switchToLast) { private void setUpTabs(boolean switchToLast) {
@ -164,8 +163,7 @@ public class MainActivity extends AppCompatActivity {
// break; // break;
case R.id.nav_exit: case R.id.nav_exit:
log.debug("Exiting"); log.debug("Exiting");
keepAliveReceiver.cancelAlarm(this); MainApp.instance().stopKeepAliveService();
MainApp.bus().post(new EventAppExit()); MainApp.bus().post(new EventAppExit());
MainApp.closeDbHelper(); MainApp.closeDbHelper();
finish(); finish();

View file

@ -1,6 +1,7 @@
package info.nightscout.androidaps; package info.nightscout.androidaps;
import android.app.Application; import android.app.Application;
import android.content.Intent;
import android.content.res.Resources; import android.content.res.Resources;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
@ -22,9 +23,9 @@ import info.nightscout.androidaps.plugins.CircadianPercentageProfile.CircadianPe
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderFragment; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderFragment;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.DanaR.DanaRFragment; import info.nightscout.androidaps.plugins.DanaR.DanaRFragment;
import info.nightscout.androidaps.plugins.DanaRKorean.DanaRKoreanFragment;
import info.nightscout.androidaps.plugins.Loop.LoopFragment; import info.nightscout.androidaps.plugins.Loop.LoopFragment;
import info.nightscout.androidaps.plugins.MM640g.MM640gFragment; import info.nightscout.androidaps.plugins.NSProfile.NSProfileFragment;
import info.nightscout.androidaps.plugins.NSProfileViewer.NSProfileViewerFragment;
import info.nightscout.androidaps.plugins.Objectives.ObjectivesFragment; import info.nightscout.androidaps.plugins.Objectives.ObjectivesFragment;
import info.nightscout.androidaps.plugins.OpenAPSMA.OpenAPSMAFragment; import info.nightscout.androidaps.plugins.OpenAPSMA.OpenAPSMAFragment;
import info.nightscout.androidaps.plugins.Overview.OverviewFragment; import info.nightscout.androidaps.plugins.Overview.OverviewFragment;
@ -37,11 +38,13 @@ import info.nightscout.androidaps.plugins.TempBasals.TempBasalsFragment;
import info.nightscout.androidaps.plugins.Treatments.TreatmentsFragment; import info.nightscout.androidaps.plugins.Treatments.TreatmentsFragment;
import info.nightscout.androidaps.plugins.VirtualPump.VirtualPumpFragment; import info.nightscout.androidaps.plugins.VirtualPump.VirtualPumpFragment;
import info.nightscout.androidaps.plugins.Wear.WearFragment; import info.nightscout.androidaps.plugins.Wear.WearFragment;
import info.nightscout.androidaps.receivers.KeepAliveReceiver;
import io.fabric.sdk.android.Fabric; import io.fabric.sdk.android.Fabric;
public class MainApp extends Application { public class MainApp extends Application {
private static Logger log = LoggerFactory.getLogger(MainApp.class); private static Logger log = LoggerFactory.getLogger(MainApp.class);
private static KeepAliveReceiver keepAliveReceiver;
private static Bus sBus; private static Bus sBus;
private static MainApp sInstance; private static MainApp sInstance;
@ -70,12 +73,12 @@ public class MainApp extends Application {
pluginsList.add(OverviewFragment.getPlugin()); pluginsList.add(OverviewFragment.getPlugin());
pluginsList.add(ActionsFragment.getPlugin()); pluginsList.add(ActionsFragment.getPlugin());
if (Config.DANAR) pluginsList.add(DanaRFragment.getPlugin()); if (Config.DANAR) pluginsList.add(DanaRFragment.getPlugin());
if (Config.MM640G) pluginsList.add(MM640gFragment.getPlugin()); if (Config.DANARKOREAN) pluginsList.add(DanaRKoreanFragment.getPlugin());
if (Config.CAREPORTALENABLED) pluginsList.add(CareportalFragment.getPlugin()); if (Config.CAREPORTALENABLED) pluginsList.add(CareportalFragment.getPlugin());
pluginsList.add(VirtualPumpFragment.getPlugin()); pluginsList.add(VirtualPumpFragment.getPlugin());
if (Config.LOOPENABLED) pluginsList.add(LoopFragment.getPlugin()); if (Config.LOOPENABLED) pluginsList.add(LoopFragment.getPlugin());
if (Config.OPENAPSMAENABLED) pluginsList.add(OpenAPSMAFragment.getPlugin()); if (Config.OPENAPSMAENABLED) pluginsList.add(OpenAPSMAFragment.getPlugin());
pluginsList.add(NSProfileViewerFragment.getPlugin()); pluginsList.add(NSProfileFragment.getPlugin());
pluginsList.add(SimpleProfileFragment.getPlugin()); pluginsList.add(SimpleProfileFragment.getPlugin());
pluginsList.add(CircadianPercentageProfileFragment.getPlugin()); pluginsList.add(CircadianPercentageProfileFragment.getPlugin());
pluginsList.add(TreatmentsFragment.getPlugin()); pluginsList.add(TreatmentsFragment.getPlugin());
@ -94,6 +97,26 @@ public class MainApp extends Application {
MainApp.getConfigBuilder().initialize(); MainApp.getConfigBuilder().initialize();
} }
MainApp.getConfigBuilder().uploadAppStart(); MainApp.getConfigBuilder().uploadAppStart();
startKeepAliveService();
}
private void startKeepAliveService() {
if (keepAliveReceiver == null) {
keepAliveReceiver = new KeepAliveReceiver();
if (Config.DANAR) {
startService(new Intent(this, info.nightscout.androidaps.plugins.DanaR.Services.ExecutionService.class));
startService(new Intent(this, info.nightscout.androidaps.plugins.DanaRKorean.Services.ExecutionService.class));
}
keepAliveReceiver.setAlarm(this);
}
}
public void stopKeepAliveService(){
if(keepAliveReceiver!=null)
keepAliveReceiver.cancelAlarm(this);
} }
public static Bus bus() { public static Bus bus() {

View file

@ -17,6 +17,7 @@ import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.plugins.DanaR.BluetoothDevicePreference; import info.nightscout.androidaps.plugins.DanaR.BluetoothDevicePreference;
import info.nightscout.androidaps.plugins.DanaR.DanaRFragment; import info.nightscout.androidaps.plugins.DanaR.DanaRFragment;
import info.nightscout.androidaps.plugins.DanaR.DanaRPlugin; import info.nightscout.androidaps.plugins.DanaR.DanaRPlugin;
import info.nightscout.androidaps.plugins.DanaRKorean.DanaRKoreanPlugin;
import info.nightscout.utils.LocaleHelper; import info.nightscout.utils.LocaleHelper;
public class PreferencesActivity extends PreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener { public class PreferencesActivity extends PreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
@ -89,13 +90,12 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
addPreferencesFromResource(R.xml.pref_nightscout); addPreferencesFromResource(R.xml.pref_nightscout);
if (Config.DANAR) { if (Config.DANAR) {
DanaRPlugin danaRPlugin = (DanaRPlugin) MainApp.getSpecificPlugin(DanaRPlugin.class); DanaRPlugin danaRPlugin = (DanaRPlugin) MainApp.getSpecificPlugin(DanaRPlugin.class);
if (danaRPlugin.isEnabled(PluginBase.PUMP)) { DanaRKoreanPlugin danaRKoreanPlugin = (DanaRKoreanPlugin) MainApp.getSpecificPlugin(DanaRKoreanPlugin.class);
if (danaRPlugin.isEnabled(PluginBase.PUMP) || danaRKoreanPlugin.isEnabled(PluginBase.PUMP)) {
addPreferencesFromResource(R.xml.pref_danar); addPreferencesFromResource(R.xml.pref_danar);
addPreferencesFromResource(R.xml.pref_danarprofile); addPreferencesFromResource(R.xml.pref_danarprofile);
} }
} }
if (Config.MM640G)
addPreferencesFromResource(R.xml.pref_mm640g);
if (Config.SMSCOMMUNICATORENABLED) if (Config.SMSCOMMUNICATORENABLED)
addPreferencesFromResource(R.xml.pref_smscommunicator); addPreferencesFromResource(R.xml.pref_smscommunicator);
addPreferencesFromResource(R.xml.pref_others); addPreferencesFromResource(R.xml.pref_others);

View file

@ -22,9 +22,6 @@ import org.slf4j.LoggerFactory;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.Constants;
@ -36,10 +33,11 @@ import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.events.EventNewBG; import info.nightscout.androidaps.events.EventNewBG;
import info.nightscout.androidaps.events.EventNewBasalProfile; import info.nightscout.androidaps.events.EventNewBasalProfile;
import info.nightscout.androidaps.events.EventTreatmentChange; import info.nightscout.androidaps.events.EventTreatmentChange;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.DanaR.History.DanaRNSHistorySync; import info.nightscout.androidaps.plugins.DanaR.History.DanaRNSHistorySync;
import info.nightscout.androidaps.plugins.NSProfileViewer.NSProfileViewerPlugin; import info.nightscout.androidaps.plugins.NSProfile.NSProfilePlugin;
import info.nightscout.androidaps.plugins.Objectives.ObjectivesPlugin; import info.nightscout.androidaps.plugins.Objectives.ObjectivesPlugin;
import info.nightscout.androidaps.plugins.Overview.OverviewPlugin; import info.nightscout.androidaps.plugins.Overview.OverviewPlugin;
import info.nightscout.androidaps.plugins.SmsCommunicator.SmsCommunicatorPlugin; import info.nightscout.androidaps.plugins.SmsCommunicator.SmsCommunicatorPlugin;
@ -76,7 +74,7 @@ public class DataService extends IntentService {
nsClientEnabled = true; nsClientEnabled = true;
} }
boolean isNSProfile = ConfigBuilderPlugin.getActiveProfile().getClass().equals(NSProfileViewerPlugin.class); boolean isNSProfile = ConfigBuilderPlugin.getActiveProfile().getClass().equals(NSProfilePlugin.class);
SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
boolean nsUploadOnly = SP.getBoolean("ns_upload_only", false); boolean nsUploadOnly = SP.getBoolean("ns_upload_only", false);
@ -95,12 +93,11 @@ public class DataService extends IntentService {
// Objectives 0 // Objectives 0
ObjectivesPlugin.bgIsAvailableInNS = true; ObjectivesPlugin.bgIsAvailableInNS = true;
ObjectivesPlugin.saveProgress(); ObjectivesPlugin.saveProgress();
} else if (isNSProfile && Intents.ACTION_NEW_PROFILE.equals(action)){ } else if (isNSProfile && Intents.ACTION_NEW_PROFILE.equals(action)) {
// always handle Profili if NSProfile is enabled without looking at nsUploadOnly // always handle Profile if NSProfile is enabled without looking at nsUploadOnly
handleNewDataFromNSClient(intent); handleNewDataFromNSClient(intent);
} else if (!nsUploadOnly && } else if (!nsUploadOnly &&
(Intents.ACTION_NEW_PROFILE.equals(action) || (Intents.ACTION_NEW_TREATMENT.equals(action) ||
Intents.ACTION_NEW_TREATMENT.equals(action) ||
Intents.ACTION_CHANGED_TREATMENT.equals(action) || Intents.ACTION_CHANGED_TREATMENT.equals(action) ||
Intents.ACTION_REMOVED_TREATMENT.equals(action) || Intents.ACTION_REMOVED_TREATMENT.equals(action) ||
Intents.ACTION_NEW_STATUS.equals(action) || Intents.ACTION_NEW_STATUS.equals(action) ||
@ -248,21 +245,24 @@ public class DataService extends IntentService {
String activeProfile = bundles.getString("activeprofile"); String activeProfile = bundles.getString("activeprofile");
String profile = bundles.getString("profile"); String profile = bundles.getString("profile");
NSProfile nsProfile = new NSProfile(new JSONObject(profile), activeProfile); NSProfile nsProfile = new NSProfile(new JSONObject(profile), activeProfile);
if (MainApp.getConfigBuilder() == null) { MainApp.bus().post(new EventNewBasalProfile(nsProfile));
log.error("Config builder not ready on receive profile");
return;
}
PumpInterface pump = MainApp.getConfigBuilder(); PumpInterface pump = MainApp.getConfigBuilder();
if (pump != null) { if (pump != null) {
SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
if (SP.getBoolean("syncprofiletopump", false)) if (SP.getBoolean("syncprofiletopump", false)) {
pump.setNewBasalProfile(nsProfile); if (pump.setNewBasalProfile(nsProfile) == PumpInterface.SUCCESS) {
SmsCommunicatorPlugin smsCommunicatorPlugin = (SmsCommunicatorPlugin) MainApp.getSpecificPlugin(SmsCommunicatorPlugin.class);
if (smsCommunicatorPlugin != null && smsCommunicatorPlugin.isEnabled(PluginBase.GENERAL)) {
smsCommunicatorPlugin.sendNotificationToAllNumbers(MainApp.sResources.getString(R.string.profile_set_ok));
}
}
}
} else { } else {
log.error("No active pump selected"); log.error("No active pump selected");
} }
if (Config.logIncommingData) if (Config.logIncommingData)
log.debug("Received profile: " + activeProfile + " " + profile); log.debug("Received profile: " + activeProfile + " " + profile);
MainApp.bus().post(new EventNewBasalProfile(nsProfile));
} catch (JSONException e) { } catch (JSONException e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -419,7 +419,8 @@ public class DataService extends IntentService {
if (trJson.has("eventType")) { if (trJson.has("eventType")) {
treatment.mealBolus = true; treatment.mealBolus = true;
if (trJson.get("eventType").equals("Correction Bolus")) treatment.mealBolus = false; if (trJson.get("eventType").equals("Correction Bolus")) treatment.mealBolus = false;
if (trJson.get("eventType").equals("Bolus Wizard") && treatment.carbs <= 0) treatment.mealBolus = false; if (trJson.get("eventType").equals("Bolus Wizard") && treatment.carbs <= 0)
treatment.mealBolus = false;
} }
treatment.setTimeIndex(treatment.getTimeIndex()); treatment.setTimeIndex(treatment.getTimeIndex());
try { try {
@ -469,7 +470,8 @@ public class DataService extends IntentService {
if (trJson.has("eventType")) { if (trJson.has("eventType")) {
treatment.mealBolus = true; treatment.mealBolus = true;
if (trJson.get("eventType").equals("Correction Bolus")) treatment.mealBolus = false; if (trJson.get("eventType").equals("Correction Bolus")) treatment.mealBolus = false;
if (trJson.get("eventType").equals("Bolus Wizard") && treatment.carbs <= 0) treatment.mealBolus = false; if (trJson.get("eventType").equals("Bolus Wizard") && treatment.carbs <= 0)
treatment.mealBolus = false;
} }
treatment.setTimeIndex(treatment.getTimeIndex()); treatment.setTimeIndex(treatment.getTimeIndex());
try { try {

View file

@ -0,0 +1,8 @@
package info.nightscout.androidaps.events;
/**
* Created by mike on 13.12.2016.
*/
public class EventInitializationChanged {
}

View file

@ -0,0 +1,37 @@
package info.nightscout.androidaps.interfaces;
/**
* Created by mike on 08.12.2016.
*/
public class PumpDescription {
public static final int PERCENT = 1;
public static final int ABSOLUTE = 2;
public static final int EXTENDED = 4;
public boolean isBolusCapable = true;
public double bolusStep = 0.1d;
public boolean isExtendedBolusCapable = true;
public double extendedBolusStep = 0.1d;
public boolean isTempBasalCapable = true;
public int lowTempBasalStyle = PERCENT;
public int highTempBasalStyle = PERCENT;
public double maxHighTempPercent = 200;
public double maxHighTempAbsolute = 0; // zero = no limit
public double lowTempPercentStep = 10;
public double lowTempAbsoluteStep = 0.05d;
public int lowTempPercentDuration = 30;
public int lowTempAbsoluteDuration = 30;
public double highTempPercentStep = 10;
public double highTempAbsoluteStep = 0.05d;
public int highTempPercentDuration = 30;
public int highTempAbsoluteDuration = 30;
public boolean isSetBasalProfileCapable = true;
public double basalStep = 0.01d;
public double basalMinimumRate = 0.04d;
public boolean isRefillingCapable = false;
}

View file

@ -22,7 +22,11 @@ public interface PumpInterface {
boolean isExtendedBoluslInProgress(); boolean isExtendedBoluslInProgress();
// Upload to pump new basal profile // Upload to pump new basal profile
void setNewBasalProfile(NSProfile profile); int SUCCESS = 0;
int FAILED = 1;
int NOT_NEEDED = 2;
int setNewBasalProfile(NSProfile profile);
boolean isThisProfileSet(NSProfile profile);
double getBaseBasalRate(); // base basal rate, not temp basal double getBaseBasalRate(); // base basal rate, not temp basal
double getTempBasalAbsoluteRate(); double getTempBasalAbsoluteRate();
@ -42,4 +46,6 @@ public interface PumpInterface {
// Status to be passed to NS // Status to be passed to NS
JSONObject getJSONStatus(); JSONObject getJSONStatus();
String deviceID(); String deviceID();
PumpDescription getPumpDescription();
} }

View file

@ -1,14 +1,21 @@
package info.nightscout.androidaps.plugins.Actions; package info.nightscout.androidaps.plugins.Actions;
import android.app.Activity;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentManager;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Button;
import com.squareup.otto.Subscribe;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.events.EventInitializationChanged;
import info.nightscout.androidaps.events.EventRefreshGui;
import info.nightscout.androidaps.interfaces.FragmentBase; import info.nightscout.androidaps.interfaces.FragmentBase;
import info.nightscout.androidaps.plugins.Actions.dialogs.FillDialog; import info.nightscout.androidaps.plugins.Actions.dialogs.FillDialog;
import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialog; import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialog;
@ -22,10 +29,16 @@ import info.nightscout.androidaps.plugins.Actions.dialogs.NewTempBasalDialog;
public class ActionsFragment extends Fragment implements FragmentBase, View.OnClickListener { public class ActionsFragment extends Fragment implements FragmentBase, View.OnClickListener {
static ActionsPlugin actionsPlugin = new ActionsPlugin(); static ActionsPlugin actionsPlugin = new ActionsPlugin();
static public ActionsPlugin getPlugin() { static public ActionsPlugin getPlugin() {
return actionsPlugin; return actionsPlugin;
} }
Button profileSwitch;
Button extendedBolus;
Button tempBasal;
Button fill;
public ActionsFragment() { public ActionsFragment() {
} }
@ -35,14 +48,69 @@ public class ActionsFragment extends Fragment implements FragmentBase, View.OnCl
Bundle savedInstanceState) { Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.actions_fragment, container, false); View view = inflater.inflate(R.layout.actions_fragment, container, false);
view.findViewById(R.id.actions_profileswitch).setOnClickListener(this); profileSwitch = (Button) view.findViewById(R.id.actions_profileswitch);
view.findViewById(R.id.actions_extendedbolus).setOnClickListener(this); extendedBolus = (Button) view.findViewById(R.id.actions_extendedbolus);
view.findViewById(R.id.actions_settempbasal).setOnClickListener(this); tempBasal = (Button) view.findViewById(R.id.actions_settempbasal);
view.findViewById(R.id.actions_fill).setOnClickListener(this); fill = (Button) view.findViewById(R.id.actions_fill);
profileSwitch.setOnClickListener(this);
extendedBolus.setOnClickListener(this);
tempBasal.setOnClickListener(this);
fill.setOnClickListener(this);
updateGUIIfVisible();
return view; return view;
} }
@Override
public void onPause() {
super.onPause();
MainApp.bus().unregister(this);
}
@Override
public void onResume() {
super.onResume();
MainApp.bus().register(this);
}
@Subscribe
public void onStatusEvent(final EventInitializationChanged ev) {
updateGUIIfVisible();
}
@Subscribe
public void onStatusEvent(final EventRefreshGui ev) {
updateGUIIfVisible();
}
void updateGUIIfVisible() {
Activity activity = getActivity();
if (activity != null)
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
if (!MainApp.getConfigBuilder().getPumpDescription().isSetBasalProfileCapable || !MainApp.getConfigBuilder().isInitialized())
profileSwitch.setVisibility(View.GONE);
else
profileSwitch.setVisibility(View.VISIBLE);
if (!MainApp.getConfigBuilder().getPumpDescription().isExtendedBolusCapable || !MainApp.getConfigBuilder().isInitialized())
extendedBolus.setVisibility(View.GONE);
else
extendedBolus.setVisibility(View.VISIBLE);
if (!MainApp.getConfigBuilder().getPumpDescription().isTempBasalCapable || !MainApp.getConfigBuilder().isInitialized())
tempBasal.setVisibility(View.GONE);
else
tempBasal.setVisibility(View.VISIBLE);
if (!MainApp.getConfigBuilder().getPumpDescription().isRefillingCapable || !MainApp.getConfigBuilder().isInitialized())
fill.setVisibility(View.GONE);
else
fill.setVisibility(View.VISIBLE);
}
});
}
@Override @Override
public void onClick(View view) { public void onClick(View view) {
FragmentManager manager = getFragmentManager(); FragmentManager manager = getFragmentManager();
@ -57,11 +125,11 @@ public class ActionsFragment extends Fragment implements FragmentBase, View.OnCl
case R.id.actions_extendedbolus: case R.id.actions_extendedbolus:
NewExtendedBolusDialog newExtendedDialog = new NewExtendedBolusDialog(); NewExtendedBolusDialog newExtendedDialog = new NewExtendedBolusDialog();
newExtendedDialog.show(manager, "NewExtendedDialog"); newExtendedDialog.show(manager, "NewExtendedDialog");
break; break;
case R.id.actions_settempbasal: case R.id.actions_settempbasal:
NewTempBasalDialog newTempDialog = new NewTempBasalDialog(); NewTempBasalDialog newTempDialog = new NewTempBasalDialog();
newTempDialog.show(manager, "NewTempDialog"); newTempDialog.show(manager, "NewTempDialog");
break; break;
case R.id.actions_fill: case R.id.actions_fill:
FillDialog fillDialog = new FillDialog(); FillDialog fillDialog = new FillDialog();
fillDialog.show(manager, "FillDialog"); fillDialog.show(manager, "FillDialog");

View file

@ -30,12 +30,12 @@ public class ActionsPlugin implements PluginBase {
@Override @Override
public boolean isEnabled(int type) { public boolean isEnabled(int type) {
return fragmentEnabled; return type == GENERAL && fragmentEnabled;
} }
@Override @Override
public boolean isVisibleInTabs(int type) { public boolean isVisibleInTabs(int type) {
return fragmentVisible; return type == GENERAL && fragmentVisible;
} }
@Override @Override
@ -45,12 +45,12 @@ public class ActionsPlugin implements PluginBase {
@Override @Override
public void setFragmentEnabled(int type, boolean fragmentEnabled) { public void setFragmentEnabled(int type, boolean fragmentEnabled) {
this.fragmentEnabled = fragmentEnabled; if (type == GENERAL) this.fragmentEnabled = fragmentEnabled;
} }
@Override @Override
public void setFragmentVisible(int type, boolean fragmentVisible) { public void setFragmentVisible(int type, boolean fragmentVisible) {
this.fragmentVisible = fragmentVisible; if (type == GENERAL) this.fragmentVisible = fragmentVisible;
} }
} }

View file

@ -26,12 +26,12 @@ public class CareportalPlugin implements PluginBase {
@Override @Override
public boolean isEnabled(int type) { public boolean isEnabled(int type) {
return fragmentEnabled; return type == GENERAL && fragmentEnabled;
} }
@Override @Override
public boolean isVisibleInTabs(int type) { public boolean isVisibleInTabs(int type) {
return fragmentVisible; return type == GENERAL && fragmentVisible;
} }
@Override @Override
@ -41,12 +41,12 @@ public class CareportalPlugin implements PluginBase {
@Override @Override
public void setFragmentEnabled(int type, boolean fragmentEnabled) { public void setFragmentEnabled(int type, boolean fragmentEnabled) {
this.fragmentEnabled = fragmentEnabled; if (type == GENERAL) this.fragmentEnabled = fragmentEnabled;
} }
@Override @Override
public void setFragmentVisible(int type, boolean fragmentVisible) { public void setFragmentVisible(int type, boolean fragmentVisible) {
this.fragmentVisible = fragmentVisible; if (type == GENERAL) this.fragmentVisible = fragmentVisible;
} }
} }

View file

@ -541,7 +541,6 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
builder.setMessage(confirmText); builder.setMessage(confirmText);
builder.setPositiveButton(getContext().getString(R.string.ok), new DialogInterface.OnClickListener() { builder.setPositiveButton(getContext().getString(R.string.ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) { public void onClick(DialogInterface dialog, int id) {
ConfigBuilderPlugin.uploadCareportalEntryToNS(data);
if (options.executeProfileSwitch) { if (options.executeProfileSwitch) {
if (data.has("profile")) { if (data.has("profile")) {
sHandler.post(new Runnable() { sHandler.post(new Runnable() {
@ -559,12 +558,15 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
} else { } else {
log.error("No active pump selected"); log.error("No active pump selected");
} }
ConfigBuilderPlugin.uploadCareportalEntryToNS(data);
} catch (JSONException e) { } catch (JSONException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
}); });
} }
} else {
ConfigBuilderPlugin.uploadCareportalEntryToNS(data);
} }
} }
}); });

View file

@ -69,12 +69,12 @@ public class CircadianPercentageProfilePlugin implements PluginBase, ProfileInte
@Override @Override
public boolean isEnabled(int type) { public boolean isEnabled(int type) {
return fragmentEnabled; return type == PROFILE && fragmentEnabled;
} }
@Override @Override
public boolean isVisibleInTabs(int type) { public boolean isVisibleInTabs(int type) {
return fragmentVisible; return type == PROFILE && fragmentVisible;
} }
@Override @Override
@ -84,12 +84,12 @@ public class CircadianPercentageProfilePlugin implements PluginBase, ProfileInte
@Override @Override
public void setFragmentEnabled(int type, boolean fragmentEnabled) { public void setFragmentEnabled(int type, boolean fragmentEnabled) {
this.fragmentEnabled = fragmentEnabled; if (type == PROFILE) this.fragmentEnabled = fragmentEnabled;
} }
@Override @Override
public void setFragmentVisible(int type, boolean fragmentVisible) { public void setFragmentVisible(int type, boolean fragmentVisible) {
this.fragmentVisible = fragmentVisible; if (type == PROFILE) this.fragmentVisible = fragmentVisible;
} }
void storeSettings() { void storeSettings() {
@ -265,7 +265,7 @@ public class CircadianPercentageProfilePlugin implements PluginBase, ProfileInte
if (percentage < MIN_PERCENTAGE || percentage > MAX_PERCENTAGE){ if (percentage < MIN_PERCENTAGE || percentage > MAX_PERCENTAGE){
String msg = String.format(MainApp.sResources.getString(R.string.openapsma_valueoutofrange), "Profile-Percentage"); String msg = String.format(MainApp.sResources.getString(R.string.openapsma_valueoutofrange), "Profile-Percentage");
log.error(msg); log.error(msg);
OpenAPSMAPlugin.sendErrorToNSClient(msg); MainApp.getConfigBuilder().uploadError(msg);
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), msg, R.raw.error); ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), msg, R.raw.error);
percentage = Math.max(percentage, MIN_PERCENTAGE); percentage = Math.max(percentage, MIN_PERCENTAGE);
percentage = Math.min(percentage, MAX_PERCENTAGE); percentage = Math.min(percentage, MAX_PERCENTAGE);

View file

@ -1,16 +1,10 @@
package info.nightscout.androidaps.plugins.ConfigBuilder; package info.nightscout.androidaps.plugins.ConfigBuilder;
import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color; import android.graphics.Color;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -21,6 +15,7 @@ import android.widget.ListView;
import android.widget.TextView; import android.widget.TextView;
import java.util.ArrayList; import java.util.ArrayList;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.events.EventRefreshGui; import info.nightscout.androidaps.events.EventRefreshGui;
@ -31,9 +26,8 @@ import info.nightscout.androidaps.interfaces.FragmentBase;
import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.ProfileInterface; import info.nightscout.androidaps.interfaces.ProfileInterface;
import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.interfaces.TempBasalsInterface; import info.nightscout.androidaps.plugins.NSProfile.NSProfilePlugin;
import info.nightscout.androidaps.interfaces.TreatmentsInterface; import info.nightscout.androidaps.plugins.VirtualPump.VirtualPumpPlugin;
import info.nightscout.androidaps.plugins.Loop.LoopFragment;
public class ConfigBuilderFragment extends Fragment implements FragmentBase { public class ConfigBuilderFragment extends Fragment implements FragmentBase {
@ -93,7 +87,8 @@ public class ConfigBuilderFragment extends Fragment implements FragmentBase {
nsclientVerView.setText(ConfigBuilderPlugin.nsClientVersionName); nsclientVerView.setText(ConfigBuilderPlugin.nsClientVersionName);
nightscoutVerView.setText(ConfigBuilderPlugin.nightscoutVersionName); nightscoutVerView.setText(ConfigBuilderPlugin.nightscoutVersionName);
if (ConfigBuilderPlugin.nsClientVersionCode < 117) nsclientVerView.setTextColor(Color.RED); if (ConfigBuilderPlugin.nsClientVersionCode < 117) nsclientVerView.setTextColor(Color.RED);
if (ConfigBuilderPlugin.nightscoutVersionCode < 900) nightscoutVerView.setTextColor(Color.RED); if (ConfigBuilderPlugin.nightscoutVersionCode < 900)
nightscoutVerView.setTextColor(Color.RED);
setViews(); setViews();
return view; return view;
} }
@ -179,6 +174,7 @@ public class ConfigBuilderFragment extends Fragment implements FragmentBase {
onEnabledCategoryChanged(plugin, type); onEnabledCategoryChanged(plugin, type);
configBuilderPlugin.storeSettings(); configBuilderPlugin.storeSettings();
MainApp.bus().post(new EventRefreshGui(true)); MainApp.bus().post(new EventRefreshGui(true));
getPlugin().logPluginStatus();
} }
}); });
@ -189,6 +185,7 @@ public class ConfigBuilderFragment extends Fragment implements FragmentBase {
plugin.setFragmentVisible(type, cb.isChecked()); plugin.setFragmentVisible(type, cb.isChecked());
configBuilderPlugin.storeSettings(); configBuilderPlugin.storeSettings();
MainApp.bus().post(new EventRefreshGui(true)); MainApp.bus().post(new EventRefreshGui(true));
getPlugin().logPluginStatus();
} }
}); });
} else { } else {
@ -208,11 +205,13 @@ public class ConfigBuilderFragment extends Fragment implements FragmentBase {
holder.checkboxVisible.setEnabled(false); holder.checkboxVisible.setEnabled(false);
} }
int type = plugin.getType(); // Hide enabled control and force enabled plugin if there is only one plugin available
// Force enabled if there is only one plugin
if (type == PluginBase.PUMP || type == PluginBase.TREATMENT || type == PluginBase.TEMPBASAL || type == PluginBase.PROFILE) if (type == PluginBase.PUMP || type == PluginBase.TREATMENT || type == PluginBase.TEMPBASAL || type == PluginBase.PROFILE)
if (pluginList.size() < 2) if (pluginList.size() < 2) {
holder.checkboxEnabled.setEnabled(false); holder.checkboxEnabled.setEnabled(false);
plugin.setFragmentEnabled(type, true);
getPlugin().storeSettings();
}
// Constraints cannot be disabled // Constraints cannot be disabled
if (type == PluginBase.CONSTRAINTS) if (type == PluginBase.CONSTRAINTS)
@ -228,6 +227,16 @@ public class ConfigBuilderFragment extends Fragment implements FragmentBase {
} }
} }
// Disable profile control for pump profiles if pump is not enabled
if (type == PluginBase.PROFILE) {
if (PumpInterface.class.isAssignableFrom(plugin.getClass())) {
if (!plugin.isEnabled(PluginBase.PUMP)) {
holder.checkboxEnabled.setEnabled(false);
holder.checkboxEnabled.setChecked(false);
}
}
}
return convertView; return convertView;
} }
@ -235,9 +244,8 @@ public class ConfigBuilderFragment extends Fragment implements FragmentBase {
} }
void onEnabledCategoryChanged(PluginBase changedPlugin, int type) { void onEnabledCategoryChanged(PluginBase changedPlugin, int type) {
int category = changedPlugin.getType();
ArrayList<PluginBase> pluginsInCategory = null; ArrayList<PluginBase> pluginsInCategory = null;
switch (category) { switch (type) {
// Multiple selection allowed // Multiple selection allowed
case PluginBase.GENERAL: case PluginBase.GENERAL:
case PluginBase.CONSTRAINTS: case PluginBase.CONSTRAINTS:
@ -256,7 +264,7 @@ public class ConfigBuilderFragment extends Fragment implements FragmentBase {
case PluginBase.TEMPBASAL: case PluginBase.TEMPBASAL:
case PluginBase.TREATMENT: case PluginBase.TREATMENT:
case PluginBase.PUMP: case PluginBase.PUMP:
pluginsInCategory = MainApp.getSpecificPluginsList(category); pluginsInCategory = MainApp.getSpecificPluginsListByInterface(PumpInterface.class);
break; break;
} }
if (pluginsInCategory != null) { if (pluginsInCategory != null) {
@ -271,7 +279,12 @@ public class ConfigBuilderFragment extends Fragment implements FragmentBase {
} }
} }
} else { // enable first plugin in list } else { // enable first plugin in list
pluginsInCategory.get(0).setFragmentEnabled(type, true); if (type == PluginBase.PUMP)
MainApp.getSpecificPlugin(VirtualPumpPlugin.class).setFragmentEnabled(type, true);
else if (type == PluginBase.PROFILE)
MainApp.getSpecificPlugin(NSProfilePlugin.class).setFragmentEnabled(type, true);
else
pluginsInCategory.get(0).setFragmentEnabled(type, true);
} }
setViews(); setViews();
} }

View file

@ -35,6 +35,7 @@ import info.nightscout.androidaps.interfaces.BgSourceInterface;
import info.nightscout.androidaps.interfaces.ConstraintsInterface; import info.nightscout.androidaps.interfaces.ConstraintsInterface;
import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.ProfileInterface; import info.nightscout.androidaps.interfaces.ProfileInterface;
import info.nightscout.androidaps.interfaces.PumpDescription;
import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.interfaces.TempBasalsInterface; import info.nightscout.androidaps.interfaces.TempBasalsInterface;
import info.nightscout.androidaps.interfaces.TreatmentsInterface; import info.nightscout.androidaps.interfaces.TreatmentsInterface;
@ -45,6 +46,10 @@ import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
import info.nightscout.androidaps.plugins.OpenAPSMA.DetermineBasalResult; import info.nightscout.androidaps.plugins.OpenAPSMA.DetermineBasalResult;
import info.nightscout.androidaps.plugins.Overview.Dialogs.BolusProgressDialog; import info.nightscout.androidaps.plugins.Overview.Dialogs.BolusProgressDialog;
import info.nightscout.androidaps.plugins.Actions.dialogs.NewExtendedBolusDialog; import info.nightscout.androidaps.plugins.Actions.dialogs.NewExtendedBolusDialog;
import info.nightscout.androidaps.plugins.Overview.Notification;
import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification;
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
import info.nightscout.androidaps.plugins.SmsCommunicator.SmsCommunicatorPlugin;
import info.nightscout.client.data.DbLogger; import info.nightscout.client.data.DbLogger;
import info.nightscout.client.data.NSProfile; import info.nightscout.client.data.NSProfile;
import info.nightscout.utils.DateUtil; import info.nightscout.utils.DateUtil;
@ -97,12 +102,12 @@ public class ConfigBuilderPlugin implements PluginBase, PumpInterface, Constrain
@Override @Override
public boolean isEnabled(int type) { public boolean isEnabled(int type) {
return true; return type == GENERAL && true;
} }
@Override @Override
public boolean isVisibleInTabs(int type) { public boolean isVisibleInTabs(int type) {
return true; return type == GENERAL && true;
} }
@Override @Override
@ -191,6 +196,22 @@ public class ConfigBuilderPlugin implements PluginBase, PumpInterface, Constrain
return activeLoop; return activeLoop;
} }
public void logPluginStatus() {
for (PluginBase p : pluginList) {
log.debug(p.getName() + ":" +
(p.isEnabled(1) ? " GENERAL" : "") +
(p.isEnabled(2) ? " TREATMENT" : "") +
(p.isEnabled(3) ? " TEMPBASAL" : "") +
(p.isEnabled(4) ? " PROFILE" : "") +
(p.isEnabled(5) ? " APS" : "") +
(p.isEnabled(6) ? " PUMP" : "") +
(p.isEnabled(7) ? " CONSTRAINTS" : "") +
(p.isEnabled(8) ? " LOOP" : "") +
(p.isEnabled(9) ? " BGSOURCE" : "")
);
}
}
private void verifySelectionInCategories() { private void verifySelectionInCategories() {
ArrayList<PluginBase> pluginsInCategory; ArrayList<PluginBase> pluginsInCategory;
@ -314,8 +335,31 @@ public class ConfigBuilderPlugin implements PluginBase, PumpInterface, Constrain
} }
@Override @Override
public void setNewBasalProfile(NSProfile profile) { public int setNewBasalProfile(NSProfile profile) {
activePump.setNewBasalProfile(profile); // Compare with pump limits
NSProfile.BasalValue[] basalValues = profile.getBasalValues();
for (int index = 0; index < basalValues.length; index++) {
if (basalValues[index].value < getPumpDescription().basalMinimumRate) {
Notification notification = new Notification(Notification.BASAL_VALUE_BELOW_MINIMUM, MainApp.sResources.getString(R.string.basalvaluebelowminimum), Notification.URGENT);
MainApp.bus().post(new EventNewNotification(notification));
return FAILED;
}
}
MainApp.bus().post(new EventDismissNotification(Notification.BASAL_VALUE_BELOW_MINIMUM));
if (isThisProfileSet(profile)) {
log.debug("Correct profile already set");
return NOT_NEEDED;
} else {
return activePump.setNewBasalProfile(profile);
}
}
@Override
public boolean isThisProfileSet(NSProfile profile) {
return activePump.isThisProfileSet(profile);
} }
@Override @Override
@ -594,6 +638,21 @@ public class ConfigBuilderPlugin implements PluginBase, PumpInterface, Constrain
else return "Unknown"; else return "Unknown";
} }
@Override
public PumpDescription getPumpDescription() {
if (activePump != null)
return activePump.getPumpDescription();
else {
PumpDescription emptyDescription = new PumpDescription();
emptyDescription.isBolusCapable = false;
emptyDescription.isExtendedBolusCapable = false;
emptyDescription.isSetBasalProfileCapable = false;
emptyDescription.isTempBasalCapable = false;
emptyDescription.isRefillingCapable = false;
return emptyDescription;
}
}
/** /**
* Constraints interface * Constraints interface
**/ **/

View file

@ -16,7 +16,6 @@ import org.json.JSONObject;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.text.DateFormat;
import java.util.Date; import java.util.Date;
import java.util.Objects; import java.util.Objects;
@ -33,14 +32,18 @@ import info.nightscout.androidaps.events.EventPreferenceChange;
import info.nightscout.androidaps.interfaces.ConstraintsInterface; import info.nightscout.androidaps.interfaces.ConstraintsInterface;
import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.ProfileInterface; import info.nightscout.androidaps.interfaces.ProfileInterface;
import info.nightscout.androidaps.interfaces.PumpDescription;
import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.DanaR.Services.ExecutionService; import info.nightscout.androidaps.plugins.DanaR.Services.ExecutionService;
import info.nightscout.androidaps.plugins.NSProfile.NSProfilePlugin;
import info.nightscout.androidaps.plugins.Overview.Notification;
import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification;
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
import info.nightscout.client.data.NSProfile; import info.nightscout.client.data.NSProfile;
import info.nightscout.utils.DateUtil; 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.ToastUtils;
/** /**
* Created by mike on 05.08.2016. * Created by mike on 05.08.2016.
@ -63,6 +66,8 @@ public class DanaRPlugin implements PluginBase, PumpInterface, ConstraintsInterf
private static DanaRPump sDanaRPump = new DanaRPump(); private static DanaRPump sDanaRPump = new DanaRPump();
private static boolean useExtendedBoluses = false; private static boolean useExtendedBoluses = false;
private static PumpDescription pumpDescription = new PumpDescription();
public static DanaRPump getDanaRPump() { public static DanaRPump getDanaRPump() {
return sDanaRPump; return sDanaRPump;
} }
@ -75,6 +80,32 @@ public class DanaRPlugin implements PluginBase, PumpInterface, ConstraintsInterf
Intent intent = new Intent(context, ExecutionService.class); Intent intent = new Intent(context, ExecutionService.class);
context.bindService(intent, mConnection, Context.BIND_AUTO_CREATE); context.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
MainApp.bus().register(this); MainApp.bus().register(this);
pumpDescription.isBolusCapable = true; // TODO: use description in setTempBasalAbsolute
pumpDescription.bolusStep = 0.05d;
pumpDescription.isExtendedBolusCapable = true;
pumpDescription.extendedBolusStep = 0.1d;
pumpDescription.isTempBasalCapable = true;
pumpDescription.lowTempBasalStyle = PumpDescription.PERCENT;
pumpDescription.highTempBasalStyle = useExtendedBoluses ? PumpDescription.EXTENDED : PumpDescription.PERCENT;
pumpDescription.maxHighTempPercent = 200;
pumpDescription.maxHighTempAbsolute = 0;
pumpDescription.lowTempPercentStep = 10;
pumpDescription.lowTempAbsoluteStep = 0;
pumpDescription.lowTempPercentDuration = 60;
pumpDescription.lowTempAbsoluteDuration = 60;
pumpDescription.highTempPercentStep = 10;
pumpDescription.highTempAbsoluteStep = 0.05d;
pumpDescription.highTempPercentDuration = 60;
pumpDescription.highTempAbsoluteDuration = 30;
pumpDescription.isSetBasalProfileCapable = true;
pumpDescription.basalStep = 0.01d;
pumpDescription.basalMinimumRate = 0.04d;
pumpDescription.isRefillingCapable = true;
} }
ServiceConnection mConnection = new ServiceConnection() { ServiceConnection mConnection = new ServiceConnection() {
@ -99,11 +130,16 @@ public class DanaRPlugin implements PluginBase, PumpInterface, ConstraintsInterf
@Subscribe @Subscribe
public void onStatusEvent(final EventPreferenceChange s) { public void onStatusEvent(final EventPreferenceChange s) {
boolean previousValue = useExtendedBoluses; if (isEnabled(PUMP)) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext()); boolean previousValue = useExtendedBoluses;
useExtendedBoluses = sharedPreferences.getBoolean("danar_useextended", false); SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext());
if (useExtendedBoluses != previousValue && isExtendedBoluslInProgress()) { useExtendedBoluses = sharedPreferences.getBoolean("danar_useextended", false);
sExecutionService.extendedBolusStop();
pumpDescription.highTempBasalStyle = useExtendedBoluses ? PumpDescription.EXTENDED : PumpDescription.PERCENT;
if (useExtendedBoluses != previousValue && isExtendedBoluslInProgress()) {
sExecutionService.extendedBolusStop();
}
} }
} }
@ -140,8 +176,17 @@ public class DanaRPlugin implements PluginBase, PumpInterface, ConstraintsInterf
@Override @Override
public void setFragmentEnabled(int type, boolean fragmentEnabled) { public void setFragmentEnabled(int type, boolean fragmentEnabled) {
if (type == PluginBase.PROFILE) this.fragmentProfileEnabled = fragmentEnabled; if (type == PluginBase.PROFILE)
else if (type == PluginBase.PUMP) this.fragmentPumpEnabled = fragmentEnabled; this.fragmentProfileEnabled = fragmentEnabled;
else if (type == PluginBase.PUMP)
this.fragmentPumpEnabled = fragmentEnabled;
// if pump profile was enabled need to switch to another too
if (type == PluginBase.PUMP && !fragmentEnabled && this.fragmentProfileEnabled) {
setFragmentEnabled(PluginBase.PROFILE, false);
setFragmentVisible(PluginBase.PROFILE, false);
MainApp.getSpecificPlugin(NSProfilePlugin.class).setFragmentEnabled(PluginBase.PROFILE, true);
MainApp.getSpecificPlugin(NSProfilePlugin.class).setFragmentVisible(PluginBase.PROFILE, true);
}
} }
@Override @Override
@ -152,7 +197,7 @@ public class DanaRPlugin implements PluginBase, PumpInterface, ConstraintsInterf
@Override @Override
public boolean isInitialized() { public boolean isInitialized() {
return getDanaRPump().lastConnection.getTime() > 0; return getDanaRPump().lastConnection.getTime() > 0 && getDanaRPump().isExtendedBolusEnabled;
} }
// Pump interface // Pump interface
@ -173,13 +218,46 @@ public class DanaRPlugin implements PluginBase, PumpInterface, ConstraintsInterf
} }
@Override @Override
public void setNewBasalProfile(NSProfile profile) { public int setNewBasalProfile(NSProfile profile) {
if (sExecutionService == null) { if (sExecutionService == null) {
log.error("setNewBasalProfile sExecutionService is null"); log.error("setNewBasalProfile sExecutionService is null");
return; return FAILED;
} }
if (!sExecutionService.updateBasalsInPump(profile)) if (!isInitialized()) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.failedupdatebasalprofile)); log.error("setNewBasalProfile not initialized");
Notification notification = new Notification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED, MainApp.sResources.getString(R.string.pumpNotInitializedProfileNotSet), Notification.URGENT);
MainApp.bus().post(new EventNewNotification(notification));
return FAILED;
} else {
MainApp.bus().post(new EventDismissNotification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED));
}
if (!sExecutionService.updateBasalsInPump(profile)) {
Notification notification = new Notification(Notification.FAILED_UDPATE_PROFILE, MainApp.sResources.getString(R.string.failedupdatebasalprofile), Notification.URGENT);
MainApp.bus().post(new EventNewNotification(notification));
return FAILED;
} else {
MainApp.bus().post(new EventDismissNotification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED));
MainApp.bus().post(new EventDismissNotification(Notification.FAILED_UDPATE_PROFILE));
return SUCCESS;
}
}
@Override
public boolean isThisProfileSet(NSProfile profile) {
if (!isInitialized())
return true; // TODO: not sure what's better. so far TRUE to prevent too many SMS
DanaRPump pump = getDanaRPump();
int basalValues = pump.basal48Enable ? 48 : 24;
int basalIncrement = pump.basal48Enable ? 30 * 60 : 60 * 60;
for (int h = 0; h < basalValues; h++) {
Double pumpValue = pump.pumpProfiles[pump.activeProfile][h];
Double profileValue = profile.getBasal(h * basalIncrement);
if (!pumpValue.equals(profileValue)) {
log.debug("Diff found. Hour: " + h + " Pump: " + pumpValue + " Profile: " + profileValue);
return false;
}
}
return true;
} }
@Override @Override
@ -585,6 +663,10 @@ public class DanaRPlugin implements PluginBase, PumpInterface, ConstraintsInterf
return sExecutionService != null && sExecutionService.isConnecting(); return sExecutionService != null && sExecutionService.isConnecting();
} }
public static void doDisconnect(String from) {
if (sExecutionService != null) sExecutionService.disconnect(from);
}
@Override @Override
public JSONObject getJSONStatus() { public JSONObject getJSONStatus() {
if (getDanaRPump().lastConnection.getTime() + 5 * 60 * 1000L < new Date().getTime()) { if (getDanaRPump().lastConnection.getTime() + 5 * 60 * 1000L < new Date().getTime()) {
@ -611,7 +693,8 @@ public class DanaRPlugin implements PluginBase, PumpInterface, ConstraintsInterf
extended.put("BaseBasalRate", getBaseBasalRate()); extended.put("BaseBasalRate", getBaseBasalRate());
try { try {
extended.put("ActiveProfile", MainApp.getConfigBuilder().getActiveProfile().getProfile().getActiveProfile()); extended.put("ActiveProfile", MainApp.getConfigBuilder().getActiveProfile().getProfile().getActiveProfile());
} catch (Exception e) {} } catch (Exception e) {
}
pump.put("battery", battery); pump.put("battery", battery);
pump.put("status", status); pump.put("status", status);
@ -629,6 +712,11 @@ public class DanaRPlugin implements PluginBase, PumpInterface, ConstraintsInterf
return getDanaRPump().serialNumber; return getDanaRPump().serialNumber;
} }
@Override
public PumpDescription getPumpDescription() {
return pumpDescription;
}
/** /**
* Constraint interface * Constraint interface
*/ */

View file

@ -22,6 +22,11 @@ public class DanaRPump {
public static final int UNITS_MGDL = 0; public static final int UNITS_MGDL = 0;
public static final int UNITS_MMOL = 1; public static final int UNITS_MMOL = 1;
public static final int DELIVERY_PRIME = 0x01;
public static final int DELIVERY_STEP_BOLUS = 0x02;
public static final int DELIVERY_BASAL = 0x04;
public static final int DELIVERY_EXT_BOLUS = 0x08;
public static final String PROFILE_PREFIX = "DanaR-"; public static final String PROFILE_PREFIX = "DanaR-";
public Date lastConnection = new Date(0); public Date lastConnection = new Date(0);
@ -35,12 +40,25 @@ public class DanaRPump {
public int password = -1; public int password = -1;
public Date pumpTime = new Date(0); public Date pumpTime = new Date(0);
public static final int DOMESTIC_MODEL = 0x01;
public static final int EXPORT_MODEL = 0x03;
public int model;
public int protocol;
public int productCode;
public boolean isConfigUD;
public boolean isExtendedBolusEnabled;
// Status // Status
public boolean pumpSuspended; public boolean pumpSuspended;
public boolean calculatorEnabled; public boolean calculatorEnabled;
public double dailyTotalUnits; public double dailyTotalUnits;
public int maxDailyTotalUnits; public int maxDailyTotalUnits;
public double bolusStep;
public double basalStep;
public double iob; public double iob;
public double reservoirRemainingUnits; public double reservoirRemainingUnits;
@ -58,6 +76,7 @@ public class DanaRPump {
public int tempBasalTotalSec; public int tempBasalTotalSec;
public Date tempBasalStart; public Date tempBasalStart;
public boolean isDualBolusInProgress;
public boolean isExtendedInProgress; public boolean isExtendedInProgress;
public int extendedBolusMinutes; public int extendedBolusMinutes;
public double extendedBolusAmount; public double extendedBolusAmount;

View file

@ -30,6 +30,7 @@ import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.db.Treatment; import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.events.EventAppExit; import info.nightscout.androidaps.events.EventAppExit;
import info.nightscout.androidaps.events.EventInitializationChanged;
import info.nightscout.androidaps.events.EventPreferenceChange; import info.nightscout.androidaps.events.EventPreferenceChange;
import info.nightscout.androidaps.plugins.DanaR.DanaRPlugin; import info.nightscout.androidaps.plugins.DanaR.DanaRPlugin;
import info.nightscout.androidaps.plugins.DanaR.DanaRPump; import info.nightscout.androidaps.plugins.DanaR.DanaRPump;
@ -58,8 +59,10 @@ import info.nightscout.androidaps.plugins.DanaR.comm.MsgSetExtendedBolusStart;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgSetExtendedBolusStop; import info.nightscout.androidaps.plugins.DanaR.comm.MsgSetExtendedBolusStop;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgSetTempBasalStart; import info.nightscout.androidaps.plugins.DanaR.comm.MsgSetTempBasalStart;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgSetTempBasalStop; import info.nightscout.androidaps.plugins.DanaR.comm.MsgSetTempBasalStop;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgSetTime;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgSettingActiveProfile; import info.nightscout.androidaps.plugins.DanaR.comm.MsgSettingActiveProfile;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgSettingBasal; import info.nightscout.androidaps.plugins.DanaR.comm.MsgSettingBasal;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgSettingMeal;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgSettingGlucose; import info.nightscout.androidaps.plugins.DanaR.comm.MsgSettingGlucose;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgSettingMaxValues; import info.nightscout.androidaps.plugins.DanaR.comm.MsgSettingMaxValues;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgSettingProfileRatios; import info.nightscout.androidaps.plugins.DanaR.comm.MsgSettingProfileRatios;
@ -174,6 +177,11 @@ public class ExecutionService extends Service {
return connectionInProgress; return connectionInProgress;
} }
public void disconnect(String from) {
if (mSerialIOThread != null)
mSerialIOThread.disconnect(from);
}
public void connect(String from) { public void connect(String from) {
if (danaRPump.password != -1 && danaRPump.password != SafeParse.stringToInt(SP.getString("danar_password", "-1"))) { if (danaRPump.password != -1 && danaRPump.password != SafeParse.stringToInt(SP.getString("danar_password", "-1"))) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.wrongpumppassword), R.raw.error); ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.wrongpumppassword), R.raw.error);
@ -270,11 +278,11 @@ public class ExecutionService extends Service {
MsgStatusBolusExtended exStatusMsg = new MsgStatusBolusExtended(); MsgStatusBolusExtended exStatusMsg = new MsgStatusBolusExtended();
mSerialIOThread.sendMessage(new MsgSettingShippingInfo()); // TODO: show it somewhere
mSerialIOThread.sendMessage(tempStatusMsg); // do this before statusBasic because here is temp duration mSerialIOThread.sendMessage(tempStatusMsg); // do this before statusBasic because here is temp duration
mSerialIOThread.sendMessage(exStatusMsg); mSerialIOThread.sendMessage(exStatusMsg);
mSerialIOThread.sendMessage(statusMsg); mSerialIOThread.sendMessage(statusMsg);
mSerialIOThread.sendMessage(statusBasicMsg); mSerialIOThread.sendMessage(statusBasicMsg);
mSerialIOThread.sendMessage(new MsgSettingShippingInfo()); // TODO: show it somewhere
if (danaRPump.isNewPump) { if (danaRPump.isNewPump) {
mSerialIOThread.sendMessage(new MsgCheckValue()); mSerialIOThread.sendMessage(new MsgCheckValue());
@ -303,10 +311,10 @@ public class ExecutionService extends Service {
} }
Date now = new Date(); Date now = new Date();
if (danaRPump.lastSettingsRead.getTime() + 60 * 60 * 1000L < now.getTime()) { if (danaRPump.lastSettingsRead.getTime() + 60 * 60 * 1000L < now.getTime() || !((DanaRPlugin)MainApp.getSpecificPlugin(DanaRPlugin.class)).isInitialized()) {
mSerialIOThread.sendMessage(new MsgSettingShippingInfo()); mSerialIOThread.sendMessage(new MsgSettingShippingInfo());
mSerialIOThread.sendMessage(new MsgSettingActiveProfile()); mSerialIOThread.sendMessage(new MsgSettingActiveProfile());
//0x3203 mSerialIOThread.sendMessage(new MsgSettingMeal());
mSerialIOThread.sendMessage(new MsgSettingBasal()); mSerialIOThread.sendMessage(new MsgSettingBasal());
//0x3201 //0x3201
mSerialIOThread.sendMessage(new MsgSettingMaxValues()); mSerialIOThread.sendMessage(new MsgSettingMaxValues());
@ -315,11 +323,13 @@ public class ExecutionService extends Service {
mSerialIOThread.sendMessage(new MsgSettingActiveProfile()); mSerialIOThread.sendMessage(new MsgSettingActiveProfile());
mSerialIOThread.sendMessage(new MsgSettingProfileRatios()); mSerialIOThread.sendMessage(new MsgSettingProfileRatios());
mSerialIOThread.sendMessage(new MsgSettingProfileRatiosAll()); mSerialIOThread.sendMessage(new MsgSettingProfileRatiosAll());
mSerialIOThread.sendMessage(new MsgSetTime(new Date()));
danaRPump.lastSettingsRead = now; danaRPump.lastSettingsRead = now;
} }
danaRPump.lastConnection = now; danaRPump.lastConnection = now;
MainApp.bus().post(new EventDanaRNewStatus()); MainApp.bus().post(new EventDanaRNewStatus());
MainApp.bus().post(new EventInitializationChanged());
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -466,6 +476,7 @@ public class ExecutionService extends Service {
mSerialIOThread.sendMessage(msgSet); mSerialIOThread.sendMessage(msgSet);
MsgSetActivateBasalProfile msgActivate = new MsgSetActivateBasalProfile((byte) 0); MsgSetActivateBasalProfile msgActivate = new MsgSetActivateBasalProfile((byte) 0);
mSerialIOThread.sendMessage(msgActivate); mSerialIOThread.sendMessage(msgActivate);
danaRPump.lastSettingsRead = new Date(0); // force read full settings
getPumpStatus(); getPumpStatus();
return true; return true;
} }

View file

@ -51,6 +51,15 @@ public class MessageBase {
AddParamByte((byte) (date.get(Calendar.MINUTE))); AddParamByte((byte) (date.get(Calendar.MINUTE)));
} }
public void AddParamDateTime(Date date) {
AddParamByte((byte) (date.getSeconds()));
AddParamByte((byte) (date.getMinutes()));
AddParamByte((byte) (date.getHours()));
AddParamByte((byte) (date.getDate()));
AddParamByte((byte) (date.getMonth() + 1));
AddParamByte((byte) (date.getYear() - 100));
}
public byte[] getRawMessageBytes() { public byte[] getRawMessageBytes() {
this.buffer[0] = (byte) 0x7E; this.buffer[0] = (byte) 0x7E;
this.buffer[1] = (byte) 0x7E; this.buffer[1] = (byte) 0x7E;

View file

@ -33,7 +33,7 @@ public class MessageHashTable {
put(new MsgSetTempBasalStop()); // 0x0403 CMD_PUMPSET_EXERCISE_STOP put(new MsgSetTempBasalStop()); // 0x0403 CMD_PUMPSET_EXERCISE_STOP
put(new MsgSetExtendedBolusStop()); // 0x0406 CMD_PUMPSET_EXPANS_INS_STOP put(new MsgSetExtendedBolusStop()); // 0x0406 CMD_PUMPSET_EXPANS_INS_STOP
put(new MsgSetExtendedBolusStart()); // 0x0407 CMD_PUMPSET_EXPANS_INS_S put(new MsgSetExtendedBolusStart()); // 0x0407 CMD_PUMPSET_EXPANS_INS_S
put(new MsgError()); // 0x0601 CMD_PUMPOWAY_SYSTEM_STATUS put(new MsgError()); // 0x0601 CMD_PUMPOWAY_SYSTEM_STATUS
put(new MsgPCCommStart()); // 0x3001 CMD_CONNECT put(new MsgPCCommStart()); // 0x3001 CMD_CONNECT
put(new MsgPCCommStop()); // 0x3002 CMD_DISCONNECT put(new MsgPCCommStop()); // 0x3002 CMD_DISCONNECT
put(new MsgHistoryBolus()); // 0x3101 CMD_HISTORY_MEAL_INS put(new MsgHistoryBolus()); // 0x3101 CMD_HISTORY_MEAL_INS
@ -47,6 +47,7 @@ public class MessageHashTable {
put(new MsgHistoryBasalHour()); // 0x310A CMD_HISTORY_BASAL_HOUR put(new MsgHistoryBasalHour()); // 0x310A CMD_HISTORY_BASAL_HOUR
put(new MsgHistoryDone()); // 0x31F1 CMD_HISTORY_DONT_USED put(new MsgHistoryDone()); // 0x31F1 CMD_HISTORY_DONT_USED
put(new MsgSettingBasal()); // 0x3202 CMD_SETTING_V_BASAL_INS_I put(new MsgSettingBasal()); // 0x3202 CMD_SETTING_V_BASAL_INS_I
put(new MsgSettingMeal()); // 0x3203 CMD_SETTING_V_MEAL_SETTING_I
put(new MsgSettingProfileRatios()); // 0x3204 CMD_SETTING_V_CCC_I put(new MsgSettingProfileRatios()); // 0x3204 CMD_SETTING_V_CCC_I
put(new MsgSettingMaxValues()); // 0x3205 CMD_SETTING_V_MAX_VALUE_I put(new MsgSettingMaxValues()); // 0x3205 CMD_SETTING_V_MAX_VALUE_I
put(new MsgSettingBasalProfileAll()); // 0x3206 CMD_SETTING_V_BASAL_PROFILE_ALL put(new MsgSettingBasalProfileAll()); // 0x3206 CMD_SETTING_V_BASAL_PROFILE_ALL
@ -56,6 +57,7 @@ public class MessageHashTable {
put(new MsgSettingUserOptions()); // 0x320B CMD_SETTING_V_USER_OPTIONS put(new MsgSettingUserOptions()); // 0x320B CMD_SETTING_V_USER_OPTIONS
put(new MsgSettingActiveProfile()); // 0x320C CMD_SETTING_V_PROFILE_NUMBER put(new MsgSettingActiveProfile()); // 0x320C CMD_SETTING_V_PROFILE_NUMBER
put(new MsgSettingProfileRatiosAll()); // 0x320D CMD_SETTING_V_CIR_CF_VALUE put(new MsgSettingProfileRatiosAll()); // 0x320D CMD_SETTING_V_CIR_CF_VALUE
put(new MsgSetSingleBasalProfile()); // 0x3302 CMD_SETTING_BASAL_INS_S
put(new MsgSetBasalProfile()); // 0x3306 CMD_SETTING_BASAL_PROFILE_S put(new MsgSetBasalProfile()); // 0x3306 CMD_SETTING_BASAL_PROFILE_S
put(new MsgSetActivateBasalProfile()); // 0x330C CMD_SETTING_PROFILE_NUMBER_S put(new MsgSetActivateBasalProfile()); // 0x330C CMD_SETTING_PROFILE_NUMBER_S
put(new MsgHistoryAllDone()); // 0x41F1 CMD_HISTORY_ALL_DONE put(new MsgHistoryAllDone()); // 0x41F1 CMD_HISTORY_ALL_DONE

View file

@ -62,7 +62,7 @@ public class MessageOriginalNames {
messageNames.put(0x320d, "CMD_SETTING_V_CIR_CF_VALUE"); messageNames.put(0x320d, "CMD_SETTING_V_CIR_CF_VALUE");
messageNames.put(0x3301, "CMD_SETTING_MEAL_INS_S"); messageNames.put(0x3301, "CMD_SETTING_MEAL_INS_S");
messageNames.put(0x3302, "CMD_SETTING_Based_INS_S"); messageNames.put(0x3302, "CMD_SETTING_BASAL_INS_S");
messageNames.put(0x3303, "CMD_SETTING_MEAL_SETTING_S"); messageNames.put(0x3303, "CMD_SETTING_MEAL_SETTING_S");
messageNames.put(0x3304, "CMD_SETTING_CCC_S"); messageNames.put(0x3304, "CMD_SETTING_CCC_S");
messageNames.put(0x3305, "CMD_SETTING_MAX_VALUE_S"); messageNames.put(0x3305, "CMD_SETTING_MAX_VALUE_S");

View file

@ -4,6 +4,11 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.plugins.DanaR.DanaRPlugin;
import info.nightscout.androidaps.plugins.DanaR.DanaRPump;
import info.nightscout.utils.ToastUtils;
/** /**
* Created by mike on 30.06.2016. * Created by mike on 30.06.2016.
@ -17,15 +22,22 @@ public class MsgCheckValue extends MessageBase {
@Override @Override
public void handleMessage(byte[] bytes) { public void handleMessage(byte[] bytes) {
int a = intFromBuff(bytes, 0, 1); DanaRPump pump = DanaRPlugin.getDanaRPump();
int b = intFromBuff(bytes, 1, 1);
if (a != 3 || b <= 0) {
// another message will follow
} else {
pump.model = intFromBuff(bytes, 0, 1);
pump.protocol = intFromBuff(bytes, 1, 1);
pump.productCode = intFromBuff(bytes, 2, 1);
if (pump.model != DanaRPump.EXPORT_MODEL) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.wrongpumpdriverselected), R.raw.error);
((DanaRPlugin) MainApp.getSpecificPlugin(DanaRPlugin.class)).doDisconnect("Wrong Model");
log.debug("Wrong model selected");
}
if (Config.logDanaMessageDetail) {
log.debug("Model: " + String.format("%02X ", pump.model));
log.debug("Protocol: " + String.format("%02X ", pump.protocol));
log.debug("Product Code: " + String.format("%02X ", pump.productCode));
} }
if (Config.logDanaMessageDetail)
log.debug("Response: " + String.format("%02X ", a) + String.format("%02X ", b));
} }
} }

View file

@ -31,10 +31,6 @@ public class MsgError extends MessageBase {
break; break;
case 5: // Occlusion case 5: // Occlusion
errorString = MainApp.sResources.getString(R.string.occlusion); errorString = MainApp.sResources.getString(R.string.occlusion);
EventOverviewBolusProgress bolusingEvent = EventOverviewBolusProgress.getInstance();
MsgBolusStop.stopped = true;
bolusingEvent.status = errorString;
MainApp.bus().post(bolusingEvent);
break; break;
case 7: // Low Battery case 7: // Low Battery
errorString = MainApp.sResources.getString(R.string.lowbattery); errorString = MainApp.sResources.getString(R.string.lowbattery);
@ -43,6 +39,13 @@ public class MsgError extends MessageBase {
errorString = MainApp.sResources.getString(R.string.batterydischarged); errorString = MainApp.sResources.getString(R.string.batterydischarged);
break; break;
} }
if (errorCode < 8) { // bolus delivering stopped
EventOverviewBolusProgress bolusingEvent = EventOverviewBolusProgress.getInstance();
MsgBolusStop.stopped = true;
bolusingEvent.status = errorString;
MainApp.bus().post(bolusingEvent);
}
if (Config.logDanaMessageDetail) if (Config.logDanaMessageDetail)
log.debug("Error detected: " + errorString); log.debug("Error detected: " + errorString);
MainApp.getConfigBuilder().uploadError(errorString); MainApp.getConfigBuilder().uploadError(errorString);

View file

@ -3,6 +3,10 @@ package info.nightscout.androidaps.plugins.DanaR.comm;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.plugins.DanaR.DanaRPlugin;
import info.nightscout.androidaps.plugins.DanaR.DanaRPump;
public class MsgInitConnStatusBasic extends MessageBase { public class MsgInitConnStatusBasic extends MessageBase {
private static Logger log = LoggerFactory.getLogger(MsgInitConnStatusBasic.class); private static Logger log = LoggerFactory.getLogger(MsgInitConnStatusBasic.class);
@ -12,25 +16,51 @@ public class MsgInitConnStatusBasic extends MessageBase {
@Override @Override
public void handleMessage(byte[] bytes) { public void handleMessage(byte[] bytes) {
int a = intFromBuff(bytes, 0, 1); if (bytes.length - 10 < 21) {
int b = intFromBuff(bytes, 1, 1); return;
int c = intFromBuff(bytes, 2, 1); }
int d = intFromBuff(bytes, 3, 1); DanaRPump pump = DanaRPlugin.getDanaRPump();
int e = intFromBuff(bytes, 4, 1); pump.pumpSuspended = intFromBuff(bytes, 0, 1) == 1;
int f = intFromBuff(bytes, 5, 1); pump.calculatorEnabled = intFromBuff(bytes, 1, 1) == 1;
int g = intFromBuff(bytes, 6, 1); pump.dailyTotalUnits = intFromBuff(bytes, 2, 3) / 750d;
int h = intFromBuff(bytes, 7, 1); pump.maxDailyTotalUnits = intFromBuff(bytes, 5, 2) / 100;
int i = intFromBuff(bytes, 8, 1); pump.reservoirRemainingUnits = intFromBuff(bytes, 7, 3) / 750d;
int j = intFromBuff(bytes, 9, 1); pump.bolusBlocked = intFromBuff(bytes, 10, 1) == 1;
int k = intFromBuff(bytes, 10, 1); pump.currentBasal = intFromBuff(bytes, 11, 2) / 100d;
int l = intFromBuff(bytes, 11, 1); pump.tempBasalPercent = intFromBuff(bytes, 13, 1);
int m = intFromBuff(bytes, 12, 1); pump.isExtendedInProgress = intFromBuff(bytes, 14, 1) == 1;
int n = intFromBuff(bytes, 13, 1); pump.isTempBasalInProgress = intFromBuff(bytes, 15, 1) == 1;
int o; int statusBasalUDOption = intFromBuff(bytes, 16, 1);
pump.isDualBolusInProgress = intFromBuff(bytes, 17, 1) == 1;
double extendedBolusRate = intFromBuff(bytes, 18, 2) / 100d;
pump.batteryRemaining = intFromBuff(bytes, 20, 1);
try { try {
o = intFromBuff(bytes, 21, 1); int bolusConfig = intFromBuff(bytes, 21, 1);
} catch (Exception ex) { boolean deliveryPrime = (bolusConfig & DanaRPump.DELIVERY_PRIME) != 0;
o = 0; boolean deliveryStepBolus = (bolusConfig & DanaRPump.DELIVERY_STEP_BOLUS) != 0;
boolean deliveryBasal = (bolusConfig & DanaRPump.DELIVERY_BASAL) != 0;
boolean deliveryExtBolus = (bolusConfig & DanaRPump.DELIVERY_EXT_BOLUS) != 0;
log.debug("Delivery prime: " + deliveryPrime);
log.debug("Delivery step bolus: " + deliveryStepBolus);
log.debug("Delivery basal: " + deliveryBasal);
log.debug("Delivery ext bolus: " + deliveryExtBolus);
} catch (Exception e) {
}
if (Config.logDanaMessageDetail) {
log.debug("Pump suspended: " + pump.pumpSuspended);
log.debug("Calculator enabled: " + pump.calculatorEnabled);
log.debug("Daily total units: " + pump.dailyTotalUnits);
log.debug("Max daily total units: " + pump.maxDailyTotalUnits);
log.debug("Reservoir remaining units: " + pump.reservoirRemainingUnits);
log.debug("Bolus blocked: " + pump.bolusBlocked);
log.debug("Current basal: " + pump.currentBasal);
log.debug("Current temp basal percent: " + pump.tempBasalPercent);
log.debug("Is extended bolus running: " + pump.isExtendedInProgress);
log.debug("statusBasalUDOption: " + statusBasalUDOption);
log.debug("Is dual bolus running: " + pump.isDualBolusInProgress);
log.debug("Extended bolus rate: " + extendedBolusRate);
log.debug("Battery remaining: " + pump.batteryRemaining);
} }
} }
} }

View file

@ -3,6 +3,15 @@ package info.nightscout.androidaps.plugins.DanaR.comm;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.plugins.DanaR.DanaRPlugin;
import info.nightscout.androidaps.plugins.DanaR.DanaRPump;
import info.nightscout.androidaps.plugins.Overview.Notification;
import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification;
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
/** /**
* Created by mike on 28.05.2016. * Created by mike on 28.05.2016.
*/ */
@ -15,10 +24,28 @@ public class MsgInitConnStatusBolus extends MessageBase {
@Override @Override
public void handleMessage(byte[] bytes) { public void handleMessage(byte[] bytes) {
int a1 = intFromBuff(bytes, 0, 1); if (bytes.length - 10 > 12) {
int a2 = intFromBuff(bytes, 1, 1); return;
int c = intFromBuff(bytes, 8, 2); }
int d = c / 100; DanaRPump pump = DanaRPlugin.getDanaRPump();
int e = intFromBuff(bytes, 10, 2); int bolusConfig = intFromBuff(bytes, 0, 1);
pump.isExtendedBolusEnabled = (bolusConfig & 0x01) != 0;
pump.bolusStep = intFromBuff(bytes, 1, 1) / 100d;
pump.maxBolus = intFromBuff(bytes, 2, 2) / 100d;
//int bolusRate = intFromBuff(bytes, 4, 8);
if (Config.logDanaMessageDetail) {
log.debug("Is Extended bolus enabled: " + pump.isExtendedBolusEnabled);
log.debug("Bolus increment: " + pump.bolusStep);
log.debug("Bolus max: " + pump.maxBolus);
}
if (!pump.isExtendedBolusEnabled) {
Notification notification = new Notification(Notification.EXTENDED_BOLUS_DISABLED, MainApp.sResources.getString(R.string.danar_enableextendedbolus), Notification.URGENT);
MainApp.bus().post(new EventNewNotification(notification));
} else {
MainApp.bus().post(new EventDismissNotification(Notification.EXTENDED_BOLUS_DISABLED));
}
} }
} }

View file

@ -18,15 +18,15 @@ public class MsgInitConnStatusOption extends MessageBase {
@Override @Override
public void handleMessage(byte[] bytes) { public void handleMessage(byte[] bytes) {
int a = intFromBuff(bytes, 0, 1); int status1224Clock = intFromBuff(bytes, 0, 1);
int b = intFromBuff(bytes, 1, 1); int isStatusButtonScroll = intFromBuff(bytes, 1, 1);
int c = intFromBuff(bytes, 2, 1); int soundVibration = intFromBuff(bytes, 2, 1);
int d = intFromBuff(bytes, 3, 1); int glucoseUnit = intFromBuff(bytes, 3, 1);
int e = intFromBuff(bytes, 4, 1); int lcdTimeout = intFromBuff(bytes, 4, 1);
int f = intFromBuff(bytes, 5, 1); int backlightgTimeout = intFromBuff(bytes, 5, 1);
int g = intFromBuff(bytes, 6, 1); int languageOption = intFromBuff(bytes, 6, 1);
int h = intFromBuff(bytes, 7, 1); int lowReservoirAlarmBoundary = intFromBuff(bytes, 7, 1);
int i = intFromBuff(bytes, 8, 1); //int none = intFromBuff(bytes, 8, 1);
if (bytes.length >= 21) { if (bytes.length >= 21) {
DanaRPlugin.getDanaRPump().password = intFromBuff(bytes, 9, 2) ^ 0x3463; DanaRPlugin.getDanaRPump().password = intFromBuff(bytes, 9, 2) ^ 0x3463;
if (Config.logDanaMessageDetail) if (Config.logDanaMessageDetail)

View file

@ -6,6 +6,14 @@ import org.slf4j.LoggerFactory;
import java.util.Date; import java.util.Date;
import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.events.EventRefreshGui;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.plugins.DanaR.DanaRPlugin;
import info.nightscout.androidaps.plugins.DanaR.DanaRPump;
import info.nightscout.androidaps.plugins.DanaRKorean.DanaRKoreanPlugin;
import info.nightscout.utils.ToastUtils;
public class MsgInitConnStatusTime extends MessageBase { public class MsgInitConnStatusTime extends MessageBase {
private static Logger log = LoggerFactory.getLogger(MsgInitConnStatusTime.class); private static Logger log = LoggerFactory.getLogger(MsgInitConnStatusTime.class);
@ -16,9 +24,32 @@ public class MsgInitConnStatusTime extends MessageBase {
@Override @Override
public void handleMessage(byte[] bytes) { public void handleMessage(byte[] bytes) {
Date time = dateTimeSecFromBuff(bytes, 0); if (bytes.length - 10 > 7) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(),MainApp.sResources.getString(R.string.wrongpumpdriverselected), R.raw.error);
((DanaRPlugin) MainApp.getSpecificPlugin(DanaRPlugin.class)).doDisconnect("Wrong Model");
log.debug("Wrong model selected. Switching to Korean DanaR");
((DanaRKoreanPlugin)MainApp.getSpecificPlugin(DanaRKoreanPlugin.class)).setFragmentEnabled(PluginBase.PUMP, true);
((DanaRKoreanPlugin)MainApp.getSpecificPlugin(DanaRKoreanPlugin.class)).setFragmentVisible(PluginBase.PUMP, true);
((DanaRPlugin)MainApp.getSpecificPlugin(DanaRPlugin.class)).setFragmentEnabled(PluginBase.PUMP, false);
((DanaRPlugin)MainApp.getSpecificPlugin(DanaRPlugin.class)).setFragmentVisible(PluginBase.PUMP, false);
if (Config.logDanaMessageDetail) //If profile coming from pump, switch it as well
if(MainApp.getSpecificPlugin(DanaRPlugin.class).isEnabled(PluginBase.PROFILE)){
(MainApp.getSpecificPlugin(DanaRPlugin.class)).setFragmentEnabled(PluginBase.PROFILE, false);
(MainApp.getSpecificPlugin(DanaRKoreanPlugin.class)).setFragmentEnabled(PluginBase.PROFILE, true);
}
MainApp.getConfigBuilder().storeSettings();
MainApp.bus().post(new EventRefreshGui(false));
return;
}
Date time = dateTimeSecFromBuff(bytes, 0);
int versionCode = intFromBuff(bytes, 6, 1);
if (Config.logDanaMessageDetail) {
log.debug("Pump time: " + time); log.debug("Pump time: " + time);
log.debug("Version code: " + versionCode);
}
} }
} }

View file

@ -4,6 +4,10 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.plugins.Overview.Notification;
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
public class MsgSetBasalProfile extends MessageBase { public class MsgSetBasalProfile extends MessageBase {
private static Logger log = LoggerFactory.getLogger(MsgSetBasalProfile.class); private static Logger log = LoggerFactory.getLogger(MsgSetBasalProfile.class);
@ -29,9 +33,13 @@ public class MsgSetBasalProfile extends MessageBase {
if (result != 1) { if (result != 1) {
failed = true; failed = true;
log.debug("Set basal profile result: " + result + " FAILED!!!"); log.debug("Set basal profile result: " + result + " FAILED!!!");
Notification reportFail = new Notification(Notification.PROFILE_SET_FAILED, MainApp.sResources.getString(R.string.profile_set_failed), Notification.URGENT);
MainApp.bus().post(new EventNewNotification(reportFail));
} else { } else {
if (Config.logDanaMessageDetail) if (Config.logDanaMessageDetail)
log.debug("Set basal profile result: " + result); log.debug("Set basal profile result: " + result);
Notification reportOK = new Notification(Notification.PROFILE_SET_OK, MainApp.sResources.getString(R.string.profile_set_ok), Notification.INFO, 60);
MainApp.bus().post(new EventNewNotification(reportOK));
} }
} }

View file

@ -0,0 +1,48 @@
package info.nightscout.androidaps.plugins.DanaR.comm;
import com.j256.ormlite.stmt.query.Not;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.plugins.Overview.Notification;
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
public class MsgSetSingleBasalProfile extends MessageBase {
private static Logger log = LoggerFactory.getLogger(MsgSetSingleBasalProfile.class);
public MsgSetSingleBasalProfile() {
SetCommand(0x3302);
}
// index 0-3
public MsgSetSingleBasalProfile(double[] values) {
this();
for (Integer i = 0; i < 24; i++) {
AddParamInt((int) (values[i] * 100));
}
if (Config.logDanaMessageDetail)
log.debug("Set basal profile");
}
@Override
public void handleMessage(byte[] bytes) {
int result = intFromBuff(bytes, 0, 1);
if (result != 1) {
failed = true;
log.debug("Set basal profile result: " + result + " FAILED!!!");
Notification reportFail = new Notification(Notification.PROFILE_SET_FAILED, MainApp.sResources.getString(R.string.profile_set_failed), Notification.URGENT);
MainApp.bus().post(new EventNewNotification(reportFail));
} else {
if (Config.logDanaMessageDetail)
log.debug("Set basal profile result: " + result);
Notification reportOK = new Notification(Notification.PROFILE_SET_OK, MainApp.sResources.getString(R.string.profile_set_ok), Notification.INFO, 60);
MainApp.bus().post(new EventNewNotification(reportOK));
}
}
}

View file

@ -0,0 +1,28 @@
package info.nightscout.androidaps.plugins.DanaR.comm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Date;
import info.nightscout.androidaps.Config;
/**
* Created by mike on 09.12.2016.
*/
public class MsgSetTime extends MessageBase {
private static Logger log = LoggerFactory.getLogger(MsgSetTime.class);
public MsgSetTime(Date time) {
SetCommand(0x330a);
AddParamDateTime(time);
}
public void handleMessage(byte[] bytes) {
int result = intFromBuff(bytes, 0, 1);
if (Config.logDanaMessageDetail)
log.debug("Result: " + result);
}
}

View file

@ -0,0 +1,40 @@
package info.nightscout.androidaps.plugins.DanaR.comm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.plugins.DanaR.DanaRPlugin;
import info.nightscout.androidaps.plugins.DanaR.DanaRPump;
/**
* Created by mike on 13.12.2016.
*/
public class MsgSettingMeal extends MessageBase {
private static Logger log = LoggerFactory.getLogger(MsgSettingMeal.class);
public MsgSettingMeal() {
SetCommand(0x3203);
}
public void handleMessage(byte[] bytes) {
DanaRPump pump = DanaRPlugin.getDanaRPump();
pump.basalStep = intFromBuff(bytes, 0, 1) / 100d;
pump.bolusStep = intFromBuff(bytes, 1, 1) / 100d;
boolean bolusEnabled = intFromBuff(bytes, 2, 1) == 1;
int melodyTime = intFromBuff(bytes, 3, 1);
int blockTime = intFromBuff(bytes, 4, 1);
pump.isConfigUD = intFromBuff(bytes, 5, 1) == 1;
if (Config.logDanaMessageDetail) {
log.debug("Basal step: " + pump.basalStep);
log.debug("Bolus step: " + pump.bolusStep);
log.debug("Bolus enabled: " + bolusEnabled);
log.debug("Melody time: " + melodyTime);
log.debug("Block time: " + blockTime);
log.debug("Is Config U/d: " + pump.isConfigUD);
}
}
}

View file

@ -7,6 +7,7 @@ import java.util.Date;
import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.plugins.DanaR.DanaRPlugin; import info.nightscout.androidaps.plugins.DanaR.DanaRPlugin;
import info.nightscout.androidaps.plugins.DanaR.DanaRPump;
/** /**
* Created by mike on 05.07.2016. * Created by mike on 05.07.2016.
@ -19,17 +20,18 @@ public class MsgSettingShippingInfo extends MessageBase {
} }
public void handleMessage(byte[] bytes) { public void handleMessage(byte[] bytes) {
DanaRPlugin.getDanaRPump().serialNumber = stringFromBuff(bytes, 0, 10); DanaRPump pump = DanaRPlugin.getDanaRPump();
DanaRPlugin.getDanaRPump().shippingDate = dateFromBuff(bytes, 10); pump.serialNumber = stringFromBuff(bytes, 0, 10);
DanaRPlugin.getDanaRPump().shippingCountry = asciiStringFromBuff(bytes, 13, 3); pump.shippingDate = dateFromBuff(bytes, 10);
if (DanaRPlugin.getDanaRPump().shippingDate.getTime() > new Date(116, 4, 1).getTime()) { pump.shippingCountry = asciiStringFromBuff(bytes, 13, 3);
DanaRPlugin.getDanaRPump().isNewPump = true; if (pump.shippingDate.getTime() > new Date(116, 4, 1).getTime()) {
pump.isNewPump = true;
} else } else
DanaRPlugin.getDanaRPump().isNewPump = false; pump.isNewPump = false;
if (Config.logDanaMessageDetail) { if (Config.logDanaMessageDetail) {
log.debug("Serial number: " + DanaRPlugin.getDanaRPump().serialNumber); log.debug("Serial number: " + pump.serialNumber);
log.debug("Shipping date: " + DanaRPlugin.getDanaRPump().shippingDate); log.debug("Shipping date: " + pump.shippingDate);
log.debug("Shipping country: " + DanaRPlugin.getDanaRPump().shippingCountry); log.debug("Shipping country: " + pump.shippingCountry);
} }
} }
} }

View file

@ -5,6 +5,7 @@ import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.plugins.DanaR.DanaRPlugin; import info.nightscout.androidaps.plugins.DanaR.DanaRPlugin;
import info.nightscout.androidaps.plugins.DanaR.DanaRPump;
public class MsgStatusBasic extends MessageBase { public class MsgStatusBasic extends MessageBase {
@ -15,41 +16,31 @@ public class MsgStatusBasic extends MessageBase {
} }
public void handleMessage(byte[] bytes) { public void handleMessage(byte[] bytes) {
boolean pumpSuspended = intFromBuff(bytes, 0, 1) == 1; DanaRPump pump = DanaRPlugin.getDanaRPump();
boolean calculatorEnabled = intFromBuff(bytes, 1, 1) == 1;
double dailyTotalUnits = intFromBuff(bytes, 2, 3) / 750d;
int maxDailyTotalUnits = intFromBuff(bytes, 5, 2) / 100;
double reservoirRemainingUnits = intFromBuff(bytes, 7, 3) / 750d;
boolean bolusBlocked = intFromBuff(bytes, 10, 1) == 1;
double currentBasal = intFromBuff(bytes, 11, 2) / 100d;
int tempBasalPercent = intFromBuff(bytes, 13, 1);
boolean isExtendedInProgress = intFromBuff(bytes, 14, 1) == 1;
boolean isTempBasalInProgress = intFromBuff(bytes, 15, 1) == 1;
int batteryRemaining = intFromBuff(bytes, 20, 1);
DanaRPlugin.getDanaRPump().pumpSuspended = pumpSuspended; pump.pumpSuspended = intFromBuff(bytes, 0, 1) == 1;
DanaRPlugin.getDanaRPump().calculatorEnabled = calculatorEnabled; pump.calculatorEnabled = intFromBuff(bytes, 1, 1) == 1;
DanaRPlugin.getDanaRPump().dailyTotalUnits = dailyTotalUnits; pump.dailyTotalUnits = intFromBuff(bytes, 2, 3) / 750d;
DanaRPlugin.getDanaRPump().maxDailyTotalUnits = maxDailyTotalUnits; pump.maxDailyTotalUnits = intFromBuff(bytes, 5, 2) / 100;
DanaRPlugin.getDanaRPump().reservoirRemainingUnits = reservoirRemainingUnits; pump.reservoirRemainingUnits = intFromBuff(bytes, 7, 3) / 750d;
DanaRPlugin.getDanaRPump().bolusBlocked = bolusBlocked; pump.bolusBlocked = intFromBuff(bytes, 10, 1) == 1;
DanaRPlugin.getDanaRPump().currentBasal = currentBasal; pump.currentBasal = intFromBuff(bytes, 11, 2) / 100d;
DanaRPlugin.getDanaRPump().tempBasalPercent = tempBasalPercent; pump.tempBasalPercent = intFromBuff(bytes, 13, 1);
DanaRPlugin.getDanaRPump().isExtendedInProgress = isExtendedInProgress; pump.isExtendedInProgress = intFromBuff(bytes, 14, 1) == 1;
DanaRPlugin.getDanaRPump().isTempBasalInProgress = isTempBasalInProgress; pump.isTempBasalInProgress = intFromBuff(bytes, 15, 1) == 1;
DanaRPlugin.getDanaRPump().batteryRemaining = batteryRemaining; pump.batteryRemaining = intFromBuff(bytes, 20, 1);
if (Config.logDanaMessageDetail) { if (Config.logDanaMessageDetail) {
log.debug("Pump suspended: " + pumpSuspended); log.debug("Pump suspended: " + pump.pumpSuspended);
log.debug("Calculator enabled: " + calculatorEnabled); log.debug("Calculator enabled: " + pump.calculatorEnabled);
log.debug("Daily total units: " + dailyTotalUnits); log.debug("Daily total units: " + pump.dailyTotalUnits);
log.debug("Max daily total units: " + maxDailyTotalUnits); log.debug("Max daily total units: " + pump.maxDailyTotalUnits);
log.debug("Reservoir remaining units: " + reservoirRemainingUnits); log.debug("Reservoir remaining units: " + pump.reservoirRemainingUnits);
log.debug("Bolus blocked: " + bolusBlocked); log.debug("Bolus blocked: " + pump.bolusBlocked);
log.debug("Current basal: " + currentBasal); log.debug("Current basal: " + pump.currentBasal);
log.debug("Current temp basal percent: " + tempBasalPercent); log.debug("Current temp basal percent: " + pump.tempBasalPercent);
log.debug("Is extended bolus running: " + isExtendedInProgress); log.debug("Is extended bolus running: " + pump.isExtendedInProgress);
log.debug("Is temp basal running: " + isTempBasalInProgress); log.debug("Is temp basal running: " + pump.isTempBasalInProgress);
} }
} }
} }

View file

@ -0,0 +1,234 @@
package info.nightscout.androidaps.plugins.DanaRKorean;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import com.squareup.otto.Subscribe;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.DateFormat;
import java.util.Date;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.events.EventPreferenceChange;
import info.nightscout.androidaps.events.EventTempBasalChange;
import info.nightscout.androidaps.interfaces.FragmentBase;
import info.nightscout.androidaps.plugins.DanaR.Dialogs.ProfileViewDialog;
import info.nightscout.androidaps.plugins.DanaR.events.EventDanaRConnectionStatus;
import info.nightscout.androidaps.plugins.DanaR.events.EventDanaRNewStatus;
import info.nightscout.androidaps.plugins.DanaRKorean.History.DanaRHistoryActivity;
import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.SetWarnColor;
public class DanaRKoreanFragment extends Fragment implements FragmentBase {
private static Logger log = LoggerFactory.getLogger(DanaRKoreanFragment.class);
private static DanaRKoreanPlugin danaRKoreanPlugin = new DanaRKoreanPlugin();
public static DanaRKoreanPlugin getPlugin() {
return danaRKoreanPlugin;
}
private static Handler sHandler;
private static HandlerThread sHandlerThread;
private Handler loopHandler = new Handler();
private Runnable refreshLoop = null;
TextView lastConnectionView;
TextView btConnectionView;
TextView lastBolusView;
TextView dailyUnitsView;
TextView basaBasalRateView;
TextView tempBasalView;
TextView extendedBolusView;
TextView batteryView;
TextView reservoirView;
TextView iobView;
Button viewProfileButton;
Button historyButton;
public DanaRKoreanFragment() {
if (sHandlerThread == null) {
sHandlerThread = new HandlerThread(DanaRKoreanFragment.class.getSimpleName());
sHandlerThread.start();
sHandler = new Handler(sHandlerThread.getLooper());
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (refreshLoop == null) {
refreshLoop = new Runnable() {
@Override
public void run() {
updateGUI();
loopHandler.postDelayed(refreshLoop, 60 * 1000L);
}
};
loopHandler.postDelayed(refreshLoop, 60 * 1000L);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.danar_fragment, container, false);
btConnectionView = (TextView) view.findViewById(R.id.danar_btconnection);
lastConnectionView = (TextView) view.findViewById(R.id.danar_lastconnection);
lastBolusView = (TextView) view.findViewById(R.id.danar_lastbolus);
dailyUnitsView = (TextView) view.findViewById(R.id.danar_dailyunits);
basaBasalRateView = (TextView) view.findViewById(R.id.danar_basabasalrate);
tempBasalView = (TextView) view.findViewById(R.id.danar_tempbasal);
extendedBolusView = (TextView) view.findViewById(R.id.danar_extendedbolus);
batteryView = (TextView) view.findViewById(R.id.danar_battery);
reservoirView = (TextView) view.findViewById(R.id.danar_reservoir);
iobView = (TextView) view.findViewById(R.id.danar_iob);
viewProfileButton = (Button) view.findViewById(R.id.danar_viewprofile);
historyButton = (Button) view.findViewById(R.id.danar_history);
viewProfileButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FragmentManager manager = getFragmentManager();
ProfileViewDialog profileViewDialog = new ProfileViewDialog();
profileViewDialog.show(manager, "ProfileViewDialog");
}
});
historyButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(getContext(), DanaRHistoryActivity.class));
}
});
btConnectionView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
sHandler.post(new Runnable() {
@Override
public void run() {
DanaRKoreanPlugin.sExecutionService.connect("Connect request from GUI");
}
}
);
}
});
updateGUI();
return view;
}
@Override
public void onPause() {
super.onPause();
MainApp.bus().unregister(this);
}
@Override
public void onResume() {
super.onResume();
MainApp.bus().register(this);
}
@Subscribe
public void onStatusEvent(final EventDanaRConnectionStatus c) {
Activity activity = getActivity();
if (activity != null) {
activity.runOnUiThread(
new Runnable() {
@Override
public void run() {
if (c.sStatus == EventDanaRConnectionStatus.CONNECTING)
btConnectionView.setText("{fa-bluetooth-b spin} " + c.sSecondsElapsed + "s");
else if (c.sStatus == EventDanaRConnectionStatus.CONNECTED)
btConnectionView.setText("{fa-bluetooth}");
else
btConnectionView.setText("{fa-bluetooth-b}");
}
}
);
}
}
@Subscribe
public void onStatusEvent(final EventDanaRNewStatus s) {
updateGUI();
}
@Subscribe
public void onStatusEvent(final EventTempBasalChange s) {
updateGUI();
}
@Subscribe
public void onStatusEvent(final EventPreferenceChange s) {
updateGUI();
}
// GUI functions
private void updateGUI() {
final DateFormat formatTime = DateFormat.getTimeInstance(DateFormat.SHORT);
Activity activity = getActivity();
if (activity != null && basaBasalRateView != null)
activity.runOnUiThread(new Runnable() {
@SuppressLint("SetTextI18n")
@Override
public void run() {
if (DanaRKoreanPlugin.getDanaRPump().lastConnection.getTime() != 0) {
Long agoMsec = new Date().getTime() - DanaRKoreanPlugin.getDanaRPump().lastConnection.getTime();
int agoMin = (int) (agoMsec / 60d / 1000d);
lastConnectionView.setText(formatTime.format(DanaRKoreanPlugin.getDanaRPump().lastConnection) + " (" + agoMin + " " + MainApp.sResources.getString(R.string.minago) + ")");
SetWarnColor.setColor(lastConnectionView, agoMin, 16d, 31d);
}
// if (DanaRKoreanPlugin.getDanaRPump().lastBolusTime.getTime() != 0) {
// Long agoMsec = new Date().getTime() - DanaRKoreanPlugin.getDanaRPump().lastBolusTime.getTime();
// double agoHours = agoMsec / 60d / 60d / 1000d;
// if (agoHours < 6) // max 6h back
// lastBolusView.setText(formatTime.format(DanaRKoreanPlugin.getDanaRPump().lastBolusTime) + " (" + DecimalFormatter.to1Decimal(agoHours) + " " + getString(R.string.hoursago) + ") " + DecimalFormatter.to2Decimal(danaRKoreanPlugin.getDanaRPump().lastBolusAmount) + " U");
// else lastBolusView.setText("");
// }
dailyUnitsView.setText(DecimalFormatter.to0Decimal(DanaRKoreanPlugin.getDanaRPump().dailyTotalUnits) + " / " + DanaRKoreanPlugin.getDanaRPump().maxDailyTotalUnits + " U");
SetWarnColor.setColor(dailyUnitsView, DanaRKoreanPlugin.getDanaRPump().dailyTotalUnits, DanaRKoreanPlugin.getDanaRPump().maxDailyTotalUnits * 0.75d, DanaRKoreanPlugin.getDanaRPump().maxDailyTotalUnits * 0.9d);
basaBasalRateView.setText("( " + (DanaRKoreanPlugin.getDanaRPump().activeProfile + 1) + " ) " + DecimalFormatter.to2Decimal(danaRKoreanPlugin.getBaseBasalRate()) + " U/h");
if (danaRKoreanPlugin.isRealTempBasalInProgress()) {
tempBasalView.setText(danaRKoreanPlugin.getRealTempBasal().toString());
} else {
tempBasalView.setText("");
}
if (danaRKoreanPlugin.isExtendedBoluslInProgress()) {
extendedBolusView.setText(danaRKoreanPlugin.getExtendedBolus().toString());
} else {
extendedBolusView.setText("");
}
reservoirView.setText(DecimalFormatter.to0Decimal(DanaRKoreanPlugin.getDanaRPump().reservoirRemainingUnits) + " / 300 U");
SetWarnColor.setColorInverse(reservoirView, DanaRKoreanPlugin.getDanaRPump().reservoirRemainingUnits, 50d, 20d);
batteryView.setText("{fa-battery-" + (DanaRKoreanPlugin.getDanaRPump().batteryRemaining / 25) + "}");
SetWarnColor.setColorInverse(batteryView, DanaRKoreanPlugin.getDanaRPump().batteryRemaining, 51d, 26d);
iobView.setText(DanaRKoreanPlugin.getDanaRPump().iob + " U");
}
});
}
}

View file

@ -0,0 +1,826 @@
package info.nightscout.androidaps.plugins.DanaRKorean;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
import com.squareup.otto.Subscribe;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Date;
import java.util.Objects;
import info.nightscout.androidaps.BuildConfig;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.TempBasal;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.events.EventAppExit;
import info.nightscout.androidaps.events.EventPreferenceChange;
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.ProfileInterface;
import info.nightscout.androidaps.interfaces.PumpDescription;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.DanaRKorean.Services.ExecutionService;
import info.nightscout.androidaps.plugins.NSProfile.NSProfilePlugin;
import info.nightscout.androidaps.plugins.Overview.Notification;
import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification;
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
import info.nightscout.client.data.NSProfile;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.Round;
/**
* Created by mike on 05.08.2016.
*/
public class DanaRKoreanPlugin implements PluginBase, PumpInterface, ConstraintsInterface, ProfileInterface {
private static Logger log = LoggerFactory.getLogger(DanaRKoreanPlugin.class);
@Override
public String getFragmentClass() {
return DanaRKoreanFragment.class.getName();
}
static boolean fragmentPumpEnabled = true;
static boolean fragmentProfileEnabled = true;
static boolean fragmentPumpVisible = true;
public static ExecutionService sExecutionService;
private static DanaRKoreanPump sDanaRKoreanPump = new DanaRKoreanPump();
private static boolean useExtendedBoluses = false;
private PumpDescription pumpDescription = new PumpDescription();
public static DanaRKoreanPump getDanaRPump() {
return sDanaRKoreanPump;
}
public DanaRKoreanPlugin() {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext());
useExtendedBoluses = sharedPreferences.getBoolean("danar_useextended", false);
Context context = MainApp.instance().getApplicationContext();
Intent intent = new Intent(context, ExecutionService.class);
context.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
MainApp.bus().register(this);
pumpDescription.isBolusCapable = true; // TODO: use description in setTempBasalAbsolute
pumpDescription.bolusStep = 0.1d;
pumpDescription.isExtendedBolusCapable = true;
pumpDescription.extendedBolusStep = 0.1d;
pumpDescription.isTempBasalCapable = true;
pumpDescription.lowTempBasalStyle = PumpDescription.PERCENT;
pumpDescription.highTempBasalStyle = useExtendedBoluses ? PumpDescription.EXTENDED : PumpDescription.PERCENT;
pumpDescription.maxHighTempPercent = 200;
pumpDescription.maxHighTempAbsolute = 0;
pumpDescription.lowTempPercentStep = 10;
pumpDescription.lowTempAbsoluteStep = 0;
pumpDescription.lowTempPercentDuration = 60;
pumpDescription.lowTempAbsoluteDuration = 60;
pumpDescription.highTempPercentStep = 10;
pumpDescription.highTempAbsoluteStep = 0.05d;
pumpDescription.highTempPercentDuration = 60;
pumpDescription.highTempAbsoluteDuration = 30;
pumpDescription.isSetBasalProfileCapable = true;
pumpDescription.basalStep = 0.01d;
pumpDescription.basalMinimumRate = 0.1d;
pumpDescription.isRefillingCapable = true;
}
ServiceConnection mConnection = new ServiceConnection() {
public void onServiceDisconnected(ComponentName name) {
log.debug("Service is disconnected");
sExecutionService = null;
}
public void onServiceConnected(ComponentName name, IBinder service) {
log.debug("Service is connected");
ExecutionService.LocalBinder mLocalBinder = (ExecutionService.LocalBinder) service;
sExecutionService = mLocalBinder.getServiceInstance();
}
};
@SuppressWarnings("UnusedParameters")
@Subscribe
public void onStatusEvent(final EventAppExit e) {
MainApp.instance().getApplicationContext().unbindService(mConnection);
}
@Subscribe
public void onStatusEvent(final EventPreferenceChange s) {
if (isEnabled(PUMP)) {
boolean previousValue = useExtendedBoluses;
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext());
useExtendedBoluses = sharedPreferences.getBoolean("danar_useextended", false);
pumpDescription.highTempBasalStyle = useExtendedBoluses ? PumpDescription.EXTENDED : PumpDescription.PERCENT;
if (useExtendedBoluses != previousValue && isExtendedBoluslInProgress()) {
sExecutionService.extendedBolusStop();
}
}
}
// Plugin base interface
@Override
public int getType() {
return PluginBase.PUMP;
}
@Override
public String getName() {
return MainApp.instance().getString(R.string.danarkoreanpump);
}
@Override
public boolean isEnabled(int type) {
if (type == PluginBase.PROFILE) return fragmentProfileEnabled && fragmentPumpEnabled;
else if (type == PluginBase.PUMP) return fragmentPumpEnabled;
else if (type == PluginBase.CONSTRAINTS) return fragmentPumpEnabled;
return false;
}
@Override
public boolean isVisibleInTabs(int type) {
if (type == PluginBase.PROFILE || type == PluginBase.CONSTRAINTS) return false;
else if (type == PluginBase.PUMP) return fragmentPumpVisible;
return false;
}
@Override
public boolean canBeHidden(int type) {
return true;
}
@Override
public void setFragmentEnabled(int type, boolean fragmentEnabled) {
if (type == PluginBase.PROFILE)
this.fragmentProfileEnabled = fragmentEnabled;
else if (type == PluginBase.PUMP)
this.fragmentPumpEnabled = fragmentEnabled;
// if pump profile was enabled need to switch to another too
if (type == PluginBase.PUMP && !fragmentEnabled && this.fragmentProfileEnabled) {
setFragmentEnabled(PluginBase.PROFILE, false);
setFragmentVisible(PluginBase.PROFILE, false);
MainApp.getSpecificPlugin(NSProfilePlugin.class).setFragmentEnabled(PluginBase.PROFILE, true);
MainApp.getSpecificPlugin(NSProfilePlugin.class).setFragmentVisible(PluginBase.PROFILE, true);
}
}
@Override
public void setFragmentVisible(int type, boolean fragmentVisible) {
if (type == PluginBase.PUMP)
this.fragmentPumpVisible = fragmentVisible;
}
@Override
public boolean isInitialized() {
return getDanaRPump().lastConnection.getTime() > 0 && !getDanaRPump().isConfigUD && !getDanaRPump().isEasyModeEnabled && getDanaRPump().isExtendedBolusEnabled;
}
// Pump interface
@Override
public boolean isTempBasalInProgress() {
if (getRealTempBasal() != null) return true;
if (getExtendedBolus() != null && useExtendedBoluses) return true;
return false;
}
public boolean isRealTempBasalInProgress() {
return getRealTempBasal() != null; //TODO: crosscheck here
}
@Override
public boolean isExtendedBoluslInProgress() {
return getExtendedBolus() != null; //TODO: crosscheck here
}
@Override
public int setNewBasalProfile(NSProfile profile) {
if (sExecutionService == null) {
log.error("setNewBasalProfile sExecutionService is null");
return FAILED;
}
if (!isInitialized()) {
log.error("setNewBasalProfile not initialized");
Notification notification = new Notification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED, MainApp.sResources.getString(R.string.pumpNotInitializedProfileNotSet), Notification.URGENT);
MainApp.bus().post(new EventNewNotification(notification));
return FAILED;
} else {
MainApp.bus().post(new EventDismissNotification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED));
}
if (!sExecutionService.updateBasalsInPump(profile)) {
Notification notification = new Notification(Notification.FAILED_UDPATE_PROFILE, MainApp.sResources.getString(R.string.failedupdatebasalprofile), Notification.URGENT);
MainApp.bus().post(new EventNewNotification(notification));
return FAILED;
} else {
MainApp.bus().post(new EventDismissNotification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED));
MainApp.bus().post(new EventDismissNotification(Notification.FAILED_UDPATE_PROFILE));
return SUCCESS;
}
}
@Override
public boolean isThisProfileSet(NSProfile profile) {
if (!isInitialized())
return true; // TODO: not sure what's better. so far TRUE to prevent too many SMS
DanaRKoreanPump pump = getDanaRPump();
int basalValues = pump.basal48Enable ? 48 : 24;
int basalIncrement = pump.basal48Enable ? 30 * 60 : 60 * 60;
for (int h = 0; h < basalValues; h++) {
Double pumpValue = pump.pumpProfiles[pump.activeProfile][h];
Double profileValue = profile.getBasal(h * basalIncrement);
if (Math.abs(pumpValue - profileValue) > getPumpDescription().basalStep) {
log.debug("Diff found. Hour: " + h + " Pump: " + pumpValue + " Profile: " + profileValue);
return false;
}
}
return true;
}
@Override
public double getBaseBasalRate() {
return getDanaRPump().currentBasal;
}
@Override
public double getTempBasalAbsoluteRate() {
if (isRealTempBasalInProgress()) {
if (getRealTempBasal().isAbsolute) {
return getRealTempBasal().absolute;
} else {
Double baseRate = getBaseBasalRate();
Double tempRate = baseRate * (getRealTempBasal().percent / 100d);
return tempRate;
}
}
if (isExtendedBoluslInProgress() && useExtendedBoluses) {
return getBaseBasalRate() + getExtendedBolus().absolute;
}
return 0;
}
@Override
public double getTempBasalRemainingMinutes() {
if (isRealTempBasalInProgress())
return getRealTempBasal().getPlannedRemainingMinutes();
if (isExtendedBoluslInProgress() && useExtendedBoluses)
return getExtendedBolus().getPlannedRemainingMinutes();
return 0;
}
@Override
public TempBasal getTempBasal() {
if (isRealTempBasalInProgress())
return getRealTempBasal();
if (isExtendedBoluslInProgress() && useExtendedBoluses)
return getExtendedBolus();
return null;
}
public TempBasal getTempBasal(Date time) {
TempBasal temp = MainApp.getConfigBuilder().getActiveTempBasals().getTempBasal(time);
if (temp != null) return temp;
if (useExtendedBoluses)
return MainApp.getConfigBuilder().getActiveTempBasals().getExtendedBolus(time);
return null;
}
public TempBasal getRealTempBasal() {
return MainApp.getConfigBuilder().getActiveTempBasals().getTempBasal(new Date());
}
@Override
public TempBasal getExtendedBolus() {
return MainApp.getConfigBuilder().getActiveTempBasals().getExtendedBolus(new Date());
}
@Override
public PumpEnactResult deliverTreatment(Double insulin, Integer carbs, Context context) {
ConfigBuilderPlugin configBuilderPlugin = MainApp.getConfigBuilder();
insulin = configBuilderPlugin.applyBolusConstraints(insulin);
if (insulin > 0 || carbs > 0) {
Treatment t = new Treatment();
boolean connectionOK = false;
if (insulin > 0 || carbs > 0) connectionOK = sExecutionService.bolus(insulin, carbs, t);
PumpEnactResult result = new PumpEnactResult();
result.success = connectionOK;
result.bolusDelivered = t.insulin;
result.carbsDelivered = carbs;
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
if (Config.logPumpActions)
log.debug("deliverTreatment: OK. Asked: " + insulin + " Delivered: " + result.bolusDelivered);
return result;
} else {
PumpEnactResult result = new PumpEnactResult();
result.success = false;
result.bolusDelivered = 0d;
result.carbsDelivered = 0;
result.comment = MainApp.instance().getString(R.string.danar_invalidinput);
log.error("deliverTreatment: Invalid input");
return result;
}
}
@Override
public void stopBolusDelivering() {
if (sExecutionService == null) {
log.error("stopBolusDelivering sExecutionService is null");
return;
}
sExecutionService.bolusStop();
}
// This is called from APS
@Override
public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes) {
// Recheck pump status if older than 30 min
if (getDanaRPump().lastConnection.getTime() + 30 * 60 * 1000L < new Date().getTime()) {
doConnect("setTempBasalAbsolute old data");
}
PumpEnactResult result = new PumpEnactResult();
ConfigBuilderPlugin configBuilderPlugin = MainApp.getConfigBuilder();
absoluteRate = configBuilderPlugin.applyBasalConstraints(absoluteRate);
final boolean doTempOff = getBaseBasalRate() - absoluteRate == 0d;
final boolean doLowTemp = absoluteRate < getBaseBasalRate();
final boolean doHighTemp = absoluteRate > getBaseBasalRate() && !useExtendedBoluses;
final boolean doExtendedTemp = absoluteRate > getBaseBasalRate() && useExtendedBoluses;
if (doTempOff) {
// If extended in progress
if (isExtendedBoluslInProgress() && useExtendedBoluses) {
if (Config.logPumpActions)
log.debug("setTempBasalAbsolute: Stopping extended bolus (doTempOff)");
return cancelExtendedBolus();
}
// If temp in progress
if (isRealTempBasalInProgress()) {
if (Config.logPumpActions)
log.debug("setTempBasalAbsolute: Stopping temp basal (doTempOff)");
return cancelRealTempBasal();
}
result.success = true;
result.enacted = false;
result.percent = 100;
result.isPercent = true;
result.isTempCancel = true;
if (Config.logPumpActions)
log.debug("setTempBasalAbsolute: doTempOff OK");
return result;
}
if (doLowTemp || doHighTemp) {
Integer percentRate = Double.valueOf(absoluteRate / getBaseBasalRate() * 100).intValue();
if (percentRate < 100) percentRate = Round.ceilTo((double) percentRate, 10d).intValue();
else percentRate = Round.floorTo((double) percentRate, 10d).intValue();
if (percentRate > 200) {
percentRate = 200;
}
// If extended in progress
if (isExtendedBoluslInProgress() && useExtendedBoluses) {
if (Config.logPumpActions)
log.debug("setTempBasalAbsolute: Stopping extended bolus (doLowTemp || doHighTemp)");
result = cancelExtendedBolus();
if (!result.success) {
log.error("setTempBasalAbsolute: Failed to stop previous extended bolus (doLowTemp || doHighTemp)");
return result;
}
}
// Check if some temp is already in progress
if (isRealTempBasalInProgress()) {
// Correct basal already set ?
if (getRealTempBasal().percent == percentRate) {
result.success = true;
result.percent = percentRate;
result.absolute = getTempBasalAbsoluteRate();
result.enacted = false;
result.duration = ((Double) getTempBasalRemainingMinutes()).intValue();
result.isPercent = true;
result.isTempCancel = false;
if (Config.logPumpActions)
log.debug("setTempBasalAbsolute: Correct temp basal already set (doLowTemp || doHighTemp)");
return result;
} else {
if (Config.logPumpActions)
log.debug("setTempBasalAbsolute: Stopping temp basal (doLowTemp || doHighTemp)");
result = cancelRealTempBasal();
// Check for proper result
if (!result.success) {
log.error("setTempBasalAbsolute: Failed to stop previous temp basal (doLowTemp || doHighTemp)");
return result;
}
}
}
// Convert duration from minutes to hours
if (Config.logPumpActions)
log.debug("setTempBasalAbsolute: Setting temp basal " + percentRate + "% for " + durationInMinutes + " mins (doLowTemp || doHighTemp)");
return setTempBasalPercent(percentRate, durationInMinutes);
}
if (doExtendedTemp) {
// Check if some temp is already in progress
if (isRealTempBasalInProgress()) {
if (Config.logPumpActions)
log.debug("setTempBasalAbsolute: Stopping temp basal (doExtendedTemp)");
result = cancelRealTempBasal();
// Check for proper result
if (!result.success) {
log.error("setTempBasalAbsolute: Failed to stop previous temp basal (doExtendedTemp)");
return result;
}
}
// Calculate # of halfHours from minutes
Integer durationInHalfHours = Math.max(durationInMinutes / 30, 1);
// We keep current basal running so need to sub current basal
Double extendedRateToSet = absoluteRate - getBaseBasalRate();
extendedRateToSet = configBuilderPlugin.applyBasalConstraints(extendedRateToSet);
// needs to be rounded to 0.1
extendedRateToSet = Round.roundTo(extendedRateToSet, 0.1d);
// What is current rate of extended bolusing in u/h?
if (Config.logPumpActions) {
log.debug("setTempBasalAbsolute: Extended bolus in progress: " + isExtendedBoluslInProgress() + " rate: " + getDanaRPump().extendedBolusAbsoluteRate + "U/h duration remaining: " + getDanaRPump().extendedBolusRemainingMinutes + "min");
log.debug("setTempBasalAbsolute: Rate to set: " + extendedRateToSet + "U/h");
}
// Compare with extended rate in progress
if (Math.abs(getDanaRPump().extendedBolusAbsoluteRate - extendedRateToSet) < 0.02D) { // Allow some rounding diff
// correct extended already set
result.success = true;
result.absolute = getDanaRPump().extendedBolusAbsoluteRate;
result.enacted = false;
result.duration = getDanaRPump().extendedBolusRemainingMinutes;
result.isPercent = false;
result.isTempCancel = false;
if (Config.logPumpActions)
log.debug("setTempBasalAbsolute: Correct extended already set");
return result;
}
// Now set new extended, no need to to stop previous (if running) because it's replaced
Double extendedAmount = extendedRateToSet / 2 * durationInHalfHours;
if (Config.logPumpActions)
log.debug("setTempBasalAbsolute: Setting extended: " + extendedAmount + "U halfhours: " + durationInHalfHours);
result = setExtendedBolus(extendedAmount, durationInMinutes);
if (!result.success) {
log.error("setTempBasalAbsolute: Failed to set extended bolus");
return result;
}
if (Config.logPumpActions)
log.debug("setTempBasalAbsolute: Extended bolus set ok");
result.absolute = result.absolute + getBaseBasalRate();
return result;
}
// We should never end here
log.error("setTempBasalAbsolute: Internal error");
result.success = false;
result.comment = "Internal error";
return result;
}
@Override
public PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes) {
PumpEnactResult result = new PumpEnactResult();
ConfigBuilderPlugin configBuilderPlugin = MainApp.getConfigBuilder();
percent = configBuilderPlugin.applyBasalConstraints(percent);
if (percent < 0) {
result.isTempCancel = false;
result.enacted = false;
result.success = false;
result.comment = MainApp.instance().getString(R.string.danar_invalidinput);
log.error("setTempBasalPercent: Invalid input");
return result;
}
if (percent > 200) percent = 200;
if (getDanaRPump().isTempBasalInProgress && getDanaRPump().tempBasalPercent == percent) {
result.enacted = false;
result.success = true;
result.isTempCancel = false;
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
result.duration = getDanaRPump().tempBasalRemainingMin;
result.percent = getDanaRPump().tempBasalPercent;
result.isPercent = true;
if (Config.logPumpActions)
log.debug("setTempBasalPercent: Correct value already set");
return result;
}
int durationInHours = Math.max(durationInMinutes / 60, 1);
boolean connectionOK = sExecutionService.tempBasal(percent, durationInHours);
if (connectionOK && getDanaRPump().isTempBasalInProgress && getDanaRPump().tempBasalPercent == percent) {
result.enacted = true;
result.success = true;
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
result.isTempCancel = false;
result.duration = getDanaRPump().tempBasalRemainingMin;
result.percent = getDanaRPump().tempBasalPercent;
result.isPercent = true;
if (Config.logPumpActions)
log.debug("setTempBasalPercent: OK");
return result;
}
result.enacted = false;
result.success = false;
result.comment = MainApp.instance().getString(R.string.danar_valuenotsetproperly);
log.error("setTempBasalPercent: Failed to set temp basal");
return result;
}
@Override
public PumpEnactResult setExtendedBolus(Double insulin, Integer durationInMinutes) {
ConfigBuilderPlugin configBuilderPlugin = MainApp.getConfigBuilder();
insulin = configBuilderPlugin.applyBolusConstraints(insulin);
// needs to be rounded to 0.1
insulin = Round.roundTo(insulin, 0.1d);
PumpEnactResult result = new PumpEnactResult();
if (getDanaRPump().isExtendedInProgress && Math.abs(getDanaRPump().extendedBolusAmount - insulin) < 0.1d) {
result.enacted = false;
result.success = true;
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
result.duration = getDanaRPump().extendedBolusRemainingMinutes;
result.absolute = getDanaRPump().extendedBolusAbsoluteRate;
result.isPercent = false;
result.isTempCancel = false;
if (Config.logPumpActions)
log.debug("setExtendedBolus: Correct extended bolus already set");
return result;
}
int durationInHalfHours = Math.max(durationInMinutes / 30, 1);
boolean connectionOK = sExecutionService.extendedBolus(insulin, durationInHalfHours);
if (connectionOK && getDanaRPump().isExtendedInProgress && Math.abs(getDanaRPump().extendedBolusAmount - insulin) < 0.1d) {
result.enacted = true;
result.success = true;
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
result.isTempCancel = false;
result.duration = getDanaRPump().extendedBolusRemainingMinutes;
result.absolute = getDanaRPump().extendedBolusAbsoluteRate;
result.bolusDelivered = getDanaRPump().extendedBolusAmount;
result.isPercent = false;
if (Config.logPumpActions)
log.debug("setExtendedBolus: OK");
return result;
}
result.enacted = false;
result.success = false;
result.comment = MainApp.instance().getString(R.string.danar_valuenotsetproperly);
log.error("setExtendedBolus: Failed to extended bolus");
return result;
}
@Override
public PumpEnactResult cancelTempBasal() {
if (isRealTempBasalInProgress())
return cancelRealTempBasal();
if (isExtendedBoluslInProgress())
return cancelExtendedBolus();
PumpEnactResult result = new PumpEnactResult();
result.success = true;
result.enacted = false;
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
result.isTempCancel = true;
return result;
}
public PumpEnactResult cancelRealTempBasal() {
PumpEnactResult result = new PumpEnactResult();
if (getDanaRPump().isTempBasalInProgress) {
sExecutionService.tempBasalStop();
result.enacted = true;
result.isTempCancel = true;
}
if (!getDanaRPump().isTempBasalInProgress) {
result.success = true;
result.isTempCancel = true;
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
if (Config.logPumpActions)
log.debug("cancelRealTempBasal: OK");
return result;
} else {
result.success = false;
result.comment = MainApp.instance().getString(R.string.danar_valuenotsetproperly);
result.isTempCancel = true;
log.error("cancelRealTempBasal: Failed to cancel temp basal");
return result;
}
}
@Override
public PumpEnactResult cancelExtendedBolus() {
PumpEnactResult result = new PumpEnactResult();
if (getDanaRPump().isExtendedInProgress) {
sExecutionService.extendedBolusStop();
result.enacted = true;
result.isTempCancel = true;
}
if (!getDanaRPump().isExtendedInProgress) {
result.success = true;
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
if (Config.logPumpActions)
log.debug("cancelExtendedBolus: OK");
return result;
} else {
result.success = false;
result.comment = MainApp.instance().getString(R.string.danar_valuenotsetproperly);
log.error("cancelExtendedBolus: Failed to cancel extended bolus");
return result;
}
}
public static void doConnect(String from) {
if (sExecutionService != null) sExecutionService.connect(from);
}
public static boolean isConnected() {
return sExecutionService != null && sExecutionService.isConnected();
}
public static boolean isConnecting() {
return sExecutionService != null && sExecutionService.isConnecting();
}
public static void doDisconnect(String from) {
if (sExecutionService != null) sExecutionService.disconnect(from);
}
@Override
public JSONObject getJSONStatus() {
if (getDanaRPump().lastConnection.getTime() + 5 * 60 * 1000L < new Date().getTime()) {
return null;
}
JSONObject pump = new JSONObject();
JSONObject battery = new JSONObject();
JSONObject status = new JSONObject();
JSONObject extended = new JSONObject();
try {
battery.put("percent", getDanaRPump().batteryRemaining);
status.put("status", "normal");
status.put("timestamp", DateUtil.toISOString(getDanaRPump().lastConnection));
extended.put("Version", BuildConfig.VERSION_NAME + "-" + BuildConfig.BUILDVERSION);
extended.put("PumpIOB", getDanaRPump().iob);
// extended.put("LastBolus", getDanaRPump().lastBolusTime.toLocaleString());
// extended.put("LastBolusAmount", getDanaRPump().lastBolusAmount);
if (isTempBasalInProgress()) {
extended.put("TempBasalAbsoluteRate", getTempBasalAbsoluteRate());
extended.put("TempBasalStart", getTempBasal().timeStart.toLocaleString());
extended.put("TempBasalRemaining", getTempBasal().getPlannedRemainingMinutes());
extended.put("IsExtended", getTempBasal().isExtended);
}
extended.put("BaseBasalRate", getBaseBasalRate());
try {
extended.put("ActiveProfile", MainApp.getConfigBuilder().getActiveProfile().getProfile().getActiveProfile());
} catch (Exception e) {
}
pump.put("battery", battery);
pump.put("status", status);
pump.put("extended", extended);
pump.put("reservoir", (int) getDanaRPump().reservoirRemainingUnits);
pump.put("clock", DateUtil.toISOString(new Date()));
} catch (JSONException e) {
e.printStackTrace();
}
return pump;
}
@Override
public String deviceID() {
return getDanaRPump().serialNumber;
}
@Override
public PumpDescription getPumpDescription() {
return pumpDescription;
}
/**
* Constraint interface
*/
@Override
public boolean isLoopEnabled() {
return true;
}
@Override
public boolean isClosedModeEnabled() {
return true;
}
@Override
public boolean isAutosensModeEnabled() {
return true;
}
@Override
public boolean isAMAModeEnabled() {
return true;
}
@SuppressWarnings("PointlessBooleanExpression")
@Override
public Double applyBasalConstraints(Double absoluteRate) {
double origAbsoluteRate = absoluteRate;
if (getDanaRPump() != null) {
if (absoluteRate > getDanaRPump().maxBasal) {
absoluteRate = getDanaRPump().maxBasal;
if (Config.logConstraintsChanges && origAbsoluteRate != Constants.basalAbsoluteOnlyForCheckLimit)
log.debug("Limiting rate " + origAbsoluteRate + "U/h by pump constraint to " + absoluteRate + "U/h");
}
}
return absoluteRate;
}
@SuppressWarnings("PointlessBooleanExpression")
@Override
public Integer applyBasalConstraints(Integer percentRate) {
Integer origPercentRate = percentRate;
if (percentRate < 0) percentRate = 0;
if (percentRate > 200) percentRate = 200;
if (!Objects.equals(percentRate, origPercentRate) && Config.logConstraintsChanges && !Objects.equals(origPercentRate, Constants.basalPercentOnlyForCheckLimit))
log.debug("Limiting percent rate " + origPercentRate + "% to " + percentRate + "%");
return percentRate;
}
@SuppressWarnings("PointlessBooleanExpression")
@Override
public Double applyBolusConstraints(Double insulin) {
double origInsulin = insulin;
if (getDanaRPump() != null) {
if (insulin > getDanaRPump().maxBolus) {
insulin = getDanaRPump().maxBolus;
if (Config.logConstraintsChanges && origInsulin != Constants.bolusOnlyForCheckLimit)
log.debug("Limiting bolus " + origInsulin + "U by pump constraint to " + insulin + "U");
}
}
return insulin;
}
@Override
public Integer applyCarbsConstraints(Integer carbs) {
return carbs;
}
@Override
public Double applyMaxIOBConstraints(Double maxIob) {
return maxIob;
}
@Nullable
@Override
public NSProfile getProfile() {
DanaRKoreanPump pump = getDanaRPump();
if (pump.lastSettingsRead.getTime() == 0)
return null; // no info now
return pump.createConvertedProfile();
}
// Reply for sms communicator
public String shortStatus() {
String ret = "";
if (getDanaRPump().lastConnection.getTime() != 0) {
Long agoMsec = new Date().getTime() - getDanaRPump().lastConnection.getTime();
int agoMin = (int) (agoMsec / 60d / 1000d);
ret += "LastConn: " + agoMin + " minago\n";
}
// if (getDanaRPump().lastBolusTime.getTime() != 0) {
// ret += "LastBolus: " + DecimalFormatter.to2Decimal(getDanaRPump().lastBolusAmount) + "U @" + android.text.format.DateFormat.format("HH:mm", getDanaRPump().lastBolusTime) + "\n";
// }
if (isRealTempBasalInProgress()) {
ret += "Temp: " + getRealTempBasal().toString() + "\n";
}
if (isExtendedBoluslInProgress()) {
ret += "Extended: " + getExtendedBolus().toString() + "\n";
}
ret += "IOB: " + getDanaRPump().iob + "U\n";
ret += "Reserv: " + DecimalFormatter.to0Decimal(getDanaRPump().reservoirRemainingUnits) + "U\n";
ret += "Batt: " + getDanaRPump().batteryRemaining + "\n";
return ret;
}
// TODO: daily total constraint
}

View file

@ -0,0 +1,172 @@
package info.nightscout.androidaps.plugins.DanaRKorean;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.text.DecimalFormat;
import java.util.Date;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp;
import info.nightscout.client.data.NSProfile;
import info.nightscout.utils.SafeParse;
/**
* Created by mike on 04.07.2016.
*/
public class DanaRKoreanPump {
public static final int UNITS_MGDL = 0;
public static final int UNITS_MMOL = 1;
public static final int DELIVERY_PRIME = 0x01;
public static final int DELIVERY_STEP_BOLUS = 0x02;
public static final int DELIVERY_BASAL = 0x04;
public static final int DELIVERY_EXT_BOLUS = 0x08;
public static final String PROFILE_PREFIX = "DanaR-";
public Date lastConnection = new Date(0);
public Date lastSettingsRead = new Date(0);
// Info
public String serialNumber = "";
public Date shippingDate = new Date(0);
public String shippingCountry = "";
public boolean isNewPump = false;
public int password = -1;
public Date pumpTime = new Date(0);
public static final int DOMESTIC_MODEL = 0x01;
public static final int EXPORT_MODEL = 0x03;
public int model;
public int protocol;
public int productCode;
public boolean isConfigUD;
public boolean isExtendedBolusEnabled;
public boolean isEasyModeEnabled;
// Status
public double dailyTotalUnits;
public int maxDailyTotalUnits;
public double bolusStep;
public double basalStep;
public double iob;
public double reservoirRemainingUnits;
public int batteryRemaining;
public double currentBasal;
public boolean isTempBasalInProgress;
public int tempBasalPercent;
public int tempBasalRemainingMin;
public int tempBasalTotalSec;
public Date tempBasalStart;
public boolean isExtendedInProgress;
public int extendedBolusMinutes;
public double extendedBolusAmount;
public double extendedBolusAbsoluteRate;
public int extendedBolusSoFarInMinutes;
public Date extendedBolusStart;
public int extendedBolusRemainingMinutes;
// Profile
public int units;
public int easyBasalMode;
public boolean basal48Enable = false;
public int currentCIR;
public double currentCF;
public double currentAI;
public double currentTarget;
public int currentAIDR;
public int morningCIR;
public double morningCF;
public int afternoonCIR;
public double afternoonCF;
public int eveningCIR;
public double eveningCF;
public int nightCIR;
public double nightCF;
public int activeProfile = 0;
public double[][] pumpProfiles = null;
//Limits
public double maxBolus;
public double maxBasal;
public NSProfile createConvertedProfile() {
JSONObject json = new JSONObject();
JSONObject store = new JSONObject();
JSONObject profile = new JSONObject();
// Morning / 6:0010:59
// Afternoon / 11:0016:59
// Evening / 17:0021:59
// Night / 22:005:59
SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext());
double dia = SafeParse.stringToDouble(SP.getString("danarprofile_dia", "3"));
double car = SafeParse.stringToDouble(SP.getString("danarprofile_car", "20"));
try {
json.put("defaultProfile", PROFILE_PREFIX + (activeProfile + 1));
json.put("store", store);
profile.put("dia", dia);
JSONArray carbratios = new JSONArray();
carbratios.put(new JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", nightCIR));
carbratios.put(new JSONObject().put("time", "06:00").put("timeAsSeconds", 6 * 3600).put("value", morningCIR));
carbratios.put(new JSONObject().put("time", "11:00").put("timeAsSeconds", 11 * 3600).put("value", afternoonCIR));
carbratios.put(new JSONObject().put("time", "14:00").put("timeAsSeconds", 17 * 3600).put("value", eveningCIR));
carbratios.put(new JSONObject().put("time", "22:00").put("timeAsSeconds", 22 * 3600).put("value", nightCIR));
profile.put("carbratio", carbratios);
profile.put("carbs_hr", car);
JSONArray sens = new JSONArray();
sens.put(new JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", nightCF));
sens.put(new JSONObject().put("time", "06:00").put("timeAsSeconds", 6 * 3600).put("value", morningCF));
sens.put(new JSONObject().put("time", "11:00").put("timeAsSeconds", 11 * 3600).put("value", afternoonCF));
sens.put(new JSONObject().put("time", "17:00").put("timeAsSeconds", 17 * 3600).put("value", eveningCF));
sens.put(new JSONObject().put("time", "22:00").put("timeAsSeconds", 22 * 3600).put("value", nightCF));
profile.put("sens", sens);
JSONArray basals = new JSONArray();
int basalValues = basal48Enable ? 48 : 24;
int basalIncrement = basal48Enable ? 30 * 60 : 60 * 60;
for (int h = 0; h < basalValues; h++) {
String time;
DecimalFormat df = new DecimalFormat("00");
if (basal48Enable) {
time = df.format((long) h / 2) + ":" + df.format(30 * (h % 2));
} else {
time = df.format(h) + ":00";
}
basals.put(new JSONObject().put("time", time).put("timeAsSeconds", h * basalIncrement).put("value", pumpProfiles[activeProfile][h]));
}
profile.put("basal", basals);
profile.put("target_low", new JSONArray().put(new JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", currentTarget)));
profile.put("target_high", new JSONArray().put(new JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", currentTarget)));
profile.put("units", units == UNITS_MGDL ? Constants.MGDL : Constants.MMOL);
store.put(PROFILE_PREFIX + (activeProfile + 1), profile);
} catch (JSONException e) {
e.printStackTrace();
} catch (Exception e) {
return null;
}
return new NSProfile(json, PROFILE_PREFIX + (activeProfile + 1));
}
}

View file

@ -0,0 +1,460 @@
package info.nightscout.androidaps.plugins.DanaRKorean.History;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.support.v7.widget.CardView;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.TextView;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.stmt.PreparedQuery;
import com.j256.ormlite.stmt.QueryBuilder;
import com.j256.ormlite.stmt.Where;
import com.squareup.otto.Subscribe;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.SQLException;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.db.DanaRHistoryRecord;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.DanaR.History.DanaRNSHistorySync;
import info.nightscout.androidaps.plugins.DanaR.comm.RecordTypes;
import info.nightscout.androidaps.plugins.DanaR.events.EventDanaRConnectionStatus;
import info.nightscout.androidaps.plugins.DanaR.events.EventDanaRSyncStatus;
import info.nightscout.androidaps.plugins.DanaRKorean.Services.ExecutionService;
import info.nightscout.client.data.NSProfile;
import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.ToastUtils;
public class DanaRHistoryActivity extends Activity {
private static Logger log = LoggerFactory.getLogger(DanaRHistoryActivity.class);
private boolean mBounded;
private static ExecutionService mExecutionService;
private Handler mHandler;
private static HandlerThread mHandlerThread;
static NSProfile profile = null;
Spinner historyTypeSpinner;
TextView statusView;
Button reloadButton;
Button syncButton;
RecyclerView recyclerView;
LinearLayoutManager llm;
static byte showingType = RecordTypes.RECORD_TYPE_ALARM;
List<DanaRHistoryRecord> historyList = new ArrayList<>();
public static class TypeList {
public byte type;
String name;
public TypeList(byte type, String name) {
this.type = type;
this.name = name;
}
@Override
public String toString() {
return name;
}
}
public DanaRHistoryActivity() {
super();
mHandlerThread = new HandlerThread(DanaRHistoryActivity.class.getSimpleName());
mHandlerThread.start();
this.mHandler = new Handler(mHandlerThread.getLooper());
}
@Override
public void onStart() {
super.onStart();
Intent intent = new Intent(this, ExecutionService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
@Override
protected void onResume() {
super.onResume();
MainApp.bus().register(this);
}
@Override
protected void onPause() {
super.onPause();
MainApp.bus().unregister(this);
}
@Override
public void onStop() {
super.onStop();
if (mBounded) {
unbindService(mConnection);
mBounded = false;
}
}
ServiceConnection mConnection = new ServiceConnection() {
public void onServiceDisconnected(ComponentName name) {
log.debug("Service is disconnected");
mBounded = false;
mExecutionService = null;
}
public void onServiceConnected(ComponentName name, IBinder service) {
log.debug("Service is connected");
mBounded = true;
ExecutionService.LocalBinder mLocalBinder = (ExecutionService.LocalBinder) service;
mExecutionService = mLocalBinder.getServiceInstance();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.danar_historyactivity);
historyTypeSpinner = (Spinner) findViewById(R.id.danar_historytype);
statusView = (TextView) findViewById(R.id.danar_historystatus);
reloadButton = (Button) findViewById(R.id.danar_historyreload);
syncButton = (Button) findViewById(R.id.danar_historysync);
recyclerView = (RecyclerView) findViewById(R.id.danar_history_recyclerview);
recyclerView.setHasFixedSize(true);
llm = new LinearLayoutManager(this);
recyclerView.setLayoutManager(llm);
RecyclerViewAdapter adapter = new RecyclerViewAdapter(historyList);
recyclerView.setAdapter(adapter);
statusView.setVisibility(View.GONE);
// Types
ArrayList<TypeList> typeList = new ArrayList<>();
typeList.add(new TypeList(RecordTypes.RECORD_TYPE_ALARM, getString(R.string.danar_history_alarm)));
typeList.add(new TypeList(RecordTypes.RECORD_TYPE_BASALHOUR, getString(R.string.danar_history_basalhours)));
typeList.add(new TypeList(RecordTypes.RECORD_TYPE_BOLUS, getString(R.string.danar_history_bolus)));
typeList.add(new TypeList(RecordTypes.RECORD_TYPE_CARBO, getString(R.string.danar_history_carbohydrates)));
typeList.add(new TypeList(RecordTypes.RECORD_TYPE_DAILY, getString(R.string.danar_history_dailyinsulin)));
typeList.add(new TypeList(RecordTypes.RECORD_TYPE_GLUCOSE, getString(R.string.danar_history_glucose)));
ArrayAdapter<TypeList> spinnerAdapter = new ArrayAdapter<>(this,
android.R.layout.simple_spinner_item, typeList);
spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
historyTypeSpinner.setAdapter(spinnerAdapter);
reloadButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mExecutionService.isConnected() || mExecutionService.isConnecting()) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), getString(R.string.pumpbusy));
return;
}
mHandler.post(new Runnable() {
@Override
public void run() {
TypeList selected = (TypeList) historyTypeSpinner.getSelectedItem();
runOnUiThread(new Runnable() {
@Override
public void run() {
reloadButton.setVisibility(View.GONE);
syncButton.setVisibility(View.GONE);
statusView.setVisibility(View.VISIBLE);
}
});
clearCardView();
mExecutionService.loadHistory(selected.type);
loadDataFromDB(selected.type);
runOnUiThread(new Runnable() {
@Override
public void run() {
reloadButton.setVisibility(View.VISIBLE);
syncButton.setVisibility(View.VISIBLE);
statusView.setVisibility(View.GONE);
}
});
}
});
}
});
syncButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mHandler.post(new Runnable() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
reloadButton.setVisibility(View.GONE);
syncButton.setVisibility(View.GONE);
statusView.setVisibility(View.VISIBLE);
}
});
DanaRNSHistorySync sync = new DanaRNSHistorySync(historyList);
sync.sync(DanaRNSHistorySync.SYNC_ALL);
runOnUiThread(new Runnable() {
@Override
public void run() {
reloadButton.setVisibility(View.VISIBLE);
syncButton.setVisibility(View.VISIBLE);
statusView.setVisibility(View.GONE);
}
});
}
});
}
});
historyTypeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
TypeList selected = (TypeList) historyTypeSpinner.getSelectedItem();
loadDataFromDB(selected.type);
showingType = selected.type;
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
clearCardView();
}
});
profile = ConfigBuilderPlugin.getActiveProfile().getProfile();
if (profile == null) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.noprofile));
finish();
}
}
public static class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.HistoryViewHolder> {
List<DanaRHistoryRecord> historyList;
RecyclerViewAdapter(List<DanaRHistoryRecord> historyList) {
this.historyList = historyList;
}
@Override
public HistoryViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.danar_history_item, viewGroup, false);
return new HistoryViewHolder(v);
}
@Override
public void onBindViewHolder(HistoryViewHolder holder, int position) {
DateFormat df = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
DanaRHistoryRecord record = historyList.get(position);
holder.time.setText(df.format(new Date(record.getRecordDate())));
holder.value.setText(DecimalFormatter.to2Decimal(record.getRecordValue()));
holder.stringvalue.setText(record.getStringRecordValue());
holder.bolustype.setText(record.getBolusType());
holder.duration.setText(DecimalFormatter.to0Decimal(record.getRecordDuration()));
holder.alarm.setText(record.getRecordAlarm());
switch (showingType) {
case RecordTypes.RECORD_TYPE_ALARM:
holder.time.setVisibility(View.VISIBLE);
holder.value.setVisibility(View.VISIBLE);
holder.stringvalue.setVisibility(View.GONE);
holder.bolustype.setVisibility(View.GONE);
holder.duration.setVisibility(View.GONE);
holder.dailybasal.setVisibility(View.GONE);
holder.dailybolus.setVisibility(View.GONE);
holder.dailytotal.setVisibility(View.GONE);
holder.alarm.setVisibility(View.VISIBLE);
break;
case RecordTypes.RECORD_TYPE_BOLUS:
holder.time.setVisibility(View.VISIBLE);
holder.value.setVisibility(View.VISIBLE);
holder.stringvalue.setVisibility(View.GONE);
holder.bolustype.setVisibility(View.VISIBLE);
holder.duration.setVisibility(View.VISIBLE);
holder.dailybasal.setVisibility(View.GONE);
holder.dailybolus.setVisibility(View.GONE);
holder.dailytotal.setVisibility(View.GONE);
holder.alarm.setVisibility(View.GONE);
break;
case RecordTypes.RECORD_TYPE_DAILY:
df = DateFormat.getDateInstance(DateFormat.SHORT);
holder.dailybasal.setText(DecimalFormatter.to2Decimal(record.getRecordDailyBasal()) + "U");
holder.dailybolus.setText(DecimalFormatter.to2Decimal(record.getRecordDailyBolus()) + "U");
holder.dailytotal.setText(DecimalFormatter.to2Decimal(record.getRecordDailyBolus()+ record.getRecordDailyBasal()) + "U");
holder.time.setText(df.format(new Date(record.getRecordDate())));
holder.time.setVisibility(View.VISIBLE);
holder.value.setVisibility(View.GONE);
holder.stringvalue.setVisibility(View.GONE);
holder.bolustype.setVisibility(View.GONE);
holder.duration.setVisibility(View.GONE);
holder.dailybasal.setVisibility(View.VISIBLE);
holder.dailybolus.setVisibility(View.VISIBLE);
holder.dailytotal.setVisibility(View.VISIBLE);
holder.alarm.setVisibility(View.GONE);
break;
case RecordTypes.RECORD_TYPE_GLUCOSE:
holder.value.setText(NSProfile.toUnitsString(record.getRecordValue(), record.getRecordValue() * Constants.MGDL_TO_MMOLL, profile.getUnits()));
// rest is the same
case RecordTypes.RECORD_TYPE_CARBO:
case RecordTypes.RECORD_TYPE_BASALHOUR:
case RecordTypes.RECORD_TYPE_ERROR:
case RecordTypes.RECORD_TYPE_PRIME:
case RecordTypes.RECORD_TYPE_REFILL:
case RecordTypes.RECORD_TYPE_TB:
holder.time.setVisibility(View.VISIBLE);
holder.value.setVisibility(View.VISIBLE);
holder.stringvalue.setVisibility(View.GONE);
holder.bolustype.setVisibility(View.GONE);
holder.duration.setVisibility(View.GONE);
holder.dailybasal.setVisibility(View.GONE);
holder.dailybolus.setVisibility(View.GONE);
holder.dailytotal.setVisibility(View.GONE);
holder.alarm.setVisibility(View.GONE);
break;
case RecordTypes.RECORD_TYPE_SUSPEND:
holder.time.setVisibility(View.VISIBLE);
holder.value.setVisibility(View.GONE);
holder.stringvalue.setVisibility(View.VISIBLE);
holder.bolustype.setVisibility(View.GONE);
holder.duration.setVisibility(View.GONE);
holder.dailybasal.setVisibility(View.GONE);
holder.dailybolus.setVisibility(View.GONE);
holder.dailytotal.setVisibility(View.GONE);
holder.alarm.setVisibility(View.GONE);
break;
}
}
@Override
public int getItemCount() {
return historyList.size();
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
public static class HistoryViewHolder extends RecyclerView.ViewHolder {
CardView cv;
TextView time;
TextView value;
TextView bolustype;
TextView stringvalue;
TextView duration;
TextView dailybasal;
TextView dailybolus;
TextView dailytotal;
TextView alarm;
HistoryViewHolder(View itemView) {
super(itemView);
cv = (CardView) itemView.findViewById(R.id.danar_history_cardview);
time = (TextView) itemView.findViewById(R.id.danar_history_time);
value = (TextView) itemView.findViewById(R.id.danar_history_value);
bolustype = (TextView) itemView.findViewById(R.id.danar_history_bolustype);
stringvalue = (TextView) itemView.findViewById(R.id.danar_history_stringvalue);
duration = (TextView) itemView.findViewById(R.id.danar_history_duration);
dailybasal = (TextView) itemView.findViewById(R.id.danar_history_dailybasal);
dailybolus = (TextView) itemView.findViewById(R.id.danar_history_dailybolus);
dailytotal = (TextView) itemView.findViewById(R.id.danar_history_dailytotal);
alarm = (TextView) itemView.findViewById(R.id.danar_history_alarm);
}
}
}
private void loadDataFromDB(byte type) {
try {
Dao<DanaRHistoryRecord, String> dao = MainApp.getDbHelper().getDaoDanaRHistory();
QueryBuilder<DanaRHistoryRecord, String> queryBuilder = dao.queryBuilder();
queryBuilder.orderBy("recordDate", false);
Where where = queryBuilder.where();
where.eq("recordCode", type);
queryBuilder.limit(200L);
PreparedQuery<DanaRHistoryRecord> preparedQuery = queryBuilder.prepare();
historyList = dao.query(preparedQuery);
} catch (SQLException e) {
e.printStackTrace();
historyList = new ArrayList<>();
}
runOnUiThread(new Runnable() {
@Override
public void run() {
recyclerView.swapAdapter(new RecyclerViewAdapter(historyList), false);
}
});
}
private void clearCardView() {
historyList = new ArrayList<>();
runOnUiThread(new Runnable() {
@Override
public void run() {
recyclerView.swapAdapter(new RecyclerViewAdapter(historyList), false);
}
});
}
@Subscribe
public void onStatusEvent(final EventDanaRSyncStatus s) {
log.debug("EventDanaRSyncStatus: " + s.message);
runOnUiThread(
new Runnable() {
@Override
public void run() {
statusView.setText(s.message);
}
});
}
@Subscribe
public void onStatusEvent(final EventDanaRConnectionStatus c) {
runOnUiThread(
new Runnable() {
@Override
public void run() {
if (c.sStatus == EventDanaRConnectionStatus.CONNECTING) {
statusView.setText(String.format(getString(R.string.danar_history_connectingfor), c.sSecondsElapsed));
log.debug("EventDanaRConnectionStatus: " + "Connecting for " + c.sSecondsElapsed + "s");
} else if (c.sStatus == EventDanaRConnectionStatus.CONNECTED) {
statusView.setText(MainApp.sResources.getString(R.string.connected));
log.debug("EventDanaRConnectionStatus: Connected");
} else {
statusView.setText(MainApp.sResources.getString(R.string.disconnected));
log.debug("EventDanaRConnectionStatus: Disconnected");
}
}
}
);
}
}

View file

@ -0,0 +1,224 @@
package info.nightscout.androidaps.plugins.DanaRKorean;
import android.bluetooth.BluetoothSocket;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.plugins.DanaR.comm.MessageBase;
import info.nightscout.androidaps.plugins.DanaRKorean.comm.MessageHashTable;
import info.nightscout.utils.CRC;
/**
* Created by mike on 17.07.2016.
*/
public class SerialIOThread extends Thread {
private static Logger log = LoggerFactory.getLogger(SerialIOThread.class);
private InputStream mInputStream = null;
private OutputStream mOutputStream = null;
private BluetoothSocket mRfCommSocket;
private static final ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor();
private static ScheduledFuture<?> scheduledDisconnection = null;
private boolean mKeepRunning = true;
private byte[] mReadBuff = new byte[0];
MessageBase processedMessage;
public SerialIOThread(BluetoothSocket rfcommSocket) {
super(SerialIOThread.class.toString());
mRfCommSocket = rfcommSocket;
try {
mOutputStream = mRfCommSocket.getOutputStream();
mInputStream = mRfCommSocket.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
this.start();
}
@Override
public final void run() {
try {
while (mKeepRunning) {
int availableBytes = mInputStream.available();
// Ask for 1024 byte (or more if available)
byte[] newData = new byte[Math.max(1024, availableBytes)];
int gotBytes = mInputStream.read(newData);
// When we are here there is some new data available
appendToBuffer(newData, gotBytes);
// process all messages we already got
while (mReadBuff.length > 3) { // 3rd byte is packet size. continue only if we an determine packet size
byte[] extractedBuff = cutMessageFromBuffer();
if (extractedBuff == null) break; // message is not complete in buffer (wrong packet calls disconnection)
int command = (extractedBuff[5] & 0xFF) | ((extractedBuff[4] << 8) & 0xFF00);
MessageBase message;
if (processedMessage != null && processedMessage.getCommand() == command) {
message = processedMessage;
} else {
// get it from hash table
message = MessageHashTable.findMessage(command);
}
if (Config.logDanaMessageDetail)
log.debug("<<<<< " + message.getMessageName() + " " + message.toHexString(extractedBuff));
// process the message content
message.received = true;
message.handleMessage(extractedBuff);
synchronized (message) {
message.notify();
}
scheduleDisconnection();
}
}
} catch (Exception e) {
if (Config.logDanaSerialEngine && e.getMessage().indexOf("bt socket closed") < 0)
log.error("Thread exception: ", e);
mKeepRunning = false;
}
disconnect("EndOfLoop");
}
void appendToBuffer(byte[] newData, int gotBytes) {
// add newData to mReadBuff
byte[] newReadBuff = new byte[mReadBuff.length + gotBytes];
System.arraycopy(mReadBuff, 0, newReadBuff, 0, mReadBuff.length);
System.arraycopy(newData, 0, newReadBuff, mReadBuff.length, gotBytes);
mReadBuff = newReadBuff;
}
byte[] cutMessageFromBuffer() {
if (mReadBuff[0] == (byte) 0x7E && mReadBuff[1] == (byte) 0x7E) {
int length = (mReadBuff[2] & 0xFF) + 7;
// Check if we have enough data
if (mReadBuff.length < length) {
return null;
}
if (mReadBuff[length - 2] != (byte) 0x2E || mReadBuff[length - 1] != (byte) 0x2E) {
log.error("wrong packet lenght=" + length + " data " + MessageBase.toHexString(mReadBuff));
disconnect("wrong packet");
return null;
}
short crc = CRC.getCrc16(mReadBuff, 3, length - 7);
byte crcByte0 = (byte) (crc >> 8 & 0xFF);
byte crcByte1 = (byte) (crc & 0xFF);
byte crcByte0received = mReadBuff[length - 4];
byte crcByte1received = mReadBuff[length - 3];
if (crcByte0 != crcByte0received || crcByte1 != crcByte1received) {
log.error("CRC Error" + String.format("%02x ", crcByte0) + String.format("%02x ", crcByte1) + String.format("%02x ", crcByte0received) + String.format("%02x ", crcByte1received));
disconnect("crc error");
return null;
}
// Packet is verified here. extract data
byte[] extractedBuff = new byte[length];
System.arraycopy(mReadBuff, 0, extractedBuff, 0, length);
// remove extracted data from read buffer
byte[] unprocessedData = new byte[mReadBuff.length - length];
System.arraycopy(mReadBuff, length, unprocessedData, 0, unprocessedData.length);
mReadBuff = unprocessedData;
return extractedBuff;
} else {
log.error("Wrong beginning of packet len=" + mReadBuff.length + " " + MessageBase.toHexString(mReadBuff));
disconnect("Wrong beginning of packet");
return null;
}
}
public synchronized void sendMessage(MessageBase message) {
if (!mRfCommSocket.isConnected()) {
log.error("Socket not connected on sendMessage");
return;
}
processedMessage = message;
byte[] messageBytes = message.getRawMessageBytes();
if (Config.logDanaSerialEngine)
log.debug(">>>>> " + message.getMessageName() + " " + message.toHexString(messageBytes));
try {
mOutputStream.write(messageBytes);
} catch (Exception e) {
log.error("sendMessage write exception: ", e);
e.printStackTrace();
}
synchronized (message) {
try {
message.wait(5000);
} catch (InterruptedException e) {
log.error("sendMessage InterruptedException", e);
e.printStackTrace();
}
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
if (!message.received) {
log.warn("Reply not received " + message.getMessageName());
}
scheduleDisconnection();
}
public void scheduleDisconnection() {
class DisconnectRunnable implements Runnable {
public void run() {
disconnect("scheduleDisconnection");
scheduledDisconnection = null;
}
}
// prepare task for execution in 5 sec
// cancel waiting task to prevent sending multiple disconnections
if (scheduledDisconnection != null)
scheduledDisconnection.cancel(false);
Runnable task = new DisconnectRunnable();
final int sec = 5;
scheduledDisconnection = worker.schedule(task, sec, TimeUnit.SECONDS);
}
public void disconnect(String reason) {
mKeepRunning = false;
try {
mInputStream.close();
} catch (Exception e) {
if (Config.logDanaSerialEngine) log.debug(e.getMessage());
}
try {
mOutputStream.close();
} catch (Exception e) {
if (Config.logDanaSerialEngine) log.debug(e.getMessage());
}
try {
mRfCommSocket.close();
} catch (Exception e) {
if (Config.logDanaSerialEngine) log.debug(e.getMessage());
}
try {
System.runFinalization();
} catch (Exception e) {
if (Config.logDanaSerialEngine) log.debug(e.getMessage());
}
if (Config.logDanaSerialEngine) log.debug("Disconnected: " + reason);
}
}

View file

@ -0,0 +1,491 @@
package info.nightscout.androidaps.plugins.DanaRKorean.Services;
import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Binder;
import android.os.IBinder;
import android.os.PowerManager;
import android.preference.PreferenceManager;
import com.squareup.otto.Subscribe;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.Set;
import java.util.UUID;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.events.EventAppExit;
import info.nightscout.androidaps.events.EventInitializationChanged;
import info.nightscout.androidaps.events.EventPreferenceChange;
import info.nightscout.androidaps.plugins.DanaR.comm.MessageBase;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgBolusProgress;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgBolusStart;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgBolusStop;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgHistoryAlarm;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgHistoryBasalHour;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgHistoryBolus;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgHistoryCarbo;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgHistoryDailyInsulin;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgHistoryDone;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgHistoryError;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgHistoryGlucose;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgHistoryRefill;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgHistorySuspend;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgPCCommStart;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgPCCommStop;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgSetCarbsEntry;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgSetExtendedBolusStart;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgSetExtendedBolusStop;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgSetSingleBasalProfile;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgSetTempBasalStart;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgSetTempBasalStop;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgSetTime;
import info.nightscout.androidaps.plugins.DanaR.comm.RecordTypes;
import info.nightscout.androidaps.plugins.DanaR.events.EventDanaRBolusStart;
import info.nightscout.androidaps.plugins.DanaR.events.EventDanaRConnectionStatus;
import info.nightscout.androidaps.plugins.DanaR.events.EventDanaRNewStatus;
import info.nightscout.androidaps.plugins.DanaRKorean.DanaRKoreanPlugin;
import info.nightscout.androidaps.plugins.DanaRKorean.DanaRKoreanPump;
import info.nightscout.androidaps.plugins.DanaRKorean.SerialIOThread;
import info.nightscout.androidaps.plugins.DanaRKorean.comm.MsgCheckValue;
import info.nightscout.androidaps.plugins.DanaRKorean.comm.MsgSettingBasal;
import info.nightscout.androidaps.plugins.DanaRKorean.comm.MsgSettingGlucose;
import info.nightscout.androidaps.plugins.DanaRKorean.comm.MsgSettingMaxValues;
import info.nightscout.androidaps.plugins.DanaRKorean.comm.MsgSettingMeal;
import info.nightscout.androidaps.plugins.DanaRKorean.comm.MsgSettingProfileRatios;
import info.nightscout.androidaps.plugins.DanaRKorean.comm.MsgSettingPumpTime;
import info.nightscout.androidaps.plugins.DanaRKorean.comm.MsgSettingShippingInfo;
import info.nightscout.androidaps.plugins.DanaRKorean.comm.MsgStatusBasic;
import info.nightscout.androidaps.plugins.DanaRKorean.comm.MsgStatusBolusExtended;
import info.nightscout.androidaps.plugins.DanaRKorean.comm.MsgStatusTempBasal;
import info.nightscout.client.data.NSProfile;
import info.nightscout.utils.SafeParse;
import info.nightscout.utils.ToastUtils;
public class ExecutionService extends Service {
private static Logger log = LoggerFactory.getLogger(ExecutionService.class);
private SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext());
private String devName;
private SerialIOThread mSerialIOThread;
private BluetoothSocket mRfcommSocket;
private BluetoothDevice mBTDevice;
private PowerManager.WakeLock mWakeLock;
private IBinder mBinder = new LocalBinder();
private DanaRKoreanPump danaRKoreanPump;
private Treatment bolusingTreatment = null;
private static Boolean connectionInProgress = false;
private static final Object connectionLock = new Object();
private static final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
private BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String action = intent.getAction();
if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {
log.debug("Device has disconnected " + device.getName());//Device has disconnected
if (mBTDevice != null && mBTDevice.getName().equals(device.getName())) {
if (mSerialIOThread != null) {
mSerialIOThread.disconnect("BT disconnection broadcast");
}
MainApp.bus().post(new EventDanaRConnectionStatus(EventDanaRConnectionStatus.DISCONNECTED, 0));
}
}
}
};
public ExecutionService() {
registerBus();
MainApp.instance().getApplicationContext().registerReceiver(receiver, new IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECTED));
danaRKoreanPump = DanaRKoreanPlugin.getDanaRPump();
PowerManager powerManager = (PowerManager) MainApp.instance().getApplicationContext().getSystemService(Context.POWER_SERVICE);
mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ExecutionService");
}
public class LocalBinder extends Binder {
public ExecutionService getServiceInstance() {
return ExecutionService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
private void registerBus() {
try {
MainApp.bus().unregister(this);
} catch (RuntimeException x) {
// Ignore
}
MainApp.bus().register(this);
}
@Subscribe
public void onStatusEvent(EventAppExit event) {
if (Config.logFunctionCalls)
log.debug("EventAppExit received");
if (mSerialIOThread != null)
mSerialIOThread.disconnect("Application exit");
MainApp.instance().getApplicationContext().unregisterReceiver(receiver);
stopSelf();
if (Config.logFunctionCalls)
log.debug("EventAppExit finished");
}
public boolean isConnected() {
return mRfcommSocket != null && mRfcommSocket.isConnected();
}
public boolean isConnecting() {
return connectionInProgress;
}
public void disconnect(String from) {
if (mSerialIOThread != null)
mSerialIOThread.disconnect(from);
}
public void connect(String from) {
if (danaRKoreanPump.password != -1 && danaRKoreanPump.password != SafeParse.stringToInt(SP.getString("danar_password", "-1"))) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.wrongpumppassword), R.raw.error);
return;
}
while (isConnected() || isConnecting()) {
if (Config.logDanaBTComm)
log.debug("already connected/connecting from: " + from);
waitMsec(3000);
}
final long maxConnectionTime = 5 * 60 * 1000L; // 5 min
synchronized (connectionLock) {
//log.debug("entering connection while loop");
connectionInProgress = true;
mWakeLock.acquire();
getBTSocketForSelectedPump();
if (mRfcommSocket == null || mBTDevice == null)
return; // Device not found
long startTime = new Date().getTime();
while (!isConnected() && startTime + maxConnectionTime >= new Date().getTime()) {
long secondsElapsed = (new Date().getTime() - startTime) / 1000L;
MainApp.bus().post(new EventDanaRConnectionStatus(EventDanaRConnectionStatus.CONNECTING, (int) secondsElapsed));
if (Config.logDanaBTComm)
log.debug("connect waiting " + secondsElapsed + "sec from: " + from);
try {
mRfcommSocket.connect();
} catch (IOException e) {
//e.printStackTrace();
if (e.getMessage().contains("socket closed")) {
e.printStackTrace();
break;
}
}
waitMsec(1000);
if (isConnected()) {
if (mSerialIOThread != null) {
mSerialIOThread.disconnect("Recreate SerialIOThread");
}
mSerialIOThread = new SerialIOThread(mRfcommSocket);
MainApp.bus().post(new EventDanaRConnectionStatus(EventDanaRConnectionStatus.CONNECTED, 0));
if (!getPumpStatus()) {
mSerialIOThread.disconnect("getPumpStatus failed");
waitMsec(3000);
}
}
}
if (!isConnected()) {
MainApp.bus().post(new EventDanaRConnectionStatus(EventDanaRConnectionStatus.DISCONNECTED, 0));
log.error("Pump connection timed out");
}
connectionInProgress = false;
mWakeLock.release();
}
}
private void getBTSocketForSelectedPump() {
devName = SP.getString("danar_bt_name", "");
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter != null) {
Set<BluetoothDevice> bondedDevices = bluetoothAdapter.getBondedDevices();
for (BluetoothDevice device : bondedDevices) {
if (devName.equals(device.getName())) {
mBTDevice = device;
try {
mRfcommSocket = mBTDevice.createRfcommSocketToServiceRecord(SPP_UUID);
} catch (IOException e) {
log.error("Error creating socket: ", e);
}
break;
}
}
} else {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.nobtadapter));
}
if (mBTDevice == null) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.devicenotfound));
}
}
@Subscribe
public void onStatusEvent(final EventPreferenceChange pch) {
if (mSerialIOThread != null)
mSerialIOThread.disconnect("EventPreferenceChange");
}
private boolean getPumpStatus() {
try {
//MsgStatus statusMsg = new MsgStatus();
MsgStatusBasic statusBasicMsg = new MsgStatusBasic();
MsgStatusTempBasal tempStatusMsg = new MsgStatusTempBasal();
MsgStatusBolusExtended exStatusMsg = new MsgStatusBolusExtended();
mSerialIOThread.sendMessage(new MsgSettingShippingInfo()); // TODO: show it somewhere
mSerialIOThread.sendMessage(tempStatusMsg); // do this before statusBasic because here is temp duration
mSerialIOThread.sendMessage(exStatusMsg);
//mSerialIOThread.sendMessage(statusMsg);
mSerialIOThread.sendMessage(statusBasicMsg);
mSerialIOThread.sendMessage(new MsgCheckValue());
// if (!statusMsg.received) {
// mSerialIOThread.sendMessage(statusMsg);
// }
if (!statusBasicMsg.received) {
mSerialIOThread.sendMessage(statusBasicMsg);
}
if (!tempStatusMsg.received) {
// Load of status of current basal rate failed, give one more try
mSerialIOThread.sendMessage(tempStatusMsg);
}
if (!exStatusMsg.received) {
// Load of status of current extended bolus failed, give one more try
mSerialIOThread.sendMessage(exStatusMsg);
}
// Check we have really current status of pump
if (/*!statusMsg.received || */!statusBasicMsg.received || !tempStatusMsg.received || !exStatusMsg.received) {
waitMsec(10 * 1000);
log.debug("getPumpStatus failed");
return false;
}
Date now = new Date();
if (danaRKoreanPump.lastSettingsRead.getTime() + 60 * 60 * 1000L < now.getTime() || !((DanaRKoreanPlugin)MainApp.getSpecificPlugin(DanaRKoreanPlugin.class)).isInitialized()) {
mSerialIOThread.sendMessage(new MsgSettingShippingInfo());
mSerialIOThread.sendMessage(new MsgSettingMeal());
mSerialIOThread.sendMessage(new MsgSettingBasal());
//0x3201
mSerialIOThread.sendMessage(new MsgSettingMaxValues());
mSerialIOThread.sendMessage(new MsgSettingGlucose());
mSerialIOThread.sendMessage(new MsgSettingPumpTime());
mSerialIOThread.sendMessage(new MsgSettingProfileRatios());
mSerialIOThread.sendMessage(new MsgSetTime(new Date()));
danaRKoreanPump.lastSettingsRead = now;
}
danaRKoreanPump.lastConnection = now;
MainApp.bus().post(new EventDanaRNewStatus());
MainApp.bus().post(new EventInitializationChanged());
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
public boolean tempBasal(int percent, int durationInHours) {
connect("tempBasal");
if (!isConnected()) return false;
mSerialIOThread.sendMessage(new MsgSetTempBasalStart(percent, durationInHours));
mSerialIOThread.sendMessage(new MsgStatusTempBasal());
return true;
}
public boolean tempBasalStop() {
connect("tempBasalStop");
if (!isConnected()) return false;
mSerialIOThread.sendMessage(new MsgSetTempBasalStop());
mSerialIOThread.sendMessage(new MsgStatusTempBasal());
return true;
}
public boolean extendedBolus(double insulin, int durationInHalfHours) {
connect("extendedBolus");
if (!isConnected()) return false;
mSerialIOThread.sendMessage(new MsgSetExtendedBolusStart(insulin, (byte) (durationInHalfHours & 0xFF)));
mSerialIOThread.sendMessage(new MsgStatusBolusExtended());
return true;
}
public boolean extendedBolusStop() {
connect("extendedBolusStop");
if (!isConnected()) return false;
mSerialIOThread.sendMessage(new MsgSetExtendedBolusStop());
mSerialIOThread.sendMessage(new MsgStatusBolusExtended());
return true;
}
public boolean bolus(Double amount, int carbs, Treatment t) {
bolusingTreatment = t;
MsgBolusStart start = new MsgBolusStart(amount);
MsgBolusProgress progress = new MsgBolusProgress(MainApp.bus(), amount, t);
MsgBolusStop stop = new MsgBolusStop(MainApp.bus(), amount, t);
connect("bolus");
if (!isConnected()) return false;
if (carbs > 0) {
Calendar time = Calendar.getInstance();
mSerialIOThread.sendMessage(new MsgSetCarbsEntry(time, carbs));
}
MainApp.bus().post(new EventDanaRBolusStart());
if (!stop.stopped) {
mSerialIOThread.sendMessage(start);
} else {
t.insulin = 0d;
return false;
}
while (!stop.stopped && !start.failed) {
waitMsec(100);
}
waitMsec(300);
bolusingTreatment = null;
getPumpStatus();
return true;
}
public void bolusStop() {
if (Config.logDanaBTComm)
log.debug("bolusStop >>>>> @ " + (bolusingTreatment == null ? "" : bolusingTreatment.insulin));
MsgBolusStop stop = new MsgBolusStop();
stop.forced = true;
if (isConnected()) {
mSerialIOThread.sendMessage(stop);
while (!stop.stopped) {
mSerialIOThread.sendMessage(stop);
waitMsec(200);
}
} else {
stop.stopped = true;
}
}
public boolean carbsEntry(int amount) {
connect("carbsEntry");
if (!isConnected()) return false;
Calendar time = Calendar.getInstance();
MsgSetCarbsEntry msg = new MsgSetCarbsEntry(time, amount);
mSerialIOThread.sendMessage(msg);
return true;
}
public boolean loadHistory(byte type) {
connect("loadHistory");
if (!isConnected()) return false;
MessageBase msg = null;
switch (type) {
case RecordTypes.RECORD_TYPE_ALARM:
msg = new MsgHistoryAlarm();
break;
case RecordTypes.RECORD_TYPE_BASALHOUR:
msg = new MsgHistoryBasalHour();
break;
case RecordTypes.RECORD_TYPE_BOLUS:
msg = new MsgHistoryBolus();
break;
case RecordTypes.RECORD_TYPE_CARBO:
msg = new MsgHistoryCarbo();
break;
case RecordTypes.RECORD_TYPE_DAILY:
msg = new MsgHistoryDailyInsulin();
break;
case RecordTypes.RECORD_TYPE_ERROR:
msg = new MsgHistoryError();
break;
case RecordTypes.RECORD_TYPE_GLUCOSE:
msg = new MsgHistoryGlucose();
break;
case RecordTypes.RECORD_TYPE_REFILL:
msg = new MsgHistoryRefill();
break;
case RecordTypes.RECORD_TYPE_SUSPEND:
msg = new MsgHistorySuspend();
break;
}
MsgHistoryDone done = new MsgHistoryDone();
mSerialIOThread.sendMessage(new MsgPCCommStart());
waitMsec(400);
mSerialIOThread.sendMessage(msg);
while (!done.received && mRfcommSocket.isConnected()) {
waitMsec(100);
}
waitMsec(200);
mSerialIOThread.sendMessage(new MsgPCCommStop());
return true;
}
public boolean updateBasalsInPump(final NSProfile profile) {
connect("updateBasalsInPump");
if (!isConnected()) return false;
double[] basal = buildDanaRProfileRecord(profile);
MsgSetSingleBasalProfile msgSet = new MsgSetSingleBasalProfile(basal);
mSerialIOThread.sendMessage(msgSet);
danaRKoreanPump.lastSettingsRead = new Date(0); // force read full settings
getPumpStatus();
return true;
}
private double[] buildDanaRProfileRecord(NSProfile nsProfile) {
double[] record = new double[24];
for (Integer hour = 0; hour < 24; hour++) {
double value = nsProfile.getBasal(hour * 60 * 60);
if (Config.logDanaMessageDetail)
log.debug("NS basal value for " + hour + ":00 is " + value);
record[hour] = value;
}
return record;
}
private void waitMsec(long msecs) {
try {
Thread.sleep(msecs);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,95 @@
package info.nightscout.androidaps.plugins.DanaRKorean.comm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import info.nightscout.androidaps.plugins.DanaR.comm.MessageBase;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgBolusProgress;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgBolusStart;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgBolusStop;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgError;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgHistoryAlarm;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgHistoryAll;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgHistoryBolus;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgHistoryCarbo;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgHistoryDailyInsulin;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgHistoryGlucose;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgHistoryNew;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgHistoryNewDone;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgPCCommStart;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgPCCommStop;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgSetCarbsEntry;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgSetExtendedBolusStart;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgSetExtendedBolusStop;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgSetSingleBasalProfile;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgSetTempBasalStart;
import info.nightscout.androidaps.plugins.DanaR.comm.MsgSetTempBasalStop;
/**
* Created by mike on 28.05.2016.
*/
public class MessageHashTable {
private static Logger log = LoggerFactory.getLogger(MessageHashTable.class);
public static HashMap<Integer, MessageBase> messages = null;
static {
if (messages == null) {
messages = new HashMap<Integer, MessageBase>();
put(new MsgBolusStop()); // 0x0101 CMD_MEALINS_STOP
put(new MsgBolusStart()); // 0x0102 CMD_MEALINS_START_DATA
put(new MsgBolusProgress()); // 0x0202 CMD_PUMP_THIS_REMAINDER_MEAL_INS
put(new MsgStatusProfile()); // 0x0204 CMD_PUMP_CALCULATION_SETTING
put(new MsgStatusTempBasal()); // 0x0205 CMD_PUMP_EXERCISE_MODE
put(new MsgStatusBolusExtended()); // 0x0207 CMD_PUMP_EXPANS_INS_I
put(new MsgStatusBasic()); // 0x020A CMD_PUMP_INITVIEW_I
put(new MsgStatus()); // 0x020B CMD_PUMP_STATUS
put(new MsgInitConnStatusTime()); // 0x0301 CMD_PUMPINIT_TIME_INFO
put(new MsgInitConnStatusBolus()); // 0x0302 CMD_PUMPINIT_BOLUS_INFO
put(new MsgInitConnStatusBasic()); // 0x0303 CMD_PUMPINIT_INIT_INFO
put(new MsgSetTempBasalStart()); // 0x0401 CMD_PUMPSET_EXERCISE_S
put(new MsgSetCarbsEntry()); // 0x0402 CMD_PUMPSET_HIS_S
put(new MsgSetTempBasalStop()); // 0x0403 CMD_PUMPSET_EXERCISE_STOP
put(new MsgSetExtendedBolusStop()); // 0x0406 CMD_PUMPSET_EXPANS_INS_STOP
put(new MsgSetExtendedBolusStart()); // 0x0407 CMD_PUMPSET_EXPANS_INS_S
put(new MsgError()); // 0x0601 CMD_PUMPOWAY_SYSTEM_STATUS
put(new MsgPCCommStart()); // 0x3001 CMD_CONNECT
put(new MsgPCCommStop()); // 0x3002 CMD_DISCONNECT
put(new MsgHistoryBolus()); // 0x3101 CMD_HISTORY_MEAL_INS
put(new MsgHistoryDailyInsulin()); // 0x3102 CMD_HISTORY_DAY_INS
put(new MsgHistoryGlucose()); // 0x3104 CMD_HISTORY_GLUCOSE
put(new MsgHistoryAlarm()); // 0x3105 CMD_HISTORY_ALARM
put(new MsgHistoryCarbo()); // 0x3107 CMD_HISTORY_CARBOHY
put(new MsgSettingBasal()); // 0x3202 CMD_SETTING_V_BASAL_INS_I
put(new MsgSettingMeal()); // 0x3203 CMD_SETTING_V_MEAL_SETTING_I
put(new MsgSettingProfileRatios()); // 0x3204 CMD_SETTING_V_CCC_I
put(new MsgSettingMaxValues()); // 0x3205 CMD_SETTING_V_MAX_VALUE_I
put(new MsgSettingBasalProfileAll()); // 0x3206 CMD_SETTING_V_BASAL_PROFILE_ALL
put(new MsgSettingShippingInfo()); // 0x3207 CMD_SETTING_V_SHIPPING_I
put(new MsgSettingGlucose()); // 0x3209 CMD_SETTING_V_GLUCOSEandEASY
put(new MsgSettingPumpTime()); // 0x320A CMD_SETTING_V_TIME_I
put(new MsgSetSingleBasalProfile()); // 0x3302 CMD_SETTING_BASAL_INS_S
put(new MsgHistoryAll()); // 0x41F2 CMD_HISTORY_ALL
put(new MsgHistoryNewDone()); // 0x42F1 CMD_HISTORY_NEW_DONE
put(new MsgHistoryNew()); // 0x42F2 CMD_HISTORY_NEW
put(new MsgCheckValue()); // 0xF0F1 CMD_PUMP_CHECK_VALUE
}
}
public static void put(MessageBase message) {
int command = message.getCommand();
//String name = MessageOriginalNames.getName(command);
messages.put(command, message);
//log.debug(String.format("%04x ", command) + " " + name);
}
public static MessageBase findMessage(Integer command) {
if (messages.containsKey(command)) {
return messages.get(command);
} else {
return new MessageBase();
}
}
}

View file

@ -0,0 +1,44 @@
package info.nightscout.androidaps.plugins.DanaRKorean.comm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.plugins.DanaR.comm.MessageBase;
import info.nightscout.androidaps.plugins.DanaRKorean.DanaRKoreanPlugin;
import info.nightscout.androidaps.plugins.DanaRKorean.DanaRKoreanPump;
import info.nightscout.utils.ToastUtils;
/**
* Created by mike on 30.06.2016.
*/
public class MsgCheckValue extends MessageBase {
private static Logger log = LoggerFactory.getLogger(MsgCheckValue.class);
public MsgCheckValue() {
SetCommand(0xF0F1);
}
@Override
public void handleMessage(byte[] bytes) {
DanaRKoreanPump pump = DanaRKoreanPlugin.getDanaRPump();
pump.model = intFromBuff(bytes, 0, 1);
pump.protocol = intFromBuff(bytes, 1, 1);
pump.productCode = intFromBuff(bytes, 2, 1);
if (pump.model != DanaRKoreanPump.DOMESTIC_MODEL) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(),MainApp.sResources.getString(R.string.wrongpumpdriverselected), R.raw.error);
((DanaRKoreanPlugin)MainApp.getSpecificPlugin(DanaRKoreanPlugin.class)).doDisconnect("Wrong Model");
log.debug("Wrong model selected");
}
if (Config.logDanaMessageDetail) {
log.debug("Model: " + String.format("%02X ", pump.model));
log.debug("Protocol: " + String.format("%02X ", pump.protocol));
log.debug("Product Code: " + String.format("%02X ", pump.productCode));
}
}
}

View file

@ -0,0 +1,49 @@
package info.nightscout.androidaps.plugins.DanaRKorean.comm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.plugins.DanaR.comm.MessageBase;
import info.nightscout.androidaps.plugins.DanaRKorean.DanaRKoreanPlugin;
import info.nightscout.androidaps.plugins.DanaRKorean.DanaRKoreanPump;
import info.nightscout.androidaps.plugins.Overview.Notification;
import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification;
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
public class MsgInitConnStatusBasic extends MessageBase {
private static Logger log = LoggerFactory.getLogger(MsgInitConnStatusBasic.class);
public MsgInitConnStatusBasic() {
SetCommand(0x0303);
}
@Override
public void handleMessage(byte[] bytes) {
if (bytes.length - 10 > 6) {
return;
}
DanaRKoreanPump pump = DanaRKoreanPlugin.getDanaRPump();
int isStatusSuspendOn = intFromBuff(bytes, 0, 1);
int isUtilityEnable = intFromBuff(bytes, 1, 1);
pump.isEasyModeEnabled = intFromBuff(bytes, 2, 1) == 1;
int easyUIMode = intFromBuff(bytes, 3, 1);
pump.password = intFromBuff(bytes, 4, 2) ^ 0x3463;
if (Config.logDanaMessageDetail) {
log.debug("isStatusSuspendOn: " + isStatusSuspendOn);
log.debug("isUtilityEnable: " + isUtilityEnable);
log.debug("Is EasyUI Enabled: " + pump.isEasyModeEnabled);
log.debug("easyUIMode: " + easyUIMode);
log.debug("Pump password: " + pump.password);
}
if (pump.isEasyModeEnabled) {
Notification notification = new Notification(Notification.EASYMODE_ENABLED, MainApp.sResources.getString(R.string.danar_disableeasymode), Notification.URGENT);
MainApp.bus().post(new EventNewNotification(notification));
} else {
MainApp.bus().post(new EventDismissNotification(Notification.EASYMODE_ENABLED));
}
}
}

View file

@ -0,0 +1,54 @@
package info.nightscout.androidaps.plugins.DanaRKorean.comm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.plugins.DanaR.comm.MessageBase;
import info.nightscout.androidaps.plugins.DanaRKorean.DanaRKoreanPlugin;
import info.nightscout.androidaps.plugins.DanaRKorean.DanaRKoreanPump;
import info.nightscout.androidaps.plugins.Overview.Notification;
import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification;
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
/**
* Created by mike on 28.05.2016.
*/
public class MsgInitConnStatusBolus extends MessageBase {
private static Logger log = LoggerFactory.getLogger(MsgInitConnStatusBolus.class);
public MsgInitConnStatusBolus() {
SetCommand(0x0302);
}
@Override
public void handleMessage(byte[] bytes) {
if (bytes.length - 10 < 13) {
return;
}
DanaRKoreanPump pump = DanaRKoreanPlugin.getDanaRPump();
int bolusConfig = intFromBuff(bytes, 0, 1);
pump.isExtendedBolusEnabled = (bolusConfig & 0x01) != 0;
pump.bolusStep = intFromBuff(bytes, 1, 1) / 100d;
pump.maxBolus = intFromBuff(bytes, 2, 2) / 100d;
//int bolusRate = intFromBuff(bytes, 4, 8);
int deliveryStatus = intFromBuff(bytes, 12, 1);
if (Config.logDanaMessageDetail) {
log.debug("Is Extended bolus enabled: " + pump.isExtendedBolusEnabled);
log.debug("Bolus increment: " + pump.bolusStep);
log.debug("Bolus max: " + pump.maxBolus);
log.debug("Delivery status: " + deliveryStatus);
}
if (!pump.isExtendedBolusEnabled) {
Notification notification = new Notification(Notification.EXTENDED_BOLUS_DISABLED, MainApp.sResources.getString(R.string.danar_enableextendedbolus), Notification.URGENT);
MainApp.bus().post(new EventNewNotification(notification));
} else {
MainApp.bus().post(new EventDismissNotification(Notification.EXTENDED_BOLUS_DISABLED));
}
}
}

View file

@ -0,0 +1,62 @@
package info.nightscout.androidaps.plugins.DanaRKorean.comm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Date;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.events.EventRefreshGui;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.plugins.DanaR.DanaRPlugin;
import info.nightscout.androidaps.plugins.DanaR.comm.MessageBase;
import info.nightscout.androidaps.plugins.DanaRKorean.DanaRKoreanPlugin;
import info.nightscout.utils.ToastUtils;
public class MsgInitConnStatusTime extends MessageBase {
private static Logger log = LoggerFactory.getLogger(MsgInitConnStatusTime.class);
public MsgInitConnStatusTime() {
SetCommand(0x0301);
}
@Override
public void handleMessage(byte[] bytes) {
if (bytes.length - 10 < 10) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(),MainApp.sResources.getString(R.string.wrongpumpdriverselected), R.raw.error);
((DanaRKoreanPlugin)MainApp.getSpecificPlugin(DanaRKoreanPlugin.class)).doDisconnect("Wrong Model");
log.debug("Wrong model selected. Switching to export DanaR");
((DanaRKoreanPlugin)MainApp.getSpecificPlugin(DanaRKoreanPlugin.class)).setFragmentEnabled(PluginBase.PUMP, false);
((DanaRKoreanPlugin)MainApp.getSpecificPlugin(DanaRKoreanPlugin.class)).setFragmentVisible(PluginBase.PUMP, false);
((DanaRPlugin)MainApp.getSpecificPlugin(DanaRPlugin.class)).setFragmentEnabled(PluginBase.PUMP, true);
((DanaRPlugin)MainApp.getSpecificPlugin(DanaRPlugin.class)).setFragmentVisible(PluginBase.PUMP, true);
//If profile coming from pump, switch it as well
if(MainApp.getSpecificPlugin(DanaRKoreanPlugin.class).isEnabled(PluginBase.PROFILE)){
(MainApp.getSpecificPlugin(DanaRKoreanPlugin.class)).setFragmentEnabled(PluginBase.PROFILE, false);
(MainApp.getSpecificPlugin(DanaRPlugin.class)).setFragmentEnabled(PluginBase.PROFILE, true);
}
MainApp.getConfigBuilder().storeSettings();
MainApp.bus().post(new EventRefreshGui(false));
return;
}
Date time = dateTimeSecFromBuff(bytes, 0);
int versionCode1 = intFromBuff(bytes, 6, 1);
int versionCode2 = intFromBuff(bytes, 7, 1);
int versionCode3 = intFromBuff(bytes, 8, 1);
int versionCode4 = intFromBuff(bytes, 9, 1);
if (Config.logDanaMessageDetail) {
log.debug("Pump time: " + time);
log.debug("Version code1: " + versionCode1);
log.debug("Version code2: " + versionCode2);
log.debug("Version code3: " + versionCode3);
log.debug("Version code4: " + versionCode4);
}
}
}

View file

@ -0,0 +1,36 @@
package info.nightscout.androidaps.plugins.DanaRKorean.comm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.plugins.DanaR.comm.MessageBase;
import info.nightscout.androidaps.plugins.DanaRKorean.DanaRKoreanPlugin;
import info.nightscout.androidaps.plugins.DanaRKorean.DanaRKoreanPump;
/**
* Created by mike on 05.07.2016.
*/
public class MsgSettingBasal extends MessageBase {
private static Logger log = LoggerFactory.getLogger(MsgSettingBasal.class);
public MsgSettingBasal() {
SetCommand(0x3202);
}
public void handleMessage(byte[] bytes) {
DanaRKoreanPump pump = DanaRKoreanPlugin.getDanaRPump();
if (pump.pumpProfiles == null) pump.pumpProfiles = new double[4][];
pump.pumpProfiles[pump.activeProfile] = new double[24];
for (int index = 0; index < 24; index++) {
int basal = intFromBuff(bytes, 2 * index, 2);
if (basal < 10) basal = 0;
pump.pumpProfiles[pump.activeProfile][index] = basal / 100d;
}
if (Config.logDanaMessageDetail)
for (int index = 0; index < 24; index++) {
log.debug("Basal " + String.format("%02d", index) + "h: " + DanaRKoreanPlugin.getDanaRPump().pumpProfiles[DanaRKoreanPlugin.getDanaRPump().activeProfile][index]);
}
}
}

View file

@ -0,0 +1,73 @@
package info.nightscout.androidaps.plugins.DanaRKorean.comm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.plugins.DanaR.comm.MessageBase;
import info.nightscout.androidaps.plugins.DanaRKorean.DanaRKoreanPlugin;
import info.nightscout.androidaps.plugins.DanaRKorean.DanaRKoreanPump;
/**
* Created by mike on 05.07.2016.
* <p/>
* <p/>
* THIS IS BROKEN IN PUMP... SENDING ONLY 1 PROFILE
*/
public class MsgSettingBasalProfileAll extends MessageBase {
private static Logger log = LoggerFactory.getLogger(MsgSettingBasalProfileAll.class);
public MsgSettingBasalProfileAll() {
SetCommand(0x3206);
}
public void handleMessage(byte[] bytes) {
DanaRKoreanPump pump = DanaRKoreanPlugin.getDanaRPump();
if (DanaRKoreanPlugin.getDanaRPump().basal48Enable) {
pump.pumpProfiles = new double[4][];
for (int profile = 0; profile < 4; profile++) {
int position = intFromBuff(bytes, 107 * profile, 1);
pump.pumpProfiles[position] = new double[48];
for (int index = 0; index < 48; index++) {
int basal = intFromBuff(bytes, 107 * profile + 2 * index + 1, 2);
if (basal < 10) basal = 0;
pump.pumpProfiles[position][index] = basal / 100 / 24d; // in units/day
}
}
} else {
pump.pumpProfiles = new double[4][];
for (int profile = 0; profile < 4; profile++) {
int position = intFromBuff(bytes, 49 * profile, 1);
log.debug("position " + position);
pump.pumpProfiles[position] = new double[24];
for (int index = 0; index < 24; index++) {
int basal = intFromBuff(bytes, 59 * profile + 2 * index + 1, 2);
if (basal < 10) basal = 0;
log.debug("position " + position + " index " + index);
pump.pumpProfiles[position][index] = basal / 100 / 24d; // in units/day
}
}
}
if (Config.logDanaMessageDetail) {
if (DanaRKoreanPlugin.getDanaRPump().basal48Enable) {
for (int profile = 0; profile < 4; profile++) {
for (int index = 0; index < 24; index++) {
log.debug("Basal profile " + profile + ": " + String.format("%02d", index) + "h: " + DanaRKoreanPlugin.getDanaRPump().pumpProfiles[profile][index]);
}
}
} else {
for (int profile = 0; profile < 4; profile++) {
for (int index = 0; index < 48; index++) {
log.debug("Basal profile " + profile + ": " +
String.format("%02d", (index / 2)) +
":" + String.format("%02d", (index % 2) * 30) + " : " +
DanaRKoreanPlugin.getDanaRPump().pumpProfiles[profile][index]);
}
}
}
}
}
}

View file

@ -0,0 +1,30 @@
package info.nightscout.androidaps.plugins.DanaRKorean.comm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.plugins.DanaR.comm.MessageBase;
import info.nightscout.androidaps.plugins.DanaRKorean.DanaRKoreanPlugin;
import info.nightscout.androidaps.plugins.DanaRKorean.DanaRKoreanPump;
/**
* Created by mike on 05.07.2016.
*/
public class MsgSettingGlucose extends MessageBase {
private static Logger log = LoggerFactory.getLogger(MsgSettingGlucose.class);
public MsgSettingGlucose() {
SetCommand(0x3209);
}
public void handleMessage(byte[] bytes) {
DanaRKoreanPlugin.getDanaRPump().units = intFromBuff(bytes, 0, 1);
DanaRKoreanPlugin.getDanaRPump().easyBasalMode = intFromBuff(bytes, 1, 1);
if (Config.logDanaMessageDetail) {
log.debug("Pump units: " + (DanaRKoreanPlugin.getDanaRPump().units == DanaRKoreanPump.UNITS_MGDL ? "MGDL" : "MMOL"));
log.debug("Easy basal mode: " + DanaRKoreanPlugin.getDanaRPump().easyBasalMode);
}
}
}

View file

@ -0,0 +1,33 @@
package info.nightscout.androidaps.plugins.DanaRKorean.comm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.plugins.DanaR.comm.MessageBase;
import info.nightscout.androidaps.plugins.DanaRKorean.DanaRKoreanPlugin;
/**
* Created by mike on 05.07.2016.
*/
public class MsgSettingMaxValues extends MessageBase {
private static Logger log = LoggerFactory.getLogger(MsgSettingMaxValues.class);
public MsgSettingMaxValues() {
SetCommand(0x3205);
}
public void handleMessage(byte[] bytes) {
DanaRKoreanPlugin.getDanaRPump().maxBolus = intFromBuff(bytes, 0, 2) / 100d;
DanaRKoreanPlugin.getDanaRPump().maxBasal = intFromBuff(bytes, 2, 2) / 100d;
DanaRKoreanPlugin.getDanaRPump().maxDailyTotalUnits = intFromBuff(bytes, 4, 2) / 100;
if (Config.logDanaMessageDetail) {
log.debug("Max bolus: " + DanaRKoreanPlugin.getDanaRPump().maxBolus);
log.debug("Max basal: " + DanaRKoreanPlugin.getDanaRPump().maxBasal);
log.debug("Total daily max units: " + DanaRKoreanPlugin.getDanaRPump().maxDailyTotalUnits);
}
}
}

View file

@ -0,0 +1,55 @@
package info.nightscout.androidaps.plugins.DanaRKorean.comm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.plugins.DanaR.DanaRPlugin;
import info.nightscout.androidaps.plugins.DanaR.DanaRPump;
import info.nightscout.androidaps.plugins.DanaR.comm.MessageBase;
import info.nightscout.androidaps.plugins.DanaRKorean.DanaRKoreanPlugin;
import info.nightscout.androidaps.plugins.DanaRKorean.DanaRKoreanPump;
import info.nightscout.androidaps.plugins.Overview.Notification;
import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification;
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
/**
* Created by mike on 13.12.2016.
*/
public class MsgSettingMeal extends MessageBase {
private static Logger log = LoggerFactory.getLogger(MsgSettingMeal.class);
public MsgSettingMeal() {
SetCommand(0x3203);
}
public void handleMessage(byte[] bytes) {
DanaRKoreanPump pump = DanaRKoreanPlugin.getDanaRPump();
pump.basalStep = intFromBuff(bytes, 0, 1) / 100d;
pump.bolusStep = intFromBuff(bytes, 1, 1) / 100d;
boolean bolusEnabled = intFromBuff(bytes, 2, 1) == 1;
int melodyTime = intFromBuff(bytes, 3, 1);
int blockTime = intFromBuff(bytes, 4, 1);
pump.isConfigUD = intFromBuff(bytes, 5, 1) == 1;
if (Config.logDanaMessageDetail) {
log.debug("Basal step: " + pump.basalStep);
log.debug("Bolus step: " + pump.bolusStep);
log.debug("Bolus enabled: " + bolusEnabled);
log.debug("Melody time: " + melodyTime);
log.debug("Block time: " + blockTime);
log.debug("Is Config U/d: " + pump.isConfigUD);
}
if (pump.isConfigUD) {
Notification notification = new Notification(Notification.UD_MODE_ENABLED, MainApp.sResources.getString(R.string.danar_switchtouhmode), Notification.URGENT);
MainApp.bus().post(new EventNewNotification(notification));
} else {
MainApp.bus().post(new EventDismissNotification(Notification.UD_MODE_ENABLED));
}
}
}

View file

@ -0,0 +1,45 @@
package info.nightscout.androidaps.plugins.DanaRKorean.comm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.plugins.DanaR.comm.MessageBase;
import info.nightscout.androidaps.plugins.DanaRKorean.DanaRKoreanPlugin;
import info.nightscout.androidaps.plugins.DanaRKorean.DanaRKoreanPump;
/**
* Created by mike on 05.07.2016.
*/
public class MsgSettingProfileRatios extends MessageBase {
private static Logger log = LoggerFactory.getLogger(MsgSettingProfileRatios.class);
public MsgSettingProfileRatios() {
SetCommand(0x3204);
}
public void handleMessage(byte[] bytes) {
if (DanaRKoreanPlugin.getDanaRPump().units == DanaRKoreanPump.UNITS_MGDL) {
DanaRKoreanPlugin.getDanaRPump().currentCIR = intFromBuff(bytes, 0, 2);
DanaRKoreanPlugin.getDanaRPump().currentCF = intFromBuff(bytes, 2, 2);
DanaRKoreanPlugin.getDanaRPump().currentAI = intFromBuff(bytes, 4, 2) / 100d;
DanaRKoreanPlugin.getDanaRPump().currentTarget = intFromBuff(bytes, 6, 2);
DanaRKoreanPlugin.getDanaRPump().currentAIDR = intFromBuff(bytes, 8, 1);
} else {
DanaRKoreanPlugin.getDanaRPump().currentCIR = intFromBuff(bytes, 0, 2);
DanaRKoreanPlugin.getDanaRPump().currentCF = intFromBuff(bytes, 2, 2) / 100d;
DanaRKoreanPlugin.getDanaRPump().currentAI = intFromBuff(bytes, 4, 2) / 100d;
DanaRKoreanPlugin.getDanaRPump().currentTarget = intFromBuff(bytes, 6, 2) / 100d;
DanaRKoreanPlugin.getDanaRPump().currentAIDR = intFromBuff(bytes, 8, 1);
}
if (Config.logDanaMessageDetail) {
log.debug("Pump units (saved): " + (DanaRKoreanPlugin.getDanaRPump().units == DanaRKoreanPump.UNITS_MGDL ? "MGDL" : "MMOL"));
log.debug("Current pump CIR: " + DanaRKoreanPlugin.getDanaRPump().currentCIR);
log.debug("Current pump CF: " + DanaRKoreanPlugin.getDanaRPump().currentCF);
log.debug("Current pump AI: " + DanaRKoreanPlugin.getDanaRPump().currentAI);
log.debug("Current pump target: " + DanaRKoreanPlugin.getDanaRPump().currentTarget);
log.debug("Current pump AIDR: " + DanaRKoreanPlugin.getDanaRPump().currentAIDR);
}
}
}

View file

@ -0,0 +1,35 @@
package info.nightscout.androidaps.plugins.DanaRKorean.comm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Date;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.plugins.DanaR.comm.MessageBase;
import info.nightscout.androidaps.plugins.DanaRKorean.DanaRKoreanPlugin;
public class MsgSettingPumpTime extends MessageBase {
private static Logger log = LoggerFactory.getLogger(MsgSettingPumpTime.class);
public MsgSettingPumpTime() {
SetCommand(0x320A);
}
public void handleMessage(byte[] bytes) {
Date time =
new Date(
100 + intFromBuff(bytes, 5, 1),
intFromBuff(bytes, 4, 1) - 1,
intFromBuff(bytes, 3, 1),
intFromBuff(bytes, 2, 1),
intFromBuff(bytes, 1, 1),
intFromBuff(bytes, 0, 1)
);
if (Config.logDanaMessageDetail)
log.debug("Pump time: " + time);
DanaRKoreanPlugin.getDanaRPump().pumpTime = time;
}
}

View file

@ -0,0 +1,39 @@
package info.nightscout.androidaps.plugins.DanaRKorean.comm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Date;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.plugins.DanaR.comm.MessageBase;
import info.nightscout.androidaps.plugins.DanaRKorean.DanaRKoreanPlugin;
import info.nightscout.androidaps.plugins.DanaRKorean.DanaRKoreanPump;
/**
* Created by mike on 05.07.2016.
*/
public class MsgSettingShippingInfo extends MessageBase {
private static Logger log = LoggerFactory.getLogger(MsgSettingShippingInfo.class);
public MsgSettingShippingInfo() {
SetCommand(0x3207);
}
public void handleMessage(byte[] bytes) {
DanaRKoreanPump pump = DanaRKoreanPlugin.getDanaRPump();
pump.serialNumber = stringFromBuff(bytes, 0, 10);
pump.shippingDate = dateFromBuff(bytes, 10);
pump.shippingCountry = asciiStringFromBuff(bytes, 13, 3);
if (pump.shippingDate.getTime() > new Date(116, 4, 1).getTime()) {
pump.isNewPump = true;
} else
pump.isNewPump = false;
if (Config.logDanaMessageDetail) {
log.debug("Serial number: " + pump.serialNumber);
log.debug("Shipping date: " + pump.shippingDate);
log.debug("Shipping country: " + pump.shippingCountry);
}
}
}

View file

@ -0,0 +1,39 @@
package info.nightscout.androidaps.plugins.DanaRKorean.comm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.plugins.DanaR.comm.MessageBase;
import info.nightscout.androidaps.plugins.DanaRKorean.DanaRKoreanPlugin;
public class MsgStatus extends MessageBase {
private static Logger log = LoggerFactory.getLogger(MsgStatus.class);
public MsgStatus() {
SetCommand(0x020B);
}
public void handleMessage(byte[] bytes) {
DanaRKoreanPlugin.getDanaRPump().dailyTotalUnits = intFromBuff(bytes, 0, 3) / 750d;
DanaRKoreanPlugin.getDanaRPump().isExtendedInProgress = intFromBuff(bytes, 3, 1) == 1;
DanaRKoreanPlugin.getDanaRPump().extendedBolusMinutes = intFromBuff(bytes, 4, 2);
DanaRKoreanPlugin.getDanaRPump().extendedBolusAmount = intFromBuff(bytes, 6, 2) / 100d;
Double lastBolusAmount = intFromBuff(bytes, 13, 2) / 100d;
// if (lastBolusAmount != 0d) {
// DanaRKoreanPlugin.getDanaRPump().lastBolusTime = dateTimeFromBuff(bytes, 8);
// DanaRKoreanPlugin.getDanaRPump().lastBolusAmount = lastBolusAmount;
// }
DanaRKoreanPlugin.getDanaRPump().iob = intFromBuff(bytes, 15, 2) / 100d;
if (Config.logDanaMessageDetail) {
log.debug("Daily total: " + DanaRKoreanPlugin.getDanaRPump().dailyTotalUnits);
log.debug("Is extended bolus running: " + DanaRKoreanPlugin.getDanaRPump().isExtendedInProgress);
log.debug("Extended bolus min: " + DanaRKoreanPlugin.getDanaRPump().extendedBolusMinutes);
log.debug("Extended bolus amount: " + DanaRKoreanPlugin.getDanaRPump().extendedBolusAmount);
// log.debug("Last bolus time: " + DanaRKoreanPlugin.getDanaRPump().lastBolusTime);
// log.debug("Last bolus amount: " + DanaRKoreanPlugin.getDanaRPump().lastBolusAmount);
log.debug("IOB: " + DanaRKoreanPlugin.getDanaRPump().iob);
}
}
}

View file

@ -0,0 +1,38 @@
package info.nightscout.androidaps.plugins.DanaRKorean.comm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.plugins.DanaR.comm.MessageBase;
import info.nightscout.androidaps.plugins.DanaRKorean.DanaRKoreanPlugin;
public class MsgStatusBasic extends MessageBase {
private static Logger log = LoggerFactory.getLogger(MsgStatusBasic.class);
public MsgStatusBasic() {
SetCommand(0x020A);
}
public void handleMessage(byte[] bytes) {
double currentBasal = intFromBuff(bytes, 0, 2) / 100d;
int batteryRemaining = intFromBuff(bytes, 2, 1);
double reservoirRemainingUnits = intFromBuff(bytes, 3, 3) / 750d;
double dailyTotalUnits = intFromBuff(bytes, 6, 3) / 750d;
int maxDailyTotalUnits = intFromBuff(bytes, 9, 2) / 100;
DanaRKoreanPlugin.getDanaRPump().dailyTotalUnits = dailyTotalUnits;
DanaRKoreanPlugin.getDanaRPump().maxDailyTotalUnits = maxDailyTotalUnits;
DanaRKoreanPlugin.getDanaRPump().reservoirRemainingUnits = reservoirRemainingUnits;
DanaRKoreanPlugin.getDanaRPump().currentBasal = currentBasal;
DanaRKoreanPlugin.getDanaRPump().batteryRemaining = batteryRemaining;
if (Config.logDanaMessageDetail) {
log.debug("Daily total units: " + dailyTotalUnits);
log.debug("Max daily total units: " + maxDailyTotalUnits);
log.debug("Reservoir remaining units: " + reservoirRemainingUnits);
log.debug("Current basal: " + currentBasal);
}
}
}

View file

@ -0,0 +1,114 @@
package info.nightscout.androidaps.plugins.DanaRKorean.comm;
import android.support.annotation.NonNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.SQLException;
import java.util.Date;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.db.TempBasal;
import info.nightscout.androidaps.events.EventTempBasalChange;
import info.nightscout.androidaps.plugins.DanaR.comm.MessageBase;
import info.nightscout.androidaps.plugins.DanaRKorean.DanaRKoreanPlugin;
import info.nightscout.androidaps.plugins.DanaRKorean.DanaRKoreanPump;
public class MsgStatusBolusExtended extends MessageBase {
private static Logger log = LoggerFactory.getLogger(MsgStatusBolusExtended.class);
public MsgStatusBolusExtended() {
SetCommand(0x0207);
}
public void handleMessage(byte[] bytes) {
boolean isExtendedInProgress = intFromBuff(bytes, 0, 1) == 1;
int extendedBolusHalfHours = intFromBuff(bytes, 1, 1);
int extendedBolusMinutes = extendedBolusHalfHours * 30;
double extendedBolusAmount = intFromBuff(bytes, 2, 2) / 100d;
int extendedBolusSoFarInSecs = intFromBuff(bytes, 4, 3);
int extendedBolusDeliveryPulse = intFromBuff(bytes, 7, 2);
int isEasyUIUserSleep = intFromBuff(bytes, 9, 1);
int extendedBolusSoFarInMinutes = extendedBolusSoFarInSecs / 60;
double extendedBolusAbsoluteRate = isExtendedInProgress ? extendedBolusAmount / extendedBolusMinutes * 60 : 0d;
Date extendedBolusStart = isExtendedInProgress ? getDateFromSecAgo(extendedBolusSoFarInSecs) : new Date(0);
int extendedBolusRemainingMinutes = extendedBolusMinutes - extendedBolusSoFarInMinutes;
DanaRKoreanPlugin.getDanaRPump().isExtendedInProgress = isExtendedInProgress;
DanaRKoreanPlugin.getDanaRPump().extendedBolusMinutes = extendedBolusMinutes;
DanaRKoreanPlugin.getDanaRPump().extendedBolusAmount = extendedBolusAmount;
DanaRKoreanPlugin.getDanaRPump().extendedBolusSoFarInMinutes = extendedBolusSoFarInMinutes;
DanaRKoreanPlugin.getDanaRPump().extendedBolusAbsoluteRate = extendedBolusAbsoluteRate;
DanaRKoreanPlugin.getDanaRPump().extendedBolusStart = extendedBolusStart;
DanaRKoreanPlugin.getDanaRPump().extendedBolusRemainingMinutes = extendedBolusRemainingMinutes;
updateExtendedBolusInDB();
if (Config.logDanaMessageDetail) {
log.debug("Is extended bolus running: " + isExtendedInProgress);
log.debug("Extended bolus min: " + extendedBolusMinutes);
log.debug("Extended bolus amount: " + extendedBolusAmount);
log.debug("Extended bolus so far in minutes: " + extendedBolusSoFarInMinutes);
log.debug("Extended bolus absolute rate: " + extendedBolusAbsoluteRate);
log.debug("Extended bolus start: " + extendedBolusStart);
log.debug("Extended bolus remaining minutes: " + extendedBolusRemainingMinutes);
}
}
@NonNull
private Date getDateFromSecAgo(int tempBasalAgoSecs) {
return new Date((long) (Math.ceil(new Date().getTime() / 1000d) - tempBasalAgoSecs) * 1000);
}
public static void updateExtendedBolusInDB() {
DanaRKoreanPlugin DanaRKoreanPlugin = (DanaRKoreanPlugin) MainApp.getSpecificPlugin(DanaRKoreanPlugin.class);
DanaRKoreanPump danaRKoreanPump = DanaRKoreanPlugin.getDanaRPump();
Date now = new Date();
try {
if (DanaRKoreanPlugin.isExtendedBoluslInProgress()) {
TempBasal extendedBolus = DanaRKoreanPlugin.getExtendedBolus();
if (danaRKoreanPump.isExtendedInProgress) {
if (extendedBolus.absolute != danaRKoreanPump.extendedBolusAbsoluteRate) {
// Close current extended
extendedBolus.timeEnd = now;
MainApp.getDbHelper().getDaoTempBasals().update(extendedBolus);
// Create new
TempBasal newExtended = new TempBasal();
newExtended.timeStart = now;
newExtended.absolute = danaRKoreanPump.extendedBolusAbsoluteRate;
newExtended.isAbsolute = true;
newExtended.duration = danaRKoreanPump.extendedBolusMinutes;
newExtended.isExtended = true;
MainApp.getDbHelper().getDaoTempBasals().create(newExtended);
MainApp.bus().post(new EventTempBasalChange());
}
} else {
// Close curent temp basal
extendedBolus.timeEnd = now;
MainApp.getDbHelper().getDaoTempBasals().update(extendedBolus);
MainApp.bus().post(new EventTempBasalChange());
}
} else {
if (danaRKoreanPump.isExtendedInProgress) {
// Create new
TempBasal newExtended = new TempBasal();
newExtended.timeStart = now;
newExtended.absolute = danaRKoreanPump.extendedBolusAbsoluteRate;
newExtended.isAbsolute = true;
newExtended.duration = danaRKoreanPump.extendedBolusMinutes;
newExtended.isExtended = true;
MainApp.getDbHelper().getDaoTempBasals().create(newExtended);
MainApp.bus().post(new EventTempBasalChange());
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,43 @@
package info.nightscout.androidaps.plugins.DanaRKorean.comm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.plugins.DanaR.comm.MessageBase;
import info.nightscout.androidaps.plugins.DanaRKorean.DanaRKoreanPlugin;
import info.nightscout.androidaps.plugins.DanaRKorean.DanaRKoreanPump;
/**
* Created by mike on 05.07.2016.
*/
public class MsgStatusProfile extends MessageBase {
private static Logger log = LoggerFactory.getLogger(MsgStatusProfile.class);
public MsgStatusProfile() {
SetCommand(0x0204);
}
public void handleMessage(byte[] bytes) {
if (DanaRKoreanPlugin.getDanaRPump().units == DanaRKoreanPump.UNITS_MGDL) {
DanaRKoreanPlugin.getDanaRPump().currentCIR = intFromBuff(bytes, 0, 2);
DanaRKoreanPlugin.getDanaRPump().currentCF = intFromBuff(bytes, 2, 2);
DanaRKoreanPlugin.getDanaRPump().currentAI = intFromBuff(bytes, 4, 2) / 100d;
DanaRKoreanPlugin.getDanaRPump().currentTarget = intFromBuff(bytes, 6, 2);
} else {
DanaRKoreanPlugin.getDanaRPump().currentCIR = intFromBuff(bytes, 0, 2);
DanaRKoreanPlugin.getDanaRPump().currentCF = intFromBuff(bytes, 2, 2) / 100d;
DanaRKoreanPlugin.getDanaRPump().currentAI = intFromBuff(bytes, 4, 2) / 100d;
DanaRKoreanPlugin.getDanaRPump().currentTarget = intFromBuff(bytes, 6, 2) / 100d;
}
if (Config.logDanaMessageDetail) {
log.debug("Pump units (saved): " + (DanaRKoreanPlugin.getDanaRPump().units == DanaRKoreanPump.UNITS_MGDL ? "MGDL" : "MMOL"));
log.debug("Current pump CIR: " + DanaRKoreanPlugin.getDanaRPump().currentCIR);
log.debug("Current pump CF: " + DanaRKoreanPlugin.getDanaRPump().currentCF);
log.debug("Current pump AI: " + DanaRKoreanPlugin.getDanaRPump().currentAI);
log.debug("Current pump target: " + DanaRKoreanPlugin.getDanaRPump().currentTarget);
log.debug("Current pump AIDR: " + DanaRKoreanPlugin.getDanaRPump().currentAIDR);
}
}
}

View file

@ -0,0 +1,103 @@
package info.nightscout.androidaps.plugins.DanaRKorean.comm;
import android.support.annotation.NonNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.SQLException;
import java.util.Date;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.db.TempBasal;
import info.nightscout.androidaps.events.EventTempBasalChange;
import info.nightscout.androidaps.plugins.DanaR.comm.MessageBase;
import info.nightscout.androidaps.plugins.DanaRKorean.DanaRKoreanPlugin;
import info.nightscout.androidaps.plugins.DanaRKorean.DanaRKoreanPump;
public class MsgStatusTempBasal extends MessageBase {
private static Logger log = LoggerFactory.getLogger(MsgStatusTempBasal.class);
public MsgStatusTempBasal() {
SetCommand(0x0205);
}
public void handleMessage(byte[] bytes) {
boolean isTempBasalInProgress = intFromBuff(bytes, 0, 1) == 1;
int tempBasalPercent = intFromBuff(bytes, 1, 1);
int tempBasalTotalSec = intFromBuff(bytes, 2, 1) * 60 * 60;
int tempBasalRunningSeconds = intFromBuff(bytes, 3, 3);
int tempBasalRemainingMin = (tempBasalTotalSec - tempBasalRunningSeconds) / 60;
Date tempBasalStart = isTempBasalInProgress ? getDateFromTempBasalSecAgo(tempBasalRunningSeconds) : new Date(0);
DanaRKoreanPlugin.getDanaRPump().isTempBasalInProgress = isTempBasalInProgress;
DanaRKoreanPlugin.getDanaRPump().tempBasalPercent = tempBasalPercent;
DanaRKoreanPlugin.getDanaRPump().tempBasalRemainingMin = tempBasalRemainingMin;
DanaRKoreanPlugin.getDanaRPump().tempBasalTotalSec = tempBasalTotalSec;
DanaRKoreanPlugin.getDanaRPump().tempBasalStart = tempBasalStart;
updateTempBasalInDB();
if (Config.logDanaMessageDetail) {
log.debug("Is temp basal running: " + isTempBasalInProgress);
log.debug("Current temp basal percent: " + tempBasalPercent);
log.debug("Current temp basal remaining min: " + tempBasalRemainingMin);
log.debug("Current temp basal total sec: " + tempBasalTotalSec);
log.debug("Current temp basal start: " + tempBasalStart);
}
}
@NonNull
private Date getDateFromTempBasalSecAgo(int tempBasalAgoSecs) {
return new Date((long) (Math.ceil(new Date().getTime() / 1000d) - tempBasalAgoSecs) * 1000);
}
public static void updateTempBasalInDB() {
DanaRKoreanPlugin DanaRKoreanPlugin = (DanaRKoreanPlugin) MainApp.getSpecificPlugin(DanaRKoreanPlugin.class);
DanaRKoreanPump danaRKoreanPump = DanaRKoreanPlugin.getDanaRPump();
Date now = new Date();
try {
if (DanaRKoreanPlugin.isRealTempBasalInProgress()) {
TempBasal tempBasal = DanaRKoreanPlugin.getRealTempBasal();
if (danaRKoreanPump.isTempBasalInProgress) {
if (tempBasal.percent != danaRKoreanPump.tempBasalPercent) {
// Close current temp basal
tempBasal.timeEnd = now;
MainApp.getDbHelper().getDaoTempBasals().update(tempBasal);
// Create new
TempBasal newTempBasal = new TempBasal();
newTempBasal.timeStart = now;
newTempBasal.percent = danaRKoreanPump.tempBasalPercent;
newTempBasal.isAbsolute = false;
newTempBasal.duration = danaRKoreanPump.tempBasalTotalSec / 60;
newTempBasal.isExtended = false;
MainApp.getDbHelper().getDaoTempBasals().create(newTempBasal);
MainApp.bus().post(new EventTempBasalChange());
}
} else {
// Close current temp basal
tempBasal.timeEnd = now;
MainApp.getDbHelper().getDaoTempBasals().update(tempBasal);
MainApp.bus().post(new EventTempBasalChange());
}
} else {
if (danaRKoreanPump.isTempBasalInProgress) {
// Create new
TempBasal newTempBasal = new TempBasal();
newTempBasal.timeStart = now;
newTempBasal.percent = danaRKoreanPump.tempBasalPercent;
newTempBasal.isAbsolute = false;
newTempBasal.duration = danaRKoreanPump.tempBasalTotalSec / 60;
newTempBasal.isExtended = false;
MainApp.getDbHelper().getDaoTempBasals().create(newTempBasal);
MainApp.bus().post(new EventTempBasalChange());
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}

View file

@ -83,12 +83,12 @@ public class LoopPlugin implements PluginBase {
@Override @Override
public boolean isEnabled(int type) { public boolean isEnabled(int type) {
return fragmentEnabled; return type == LOOP && fragmentEnabled;
} }
@Override @Override
public boolean isVisibleInTabs(int type) { public boolean isVisibleInTabs(int type) {
return fragmentVisible; return type == LOOP && fragmentVisible;
} }
@Override @Override
@ -98,12 +98,12 @@ public class LoopPlugin implements PluginBase {
@Override @Override
public void setFragmentEnabled(int type, boolean fragmentEnabled) { public void setFragmentEnabled(int type, boolean fragmentEnabled) {
this.fragmentEnabled = fragmentEnabled; if (type == LOOP) this.fragmentEnabled = fragmentEnabled;
} }
@Override @Override
public void setFragmentVisible(int type, boolean fragmentVisible) { public void setFragmentVisible(int type, boolean fragmentVisible) {
this.fragmentVisible = fragmentVisible; if (type == LOOP) this.fragmentVisible = fragmentVisible;
} }
@Subscribe @Subscribe
@ -128,7 +128,7 @@ 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.GENERAL)) if (configBuilder == null || !isEnabled(PluginBase.LOOP))
return; return;
// Check if pump info is loaded // Check if pump info is loaded

View file

@ -1,43 +0,0 @@
package info.nightscout.androidaps.plugins.MM640g;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.squareup.otto.Subscribe;
import org.json.JSONObject;
import java.util.Date;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.TempBasal;
import info.nightscout.androidaps.events.EventPreferenceChange;
import info.nightscout.androidaps.interfaces.BgSourceInterface;
import info.nightscout.androidaps.interfaces.FragmentBase;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.client.data.NSProfile;
public class MM640gFragment extends Fragment implements FragmentBase {
private static MM640gPlugin mm640gPlugin = new MM640gPlugin();
public static MM640gPlugin getPlugin() {
return mm640gPlugin;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.mm640g_fragment, container, false);
return view;
}
}

View file

@ -1,192 +0,0 @@
package info.nightscout.androidaps.plugins.MM640g;
import android.content.Context;
import com.squareup.otto.Subscribe;
import org.json.JSONObject;
import java.util.Date;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.TempBasal;
import info.nightscout.androidaps.events.EventPreferenceChange;
import info.nightscout.androidaps.interfaces.BgSourceInterface;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.client.data.NSProfile;
/**
* Created by mike on 05.08.2016.
*/
public class MM640gPlugin implements PluginBase, PumpInterface, BgSourceInterface {
boolean fragmentPumpEnabled = false;
boolean fragmentProfileEnabled = false;
boolean fragmentBgSourceEnabled = false;
boolean fragmentPumpVisible = true;
@Override
public String getFragmentClass() {
return MM640gFragment.class.getName();
}
/**
* Plugin base interface
*/
@Override
public int getType() {
return PluginBase.PUMP;
}
@Override
public String getName() {
return MainApp.instance().getString(R.string.mm640g);
}
@Override
public boolean isEnabled(int type) {
if (type == PluginBase.PROFILE) return fragmentProfileEnabled;
else if (type == PluginBase.BGSOURCE) return fragmentBgSourceEnabled;
else if (type == PluginBase.PUMP) return fragmentPumpEnabled;
else if (type == PluginBase.CONSTRAINTS) return fragmentPumpEnabled;
return false;
}
@Override
public boolean isVisibleInTabs(int type) {
if (type == PluginBase.PROFILE || type == PluginBase.CONSTRAINTS) return false;
else if (type == PluginBase.PUMP) return fragmentPumpVisible;
return false;
}
@Override
public boolean canBeHidden(int type) {
return true;
}
@Override
public void setFragmentEnabled(int type, boolean fragmentEnabled) {
if (type == PluginBase.PROFILE) this.fragmentProfileEnabled = fragmentEnabled;
if (type == PluginBase.BGSOURCE) this.fragmentBgSourceEnabled = fragmentEnabled;
else if (type == PluginBase.PUMP) this.fragmentPumpEnabled = fragmentEnabled;
}
@Override
public void setFragmentVisible(int type, boolean fragmentVisible) {
if (type == PluginBase.PUMP)
this.fragmentPumpVisible = fragmentVisible;
}
/**
* Plugin communications
*/
@Subscribe
public void onStatusEvent(final EventPreferenceChange s) {
}
/**
* Pump Interface
*/
@Override
public boolean isInitialized() {
return false;
}
@Override
public boolean isTempBasalInProgress() {
return false;
}
@Override
public boolean isExtendedBoluslInProgress() {
return false;
}
@Override
public void setNewBasalProfile(NSProfile profile) {
}
@Override
public double getBaseBasalRate() {
return 0;
}
@Override
public double getTempBasalAbsoluteRate() {
return 0;
}
@Override
public double getTempBasalRemainingMinutes() {
return 0;
}
@Override
public TempBasal getTempBasal(Date time) {
return null;
}
@Override
public TempBasal getTempBasal() {
return null;
}
@Override
public TempBasal getExtendedBolus() {
return null;
}
@Override
public PumpEnactResult deliverTreatment(Double insulin, Integer carbs, Context context) {
return new PumpEnactResult();
}
@Override
public void stopBolusDelivering() {
}
@Override
public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes) {
return new PumpEnactResult();
}
@Override
public PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes) {
return new PumpEnactResult();
}
@Override
public PumpEnactResult setExtendedBolus(Double insulin, Integer durationInMinutes) {
return new PumpEnactResult();
}
@Override
public PumpEnactResult cancelTempBasal() {
return new PumpEnactResult();
}
@Override
public PumpEnactResult cancelExtendedBolus() {
return new PumpEnactResult();
}
@Override
public JSONObject getJSONStatus() {
return new JSONObject();
}
@Override
public String deviceID() {
return "MM640G"; // TODO: probably serial goes here
}
}

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.plugins.NSProfileViewer; package info.nightscout.androidaps.plugins.NSProfile;
import android.app.Activity; import android.app.Activity;
import android.os.Bundle; import android.os.Bundle;
@ -13,14 +13,14 @@ import com.squareup.otto.Subscribe;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.interfaces.FragmentBase; import info.nightscout.androidaps.interfaces.FragmentBase;
import info.nightscout.androidaps.plugins.NSProfileViewer.events.EventNSProfileViewerUpdateGUI; import info.nightscout.androidaps.plugins.NSProfile.events.EventNSProfileUpdateGUI;
import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.DecimalFormatter;
public class NSProfileViewerFragment extends Fragment implements FragmentBase { public class NSProfileFragment extends Fragment implements FragmentBase {
private static NSProfileViewerPlugin nsProfileViewerPlugin = new NSProfileViewerPlugin(); private static NSProfilePlugin nsProfilePlugin = new NSProfilePlugin();
public static NSProfileViewerPlugin getPlugin() { public static NSProfilePlugin getPlugin() {
return nsProfileViewerPlugin; return nsProfilePlugin;
} }
private static TextView noProfile; private static TextView noProfile;
@ -63,7 +63,7 @@ public class NSProfileViewerFragment extends Fragment implements FragmentBase {
} }
@Subscribe @Subscribe
public void onStatusEvent(final EventNSProfileViewerUpdateGUI ev) { public void onStatusEvent(final EventNSProfileUpdateGUI ev) {
Activity activity = getActivity(); Activity activity = getActivity();
if (activity != null) if (activity != null)
activity.runOnUiThread(new Runnable() { activity.runOnUiThread(new Runnable() {
@ -75,19 +75,19 @@ public class NSProfileViewerFragment extends Fragment implements FragmentBase {
} }
private void updateGUI() { private void updateGUI() {
if (nsProfileViewerPlugin.profile == null) { if (nsProfilePlugin.profile == null) {
noProfile.setVisibility(View.VISIBLE); noProfile.setVisibility(View.VISIBLE);
return; return;
} else { } else {
noProfile.setVisibility(View.GONE); noProfile.setVisibility(View.GONE);
} }
units.setText(nsProfileViewerPlugin.profile.getUnits()); units.setText(nsProfilePlugin.profile.getUnits());
dia.setText(DecimalFormatter.to2Decimal(nsProfileViewerPlugin.profile.getDia()) + " h"); dia.setText(DecimalFormatter.to2Decimal(nsProfilePlugin.profile.getDia()) + " h");
activeProfile.setText(nsProfileViewerPlugin.profile.getActiveProfile()); activeProfile.setText(nsProfilePlugin.profile.getActiveProfile());
ic.setText(nsProfileViewerPlugin.profile.getIcList()); ic.setText(nsProfilePlugin.profile.getIcList());
isf.setText(nsProfileViewerPlugin.profile.getIsfList()); isf.setText(nsProfilePlugin.profile.getIsfList());
basal.setText(nsProfileViewerPlugin.profile.getBasalList()); basal.setText(nsProfilePlugin.profile.getBasalList());
target.setText(nsProfileViewerPlugin.profile.getTargetList()); target.setText(nsProfilePlugin.profile.getTargetList());
} }
} }

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.plugins.NSProfileViewer; package info.nightscout.androidaps.plugins.NSProfile;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
@ -19,18 +19,18 @@ import info.nightscout.androidaps.Services.Intents;
import info.nightscout.androidaps.events.EventNewBasalProfile; import info.nightscout.androidaps.events.EventNewBasalProfile;
import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.ProfileInterface; import info.nightscout.androidaps.interfaces.ProfileInterface;
import info.nightscout.androidaps.plugins.NSProfileViewer.events.EventNSProfileViewerUpdateGUI; import info.nightscout.androidaps.plugins.NSProfile.events.EventNSProfileUpdateGUI;
import info.nightscout.client.data.NSProfile; import info.nightscout.client.data.NSProfile;
/** /**
* Created by mike on 05.08.2016. * Created by mike on 05.08.2016.
*/ */
public class NSProfileViewerPlugin implements PluginBase, ProfileInterface { public class NSProfilePlugin implements PluginBase, ProfileInterface {
private static Logger log = LoggerFactory.getLogger(NSProfileViewerPlugin.class); private static Logger log = LoggerFactory.getLogger(NSProfilePlugin.class);
@Override @Override
public String getFragmentClass() { public String getFragmentClass() {
return NSProfileViewerFragment.class.getName(); return NSProfileFragment.class.getName();
} }
static boolean fragmentEnabled = true; static boolean fragmentEnabled = true;
@ -38,7 +38,7 @@ public class NSProfileViewerPlugin implements PluginBase, ProfileInterface {
static NSProfile profile = null; static NSProfile profile = null;
public NSProfileViewerPlugin() { public NSProfilePlugin() {
MainApp.bus().register(this); MainApp.bus().register(this);
loadNSProfile(); loadNSProfile();
@ -51,12 +51,12 @@ public class NSProfileViewerPlugin implements PluginBase, ProfileInterface {
@Override @Override
public boolean isEnabled(int type) { public boolean isEnabled(int type) {
return fragmentEnabled; return type == PROFILE && fragmentEnabled;
} }
@Override @Override
public boolean isVisibleInTabs(int type) { public boolean isVisibleInTabs(int type) {
return fragmentVisible; return type == PROFILE && fragmentVisible;
} }
@Override @Override
@ -66,12 +66,12 @@ public class NSProfileViewerPlugin implements PluginBase, ProfileInterface {
@Override @Override
public void setFragmentEnabled(int type, boolean fragmentEnabled) { public void setFragmentEnabled(int type, boolean fragmentEnabled) {
this.fragmentEnabled = fragmentEnabled; if (type == PROFILE) this.fragmentEnabled = fragmentEnabled;
} }
@Override @Override
public void setFragmentVisible(int type, boolean fragmentVisible) { public void setFragmentVisible(int type, boolean fragmentVisible) {
this.fragmentVisible = fragmentVisible; if (type == PROFILE) this.fragmentVisible = fragmentVisible;
} }
@Override @Override
@ -83,7 +83,7 @@ public class NSProfileViewerPlugin implements PluginBase, ProfileInterface {
public void onStatusEvent(final EventNewBasalProfile ev) { public void onStatusEvent(final EventNewBasalProfile ev) {
profile = new NSProfile(ev.newNSProfile.getData(), ev.newNSProfile.getActiveProfile()); profile = new NSProfile(ev.newNSProfile.getData(), ev.newNSProfile.getActiveProfile());
storeNSProfile(); storeNSProfile();
MainApp.bus().post(new EventNSProfileViewerUpdateGUI()); MainApp.bus().post(new EventNSProfileUpdateGUI());
} }
private void storeNSProfile() { private void storeNSProfile() {

View file

@ -0,0 +1,7 @@
package info.nightscout.androidaps.plugins.NSProfile.events;
/**
* Created by mike on 05.08.2016.
*/
public class EventNSProfileUpdateGUI {
}

View file

@ -1,7 +0,0 @@
package info.nightscout.androidaps.plugins.NSProfileViewer.events;
/**
* Created by mike on 05.08.2016.
*/
public class EventNSProfileViewerUpdateGUI {
}

View file

@ -51,13 +51,13 @@ public class ObjectivesPlugin implements PluginBase, ConstraintsInterface {
@Override @Override
public boolean isEnabled(int type) { public boolean isEnabled(int type) {
return true; return type == CONSTRAINTS;
} }
@Override @Override
public boolean isVisibleInTabs(int type) { public boolean isVisibleInTabs(int type) {
LoopPlugin loopPlugin = (LoopPlugin) MainApp.getSpecificPlugin(LoopPlugin.class); LoopPlugin loopPlugin = (LoopPlugin) MainApp.getSpecificPlugin(LoopPlugin.class);
return fragmentVisible && loopPlugin != null && loopPlugin.isVisibleInTabs(type); return type == CONSTRAINTS && fragmentVisible && loopPlugin != null && loopPlugin.isVisibleInTabs(LOOP);
} }
@Override @Override
@ -71,7 +71,7 @@ public class ObjectivesPlugin implements PluginBase, ConstraintsInterface {
@Override @Override
public void setFragmentVisible(int type, boolean fragmentVisible) { public void setFragmentVisible(int type, boolean fragmentVisible) {
this.fragmentVisible = fragmentVisible; if (type == CONSTRAINTS) this.fragmentVisible = fragmentVisible;
} }
public class Objective { public class Objective {

View file

@ -58,12 +58,12 @@ public class OpenAPSMAPlugin implements PluginBase, APSInterface {
@Override @Override
public boolean isEnabled(int type) { public boolean isEnabled(int type) {
return fragmentEnabled; return type == APS && fragmentEnabled;
} }
@Override @Override
public boolean isVisibleInTabs(int type) { public boolean isVisibleInTabs(int type) {
return fragmentVisible; return type == APS && fragmentVisible;
} }
@Override @Override
@ -73,12 +73,12 @@ public class OpenAPSMAPlugin implements PluginBase, APSInterface {
@Override @Override
public void setFragmentVisible(int type, boolean fragmentVisible) { public void setFragmentVisible(int type, boolean fragmentVisible) {
this.fragmentVisible = fragmentVisible; if (type == APS) this.fragmentVisible = fragmentVisible;
} }
@Override @Override
public void setFragmentEnabled(int type, boolean fragmentEnabled) { public void setFragmentEnabled(int type, boolean fragmentEnabled) {
this.fragmentEnabled = fragmentEnabled; if (type == APS) this.fragmentEnabled = fragmentEnabled;
} }
@Override @Override
@ -235,7 +235,7 @@ public class OpenAPSMAPlugin implements PluginBase, APSInterface {
if (value < lowLimit || value > highLimit) { if (value < lowLimit || value > highLimit) {
String msg = String.format(MainApp.sResources.getString(R.string.openapsma_valueoutofrange), valueName); String msg = String.format(MainApp.sResources.getString(R.string.openapsma_valueoutofrange), valueName);
log.error(msg); log.error(msg);
sendErrorToNSClient(msg); MainApp.getConfigBuilder().uploadError(msg);
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), msg, R.raw.error); ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), msg, R.raw.error);
value = Math.max(value, lowLimit); value = Math.max(value, lowLimit);
value = Math.min(value, highLimit); value = Math.min(value, highLimit);
@ -243,26 +243,4 @@ public class OpenAPSMAPlugin implements PluginBase, APSInterface {
return value; return value;
} }
public static void sendErrorToNSClient(String error) {
Context context = MainApp.instance().getApplicationContext();
Bundle bundle = new Bundle();
bundle.putString("action", "dbAdd");
bundle.putString("collection", "treatments");
JSONObject data = new JSONObject();
try {
data.put("eventType", "Announcement");
data.put("created_at", DateUtil.toISOString(new Date()));
data.put("notes", error);
data.put("isAnnouncement", true);
} catch (JSONException e) {
e.printStackTrace();
}
bundle.putString("data", data.toString());
Intent intent = new Intent(Intents.ACTION_DATABASE);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
context.sendBroadcast(intent);
DbLogger.dbAdd(intent, data.toString(), OpenAPSMAPlugin.class);
}
} }

View file

@ -380,7 +380,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener {
correctionInsulin.setText(DecimalFormatter.to2Decimal(wizard.insulinFromCorrection) + "U"); correctionInsulin.setText(DecimalFormatter.to2Decimal(wizard.insulinFromCorrection) + "U");
calculatedTotalInsulin = wizard.calculatedTotalInsulin; calculatedTotalInsulin = wizard.calculatedTotalInsulin;
if (calculatedTotalInsulin < 0) { if (calculatedTotalInsulin <= 0) {
total.setText(getString(R.string.missing) + " " + DecimalFormatter.to0Decimal(wizard.carbsEquivalent) + "g"); total.setText(getString(R.string.missing) + " " + DecimalFormatter.to0Decimal(wizard.carbsEquivalent) + "g");
totalInsulin.setText(""); totalInsulin.setText("");
} else { } else {

View file

@ -12,9 +12,45 @@ public class Notification {
public static final int LOW = 2; public static final int LOW = 2;
public static final int INFO = 3; public static final int INFO = 3;
public static final int PROFILE_SET_FAILED = 0;
public static final int PROFILE_SET_OK = 1;
public static final int EASYMODE_ENABLED = 2;
public static final int EXTENDED_BOLUS_DISABLED = 3;
public static final int UD_MODE_ENABLED = 4;
public static final int PROFILE_NOT_SET_NOT_INITIALIZED = 5;
public static final int FAILED_UDPATE_PROFILE = 6;
public static final int BASAL_VALUE_BELOW_MINIMUM = 7;
public int id; public int id;
Date date; public Date date;
String text; public String text;
Date validTo = new Date(0); public int level;
int level; public Date validTo = new Date(0);
public Notification() {
}
public Notification(int id, Date date, String text, int level, Date validTo) {
this.id = id;
this.date = date;
this.text = text;
this.level = level;
this.validTo = validTo;
}
public Notification(int id, String text, int level, int validMinutes) {
this.id = id;
this.date = new Date();
this.text = text;
this.level = level;
this.validTo = new Date(new Date().getTime() + validMinutes * 60 * 1000L);
}
public Notification(int id, String text, int level) {
this.id = id;
this.date = new Date();
this.text = text;
this.level = level;
this.validTo = new Date(0);
}
} }

View file

@ -1,5 +1,8 @@
package info.nightscout.androidaps.plugins.Overview; package info.nightscout.androidaps.plugins.Overview;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
@ -12,6 +15,7 @@ import java.util.List;
*/ */
public class NotificationStore { public class NotificationStore {
private static Logger log = LoggerFactory.getLogger(NotificationStore.class);
public List<Notification> store = new ArrayList<Notification>(); public List<Notification> store = new ArrayList<Notification>();
public NotificationStore() { public NotificationStore() {
@ -29,6 +33,7 @@ public class NotificationStore {
} }
public void add(Notification n) { public void add(Notification n) {
log.info("Notification received: " + n.text);
for (int i = 0; i < store.size(); i++) { for (int i = 0; i < store.size(); i++) {
if (get(i).id == n.id) { if (get(i).id == n.id) {
get(i).date = n.date; get(i).date = n.date;

View file

@ -55,6 +55,7 @@ import info.nightscout.androidaps.db.BgReading;
import info.nightscout.androidaps.db.DatabaseHelper; import info.nightscout.androidaps.db.DatabaseHelper;
import info.nightscout.androidaps.db.TempBasal; import info.nightscout.androidaps.db.TempBasal;
import info.nightscout.androidaps.db.Treatment; import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.events.EventInitializationChanged;
import info.nightscout.androidaps.events.EventNewBG; import info.nightscout.androidaps.events.EventNewBG;
import info.nightscout.androidaps.events.EventNewBasalProfile; import info.nightscout.androidaps.events.EventNewBasalProfile;
import info.nightscout.androidaps.events.EventPreferenceChange; import info.nightscout.androidaps.events.EventPreferenceChange;
@ -364,6 +365,11 @@ public class OverviewFragment extends Fragment {
updateGUIIfVisible(); updateGUIIfVisible();
} }
@Subscribe
public void onStatusEvent(final EventInitializationChanged ev) {
updateGUIIfVisible();
}
@Subscribe @Subscribe
public void onStatusEvent(final EventPreferenceChange ev) { public void onStatusEvent(final EventPreferenceChange ev) {
updateGUIIfVisible(); updateGUIIfVisible();
@ -486,22 +492,22 @@ public class OverviewFragment extends Fragment {
apsModeView.setVisibility(View.GONE); apsModeView.setVisibility(View.GONE);
} }
// **** Temp button ****
NSProfile profile = MainApp.getConfigBuilder().getActiveProfile().getProfile();
PumpInterface pump = MainApp.getConfigBuilder();
boolean showAcceptButton = !MainApp.getConfigBuilder().isClosedModeEnabled(); // Open mode needed boolean showAcceptButton = !MainApp.getConfigBuilder().isClosedModeEnabled(); // Open mode needed
showAcceptButton = showAcceptButton && finalLastRun != null && finalLastRun.lastAPSRun != null; // aps result must exist showAcceptButton = showAcceptButton && finalLastRun != null && finalLastRun.lastAPSRun != null; // aps result must exist
showAcceptButton = showAcceptButton && (finalLastRun.lastOpenModeAccept == null || finalLastRun.lastOpenModeAccept.getTime() < finalLastRun.lastAPSRun.getTime()); // never accepted or before last result showAcceptButton = showAcceptButton && (finalLastRun.lastOpenModeAccept == null || finalLastRun.lastOpenModeAccept.getTime() < finalLastRun.lastAPSRun.getTime()); // never accepted or before last result
showAcceptButton = showAcceptButton && finalLastRun.constraintsProcessed.changeRequested; // change is requested showAcceptButton = showAcceptButton && finalLastRun.constraintsProcessed.changeRequested; // change is requested
if (showAcceptButton) { if (showAcceptButton && pump.isInitialized()) {
acceptTempLayout.setVisibility(View.VISIBLE); acceptTempLayout.setVisibility(View.VISIBLE);
acceptTempButton.setText(getContext().getString(R.string.setbasalquestion) + "\n" + finalLastRun.constraintsProcessed); acceptTempButton.setText(getContext().getString(R.string.setbasalquestion) + "\n" + finalLastRun.constraintsProcessed);
} else { } else {
acceptTempLayout.setVisibility(View.GONE); acceptTempLayout.setVisibility(View.GONE);
} }
// **** Temp button ****
NSProfile profile = MainApp.getConfigBuilder().getActiveProfile().getProfile();
PumpInterface pump = MainApp.getConfigBuilder();
if (pump.isTempBasalInProgress()) { if (pump.isTempBasalInProgress()) {
TempBasal activeTemp = pump.getTempBasal(); TempBasal activeTemp = pump.getTempBasal();
cancelTempLayout.setVisibility(View.VISIBLE); cancelTempLayout.setVisibility(View.VISIBLE);
@ -531,7 +537,7 @@ public class OverviewFragment extends Fragment {
}); });
activeProfileView.setLongClickable(true); activeProfileView.setLongClickable(true);
if (profile == null) { if (profile == null || !pump.isInitialized()) {
// disable all treatment buttons because we are not able to check constraints without profile // disable all treatment buttons because we are not able to check constraints without profile
wizardButton.setVisibility(View.INVISIBLE); wizardButton.setVisibility(View.INVISIBLE);
treatmentButton.setVisibility(View.INVISIBLE); treatmentButton.setVisibility(View.INVISIBLE);
@ -545,7 +551,7 @@ public class OverviewFragment extends Fragment {
// QuickWizard button // QuickWizard button
QuickWizard.QuickWizardEntry quickWizardEntry = getPlugin().quickWizard.getActive(); QuickWizard.QuickWizardEntry quickWizardEntry = getPlugin().quickWizard.getActive();
if (quickWizardEntry != null && lastBG != null) { if (quickWizardEntry != null && lastBG != null && pump.isInitialized()) {
quickWizardLayout.setVisibility(View.VISIBLE); quickWizardLayout.setVisibility(View.VISIBLE);
String text = MainApp.sResources.getString(R.string.bolus) + ": " + quickWizardEntry.buttonText() + " " + DecimalFormatter.to0Decimal(quickWizardEntry.carbs()) + "g"; String text = MainApp.sResources.getString(R.string.bolus) + ": " + quickWizardEntry.buttonText() + " " + DecimalFormatter.to0Decimal(quickWizardEntry.carbs()) + "g";
BolusWizard wizard = new BolusWizard(); BolusWizard wizard = new BolusWizard();
@ -677,6 +683,13 @@ public class OverviewFragment extends Fragment {
} }
}); });
// set manual x bounds to have nice steps
bgGraph.getViewport().setMaxX(toTime);
bgGraph.getViewport().setMinX(fromTime);
bgGraph.getViewport().setXAxisBoundsManual(true);
bgGraph.getGridLabelRenderer().setLabelFormatter(new TimeAsXAxisLabelFormatter(getActivity(), "HH"));
bgGraph.getGridLabelRenderer().setNumHorizontalLabels(7); // only 7 because of the space
// **** BG graph **** // **** BG graph ****
List<BgReading> bgReadingsArray = MainApp.getDbHelper().getDataFromTime(fromTime); List<BgReading> bgReadingsArray = MainApp.getDbHelper().getDataFromTime(fromTime);
List<BgReading> inRangeArray = new ArrayList<BgReading>(); List<BgReading> inRangeArray = new ArrayList<BgReading>();
@ -757,13 +770,6 @@ public class OverviewFragment extends Fragment {
seriesTreatments.setColor(Color.CYAN); seriesTreatments.setColor(Color.CYAN);
} }
// set manual x bounds to have nice steps
bgGraph.getViewport().setMaxX(toTime);
bgGraph.getViewport().setMinX(fromTime);
bgGraph.getViewport().setXAxisBoundsManual(true);
bgGraph.getGridLabelRenderer().setLabelFormatter(new TimeAsXAxisLabelFormatter(getActivity(), "HH"));
bgGraph.getGridLabelRenderer().setNumHorizontalLabels(7); // only 7 because of the space
// set manual y bounds to have nice steps // set manual y bounds to have nice steps
bgGraph.getViewport().setMaxY(maxBgValue); bgGraph.getViewport().setMaxY(maxBgValue);
bgGraph.getViewport().setMinY(0); bgGraph.getViewport().setMinY(0);

View file

@ -49,7 +49,7 @@ public class OverviewPlugin implements PluginBase {
@Override @Override
public boolean isEnabled(int type) { public boolean isEnabled(int type) {
return true; return type == GENERAL;
} }
@Override @Override

View file

@ -40,7 +40,7 @@ public class SafetyPlugin implements PluginBase, ConstraintsInterface {
@Override @Override
public boolean isEnabled(int type) { public boolean isEnabled(int type) {
return true; return type == CONSTRAINTS;
} }
@Override @Override
@ -54,7 +54,7 @@ public class SafetyPlugin implements PluginBase, ConstraintsInterface {
} }
@Override @Override
public void setFragmentEnabled(int tyep, boolean fragmentEnabled) { public void setFragmentEnabled(int type, boolean fragmentEnabled) {
} }
@ -64,7 +64,7 @@ public class SafetyPlugin implements PluginBase, ConstraintsInterface {
@Override @Override
public boolean isLoopEnabled() { public boolean isLoopEnabled() {
return true; return MainApp.getConfigBuilder().getPumpDescription().isTempBasalCapable;
} }
/** /**

View file

@ -1,6 +1,7 @@
package info.nightscout.androidaps.plugins.SimpleProfile; package info.nightscout.androidaps.plugins.SimpleProfile;
import android.app.Activity;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.text.Editable; import android.text.Editable;
@ -8,14 +9,22 @@ import android.text.TextWatcher;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.RadioButton; import android.widget.RadioButton;
import com.squareup.otto.Subscribe;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.events.EventInitializationChanged;
import info.nightscout.androidaps.interfaces.FragmentBase; import info.nightscout.androidaps.interfaces.FragmentBase;
import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialog;
import info.nightscout.androidaps.plugins.Careportal.OptionsToShow;
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
import info.nightscout.utils.SafeParse; import info.nightscout.utils.SafeParse;
public class SimpleProfileFragment extends Fragment implements FragmentBase { public class SimpleProfileFragment extends Fragment implements FragmentBase {
@ -36,6 +45,7 @@ public class SimpleProfileFragment extends Fragment implements FragmentBase {
EditText basalView; EditText basalView;
EditText targetlowView; EditText targetlowView;
EditText targethighView; EditText targethighView;
Button profileswitchButton;
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
@ -50,6 +60,9 @@ public class SimpleProfileFragment extends Fragment implements FragmentBase {
basalView = (EditText) layout.findViewById(R.id.simpleprofile_basalrate); basalView = (EditText) layout.findViewById(R.id.simpleprofile_basalrate);
targetlowView = (EditText) layout.findViewById(R.id.simpleprofile_targetlow); targetlowView = (EditText) layout.findViewById(R.id.simpleprofile_targetlow);
targethighView = (EditText) layout.findViewById(R.id.simpleprofile_targethigh); targethighView = (EditText) layout.findViewById(R.id.simpleprofile_targethigh);
profileswitchButton = (Button) layout.findViewById(R.id.simpleprofile_profileswitch);
onStatusEvent(null);
mgdlView.setChecked(simpleProfilePlugin.mgdl); mgdlView.setChecked(simpleProfilePlugin.mgdl);
mmolView.setChecked(simpleProfilePlugin.mmol); mmolView.setChecked(simpleProfilePlugin.mmol);
@ -80,6 +93,17 @@ public class SimpleProfileFragment extends Fragment implements FragmentBase {
} }
}); });
profileswitchButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
NewNSTreatmentDialog newDialog = new NewNSTreatmentDialog();
final OptionsToShow profileswitch = new OptionsToShow(R.id.careportal_profileswitch, R.string.careportal_profileswitch, true, false, false, false, false, false, false, true, false);
profileswitch.executeProfileSwitch = true;
newDialog.setOptions(profileswitch);
newDialog.show(getFragmentManager(), "NewNSTreatmentDialog");
}
});
TextWatcher textWatch = new TextWatcher() { TextWatcher textWatch = new TextWatcher() {
@Override @Override
@ -115,4 +139,32 @@ public class SimpleProfileFragment extends Fragment implements FragmentBase {
return layout; return layout;
} }
@Override
public void onPause() {
super.onPause();
MainApp.bus().unregister(this);
}
@Override
public void onResume() {
super.onResume();
MainApp.bus().register(this);
}
@Subscribe
public void onStatusEvent(final EventInitializationChanged e) {
Activity activity = getActivity();
if (activity != null)
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
if (!MainApp.getConfigBuilder().isInitialized()) {
profileswitchButton.setVisibility(View.GONE);
} else {
profileswitchButton.setVisibility(View.VISIBLE);
}
}
});
}
} }

View file

@ -60,12 +60,12 @@ public class SimpleProfilePlugin implements PluginBase, ProfileInterface {
@Override @Override
public boolean isEnabled(int type) { public boolean isEnabled(int type) {
return fragmentEnabled; return type == PROFILE && fragmentEnabled;
} }
@Override @Override
public boolean isVisibleInTabs(int type) { public boolean isVisibleInTabs(int type) {
return fragmentVisible; return type == PROFILE && fragmentVisible;
} }
@Override @Override
@ -75,12 +75,12 @@ public class SimpleProfilePlugin implements PluginBase, ProfileInterface {
@Override @Override
public void setFragmentEnabled(int type, boolean fragmentEnabled) { public void setFragmentEnabled(int type, boolean fragmentEnabled) {
this.fragmentEnabled = fragmentEnabled; if (type == PROFILE) this.fragmentEnabled = fragmentEnabled;
} }
@Override @Override
public void setFragmentVisible(int type, boolean fragmentVisible) { public void setFragmentVisible(int type, boolean fragmentVisible) {
this.fragmentVisible = fragmentVisible; if (type == PROFILE) this.fragmentVisible = fragmentVisible;
} }
public void storeSettings() { public void storeSettings() {

View file

@ -16,18 +16,26 @@ import java.text.Normalizer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.StringTokenizer;
import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.Services.Intents; import info.nightscout.androidaps.Services.Intents;
import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.BgReading;
import info.nightscout.androidaps.db.DatabaseHelper;
import info.nightscout.androidaps.events.EventPreferenceChange;
import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.DanaR.DanaRPlugin; import info.nightscout.androidaps.plugins.DanaR.DanaRPlugin;
import info.nightscout.androidaps.plugins.DanaRKorean.DanaRKoreanPlugin;
import info.nightscout.androidaps.plugins.Loop.LoopPlugin; import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
import info.nightscout.androidaps.plugins.OpenAPSMA.IobTotal;
import info.nightscout.androidaps.plugins.SmsCommunicator.events.EventNewSMS; import info.nightscout.androidaps.plugins.SmsCommunicator.events.EventNewSMS;
import info.nightscout.androidaps.plugins.SmsCommunicator.events.EventSmsCommunicatorUpdateGui; import info.nightscout.androidaps.plugins.SmsCommunicator.events.EventSmsCommunicatorUpdateGui;
import info.nightscout.client.data.NSProfile;
import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.SafeParse; import info.nightscout.utils.SafeParse;
/** /**
@ -41,6 +49,8 @@ public class SmsCommunicatorPlugin implements PluginBase {
final long CONFIRM_TIMEOUT = 5 * 60 * 1000L; final long CONFIRM_TIMEOUT = 5 * 60 * 1000L;
List<String> allowedNumbers = new ArrayList<String>();
public class Sms { public class Sms {
String phoneNumber; String phoneNumber;
String text; String text;
@ -67,6 +77,14 @@ public class SmsCommunicatorPlugin implements PluginBase {
sent = true; sent = true;
} }
public Sms(String phoneNumber, String text, Date date, String confirmCode) {
this.phoneNumber = phoneNumber;
this.text = text;
this.date = date;
this.confirmCode = confirmCode;
sent = true;
}
public String toString() { public String toString() {
return "SMS from " + phoneNumber + ": " + text; return "SMS from " + phoneNumber + ": " + text;
} }
@ -81,6 +99,7 @@ public class SmsCommunicatorPlugin implements PluginBase {
public SmsCommunicatorPlugin() { public SmsCommunicatorPlugin() {
MainApp.bus().register(this); MainApp.bus().register(this);
processSettings(null);
} }
@Override @Override
@ -100,12 +119,12 @@ public class SmsCommunicatorPlugin implements PluginBase {
@Override @Override
public boolean isEnabled(int type) { public boolean isEnabled(int type) {
return fragmentEnabled; return type == GENERAL && fragmentEnabled;
} }
@Override @Override
public boolean isVisibleInTabs(int type) { public boolean isVisibleInTabs(int type) {
return fragmentVisible; return type == GENERAL && fragmentVisible;
} }
@Override @Override
@ -115,12 +134,34 @@ public class SmsCommunicatorPlugin implements PluginBase {
@Override @Override
public void setFragmentEnabled(int type, boolean fragmentEnabled) { public void setFragmentEnabled(int type, boolean fragmentEnabled) {
SmsCommunicatorPlugin.fragmentEnabled = fragmentEnabled; if (type == GENERAL) this.fragmentEnabled = fragmentEnabled;
} }
@Override @Override
public void setFragmentVisible(int type, boolean fragmentVisible) { public void setFragmentVisible(int type, boolean fragmentVisible) {
SmsCommunicatorPlugin.fragmentVisible = fragmentVisible; if (type == GENERAL) this.fragmentVisible = fragmentVisible;
}
@Subscribe
public void processSettings(final EventPreferenceChange ev) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext());
String settings = sharedPreferences.getString("smscommunicator_allowednumbers", "");
String pattern = ";";
String[] substrings = settings.split(pattern);
for (String number : substrings) {
String cleaned = number.replaceAll("\\s+", "");
allowedNumbers.add(cleaned);
log.debug("Found allowed number: " + cleaned);
}
}
boolean isAllowedNumber(String number) {
for (String num : allowedNumbers) {
if (num.equals(number)) return true;
}
return false;
} }
@Subscribe @Subscribe
@ -135,14 +176,13 @@ public class SmsCommunicatorPlugin implements PluginBase {
} }
private void processSms(Sms receivedSms) { private void processSms(Sms receivedSms) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext());
if (!isEnabled(PluginBase.GENERAL)) { if (!isEnabled(PluginBase.GENERAL)) {
log.debug("Ignoring SMS. Plugin disabled."); log.debug("Ignoring SMS. Plugin disabled.");
return; return;
} }
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext()); if (!isAllowedNumber(receivedSms.phoneNumber)) {
String allowedNumbers = sharedPreferences.getString("smscommunicator_allowednumbers", "");
if (!allowedNumbers.contains(receivedSms.phoneNumber)) {
log.debug("Ignoring SMS from: " + receivedSms.phoneNumber + ". Sender not allowed"); log.debug("Ignoring SMS from: " + receivedSms.phoneNumber + ". Sender not allowed");
return; return;
} }
@ -156,10 +196,42 @@ public class SmsCommunicatorPlugin implements PluginBase {
Double amount = 0d; Double amount = 0d;
Double tempBasal = 0d; Double tempBasal = 0d;
String passCode = ""; String passCode = "";
Sms newSms = null;
if (splited.length > 0) { if (splited.length > 0) {
switch (splited[0].toUpperCase()) { switch (splited[0].toUpperCase()) {
case "BG":
BgReading actualBG = MainApp.getDbHelper().actualBg();
BgReading lastBG = MainApp.getDbHelper().lastBg();
NSProfile profile = MainApp.getConfigBuilder().getActiveProfile().getProfile();
String units = profile.getUnits();
Long agoMsec = new Date().getTime() - lastBG.timeIndex;
int agoMin = (int) (agoMsec / 60d / 1000d);
if (actualBG != null) {
reply = MainApp.sResources.getString(R.string.actualbg) + " " + actualBG.valueToUnitsToString(units) + ", ";
} else if (lastBG != null) {
reply = MainApp.sResources.getString(R.string.lastbg) + " " + lastBG.valueToUnitsToString(units) + " " + agoMin + MainApp.sResources.getString(R.string.minago) + ", ";
}
DatabaseHelper.GlucoseStatus glucoseStatus = MainApp.getDbHelper().getGlucoseStatusData();
if (glucoseStatus != null)
reply += MainApp.sResources.getString(R.string.delta) + ": " + NSProfile.toUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units) + " " + units + ", ";
MainApp.getConfigBuilder().getActiveTreatments().updateTotalIOB();
IobTotal bolusIob = MainApp.getConfigBuilder().getActiveTreatments().getLastCalculation().round();
if (bolusIob == null) bolusIob = new IobTotal();
MainApp.getConfigBuilder().getActiveTempBasals().updateTotalIOB();
IobTotal basalIob = MainApp.getConfigBuilder().getActiveTempBasals().getLastCalculation().round();
if (basalIob == null) basalIob = new IobTotal();
reply += MainApp.sResources.getString(R.string.treatments_iob_label_string) + " " + DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U ("
+ MainApp.sResources.getString(R.string.bolus) + ": " + DecimalFormatter.to2Decimal(bolusIob.iob) + "U "
+ MainApp.sResources.getString(R.string.basal) + ": " + DecimalFormatter.to2Decimal(basalIob.basaliob) + "U)";
sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date()));
receivedSms.processed = true;
break;
case "LOOP": case "LOOP":
switch (splited[1].toUpperCase()) { switch (splited[1].toUpperCase()) {
case "STOP": case "STOP":
@ -167,7 +239,7 @@ public class SmsCommunicatorPlugin implements PluginBase {
if (loopPlugin != null && loopPlugin.isEnabled(PluginBase.LOOP)) { if (loopPlugin != null && loopPlugin.isEnabled(PluginBase.LOOP)) {
loopPlugin.setFragmentEnabled(PluginBase.LOOP, false); loopPlugin.setFragmentEnabled(PluginBase.LOOP, false);
reply = MainApp.sResources.getString(R.string.smscommunicator_loophasbeendisabled); reply = MainApp.sResources.getString(R.string.smscommunicator_loophasbeendisabled);
newSms = new Sms(receivedSms.phoneNumber, reply, new Date()); sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date()));
} }
receivedSms.processed = true; receivedSms.processed = true;
break; break;
@ -176,7 +248,7 @@ public class SmsCommunicatorPlugin implements PluginBase {
if (loopPlugin != null && !loopPlugin.isEnabled(PluginBase.LOOP)) { if (loopPlugin != null && !loopPlugin.isEnabled(PluginBase.LOOP)) {
loopPlugin.setFragmentEnabled(PluginBase.LOOP, true); loopPlugin.setFragmentEnabled(PluginBase.LOOP, true);
reply = MainApp.sResources.getString(R.string.smscommunicator_loophasbeenenabled); reply = MainApp.sResources.getString(R.string.smscommunicator_loophasbeenenabled);
newSms = new Sms(receivedSms.phoneNumber, reply, new Date()); sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date()));
} }
receivedSms.processed = true; receivedSms.processed = true;
break; break;
@ -188,7 +260,7 @@ public class SmsCommunicatorPlugin implements PluginBase {
} else { } else {
reply = MainApp.sResources.getString(R.string.smscommunicator_loopisdisabled); reply = MainApp.sResources.getString(R.string.smscommunicator_loopisdisabled);
} }
newSms = new Sms(receivedSms.phoneNumber, reply, new Date()); sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date()));
} }
receivedSms.processed = true; receivedSms.processed = true;
break; break;
@ -202,7 +274,7 @@ public class SmsCommunicatorPlugin implements PluginBase {
MainApp.instance().getApplicationContext().sendBroadcast(restartNSClient); MainApp.instance().getApplicationContext().sendBroadcast(restartNSClient);
List<ResolveInfo> q = MainApp.instance().getApplicationContext().getPackageManager().queryBroadcastReceivers(restartNSClient, 0); List<ResolveInfo> q = MainApp.instance().getApplicationContext().getPackageManager().queryBroadcastReceivers(restartNSClient, 0);
reply = "TERATMENTS REFRESH " + q.size() + " receivers"; reply = "TERATMENTS REFRESH " + q.size() + " receivers";
newSms = new Sms(receivedSms.phoneNumber, reply, new Date()); sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date()));
receivedSms.processed = true; receivedSms.processed = true;
break; break;
} }
@ -214,16 +286,22 @@ public class SmsCommunicatorPlugin implements PluginBase {
MainApp.instance().getApplicationContext().sendBroadcast(restartNSClient); MainApp.instance().getApplicationContext().sendBroadcast(restartNSClient);
List<ResolveInfo> q = MainApp.instance().getApplicationContext().getPackageManager().queryBroadcastReceivers(restartNSClient, 0); List<ResolveInfo> q = MainApp.instance().getApplicationContext().getPackageManager().queryBroadcastReceivers(restartNSClient, 0);
reply = "NSCLIENT RESTART " + q.size() + " receivers"; reply = "NSCLIENT RESTART " + q.size() + " receivers";
newSms = new Sms(receivedSms.phoneNumber, reply, new Date()); sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date()));
receivedSms.processed = true; receivedSms.processed = true;
break; break;
} }
break; break;
case "DANAR": case "DANAR":
DanaRPlugin danaRPlugin = (DanaRPlugin) MainApp.getSpecificPlugin(DanaRPlugin.class); DanaRPlugin danaRPlugin = (DanaRPlugin) MainApp.getSpecificPlugin(DanaRPlugin.class);
if (danaRPlugin != null && danaRPlugin.isEnabled(PluginBase.PUMP)) if (danaRPlugin != null && danaRPlugin.isEnabled(PluginBase.PUMP)) {
reply = danaRPlugin.shortStatus(); reply = danaRPlugin.shortStatus();
newSms = new Sms(receivedSms.phoneNumber, reply, new Date()); sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date()));
}
DanaRKoreanPlugin danaRKoreanPlugin = (DanaRKoreanPlugin) MainApp.getSpecificPlugin(DanaRKoreanPlugin.class);
if (danaRKoreanPlugin != null && danaRKoreanPlugin.isEnabled(PluginBase.PUMP)) {
reply = danaRKoreanPlugin.shortStatus();
sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date()));
}
receivedSms.processed = true; receivedSms.processed = true;
break; break;
case "BASAL": case "BASAL":
@ -234,13 +312,11 @@ public class SmsCommunicatorPlugin implements PluginBase {
passCode = generatePasscode(); passCode = generatePasscode();
reply = String.format(MainApp.sResources.getString(R.string.smscommunicator_basalstopreplywithcode), passCode); reply = String.format(MainApp.sResources.getString(R.string.smscommunicator_basalstopreplywithcode), passCode);
receivedSms.processed = true; receivedSms.processed = true;
newSms = new Sms(receivedSms.phoneNumber, reply, new Date());
newSms.confirmCode = passCode;
resetWaitingMessages(); resetWaitingMessages();
cancelTempBasalWaitingForConfirmation = newSms; sendSMS(cancelTempBasalWaitingForConfirmation = new Sms(receivedSms.phoneNumber, reply, new Date(), passCode));
} else { } else {
reply = MainApp.sResources.getString(R.string.remotebasalnotallowed); reply = MainApp.sResources.getString(R.string.remotebasalnotallowed);
newSms = new Sms(receivedSms.phoneNumber, reply, new Date()); sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date()));
} }
} else { } else {
tempBasal = SafeParse.stringToDouble(splited[1]); tempBasal = SafeParse.stringToDouble(splited[1]);
@ -249,14 +325,12 @@ public class SmsCommunicatorPlugin implements PluginBase {
passCode = generatePasscode(); passCode = generatePasscode();
reply = String.format(MainApp.sResources.getString(R.string.smscommunicator_basalreplywithcode), tempBasal, passCode); reply = String.format(MainApp.sResources.getString(R.string.smscommunicator_basalreplywithcode), tempBasal, passCode);
receivedSms.processed = true; receivedSms.processed = true;
newSms = new Sms(receivedSms.phoneNumber, reply, new Date());
newSms.tempBasal = tempBasal;
newSms.confirmCode = passCode;
resetWaitingMessages(); resetWaitingMessages();
tempBasalWaitingForConfirmation = newSms; sendSMS(tempBasalWaitingForConfirmation = new Sms(receivedSms.phoneNumber, reply, new Date(), passCode));
tempBasalWaitingForConfirmation.tempBasal = tempBasal;
} else { } else {
reply = MainApp.sResources.getString(R.string.remotebasalnotallowed); reply = MainApp.sResources.getString(R.string.remotebasalnotallowed);
newSms = new Sms(receivedSms.phoneNumber, reply, new Date()); sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date()));
} }
} }
} }
@ -264,7 +338,7 @@ public class SmsCommunicatorPlugin implements PluginBase {
case "BOLUS": case "BOLUS":
if (new Date().getTime() - lastRemoteBolusTime.getTime() < Constants.remoteBolusMinDistance) { if (new Date().getTime() - lastRemoteBolusTime.getTime() < Constants.remoteBolusMinDistance) {
reply = MainApp.sResources.getString(R.string.remotebolusnotallowed); reply = MainApp.sResources.getString(R.string.remotebolusnotallowed);
newSms = new Sms(receivedSms.phoneNumber, reply, new Date()); sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date()));
} else if (splited.length > 1) { } else if (splited.length > 1) {
amount = SafeParse.stringToDouble(splited[1]); amount = SafeParse.stringToDouble(splited[1]);
amount = MainApp.getConfigBuilder().applyBolusConstraints(amount); amount = MainApp.getConfigBuilder().applyBolusConstraints(amount);
@ -273,14 +347,12 @@ public class SmsCommunicatorPlugin implements PluginBase {
passCode = generatePasscode(); passCode = generatePasscode();
reply = String.format(MainApp.sResources.getString(R.string.smscommunicator_bolusreplywithcode), amount, passCode); reply = String.format(MainApp.sResources.getString(R.string.smscommunicator_bolusreplywithcode), amount, passCode);
receivedSms.processed = true; receivedSms.processed = true;
newSms = new Sms(receivedSms.phoneNumber, reply, new Date());
newSms.bolusRequested = amount;
newSms.confirmCode = passCode;
resetWaitingMessages(); resetWaitingMessages();
bolusWaitingForConfirmation = newSms; sendSMS(bolusWaitingForConfirmation = new Sms(receivedSms.phoneNumber, reply, new Date(), passCode));
bolusWaitingForConfirmation.bolusRequested = amount;
} else { } else {
reply = MainApp.sResources.getString(R.string.remotebolusnotallowed); reply = MainApp.sResources.getString(R.string.remotebolusnotallowed);
newSms = new Sms(receivedSms.phoneNumber, reply, new Date()); sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date()));
} }
} }
break; break;
@ -296,11 +368,12 @@ public class SmsCommunicatorPlugin implements PluginBase {
reply = String.format(MainApp.sResources.getString(R.string.bolusdelivered), result.bolusDelivered); reply = String.format(MainApp.sResources.getString(R.string.bolusdelivered), result.bolusDelivered);
if (danaRPlugin != null) reply += "\n" + danaRPlugin.shortStatus(); if (danaRPlugin != null) reply += "\n" + danaRPlugin.shortStatus();
lastRemoteBolusTime = new Date(); lastRemoteBolusTime = new Date();
sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply, new Date()));
} else { } else {
reply = MainApp.sResources.getString(R.string.bolusfailed); reply = MainApp.sResources.getString(R.string.bolusfailed);
if (danaRPlugin != null) reply += "\n" + danaRPlugin.shortStatus(); if (danaRPlugin != null) reply += "\n" + danaRPlugin.shortStatus();
sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date()));
} }
newSms = new Sms(receivedSms.phoneNumber, reply, new Date());
} }
} else if (tempBasalWaitingForConfirmation != null && !tempBasalWaitingForConfirmation.processed && } else if (tempBasalWaitingForConfirmation != null && !tempBasalWaitingForConfirmation.processed &&
tempBasalWaitingForConfirmation.confirmCode.equals(splited[0]) && new Date().getTime() - tempBasalWaitingForConfirmation.date.getTime() < CONFIRM_TIMEOUT) { tempBasalWaitingForConfirmation.confirmCode.equals(splited[0]) && new Date().getTime() - tempBasalWaitingForConfirmation.date.getTime() < CONFIRM_TIMEOUT) {
@ -312,11 +385,12 @@ public class SmsCommunicatorPlugin implements PluginBase {
if (result.success) { if (result.success) {
reply = String.format(MainApp.sResources.getString(R.string.smscommunicator_tempbasalset), result.absolute, result.duration); reply = String.format(MainApp.sResources.getString(R.string.smscommunicator_tempbasalset), result.absolute, result.duration);
if (danaRPlugin != null) reply += "\n" + danaRPlugin.shortStatus(); if (danaRPlugin != null) reply += "\n" + danaRPlugin.shortStatus();
sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply, new Date()));
} else { } else {
reply = MainApp.sResources.getString(R.string.smscommunicator_tempbasalfailed); reply = MainApp.sResources.getString(R.string.smscommunicator_tempbasalfailed);
if (danaRPlugin != null) reply += "\n" + danaRPlugin.shortStatus(); if (danaRPlugin != null) reply += "\n" + danaRPlugin.shortStatus();
sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date()));
} }
newSms = new Sms(receivedSms.phoneNumber, reply, new Date());
} }
} else if (cancelTempBasalWaitingForConfirmation != null && !cancelTempBasalWaitingForConfirmation.processed && } else if (cancelTempBasalWaitingForConfirmation != null && !cancelTempBasalWaitingForConfirmation.processed &&
cancelTempBasalWaitingForConfirmation.confirmCode.equals(splited[0]) && new Date().getTime() - cancelTempBasalWaitingForConfirmation.date.getTime() < CONFIRM_TIMEOUT) { cancelTempBasalWaitingForConfirmation.confirmCode.equals(splited[0]) && new Date().getTime() - cancelTempBasalWaitingForConfirmation.date.getTime() < CONFIRM_TIMEOUT) {
@ -328,30 +402,46 @@ public class SmsCommunicatorPlugin implements PluginBase {
if (result.success) { if (result.success) {
reply = String.format(MainApp.sResources.getString(R.string.smscommunicator_tempbasalcanceled)); reply = String.format(MainApp.sResources.getString(R.string.smscommunicator_tempbasalcanceled));
if (danaRPlugin != null) reply += "\n" + danaRPlugin.shortStatus(); if (danaRPlugin != null) reply += "\n" + danaRPlugin.shortStatus();
sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply, new Date()));
} else { } else {
reply = MainApp.sResources.getString(R.string.smscommunicator_tempbasalcancelfailed); reply = MainApp.sResources.getString(R.string.smscommunicator_tempbasalcancelfailed);
if (danaRPlugin != null) reply += "\n" + danaRPlugin.shortStatus(); if (danaRPlugin != null) reply += "\n" + danaRPlugin.shortStatus();
sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date()));
} }
newSms = new Sms(receivedSms.phoneNumber, reply, new Date());
} }
} else { } else {
newSms = new Sms(receivedSms.phoneNumber, MainApp.sResources.getString(R.string.smscommunicator_unknowncommand), new Date()); sendSMS(new Sms(receivedSms.phoneNumber, MainApp.sResources.getString(R.string.smscommunicator_unknowncommand), new Date()));
} }
resetWaitingMessages(); resetWaitingMessages();
break; break;
} }
} }
if (newSms != null) {
SmsManager smsManager = SmsManager.getDefault();
newSms.text = stripAccents(newSms.text);
if (newSms.text.length() > 140) newSms.text = newSms.text.substring(0, 139);
smsManager.sendTextMessage(newSms.phoneNumber, null, newSms.text, null, null);
messages.add(newSms);
}
MainApp.bus().post(new EventSmsCommunicatorUpdateGui()); MainApp.bus().post(new EventSmsCommunicatorUpdateGui());
} }
public void sendNotificationToAllNumbers(String text) {
for (int i = 0; i < allowedNumbers.size(); i++) {
Sms sms = new Sms(allowedNumbers.get(i), text, new Date());
sendSMS(sms);
}
}
public void sendSMSToAllNumbers(Sms sms) {
for (int i = 0; i < allowedNumbers.size(); i++) {
sms.phoneNumber = allowedNumbers.get(i);
sendSMS(sms);
}
}
public void sendSMS(Sms sms) {
SmsManager smsManager = SmsManager.getDefault();
sms.text = stripAccents(sms.text);
if (sms.text.length() > 140) sms.text = sms.text.substring(0, 139);
smsManager.sendTextMessage(sms.phoneNumber, null, sms.text, null, null);
messages.add(sms);
}
private String generatePasscode() { private String generatePasscode() {
int startChar1 = 'A'; // on iphone 1st char is uppercase :) int startChar1 = 'A'; // on iphone 1st char is uppercase :)
String passCode = Character.toString((char) (startChar1 + Math.random() * ('z' - 'a' + 1))); String passCode = Character.toString((char) (startChar1 + Math.random() * ('z' - 'a' + 1)));

View file

@ -28,7 +28,7 @@ public class SourceNSClientPlugin implements PluginBase, BgSourceInterface {
@Override @Override
public boolean isEnabled(int type) { public boolean isEnabled(int type) {
return fragmentEnabled; return type == BGSOURCE && fragmentEnabled;
} }
@Override @Override
@ -43,7 +43,7 @@ public class SourceNSClientPlugin implements PluginBase, BgSourceInterface {
@Override @Override
public void setFragmentEnabled(int type, boolean fragmentEnabled) { public void setFragmentEnabled(int type, boolean fragmentEnabled) {
this.fragmentEnabled = fragmentEnabled; if (type == BGSOURCE) this.fragmentEnabled = fragmentEnabled;
} }
@Override @Override

View file

@ -30,7 +30,7 @@ public class SourceXdripPlugin implements PluginBase, BgSourceInterface {
@Override @Override
public boolean isEnabled(int type) { public boolean isEnabled(int type) {
return fragmentEnabled; return type == BGSOURCE && fragmentEnabled;
} }
@Override @Override
@ -45,7 +45,7 @@ public class SourceXdripPlugin implements PluginBase, BgSourceInterface {
@Override @Override
public void setFragmentEnabled(int type, boolean fragmentEnabled) { public void setFragmentEnabled(int type, boolean fragmentEnabled) {
SourceXdripPlugin.fragmentEnabled = fragmentEnabled; if (type == BGSOURCE) this.fragmentEnabled = fragmentEnabled;
} }
@Override @Override

View file

@ -66,12 +66,12 @@ public class TempBasalsPlugin implements PluginBase, TempBasalsInterface {
@Override @Override
public boolean isEnabled(int type) { public boolean isEnabled(int type) {
return fragmentEnabled; return type == TEMPBASAL && fragmentEnabled;
} }
@Override @Override
public boolean isVisibleInTabs(int type) { public boolean isVisibleInTabs(int type) {
return fragmentVisible; return type == TEMPBASAL && fragmentVisible;
} }
@Override @Override
@ -81,12 +81,12 @@ public class TempBasalsPlugin implements PluginBase, TempBasalsInterface {
@Override @Override
public void setFragmentEnabled(int type, boolean fragmentEnabled) { public void setFragmentEnabled(int type, boolean fragmentEnabled) {
this.fragmentEnabled = fragmentEnabled; if (type == TEMPBASAL) this.fragmentEnabled = fragmentEnabled;
} }
@Override @Override
public void setFragmentVisible(int type, boolean fragmentVisible) { public void setFragmentVisible(int type, boolean fragmentVisible) {
this.fragmentVisible = fragmentVisible; if (type == TEMPBASAL) this.fragmentVisible = fragmentVisible;
} }
@Override @Override

View file

@ -49,12 +49,12 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
@Override @Override
public boolean isEnabled(int type) { public boolean isEnabled(int type) {
return fragmentEnabled; return type == TREATMENT && fragmentEnabled;
} }
@Override @Override
public boolean isVisibleInTabs(int type) { public boolean isVisibleInTabs(int type) {
return fragmentVisible; return type == TREATMENT && fragmentVisible;
} }
@Override @Override
@ -64,12 +64,12 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
@Override @Override
public void setFragmentEnabled(int type, boolean fragmentEnabled) { public void setFragmentEnabled(int type, boolean fragmentEnabled) {
this.fragmentEnabled = fragmentEnabled; if (type == TREATMENT) this.fragmentEnabled = fragmentEnabled;
} }
@Override @Override
public void setFragmentVisible(int type, boolean fragmentVisible) { public void setFragmentVisible(int type, boolean fragmentVisible) {
this.fragmentVisible = fragmentVisible; if (type == TREATMENT) this.fragmentVisible = fragmentVisible;
} }
@Override @Override

View file

@ -17,6 +17,7 @@ import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.TempBasal; import info.nightscout.androidaps.db.TempBasal;
import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.PumpDescription;
import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress; import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress;
import info.nightscout.androidaps.plugins.VirtualPump.events.EventVirtualPumpUpdateGui; import info.nightscout.androidaps.plugins.VirtualPump.events.EventVirtualPumpUpdateGui;
@ -37,6 +38,36 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface {
boolean fragmentEnabled = true; boolean fragmentEnabled = true;
boolean fragmentVisible = true; boolean fragmentVisible = true;
PumpDescription pumpDescription = new PumpDescription();
public VirtualPumpPlugin() {
pumpDescription.isBolusCapable = true;
pumpDescription.bolusStep = 1d;
pumpDescription.isExtendedBolusCapable = true;
pumpDescription.extendedBolusStep = 0.2d;
pumpDescription.isTempBasalCapable = true;
pumpDescription.lowTempBasalStyle = PumpDescription.ABSOLUTE | PumpDescription.PERCENT;
pumpDescription.highTempBasalStyle = PumpDescription.ABSOLUTE | PumpDescription.PERCENT;
pumpDescription.maxHighTempPercent = 600;
pumpDescription.maxHighTempAbsolute = 10;
pumpDescription.lowTempPercentStep = 5;
pumpDescription.lowTempAbsoluteStep = 0.1;
pumpDescription.lowTempPercentDuration = 30;
pumpDescription.lowTempAbsoluteDuration = 30;
pumpDescription.highTempPercentStep = 10;
pumpDescription.highTempAbsoluteStep = 0.05d;
pumpDescription.highTempPercentDuration = 30;
pumpDescription.highTempAbsoluteDuration = 30;
pumpDescription.isSetBasalProfileCapable = true;
pumpDescription.basalStep = 0.01d;
pumpDescription.basalMinimumRate = 0.04d;
pumpDescription.isRefillingCapable = false;
}
@Override @Override
public String getFragmentClass() { public String getFragmentClass() {
return VirtualPumpFragment.class.getName(); return VirtualPumpFragment.class.getName();
@ -49,12 +80,12 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface {
@Override @Override
public boolean isEnabled(int type) { public boolean isEnabled(int type) {
return fragmentEnabled; return type == PUMP && fragmentEnabled;
} }
@Override @Override
public boolean isVisibleInTabs(int type) { public boolean isVisibleInTabs(int type) {
return fragmentVisible; return type == PUMP && fragmentVisible;
} }
@Override @Override
@ -64,12 +95,12 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface {
@Override @Override
public void setFragmentEnabled(int type, boolean fragmentEnabled) { public void setFragmentEnabled(int type, boolean fragmentEnabled) {
this.fragmentEnabled = fragmentEnabled; if (type == PUMP) this.fragmentEnabled = fragmentEnabled;
} }
@Override @Override
public void setFragmentVisible(int type, boolean fragmentVisible) { public void setFragmentVisible(int type, boolean fragmentVisible) {
this.fragmentVisible = fragmentVisible; if (type == PUMP) this.fragmentVisible = fragmentVisible;
} }
@Override @Override
@ -93,8 +124,14 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface {
} }
@Override @Override
public void setNewBasalProfile(NSProfile profile) { public int setNewBasalProfile(NSProfile profile) {
// Do nothing here. we are using MainApp.getConfigBuilder().getActiveProfile().getProfile(); // Do nothing here. we are using MainApp.getConfigBuilder().getActiveProfile().getProfile();
return SUCCESS;
}
@Override
public boolean isThisProfileSet(NSProfile profile) {
return false;
} }
@Override @Override
@ -367,4 +404,9 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface {
return "VirtualPump"; return "VirtualPump";
} }
@Override
public PumpDescription getPumpDescription() {
return pumpDescription;
}
} }

View file

@ -28,7 +28,7 @@ public class WearPlugin implements PluginBase {
private static WatchUpdaterService watchUS; private static WatchUpdaterService watchUS;
private final Context ctx; private final Context ctx;
WearPlugin(Context ctx){ WearPlugin(Context ctx) {
this.ctx = ctx; this.ctx = ctx;
MainApp.bus().register(this); MainApp.bus().register(this);
} }
@ -50,12 +50,12 @@ public class WearPlugin implements PluginBase {
@Override @Override
public boolean isEnabled(int type) { public boolean isEnabled(int type) {
return fragmentEnabled; return type == GENERAL && fragmentEnabled;
} }
@Override @Override
public boolean isVisibleInTabs(int type) { public boolean isVisibleInTabs(int type) {
return fragmentVisible; return type == GENERAL && fragmentVisible;
} }
@Override @Override
@ -65,39 +65,41 @@ public class WearPlugin implements PluginBase {
@Override @Override
public void setFragmentEnabled(int type, boolean fragmentEnabled) { public void setFragmentEnabled(int type, boolean fragmentEnabled) {
WearPlugin.fragmentEnabled = fragmentEnabled; if (type == GENERAL) {
if(watchUS!=null){ this.fragmentEnabled = fragmentEnabled;
watchUS.setSettings(); if (watchUS != null) {
watchUS.setSettings();
}
} }
} }
@Override @Override
public void setFragmentVisible(int type, boolean fragmentVisible) { public void setFragmentVisible(int type, boolean fragmentVisible) {
WearPlugin.fragmentVisible = fragmentVisible; if (type == GENERAL) this.fragmentVisible = fragmentVisible;
} }
private void sendDataToWatch(boolean status, boolean basals, boolean bgValue){ private void sendDataToWatch(boolean status, boolean basals, boolean bgValue) {
if (isEnabled(getType())) { //only start service when this plugin is enabled if (isEnabled(getType())) { //only start service when this plugin is enabled
if(bgValue){ if (bgValue) {
ctx.startService(new Intent(ctx, WatchUpdaterService.class)); ctx.startService(new Intent(ctx, WatchUpdaterService.class));
} }
if(basals){ if (basals) {
ctx.startService(new Intent(ctx, WatchUpdaterService.class).setAction(WatchUpdaterService.ACTION_SEND_BASALS)); ctx.startService(new Intent(ctx, WatchUpdaterService.class).setAction(WatchUpdaterService.ACTION_SEND_BASALS));
} }
if(status){ if (status) {
ctx.startService(new Intent(ctx, WatchUpdaterService.class).setAction(WatchUpdaterService.ACTION_SEND_STATUS)); ctx.startService(new Intent(ctx, WatchUpdaterService.class).setAction(WatchUpdaterService.ACTION_SEND_STATUS));
} }
} }
} }
void resendDataToWatch(){ void resendDataToWatch() {
ctx.startService(new Intent(ctx, WatchUpdaterService.class).setAction(WatchUpdaterService.ACTION_RESEND)); ctx.startService(new Intent(ctx, WatchUpdaterService.class).setAction(WatchUpdaterService.ACTION_RESEND));
} }
void openSettings(){ void openSettings() {
ctx.startService(new Intent(ctx, WatchUpdaterService.class).setAction(WatchUpdaterService.ACTION_OPEN_SETTINGS)); ctx.startService(new Intent(ctx, WatchUpdaterService.class).setAction(WatchUpdaterService.ACTION_OPEN_SETTINGS));
} }
@ -132,11 +134,11 @@ public class WearPlugin implements PluginBase {
return fragmentEnabled; return fragmentEnabled;
} }
public static void registerWatchUpdaterService(WatchUpdaterService wus){ public static void registerWatchUpdaterService(WatchUpdaterService wus) {
watchUS = wus; watchUS = wus;
} }
public static void unRegisterWatchUpdaterService(){ public static void unRegisterWatchUpdaterService() {
watchUS = null; watchUS = null;
} }

View file

@ -27,6 +27,7 @@ import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.plugins.DanaR.DanaRFragment; import info.nightscout.androidaps.plugins.DanaR.DanaRFragment;
import info.nightscout.androidaps.plugins.DanaR.DanaRPlugin; import info.nightscout.androidaps.plugins.DanaR.DanaRPlugin;
import info.nightscout.androidaps.plugins.DanaR.Services.ExecutionService; import info.nightscout.androidaps.plugins.DanaR.Services.ExecutionService;
import info.nightscout.androidaps.plugins.DanaRKorean.DanaRKoreanPlugin;
import info.nightscout.utils.ToastUtils; import info.nightscout.utils.ToastUtils;
public class KeepAliveReceiver extends BroadcastReceiver { public class KeepAliveReceiver extends BroadcastReceiver {
@ -51,6 +52,18 @@ public class KeepAliveReceiver extends BroadcastReceiver {
t.start(); t.start();
} }
} }
final DanaRKoreanPlugin danaRKoreanPlugin = (DanaRKoreanPlugin) MainApp.getSpecificPlugin(DanaRKoreanPlugin.class);
if (danaRKoreanPlugin != null && Config.DANAR && danaRKoreanPlugin.isEnabled(PluginBase.PUMP)) {
if (danaRKoreanPlugin.getDanaRPump().lastConnection.getTime() + 30 * 60 * 1000L < new Date().getTime() && !danaRKoreanPlugin.isConnected() && !danaRKoreanPlugin.isConnecting()) {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
danaRKoreanPlugin.doConnect("KeepAlive");
}
});
t.start();
}
}
wl.release(); wl.release();
} }

View file

@ -300,6 +300,34 @@ public class NSProfile {
return getBasalList(getDefaultProfile()); return getBasalList(getDefaultProfile());
} }
public class BasalValue {
public BasalValue(Integer timeAsSeconds, Double value) {
this.timeAsSeconds = timeAsSeconds;
this.value = value;
}
public Integer timeAsSeconds;
public Double value;
}
public BasalValue[] getBasalValues() {
try {
JSONArray array = getDefaultProfile().getJSONArray("basal");
BasalValue[] ret = new BasalValue[array.length()];
for (Integer index = 0; index < array.length(); index++) {
JSONObject o = array.getJSONObject(index);
Integer tas = o.getInt("timeAsSeconds");
Double value = o.getDouble("value");
ret[index] = new BasalValue(tas, value);
}
return ret;
} catch (JSONException e) {
e.printStackTrace();
}
return new BasalValue[0];
}
public String getBasalList(JSONObject profile) { public String getBasalList(JSONObject profile) {
if (profile != null) { if (profile != null) {
try { try {

View file

@ -1,7 +0,0 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="info.nightscout.androidaps.plugins.MM640g.MM640gFragment">
</FrameLayout>

View file

@ -2,7 +2,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".plugins.NSProfileViewer.NSProfileViewerFragment"> tools:context=".plugins.NSProfile.NSProfileFragment">
<ScrollView <ScrollView
android:layout_width="match_parent" android:layout_width="match_parent"

View file

@ -33,7 +33,7 @@
android:text="Notification text" /> android:text="Notification text" />
<Button <Button
android:text="Dismiss" android:text="@string/dismiss"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="35dp" android:layout_height="35dp"
android:id="@+id/notification_dismiss" android:id="@+id/notification_dismiss"

View file

@ -16,7 +16,7 @@
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Units:" android:text="@string/units"
android:textAppearance="?android:attr/textAppearanceMedium" /> android:textAppearance="?android:attr/textAppearanceMedium" />
@ -25,14 +25,14 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_column="2" android:layout_column="2"
android:text="mgdl" /> android:text="@string/mgdl" />
<RadioButton <RadioButton
android:id="@+id/simpleprofile_mmol" android:id="@+id/simpleprofile_mmol"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_column="3" android:layout_column="3"
android:text="mmol" /> android:text="@string/mmol" />
</TableRow> </TableRow>
@ -43,7 +43,7 @@
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="DIA:" android:text="@string/dia"
android:textAppearance="?android:attr/textAppearanceMedium" /> android:textAppearance="?android:attr/textAppearanceMedium" />
<EditText <EditText
@ -61,7 +61,7 @@
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="IC:" android:text="@string/nsprofileview_ic_label"
android:textAppearance="?android:attr/textAppearanceMedium" /> android:textAppearance="?android:attr/textAppearanceMedium" />
<EditText <EditText
@ -79,7 +79,7 @@
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="ISF:" android:text="@string/nsprofileview_isf_label"
android:textAppearance="?android:attr/textAppearanceMedium" /> android:textAppearance="?android:attr/textAppearanceMedium" />
<EditText <EditText
@ -97,7 +97,7 @@
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Absorption rate:" android:text="@string/absorption_rate"
android:textAppearance="?android:attr/textAppearanceMedium" /> android:textAppearance="?android:attr/textAppearanceMedium" />
<EditText <EditText
@ -115,7 +115,7 @@
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Basal rate:" android:text="@string/basal_rate"
android:textAppearance="?android:attr/textAppearanceMedium" /> android:textAppearance="?android:attr/textAppearanceMedium" />
<EditText <EditText
@ -133,7 +133,7 @@
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Target range:" android:text="@string/target_range"
android:textAppearance="?android:attr/textAppearanceMedium" /> android:textAppearance="?android:attr/textAppearanceMedium" />
<EditText <EditText
@ -150,6 +150,22 @@
android:layout_column="2" android:layout_column="2"
android:inputType="numberDecimal" /> android:inputType="numberDecimal" />
</TableRow> </TableRow>
<Button
android:id="@+id/simpleprofile_profileswitch"
style="?android:attr/buttonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="3dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="3dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:text="@string/send_to_pump"
android:textColor="@color/colorProfileSwitchButton" />
</TableLayout> </TableLayout>
</FrameLayout> </FrameLayout>

View file

@ -280,7 +280,6 @@
<string name="danar_debolus">DE bolus</string> <string name="danar_debolus">DE bolus</string>
<string name="danar_dsbolus">DS bolus</string> <string name="danar_dsbolus">DS bolus</string>
<string name="danar_ebolus">E bolus</string> <string name="danar_ebolus">E bolus</string>
<string name="mm640g">MM 640g</string>
<string name="objectives_0_objective">Настройка на визуализацията и наблюдението, а също и анализиране на базалните нужди и коефициенти</string> <string name="objectives_0_objective">Настройка на визуализацията и наблюдението, а също и анализиране на базалните нужди и коефициенти</string>
<string name="objectives_1_gate">Стартиране в Open loop режим за няколко дни и ръчно прилагане на много временни базали</string> <string name="objectives_1_gate">Стартиране в Open loop режим за няколко дни и ръчно прилагане на много временни базали</string>
<string name="objectives_1_objective">Стартиране на Open Loop </string> <string name="objectives_1_objective">Стартиране на Open Loop </string>

View file

@ -270,7 +270,6 @@
<string name="uploading">Nahrávám</string> <string name="uploading">Nahrávám</string>
<string name="pumpbusy">Pumpa je zaneprázdněna</string> <string name="pumpbusy">Pumpa je zaneprázdněna</string>
<string name="wrongpumppassword">Špatné heslo k pumpě</string> <string name="wrongpumppassword">Špatné heslo k pumpě</string>
<string name="mm640g">MM 640g</string>
<string name="danar_password">Heslo k pumpě</string> <string name="danar_password">Heslo k pumpě</string>
<string name="occlusion">Okluze</string> <string name="occlusion">Okluze</string>
<string name="overview_bolusprogress_delivered">Podáno</string> <string name="overview_bolusprogress_delivered">Podáno</string>
@ -364,4 +363,14 @@
<string name="timeshift_hint">Čas v hodinách, o který bude bazál posunutý.</string> <string name="timeshift_hint">Čas v hodinách, o který bude bazál posunutý.</string>
<string name="units">Jednotky:</string> <string name="units">Jednotky:</string>
<string name="wear">Wear</string> <string name="wear">Wear</string>
<string name="basal_rate">Bazál:</string>
<string name="danar_disableeasymode">Zakázat EasyUI režim v pumpě</string>
<string name="danar_enableextendedbolus">Povolit kombo bolusy v pumpě</string>
<string name="danar_switchtouhmode">Změnit režim z U/d na U/h v pumpě</string>
<string name="danarkoreanpump">Korejská DanaR</string>
<string name="profile_set_failed">Nastavení bazálního profilu selhalo</string>
<string name="profile_set_ok">Bazální profil aktualizován</string>
<string name="pumpNotInitializedProfileNotSet">Pumpa není inicializována, profil nenastaven!</string>
<string name="wrongpumpdriverselected">Vybrán špatný ovladač pumpy</string>
<string name="basalvaluebelowminimum">Hodnota bazálu pod minimem. Nenastaveno!</string>
</resources> </resources>

View file

@ -214,7 +214,6 @@
<string name="glucosetype_sensor">Sensor</string> <string name="glucosetype_sensor">Sensor</string>
<string name="glucosetype_finger">Finger</string> <string name="glucosetype_finger">Finger</string>
<string name="language">Sprache</string> <string name="language">Sprache</string>
<string name="mm640g">MM 640g</string>
<string name="percent">Prozent</string> <string name="percent">Prozent</string>
<string name="reloadprofile">Profil neuladen</string> <string name="reloadprofile">Profil neuladen</string>
<string name="save">Speichern</string> <string name="save">Speichern</string>

View file

@ -236,7 +236,6 @@
<string name="absolute">Absoluto</string> <string name="absolute">Absoluto</string>
<string name="canceltemp">Cancelar basal temporal</string> <string name="canceltemp">Cancelar basal temporal</string>
<string name="smscommunicator">SMS Communicator</string> <string name="smscommunicator">SMS Communicator</string>
<string name="mm640g">MM 640g</string>
<string name="waitingforpumpresult">Esperando resultado</string> <string name="waitingforpumpresult">Esperando resultado</string>
<string name="smscommunicator_allowednumbers">Números de teléfono permitidos</string> <string name="smscommunicator_allowednumbers">Números de teléfono permitidos</string>
<string name="smscommunicator_allowednumbers_summary">XXXXXXXXXX +; + YYYYYYYYYY</string> <string name="smscommunicator_allowednumbers_summary">XXXXXXXXXX +; + YYYYYYYYYY</string>

View file

@ -238,7 +238,6 @@
<string name="absolute">Absolute</string> <string name="absolute">Absolute</string>
<string name="canceltemp">임시기초주입 취소하기</string> <string name="canceltemp">임시기초주입 취소하기</string>
<string name="smscommunicator">SMS 전송</string> <string name="smscommunicator">SMS 전송</string>
<string name="mm640g">MM 640g</string>
<string name="waitingforpumpresult">결과 기다리는 중</string> <string name="waitingforpumpresult">결과 기다리는 중</string>
<string name="smscommunicator_allowednumbers">허가된 전화번호</string> <string name="smscommunicator_allowednumbers">허가된 전화번호</string>
<string name="smscommunicator_allowednumbers_summary">+XXXXXXXXXX;+YYYYYYYYYY</string> <string name="smscommunicator_allowednumbers_summary">+XXXXXXXXXX;+YYYYYYYYYY</string>

View file

@ -241,7 +241,6 @@
<string name="absolute">Absolute</string> <string name="absolute">Absolute</string>
<string name="canceltemp">Cancel temp basal</string> <string name="canceltemp">Cancel temp basal</string>
<string name="smscommunicator">SMS Communicator</string> <string name="smscommunicator">SMS Communicator</string>
<string name="mm640g">MM 640g</string>
<string name="waitingforpumpresult">Waiting for result</string> <string name="waitingforpumpresult">Waiting for result</string>
<string name="smscommunicator_allowednumbers">Allowed phone numbers</string> <string name="smscommunicator_allowednumbers">Allowed phone numbers</string>
<string name="smscommunicator_allowednumbers_summary">+XXXXXXXXXX;+YYYYYYYYYY</string> <string name="smscommunicator_allowednumbers_summary">+XXXXXXXXXX;+YYYYYYYYYY</string>
@ -341,6 +340,7 @@
<string name="ns_upload_only_summary">NS upload only. Not effective on SGV unless a local source like xDrip is selected. Not effective on Profiles while NS-Profiles is used.</string> <string name="ns_upload_only_summary">NS upload only. Not effective on SGV unless a local source like xDrip is selected. Not effective on Profiles while NS-Profiles is used.</string>
<string name="ns_upload_only_enabled">Please deactivate "NS upload only" to use this feature.</string> <string name="ns_upload_only_enabled">Please deactivate "NS upload only" to use this feature.</string>
<string name="pumpNotInitialized">Pump not initialized!</string> <string name="pumpNotInitialized">Pump not initialized!</string>
<string name="pumpNotInitializedProfileNotSet">Pump not initialized, profile not set!</string>
<string name="primefill">Prime/Fill</string> <string name="primefill">Prime/Fill</string>
<string name="fillwarning">Please make sure the amount matches the specification of your infusion set!</string> <string name="fillwarning">Please make sure the amount matches the specification of your infusion set!</string>
<string name="othersettings_title">Other</string> <string name="othersettings_title">Other</string>
@ -375,4 +375,15 @@
<string name="lowbattery">Low Battery</string> <string name="lowbattery">Low Battery</string>
<string name="pumpshutdown">Pump Shutdown</string> <string name="pumpshutdown">Pump Shutdown</string>
<string name="batterydischarged">Pump Battery Discharged</string> <string name="batterydischarged">Pump Battery Discharged</string>
<string name="danarkoreanpump">DanaR Korean</string>
<string name="wrongpumpdriverselected">Wrong pump driver selected</string>
<string name="basal_rate">Basal rate:</string>
<string name="profile_set_failed">Setting of basal profile failed</string>
<string name="profile_set_ok">Basal profile in pump updated</string>
<string name="danar_disableeasymode">Disable EasyUI mode in pump</string>
<string name="danar_enableextendedbolus">Enable extended boluses on pump</string>
<string name="danar_switchtouhmode">Change mode from U/d to U/h on pump</string>
<string name="basalvaluebelowminimum">Basal value below minimum. Profile not set!</string>
<string name="actualbg">BG:</string>
<string name="lastbg">Last BG:</string>
</resources> </resources>

View file

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:key="mm640g"
android:title="@string/mm640g">
</PreferenceCategory>
</PreferenceScreen>

View file

@ -1,15 +0,0 @@
package info.nightscout.androidaps;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* To work on unit tests, switch the Test Artifact in the Build Variants view.
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() throws Exception {
assertEquals(4, 2 + 2);
}
}

View file

@ -66,14 +66,6 @@
<sourceFolder url="file://$MODULE_DIR$/src/full/jni" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/full/jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/full/rs" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/full/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/full/shaders" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/full/shaders" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/testFull/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testFull/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testFull/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testFull/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testFull/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testFull/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testFull/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testFull/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestFull/res" type="java-test-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTestFull/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestFull/resources" type="java-test-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTestFull/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestFull/assets" type="java-test-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTestFull/assets" type="java-test-resource" />
@ -82,6 +74,14 @@
<sourceFolder url="file://$MODULE_DIR$/src/androidTestFull/jni" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTestFull/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestFull/rs" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTestFull/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestFull/shaders" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTestFull/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testFull/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testFull/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testFull/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testFull/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testFull/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testFull/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testFull/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testFull/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
@ -106,14 +106,6 @@
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/shaders" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/main/shaders" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
@ -122,9 +114,15 @@
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/recyclerview-v7/23.0.1/jars" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/recyclerview-v7/23.0.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-v4/23.0.1/jars" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-v4/23.0.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.google.android.gms/play-services-base/7.3.0/jars" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.google.android.gms/play-services-base/7.3.0/jars" />
@ -133,13 +131,11 @@
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/me.denley.wearpreferenceactivity/wearpreferenceactivity/0.5.0/jars" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/me.denley.wearpreferenceactivity/wearpreferenceactivity/0.5.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/ustwo-clockwise-debug/jars" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/ustwo-clockwise-debug/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-safeguard" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
<excludeFolder url="file://$MODULE_DIR$/build/outputs" /> <excludeFolder url="file://$MODULE_DIR$/build/outputs" />
<excludeFolder url="file://$MODULE_DIR$/build/tmp" />
</content> </content>
<orderEntry type="jdk" jdkName="Android API 23 Platform" jdkType="Android SDK" /> <orderEntry type="jdk" jdkName="Android API 23 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />