Merge pull request #6 from MilosKozak/dev

Dev
This commit is contained in:
Simon Pauwels 2017-10-18 19:00:01 +02:00 committed by GitHub
commit 89faa904bd
253 changed files with 11747 additions and 3220 deletions

View file

@ -43,10 +43,16 @@ android {
applicationId "info.nightscout.androidaps"
minSdkVersion 21
targetSdkVersion 23
multiDexEnabled true
versionCode 1500
version "1.53"
version "1.54-dev"
buildConfigField "String", "VERSION", '"' + version + '"'
buildConfigField "String", "BUILDVERSION", generateGitBuild()
ndk {
abiFilters "armeabi-v7a", "x86", "armeabi", "mips"
moduleName "BleCommandUtil"
}
}
lintOptions {
disable 'MissingTranslation'
@ -58,7 +64,7 @@ android {
}
}
productFlavors {
flavorDimensions "standard", "wear"
flavorDimensions "standard"
full {
dimension "standard"
resValue "string", "app_name", "AndroidAPS"
@ -107,22 +113,6 @@ android {
buildConfigField "boolean", "NSCLIENTOLNY", "true"
buildConfigField "boolean", "CLOSEDLOOP", "false"
}
wear {
dimension "wear"
buildConfigField "boolean", "WEAR", "true"
buildConfigField "boolean", "WEAR_CONTROL", "false"
}
wearcontrol {
dimension "wear"
buildConfigField "boolean", "WEAR", "true"
buildConfigField "boolean", "WEAR_CONTROL", "true"
}
nowear {
dimension "wear"
buildConfigField "boolean", "WEAR", "false"
buildConfigField "boolean", "WEAR_CONTROL", "false"
}
}
}
@ -136,8 +126,7 @@ allprojects {
}
dependencies {
wearWearApp project(path: ':wear', configuration: 'restrictedRelease')
wearcontrolWearApp project(path: ':wear', configuration: 'fullRelease')
wearApp project(':wear')
compile fileTree(include: ['*.jar'], dir: 'libs')
compile('com.crashlytics.sdk.android:crashlytics:2.6.7@aar') {

BIN
app/libs/rhino-1.7.7.2.jar Normal file

Binary file not shown.

View file

@ -17,6 +17,7 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="com.google.android.permission.PROVIDE_BACKGROUND" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission-sdk-23 android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
@ -50,6 +51,13 @@
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity android:name=".plugins.PumpDanaRS.activities.BLEScanActivity">
<intent-filter>
<action android:name="info.nightscout.androidaps.plugins.PumpDanaRS.activities.BLEScanActivity" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity android:name=".plugins.PumpDanaRS.activities.PairingHelperActivity" />
<receiver
android:name=".receivers.DataReceiver"
@ -113,6 +121,10 @@
android:name=".plugins.PumpDanaRv2.services.DanaRv2ExecutionService"
android:enabled="true"
android:exported="false" />
<service
android:name=".plugins.PumpDanaRS.services.DanaRSService"
android:enabled="true"
android:exported="true"></service>
<service
android:name=".plugins.Wear.wearintegration.WatchUpdaterService"
android:exported="true">

View file

@ -0,0 +1,12 @@
var console = { };
console.error = function error(){
for (var i = 0, len = arguments.length; i < len; i++) {
console2.log(arguments[i]);
}
};
console.log = function log(){
for (var i = 0, len = arguments.length; i < len; i++) {
console2.log(arguments[i]);
}
};

View file

@ -0,0 +1,120 @@
package com.cozmo.danar.util;
import android.content.Context;
import info.nightscout.androidaps.MainApp;
public class BleCommandUtil {
public static final int DANAR_PACKET__TYPE_ENCRYPTION_REQUEST = 0x01;
public static final int DANAR_PACKET__TYPE_ENCRYPTION_RESPONSE = 0x02;
public static final int DANAR_PACKET__TYPE_COMMAND = 0xA1;
public static final int DANAR_PACKET__TYPE_RESPONSE = 0xB2;
public static final int DANAR_PACKET__TYPE_NOTIFY = 0xC3;
public static final int DANAR_PACKET__OPCODE_ENCRYPTION__PUMP_CHECK = 0x00;
public static final int DANAR_PACKET__OPCODE_ENCRYPTION__CHECK_PASSKEY = 0xD0;
public static final int DANAR_PACKET__OPCODE_ENCRYPTION__PASSKEY_REQUEST = 0xD1;
public static final int DANAR_PACKET__OPCODE_ENCRYPTION__PASSKEY_RETURN = 0xD2;
public static final int DANAR_PACKET__OPCODE_ENCRYPTION__TIME_INFORMATION = 0x01;
public static final int DANAR_PACKET__OPCODE_NOTIFY__DELIVERY_COMPLETE = 0x01;
public static final int DANAR_PACKET__OPCODE_NOTIFY__DELIVERY_RATE_DISPLAY = 0x02;
public static final int DANAR_PACKET__OPCODE_NOTIFY__ALARM = 0x03;
public static final int DANAR_PACKET__OPCODE_NOTIFY__MISSED_BOLUS_ALARM = 0x04;
public static final int DANAR_PACKET__OPCODE_REVIEW__INITIAL_SCREEN_INFORMATION = 0x02;
public static final int DANAR_PACKET__OPCODE_REVIEW__DELIVERY_STATUS = 0x03;
public static final int DANAR_PACKET__OPCODE_REVIEW__GET_PASSWORD = 0x04;
public static final int DANAR_PACKET__OPCODE_REVIEW__BOLUS_AVG = 0x10;
public static final int DANAR_PACKET__OPCODE_REVIEW__BOLUS = 0x11;
public static final int DANAR_PACKET__OPCODE_REVIEW__DAILY = 0x12;
public static final int DANAR_PACKET__OPCODE_REVIEW__PRIME = 0x13;
public static final int DANAR_PACKET__OPCODE_REVIEW__REFILL = 0x14;
public static final int DANAR_PACKET__OPCODE_REVIEW__BLOOD_GLUCOSE = 0x15;
public static final int DANAR_PACKET__OPCODE_REVIEW__CARBOHYDRATE = 0x16;
public static final int DANAR_PACKET__OPCODE_REVIEW__TEMPORARY = 0x17;
public static final int DANAR_PACKET__OPCODE_REVIEW__SUSPEND = 0x18;
public static final int DANAR_PACKET__OPCODE_REVIEW__ALARM = 0x19;
public static final int DANAR_PACKET__OPCODE_REVIEW__BASAL = 0x1A;
public static final int DANAR_PACKET__OPCODE_REVIEW__ALL_HISTORY = 0x1F;
public static final int DANAR_PACKET__OPCODE_REVIEW__GET_SHIPPING_INFORMATION = 0x20;
public static final int DANAR_PACKET__OPCODE_REVIEW__GET_PUMP_CHECK = 0x21;
public static final int DANAR_PACKET__OPCODE_REVIEW__GET_USER_TIME_CHANGE_FLAG = 0x22;
public static final int DANAR_PACKET__OPCODE_REVIEW__SET_USER_TIME_CHANGE_FLAG_CLEAR = 0x23;
public static final int DANAR_PACKET__OPCODE_REVIEW__GET_MORE_INFORMATION = 0x24;
public static final int DANAR_PACKET__OPCODE_REVIEW__SET_HISTORY_UPLOAD_MODE = 0x25;
public static final int DANAR_PACKET__OPCODE_REVIEW__GET_TODAY_DELIVERY_TOTAL = 0x26;
public static final int DANAR_PACKET__OPCODE_BOLUS__GET_STEP_BOLUS_INFORMATION = 0x40;
public static final int DANAR_PACKET__OPCODE_BOLUS__GET_EXTENDED_BOLUS_STATE = 0x41;
public static final int DANAR_PACKET__OPCODE_BOLUS__GET_EXTENDED_BOLUS = 0x42;
public static final int DANAR_PACKET__OPCODE_BOLUS__GET_DUAL_BOLUS = 0x43;
public static final int DANAR_PACKET__OPCODE_BOLUS__SET_STEP_BOLUS_STOP = 0x44;
public static final int DANAR_PACKET__OPCODE_BOLUS__GET_CARBOHYDRATE_CALCULATION_INFORMATION = 0x45;
public static final int DANAR_PACKET__OPCODE_BOLUS__GET_EXTENDED_MENU_OPTION_STATE = 0x46;
public static final int DANAR_PACKET__OPCODE_BOLUS__SET_EXTENDED_BOLUS = 0x47;
public static final int DANAR_PACKET__OPCODE_BOLUS__SET_DUAL_BOLUS = 0x48;
public static final int DANAR_PACKET__OPCODE_BOLUS__SET_EXTENDED_BOLUS_CANCEL = 0x49;
public static final int DANAR_PACKET__OPCODE_BOLUS__SET_STEP_BOLUS_START = 0x4A;
public static final int DANAR_PACKET__OPCODE_BOLUS__GET_CALCULATION_INFORMATION = 0x4B;
public static final int DANAR_PACKET__OPCODE_BOLUS__GET_BOLUS_RATE = 0x4C;
public static final int DANAR_PACKET__OPCODE_BOLUS__SET_BOLUS_RATE = 0x4D;
public static final int DANAR_PACKET__OPCODE_BOLUS__GET_CIR_CF_ARRAY = 0x4E;
public static final int DANAR_PACKET__OPCODE_BOLUS__SET_CIR_CF_ARRAY = 0x4F;
public static final int DANAR_PACKET__OPCODE_BOLUS__GET_BOLUS_OPTION = 0x50;
public static final int DANAR_PACKET__OPCODE_BOLUS__SET_BOLUS_OPTION = 0x51;
public static final int DANAR_PACKET__OPCODE_BASAL__SET_TEMPORARY_BASAL = 0x60;
public static final int DANAR_PACKET__OPCODE_BASAL__TEMPORARY_BASAL_STATE = 0x61;
public static final int DANAR_PACKET__OPCODE_BASAL__CANCEL_TEMPORARY_BASAL = 0x62;
public static final int DANAR_PACKET__OPCODE_BASAL__GET_PROFILE_NUMBER = 0x63;
public static final int DANAR_PACKET__OPCODE_BASAL__SET_PROFILE_NUMBER = 0x64;
public static final int DANAR_PACKET__OPCODE_BASAL__GET_PROFILE_BASAL_RATE = 0x65;
public static final int DANAR_PACKET__OPCODE_BASAL__SET_PROFILE_BASAL_RATE = 0x66;
public static final int DANAR_PACKET__OPCODE_BASAL__GET_BASAL_RATE = 0x67;
public static final int DANAR_PACKET__OPCODE_BASAL__SET_BASAL_RATE = 0x68;
public static final int DANAR_PACKET__OPCODE_BASAL__SET_SUSPEND_ON = 0x69;
public static final int DANAR_PACKET__OPCODE_BASAL__SET_SUSPEND_OFF = 0x6A;
public static final int DANAR_PACKET__OPCODE_OPTION__GET_PUMP_TIME = 0x70;
public static final int DANAR_PACKET__OPCODE_OPTION__SET_PUMP_TIME = 0x71;
public static final int DANAR_PACKET__OPCODE_OPTION__GET_USER_OPTION = 0x72;
public static final int DANAR_PACKET__OPCODE_OPTION__SET_USER_OPTION = 0x73;
public static final int DANAR_PACKET__OPCODE_BASAL__APS_SET_TEMPORARY_BASAL = 0xC1;
public static final int DANAR_PACKET__OPCODE__APS_HISTORY_EVENTS = 0xC2;
public static final int DANAR_PACKET__OPCODE__APS_SET_EVENT_HISTORY = 0xC3;
public static final int DANAR_PACKET__OPCODE_ETC__SET_HISTORY_SAVE = 0xE0;
public static final int DANAR_PACKET__OPCODE_ETC__KEEP_CONNECTION = 0xFF;
static {
System.loadLibrary("BleCommandUtil");
}
private static native byte[] getEncryptedPacketJni(Object context, int opcode, byte[] bytes, String deviceName);
private static native byte[] getDecryptedPacketJni(Object context, byte[] bytes);
// ---------------------------------------------------------
private static BleCommandUtil mInstance = null;
public static BleCommandUtil getInstance() {
if (mInstance == null) {
mInstance = new BleCommandUtil();
}
return mInstance;
}
// ---------------------------------------------------------
public byte[] getEncryptedPacket(int opcode, byte[] bytes, String deviceName) {
return getEncryptedPacketJni(MainApp.instance().getApplicationContext(), opcode, bytes, deviceName);
}
public byte[] getDecryptedPacket(byte[] bytes) {
return getDecryptedPacketJni(MainApp.instance().getApplicationContext(), bytes);
}
}

View file

@ -11,7 +11,6 @@ public class Config {
// PLUGINS
public static final boolean OPENAPSENABLED = APS;
public static final boolean LOOPENABLED = APS;
public static final boolean WEAR = BuildConfig.WEAR;
public static final boolean NSCLIENT = BuildConfig.NSCLIENTOLNY;
@ -40,10 +39,10 @@ public class Config {
public static final boolean logNSUpload = true;
public static final boolean logPumpActions = true;
public static final boolean logCongigBuilderActions = true;
public static final boolean logAutosensData = true;
public static final boolean logAutosensData = false;
// DanaR specific
public static final boolean logDanaBTComm = true;
public static final boolean logDanaMessageDetail = true;
public static boolean logDanaMessageDetail = true;
public static final boolean logDanaSerialEngine = true;
}

View file

@ -32,6 +32,8 @@ public class Constants {
// Circadian Percentage Profile
public static final int CPP_MIN_PERCENTAGE = 50;
public static final int CPP_MAX_PERCENTAGE = 200;
public static final int CPP_MIN_TIMESHIFT = -6;
public static final int CPP_MAX_TIMESHIFT = 23;
// Very Hard Limits Ranges
// First value is the Lowest and second value is the Highest a Limit can define

View file

@ -58,8 +58,10 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
static final int CASE_STORAGE = 0x1;
static final int CASE_SMS = 0x2;
static final int CASE_LOCATION = 0x3;
private boolean askForSMS = false;
private boolean askForLocation = true;
ImageButton menuButton;
@ -202,6 +204,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
protected void onResume() {
super.onResume();
askForSMSPermissions();
askForLocationPermissions();
}
@Override
@ -256,6 +259,17 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
}
}
private synchronized void askForLocationPermissions() {
if (askForLocation) { //only when settings were changed an MainActivity resumes.
askForLocation = false;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
askForPermission(new String[]{Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION}, CASE_LOCATION);
}
}
}
private void askForPermission(String[] permission, Integer requestCode) {
boolean test = false;
for (int i = 0; i < permission.length; i++) {
@ -279,6 +293,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
alert.setPositiveButton(R.string.ok, null);
alert.show();
break;
case CASE_LOCATION:
case CASE_SMS:
break;
}

View file

@ -29,7 +29,7 @@ import info.nightscout.androidaps.plugins.Actions.ActionsFragment;
import info.nightscout.androidaps.plugins.Careportal.CareportalFragment;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderFragment;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesFragment;
import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin;
import info.nightscout.androidaps.plugins.ConstraintsSafety.SafetyPlugin;
import info.nightscout.androidaps.plugins.Insulin.InsulinFastactingPlugin;
import info.nightscout.androidaps.plugins.Insulin.InsulinFastactingProlongedPlugin;
@ -37,21 +37,23 @@ import info.nightscout.androidaps.plugins.Insulin.InsulinOrefFreePeakPlugin;
import info.nightscout.androidaps.plugins.Insulin.InsulinOrefRapidActingPlugin;
import info.nightscout.androidaps.plugins.Insulin.InsulinOrefUltraRapidActingPlugin;
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
import info.nightscout.androidaps.plugins.Loop.LoopFragment;
import info.nightscout.androidaps.plugins.NSClientInternal.NSClientInternalFragment;
import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
import info.nightscout.androidaps.plugins.NSClientInternal.NSClientInternalPlugin;
import info.nightscout.androidaps.plugins.NSClientInternal.receivers.AckAlarmReceiver;
import info.nightscout.androidaps.plugins.OpenAPSAMA.OpenAPSAMAFragment;
import info.nightscout.androidaps.plugins.OpenAPSMA.OpenAPSMAFragment;
import info.nightscout.androidaps.plugins.Overview.OverviewFragment;
import info.nightscout.androidaps.plugins.OpenAPSAMA.OpenAPSAMAPlugin;
import info.nightscout.androidaps.plugins.OpenAPSMA.OpenAPSMAPlugin;
import info.nightscout.androidaps.plugins.Overview.OverviewPlugin;
import info.nightscout.androidaps.plugins.Persistentnotification.PersistentNotificationPlugin;
import info.nightscout.androidaps.plugins.ProfileCircadianPercentage.CircadianPercentageProfileFragment;
import info.nightscout.androidaps.plugins.ProfileLocal.LocalProfileFragment;
import info.nightscout.androidaps.plugins.ProfileNS.NSProfileFragment;
import info.nightscout.androidaps.plugins.ProfileSimple.SimpleProfileFragment;
import info.nightscout.androidaps.plugins.ProfileNS.NSProfilePlugin;
import info.nightscout.androidaps.plugins.ProfileSimple.SimpleProfilePlugin;
import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPlugin;
import info.nightscout.androidaps.plugins.PumpDanaR.services.DanaRExecutionService;
import info.nightscout.androidaps.plugins.PumpDanaRKorean.DanaRKoreanPlugin;
import info.nightscout.androidaps.plugins.PumpDanaRKorean.services.DanaRKoreanExecutionService;
import info.nightscout.androidaps.plugins.PumpDanaRS.DanaRSPlugin;
import info.nightscout.androidaps.plugins.PumpDanaRS.services.DanaRSService;
import info.nightscout.androidaps.plugins.PumpDanaRv2.DanaRv2Plugin;
import info.nightscout.androidaps.plugins.PumpDanaRv2.services.DanaRv2ExecutionService;
import info.nightscout.androidaps.plugins.PumpMDI.MDIPlugin;
@ -59,12 +61,12 @@ import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
import info.nightscout.androidaps.plugins.SensitivityAAPS.SensitivityAAPSPlugin;
import info.nightscout.androidaps.plugins.SensitivityOref0.SensitivityOref0Plugin;
import info.nightscout.androidaps.plugins.SensitivityWeightedAverage.SensitivityWeightedAveragePlugin;
import info.nightscout.androidaps.plugins.SmsCommunicator.SmsCommunicatorFragment;
import info.nightscout.androidaps.plugins.SmsCommunicator.SmsCommunicatorPlugin;
import info.nightscout.androidaps.plugins.SourceGlimp.SourceGlimpPlugin;
import info.nightscout.androidaps.plugins.SourceMM640g.SourceMM640gPlugin;
import info.nightscout.androidaps.plugins.SourceNSClient.SourceNSClientPlugin;
import info.nightscout.androidaps.plugins.SourceXdrip.SourceXdripPlugin;
import info.nightscout.androidaps.plugins.Treatments.TreatmentsFragment;
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
import info.nightscout.androidaps.plugins.Wear.WearFragment;
import info.nightscout.androidaps.plugins.XDripStatusline.StatuslinePlugin;
import info.nightscout.androidaps.receivers.DataReceiver;
@ -110,7 +112,7 @@ public class MainApp extends Application {
if (pluginsList == null) {
pluginsList = new ArrayList<>();
// Register all tabs in app here
pluginsList.add(OverviewFragment.getPlugin());
pluginsList.add(OverviewPlugin.getPlugin());
pluginsList.add(IobCobCalculatorPlugin.getPlugin());
if (Config.ACTION) pluginsList.add(ActionsFragment.getPlugin());
pluginsList.add(InsulinFastactingPlugin.getPlugin());
@ -123,21 +125,22 @@ public class MainApp extends Application {
pluginsList.add(SensitivityWeightedAveragePlugin.getPlugin());
if (Config.DANAR) pluginsList.add(DanaRPlugin.getPlugin());
if (Config.DANAR) pluginsList.add(DanaRKoreanPlugin.getPlugin());
if (Config.DANARv2) pluginsList.add(DanaRv2Plugin.getPlugin());
if (Config.DANAR) pluginsList.add(DanaRv2Plugin.getPlugin());
if (Config.DANAR) pluginsList.add(DanaRSPlugin.getPlugin());
pluginsList.add(CareportalFragment.getPlugin());
if (Config.MDI) pluginsList.add(MDIPlugin.getPlugin());
if (Config.VIRTUALPUMP) pluginsList.add(VirtualPumpPlugin.getInstance());
if (Config.LOOPENABLED) pluginsList.add(LoopFragment.getPlugin());
if (Config.OPENAPSENABLED) pluginsList.add(OpenAPSMAFragment.getPlugin());
if (Config.OPENAPSENABLED) pluginsList.add(OpenAPSAMAFragment.getPlugin());
pluginsList.add(NSProfileFragment.getPlugin());
if (Config.OTHERPROFILES) pluginsList.add(SimpleProfileFragment.getPlugin());
if (Config.LOOPENABLED) pluginsList.add(LoopPlugin.getPlugin());
if (Config.OPENAPSENABLED) pluginsList.add(OpenAPSMAPlugin.getPlugin());
if (Config.OPENAPSENABLED) pluginsList.add(OpenAPSAMAPlugin.getPlugin());
pluginsList.add(NSProfilePlugin.getPlugin());
if (Config.OTHERPROFILES) pluginsList.add(SimpleProfilePlugin.getPlugin());
if (Config.OTHERPROFILES) pluginsList.add(LocalProfileFragment.getPlugin());
if (Config.OTHERPROFILES)
pluginsList.add(CircadianPercentageProfileFragment.getPlugin());
pluginsList.add(TreatmentsFragment.getPlugin());
pluginsList.add(TreatmentsPlugin.getPlugin());
if (Config.SAFETY) pluginsList.add(SafetyPlugin.getPlugin());
if (Config.APS) pluginsList.add(ObjectivesFragment.getPlugin());
if (Config.APS) pluginsList.add(ObjectivesPlugin.getPlugin());
if (!Config.NSCLIENT)
pluginsList.add(SourceXdripPlugin.getPlugin());
pluginsList.add(SourceNSClientPlugin.getPlugin());
@ -145,12 +148,12 @@ public class MainApp extends Application {
pluginsList.add(SourceMM640gPlugin.getPlugin());
if (!Config.NSCLIENT)
pluginsList.add(SourceGlimpPlugin.getPlugin());
if (Config.SMSCOMMUNICATORENABLED) pluginsList.add(SmsCommunicatorFragment.getPlugin());
if (Config.SMSCOMMUNICATORENABLED) pluginsList.add(SmsCommunicatorPlugin.getPlugin());
if (Config.WEAR) pluginsList.add(WearFragment.getPlugin(this));
pluginsList.add(WearFragment.getPlugin(this));
pluginsList.add(StatuslinePlugin.getPlugin(this));
pluginsList.add(new PersistentNotificationPlugin(this));
pluginsList.add(NSClientInternalFragment.getPlugin());
pluginsList.add(NSClientInternalPlugin.getPlugin());
pluginsList.add(sConfigBuilder = ConfigBuilderFragment.getPlugin());
@ -207,6 +210,7 @@ public class MainApp extends Application {
startService(new Intent(this, DanaRExecutionService.class));
startService(new Intent(this, DanaRKoreanExecutionService.class));
startService(new Intent(this, DanaRv2ExecutionService.class));
startService(new Intent(this, DanaRSService.class));
}
keepAliveReceiver.setAlarm(this);
}

View file

@ -21,6 +21,7 @@ import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPlugin;
import info.nightscout.androidaps.plugins.PumpDanaRKorean.DanaRKoreanPlugin;
import info.nightscout.androidaps.plugins.NSClientInternal.NSClientInternalPlugin;
import info.nightscout.androidaps.plugins.OpenAPSAMA.OpenAPSAMAPlugin;
import info.nightscout.androidaps.plugins.PumpDanaRS.DanaRSPlugin;
import info.nightscout.androidaps.plugins.PumpDanaRv2.DanaRv2Plugin;
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
import info.nightscout.androidaps.plugins.SensitivityAAPS.SensitivityAAPSPlugin;
@ -70,6 +71,8 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
EditTextPreference editTextPref = (EditTextPreference) pref;
if (pref.getKey().contains("password") || pref.getKey().contains("secret")) {
pref.setSummary("******");
} else if (pref.getKey().equals(MainApp.sResources.getString(R.string.key_danars_name))) {
pref.setSummary(SP.getString(R.string.key_danars_name,""));
} else if (editTextPref.getText() != null && !editTextPref.getText().equals("")) {
((EditTextPreference) pref).setDialogMessage(editTextPref.getDialogMessage());
pref.setSummary(editTextPref.getText());
@ -130,12 +133,19 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
DanaRPlugin danaRPlugin = MainApp.getSpecificPlugin(DanaRPlugin.class);
DanaRKoreanPlugin danaRKoreanPlugin = MainApp.getSpecificPlugin(DanaRKoreanPlugin.class);
DanaRv2Plugin danaRv2Plugin = MainApp.getSpecificPlugin(DanaRv2Plugin.class);
if (danaRPlugin.isEnabled(PluginBase.PUMP) || danaRKoreanPlugin.isEnabled(PluginBase.PUMP)) {
DanaRSPlugin danaRSPlugin = MainApp.getSpecificPlugin(DanaRSPlugin.class);
if (danaRPlugin.isEnabled(PluginBase.PUMP)) {
addPreferencesFromResource(R.xml.pref_danar);
}
if (danaRKoreanPlugin.isEnabled(PluginBase.PUMP)) {
addPreferencesFromResource(R.xml.pref_danarkorean);
}
if (danaRv2Plugin != null && danaRv2Plugin.isEnabled(PluginBase.PUMP)) {
addPreferencesFromResource(R.xml.pref_danarv2);
}
if (danaRSPlugin != null && danaRSPlugin.isEnabled(PluginBase.PUMP)) {
addPreferencesFromResource(R.xml.pref_danars);
}
if (danaRPlugin.isEnabled(PluginBase.PROFILE) || danaRKoreanPlugin.isEnabled(PluginBase.PROFILE) || danaRv2Plugin != null && danaRv2Plugin.isEnabled(PluginBase.PROFILE)) {
addPreferencesFromResource(R.xml.pref_danarprofile);
}
@ -160,12 +170,10 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
}
addPreferencesFromResource(R.xml.pref_advanced);
if (Config.WEAR) {
WearPlugin wearPlugin = MainApp.getSpecificPlugin(WearPlugin.class);
if (wearPlugin != null && wearPlugin.isEnabled(PluginBase.GENERAL)) {
addPreferencesFromResource(R.xml.pref_wear);
}
}
StatuslinePlugin statuslinePlugin = MainApp.getSpecificPlugin(StatuslinePlugin.class);
if (statuslinePlugin != null && statuslinePlugin.isEnabled(PluginBase.GENERAL)) {

View file

@ -316,28 +316,8 @@ public class DataService extends IntentService {
log.error("Unhandled exception", e);
}
}
if (intent.getAction().equals(Intents.ACTION_NEW_TREATMENT)) {
try {
if (bundles.containsKey("treatment")) {
String trstring = bundles.getString("treatment");
handleAddChangeDataFromNS(trstring);
}
if (bundles.containsKey("treatments")) {
String trstring = bundles.getString("treatments");
JSONArray jsonArray = new JSONArray(trstring);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject trJson = jsonArray.getJSONObject(i);
String trstr = trJson.toString();
handleAddChangeDataFromNS(trstr);
}
}
} catch (Exception e) {
log.error("Unhandled exception", e);
}
}
if (intent.getAction().equals(Intents.ACTION_CHANGED_TREATMENT)) {
if (intent.getAction().equals(Intents.ACTION_NEW_TREATMENT) || intent.getAction().equals(Intents.ACTION_CHANGED_TREATMENT)) {
try {
if (bundles.containsKey("treatment")) {
String trstring = bundles.getString("treatment");

View file

@ -8,6 +8,9 @@ public interface Intents {
String ACTION_NEW_PROFILE = "info.nightscout.client.NEW_PROFILE";
String ACTION_NEW_SGV = "info.nightscout.client.NEW_SGV";
String ACTION_NEW_DEVICESTATUS = "info.nightscout.client.NEW_DEVICESTATUS";
String ACTION_NEW_FOOD = "info.nightscout.client.NEW_FOOD";
String ACTION_CHANGED_FOOD = "info.nightscout.client.CHANGED_FOOD";
String ACTION_REMOVED_FOOD = "info.nightscout.client.REMOVED_FOOD";
String ACTION_NEW_MBG = "info.nightscout.client.NEW_MBG";
String ACTION_NEW_CAL = "info.nightscout.client.NEW_CAL";
String ACTION_NEW_STATUS = "info.nightscout.client.NEW_STATUS";

View file

@ -22,6 +22,7 @@ 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.utils.DecimalFormatter;
import info.nightscout.utils.SafeParse;
import info.nightscout.utils.ToastUtils;
public class Profile {
@ -38,10 +39,15 @@ public class Profile {
JSONArray basal;
private LongSparseArray<Double> basal_v = null; // oldest at index 0
JSONArray targetLow;
private LongSparseArray<Double> targetLow_v = null; // oldest at index 0
JSONArray targetHigh;
private LongSparseArray<Double> targetHigh_v = null; // oldest at index 0
int percentage = 100;
int timeshift = 0;
public Profile(JSONObject json, String units) {
this(json);
this(json, 100, 0);
if (this.units == null) {
if (units != null)
this.units = units;
@ -52,7 +58,9 @@ public class Profile {
}
}
public Profile(JSONObject json) {
public Profile(JSONObject json, int percentage, int timeshift) {
this.percentage = percentage;
this.timeshift = timeshift;
this.json = json;
try {
if (json.has("units"))
@ -148,17 +156,25 @@ public class Profile {
}
private LongSparseArray<Double> convertToSparseArray(JSONArray array) {
double multiplier = getMultiplier(array);
LongSparseArray<Double> sparse = new LongSparseArray<>();
for (Integer index = 0; index < array.length(); index++) {
try {
JSONObject o = array.getJSONObject(index);
long tas = o.getLong("timeAsSeconds");
Double value = o.getDouble("value");
long tas = getShitfTimeSecs((int) o.getLong("timeAsSeconds"));
Double value = o.getDouble("value") * multiplier;
sparse.put(tas, value);
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
}
// check if start is at 0 (midnight)
// and add last value before midnight if not
if (sparse.keyAt(0) != 0) {
sparse.put(0, sparse.valueAt(sparse.size() - 1));
}
return sparse;
}
@ -182,7 +198,47 @@ public class Profile {
return lastValue;
}
private Double getValueToTime(LongSparseArray<Double> array, long timeAsSeconds) {
Integer getShitfTimeSecs(Integer originalTime) {
Integer shiftedTime = originalTime + timeshift * 60 * 60;
shiftedTime = (shiftedTime + 24 * 60 * 60) % (24 * 60 * 60);
if (timeshift != 0)
log.debug("(Sec) Original time: " + originalTime + " ShiftedTime: " + shiftedTime);
return shiftedTime;
}
double getMultiplier(LongSparseArray<Double> array) {
double multiplier = 1d;
if (array == isf_v)
multiplier = 100d / percentage;
else if (array == ic_v)
multiplier = 100d / percentage;
else if (array == basal_v)
multiplier = percentage / 100d;
else
log.error("Unknown array type");
return multiplier;
}
double getMultiplier(JSONArray array) {
double multiplier = 1d;
if (array == isf)
multiplier = 100d / percentage;
else if (array == ic)
multiplier = 100d / percentage;
else if (array == basal)
multiplier = percentage / 100d;
else if (array == targetLow)
multiplier = 1d;
else if (array == targetHigh)
multiplier = 1d;
else
log.error("Unknown array type");
return multiplier;
}
private Double getValueToTime(LongSparseArray<Double> array, Integer timeAsSeconds) {
Double lastValue = null;
for (Integer index = 0; index < array.size(); index++) {
@ -197,26 +253,29 @@ public class Profile {
return lastValue;
}
private String getValuesList(JSONArray array, JSONArray array2, DecimalFormat format, String units) {
private String format_HH_MM(Integer timeAsSeconds) {
String time;
int hour = timeAsSeconds / 60 / 60;
int minutes = timeAsSeconds - hour * 60 * 60;
DecimalFormat df = new DecimalFormat("00");
time = df.format(hour) + ":" + df.format(minutes);
return time;
}
private String getValuesList(LongSparseArray<Double> array, LongSparseArray<Double> array2, DecimalFormat format, String units) {
String retValue = "";
for (Integer index = 0; index < array.length(); index++) {
try {
JSONObject o = array.getJSONObject(index);
retValue += o.getString("time");
for (Integer index = 0; index < array.size(); index++) {
retValue += format_HH_MM((int) array.keyAt(index));
retValue += " ";
retValue += format.format(o.getDouble("value"));
retValue += format.format(array.valueAt(index));
if (array2 != null) {
JSONObject o2 = array2.getJSONObject(index);
retValue += " - ";
retValue += format.format(o2.getDouble("value"));
retValue += format.format(array2.valueAt(index));
}
retValue += " " + units;
if (index + 1 < array.length())
if (index + 1 < array.size())
retValue += "\n";
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
}
return retValue;
}
@ -236,7 +295,7 @@ public class Profile {
}
public String getIsfList() {
return getValuesList(isf, null, new DecimalFormat("0.0"), getUnits() + "/U");
return getValuesList(isf_v, null, new DecimalFormat("0.0"), getUnits() + "/U");
}
public Double getIc() {
@ -254,7 +313,7 @@ public class Profile {
}
public String getIcList() {
return getValuesList(ic, null, new DecimalFormat("0.0"), " g/U");
return getValuesList(ic_v, null, new DecimalFormat("0.0"), " g/U");
}
public Double getBasal() {
@ -272,7 +331,7 @@ public class Profile {
}
public String getBasalList() {
return getValuesList(basal, null, new DecimalFormat("0.00"), "U");
return getValuesList(basal_v, null, new DecimalFormat("0.00"), "U");
}
public class BasalValue {
@ -286,20 +345,14 @@ public class Profile {
}
public BasalValue[] getBasalValues() {
try {
BasalValue[] ret = new BasalValue[basal.length()];
BasalValue[] ret = new BasalValue[basal_v.size()];
for (Integer index = 0; index < basal.length(); index++) {
JSONObject o = basal.getJSONObject(index);
Integer tas = o.getInt("timeAsSeconds");
Double value = o.getDouble("value");
for (Integer index = 0; index < basal_v.size(); index++) {
Integer tas = (int) basal_v.keyAt(index);
Double value = basal_v.valueAt(index);
ret[index] = new BasalValue(tas, value);
}
return ret;
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
return new BasalValue[0];
}
public Double getTargetLow() {
@ -311,7 +364,9 @@ public class Profile {
}
public Double getTargetLow(Integer timeAsSeconds) {
return getValueToTime(targetLow, timeAsSeconds);
if (targetLow_v == null)
targetLow_v = convertToSparseArray(targetLow);
return getValueToTime(targetLow_v, timeAsSeconds);
}
public Double getTargetHigh() {
@ -323,11 +378,13 @@ public class Profile {
}
public Double getTargetHigh(Integer timeAsSeconds) {
return getValueToTime(targetHigh, timeAsSeconds);
if (targetHigh_v == null)
targetHigh_v = convertToSparseArray(targetHigh);
return getValueToTime(targetHigh_v, timeAsSeconds);
}
public String getTargetList() {
return getValuesList(targetLow, targetHigh, new DecimalFormat("0.0"), getUnits());
return getValuesList(targetLow_v, targetHigh_v, new DecimalFormat("0.0"), getUnits());
}
public double getMaxDailyBasal() {
@ -350,18 +407,6 @@ public class Profile {
return (int) (passed / 1000);
}
public static Integer secondsFromMidnight(Date date) {
Calendar c = Calendar.getInstance();
long now = date.getTime();
c.setTime(date);
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
long passed = now - c.getTimeInMillis();
return (int) (passed / 1000);
}
public static Integer secondsFromMidnight(long date) {
Calendar c = Calendar.getInstance();
c.setTimeInMillis(date);
@ -410,4 +455,29 @@ public class Profile {
return toUnitsString(lowMgdl, lowMmol, units) + " - " + toUnitsString(highMgdl, highMmol, units);
}
public double percentageBasalSum() {
double result = 0d;
for (int i = 0; i < 24; i++) {
result += getBasal((Integer) (i * 60 * 60));
}
return result;
}
public double baseBasalSum() {
double result = 0d;
for (int i = 0; i < 24; i++) {
result += getBasal((Integer) (i * 60 * 60)) / getMultiplier(basal_v);
}
return result;
}
public int getPercentage() {
return percentage;
}
public int getTimeshift() {
return timeshift;
}
}

View file

@ -33,6 +33,7 @@ import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.events.EventCareportalEventChange;
import info.nightscout.androidaps.events.EventExtendedBolusChange;
import info.nightscout.androidaps.events.EventFoodDatabaseChanged;
import info.nightscout.androidaps.events.EventNewBG;
import info.nightscout.androidaps.events.EventProfileSwitchChange;
import info.nightscout.androidaps.events.EventRefreshOverview;
@ -59,6 +60,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
public static final String DATABASE_DBREQUESTS = "DBRequests";
public static final String DATABASE_CAREPORTALEVENTS = "CareportalEvents";
public static final String DATABASE_PROFILESWITCHES = "ProfileSwitches";
public static final String DATABASE_FOODS = "Foods";
private static final int DATABASE_VERSION = 8;
@ -85,6 +87,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
private static final ScheduledExecutorService profileSwitchEventWorker = Executors.newSingleThreadScheduledExecutor();
private static ScheduledFuture<?> scheduledProfileSwitchEventPost = null;
public FoodHelper foodHelper = new FoodHelper(this);
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
onCreate(getWritableDatabase(), getConnectionSource());
@ -104,6 +108,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
TableUtils.createTableIfNotExists(connectionSource, ExtendedBolus.class);
TableUtils.createTableIfNotExists(connectionSource, CareportalEvent.class);
TableUtils.createTableIfNotExists(connectionSource, ProfileSwitch.class);
TableUtils.createTableIfNotExists(connectionSource, Food.class);
} catch (SQLException e) {
log.error("Can't create database", e);
throw new RuntimeException(e);
@ -128,6 +133,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
TableUtils.dropTable(connectionSource, ExtendedBolus.class, true);
TableUtils.dropTable(connectionSource, CareportalEvent.class, true);
TableUtils.dropTable(connectionSource, ProfileSwitch.class, true);
TableUtils.dropTable(connectionSource, Food.class, true);
onCreate(database, connectionSource);
}
} catch (SQLException e) {
@ -205,6 +211,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
TableUtils.createTableIfNotExists(connectionSource, ExtendedBolus.class);
TableUtils.createTableIfNotExists(connectionSource, CareportalEvent.class);
TableUtils.createTableIfNotExists(connectionSource, ProfileSwitch.class);
foodHelper.resetFood();
updateEarliestDataChange(0);
} catch (SQLException e) {
log.error("Unhandled exception", e);
@ -217,6 +224,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
scheduleTemporaryTargetChange();
scheduleCareportalEventChange();
scheduleProfileSwitchChange();
foodHelper.scheduleFoodChange();
new java.util.Timer().schedule(
new java.util.TimerTask() {
@Override
@ -655,8 +663,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
class PostRunnable implements Runnable {
public void run() {
log.debug("Firing EventTreatmentChange");
MainApp.bus().post(new EventReloadTreatmentData());
MainApp.bus().post(new EventTreatmentChange());
MainApp.bus().post(new EventReloadTreatmentData(new EventTreatmentChange()));
if (earliestDataChange != null)
MainApp.bus().post(new EventNewHistoryData(earliestDataChange));
earliestDataChange = null;
@ -1357,8 +1364,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
class PostRunnable implements Runnable {
public void run() {
log.debug("Firing EventExtendedBolusChange");
MainApp.bus().post(new EventReloadTreatmentData());
MainApp.bus().post(new EventExtendedBolusChange());
MainApp.bus().post(new EventReloadTreatmentData(new EventExtendedBolusChange()));
if (earliestDataChange != null)
MainApp.bus().post(new EventNewHistoryData(earliestDataChange));
earliestDataChange = null;
@ -1535,9 +1541,10 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
old = getDaoProfileSwitch().queryForId(profileSwitch.date);
if (old != null) {
if (!old.isEqual(profileSwitch)) {
profileSwitch.source = old.source;
profileSwitch.profileName = old.profileName; // preserver profileName to prevent multiple CPP extension
getDaoProfileSwitch().delete(old); // need to delete/create because date may change too
old.copyFrom(profileSwitch);
getDaoProfileSwitch().create(old);
getDaoProfileSwitch().create(profileSwitch);
log.debug("PROFILESWITCH: Updating record by date from: " + Source.getString(profileSwitch.source) + " " + old.toString());
scheduleProfileSwitchChange();
return true;
@ -1672,4 +1679,5 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
return null;
}
// ---------------- Food handling ---------------
}

View file

@ -0,0 +1,107 @@
package info.nightscout.androidaps.db;
import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.table.DatabaseTable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Objects;
/**
* Created by mike on 20.09.2017.
*/
@DatabaseTable(tableName = DatabaseHelper.DATABASE_FOODS)
public class Food {
private static Logger log = LoggerFactory.getLogger(Food.class);
@DatabaseField(id = true)
public long key;
@DatabaseField
public boolean isValid = true;
@DatabaseField
public String _id; // NS _id
@DatabaseField
public String name;
@DatabaseField
public String category;
@DatabaseField
public String subcategory;
// Example:
// name="juice" portion=250 units="ml" carbs=12
// means 250ml of juice has 12g of carbs
@DatabaseField
public double portion; // common portion in "units"
@DatabaseField
public int carbs; // in grams
@DatabaseField
public int fat = 0; // in grams
@DatabaseField
public int protein = 0; // in grams
@DatabaseField
public int energy = 0; // in kJ
@DatabaseField
public String units = "g";
@DatabaseField
public int gi; // not used yet
public Food() {
key = System.currentTimeMillis();
}
public boolean isEqual(Food other) {
if (portion != other.portion)
return false;
if (carbs != other.carbs)
return false;
if (fat != other.fat)
return false;
if (protein != other.protein)
return false;
if (energy != other.energy)
return false;
if (gi != other.gi)
return false;
if (!Objects.equals(_id, other._id))
return false;
if (!Objects.equals(name, other.name))
return false;
if (!Objects.equals(category, other.category))
return false;
if (!Objects.equals(subcategory, other.subcategory))
return false;
if (!Objects.equals(units, other.units))
return false;
return true;
}
public void copyFrom(Food other) {
isValid = other.isValid;
_id = other._id;
name = other.name;
category = other.category;
subcategory = other.subcategory;
portion = other.portion;
carbs = other.carbs;
fat = other.fat;
protein = other.protein;
energy = other.energy;
units = other.units;
gi = other.gi;
}
}

View file

@ -0,0 +1,205 @@
package info.nightscout.androidaps.db;
import com.j256.ormlite.android.AndroidConnectionSource;
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.j256.ormlite.table.TableUtils;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.events.EventFoodDatabaseChanged;
/**
* Created by mike on 24.09.2017.
*/
public class FoodHelper {
private static Logger log = LoggerFactory.getLogger(FoodHelper.class);
DatabaseHelper databaseHelper;
private static final ScheduledExecutorService foodEventWorker = Executors.newSingleThreadScheduledExecutor();
private static ScheduledFuture<?> scheduledFoodEventPost = null;
public FoodHelper(DatabaseHelper databaseHelper) {
this.databaseHelper = databaseHelper;
}
private Dao<Food, Long> getDaoFood() throws SQLException {
return databaseHelper.getDao(Food.class);
}
public void resetFood() {
try {
TableUtils.dropTable(databaseHelper.getConnectionSource(), Food.class, true);
TableUtils.createTableIfNotExists(databaseHelper.getConnectionSource(), Food.class);
} catch (SQLException e) {
log.error("Unhandled exception", e);
}
scheduleFoodChange();
}
public List<Food> getFoodData() {
try {
Dao<Food, Long> daoFood = getDaoFood();
List<Food> foods;
QueryBuilder<Food, Long> queryBuilder = daoFood.queryBuilder();
PreparedQuery<Food> preparedQuery = queryBuilder.prepare();
foods = daoFood.query(preparedQuery);
return foods;
} catch (SQLException e) {
log.error("Unhandled exception", e);
}
return new ArrayList<>();
}
public boolean createOrUpdate(Food food) {
try {
// find by NS _id
if (food._id != null) {
Food old;
QueryBuilder<Food, Long> queryBuilder = getDaoFood().queryBuilder();
Where where = queryBuilder.where();
where.eq("_id", food._id);
PreparedQuery<Food> preparedQuery = queryBuilder.prepare();
List<Food> found = getDaoFood().query(preparedQuery);
if (found.size() > 0) {
old = found.get(0);
if (!old.isEqual(food)) {
getDaoFood().delete(old); // need to delete/create because date may change too
old.copyFrom(food);
getDaoFood().create(old);
log.debug("FOOD: Updating record by _id: " + old.toString());
scheduleFoodChange();
return true;
}
}
}
getDaoFood().createOrUpdate(food);
log.debug("FOOD: New record: " + food.toString());
scheduleFoodChange();
return true;
} catch (SQLException e) {
log.error("Unhandled exception", e);
}
return false;
}
public void delete(Food food) {
try {
getDaoFood().delete(food);
scheduleFoodChange();
} catch (SQLException e) {
log.error("Unhandled exception", e);
}
}
public static void scheduleFoodChange() {
class PostRunnable implements Runnable {
public void run() {
log.debug("Firing EventFoodChange");
MainApp.bus().post(new EventFoodDatabaseChanged());
scheduledFoodEventPost = null;
}
}
// prepare task for execution in 1 sec
// cancel waiting task to prevent sending multiple posts
if (scheduledFoodEventPost != null)
scheduledFoodEventPost.cancel(false);
Runnable task = new PostRunnable();
final int sec = 1;
scheduledFoodEventPost = foodEventWorker.schedule(task, sec, TimeUnit.SECONDS);
}
/*
{
"_id": "551ee3ad368e06e80856e6a9",
"type": "food",
"category": "Zakladni",
"subcategory": "Napoje",
"name": "Mleko",
"portion": 250,
"carbs": 12,
"gi": 1,
"created_at": "2015-04-14T06:59:16.500Z",
"unit": "ml"
}
*/
public void createFoodFromJsonIfNotExists(JSONObject trJson) {
try {
Food food = new Food();
if (trJson.has("type") && trJson.getString("type").equals("food")) {
if (trJson.has("_id"))
food._id = trJson.getString("_id");
if (trJson.has("category"))
food.category = trJson.getString("category");
if (trJson.has("subcategory"))
food.subcategory = trJson.getString("subcategory");
if (trJson.has("name"))
food.name = trJson.getString("name");
if (trJson.has("unit"))
food.units = trJson.getString("unit");
if (trJson.has("portion"))
food.portion = trJson.getDouble("portion");
if (trJson.has("carbs"))
food.carbs = trJson.getInt("carbs");
if (trJson.has("gi"))
food.gi = trJson.getInt("gi");
if (trJson.has("energy"))
food.energy = trJson.getInt("energy");
if (trJson.has("protein"))
food.protein = trJson.getInt("protein");
if (trJson.has("fat"))
food.fat = trJson.getInt("fat");
}
createOrUpdate(food);
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
}
public void deleteFoodById(String _id) {
Food stored = findFoodById(_id);
if (stored != null) {
log.debug("FOOD: Removing Food record from database: " + stored.toString());
delete(stored);
scheduleFoodChange();
}
}
public Food findFoodById(String _id) {
try {
QueryBuilder<Food, Long> queryBuilder = getDaoFood().queryBuilder();
Where where = queryBuilder.where();
where.eq("_id", _id);
PreparedQuery<Food> preparedQuery = queryBuilder.prepare();
List<Food> list = getDaoFood().query(preparedQuery);
if (list.size() == 1) {
return list.get(0);
} else {
return null;
}
} catch (SQLException e) {
log.error("Unhandled exception", e);
}
return null;
}
}

View file

@ -10,14 +10,15 @@ import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Date;
import java.util.Objects;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.interfaces.Interval;
import info.nightscout.androidaps.plugins.Overview.graphExtensions.DataPointWithLabelInterface;
import info.nightscout.androidaps.plugins.Overview.graphExtensions.PointsWithLabelGraphSeries;
import info.nightscout.androidaps.plugins.ProfileLocal.LocalProfilePlugin;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.DecimalFormatter;
@DatabaseTable(tableName = DatabaseHelper.DATABASE_PROFILESWITCHES)
public class ProfileSwitch implements Interval, DataPointWithLabelInterface {
@ -58,13 +59,24 @@ public class ProfileSwitch implements Interval, DataPointWithLabelInterface {
public Profile getProfileObject() {
if (profile == null)
try {
profile = new Profile(new JSONObject(profileJson));
profile = new Profile(new JSONObject(profileJson), percentage, timeshift);
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
return profile;
}
public String getCustomizedName() {
String name = profileName;
if(LocalProfilePlugin.LOCAL_PROFILE.equals(name)){
name = DecimalFormatter.to2Decimal(getProfileObject().percentageBasalSum()) + "U ";
}
if (isCPP) {
name += "(" + percentage + "%," + timeshift + "h)";
}
return name;
}
public boolean isEqual(ProfileSwitch other) {
if (date != other.date) {
return false;
@ -179,7 +191,7 @@ public class ProfileSwitch implements Interval, DataPointWithLabelInterface {
@Override
public String getLabel() {
return profileName;
return getCustomizedName();
}
@Override

View file

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

View file

@ -18,14 +18,24 @@ public class EventPumpStatusChanged {
public int sSecondsElapsed = 0;
public String sPerfomingAction = "";
public static String error = "";
public EventPumpStatusChanged(int status) {
sStatus = status;
sSecondsElapsed = 0;
error = "";
}
public EventPumpStatusChanged(int status, int secondsElapsed) {
sStatus = status;
sSecondsElapsed = secondsElapsed;
error = "";
}
public EventPumpStatusChanged(int status, String error) {
sStatus = status;
sSecondsElapsed = 0;
this.error = error;
}
public EventPumpStatusChanged(String action) {

View file

@ -5,4 +5,9 @@ package info.nightscout.androidaps.events;
*/
public class EventReloadTreatmentData {
public Object next;
public EventReloadTreatmentData(Object next) {
this.next = next;
}
}

View file

@ -31,7 +31,7 @@ public interface PumpInterface {
PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo);
void stopBolusDelivering();
PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, boolean force);
PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, boolean enforceNew);
PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes);
PumpEnactResult setExtendedBolus(Double insulin, Integer durationInMinutes);
//some pumps might set a very short temp close to 100% as cancelling a temp can be noisy

View file

@ -12,6 +12,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import com.crashlytics.android.Crashlytics;
import com.crashlytics.android.answers.Answers;
import com.crashlytics.android.answers.CustomEvent;
import com.squareup.otto.Subscribe;
@ -69,6 +70,7 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
try {
View view = inflater.inflate(R.layout.actions_fragment, container, false);
profileSwitch = (Button) view.findViewById(R.id.actions_profileswitch);
@ -89,6 +91,11 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL
updateGUI();
return view;
} catch (Exception e) {
Crashlytics.logException(e);
}
return null;
}
@Subscribe
@ -187,14 +194,14 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL
switch (view.getId()) {
case R.id.actions_profileswitch:
NewNSTreatmentDialog newDialog = new NewNSTreatmentDialog();
final OptionsToShow profileswitch = CareportalFragment.profileswitch;
final OptionsToShow profileswitch = CareportalFragment.PROFILESWITCH;
profileswitch.executeProfileSwitch = true;
newDialog.setOptions(profileswitch, R.string.careportal_profileswitch);
newDialog.show(manager, "NewNSTreatmentDialog");
break;
case R.id.actions_temptarget:
NewNSTreatmentDialog newTTDialog = new NewNSTreatmentDialog();
final OptionsToShow temptarget = CareportalFragment.temptarget;
final OptionsToShow temptarget = CareportalFragment.TEMPTARGET;
temptarget.executeTempTarget = true;
newTTDialog.setOptions(temptarget, R.string.careportal_temporarytarget);
newTTDialog.show(manager, "NewNSTreatmentDialog");

View file

@ -10,8 +10,8 @@ import info.nightscout.androidaps.interfaces.PluginBase;
public class ActionsPlugin implements PluginBase {
boolean fragmentEnabled = true;
boolean fragmentVisible = true;
private boolean fragmentEnabled = true;
private boolean fragmentVisible = true;
@Override
public int getType() {

View file

@ -2,11 +2,9 @@ package info.nightscout.androidaps.plugins.Actions.dialogs;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.preference.PreferenceManager;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater;
@ -16,7 +14,6 @@ import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;
import com.crashlytics.android.answers.Answers;
import com.crashlytics.android.answers.CustomEvent;
@ -32,12 +29,11 @@ import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.DetailedBolusInfo;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.Overview.Notification;
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.PlusMinusEditText;
import info.nightscout.utils.NumberPicker;
import info.nightscout.utils.SP;
import info.nightscout.utils.SafeParse;
@ -45,13 +41,12 @@ public class FillDialog extends DialogFragment implements OnClickListener {
private static Logger log = LoggerFactory.getLogger(FillDialog.class);
Button deliverButton;
TextView insulin;
double amount1 = 0d;
double amount2 = 0d;
double amount3 = 0d;
PlusMinusEditText editInsulin;
NumberPicker editInsulin;
Handler mHandler;
public static HandlerThread mHandlerThread;
@ -73,10 +68,10 @@ public class FillDialog extends DialogFragment implements OnClickListener {
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
insulin = (TextView) view.findViewById(R.id.treatments_newtreatment_insulinamount);
Double maxInsulin = MainApp.getConfigBuilder().applyBolusConstraints(Constants.bolusOnlyForCheckLimit);
double bolusstep = MainApp.getConfigBuilder().getPumpDescription().bolusStep;
editInsulin = new PlusMinusEditText(view, R.id.treatments_newtreatment_insulinamount, R.id.treatments_newtreatment_insulinamount_plus, R.id.treatments_newtreatment_insulinamount_minus, 0d, 0d, maxInsulin, bolusstep, new DecimalFormat("0.00"), false);
editInsulin = (NumberPicker) view.findViewById(R.id.treatments_newtreatment_insulinamount);
editInsulin.setParams(0d, 0d, maxInsulin, bolusstep, new DecimalFormat("0.00"), false);
//setup preset buttons
Button button1 = (Button) view.findViewById(R.id.fill_preset_button1);
@ -127,7 +122,7 @@ public class FillDialog extends DialogFragment implements OnClickListener {
public void onClick(View view) {
switch (view.getId()) {
case R.id.treatments_newtreatment_deliverbutton:
Double insulin = SafeParse.stringToDouble(this.insulin.getText().toString());
Double insulin = SafeParse.stringToDouble(editInsulin.getText().toString());
confirmAndDeliver(insulin);
break;
case R.id.fill_preset_button1:

View file

@ -11,9 +11,6 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioButton;
import com.crashlytics.android.answers.Answers;
import com.crashlytics.android.answers.CustomEvent;
@ -30,14 +27,14 @@ import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.Overview.Notification;
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
import info.nightscout.utils.PlusMinusEditText;
import info.nightscout.utils.NumberPicker;
import info.nightscout.utils.SafeParse;
public class NewExtendedBolusDialog extends DialogFragment implements View.OnClickListener {
private static Logger log = LoggerFactory.getLogger(NewExtendedBolusDialog.class);
PlusMinusEditText editInsulin;
PlusMinusEditText editDuration;
NumberPicker editInsulin;
NumberPicker editDuration;
Handler mHandler;
public static HandlerThread mHandlerThread;
@ -56,11 +53,13 @@ public class NewExtendedBolusDialog extends DialogFragment implements View.OnCli
View view = inflater.inflate(R.layout.overview_newextendedbolus_dialog, container, false);
Double maxInsulin = MainApp.getConfigBuilder().applyBolusConstraints(Constants.bolusOnlyForCheckLimit);
editInsulin = new PlusMinusEditText(view, R.id.overview_newextendedbolus_insulin, R.id.overview_newextendedbolus_insulin_plus, R.id.overview_newextendedbolus_insulin_minus, 0d, 0d, maxInsulin, 0.1d, new DecimalFormat("0.00"), false);
editInsulin = (NumberPicker) view.findViewById(R.id.overview_newextendedbolus_insulin);
editInsulin.setParams(0d, 0d, maxInsulin, 0.1d, new DecimalFormat("0.00"), false);
double extendedDurationStep = MainApp.getConfigBuilder().getPumpDescription().extendedBolusDurationStep;
double extendedMaxDuration = MainApp.getConfigBuilder().getPumpDescription().extendedBolusMaxDuration;
editDuration = new PlusMinusEditText(view, R.id.overview_newextendedbolus_duration, R.id.overview_newextendedbolus_duration_plus, R.id.overview_newextendedbolus_duration_minus, extendedDurationStep, extendedDurationStep, extendedMaxDuration, extendedDurationStep, new DecimalFormat("0"), false);
editDuration = (NumberPicker) view.findViewById(R.id.overview_newextendedbolus_duration);
editDuration.setParams(extendedDurationStep, extendedDurationStep, extendedMaxDuration, extendedDurationStep, new DecimalFormat("0"), false);
view.findViewById(R.id.ok).setOnClickListener(this);
view.findViewById(R.id.cancel).setOnClickListener(this);

View file

@ -14,7 +14,6 @@ import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.RelativeLayout;
import com.crashlytics.android.answers.Answers;
import com.crashlytics.android.answers.CustomEvent;
@ -26,12 +25,11 @@ import java.text.DecimalFormat;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.interfaces.PumpDescription;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.utils.NumberPicker;
import info.nightscout.utils.PlusMinusEditText;
import info.nightscout.utils.SafeParse;
public class NewTempBasalDialog extends DialogFragment implements View.OnClickListener, RadioGroup.OnCheckedChangeListener {
@ -159,7 +157,7 @@ public class NewTempBasalDialog extends DialogFragment implements View.OnClickLi
if (setAsPercent) {
result = pump.setTempBasalPercent(finalBasalPercent, finalDurationInMinutes);
} else {
result = pump.setTempBasalAbsolute(finalBasal, finalDurationInMinutes, false);
result = pump.setTempBasalAbsolute(finalBasal, finalDurationInMinutes, true);
}
if (!result.success) {
if (context instanceof Activity) {

View file

@ -3,21 +3,19 @@ package info.nightscout.androidaps.plugins.Careportal;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.text.Layout;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.crashlytics.android.Crashlytics;
import com.squareup.otto.Subscribe;
import info.nightscout.androidaps.BuildConfig;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.ProfileStore;
import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.events.EventCareportalEventChange;
@ -46,31 +44,33 @@ public class CareportalFragment extends SubscriberFragment implements View.OnCli
return careportalPlugin;
}
// bg,insulin,carbs,prebolus,duration,percent,absolute,profile,split,temptarget
public static final OptionsToShow bgcheck = new OptionsToShow(R.id.careportal_bgcheck, R.string.careportal_bgcheck, true, true, true, false, false, false, false, false, false, false);
public static final OptionsToShow snackbolus = new OptionsToShow(R.id.careportal_snackbolus, R.string.careportal_snackbolus, true, true, true, true, false, false, false, false, false, false);
public static final OptionsToShow mealbolus = new OptionsToShow(R.id.careportal_mealbolus, R.string.careportal_mealbolus, true, true, true, true, false, false, false, false, false, false);
public static final OptionsToShow correctionbolus = new OptionsToShow(R.id.careportal_correctionbolus, R.string.careportal_correctionbolus, true, true, true, true, false, false, false, false, false, false);
public static final OptionsToShow carbcorrection = new OptionsToShow(R.id.careportal_carbscorrection, R.string.careportal_carbscorrection, true, false, true, false, false, false, false, false, false, false);
public static final OptionsToShow combobolus = new OptionsToShow(R.id.careportal_combobolus, R.string.careportal_combobolus, true, true, true, true, true, false, false, false, true, false);
public static final OptionsToShow announcement = new OptionsToShow(R.id.careportal_announcement, R.string.careportal_announcement, true, false, false, false, false, false, false, false, false, false);
public static final OptionsToShow note = new OptionsToShow(R.id.careportal_note, R.string.careportal_note, true, false, false, false, true, false, false, false, false, false);
public static final OptionsToShow question = new OptionsToShow(R.id.careportal_question, R.string.careportal_question, true, false, false, false, false, false, false, false, false, false);
public static final OptionsToShow exercise = new OptionsToShow(R.id.careportal_exercise, R.string.careportal_exercise, false, false, false, false, true, false, false, false, false, false);
public static final OptionsToShow sitechange = new OptionsToShow(R.id.careportal_pumpsitechange, R.string.careportal_pumpsitechange, true, true, false, false, false, false, false, false, false, false);
public static final OptionsToShow sensorstart = new OptionsToShow(R.id.careportal_cgmsensorstart, R.string.careportal_cgmsensorstart, true, false, false, false, false, false, false, false, false, false);
public static final OptionsToShow sensorchange = new OptionsToShow(R.id.careportal_cgmsensorinsert, R.string.careportal_cgmsensorinsert, true, false, false, false, false, false, false, false, false, false);
public static final OptionsToShow insulinchange = new OptionsToShow(R.id.careportal_insulincartridgechange, R.string.careportal_insulincartridgechange, true, false, false, false, false, false, false, false, false, false);
public static final OptionsToShow pumpbatterychange = new OptionsToShow(R.id.careportal_pumpbatterychange, R.string.careportal_pumpbatterychange, true, false, false, false, false, false, false, false, false, false);
public static final OptionsToShow tempbasalstart = new OptionsToShow(R.id.careportal_tempbasalstart, R.string.careportal_tempbasalstart, true, false, false, false, true, true, true, false, false, false);
public static final OptionsToShow tempbasalend = new OptionsToShow(R.id.careportal_tempbasalend, R.string.careportal_tempbasalend, true, false, false, false, false, false, false, false, false, false);
public static final OptionsToShow profileswitch = new OptionsToShow(R.id.careportal_profileswitch, R.string.careportal_profileswitch, true, false, false, false, true, false, false, true, false, false);
public static final OptionsToShow openapsoffline = new OptionsToShow(R.id.careportal_openapsoffline, R.string.careportal_openapsoffline, false, false, false, false, true, false, false, false, false, false);
public static final OptionsToShow temptarget = new OptionsToShow(R.id.careportal_temporarytarget, R.string.careportal_temporarytarget, false, false, false, false, true, false, false, false, false, true);
// date,bg,insulin,carbs,prebolus,duration,percent,absolute,profile,split,temptarget
public static final OptionsToShow BGCHECK = new OptionsToShow(R.id.careportal_bgcheck, R.string.careportal_bgcheck).date().bg();
public static final OptionsToShow SNACKBOLUS = new OptionsToShow(R.id.careportal_snackbolus, R.string.careportal_snackbolus).date().bg().insulin().carbs().prebolus();
public static final OptionsToShow MEALBOLUS = new OptionsToShow(R.id.careportal_mealbolus, R.string.careportal_mealbolus).date().bg().insulin().carbs().prebolus();
public static final OptionsToShow CORRECTIONBOLUS = new OptionsToShow(R.id.careportal_correctionbolus, R.string.careportal_correctionbolus).date().bg().insulin().carbs().prebolus();
public static final OptionsToShow CARBCORRECTION = new OptionsToShow(R.id.careportal_carbscorrection, R.string.careportal_carbscorrection).date().bg().carbs();
public static final OptionsToShow COMBOBOLUS = new OptionsToShow(R.id.careportal_combobolus, R.string.careportal_combobolus).date().bg().insulin().carbs().prebolus().duration().split();
public static final OptionsToShow ANNOUNCEMENT = new OptionsToShow(R.id.careportal_announcement, R.string.careportal_announcement).date().bg();
public static final OptionsToShow NOTE = new OptionsToShow(R.id.careportal_note, R.string.careportal_note).date().bg().duration();
public static final OptionsToShow QUESTION = new OptionsToShow(R.id.careportal_question, R.string.careportal_question).date().bg();
public static final OptionsToShow EXERCISE = new OptionsToShow(R.id.careportal_exercise, R.string.careportal_exercise).date().duration();
public static final OptionsToShow SITECHANGE = new OptionsToShow(R.id.careportal_pumpsitechange, R.string.careportal_pumpsitechange).date().bg();
public static final OptionsToShow SENSORSTART = new OptionsToShow(R.id.careportal_cgmsensorstart, R.string.careportal_cgmsensorstart).date().bg();
public static final OptionsToShow SENSORCHANGE = new OptionsToShow(R.id.careportal_cgmsensorinsert, R.string.careportal_cgmsensorinsert).date().bg();
public static final OptionsToShow INSULINCHANGE = new OptionsToShow(R.id.careportal_insulincartridgechange, R.string.careportal_insulincartridgechange).date().bg();
public static final OptionsToShow PUMPBATTERYCHANGE = new OptionsToShow(R.id.careportal_pumpbatterychange, R.string.careportal_pumpbatterychange).date().bg();
public static final OptionsToShow TEMPBASALSTART = new OptionsToShow(R.id.careportal_tempbasalstart, R.string.careportal_tempbasalstart).date().bg().duration().percent().absolute();
public static final OptionsToShow TEMPBASALEND = new OptionsToShow(R.id.careportal_tempbasalend, R.string.careportal_tempbasalend).date().bg();
public static final OptionsToShow PROFILESWITCH = new OptionsToShow(R.id.careportal_profileswitch, R.string.careportal_profileswitch).date().duration().profile();
public static final OptionsToShow PROFILESWITCHDIRECT = new OptionsToShow(R.id.careportal_profileswitch, R.string.careportal_profileswitch).duration().profile();
public static final OptionsToShow OPENAPSOFFLINE = new OptionsToShow(R.id.careportal_openapsoffline, R.string.careportal_openapsoffline).date().duration();
public static final OptionsToShow TEMPTARGET = new OptionsToShow(R.id.careportal_temporarytarget, R.string.careportal_temporarytarget).date().duration().tempTarget();
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
try {
View view = inflater.inflate(R.layout.careportal_fragment, container, false);
view.findViewById(R.id.careportal_bgcheck).setOnClickListener(this);
@ -99,9 +99,9 @@ public class CareportalFragment extends SubscriberFragment implements View.OnCli
sage = (TextView) view.findViewById(R.id.careportal_sensorage);
pbage = (TextView) view.findViewById(R.id.careportal_pbage);
statsLayout = (View) view.findViewById(R.id.careportal_stats);
statsLayout = view.findViewById(R.id.careportal_stats);
noProfileView = (View) view.findViewById(R.id.profileview_noprofile);
noProfileView = view.findViewById(R.id.profileview_noprofile);
butonsLayout = (LinearLayout) view.findViewById(R.id.careportal_buttons);
ProfileStore profileStore = ConfigBuilderPlugin.getActiveProfileInterface().getProfile();
@ -118,6 +118,11 @@ public class CareportalFragment extends SubscriberFragment implements View.OnCli
updateGUI();
return view;
} catch (Exception e) {
Crashlytics.logException(e);
}
return null;
}
@Override
@ -129,66 +134,66 @@ public class CareportalFragment extends SubscriberFragment implements View.OnCli
NewNSTreatmentDialog newDialog = new NewNSTreatmentDialog();
switch (id) {
case R.id.careportal_bgcheck:
newDialog.setOptions(bgcheck, R.string.careportal_bgcheck);
newDialog.setOptions(BGCHECK, R.string.careportal_bgcheck);
break;
case R.id.careportal_announcement:
newDialog.setOptions(announcement, R.string.careportal_announcement);
newDialog.setOptions(ANNOUNCEMENT, R.string.careportal_announcement);
break;
case R.id.careportal_cgmsensorinsert:
newDialog.setOptions(sensorchange, R.string.careportal_cgmsensorinsert);
newDialog.setOptions(SENSORCHANGE, R.string.careportal_cgmsensorinsert);
break;
case R.id.careportal_cgmsensorstart:
newDialog.setOptions(sensorstart, R.string.careportal_cgmsensorstart);
newDialog.setOptions(SENSORSTART, R.string.careportal_cgmsensorstart);
break;
case R.id.careportal_combobolus:
newDialog.setOptions(combobolus, R.string.careportal_combobolus);
newDialog.setOptions(COMBOBOLUS, R.string.careportal_combobolus);
break;
case R.id.careportal_correctionbolus:
newDialog.setOptions(correctionbolus, R.string.careportal_correctionbolus);
newDialog.setOptions(CORRECTIONBOLUS, R.string.careportal_correctionbolus);
break;
case R.id.careportal_carbscorrection:
newDialog.setOptions(carbcorrection, R.string.careportal_carbscorrection);
newDialog.setOptions(CARBCORRECTION, R.string.careportal_carbscorrection);
break;
case R.id.careportal_exercise:
newDialog.setOptions(exercise, R.string.careportal_exercise);
newDialog.setOptions(EXERCISE, R.string.careportal_exercise);
break;
case R.id.careportal_insulincartridgechange:
newDialog.setOptions(insulinchange, R.string.careportal_insulincartridgechange);
newDialog.setOptions(INSULINCHANGE, R.string.careportal_insulincartridgechange);
break;
case R.id.careportal_pumpbatterychange:
newDialog.setOptions(pumpbatterychange, R.string.careportal_pumpbatterychange);
newDialog.setOptions(PUMPBATTERYCHANGE, R.string.careportal_pumpbatterychange);
break;
case R.id.careportal_mealbolus:
newDialog.setOptions(mealbolus, R.string.careportal_mealbolus);
newDialog.setOptions(MEALBOLUS, R.string.careportal_mealbolus);
break;
case R.id.careportal_note:
newDialog.setOptions(note, R.string.careportal_note);
newDialog.setOptions(NOTE, R.string.careportal_note);
break;
case R.id.careportal_profileswitch:
profileswitch.executeProfileSwitch = false;
newDialog.setOptions(profileswitch, R.string.careportal_profileswitch);
PROFILESWITCH.executeProfileSwitch = false;
newDialog.setOptions(PROFILESWITCH, R.string.careportal_profileswitch);
break;
case R.id.careportal_pumpsitechange:
newDialog.setOptions(sitechange, R.string.careportal_pumpsitechange);
newDialog.setOptions(SITECHANGE, R.string.careportal_pumpsitechange);
break;
case R.id.careportal_question:
newDialog.setOptions(question, R.string.careportal_question);
newDialog.setOptions(QUESTION, R.string.careportal_question);
break;
case R.id.careportal_snackbolus:
newDialog.setOptions(snackbolus, R.string.careportal_snackbolus);
newDialog.setOptions(SNACKBOLUS, R.string.careportal_snackbolus);
break;
case R.id.careportal_tempbasalstart:
newDialog.setOptions(tempbasalstart, R.string.careportal_tempbasalstart);
newDialog.setOptions(TEMPBASALSTART, R.string.careportal_tempbasalstart);
break;
case R.id.careportal_tempbasalend:
newDialog.setOptions(tempbasalend, R.string.careportal_tempbasalend);
newDialog.setOptions(TEMPBASALEND, R.string.careportal_tempbasalend);
break;
case R.id.careportal_openapsoffline:
newDialog.setOptions(openapsoffline, R.string.careportal_openapsoffline);
newDialog.setOptions(OPENAPSOFFLINE, R.string.careportal_openapsoffline);
break;
case R.id.careportal_temporarytarget:
temptarget.executeTempTarget = false;
newDialog.setOptions(temptarget, R.string.careportal_temporarytarget);
TEMPTARGET.executeTempTarget = false;
newDialog.setOptions(TEMPTARGET, R.string.careportal_temporarytarget);
break;
default:
newDialog = null;

View file

@ -7,8 +7,8 @@ import info.nightscout.androidaps.interfaces.PluginBase;
public class CareportalPlugin implements PluginBase {
boolean fragmentEnabled = true;
boolean fragmentVisible = true;
private boolean fragmentEnabled = true;
private boolean fragmentVisible = true;
@Override
public int getType() {

View file

@ -14,7 +14,9 @@ import android.text.format.DateFormat;
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.CompoundButton;
import android.widget.EditText;
import android.widget.LinearLayout;
@ -52,7 +54,6 @@ import info.nightscout.androidaps.events.EventNewBasalProfile;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.Careportal.OptionsToShow;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.ProfileCircadianPercentage.CircadianPercentageProfilePlugin;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.NSUpload;
import info.nightscout.utils.NumberPicker;
@ -73,17 +74,11 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
String units;
TextView eventTypeText;
LinearLayout layoutBg;
LinearLayout layoutBgSource;
LinearLayout layoutInsulin;
LinearLayout layoutCarbs;
LinearLayout layoutSplit;
LinearLayout layoutDuration;
LinearLayout layoutPercent;
LinearLayout layoutAbsolute;
LinearLayout layoutCarbTime;
LinearLayout layoutProfile;
LinearLayout layoutTempTarget;
LinearLayout layoutReuse;
TextView dateButton;
TextView timeButton;
@ -94,6 +89,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
EditText notesEdit;
Spinner profileSpinner;
Spinner reasonSpinner;
Button reuseButton;
NumberPicker editBg;
NumberPicker editCarbs;
@ -104,6 +100,8 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
NumberPicker editAbsolute;
NumberPicker editCarbTime;
NumberPicker editTemptarget;
NumberPicker editPercentage;
NumberPicker editTimeshift;
Date eventTime;
@ -144,17 +142,10 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
setStyle(DialogFragment.STYLE_NORMAL, getTheme());
View view = inflater.inflate(R.layout.careportal_newnstreatment_dialog, container, false);
layoutBg = (LinearLayout) view.findViewById(R.id.careportal_newnstreatment_bg_layout);
layoutBgSource = (LinearLayout) view.findViewById(R.id.careportal_newnstreatment_bgsource_layout);
layoutInsulin = (LinearLayout) view.findViewById(R.id.careportal_newnstreatment_insulin_layout);
layoutCarbs = (LinearLayout) view.findViewById(R.id.careportal_newnstreatment_carbs_layout);
layoutSplit = (LinearLayout) view.findViewById(R.id.careportal_newnstreatment_split_layout);
layoutDuration = (LinearLayout) view.findViewById(R.id.careportal_newnstreatment_duration_layout);
layoutPercent = (LinearLayout) view.findViewById(R.id.careportal_newnstreatment_percent_layout);
layoutAbsolute = (LinearLayout) view.findViewById(R.id.careportal_newnstreatment_absolute_layout);
layoutCarbTime = (LinearLayout) view.findViewById(R.id.careportal_newnstreatment_carbtime_layout);
layoutProfile = (LinearLayout) view.findViewById(R.id.careportal_newnstreatment_profile_layout);
layoutTempTarget = (LinearLayout) view.findViewById(R.id.careportal_newnstreatment_temptarget_layout);
layoutReuse = (LinearLayout) view.findViewById(R.id.careportal_newnstreatment_reuse_layout);
eventTypeText = (TextView) view.findViewById(R.id.careportal_newnstreatment_eventtype);
eventTypeText.setText(event);
@ -164,6 +155,8 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
otherRadioButton = (RadioButton) view.findViewById(R.id.careportal_newnstreatment_other);
profileSpinner = (Spinner) view.findViewById(R.id.careportal_newnstreatment_profile);
reuseButton = (Button) view.findViewById(R.id.careportal_newnstreatment_reusebutton);
notesEdit = (EditText) view.findViewById(R.id.careportal_newnstreatment_notes);
reasonSpinner = (Spinner) view.findViewById(R.id.careportal_newnstreatment_temptarget_reason);
@ -194,32 +187,57 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
profileSpinner.setSelection(p);
}
final Double bg = Profile.fromMgdlToUnits(GlucoseStatus.getGlucoseStatusData() != null ? GlucoseStatus.getGlucoseStatusData().glucose : 0d, profile != null ? profile.getUnits() : Constants.MGDL);
// temp target
ArrayList<CharSequence> reasonList = new ArrayList<CharSequence>();
final ArrayList<CharSequence> reasonList = new ArrayList<CharSequence>();
reasonList.add(MainApp.sResources.getString(R.string.manual));
reasonList.add(MainApp.sResources.getString(R.string.eatingsoon));
reasonList.add(MainApp.sResources.getString(R.string.activity));
reasonList.add(MainApp.sResources.getString(R.string.manual));
ArrayAdapter<CharSequence> adapterReason = new ArrayAdapter<CharSequence>(getContext(),
R.layout.spinner_centered, reasonList);
reasonSpinner.setAdapter(adapterReason);
reasonSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
double defaultDuration = 0;
double defaultTarget = 0;
if(profile!=null){
defaultTarget = bg.doubleValue();
}
boolean erase = false;
if(MainApp.sResources.getString(R.string.eatingsoon).equals(reasonList.get(position))){
defaultDuration = SP.getDouble(R.string.key_eatingsoon_duration, 0d);
defaultTarget = SP.getDouble(R.string.key_eatingsoon_target, 0d);;
} else if (MainApp.sResources.getString(R.string.activity).equals(reasonList.get(position))){
defaultDuration = SP.getDouble(R.string.key_activity_duration, 0d);;
defaultTarget = SP.getDouble(R.string.key_activity_target, 0d);;
} else {
defaultDuration = 0;
erase = true;
}
if(defaultTarget != 0 || erase){
editTemptarget.setValue(defaultTarget);
}
if(defaultDuration != 0){
editDuration.setValue(defaultDuration);
} else if (erase){
editDuration.setValue(0d);
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
// bg
bgUnitsView.setText(units);
Double bg = Profile.fromMgdlToUnits(GlucoseStatus.getGlucoseStatusData() != null ? GlucoseStatus.getGlucoseStatusData().glucose : 0d, profile != null ? profile.getUnits() : Constants.MGDL);
editBg = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_bginput);
editTemptarget = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_temptarget);
if (profile == null) {
editBg.setParams(bg, 0d, 500d, 0.1d, new DecimalFormat("0.0"), false);
editTemptarget.setParams(bg, 0d, 500d, 0.1d, new DecimalFormat("0.0"), false);
} else if (profile.getUnits().equals(Constants.MMOL)) {
editBg.setParams(bg, 0d, 30d, 0.1d, new DecimalFormat("0.0"), false);
editTemptarget.setParams(bg, 0d, 30d, 0.1d, new DecimalFormat("0.0"), false);
} else {
editBg.setParams(bg, 0d, 500d, 1d, new DecimalFormat("0"), false);
editTemptarget.setParams(bg, 0d, 500d, 1d, new DecimalFormat("0"), false);
}
editBg.addTextChangedListener(new TextWatcher() {
TextWatcher bgTextWatcher = new TextWatcher() {
public void afterTextChanged(Editable s) {
}
@ -229,8 +247,20 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (sensorRadioButton.isChecked()) meterRadioButton.setChecked(true);
}
});
};
editBg = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_bginput);
editTemptarget = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_temptarget);
if (profile == null) {
editBg.setParams(bg, 0d, 500d, 0.1d, new DecimalFormat("0.0"), false, bgTextWatcher);
editTemptarget.setParams(bg, 0d, 500d, 0.1d, new DecimalFormat("0.0"), false);
} else if (profile.getUnits().equals(Constants.MMOL)) {
editBg.setParams(bg, 0d, 30d, 0.1d, new DecimalFormat("0.0"), false, bgTextWatcher);
editTemptarget.setParams(bg, 0d, 30d, 0.1d, new DecimalFormat("0.0"), false);
} else {
editBg.setParams(bg, 0d, 500d, 1d, new DecimalFormat("0"), false, bgTextWatcher);
editTemptarget.setParams(bg, 0d, 500d, 1d, new DecimalFormat("0"), false);
}
sensorRadioButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
@ -252,10 +282,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
editDuration = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_durationinput);
editDuration.setParams(0d, 0d, 24 * 60d, 10d, new DecimalFormat("0"), false);
Integer maxPercent = MainApp.getConfigBuilder().applyBasalConstraints(Constants.basalPercentOnlyForCheckLimit);
editPercent = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_percentinput);
editPercent.setParams(0d, 0d, (double) maxPercent, 5d, new DecimalFormat("0"), true);
editPercent.addTextChangedListener(new TextWatcher() {
TextWatcher percentTextWatcher = new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
}
@ -271,12 +298,13 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
layoutPercent.setVisibility(View.VISIBLE);
layoutAbsolute.setVisibility(View.GONE);
}
});
};
Double maxAbsolute = MainApp.getConfigBuilder().applyBasalConstraints(Constants.basalAbsoluteOnlyForCheckLimit);
editAbsolute = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_absoluteinput);
editAbsolute.setParams(0d, 0d, maxAbsolute, 0.05d, new DecimalFormat("0.00"), true);
editAbsolute.addTextChangedListener(new TextWatcher() {
Integer maxPercent = MainApp.getConfigBuilder().applyBasalConstraints(Constants.basalPercentOnlyForCheckLimit);
editPercent = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_percentinput);
editPercent.setParams(0d, 0d, (double) maxPercent, 5d, new DecimalFormat("0"), true, percentTextWatcher);
TextWatcher absoluteTextWatcher = new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
}
@ -292,23 +320,50 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
layoutPercent.setVisibility(View.GONE);
layoutAbsolute.setVisibility(View.VISIBLE);
}
});
};
Double maxAbsolute = MainApp.getConfigBuilder().applyBasalConstraints(Constants.basalAbsoluteOnlyForCheckLimit);
editAbsolute = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_absoluteinput);
editAbsolute.setParams(0d, 0d, maxAbsolute, 0.05d, new DecimalFormat("0.00"), true, absoluteTextWatcher);
editCarbTime = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_carbtimeinput);
editCarbTime.setParams(0d, -60d, 60d, 5d, new DecimalFormat("0"), false);
editPercentage = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_percentage);
editPercentage.setParams(100d, (double) Constants.CPP_MIN_PERCENTAGE, (double) Constants.CPP_MAX_PERCENTAGE, 1d, new DecimalFormat("0"), false);
showOrHide(layoutBg, options.bg);
showOrHide(layoutBgSource, options.bg);
showOrHide(layoutInsulin, options.insulin);
showOrHide(layoutCarbs, options.carbs);
showOrHide(layoutSplit, options.split);
showOrHide(layoutDuration, options.duration);
editTimeshift = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_timeshift);
editTimeshift.setParams(0d, (double) Constants.CPP_MIN_TIMESHIFT, (double) Constants.CPP_MAX_TIMESHIFT, 1d, new DecimalFormat("0"), false);
ProfileSwitch ps = MainApp.getConfigBuilder().getProfileSwitchFromHistory(System.currentTimeMillis());
if(ps!=null && ps.isCPP){
final int percentage = ps.percentage;
final int timeshift = ps.timeshift;
reuseButton.setText(reuseButton.getText() + " " + percentage + "% " + timeshift +"h");
reuseButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
editPercentage.setValue((double)percentage);
editTimeshift.setValue((double)timeshift);
}
});
}
showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_eventtime_layout), options.date);
showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_bg_layout), options.bg);
showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_bgsource_layout), options.bg);
showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_insulin_layout), options.insulin);
showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_carbs_layout), options.carbs);
showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_split_layout), options.split);
showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_duration_layout), options.duration);
showOrHide(layoutPercent, options.percent);
showOrHide(layoutAbsolute, options.absolute);
showOrHide(layoutCarbTime, options.prebolus);
showOrHide(layoutProfile, options.profile);
showOrHide(layoutTempTarget, options.tempTarget);
showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_carbtime_layout), options.prebolus);
showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_profile_layout), options.profile);
showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_percentage_layout), options.profile);
showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_timeshift_layout), options.profile);
showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_reuse_layout), options.profile && ps!=null && ps.isCPP);
showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_temptarget_layout), options.tempTarget);
return view;
}
@ -451,7 +506,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
allowZeroDuration = true;
break;
}
if (SafeParse.stringToDouble(editBg.getText()) != 0d) {
if (options.bg && SafeParse.stringToDouble(editBg.getText()) != 0d) {
data.put("glucose", SafeParse.stringToDouble(editBg.getText()));
if (meterRadioButton.isChecked()) data.put("glucoseType", "Finger");
if (sensorRadioButton.isChecked()) data.put("glucoseType", "Sensor");
@ -469,6 +524,10 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
data.put("absolute", SafeParse.stringToDouble(editAbsolute.getText()));
if (options.profile && profileSpinner.getSelectedItem() != null)
data.put("profile", profileSpinner.getSelectedItem().toString());
if (options.profile)
data.put("percentage", SafeParse.stringToInt(editPercentage.getText()));
if (options.profile)
data.put("timeshift", SafeParse.stringToInt(editTimeshift.getText()));
if (SafeParse.stringToDouble(editCarbTime.getText()) != 0d)
data.put("preBolus", SafeParse.stringToDouble(editCarbTime.getText()));
if (!notesEdit.getText().toString().equals(""))
@ -556,6 +615,18 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
ret += data.get("profile");
ret += "\n";
}
if (data.has("percentage")) {
ret += getString(R.string.careportal_newnstreatment_percentage_label);
ret += ": ";
ret += data.get("percentage");
ret += " %\n";
}
if (data.has("timeshift")) {
ret += getString(R.string.careportal_newnstreatment_timeshift_label);
ret += ": ";
ret += data.get("timeshift");
ret += " h\n";
}
if (data.has("targetBottom") && data.has("targetTop")) {
ret += getString(R.string.target_range);
ret += " ";
@ -594,7 +665,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
if (options.executeProfileSwitch) {
if (data.has("profile")) {
try {
doProfileSwitch(profileStore, data.getString("profile"), data.getInt("duration"));
doProfileSwitch(profileStore, data.getString("profile"), data.getInt("duration"), data.getInt("percentage"), data.getInt("timeshift"));
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
@ -641,7 +712,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
builder.show();
}
public static void doProfileSwitch(final ProfileStore profileStore, final String profileName, final int duration) {
public static void doProfileSwitch(final ProfileStore profileStore, final String profileName, final int duration, final int percentage, final int timeshift) {
sHandler.post(new Runnable() {
@Override
public void run() {
@ -652,17 +723,14 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
profileSwitch.profileJson = profileStore.getSpecificProfile(profileName).getData().toString();
profileSwitch.profilePlugin = ConfigBuilderPlugin.getActiveProfileInterface().getClass().getName();
profileSwitch.durationInMinutes = duration;
if (ConfigBuilderPlugin.getActiveProfileInterface() instanceof CircadianPercentageProfilePlugin) {
CircadianPercentageProfilePlugin cpp = (CircadianPercentageProfilePlugin) ConfigBuilderPlugin.getActiveProfileInterface();
profileSwitch.isCPP = true;
profileSwitch.timeshift = cpp.timeshift;
profileSwitch.percentage = cpp.percentage;
}
profileSwitch.isCPP = percentage != 100 || timeshift != 0;
profileSwitch.timeshift = timeshift;
profileSwitch.percentage = percentage;
MainApp.getConfigBuilder().addToHistoryProfileSwitch(profileSwitch);
PumpInterface pump = MainApp.getConfigBuilder();
if (pump != null) {
pump.setNewBasalProfile(profileStore.getSpecificProfile(profileName));
pump.setNewBasalProfile(profileSwitch.getProfileObject());
MainApp.bus().post(new EventNewBasalProfile());
} else {
log.error("No active pump selected");
@ -672,4 +740,37 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
});
}
public static void doProfileSwitch(final int duration, final int percentage, final int timeshift) {
sHandler.post(new Runnable() {
@Override
public void run() {
ProfileSwitch profileSwitch = MainApp.getConfigBuilder().getProfileSwitchFromHistory(System.currentTimeMillis());
if (profileSwitch != null) {
profileSwitch = new ProfileSwitch();
profileSwitch.date = System.currentTimeMillis();
profileSwitch.source = Source.USER;
profileSwitch.profileName = MainApp.getConfigBuilder().getProfileName(System.currentTimeMillis(), false);
profileSwitch.profileJson = MainApp.getConfigBuilder().getProfile().getData().toString();
profileSwitch.profilePlugin = ConfigBuilderPlugin.getActiveProfileInterface().getClass().getName();
profileSwitch.durationInMinutes = duration;
profileSwitch.isCPP = percentage != 100 || timeshift != 0;
profileSwitch.timeshift = timeshift;
profileSwitch.percentage = percentage;
MainApp.getConfigBuilder().addToHistoryProfileSwitch(profileSwitch);
PumpInterface pump = MainApp.getConfigBuilder();
if (pump != null) {
pump.setNewBasalProfile(profileSwitch.getProfileObject());
MainApp.bus().post(new EventNewBasalProfile());
} else {
log.error("No active pump selected");
}
Answers.getInstance().logCustom(new CustomEvent("ProfileSwitch"));
} else {
log.error("No profile switch existing");
}
}
});
}
}

View file

@ -7,6 +7,7 @@ package info.nightscout.androidaps.plugins.Careportal;
public class OptionsToShow {
public int eventType;
public int eventName;
public boolean date;
public boolean bg;
public boolean insulin;
public boolean carbs;
@ -22,29 +23,63 @@ public class OptionsToShow {
public boolean executeProfileSwitch = false;
public boolean executeTempTarget = false;
public OptionsToShow(int eventType,
int eventName,
boolean bg,
boolean insulin,
boolean carbs,
boolean prebolus,
boolean duration,
boolean percent,
boolean absolute,
boolean profile,
boolean split,
boolean tempTarget) {
public OptionsToShow(int eventType, int eventName) {
this.eventType = eventType;
this.eventName = eventName;
this.bg = bg;
this.insulin = insulin;
this.carbs = carbs;
this.prebolus = prebolus;
this.duration = duration;
this.percent = percent;
this.absolute = absolute;
this.profile = profile;
this.split = split;
this.tempTarget = tempTarget;
}
public OptionsToShow date() {
date = true;
return this;
}
public OptionsToShow bg() {
bg = true;
return this;
}
public OptionsToShow insulin() {
insulin = true;
return this;
}
public OptionsToShow carbs() {
carbs = true;
return this;
}
public OptionsToShow prebolus() {
prebolus = true;
return this;
}
public OptionsToShow duration() {
duration = true;
return this;
}
public OptionsToShow percent() {
percent = true;
return this;
}
public OptionsToShow absolute() {
absolute = true;
return this;
}
public OptionsToShow profile() {
profile = true;
return this;
}
public OptionsToShow split() {
split = true;
return this;
}
public OptionsToShow tempTarget() {
tempTarget = true;
return this;
}
}

View file

@ -15,6 +15,7 @@ import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
import com.crashlytics.android.Crashlytics;
import com.crashlytics.android.answers.Answers;
import com.crashlytics.android.answers.CustomEvent;
@ -55,6 +56,8 @@ public class ConfigBuilderFragment extends Fragment {
TextView pumpLabel;
ListView loopListView;
TextView loopLabel;
ListView treatmentsListView;
TextView treatmentsLabel;
ListView profileListView;
TextView profileLabel;
ListView apsListView;
@ -71,6 +74,7 @@ public class ConfigBuilderFragment extends Fragment {
PluginCustomAdapter bgsourceDataAdapter = null;
PluginCustomAdapter pumpDataAdapter = null;
PluginCustomAdapter loopDataAdapter = null;
PluginCustomAdapter treatmentDataAdapter = null;
PluginCustomAdapter profileDataAdapter = null;
PluginCustomAdapter apsDataAdapter = null;
PluginCustomAdapter constraintsDataAdapter = null;
@ -79,6 +83,7 @@ public class ConfigBuilderFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
try {
View view = inflater.inflate(R.layout.configbuilder_fragment, container, false);
insulinListView = (ListView) view.findViewById(R.id.configbuilder_insulinlistview);
@ -89,6 +94,8 @@ public class ConfigBuilderFragment extends Fragment {
pumpLabel = (TextView) view.findViewById(R.id.configbuilder_pumplabel);
loopListView = (ListView) view.findViewById(R.id.configbuilder_looplistview);
loopLabel = (TextView) view.findViewById(R.id.configbuilder_looplabel);
treatmentsListView = (ListView) view.findViewById(R.id.configbuilder_treatmentslistview);
treatmentsLabel = (TextView) view.findViewById(R.id.configbuilder_treatmentslabel);
profileListView = (ListView) view.findViewById(R.id.configbuilder_profilelistview);
profileLabel = (TextView) view.findViewById(R.id.configbuilder_profilelabel);
apsListView = (ListView) view.findViewById(R.id.configbuilder_apslistview);
@ -120,6 +127,11 @@ public class ConfigBuilderFragment extends Fragment {
unlock.setVisibility(View.GONE);
}
return view;
} catch (Exception e) {
Crashlytics.logException(e);
}
return null;
}
void setViews() {
@ -141,6 +153,11 @@ public class ConfigBuilderFragment extends Fragment {
setListViewHeightBasedOnChildren(loopListView);
if (MainApp.getSpecificPluginsVisibleInList(PluginBase.LOOP).size() == 0)
loopLabel.setVisibility(View.GONE);
treatmentDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInList(PluginBase.TREATMENT), PluginBase.TREATMENT);
treatmentsListView.setAdapter(treatmentDataAdapter);
setListViewHeightBasedOnChildren(treatmentsListView);
if (MainApp.getSpecificPluginsVisibleInList(PluginBase.TREATMENT).size() == 0)
treatmentsLabel.setVisibility(View.GONE);
profileDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInListByInterface(ProfileInterface.class, PluginBase.PROFILE), PluginBase.PROFILE);
profileListView.setAdapter(profileDataAdapter);
if (MainApp.getSpecificPluginsVisibleInList(PluginBase.PROFILE).size() == 0)

View file

@ -574,7 +574,7 @@ public class ConfigBuilderPlugin implements PluginBase, PumpInterface, Constrain
if (Config.logCongigBuilderActions)
log.debug("applyAPSRequest: Basal set correctly");
}
} else if (isTempBasalInProgress() && Math.abs(request.rate - getTempBasalAbsoluteRateHistory()) < 0.05) {
} else if (isTempBasalInProgress() && Math.abs(request.rate - getTempBasalAbsoluteRateHistory()) < getPumpDescription().basalStep) {
result = new PumpEnactResult();
result.absolute = getTempBasalAbsoluteRateHistory();
result.duration = getTempBasalFromHistory(System.currentTimeMillis()).getPlannedRemainingMinutes();
@ -934,10 +934,14 @@ public class ConfigBuilderPlugin implements PluginBase, PumpInterface, Constrain
}
public String getProfileName(long time) {
return getProfileName(time, true);
}
public String getProfileName(long time, boolean customized) {
ProfileSwitch profileSwitch = getProfileSwitchFromHistory(time);
if (profileSwitch != null) {
if (profileSwitch.profileJson != null) {
return profileSwitch.profileName;
return customized ? profileSwitch.getCustomizedName() : profileSwitch.profileName;
} else {
Profile profile = activeProfile.getProfile().getSpecificProfile(profileSwitch.profileName);
if (profile != null)
@ -993,7 +997,7 @@ public class ConfigBuilderPlugin implements PluginBase, PumpInterface, Constrain
MainApp.bus().post(new EventNewNotification(nobasal));
Notification notarget = new Notification(Notification.TARGET_MISSING, MainApp.sResources.getString(R.string.targetmissing), Notification.URGENT);
MainApp.bus().post(new EventNewNotification(notarget));
return new Profile(new JSONObject("{\"dia\":\"3\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"20\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"20\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"6\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"8\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}}"));
return new Profile(new JSONObject("{\"dia\":\"3\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"20\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"20\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"6\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"8\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}}"), 100, 0);
} catch (JSONException e) {
log.error("Unhandled exception", e);
}

View file

@ -15,6 +15,8 @@ import android.widget.CheckBox;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.crashlytics.android.Crashlytics;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -27,15 +29,6 @@ import info.nightscout.androidaps.R;
public class ObjectivesFragment extends Fragment {
private static Logger log = LoggerFactory.getLogger(ObjectivesFragment.class);
private static ObjectivesPlugin objectivesPlugin;
public static ObjectivesPlugin getPlugin() {
if (objectivesPlugin == null) {
objectivesPlugin = new ObjectivesPlugin();
}
return objectivesPlugin;
}
RecyclerView recyclerView;
LinearLayoutManager llm;
CheckBox enableFake;
@ -59,7 +52,7 @@ public class ObjectivesFragment extends Fragment {
@Override
public void onBindViewHolder(ObjectiveViewHolder holder, int position) {
ObjectivesPlugin.Objective o = objectives.get(position);
ObjectivesPlugin.RequirementResult requirementsMet = getPlugin().requirementsMet(position);
ObjectivesPlugin.RequirementResult requirementsMet = ObjectivesPlugin.getPlugin().requirementsMet(position);
Context context = MainApp.instance().getApplicationContext();
holder.position.setText(String.valueOf(position + 1));
holder.objective.setText(o.objective);
@ -83,7 +76,7 @@ public class ObjectivesFragment extends Fragment {
holder.verifyButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
ObjectivesPlugin.Objective o = (ObjectivesPlugin.Objective) v.getTag();
if (getPlugin().requirementsMet(o.num).done || enableFake.isChecked()) {
if (ObjectivesPlugin.getPlugin().requirementsMet(o.num).done || enableFake.isChecked()) {
o.accomplished = new Date();
updateGUI();
ObjectivesPlugin.saveProgress();
@ -173,6 +166,7 @@ public class ObjectivesFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
try {
View view = inflater.inflate(R.layout.objectives_fragment, container, false);
recyclerView = (RecyclerView) view.findViewById(R.id.objectives_recyclerview);
@ -189,29 +183,34 @@ public class ObjectivesFragment extends Fragment {
});
reset.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
getPlugin().initializeData();
getPlugin().saveProgress();
ObjectivesPlugin.getPlugin().initializeData();
ObjectivesPlugin.saveProgress();
updateGUI();
}
});
// Add correct translations to array after app is initialized
getPlugin().objectives.get(0).objective = MainApp.sResources.getString(R.string.objectives_0_objective);
getPlugin().objectives.get(1).objective = MainApp.sResources.getString(R.string.objectives_1_objective);
getPlugin().objectives.get(2).objective = MainApp.sResources.getString(R.string.objectives_2_objective);
getPlugin().objectives.get(3).objective = MainApp.sResources.getString(R.string.objectives_3_objective);
getPlugin().objectives.get(4).objective = MainApp.sResources.getString(R.string.objectives_4_objective);
getPlugin().objectives.get(5).objective = MainApp.sResources.getString(R.string.objectives_5_objective);
getPlugin().objectives.get(6).objective = MainApp.sResources.getString(R.string.objectives_6_objective);
getPlugin().objectives.get(0).gate = MainApp.sResources.getString(R.string.objectives_0_gate);
getPlugin().objectives.get(1).gate = MainApp.sResources.getString(R.string.objectives_1_gate);
getPlugin().objectives.get(2).gate = MainApp.sResources.getString(R.string.objectives_2_gate);
getPlugin().objectives.get(3).gate = MainApp.sResources.getString(R.string.objectives_3_gate);
getPlugin().objectives.get(4).gate = MainApp.sResources.getString(R.string.objectives_4_gate);
getPlugin().objectives.get(5).gate = MainApp.sResources.getString(R.string.objectives_5_gate);
ObjectivesPlugin.objectives.get(0).objective = MainApp.sResources.getString(R.string.objectives_0_objective);
ObjectivesPlugin.objectives.get(1).objective = MainApp.sResources.getString(R.string.objectives_1_objective);
ObjectivesPlugin.objectives.get(2).objective = MainApp.sResources.getString(R.string.objectives_2_objective);
ObjectivesPlugin.objectives.get(3).objective = MainApp.sResources.getString(R.string.objectives_3_objective);
ObjectivesPlugin.objectives.get(4).objective = MainApp.sResources.getString(R.string.objectives_4_objective);
ObjectivesPlugin.objectives.get(5).objective = MainApp.sResources.getString(R.string.objectives_5_objective);
ObjectivesPlugin.objectives.get(6).objective = MainApp.sResources.getString(R.string.objectives_6_objective);
ObjectivesPlugin.objectives.get(0).gate = MainApp.sResources.getString(R.string.objectives_0_gate);
ObjectivesPlugin.objectives.get(1).gate = MainApp.sResources.getString(R.string.objectives_1_gate);
ObjectivesPlugin.objectives.get(2).gate = MainApp.sResources.getString(R.string.objectives_2_gate);
ObjectivesPlugin.objectives.get(3).gate = MainApp.sResources.getString(R.string.objectives_3_gate);
ObjectivesPlugin.objectives.get(4).gate = MainApp.sResources.getString(R.string.objectives_4_gate);
ObjectivesPlugin.objectives.get(5).gate = MainApp.sResources.getString(R.string.objectives_5_gate);
updateGUI();
return view;
} catch (Exception e) {
Crashlytics.logException(e);
}
return null;
}
void updateGUI() {

View file

@ -25,11 +25,20 @@ import info.nightscout.utils.SP;
public class ObjectivesPlugin implements PluginBase, ConstraintsInterface {
private static Logger log = LoggerFactory.getLogger(ObjectivesPlugin.class);
private static ObjectivesPlugin objectivesPlugin;
public static ObjectivesPlugin getPlugin() {
if (objectivesPlugin == null) {
objectivesPlugin = new ObjectivesPlugin();
}
return objectivesPlugin;
}
public static List<Objective> objectives;
boolean fragmentVisible = true;
private boolean fragmentVisible = true;
public ObjectivesPlugin() {
private ObjectivesPlugin() {
initializeData();
loadProgress();
MainApp.bus().register(this);
@ -95,7 +104,7 @@ public class ObjectivesPlugin implements PluginBase, ConstraintsInterface {
if (type == CONSTRAINTS) this.fragmentVisible = fragmentVisible;
}
public class Objective {
class Objective {
Integer num;
String objective;
String gate;
@ -118,13 +127,13 @@ public class ObjectivesPlugin implements PluginBase, ConstraintsInterface {
public static boolean pumpStatusIsAvailableInNS = false;
// Objective 1
public static Integer manualEnacts = 0;
public static final Integer manualEnactsNeeded = 20;
private static final Integer manualEnactsNeeded = 20;
public class RequirementResult {
class RequirementResult {
boolean done = false;
String comment = "";
public RequirementResult(boolean done, String comment) {
RequirementResult(boolean done, String comment) {
this.done = done;
this.comment = comment;
}
@ -135,7 +144,7 @@ public class ObjectivesPlugin implements PluginBase, ConstraintsInterface {
else return "---";
}
public RequirementResult requirementsMet(Integer objNum) {
RequirementResult requirementsMet(Integer objNum) {
switch (objNum) {
case 0:
return new RequirementResult(bgIsAvailableInNS && pumpStatusIsAvailableInNS,
@ -152,7 +161,7 @@ public class ObjectivesPlugin implements PluginBase, ConstraintsInterface {
}
public void initializeData() {
void initializeData() {
bgIsAvailableInNS = false;
pumpStatusIsAvailableInNS = false;
manualEnacts = 0;
@ -220,7 +229,7 @@ public class ObjectivesPlugin implements PluginBase, ConstraintsInterface {
}
}
void loadProgress() {
private void loadProgress() {
for (int num = 0; num < objectives.size(); num++) {
Objective o = objectives.get(num);
try {

View file

@ -14,8 +14,8 @@ import info.nightscout.androidaps.interfaces.PluginBase;
public class InsulinFastactingPlugin implements PluginBase, InsulinInterface {
private static boolean fragmentEnabled = true;
private static boolean fragmentVisible = false;
private boolean fragmentEnabled = true;
private boolean fragmentVisible = false;
private static InsulinFastactingPlugin plugin = null;

View file

@ -14,8 +14,8 @@ import info.nightscout.androidaps.interfaces.PluginBase;
public class InsulinFastactingProlongedPlugin implements PluginBase, InsulinInterface {
private static boolean fragmentEnabled = false;
private static boolean fragmentVisible = false;
private boolean fragmentEnabled = false;
private boolean fragmentVisible = false;
private static InsulinFastactingProlongedPlugin plugin = null;

View file

@ -7,8 +7,11 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.crashlytics.android.Crashlytics;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
/**
* Created by mike on 17.04.2017.
@ -22,6 +25,7 @@ public class InsulinFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
try {
View view = inflater.inflate(R.layout.insulin_fragment, container, false);
insulinName = (TextView) view.findViewById(R.id.insulin_name);
@ -32,6 +36,11 @@ public class InsulinFragment extends Fragment {
updateGUI();
return view;
} catch (Exception e) {
Crashlytics.logException(e);
}
return null;
}
@Override
@ -41,10 +50,10 @@ public class InsulinFragment extends Fragment {
}
private void updateGUI() {
insulinName.setText(MainApp.getConfigBuilder().getActiveInsulin().getFriendlyName());
insulinComment.setText(MainApp.getConfigBuilder().getActiveInsulin().getComment());
insulinDia.setText(MainApp.sResources.getText(R.string.dia) + " " + Double.toString(MainApp.getConfigBuilder().getActiveInsulin().getDia()) + "h");
insulinGraph.show(MainApp.getConfigBuilder().getActiveInsulin());
insulinName.setText(ConfigBuilderPlugin.getActiveInsulin().getFriendlyName());
insulinComment.setText(ConfigBuilderPlugin.getActiveInsulin().getComment());
insulinDia.setText(MainApp.sResources.getText(R.string.dia) + " " + Double.toString(ConfigBuilderPlugin.getActiveInsulin().getDia()) + "h");
insulinGraph.show(ConfigBuilderPlugin.getActiveInsulin());
}
}

View file

@ -10,8 +10,8 @@ import info.nightscout.utils.SP;
public class InsulinOrefFreePeakPlugin extends InsulinOrefBasePlugin {
private static boolean fragmentEnabled = false;
private static boolean fragmentVisible = false;
private boolean fragmentEnabled = false;
private boolean fragmentVisible = false;
private static InsulinOrefFreePeakPlugin plugin = null;

View file

@ -9,8 +9,8 @@ import info.nightscout.androidaps.R;
public class InsulinOrefRapidActingPlugin extends InsulinOrefBasePlugin {
private static boolean fragmentEnabled = false;
private static boolean fragmentVisible = false;
private boolean fragmentEnabled = false;
private boolean fragmentVisible = false;
private static InsulinOrefRapidActingPlugin plugin = null;

View file

@ -9,8 +9,8 @@ import info.nightscout.androidaps.R;
public class InsulinOrefUltraRapidActingPlugin extends InsulinOrefBasePlugin {
private static boolean fragmentEnabled = false;
private static boolean fragmentVisible = false;
private boolean fragmentEnabled = false;
private boolean fragmentVisible = false;
private static InsulinOrefUltraRapidActingPlugin plugin = null;

View file

@ -9,6 +9,7 @@ import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import com.crashlytics.android.Crashlytics;
import com.crashlytics.android.answers.Answers;
import com.crashlytics.android.answers.CustomEvent;
import com.squareup.otto.Subscribe;
@ -25,15 +26,6 @@ import info.nightscout.androidaps.plugins.Loop.events.EventLoopUpdateGui;
public class LoopFragment extends SubscriberFragment implements View.OnClickListener {
private static Logger log = LoggerFactory.getLogger(LoopFragment.class);
private static LoopPlugin loopPlugin;
public static LoopPlugin getPlugin() {
if (loopPlugin == null){
loopPlugin = new LoopPlugin();
}
return loopPlugin;
}
Button runNowButton;
TextView lastRunView;
TextView lastEnactView;
@ -46,6 +38,7 @@ public class LoopFragment extends SubscriberFragment implements View.OnClickList
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
try {
View view = inflater.inflate(R.layout.loop_fragment, container, false);
lastRunView = (TextView) view.findViewById(R.id.loop_lastrun);
@ -59,6 +52,11 @@ public class LoopFragment extends SubscriberFragment implements View.OnClickList
updateGUI();
return view;
} catch (Exception e) {
Crashlytics.logException(e);
}
return null;
}
@Override
@ -69,7 +67,7 @@ public class LoopFragment extends SubscriberFragment implements View.OnClickList
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
getPlugin().invoke("Loop button", true);
LoopPlugin.getPlugin().invoke("Loop button", true);
}
});
thread.start();
@ -105,13 +103,13 @@ public class LoopFragment extends SubscriberFragment implements View.OnClickList
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
if (getPlugin().lastRun != null) {
requestView.setText(getPlugin().lastRun.request != null ? getPlugin().lastRun.request.toSpanned() : "");
constraintsProcessedView.setText(getPlugin().lastRun.constraintsProcessed != null ? getPlugin().lastRun.constraintsProcessed.toSpanned() : "");
setByPumpView.setText(getPlugin().lastRun.setByPump != null ? getPlugin().lastRun.setByPump.toSpanned() : "");
sourceView.setText(getPlugin().lastRun.source != null ? getPlugin().lastRun.source : "");
lastRunView.setText(getPlugin().lastRun.lastAPSRun != null && getPlugin().lastRun.lastAPSRun.getTime() != 0 ? getPlugin().lastRun.lastAPSRun.toLocaleString() : "");
lastEnactView.setText(getPlugin().lastRun.lastEnact != null && getPlugin().lastRun.lastEnact.getTime() != 0 ? getPlugin().lastRun.lastEnact.toLocaleString() : "");
if (LoopPlugin.lastRun != null) {
requestView.setText(LoopPlugin.lastRun.request != null ? LoopPlugin.lastRun.request.toSpanned() : "");
constraintsProcessedView.setText(LoopPlugin.lastRun.constraintsProcessed != null ? LoopPlugin.lastRun.constraintsProcessed.toSpanned() : "");
setByPumpView.setText(LoopPlugin.lastRun.setByPump != null ? LoopPlugin.lastRun.setByPump.toSpanned() : "");
sourceView.setText(LoopPlugin.lastRun.source != null ? LoopPlugin.lastRun.source : "");
lastRunView.setText(LoopPlugin.lastRun.lastAPSRun != null && LoopPlugin.lastRun.lastAPSRun.getTime() != 0 ? LoopPlugin.lastRun.lastAPSRun.toLocaleString() : "");
lastEnactView.setText(LoopPlugin.lastRun.lastEnact != null && LoopPlugin.lastRun.lastEnact.getTime() != 0 ? LoopPlugin.lastRun.lastEnact.toLocaleString() : "");
}
}
});

View file

@ -46,6 +46,15 @@ import info.nightscout.utils.SafeParse;
public class LoopPlugin implements PluginBase {
private static Logger log = LoggerFactory.getLogger(LoopPlugin.class);
private static LoopPlugin loopPlugin;
public static LoopPlugin getPlugin() {
if (loopPlugin == null) {
loopPlugin = new LoopPlugin();
}
return loopPlugin;
}
private static Handler sHandler;
private static HandlerThread sHandlerThread;

View file

@ -18,6 +18,7 @@ import android.widget.CompoundButton;
import android.widget.ScrollView;
import android.widget.TextView;
import com.crashlytics.android.Crashlytics;
import com.crashlytics.android.answers.Answers;
import com.crashlytics.android.answers.CustomEvent;
import com.squareup.otto.Subscribe;
@ -37,15 +38,6 @@ import info.nightscout.utils.SP;
public class NSClientInternalFragment extends SubscriberFragment implements View.OnClickListener, CompoundButton.OnCheckedChangeListener {
private static Logger log = LoggerFactory.getLogger(NSClientInternalFragment.class);
static NSClientInternalPlugin nsClientInternalPlugin;
static public NSClientInternalPlugin getPlugin() {
if (nsClientInternalPlugin == null) {
nsClientInternalPlugin = new NSClientInternalPlugin();
}
return nsClientInternalPlugin;
}
private TextView logTextView;
private TextView queueTextView;
private TextView urlTextView;
@ -62,14 +54,15 @@ public class NSClientInternalFragment extends SubscriberFragment implements View
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
try {
View view = inflater.inflate(R.layout.nsclientinternal_fragment, container, false);
logScrollview = (ScrollView) view.findViewById(R.id.nsclientinternal_logscrollview);
autoscrollCheckbox = (CheckBox) view.findViewById(R.id.nsclientinternal_autoscroll);
autoscrollCheckbox.setChecked(getPlugin().autoscroll);
autoscrollCheckbox.setChecked(NSClientInternalPlugin.getPlugin().autoscroll);
autoscrollCheckbox.setOnCheckedChangeListener(this);
pausedCheckbox = (CheckBox) view.findViewById(R.id.nsclientinternal_paused);
pausedCheckbox.setChecked(getPlugin().paused);
pausedCheckbox.setChecked(NSClientInternalPlugin.getPlugin().paused);
pausedCheckbox.setOnCheckedChangeListener(this);
logTextView = (TextView) view.findViewById(R.id.nsclientinternal_log);
queueTextView = (TextView) view.findViewById(R.id.nsclientinternal_queue);
@ -94,6 +87,11 @@ public class NSClientInternalFragment extends SubscriberFragment implements View
updateGUI();
return view;
} catch (Exception e) {
Crashlytics.logException(e);
}
return null;
}
@Override
@ -104,11 +102,11 @@ public class NSClientInternalFragment extends SubscriberFragment implements View
Answers.getInstance().logCustom(new CustomEvent("NSClientRestart"));
break;
case R.id.nsclientinternal_delivernow:
getPlugin().resend("GUI");
NSClientInternalPlugin.getPlugin().resend("GUI");
Answers.getInstance().logCustom(new CustomEvent("NSClientDeliverNow"));
break;
case R.id.nsclientinternal_clearlog:
getPlugin().clearLog();
NSClientInternalPlugin.getPlugin().clearLog();
break;
case R.id.nsclientinternal_clearqueue:
final Context context = getContext();
@ -127,7 +125,7 @@ public class NSClientInternalFragment extends SubscriberFragment implements View
builder.show();
break;
case R.id.nsclientinternal_showqueue:
MainApp.bus().post(new EventNSClientNewLog("QUEUE", getPlugin().queue().textList()));
MainApp.bus().post(new EventNSClientNewLog("QUEUE", NSClientInternalPlugin.getPlugin().queue().textList()));
Answers.getInstance().logCustom(new CustomEvent("NSClientShowQueue"));
break;
}
@ -138,14 +136,14 @@ public class NSClientInternalFragment extends SubscriberFragment implements View
switch (buttonView.getId()) {
case R.id.nsclientinternal_paused:
SP.putBoolean(R.string.key_nsclientinternal_paused, isChecked);
getPlugin().paused = isChecked;
NSClientInternalPlugin.getPlugin().paused = isChecked;
MainApp.bus().post(new EventPreferenceChange(R.string.key_nsclientinternal_paused));
updateGUI();
Answers.getInstance().logCustom(new CustomEvent("NSClientPause"));
break;
case R.id.nsclientinternal_autoscroll:
SP.putBoolean(R.string.key_nsclientinternal_autoscroll, isChecked);
getPlugin().autoscroll = isChecked;
NSClientInternalPlugin.getPlugin().autoscroll = isChecked;
updateGUI();
break;
}
@ -165,13 +163,13 @@ public class NSClientInternalFragment extends SubscriberFragment implements View
public void run() {
NSClientInternalPlugin.updateLog();
logTextView.setText(NSClientInternalPlugin.textLog);
if (getPlugin().autoscroll) {
if (NSClientInternalPlugin.getPlugin().autoscroll) {
logScrollview.fullScroll(ScrollView.FOCUS_DOWN);
}
urlTextView.setText(getPlugin().url());
urlTextView.setText(NSClientInternalPlugin.getPlugin().url());
Spanned queuetext = Html.fromHtml(MainApp.sResources.getString(R.string.queue) + " <b>" + UploadQueue.size() + "</b>");
queueTextView.setText(queuetext);
statusTextView.setText(getPlugin().status);
statusTextView.setText(NSClientInternalPlugin.getPlugin().status);
}
});
}

View file

@ -34,6 +34,15 @@ import info.nightscout.utils.ToastUtils;
public class NSClientInternalPlugin implements PluginBase {
private static Logger log = LoggerFactory.getLogger(NSClientInternalPlugin.class);
static NSClientInternalPlugin nsClientInternalPlugin;
static public NSClientInternalPlugin getPlugin() {
if (nsClientInternalPlugin == null) {
nsClientInternalPlugin = new NSClientInternalPlugin();
}
return nsClientInternalPlugin;
}
private boolean fragmentEnabled = true;
private boolean fragmentVisible = true;

View file

@ -67,4 +67,31 @@ public class BroadcastDeviceStatus {
}
}
}
public static void handleNewFoods(JSONArray foods, Context context, boolean isDelta) {
List<JSONArray> splitted = BroadcastTreatment.splitArray(foods);
for (JSONArray part: splitted) {
Bundle bundle = new Bundle();
bundle.putString("foods", part.toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_NEW_FOOD);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
}
if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) {
splitted = BroadcastTreatment.splitArray(foods);
for (JSONArray part : splitted) {
Bundle bundle = new Bundle();
bundle.putString("foods", part.toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_NEW_FOOD);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
context.sendBroadcast(intent);
}
}
}
}

View file

@ -0,0 +1,104 @@
package info.nightscout.androidaps.plugins.NSClientInternal.broadcasts;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.Services.Intents;
import info.nightscout.androidaps.plugins.NSClientInternal.data.NSTreatment;
import info.nightscout.utils.SP;
/**
* Created by mike on 20.02.2016.
*/
public class BroadcastFood {
private static Logger log = LoggerFactory.getLogger(BroadcastFood.class);
public static void handleNewFood(JSONArray foods, Context context, boolean isDelta) {
List<JSONArray> splitted = BroadcastTreatment.splitArray(foods);
for (JSONArray part : splitted) {
Bundle bundle = new Bundle();
bundle.putString("foods", part.toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_NEW_FOOD);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
}
if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) {
for (JSONArray part : splitted) {
Bundle bundle = new Bundle();
bundle.putString("foods", part.toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_NEW_FOOD);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
context.sendBroadcast(intent);
}
}
}
public static void handleChangedFood(JSONArray foods, Context context, boolean isDelta) {
List<JSONArray> splitted = BroadcastTreatment.splitArray(foods);
for (JSONArray part : splitted) {
Bundle bundle = new Bundle();
bundle.putString("foods", part.toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_CHANGED_FOOD);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
}
if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) {
for (JSONArray part : splitted) {
Bundle bundle = new Bundle();
bundle.putString("foods", part.toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_CHANGED_FOOD);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
context.sendBroadcast(intent);
}
}
}
public static void handleRemovedFood(JSONArray foods, Context context, boolean isDelta) {
Bundle bundle = new Bundle();
bundle.putString("foods", foods.toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_REMOVED_FOOD);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
if (SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) {
bundle = new Bundle();
bundle.putString("foods", foods.toString());
bundle.putBoolean("delta", isDelta);
intent = new Intent(Intents.ACTION_REMOVED_FOOD);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
context.sendBroadcast(intent);
}
}
}

View file

@ -46,23 +46,29 @@ public class BroadcastSgvs {
}
public static void handleNewSgv(JSONArray sgvs, Context context, boolean isDelta) {
List<JSONArray> splitted = BroadcastTreatment.splitArray(sgvs);
for (JSONArray part : splitted) {
Bundle bundle = new Bundle();
bundle.putString("sgvs", sgvs.toString());
bundle.putString("sgvs", part.toString());
bundle.putBoolean("delta", isDelta);
Intent intent = new Intent(Intents.ACTION_NEW_SGV);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
LocalBroadcastManager.getInstance(MainApp.instance()).sendBroadcast(intent);
}
if(SP.getBoolean(R.string.key_nsclient_localbroadcasts, true)) {
bundle = new Bundle();
bundle.putString("sgvs", sgvs.toString());
for (JSONArray part : splitted) {
Bundle bundle = new Bundle();
bundle.putString("sgvs", part.toString());
bundle.putBoolean("delta", isDelta);
intent = new Intent(Intents.ACTION_NEW_SGV);
Intent intent = new Intent(Intents.ACTION_NEW_SGV);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
context.sendBroadcast(intent);
}
}
}
}

View file

@ -9,6 +9,7 @@ import android.os.HandlerThread;
import android.os.IBinder;
import android.os.PowerManager;
import com.crashlytics.android.Crashlytics;
import com.google.common.base.Charsets;
import com.google.common.hash.Hashing;
import com.j256.ormlite.dao.CloseableIterator;
@ -43,6 +44,7 @@ import info.nightscout.androidaps.plugins.NSClientInternal.broadcasts.BroadcastA
import info.nightscout.androidaps.plugins.NSClientInternal.broadcasts.BroadcastCals;
import info.nightscout.androidaps.plugins.NSClientInternal.broadcasts.BroadcastClearAlarm;
import info.nightscout.androidaps.plugins.NSClientInternal.broadcasts.BroadcastDeviceStatus;
import info.nightscout.androidaps.plugins.NSClientInternal.broadcasts.BroadcastFood;
import info.nightscout.androidaps.plugins.NSClientInternal.broadcasts.BroadcastMbgs;
import info.nightscout.androidaps.plugins.NSClientInternal.broadcasts.BroadcastProfile;
import info.nightscout.androidaps.plugins.NSClientInternal.broadcasts.BroadcastSgvs;
@ -321,12 +323,18 @@ public class NSClientService extends Service {
*/
@Override
public void call(final Object... args) {
JSONObject data = (JSONObject) args[0];
JSONObject data;
try {
data = (JSONObject) args[0];
} catch (Exception e) {
Crashlytics.log("Wrong Announcement from NS: " + args[0]);
return;
}
if (Config.detailedLog)
try {
MainApp.bus().post(new EventNSClientNewLog("ANNOUNCEMENT", data.has("message") ? data.getString("message") : "received"));
} catch (JSONException e) {
log.error("Unhandled exception", e);
} catch (Exception e) {
Crashlytics.logException(e);
}
BroadcastAnnouncement.handleAnnouncement(data, getApplicationContext());
log.debug(data.toString());
@ -351,7 +359,13 @@ public class NSClientService extends Service {
public void call(final Object... args) {
if (Config.detailedLog)
MainApp.bus().post(new EventNSClientNewLog("ALARM", "received"));
JSONObject data = (JSONObject) args[0];
JSONObject data;
try {
data = (JSONObject) args[0];
} catch (Exception e) {
Crashlytics.log("Wrong alarm from NS: " + args[0]);
return;
}
BroadcastAlarm.handleAlarm(data, getApplicationContext());
log.debug(data.toString());
}
@ -373,7 +387,13 @@ public class NSClientService extends Service {
*/
@Override
public void call(final Object... args) {
JSONObject data = (JSONObject) args[0];
JSONObject data;
try {
data = (JSONObject) args[0];
} catch (Exception e) {
Crashlytics.log("Wrong Urgent alarm from NS: " + args[0]);
return;
}
if (Config.detailedLog)
MainApp.bus().post(new EventNSClientNewLog("URGENTALARM", "received"));
BroadcastUrgentAlarm.handleUrgentAlarm(data, getApplicationContext());
@ -392,9 +412,15 @@ public class NSClientService extends Service {
*/
@Override
public void call(final Object... args) {
JSONObject data;
try {
data = (JSONObject) args[0];
} catch (Exception e) {
Crashlytics.log("Wrong Urgent alarm from NS: " + args[0]);
return;
}
if (Config.detailedLog)
MainApp.bus().post(new EventNSClientNewLog("CLEARALARM", "received"));
JSONObject data = (JSONObject) args[0];
BroadcastClearAlarm.handleClearAlarm(data, getApplicationContext());
log.debug(data.toString());
}
@ -519,6 +545,55 @@ public class NSClientService extends Service {
BroadcastDeviceStatus.handleNewDeviceStatus(devicestatuses, MainApp.instance().getApplicationContext(), isDelta);
}
}
if (data.has("food")) {
JSONArray foods = data.getJSONArray("food");
JSONArray removedFoods = new JSONArray();
JSONArray updatedFoods = new JSONArray();
JSONArray addedFoods = new JSONArray();
if (foods.length() > 0)
MainApp.bus().post(new EventNSClientNewLog("DATA", "received " + foods.length() + " foods"));
for (Integer index = 0; index < foods.length(); index++) {
JSONObject jsonFood = foods.getJSONObject(index);
NSTreatment treatment = new NSTreatment(jsonFood);
// remove from upload queue if Ack is failing
UploadQueue.removeID(jsonFood);
//Find latest date in treatment
if (treatment.getMills() != null && treatment.getMills() < System.currentTimeMillis())
if (treatment.getMills() > latestDateInReceivedData)
latestDateInReceivedData = treatment.getMills();
if (treatment.getAction() == null) {
addedFoods.put(jsonFood);
} else if (treatment.getAction().equals("update")) {
updatedFoods.put(jsonFood);
} else if (treatment.getAction().equals("remove")) {
if (treatment.getMills() != null && treatment.getMills() > System.currentTimeMillis() - 24 * 60 * 60 * 1000L) // handle 1 day old deletions only
removedFoods.put(jsonFood);
}
}
if (removedFoods.length() > 0) {
BroadcastFood.handleRemovedFood(removedFoods, MainApp.instance().getApplicationContext(), isDelta);
}
if (updatedFoods.length() > 0) {
BroadcastFood.handleChangedFood(updatedFoods, MainApp.instance().getApplicationContext(), isDelta);
}
if (addedFoods.length() > 0) {
BroadcastFood.handleNewFood(addedFoods, MainApp.instance().getApplicationContext(), isDelta);
}
}
if (data.has("")) {
JSONArray foods = data.getJSONArray("food");
if (foods.length() > 0) {
MainApp.bus().post(new EventNSClientNewLog("DATA", "received " + foods.length() + " foods"));
for (Integer index = 0; index < foods.length(); index++) {
JSONObject jsonFood = foods.getJSONObject(index);
// remove from upload queue if Ack is failing
UploadQueue.removeID(jsonFood);
}
BroadcastDeviceStatus.handleNewFoods(foods, MainApp.instance().getApplicationContext(), isDelta);
}
}
if (data.has("mbgs")) {
JSONArray mbgs = data.getJSONArray("mbgs");
if (mbgs.length() > 0)

View file

@ -1,16 +1,22 @@
package info.nightscout.androidaps.plugins.OpenAPSAMA;
import com.eclipsesource.v8.JavaVoidCallback;
import com.eclipsesource.v8.V8;
import com.eclipsesource.v8.V8Array;
import com.eclipsesource.v8.V8Object;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.mozilla.javascript.Callable;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Function;
import org.mozilla.javascript.NativeJSON;
import org.mozilla.javascript.NativeObject;
import org.mozilla.javascript.RhinoException;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import org.mozilla.javascript.Undefined;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Date;
import info.nightscout.androidaps.Config;
@ -24,6 +30,7 @@ import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
import info.nightscout.androidaps.plugins.Loop.ScriptReader;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.plugins.OpenAPSMA.LoggerCallback;
import info.nightscout.utils.SP;
public class DetermineBasalAdapterAMAJS {
@ -31,20 +38,13 @@ public class DetermineBasalAdapterAMAJS {
private ScriptReader mScriptReader = null;
V8 mV8rt;
private V8Object mProfile;
private V8Object mGlucoseStatus;
private V8Array mIobData;
private V8Object mMealData;
private V8Object mCurrentTemp;
private V8Object mAutosensData = null;
private final String PARAM_currentTemp = "currentTemp";
private final String PARAM_iobData = "iobData";
private final String PARAM_glucoseStatus = "glucose_status";
private final String PARAM_profile = "profile";
private final String PARAM_meal_data = "meal_data";
private final String PARAM_autosens_data = "autosens_data";
private JSONObject mProfile;
private JSONObject mGlucoseStatus;
private JSONArray mIobData;
private JSONObject mMealData;
private JSONObject mCurrentTemp;
private JSONObject mAutosensData = null;
private String storedCurrentTemp = null;
private String storedIobData = null;
@ -55,58 +55,101 @@ public class DetermineBasalAdapterAMAJS {
private String scriptDebug = "";
/**
* Main code
*/
public DetermineBasalAdapterAMAJS(ScriptReader scriptReader) throws IOException {
mV8rt = V8.createV8Runtime();
mScriptReader = scriptReader;
initLogCallback();
initProcessExitCallback();
initModuleParent();
loadScript();
}
public DetermineBasalResultAMA invoke() {
log.debug(">>> Invoking detemine_basal <<<");
log.debug("Glucose status: " + (storedGlucoseStatus = mV8rt.executeStringScript("JSON.stringify(" + PARAM_glucoseStatus + ");")));
log.debug("IOB data: " + (storedIobData = mV8rt.executeStringScript("JSON.stringify(" + PARAM_iobData + ");")));
log.debug("Current temp: " + (storedCurrentTemp = mV8rt.executeStringScript("JSON.stringify(" + PARAM_currentTemp + ");")));
log.debug("Profile: " + (storedProfile = mV8rt.executeStringScript("JSON.stringify(" + PARAM_profile + ");")));
log.debug("Meal data: " + (storedMeal_data = mV8rt.executeStringScript("JSON.stringify(" + PARAM_meal_data + ");")));
log.debug("Glucose status: " + (storedGlucoseStatus = mGlucoseStatus.toString()));
log.debug("IOB data: " + (storedIobData = mIobData.toString()));
log.debug("Current temp: " + (storedCurrentTemp = mCurrentTemp.toString()));
log.debug("Profile: " + (storedProfile = mProfile.toString()));
log.debug("Meal data: " + (storedMeal_data = mMealData.toString()));
if (mAutosensData != null)
log.debug("Autosens data: " + (storedAutosens_data = mV8rt.executeStringScript("JSON.stringify(" + PARAM_autosens_data + ");")));
log.debug("Autosens data: " + (storedAutosens_data = mAutosensData.toString()));
else
log.debug("Autosens data: " + (storedAutosens_data = "undefined"));
mV8rt.executeVoidScript(
"var rT = determine_basal(" +
PARAM_glucoseStatus + ", " +
PARAM_currentTemp + ", " +
PARAM_iobData + ", " +
PARAM_profile + ", " +
PARAM_autosens_data + ", " +
PARAM_meal_data + ", " +
"tempBasalFunctions" +
");");
DetermineBasalResultAMA determineBasalResultAMA = null;
Context rhino = Context.enter();
Scriptable scope = rhino.initStandardObjects();
// Turn off optimization to make Rhino Android compatible
rhino.setOptimizationLevel(-1);
String ret = mV8rt.executeStringScript("JSON.stringify(rT);");
log.debug("Result: " + ret);
V8Object v8ObjectReuslt = mV8rt.getObject("rT");
DetermineBasalResultAMA result = null;
try {
result = new DetermineBasalResultAMA(v8ObjectReuslt, new JSONObject(ret));
//register logger callback for console.log and console.error
ScriptableObject.defineClass(scope, LoggerCallback.class);
Scriptable myLogger = rhino.newObject(scope, "LoggerCallback", null);
scope.put("console2", scope, myLogger);
rhino.evaluateString(scope, readFile("OpenAPSAMA/loggerhelper.js"), "JavaScript", 0, null);
//set module parent
rhino.evaluateString(scope, "var module = {\"parent\":Boolean(1)};", "JavaScript", 0, null);
rhino.evaluateString(scope, "var round_basal = function round_basal(basal, profile) { return basal; };", "JavaScript", 0, null);
rhino.evaluateString(scope, "require = function() {return round_basal;};", "JavaScript", 0, null);
//generate functions "determine_basal" and "setTempBasal"
rhino.evaluateString(scope, readFile("OpenAPSAMA/determine-basal.js"), "JavaScript", 0, null);
rhino.evaluateString(scope, readFile("OpenAPSAMA/basal-set-temp.js"), "setTempBasal.js", 0, null);
Object determineBasalObj = scope.get("determine_basal", scope);
Object setTempBasalFunctionsObj = scope.get("tempBasalFunctions", scope);
//call determine-basal
if (determineBasalObj instanceof Function && setTempBasalFunctionsObj instanceof NativeObject) {
Function determineBasalJS = (Function) determineBasalObj;
//prepare parameters
Object[] params = new Object[]{
makeParam(mGlucoseStatus, rhino, scope),
makeParam(mCurrentTemp, rhino, scope),
makeParamArray(mIobData, rhino, scope),
makeParam(mProfile, rhino, scope),
makeParam(mAutosensData, rhino, scope),
makeParam(mMealData, rhino, scope),
setTempBasalFunctionsObj};
NativeObject jsResult = (NativeObject) determineBasalJS.call(rhino, scope, scope, params);
scriptDebug = LoggerCallback.getScriptDebug();
// Parse the jsResult object to a JSON-String
String result = NativeJSON.stringify(rhino, scope, jsResult, null, null).toString();
if (Config.logAPSResult)
log.debug("Result: " + result);
try {
determineBasalResultAMA = new DetermineBasalResultAMA(jsResult, new JSONObject(result));
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
} else {
log.debug("Problem loading JS Functions");
}
} catch (IOException e) {
log.debug("IOException");
} catch (RhinoException e) {
log.error("RhinoException: (" + e.lineNumber() + "," + e.columnNumber() + ") " + e.toString());
} catch (IllegalAccessException e) {
log.error(e.toString());
} catch (InstantiationException e) {
log.error(e.toString());
} catch (InvocationTargetException e) {
log.error(e.toString());
} finally {
Context.exit();
}
storedGlucoseStatus = mGlucoseStatus.toString();
storedIobData = mIobData.toString();
storedCurrentTemp = mCurrentTemp.toString();
storedProfile = mProfile.toString();
storedMeal_data = mMealData.toString();
return determineBasalResultAMA;
return result;
}
String getGlucoseStatusParam() {
@ -137,60 +180,6 @@ public class DetermineBasalAdapterAMAJS {
return scriptDebug;
}
private void loadScript() throws IOException {
mV8rt.executeVoidScript("var round_basal = function round_basal(basal, profile) { return basal; };");
mV8rt.executeVoidScript("require = function() {return round_basal;};");
mV8rt.executeVoidScript(readFile("OpenAPSAMA/basal-set-temp.js"), "OpenAPSAMA/basal-set-temp.js ", 0);
mV8rt.executeVoidScript("var tempBasalFunctions = module.exports;");
mV8rt.executeVoidScript(
readFile("OpenAPSAMA/determine-basal.js"),
"OpenAPSAMA/determine-basal.js",
0);
mV8rt.executeVoidScript("var determine_basal = module.exports;");
}
private void initModuleParent() {
mV8rt.executeVoidScript("var module = {\"parent\":Boolean(1)};");
}
private void initProcessExitCallback() {
JavaVoidCallback callbackProccessExit = new JavaVoidCallback() {
@Override
public void invoke(V8Object arg0, V8Array parameters) {
if (parameters.length() > 0) {
Object arg1 = parameters.get(0);
log.error("ProccessExit " + arg1);
}
}
};
mV8rt.registerJavaMethod(callbackProccessExit, "proccessExit");
mV8rt.executeVoidScript("var process = {\"exit\": function () { proccessExit(); } };");
}
private void initLogCallback() {
JavaVoidCallback callbackLog = new JavaVoidCallback() {
@Override
public void invoke(V8Object arg0, V8Array parameters) {
int i = 0;
String s = "";
while (i < parameters.length()) {
Object arg = parameters.get(i);
s += arg + " ";
i++;
}
if (!s.equals("") && Config.logAPSResult) {
log.debug("Script debug: " + s);
scriptDebug += s + "\n";
}
}
};
mV8rt.registerJavaMethod(callbackLog, "log");
mV8rt.executeVoidScript("var console = {\"log\":log, \"error\":log};");
}
public void setData(Profile profile,
double maxIob,
double maxBasal,
@ -203,89 +192,94 @@ public class DetermineBasalAdapterAMAJS {
MealData mealData,
double autosensDataRatio,
boolean tempTargetSet,
double min_5m_carbimpact) {
double min_5m_carbimpact) throws JSONException {
String units = profile.getUnits();
mProfile = new V8Object(mV8rt);
mProfile.add("max_iob", maxIob);
mProfile.add("dia", Math.min(profile.getDia(), 3d));
mProfile.add("type", "current");
mProfile.add("max_daily_basal", profile.getMaxDailyBasal());
mProfile.add("max_basal", maxBasal);
mProfile.add("min_bg", minBg);
mProfile.add("max_bg", maxBg);
mProfile.add("target_bg", targetBg);
mProfile.add("carb_ratio", profile.getIc());
mProfile.add("sens", Profile.toMgdl(profile.getIsf().doubleValue(), units));
mProfile.add("max_daily_safety_multiplier", SP.getInt("openapsama_max_daily_safety_multiplier", 3));
mProfile.add("current_basal_safety_multiplier", SP.getInt("openapsama_current_basal_safety_multiplier", 4));
mProfile.add("skip_neutral_temps", true);
mProfile.add("current_basal", pump.getBaseBasalRate());
mProfile.add("temptargetSet", tempTargetSet);
mProfile.add("autosens_adjust_targets", SP.getBoolean("openapsama_autosens_adjusttargets", true));
mProfile.add("min_5m_carbimpact", SP.getDouble("openapsama_min_5m_carbimpact", 3d));
mProfile = new JSONObject();
mProfile.put("max_iob", maxIob);
mProfile.put("dia", Math.min(profile.getDia(), 3d));
mProfile.put("type", "current");
mProfile.put("max_daily_basal", profile.getMaxDailyBasal());
mProfile.put("max_basal", maxBasal);
mProfile.put("min_bg", minBg);
mProfile.put("max_bg", maxBg);
mProfile.put("target_bg", targetBg);
mProfile.put("carb_ratio", profile.getIc());
mProfile.put("sens", Profile.toMgdl(profile.getIsf().doubleValue(), units));
mProfile.put("max_daily_safety_multiplier", SP.getInt("openapsama_max_daily_safety_multiplier", 3));
mProfile.put("current_basal_safety_multiplier", SP.getInt("openapsama_current_basal_safety_multiplier", 4));
mProfile.put("skip_neutral_temps", true);
mProfile.put("current_basal", pump.getBaseBasalRate());
mProfile.put("temptargetSet", tempTargetSet);
mProfile.put("autosens_adjust_targets", SP.getBoolean("openapsama_autosens_adjusttargets", true));
mProfile.put("min_5m_carbimpact", SP.getDouble("openapsama_min_5m_carbimpact", 3d));
if (units.equals(Constants.MMOL)) {
mProfile.add("out_units", "mmol/L");
mProfile.put("out_units", "mmol/L");
}
mV8rt.add(PARAM_profile, mProfile);
mCurrentTemp = new V8Object(mV8rt);
mCurrentTemp.add("temp", "absolute");
mCurrentTemp.add("duration", MainApp.getConfigBuilder().getTempBasalRemainingMinutesFromHistory());
mCurrentTemp.add("rate", MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory());
mCurrentTemp = new JSONObject();
mCurrentTemp.put("temp", "absolute");
mCurrentTemp.put("duration", MainApp.getConfigBuilder().getTempBasalRemainingMinutesFromHistory());
mCurrentTemp.put("rate", MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory());
// as we have non default temps longer than 30 mintues
TemporaryBasal tempBasal = MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis());
if (tempBasal != null) {
mCurrentTemp.add("minutesrunning", tempBasal.getRealDuration());
mCurrentTemp.put("minutesrunning", tempBasal.getRealDuration());
}
mV8rt.add(PARAM_currentTemp, mCurrentTemp);
mIobData = IobCobCalculatorPlugin.convertToJSONArray(iobArray);
mIobData = mV8rt.executeArrayScript(IobCobCalculatorPlugin.convertToJSONArray(iobArray).toString());
mV8rt.add(PARAM_iobData, mIobData);
mGlucoseStatus = new V8Object(mV8rt);
mGlucoseStatus.add("glucose", glucoseStatus.glucose);
mGlucoseStatus = new JSONObject();
mGlucoseStatus.put("glucose", glucoseStatus.glucose);
if (SP.getBoolean("always_use_shortavg", false)) {
mGlucoseStatus.add("delta", glucoseStatus.short_avgdelta);
mGlucoseStatus.put("delta", glucoseStatus.short_avgdelta);
} else {
mGlucoseStatus.add("delta", glucoseStatus.delta);
mGlucoseStatus.put("delta", glucoseStatus.delta);
}
mGlucoseStatus.add("short_avgdelta", glucoseStatus.short_avgdelta);
mGlucoseStatus.add("long_avgdelta", glucoseStatus.long_avgdelta);
mV8rt.add(PARAM_glucoseStatus, mGlucoseStatus);
mGlucoseStatus.put("short_avgdelta", glucoseStatus.short_avgdelta);
mGlucoseStatus.put("long_avgdelta", glucoseStatus.long_avgdelta);
mMealData = new V8Object(mV8rt);
mMealData.add("carbs", mealData.carbs);
mMealData.add("boluses", mealData.boluses);
mMealData.add("mealCOB", mealData.mealCOB);
mV8rt.add(PARAM_meal_data, mMealData);
mMealData = new JSONObject();
mMealData.put("carbs", mealData.carbs);
mMealData.put("boluses", mealData.boluses);
mMealData.put("mealCOB", mealData.mealCOB);
if (MainApp.getConfigBuilder().isAMAModeEnabled()) {
mAutosensData = new V8Object(mV8rt);
mAutosensData.add("ratio", autosensDataRatio);
mV8rt.add(PARAM_autosens_data, mAutosensData);
mAutosensData = new JSONObject();
mAutosensData.put("ratio", autosensDataRatio);
} else {
mV8rt.addUndefined(PARAM_autosens_data);
mAutosensData = null;
}
}
public void release() {
mProfile.release();
mCurrentTemp.release();
mIobData.release();
mMealData.release();
mGlucoseStatus.release();
if (mAutosensData != null) {
mAutosensData.release();
public Object makeParam(JSONObject jsonObject, Context rhino, Scriptable scope) {
if(jsonObject == null) return Undefined.instance;
Object param = NativeJSON.parse(rhino, scope, jsonObject.toString(), new Callable() {
@Override
public Object call(Context context, Scriptable scriptable, Scriptable scriptable1, Object[] objects) {
return objects[1];
}
mV8rt.release();
});
return param;
}
public Object makeParamArray(JSONArray jsonArray, Context rhino, Scriptable scope) {
//Object param = NativeJSON.parse(rhino, scope, "{myarray: " + jsonArray.toString() + " }", new Callable() {
Object param = NativeJSON.parse(rhino, scope, jsonArray.toString(), new Callable() {
@Override
public Object call(Context context, Scriptable scriptable, Scriptable scriptable1, Object[] objects) {
return objects[1];
}
});
return param;
}
public String readFile(String filename) throws IOException {

View file

@ -5,6 +5,7 @@ import com.eclipsesource.v8.V8Object;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.mozilla.javascript.NativeObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -25,35 +26,34 @@ public class DetermineBasalResultAMA extends APSResult {
public double snoozeBG;
public IobTotal iob;
public DetermineBasalResultAMA(V8Object result, JSONObject j) {
public DetermineBasalResultAMA(NativeObject result, JSONObject j) {
date = new Date();
json = j;
if (result.contains("error")) {
reason = result.getString("error");
if (result.containsKey("error")) {
reason = result.get("error").toString();
changeRequested = false;
rate = -1;
duration = -1;
} else {
reason = result.getString("reason");
if (result.contains("eventualBG")) eventualBG = result.getDouble("eventualBG");
if (result.contains("snoozeBG")) snoozeBG = result.getDouble("snoozeBG");
if (result.contains("rate")) {
rate = result.getDouble("rate");
reason = result.get("reason").toString();
if (result.containsKey("eventualBG")) eventualBG = (Double) result.get("eventualBG");
if (result.containsKey("snoozeBG")) snoozeBG = (Double) result.get("snoozeBG");
if (result.containsKey("rate")) {
rate = (Double) result.get("rate");
if (rate < 0d) rate = 0d;
changeRequested = true;
} else {
rate = -1;
changeRequested = false;
}
if (result.contains("duration")) {
duration = result.getInteger("duration");
if (result.containsKey("duration")) {
duration = ((Double)result.get("duration")).intValue();
//changeRequested as above
} else {
duration = -1;
changeRequested = false;
}
}
result.release();
}
public DetermineBasalResultAMA() {

View file

@ -9,6 +9,7 @@ import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import com.crashlytics.android.Crashlytics;
import com.crashlytics.android.answers.Answers;
import com.crashlytics.android.answers.CustomEvent;
import com.squareup.otto.Subscribe;
@ -28,15 +29,6 @@ import info.nightscout.utils.JSONFormatter;
public class OpenAPSAMAFragment extends SubscriberFragment implements View.OnClickListener {
private static Logger log = LoggerFactory.getLogger(OpenAPSAMAFragment.class);
private static OpenAPSAMAPlugin openAPSAMAPlugin;
public static OpenAPSAMAPlugin getPlugin() {
if(openAPSAMAPlugin ==null){
openAPSAMAPlugin = new OpenAPSAMAPlugin();
}
return openAPSAMAPlugin;
}
Button run;
TextView lastRunView;
TextView glucoseStatusView;
@ -52,6 +44,7 @@ public class OpenAPSAMAFragment extends SubscriberFragment implements View.OnCli
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
try {
View view = inflater.inflate(R.layout.openapsama_fragment, container, false);
run = (Button) view.findViewById(R.id.openapsma_run);
@ -69,13 +62,18 @@ public class OpenAPSAMAFragment extends SubscriberFragment implements View.OnCli
updateGUI();
return view;
} catch (Exception e) {
Crashlytics.logException(e);
}
return null;
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.openapsma_run:
getPlugin().invoke("OpenAPSAMA button");
OpenAPSAMAPlugin.getPlugin().invoke("OpenAPSAMA button");
Answers.getInstance().logCustom(new CustomEvent("OpenAPS_AMA_Run"));
break;
}
@ -99,12 +97,12 @@ public class OpenAPSAMAFragment extends SubscriberFragment implements View.OnCli
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
DetermineBasalResultAMA lastAPSResult = getPlugin().lastAPSResult;
DetermineBasalResultAMA lastAPSResult = OpenAPSAMAPlugin.getPlugin().lastAPSResult;
if (lastAPSResult != null) {
resultView.setText(JSONFormatter.format(lastAPSResult.json));
requestView.setText(lastAPSResult.toSpanned());
}
DetermineBasalAdapterAMAJS determineBasalAdapterAMAJS = getPlugin().lastDetermineBasalAdapterAMAJS;
DetermineBasalAdapterAMAJS determineBasalAdapterAMAJS = OpenAPSAMAPlugin.getPlugin().lastDetermineBasalAdapterAMAJS;
if (determineBasalAdapterAMAJS != null) {
glucoseStatusView.setText(JSONFormatter.format(determineBasalAdapterAMAJS.getGlucoseStatusParam()));
currentTempView.setText(JSONFormatter.format(determineBasalAdapterAMAJS.getCurrentTempParam()));
@ -119,11 +117,11 @@ public class OpenAPSAMAFragment extends SubscriberFragment implements View.OnCli
mealDataView.setText(JSONFormatter.format(determineBasalAdapterAMAJS.getMealDataParam()));
scriptdebugView.setText(determineBasalAdapterAMAJS.getScriptDebug());
}
if (getPlugin().lastAPSRun != null) {
lastRunView.setText(getPlugin().lastAPSRun.toLocaleString());
if (OpenAPSAMAPlugin.getPlugin().lastAPSRun != null) {
lastRunView.setText(OpenAPSAMAPlugin.getPlugin().lastAPSRun.toLocaleString());
}
if (getPlugin().lastAutosensResult != null) {
autosensDataView.setText(JSONFormatter.format(getPlugin().lastAutosensResult.json()));
if (OpenAPSAMAPlugin.getPlugin().lastAutosensResult != null) {
autosensDataView.setText(JSONFormatter.format(OpenAPSAMAPlugin.getPlugin().lastAutosensResult.json()));
}
}
});

View file

@ -39,14 +39,23 @@ import info.nightscout.utils.ToastUtils;
public class OpenAPSAMAPlugin implements PluginBase, APSInterface {
private static Logger log = LoggerFactory.getLogger(OpenAPSAMAPlugin.class);
private static OpenAPSAMAPlugin openAPSAMAPlugin;
public static OpenAPSAMAPlugin getPlugin() {
if (openAPSAMAPlugin == null) {
openAPSAMAPlugin = new OpenAPSAMAPlugin();
}
return openAPSAMAPlugin;
}
// last values
DetermineBasalAdapterAMAJS lastDetermineBasalAdapterAMAJS = null;
Date lastAPSRun = null;
DetermineBasalResultAMA lastAPSResult = null;
AutosensResult lastAutosensResult = null;
boolean fragmentEnabled = false;
boolean fragmentVisible = true;
private boolean fragmentEnabled = false;
private boolean fragmentVisible = false;
@Override
public String getName() {
@ -196,9 +205,9 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface {
maxBasal = verifyHardLimits(maxBasal, "max_basal", 0.1, 10);
if (!checkOnlyHardLimits(profile.getDia(), "dia", 2, 7)) return;
if (!checkOnlyHardLimits(profile.getIc(profile.secondsFromMidnight()), "carbratio", 2, 100))
if (!checkOnlyHardLimits(profile.getIc(Profile.secondsFromMidnight()), "carbratio", 2, 100))
return;
if (!checkOnlyHardLimits(Profile.toMgdl(profile.getIsf().doubleValue(), units), "sens", 2, 900))
if (!checkOnlyHardLimits(Profile.toMgdl(profile.getIsf(), units), "sens", 2, 900))
return;
if (!checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.1, 10)) return;
if (!checkOnlyHardLimits(pump.getBaseBasalRate(), "current_basal", 0.01, 5)) return;
@ -213,11 +222,16 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface {
Profiler.log(log, "AMA data gathering", start);
start = new Date();
try {
determineBasalAdapterAMAJS.setData(profile, maxIob, maxBasal, minBg, maxBg, targetBg, pump, iobArray, glucoseStatus, mealData,
lastAutosensResult.ratio, //autosensDataRatio
isTempTarget,
SafeParse.stringToDouble(SP.getString("openapsama_min_5m_carbimpact", "3.0"))//min_5m_carbimpact
);
} catch (JSONException e) {
log.error("Unable to set data: " + e.toString());
}
DetermineBasalResultAMA determineBasalResultAMA = determineBasalAdapterAMAJS.invoke();
@ -235,8 +249,6 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface {
determineBasalResultAMA.iob = iobArray[0];
determineBasalAdapterAMAJS.release();
Date now = new Date();
try {

View file

@ -1,16 +1,20 @@
package info.nightscout.androidaps.plugins.OpenAPSMA;
import com.eclipsesource.v8.JavaVoidCallback;
import com.eclipsesource.v8.V8;
import com.eclipsesource.v8.V8Array;
import com.eclipsesource.v8.V8Object;
import org.json.JSONException;
import org.json.JSONObject;
import org.mozilla.javascript.Callable;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Function;
import org.mozilla.javascript.NativeJSON;
import org.mozilla.javascript.NativeObject;
import org.mozilla.javascript.RhinoException;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.Constants;
@ -26,20 +30,12 @@ import info.nightscout.utils.SP;
public class DetermineBasalAdapterMAJS {
private static Logger log = LoggerFactory.getLogger(DetermineBasalAdapterMAJS.class);
private ScriptReader mScriptReader = null;
V8 mV8rt;
private V8Object mProfile;
private V8Object mGlucoseStatus;
private V8Object mIobData;
private V8Object mMealData;
private V8Object mCurrentTemp;
private final String PARAM_currentTemp = "currentTemp";
private final String PARAM_iobData = "iobData";
private final String PARAM_glucoseStatus = "glucose_status";
private final String PARAM_profile = "profile";
private final String PARAM_meal_data = "meal_data";
private JSONObject mProfile;
private JSONObject mGlucoseStatus;
private JSONObject mIobData;
private JSONObject mMealData;
private JSONObject mCurrentTemp;
private String storedCurrentTemp = null;
public String storedIobData = null;
@ -47,104 +43,90 @@ public class DetermineBasalAdapterMAJS {
private String storedProfile = null;
private String storedMeal_data = null;
/**
* Main code
*/
public DetermineBasalAdapterMAJS(ScriptReader scriptReader) throws IOException {
mV8rt = V8.createV8Runtime();
mScriptReader = scriptReader;
init();
initLogCallback();
initProcessExitCallback();
initModuleParent();
loadScript();
}
public void init() {
// Profile
mProfile = new V8Object(mV8rt);
mProfile.add("max_iob", 0);
mProfile.add("dia", 0);
mProfile.add("type", "current");
mProfile.add("max_daily_basal", 0);
mProfile.add("max_basal", 0);
mProfile.add("max_bg", 0);
mProfile.add("min_bg", 0);
mProfile.add("carb_ratio", 0);
mProfile.add("sens", 0);
mProfile.add("current_basal", 0);
mV8rt.add(PARAM_profile, mProfile);
// Current temp
mCurrentTemp = new V8Object(mV8rt);
mCurrentTemp.add("temp", "absolute");
mCurrentTemp.add("duration", 0);
mCurrentTemp.add("rate", 0);
mV8rt.add(PARAM_currentTemp, mCurrentTemp);
// IOB data
mIobData = new V8Object(mV8rt);
mIobData.add("iob", 0); //netIob
mIobData.add("activity", 0); //netActivity
mIobData.add("bolussnooze", 0); //bolusIob
mIobData.add("basaliob", 0);
mIobData.add("netbasalinsulin", 0);
mIobData.add("hightempinsulin", 0);
mV8rt.add(PARAM_iobData, mIobData);
// Glucose status
mGlucoseStatus = new V8Object(mV8rt);
mGlucoseStatus.add("glucose", 0);
mGlucoseStatus.add("delta", 0);
mGlucoseStatus.add("avgdelta", 0);
mV8rt.add(PARAM_glucoseStatus, mGlucoseStatus);
// Meal data
mMealData = new V8Object(mV8rt);
mMealData.add("carbs", 0);
mMealData.add("boluses", 0);
mV8rt.add(PARAM_meal_data, mMealData);
}
public DetermineBasalResultMA invoke() {
mV8rt.executeVoidScript(
"console.error(\"determine_basal(\"+\n" +
"JSON.stringify(" + PARAM_glucoseStatus + ")+ \", \" +\n" +
"JSON.stringify(" + PARAM_currentTemp + ")+ \", \" +\n" +
"JSON.stringify(" + PARAM_iobData + ")+ \", \" +\n" +
"JSON.stringify(" + PARAM_profile + ")+ \", \" +\n" +
"JSON.stringify(" + PARAM_meal_data + ")+ \") \");"
);
mV8rt.executeVoidScript(
"var rT = determine_basal(" +
PARAM_glucoseStatus + ", " +
PARAM_currentTemp + ", " +
PARAM_iobData + ", " +
PARAM_profile + ", " +
"undefined, " +
PARAM_meal_data + ", " +
"setTempBasal" +
");");
DetermineBasalResultMA determineBasalResultMA = null;
Context rhino = Context.enter();
Scriptable scope = rhino.initStandardObjects();
// Turn off optimization to make Rhino Android compatible
rhino.setOptimizationLevel(-1);
String ret = mV8rt.executeStringScript("JSON.stringify(rT);");
if (Config.logAPSResult)
log.debug("Result: " + ret);
V8Object v8ObjectReuslt = mV8rt.getObject("rT");
DetermineBasalResultMA result = null;
try {
result = new DetermineBasalResultMA(v8ObjectReuslt, new JSONObject(ret));
//register logger callback for console.log and console.error
ScriptableObject.defineClass(scope, LoggerCallback.class);
Scriptable myLogger = rhino.newObject(scope, "LoggerCallback", null);
scope.put("console", scope, myLogger);
//set module parent
rhino.evaluateString(scope, "var module = {\"parent\":Boolean(1)};", "JavaScript", 0, null);
//generate functions "determine_basal" and "setTempBasal"
rhino.evaluateString(scope, readFile("OpenAPSMA/determine-basal.js"), "JavaScript", 0, null);
String setTempBasalCode = "var setTempBasal = function (rate, duration, profile, rT, offline) {" +
"rT.duration = duration;\n" +
" rT.rate = rate;" +
"return rT;" +
"};";
rhino.evaluateString(scope, setTempBasalCode, "setTempBasal.js", 0, null);
Object determineBasalObj = scope.get("determine_basal", scope);
Object setTempBasalObj = scope.get("setTempBasal", scope);
//call determine-basal
if (determineBasalObj instanceof Function && setTempBasalObj instanceof Function) {
Function determineBasalJS = (Function) determineBasalObj;
Function setTempBasalJS = (Function) setTempBasalObj;
//prepare parameters
Object[] params = new Object[]{
makeParam(mGlucoseStatus, rhino, scope),
makeParam(mCurrentTemp, rhino, scope),
makeParam(mIobData, rhino, scope),
makeParam(mProfile, rhino, scope),
"undefined",
makeParam(mMealData, rhino, scope),
setTempBasalJS};
NativeObject jsResult = (NativeObject) determineBasalJS.call(rhino, scope, scope, params);
// Parse the jsResult object to a JSON-String
String result = NativeJSON.stringify(rhino, scope, jsResult, null, null).toString();
if (Config.logAPSResult)
log.debug("Result: " + result);
try {
determineBasalResultMA = new DetermineBasalResultMA(jsResult, new JSONObject(result));
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
} else {
log.debug("Problem loading JS Functions");
}
} catch (IOException e) {
log.debug("IOException");
} catch (RhinoException e) {
log.error("RhinoException: (" + e.lineNumber() + "," + e.columnNumber() + ") " + e.toString());
} catch (IllegalAccessException e) {
log.error(e.toString());
} catch (InstantiationException e) {
log.error(e.toString());
} catch (InvocationTargetException e) {
log.error(e.toString());
} finally {
Context.exit();
}
storedGlucoseStatus = mV8rt.executeStringScript("JSON.stringify(" + PARAM_glucoseStatus + ");");
storedIobData = mV8rt.executeStringScript("JSON.stringify(" + PARAM_iobData + ");");
storedCurrentTemp = mV8rt.executeStringScript("JSON.stringify(" + PARAM_currentTemp + ");");
storedProfile = mV8rt.executeStringScript("JSON.stringify(" + PARAM_profile + ");");
storedMeal_data = mV8rt.executeStringScript("JSON.stringify(" + PARAM_meal_data + ");");
storedGlucoseStatus = mGlucoseStatus.toString();
storedIobData = mIobData.toString();
storedCurrentTemp = mCurrentTemp.toString();
storedProfile = mProfile.toString();
storedMeal_data = mMealData.toString();
return result;
return determineBasalResultMA;
}
String getGlucoseStatusParam() {
@ -167,57 +149,6 @@ public class DetermineBasalAdapterMAJS {
return storedMeal_data;
}
private void loadScript() throws IOException {
mV8rt.executeVoidScript(
readFile("OpenAPSMA/determine-basal.js"),
"OpenAPSMA/bin/oref0-determine-basal.js",
0);
mV8rt.executeVoidScript("var determine_basal = module.exports;");
mV8rt.executeVoidScript(
"var setTempBasal = function (rate, duration, profile, rT, offline) {" +
"rT.duration = duration;\n" +
" rT.rate = rate;" +
"return rT;" +
"};",
"setTempBasal.js",
0
);
}
private void initModuleParent() {
mV8rt.executeVoidScript("var module = {\"parent\":Boolean(1)};");
}
private void initProcessExitCallback() {
JavaVoidCallback callbackProccessExit = new JavaVoidCallback() {
@Override
public void invoke(V8Object arg0, V8Array parameters) {
if (parameters.length() > 0) {
Object arg1 = parameters.get(0);
log.error("ProccessExit " + arg1);
}
}
};
mV8rt.registerJavaMethod(callbackProccessExit, "proccessExit");
mV8rt.executeVoidScript("var process = {\"exit\": function () { proccessExit(); } };");
}
private void initLogCallback() {
JavaVoidCallback callbackLog = new JavaVoidCallback() {
@Override
public void invoke(V8Object arg0, V8Array parameters) {
if (parameters.length() > 0) {
Object arg1 = parameters.get(0);
if (Config.logAPSResult)
log.debug("Input params: " + arg1);
}
}
};
mV8rt.registerJavaMethod(callbackLog, "log");
mV8rt.executeVoidScript("var console = {\"log\":log, \"error\":log};");
}
public void setData(Profile profile,
double maxIob,
double maxBasal,
@ -227,57 +158,52 @@ public class DetermineBasalAdapterMAJS {
PumpInterface pump,
IobTotal iobData,
GlucoseStatus glucoseStatus,
MealData mealData) {
MealData mealData) throws JSONException {
String units = profile.getUnits();
mProfile.add("max_iob", maxIob);
mProfile.add("dia", Math.min(profile.getDia(), 3d));
mProfile.add("type", "current");
mProfile.add("max_daily_basal", profile.getMaxDailyBasal());
mProfile.add("max_basal", maxBasal);
mProfile.add("min_bg", minBg);
mProfile.add("max_bg", maxBg);
mProfile.add("target_bg", targetBg);
mProfile.add("carb_ratio", profile.getIc());
mProfile.add("sens", Profile.toMgdl(profile.getIsf().doubleValue(), units));
mProfile = new JSONObject();
mProfile.put("max_iob", maxIob);
mProfile.put("dia", Math.min(profile.getDia(), 3d));
mProfile.put("type", "current");
mProfile.put("max_daily_basal", profile.getMaxDailyBasal());
mProfile.put("max_basal", maxBasal);
mProfile.put("min_bg", minBg);
mProfile.put("max_bg", maxBg);
mProfile.put("target_bg", targetBg);
mProfile.put("carb_ratio", profile.getIc());
mProfile.put("sens", Profile.toMgdl(profile.getIsf().doubleValue(), units));
mProfile.add("current_basal", pump.getBaseBasalRate());
mProfile.put("current_basal", pump.getBaseBasalRate());
if (units.equals(Constants.MMOL)) {
mProfile.add("out_units", "mmol/L");
mProfile.put("out_units", "mmol/L");
}
mCurrentTemp.add("duration", MainApp.getConfigBuilder().getTempBasalRemainingMinutesFromHistory());
mCurrentTemp.add("rate", MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory());
mCurrentTemp = new JSONObject();
mCurrentTemp.put("duration", MainApp.getConfigBuilder().getTempBasalRemainingMinutesFromHistory());
mCurrentTemp.put("rate", MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory());
mIobData.add("iob", iobData.iob); //netIob
mIobData.add("activity", iobData.activity); //netActivity
mIobData.add("bolussnooze", iobData.bolussnooze); //bolusIob
mIobData.add("basaliob", iobData.basaliob);
mIobData.add("netbasalinsulin", iobData.netbasalinsulin);
mIobData.add("hightempinsulin", iobData.hightempinsulin);
mIobData = new JSONObject();
mIobData.put("iob", iobData.iob); //netIob
mIobData.put("activity", iobData.activity); //netActivity
mIobData.put("bolussnooze", iobData.bolussnooze); //bolusIob
mIobData.put("basaliob", iobData.basaliob);
mIobData.put("netbasalinsulin", iobData.netbasalinsulin);
mIobData.put("hightempinsulin", iobData.hightempinsulin);
mGlucoseStatus.add("glucose", glucoseStatus.glucose);
mGlucoseStatus = new JSONObject();
mGlucoseStatus.put("glucose", glucoseStatus.glucose);
if (SP.getBoolean("always_use_shortavg", false)) {
mGlucoseStatus.add("delta", glucoseStatus.short_avgdelta);
mGlucoseStatus.put("delta", glucoseStatus.short_avgdelta);
} else {
mGlucoseStatus.add("delta", glucoseStatus.delta);
mGlucoseStatus.put("delta", glucoseStatus.delta);
}
mGlucoseStatus.add("avgdelta", glucoseStatus.avgdelta);
mGlucoseStatus.put("avgdelta", glucoseStatus.avgdelta);
mMealData.add("carbs", mealData.carbs);
mMealData.add("boluses", mealData.boluses);
}
public void release() {
mProfile.release();
mCurrentTemp.release();
mIobData.release();
mMealData.release();
mGlucoseStatus.release();
mV8rt.release();
mMealData = new JSONObject();
mMealData.put("carbs", mealData.carbs);
mMealData.put("boluses", mealData.boluses);
}
public String readFile(String filename) throws IOException {
@ -289,4 +215,14 @@ public class DetermineBasalAdapterMAJS {
return string;
}
public Object makeParam(JSONObject jsonObject, Context rhino, Scriptable scope) {
Object param = NativeJSON.parse(rhino, scope, jsonObject.toString(), new Callable() {
@Override
public Object call(Context context, Scriptable scriptable, Scriptable scriptable1, Object[] objects) {
return objects[1];
}
});
return param;
}
}

View file

@ -1,12 +1,8 @@
package info.nightscout.androidaps.plugins.OpenAPSMA;
import android.os.Parcel;
import android.os.Parcelable;
import com.eclipsesource.v8.V8Object;
import org.json.JSONException;
import org.json.JSONObject;
import org.mozilla.javascript.NativeObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -22,38 +18,37 @@ public class DetermineBasalResultMA extends APSResult {
public String mealAssist;
public IobTotal iob;
public DetermineBasalResultMA(V8Object result, JSONObject j) {
public DetermineBasalResultMA(NativeObject result, JSONObject j) {
json = j;
if (result.contains("error")) {
reason = result.getString("error");
if (result.containsKey("error")) {
reason = (String) result.get("error");
changeRequested = false;
rate = -1;
duration = -1;
mealAssist = "";
} else {
reason = result.getString("reason");
eventualBG = result.getDouble("eventualBG");
snoozeBG = result.getDouble("snoozeBG");
if (result.contains("rate")) {
rate = result.getDouble("rate");
reason = result.get("reason").toString();
eventualBG = (Double) result.get("eventualBG");
snoozeBG = (Double) result.get("snoozeBG");
if (result.containsKey("rate")) {
rate = (Double) result.get("rate");
if (rate < 0d) rate = 0d;
changeRequested = true;
} else {
rate = -1;
changeRequested = false;
}
if (result.contains("duration")) {
duration = result.getInteger("duration");
if (result.containsKey("duration")) {
duration = ((Double) result.get("duration")).intValue();
//changeRequested as above
} else {
duration = -1;
changeRequested = false;
}
if (result.contains("mealAssist")) {
mealAssist = result.getString("mealAssist");
if (result.containsKey("mealAssist")) {
mealAssist = result.get("mealAssist").toString();
} else mealAssist = "";
}
result.release();
}
public DetermineBasalResultMA() {

View file

@ -0,0 +1,63 @@
package info.nightscout.androidaps.plugins.OpenAPSMA;
import org.mozilla.javascript.ScriptableObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.MainApp;
import info.nightscout.utils.ToastUtils;
/**
* Created by adrian on 15/10/17.
*/
public class LoggerCallback extends ScriptableObject {
private static Logger log = LoggerFactory.getLogger(DetermineBasalAdapterMAJS.class);
static StringBuffer errorBuffer = new StringBuffer();
static StringBuffer logBuffer = new StringBuffer();
public LoggerCallback() {
//empty constructor needed for Rhino
errorBuffer = new StringBuffer();
logBuffer = new StringBuffer();
}
@Override
public String getClassName() {
return "LoggerCallback";
}
public void jsConstructor() {
//empty constructor on JS site; could work as setter
}
public void jsFunction_log(Object obj1) {
log.debug(obj1.toString());
logBuffer.append(obj1.toString());
logBuffer.append(' ');
}
public void jsFunction_error(Object obj1) {
log.error(obj1.toString());
errorBuffer.append(obj1.toString());
errorBuffer.append(' ');
}
public static String getScriptDebug(){
String ret = "";
if(errorBuffer.length() > 0){
ret += "e:\n" + errorBuffer.toString();
}
if(ret.length() > 0 && logBuffer.length() > 0) ret += '\n';
if(logBuffer.length() > 0){
ret += "d:\n" + logBuffer.toString();
}
return ret;
}
}

View file

@ -9,6 +9,7 @@ import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import com.crashlytics.android.Crashlytics;
import com.crashlytics.android.answers.Answers;
import com.crashlytics.android.answers.CustomEvent;
import com.squareup.otto.Subscribe;
@ -26,15 +27,6 @@ import info.nightscout.utils.JSONFormatter;
public class OpenAPSMAFragment extends SubscriberFragment implements View.OnClickListener {
private static Logger log = LoggerFactory.getLogger(OpenAPSMAFragment.class);
private static OpenAPSMAPlugin openAPSMAPlugin;
public static OpenAPSMAPlugin getPlugin() {
if (openAPSMAPlugin == null) {
openAPSMAPlugin = new OpenAPSMAPlugin();
}
return openAPSMAPlugin;
}
Button run;
TextView lastRunView;
TextView glucoseStatusView;
@ -48,6 +40,7 @@ public class OpenAPSMAFragment extends SubscriberFragment implements View.OnClic
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
try {
View view = inflater.inflate(R.layout.openapsma_fragment, container, false);
run = (Button) view.findViewById(R.id.openapsma_run);
@ -63,13 +56,18 @@ public class OpenAPSMAFragment extends SubscriberFragment implements View.OnClic
updateGUI();
return view;
} catch (Exception e) {
Crashlytics.logException(e);
}
return null;
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.openapsma_run:
getPlugin().invoke("OpenAPSMA button");
OpenAPSMAPlugin.getPlugin().invoke("OpenAPSMA button");
Answers.getInstance().logCustom(new CustomEvent("OpenAPS_MA_Run"));
break;
}
@ -93,12 +91,12 @@ public class OpenAPSMAFragment extends SubscriberFragment implements View.OnClic
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
DetermineBasalResultMA lastAPSResult = getPlugin().lastAPSResult;
DetermineBasalResultMA lastAPSResult = OpenAPSMAPlugin.getPlugin().lastAPSResult;
if (lastAPSResult != null) {
resultView.setText(JSONFormatter.format(lastAPSResult.json));
requestView.setText(lastAPSResult.toSpanned());
}
DetermineBasalAdapterMAJS determineBasalAdapterMAJS = getPlugin().lastDetermineBasalAdapterMAJS;
DetermineBasalAdapterMAJS determineBasalAdapterMAJS = OpenAPSMAPlugin.getPlugin().lastDetermineBasalAdapterMAJS;
if (determineBasalAdapterMAJS != null) {
glucoseStatusView.setText(JSONFormatter.format(determineBasalAdapterMAJS.getGlucoseStatusParam()));
currentTempView.setText(JSONFormatter.format(determineBasalAdapterMAJS.getCurrentTempParam()));
@ -106,8 +104,8 @@ public class OpenAPSMAFragment extends SubscriberFragment implements View.OnClic
profileView.setText(JSONFormatter.format(determineBasalAdapterMAJS.getProfileParam()));
mealDataView.setText(JSONFormatter.format(determineBasalAdapterMAJS.getMealDataParam()));
}
if (getPlugin().lastAPSRun != null) {
lastRunView.setText(getPlugin().lastAPSRun.toLocaleString());
if (OpenAPSMAPlugin.getPlugin().lastAPSRun != null) {
lastRunView.setText(OpenAPSMAPlugin.getPlugin().lastAPSRun.toLocaleString());
}
}
});

View file

@ -38,13 +38,22 @@ import static info.nightscout.androidaps.plugins.OpenAPSAMA.OpenAPSAMAPlugin.ver
public class OpenAPSMAPlugin implements PluginBase, APSInterface {
private static Logger log = LoggerFactory.getLogger(OpenAPSMAPlugin.class);
private static OpenAPSMAPlugin openAPSMAPlugin;
public static OpenAPSMAPlugin getPlugin() {
if (openAPSMAPlugin == null) {
openAPSMAPlugin = new OpenAPSMAPlugin();
}
return openAPSMAPlugin;
}
// last values
DetermineBasalAdapterMAJS lastDetermineBasalAdapterMAJS = null;
Date lastAPSRun = null;
DetermineBasalResultMA lastAPSResult = null;
boolean fragmentEnabled = false;
boolean fragmentVisible = true;
private boolean fragmentEnabled = false;
private boolean fragmentVisible = false;
@Override
public String getName() {
@ -196,18 +205,22 @@ public class OpenAPSMAPlugin implements PluginBase, APSInterface {
if (!checkOnlyHardLimits(profile.getDia(), "dia", 2, 7)) return;
if (!checkOnlyHardLimits(profile.getIc(), "carbratio", 2, 100)) return;
if (!checkOnlyHardLimits(Profile.toMgdl(profile.getIsf().doubleValue(), units), "sens", 2, 900))
if (!checkOnlyHardLimits(Profile.toMgdl(profile.getIsf(), units), "sens", 2, 900))
return;
if (!checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.1, 10)) return;
if (!checkOnlyHardLimits(pump.getBaseBasalRate(), "current_basal", 0.01, 5)) return;
start = new Date();
try {
determineBasalAdapterMAJS.setData(profile, maxIob, maxBasal, minBg, maxBg, targetBg, pump, iobTotal, glucoseStatus, mealData);
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
Profiler.log(log, "MA calculation", start);
DetermineBasalResultMA determineBasalResultMA = determineBasalAdapterMAJS.invoke();
// Fix bug determine basal
// Fix bug determinef basal
if (determineBasalResultMA.rate == 0d && determineBasalResultMA.duration == 0 && !MainApp.getConfigBuilder().isTempBasalInProgress())
determineBasalResultMA.changeRequested = false;
// limit requests on openloop mode
@ -220,8 +233,6 @@ public class OpenAPSMAPlugin implements PluginBase, APSInterface {
determineBasalResultMA.iob = iobTotal;
determineBasalAdapterMAJS.release();
try {
determineBasalResultMA.json.put("timestamp", DateUtil.toISOString(now));
} catch (JSONException e) {
@ -232,8 +243,6 @@ public class OpenAPSMAPlugin implements PluginBase, APSInterface {
lastAPSResult = determineBasalResultMA;
lastAPSRun = now;
MainApp.bus().post(new EventOpenAPSUpdateGui());
//deviceStatus.suggested = determineBasalResultMA.json;
}

View file

@ -7,7 +7,9 @@ import android.os.Handler;
import android.os.HandlerThread;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import android.text.Editable;
import android.text.Html;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
@ -36,22 +38,53 @@ import info.nightscout.androidaps.plugins.Overview.Notification;
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
import info.nightscout.utils.NumberPicker;
import info.nightscout.utils.SafeParse;
import info.nightscout.utils.ToastUtils;
public class NewTreatmentDialog extends DialogFragment implements OnClickListener {
private static Logger log = LoggerFactory.getLogger(NewTreatmentDialog.class);
NumberPicker editCarbs;
NumberPicker editInsulin;
private NumberPicker editCarbs;
private NumberPicker editInsulin;
Handler mHandler;
public static HandlerThread mHandlerThread;
private Integer maxCarbs;
private Double maxInsulin;
private Handler mHandler;
public NewTreatmentDialog() {
mHandlerThread = new HandlerThread(NewTreatmentDialog.class.getSimpleName());
HandlerThread mHandlerThread = new HandlerThread(NewTreatmentDialog.class.getSimpleName());
mHandlerThread.start();
this.mHandler = new Handler(mHandlerThread.getLooper());
}
final private TextWatcher textWatcher = new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
validateInputs();
}
};
private void validateInputs() {
Integer carbs = SafeParse.stringToInt(editCarbs.getText());
if (carbs > maxCarbs) {
editCarbs.setValue(0d);
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), getString(R.string.carbsconstraintapplied));
}
Double insulin = SafeParse.stringToDouble(editInsulin.getText());
if (insulin > maxInsulin) {
editInsulin.setValue(0d);
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), getString(R.string.bolusconstraintapplied));
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
@ -63,14 +96,14 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
Integer maxCarbs = MainApp.getConfigBuilder().applyCarbsConstraints(Constants.carbsOnlyForCheckLimit);
Double maxInsulin = MainApp.getConfigBuilder().applyBolusConstraints(Constants.bolusOnlyForCheckLimit);
maxCarbs = MainApp.getConfigBuilder().applyCarbsConstraints(Constants.carbsOnlyForCheckLimit);
maxInsulin = MainApp.getConfigBuilder().applyBolusConstraints(Constants.bolusOnlyForCheckLimit);
editCarbs = (NumberPicker) view.findViewById(R.id.treatments_newtreatment_carbsamount);
editInsulin = (NumberPicker) view.findViewById(R.id.treatments_newtreatment_insulinamount);
editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false);
editInsulin.setParams(0d, 0d, maxInsulin, MainApp.getConfigBuilder().getPumpDescription().bolusStep, new DecimalFormat("0.00"), false);
editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false, textWatcher);
editInsulin.setParams(0d, 0d, maxInsulin, MainApp.getConfigBuilder().getPumpDescription().bolusStep, new DecimalFormat("0.00"), false, textWatcher);
return view;
}

View file

@ -344,7 +344,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
MainApp.bus().post(new EventRefreshOverview("WizardDialog"));
}
pump.cancelTempBasal(true);
result = pump.setTempBasalAbsolute(0d, 120);
result = pump.setTempBasalAbsolute(0d, 120, true);
if (!result.success) {
OKDialog.show(getActivity(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror), result.comment, null);
}
@ -420,15 +420,9 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
BgReading lastBg = DatabaseHelper.actualBg();
if (lastBg != null) {
editBg.removeTextChangedListener(textWatcher);
//bgInput.setText(lastBg.valueToUnitsToString(units));
editBg.setValue(lastBg.valueToUnits(units));
editBg.addTextChangedListener(textWatcher);
} else {
editBg.removeTextChangedListener(textWatcher);
//bgInput.setText("");
editBg.setValue(0d);
editBg.addTextChangedListener(textWatcher);
}
ttCheckbox.setEnabled(MainApp.getConfigBuilder().getTempTargetFromHistory() != null);
@ -465,19 +459,13 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
Double c_correction = SafeParse.stringToDouble(editCorr.getText());
Double corrAfterConstraint = MainApp.getConfigBuilder().applyBolusConstraints(c_correction);
if (c_correction - corrAfterConstraint != 0) { // c_correction != corrAfterConstraint doesn't work
editCorr.removeTextChangedListener(textWatcher);
editCorr.setValue(0d);
editCorr.addTextChangedListener(textWatcher);
//wizardDialogDeliverButton.setVisibility(Button.GONE);
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), getString(R.string.bolusconstraintapplied));
return;
}
Integer carbsAfterConstraint = MainApp.getConfigBuilder().applyCarbsConstraints(c_carbs);
if (c_carbs - carbsAfterConstraint != 0) {
editCarbs.removeTextChangedListener(textWatcher);
editCarbs.setValue(0d);
editCarbs.addTextChangedListener(textWatcher);
//wizardDialogDeliverButton.setVisibility(Button.GONE);
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), getString(R.string.carbsconstraintapplied));
return;
}

View file

@ -49,9 +49,9 @@ public class Notification {
public static final int NSURGENTALARM = 20;
public static final int SHORT_DIA = 21;
public static final int TOAST_ALARM = 22;
public static final int WRONGBASALSTEP = 23;
public static final int BOLUS_DELIVERY_ERROR = 24;
public int id;
public Date date;
public String text;

View file

@ -33,6 +33,7 @@ import android.widget.CompoundButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.crashlytics.android.Crashlytics;
import com.crashlytics.android.answers.Answers;
import com.crashlytics.android.answers.CustomEvent;
import com.jjoe64.graphview.GraphView;
@ -120,6 +121,7 @@ import info.nightscout.androidaps.plugins.Overview.graphExtensions.FixedLineGrap
import info.nightscout.androidaps.plugins.Overview.graphExtensions.PointsWithLabelGraphSeries;
import info.nightscout.androidaps.plugins.Overview.graphExtensions.TimeAsXAxisLabelFormatter;
import info.nightscout.androidaps.plugins.SourceXdrip.SourceXdripPlugin;
import info.nightscout.androidaps.plugins.Treatments.fragments.ProfileViewerDialog;
import info.nightscout.utils.BolusWizard;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.DecimalFormatter;
@ -133,12 +135,6 @@ import info.nightscout.utils.ToastUtils;
public class OverviewFragment extends Fragment implements View.OnClickListener, CompoundButton.OnCheckedChangeListener {
private static Logger log = LoggerFactory.getLogger(OverviewFragment.class);
private static OverviewPlugin overviewPlugin = new OverviewPlugin();
public static OverviewPlugin getPlugin() {
return overviewPlugin;
}
TextView timeView;
TextView bgView;
TextView arrowView;
@ -214,6 +210,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
try {
//check screen width
final DisplayMetrics dm = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm);
@ -344,12 +341,18 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
}
return view;
} catch (Exception e) {
Crashlytics.logException(e);
}
return null;
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
if (v == apsModeView) {
final LoopPlugin activeloop = ConfigBuilderPlugin.getActiveLoop();
if (activeloop == null)
return;
@ -371,6 +374,11 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
}
if (!activeloop.isEnabled(PluginBase.LOOP))
menu.add(MainApp.sResources.getString(R.string.enableloop));
} else if (v == activeProfileView) {
menu.setHeaderTitle(MainApp.sResources.getString(R.string.profile));
menu.add(MainApp.sResources.getString(R.string.danar_viewprofile));
menu.add(MainApp.sResources.getString(R.string.careportal_profileswitch));
}
}
@Override
@ -554,6 +562,16 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
});
NSUpload.uploadOpenAPSOffline(180);
return true;
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.careportal_profileswitch))) {
NewNSTreatmentDialog newDialog = new NewNSTreatmentDialog();
final OptionsToShow profileswitch = CareportalFragment.PROFILESWITCHDIRECT;
profileswitch.executeProfileSwitch = true;
newDialog.setOptions(profileswitch, R.string.careportal_profileswitch);
newDialog.show(getFragmentManager(), "NewNSTreatmentDialog");
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.danar_viewprofile))) {
ProfileViewerDialog pvd = ProfileViewerDialog.newInstance(System.currentTimeMillis());
FragmentManager manager = getFragmentManager();
pvd.show(manager, "ProfileViewDialog");
}
return super.onContextItemSelected(item);
@ -638,7 +656,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
final Profile profile = MainApp.getConfigBuilder().getProfile();
final TempTarget tempTarget = MainApp.getConfigBuilder().getTempTargetFromHistory();
QuickWizard.QuickWizardEntry quickWizardEntry = getPlugin().quickWizard.getActive();
QuickWizard.QuickWizardEntry quickWizardEntry = OverviewPlugin.getPlugin().quickWizard.getActive();
if (quickWizardEntry != null && actualBg != null) {
quickWizardButton.setVisibility(View.VISIBLE);
BolusWizard wizard = new BolusWizard();
@ -738,6 +756,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
MainApp.bus().unregister(this);
sLoopHandler.removeCallbacksAndMessages(null);
unregisterForContextMenu(apsModeView);
unregisterForContextMenu(activeProfileView);
}
@Override
@ -753,6 +772,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
};
sLoopHandler.postDelayed(sRefreshLoop, 60 * 1000L);
registerForContextMenu(apsModeView);
registerForContextMenu(activeProfileView);
updateGUI("onResume");
}
@ -1088,27 +1108,12 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
activeProfileView.setText(MainApp.getConfigBuilder().getProfileName());
activeProfileView.setBackgroundColor(Color.GRAY);
activeProfileView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
NewNSTreatmentDialog newDialog = new NewNSTreatmentDialog();
final OptionsToShow profileswitch = CareportalFragment.profileswitch;
profileswitch.executeProfileSwitch = true;
newDialog.setOptions(profileswitch, R.string.careportal_profileswitch);
newDialog.show(getFragmentManager(), "NewNSTreatmentDialog");
return true;
}
});
activeProfileView.setLongClickable(true);
tempTargetView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
NewNSTreatmentDialog newTTDialog = new NewNSTreatmentDialog();
final OptionsToShow temptarget = CareportalFragment.temptarget;
final OptionsToShow temptarget = CareportalFragment.TEMPTARGET;
temptarget.executeTempTarget = true;
newTTDialog.setOptions(temptarget, R.string.careportal_temporarytarget);
newTTDialog.show(getFragmentManager(), "NewNSTreatmentDialog");
@ -1118,7 +1123,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
tempTargetView.setLongClickable(true);
// QuickWizard button
QuickWizard.QuickWizardEntry quickWizardEntry = getPlugin().quickWizard.getActive();
QuickWizard.QuickWizardEntry quickWizardEntry = OverviewPlugin.getPlugin().quickWizard.getActive();
if (quickWizardEntry != null && lastBG != null && pump.isInitialized() && !pump.isSuspended()) {
quickWizardButton.setVisibility(View.VISIBLE);
String text = quickWizardEntry.buttonText() + "\n" + DecimalFormatter.to0Decimal(quickWizardEntry.carbs()) + "g";
@ -1805,7 +1810,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
// Adding current time to snooze if we got staleData
log.debug("Notification text is: " + notification.text);
if (notification.text.equals(MainApp.sResources.getString(R.string.nsalarm_staledata))) {
NotificationStore nstore = getPlugin().notificationStore;
NotificationStore nstore = OverviewPlugin.getPlugin().notificationStore;
long msToSnooze = SP.getInt("nsalarm_staledatavalue", 15) * 60 * 1000L;
log.debug("snooze nsalarm_staledatavalue in minutes is " + SP.getInt("nsalarm_staledatavalue", 15) + "\n in ms is: " + msToSnooze + " currentTimeMillis is: " + System.currentTimeMillis());
nstore.snoozeTo(System.currentTimeMillis() + (SP.getInt("nsalarm_staledatavalue", 15) * 60 * 1000L));
@ -1822,7 +1827,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
NotificationStore nstore = getPlugin().notificationStore;
NotificationStore nstore = OverviewPlugin.getPlugin().notificationStore;
nstore.removeExpired();
nstore.unSnooze();
if (nstore.store.size() > 0) {

View file

@ -21,6 +21,15 @@ import info.nightscout.utils.SP;
public class OverviewPlugin implements PluginBase {
private static Logger log = LoggerFactory.getLogger(OverviewPlugin.class);
private static OverviewPlugin overviewPlugin = new OverviewPlugin();
public static OverviewPlugin getPlugin() {
if (overviewPlugin == null)
overviewPlugin = new OverviewPlugin();
return overviewPlugin;
}
public static double bgTargetLow = 80d;
public static double bgTargetHigh = 180d;

View file

@ -39,7 +39,7 @@ import info.nightscout.utils.DecimalFormatter;
public class PersistentNotificationPlugin implements PluginBase {
private static final int ONGOING_NOTIFICATION_ID = 4711;
static boolean fragmentEnabled = true;
private boolean fragmentEnabled = true;
private final Context ctx;
public PersistentNotificationPlugin(Context ctx) {

View file

@ -2,11 +2,12 @@ package info.nightscout.androidaps.plugins.ProfileCircadianPercentage;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.text.Editable;
import android.text.Html;
@ -33,7 +34,6 @@ import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.events.EventInitializationChanged;
import info.nightscout.androidaps.events.EventNewBasalProfile;
import info.nightscout.androidaps.events.EventProfileSwitchChange;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.Careportal.CareportalFragment;
@ -125,6 +125,9 @@ public class CircadianPercentageProfileFragment extends SubscriberFragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
showDeprecatedDialog();
View layout = inflater.inflate(R.layout.circadianpercentageprofile_fragment, container, false);
fl = (FrameLayout) layout.findViewById(R.id.circadianpercentageprofile_framelayout);
fl.requestFocusFromTouch();
@ -178,7 +181,7 @@ public class CircadianPercentageProfileFragment extends SubscriberFragment {
@Override
public void onClick(View view) {
NewNSTreatmentDialog newDialog = new NewNSTreatmentDialog();
final OptionsToShow profileswitch = CareportalFragment.profileswitch;
final OptionsToShow profileswitch = CareportalFragment.PROFILESWITCHDIRECT;
profileswitch.executeProfileSwitch = true;
newDialog.setOptions(profileswitch, R.string.careportal_profileswitch);
newDialog.show(getFragmentManager(), "NewNSTreatmentDialog");
@ -232,7 +235,7 @@ public class CircadianPercentageProfileFragment extends SubscriberFragment {
}
});
timeshiftView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
/*timeshiftView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View view, boolean hasFocus) {
@ -268,7 +271,7 @@ public class CircadianPercentageProfileFragment extends SubscriberFragment {
}
}
}
});
});*/
diaView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@ -317,6 +320,25 @@ public class CircadianPercentageProfileFragment extends SubscriberFragment {
return layout;
}
private void showDeprecatedDialog() {
AlertDialog.Builder adb = new AlertDialog.Builder(getContext());
adb.setTitle("DEPRECATED! Please migrate!");
adb.setMessage("CircadianPercentageProfile has been deprecated. " +
"It is recommended to migrate to LocalProfile.\n\n" +
"Good news: You won't lose any functionality! Percentage and Timeshift have been ported to the ProfileSwitch :) \n\n " +
"How to migrate:\n" +
"1) Press MIGRATE, the system will automatically fill the LocalProfile for you.\n" +
"2) Switch to LocalProfile in the ConfigBuilder\n" +
"3) CHECK that all settings are correct in the LocalProfile!!!");
adb.setIcon(android.R.drawable.ic_dialog_alert);
adb.setPositiveButton("MIGRATE", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
CircadianPercentageProfilePlugin.migrateToLP();
} });
adb.setNegativeButton("Cancel", null);
adb.show();
}
public void updateGUI() {
updateProfileInfo();
@ -502,11 +524,7 @@ public class CircadianPercentageProfileFragment extends SubscriberFragment {
public void run() {
if (!MainApp.getConfigBuilder().isInitialized() || MainApp.getConfigBuilder().isSuspended()) {
profileswitchButton.setVisibility(View.GONE);
} else if (!MainApp.getConfigBuilder().getPumpDescription().isSetBasalProfileCapable) {
profileswitchButton.setText(MainApp.instance().getText(R.string.activate_profile));
profileswitchButton.setVisibility(View.VISIBLE);
} else {
profileswitchButton.setText(MainApp.instance().getText(R.string.send_to_pump));
profileswitchButton.setVisibility(View.VISIBLE);
}
}

View file

@ -21,6 +21,8 @@ import info.nightscout.androidaps.interfaces.ProfileInterface;
import info.nightscout.androidaps.data.ProfileStore;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialog;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.ProfileLocal.LocalProfilePlugin;
import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.NSUpload;
import info.nightscout.utils.SP;
@ -35,8 +37,8 @@ public class CircadianPercentageProfilePlugin implements PluginBase, ProfileInte
public static final String SETTINGS_PREFIX = "CircadianPercentageProfile";
private static Logger log = LoggerFactory.getLogger(CircadianPercentageProfilePlugin.class);
private static boolean fragmentEnabled = false;
private static boolean fragmentVisible = true;
private boolean fragmentEnabled = false;
private boolean fragmentVisible = false;
private static ProfileStore convertedProfile = null;
private static String convertedProfileName = null;
@ -199,7 +201,7 @@ public class CircadianPercentageProfilePlugin implements PluginBase, ProfileInte
//send profile to pumpe
new NewNSTreatmentDialog(); //init
NewNSTreatmentDialog.doProfileSwitch(this.getProfile(), this.getProfileName(), 0);
NewNSTreatmentDialog.doProfileSwitch(this.getProfile(), this.getProfileName(), 0, percentage, timeshift);
//return formatted string
/*msg += "%: " + this.percentage + " h: +" + this.timeshift;
@ -211,6 +213,91 @@ public class CircadianPercentageProfilePlugin implements PluginBase, ProfileInte
return msg;
}
public static void migrateToLP(){
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext());
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("LocalProfile" + "mmol", SP.getBoolean(SETTINGS_PREFIX + "mmol", false));
editor.putBoolean("LocalProfile" + "mgdl", SP.getBoolean(SETTINGS_PREFIX + "mgdl", true));
editor.putString("LocalProfile" + "dia", "" + SP.getDouble(SETTINGS_PREFIX + "dia", Constants.defaultDIA));
editor.putString("LocalProfile" + "ic", getLPic());
editor.putString("LocalProfile" + "isf", getLPisf());
editor.putString("LocalProfile" + "basal", getLPbasal());
try {
JSONArray targetLow = new JSONArray().put(new JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", SP.getDouble(SETTINGS_PREFIX + "targetlow", 120d)));
JSONArray targetHigh = new JSONArray().put(new JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", SP.getDouble(SETTINGS_PREFIX + "targethigh", 120d)));
editor.putString("LocalProfile" + "targetlow", targetLow.toString());
editor.putString("LocalProfile" + "targethigh", targetHigh.toString());
} catch (JSONException e) {
e.printStackTrace();
}
editor.commit();
LocalProfilePlugin lp = MainApp.getSpecificPlugin(LocalProfilePlugin.class);
lp.loadSettings();
/* TODO: remove Settings and switch to LP later on
* For now only nag the user every time (s)he opens the CPP fragment and offer to migrate.
* Keep settings for now in order to allow the user to check that the migration went well.
*/
//removeSettings();
}
public static String getLPisf(){
return getLPConversion("baseisf", 35d);
}
public static String getLPic(){
return getLPConversion("baseic", 4);
}
public static String getLPbasal(){
return getLPConversion("basebasal", 1);
}
public static String getLPConversion(String type, double defaultValue){
try {
JSONArray jsonArray = new JSONArray();
double last = -1d;
for (int i = 0; i < 24; i++) {
double value = SP.getDouble(SETTINGS_PREFIX + type + i, defaultValue);
String time;
DecimalFormat df = new DecimalFormat("00");
time = df.format(i) + ":00";
if(last != value) {
jsonArray.put(new JSONObject().put("time", time).put("timeAsSeconds", i * 60 * 60).put("value", value));
}
last = value;
}
return jsonArray.toString();
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
return LocalProfilePlugin.DEFAULTARRAY;
}
static void removeSettings() {
if (Config.logPrefsChange)
log.debug("Removing settings");
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext());
SharedPreferences.Editor editor = settings.edit();
editor.remove(SETTINGS_PREFIX + "mmol");
editor.remove(SETTINGS_PREFIX + "mgdl");
editor.remove(SETTINGS_PREFIX + "dia");
editor.remove(SETTINGS_PREFIX + "targetlow");
editor.remove(SETTINGS_PREFIX + "targethigh");
editor.remove(SETTINGS_PREFIX + "timeshift");
editor.remove(SETTINGS_PREFIX + "percentage");
for (int i = 0; i < 24; i++) {
editor.remove(SETTINGS_PREFIX + "basebasal");
editor.remove(SETTINGS_PREFIX + "baseisf" + i);
editor.remove(SETTINGS_PREFIX + "baseic" + i);
}
editor.commit();
}
private void createConvertedProfile() {
JSONObject json = new JSONObject();
JSONObject store = new JSONObject();

View file

@ -3,16 +3,16 @@ package info.nightscout.androidaps.plugins.ProfileLocal;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.annotation.NonNull;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioButton;
import com.crashlytics.android.Crashlytics;
import com.squareup.otto.Subscribe;
import org.slf4j.Logger;
@ -28,6 +28,8 @@ import info.nightscout.androidaps.plugins.Careportal.CareportalFragment;
import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialog;
import info.nightscout.androidaps.plugins.Careportal.OptionsToShow;
import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.NumberPicker;
import info.nightscout.utils.SafeParse;
import info.nightscout.utils.TimeListEdit;
@ -40,7 +42,7 @@ public class LocalProfileFragment extends SubscriberFragment {
return localProfilePlugin;
}
EditText diaView;
NumberPicker diaView;
RadioButton mgdlView;
RadioButton mmolView;
TimeListEdit icView;
@ -52,21 +54,45 @@ public class LocalProfileFragment extends SubscriberFragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
try {
Runnable save = new Runnable() {
@Override
public void run() {
localProfilePlugin.storeSettings();
if(basalView!=null){
basalView.updateLabel(MainApp.sResources.getString(R.string.nsprofileview_basal_label)+ ": "+ getSumLabel());
}
}
};
TextWatcher textWatch = new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
}
@Override
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start,
int before, int count) {
localProfilePlugin.dia = SafeParse.stringToDouble(diaView.getText().toString());
localProfilePlugin.storeSettings();
}
};
View layout = inflater.inflate(R.layout.localprofile_fragment, container, false);
diaView = (EditText) layout.findViewById(R.id.localprofile_dia);
diaView = (NumberPicker) layout.findViewById(R.id.localprofile_dia);
diaView.setParams(localProfilePlugin.dia, 2d, 48d, 0.1d, new DecimalFormat("0.0"), false, textWatch);
mgdlView = (RadioButton) layout.findViewById(R.id.localprofile_mgdl);
mmolView = (RadioButton) layout.findViewById(R.id.localprofile_mmol);
icView = new TimeListEdit(getContext(), layout, R.id.localprofile_ic, MainApp.sResources.getString(R.string.nsprofileview_ic_label), getPlugin().ic, null, new DecimalFormat("0.0"), save);
isfView = new TimeListEdit(getContext(), layout, R.id.localprofile_isf, MainApp.sResources.getString(R.string.nsprofileview_isf_label), getPlugin().isf, null, new DecimalFormat("0.0"), save);
basalView = new TimeListEdit(getContext(), layout, R.id.localprofile_basal, MainApp.sResources.getString(R.string.nsprofileview_basal_label), getPlugin().basal, null, new DecimalFormat("0.00"), save);
targetView = new TimeListEdit(getContext(), layout, R.id.localprofile_target, MainApp.sResources.getString(R.string.nsprofileview_target_label), getPlugin().targetLow, getPlugin().targetHigh, new DecimalFormat("0.0"), save);
icView = new TimeListEdit(getContext(), layout, R.id.localprofile_ic, MainApp.sResources.getString(R.string.nsprofileview_ic_label) + ":", getPlugin().ic, null, 0.1d, new DecimalFormat("0.0"), save);
isfView = new TimeListEdit(getContext(), layout, R.id.localprofile_isf, MainApp.sResources.getString(R.string.nsprofileview_isf_label) + ":", getPlugin().isf, null, 0.1d, new DecimalFormat("0.0"), save);
basalView = new TimeListEdit(getContext(), layout, R.id.localprofile_basal, MainApp.sResources.getString(R.string.nsprofileview_basal_label)+ ": " + getSumLabel(), getPlugin().basal, null, 0.01d, new DecimalFormat("0.00"), save);
targetView = new TimeListEdit(getContext(), layout, R.id.localprofile_target, MainApp.sResources.getString(R.string.nsprofileview_target_label)+ ":", getPlugin().targetLow, getPlugin().targetHigh, 0.1d, new DecimalFormat("0.0"), save);
profileswitchButton = (Button) layout.findViewById(R.id.localprofile_profileswitch);
PumpInterface pump = MainApp.getConfigBuilder();
@ -78,7 +104,6 @@ public class LocalProfileFragment extends SubscriberFragment {
mgdlView.setChecked(localProfilePlugin.mgdl);
mmolView.setChecked(localProfilePlugin.mmol);
diaView.setText(localProfilePlugin.dia.toString());
mgdlView.setOnClickListener(new View.OnClickListener() {
@Override
@ -103,37 +128,27 @@ public class LocalProfileFragment extends SubscriberFragment {
@Override
public void onClick(View view) {
NewNSTreatmentDialog newDialog = new NewNSTreatmentDialog();
final OptionsToShow profileswitch = CareportalFragment.profileswitch;
final OptionsToShow profileswitch = CareportalFragment.PROFILESWITCHDIRECT;
profileswitch.executeProfileSwitch = true;
newDialog.setOptions(profileswitch, R.string.careportal_profileswitch);
newDialog.show(getFragmentManager(), "NewNSTreatmentDialog");
}
});
TextWatcher textWatch = new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
}
@Override
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start,
int before, int count) {
localProfilePlugin.dia = SafeParse.stringToDouble(diaView.getText().toString());
localProfilePlugin.storeSettings();
}
};
diaView.addTextChangedListener(textWatch);
updateGUI();
return layout;
} catch (Exception e) {
log.error("Unhandled exception: ", e);
Crashlytics.logException(e);
}
return null;
}
@NonNull
public String getSumLabel() {
return "" + DecimalFormatter.to2Decimal(localProfilePlugin.getProfile().getDefaultProfile().baseBasalSum()) +"U";
}
@Subscribe
@ -150,11 +165,7 @@ public class LocalProfileFragment extends SubscriberFragment {
public void run() {
if (!MainApp.getConfigBuilder().isInitialized() || MainApp.getConfigBuilder().isSuspended()) {
profileswitchButton.setVisibility(View.GONE);
} else if (!MainApp.getConfigBuilder().getPumpDescription().isSetBasalProfileCapable) {
profileswitchButton.setText(MainApp.instance().getText(R.string.activate_profile));
profileswitchButton.setVisibility(View.VISIBLE);
} else {
profileswitchButton.setText(MainApp.instance().getText(R.string.send_to_pump));
profileswitchButton.setVisibility(View.VISIBLE);
}
}

View file

@ -16,21 +16,23 @@ import info.nightscout.androidaps.R;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.ProfileInterface;
import info.nightscout.androidaps.data.ProfileStore;
import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.SP;
/**
* Created by mike on 05.08.2016.
*/
public class LocalProfilePlugin implements PluginBase, ProfileInterface {
public static final String LOCAL_PROFILE = "LocalProfile";
private static Logger log = LoggerFactory.getLogger(LocalProfilePlugin.class);
private static boolean fragmentEnabled = false;
private static boolean fragmentVisible = true;
private boolean fragmentEnabled = false;
private boolean fragmentVisible = false;
private static ProfileStore convertedProfile = null;
private static String convertedProfileName = null;
private ProfileStore convertedProfile = null;
private String convertedProfileName = null;
final private String DEFAULTARRAY = "[{\"time\":\"00:00\",\"timeAsSeconds\":0,\"value\":0}]";
public static final String DEFAULTARRAY = "[{\"time\":\"00:00\",\"timeAsSeconds\":0,\"value\":0}]";
boolean mgdl;
boolean mmol;
@ -107,68 +109,68 @@ public class LocalProfilePlugin implements PluginBase, ProfileInterface {
}
public void storeSettings() {
if (Config.logPrefsChange)
log.debug("Storing settings");
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext());
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("LocalProfile" + "mmol", mmol);
editor.putBoolean("LocalProfile" + "mgdl", mgdl);
editor.putString("LocalProfile" + "dia", dia.toString());
editor.putString("LocalProfile" + "ic", ic.toString());
editor.putString("LocalProfile" + "isf", isf.toString());
editor.putString("LocalProfile" + "basal", basal.toString());
editor.putString("LocalProfile" + "targetlow", targetLow.toString());
editor.putString("LocalProfile" + "targethigh", targetHigh.toString());
editor.putBoolean(LOCAL_PROFILE + "mmol", mmol);
editor.putBoolean(LOCAL_PROFILE + "mgdl", mgdl);
editor.putString(LOCAL_PROFILE + "dia", dia.toString());
editor.putString(LOCAL_PROFILE + "ic", ic.toString());
editor.putString(LOCAL_PROFILE + "isf", isf.toString());
editor.putString(LOCAL_PROFILE + "basal", basal.toString());
editor.putString(LOCAL_PROFILE + "targetlow", targetLow.toString());
editor.putString(LOCAL_PROFILE + "targethigh", targetHigh.toString());
editor.commit();
editor.apply();
createConvertedProfile();
if (Config.logPrefsChange)
log.debug("Storing settings: " + getProfile().getData().toString());
}
private void loadSettings() {
public void loadSettings() {
if (Config.logPrefsChange)
log.debug("Loading stored settings");
mgdl = SP.getBoolean("LocalProfile" + "mgdl", false);
mmol = SP.getBoolean("LocalProfile" + "mmol", true);
dia = SP.getDouble("LocalProfile" + "dia", Constants.defaultDIA);
mgdl = SP.getBoolean(LOCAL_PROFILE + "mgdl", false);
mmol = SP.getBoolean(LOCAL_PROFILE + "mmol", true);
dia = SP.getDouble(LOCAL_PROFILE + "dia", Constants.defaultDIA);
try {
ic = new JSONArray(SP.getString("LocalProfile" + "ic", DEFAULTARRAY));
ic = new JSONArray(SP.getString(LOCAL_PROFILE + "ic", DEFAULTARRAY));
} catch (JSONException e1) {
try {
ic = new JSONArray(DEFAULTARRAY);
} catch (JSONException e2) {
} catch (JSONException ignored) {
}
}
try {
isf = new JSONArray(SP.getString("LocalProfile" + "isf", DEFAULTARRAY));
isf = new JSONArray(SP.getString(LOCAL_PROFILE + "isf", DEFAULTARRAY));
} catch (JSONException e1) {
try {
isf = new JSONArray(DEFAULTARRAY);
} catch (JSONException e2) {
} catch (JSONException ignored) {
}
}
try {
basal = new JSONArray(SP.getString("LocalProfile" + "basal", DEFAULTARRAY));
basal = new JSONArray(SP.getString(LOCAL_PROFILE + "basal", DEFAULTARRAY));
} catch (JSONException e1) {
try {
basal = new JSONArray(DEFAULTARRAY);
} catch (JSONException e2) {
} catch (JSONException ignored) {
}
}
try {
targetLow = new JSONArray(SP.getString("LocalProfile" + "targetlow", DEFAULTARRAY));
targetLow = new JSONArray(SP.getString(LOCAL_PROFILE + "targetlow", DEFAULTARRAY));
} catch (JSONException e1) {
try {
targetLow = new JSONArray(DEFAULTARRAY);
} catch (JSONException e2) {
} catch (JSONException ignored) {
}
}
try {
targetHigh = new JSONArray(SP.getString("LocalProfile" + "targethigh", DEFAULTARRAY));
targetHigh = new JSONArray(SP.getString(LOCAL_PROFILE + "targethigh", DEFAULTARRAY));
} catch (JSONException e1) {
try {
targetHigh = new JSONArray(DEFAULTARRAY);
} catch (JSONException e2) {
} catch (JSONException ignored) {
}
}
createConvertedProfile();
@ -212,13 +214,13 @@ public class LocalProfilePlugin implements PluginBase, ProfileInterface {
"created_at": "2016-06-16T08:34:41.256Z"
}
*/
void createConvertedProfile() {
private void createConvertedProfile() {
JSONObject json = new JSONObject();
JSONObject store = new JSONObject();
JSONObject profile = new JSONObject();
try {
json.put("defaultProfile", "LocalProfile");
json.put("defaultProfile", LOCAL_PROFILE);
json.put("store", store);
profile.put("dia", dia);
profile.put("carbratio", ic);
@ -227,12 +229,12 @@ public class LocalProfilePlugin implements PluginBase, ProfileInterface {
profile.put("target_low", targetLow);
profile.put("target_high", targetHigh);
profile.put("units", mgdl ? Constants.MGDL : Constants.MMOL);
store.put("LocalProfile", profile);
store.put(LOCAL_PROFILE, profile);
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
convertedProfile = new ProfileStore(json);
convertedProfileName = "LocalProfile";
convertedProfileName = LOCAL_PROFILE;
}
@Override
@ -247,7 +249,7 @@ public class LocalProfilePlugin implements PluginBase, ProfileInterface {
@Override
public String getProfileName() {
return convertedProfileName;
return DecimalFormatter.to2Decimal(convertedProfile.getDefaultProfile().percentageBasalSum()) + "U ";
}
}

View file

@ -2,28 +2,30 @@ package info.nightscout.androidaps.plugins.ProfileNS;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import com.crashlytics.android.Crashlytics;
import com.squareup.otto.Subscribe;
import java.util.ArrayList;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.ProfileStore;
import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
import info.nightscout.androidaps.plugins.ProfileNS.events.EventNSProfileUpdateGUI;
import info.nightscout.utils.DecimalFormatter;
public class NSProfileFragment extends SubscriberFragment {
private static NSProfilePlugin nsProfilePlugin = new NSProfilePlugin();
public static NSProfilePlugin getPlugin() {
return nsProfilePlugin;
}
public class NSProfileFragment extends SubscriberFragment implements AdapterView.OnItemSelectedListener {
private Spinner profileSpinner;
private TextView noProfile;
private TextView units;
private TextView dia;
@ -36,8 +38,10 @@ public class NSProfileFragment extends SubscriberFragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View layout = inflater.inflate(R.layout.nsprofileviewer_fragment, container, false);
try {
View layout = inflater.inflate(R.layout.nsprofile_fragment, container, false);
profileSpinner = (Spinner) layout.findViewById(R.id.nsprofile_spinner);
noProfile = (TextView) layout.findViewById(R.id.profileview_noprofile);
units = (TextView) layout.findViewById(R.id.profileview_units);
dia = (TextView) layout.findViewById(R.id.profileview_dia);
@ -47,8 +51,15 @@ public class NSProfileFragment extends SubscriberFragment {
basal = (TextView) layout.findViewById(R.id.profileview_basal);
target = (TextView) layout.findViewById(R.id.profileview_target);
profileSpinner.setOnItemSelectedListener(this);
updateGUI();
return layout;
} catch (Exception e) {
Crashlytics.logException(e);
}
return null;
}
@Subscribe
@ -72,14 +83,42 @@ public class NSProfileFragment extends SubscriberFragment {
noProfile.setVisibility(View.GONE);
}
Profile profile = MainApp.getConfigBuilder().getProfile();
ProfileStore profileStore = NSProfilePlugin.getPlugin().getProfile();
ArrayList<CharSequence> profileList = profileStore.getProfileList();
ArrayAdapter<CharSequence> adapter = new ArrayAdapter<>(getContext(),
R.layout.spinner_centered, profileList);
profileSpinner.setAdapter(adapter);
// set selected to actual profile
for (int p = 0; p < profileList.size(); p++) {
if (profileList.get(p).equals(MainApp.getConfigBuilder().getProfileName()))
profileSpinner.setSelection(p);
}
}
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String name = parent.getItemAtPosition(position).toString();
Profile profile = NSProfilePlugin.getPlugin().getProfile().getSpecificProfile(name);
units.setText(profile.getUnits());
dia.setText(DecimalFormatter.to2Decimal(profile.getDia()) + " h");
activeProfile.setText(MainApp.getConfigBuilder().getProfileName());
activeProfile.setText(name);
ic.setText(profile.getIcList());
isf.setText(profile.getIsfList());
basal.setText(profile.getBasalList());
target.setText(profile.getTargetList());
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
noProfile.setVisibility(View.VISIBLE);
units.setText("");
dia.setText("");
activeProfile.setText("");
ic.setText("");
isf.setText("");
basal.setText("");
target.setText("");
}
}

View file

@ -29,17 +29,25 @@ import info.nightscout.utils.SP;
public class NSProfilePlugin implements PluginBase, ProfileInterface {
private static Logger log = LoggerFactory.getLogger(NSProfilePlugin.class);
private static NSProfilePlugin nsProfilePlugin;
public static NSProfilePlugin getPlugin() {
if (nsProfilePlugin == null)
nsProfilePlugin = new NSProfilePlugin();
return nsProfilePlugin;
}
@Override
public String getFragmentClass() {
return NSProfileFragment.class.getName();
}
static boolean fragmentEnabled = true;
static boolean fragmentVisible = true;
private boolean fragmentEnabled = true;
private boolean fragmentVisible = true;
static ProfileStore profile = null;
private static ProfileStore profile = null;
public NSProfilePlugin() {
private NSProfilePlugin() {
MainApp.bus().register(this);
loadNSProfile();

View file

@ -3,7 +3,6 @@ package info.nightscout.androidaps.plugins.ProfileSimple;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
@ -13,6 +12,7 @@ import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioButton;
import com.crashlytics.android.Crashlytics;
import com.squareup.otto.Subscribe;
import org.slf4j.Logger;
@ -31,12 +31,6 @@ import info.nightscout.utils.SafeParse;
public class SimpleProfileFragment extends SubscriberFragment {
private static Logger log = LoggerFactory.getLogger(SimpleProfileFragment.class);
private static SimpleProfilePlugin simpleProfilePlugin = new SimpleProfilePlugin();
public static SimpleProfilePlugin getPlugin() {
return simpleProfilePlugin;
}
EditText diaView;
RadioButton mgdlView;
RadioButton mmolView;
@ -50,6 +44,7 @@ public class SimpleProfileFragment extends SubscriberFragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
try {
View layout = inflater.inflate(R.layout.simpleprofile_fragment, container, false);
diaView = (EditText) layout.findViewById(R.id.simpleprofile_dia);
mgdlView = (RadioButton) layout.findViewById(R.id.simpleprofile_mgdl);
@ -69,31 +64,31 @@ public class SimpleProfileFragment extends SubscriberFragment {
updateGUI();
mgdlView.setChecked(simpleProfilePlugin.mgdl);
mmolView.setChecked(simpleProfilePlugin.mmol);
diaView.setText(simpleProfilePlugin.dia.toString());
icView.setText(simpleProfilePlugin.ic.toString());
isfView.setText(simpleProfilePlugin.isf.toString());
basalView.setText(simpleProfilePlugin.basal.toString());
targetlowView.setText(simpleProfilePlugin.targetLow.toString());
targethighView.setText(simpleProfilePlugin.targetHigh.toString());
mgdlView.setChecked(SimpleProfilePlugin.getPlugin().mgdl);
mmolView.setChecked(SimpleProfilePlugin.getPlugin().mmol);
diaView.setText(SimpleProfilePlugin.getPlugin().dia.toString());
icView.setText(SimpleProfilePlugin.getPlugin().ic.toString());
isfView.setText(SimpleProfilePlugin.getPlugin().isf.toString());
basalView.setText(SimpleProfilePlugin.getPlugin().basal.toString());
targetlowView.setText(SimpleProfilePlugin.getPlugin().targetLow.toString());
targethighView.setText(SimpleProfilePlugin.getPlugin().targetHigh.toString());
mgdlView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
simpleProfilePlugin.mgdl = mgdlView.isChecked();
simpleProfilePlugin.mmol = !simpleProfilePlugin.mgdl;
mmolView.setChecked(simpleProfilePlugin.mmol);
simpleProfilePlugin.storeSettings();
SimpleProfilePlugin.getPlugin().mgdl = mgdlView.isChecked();
SimpleProfilePlugin.getPlugin().mmol = !SimpleProfilePlugin.getPlugin().mgdl;
mmolView.setChecked(SimpleProfilePlugin.getPlugin().mmol);
SimpleProfilePlugin.getPlugin().storeSettings();
}
});
mmolView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
simpleProfilePlugin.mmol = mmolView.isChecked();
simpleProfilePlugin.mgdl = !simpleProfilePlugin.mmol;
mgdlView.setChecked(simpleProfilePlugin.mgdl);
simpleProfilePlugin.storeSettings();
SimpleProfilePlugin.getPlugin().mmol = mmolView.isChecked();
SimpleProfilePlugin.getPlugin().mgdl = !SimpleProfilePlugin.getPlugin().mmol;
mgdlView.setChecked(SimpleProfilePlugin.getPlugin().mgdl);
SimpleProfilePlugin.getPlugin().storeSettings();
}
});
@ -101,7 +96,7 @@ public class SimpleProfileFragment extends SubscriberFragment {
@Override
public void onClick(View view) {
NewNSTreatmentDialog newDialog = new NewNSTreatmentDialog();
final OptionsToShow profileswitch = CareportalFragment.profileswitch;
final OptionsToShow profileswitch = CareportalFragment.PROFILESWITCH;
profileswitch.executeProfileSwitch = true;
newDialog.setOptions(profileswitch, R.string.careportal_profileswitch);
newDialog.show(getFragmentManager(), "NewNSTreatmentDialog");
@ -122,13 +117,13 @@ public class SimpleProfileFragment extends SubscriberFragment {
@Override
public void onTextChanged(CharSequence s, int start,
int before, int count) {
simpleProfilePlugin.dia = SafeParse.stringToDouble(diaView.getText().toString());
simpleProfilePlugin.ic = SafeParse.stringToDouble(icView.getText().toString());
simpleProfilePlugin.isf = SafeParse.stringToDouble(isfView.getText().toString());
simpleProfilePlugin.basal = SafeParse.stringToDouble(basalView.getText().toString());
simpleProfilePlugin.targetLow = SafeParse.stringToDouble(targetlowView.getText().toString());
simpleProfilePlugin.targetHigh = SafeParse.stringToDouble(targethighView.getText().toString());
simpleProfilePlugin.storeSettings();
SimpleProfilePlugin.getPlugin().dia = SafeParse.stringToDouble(diaView.getText().toString());
SimpleProfilePlugin.getPlugin().ic = SafeParse.stringToDouble(icView.getText().toString());
SimpleProfilePlugin.getPlugin().isf = SafeParse.stringToDouble(isfView.getText().toString());
SimpleProfilePlugin.getPlugin().basal = SafeParse.stringToDouble(basalView.getText().toString());
SimpleProfilePlugin.getPlugin().targetLow = SafeParse.stringToDouble(targetlowView.getText().toString());
SimpleProfilePlugin.getPlugin().targetHigh = SafeParse.stringToDouble(targethighView.getText().toString());
SimpleProfilePlugin.getPlugin().storeSettings();
}
};
@ -142,6 +137,11 @@ public class SimpleProfileFragment extends SubscriberFragment {
updateGUI();
return layout;
} catch (Exception e) {
Crashlytics.logException(e);
}
return null;
}
@Subscribe
@ -158,11 +158,7 @@ public class SimpleProfileFragment extends SubscriberFragment {
public void run() {
if (!MainApp.getConfigBuilder().isInitialized() || MainApp.getConfigBuilder().isSuspended()) {
profileswitchButton.setVisibility(View.GONE);
} else if (!MainApp.getConfigBuilder().getPumpDescription().isSetBasalProfileCapable) {
profileswitchButton.setText(MainApp.instance().getText(R.string.activate_profile));
profileswitchButton.setVisibility(View.VISIBLE);
} else {
profileswitchButton.setText(MainApp.instance().getText(R.string.send_to_pump));
profileswitchButton.setVisibility(View.VISIBLE);
}
}

View file

@ -24,8 +24,16 @@ import info.nightscout.utils.SP;
public class SimpleProfilePlugin implements PluginBase, ProfileInterface {
private static Logger log = LoggerFactory.getLogger(SimpleProfilePlugin.class);
private static boolean fragmentEnabled = false;
private static boolean fragmentVisible = true;
private static SimpleProfilePlugin simpleProfilePlugin;
public static SimpleProfilePlugin getPlugin() {
if (simpleProfilePlugin == null)
simpleProfilePlugin = new SimpleProfilePlugin();
return simpleProfilePlugin;
}
private boolean fragmentEnabled = false;
private boolean fragmentVisible = false;
private static ProfileStore convertedProfile = null;
@ -38,7 +46,7 @@ public class SimpleProfilePlugin implements PluginBase, ProfileInterface {
Double targetLow;
Double targetHigh;
public SimpleProfilePlugin() {
private SimpleProfilePlugin() {
loadSettings();
}
@ -117,7 +125,7 @@ public class SimpleProfilePlugin implements PluginBase, ProfileInterface {
editor.putString("SimpleProfile" + "targetlow", targetLow.toString());
editor.putString("SimpleProfile" + "targethigh", targetHigh.toString());
editor.commit();
editor.apply();
createConvertedProfile();
}
@ -174,7 +182,7 @@ public class SimpleProfilePlugin implements PluginBase, ProfileInterface {
"created_at": "2016-06-16T08:34:41.256Z"
}
*/
void createConvertedProfile() {
private void createConvertedProfile() {
JSONObject json = new JSONObject();
JSONObject store = new JSONObject();
JSONObject profile = new JSONObject();

View file

@ -7,21 +7,20 @@ 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.LinearLayout;
import android.widget.TextView;
import com.crashlytics.android.Crashlytics;
import com.squareup.otto.Subscribe;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Date;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.events.EventExtendedBolusChange;
@ -58,10 +57,21 @@ public class DanaRFragment extends SubscriberFragment {
TextView firmwareView;
TextView basalStepView;
TextView bolusStepView;
TextView serialNumberView;
Button viewProfileButton;
Button historyButton;
Button statsButton;
LinearLayout pumpStatusLayout;
TextView pumpStatusView;
static Runnable connectRunnable = new Runnable() {
@Override
public void run() {
MainApp.getConfigBuilder().refreshDataFromPump("Connect request from GUI");
}
};
public DanaRFragment() {
if (sHandlerThread == null) {
@ -89,6 +99,7 @@ public class DanaRFragment extends SubscriberFragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
try {
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);
@ -106,7 +117,11 @@ public class DanaRFragment extends SubscriberFragment {
statsButton = (Button) view.findViewById(R.id.danar_stats);
basalStepView = (TextView) view.findViewById(R.id.danar_basalstep);
bolusStepView = (TextView) view.findViewById(R.id.danar_bolusstep);
serialNumberView = (TextView) view.findViewById(R.id.danar_serialnumber);
pumpStatusView = (TextView) view.findViewById(R.id.overview_pumpstatus);
pumpStatusView.setBackgroundColor(MainApp.sResources.getColor(R.color.colorInitializingBorder));
pumpStatusLayout = (LinearLayout) view.findViewById(R.id.overview_pumpstatuslayout);
viewProfileButton.setOnClickListener(new View.OnClickListener() {
@Override
@ -134,23 +149,24 @@ public class DanaRFragment extends SubscriberFragment {
btConnectionView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
sHandler.post(new Runnable() {
@Override
public void run() {
MainApp.getConfigBuilder().refreshDataFromPump("Connect request from GUI");
}
}
);
log.debug("Clicked connect to pump");
sHandler.post(connectRunnable);
}
});
updateGUI();
return view;
} catch (Exception e) {
Crashlytics.logException(e);
}
return null;
}
@Subscribe
public void onStatusEvent(final EventPumpStatusChanged c) {
Activity activity = getActivity();
final String status = c.textStatus();
if (activity != null) {
activity.runOnUiThread(
new Runnable() {
@ -162,6 +178,13 @@ public class DanaRFragment extends SubscriberFragment {
btConnectionView.setText("{fa-bluetooth}");
else if (c.sStatus == EventPumpStatusChanged.DISCONNECTED)
btConnectionView.setText("{fa-bluetooth-b}");
if (!status.equals("")) {
pumpStatusView.setText(status);
pumpStatusLayout.setVisibility(View.VISIBLE);
} else {
pumpStatusLayout.setVisibility(View.GONE);
}
}
}
);
@ -242,6 +265,7 @@ public class DanaRFragment extends SubscriberFragment {
}
basalStepView.setText("" + pump.basalStep);
bolusStepView.setText("" + pump.bolusStep);
serialNumberView.setText("" + pump.serialNumber);
}
});

View file

@ -59,11 +59,11 @@ public class DanaRPlugin implements PluginBase, PumpInterface, DanaRInterface, C
return DanaRFragment.class.getName();
}
static boolean fragmentPumpEnabled = false;
static boolean fragmentProfileEnabled = false;
static boolean fragmentPumpVisible = true;
private static boolean fragmentPumpEnabled = false;
private static boolean fragmentProfileEnabled = false;
private static boolean fragmentPumpVisible = true;
public static DanaRExecutionService sExecutionService;
private static DanaRExecutionService sExecutionService;
private static DanaRPump pump = DanaRPump.getInstance();
@ -199,22 +199,22 @@ public class DanaRPlugin implements PluginBase, PumpInterface, DanaRInterface, C
@Override
public void setFragmentEnabled(int type, boolean fragmentEnabled) {
if (type == PluginBase.PROFILE)
this.fragmentProfileEnabled = fragmentEnabled;
fragmentProfileEnabled = fragmentEnabled;
else if (type == PluginBase.PUMP)
this.fragmentPumpEnabled = fragmentEnabled;
fragmentPumpEnabled = fragmentEnabled;
// if pump profile was enabled need to switch to another too
if (type == PluginBase.PUMP && !fragmentEnabled && this.fragmentProfileEnabled) {
if (type == PluginBase.PUMP && !fragmentEnabled && 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);
NSProfilePlugin.getPlugin().setFragmentEnabled(PluginBase.PROFILE, true);
NSProfilePlugin.getPlugin().setFragmentVisible(PluginBase.PROFILE, true);
}
}
@Override
public void setFragmentVisible(int type, boolean fragmentVisible) {
if (type == PluginBase.PUMP)
this.fragmentPumpVisible = fragmentVisible;
fragmentPumpVisible = fragmentVisible;
}
@Override
@ -342,7 +342,7 @@ public class DanaRPlugin implements PluginBase, PumpInterface, DanaRInterface, C
// This is called from APS
@Override
public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, boolean force) {
public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, boolean enforceNew) {
// Recheck pump status if older than 30 min
if (pump.lastConnection.getTime() + 30 * 60 * 1000L < System.currentTimeMillis()) {
doConnect("setTempBasalAbsolute old data");
@ -408,7 +408,7 @@ public class DanaRPlugin implements PluginBase, PumpInterface, DanaRInterface, C
if (Config.logPumpActions)
log.debug("setTempBasalAbsolute: currently running: " + running.toString());
if (running.percentRate == percentRate) {
if (force) {
if (enforceNew) {
cancelTempBasal(true);
} else {
result.success = true;
@ -506,7 +506,8 @@ public class DanaRPlugin implements PluginBase, PumpInterface, DanaRInterface, C
}
if (percent > getPumpDescription().maxTempPercent)
percent = getPumpDescription().maxTempPercent;
if (pump.isTempBasalInProgress && pump.tempBasalPercent == percent) {
TemporaryBasal runningTB = MainApp.getConfigBuilder().getRealTempBasalFromHistory(System.currentTimeMillis());
if (runningTB != null && runningTB.percentRate == percent) {
result.enacted = false;
result.success = true;
result.isTempCancel = false;
@ -550,7 +551,8 @@ public class DanaRPlugin implements PluginBase, PumpInterface, DanaRInterface, C
insulin = Round.roundTo(insulin, getPumpDescription().extendedBolusStep * (1 + durationInHalfHours % 1));
PumpEnactResult result = new PumpEnactResult();
if (pump.isExtendedInProgress && Math.abs(pump.extendedBolusAmount - insulin) < getPumpDescription().extendedBolusStep) {
ExtendedBolus runningEB = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis());
if (runningEB != null && Math.abs(runningEB.insulin - insulin) < getPumpDescription().extendedBolusStep) {
result.enacted = false;
result.success = true;
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
@ -601,7 +603,8 @@ public class DanaRPlugin implements PluginBase, PumpInterface, DanaRInterface, C
public PumpEnactResult cancelRealTempBasal() {
PumpEnactResult result = new PumpEnactResult();
if (pump.isTempBasalInProgress) {
TemporaryBasal runningTB = MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis());
if (runningTB != null) {
sExecutionService.tempBasalStop();
result.enacted = true;
result.isTempCancel = true;
@ -625,7 +628,8 @@ public class DanaRPlugin implements PluginBase, PumpInterface, DanaRInterface, C
@Override
public PumpEnactResult cancelExtendedBolus() {
PumpEnactResult result = new PumpEnactResult();
if (pump.isExtendedInProgress) {
ExtendedBolus runningEB = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis());
if (runningEB != null) {
sExecutionService.extendedBolusStop();
result.enacted = true;
result.isTempCancel = true;
@ -645,7 +649,11 @@ public class DanaRPlugin implements PluginBase, PumpInterface, DanaRInterface, C
}
public static void doConnect(String from) {
if (sExecutionService != null) sExecutionService.connect(from);
if (sExecutionService != null) {
sExecutionService.connect(from);
pumpDescription.basalStep = pump.basalStep;
pumpDescription.bolusStep = pump.bolusStep;
}
}
public static boolean isConnected() {

View file

@ -9,8 +9,10 @@ import org.slf4j.LoggerFactory;
import java.text.DecimalFormat;
import java.util.Date;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.ProfileStore;
import info.nightscout.utils.SP;
@ -52,6 +54,7 @@ public class DanaRPump {
public static final int PRIME = 12;
public static final int PROFILECHANGE = 13;
public static final int CARBS = 14;
public static final int PRIMECANNULA = 15;
public Date lastConnection = new Date(0);
public Date lastSettingsRead = new Date(0);
@ -78,10 +81,12 @@ public class DanaRPump {
public boolean pumpSuspended;
public boolean calculatorEnabled;
public double dailyTotalUnits;
public double dailyTotalBolusUnits = 0; // RS only
public double dailyTotalBasalUnits = 0; // RS only
public int maxDailyTotalUnits;
public double bolusStep;
public double basalStep;
public double bolusStep = 0.1;
public double basalStep = 0.1;
public double iob;
@ -108,6 +113,7 @@ public class DanaRPump {
public int extendedBolusSoFarInMinutes;
public Date extendedBolusStart;
public int extendedBolusRemainingMinutes;
public double extendedBolusDeliveredSoFar; //RS only
// Profile
public int units;
@ -136,6 +142,27 @@ public class DanaRPump {
public double maxBolus;
public double maxBasal;
// DanaRS specific
public String rs_password = "";
// User settings
public int timeDisplayType;
public int buttonScrollOnOff;
public int beepAndAlarm;
public int lcdOnTimeSec;
public int backlightOnTimeSec;
public int selectedLanguage;
public int shutdownHour;
public int lowReservoirRate;
public int cannulaVolume;
public int refillAmount;
public double initialBolusAmount;
// Bolus settings
public int bolusCalculationOption;
public int missedBolusConfig;
public String getUnits() {
return units == UNITS_MGDL ? Constants.MGDL : Constants.MMOL;
}
@ -205,4 +232,17 @@ public class DanaRPump {
return PROFILE_PREFIX + (activeProfile + 1);
}
public static double[] buildDanaRProfileRecord(Profile nsProfile) {
double[] record = new double[24];
for (Integer hour = 0; hour < 24; hour++) {
//Some values get truncated to the next lower one.
// -> round them to two decimals and make sure we are a small delta larger (that will get truncated)
double value = Math.round(100d * nsProfile.getBasal((Integer) (hour * 60 * 60)))/100d + 0.00001;
if (Config.logDanaMessageDetail)
log.debug("NS basal value for " + hour + ":00 is " + value);
record[hour] = value;
}
return record;
}
}

View file

@ -57,7 +57,7 @@ public class ProfileViewDialog extends DialogFragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View layout = inflater.inflate(R.layout.nsprofileviewer_fragment, container, false);
View layout = inflater.inflate(R.layout.profileviewer_fragment, container, false);
noProfile = (TextView) layout.findViewById(R.id.profileview_noprofile);
units = (TextView) layout.findViewById(R.id.profileview_units);

View file

@ -42,6 +42,7 @@ import info.nightscout.androidaps.plugins.PumpDanaR.services.DanaRExecutionServi
import info.nightscout.androidaps.plugins.PumpDanaR.comm.RecordTypes;
import info.nightscout.androidaps.plugins.PumpDanaR.events.EventDanaRSyncStatus;
import info.nightscout.androidaps.plugins.PumpDanaRKorean.DanaRKoreanPlugin;
import info.nightscout.androidaps.plugins.PumpDanaRS.DanaRSPlugin;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.ToastUtils;
@ -122,6 +123,7 @@ public class DanaRHistoryActivity extends Activity {
statusView.setVisibility(View.GONE);
boolean isKorean = MainApp.getSpecificPlugin(DanaRKoreanPlugin.class).isEnabled(PluginBase.PUMP);
boolean isRS = MainApp.getSpecificPlugin(DanaRSPlugin.class).isEnabled(PluginBase.PUMP);
// Types
@ -132,8 +134,12 @@ public class DanaRHistoryActivity extends Activity {
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)));
if (!isKorean) {
if (!isKorean && !isRS) {
typeList.add(new TypeList(RecordTypes.RECORD_TYPE_ERROR, getString(R.string.danar_history_errors)));
}
if (isRS)
typeList.add(new TypeList(RecordTypes.RECORD_TYPE_PRIME, getString(R.string.danar_history_prime)));
if (!isKorean) {
typeList.add(new TypeList(RecordTypes.RECORD_TYPE_REFILL, getString(R.string.danar_history_refill)));
typeList.add(new TypeList(RecordTypes.RECORD_TYPE_SUSPEND, getString(R.string.danar_history_syspend)));
}

View file

@ -1,16 +1,11 @@
package info.nightscout.androidaps.plugins.PumpDanaR.activities;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.Color;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.support.v7.widget.LinearLayoutManager;
import android.text.TextUtils;
import android.view.KeyEvent;
@ -42,16 +37,14 @@ import java.util.List;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.db.DanaRHistoryRecord;
import info.nightscout.androidaps.events.EventPumpStatusChanged;
import info.nightscout.androidaps.interfaces.DanaRInterface;
import info.nightscout.androidaps.interfaces.ProfileInterface;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.ProfileCircadianPercentage.CircadianPercentageProfilePlugin;
import info.nightscout.androidaps.plugins.PumpDanaR.comm.RecordTypes;
import info.nightscout.androidaps.plugins.PumpDanaR.events.EventDanaRSyncStatus;
import info.nightscout.androidaps.plugins.PumpDanaR.services.DanaRExecutionService;
import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.SP;
import info.nightscout.utils.SafeParse;
@ -134,15 +127,14 @@ public class DanaRStatsActivity extends Activity {
llm = new LinearLayoutManager(this);
TBB = SP.getString("TBB", "10.00");
totalBaseBasal.setText(TBB);
ProfileInterface pi = ConfigBuilderPlugin.getActiveProfileInterface();
if (pi != null && pi instanceof CircadianPercentageProfilePlugin) {
double cppTBB = ((CircadianPercentageProfilePlugin) pi).baseBasalSum();
totalBaseBasal.setText(decimalFormat.format(cppTBB));
SP.putString("TBB", totalBaseBasal.getText().toString());
TBB = SP.getString("TBB", "");
Profile profile = MainApp.getConfigBuilder().getProfile();
if (profile != null) {
double cppTBB = profile.baseBasalSum();
TBB = decimalFormat.format(cppTBB);
SP.putString("TBB", TBB);
}
totalBaseBasal.setText(TBB);
// stats table
tl = (TableLayout) findViewById(R.id.main_table);
@ -241,7 +233,7 @@ public class DanaRStatsActivity extends Activity {
reloadButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final PumpInterface pump = MainApp.getConfigBuilder().getActivePump();
final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
if (pump.isBusy()) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), getString(R.string.pumpbusy));
return;

View file

@ -18,6 +18,7 @@ public class MessageHashTable {
messages = new HashMap<Integer, MessageBase>();
put(new MsgBolusStop()); // 0x0101 CMD_MEALINS_STOP
put(new MsgBolusStart()); // 0x0102 CMD_MEALINS_START_DATA
put(new MsgBolusStartWithSpeed()); // 0x0104 CMD_MEALINS_START_DATA_SPEED
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

View file

@ -0,0 +1,43 @@
package info.nightscout.androidaps.plugins.PumpDanaR.comm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.MainApp;
import info.nightscout.utils.HardLimits;
public class MsgBolusStartWithSpeed extends MessageBase {
private static Logger log = LoggerFactory.getLogger(MsgBolusStartWithSpeed.class);
public MsgBolusStartWithSpeed() {
SetCommand(0x0104);
}
public MsgBolusStartWithSpeed(double amount, int speed) {
this();
// HARDCODED LIMIT
amount = MainApp.getConfigBuilder().applyBolusConstraints(amount);
if (amount < 0) amount = 0d;
if (amount > HardLimits.maxBolus()) amount = HardLimits.maxBolus();
AddParamInt((int) (amount * 100));
AddParamByte((byte) speed);
if (Config.logDanaMessageDetail)
log.debug("Bolus start : " + amount + " speed: " + speed);
}
@Override
public void handleMessage(byte[] bytes) {
int result = intFromBuff(bytes, 0, 1);
if (result != 2) {
failed = true;
log.debug("Messsage response: " + result + " FAILED!!");
} else {
if (Config.logDanaMessageDetail)
log.debug("Messsage response: " + result);
}
}
}

View file

@ -40,6 +40,13 @@ public class MsgSettingMeal extends MessageBase {
log.debug("Is Config U/d: " + pump.isConfigUD);
}
if (pump.basalStep != 0.01d) {
Notification notification = new Notification(Notification.WRONGBASALSTEP, MainApp.sResources.getString(R.string.danar_setbasalstep001), Notification.URGENT);
MainApp.bus().post(new EventNewNotification(notification));
} else {
MainApp.bus().post(new EventDismissNotification(Notification.WRONGBASALSTEP));
}
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));

View file

@ -24,9 +24,10 @@ public class MsgStatusBasic extends MessageBase {
pump.reservoirRemainingUnits = intFromBuff(bytes, 7, 3) / 750d;
pump.bolusBlocked = intFromBuff(bytes, 10, 1) == 1;
pump.currentBasal = intFromBuff(bytes, 11, 2) / 100d;
pump.tempBasalPercent = intFromBuff(bytes, 13, 1);
pump.isExtendedInProgress = intFromBuff(bytes, 14, 1) == 1;
pump.isTempBasalInProgress = intFromBuff(bytes, 15, 1) == 1;
// removed. info taken from tempstatus message
//pump.tempBasalPercent = intFromBuff(bytes, 13, 1);
//pump.isExtendedInProgress = intFromBuff(bytes, 14, 1) == 1;
//pump.isTempBasalInProgress = intFromBuff(bytes, 15, 1) == 1;
pump.batteryRemaining = intFromBuff(bytes, 20, 1);
if (Config.logDanaMessageDetail) {
@ -37,9 +38,9 @@ public class MsgStatusBasic extends MessageBase {
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("Is temp basal running: " + pump.isTempBasalInProgress);
//log.debug("Current temp basal percent: " + pump.tempBasalPercent);
//log.debug("Is extended bolus running: " + pump.isExtendedInProgress);
//log.debug("Is temp basal running: " + pump.isTempBasalInProgress);
}
}
}

View file

@ -40,6 +40,7 @@ import info.nightscout.androidaps.plugins.PumpDanaR.SerialIOThread;
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase;
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgBolusProgress;
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgBolusStart;
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgBolusStartWithSpeed;
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgBolusStop;
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgCheckValue;
import info.nightscout.androidaps.plugins.PumpDanaR.comm.MsgHistoryAlarm;
@ -109,7 +110,7 @@ public class DanaRExecutionService extends Service {
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
log.debug("Device was disconnected " + device.getName());//Device was disconnected
if (mBTDevice != null && mBTDevice.getName() != null && mBTDevice.getName().equals(device.getName())) {
if (mSerialIOThread != null) {
mSerialIOThread.disconnect("BT disconnection broadcast");
@ -290,10 +291,13 @@ public class DanaRExecutionService extends Service {
}
}
mSerialIOThread.sendMessage(tempStatusMsg); // do this before statusBasic because here is temp duration
mSerialIOThread.sendMessage(exStatusMsg);
mSerialIOThread.sendMessage(statusMsg);
mSerialIOThread.sendMessage(statusBasicMsg);
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.gettingtempbasalstatus)));
mSerialIOThread.sendMessage(tempStatusMsg);
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.gettingextendedbolusstatus)));
mSerialIOThread.sendMessage(exStatusMsg);
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.gettingbolusstatus)));
if (!statusMsg.received) {
mSerialIOThread.sendMessage(statusMsg);
@ -319,6 +323,7 @@ public class DanaRExecutionService extends Service {
Date now = new Date();
if (danaRPump.lastSettingsRead.getTime() + 60 * 60 * 1000L < now.getTime() || !MainApp.getSpecificPlugin(DanaRPlugin.class).isInitialized()) {
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.gettingpumpsettings)));
mSerialIOThread.sendMessage(new MsgSettingShippingInfo());
mSerialIOThread.sendMessage(new MsgSettingActiveProfile());
mSerialIOThread.sendMessage(new MsgSettingMeal());
@ -329,6 +334,7 @@ public class DanaRExecutionService extends Service {
mSerialIOThread.sendMessage(new MsgSettingActiveProfile());
mSerialIOThread.sendMessage(new MsgSettingProfileRatios());
mSerialIOThread.sendMessage(new MsgSettingProfileRatiosAll());
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.gettingpumptime)));
mSerialIOThread.sendMessage(new MsgSettingPumpTime());
long timeDiff = (danaRPump.pumpTime.getTime() - System.currentTimeMillis()) / 1000L;
log.debug("Pump time difference: " + timeDiff + " seconds");
@ -404,7 +410,12 @@ public class DanaRExecutionService extends Service {
public boolean bolus(double amount, int carbs, Treatment t) {
bolusingTreatment = t;
MsgBolusStart start = new MsgBolusStart(amount);
int speed = SP.getInt(R.string.key_danars_bolusspeed, 0);
MessageBase start;
if (speed == 0)
start = new MsgBolusStart(amount);
else
start = new MsgBolusStartWithSpeed(amount, speed);
MsgBolusStop stop = new MsgBolusStop(amount, t);
connect("bolus");
@ -526,7 +537,7 @@ public class DanaRExecutionService extends Service {
connect("updateBasalsInPump");
if (!isConnected()) return false;
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.updatingbasalrates)));
double[] basal = buildDanaRProfileRecord(profile);
double[] basal = DanaRPump.buildDanaRProfileRecord(profile);
MsgSetBasalProfile msgSet = new MsgSetBasalProfile((byte) 0, basal);
mSerialIOThread.sendMessage(msgSet);
MsgSetActivateBasalProfile msgActivate = new MsgSetActivateBasalProfile((byte) 0);
@ -537,19 +548,6 @@ public class DanaRExecutionService extends Service {
return true;
}
private double[] buildDanaRProfileRecord(Profile nsProfile) {
double[] record = new double[24];
for (Integer hour = 0; hour < 24; hour++) {
//Some values get truncated to the next lower one.
// -> round them to two decimals and make sure we are a small delta larger (that will get truncated)
double value = Math.round(100d * nsProfile.getBasal((Integer) (hour * 60 * 60)))/100d + 0.00001;
if (Config.logDanaMessageDetail)
log.debug("NS basal value for " + hour + ":00 is " + value);
record[hour] = value;
}
return record;
}
private void waitMsec(long msecs) {
SystemClock.sleep(msecs);
}

View file

@ -61,15 +61,15 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, DanaRInterf
return DanaRFragment.class.getName();
}
static boolean fragmentPumpEnabled = false;
static boolean fragmentProfileEnabled = false;
static boolean fragmentPumpVisible = true;
private boolean fragmentPumpEnabled = false;
private boolean fragmentProfileEnabled = false;
private boolean fragmentPumpVisible = true;
public static DanaRKoreanExecutionService sExecutionService;
private static DanaRKoreanExecutionService sExecutionService;
private static DanaRPump pump = DanaRPump.getInstance();
private static boolean useExtendedBoluses = false;
private boolean useExtendedBoluses = false;
private static DanaRKoreanPlugin plugin = null;
@ -208,8 +208,8 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, DanaRInterf
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);
NSProfilePlugin.getPlugin().setFragmentEnabled(PluginBase.PROFILE, true);
NSProfilePlugin.getPlugin().setFragmentVisible(PluginBase.PROFILE, true);
}
}
@ -345,7 +345,7 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, DanaRInterf
// This is called from APS
@Override
public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, boolean force) {
public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, boolean enforceNew) {
// Recheck pump status if older than 30 min
if (pump.lastConnection.getTime() + 30 * 60 * 1000L < System.currentTimeMillis()) {
doConnect("setTempBasalAbsolute old data");
@ -405,7 +405,7 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, DanaRInterf
if (MainApp.getConfigBuilder().isInHistoryRealTempBasalInProgress()) {
// Correct basal already set ?
if (MainApp.getConfigBuilder().getRealTempBasalFromHistory(System.currentTimeMillis()).percentRate == percentRate) {
if (force) {
if (enforceNew) {
cancelTempBasal(true);
} else {
result.success = true;
@ -503,7 +503,8 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, DanaRInterf
}
if (percent > getPumpDescription().maxTempPercent)
percent = getPumpDescription().maxTempPercent;
if (pump.isTempBasalInProgress && pump.tempBasalPercent == percent) {
TemporaryBasal runningTB = MainApp.getConfigBuilder().getRealTempBasalFromHistory(System.currentTimeMillis());
if (runningTB != null && runningTB.percentRate == percent) {
result.enacted = false;
result.success = true;
result.isTempCancel = false;
@ -547,7 +548,8 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, DanaRInterf
insulin = Round.roundTo(insulin, getPumpDescription().extendedBolusStep * (1 + durationInHalfHours % 1));
PumpEnactResult result = new PumpEnactResult();
if (pump.isExtendedInProgress && Math.abs(pump.extendedBolusAmount - insulin) < getPumpDescription().extendedBolusStep) {
ExtendedBolus runningEB = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis());
if (runningEB != null && Math.abs(runningEB.insulin - insulin) < getPumpDescription().extendedBolusStep) {
result.enacted = false;
result.success = true;
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
@ -598,7 +600,8 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, DanaRInterf
public PumpEnactResult cancelRealTempBasal() {
PumpEnactResult result = new PumpEnactResult();
if (pump.isTempBasalInProgress) {
TemporaryBasal runningTB = MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis());
if (runningTB != null) {
sExecutionService.tempBasalStop();
result.enacted = true;
result.isTempCancel = true;
@ -622,7 +625,8 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, DanaRInterf
@Override
public PumpEnactResult cancelExtendedBolus() {
PumpEnactResult result = new PumpEnactResult();
if (pump.isExtendedInProgress) {
ExtendedBolus runningEB = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis());
if (runningEB != null) {
sExecutionService.extendedBolusStop();
result.enacted = true;
result.isTempCancel = true;
@ -642,7 +646,11 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, DanaRInterf
}
public static void doConnect(String from) {
if (sExecutionService != null) sExecutionService.connect(from);
if (sExecutionService != null) {
sExecutionService.connect(from);
pumpDescription.basalStep = pump.basalStep;
pumpDescription.bolusStep = pump.bolusStep;
}
}
public static boolean isConnected() {

View file

@ -105,7 +105,7 @@ public class DanaRKoreanExecutionService extends Service {
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
log.debug("Device was disconnected " + device.getName());//Device was disconnected
if (mBTDevice != null && mBTDevice.getName() != null && mBTDevice.getName().equals(device.getName())) {
if (mSerialIOThread != null) {
mSerialIOThread.disconnect("BT disconnection broadcast");
@ -286,11 +286,13 @@ public class DanaRKoreanExecutionService extends Service {
}
}
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);
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.gettingtempbasalstatus)));
mSerialIOThread.sendMessage(tempStatusMsg);
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.gettingextendedbolusstatus)));
mSerialIOThread.sendMessage(exStatusMsg);
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.gettingbolusstatus)));
// if (!statusMsg.received) {
// mSerialIOThread.sendMessage(statusMsg);
@ -316,6 +318,7 @@ public class DanaRKoreanExecutionService extends Service {
Date now = new Date();
if (danaRPump.lastSettingsRead.getTime() + 60 * 60 * 1000L < now.getTime() || !MainApp.getSpecificPlugin(DanaRKoreanPlugin.class).isInitialized()) {
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.gettingpumpsettings)));
mSerialIOThread.sendMessage(new MsgSettingShippingInfo());
mSerialIOThread.sendMessage(new MsgSettingMeal());
mSerialIOThread.sendMessage(new MsgSettingBasal_k());
@ -323,6 +326,8 @@ public class DanaRKoreanExecutionService extends Service {
mSerialIOThread.sendMessage(new MsgSettingMaxValues());
mSerialIOThread.sendMessage(new MsgSettingGlucose());
mSerialIOThread.sendMessage(new MsgSettingProfileRatios());
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.gettingpumptime)));
mSerialIOThread.sendMessage(new MsgSettingPumpTime());
long timeDiff = (danaRPump.pumpTime.getTime() - System.currentTimeMillis()) / 1000L;
log.debug("Pump time difference: " + timeDiff + " seconds");
if (Math.abs(timeDiff) > 10) {
@ -502,7 +507,7 @@ public class DanaRKoreanExecutionService extends Service {
connect("updateBasalsInPump");
if (!isConnected()) return false;
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.updatingbasalrates)));
double[] basal = buildDanaRProfileRecord(profile);
double[] basal = DanaRPump.buildDanaRProfileRecord(profile);
MsgSetSingleBasalProfile msgSet = new MsgSetSingleBasalProfile(basal);
mSerialIOThread.sendMessage(msgSet);
danaRPump.lastSettingsRead = new Date(0); // force read full settings
@ -511,17 +516,6 @@ public class DanaRKoreanExecutionService extends Service {
return true;
}
private double[] buildDanaRProfileRecord(Profile nsProfile) {
double[] record = new double[24];
for (Integer hour = 0; hour < 24; hour++) {
double value = Math.round(100d * nsProfile.getBasal((Integer) (hour * 60 * 60)))/100d + 0.00001;
if (Config.logDanaMessageDetail)
log.debug("NS basal value for " + hour + ":00 is " + value);
record[hour] = value;
}
return record;
}
private void waitMsec(long msecs) {
SystemClock.sleep(msecs);
}

View file

@ -0,0 +1,818 @@
package info.nightscout.androidaps.plugins.PumpDanaRS;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
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.data.DetailedBolusInfo;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.ProfileStore;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.ExtendedBolus;
import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.events.EventPumpStatusChanged;
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
import info.nightscout.androidaps.interfaces.DanaRInterface;
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.ConfigBuilder.DetailedBolusInfoStorage;
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.ProfileNS.NSProfilePlugin;
import info.nightscout.androidaps.plugins.PumpDanaR.DanaRFragment;
import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump;
import info.nightscout.androidaps.plugins.PumpDanaRS.comm.DanaRS_Packet;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.events.EventAppExit;
import info.nightscout.androidaps.plugins.PumpDanaRS.events.EventDanaRSDeviceChange;
import info.nightscout.androidaps.plugins.PumpDanaRS.services.DanaRSService;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.Round;
import info.nightscout.utils.SP;
/**
* Created by mike on 03.09.2017.
*/
public class DanaRSPlugin implements PluginBase, PumpInterface, DanaRInterface, ConstraintsInterface, ProfileInterface {
private static Logger log = LoggerFactory.getLogger(DanaRSPlugin.class);
@Override
public int getType() {
return PluginBase.PUMP;
}
@Override
public String getFragmentClass() {
return DanaRFragment.class.getName();
}
@Override
public String getName() {
return MainApp.instance().getString(R.string.danarspump);
}
@Override
public String getNameShort() {
String name = MainApp.sResources.getString(R.string.danarspump_shortname);
if (!name.trim().isEmpty()) {
//only if translation exists
return name;
}
// use long name as fallback
return getName();
}
@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 boolean hasFragment() {
return true;
}
@Override
public boolean showInList(int type) {
return type == PUMP;
}
@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;
}
static boolean fragmentPumpEnabled = false;
static boolean fragmentProfileEnabled = false;
static boolean fragmentPumpVisible = false;
public static DanaRSService danaRSService;
public static String mDeviceAddress = "";
public static String mDeviceName = "";
private static DanaRSPlugin plugin = null;
private static DanaRPump pump = DanaRPump.getInstance();
public static PumpDescription pumpDescription = new PumpDescription();
public static DanaRSPlugin getPlugin() {
if (plugin == null)
plugin = new DanaRSPlugin();
return plugin;
}
DanaRSPlugin() {
Context context = MainApp.instance().getApplicationContext();
Intent intent = new Intent(context, DanaRSService.class);
context.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
MainApp.bus().register(this);
onStatusEvent(new EventDanaRSDeviceChange()); // load device name
pumpDescription.isBolusCapable = true;
pumpDescription.bolusStep = 0.05d;
pumpDescription.isExtendedBolusCapable = true;
pumpDescription.extendedBolusStep = 0.05d;
pumpDescription.extendedBolusDurationStep = 30;
pumpDescription.extendedBolusMaxDuration = 8 * 60;
pumpDescription.isTempBasalCapable = true;
pumpDescription.tempBasalStyle = PumpDescription.PERCENT;
pumpDescription.maxTempPercent = 200;
pumpDescription.tempPercentStep = 10;
pumpDescription.tempDurationStep = 60;
pumpDescription.tempMaxDuration = 24 * 60;
pumpDescription.isSetBasalProfileCapable = true;
pumpDescription.basalStep = 0.01d;
pumpDescription.basalMinimumRate = 0.04d;
pumpDescription.isRefillingCapable = true;
}
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceDisconnected(ComponentName name) {
log.debug("Service is disconnected");
danaRSService = null;
}
public void onServiceConnected(ComponentName name, IBinder service) {
log.debug("Service is connected");
DanaRSService.LocalBinder mLocalBinder = (DanaRSService.LocalBinder) service;
danaRSService = mLocalBinder.getServiceInstance();
}
};
@SuppressWarnings("UnusedParameters")
@Subscribe
public void onStatusEvent(final EventAppExit e) {
MainApp.instance().getApplicationContext().unbindService(mConnection);
}
@Subscribe
public void onStatusEvent(final EventDanaRSDeviceChange e) {
mDeviceAddress = SP.getString(R.string.key_danars_address, "");
mDeviceName = SP.getString(R.string.key_danars_name, "");
}
public static void connectIfNotConnected(String from) {
if (!isConnected())
connect(from);
}
public static synchronized void connect(String from) {
log.debug("RS connect from: " + from);
if (danaRSService != null && !mDeviceAddress.equals("") && !mDeviceName.equals("")) {
final Object o = new Object();
danaRSService.connect(from, mDeviceAddress, o);
synchronized (o) {
try {
o.wait(20000);
} catch (InterruptedException e) {
log.error("InterruptedException " + e);
}
}
pumpDescription.basalStep = pump.basalStep;
pumpDescription.bolusStep = pump.bolusStep;
if (isConnected())
log.debug("RS connected: " + from);
else {
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.connectiontimedout)));
danaRSService.stopConnecting();
log.debug("RS connect failed from: " + from);
}
}
}
public static boolean isConnected() {
return danaRSService != null && danaRSService.isConnected();
}
public static boolean isConnecting() {
return danaRSService != null && danaRSService.isConnecting();
}
public static void disconnect(String from) {
if (danaRSService != null) danaRSService.disconnect(from);
}
public static void sendMessage(DanaRS_Packet message) {
if (danaRSService != null) danaRSService.sendMessage(message);
}
// DanaR interface
@Override
public boolean loadHistory(byte type) {
connectIfNotConnected("loadHistory");
return danaRSService.loadHistory(type);
}
// Constraints 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;
}
@Override
public Double applyBasalConstraints(Double absoluteRate) {
double origAbsoluteRate = absoluteRate;
if (pump != null) {
if (absoluteRate > pump.maxBasal) {
absoluteRate = pump.maxBasal;
if (Config.logConstraintsChanges && origAbsoluteRate != Constants.basalAbsoluteOnlyForCheckLimit)
log.debug("Limiting rate " + origAbsoluteRate + "U/h by pump constraint to " + absoluteRate + "U/h");
}
}
return absoluteRate;
}
@Override
public Integer applyBasalConstraints(Integer percentRate) {
Integer origPercentRate = percentRate;
if (percentRate < 0) percentRate = 0;
if (percentRate > getPumpDescription().maxTempPercent)
percentRate = getPumpDescription().maxTempPercent;
if (!Objects.equals(percentRate, origPercentRate) && Config.logConstraintsChanges && !Objects.equals(origPercentRate, Constants.basalPercentOnlyForCheckLimit))
log.debug("Limiting percent rate " + origPercentRate + "% to " + percentRate + "%");
return percentRate;
}
@Override
public Double applyBolusConstraints(Double insulin) {
double origInsulin = insulin;
if (pump != null) {
if (insulin > pump.maxBolus) {
insulin = pump.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;
}
// Profile interface
@Nullable
@Override
public ProfileStore getProfile() {
if (pump.lastSettingsRead.getTime() == 0)
return null; // no info now
return pump.createConvertedProfile();
}
@Override
public String getUnits() {
return pump.getUnits();
}
@Override
public String getProfileName() {
return pump.createConvertedProfileName();
}
// Pump interface
@Override
public boolean isInitialized() {
return pump.lastConnection.getTime() > 0;
}
@Override
public boolean isSuspended() {
return pump.pumpSuspended;
}
@Override
public boolean isBusy() {
if (danaRSService == null) return false;
return danaRSService.isConnected() || danaRSService.isConnecting();
}
@Override
public int setNewBasalProfile(Profile profile) {
if (danaRSService == 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));
}
connectIfNotConnected("updateBasalsInPump");
if (!danaRSService.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(Profile profile) {
if (!isInitialized())
return true; // TODO: not sure what's better. so far TRUE to prevent too many SMS
if (pump.pumpProfiles == null)
return true; // TODO: not sure what's better. so far TRUE to prevent too many SMS
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((Integer) (h * basalIncrement));
if (profileValue == null) return true;
if (Math.abs(pumpValue - profileValue) > getPumpDescription().basalStep) {
log.debug("Diff found. Hour: " + h + " Pump: " + pumpValue + " Profile: " + profileValue);
return false;
}
}
return true;
}
@Override
public Date lastDataTime() {
return pump.lastConnection;
}
@Override
public void refreshDataFromPump(String reason) {
log.debug("Refreshing data from pump");
if (!isConnected() && !isConnecting()) {
connect(reason);
} else
log.debug("Already connecting ...");
}
@Override
public double getBaseBasalRate() {
return pump.currentBasal;
}
@Override
public PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo) {
ConfigBuilderPlugin configBuilderPlugin = MainApp.getConfigBuilder();
detailedBolusInfo.insulin = configBuilderPlugin.applyBolusConstraints(detailedBolusInfo.insulin);
if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) {
DetailedBolusInfoStorage.add(detailedBolusInfo); // will be picked up on reading history
int preferencesSpeed = SP.getInt(R.string.key_danars_bolusspeed, 0);
int speed = 12;
switch (preferencesSpeed) {
case 0:
speed = 12;
break;
case 1:
speed = 30;
break;
case 2:
speed = 60;
break;
}
// v2 stores end time for bolus, we need to adjust time
// default delivery speed is 12 U/min
detailedBolusInfo.date += detailedBolusInfo.insulin / speed * 60d * 1000;
// clean carbs to prevent counting them as twice because they will picked up as another record
// I don't think it's necessary to copy DetailedBolusInfo right now for carbs records
double carbs = detailedBolusInfo.carbs;
detailedBolusInfo.carbs = 0;
int carbTime = detailedBolusInfo.carbTime;
detailedBolusInfo.carbTime = 0;
Treatment t = new Treatment();
boolean connectionOK = false;
connectIfNotConnected("bolus");
if (detailedBolusInfo.insulin > 0 || carbs > 0)
connectionOK = danaRSService.bolus(detailedBolusInfo.insulin, (int) carbs, System.currentTimeMillis() + carbTime * 60 * 1000 + 1000, t); // +1000 to make the record different
PumpEnactResult result = new PumpEnactResult();
result.success = connectionOK;
result.bolusDelivered = t.insulin;
result.carbsDelivered = detailedBolusInfo.carbs;
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
if (Config.logPumpActions)
log.debug("deliverTreatment: OK. Asked: " + detailedBolusInfo.insulin + " Delivered: " + result.bolusDelivered);
// remove carbs because it's get from history seprately
return result;
} else {
PumpEnactResult result = new PumpEnactResult();
result.success = false;
result.bolusDelivered = 0d;
result.carbsDelivered = 0d;
result.comment = MainApp.instance().getString(R.string.danar_invalidinput);
log.error("deliverTreatment: Invalid input");
return result;
}
}
@Override
public void stopBolusDelivering() {
if (danaRSService == null) {
log.error("stopBolusDelivering sExecutionService is null");
return;
}
danaRSService.bolusStop();
}
// This is called from APS
@Override
public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, boolean enforceNew) {
// Recheck pump status if older than 30 min
if (pump.lastConnection.getTime() + 30 * 60 * 1000L < System.currentTimeMillis()) {
connect("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();
if (doTempOff) {
// If temp in progress
if (MainApp.getConfigBuilder().isTempBasalInProgress()) {
if (Config.logPumpActions)
log.debug("setTempBasalAbsolute: Stopping temp basal (doTempOff)");
return cancelTempBasal(false);
}
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 > 500) // Special high temp 500/15min
percentRate = 500;
// Check if some temp is already in progress
if (MainApp.getConfigBuilder().isTempBasalInProgress()) {
// Correct basal already set ?
if (MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis()).percentRate == percentRate) {
if (!enforceNew) {
result.success = true;
result.percent = percentRate;
result.absolute = MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory();
result.enacted = false;
result.duration = ((Double) MainApp.getConfigBuilder().getTempBasalRemainingMinutesFromHistory()).intValue();
result.isPercent = true;
result.isTempCancel = false;
if (Config.logPumpActions)
log.debug("setTempBasalAbsolute: Correct temp basal already set (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)");
// use special APS temp basal call ... 100+/15min .... 100-/30min
result = setHighTempBasalPercent(percentRate);
if (!result.success) {
log.error("setTempBasalAbsolute: Failed to set hightemp basal");
return result;
}
if (Config.logPumpActions)
log.debug("setTempBasalAbsolute: hightemp basal set ok");
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 > getPumpDescription().maxTempPercent)
percent = getPumpDescription().maxTempPercent;
TemporaryBasal runningTB = MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis());
if (runningTB != null && runningTB.percentRate == percent) {
result.enacted = false;
result.success = true;
result.isTempCancel = false;
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
result.duration = pump.tempBasalRemainingMin;
result.percent = pump.tempBasalPercent;
result.absolute = MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory();
result.isPercent = true;
if (Config.logPumpActions)
log.debug("setTempBasalPercent: Correct value already set");
return result;
}
int durationInHours = Math.max(durationInMinutes / 60, 1);
connectIfNotConnected("tempbasal");
boolean connectionOK = danaRSService.tempBasal(percent, durationInHours);
if (connectionOK && pump.isTempBasalInProgress && pump.tempBasalPercent == percent) {
result.enacted = true;
result.success = true;
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
result.isTempCancel = false;
result.duration = pump.tempBasalRemainingMin;
result.percent = pump.tempBasalPercent;
result.absolute = MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory();
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.tempbasaldeliveryerror);
log.error("setTempBasalPercent: Failed to set temp basal");
return result;
}
public PumpEnactResult setHighTempBasalPercent(Integer percent) {
PumpEnactResult result = new PumpEnactResult();
connectIfNotConnected("hightempbasal");
boolean connectionOK = danaRSService.highTempBasal(percent);
if (connectionOK && pump.isTempBasalInProgress && pump.tempBasalPercent == percent) {
result.enacted = true;
result.success = true;
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
result.isTempCancel = false;
result.duration = pump.tempBasalRemainingMin;
result.percent = pump.tempBasalPercent;
result.isPercent = true;
if (Config.logPumpActions)
log.debug("setHighTempBasalPercent: OK");
return result;
}
result.enacted = false;
result.success = false;
result.comment = MainApp.instance().getString(R.string.danar_valuenotsetproperly);
log.error("setHighTempBasalPercent: 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
int durationInHalfHours = Math.max(durationInMinutes / 30, 1);
insulin = Round.roundTo(insulin, getPumpDescription().extendedBolusStep * (1 + durationInHalfHours % 1));
PumpEnactResult result = new PumpEnactResult();
ExtendedBolus runningEB = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis());
if (runningEB != null && Math.abs(runningEB.insulin - insulin) < getPumpDescription().extendedBolusStep) {
result.enacted = false;
result.success = true;
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
result.duration = pump.extendedBolusRemainingMinutes;
result.absolute = pump.extendedBolusAbsoluteRate;
result.isPercent = false;
result.isTempCancel = false;
if (Config.logPumpActions)
log.debug("setExtendedBolus: Correct extended bolus already set. Current: " + pump.extendedBolusAmount + " Asked: " + insulin);
return result;
}
connectIfNotConnected("extendedBolus");
boolean connectionOK = danaRSService.extendedBolus(insulin, durationInHalfHours);
if (connectionOK && pump.isExtendedInProgress && Math.abs(pump.extendedBolusAmount - insulin) < getPumpDescription().extendedBolusStep) {
result.enacted = true;
result.success = true;
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
result.isTempCancel = false;
result.duration = pump.extendedBolusRemainingMinutes;
result.absolute = pump.extendedBolusAbsoluteRate;
result.bolusDelivered = pump.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(boolean force) {
PumpEnactResult result = new PumpEnactResult();
TemporaryBasal runningTB = MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis());
if (runningTB != null) {
connectIfNotConnected("tempBasalStop");
danaRSService.tempBasalStop();
result.enacted = true;
result.isTempCancel = true;
}
if (!pump.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();
ExtendedBolus runningEB = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis());
if (runningEB != null) {
connectIfNotConnected("extendedBolusStop");
danaRSService.extendedBolusStop();
result.enacted = true;
result.isTempCancel = true;
}
if (!pump.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;
}
}
@Override
public JSONObject getJSONStatus() {
if (pump.lastConnection.getTime() + 5 * 60 * 1000L < System.currentTimeMillis()) {
return null;
}
JSONObject pumpjson = new JSONObject();
JSONObject battery = new JSONObject();
JSONObject status = new JSONObject();
JSONObject extended = new JSONObject();
try {
battery.put("percent", pump.batteryRemaining);
status.put("status", pump.pumpSuspended ? "suspended" : "normal");
status.put("timestamp", DateUtil.toISOString(pump.lastConnection));
extended.put("Version", BuildConfig.VERSION_NAME + "-" + BuildConfig.BUILDVERSION);
extended.put("PumpIOB", pump.iob);
if (pump.lastBolusTime.getTime() != 0) {
extended.put("LastBolus", pump.lastBolusTime.toLocaleString());
extended.put("LastBolusAmount", pump.lastBolusAmount);
}
TemporaryBasal tb = MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis());
if (tb != null) {
extended.put("TempBasalAbsoluteRate", tb.tempBasalConvertedToAbsolute(System.currentTimeMillis()));
extended.put("TempBasalStart", DateUtil.dateAndTimeString(tb.date));
extended.put("TempBasalRemaining", tb.getPlannedRemainingMinutes());
}
ExtendedBolus eb = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis());
if (eb != null) {
extended.put("ExtendedBolusAbsoluteRate", eb.absoluteRate());
extended.put("ExtendedBolusStart", DateUtil.dateAndTimeString(eb.date));
extended.put("ExtendedBolusRemaining", eb.getPlannedRemainingMinutes());
}
extended.put("BaseBasalRate", getBaseBasalRate());
try {
extended.put("ActiveProfile", MainApp.getConfigBuilder().getProfileName());
} catch (Exception e) {
}
pumpjson.put("battery", battery);
pumpjson.put("status", status);
pumpjson.put("extended", extended);
pumpjson.put("reservoir", (int) pump.reservoirRemainingUnits);
pumpjson.put("clock", DateUtil.toISOString(new Date()));
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
return pumpjson;
}
@Override
public String deviceID() {
return pump.serialNumber;
}
@Override
public PumpDescription getPumpDescription() {
return pumpDescription;
}
@Override
public String shortStatus(boolean veryShort) {
return null;
}
@Override
public boolean isFakingTempsByExtendedBoluses() {
return false;
}
}

View file

@ -0,0 +1,232 @@
package info.nightscout.androidaps.plugins.PumpDanaRS.activities;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.plugins.PumpDanaRS.events.EventDanaRSDeviceChange;
import info.nightscout.utils.SP;
public class BLEScanActivity extends AppCompatActivity {
private static Logger log = LoggerFactory.getLogger(BLEScanActivity.class);
private Context mContext = null;
private ListView listView = null;
private ListAdapter mListAdapter = null;
private ArrayList<BluetoothDeviceItem> mDevices = new ArrayList<>();
;
private BluetoothAdapter mBluetoothAdapter = null;
private BluetoothLeScanner mBluetoothLeScanner = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.danars_blescanner_activity);
mListAdapter = new ListAdapter();
listView = (ListView) findViewById(R.id.danars_blescanner_listview);
listView.setEmptyView(findViewById(R.id.danars_blescanner_nodevice));
listView.setAdapter(mListAdapter);
initView();
}
private void initView() {
mContext = getApplicationContext();
BluetoothManager bluetoothManager = (BluetoothManager) mContext.getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
// MIKE: test mBluetoothLeScanner for null (bt disabled)
mListAdapter.notifyDataSetChanged();
}
@Override
protected void onResume() {
super.onResume();
startScan();
}
@Override
protected void onPause() {
super.onPause();
stopScan();
}
private void startScan() {
mBluetoothLeScanner.startScan(mBleScanCallback);
}
private void stopScan() {
mBluetoothLeScanner.stopScan(mBleScanCallback);
}
private void addBleDevice(BluetoothDevice device) {
if (device == null || device.getName() == null || device.getName().equals("")) {
return;
}
BluetoothDeviceItem item = new BluetoothDeviceItem(device);
if (!isSNCheck(device.getName()) || mDevices.contains(item)) {
return;
}
mDevices.add(item);
new Handler().post(new Runnable() {
public void run() {
mListAdapter.notifyDataSetChanged();
}
});
}
private ScanCallback mBleScanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
addBleDevice(result.getDevice());
}
};
class ListAdapter extends BaseAdapter {
@Override
public int getCount() {
return mDevices.size();
}
@Override
public BluetoothDeviceItem getItem(int i) {
return mDevices.get(i);
}
@Override
public long getItemId(int i) {
return 0;
}
@Override
public View getView(int i, View convertView, ViewGroup parent) {
View v = convertView;
ViewHolder holder;
if (v == null) {
v = View.inflate(mContext, R.layout.danars_blescanner_item, null);
holder = new ViewHolder(v);
v.setTag(holder);
} else {
holder = (ViewHolder) v.getTag();
}
BluetoothDeviceItem item = getItem(i);
holder.setData(i, item);
return v;
}
private class ViewHolder implements View.OnClickListener {
private BluetoothDeviceItem item = null;
private TextView mName = null;
private TextView mAddress = null;
public ViewHolder(View v) {
mName = (TextView) v.findViewById(R.id.ble_name);
mAddress = (TextView) v.findViewById(R.id.ble_address);
v.setOnClickListener(ViewHolder.this);
}
@Override
public void onClick(View v) {
SP.putString(R.string.key_danars_address, item.device.getAddress());
SP.putString(R.string.key_danars_name, mName.getText().toString());
MainApp.bus().post(new EventDanaRSDeviceChange());
finish();
}
public void setData(int pos, BluetoothDeviceItem data) {
if (data != null) {
try {
String tTitle = data.device.getName();
if (tTitle == null || tTitle.equals("")) {
tTitle = "(unknown)";
} else if (tTitle.length() > 10) {
tTitle = tTitle.substring(0, 10);
}
mName.setText(tTitle);
mAddress.setText(data.device.getAddress());
item = data;
} catch (Exception e) {
}
}
}
}
}
//
private class BluetoothDeviceItem {
private BluetoothDevice device;
public BluetoothDeviceItem(BluetoothDevice device) {
super();
this.device = device;
}
@Override
public boolean equals(Object o) {
if (device == null || o == null || !(o instanceof BluetoothDeviceItem)) {
return false;
}
BluetoothDeviceItem checkItem = (BluetoothDeviceItem) o;
if (checkItem.device == null) {
return false;
}
return stringEquals(device.getAddress(), checkItem.device.getAddress());
}
public boolean stringEquals(String arg1, String arg2) {
try {
return arg1.equals(arg2);
} catch (Exception e) {
return false;
}
}
}
public static boolean isSNCheck(String sn) {
String regex = "^([a-zA-Z]{3})([0-9]{5})([a-zA-Z]{2})$";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(sn);
return m.matches();
}
}

View file

@ -0,0 +1,15 @@
package info.nightscout.androidaps.plugins.PumpDanaRS.activities;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class PairingHelperActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
PairingProgressDialog bolusProgressDialog = new PairingProgressDialog();
bolusProgressDialog.setHelperActivity(this);
bolusProgressDialog.show(this.getSupportFragmentManager(), "PairingProgress");
}
}

View file

@ -0,0 +1,148 @@
package info.nightscout.androidaps.plugins.PumpDanaRS.activities;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.support.v4.app.DialogFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.squareup.otto.Subscribe;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.plugins.PumpDanaRS.events.EventDanaRSPairingSuccess;
public class PairingProgressDialog extends DialogFragment implements View.OnClickListener {
TextView statusView;
ProgressBar progressBar;
Button button;
PairingHelperActivity helperActivity;
static int secondsPassed = 0;
public static boolean pairingEnded = false;
public static boolean running = true;
private static Handler sHandler;
private static HandlerThread sHandlerThread;
public PairingProgressDialog() {
super();
// Required empty public constructor
if (sHandlerThread == null) {
sHandlerThread = new HandlerThread(PairingProgressDialog.class.getSimpleName());
sHandlerThread.start();
sHandler = new Handler(sHandlerThread.getLooper());
}
secondsPassed = 0;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.danars_pairingprogressdialog, container, false);
getDialog().setTitle(MainApp.sResources.getString(R.string.pairing));
statusView = (TextView) view.findViewById(R.id.danars_paringprogress_status);
progressBar = (ProgressBar) view.findViewById(R.id.danars_paringprogress_progressbar);
button = (Button) view.findViewById(R.id.ok);
progressBar.setMax(100);
progressBar.setProgress(0);
statusView.setText(MainApp.sResources.getString(R.string.waitingforpairing));
button.setVisibility(View.GONE);
button.setOnClickListener(this);
setCancelable(false);
sHandler.post(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 20; i++) {
if (pairingEnded) {
Activity activity = getActivity();
if (activity != null) {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
progressBar.setProgress(100);
statusView.setText(R.string.pairingok);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
dismiss();
}
});
} else
dismiss();
return;
}
progressBar.setProgress(i * 5);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
Activity activity = getActivity();
if (activity != null) {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
progressBar.setProgress(100);
statusView.setText(R.string.pairingtimedout);
button.setVisibility(View.VISIBLE);
}
});
}
}
});
return view;
}
@Override
public void onResume() {
super.onResume();
MainApp.bus().register(this);
running = true;
if (pairingEnded) dismiss();
}
@Override
public void dismiss() {
super.dismiss();
if (helperActivity != null) {
helperActivity.finish();
}
}
@Override
public void onPause() {
super.onPause();
MainApp.bus().unregister(this);
running = false;
}
@Subscribe
public void onStatusEvent(final EventDanaRSPairingSuccess ev) {
pairingEnded = true;
}
public void setHelperActivity(PairingHelperActivity activity) {
this.helperActivity = activity;
}
@Override
public void onClick(View v) {
running = false;
dismiss();
}
}

View file

@ -0,0 +1,108 @@
package info.nightscout.androidaps.plugins.PumpDanaRS.comm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import info.nightscout.androidaps.Config;
/**
* Created by mike on 28.05.2016.
*/
public class DanaRSMessageHashTable {
private static Logger log = LoggerFactory.getLogger(DanaRSMessageHashTable.class);
public static HashMap<Integer, DanaRS_Packet> messages = null;
static {
if (messages == null) {
boolean savedState = Config.logDanaMessageDetail;
Config.logDanaMessageDetail = false;
messages = new HashMap<>();
put(new DanaRS_Packet_Basal_Set_Cancel_Temporary_Basal());
put(new DanaRS_Packet_Basal_Get_Basal_Rate());
put(new DanaRS_Packet_Basal_Get_Profile_Basal_Rate());
put(new DanaRS_Packet_Basal_Get_Profile_Number());
put(new DanaRS_Packet_Basal_Set_Basal_Rate());
put(new DanaRS_Packet_Basal_Set_Profile_Basal_Rate());
put(new DanaRS_Packet_Basal_Set_Profile_Number());
put(new DanaRS_Packet_Basal_Set_Suspend_Off());
put(new DanaRS_Packet_Basal_Set_Suspend_On());
put(new DanaRS_Packet_Basal_Set_Temporary_Basal());
put(new DanaRS_Packet_Basal_Get_Temporary_Basal_State());
put(new DanaRS_Packet_Bolus_Get_Bolus_Option());
put(new DanaRS_Packet_Bolus_Get_Initial_Bolus());
put(new DanaRS_Packet_Bolus_Get_Calculation_Information());
put(new DanaRS_Packet_Bolus_Get_Carbohydrate_Calculation_Information());
put(new DanaRS_Packet_Bolus_Get_CIR_CF_Array());
put(new DanaRS_Packet_Bolus_Get_Dual_Bolus());
put(new DanaRS_Packet_Bolus_Get_Extended_Bolus());
put(new DanaRS_Packet_Bolus_Get_Extended_Bolus_State());
put(new DanaRS_Packet_Bolus_Get_Extended_Menu_Option_State());
put(new DanaRS_Packet_Bolus_Get_Step_Bolus_Information());
put(new DanaRS_Packet_Bolus_Set_Bolus_Option());
put(new DanaRS_Packet_Bolus_Set_Initial_Bolus());
put(new DanaRS_Packet_Bolus_Set_CIR_CF_Array());
put(new DanaRS_Packet_Bolus_Set_Dual_Bolus());
put(new DanaRS_Packet_Bolus_Set_Extended_Bolus());
put(new DanaRS_Packet_Bolus_Set_Extended_Bolus_Cancel());
put(new DanaRS_Packet_Bolus_Set_Step_Bolus_Start());
put(new DanaRS_Packet_Bolus_Set_Step_Bolus_Stop());
put(new DanaRS_Packet_Etc_Keep_Connection());
put(new DanaRS_Packet_Etc_Set_History_Save());
put(new DanaRS_Packet_General_Delivery_Status());
put(new DanaRS_Packet_General_Get_Password());
put(new DanaRS_Packet_General_Initial_Screen_Information());
put(new DanaRS_Packet_Notify_Alarm());
put(new DanaRS_Packet_Notify_Delivery_Complete());
put(new DanaRS_Packet_Notify_Delivery_Rate_Display());
put(new DanaRS_Packet_Notify_Missed_Bolus_Alarm());
put(new DanaRS_Packet_Option_Get_Pump_Time());
put(new DanaRS_Packet_Option_Get_User_Option());
put(new DanaRS_Packet_Option_Set_Pump_Time());
put(new DanaRS_Packet_Option_Set_User_Option());
//put(new DanaRS_Packet_History_());
put(new DanaRS_Packet_History_Alarm());
put(new DanaRS_Packet_History_All_History());
put(new DanaRS_Packet_History_Basal());
put(new DanaRS_Packet_History_Blood_Glucose());
put(new DanaRS_Packet_History_Bolus());
put(new DanaRS_Packet_Review_Bolus_Avg());
put(new DanaRS_Packet_History_Carbohydrate());
put(new DanaRS_Packet_History_Daily());
put(new DanaRS_Packet_General_Get_More_Information());
put(new DanaRS_Packet_General_Get_Pump_Check());
put(new DanaRS_Packet_General_Get_Shipping_Information());
put(new DanaRS_Packet_General_Get_Today_Delivery_Total());
put(new DanaRS_Packet_General_Get_User_Time_Change_Flag());
put(new DanaRS_Packet_History_Prime());
put(new DanaRS_Packet_History_Refill());
put(new DanaRS_Packet_General_Set_History_Upload_Mode());
put(new DanaRS_Packet_General_Set_User_Time_Change_Flag_Clear());
put(new DanaRS_Packet_History_Suspend());
put(new DanaRS_Packet_History_Temporary());
// APS
put(new DanaRS_Packet_APS_Basal_Set_Temporary_Basal());
put(new DanaRS_Packet_APS_History_Events());
put(new DanaRS_Packet_APS_Set_Event_History());
Config.logDanaMessageDetail = savedState;
}
}
public static void put(DanaRS_Packet message) {
int command = message.getCommand();
messages.put(command, message);
}
public static DanaRS_Packet findMessage(Integer command) {
if (messages.containsKey(command)) {
return messages.get(command);
} else {
return new DanaRS_Packet();
}
}
}

View file

@ -0,0 +1,207 @@
package info.nightscout.androidaps.plugins.PumpDanaRS.comm;
import android.annotation.TargetApi;
import android.os.Build;
import com.cozmo.danar.util.BleCommandUtil;
import java.nio.charset.StandardCharsets;
import java.util.Date;
public class DanaRS_Packet {
protected static final int TYPE_START = 0;
protected static final int OPCODE_START = 1;
protected static final int DATA_START = 2;
private boolean received;
protected boolean failed;
protected int type = BleCommandUtil.DANAR_PACKET__TYPE_RESPONSE; // most of the messages, should be changed for others
protected int opCode;
public DanaRS_Packet() {
received = false;
failed = false;
}
public void setReceived() {
received = true;
}
public boolean isReceived() {
return received;
}
public int getType() {
return type;
}
public int getOpCode() {
return opCode;
}
public int getCommand() {
return ((type & 0xFF) << 8) + (opCode & 0xFF);
}
public byte[] getRequestParams() {
return null;
}
;
// STATIC FUNCTIONS
public static int getCommand(byte[] data) {
int type = byteArrayToInt(getBytes(data, TYPE_START, 1));
int opCode = byteArrayToInt(getBytes(data, OPCODE_START, 1));
return ((type & 0xFF) << 8) + (opCode & 0xFF);
}
public void handleMessage(byte[] data) {
}
public String getFriendlyName() {
return "UNKNOWN_PACKET";
}
protected static byte[] getBytes(byte[] data, int srcStart, int srcLength) {
try {
byte[] ret = new byte[srcLength];
System.arraycopy(data, srcStart, ret, 0, srcLength);
return ret;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
protected static int byteArrayToInt(byte[] b) {
int ret;
switch (b.length) {
case 1:
ret = b[0] & 0x000000FF;
break;
case 2:
ret = ((b[1] & 0x000000FF) << 8) + (b[0] & 0x000000FF);
break;
case 3:
ret = ((b[2] & 0x000000FF) << 16) + ((b[1] & 0x000000FF) << 8) + (b[0] & 0x000000FF);
break;
case 4:
ret = ((b[3] & 0x000000FF) << 24) + ((b[2] & 0x000000FF) << 16) + ((b[1] & 0x000000FF) << 8) + (b[0] & 0x000000FF);
break;
default:
ret = -1;
break;
}
return ret;
}
public static Date dateTimeSecFromBuff(byte[] buff, int offset) {
Date date =
new Date(
100 + intFromBuff(buff, offset, 1),
intFromBuff(buff, offset + 1, 1) - 1,
intFromBuff(buff, offset + 2, 1),
intFromBuff(buff, offset + 3, 1),
intFromBuff(buff, offset + 4, 1),
intFromBuff(buff, offset + 5, 1)
);
return date;
}
protected static int intFromBuff(byte[] b, int srcStart, int srcLength) {
int ret;
switch (srcLength) {
case 1:
ret = b[DATA_START + srcStart + 0] & 0x000000FF;
break;
case 2:
ret = ((b[DATA_START + srcStart + 1] & 0x000000FF) << 8) + (b[DATA_START + srcStart + 0] & 0x000000FF);
break;
case 3:
ret = ((b[DATA_START + srcStart + 2] & 0x000000FF) << 16) + ((b[DATA_START + srcStart + 1] & 0x000000FF) << 8) + (b[DATA_START + srcStart + 0] & 0x000000FF);
break;
case 4:
ret = ((b[DATA_START + srcStart + 3] & 0x000000FF) << 24) + ((b[DATA_START + srcStart + 2] & 0x000000FF) << 16) + ((b[DATA_START + srcStart + 1] & 0x000000FF) << 8) + (b[DATA_START + srcStart + 0] & 0x000000FF);
break;
default:
ret = -1;
break;
}
return ret;
}
@TargetApi(Build.VERSION_CODES.KITKAT)
public static String stringFromBuff(byte[] buff, int offset, int length) {
byte[] strbuff = new byte[length];
System.arraycopy(buff, offset, strbuff, 0, length);
return new String(strbuff, StandardCharsets.UTF_8);
}
public static Date dateFromBuff(byte[] buff, int offset) {
Date date =
new Date(
100 + byteArrayToInt(getBytes(buff, offset, 1)),
byteArrayToInt(getBytes(buff, offset + 1, 1)) - 1,
byteArrayToInt(getBytes(buff, offset + 2, 1))
);
return date;
}
@TargetApi(Build.VERSION_CODES.KITKAT)
public static String asciiStringFromBuff(byte[] buff, int offset, int length) {
byte[] strbuff = new byte[length];
System.arraycopy(buff, offset, strbuff, 0, length);
for (int pos = 0; pos < length; pos++)
strbuff[pos] += 65; // "A"
return new String(strbuff, StandardCharsets.UTF_8);
}
public static String toHexString(byte[] buff) {
if (buff == null)
return "";
StringBuffer sb = new StringBuffer();
int count = 0;
for (byte element : buff) {
sb.append(String.format("%02X ", element));
if (++count % 4 == 0) sb.append(" ");
}
return sb.toString();
}
final private static char[] hexArray = "0123456789ABCDEF".toCharArray();
public static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
public static byte[] hexToBytes(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i + 1), 16));
}
return data;
}
public static int ByteToInt(byte b) {
return b & 0x000000FF;
}
}

View file

@ -0,0 +1,67 @@
package info.nightscout.androidaps.plugins.PumpDanaRS.comm;
import com.cozmo.danar.util.BleCommandUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.Config;
public class DanaRS_Packet_APS_Basal_Set_Temporary_Basal extends DanaRS_Packet {
private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_APS_Basal_Set_Temporary_Basal.class);
private int temporaryBasalRatio;
private int temporaryBasalDuration;
public int error;
public DanaRS_Packet_APS_Basal_Set_Temporary_Basal() {
super();
opCode = BleCommandUtil.DANAR_PACKET__OPCODE_BASAL__APS_SET_TEMPORARY_BASAL;
}
public DanaRS_Packet_APS_Basal_Set_Temporary_Basal(int percent) {
this();
//HARDCODED LIMITS
if (percent < 0) percent = 0;
if (percent > 500) percent = 500;
temporaryBasalRatio = percent;
if (percent < 100) {
temporaryBasalDuration = 160;
if (Config.logDanaMessageDetail)
log.debug("APS Temp basal start percent: " + percent + " duration 30 min");
} else {
temporaryBasalDuration = 150;
if (Config.logDanaMessageDetail)
log.debug("APS Temp basal start percent: " + percent + " duration 15 min");
}
}
@Override
public byte[] getRequestParams() {
byte[] request = new byte[3];
request[0] = (byte) (temporaryBasalRatio & 0xff);
request[1] = (byte) ((temporaryBasalRatio >>> 8) & 0xff);
request[2] = (byte) (temporaryBasalDuration & 0xff);
return request;
}
@Override
public void handleMessage(byte[] data) {
int result = byteArrayToInt(getBytes(data, DATA_START, 1));
if (result != 1) {
failed = true;
log.debug("Set APS temp basal start result: " + result + " FAILED!!!");
} else {
if (Config.logDanaMessageDetail)
log.debug("Set APS temp basal start result: " + result);
}
}
@Override
public String getFriendlyName() {
return "BASAL__APS_SET_TEMPORARY_BASAL";
}
}

View file

@ -0,0 +1,190 @@
package info.nightscout.androidaps.plugins.PumpDanaRS.comm;
import com.cozmo.danar.util.BleCommandUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.data.DetailedBolusInfo;
import info.nightscout.androidaps.db.DanaRHistoryRecord;
import info.nightscout.androidaps.db.ExtendedBolus;
import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.plugins.ConfigBuilder.DetailedBolusInfoStorage;
import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump;
import info.nightscout.androidaps.plugins.PumpDanaR.comm.RecordTypes;
import info.nightscout.androidaps.plugins.PumpDanaR.events.EventDanaRSyncStatus;
import info.nightscout.utils.DateUtil;
public class DanaRS_Packet_APS_History_Events extends DanaRS_Packet {
private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_APS_History_Events.class);
private int year = 0;
private int month = 0;
private int day = 0;
private int hour = 0;
private int min = 0;
private int sec = 0;
public boolean done;
public int totalCount;
public static long lastEventTimeLoaded = 0;
public DanaRS_Packet_APS_History_Events() {
super();
opCode = BleCommandUtil.DANAR_PACKET__OPCODE__APS_HISTORY_EVENTS;
done = false;
totalCount = 0;
}
public DanaRS_Packet_APS_History_Events(long from) {
this();
GregorianCalendar cal = new GregorianCalendar();
if (from != 0)
cal.setTimeInMillis(from);
else
cal.set(2000, 0, 1, 0, 0, 0);
year = cal.get(Calendar.YEAR) - 1900 - 100;
month = cal.get(Calendar.MONTH) + 1;
day = cal.get(Calendar.DAY_OF_MONTH);
hour = cal.get(Calendar.HOUR_OF_DAY);
min = cal.get(Calendar.MINUTE);
sec = cal.get(Calendar.SECOND);
log.debug("Loading event history from: " + new Date(cal.getTimeInMillis()).toLocaleString());
}
@Override
public byte[] getRequestParams() {
byte[] request = new byte[6];
request[0] = (byte) (year & 0xff);
request[1] = (byte) (month & 0xff);
request[2] = (byte) (day & 0xff);
request[3] = (byte) (hour & 0xff);
request[4] = (byte) (min & 0xff);
request[5] = (byte) (sec & 0xff);
return request;
}
@Override
public void handleMessage(byte[] data) {
byte recordCode = (byte) intFromBuff(data, 0, 1);
// Last record
if (recordCode == (byte) 0xFF) {
done = true;
return;
}
Date datetime = dateTimeSecFromBuff(data, 1); // 6 bytes
int param1 = ((intFromBuff(data, 7, 1) << 8) & 0xFF00) + (intFromBuff(data, 8, 1) & 0xFF);
int param2 = ((intFromBuff(data, 9, 1) << 8) & 0xFF00) + (intFromBuff(data, 10, 1) & 0xFF);
TemporaryBasal temporaryBasal = new TemporaryBasal();
temporaryBasal.date = datetime.getTime();
temporaryBasal.source = Source.PUMP;
temporaryBasal.pumpId = datetime.getTime();
ExtendedBolus extendedBolus = new ExtendedBolus();
extendedBolus.date = datetime.getTime();
extendedBolus.source = Source.PUMP;
extendedBolus.pumpId = datetime.getTime();
DetailedBolusInfo detailedBolusInfo = DetailedBolusInfoStorage.findDetailedBolusInfo(datetime.getTime());
if (detailedBolusInfo == null) {
log.debug("DetailedBolusInfo not found for " + datetime.toLocaleString());
detailedBolusInfo = new DetailedBolusInfo();
}
detailedBolusInfo.date = datetime.getTime();
detailedBolusInfo.source = Source.PUMP;
detailedBolusInfo.pumpId = datetime.getTime();
switch (recordCode) {
case DanaRPump.TEMPSTART:
log.debug("EVENT TEMPSTART (" + recordCode + ") " + datetime.toLocaleString() + " Ratio: " + param1 + "% Duration: " + param2 + "min");
temporaryBasal.percentRate = param1;
temporaryBasal.durationInMinutes = param2;
MainApp.getConfigBuilder().addToHistoryTempBasal(temporaryBasal);
break;
case DanaRPump.TEMPSTOP:
log.debug("EVENT TEMPSTOP (" + recordCode + ") " + datetime.toLocaleString());
MainApp.getConfigBuilder().addToHistoryTempBasal(temporaryBasal);
break;
case DanaRPump.EXTENDEDSTART:
log.debug("EVENT EXTENDEDSTART (" + recordCode + ") " + datetime.toLocaleString() + " Amount: " + (param1 / 100d) + "U Duration: " + param2 + "min");
extendedBolus.insulin = param1 / 100d;
extendedBolus.durationInMinutes = param2;
MainApp.getConfigBuilder().addToHistoryExtendedBolus(extendedBolus);
break;
case DanaRPump.EXTENDEDSTOP:
log.debug("EVENT EXTENDEDSTOP (" + recordCode + ") " + datetime.toLocaleString() + " Delivered: " + (param1 / 100d) + "U RealDuration: " + param2 + "min");
MainApp.getConfigBuilder().addToHistoryExtendedBolus(extendedBolus);
break;
case DanaRPump.BOLUS:
detailedBolusInfo.insulin = param1 / 100d;
boolean newRecord = MainApp.getConfigBuilder().addToHistoryTreatment(detailedBolusInfo);
log.debug((newRecord ? "**NEW** " : "") + "EVENT BOLUS (" + recordCode + ") " + datetime.toLocaleString() + " Bolus: " + (param1 / 100d) + "U Duration: " + param2 + "min");
DetailedBolusInfoStorage.remove(detailedBolusInfo.date);
break;
case DanaRPump.DUALBOLUS:
detailedBolusInfo.insulin = param1 / 100d;
newRecord = MainApp.getConfigBuilder().addToHistoryTreatment(detailedBolusInfo);
log.debug((newRecord ? "**NEW** " : "") + "EVENT DUALBOLUS (" + recordCode + ") " + datetime.toLocaleString() + " Bolus: " + (param1 / 100d) + "U Duration: " + param2 + "min");
DetailedBolusInfoStorage.remove(detailedBolusInfo.date);
break;
case DanaRPump.DUALEXTENDEDSTART:
log.debug("EVENT DUALEXTENDEDSTART (" + recordCode + ") " + datetime.toLocaleString() + " Amount: " + (param1 / 100d) + "U Duration: " + param2 + "min");
extendedBolus.insulin = param1 / 100d;
extendedBolus.durationInMinutes = param2;
MainApp.getConfigBuilder().addToHistoryExtendedBolus(extendedBolus);
break;
case DanaRPump.DUALEXTENDEDSTOP:
log.debug("EVENT DUALEXTENDEDSTOP (" + recordCode + ") " + datetime.toLocaleString() + " Delivered: " + (param1 / 100d) + "U RealDuration: " + param2 + "min");
MainApp.getConfigBuilder().addToHistoryExtendedBolus(extendedBolus);
break;
case DanaRPump.SUSPENDON:
log.debug("EVENT SUSPENDON (" + recordCode + ") " + datetime.toLocaleString());
break;
case DanaRPump.SUSPENDOFF:
log.debug("EVENT SUSPENDOFF (" + recordCode + ") " + datetime.toLocaleString());
break;
case DanaRPump.REFILL:
log.debug("EVENT REFILL (" + recordCode + ") " + datetime.toLocaleString() + " Amount: " + param1 / 100d + "U");
break;
case DanaRPump.PRIME:
log.debug("EVENT PRIME (" + recordCode + ") " + datetime.toLocaleString() + " Amount: " + param1 / 100d + "U");
break;
case DanaRPump.PROFILECHANGE:
log.debug("EVENT PROFILECHANGE (" + recordCode + ") " + datetime.toLocaleString() + " No: " + param1 + " CurrentRate: " + (param2 / 100d) + "U/h");
break;
case DanaRPump.CARBS:
DetailedBolusInfo emptyCarbsInfo = new DetailedBolusInfo();
emptyCarbsInfo.carbs = param1;
emptyCarbsInfo.date = datetime.getTime();
emptyCarbsInfo.source = Source.PUMP;
emptyCarbsInfo.pumpId = datetime.getTime();
newRecord = MainApp.getConfigBuilder().addToHistoryTreatment(emptyCarbsInfo);
log.debug((newRecord ? "**NEW** " : "") + "EVENT CARBS (" + recordCode + ") " + datetime.toLocaleString() + " Carbs: " + param1 + "g");
break;
case DanaRPump.PRIMECANNULA:
log.debug("EVENT PRIME CANNULA(" + recordCode + ") " + datetime.toLocaleString() + " Amount: " + param1 / 100d + "U");
break;
default:
log.debug("Event: " + recordCode + " " + datetime.toLocaleString() + " Param1: " + param1 + " Param2: " + param2);
break;
}
if (datetime.getTime() > lastEventTimeLoaded)
lastEventTimeLoaded = datetime.getTime();
}
@Override
public String getFriendlyName() {
return "APS_HISTORY_EVENTS";
}
}

View file

@ -0,0 +1,77 @@
package info.nightscout.androidaps.plugins.PumpDanaRS.comm;
import com.cozmo.danar.util.BleCommandUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Calendar;
import java.util.GregorianCalendar;
import info.nightscout.androidaps.Config;
public class DanaRS_Packet_APS_Set_Event_History extends DanaRS_Packet {
private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_APS_Set_Event_History.class);
private int type;
private long time;
public int param1;
public int param2;
public DanaRS_Packet_APS_Set_Event_History() {
super();
opCode = BleCommandUtil.DANAR_PACKET__OPCODE__APS_SET_EVENT_HISTORY;
}
public DanaRS_Packet_APS_Set_Event_History(int type, long time, int param1, int param2) {
this();
this.type = type;
this.time = time;
this.param1 = param1;
this.param2 = param2;
}
@Override
public byte[] getRequestParams() {
GregorianCalendar cal = new GregorianCalendar();
cal.setTimeInMillis(time);
int year = cal.get(Calendar.YEAR) - 1900 - 100;
int month = cal.get(Calendar.MONTH) + 1;
int day = cal.get(Calendar.DAY_OF_MONTH);
int hour = cal.get(Calendar.HOUR_OF_DAY);
int min = cal.get(Calendar.MINUTE);
int sec = cal.get(Calendar.SECOND);
byte[] request = new byte[11];
request[0] = (byte) (type & 0xff);
request[1] = (byte) (year & 0xff);
request[2] = (byte) (month & 0xff);
request[3] = (byte) (day & 0xff);
request[4] = (byte) (hour & 0xff);
request[5] = (byte) (min & 0xff);
request[6] = (byte) (sec & 0xff);
request[7] = (byte) ((param1 >>> 8) & 0xff);
request[8] = (byte) (param1 & 0xff);
request[9] = (byte) ((param2 >>> 8) & 0xff);
request[10] = (byte) (param2 & 0xff);
return request;
}
@Override
public void handleMessage(byte[] data) {
int result = intFromBuff(data, 0, 1);
if (result != 1) {
failed = true;
log.debug("Set history entry result: " + result + " FAILED!!!");
} else {
if (Config.logDanaMessageDetail)
log.debug("Set history entry result: " + result);
}
}
@Override
public String getFriendlyName() {
return "APS_SET_EVENT_HISTORY";
}
}

View file

@ -0,0 +1,68 @@
package info.nightscout.androidaps.plugins.PumpDanaRS.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.Overview.Notification;
import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification;
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump;
import com.cozmo.danar.util.BleCommandUtil;
public class DanaRS_Packet_Basal_Get_Basal_Rate extends DanaRS_Packet {
private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Basal_Set_Cancel_Temporary_Basal.class);
public DanaRS_Packet_Basal_Get_Basal_Rate() {
super();
opCode = BleCommandUtil.DANAR_PACKET__OPCODE_BASAL__GET_BASAL_RATE;
if (Config.logDanaMessageDetail) {
log.debug("Requesting basal rates");
}
}
@Override
public void handleMessage(byte[] data) {
DanaRPump pump = DanaRPump.getInstance();
int dataIndex = DATA_START;
int dataSize = 2;
pump.maxBasal = byteArrayToInt(getBytes(data, dataIndex, dataSize)) / 100d;
dataIndex += dataSize;
dataSize = 1;
pump.basalStep = byteArrayToInt(getBytes(data, dataIndex, dataSize)) / 100d;
if (pump.pumpProfiles == null) pump.pumpProfiles = new double[4][];
pump.pumpProfiles[pump.activeProfile] = new double[24];
for (int i = 0, size = 24; i < size; i++) {
dataIndex += dataSize;
dataSize = 2;
pump.pumpProfiles[pump.activeProfile][i] = byteArrayToInt(getBytes(data, dataIndex, dataSize)) / 100d;
}
if (Config.logDanaMessageDetail) {
log.debug("Max basal: " + pump.maxBasal + " U");
log.debug("Basal step: " + pump.basalStep + " U");
for (int index = 0; index < 24; index++)
log.debug("Basal " + String.format("%02d", index) + "h: " + pump.pumpProfiles[pump.activeProfile][index]);
}
if (pump.basalStep != 0.01d) {
Notification notification = new Notification(Notification.WRONGBASALSTEP, MainApp.sResources.getString(R.string.danar_setbasalstep001), Notification.URGENT);
MainApp.bus().post(new EventNewNotification(notification));
} else {
MainApp.bus().post(new EventDismissNotification(Notification.WRONGBASALSTEP));
}
}
@Override
public String getFriendlyName() {
return "BASAL__GET_BASAL_RATE";
}
}

View file

@ -0,0 +1,61 @@
package info.nightscout.androidaps.plugins.PumpDanaRS.comm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.Config;
import com.cozmo.danar.util.BleCommandUtil;
import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump;
public class DanaRS_Packet_Basal_Get_Profile_Basal_Rate extends DanaRS_Packet {
private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Basal_Get_Profile_Basal_Rate.class);
private int profileNumber;
public DanaRS_Packet_Basal_Get_Profile_Basal_Rate() {
super();
opCode = BleCommandUtil.DANAR_PACKET__OPCODE_BASAL__GET_PROFILE_BASAL_RATE;
}
// 0 - 4
public DanaRS_Packet_Basal_Get_Profile_Basal_Rate(int profileNumber) {
this();
this.profileNumber = profileNumber;
if (Config.logDanaMessageDetail) {
log.debug("Requesting basal rates for profile " + profileNumber);
}
}
@Override
public byte[] getRequestParams() {
byte[] request = new byte[1];
request[0] = (byte) (profileNumber & 0xff);
return request;
}
@Override
public void handleMessage(byte[] data) {
DanaRPump pump = DanaRPump.getInstance();
int dataIndex = DATA_START;
int dataSize = 2;
if (pump.pumpProfiles == null) pump.pumpProfiles = new double[4][];
pump.pumpProfiles[profileNumber] = new double[24];
for (int i = 0, size = 24; i < size; i++) {
pump.pumpProfiles[profileNumber][i] = byteArrayToInt(getBytes(data, dataIndex, dataSize)) / 100d;
dataIndex += dataSize;
dataSize = 2;
}
if (Config.logDanaMessageDetail) {
for (int index = 0; index < 24; index++)
log.debug("Basal " + String.format("%02d", index) + "h: " + pump.pumpProfiles[profileNumber][index]);
}
}
@Override
public String getFriendlyName() {
return "BASAL__GET_PROFILE_BASAL_RATE";
}
}

View file

@ -0,0 +1,37 @@
package info.nightscout.androidaps.plugins.PumpDanaRS.comm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.Config;
import com.cozmo.danar.util.BleCommandUtil;
import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump;
public class DanaRS_Packet_Basal_Get_Profile_Number extends DanaRS_Packet {
private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Basal_Get_Profile_Number.class);
public DanaRS_Packet_Basal_Get_Profile_Number() {
super();
opCode = BleCommandUtil.DANAR_PACKET__OPCODE_BASAL__GET_PROFILE_NUMBER;
if (Config.logDanaMessageDetail) {
log.debug("Requesting active profile");
}
}
@Override
public void handleMessage(byte[] data) {
DanaRPump pump = DanaRPump.getInstance();
int dataIndex = DATA_START;
int dataSize = 1;
pump.activeProfile = byteArrayToInt(getBytes(data, dataIndex, dataSize));
if (Config.logDanaMessageDetail) {
log.debug("Active profile: " + pump.activeProfile);
}
}
@Override
public String getFriendlyName() {
return "BASAL__GET_PROFILE_NUMBER";
}
}

View file

@ -0,0 +1,77 @@
package info.nightscout.androidaps.plugins.PumpDanaRS.comm;
import android.support.annotation.NonNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Date;
import info.nightscout.androidaps.Config;
import com.cozmo.danar.util.BleCommandUtil;
import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump;
public class DanaRS_Packet_Basal_Get_Temporary_Basal_State extends DanaRS_Packet {
private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Basal_Get_Temporary_Basal_State.class);
public DanaRS_Packet_Basal_Get_Temporary_Basal_State() {
super();
opCode = BleCommandUtil.DANAR_PACKET__OPCODE_BASAL__TEMPORARY_BASAL_STATE;
if (Config.logDanaMessageDetail) {
log.debug("Requesting temporary basal status");
}
}
@Override
public void handleMessage(byte[] data) {
DanaRPump pump = DanaRPump.getInstance();
int dataIndex = DATA_START;
int dataSize = 1;
int error = byteArrayToInt(getBytes(data, dataIndex, dataSize));
dataIndex += dataSize;
dataSize = 1;
pump.isTempBasalInProgress = byteArrayToInt(getBytes(data, dataIndex, dataSize)) == 0x01;
boolean isAPSTempBasalInProgress = byteArrayToInt(getBytes(data, dataIndex, dataSize)) == 0x02;
dataIndex += dataSize;
dataSize = 1;
pump.tempBasalPercent = byteArrayToInt(getBytes(data, dataIndex, dataSize));
if (pump.tempBasalPercent > 200) pump.tempBasalPercent = (pump.tempBasalPercent - 200) * 10;
dataIndex += dataSize;
dataSize = 1;
int durationHour = byteArrayToInt(getBytes(data, dataIndex, dataSize));
if (durationHour == 150) pump.tempBasalTotalSec = 15 * 60;
else if (durationHour == 160) pump.tempBasalTotalSec = 30 * 60;
else pump.tempBasalTotalSec = durationHour * 60 * 60;
dataIndex += dataSize;
dataSize = 2;
int runningMin = byteArrayToInt(getBytes(data, dataIndex, dataSize));
int tempBasalRemainingMin = (pump.tempBasalTotalSec - runningMin * 60) / 60;
Date tempBasalStart = pump.isTempBasalInProgress ? getDateFromTempBasalSecAgo(runningMin * 60) : new Date(0);
if (Config.logDanaMessageDetail) {
log.debug("Error code: " + error);
log.debug("Is temp basal running: " + pump.isTempBasalInProgress);
log.debug("Is APS temp basal running: " + isAPSTempBasalInProgress);
log.debug("Current temp basal percent: " + pump.tempBasalPercent);
log.debug("Current temp basal remaining min: " + tempBasalRemainingMin);
log.debug("Current temp basal total sec: " + pump.tempBasalTotalSec);
log.debug("Current temp basal start: " + tempBasalStart);
}
}
@Override
public String getFriendlyName() {
return "BASAL__TEMPORARY_BASAL_STATE";
}
@NonNull
private Date getDateFromTempBasalSecAgo(int tempBasalAgoSecs) {
return new Date((long) (Math.ceil(System.currentTimeMillis() / 1000d) - tempBasalAgoSecs) * 1000);
}
}

View file

@ -0,0 +1,53 @@
package info.nightscout.androidaps.plugins.PumpDanaRS.comm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.Config;
import com.cozmo.danar.util.BleCommandUtil;
public class DanaRS_Packet_Basal_Set_Basal_Rate extends DanaRS_Packet {
private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Basal_Set_Basal_Rate.class);
private double[] profileBasalRate;
public int error;
public DanaRS_Packet_Basal_Set_Basal_Rate() {
super();
opCode = BleCommandUtil.DANAR_PACKET__OPCODE_BASAL__SET_BASAL_RATE;
}
public DanaRS_Packet_Basal_Set_Basal_Rate(double[] profileBasalRate) {
this();
this.profileBasalRate = profileBasalRate;
if (Config.logDanaMessageDetail) {
log.debug("Setting new basal rates");
}
}
@Override
public byte[] getRequestParams() {
byte[] request = new byte[48];
for (int i = 0, size = 24; i < size; i++) {
int rate = (int) (profileBasalRate[i] * 100d);
request[0 + (i * 2)] = (byte) (rate & 0xff);
request[1 + (i * 2)] = (byte) ((rate >>> 8) & 0xff);
}
return request;
}
@Override
public void handleMessage(byte[] data) {
int dataIndex = DATA_START;
int dataSize = 1;
error = byteArrayToInt(getBytes(data, dataIndex, dataSize));
if (Config.logDanaMessageDetail) {
log.debug("Result: " + error);
}
}
@Override
public String getFriendlyName() {
return "BASAL__SET_BASAL_RATE";
}
}

View file

@ -0,0 +1,36 @@
package info.nightscout.androidaps.plugins.PumpDanaRS.comm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.Config;
import com.cozmo.danar.util.BleCommandUtil;
public class DanaRS_Packet_Basal_Set_Cancel_Temporary_Basal extends DanaRS_Packet {
private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Basal_Set_Cancel_Temporary_Basal.class);
public int error;
public DanaRS_Packet_Basal_Set_Cancel_Temporary_Basal() {
super();
opCode = BleCommandUtil.DANAR_PACKET__OPCODE_BASAL__CANCEL_TEMPORARY_BASAL;
if (Config.logDanaMessageDetail) {
log.debug("Canceling temp basal");
}
}
@Override
public void handleMessage(byte[] data) {
error = byteArrayToInt(getBytes(data, DATA_START, 1));
if (Config.logDanaMessageDetail) {
log.debug("Result " + error);
}
}
@Override
public String getFriendlyName() {
return "BASAL__CANCEL_TEMPORARY_BASAL";
}
}

View file

@ -0,0 +1,56 @@
package info.nightscout.androidaps.plugins.PumpDanaRS.comm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.Config;
import com.cozmo.danar.util.BleCommandUtil;
public class DanaRS_Packet_Basal_Set_Profile_Basal_Rate extends DanaRS_Packet {
private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_Basal_Set_Profile_Basal_Rate.class);
private int profileNumber; // 0 - 4
private double[] profileBasalRate;
public int error;
public DanaRS_Packet_Basal_Set_Profile_Basal_Rate() {
super();
opCode = BleCommandUtil.DANAR_PACKET__OPCODE_BASAL__SET_PROFILE_BASAL_RATE;
}
public DanaRS_Packet_Basal_Set_Profile_Basal_Rate(int profileNumber, double[] profileBasalRate) {
this();
this.profileNumber = profileNumber;
this.profileBasalRate = profileBasalRate;
if (Config.logDanaMessageDetail) {
log.debug("Setting new basal rates for profile " + profileNumber);
}
}
@Override
public byte[] getRequestParams() {
byte[] request = new byte[49];
request[0] = (byte) (profileNumber & 0xff);
for (int i = 0, size = 24; i < size; i++) {
int rate = (int) (profileBasalRate[i] * 100d);
request[1 + (i * 2)] = (byte) (rate & 0xff);
request[2 + (i * 2)] = (byte) ((rate >>> 8) & 0xff);
}
return request;
}
@Override
public void handleMessage(byte[] data) {
int dataIndex = DATA_START;
int dataSize = 1;
error = byteArrayToInt(getBytes(data, dataIndex, dataSize));
if (Config.logDanaMessageDetail) {
log.debug("Result: " + error);
}
}
@Override
public String getFriendlyName() {
return "BASAL__SET_PROFILE_BASAL_RATE";
}
}

Some files were not shown because too many files have changed in this diff Show more